From 1e67b2efd40f2a384f443a91eb23c1f2afe83765 Mon Sep 17 00:00:00 2001 From: James Sweet Date: Sun, 14 Sep 2014 12:55:35 -0400 Subject: [PATCH 001/338] Updated code to obey BUILD_TESTING to allow for disabling of test compilation --- CMakeLists.txt | 8 ++++++-- platforms/cpu/CMakeLists.txt | 5 +++-- plugins/amoeba/CMakeLists.txt | 4 +++- plugins/amoeba/platforms/reference/CMakeLists.txt | 5 ++++- plugins/cpupme/CMakeLists.txt | 4 +++- plugins/drude/CMakeLists.txt | 4 +++- plugins/drude/platforms/reference/CMakeLists.txt | 5 ++++- plugins/rpmd/platforms/reference/CMakeLists.txt | 5 ++++- serialization/CMakeLists.txt | 4 +++- 9 files changed, 33 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6cd196b3..d4fa57c73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -324,7 +324,9 @@ ELSE(DL_LIBRARY) ENDIF(OPENMM_BUILD_SHARED_LIB) ENDIF(DL_LIBRARY) -ADD_SUBDIRECTORY(platforms/reference/tests) +IF(BUILD_TESTING) + ADD_SUBDIRECTORY(platforms/reference/tests) +ENDIF(BUILD_TESTING) # Which hardware platforms to build @@ -506,7 +508,9 @@ ELSE (EXECUTABLE_OUTPUT_PATH) ENDIF (EXECUTABLE_OUTPUT_PATH) ADD_SUBDIRECTORY(docs-source) -ADD_SUBDIRECTORY(tests) +IF(BUILD_TESTING) + ADD_SUBDIRECTORY(tests) +ENDIF(BUILD_TESTING) ADD_SUBDIRECTORY(examples) ENDIF(NOT cmv EQUAL "2.4") # This whole file... diff --git a/platforms/cpu/CMakeLists.txt b/platforms/cpu/CMakeLists.txt index e5de19991..4881ffa17 100644 --- a/platforms/cpu/CMakeLists.txt +++ b/platforms/cpu/CMakeLists.txt @@ -12,7 +12,9 @@ # libOpenMMCPU_static.a #---------------------------------------------------- -SUBDIRS (tests) +IF(BUILD_TESTING) + SUBDIRS(tests) +ENDIF(BUILD_TESTING) # The source is organized into subdirectories, but we handle them all from # this CMakeLists file rather than letting CMake visit them as SUBDIRS. @@ -82,4 +84,3 @@ ENDIF(OPENMM_BUILD_SHARED_LIB) IF(OPENMM_BUILD_STATIC_LIB) SUBDIRS (staticTarget) ENDIF(OPENMM_BUILD_STATIC_LIB) - diff --git a/plugins/amoeba/CMakeLists.txt b/plugins/amoeba/CMakeLists.txt index 6fb8b0309..d495a47ee 100644 --- a/plugins/amoeba/CMakeLists.txt +++ b/plugins/amoeba/CMakeLists.txt @@ -162,4 +162,6 @@ ELSE (EXECUTABLE_OUTPUT_PATH) SET (TEST_PATH .) ENDIF (EXECUTABLE_OUTPUT_PATH) -ADD_SUBDIRECTORY(serialization/tests) +IF(BUILD_TESTING) + ADD_SUBDIRECTORY(serialization/tests) +ENDIF(BUILD_TESTING) diff --git a/plugins/amoeba/platforms/reference/CMakeLists.txt b/plugins/amoeba/platforms/reference/CMakeLists.txt index ed80e7cd4..441e17d4c 100644 --- a/plugins/amoeba/platforms/reference/CMakeLists.txt +++ b/plugins/amoeba/platforms/reference/CMakeLists.txt @@ -74,4 +74,7 @@ SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}") INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) -SUBDIRS (tests) + +IF(BUILD_TESTING) + SUBDIRS (tests) +ENDIF(BUILD_TESTING) diff --git a/plugins/cpupme/CMakeLists.txt b/plugins/cpupme/CMakeLists.txt index 6013abbe7..5e9e0f27a 100644 --- a/plugins/cpupme/CMakeLists.txt +++ b/plugins/cpupme/CMakeLists.txt @@ -93,4 +93,6 @@ IF(OPENMM_BUILD_STATIC_LIB) INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${STATIC_TARGET}) ENDIF(OPENMM_BUILD_STATIC_LIB) -SUBDIRS(tests) +IF(BUILD_TESTING) + SUBDIRS(tests) +ENDIF(BUILD_TESTING) diff --git a/plugins/drude/CMakeLists.txt b/plugins/drude/CMakeLists.txt index bb530632a..2f66e5e03 100644 --- a/plugins/drude/CMakeLists.txt +++ b/plugins/drude/CMakeLists.txt @@ -145,4 +145,6 @@ ENDIF (EXECUTABLE_OUTPUT_PATH) #INCLUDE(ApiDoxygen.cmake) -ADD_SUBDIRECTORY(serialization/tests) +IF(BUILD_TESTING) + ADD_SUBDIRECTORY(serialization/tests) +ENDIF(BUILD_TESTING) diff --git a/plugins/drude/platforms/reference/CMakeLists.txt b/plugins/drude/platforms/reference/CMakeLists.txt index 6fdad2ce7..78d960afb 100644 --- a/plugins/drude/platforms/reference/CMakeLists.txt +++ b/plugins/drude/platforms/reference/CMakeLists.txt @@ -74,4 +74,7 @@ TARGET_LINK_LIBRARIES(${SHARED_TARGET} debug ${SHARED_DRUDE_TARGET} optimized ${ SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY") INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) -SUBDIRS (tests) + +IF(BUILD_TESTING) + SUBDIRS (tests) +ENDIF(BUILD_TESTING) diff --git a/plugins/rpmd/platforms/reference/CMakeLists.txt b/plugins/rpmd/platforms/reference/CMakeLists.txt index 550f2a07c..7dc038274 100644 --- a/plugins/rpmd/platforms/reference/CMakeLists.txt +++ b/plugins/rpmd/platforms/reference/CMakeLists.txt @@ -74,4 +74,7 @@ TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${SHARED_RPMD_TARGET}) SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY") INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) -SUBDIRS (tests) + +IF(BUILD_TESTING) + SUBDIRS (tests) +ENDIF(BUILD_TESTING) diff --git a/serialization/CMakeLists.txt b/serialization/CMakeLists.txt index cbadd9f14..b4e2db9ec 100644 --- a/serialization/CMakeLists.txt +++ b/serialization/CMakeLists.txt @@ -6,4 +6,6 @@ INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/in INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/openmm/serialization/SerializationProxy.h) INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/openmm/serialization/XmlSerializer.h) -ADD_SUBDIRECTORY(tests) +IF(BUILD_TESTING) + ADD_SUBDIRECTORY(tests) +ENDIF(BUILD_TESTING) -- GitLab From a83607d625197e8a0ea56b7222707b2a5ea934ac Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 16 Sep 2014 12:53:31 -0700 Subject: [PATCH 002/338] Preliminary implementation of JIT compilation for CompiledExpressions --- libraries/asmjit/LICENSE.md | 18 + libraries/asmjit/apibegin.h | 49 + libraries/asmjit/apiend.h | 33 + libraries/asmjit/asmjit.h | 379 + libraries/asmjit/base.h | 34 + libraries/asmjit/base/assembler.cpp | 387 + libraries/asmjit/base/assembler.h | 540 ++ libraries/asmjit/base/codegen.cpp | 111 + libraries/asmjit/base/codegen.h | 337 + libraries/asmjit/base/compiler.cpp | 621 ++ libraries/asmjit/base/compiler.h | 3104 ++++++++ libraries/asmjit/base/constpool.cpp | 537 ++ libraries/asmjit/base/constpool.h | 299 + libraries/asmjit/base/containers.cpp | 116 + libraries/asmjit/base/containers.h | 350 + libraries/asmjit/base/context.cpp | 561 ++ libraries/asmjit/base/context_p.h | 307 + libraries/asmjit/base/cpuinfo.cpp | 79 + libraries/asmjit/base/cpuinfo.h | 147 + libraries/asmjit/base/cputicks.cpp | 131 + libraries/asmjit/base/cputicks.h | 40 + libraries/asmjit/base/error.cpp | 81 + libraries/asmjit/base/error.h | 218 + libraries/asmjit/base/globals.cpp | 30 + libraries/asmjit/base/globals.h | 177 + libraries/asmjit/base/intutil.cpp | 210 + libraries/asmjit/base/intutil.h | 713 ++ libraries/asmjit/base/lock.h | 131 + libraries/asmjit/base/logger.cpp | 167 + libraries/asmjit/base/logger.h | 246 + libraries/asmjit/base/operand.cpp | 38 + libraries/asmjit/base/operand.h | 1090 +++ libraries/asmjit/base/runtime.cpp | 191 + libraries/asmjit/base/runtime.h | 262 + libraries/asmjit/base/string.cpp | 374 + libraries/asmjit/base/string.h | 372 + libraries/asmjit/base/vectypes.h | 1251 ++++ libraries/asmjit/base/vmem.cpp | 1286 ++++ libraries/asmjit/base/vmem.h | 240 + libraries/asmjit/base/zone.cpp | 195 + libraries/asmjit/base/zone.h | 221 + libraries/asmjit/build.h | 385 + libraries/asmjit/config.h | 53 + libraries/asmjit/contrib.h | 18 + libraries/asmjit/contrib/winremoteruntime.cpp | 79 + libraries/asmjit/contrib/winremoteruntime.h | 74 + libraries/asmjit/host.h | 59 + libraries/asmjit/x86.h | 21 + libraries/asmjit/x86/x86assembler.cpp | 4189 +++++++++++ libraries/asmjit/x86/x86assembler.h | 6520 +++++++++++++++++ libraries/asmjit/x86/x86compiler.cpp | 1370 ++++ libraries/asmjit/x86/x86compiler.h | 5489 ++++++++++++++ libraries/asmjit/x86/x86context.cpp | 5691 ++++++++++++++ libraries/asmjit/x86/x86context_p.h | 523 ++ libraries/asmjit/x86/x86cpuinfo.cpp | 303 + libraries/asmjit/x86/x86cpuinfo.h | 232 + libraries/asmjit/x86/x86inst.cpp | 4850 ++++++++++++ libraries/asmjit/x86/x86inst.h | 2211 ++++++ libraries/asmjit/x86/x86operand.cpp | 85 + libraries/asmjit/x86/x86operand.h | 1531 ++++ libraries/asmjit/x86/x86operand_regs.cpp | 188 + libraries/asmjit/x86/x86scheduler.cpp | 94 + libraries/asmjit/x86/x86scheduler_p.h | 63 + .../include/lepton/CompiledExpression.h | 4 + libraries/lepton/src/CompiledExpression.cpp | 73 +- 65 files changed, 49771 insertions(+), 7 deletions(-) create mode 100644 libraries/asmjit/LICENSE.md create mode 100644 libraries/asmjit/apibegin.h create mode 100644 libraries/asmjit/apiend.h create mode 100644 libraries/asmjit/asmjit.h create mode 100644 libraries/asmjit/base.h create mode 100644 libraries/asmjit/base/assembler.cpp create mode 100644 libraries/asmjit/base/assembler.h create mode 100644 libraries/asmjit/base/codegen.cpp create mode 100644 libraries/asmjit/base/codegen.h create mode 100644 libraries/asmjit/base/compiler.cpp create mode 100644 libraries/asmjit/base/compiler.h create mode 100644 libraries/asmjit/base/constpool.cpp create mode 100644 libraries/asmjit/base/constpool.h create mode 100644 libraries/asmjit/base/containers.cpp create mode 100644 libraries/asmjit/base/containers.h create mode 100644 libraries/asmjit/base/context.cpp create mode 100644 libraries/asmjit/base/context_p.h create mode 100644 libraries/asmjit/base/cpuinfo.cpp create mode 100644 libraries/asmjit/base/cpuinfo.h create mode 100644 libraries/asmjit/base/cputicks.cpp create mode 100644 libraries/asmjit/base/cputicks.h create mode 100644 libraries/asmjit/base/error.cpp create mode 100644 libraries/asmjit/base/error.h create mode 100644 libraries/asmjit/base/globals.cpp create mode 100644 libraries/asmjit/base/globals.h create mode 100644 libraries/asmjit/base/intutil.cpp create mode 100644 libraries/asmjit/base/intutil.h create mode 100644 libraries/asmjit/base/lock.h create mode 100644 libraries/asmjit/base/logger.cpp create mode 100644 libraries/asmjit/base/logger.h create mode 100644 libraries/asmjit/base/operand.cpp create mode 100644 libraries/asmjit/base/operand.h create mode 100644 libraries/asmjit/base/runtime.cpp create mode 100644 libraries/asmjit/base/runtime.h create mode 100644 libraries/asmjit/base/string.cpp create mode 100644 libraries/asmjit/base/string.h create mode 100644 libraries/asmjit/base/vectypes.h create mode 100644 libraries/asmjit/base/vmem.cpp create mode 100644 libraries/asmjit/base/vmem.h create mode 100644 libraries/asmjit/base/zone.cpp create mode 100644 libraries/asmjit/base/zone.h create mode 100644 libraries/asmjit/build.h create mode 100644 libraries/asmjit/config.h create mode 100644 libraries/asmjit/contrib.h create mode 100644 libraries/asmjit/contrib/winremoteruntime.cpp create mode 100644 libraries/asmjit/contrib/winremoteruntime.h create mode 100644 libraries/asmjit/host.h create mode 100644 libraries/asmjit/x86.h create mode 100644 libraries/asmjit/x86/x86assembler.cpp create mode 100644 libraries/asmjit/x86/x86assembler.h create mode 100644 libraries/asmjit/x86/x86compiler.cpp create mode 100644 libraries/asmjit/x86/x86compiler.h create mode 100644 libraries/asmjit/x86/x86context.cpp create mode 100644 libraries/asmjit/x86/x86context_p.h create mode 100644 libraries/asmjit/x86/x86cpuinfo.cpp create mode 100644 libraries/asmjit/x86/x86cpuinfo.h create mode 100644 libraries/asmjit/x86/x86inst.cpp create mode 100644 libraries/asmjit/x86/x86inst.h create mode 100644 libraries/asmjit/x86/x86operand.cpp create mode 100644 libraries/asmjit/x86/x86operand.h create mode 100644 libraries/asmjit/x86/x86operand_regs.cpp create mode 100644 libraries/asmjit/x86/x86scheduler.cpp create mode 100644 libraries/asmjit/x86/x86scheduler_p.h diff --git a/libraries/asmjit/LICENSE.md b/libraries/asmjit/LICENSE.md new file mode 100644 index 000000000..7742e92ff --- /dev/null +++ b/libraries/asmjit/LICENSE.md @@ -0,0 +1,18 @@ +AsmJit - Complete x86/x64 JIT and Remote Assembler for C++ +Copyright (c) 2008-2014, Petr Kobalicek + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. diff --git a/libraries/asmjit/apibegin.h b/libraries/asmjit/apibegin.h new file mode 100644 index 000000000..b025e2e96 --- /dev/null +++ b/libraries/asmjit/apibegin.h @@ -0,0 +1,49 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +#if !defined(_ASMJIT_BUILD_H) +#include "build.h" +#endif // !_ASMJIT_BUILD_H + +// ============================================================================ +// [MSVC] +// ============================================================================ + +#if defined(_MSC_VER) +// Disable some warnings we know about +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4201) // nameless struct/union +# pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible + // loss of data +# pragma warning(disable: 4251) // struct needs to have dll-interface to be used + // by clients of struct ... +# pragma warning(disable: 4275) // non dll-interface struct ... used as base for + // dll-interface struct +# pragma warning(disable: 4355) // this used in base member initializer list +# pragma warning(disable: 4480) // specifying underlying type for enum +# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' + +// Rename symbols. +# if !defined(vsnprintf) +# define ASMJIT_DEFINED_VSNPRINTF +# define vsnprintf _vsnprintf +# endif // !vsnprintf +# if !defined(snprintf) +# define ASMJIT_DEFINED_SNPRINTF +# define snprintf _snprintf +# endif // !snprintf +#endif // _MSC_VER + +// ============================================================================ +// [GNUC] +// ============================================================================ + +#if defined(__GNUC__) && !defined(__clang__) +# if __GNUC__ >= 4 && !defined(__MINGW32__) +# pragma GCC visibility push(hidden) +# endif // __GNUC__ >= 4 +#endif // __GNUC__ diff --git a/libraries/asmjit/apiend.h b/libraries/asmjit/apiend.h new file mode 100644 index 000000000..4ec7834cb --- /dev/null +++ b/libraries/asmjit/apiend.h @@ -0,0 +1,33 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// ============================================================================ +// [MSVC] +// ============================================================================ + +#if defined(_MSC_VER) +// Pop disabled warnings by ApiBegin.h +# pragma warning(pop) +// Rename symbols back. +# if defined(ASMJIT_DEFINED_VSNPRINTF) +# undef ASMJIT_DEFINED_VSNPRINTF +# undef vsnprintf +# endif // ASMJIT_DEFINED_VSNPRINTF +# if defined(ASMJIT_DEFINED_SNPRINTF) +# undef ASMJIT_DEFINED_SNPRINTF +# undef snprintf +# endif // ASMJIT_DEFINED_SNPRINTF +#endif // _MSC_VER + +// ============================================================================ +// [GNUC] +// ============================================================================ + +#if defined(__GNUC__) && !defined(__clang__) +# if __GNUC__ >= 4 && !defined(__MINGW32__) +# pragma GCC visibility pop +# endif // __GNUC__ >= 4 +#endif // __GNUC__ diff --git a/libraries/asmjit/asmjit.h b/libraries/asmjit/asmjit.h new file mode 100644 index 000000000..5737ff834 --- /dev/null +++ b/libraries/asmjit/asmjit.h @@ -0,0 +1,379 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_ASMJIT_H +#define _ASMJIT_ASMJIT_H + +// ============================================================================ +// [asmjit_mainpage] +// ============================================================================ + +//! @mainpage +//! +//! AsmJit - Complete x86/x64 JIT and Remote Assembler for C++. +//! +//! AsmJit is a complete JIT and remote assembler for C++ language. It can +//! generate native code for x86 and x64 architectures having support for +//! a full instruction set, from legacy MMX to the newest AVX2. It has a +//! type-safe API that allows C++ compiler to do a semantic checks at +//! compile-time even before the assembled code is generated or run. +//! +//! AsmJit is not a virtual machine (VM). It doesn't have functionality to +//! implement VM out of the box; however, it can be be used as a JIT backend +//! for your own VM. The usage of AsmJit is not limited at all; it's suitable +//! for multimedia, VM backends or remote code generation. +//! +//! @section AsmJit_Concepts Code Generation Concepts +//! +//! AsmJit has two completely different code generation concepts. The difference +//! is in how the code is generated. The first concept, also referred as the low +//! level concept, is called 'Assembler' and it's the same as writing RAW +//! assembly by using physical registers directly. In this case AsmJit does only +//! instruction encoding, verification and relocation. +//! +//! The second concept, also referred as the high level concept, is called +//! 'Compiler'. Compiler lets you use virtually unlimited number of registers +//! (called variables) significantly simplifying the code generation process. +//! Compiler allocates these virtual registers to physical registers after the +//! code generation is done. This requires some extra effort - Compiler has to +//! generate information for each node (instruction, function declaration, +//! function call) in the code, perform a variable liveness analysis and +//! translate the code having variables into code having only registers. +//! +//! In addition, Compiler understands functions and function calling conventions. +//! It has been designed in a way that the code generated is always a function +//! having prototype like in a programming language. By having a function +//! prototype the Compiler is able to insert prolog and epilog to a function +//! being generated and it is able to call a function inside a generated one. +//! +//! There is no conclusion on which concept is better. Assembler brings full +//! control on how the code is generated, while Compiler makes the generation +//! more portable. +//! +//! @section AsmJit_Main_CodeGeneration Code Generation +//! +//! - \ref asmjit_base_general "Assembler core" - Operands, intrinsics and low-level assembler. +//! - \ref asmjit_compiler "Compiler" - High level code generation. +//! - \ref asmjit_cpuinfo "Cpu Information" - Get information about host processor. +//! - \ref asmjit_logging "Logging" - Logging and error handling. +//! - \ref AsmJit_MemoryManagement "Memory Management" - Virtual memory management. +//! +//! @section AsmJit_Main_HomePage AsmJit Homepage +//! +//! - https://github.com/kobalicek/asmjit + +// ============================================================================ +// [asmjit_base] +// ============================================================================ + +//! \defgroup asmjit_base AsmJit +//! +//! \brief AsmJit. + +// ============================================================================ +// [asmjit_base_general] +// ============================================================================ + +//! \defgroup asmjit_base_general AsmJit General API +//! \ingroup asmjit_base +//! +//! \brief AsmJit general API. +//! +//! Contains all `asmjit` classes and helper functions that are architecture +//! independent or abstract. Abstract classes are implemented by the backend, +//! for example `Assembler` is implemented by `X86Assembler`. +//! +//! - See `Assembler` for low level code generation documentation. +//! - See `Compiler` for high level code generation documentation. +//! - See `Operand` for operand's overview. +//! +//! Logging and Error Handling +//! -------------------------- +//! +//! AsmJit contains robust interface that can be used to log the generated code +//! and to handle possible errors. Base logging interface is defined in `Logger` +//! class that is abstract and can be overridden. AsmJit contains two loggers +//! that can be used out of the box - `FileLogger` that logs into a pure C +//! `FILE*` stream and `StringLogger` that just concatenates all log messages +//! by using a `StringBuilder` class. +//! +//! The following snippet shows how to setup a logger that logs to `stderr`: +//! +//! ~~~ +//! // `FileLogger` instance. +//! FileLogger logger(stderr); +//! +//! // `Compiler` or any other `CodeGen` interface. +//! host::Compiler c; +//! +//! // use `setLogger` to replace the `CodeGen` logger. +//! c.setLogger(&logger); +//! ~~~ +//! +//! \sa \ref Logger, \ref FileLogger, \ref StringLogger. + +// ============================================================================ +// [asmjit_base_compiler] +// ============================================================================ + +//! \defgroup asmjit_base_compiler AsmJit Compiler +//! \ingroup asmjit_base +//! +//! \brief AsmJit code-tree used by Compiler. +//! +//! AsmJit intermediate code-tree is a double-linked list that is made of nodes +//! that represent assembler instructions, directives, labels and high-level +//! constructs compiler is using to represent functions and function calls. The +//! node list can only be used together with \ref Compiler. +//! +//! TODO + +// ============================================================================ +// [asmjit_base_util] +// ============================================================================ + +//! \defgroup asmjit_base_util AsmJit Utilities +//! \ingroup asmjit_base +//! +//! \brief AsmJit utility classes. +//! +//! AsmJit contains numerous utility classes that are needed by the library +//! itself. The most useful ones have been made public and are now exported. +//! +//! POD Containers +//! -------------- +//! +//! POD containers are used by AsmJit to manage its own data structures. The +//! following classes can be used by AsmJit consumers: +//! +//! - \ref PodVector - Simple growing array-like container for POD data. +//! - \ref StringBuilder - Simple string builder that can append string +//! and integers. +//! +//! Zone Memory Allocator +//! --------------------- +//! +//! Zone memory allocator is an incremental memory allocator that can be used +//! to allocate data of short life-time. It has much better performance +//! characteristics than all other allocators, because the only thing it can do +//! is to increment a pointer and return its previous address. See \ref Zone +//! for more details. +//! +//! CPU Ticks +//! --------- +//! +//! CPU Ticks is a simple helper that can be used to do basic benchmarks. See +//! \ref CpuTicks class for more details. +//! +//! Integer Utilities +//! ----------------- +//! +//! Integer utilities are all implemented by a static class \ref IntUtil. +//! There are utilities for bit manipulation and bit counting, utilities to get +//! an integer minimum / maximum and various other helpers required to perform +//! alignment checks and binary casting from float to integer and vica versa. +//! +//! Vector Utilities +//! ---------------- +//! +//! SIMD code generation often requires to embed constants after each function +//! or a block of functions generated. AsmJit contains classes `Vec64`, +//! `Vec128` and `Vec256` that can be used to prepare data useful when +//! generating SIMD code. +//! +//! X86/X64 code generator contains member functions `dmm`, `dxmm` and `dymm` +//! which can be used to embed 64-bit, 128-bit and 256-bit data structures into +//! machine code (both assembler and compiler are supported). +//! +//! \note Compiler contains a constant pool, which should be used instead of +//! embedding constants manually after the function body. + +// ============================================================================ +// [asmjit_x86] +// ============================================================================ + +//! \defgroup asmjit_x86 X86/X64 +//! +//! \brief X86/X64 module + +// ============================================================================ +// [asmjit_x86_general] +// ============================================================================ + +//! \defgroup asmjit_x86_general X86/X64 General API +//! \ingroup asmjit_x86 +//! +//! \brief X86/X64 general API. +//! +//! X86/X64 Registers +//! ----------------- +//! +//! There are static objects that represents X86 and X64 registers. They can +//! be used directly (like `eax`, `mm`, `xmm`, ...) or created through +//! these functions: +//! +//! - `asmjit::gpb_lo()` - Get Gpb-lo register. +//! - `asmjit::gpb_hi()` - Get Gpb-hi register. +//! - `asmjit::gpw()` - Get Gpw register. +//! - `asmjit::gpd()` - Get Gpd register. +//! - `asmjit::gpq()` - Get Gpq Gp register. +//! - `asmjit::gpz()` - Get Gpd/Gpq register. +//! - `asmjit::fp()` - Get Fp register. +//! - `asmjit::mm()` - Get Mm register. +//! - `asmjit::xmm()` - Get Xmm register. +//! - `asmjit::ymm()` - Get Ymm register. +//! +//! X86/X64 Addressing +//! ------------------ +//! +//! X86 and x64 architectures contains several addressing modes and most ones +//! are possible with AsmJit library. Memory represents are represented by +//! `BaseMem` class. These functions are used to make operands that represents +//! memory addresses: +//! +//! - `asmjit::ptr()` +//! - `asmjit::byte_ptr()` +//! - `asmjit::word_ptr()` +//! - `asmjit::dword_ptr()` +//! - `asmjit::qword_ptr()` +//! - `asmjit::tword_ptr()` +//! - `asmjit::oword_ptr()` +//! - `asmjit::yword_ptr()` +//! - `asmjit::zword_ptr()` +//! +//! Most useful function to make pointer should be `asmjit::ptr()`. It creates +//! pointer to the target with unspecified size. Unspecified size works in all +//! intrinsics where are used registers (this means that size is specified by +//! register operand or by instruction itself). For example `asmjit::ptr()` +//! can't be used with `Assembler::inc()` instruction. In this case size must +//! be specified and it's also reason to make difference between pointer sizes. +//! +//! Supported are simple address forms `[base + displacement]` and complex +//! address forms `[base + index * scale + displacement]`. +//! +//! X86/X64 Immediates +//! ------------------ +//! +//! Immediate values are constants thats passed directly after instruction +//! opcode. To create such value use `imm()` or `imm_u()` methods to create +//! signed or unsigned immediate value. +//! +//! X86/X64 CPU Information +//! ----------------------- +//! +//! The CPUID instruction can be used to get an exhaustive information about +//! the host X86/X64 processor. AsmJit contains utilities that can get the most +//! important information related to the features supported by the CPU and the +//! host operating system, in addition to host processor name and number of +//! cores. Class `X86CpuInfo` extends `CpuInfo` and provides functionality +//! specific to X86 and X64. +//! +//! By default AsmJit queries the CPU information after the library is loaded +//! and the queried information is reused by all instances of `JitRuntime`. +//! The global instance of `X86CpuInfo` can't be changed, because it will affect +//! the code generation of all `Runtime`s. If there is a need to have a +//! specific CPU information which contains modified features or processor +//! vendor it's possible by creating a new instance of `X86CpuInfo` and setting +//! up its members. `X86CpuUtil::detect` can be used to detect CPU features into +//! an existing `X86CpuInfo` instance - it may become handly if only one property +//! has to be turned on/off. +//! +//! If the high-level interface `X86CpuInfo` offers is not enough there is also +//! `X86CpuUtil::callCpuId` helper that can be used to call CPUID instruction +//! with a given parameters and to consume the output. +//! +//! Cpu detection is important when generating a JIT code that may or may not +//! use certain CPU features. For example there used to be a SSE/SSE2 detection +//! in the past and today there is often AVX/AVX2 detection. +//! +//! The example below shows how to detect SSE2: +//! +//! ~~~ +//! using namespace asmjit; +//! +//! // Get `X86CpuInfo` global instance. +//! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost(); +//! +//! if (cpuInfo->hasFeature(kX86CpuFeatureSse2)) { +//! // Processor has SSE2. +//! } +//! else if (cpuInfo->hasFeature(kX86CpuFeatureMmx)) { +//! // Processor doesn't have SSE2, but has MMX. +//! } +//! else { +//! // Processor is archaic; it's a wonder AsmJit works here! +//! } +//! ~~~ +//! +//! The next example shows how to call `CPUID` directly: +//! +//! ~~~ +//! using namespace asmjit; +//! +//! // Call cpuid, first two arguments are passed in Eax/Ecx. +//! X86CpuId out; +//! X86CpuUtil::callCpuId(0, 0, &out); +//! +//! // If Eax argument is 0, Ebx, Ecx and Edx registers are filled with a cpu vendor. +//! char cpuVendor[13]; +//! ::memcpy(cpuVendor, &out.ebx, 4); +//! ::memcpy(cpuVendor + 4, &out.edx, 4); +//! ::memcpy(cpuVendor + 8, &out.ecx, 4); +//! vendor[12] = '\0'; +//! +//! // Print a CPU vendor retrieved from CPUID. +//! ::printf("%s", cpuVendor); +//! ~~~ + +// ============================================================================ +// [asmjit_x86_compiler] +// ============================================================================ + +//! \defgroup asmjit_x86_compiler X86/X64 Code-Tree +//! \ingroup asmjit_x86 +//! +//! \brief X86/X64 code-tree and helpers. + +// ============================================================================ +// [asmjit_x86_inst] +// ============================================================================ + +//! \defgroup asmjit_x86_inst X86/X64 Instructions +//! \ingroup asmjit_x86 +//! +//! \brief X86/X64 low-level instruction definitions. + +// ============================================================================ +// [asmjit_x86_util] +// ============================================================================ + +//! \defgroup asmjit_x86_util X86/X64 Utilities +//! \ingroup asmjit_x86 +//! +//! \brief X86/X64 utility classes. + +// ============================================================================ +// [asmjit_contrib] +// ============================================================================ + +//! \defgroup asmjit_contrib Contributions +//! +//! \brief Contributions. + +// [Dependencies - Base] +#include "base.h" + +// [Dependencies - X86/X64] +#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) +#include "x86.h" +#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 + +// [Dependencies - Host] +#include "host.h" + +// [Guard] +#endif // _ASMJIT_ASMJIT_H diff --git a/libraries/asmjit/base.h b/libraries/asmjit/base.h new file mode 100644 index 000000000..47e1bfef3 --- /dev/null +++ b/libraries/asmjit/base.h @@ -0,0 +1,34 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_H +#define _ASMJIT_BASE_H + +// [Dependencies - AsmJit] +#include "build.h" + +#include "base/assembler.h" +#include "base/codegen.h" +#include "base/compiler.h" +#include "base/constpool.h" +#include "base/containers.h" +#include "base/cpuinfo.h" +#include "base/cputicks.h" +#include "base/error.h" +#include "base/globals.h" +#include "base/intutil.h" +#include "base/lock.h" +#include "base/logger.h" +#include "base/operand.h" +#include "base/runtime.h" +#include "base/string.h" +#include "base/vectypes.h" +#include "base/vmem.h" +#include "base/zone.h" + +// [Guard] +#endif // _ASMJIT_BASE_H diff --git a/libraries/asmjit/base/assembler.cpp b/libraries/asmjit/base/assembler.cpp new file mode 100644 index 000000000..3718bafee --- /dev/null +++ b/libraries/asmjit/base/assembler.cpp @@ -0,0 +1,387 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/intutil.h" +#include "../base/vmem.h" + +// [Dependenceis - C] +#include + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::Assembler - Construction / Destruction] +// ============================================================================ + +Assembler::Assembler(Runtime* runtime) : + CodeGen(runtime), + _buffer(NULL), + _end(NULL), + _cursor(NULL), + _trampolineSize(0), + _comment(NULL), + _unusedLinks(NULL) {} + +Assembler::~Assembler() { + reset(true); +} + +// ============================================================================ +// [asmjit::Assembler - Clear / Reset] +// ============================================================================ + +void Assembler::reset(bool releaseMemory) { + // CodeGen members. + _baseAddress = kNoBaseAddress; + _instOptions = 0; + _error = kErrorOk; + + _baseZone.reset(releaseMemory); + + // Assembler members. + if (releaseMemory && _buffer != NULL) { + ASMJIT_FREE(_buffer); + _buffer = NULL; + _end = NULL; + } + + _cursor = _buffer; + _trampolineSize = 0; + + _comment = NULL; + _unusedLinks = NULL; + + _labelList.reset(releaseMemory); + _relocList.reset(releaseMemory); +} + +// ============================================================================ +// [asmjit::Assembler - Buffer] +// ============================================================================ + +Error Assembler::_grow(size_t n) { + size_t capacity = getCapacity(); + size_t after = getOffset() + n; + + // Overflow. + if (n > IntUtil::maxUInt() - capacity) + return setError(kErrorNoHeapMemory); + + // Grow is called when allocation is needed, so it shouldn't happen, but on + // the other hand it is simple to catch and it's not an error. + if (after <= capacity) + return kErrorOk; + + if (capacity < kMemAllocOverhead) + capacity = kMemAllocOverhead; + else + capacity += kMemAllocOverhead; + + do { + size_t oldCapacity = capacity; + + if (capacity < kMemAllocGrowMax) + capacity *= 2; + else + capacity += kMemAllocGrowMax; + + // Overflow. + if (oldCapacity > capacity) + return setError(kErrorNoHeapMemory); + } while (capacity - kMemAllocOverhead < after); + + capacity -= kMemAllocOverhead; + return _reserve(capacity); +} + +Error Assembler::_reserve(size_t n) { + size_t capacity = getCapacity(); + if (n <= capacity) + return kErrorOk; + + uint8_t* newBuffer; + if (_buffer == NULL) + newBuffer = static_cast(ASMJIT_ALLOC(n)); + else + newBuffer = static_cast(ASMJIT_REALLOC(_buffer, n)); + + if (newBuffer == NULL) + return setError(kErrorNoHeapMemory); + + size_t offset = getOffset(); + + _buffer = newBuffer; + _end = _buffer + n; + _cursor = newBuffer + offset; + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::Assembler - Label] +// ============================================================================ + +Error Assembler::_registerIndexedLabels(size_t index) { + size_t i = _labelList.getLength(); + if (index < i) + return kErrorOk; + + if (_labelList._grow(index - i) != kErrorOk) + return setError(kErrorNoHeapMemory); + + LabelData data; + data.offset = -1; + data.links = NULL; + + do { + _labelList.append(data); + } while (++i < index); + + return kErrorOk; +} + +Error Assembler::_newLabel(Label* dst) { + dst->_label.op = kOperandTypeLabel; + dst->_label.size = 0; + dst->_label.id = OperandUtil::makeLabelId(static_cast(_labelList.getLength())); + + LabelData data; + data.offset = -1; + data.links = NULL; + + if (_labelList.append(data) != kErrorOk) + goto _NoMemory; + return kErrorOk; + +_NoMemory: + dst->_label.id = kInvalidValue; + return setError(kErrorNoHeapMemory); +} + +LabelLink* Assembler::_newLabelLink() { + LabelLink* link = _unusedLinks; + + if (link) { + _unusedLinks = link->prev; + } + else { + link = _baseZone.allocT(); + if (link == NULL) + return NULL; + } + + link->prev = NULL; + link->offset = 0; + link->displacement = 0; + link->relocId = -1; + + return link; +} + +Error Assembler::bind(const Label& label) { + // Get label data based on label id. + uint32_t index = label.getId(); + LabelData* data = getLabelData(index); + + // Label can be bound only once. + if (data->offset != -1) + return setError(kErrorLabelAlreadyBound); + +#if !defined(ASMJIT_DISABLE_LOGGER) + if (_logger) + _logger->logFormat(kLoggerStyleLabel, "L%u:\n", index); +#endif // !ASMJIT_DISABLE_LOGGER + + Error error = kErrorOk; + size_t pos = getOffset(); + + LabelLink* link = data->links; + LabelLink* prev = NULL; + + while (link) { + intptr_t offset = link->offset; + + if (link->relocId != -1) { + // Handle RelocData - We have to update RelocData information instead of + // patching the displacement in LabelData. + _relocList[link->relocId].data += static_cast(pos); + } + else { + // Not using relocId, this means that we are overwriting a real + // displacement in the binary stream. + int32_t patchedValue = static_cast( + static_cast(pos) - offset + link->displacement); + + // Size of the value we are going to patch. Only BYTE/DWORD is allowed. + uint32_t size = getByteAt(offset); + ASMJIT_ASSERT(size == 1 || size == 4); + + if (size == 4) { + setInt32At(offset, patchedValue); + } + else { + ASMJIT_ASSERT(size == 1); + if (IntUtil::isInt8(patchedValue)) + setByteAt(offset, static_cast(patchedValue & 0xFF)); + else + error = kErrorIllegalDisplacement; + } + } + + prev = link->prev; + link = prev; + } + + // Chain unused links. + link = data->links; + if (link) { + if (prev == NULL) + prev = link; + + prev->prev = _unusedLinks; + _unusedLinks = link; + } + + // Set as bound (offset is zero or greater and no links). + data->offset = pos; + data->links = NULL; + + if (error != kErrorOk) + return setError(error); + + return error; +} + +// ============================================================================ +// [asmjit::Assembler - Embed] +// ============================================================================ + +Error Assembler::embed(const void* data, uint32_t size) { + if (getRemainingSpace() < size) { + Error error = _grow(size); + if (error != kErrorOk) + return setError(error); + } + + uint8_t* cursor = getCursor(); + ::memcpy(cursor, data, size); + setCursor(cursor + size); + +#if !defined(ASMJIT_DISABLE_LOGGER) + if (_logger) + _logger->logBinary(kLoggerStyleData, data, size); +#endif // !ASMJIT_DISABLE_LOGGER + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::Assembler - Reloc] +// ============================================================================ + +size_t Assembler::relocCode(void* dst, Ptr baseAddress) const { + if (baseAddress == kNoBaseAddress) + baseAddress = hasBaseAddress() ? getBaseAddress() : static_cast((uintptr_t)dst); + else if (getBaseAddress() != baseAddress) + return 0; + + return _relocCode(dst, baseAddress); +} + +// ============================================================================ +// [asmjit::Assembler - Make] +// ============================================================================ + +void* Assembler::make() { + // Do nothing on error condition or if no instruction has been emitted. + if (_error != kErrorOk || getCodeSize() == 0) + return NULL; + + void* p; + Error error = _runtime->add(&p, this); + + if (error != kErrorOk) + setError(error); + + return p; +} + +// ============================================================================ +// [asmjit::Assembler - Emit (Helpers)] +// ============================================================================ + +#define NA noOperand + +Error Assembler::emit(uint32_t code) { + return _emit(code, NA, NA, NA, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0) { + return _emit(code, o0, NA, NA, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1) { + return _emit(code, o0, o1, NA, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { + return _emit(code, o0, o1, o2, NA); +} + +Error Assembler::emit(uint32_t code, int o0) { + Imm imm(o0); + return _emit(code, imm, NA, NA, NA); +} + +Error Assembler::emit(uint32_t code, uint64_t o0) { + Imm imm(o0); + return _emit(code, imm, NA, NA, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, int o1) { + Imm imm(o1); + return _emit(code, o0, imm, NA, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, uint64_t o1) { + Imm imm(o1); + return _emit(code, o0, imm, NA, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2) { + Imm imm(o2); + return _emit(code, o0, o1, imm, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2) { + Imm imm(o2); + return _emit(code, o0, o1, imm, NA); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3) { + Imm imm(o3); + return _emit(code, o0, o1, o2, imm); +} + +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3) { + Imm imm(o3); + return _emit(code, o0, o1, o2, imm); +} + +#undef NA + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/assembler.h b/libraries/asmjit/base/assembler.h new file mode 100644 index 000000000..42bd17abb --- /dev/null +++ b/libraries/asmjit/base/assembler.h @@ -0,0 +1,540 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_ASSEMBLER_H +#define _ASMJIT_BASE_ASSEMBLER_H + +// [Dependencies - AsmJit] +#include "../base/codegen.h" +#include "../base/containers.h" +#include "../base/error.h" +#include "../base/logger.h" +#include "../base/operand.h" +#include "../base/runtime.h" +#include "../base/zone.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_general +//! \{ + +// ============================================================================ +// [asmjit::kInstId] +// ============================================================================ + +//! Instruction codes (stub). +ASMJIT_ENUM(kInstId) { + //! No instruction. + kInstIdNone = 0 +}; + +// ============================================================================ +// [asmjit::kInstOptions] +// ============================================================================ + +//! Instruction options (stub). +ASMJIT_ENUM(kInstOptions) { + //! No instruction options. + kInstOptionNone = 0x00, + + //! Emit short form of the instruction. + //! + //! X86/X64: + //! + //! Short form is mostly related to jmp and jcc instructions, but can be used + //! by other instructions supporting 8-bit or 32-bit immediates. This option + //! can be dangerous if the short jmp/jcc is required, but not encodable due + //! to large displacement, in such case an error happens and the whole + //! assembler/compiler stream is unusable. + kInstOptionShortForm = 0x01, + //! Emit long form of the instruction. + //! + //! X86/X64: + //! + //! Long form is mosrlt related to jmp and jcc instructions, but like the + //! `kInstOptionShortForm` option it can be used by other instructions + //! supporting both 8-bit and 32-bit immediates. + kInstOptionLongForm = 0x02, + + //! Condition is likely to be taken. + kInstOptionTaken = 0x04, + //! Condition is unlikely to be taken. + kInstOptionNotTaken = 0x08 +}; + +// ============================================================================ +// [asmjit::LabelLink] +// ============================================================================ + +//! \internal +//! +//! Data structure used to link linked-labels. +struct LabelLink { + //! Previous link. + LabelLink* prev; + //! Offset. + intptr_t offset; + //! Inlined displacement. + intptr_t displacement; + //! RelocId if link must be absolute when relocated. + intptr_t relocId; +}; + +// ============================================================================ +// [asmjit::LabelData] +// ============================================================================ + +//! \internal +//! +//! Label data. +struct LabelData { + //! Label offset. + intptr_t offset; + //! Label links chain. + LabelLink* links; +}; + +// ============================================================================ +// [asmjit::RelocData] +// ============================================================================ + +//! \internal +//! +//! Code relocation data (relative vs absolute addresses). +//! +//! X86/X64: +//! +//! X86 architecture uses 32-bit absolute addressing model by memory operands, +//! but 64-bit mode uses relative addressing model (RIP + displacement). In +//! code we are always using relative addressing model for referencing labels +//! and embedded data. In 32-bit mode we must patch all references to absolute +//! address before we can call generated function. +struct RelocData { + //! Type of relocation. + uint32_t type; + //! Size of relocation (4 or 8 bytes). + uint32_t size; + + //! Offset from code begin address. + Ptr from; + + //! Relative displacement from code begin address (not to `offset`) or + //! absolute address. + Ptr data; +}; + +// ============================================================================ +// [asmjit::Assembler] +// ============================================================================ + +//! Base assembler. +//! +//! This class implements the base interface to an assembler. The architecture +//! specific API is implemented by backends. +//! +//! \sa Compiler. +struct ASMJIT_VCLASS Assembler : public CodeGen { + ASMJIT_NO_COPY(Assembler) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `Assembler` instance. + ASMJIT_API Assembler(Runtime* runtime); + //! Destroy the `Assembler` instance. + ASMJIT_API virtual ~Assembler(); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset the assembler. + //! + //! If `releaseMemory` is true all buffers will be released to the system. + ASMJIT_API void reset(bool releaseMemory = false); + + // -------------------------------------------------------------------------- + // [Buffer] + // -------------------------------------------------------------------------- + + //! Get capacity of the code buffer. + ASMJIT_INLINE size_t getCapacity() const { + return (size_t)(_end - _buffer); + } + + //! Get the number of remaining bytes (space between cursor and the end of + //! the buffer). + ASMJIT_INLINE size_t getRemainingSpace() const { + return (size_t)(_end - _cursor); + } + + //! Get buffer. + ASMJIT_INLINE uint8_t* getBuffer() const { + return _buffer; + } + + //! Get the end of the buffer (points to the first byte that is outside). + ASMJIT_INLINE uint8_t* getEnd() const { + return _end; + } + + //! Get the current position in the buffer. + ASMJIT_INLINE uint8_t* getCursor() const { + return _cursor; + } + + //! Set the current position in the buffer. + ASMJIT_INLINE void setCursor(uint8_t* cursor) { + ASMJIT_ASSERT(cursor >= _buffer && cursor <= _end); + _cursor = cursor; + } + + //! Get the current offset in the buffer. + ASMJIT_INLINE size_t getOffset() const { + return (size_t)(_cursor - _buffer); + } + + //! Set the current offset in the buffer to `offset` and get the previous + //! offset value. + ASMJIT_INLINE size_t setOffset(size_t offset) { + ASMJIT_ASSERT(offset < getCapacity()); + + size_t oldOffset = (size_t)(_cursor - _buffer); + _cursor = _buffer + offset; + return oldOffset; + } + + //! Grow the internal buffer. + //! + //! The internal buffer will grow at least by `n` bytes so `n` bytes can be + //! added to it. If `n` is zero or `getOffset() + n` is not greater than the + //! current capacity of the buffer this function does nothing. + ASMJIT_API Error _grow(size_t n); + + //! Reserve the internal buffer to at least `n` bytes. + ASMJIT_API Error _reserve(size_t n); + + //! Get BYTE at position `pos`. + ASMJIT_INLINE uint8_t getByteAt(size_t pos) const { + ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer)); + return *reinterpret_cast(_buffer + pos); + } + + //! Get WORD at position `pos`. + ASMJIT_INLINE uint16_t getWordAt(size_t pos) const { + ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer)); + return *reinterpret_cast(_buffer + pos); + } + + //! Get DWORD at position `pos`. + ASMJIT_INLINE uint32_t getDWordAt(size_t pos) const { + ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); + return *reinterpret_cast(_buffer + pos); + } + + //! Get QWORD at position `pos`. + ASMJIT_INLINE uint64_t getQWordAt(size_t pos) const { + ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer)); + return *reinterpret_cast(_buffer + pos); + } + + //! Get int32_t at position `pos`. + ASMJIT_INLINE int32_t getInt32At(size_t pos) const { + ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); + return *reinterpret_cast(_buffer + pos); + } + + //! Get uint32_t at position `pos`. + ASMJIT_INLINE uint32_t getUInt32At(size_t pos) const { + ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); + return *reinterpret_cast(_buffer + pos); + } + + //! Set BYTE at position `pos`. + ASMJIT_INLINE void setByteAt(size_t pos, uint8_t x) { + ASMJIT_ASSERT(pos + 1 <= (size_t)(_end - _buffer)); + *reinterpret_cast(_buffer + pos) = x; + } + + //! Set WORD at position `pos`. + ASMJIT_INLINE void setWordAt(size_t pos, uint16_t x) { + ASMJIT_ASSERT(pos + 2 <= (size_t)(_end - _buffer)); + *reinterpret_cast(_buffer + pos) = x; + } + + //! Set DWORD at position `pos`. + ASMJIT_INLINE void setDWordAt(size_t pos, uint32_t x) { + ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); + *reinterpret_cast(_buffer + pos) = x; + } + + //! Set QWORD at position `pos`. + ASMJIT_INLINE void setQWordAt(size_t pos, uint64_t x) { + ASMJIT_ASSERT(pos + 8 <= (size_t)(_end - _buffer)); + *reinterpret_cast(_buffer + pos) = x; + } + + //! Set int32_t at position `pos`. + ASMJIT_INLINE void setInt32At(size_t pos, int32_t x) { + ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); + *reinterpret_cast(_buffer + pos) = x; + } + + //! Set uint32_t at position `pos`. + ASMJIT_INLINE void setUInt32At(size_t pos, uint32_t x) { + ASMJIT_ASSERT(pos + 4 <= (size_t)(_end - _buffer)); + *reinterpret_cast(_buffer + pos) = x; + } + + // -------------------------------------------------------------------------- + // [GetCodeSize] + // -------------------------------------------------------------------------- + + //! Get current offset in buffer, same as `getOffset() + getTramplineSize()`. + ASMJIT_INLINE size_t getCodeSize() const { + return getOffset() + getTrampolineSize(); + } + + // -------------------------------------------------------------------------- + // [GetTrampolineSize] + // -------------------------------------------------------------------------- + + //! Get size of all possible trampolines. + //! + //! Trampolines are needed to successfuly generate relative jumps to absolute + //! addresses. This value is only non-zero if jmp of call instructions were + //! used with immediate operand (this means jumping or calling an absolute + //! address directly). + ASMJIT_INLINE size_t getTrampolineSize() const { + return _trampolineSize; + } + + // -------------------------------------------------------------------------- + // [Label] + // -------------------------------------------------------------------------- + + //! Get number of labels created. + ASMJIT_INLINE size_t getLabelsCount() const { + return _labelList.getLength(); + } + + //! Get whether the `label` is valid (created by the assembler). + ASMJIT_INLINE bool isLabelValid(const Label& label) const { + return isLabelValid(label.getId()); + } + + //! \overload + ASMJIT_INLINE bool isLabelValid(uint32_t id) const { + return static_cast(id) < _labelList.getLength(); + } + + //! Get whether the `label` is bound. + //! + //! \note It's an error to pass label that is not valid. Check the validity + //! of the label by using `isLabelValid()` method before the bound check if + //! you are not sure about its validity, otherwise you may hit an assertion + //! failure in debug mode, and undefined behavior in release mode. + ASMJIT_INLINE bool isLabelBound(const Label& label) const { + return isLabelBound(label.getId()); + } + + //! \overload + ASMJIT_INLINE bool isLabelBound(uint32_t id) const { + ASMJIT_ASSERT(isLabelValid(id)); + + return _labelList[id].offset != -1; + } + + //! Get `label` offset or -1 if the label is not yet bound. + ASMJIT_INLINE intptr_t getLabelOffset(const Label& label) const { + return getLabelOffset(label.getId()); + } + + //! \overload + ASMJIT_INLINE intptr_t getLabelOffset(uint32_t id) const { + ASMJIT_ASSERT(isLabelValid(id)); + return _labelList[id].offset; + } + + //! Get `LabelData` by `label`. + ASMJIT_INLINE LabelData* getLabelData(const Label& label) const { + return getLabelData(label.getId()); + } + + //! \overload + ASMJIT_INLINE LabelData* getLabelData(uint32_t id) const { + ASMJIT_ASSERT(isLabelValid(id)); + return const_cast(&_labelList[id]); + } + + //! \internal + //! + //! Register labels for other code generator, i.e. `Compiler`. + ASMJIT_API Error _registerIndexedLabels(size_t index); + + //! \internal + //! + //! Create and initialize a new `Label`. + ASMJIT_API Error _newLabel(Label* dst); + + //! \internal + //! + //! New LabelLink instance. + ASMJIT_API LabelLink* _newLabelLink(); + + //! Create and return a new `Label`. + ASMJIT_INLINE Label newLabel() { + Label result(NoInit); + _newLabel(&result); + return result; + } + + //! Bind label to the current offset. + //! + //! \note Label can be bound only once! + ASMJIT_API virtual Error bind(const Label& label); + + // -------------------------------------------------------------------------- + // [Embed] + // -------------------------------------------------------------------------- + + //! Embed data into the code buffer. + ASMJIT_API virtual Error embed(const void* data, uint32_t size); + + // -------------------------------------------------------------------------- + // [Align] + // -------------------------------------------------------------------------- + + //! Align target buffer to `m` bytes. + //! + //! Typical usage of this is to align labels at start of the inner loops. + //! + //! Inserts `nop()` instructions or CPU optimized NOPs. + virtual Error align(uint32_t mode, uint32_t offset) = 0; + + // -------------------------------------------------------------------------- + // [Reloc] + // -------------------------------------------------------------------------- + + //! Relocate the code to `baseAddress` and copy to `dst`. + //! + //! \param dst Contains the location where the relocated code should be + //! copied. The pointer can be address returned by virtual memory allocator + //! or any other address that has sufficient space. + //! + //! \param base Base address used for relocation. The `JitRuntime` always + //! sets the `base` address to be the same as `dst`, but other runtimes, for + //! example `StaticRuntime`, do not have to follow this rule. + //! + //! \retval The number bytes actually used. If the code generator reserved + //! space for possible trampolines, but didn't use it, the number of bytes + //! used can actually be less than the expected worst case. Virtual memory + //! allocator can shrink the memory allocated first time. + //! + //! A given buffer will be overwritten, to get the number of bytes required, + //! use `getCodeSize()`. + ASMJIT_API size_t relocCode(void* dst, Ptr baseAddress = kNoBaseAddress) const; + + //! \internal + //! + //! Reloc code. + virtual size_t _relocCode(void* dst, Ptr baseAddress) const = 0; + + // -------------------------------------------------------------------------- + // [Make] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual void* make(); + + // -------------------------------------------------------------------------- + // [Emit] + // -------------------------------------------------------------------------- + + //! Emit an instruction. + ASMJIT_API Error emit(uint32_t code); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2); + //! \overload + ASMJIT_INLINE Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { + return _emit(code, o0, o1, o2, o3); + } + + //! Emit an instruction with integer immediate operand. + ASMJIT_API Error emit(uint32_t code, int o0); + //! \overload + ASMJIT_API Error emit(uint32_t code, uint64_t o0); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, int o1); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, uint64_t o1); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int o2); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3); + + //! Emit an instruction (virtual). + virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) = 0; + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Buffer where the code is emitted (either live or temporary). + //! + //! This is actually the base pointer of the buffer, to get the current + //! position (cursor) look at the `_cursor` member. + uint8_t* _buffer; + //! The end of the buffer (points to the first invalid byte). + //! + //! The end of the buffer is calculated as _buffer + size. + uint8_t* _end; + //! The current position in code `_buffer`. + uint8_t* _cursor; + + //! Size of possible trampolines. + uint32_t _trampolineSize; + + //! Inline comment that will be logged by the next instruction and set to NULL. + const char* _comment; + //! Unused `LabelLink` structures pool. + LabelLink* _unusedLinks; + + //! LabelData list. + PodVector _labelList; + //! RelocData list. + PodVector _relocList; +}; + +//! \} + +// ============================================================================ +// [Defined-Later] +// ============================================================================ + +ASMJIT_INLINE Label::Label(Assembler& a) : Operand(NoInit) { + a._newLabel(this); +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_ASSEMBLER_H diff --git a/libraries/asmjit/base/codegen.cpp b/libraries/asmjit/base/codegen.cpp new file mode 100644 index 000000000..55192ed0e --- /dev/null +++ b/libraries/asmjit/base/codegen.cpp @@ -0,0 +1,111 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/codegen.h" +#include "../base/intutil.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::CodeGen - Construction / Destruction] +// ============================================================================ + +CodeGen::CodeGen(Runtime* runtime) : + _runtime(runtime), + _logger(NULL), + _errorHandler(NULL), + _baseAddress(runtime->getBaseAddress()), + _arch(kArchNone), + _regSize(0), + _reserved(0), + _features(IntUtil::mask(kCodeGenOptimizedAlign)), + _instOptions(0), + _error(kErrorOk), + _baseZone(16384 - kZoneOverhead) {} + +CodeGen::~CodeGen() { + if (_errorHandler != NULL) + _errorHandler->release(); +} + +// ============================================================================ +// [asmjit::CodeGen - Logging] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_LOGGER) +Error CodeGen::setLogger(Logger* logger) { + _logger = logger; + return kErrorOk; +} +#endif // !ASMJIT_DISABLE_LOGGER + +// ============================================================================ +// [asmjit::CodeGen - Error] +// ============================================================================ + +Error CodeGen::setError(Error error, const char* message) { + if (error == kErrorOk) { + _error = kErrorOk; + return kErrorOk; + } + + if (message == NULL) { +#if !defined(ASMJIT_DISABLE_NAMES) + message = ErrorUtil::asString(error); +#else + static const char noMessage[] = ""; + message = noMessage; +#endif // ASMJIT_DISABLE_NAMES + } + + // Error handler is called before logger so logging can be skipped if error + // has been handled. + ErrorHandler* handler = _errorHandler; + ASMJIT_TLOG("[ERROR] %s %s\n", message, !handler ? "(Possibly unhandled?)" : ""); + + if (handler != NULL && handler->handleError(error, message)) + return error; + +#if !defined(ASMJIT_DISABLE_LOGGER) + Logger* logger = _logger; + if (logger != NULL) { + logger->logFormat(kLoggerStyleComment, + "*** ERROR: %s (%u).\n", message, static_cast(error)); + } +#endif // !ASMJIT_DISABLE_LOGGER + + // The handler->handleError() function may throw an exception or longjmp() + // to terminate the execution of setError(). This is the reason why we have + // delayed changing the _error member until now. + _error = error; + + return error; +} + +Error CodeGen::setErrorHandler(ErrorHandler* handler) { + ErrorHandler* oldHandler = _errorHandler; + + if (oldHandler != NULL) + oldHandler->release(); + + if (handler != NULL) + handler = handler->addRef(); + + _errorHandler = handler; + return kErrorOk; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/codegen.h b/libraries/asmjit/base/codegen.h new file mode 100644 index 000000000..551b84bb1 --- /dev/null +++ b/libraries/asmjit/base/codegen.h @@ -0,0 +1,337 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_CODEGEN_H +#define _ASMJIT_BASE_CODEGEN_H + +// [Dependencies - AsmJit] +#include "../base/error.h" +#include "../base/logger.h" +#include "../base/runtime.h" +#include "../base/zone.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_general +//! \{ + +// ============================================================================ +// [asmjit::kCodeGen] +// ============================================================================ + +//! Features of \ref CodeGen. +ASMJIT_ENUM(kCodeGen) { + //! Emit optimized code-alignment sequences (`Assembler` and `Compiler`). + //! + //! Default `true`. + //! + //! X86/X64 + //! ------- + //! + //! Default align sequence used by X86/X64 architecture is one-byte 0x90 + //! opcode that is mostly shown by disassemblers as nop. However there are + //! more optimized align sequences for 2-11 bytes that may execute faster. + //! If this feature is enabled asmjit will generate specialized sequences + //! for alignment between 1 to 11 bytes. Also when `X86Compiler` is used, + //! it can add REX prefixes into the code to make some instructions greater + //! so no alignment sequence is needed. + kCodeGenOptimizedAlign = 0, + + //! Emit jump-prediction hints (`Assembler` and `Compiler`). + //! + //! Default `false`. + //! + //! X86/X64 + //! ------- + //! + //! Jump prediction is usually based on the direction of the jump. If the + //! jump is backward it is usually predicted as taken; and if the jump is + //! forward it is usually predicted as not-taken. The reason is that loops + //! generally use backward jumps and conditions usually use forward jumps. + //! However this behavior can be overridden by using instruction prefixes. + //! If this option is enabled these hints will be emitted. + //! + //! This feature is disabled by default, because the only processor that + //! used to take into consideration prediction hints was P4. Newer processors + //! implement heuristics for branch prediction that ignores any static hints. + kCodeGenPredictedJumps = 1, + + //! Schedule instructions so they can be executed faster (`Compiler` only). + //! + //! Default `false` - has to be explicitly enabled as the scheduler needs + //! some time to run. + //! + //! X86/X64 + //! ------- + //! + //! If scheduling is enabled AsmJit will try to reorder instructions to + //! minimize dependency chain. Scheduler always runs after the registers are + //! allocated so it doesn't change count of register allocs/spills. + //! + //! This feature is highly experimental and untested. + kCodeGenEnableScheduler = 2 +}; + +// ============================================================================ +// [asmjit::kAlignMode] +// ============================================================================ + +//! Code aligning mode. +ASMJIT_ENUM(kAlignMode) { + //! Align by emitting a sequence that can be executed (code). + kAlignCode = 0, + //! Align by emitting sequence that shouldn't be executed (data). + kAlignData = 1 +}; + +// ============================================================================ +// [asmjit::kRelocMode] +// ============================================================================ + +//! Relocation mode. +ASMJIT_ENUM(kRelocMode) { + //! Relocate an absolute address to an absolute address. + kRelocAbsToAbs = 0, + //! Relocate a relative address to an absolute address. + kRelocRelToAbs = 1, + //! Relocate an absolute address to a relative address. + kRelocAbsToRel = 2, + //! Relocate an absolute address to a relative address or use trampoline. + kRelocTrampoline = 3 +}; + +// ============================================================================ +// [asmjit::CodeGen] +// ============================================================================ + +//! Abstract class defining basics of \ref Assembler and \ref Compiler. +struct ASMJIT_VCLASS CodeGen { + ASMJIT_NO_COPY(CodeGen) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `CodeGen` instance. + ASMJIT_API CodeGen(Runtime* runtime); + //! Destroy the `CodeGen` instance. + ASMJIT_API virtual ~CodeGen(); + + // -------------------------------------------------------------------------- + // [Runtime] + // -------------------------------------------------------------------------- + + //! Get runtime. + ASMJIT_INLINE Runtime* getRuntime() const { + return _runtime; + } + + // -------------------------------------------------------------------------- + // [Logger] + // -------------------------------------------------------------------------- + +#if !defined(ASMJIT_DISABLE_LOGGER) + //! Get whether the code generator has a logger. + ASMJIT_INLINE bool hasLogger() const { + return _logger != NULL; + } + + //! Get logger. + ASMJIT_INLINE Logger* getLogger() const { + return _logger; + } + + //! Set logger to `logger`. + ASMJIT_API Error setLogger(Logger* logger); +#endif // !ASMJIT_DISABLE_LOGGER + + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + //! Get target architecture. + ASMJIT_INLINE uint32_t getArch() const { + return _arch; + } + + //! Get default register size (4 or 8 bytes). + ASMJIT_INLINE uint32_t getRegSize() const { + return _regSize; + } + + // -------------------------------------------------------------------------- + // [BaseAddress] + // -------------------------------------------------------------------------- + + //! Get whether the code-generator has a base address. + //! + //! \sa \ref getBaseAddress() + ASMJIT_INLINE bool hasBaseAddress() const { + return _baseAddress != kNoBaseAddress; + } + + //! Get the base address. + ASMJIT_INLINE Ptr getBaseAddress() const { + return _baseAddress; + } + + //! Set the base address to `baseAddress`. + ASMJIT_INLINE void setBaseAddress(Ptr baseAddress) { + _baseAddress = baseAddress; + } + + //! Reset the base address. + ASMJIT_INLINE void resetBaseAddress() { + setBaseAddress(kNoBaseAddress); + } + + // -------------------------------------------------------------------------- + // [LastError / ErrorHandler] + // -------------------------------------------------------------------------- + + //! Get last error code. + ASMJIT_INLINE Error getError() const { + return _error; + } + + //! Set last error code and propagate it through the error handler. + ASMJIT_API Error setError(Error error, const char* message = NULL); + + //! Clear the last error code. + ASMJIT_INLINE void resetError() { + _error = kErrorOk; + } + + //! Get error handler. + ASMJIT_INLINE ErrorHandler* getErrorHandler() const { + return _errorHandler; + } + + //! Set error handler. + ASMJIT_API Error setErrorHandler(ErrorHandler* handler); + + //! Clear error handler. + ASMJIT_INLINE Error resetErrorHandler() { + return setErrorHandler(NULL); + } + + // -------------------------------------------------------------------------- + // [Code-Generation Features] + // -------------------------------------------------------------------------- + + //! Get code-generator `feature`. + ASMJIT_INLINE bool hasFeature(uint32_t feature) const { + ASMJIT_ASSERT(feature < 32); + + return (_features & (1 << feature)) != 0; + } + + //! Set code-generator `feature` to `value`. + ASMJIT_INLINE void setFeature(uint32_t feature, bool value) { + ASMJIT_ASSERT(feature < 32); + + feature = static_cast(value) << feature; + _features = (_features & ~feature) | feature; + } + + //! Get code-generator features. + ASMJIT_INLINE uint32_t getFeatures() const { + return _features; + } + + //! Set code-generator features. + ASMJIT_INLINE void setFeatures(uint32_t features) { + _features = features; + } + + // -------------------------------------------------------------------------- + // [Instruction Options] + // -------------------------------------------------------------------------- + + //! Get options of the next instruction. + ASMJIT_INLINE uint32_t getInstOptions() const { + return _instOptions; + } + + //! Get options of the next instruction and reset them. + ASMJIT_INLINE uint32_t getInstOptionsAndReset() { + uint32_t instOptions = _instOptions; + _instOptions = 0; + return instOptions; + }; + + //! Set options of the next instruction. + ASMJIT_INLINE void setInstOptions(uint32_t instOptions) { + _instOptions = instOptions; + } + + // -------------------------------------------------------------------------- + // [Make] + // -------------------------------------------------------------------------- + + //! Make is a convenience method to make and relocate the current code and + //! add it to the associated `Runtime`. + //! + //! What is needed is only to cast the returned pointer to your function type + //! and then use it. If there was an error during `make()` `NULL` is returned + //! and the last error code can be obtained by calling `getError()`. + virtual void* make() = 0; + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Target runtime. + Runtime* _runtime; + +#if !defined(ASMJIT_DISABLE_LOGGER) + //! Logger. + Logger* _logger; +#else + //! \internal + //! + //! Makes libraries built with or without logging support binary compatible. + void* _logger; +#endif // ASMJIT_DISABLE_LOGGER + + //! Error handler, called by \ref setError(). + ErrorHandler* _errorHandler; + + //! Base address (-1 if unknown/not used). + Ptr _baseAddress; + + //! Target architecture ID. + uint8_t _arch; + //! Target architecture GP register size in bytes (4 or 8). + uint8_t _regSize; + //! \internal + uint16_t _reserved; + + //! Code-Generation features, used by \ref hasFeature() and \ref setFeature(). + uint32_t _features; + //! Options affecting the next instruction. + uint32_t _instOptions; + + //! Last error code. + uint32_t _error; + + //! Base zone. + Zone _baseZone; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_CODEGEN_H diff --git a/libraries/asmjit/base/compiler.cpp b/libraries/asmjit/base/compiler.cpp new file mode 100644 index 000000000..9828a2899 --- /dev/null +++ b/libraries/asmjit/base/compiler.cpp @@ -0,0 +1,621 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/compiler.h" +#include "../base/context_p.h" +#include "../base/cpuinfo.h" +#include "../base/intutil.h" +#include "../base/logger.h" + +// [Dependencies - C] +#include + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Constants] +// ============================================================================ + +static const char noName[1] = { '\0' }; +enum { kBaseCompilerDefaultLookAhead = 64 }; + +// ============================================================================ +// [asmjit::Compiler - Construction / Destruction] +// ============================================================================ + +Compiler::Compiler(Runtime* runtime) : + CodeGen(runtime), + _nodeFlowId(0), + _nodeFlags(0), + _maxLookAhead(kBaseCompilerDefaultLookAhead), + _targetVarMapping(NULL), + _assembler(NULL), + _firstNode(NULL), + _lastNode(NULL), + _cursor(NULL), + _func(NULL), + _varZone(4096 - kZoneOverhead), + _stringZone(4096 - kZoneOverhead), + _localConstZone(4096 - kZoneOverhead), + _localConstPool(&_localConstZone), + _globalConstPool(&_baseZone) {} + +Compiler::~Compiler() { + reset(true); + + if (_assembler != NULL) + delete _assembler; +} + +// ============================================================================ +// [asmjit::Compiler - Clear / Reset] +// ============================================================================ + +void Compiler::reset(bool releaseMemory) { + // CodeGen members. + _baseAddress = kNoBaseAddress; + _instOptions = 0; + _error = kErrorOk; + + _baseZone.reset(releaseMemory); + + // Compiler members. + _nodeFlowId = 0; + _nodeFlags = 0; + + if (_assembler != NULL) + _assembler->reset(releaseMemory); + + _firstNode = NULL; + _lastNode = NULL; + + _cursor = NULL; + _func = NULL; + + _localConstPool.reset(); + _globalConstPool.reset(); + + _localConstPoolLabel.reset(); + _globalConstPoolLabel.reset(); + + _varZone.reset(releaseMemory); + _stringZone.reset(releaseMemory); + _localConstZone.reset(releaseMemory); + + _targetList.reset(releaseMemory); + _varList.reset(releaseMemory); +} + +// ============================================================================ +// [asmjit::Compiler - Node Management] +// ============================================================================ + +Node* Compiler::setCursor(Node* node) { + Node* old = _cursor; + _cursor = node; + return old; +} + +Node* Compiler::addNode(Node* node) { + ASMJIT_ASSERT(node != NULL); + ASMJIT_ASSERT(node->_prev == NULL); + ASMJIT_ASSERT(node->_next == NULL); + + if (_cursor == NULL) { + if (_firstNode == NULL) { + _firstNode = node; + _lastNode = node; + } + else { + node->_next = _firstNode; + _firstNode->_prev = node; + _firstNode = node; + } + } + else { + Node* prev = _cursor; + Node* next = _cursor->_next; + + node->_prev = prev; + node->_next = next; + + prev->_next = node; + if (next) + next->_prev = node; + else + _lastNode = node; + } + + _cursor = node; + return node; +} + +Node* Compiler::addNodeBefore(Node* node, Node* ref) { + ASMJIT_ASSERT(node != NULL); + ASMJIT_ASSERT(node->_prev == NULL); + ASMJIT_ASSERT(node->_next == NULL); + ASMJIT_ASSERT(ref != NULL); + + Node* prev = ref->_prev; + Node* next = ref; + + node->_prev = prev; + node->_next = next; + + next->_prev = node; + if (prev) + prev->_next = node; + else + _firstNode = node; + + return node; +} + +Node* Compiler::addNodeAfter(Node* node, Node* ref) { + ASMJIT_ASSERT(node != NULL); + ASMJIT_ASSERT(node->_prev == NULL); + ASMJIT_ASSERT(node->_next == NULL); + ASMJIT_ASSERT(ref != NULL); + + Node* prev = ref; + Node* next = ref->_next; + + node->_prev = prev; + node->_next = next; + + prev->_next = node; + if (next) + next->_prev = node; + else + _lastNode = node; + + return node; +} + +static ASMJIT_INLINE void BaseCompiler_nodeRemoved(Compiler* self, Node* node_) { + if (node_->isJmpOrJcc()) { + JumpNode* node = static_cast(node_); + TargetNode* target = node->getTarget(); + + // Disconnect. + JumpNode** pPrev = &target->_from; + for (;;) { + ASMJIT_ASSERT(*pPrev != NULL); + JumpNode* current = *pPrev; + + if (current == NULL) + break; + + if (current == node) { + *pPrev = node->_jumpNext; + break; + } + + pPrev = ¤t->_jumpNext; + } + + target->subNumRefs(); + } +} + +Node* Compiler::removeNode(Node* node) { + Node* prev = node->_prev; + Node* next = node->_next; + + if (_firstNode == node) + _firstNode = next; + else + prev->_next = next; + + if (_lastNode == node) + _lastNode = prev; + else + next->_prev = prev; + + node->_prev = NULL; + node->_next = NULL; + + if (_cursor == node) + _cursor = prev; + BaseCompiler_nodeRemoved(this, node); + + return node; +} + +void Compiler::removeNodes(Node* first, Node* last) { + if (first == last) { + removeNode(first); + return; + } + + Node* prev = first->_prev; + Node* next = last->_next; + + if (_firstNode == first) + _firstNode = next; + else + prev->_next = next; + + if (_lastNode == last) + _lastNode = prev; + else + next->_prev = prev; + + Node* node = first; + for (;;) { + Node* next = node->getNext(); + ASMJIT_ASSERT(next != NULL); + + node->_prev = NULL; + node->_next = NULL; + + if (_cursor == node) + _cursor = prev; + BaseCompiler_nodeRemoved(this, node); + + if (node == last) + break; + node = next; + } +} + +// ============================================================================ +// [asmjit::Compiler - Align] +// ============================================================================ + +AlignNode* Compiler::newAlign(uint32_t mode, uint32_t offset) { + AlignNode* node = newNode(mode, offset); + if (node == NULL) + goto _NoMemory; + return node; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +AlignNode* Compiler::addAlign(uint32_t mode, uint32_t offset) { + AlignNode* node = newAlign(mode, offset); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +// ============================================================================ +// [asmjit::Compiler - Target] +// ============================================================================ + +TargetNode* Compiler::newTarget() { + TargetNode* node = newNode( + OperandUtil::makeLabelId(static_cast(_targetList.getLength()))); + + if (node == NULL || _targetList.append(node) != kErrorOk) + goto _NoMemory; + return node; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +TargetNode* Compiler::addTarget() { + TargetNode* node = newTarget(); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +// ============================================================================ +// [asmjit::Compiler - Label] +// ============================================================================ + +Error Compiler::_newLabel(Label* dst) { + dst->_init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, kInvalidValue); + dst->_init_packed_d2_d3(0, 0); + + TargetNode* node = newTarget(); + if (node == NULL) + goto _NoMemory; + + dst->_label.id = node->getLabelId(); + return kErrorOk; + +_NoMemory: + return setError(kErrorNoHeapMemory); +} + +Error Compiler::bind(const Label& label) { + uint32_t index = label.getId(); + ASMJIT_ASSERT(index < _targetList.getLength()); + + addNode(_targetList[index]); + return kErrorOk; +} + +// ============================================================================ +// [asmjit::Compiler - Embed] +// ============================================================================ + +EmbedNode* Compiler::newEmbed(const void* data, uint32_t size) { + EmbedNode* node; + + if (size > EmbedNode::kInlineBufferSize) { + void* clonedData = _stringZone.alloc(size); + if (clonedData == NULL) + goto _NoMemory; + + if (data != NULL) + ::memcpy(clonedData, data, size); + data = clonedData; + } + + node = newNode(const_cast(data), size); + if (node == NULL) + goto _NoMemory; + return node; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +EmbedNode* Compiler::addEmbed(const void* data, uint32_t size) { + EmbedNode* node = newEmbed(data, size); + if (node == NULL) + return node; + return static_cast(addNode(node)); +} + +// ============================================================================ +// [asmjit::Compiler - Comment] +// ============================================================================ + +CommentNode* Compiler::newComment(const char* str) { + CommentNode* node; + + if (str != NULL && str[0]) { + str = _stringZone.sdup(str); + if (str == NULL) + goto _NoMemory; + } + + node = newNode(str); + if (node == NULL) + goto _NoMemory; + return node; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +CommentNode* Compiler::addComment(const char* str) { + CommentNode* node = newComment(str); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +CommentNode* Compiler::comment(const char* fmt, ...) { + char buf[256]; + char* p = buf; + + if (fmt) { + *p++ = ';'; + *p++ = ' '; + + va_list ap; + va_start(ap, fmt); + p += vsnprintf(p, 254, fmt, ap); + va_end(ap); + } + + p[0] = '\n'; + p[1] = '\0'; + + return addComment(fmt); +} + +// ============================================================================ +// [asmjit::Compiler - Hint] +// ============================================================================ + +HintNode* Compiler::newHint(Var& var, uint32_t hint, uint32_t value) { + if (var.getId() == kInvalidValue) + return NULL; + VarData* vd = getVd(var); + + HintNode* node = newNode(vd, hint, value); + if (node == NULL) + goto _NoMemory; + return node; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +HintNode* Compiler::addHint(Var& var, uint32_t hint, uint32_t value) { + if (var.getId() == kInvalidValue) + return NULL; + + HintNode* node = newHint(var, hint, value); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +// ============================================================================ +// [asmjit::Compiler - Vars] +// ============================================================================ + +VarData* Compiler::_newVd(uint32_t type, uint32_t size, uint32_t c, const char* name) { + VarData* vd = reinterpret_cast(_varZone.alloc(sizeof(VarData))); + if (vd == NULL) + goto _NoMemory; + + vd->_name = noName; + vd->_id = OperandUtil::makeVarId(static_cast(_varList.getLength())); + vd->_contextId = kInvalidValue; + + if (name != NULL && name[0] != '\0') { + vd->_name = _stringZone.sdup(name); + } + + vd->_type = static_cast(type); + vd->_class = static_cast(c); + vd->_flags = 0; + vd->_priority = 10; + + vd->_state = kVarStateUnused; + vd->_regIndex = kInvalidReg; + vd->_isStack = false; + vd->_isMemArg = false; + vd->_isCalculated = false; + vd->_saveOnUnuse = false; + vd->_modified = false; + vd->_reserved0 = 0; + vd->_alignment = static_cast(IntUtil::iMin(size, 64)); + + vd->_size = size; + vd->_homeMask = 0; + + vd->_memOffset = 0; + vd->_memCell = NULL; + + vd->rReadCount = 0; + vd->rWriteCount = 0; + vd->mReadCount = 0; + vd->mWriteCount = 0; + + vd->_va = NULL; + + if (_varList.append(vd) != kErrorOk) + goto _NoMemory; + return vd; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +void Compiler::alloc(Var& var) { + addHint(var, kVarHintAlloc, kInvalidValue); +} + +void Compiler::alloc(Var& var, uint32_t regIndex) { + addHint(var, kVarHintAlloc, regIndex); +} + +void Compiler::alloc(Var& var, const Reg& reg) { + addHint(var, kVarHintAlloc, reg.getRegIndex()); +} + +void Compiler::save(Var& var) { + addHint(var, kVarHintSave, kInvalidValue); +} + +void Compiler::spill(Var& var) { + addHint(var, kVarHintSpill, kInvalidValue); +} + +void Compiler::unuse(Var& var) { + addHint(var, kVarHintUnuse, kInvalidValue); +} + +uint32_t Compiler::getPriority(Var& var) const { + if (var.getId() == kInvalidValue) + return kInvalidValue; + + VarData* vd = getVdById(var.getId()); + return vd->getPriority(); +} + +void Compiler::setPriority(Var& var, uint32_t priority) { + if (var.getId() == kInvalidValue) + return; + + if (priority > 255) + priority = 255; + + VarData* vd = getVdById(var.getId()); + vd->_priority = static_cast(priority); +} + +bool Compiler::getSaveOnUnuse(Var& var) const { + if (var.getId() == kInvalidValue) + return false; + + VarData* vd = getVdById(var.getId()); + return static_cast(vd->_saveOnUnuse); +} + +void Compiler::setSaveOnUnuse(Var& var, bool value) { + if (var.getId() == kInvalidValue) + return; + + VarData* vd = getVdById(var.getId()); + vd->_saveOnUnuse = value; +} + +void Compiler::rename(Var& var, const char* name) { + if (var.getId() == kInvalidValue) + return; + + VarData* vd = getVdById(var.getId()); + vd->_name = noName; + + if (name != NULL && name[0] != '\0') { + vd->_name = _stringZone.sdup(name); + } +} + +// ============================================================================ +// [asmjit::Compiler - Assembler] +// ============================================================================ + +Assembler* Compiler::getAssembler() { + Assembler* a = _assembler; + + if (a != NULL) { + a->reset(false); + } + else { + a = _newAssembler(); + _assembler = a; + } + +#if !defined(ASMJIT_DISABLE_LOGGER) + Logger* logger = _logger; + if (logger != NULL) + a->setLogger(logger); +#endif // !ASMJIT_DISABLE_LOGGER + + a->setBaseAddress(_baseAddress); + a->setFeatures(_features); + + return a; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER diff --git a/libraries/asmjit/base/compiler.h b/libraries/asmjit/base/compiler.h new file mode 100644 index 000000000..01b8aade6 --- /dev/null +++ b/libraries/asmjit/base/compiler.h @@ -0,0 +1,3104 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_COMPILER_H +#define _ASMJIT_BASE_COMPILER_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/codegen.h" +#include "../base/constpool.h" +#include "../base/containers.h" +#include "../base/error.h" +#include "../base/intutil.h" +#include "../base/operand.h" +#include "../base/zone.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct Compiler; + +struct VarAttr; +struct VarData; +struct VarMap; +struct VarState; + +struct Node; +struct EndNode; +struct InstNode; +struct JumpNode; + +// ============================================================================ +// [asmjit::kConstScope] +// ============================================================================ + +//! \addtogroup asmjit_base_compiler +//! \{ + +//! Scope of the constant. +ASMJIT_ENUM(kConstScope) { + //! Local constant, always embedded right after the current function. + kConstScopeLocal = 0, + //! Global constant, embedded at the end of the currently compiled code. + kConstScopeGlobal = 1 +}; + +// ============================================================================ +// [asmjit::kVarType] +// ============================================================================ + +ASMJIT_ENUM(kVarType) { + //! Variable is 8-bit signed integer. + kVarTypeInt8 = 0, + //! Variable is 8-bit unsigned integer. + kVarTypeUInt8 = 1, + //! Variable is 16-bit signed integer. + kVarTypeInt16 = 2, + //! Variable is 16-bit unsigned integer. + kVarTypeUInt16 = 3, + //! Variable is 32-bit signed integer. + kVarTypeInt32 = 4, + //! Variable is 32-bit unsigned integer. + kVarTypeUInt32 = 5, + //! Variable is 64-bit signed integer. + kVarTypeInt64 = 6, + //! Variable is 64-bit unsigned integer. + kVarTypeUInt64 = 7, + + //! Variable is target `intptr_t`, not compatible with host `intptr_t`. + kVarTypeIntPtr = 8, + //! Variable is target `uintptr_t`, not compatible with host `uintptr_t`. + kVarTypeUIntPtr = 9, + + //! Variable is 32-bit floating point (single precision). + kVarTypeFp32 = 10, + //! Variable is 64-bit floating point (double precision). + kVarTypeFp64 = 11, + + //! \internal + _kVarTypeIntStart = kVarTypeInt8, + //! \internal + _kVarTypeIntEnd = kVarTypeUIntPtr, + + //! \internal + _kVarTypeFpStart = kVarTypeFp32, + //! \internal + _kVarTypeFpEnd = kVarTypeFp64 +}; + +// ============================================================================ +// [asmjit::kVarFlags] +// ============================================================================ + +//! \internal +//! +//! X86/X64 variable flags. +ASMJIT_ENUM(kVarFlags) { + //! Variable contains single-precision floating-point(s). + kVarFlagSp = 0x10, + //! Variable contains double-precision floating-point(s). + kVarFlagDp = 0x20, + //! Variable is packed, i.e. packed floats, doubles, ... + kVarFlagPacked = 0x40 +}; + +// ============================================================================ +// [asmjit::kVarAttrFlags] +// ============================================================================ + +//! Variable attribute flags. +ASMJIT_ENUM(kVarAttrFlags) { + //! Variable is accessed through register on input. + kVarAttrInReg = 0x00000001, + //! Variable is accessed through register on output. + kVarAttrOutReg = 0x00000002, + //! Variable is accessed through register on input & output. + kVarAttrInOutReg = 0x00000003, + + //! Variable is accessed through memory on input. + kVarAttrInMem = 0x00000004, + //! Variable is accessed through memory on output. + kVarAttrOutMem = 0x00000008, + //! Variable is accessed through memory on input & output. + kVarAttrInOutMem = 0x0000000C, + + //! Register allocator can decide if input will be in register or memory. + kVarAttrInDecide = 0x00000010, + //! Register allocator can decide if output will be in register or memory. + kVarAttrOutDecide = 0x00000020, + //! Register allocator can decide if in/out will be in register or memory. + kVarAttrInOutDecide = 0x00000030, + + //! Variable is converted to other type/class on the input. + kVarAttrInConv = 0x00000040, + //! Variable is converted from other type/class on the output. + kVarAttrOutConv = 0x00000080, + //! Combination of `kVarAttrInConv` and `kVarAttrOutConv`. + kVarAttrInOutConv = 0x000000C0, + + //! Variable is a function call operand. + kVarAttrInCall = 0x00000100, + //! Variable is a function argument passed in register. + kVarAttrInArg = 0x00000200, + + //! Variable is a function return value passed in register. + kVarAttrOutRet = 0x00000400, + //! Variable should be spilled. + kVarAttrSpill = 0x00000800, + //! Variable should be unused at the end of the instruction/node. + kVarAttrUnuse = 0x00001000, + + //! \internal + //! + //! All in-flags. + kVarAttrInAll = + kVarAttrInReg | + kVarAttrInMem | + kVarAttrInDecide | + kVarAttrInCall | + kVarAttrInArg, + + //! \internal + //! + //! All out-flags. + kVarAttrOutAll = + kVarAttrOutReg | + kVarAttrOutMem | + kVarAttrOutDecide | + kVarAttrOutRet, + + //! Variable is already allocated on the input. + kVarAttrAllocInDone = 0x00400000, + //! Variable is already allocated on the output. + kVarAttrAllocOutDone = 0x00800000 +}; + +// ============================================================================ +// [asmjit::kVarHint] +// ============================================================================ + +//! Variable hint (used by `Compiler)`. +//! +//! \sa Compiler. +ASMJIT_ENUM(kVarHint) { + //! Alloc variable. + kVarHintAlloc = 0, + //! Spill variable. + kVarHintSpill = 1, + //! Save variable if modified. + kVarHintSave = 2, + //! Save variable if modified and mark it as unused. + kVarHintSaveAndUnuse = 3, + //! Mark variable as unused. + kVarHintUnuse = 4 +}; + +// ============================================================================ +// [asmjit::kVarState] +// ============================================================================ + +//! State of variable. +//! +//! \note State of variable is used only during make process and it's not +//! visible to the developer. +ASMJIT_ENUM(kVarState) { + //! Variable is currently not used. + kVarStateUnused = 0, + + //! Variable is in register. + //! + //! Variable is currently allocated in register. + kVarStateReg = 1, + + //! Variable is in memory location or spilled. + //! + //! Variable was spilled from register to memory or variable is used for + //! memory only storage. + kVarStateMem = 2 +}; + +// ============================================================================ +// [asmjit::kFuncConv] +// ============================================================================ + +//! Function calling convention. +//! +//! For a platform specific calling conventions, see: +//! - `kX86FuncConv` - X86/X64 calling conventions. +ASMJIT_ENUM(kFuncConv) { + //! Calling convention is invalid (can't be used). + kFuncConvNone = 0, + +#if defined(ASMJIT_DOCGEN) + //! Default calling convention for current platform / operating system. + kFuncConvHost = DependsOnHost, + + //! Default C calling convention based on current compiler's settings. + kFuncConvHostCDecl = DependsOnHost, + + //! Compatibility for `__stdcall` calling convention. + //! + //! \note This enumeration is always set to a value which is compatible with + //! current compilers __stdcall calling convention. In 64-bit mode the value + //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`. + kFuncConvHostStdCall = DependsOnHost, + + //! Compatibility for `__fastcall` calling convention. + //! + //! \note This enumeration is always set to a value which is compatible with + //! current compilers `__fastcall` calling convention. In 64-bit mode the value + //! is compatible with `kX86FuncConvW64` or `kX86FuncConvU64`. + kFuncConvHostFastCall = DependsOnHost +#endif // ASMJIT_DOCGEN +}; + +// ============================================================================ +// [asmjit::kFuncHint] +// ============================================================================ + +//! Function hints. +//! +//! For a platform specific calling conventions, see: +//! - `kX86FuncHint` - X86/X64 function hints. +ASMJIT_ENUM(kFuncHint) { + //! Make a naked function (default true). + //! + //! Naked function is function without using standard prolog/epilog sequence). + //! + //! X86/X64 Specific + //! ---------------- + //! + //! Standard prolog sequence is: + //! + //! ~~~ + //! push zbp + //! mov zsp, zbp + //! sub zsp, StackAdjustment + //! ~~~ + //! + //! which is an equivalent to: + //! + //! ~~~ + //! enter StackAdjustment, 0 + //! ~~~ + //! + //! Standard epilog sequence is: + //! + //! ~~~ + //! mov zsp, zbp + //! pop zbp + //! ~~~ + //! + //! which is an equavalent to: + //! + //! ~~~ + //! leave + //! ~~~ + //! + //! Naked functions can omit the prolog/epilog sequence. The advantage of + //! doing such modification is that EBP/RBP register can be used by the + //! register allocator which can result in less spills/allocs. + kFuncHintNaked = 0, + + //! Generate compact function prolog/epilog if possible. + //! + //! X86/X64 Specific + //! ---------------- + //! + //! Use shorter, but possible slower prolog/epilog sequence to save/restore + //! registers. + kFuncHintCompact = 1 +}; + +// ============================================================================ +// [asmjit::kFuncFlags] +// ============================================================================ + +//! Function flags. +//! +//! For a platform specific calling conventions, see: +//! - `kX86FuncFlags` - X86/X64 function flags. +ASMJIT_ENUM(kFuncFlags) { + //! Whether the function is using naked (minimal) prolog / epilog. + kFuncFlagIsNaked = 0x00000001, + + //! Whether an another function is called from this function. + kFuncFlagIsCaller = 0x00000002, + + //! Whether the stack is not aligned to the required stack alignment, + //! thus it has to be aligned manually. + kFuncFlagIsStackMisaligned = 0x00000004, + + //! Whether the stack pointer is adjusted by the stack size needed + //! to save registers and function variables. + //! + //! X86/X64 Specific + //! ---------------- + //! + //! Stack pointer (ESP/RSP) is adjusted by 'sub' instruction in prolog and by + //! 'add' instruction in epilog (only if function is not naked). If function + //! needs to perform manual stack alignment more instructions are used to + //! adjust the stack (like "and zsp, -Alignment"). + kFuncFlagIsStackAdjusted = 0x00000008, + + //! Whether the function is finished using `Compiler::endFunc()`. + kFuncFlagIsFinished = 0x80000000 +}; + +// ============================================================================ +// [asmjit::kFuncDir] +// ============================================================================ + +//! Function arguments direction. +ASMJIT_ENUM(kFuncDir) { + //! Arguments are passed left to right. + //! + //! This arguments direction is unusual in C, however it's used in Pascal. + kFuncDirLtr = 0, + + //! Arguments are passed right ro left + //! + //! This is the default argument direction in C. + kFuncDirRtl = 1 +}; + +// ============================================================================ +// [asmjit::kFuncArg] +// ============================================================================ + +//! Function argument (lo/hi) specification. +ASMJIT_ENUM(kFuncArg) { + //! Maxumum number of function arguments supported by AsmJit. + kFuncArgCount = 16, + //! Extended maximum number of arguments (used internally). + kFuncArgCountLoHi = kFuncArgCount * 2, + + //! Index to the LO part of function argument (default). + //! + //! This value is typically omitted and added only if there is HI argument + //! accessed. + kFuncArgLo = 0, + //! Index to the HI part of function argument. + //! + //! HI part of function argument depends on target architecture. On x86 it's + //! typically used to transfer 64-bit integers (they form a pair of 32-bit + //! integers). + kFuncArgHi = kFuncArgCount +}; + +// ============================================================================ +// [asmjit::kFuncRet] +// ============================================================================ + +//! Function return value (lo/hi) specification. +ASMJIT_ENUM(kFuncRet) { + //! Index to the LO part of function return value. + kFuncRetLo = 0, + //! Index to the HI part of function return value. + kFuncRetHi = 1 +}; + +// ============================================================================ +// [asmjit::kFuncStackInvalid] +// ============================================================================ + +enum kFuncMisc { + //! Invalid stack offset in function or function parameter. + kFuncStackInvalid = -1 +}; + +// ============================================================================ +// [asmjit::kNodeType] +// ============================================================================ + +//! Type of node, see \ref Node. +ASMJIT_ENUM(kNodeType) { + //! Invalid node (internal, can't be used). + kNodeTypeNone = 0, + //! Node is an .align directive, see \ref AlignNode. + kNodeTypeAlign, + //! Node is an embedded data, see \ref EmbedNode. + kNodeTypeEmbed, + //! Node is a comment, see \ref CommentNode. + kNodeTypeComment, + //! Node is a variable hint (alloc, spill, use, unuse), see \ref HintNode. + kNodeTypeHint, + //! Node is a label, see \ref TargetNode. + kNodeTypeTarget, + //! Node is an instruction, see \ref InstNode. + kNodeTypeInst, + //! Node is a function declaration, see \ref FuncNode. + kNodeTypeFunc, + //! Node is an end of the function, see \ref EndNode. + kNodeTypeEnd, + //! Node is a return, see \ref RetNode. + kNodeTypeRet, + //! Node is a function call, see \ref CallNode. + kNodeTypeCall, + //! Node is a function call argument moved on stack, see \ref SArgNode. + kNodeTypeSArg +}; + +// ============================================================================ +// [asmjit::kNodeFlags] +// ============================================================================ + +ASMJIT_ENUM(kNodeFlags) { + //! Whether the node has been translated, thus contains only registers. + kNodeFlagIsTranslated = 0x0001, + + //! Whether the node was scheduled - possibly reordered, but basically this + //! is a mark that is set by scheduler after the node has been visited. + kNodeFlagIsScheduled = 0x0002, + + //! Whether the node is informative only and can be safely removed. + kNodeFlagIsInformative = 0x0004, + + //! Whether the `InstNode` is a jump. + kNodeFlagIsJmp = 0x0008, + //! Whether the `InstNode` is a conditional jump. + kNodeFlagIsJcc = 0x0010, + + //! Whether the `InstNode` is an unconditinal jump or conditional + //! jump that is likely to be taken. + kNodeFlagIsTaken = 0x0020, + + //! Whether the `Node` will return from a function. + //! + //! This flag is used by both `EndNode` and `RetNode`. + kNodeFlagIsRet = 0x0040, + + //! Whether the instruction is special. + kNodeFlagIsSpecial = 0x0080, + + //! Whether the instruction is an FPU instruction. + kNodeFlagIsFp = 0x0100 +}; + +// ============================================================================ +// [asmjit::MemCell] +// ============================================================================ + +struct MemCell { + ASMJIT_NO_COPY(MemCell) + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get cell offset. + ASMJIT_INLINE int32_t getOffset() const { return _offset; } + //! Set cell offset. + ASMJIT_INLINE void setOffset(int32_t offset) { _offset = offset; } + + //! Get cell size. + ASMJIT_INLINE uint32_t getSize() const { return _size; } + //! Set cell size. + ASMJIT_INLINE void setSize(uint32_t size) { _size = size; } + + //! Get cell alignment. + ASMJIT_INLINE uint32_t getAlignment() const { return _alignment; } + //! Set cell alignment. + ASMJIT_INLINE void setAlignment(uint32_t alignment) { _alignment = alignment; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Next active cell. + MemCell* _next; + + //! Offset, relative to base-offset. + int32_t _offset; + //! Size. + uint32_t _size; + //! Alignment. + uint32_t _alignment; +}; + +// ============================================================================ +// [asmjit::Var] +// ============================================================================ + +//! Base class for all variables. +struct Var : public Operand { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Var() : Operand(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, 0, 0, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, kInvalidValue); + } + + ASMJIT_INLINE Var(const Var& other) : Operand(other) {} + + explicit ASMJIT_INLINE Var(const _NoInit&) : Operand(NoInit) {} + + // -------------------------------------------------------------------------- + // [Var Specific] + // -------------------------------------------------------------------------- + + //! Clone `Var` operand. + ASMJIT_INLINE Var clone() const { + return Var(*this); + } + + //! Get whether the variable has been initialized by `Compiler`. + ASMJIT_INLINE bool isInitialized() const { + return _vreg.id != kInvalidValue; + } + + //! Get variable type. + ASMJIT_INLINE uint32_t getVarType() const { + return _vreg.vType; + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Var& operator=(const Var& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const Var& other) const { return _packed[0] == other._packed[0]; } + ASMJIT_INLINE bool operator!=(const Var& other) const { return !operator==(other); } +}; + +// ============================================================================ +// [asmjit::VarBits] +// ============================================================================ + +//! Bit-array used by variable-liveness analysis. +struct VarBits { + // -------------------------------------------------------------------------- + // [Enums] + // -------------------------------------------------------------------------- + + enum { + kEntitySize = static_cast(sizeof(uintptr_t)), + kEntityBits = kEntitySize * 8 + }; + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uintptr_t getBit(uint32_t index) const { + return (data[index / kEntityBits] >> (index % kEntityBits)) & 1; + } + + ASMJIT_INLINE void setBit(uint32_t index) { + data[index / kEntityBits] |= static_cast(1) << (index % kEntityBits); + } + + ASMJIT_INLINE void delBit(uint32_t index) { + data[index / kEntityBits] &= ~(static_cast(1) << (index % kEntityBits)); + } + + // -------------------------------------------------------------------------- + // [Ops] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool copyBits(const VarBits* s0, uint32_t len) { + uintptr_t r = 0; + for (uint32_t i = 0; i < len; i++) { + uintptr_t t = s0->data[i]; + data[i] = t; + r |= t; + } + return r != 0; + } + + ASMJIT_INLINE bool addBits(const VarBits* s0, uint32_t len) { + return addBits(this, s0, len); + } + + ASMJIT_INLINE bool addBits(const VarBits* s0, const VarBits* s1, uint32_t len) { + uintptr_t r = 0; + for (uint32_t i = 0; i < len; i++) { + uintptr_t t = s0->data[i] | s1->data[i]; + data[i] = t; + r |= t; + } + return r != 0; + } + + ASMJIT_INLINE bool andBits(const VarBits* s1, uint32_t len) { + return andBits(this, s1, len); + } + + ASMJIT_INLINE bool andBits(const VarBits* s0, const VarBits* s1, uint32_t len) { + uintptr_t r = 0; + for (uint32_t i = 0; i < len; i++) { + uintptr_t t = s0->data[i] & s1->data[i]; + data[i] = t; + r |= t; + } + return r != 0; + } + + ASMJIT_INLINE bool delBits(const VarBits* s1, uint32_t len) { + return delBits(this, s1, len); + } + + ASMJIT_INLINE bool delBits(const VarBits* s0, const VarBits* s1, uint32_t len) { + uintptr_t r = 0; + for (uint32_t i = 0; i < len; i++) { + uintptr_t t = s0->data[i] & ~s1->data[i]; + data[i] = t; + r |= t; + } + return r != 0; + } + + ASMJIT_INLINE bool _addBitsDelSource(VarBits* s1, uint32_t len) { + return _addBitsDelSource(this, s1, len); + } + + ASMJIT_INLINE bool _addBitsDelSource(const VarBits* s0, VarBits* s1, uint32_t len) { + uintptr_t r = 0; + for (uint32_t i = 0; i < len; i++) { + uintptr_t a = s0->data[i]; + uintptr_t b = s1->data[i]; + + this->data[i] = a | b; + b &= ~a; + + s1->data[i] = b; + r |= b; + } + return r != 0; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uintptr_t data[1]; +}; + +// ============================================================================ +// [asmjit::VarData] +// ============================================================================ + +//! Base variable data. +struct VarData { + // -------------------------------------------------------------------------- + // [Accessors - Base] + // -------------------------------------------------------------------------- + + //! Get variable name. + ASMJIT_INLINE const char* getName() const { + return _name; + } + + //! Get variable id. + ASMJIT_INLINE uint32_t getId() const { + return _id; + } + + //! Get variable type. + ASMJIT_INLINE uint32_t getType() const { + return _type; + } + + //! Get variable class. + ASMJIT_INLINE uint32_t getClass() const { + return _class; + } + + // -------------------------------------------------------------------------- + // [Accessors - ContextId] + // -------------------------------------------------------------------------- + + //! Get whether the variable has context id. + ASMJIT_INLINE bool hasContextId() const { + return _contextId != kInvalidValue; + } + + //! Get context variable id (used only by `Context)`. + ASMJIT_INLINE uint32_t getContextId() const { + return _contextId; + } + + //! Set context variable id (used only by `Context)`. + ASMJIT_INLINE void setContextId(uint32_t contextId) { + _contextId = contextId; + } + + //! Reset context variable id (used only by `Context)`. + ASMJIT_INLINE void resetContextId() { + _contextId = kInvalidValue; + } + + // -------------------------------------------------------------------------- + // [Accessors - Priority] + // -------------------------------------------------------------------------- + + //! Get variable priority, used by compiler to decide which variable to spill. + ASMJIT_INLINE uint32_t getPriority() const { + return _priority; + } + + //! Set variable priority. + ASMJIT_INLINE void setPriority(uint32_t priority) { + ASMJIT_ASSERT(priority <= 0xFF); + _priority = static_cast(priority); + } + + // -------------------------------------------------------------------------- + // [Accessors - State] + // -------------------------------------------------------------------------- + + //! Get variable state, only used by `Context`. + ASMJIT_INLINE uint32_t getState() const { + return _state; + } + + //! Set variable state, only used by `Context`. + ASMJIT_INLINE void setState(uint32_t state) { + ASMJIT_ASSERT(state <= 0xFF); + _state = static_cast(state); + } + + // -------------------------------------------------------------------------- + // [Accessors - RegIndex] + // -------------------------------------------------------------------------- + + //! Get register index. + ASMJIT_INLINE uint32_t getRegIndex() const { + return _regIndex; + } + + //! Set register index. + ASMJIT_INLINE void setRegIndex(uint32_t regIndex) { + ASMJIT_ASSERT(regIndex <= 0xFF); + _regIndex = static_cast(regIndex); + } + + //! Reset register index. + ASMJIT_INLINE void resetRegIndex() { + _regIndex = static_cast(kInvalidReg); + } + + // -------------------------------------------------------------------------- + // [Accessors - HomeIndex/Mask] + // -------------------------------------------------------------------------- + + //! Get home registers mask. + ASMJIT_INLINE uint32_t getHomeMask() const { + return _homeMask; + } + + //! Add a home register index to the home registers mask. + ASMJIT_INLINE void addHomeIndex(uint32_t regIndex) { + _homeMask |= IntUtil::mask(regIndex); + } + + // -------------------------------------------------------------------------- + // [Accessors - Flags] + // -------------------------------------------------------------------------- + + //! Get variable flags. + ASMJIT_INLINE uint32_t getFlags() const { + return _flags; + } + + //! Get whether the VarData is only memory allocated on the stack. + ASMJIT_INLINE bool isStack() const { return static_cast(_isStack); } + + //! Get whether the variable is a function argument passed through memory. + ASMJIT_INLINE bool isMemArg() const { return static_cast(_isMemArg); } + + //! Get variable content can be calculated by a simple instruction. + ASMJIT_INLINE bool isCalculated() const { return static_cast(_isCalculated); } + //! Get whether to save variable when it's unused (spill). + ASMJIT_INLINE bool saveOnUnuse() const { return static_cast(_saveOnUnuse); } + + //! Get whether the variable was changed. + ASMJIT_INLINE bool isModified() const { return static_cast(_modified); } + //! Set whether the variable was changed. + ASMJIT_INLINE void setModified(bool modified) { _modified = modified; } + + //! Get variable alignment. + ASMJIT_INLINE uint32_t getAlignment() const { return _alignment; } + //! Get variable size. + ASMJIT_INLINE uint32_t getSize() const { return _size; } + + //! Get home memory offset. + ASMJIT_INLINE int32_t getMemOffset() const { return _memOffset; } + //! Set home memory offset. + ASMJIT_INLINE void setMemOffset(int32_t offset) { _memOffset = offset; } + + //! Get home memory cell. + ASMJIT_INLINE MemCell* getMemCell() const { return _memCell; } + //! Set home memory cell. + ASMJIT_INLINE void setMemCell(MemCell* cell) { _memCell = cell; } + + // -------------------------------------------------------------------------- + // [Accessors - Temporary Usage] + // -------------------------------------------------------------------------- + + //! Get temporary VarAttr. + ASMJIT_INLINE VarAttr* getVa() const { return _va; } + //! Set temporary VarAttr. + ASMJIT_INLINE void setVa(VarAttr* va) { _va = va; } + //! Reset temporary VarAttr. + ASMJIT_INLINE void resetVa() { _va = NULL; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Variable name. + const char* _name; + + //! Variable id. + uint32_t _id; + //! Context variable id, used by `Context` only, initially `kInvalidValue`. + uint32_t _contextId; + + //! Variable type. + uint8_t _type; + //! Variable class. + uint8_t _class; + //! Variable flags. + uint8_t _flags; + //! Variable priority. + uint8_t _priority; + + //! Variable state (connected with actual `VarState)`. + uint8_t _state; + //! Actual register index (only used by `Context)`, during translate. + uint8_t _regIndex; + + //! Whether the variable is only used as memory allocated on the stack. + uint8_t _isStack : 1; + //! Whether the variable is a function argument passed through memory. + uint8_t _isMemArg : 1; + //! Whether variable content can be calculated by a simple instruction. + //! + //! This is used mainly by MMX and SSE2 code. This flag indicates that + //! register allocator should never reserve memory for this variable, because + //! the content can be generated by a single instruction (for example PXOR). + uint8_t _isCalculated : 1; + //! Save on unuse (at end of the variable scope). + uint8_t _saveOnUnuse : 1; + //! Whether variable was changed (connected with actual `VarState)`. + uint8_t _modified : 1; + //! \internal + uint8_t _reserved0 : 3; + //! Variable natural alignment. + uint8_t _alignment; + + //! Variable size. + uint32_t _size; + + //! Mask of all registers variable has been allocated to. + uint32_t _homeMask; + + //! Home memory offset. + int32_t _memOffset; + //! Home memory cell, used by `Context` (initially NULL). + MemCell* _memCell; + + //! Register read access statistics. + uint32_t rReadCount; + //! Register write access statistics. + uint32_t rWriteCount; + + //! Memory read statistics. + uint32_t mReadCount; + //! Memory write statistics. + uint32_t mWriteCount; + + // -------------------------------------------------------------------------- + // [Members - Temporary Usage] + // -------------------------------------------------------------------------- + + // These variables are only used during register allocation. They are + // initialized by init() phase and reset by cleanup() phase. + + union { + //! Temporary link to VarAttr* used by the `Context` used in + //! various phases, but always set back to NULL when finished. + //! + //! This temporary data is designed to be used by algorithms that need to + //! store some data into variables themselves during compilation. But it's + //! expected that after variable is compiled & translated the data is set + //! back to zero/null. Initial value is NULL. + VarAttr* _va; + + //! \internal + //! + //! Same as `_va` just provided as `uintptr_t`. + uintptr_t _vaUInt; + }; +}; + +// ============================================================================ +// [asmjit::VarAttr] +// ============================================================================ + +struct VarAttr { + // -------------------------------------------------------------------------- + // [Setup] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void setup(VarData* vd, uint32_t flags = 0, uint32_t inRegs = 0, uint32_t allocableRegs = 0) { + _vd = vd; + _flags = flags; + _varCount = 0; + _inRegIndex = kInvalidReg; + _outRegIndex = kInvalidReg; + _reserved = 0; + _inRegs = inRegs; + _allocableRegs = allocableRegs; + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get VarData. + ASMJIT_INLINE VarData* getVd() const { return _vd; } + //! Set VarData. + ASMJIT_INLINE void setVd(VarData* vd) { _vd = vd; } + + //! Get flags. + ASMJIT_INLINE uint32_t getFlags() const { return _flags; } + //! Set flags. + ASMJIT_INLINE void setFlags(uint32_t flags) { _flags = flags; } + + //! Get whether `flag` is on. + ASMJIT_INLINE bool hasFlag(uint32_t flag) { return (_flags & flag) != 0; } + //! Add `flags`. + ASMJIT_INLINE void addFlags(uint32_t flags) { _flags |= flags; } + //! Mask `flags`. + ASMJIT_INLINE void andFlags(uint32_t flags) { _flags &= flags; } + //! Clear `flags`. + ASMJIT_INLINE void delFlags(uint32_t flags) { _flags &= ~flags; } + + //! Get how many times the variable is used by the instruction/node. + ASMJIT_INLINE uint32_t getVarCount() const { return _varCount; } + //! Set how many times the variable is used by the instruction/node. + ASMJIT_INLINE void setVarCount(uint32_t count) { _varCount = static_cast(count); } + //! Add how many times the variable is used by the instruction/node. + ASMJIT_INLINE void addVarCount(uint32_t count = 1) { _varCount += static_cast(count); } + + //! Get whether the variable has to be allocated in a specific input register. + ASMJIT_INLINE uint32_t hasInRegIndex() const { return _inRegIndex != kInvalidReg; } + //! Get the input register index or `kInvalidReg`. + ASMJIT_INLINE uint32_t getInRegIndex() const { return _inRegIndex; } + //! Set the input register index. + ASMJIT_INLINE void setInRegIndex(uint32_t index) { _inRegIndex = static_cast(index); } + //! Reset the input register index. + ASMJIT_INLINE void resetInRegIndex() { _inRegIndex = kInvalidReg; } + + //! Get whether the variable has to be allocated in a specific output register. + ASMJIT_INLINE uint32_t hasOutRegIndex() const { return _outRegIndex != kInvalidReg; } + //! Get the output register index or `kInvalidReg`. + ASMJIT_INLINE uint32_t getOutRegIndex() const { return _outRegIndex; } + //! Set the output register index. + ASMJIT_INLINE void setOutRegIndex(uint32_t index) { _outRegIndex = static_cast(index); } + //! Reset the output register index. + ASMJIT_INLINE void resetOutRegIndex() { _outRegIndex = kInvalidReg; } + + //! Get whether the mandatory input registers are in used. + ASMJIT_INLINE bool hasInRegs() const { return _inRegs != 0; } + //! Get mandatory input registers (mask). + ASMJIT_INLINE uint32_t getInRegs() const { return _inRegs; } + //! Set mandatory input registers (mask). + ASMJIT_INLINE void setInRegs(uint32_t mask) { _inRegs = mask; } + //! Add mandatory input registers (mask). + ASMJIT_INLINE void addInRegs(uint32_t mask) { _inRegs |= mask; } + //! And mandatory input registers (mask). + ASMJIT_INLINE void andInRegs(uint32_t mask) { _inRegs &= mask; } + //! Clear mandatory input registers (mask). + ASMJIT_INLINE void delInRegs(uint32_t mask) { _inRegs &= ~mask; } + + //! Get allocable input registers (mask). + ASMJIT_INLINE uint32_t getAllocableRegs() const { return _allocableRegs; } + //! Set allocable input registers (mask). + ASMJIT_INLINE void setAllocableRegs(uint32_t mask) { _allocableRegs = mask; } + //! Add allocable input registers (mask). + ASMJIT_INLINE void addAllocableRegs(uint32_t mask) { _allocableRegs |= mask; } + //! And allocable input registers (mask). + ASMJIT_INLINE void andAllocableRegs(uint32_t mask) { _allocableRegs &= mask; } + //! Clear allocable input registers (mask). + ASMJIT_INLINE void delAllocableRegs(uint32_t mask) { _allocableRegs &= ~mask; } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE VarAttr& operator=(const VarAttr& other) { + ::memcpy(this, &other, sizeof(VarAttr)); + return *this; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + VarData* _vd; + //! Flags. + uint32_t _flags; + + union { + struct { + //! How many times the variable is used by the instruction/node. + uint8_t _varCount; + //! Input register index or `kInvalidReg` if it's not given. + //! + //! Even if the input register index is not given (i.e. it may by any + //! register), register allocator should assign an index that will be + //! used to persist a variable into this specific index. It's helpful + //! in situations where one variable has to be allocated in multiple + //! registers to determine the register which will be persistent. + uint8_t _inRegIndex; + //! Output register index or `kInvalidReg` if it's not given. + //! + //! Typically `kInvalidReg` if variable is only used on input. + uint8_t _outRegIndex; + //! \internal + uint8_t _reserved; + }; + + //! \internal + //! + //! Packed data #0. + uint32_t _packed; + }; + + //! Mandatory input registers. + //! + //! Mandatory input registers are required by the instruction even if + //! there are duplicates. This schema allows us to allocate one variable + //! in one or more register when needed. Required mostly by instructions + //! that have implicit register operands (imul, cpuid, ...) and function + //! call. + uint32_t _inRegs; + + //! Allocable input registers. + //! + //! Optional input registers is a mask of all allocable registers for a given + //! variable where we have to pick one of them. This mask is usually not used + //! when _inRegs is set. If both masks are used then the register + //! allocator tries first to find an intersection between these and allocates + //! an extra slot if not found. + uint32_t _allocableRegs; +}; + +// ============================================================================ +// [asmjit::VarMap] +// ============================================================================ + +//! Variables' map related to a single node (instruction / other node). +struct VarMap { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get count of variables (all). + ASMJIT_INLINE uint32_t getVaCount() const { + return _vaCount; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Variables count. + uint32_t _vaCount; +}; + +// ============================================================================ +// [asmjit::VarState] +// ============================================================================ + +//! Variables' state. +struct VarState {}; + +// ============================================================================ +// [asmjit::TypeId / VarMapping] +// ============================================================================ + +//! Function builder 'void' type. +struct Void {}; + +//! Function builder 'int8_t' type. +struct Int8Type {}; +//! Function builder 'uint8_t' type. +struct UInt8Type {}; + +//! Function builder 'int16_t' type. +struct Int16Type {}; +//! Function builder 'uint16_t' type. +struct UInt16Type {}; + +//! Function builder 'int32_t' type. +struct Int32Type {}; +//! Function builder 'uint32_t' type. +struct UInt32Type {}; + +//! Function builder 'int64_t' type. +struct Int64Type {}; +//! Function builder 'uint64_t' type. +struct UInt64Type {}; + +//! Function builder 'intptr_t' type. +struct IntPtrType {}; +//! Function builder 'uintptr_t' type. +struct UIntPtrType {}; + +//! Function builder 'float' type. +struct FloatType {}; +//! Function builder 'double' type. +struct DoubleType {}; + +#if !defined(ASMJIT_DOCGEN) +template +struct TypeId { + enum { kId = static_cast(::asmjit::kInvalidVar) }; +}; + +template +struct TypeId { + enum { kId = kVarTypeIntPtr }; +}; + +#define ASMJIT_TYPE_ID(_T_, _Id_) \ + template<> \ + struct TypeId<_T_> { enum { kId = _Id_ }; } + +ASMJIT_TYPE_ID(void, kInvalidVar); +ASMJIT_TYPE_ID(Void, kInvalidVar); + +ASMJIT_TYPE_ID(int8_t, kVarTypeInt8); +ASMJIT_TYPE_ID(Int8Type, kVarTypeInt8); + +ASMJIT_TYPE_ID(uint8_t, kVarTypeUInt8); +ASMJIT_TYPE_ID(UInt8Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(int16_t, kVarTypeInt16); +ASMJIT_TYPE_ID(Int16Type, kVarTypeInt16); + +ASMJIT_TYPE_ID(uint16_t, kVarTypeUInt8); +ASMJIT_TYPE_ID(UInt16Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(int32_t, kVarTypeInt32); +ASMJIT_TYPE_ID(Int32Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(uint32_t, kVarTypeUInt32); +ASMJIT_TYPE_ID(UInt32Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(int64_t, kVarTypeInt64); +ASMJIT_TYPE_ID(Int64Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(uint64_t, kVarTypeUInt64); +ASMJIT_TYPE_ID(UInt64Type, kVarTypeUInt8); + +ASMJIT_TYPE_ID(float, kVarTypeFp32); +ASMJIT_TYPE_ID(FloatType, kVarTypeFp32); + +ASMJIT_TYPE_ID(double, kVarTypeFp64); +ASMJIT_TYPE_ID(DoubleType, kVarTypeFp64); +#endif // !ASMJIT_DOCGEN + +// ============================================================================ +// [asmjit::FuncInOut] +// ============================================================================ + +//! Function in/out - argument or return value translated from `FuncPrototype`. +struct FuncInOut { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t getVarType() const { return _varType; } + + ASMJIT_INLINE bool hasRegIndex() const { return _regIndex != kInvalidReg; } + ASMJIT_INLINE uint32_t getRegIndex() const { return _regIndex; } + + ASMJIT_INLINE bool hasStackOffset() const { return _stackOffset != kFuncStackInvalid; } + ASMJIT_INLINE int32_t getStackOffset() const { return static_cast(_stackOffset); } + + //! Get whether the argument / return value is assigned. + ASMJIT_INLINE bool isSet() const { + return (_regIndex != kInvalidReg) | (_stackOffset != kFuncStackInvalid); + } + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset the function argument to "unassigned state". + ASMJIT_INLINE void reset() { _packed = 0xFFFFFFFF; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + struct { + //! Variable type, see `kVarType`. + uint8_t _varType; + //! Register index if argument / return value is a register. + uint8_t _regIndex; + //! Stack offset if argument / return value is on the stack. + int16_t _stackOffset; + }; + + //! All members packed into single 32-bit integer. + uint32_t _packed; + }; +}; + +// ============================================================================ +// [asmjit::FuncPrototype] +// ============================================================================ + +//! Function prototype. +//! +//! Function prototype contains information about function return type, count +//! of arguments and their types. Function prototype is a low level structure +//! which doesn't contain platform specific or calling convention specific +//! information. Function prototype is used to create a `FuncDecl`. +struct FuncPrototype { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function return value. + ASMJIT_INLINE uint32_t getRet() const { return _ret; } + + //! Get function arguments' IDs. + ASMJIT_INLINE const uint32_t* getArgList() const { return _argList; } + //! Get count of function arguments. + ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; } + + //! Get argument at index `id`. + ASMJIT_INLINE uint32_t getArg(uint32_t id) const { + ASMJIT_ASSERT(id < _argCount); + return _argList[id]; + } + + //! Set function definition - return type and arguments. + ASMJIT_INLINE void _setPrototype(uint32_t ret, const uint32_t* argList, uint32_t argCount) { + _ret = ret; + _argList = argList; + _argCount = argCount; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uint32_t _ret; + uint32_t _argCount; + const uint32_t* _argList; +}; + +// ============================================================================ +// [asmjit::FuncBuilderX] +// ============================================================================ + +//! Custom function builder for up to 32 function arguments. +struct FuncBuilderX : public FuncPrototype { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE FuncBuilderX() { + _setPrototype(kInvalidVar, _builderArgList, 0); + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Set return type to `retType`. + ASMJIT_INLINE void setRet(uint32_t retType) { + _ret = retType; + } + + ASMJIT_INLINE void setArg(uint32_t id, uint32_t type) { + ASMJIT_ASSERT(id < _argCount); + _builderArgList[id] = type; + } + + ASMJIT_INLINE void addArg(uint32_t type) { + ASMJIT_ASSERT(_argCount < kFuncArgCount); + _builderArgList[_argCount++] = type; + } + + template + ASMJIT_INLINE void setRetT() { + setRet(TypeId::kId); + } + + template + ASMJIT_INLINE void setArgT(uint32_t id) { + setArg(id, TypeId::kId); + } + + template + ASMJIT_INLINE void addArgT() { + addArg(TypeId::kId); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uint32_t _builderArgList[kFuncArgCount]; +}; + +//! \internal +#define T(_Type_) TypeId<_Type_>::kId + +//! Function prototype (no args). +template +struct FuncBuilder0 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder0() { + _setPrototype(T(RET), NULL, 0); + } +}; + +//! Function prototype (1 argument). +template +struct FuncBuilder1 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder1() { + static const uint32_t args[] = { T(P0) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (2 arguments). +template +struct FuncBuilder2 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder2() { + static const uint32_t args[] = { T(P0), T(P1) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (3 arguments). +template +struct FuncBuilder3 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder3() { + static const uint32_t args[] = { T(P0), T(P1), T(P2) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (4 arguments). +template +struct FuncBuilder4 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder4() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (5 arguments). +template +struct FuncBuilder5 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder5() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (6 arguments). +template +struct FuncBuilder6 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder6() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (7 arguments). +template +struct FuncBuilder7 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder7() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (8 arguments). +template +struct FuncBuilder8 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder8() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (9 arguments). +template +struct FuncBuilder9 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder9() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +//! Function prototype (10 arguments). +template +struct FuncBuilder10 : public FuncPrototype { + ASMJIT_INLINE FuncBuilder10() { + static const uint32_t args[] = { T(P0), T(P1), T(P2), T(P3), T(P4), T(P5), T(P6), T(P7), T(P8), T(P9) }; + _setPrototype(T(RET), args, ASMJIT_ARRAY_SIZE(args)); + } +}; + +#undef T + +// ============================================================================ +// [asmjit::FuncDecl] +// ============================================================================ + +//! Function declaration. +struct FuncDecl { + // -------------------------------------------------------------------------- + // [Accessors - Calling Convention] + // -------------------------------------------------------------------------- + + //! Get function calling convention, see `kFuncConv`. + ASMJIT_INLINE uint32_t getConvention() const { return _convention; } + + //! Get whether the callee pops the stack. + ASMJIT_INLINE uint32_t getCalleePopsStack() const { return _calleePopsStack; } + + //! Get direction of arguments passed on the stack. + //! + //! Direction should be always `kFuncDirRtl`. + //! + //! \note This is related to used calling convention, it's not affected by + //! number of function arguments or their types. + ASMJIT_INLINE uint32_t getDirection() const { return _direction; } + + //! Get stack size needed for function arguments passed on the stack. + ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; } + //! Get size of "Red Zone". + ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; } + //! Get size of "Spill Zone". + ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; } + + // -------------------------------------------------------------------------- + // [Accessors - Arguments and Return] + // -------------------------------------------------------------------------- + + //! Get whether the function has a return value. + ASMJIT_INLINE bool hasRet() const { return _retCount != 0; } + //! Get count of function return values. + ASMJIT_INLINE uint32_t getRetCount() const { return _retCount; } + + //! Get function return value. + ASMJIT_INLINE FuncInOut& getRet(uint32_t index = kFuncRetLo) { return _retList[index]; } + //! Get function return value. + ASMJIT_INLINE const FuncInOut& getRet(uint32_t index = kFuncRetLo) const { return _retList[index]; } + + //! Get count of function arguments. + ASMJIT_INLINE uint32_t getArgCount() const { return _argCount; } + + //! Get function arguments array. + ASMJIT_INLINE FuncInOut* getArgList() { return _argList; } + //! Get function arguments array (const). + ASMJIT_INLINE const FuncInOut* getArgList() const { return _argList; } + + //! Get function argument at index `index`. + ASMJIT_INLINE FuncInOut& getArg(size_t index) { + ASMJIT_ASSERT(index < kFuncArgCountLoHi); + return _argList[index]; + } + + //! Get function argument at index `index`. + ASMJIT_INLINE const FuncInOut& getArg(size_t index) const { + ASMJIT_ASSERT(index < kFuncArgCountLoHi); + return _argList[index]; + } + + ASMJIT_INLINE void resetArg(size_t index) { + ASMJIT_ASSERT(index < kFuncArgCountLoHi); + _argList[index].reset(); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Calling convention. + uint8_t _convention; + //! Whether a callee pops stack. + uint8_t _calleePopsStack : 1; + //! Direction for arguments passed on the stack, see `kFuncDir`. + uint8_t _direction : 1; + //! Reserved #0 (alignment). + uint8_t _reserved0 : 6; + + //! Count of arguments in `_argList`. + uint8_t _argCount; + //! Count of return value(s). + uint8_t _retCount; + + //! Count of bytes consumed by arguments on the stack (aligned). + uint32_t _argStackSize; + + //! Size of "Red Zone". + //! + //! \note Used by AMD64-ABI (128 bytes). + uint16_t _redZoneSize; + + //! Size of "Spill Zone". + //! + //! \note Used by WIN64-ABI (32 bytes). + uint16_t _spillZoneSize; + + //! Function arguments (including HI arguments) mapped to physical + //! registers and stack offset. + FuncInOut _argList[kFuncArgCountLoHi]; + + //! Function return value(s). + FuncInOut _retList[2]; +}; + +// ============================================================================ +// [asmjit::Node] +// ============================================================================ + +//! Base node. +//! +//! `Every` node represents an abstract instruction, directive, label, or +//! macro-instruction generated by compiler. +struct Node { + ASMJIT_NO_COPY(Node) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create new `Node`. + //! + //! \note Always use compiler to create nodes. + ASMJIT_INLINE Node(Compiler* compiler, uint32_t type); // Defined-Later. + + //! Destroy `Node`. + ASMJIT_INLINE ~Node() {} + + // -------------------------------------------------------------------------- + // [Accessors - List] + // -------------------------------------------------------------------------- + + //! Get previous node in the compiler stream. + ASMJIT_INLINE Node* getPrev() const { + return _prev; + } + + //! Get next node in the compiler stream. + ASMJIT_INLINE Node* getNext() const { + return _next; + } + + // -------------------------------------------------------------------------- + // [Accessors - Comment] + // -------------------------------------------------------------------------- + + //! Get comment string. + ASMJIT_INLINE const char* getComment() const { + return _comment; + } + + //! Set comment string to `str`. + ASMJIT_INLINE void setComment(const char* comment) { + _comment = comment; + } + + // -------------------------------------------------------------------------- + // [Accessors - Type and Flags] + // -------------------------------------------------------------------------- + + //! Get type of node, see `kNodeType`. + ASMJIT_INLINE uint32_t getType() const { + return _type; + } + + //! Get node flags. + ASMJIT_INLINE uint32_t getFlags() const { + return _flags; + } + + //! Set node flags to `flags`. + ASMJIT_INLINE void setFlags(uint32_t flags) { + _flags = static_cast(flags); + } + + //! Get whether the instruction has flag `flag`. + ASMJIT_INLINE bool hasFlag(uint32_t flag) const { + return (static_cast(_flags) & flag) != 0; + } + + //! Add instruction `flags`. + ASMJIT_INLINE void addFlags(uint32_t flags) { + _flags |= static_cast(flags); + } + + //! Clear instruction `flags`. + ASMJIT_INLINE void delFlags(uint32_t flags) { + _flags &= static_cast(~flags); + } + + //! Get whether the node has beed fetched. + ASMJIT_INLINE bool isFetched() const { + return _flowId != 0; + } + + //! Get whether the node has been translated. + ASMJIT_INLINE bool isTranslated() const { + return hasFlag(kNodeFlagIsTranslated); + } + + //! Get whether the node has been translated. + ASMJIT_INLINE bool isScheduled() const { + return hasFlag(kNodeFlagIsScheduled); + } + + //! Get whether the node is informative only and can be safely removed after + //! translation. + //! + //! Informative nodes are comments and hints. + ASMJIT_INLINE bool isInformative() const { + return hasFlag(kNodeFlagIsInformative); + } + + //! Whether the instruction is an unconditional jump. + ASMJIT_INLINE bool isJmp() const { return hasFlag(kNodeFlagIsJmp); } + //! Whether the instruction is a conditional jump. + ASMJIT_INLINE bool isJcc() const { return hasFlag(kNodeFlagIsJcc); } + //! Whether the instruction is an unconditional or conditional jump. + ASMJIT_INLINE bool isJmpOrJcc() const { return hasFlag(kNodeFlagIsJmp | kNodeFlagIsJcc); } + //! Whether the instruction is a return. + ASMJIT_INLINE bool isRet() const { return hasFlag(kNodeFlagIsRet); } + + //! Get whether the instruction is special. + ASMJIT_INLINE bool isSpecial() const { return hasFlag(kNodeFlagIsSpecial); } + //! Get whether the instruction accesses FPU. + ASMJIT_INLINE bool isFp() const { return hasFlag(kNodeFlagIsFp); } + + // -------------------------------------------------------------------------- + // [Accessors - FlowId] + // -------------------------------------------------------------------------- + + //! Get flow index. + ASMJIT_INLINE uint32_t getFlowId() const { return _flowId; } + //! Set flow index. + ASMJIT_INLINE void setFlowId(uint32_t flowId) { _flowId = flowId; } + + // -------------------------------------------------------------------------- + // [Accessors - VarMap] + // -------------------------------------------------------------------------- + + //! Get whether node contains variable allocation instructions. + ASMJIT_INLINE bool hasMap() const { + return _map != NULL; + } + + //! Get variable allocation instructions. + ASMJIT_INLINE VarMap* getMap() const { + return _map; + } + + //! Get variable allocation instructions casted to `T*`. + template + ASMJIT_INLINE T* getMap() const { + return static_cast(_map); + } + + //! Set variable allocation instructions. + ASMJIT_INLINE void setMap(VarMap* map) { + _map = map; + } + + // -------------------------------------------------------------------------- + // [Accessors - VarState] + // -------------------------------------------------------------------------- + + //! Get node state. + ASMJIT_INLINE VarState* getState() const { + return _state; + } + + //! Get node state casted to `T*`. + template + ASMJIT_INLINE T* getState() const { + return static_cast(_state); + } + + //! Set node state. + ASMJIT_INLINE void setState(VarState* state) { + _state = state; + } + + // -------------------------------------------------------------------------- + // [Accessors - Liveness] + // -------------------------------------------------------------------------- + + //! Get whether the node has variable liveness bits. + ASMJIT_INLINE bool hasLiveness() const { + return _liveness != NULL; + } + + //! Get variable liveness bits. + ASMJIT_INLINE VarBits* getLiveness() const { + return _liveness; + } + + //! Set variable liveness bits. + ASMJIT_INLINE void setLiveness(VarBits* liveness) { + _liveness = liveness; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Previous node. + Node* _prev; + //! Next node. + Node* _next; + + //! Node type, see `kNodeType`. + uint8_t _type; + //! Operands count (if the node has operands, otherwise zero). + uint8_t _opCount; + //! Node flags, different meaning for every node type. + uint16_t _flags; + + //! Flow index. + uint32_t _flowId; + + //! Inline comment string, initially set to NULL. + const char* _comment; + + //! Variable mapping (VarAttr to VarData), initially NULL, filled during + //! fetch phase. + VarMap* _map; + + //! Variable liveness bits (initially NULL, filled by analysis phase). + VarBits* _liveness; + + //! Saved state. + //! + //! Initially NULL, not all nodes have saved state, only branch/flow control + //! nodes. + VarState* _state; +}; + +// ============================================================================ +// [asmjit::AlignNode] +// ============================================================================ + +//! Align node. +struct AlignNode : public Node { + ASMJIT_NO_COPY(AlignNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `AlignNode` instance. + ASMJIT_INLINE AlignNode(Compiler* compiler, uint32_t mode, uint32_t offset) : + Node(compiler, kNodeTypeAlign) { + + _mode = mode; + _offset = offset; + } + + //! Destroy the `AlignNode` instance. + ASMJIT_INLINE ~AlignNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get alignment mode. + ASMJIT_INLINE uint32_t getMode() const { + return _mode; + } + + //! Set alignment mode. + ASMJIT_INLINE void setMode(uint32_t mode) { + _mode = mode; + } + + //! Get align offset in bytes. + ASMJIT_INLINE uint32_t getOffset() const { + return _offset; + } + + //! Set align offset in bytes to `offset`. + ASMJIT_INLINE void setOffset(uint32_t offset) { + _offset = offset; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Alignment mode, see \ref kAlignMode. + uint32_t _mode; + //! Alignment offset in bytes. + uint32_t _offset; +}; + +// ============================================================================ +// [asmjit::EmbedNode] +// ============================================================================ + +//! Embed node. +//! +//! Embed node is used to embed data into final assembler stream. The data is +//! considered to be RAW; No analysis is performed on RAW data. +struct EmbedNode : public Node { + ASMJIT_NO_COPY(EmbedNode) + + // -------------------------------------------------------------------------- + // [Enums] + // -------------------------------------------------------------------------- + + enum { kInlineBufferSize = 8 }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `EmbedNode` instance. + ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) : Node(compiler, kNodeTypeEmbed) { + _size = size; + if (size <= kInlineBufferSize) { + if (data != NULL) + ::memcpy(_data.buf, data, size); + } + else { + _data.ptr = static_cast(data); + } + } + + //! Destroy the `EmbedNode` instance. + ASMJIT_INLINE ~EmbedNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get pointer to data. + uint8_t* getData() { return getSize() <= kInlineBufferSize ? const_cast(_data.buf) : _data.ptr; } + //! Get size of data. + uint32_t getSize() const { return _size; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Size of the embedded data. + uint32_t _size; + + union { + //! data buffer. + uint8_t buf[kInlineBufferSize]; + //! Data buffer. + uint8_t* ptr; + } _data; +}; + +// ============================================================================ +// [asmjit::CommentNode] +// ============================================================================ + +//! Comment node. +//! +//! Comments allows to comment your assembler stream for better debugging +//! and visualization. Comments are usually ignored in release builds unless +//! the logger is present. +struct CommentNode : public Node { + ASMJIT_NO_COPY(CommentNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `CommentNode` instance. + ASMJIT_INLINE CommentNode(Compiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) { + addFlags(kNodeFlagIsInformative); + _comment = comment; + } + + //! Destroy the `CommentNode` instance. + ASMJIT_INLINE ~CommentNode() {} +}; + +// ============================================================================ +// [asmjit::HintNode] +// ============================================================================ + +//! Hint node. +struct HintNode : public Node { + ASMJIT_NO_COPY(HintNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `HintNode` instance. + ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : Node(compiler, kNodeTypeHint) { + addFlags(kNodeFlagIsInformative); + _vd = vd; + _hint = hint; + _value = value; + } + + //! Destroy the `HintNode` instance. + ASMJIT_INLINE ~HintNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get variable. + ASMJIT_INLINE VarData* getVd() const { return _vd; } + + //! Get hint it (see `kVarHint)`. + ASMJIT_INLINE uint32_t getHint() const{ return _hint; } + //! Set hint it (see `kVarHint)`. + ASMJIT_INLINE void setHint(uint32_t hint) { _hint = hint; } + + //! Get hint value. + ASMJIT_INLINE uint32_t getValue() const { return _value; } + //! Set hint value. + ASMJIT_INLINE void setValue(uint32_t value) { _value = value; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Variable. + VarData* _vd; + //! Hint id. + uint32_t _hint; + //! Value. + uint32_t _value; +}; + +// ============================================================================ +// [asmjit::TargetNode] +// ============================================================================ + +//! label node. +struct TargetNode : public Node { + ASMJIT_NO_COPY(TargetNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `TargetNode` instance. + ASMJIT_INLINE TargetNode(Compiler* compiler, uint32_t labelId) : Node(compiler, kNodeTypeTarget) { + _id = labelId; + _numRefs = 0; + _offset = -1; + _from = NULL; + } + + //! Destroy the `TargetNode` instance. + ASMJIT_INLINE ~TargetNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get target label. + ASMJIT_INLINE Label getLabel() const { return Label(_id); } + //! Get target label id. + ASMJIT_INLINE uint32_t getLabelId() const { return _id; } + + //! Get first jmp instruction. + ASMJIT_INLINE JumpNode* getFrom() const { return _from; } + + //! Get whether the node has assigned state. + ASMJIT_INLINE bool hasState() const { return _state != NULL; } + //! Get state for this target. + ASMJIT_INLINE VarState* getState() const { return _state; } + //! Set state for this target. + ASMJIT_INLINE void setState(VarState* state) { _state = state; } + + //! Get number of jumps to this target. + ASMJIT_INLINE uint32_t getNumRefs() const { return _numRefs; } + //! Set number of jumps to this target. + ASMJIT_INLINE void setNumRefs(uint32_t i) { _numRefs = i; } + + //! Add number of jumps to this target. + ASMJIT_INLINE void addNumRefs(uint32_t i = 1) { _numRefs += i; } + //! Subtract number of jumps to this target. + ASMJIT_INLINE void subNumRefs(uint32_t i = 1) { _numRefs -= i; } + + //! Get the label offset. + //! + //! \note Only valid after the content has been serialized to the `Assembler`. + ASMJIT_INLINE intptr_t getOffset() const { return _offset; } + + //! Set the label offset. + ASMJIT_INLINE void setOffset(intptr_t offset) { _offset = offset; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Label id. + uint32_t _id; + //! Count of jumps here. + uint32_t _numRefs; + + //! Label offset, after serialization. + intptr_t _offset; + //! First jump instruction that points to this target (label). + JumpNode* _from; +}; + +// ============================================================================ +// [asmjit::InstNode] +// ============================================================================ + +//! Instruction node. +struct InstNode : public Node { + ASMJIT_NO_COPY(InstNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `InstNode` instance. + ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : Node(compiler, kNodeTypeInst) { + _code = static_cast(code); + _options = static_cast(options); + + _opCount = static_cast(opCount); + _opList = opList; + + _updateMemOp(); + } + + //! Destroy the `InstNode` instance. + ASMJIT_INLINE ~InstNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get instruction code, see `kX86InstId`. + ASMJIT_INLINE uint32_t getCode() const { + return _code; + } + + //! Set instruction code to `code`. + //! + //! Please do not modify instruction code if you are not know what you are + //! doing. Incorrect instruction code or operands can raise assertion() at + //! runtime. + ASMJIT_INLINE void setCode(uint32_t code) { + _code = static_cast(code); + } + + //! Whether the instruction is an unconditional jump or whether the + //! instruction is a conditional jump which is likely to be taken. + ASMJIT_INLINE bool isTaken() const { + return hasFlag(kNodeFlagIsTaken); + } + + //! Get emit options. + ASMJIT_INLINE uint32_t getOptions() const { + return _options; + } + //! Set emit options. + ASMJIT_INLINE void setOptions(uint32_t options) { + _options = static_cast(options); + } + //! Add emit options. + ASMJIT_INLINE void addOptions(uint32_t options) { + _options |= static_cast(options); + } + //! Mask emit options. + ASMJIT_INLINE void andOptions(uint32_t options) { + _options &= static_cast(options); + } + //! Clear emit options. + ASMJIT_INLINE void delOptions(uint32_t options) { + _options &= static_cast(~options); + } + + //! Get operands list. + ASMJIT_INLINE Operand* getOpList() { + return _opList; + } + //! \overload + ASMJIT_INLINE const Operand* getOpList() const { + return _opList; + } + + //! Get operands count. + ASMJIT_INLINE uint32_t getOpCount() const { + return _opCount; + } + + //! Get whether the instruction contains a memory operand. + ASMJIT_INLINE bool hasMemOp() const { + return _memOpIndex != 0xFF; + } + + //! Set memory operand index (in opList), 0xFF means that instruction + //! doesn't have a memory operand. + ASMJIT_INLINE void setMemOpIndex(uint32_t index) { + _memOpIndex = static_cast(index); + } + //! Reset memory operand index, setting it to 0xFF. + ASMJIT_INLINE void resetMemOpIndex() { + _memOpIndex = 0xFF; + } + + //! Get memory operand. + //! + //! Can only be called if the instruction has such operand, see `hasMemOp()`. + ASMJIT_INLINE BaseMem* getMemOp() const { + ASMJIT_ASSERT(hasMemOp()); + return static_cast(&_opList[_memOpIndex]); + } + + //! \overload + template + ASMJIT_INLINE T* getMemOp() const { + ASMJIT_ASSERT(hasMemOp()); + return static_cast(&_opList[_memOpIndex]); + } + + // -------------------------------------------------------------------------- + // [Utils] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void _updateMemOp() { + Operand* opList = getOpList(); + uint32_t opCount = getOpCount(); + + uint32_t i; + for (i = 0; i < opCount; i++) + if (opList[i].isMem()) + goto _Update; + i = 0xFF; + +_Update: + setMemOpIndex(i); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Instruction code, see `kInstId`. + uint16_t _code; + //! Instruction options, see `kInstOptions`. + uint8_t _options; + //! \internal + uint8_t _memOpIndex; + + //! Operands list. + Operand* _opList; +}; + +// ============================================================================ +// [asmjit::JumpNode] +// ============================================================================ + +//! Jump node. +struct JumpNode : public InstNode { + ASMJIT_NO_COPY(JumpNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE JumpNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : + InstNode(compiler, code, options, opList, opCount) {} + ASMJIT_INLINE ~JumpNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE TargetNode* getTarget() const { return _target; } + ASMJIT_INLINE JumpNode* getJumpNext() const { return _jumpNext; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Target node. + TargetNode* _target; + //! Next jump to the same target in a single linked-list. + JumpNode *_jumpNext; +}; + +// ============================================================================ +// [asmjit::FuncNode] +// ============================================================================ + +//! Function declaration node. +//! +//! Functions are base blocks for generating assembler output. Each generated +//! assembler stream needs standard entry and leave sequences which are compatible +//! with the operating system ABI. +//! +//! `FuncNode` can be used to generate function prolog and epilog which are +//! compatible with a given function calling convention and to allocate and +//! manage variables that can be allocated/spilled during compilation phase. +struct FuncNode : public Node { + ASMJIT_NO_COPY(FuncNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `FuncNode` instance. + //! + //! Always use `Compiler::addFunc()` to create a `FuncNode` instance. + ASMJIT_INLINE FuncNode(Compiler* compiler) : + Node(compiler, kNodeTypeFunc), + _entryNode(NULL), + _exitNode(NULL), + _decl(NULL), + _end(NULL), + _argList(NULL), + _funcHints(IntUtil::mask(kFuncHintNaked)), + _funcFlags(0), + _expectedStackAlignment(0), + _requiredStackAlignment(0), + _redZoneSize(0), + _spillZoneSize(0), + _argStackSize(0), + _memStackSize(0), + _callStackSize(0) {} + + //! Destroy the `FuncNode` instance. + ASMJIT_INLINE ~FuncNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function entry `TargetNode`. + ASMJIT_INLINE TargetNode* getEntryNode() const { return _entryNode; } + //! Get function exit `TargetNode`. + ASMJIT_INLINE TargetNode* getExitNode() const { return _exitNode; } + + //! Get function entry label. + ASMJIT_INLINE Label getEntryLabel() const { return _entryNode->getLabel(); } + //! Get function exit label. + ASMJIT_INLINE Label getExitLabel() const { return _exitNode->getLabel(); } + + //! Get function `EndNode`. + ASMJIT_INLINE EndNode* getEnd() const { return _end; } + //! Get function declaration. + ASMJIT_INLINE FuncDecl* getDecl() const { return _decl; } + + //! Get arguments list. + ASMJIT_INLINE VarData** getArgList() const { return _argList; } + //! Get arguments count. + ASMJIT_INLINE uint32_t getArgCount() const { return _decl->getArgCount(); } + + //! Get argument at `i`. + ASMJIT_INLINE VarData* getArg(uint32_t i) const { + ASMJIT_ASSERT(i < getArgCount()); + return _argList[i]; + } + + //! Set argument at `i`. + ASMJIT_INLINE void setArg(uint32_t i, VarData* vd) { + ASMJIT_ASSERT(i < getArgCount()); + _argList[i] = vd; + } + + //! Reset argument at `i`. + ASMJIT_INLINE void resetArg(uint32_t i) { + ASMJIT_ASSERT(i < getArgCount()); + _argList[i] = NULL; + } + + //! Get function hints. + ASMJIT_INLINE uint32_t getFuncHints() const { return _funcHints; } + //! Get function flags. + ASMJIT_INLINE uint32_t getFuncFlags() const { return _funcFlags; } + + //! Get whether the _funcFlags has `flag` + ASMJIT_INLINE bool hasFuncFlag(uint32_t flag) const { return (_funcFlags & flag) != 0; } + //! Set function `flag`. + ASMJIT_INLINE void addFuncFlags(uint32_t flags) { _funcFlags |= flags; } + //! Clear function `flag`. + ASMJIT_INLINE void clearFuncFlags(uint32_t flags) { _funcFlags &= ~flags; } + + //! Get whether the function is naked. + ASMJIT_INLINE bool isNaked() const { return hasFuncFlag(kFuncFlagIsNaked); } + //! Get whether the function is also a caller. + ASMJIT_INLINE bool isCaller() const { return hasFuncFlag(kFuncFlagIsCaller); } + //! Get whether the required stack alignment is lower than expected one, + //! thus it has to be aligned manually. + ASMJIT_INLINE bool isStackMisaligned() const { return hasFuncFlag(kFuncFlagIsStackMisaligned); } + //! Get whether the stack pointer is adjusted inside function prolog/epilog. + ASMJIT_INLINE bool isStackAdjusted() const { return hasFuncFlag(kFuncFlagIsStackAdjusted); } + + //! Get whether the function is finished. + ASMJIT_INLINE bool isFinished() const { return hasFuncFlag(kFuncFlagIsFinished); } + + //! Get expected stack alignment. + ASMJIT_INLINE uint32_t getExpectedStackAlignment() const { return _expectedStackAlignment; } + //! Set expected stack alignment. + ASMJIT_INLINE void setExpectedStackAlignment(uint32_t alignment) { _expectedStackAlignment = alignment; } + + //! Get required stack alignment. + ASMJIT_INLINE uint32_t getRequiredStackAlignment() const { return _requiredStackAlignment; } + //! Set required stack alignment. + ASMJIT_INLINE void setRequiredStackAlignment(uint32_t alignment) { _requiredStackAlignment = alignment; } + + //! Update required stack alignment so it's not lower than expected + //! stack alignment. + ASMJIT_INLINE void updateRequiredStackAlignment() { + if (_requiredStackAlignment <= _expectedStackAlignment) { + _requiredStackAlignment = _expectedStackAlignment; + clearFuncFlags(kFuncFlagIsStackMisaligned); + } + else { + addFuncFlags(kFuncFlagIsStackMisaligned); + } + } + + //! Set stack "Red Zone" size. + ASMJIT_INLINE uint32_t getRedZoneSize() const { return _redZoneSize; } + //! Get stack "Red Zone" size. + ASMJIT_INLINE void setRedZoneSize(uint32_t s) { _redZoneSize = static_cast(s); } + + //! Set stack "Spill Zone" size. + ASMJIT_INLINE uint32_t getSpillZoneSize() const { return _spillZoneSize; } + //! Get stack "Spill Zone" size. + ASMJIT_INLINE void setSpillZoneSize(uint32_t s) { _spillZoneSize = static_cast(s); } + + //! Get stack size used by function arguments. + ASMJIT_INLINE uint32_t getArgStackSize() const { return _argStackSize; } + + //! Get stack size used by variables and memory allocated on the stack. + ASMJIT_INLINE uint32_t getMemStackSize() const { return _memStackSize; } + + //! Get stack size used by function calls. + ASMJIT_INLINE uint32_t getCallStackSize() const { return _callStackSize; } + //! Merge stack size used by function call with `s`. + ASMJIT_INLINE void mergeCallStackSize(uint32_t s) { if (_callStackSize < s) _callStackSize = s; } + + // -------------------------------------------------------------------------- + // [Hints] + // -------------------------------------------------------------------------- + + //! Set function hint. + ASMJIT_INLINE void setHint(uint32_t hint, uint32_t value) { + ASMJIT_ASSERT(hint <= 31); + ASMJIT_ASSERT(value <= 1); + + _funcHints &= ~(1 << hint); + _funcHints |= (value << hint); + } + + //! Get function hint. + ASMJIT_INLINE uint32_t getHint(uint32_t hint) const { + ASMJIT_ASSERT(hint <= 31); + return (_funcHints >> hint) & 0x1; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Function entry. + TargetNode* _entryNode; + //! Function exit. + TargetNode* _exitNode; + + //! Function declaration. + FuncDecl* _decl; + //! Function end. + EndNode* _end; + + //! Arguments list as `VarData`. + VarData** _argList; + + //! Function hints; + uint32_t _funcHints; + //! Function flags. + uint32_t _funcFlags; + + //! Expected stack alignment (we depend on this value). + //! + //! \note It can be global alignment given by the OS or described by an + //! target platform ABI. + uint32_t _expectedStackAlignment; + //! Required stack alignment (usually for multimedia instructions). + uint32_t _requiredStackAlignment; + + //! The "Red Zone" size - count of bytes which might be accessed without + //! adjusting the stack pointer. + uint16_t _redZoneSize; + //! Spill zone size (zone used by WIN64ABI). + uint16_t _spillZoneSize; + + //! Stack size needed for function arguments. + uint32_t _argStackSize; + //! Stack size needed for all variables and memory allocated on the stack. + uint32_t _memStackSize; + //! Stack size needed to call other functions. + uint32_t _callStackSize; +}; + +// ============================================================================ +// [asmjit::EndNode] +// ============================================================================ + +//! End of function/block node. +struct EndNode : public Node { + ASMJIT_NO_COPY(EndNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `EndNode` instance. + ASMJIT_INLINE EndNode(Compiler* compiler) : Node(compiler, kNodeTypeEnd) { + _flags |= kNodeFlagIsRet; + } + + //! Destroy the `EndNode` instance. + ASMJIT_INLINE ~EndNode() {} +}; + +// ============================================================================ +// [asmjit::RetNode] +// ============================================================================ + +//! Function return node. +struct RetNode : public Node { + ASMJIT_NO_COPY(RetNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `RetNode` instance. + ASMJIT_INLINE RetNode(Compiler* compiler, const Operand& o0, const Operand& o1) : Node(compiler, kNodeTypeRet) { + _flags |= kNodeFlagIsRet; + _ret[0] = o0; + _ret[1] = o1; + } + + //! Destroy the `RetNode` instance. + ASMJIT_INLINE ~RetNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the first return operand. + ASMJIT_INLINE Operand& getFirst() { return _ret[0]; } + //! \overload + ASMJIT_INLINE const Operand& getFirst() const { return _ret[0]; } + + //! Get the second return operand. + ASMJIT_INLINE Operand& getSecond() { return _ret[1]; } + //! \overload + ASMJIT_INLINE const Operand& getSecond() const { return _ret[1]; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Ret operand(s). + Operand _ret[2]; +}; + +// ============================================================================ +// [asmjit::CallNode] +// ============================================================================ + +//! Function-call node. +struct CallNode : public Node { + ASMJIT_NO_COPY(CallNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `CallNode` instance. + ASMJIT_INLINE CallNode(Compiler* compiler, const Operand& target) : + Node(compiler, kNodeTypeCall), + _decl(NULL), + _target(target), + _args(NULL) {} + + //! Destroy the `CallNode` instance. + ASMJIT_INLINE ~CallNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function declaration. + ASMJIT_INLINE FuncDecl* getDecl() const { return _decl; } + + //! Get target operand. + ASMJIT_INLINE Operand& getTarget() { return _target; } + //! \overload + ASMJIT_INLINE const Operand& getTarget() const { return _target; } + + //! Get return at `i`. + ASMJIT_INLINE Operand& getRet(uint32_t i = 0) { + ASMJIT_ASSERT(i < 2); + return _ret[i]; + } + //! \overload + ASMJIT_INLINE const Operand& getRet(uint32_t i = 0) const { + ASMJIT_ASSERT(i < 2); + return _ret[i]; + } + + //! Get argument at `i`. + ASMJIT_INLINE Operand& getArg(uint32_t i) { + ASMJIT_ASSERT(i < kFuncArgCountLoHi); + return _args[i]; + } + //! \overload + ASMJIT_INLINE const Operand& getArg(uint32_t i) const { + ASMJIT_ASSERT(i < kFuncArgCountLoHi); + return _args[i]; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Function declaration. + FuncDecl* _decl; + + //! Target (address of function, register, label, ...). + Operand _target; + //! Return. + Operand _ret[2]; + //! Arguments. + Operand* _args; +}; + +// ============================================================================ +// [asmjit::SArgNode] +// ============================================================================ + +//! Function-call 'argument on the stack' node. +struct SArgNode : public Node { + ASMJIT_NO_COPY(SArgNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `SArgNode` instance. + ASMJIT_INLINE SArgNode(Compiler* compiler, CallNode* call, VarData* sVd, VarData* cVd) : + Node(compiler, kNodeTypeSArg), + _call(call), + _sVd(sVd), + _cVd(cVd), + _args(0) {} + + //! Destroy the `SArgNode` instance. + ASMJIT_INLINE ~SArgNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the associated function-call. + ASMJIT_INLINE CallNode* getCall() const { return _call; } + //! Get source variable. + ASMJIT_INLINE VarData* getSVd() const { return _sVd; } + //! Get conversion variable. + ASMJIT_INLINE VarData* getCVd() const { return _cVd; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Associated `CallNode`. + CallNode* _call; + //! Source variable. + VarData* _sVd; + //! Temporary variable used for conversion (or NULL). + VarData* _cVd; + + //! Affected arguments bit-array. + uint32_t _args; +}; + +//! \} + +// ============================================================================ +// [asmjit::Compiler] +// ============================================================================ + +//! \addtogroup asmjit_base_general +//! \{ + +//! Base compiler. +//! +//! \sa Assembler. +struct ASMJIT_VCLASS Compiler : public CodeGen { + ASMJIT_NO_COPY(Compiler) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `Compiler` instance. + ASMJIT_API Compiler(Runtime* runtime); + //! Destroy the `Compiler` instance. + ASMJIT_API virtual ~Compiler(); + + // -------------------------------------------------------------------------- + // [LookAhead] + // -------------------------------------------------------------------------- + + //! Get maximum look ahead. + ASMJIT_INLINE uint32_t getMaxLookAhead() const { + return _maxLookAhead; + } + + //! Set maximum look ahead to `val`. + ASMJIT_INLINE void setMaxLookAhead(uint32_t val) { + _maxLookAhead = val; + } + + // -------------------------------------------------------------------------- + // [Clear / Reset] + // -------------------------------------------------------------------------- + + //! Reset the compiler. + //! + //! If `releaseMemory` is true all buffers will be released to the system. + ASMJIT_API void reset(bool releaseMemory = false); + + // -------------------------------------------------------------------------- + // [Nodes] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE T* newNode() { + void* p = _baseZone.alloc(sizeof(T)); + return new(p) T(this); + } + + template + ASMJIT_INLINE T* newNode(P0 p0) { + void* p = _baseZone.alloc(sizeof(T)); + return new(p) T(this, p0); + } + + template + ASMJIT_INLINE T* newNode(P0 p0, P1 p1) { + void* p = _baseZone.alloc(sizeof(T)); + return new(p) T(this, p0, p1); + } + + template + ASMJIT_INLINE T* newNode(P0 p0, P1 p1, P2 p2) { + void* p = _baseZone.alloc(sizeof(T)); + return new(p) T(this, p0, p1, p2); + } + + //! Get first node. + ASMJIT_INLINE Node* getFirstNode() const { return _firstNode; } + //! Get last node. + ASMJIT_INLINE Node* getLastNode() const { return _lastNode; } + + //! Get current node. + //! + //! \note If this method returns `NULL` it means that nothing has been emitted + //! yet. + ASMJIT_INLINE Node* getCursor() const { return _cursor; } + //! Set the current node without returning the previous node (private). + ASMJIT_INLINE void _setCursor(Node* node) { _cursor = node; } + //! Set the current node to `node` and return the previous one. + ASMJIT_API Node* setCursor(Node* node); + + //! Add node `node` after current and set current to `node`. + ASMJIT_API Node* addNode(Node* node); + //! Add node before `ref`. + ASMJIT_API Node* addNodeBefore(Node* node, Node* ref); + //! Add node after `ref`. + ASMJIT_API Node* addNodeAfter(Node* node, Node* ref); + //! Remove node `node`. + ASMJIT_API Node* removeNode(Node* node); + //! Remove multiple nodes. + ASMJIT_API void removeNodes(Node* first, Node* last); + + // -------------------------------------------------------------------------- + // [Func] + // -------------------------------------------------------------------------- + + //! Get current function. + ASMJIT_INLINE FuncNode* getFunc() const { return _func; } + + // -------------------------------------------------------------------------- + // [Align] + // -------------------------------------------------------------------------- + + //! Create a new `AlignNode`. + ASMJIT_API AlignNode* newAlign(uint32_t mode, uint32_t offset); + //! Add a new `AlignNode`. + ASMJIT_API AlignNode* addAlign(uint32_t mode, uint32_t offset); + + //! Align target buffer to `m` bytes. + //! + //! Typical usage of this is to align labels at start of the inner loops. + //! + //! Inserts `nop()` instructions or CPU optimized NOPs. + ASMJIT_INLINE AlignNode* align(uint32_t mode, uint32_t offset) { + return addAlign(mode, offset); + } + + // -------------------------------------------------------------------------- + // [Target] + // -------------------------------------------------------------------------- + + //! Create a new `TargetNode`. + ASMJIT_API TargetNode* newTarget(); + //! Add a new `TargetNode`. + ASMJIT_API TargetNode* addTarget(); + + //! Get `TargetNode` by `id`. + ASMJIT_INLINE TargetNode* getTargetById(uint32_t id) { + ASMJIT_ASSERT(OperandUtil::isLabelId(id)); + ASMJIT_ASSERT(id < _targetList.getLength()); + + return _targetList[id]; + } + + //! Get `TargetNode` by `label`. + ASMJIT_INLINE TargetNode* getTarget(const Label& label) { + return getTargetById(label.getId()); + } + + // -------------------------------------------------------------------------- + // [Label] + // -------------------------------------------------------------------------- + + //! Get count of created labels. + ASMJIT_INLINE size_t getLabelsCount() const { + return _targetList.getLength(); + } + + //! Get whether `label` is created. + ASMJIT_INLINE bool isLabelValid(const Label& label) const { + return isLabelValid(label.getId()); + } + + //! \overload + ASMJIT_INLINE bool isLabelValid(uint32_t id) const { + return static_cast(id) < _targetList.getLength(); + } + + //! Get `TargetNode` by `label`. + ASMJIT_INLINE TargetNode* getTargetByLabel(const Label& label) { + return getTargetByLabel(label.getId()); + } + + //! \overload + ASMJIT_INLINE TargetNode* getTargetByLabel(uint32_t id) { + ASMJIT_ASSERT(isLabelValid(id)); + return _targetList[id]; + } + + //! Get `label` offset or -1 if the label is not bound. + //! + //! This method can be only called after the code has been serialized to the + //! `Assembler`, otherwise the offset returned will be -1 (even if the label + //! has been bound). + ASMJIT_INLINE intptr_t getLabelOffset(const Label& label) const { + return getLabelOffset(label.getId()); + } + + //! \overload + ASMJIT_INLINE intptr_t getLabelOffset(uint32_t id) const { + ASMJIT_ASSERT(isLabelValid(id)); + return _targetList[id]->getOffset(); + } + + //! \internal + //! + //! Create and initialize a new `Label`. + ASMJIT_API Error _newLabel(Label* dst); + + //! Create and return a new `Label`. + ASMJIT_INLINE Label newLabel() { + Label result(NoInit); + _newLabel(&result); + return result; + } + + //! Bind label to the current offset. + //! + //! \note Label can be bound only once! + ASMJIT_API Error bind(const Label& label); + + // -------------------------------------------------------------------------- + // [Embed] + // -------------------------------------------------------------------------- + + //! Create a new `EmbedNode`. + ASMJIT_API EmbedNode* newEmbed(const void* data, uint32_t size); + //! Add a new `EmbedNode`. + ASMJIT_API EmbedNode* addEmbed(const void* data, uint32_t size); + + //! Embed data. + ASMJIT_INLINE EmbedNode* embed(const void* data, uint32_t size) { + return addEmbed(data, size); + } + + // -------------------------------------------------------------------------- + // [Comment] + // -------------------------------------------------------------------------- + + //! Create a new `CommentNode`. + ASMJIT_API CommentNode* newComment(const char* str); + //! Add a new `CommentNode`. + ASMJIT_API CommentNode* addComment(const char* str); + + //! Emit a single comment line. + ASMJIT_API CommentNode* comment(const char* fmt, ...); + + // -------------------------------------------------------------------------- + // [Hint] + // -------------------------------------------------------------------------- + + //! Create a new `HintNode`. + ASMJIT_API HintNode* newHint(Var& var, uint32_t hint, uint32_t value); + //! Add a new `HintNode`. + ASMJIT_API HintNode* addHint(Var& var, uint32_t hint, uint32_t value); + + // -------------------------------------------------------------------------- + // [Vars] + // -------------------------------------------------------------------------- + + //! Get whether variable `var` is created. + ASMJIT_INLINE bool isVarValid(const Var& var) const { + return static_cast(var.getId() & kOperandIdNum) < _varList.getLength(); + } + + //! \internal + //! + //! Get `VarData` by `var`. + ASMJIT_INLINE VarData* getVd(const Var& var) const { + return getVdById(var.getId()); + } + + //! \internal + //! + //! Get `VarData` by `id`. + ASMJIT_INLINE VarData* getVdById(uint32_t id) const { + ASMJIT_ASSERT(id != kInvalidValue); + ASMJIT_ASSERT(static_cast(id & kOperandIdNum) < _varList.getLength()); + + return _varList[id & kOperandIdNum]; + } + + //! \internal + //! + //! Get an array of 'VarData*'. + ASMJIT_INLINE VarData** _getVdArray() const { + return const_cast(_varList.getData()); + } + + //! \internal + //! + //! Create a new `VarData`. + ASMJIT_API VarData* _newVd(uint32_t type, uint32_t size, uint32_t c, const char* name); + + //! Create a new `Var`. + virtual Error _newVar(Var* var, uint32_t type, const char* name) = 0; + + //! Alloc variable `var`. + ASMJIT_API void alloc(Var& var); + //! Alloc variable `var` using `regIndex` as a register index. + ASMJIT_API void alloc(Var& var, uint32_t regIndex); + //! Alloc variable `var` using `reg` as a demanded register. + ASMJIT_API void alloc(Var& var, const Reg& reg); + //! Spill variable `var`. + ASMJIT_API void spill(Var& var); + //! Save variable `var` if modified. + ASMJIT_API void save(Var& var); + //! Unuse variable `var`. + ASMJIT_API void unuse(Var& var); + + //! Get priority of variable `var`. + ASMJIT_API uint32_t getPriority(Var& var) const; + //! Set priority of variable `var` to `priority`. + ASMJIT_API void setPriority(Var& var, uint32_t priority); + + //! Get save-on-unuse `var` property. + ASMJIT_API bool getSaveOnUnuse(Var& var) const; + //! Set save-on-unuse `var` property to `value`. + ASMJIT_API void setSaveOnUnuse(Var& var, bool value); + + //! Rename variable `var` to `name`. + //! + //! \note Only new name will appear in the logger. + ASMJIT_API void rename(Var& var, const char* name); + + // -------------------------------------------------------------------------- + // [Stack] + // -------------------------------------------------------------------------- + + //! \internal + //! + //! Create a new memory chunk allocated on the current function's stack. + virtual Error _newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) = 0; + + // -------------------------------------------------------------------------- + // [Const] + // -------------------------------------------------------------------------- + + //! \internal + //! + //! Put data to a constant-pool and get a memory reference to it. + virtual Error _newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) = 0; + + // -------------------------------------------------------------------------- + // [Assembler] + // -------------------------------------------------------------------------- + + //! Get an assembler instance that is associated with the compiler. + //! + //! \note One instance of `Assembler` is shared and has lifetime same as the + //! compiler, however, each call to `getAssembler()` resets the assembler so + //! new code can be serialized into it. + ASMJIT_API Assembler* getAssembler(); + + //! \internal + //! + //! Create a new `Assembler` instance associated with the compiler. + virtual Assembler* _newAssembler() = 0; + + // -------------------------------------------------------------------------- + // [Serialize] + // -------------------------------------------------------------------------- + + //! Serialize a compiled code to `assembler`. + virtual Error serialize(Assembler* assembler) = 0; + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Internal assembler. + Assembler* _assembler; + + //! Flow id added to each node created (used only by `Context)`. + uint32_t _nodeFlowId; + //! Flags added to each node created (used only by `Context)`. + uint32_t _nodeFlags; + + //! Maximum count of nodes to look ahead when allocating/spilling + //! registers. + uint32_t _maxLookAhead; + + //! Variable mapping (translates incoming kVarType into target). + const uint8_t* _targetVarMapping; + + //! First node. + Node* _firstNode; + //! Last node. + Node* _lastNode; + + //! Current node. + Node* _cursor; + //! Current function. + FuncNode* _func; + + //! Variable zone. + Zone _varZone; + //! String/data zone. + Zone _stringZone; + //! Local constant pool zone. + Zone _localConstZone; + + //! TargetNode list. + PodVector _targetList; + //! VarData list. + PodVector _varList; + + //! Local constant pool, flushed at the end of each function. + ConstPool _localConstPool; + //! Global constant pool, flushed at the end of the compilation. + ConstPool _globalConstPool; + + //! Label to start of the local constant pool. + Label _localConstPoolLabel; + //! Label to start of the global constant pool. + Label _globalConstPoolLabel; +}; + +//! \} + +// ============================================================================ +// [Defined-Later] +// ============================================================================ + +ASMJIT_INLINE Label::Label(Compiler& c) : Operand(NoInit) { + c._newLabel(this); +} + +ASMJIT_INLINE Node::Node(Compiler* compiler, uint32_t type) { + _prev = NULL; + _next = NULL; + _type = static_cast(type); + _opCount = 0; + _flags = static_cast(compiler->_nodeFlags); + _flowId = compiler->_nodeFlowId; + _comment = NULL; + _map = NULL; + _liveness = NULL; + _state = NULL; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_BASE_COMPILER_H diff --git a/libraries/asmjit/base/constpool.cpp b/libraries/asmjit/base/constpool.cpp new file mode 100644 index 000000000..d85ea3138 --- /dev/null +++ b/libraries/asmjit/base/constpool.cpp @@ -0,0 +1,537 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/constpool.h" +#include "../base/intutil.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// Binary tree code is based on Julienne Walker's "Andersson Binary Trees" +// article and implementation. However, only three operations are implemented - +// get, insert and traverse. + +// ============================================================================ +// [asmjit::ConstPoolTree - Ops] +// ============================================================================ + +//! \internal +//! +//! Remove left horizontal links. +static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_skewNode(ConstPoolNode* node) { + ConstPoolNode* link = node->_link[0]; + uint32_t level = node->_level; + + if (level != 0 && link != NULL && link->_level == level) { + node->_link[0] = link->_link[1]; + link->_link[1] = node; + + node = link; + } + + return node; +} + +//! \internal +//! +//! Remove consecutive horizontal links. +static ASMJIT_INLINE ConstPoolNode* ConstPoolTree_splitNode(ConstPoolNode* node) { + ConstPoolNode* link = node->_link[1]; + uint32_t level = node->_level; + + if (level != 0 && link != NULL && link->_link[1] != NULL && link->_link[1]->_level == level) { + node->_link[1] = link->_link[0]; + link->_link[0] = node; + + node = link; + node->_level++; + } + + return node; +} + +ConstPoolNode* ConstPoolTree::get(const void* data) { + ConstPoolNode* node = _root; + size_t dataSize = _dataSize; + + while (node != NULL) { + int c = ::memcmp(node->getData(), data, dataSize); + if (c == 0) + return node; + node = node->_link[c < 0]; + } + + return NULL; +} + +void ConstPoolTree::put(ConstPoolNode* newNode) { + size_t dataSize = _dataSize; + + _length++; + if (_root == NULL) { + _root = newNode; + return; + } + + ConstPoolNode* node = _root; + ConstPoolNode* stack[kHeightLimit]; + + unsigned int top = 0; + unsigned int dir; + + // Find a spot and save the stack. + for (;;) { + stack[top++] = node; + dir = ::memcmp(node->getData(), newNode->getData(), dataSize) < 0; + + ConstPoolNode* link = node->_link[dir]; + if (link == NULL) + break; + + node = link; + } + + // Link and rebalance. + node->_link[dir] = newNode; + + while (top > 0) { + // Which child? + node = stack[--top]; + + if (top != 0) { + dir = stack[top - 1]->_link[1] == node; + } + + node = ConstPoolTree_skewNode(node); + node = ConstPoolTree_splitNode(node); + + // Fix the parent. + if (top != 0) + stack[top - 1]->_link[dir] = node; + else + _root = node; + } +} + +// ============================================================================ +// [asmjit::ConstPool - Construction / Destruction] +// ============================================================================ + +ConstPool::ConstPool(Zone* zone) { + _zone = zone; + + size_t dataSize = 1; + for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) { + _tree[i].setDataSize(dataSize); + _gaps[i] = NULL; + dataSize <<= 1; + } + + _gapPool = NULL; + _size = 0; + _alignment = 0; +} + +ConstPool::~ConstPool() {} + +// ============================================================================ +// [asmjit::ConstPool - Reset] +// ============================================================================ + +void ConstPool::reset() { + for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) { + _tree[i].reset(); + _gaps[i] = NULL; + } + + _gapPool = NULL; + _size = 0; + _alignment = 0; +} + +// ============================================================================ +// [asmjit::ConstPool - Ops] +// ============================================================================ + +static ASMJIT_INLINE size_t ConstPool_getGapIndex(size_t size) { + if (size <= 1) + return ConstPool::kIndex1; + else if (size <= 3) + return ConstPool::kIndex2; + else if (size <= 7) + return ConstPool::kIndex4; + else if (size <= 15) + return ConstPool::kIndex8; + else + return ConstPool::kIndex16; +} + +static ASMJIT_INLINE ConstPoolGap* ConstPool_allocGap(ConstPool* self) { + ConstPoolGap* gap = self->_gapPool; + if (gap == NULL) + return self->_zone->allocT(); + + self->_gapPool = gap->_next; + return gap; +} + +static ASMJIT_INLINE void ConstPool_freeGap(ConstPool* self, ConstPoolGap* gap) { + gap->_next = self->_gapPool; + self->_gapPool = gap; +} + +static void ConstPool_addGap(ConstPool* self, size_t offset, size_t length) { + ASMJIT_ASSERT(length > 0); + + while (length > 0) { + size_t gapIndex; + size_t gapLength; + + if (length >= 16 && IntUtil::isAligned(offset, 16)) { + gapIndex = ConstPool::kIndex16; + gapLength = 16; + } + else if (length >= 8 && IntUtil::isAligned(offset, 8)) { + gapIndex = ConstPool::kIndex8; + gapLength = 8; + } + else if (length >= 4 && IntUtil::isAligned(offset, 4)) { + gapIndex = ConstPool::kIndex4; + gapLength = 4; + } + else if (length >= 2 && IntUtil::isAligned(offset, 2)) { + gapIndex = ConstPool::kIndex2; + gapLength = 2; + } + else { + gapIndex = ConstPool::kIndex1; + gapLength = 1; + } + + // We don't have to check for errors here, if this failed nothing really + // happened (just the gap won't be visible) and it will fail again at + // place where checking will cause kErrorNoHeapMemory. + ConstPoolGap* gap = ConstPool_allocGap(self); + if (gap == NULL) + return; + + gap->_next = self->_gaps[gapIndex]; + self->_gaps[gapIndex] = gap; + + gap->_offset = offset; + gap->_length = gapLength; + + offset += gapLength; + length -= gapLength; + } +} + +Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) { + size_t treeIndex; + + if (size == 32) + treeIndex = kIndex32; + else if (size == 16) + treeIndex = kIndex16; + else if (size == 8) + treeIndex = kIndex8; + else if (size == 4) + treeIndex = kIndex4; + else if (size == 2) + treeIndex = kIndex2; + else if (size == 1) + treeIndex = kIndex1; + else + return kErrorInvalidArgument; + + ConstPoolNode* node = _tree[treeIndex].get(data); + if (node != NULL) { + dstOffset = node->_offset; + return kErrorOk; + } + + // Before incrementing the current offset try if there is a gap that can + // be used for the requested data. + size_t offset = ~static_cast(0); + size_t gapIndex = treeIndex; + + while (gapIndex != kIndexCount - 1) { + ConstPoolGap* gap = _gaps[treeIndex]; + + // Check if there is a gap. + if (gap != NULL) { + size_t gapOffset = gap->_offset; + size_t gapLength = gap->_length; + + // Destroy the gap for now. + _gaps[treeIndex] = gap->_next; + ConstPool_freeGap(this, gap); + + offset = gapOffset; + ASMJIT_ASSERT(IntUtil::isAligned(offset, size)); + + gapLength -= size; + if (gapLength > 0) + ConstPool_addGap(this, gapOffset, gapLength); + } + + gapIndex++; + } + + if (offset == ~static_cast(0)) { + // Get how many bytes have to be skipped so the address is aligned accordingly + // to the 'size'. + size_t deltaTo = IntUtil::deltaTo(_size, size); + + if (deltaTo != 0) { + ConstPool_addGap(this, _size, deltaTo); + _size += deltaTo; + } + + offset = _size; + _size += size; + } + + // Add the initial node to the right index. + node = ConstPoolTree::_newNode(_zone, data, size, offset, false); + if (node == NULL) + return kErrorNoHeapMemory; + + _tree[treeIndex].put(node); + _alignment = IntUtil::iMax(_alignment, size); + + dstOffset = offset; + + // Now create a bunch of shared constants that are based on the data pattern. + // We stop at size 4, it probably doesn't make sense to split constants down + // to 1 byte. + size_t pCount = 1; + while (size > 4) { + size >>= 1; + pCount <<= 1; + + ASMJIT_ASSERT(treeIndex != 0); + treeIndex--; + + const uint8_t* pData = static_cast(data); + for (size_t i = 0; i < pCount; i++, pData += size) { + node = _tree[treeIndex].get(pData); + + if (node != NULL) + continue; + + node = ConstPoolTree::_newNode(_zone, pData, size, offset + (i * size), true); + _tree[treeIndex].put(node); + } + } + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::ConstPool - Reset] +// ============================================================================ + +struct ConstPoolFill { + ASMJIT_INLINE ConstPoolFill(uint8_t* dst, size_t dataSize) : + _dst(dst), + _dataSize(dataSize) {} + + ASMJIT_INLINE void visit(const ConstPoolNode* node) { + if (!node->_shared) + ::memcpy(_dst + node->_offset, node->getData(), _dataSize); + } + + uint8_t* _dst; + size_t _dataSize; +}; + +void ConstPool::fill(void* dst) { + // Clears possible gaps, asmjit should never emit garbage to the output. + ::memset(dst, 0, _size); + + ConstPoolFill filler(static_cast(dst), 1); + for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) { + _tree[i].iterate(filler); + filler._dataSize <<= 1; + } +} + +// ============================================================================ +// [asmjit::ConstPool - Test] +// ============================================================================ + +#if defined(ASMJIT_TEST) +UNIT(base_constpool) { + Zone zone(32384 - kZoneOverhead); + ConstPool pool(&zone); + + uint32_t i; + uint32_t kCount = 1000000; + + INFO("Adding %u constants to the pool.", kCount); + { + size_t prevOffset; + size_t curOffset; + uint64_t c = ASMJIT_UINT64_C(0x0101010101010101); + + EXPECT(pool.add(&c, 8, prevOffset) == kErrorOk, + "pool.add() - Returned error."); + EXPECT(prevOffset == 0, + "pool.add() - First constant should have zero offset."); + + for (i = 1; i < kCount; i++) { + c++; + EXPECT(pool.add(&c, 8, curOffset) == kErrorOk, + "pool.add() - Returned error."); + EXPECT(prevOffset + 8 == curOffset, + "pool.add() - Returned incorrect curOffset."); + EXPECT(pool.getSize() == (i + 1) * 8, + "pool.getSize() - Reports incorrect size."); + prevOffset = curOffset; + } + + EXPECT(pool.getAlignment() == 8, + "pool.getAlignment() - Expected 8-byte alignment."); + } + + INFO("Retrieving %u constants from the pool.", kCount); + { + uint64_t c = ASMJIT_UINT64_C(0x0101010101010101); + + for (i = 0; i < kCount; i++) { + size_t offset; + EXPECT(pool.add(&c, 8, offset) == kErrorOk, + "pool.add() - Returned error."); + EXPECT(offset == i * 8, + "pool.add() - Should have reused constant."); + c++; + } + } + + INFO("Checking if the constants were split into 4-byte patterns."); + { + uint32_t c = 0x01010101; + for (i = 0; i < kCount; i++) { + size_t offset; + EXPECT(pool.add(&c, 4, offset) == kErrorOk, + "pool.add() - Returned error."); + EXPECT(offset == i * 8, + "pool.add() - Should reuse existing constant."); + c++; + } + } + + INFO("Adding 2 byte constant to misalign the current offset."); + { + uint16_t c = 0xFFFF; + size_t offset; + + EXPECT(pool.add(&c, 2, offset) == kErrorOk, + "pool.add() - Returned error."); + EXPECT(offset == kCount * 8, + "pool.add() - Didn't return expected position."); + EXPECT(pool.getAlignment() == 8, + "pool.getAlignment() - Expected 8-byte alignment."); + } + + INFO("Adding 8 byte constant to check if pool gets aligned again."); + { + uint64_t c = ASMJIT_UINT64_C(0xFFFFFFFFFFFFFFFF); + size_t offset; + + EXPECT(pool.add(&c, 8, offset) == kErrorOk, + "pool.add() - Returned error."); + EXPECT(offset == kCount * 8 + 8, + "pool.add() - Didn't return aligned offset."); + } + + INFO("Adding 2 byte constant to verify the gap is filled."); + { + uint16_t c = 0xFFFE; + size_t offset; + + EXPECT(pool.add(&c, 2, offset) == kErrorOk, + "pool.add() - Returned error."); + EXPECT(offset == kCount * 8 + 2, + "pool.add() - Didn't fill the gap."); + EXPECT(pool.getAlignment() == 8, + "pool.getAlignment() - Expected 8-byte alignment."); + } + + INFO("Checking reset functionality."); + { + pool.reset(); + + EXPECT(pool.getSize() == 0, + "pool.getSize() - Expected pool size to be zero."); + EXPECT(pool.getAlignment() == 0, + "pool.getSize() - Expected pool alignment to be zero."); + } + + INFO("Checking pool alignment when combined constants are added."); + { + uint8_t bytes[32] = { 0 }; + uint64_t c = 0; + size_t offset; + + pool.add(bytes, 1, offset); + + EXPECT(pool.getSize() == 1, + "pool.getSize() - Expected pool size to be 1 byte."); + EXPECT(pool.getAlignment() == 1, + "pool.getSize() - Expected pool alignment to be 1 byte."); + EXPECT(offset == 0, + "pool.getSize() - Expected offset returned to be zero."); + + pool.add(bytes, 2, offset); + + EXPECT(pool.getSize() == 4, + "pool.getSize() - Expected pool size to be 4 bytes."); + EXPECT(pool.getAlignment() == 2, + "pool.getSize() - Expected pool alignment to be 2 bytes."); + EXPECT(offset == 2, + "pool.getSize() - Expected offset returned to be 2."); + + pool.add(bytes, 4, offset); + + EXPECT(pool.getSize() == 8, + "pool.getSize() - Expected pool size to be 8 bytes."); + EXPECT(pool.getAlignment() == 4, + "pool.getSize() - Expected pool alignment to be 4 bytes."); + EXPECT(offset == 4, + "pool.getSize() - Expected offset returned to be 4."); + + pool.add(bytes, 4, offset); + + EXPECT(pool.getSize() == 8, + "pool.getSize() - Expected pool size to be 8 bytes."); + EXPECT(pool.getAlignment() == 4, + "pool.getSize() - Expected pool alignment to be 4 bytes."); + EXPECT(offset == 4, + "pool.getSize() - Expected offset returned to be 8."); + + pool.add(bytes, 32, offset); + EXPECT(pool.getSize() == 64, + "pool.getSize() - Expected pool size to be 64 bytes."); + EXPECT(pool.getAlignment() == 32, + "pool.getSize() - Expected pool alignment to be 32 bytes."); + EXPECT(offset == 32, + "pool.getSize() - Expected offset returned to be 32."); + } +} +#endif // ASMJIT_TEST + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/constpool.h b/libraries/asmjit/base/constpool.h new file mode 100644 index 000000000..c2c77c427 --- /dev/null +++ b/libraries/asmjit/base/constpool.h @@ -0,0 +1,299 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_CONSTPOOL_H +#define _ASMJIT_BASE_CONSTPOOL_H + +// [Dependencies - AsmJit] +#include "../base/error.h" +#include "../base/zone.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::ConstPoolNode] +// ============================================================================ + +//! \internal +//! +//! Zone-allocated constant-pool node. +struct ConstPoolNode { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void* getData() const { + return static_cast(const_cast(this) + 1); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Left/Right nodes. + ConstPoolNode* _link[2]; + //! Horizontal level for balance. + uint32_t _level : 31; + //! Whether this constant is shared with another. + uint32_t _shared : 1; + //! Data offset from the beginning of the pool. + uint32_t _offset; +}; + +// ============================================================================ +// [asmjit::ConstPoolTree] +// ============================================================================ + +//! \internal +//! +//! Zone-allocated constant-pool tree. +struct ConstPoolTree { + enum { + //! Maximum tree height == log2(1 << 64). + kHeightLimit = 64 + }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE ConstPoolTree(size_t dataSize = 0) : + _root(NULL), + _length(0), + _dataSize(dataSize) {} + ASMJIT_INLINE ~ConstPoolTree() {} + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + _root = NULL; + _length = 0; + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isEmpty() const { + return _length == 0; + } + + ASMJIT_INLINE size_t getLength() const { + return _length; + } + + ASMJIT_INLINE void setDataSize(size_t dataSize) { + ASMJIT_ASSERT(isEmpty()); + _dataSize = dataSize; + } + + // -------------------------------------------------------------------------- + // [Ops] + // -------------------------------------------------------------------------- + + ASMJIT_API ConstPoolNode* get(const void* data); + ASMJIT_API void put(ConstPoolNode* node); + + // -------------------------------------------------------------------------- + // [Iterate] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void iterate(Visitor& visitor) const { + ConstPoolNode* node = const_cast(_root); + ConstPoolNode* link; + + ConstPoolNode* stack[kHeightLimit]; + + if (node == NULL) + return; + + size_t top = 0; + + for (;;) { + link = node->_link[0]; + + if (link != NULL) { + ASMJIT_ASSERT(top != kHeightLimit); + stack[top++] = node; + continue; + } + + visitor.visit(node); + link = node->_link[1]; + + if (link != NULL) { + node = link; + continue; + } + + if (top == 0) + break; + + node = stack[--top]; + } + } + + // -------------------------------------------------------------------------- + // [Helpers] + // -------------------------------------------------------------------------- + + static ASMJIT_INLINE ConstPoolNode* _newNode(Zone* zone, const void* data, size_t size, size_t offset, bool shared) { + ConstPoolNode* node = zone->allocT(sizeof(ConstPoolNode) + size); + if (node == NULL) + return NULL; + + node->_link[0] = NULL; + node->_link[1] = NULL; + node->_level = 1; + node->_shared = shared; + node->_offset = static_cast(offset); + + ::memcpy(node->getData(), data, size); + return node; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Root of the tree + ConstPoolNode* _root; + //! Length of the tree (count of nodes). + size_t _length; + //! Size of the data. + size_t _dataSize; +}; + +// ============================================================================ +// [asmjit::ConstPoolGap] +// ============================================================================ + +//! \internal +//! +//! Zone-allocated constant-pool gap. +struct ConstPoolGap { + //! Link to the next gap + ConstPoolGap* _next; + //! Offset of the gap. + size_t _offset; + //! Remaining bytes of the gap (basically a gap size). + size_t _length; +}; + +// ============================================================================ +// [asmjit::ConstPool] +// ============================================================================ + +//! Constant pool. +struct ConstPool { + ASMJIT_NO_COPY(ConstPool) + + enum { + kIndex1 = 0, + kIndex2 = 1, + kIndex4 = 2, + kIndex8 = 3, + kIndex16 = 4, + kIndex32 = 5, + kIndexCount = 6 + }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_API ConstPool(Zone* zone); + ASMJIT_API ~ConstPool(); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_API void reset(); + + // -------------------------------------------------------------------------- + // [Ops] + // -------------------------------------------------------------------------- + + //! Get whether the constant-pool is empty. + ASMJIT_INLINE bool isEmpty() const { + return _size == 0; + } + + //! Get the size of the constant-pool in bytes. + ASMJIT_INLINE size_t getSize() const { + return _size; + } + + //! Get minimum alignment. + ASMJIT_INLINE size_t getAlignment() const { + return _alignment; + } + + //! Add a constant to the constant pool. + //! + //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes. + //! The constant is added to the pool only if it doesn't not exist, otherwise + //! cached value is returned. + //! + //! AsmJit is able to subdivide added constants, so for example if you add + //! 8-byte constant 0x1122334455667788 it will create the following slots: + //! + //! 8-byte: 0x1122334455667788 + //! 4-byte: 0x11223344, 0x55667788 + //! + //! The reason is that when combining MMX/SSE/AVX code some patterns are used + //! frequently. However, AsmJit is not able to reallocate a constant that has + //! been already added. For example if you try to add 4-byte constant and then + //! 8-byte constant having the same 4-byte pattern as the previous one, two + //! independent slots will be generated by the pool. + ASMJIT_API Error add(const void* data, size_t size, size_t& dstOffset); + + // -------------------------------------------------------------------------- + // [Fill] + // -------------------------------------------------------------------------- + + //! Fill the destination with the constants from the pool. + ASMJIT_API void fill(void* dst); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Zone allocator. + Zone* _zone; + //! Tree per size. + ConstPoolTree _tree[kIndexCount]; + //! Gaps per size. + ConstPoolGap* _gaps[kIndexCount]; + //! Gaps pool + ConstPoolGap* _gapPool; + + //! Size of the pool (in bytes). + size_t _size; + //! Alignemnt. + size_t _alignment; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_CONSTPOOL_H diff --git a/libraries/asmjit/base/containers.cpp b/libraries/asmjit/base/containers.cpp new file mode 100644 index 000000000..b93181390 --- /dev/null +++ b/libraries/asmjit/base/containers.cpp @@ -0,0 +1,116 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/containers.h" +#include "../base/intutil.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::PodVectorBase - NullData] +// ============================================================================ + +const PodVectorData PodVectorBase::_nullData = { 0, 0 }; + +// ============================================================================ +// [asmjit::PodVectorBase - Reset] +// ============================================================================ + +//! Clear vector data and free internal buffer. +void PodVectorBase::reset(bool releaseMemory) { + PodVectorData* d = _d; + + if (d == &_nullData) + return; + + if (releaseMemory) { + ASMJIT_FREE(d); + _d = const_cast(&_nullData); + return; + } + + d->length = 0; +} + +// ============================================================================ +// [asmjit::PodVectorBase - Helpers] +// ============================================================================ + +Error PodVectorBase::_grow(size_t n, size_t sizeOfT) { + PodVectorData* d = _d; + + size_t threshold = kMemAllocGrowMax / sizeOfT; + size_t capacity = d->capacity; + size_t after = d->length; + + if (IntUtil::maxUInt() - n < after) + return kErrorNoHeapMemory; + + after += n; + + if (capacity >= after) + return kErrorOk; + + // PodVector is used as a linear array for some data structures used by + // AsmJit code generation. The purpose of this agressive growing schema + // is to minimize memory reallocations, because AsmJit code generation + // classes live short life and will be freed or reused soon. + if (capacity < 32) + capacity = 32; + else if (capacity < 128) + capacity = 128; + else if (capacity < 512) + capacity = 512; + + while (capacity < after) { + if (capacity < threshold) + capacity *= 2; + else + capacity += threshold; + } + + return _reserve(capacity, sizeOfT); +} + +Error PodVectorBase::_reserve(size_t n, size_t sizeOfT) { + PodVectorData* d = _d; + + if (d->capacity >= n) + return kErrorOk; + + size_t nBytes = sizeof(PodVectorData) + n * sizeOfT; + if (nBytes < n) + return kErrorNoHeapMemory; + + if (d == &_nullData) { + d = static_cast(ASMJIT_ALLOC(nBytes)); + if (d == NULL) + return kErrorNoHeapMemory; + d->length = 0; + } + else { + d = static_cast(ASMJIT_REALLOC(d, nBytes)); + if (d == NULL) + return kErrorNoHeapMemory; + } + + d->capacity = n; + _d = d; + + return kErrorOk; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/containers.h b/libraries/asmjit/base/containers.h new file mode 100644 index 000000000..c6dc70d46 --- /dev/null +++ b/libraries/asmjit/base/containers.h @@ -0,0 +1,350 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_CONTAINERS_H +#define _ASMJIT_BASE_CONTAINERS_H + +// [Dependencies - AsmJit] +#include "../base/error.h" +#include "../base/globals.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::PodVectorData] +// ============================================================================ + +//! \internal +struct PodVectorData { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get data. + ASMJIT_INLINE void* getData() const { + return (void*)(this + 1); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Capacity of the vector. + size_t capacity; + //! Length of the vector. + size_t length; +}; + +// ============================================================================ +// [asmjit::PodVectorBase] +// ============================================================================ + +//! \internal +struct PodVectorBase { + static ASMJIT_API const PodVectorData _nullData; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new instance of `PodVectorBase`. + ASMJIT_INLINE PodVectorBase() : + _d(const_cast(&_nullData)) {} + + //! Destroy the `PodVectorBase` and data. + ASMJIT_INLINE ~PodVectorBase() { + reset(true); + } + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset the vector data and set its `length` to zero. + //! + //! If `releaseMemory` is true the vector buffer will be released to the + //! system. + ASMJIT_API void reset(bool releaseMemory = false); + + // -------------------------------------------------------------------------- + // [Grow / Reserve] + // -------------------------------------------------------------------------- + +protected: + ASMJIT_API Error _grow(size_t n, size_t sizeOfT); + ASMJIT_API Error _reserve(size_t n, size_t sizeOfT); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + +public: + PodVectorData* _d; +}; + +// ============================================================================ +// [asmjit::PodVector] +// ============================================================================ + +//! Template used to store and manage array of POD data. +//! +//! This template has these adventages over other vector<> templates: +//! - Non-copyable (designed to be non-copyable, we want it) +//! - No copy-on-write (some implementations of stl can use it) +//! - Optimized for working only with POD types +//! - Uses ASMJIT_... memory management macros +template +struct PodVector : PodVectorBase { + ASMJIT_NO_COPY(PodVector) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new instance of `PodVector`. + ASMJIT_INLINE PodVector() {} + //! Destroy the `PodVector<>` and data. + ASMJIT_INLINE ~PodVector() {} + + // -------------------------------------------------------------------------- + // [Data] + // -------------------------------------------------------------------------- + + //! Get whether the vector is empty. + ASMJIT_INLINE bool isEmpty() const { + return _d->length == 0; + } + + //! Get length. + ASMJIT_INLINE size_t getLength() const { + return _d->length; + } + + //! Get capacity. + ASMJIT_INLINE size_t getCapacity() const { + return _d->capacity; + } + + //! Get data. + ASMJIT_INLINE T* getData() { + return static_cast(_d->getData()); + } + + //! \overload + ASMJIT_INLINE const T* getData() const { + return static_cast(_d->getData()); + } + + // -------------------------------------------------------------------------- + // [Grow / Reserve] + // -------------------------------------------------------------------------- + + //! Called to grow the buffer to fit at least `n` elements more. + ASMJIT_INLINE Error _grow(size_t n) { + return PodVectorBase::_grow(n, sizeof(T)); + } + + //! Realloc internal array to fit at least `n` items. + ASMJIT_INLINE Error _reserve(size_t n) { + return PodVectorBase::_reserve(n, sizeof(T)); + } + + // -------------------------------------------------------------------------- + // [Ops] + // -------------------------------------------------------------------------- + + //! Prepend `item` to vector. + Error prepend(const T& item) { + PodVectorData* d = _d; + + if (d->length == d->capacity) { + ASMJIT_PROPAGATE_ERROR(_grow(1)); + _d = d; + } + + ::memmove(static_cast(d->getData()) + 1, d->getData(), d->length * sizeof(T)); + ::memcpy(d->getData(), &item, sizeof(T)); + + d->length++; + return kErrorOk; + } + + //! Insert an `item` at the `index`. + Error insert(size_t index, const T& item) { + PodVectorData* d = _d; + ASMJIT_ASSERT(index <= d->length); + + if (d->length == d->capacity) { + ASMJIT_PROPAGATE_ERROR(_grow(1)); + d = _d; + } + + T* dst = static_cast(d->getData()) + index; + ::memmove(dst + 1, dst, d->length - index); + ::memcpy(dst, &item, sizeof(T)); + + d->length++; + return kErrorOk; + } + + //! Append `item` to vector. + Error append(const T& item) { + PodVectorData* d = _d; + + if (d->length == d->capacity) { + ASMJIT_PROPAGATE_ERROR(_grow(1)); + d = _d; + } + + ::memcpy(static_cast(d->getData()) + d->length, &item, sizeof(T)); + + d->length++; + return kErrorOk; + } + + //! Get index of `val` or `kInvalidIndex` if not found. + size_t indexOf(const T& val) const { + PodVectorData* d = _d; + + const T* data = static_cast(d->getData()); + size_t len = d->length; + + for (size_t i = 0; i < len; i++) + if (data[i] == val) + return i; + + return kInvalidIndex; + } + + //! Remove item at index `i`. + void removeAt(size_t i) { + PodVectorData* d = _d; + ASMJIT_ASSERT(i < d->length); + + T* data = static_cast(d->getData()) + i; + d->length--; + ::memmove(data, data + 1, d->length - i); + } + + //! Swap this pod-vector with `other`. + void swap(PodVector& other) { + T* otherData = other._d; + other._d = _d; + _d = otherData; + } + + //! Get item at index `i`. + ASMJIT_INLINE T& operator[](size_t i) { + ASMJIT_ASSERT(i < getLength()); + return getData()[i]; + } + + //! Get item at index `i`. + ASMJIT_INLINE const T& operator[](size_t i) const { + ASMJIT_ASSERT(i < getLength()); + return getData()[i]; + } +}; + +// ============================================================================ +// [asmjit::PodList] +// ============================================================================ + +//! \internal +template +struct PodList { + ASMJIT_NO_COPY(PodList) + + // -------------------------------------------------------------------------- + // [Link] + // -------------------------------------------------------------------------- + + struct Link { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get next node. + ASMJIT_INLINE Link* getNext() const { return _next; } + + //! Get value. + ASMJIT_INLINE T getValue() const { return _value; } + //! Set value to `value`. + ASMJIT_INLINE void setValue(const T& value) { _value = value; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + Link* _next; + T _value; + }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE PodList() : _first(NULL), _last(NULL) {} + ASMJIT_INLINE ~PodList() {} + + // -------------------------------------------------------------------------- + // [Data] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isEmpty() const { return _first != NULL; } + + ASMJIT_INLINE Link* getFirst() const { return _first; } + ASMJIT_INLINE Link* getLast() const { return _last; } + + // -------------------------------------------------------------------------- + // [Ops] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + _first = NULL; + _last = NULL; + } + + ASMJIT_INLINE void prepend(Link* link) { + link->_next = _first; + if (_first == NULL) + _last = link; + _first = link; + } + + ASMJIT_INLINE void append(Link* link) { + link->_next = NULL; + if (_first == NULL) + _first = link; + else + _last->_next = link; + _last = link; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + Link* _first; + Link* _last; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_CONTAINERS_H diff --git a/libraries/asmjit/base/context.cpp b/libraries/asmjit/base/context.cpp new file mode 100644 index 000000000..cedec0f42 --- /dev/null +++ b/libraries/asmjit/base/context.cpp @@ -0,0 +1,561 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/context_p.h" +#include "../base/intutil.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::Context - Construction / Destruction] +// ============================================================================ + +Context::Context(Compiler* compiler) : + _compiler(compiler), + _varMapToVaListOffset(0), + _baseZone(8192 - kZoneOverhead) { + + Context::reset(); +} + +Context::~Context() {} + +// ============================================================================ +// [asmjit::Context - Reset] +// ============================================================================ + +void Context::reset(bool releaseMemory) { + _baseZone.reset(releaseMemory); + + _func = NULL; + _start = NULL; + _end = NULL; + _extraBlock = NULL; + _stop = NULL; + + _unreachableList.reset(); + _jccList.reset(); + _contextVd.reset(releaseMemory); + + _memVarCells = NULL; + _memStackCells = NULL; + + _mem1ByteVarsUsed = 0; + _mem2ByteVarsUsed = 0; + _mem4ByteVarsUsed = 0; + _mem8ByteVarsUsed = 0; + _mem16ByteVarsUsed = 0; + _mem32ByteVarsUsed = 0; + _mem64ByteVarsUsed = 0; + _memStackCellsUsed = 0; + + _memMaxAlign = 0; + _memVarTotal = 0; + _memStackTotal = 0; + _memAllTotal = 0; + _annotationLength = 12; + + _state = NULL; +} + +// ============================================================================ +// [asmjit::Context - Mem] +// ============================================================================ + +static ASMJIT_INLINE uint32_t BaseContext_getDefaultAlignment(uint32_t size) { + if (size > 32) + return 64; + else if (size > 16) + return 32; + else if (size > 8) + return 16; + else if (size > 4) + return 8; + else if (size > 2) + return 4; + else if (size > 1) + return 2; + else + return 1; +} + +MemCell* Context::_newVarCell(VarData* vd) { + ASMJIT_ASSERT(vd->_memCell == NULL); + + MemCell* cell; + uint32_t size = vd->getSize(); + + if (vd->isStack()) { + cell = _newStackCell(size, vd->getAlignment()); + + if (cell == NULL) + return NULL; + } + else { + cell = static_cast(_baseZone.alloc(sizeof(MemCell))); + if (cell == NULL) + goto _NoMemory; + + cell->_next = _memVarCells; + _memVarCells = cell; + + cell->_offset = 0; + cell->_size = size; + cell->_alignment = size; + + _memMaxAlign = IntUtil::iMax(_memMaxAlign, size); + _memVarTotal += size; + + switch (size) { + case 1: _mem1ByteVarsUsed++ ; break; + case 2: _mem2ByteVarsUsed++ ; break; + case 4: _mem4ByteVarsUsed++ ; break; + case 8: _mem8ByteVarsUsed++ ; break; + case 16: _mem16ByteVarsUsed++; break; + case 32: _mem32ByteVarsUsed++; break; + case 64: _mem64ByteVarsUsed++; break; + default: ASMJIT_ASSERT(!"Reached"); + } + } + + vd->_memCell = cell; + return cell; + +_NoMemory: + _compiler->setError(kErrorNoHeapMemory); + return NULL; +} + +MemCell* Context::_newStackCell(uint32_t size, uint32_t alignment) { + MemCell* cell = static_cast(_baseZone.alloc(sizeof(MemCell))); + if (cell == NULL) + goto _NoMemory; + + if (alignment == 0) + alignment = BaseContext_getDefaultAlignment(size); + + if (alignment > 64) + alignment = 64; + + ASMJIT_ASSERT(IntUtil::isPowerOf2(alignment)); + size = IntUtil::alignTo(size, alignment); + + // Insert it sorted according to the alignment and size. + { + MemCell** pPrev = &_memStackCells; + MemCell* cur = *pPrev; + + for (cur = *pPrev; cur != NULL; cur = cur->_next) { + if (cur->getAlignment() > alignment) + continue; + if (cur->getAlignment() == alignment && cur->getSize() > size) + continue; + break; + } + + cell->_next = cur; + cell->_offset = 0; + cell->_size = size; + cell->_alignment = alignment; + + *pPrev = cell; + _memStackCellsUsed++; + + _memMaxAlign = IntUtil::iMax(_memMaxAlign, alignment); + _memStackTotal += size; + } + + return cell; + +_NoMemory: + _compiler->setError(kErrorNoHeapMemory); + return NULL; +} + +Error Context::resolveCellOffsets() { + MemCell* varCell = _memVarCells; + MemCell* stackCell = _memStackCells; + + uint32_t stackAlignment = 0; + if (stackCell != NULL) + stackAlignment = stackCell->getAlignment(); + + uint32_t pos64 = 0; + uint32_t pos32 = pos64 + _mem64ByteVarsUsed * 64; + uint32_t pos16 = pos32 + _mem32ByteVarsUsed * 32; + uint32_t pos8 = pos16 + _mem16ByteVarsUsed * 16; + uint32_t pos4 = pos8 + _mem8ByteVarsUsed * 8 ; + uint32_t pos2 = pos4 + _mem4ByteVarsUsed * 4 ; + uint32_t pos1 = pos2 + _mem2ByteVarsUsed * 2 ; + + uint32_t stackPos = pos1 + _mem1ByteVarsUsed; + + uint32_t gapAlignment = stackAlignment; + uint32_t gapSize = 0; + + if (gapAlignment) + IntUtil::deltaTo(stackPos, gapAlignment); + stackPos += gapSize; + + uint32_t gapPos = stackPos; + uint32_t allTotal = stackPos; + + // Vars - Allocated according to alignment/width. + while (varCell != NULL) { + uint32_t size = varCell->getSize(); + uint32_t offset; + + switch (size) { + case 1: offset = pos1 ; pos1 += 1 ; break; + case 2: offset = pos2 ; pos2 += 2 ; break; + case 4: offset = pos4 ; pos4 += 4 ; break; + case 8: offset = pos8 ; pos8 += 8 ; break; + case 16: offset = pos16; pos16 += 16; break; + case 32: offset = pos32; pos32 += 32; break; + case 64: offset = pos64; pos64 += 64; break; + default: ASMJIT_ASSERT(!"Reached"); + } + + varCell->setOffset(static_cast(offset)); + varCell = varCell->_next; + } + + // Stack - Allocated according to alignment and width. + while (stackCell != NULL) { + uint32_t size = stackCell->getSize(); + uint32_t alignment = stackCell->getAlignment(); + uint32_t offset; + + // Try to fill the gap between variables / stack first. + if (size <= gapSize && alignment <= gapAlignment) { + offset = gapPos; + + gapSize -= size; + gapPos -= size; + + if (alignment < gapAlignment) + gapAlignment = alignment; + } + else { + offset = stackPos; + + stackPos += size; + allTotal += size; + } + + stackCell->setOffset(offset); + stackCell = stackCell->_next; + } + + _memAllTotal = allTotal; + return kErrorOk; +} + +// ============================================================================ +// [asmjit::Context - RemoveUnreachableCode] +// ============================================================================ + +Error Context::removeUnreachableCode() { + PodList::Link* link = _unreachableList.getFirst(); + Node* stop = getStop(); + + while (link != NULL) { + Node* node = link->getValue(); + if (node != NULL && node->getPrev() != NULL) { + // Locate all unreachable nodes. + Node* first = node; + do { + if (node->isFetched()) + break; + node = node->getNext(); + } while (node != stop); + + // Remove. + if (node != first) { + Node* last = (node != NULL) ? node->getPrev() : getCompiler()->getLastNode(); + getCompiler()->removeNodes(first, last); + } + } + + link = link->getNext(); + } + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::Context - Liveness Analysis] +// ============================================================================ + +//! \internal +struct LivenessTarget { + //! Previous target. + LivenessTarget* prev; + + //! Target node. + TargetNode* node; + //! Jumped from. + JumpNode* from; +}; + +Error Context::livenessAnalysis() { + FuncNode* func = getFunc(); + JumpNode* from = NULL; + + Node* node = func->getEnd(); + uint32_t bLen = static_cast( + ((_contextVd.getLength() + VarBits::kEntityBits - 1) / VarBits::kEntityBits)); + + LivenessTarget* ltCur = NULL; + LivenessTarget* ltUnused = NULL; + + size_t varMapToVaListOffset = _varMapToVaListOffset; + + // No variables. + if (bLen == 0) + return kErrorOk; + + VarBits* bCur = newBits(bLen); + if (bCur == NULL) + goto _NoMemory; + + // Allocate bits for code visited first time. +_OnVisit: + for (;;) { + if (node->hasLiveness()) { + if (bCur->_addBitsDelSource(node->getLiveness(), bCur, bLen)) + goto _OnPatch; + else + goto _OnDone; + } + + VarBits* bTmp = copyBits(bCur, bLen); + if (bTmp == NULL) + goto _NoMemory; + + node->setLiveness(bTmp); + VarMap* map = node->getMap(); + + if (map != NULL) { + uint32_t vaCount = map->getVaCount(); + VarAttr* vaList = reinterpret_cast(((uint8_t*)map) + varMapToVaListOffset); + + for (uint32_t i = 0; i < vaCount; i++) { + VarAttr* va = &vaList[i]; + VarData* vd = va->getVd(); + + uint32_t flags = va->getFlags(); + uint32_t ctxId = vd->getContextId(); + + if ((flags & kVarAttrOutAll) && !(flags & kVarAttrInAll)) { + // Write-Only. + bTmp->setBit(ctxId); + bCur->delBit(ctxId); + } + else { + // Read-Only or Read/Write. + bTmp->setBit(ctxId); + bCur->setBit(ctxId); + } + } + } + + if (node->getType() == kNodeTypeTarget) + goto _OnTarget; + + if (node == func) + goto _OnDone; + + ASMJIT_ASSERT(node->getPrev()); + node = node->getPrev(); + } + + // Patch already generated liveness bits. +_OnPatch: + for (;;) { + ASMJIT_ASSERT(node->hasLiveness()); + VarBits* bNode = node->getLiveness(); + + if (!bNode->_addBitsDelSource(bCur, bLen)) + goto _OnDone; + + if (node->getType() == kNodeTypeTarget) + goto _OnTarget; + + if (node == func) + goto _OnDone; + + node = node->getPrev(); + } + +_OnTarget: + if (static_cast(node)->getNumRefs() != 0) { + // Push a new LivenessTarget onto the stack if needed. + if (ltCur == NULL || ltCur->node != node) { + // Allocate a new LivenessTarget object (from pool or zone). + LivenessTarget* ltTmp = ltUnused; + + if (ltTmp != NULL) { + ltUnused = ltUnused->prev; + } + else { + ltTmp = _baseZone.allocT( + sizeof(LivenessTarget) - sizeof(VarBits) + bLen * sizeof(uintptr_t)); + + if (ltTmp == NULL) + goto _NoMemory; + } + + // Initialize and make current - ltTmp->from will be set later on. + ltTmp->prev = ltCur; + ltTmp->node = static_cast(node); + ltCur = ltTmp; + + from = static_cast(node)->getFrom(); + ASMJIT_ASSERT(from != NULL); + } + else { + from = ltCur->from; + goto _OnJumpNext; + } + + // Visit/Patch. + do { + ltCur->from = from; + bCur->copyBits(node->getLiveness(), bLen); + + if (!from->hasLiveness()) { + node = from; + goto _OnVisit; + } + + // Issue #25: Moved '_OnJumpNext' here since it's important to patch + // code again if there are more live variables than before. +_OnJumpNext: + if (bCur->delBits(from->getLiveness(), bLen)) { + node = from; + goto _OnPatch; + } + + from = from->getJumpNext(); + } while (from != NULL); + + // Pop the current LivenessTarget from the stack. + { + LivenessTarget* ltTmp = ltCur; + + ltCur = ltCur->prev; + ltTmp->prev = ltUnused; + ltUnused = ltTmp; + } + } + + bCur->copyBits(node->getLiveness(), bLen); + node = node->getPrev(); + + if (node->isJmp() || !node->isFetched()) + goto _OnDone; + + if (!node->hasLiveness()) + goto _OnVisit; + + if (bCur->delBits(node->getLiveness(), bLen)) + goto _OnPatch; + +_OnDone: + if (ltCur != NULL) { + node = ltCur->node; + from = ltCur->from; + + goto _OnJumpNext; + } + return kErrorOk; + +_NoMemory: + return setError(kErrorNoHeapMemory); +} + +// ============================================================================ +// [asmjit::Context - Schedule] +// ============================================================================ + +Error Context::schedule() { + // By default there is no instruction scheduler implemented. + return kErrorOk; +} + +// ============================================================================ +// [asmjit::Context - Cleanup] +// ============================================================================ + +void Context::cleanup() { + VarData** array = _contextVd.getData(); + size_t length = _contextVd.getLength(); + + for (size_t i = 0; i < length; i++) { + VarData* vd = array[i]; + vd->resetContextId(); + vd->resetRegIndex(); + } + + _contextVd.reset(false); + _extraBlock = NULL; +} + +// ============================================================================ +// [asmjit::Context - CompileFunc] +// ============================================================================ + +Error Context::compile(FuncNode* func) { + Node* end = func->getEnd(); + Node* stop = end->getNext(); + + _func = func; + _stop = stop; + _extraBlock = end; + + ASMJIT_PROPAGATE_ERROR(fetch()); + ASMJIT_PROPAGATE_ERROR(removeUnreachableCode()); + ASMJIT_PROPAGATE_ERROR(livenessAnalysis()); + + Compiler* compiler = getCompiler(); + +#if !defined(ASMJIT_DISABLE_LOGGER) + if (compiler->hasLogger()) + ASMJIT_PROPAGATE_ERROR(annotate()); +#endif // !ASMJIT_DISABLE_LOGGER + + ASMJIT_PROPAGATE_ERROR(translate()); + + if (compiler->hasFeature(kCodeGenEnableScheduler)) + ASMJIT_PROPAGATE_ERROR(schedule()); + + // We alter the compiler cursor, because it doesn't make sense to reference + // it after compilation - some nodes may disappear and it's forbidden to add + // new code after the compilation is done. + compiler->_setCursor(NULL); + + return kErrorOk; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER diff --git a/libraries/asmjit/base/context_p.h b/libraries/asmjit/base/context_p.h new file mode 100644 index 000000000..bd235013e --- /dev/null +++ b/libraries/asmjit/base/context_p.h @@ -0,0 +1,307 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_CONTEXT_P_H +#define _ASMJIT_BASE_CONTEXT_P_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/compiler.h" +#include "../base/zone.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_compiler +//! \{ + +// ============================================================================ +// [asmjit::Context] +// ============================================================================ + +//! \internal +//! +//! Code generation context is the logic behind `Compiler`. The context is +//! used to compile the code stored in `Compiler`. +struct Context { + ASMJIT_NO_COPY(Context) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + Context(Compiler* compiler); + virtual ~Context(); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset the whole context. + virtual void reset(bool releaseMemory = false); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get compiler. + ASMJIT_INLINE Compiler* getCompiler() const { return _compiler; } + + //! Get function. + ASMJIT_INLINE FuncNode* getFunc() const { return _func; } + //! Get stop node. + ASMJIT_INLINE Node* getStop() const { return _stop; } + + //! Get start of the current scope. + ASMJIT_INLINE Node* getStart() const { return _start; } + //! Get end of the current scope. + ASMJIT_INLINE Node* getEnd() const { return _end; } + + //! Get extra block. + ASMJIT_INLINE Node* getExtraBlock() const { return _extraBlock; } + //! Set extra block. + ASMJIT_INLINE void setExtraBlock(Node* node) { _extraBlock = node; } + + // -------------------------------------------------------------------------- + // [Error] + // -------------------------------------------------------------------------- + + //! Get the last error code. + ASMJIT_INLINE Error getError() const { + return getCompiler()->getError(); + } + + //! Set the last error code and propagate it through the error handler. + ASMJIT_INLINE Error setError(Error error, const char* message = NULL) { + return getCompiler()->setError(error, message); + } + + // -------------------------------------------------------------------------- + // [State] + // -------------------------------------------------------------------------- + + //! Get current state. + ASMJIT_INLINE VarState* getState() const { + return _state; + } + + //! Load current state from `target` state. + virtual void loadState(VarState* src) = 0; + + //! Save current state, returning new `VarState` instance. + virtual VarState* saveState() = 0; + + //! Change the current state to `target` state. + virtual void switchState(VarState* src) = 0; + + //! Change the current state to the intersection of two states `a` and `b`. + virtual void intersectStates(VarState* a, VarState* b) = 0; + + // -------------------------------------------------------------------------- + // [Context] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Error _registerContextVar(VarData* vd) { + if (vd->hasContextId()) + return kErrorOk; + + uint32_t cid = static_cast(_contextVd.getLength()); + ASMJIT_PROPAGATE_ERROR(_contextVd.append(vd)); + + vd->setContextId(cid); + return kErrorOk; + } + + // -------------------------------------------------------------------------- + // [Mem] + // -------------------------------------------------------------------------- + + MemCell* _newVarCell(VarData* vd); + MemCell* _newStackCell(uint32_t size, uint32_t alignment); + + ASMJIT_INLINE MemCell* getVarCell(VarData* vd) { + MemCell* cell = vd->getMemCell(); + return cell ? cell : _newVarCell(vd); + } + + virtual Error resolveCellOffsets(); + + // -------------------------------------------------------------------------- + // [Bits] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE VarBits* newBits(uint32_t len) { + return static_cast( + _baseZone.allocZeroed(static_cast(len) * VarBits::kEntitySize)); + } + + ASMJIT_INLINE VarBits* copyBits(const VarBits* src, uint32_t len) { + return static_cast( + _baseZone.dup(src, static_cast(len) * VarBits::kEntitySize)); + } + + // -------------------------------------------------------------------------- + // [Fetch] + // -------------------------------------------------------------------------- + + //! Fetch. + //! + //! Fetch iterates over all nodes and gathers information about all variables + //! used. The process generates information required by register allocator, + //! variable liveness analysis and translator. + virtual Error fetch() = 0; + + // -------------------------------------------------------------------------- + // [RemoveUnreachableCode] + // -------------------------------------------------------------------------- + + //! Remove unreachable code. + virtual Error removeUnreachableCode(); + + // -------------------------------------------------------------------------- + // [Analyze] + // -------------------------------------------------------------------------- + + //! Perform variable liveness analysis. + //! + //! Analysis phase iterates over nodes in reverse order and generates a bit + //! array describing variables that are alive at every node in the function. + //! When the analysis start all variables are assumed dead. When a read or + //! read/write operations of a variable is detected the variable becomes + //! alive; when only write operation is detected the variable becomes dead. + //! + //! When a label is found all jumps to that label are followed and analysis + //! repeats until all variables are resolved. + virtual Error livenessAnalysis(); + + // -------------------------------------------------------------------------- + // [Annotate] + // -------------------------------------------------------------------------- + + virtual Error annotate() = 0; + + // -------------------------------------------------------------------------- + // [Translate] + // -------------------------------------------------------------------------- + + //! Translate code by allocating registers and handling state changes. + virtual Error translate() = 0; + + // -------------------------------------------------------------------------- + // [Schedule] + // -------------------------------------------------------------------------- + + virtual Error schedule(); + + // -------------------------------------------------------------------------- + // [Cleanup] + // -------------------------------------------------------------------------- + + virtual void cleanup(); + + // -------------------------------------------------------------------------- + // [Compile] + // -------------------------------------------------------------------------- + + virtual Error compile(FuncNode* func); + + // -------------------------------------------------------------------------- + // [Serialize] + // -------------------------------------------------------------------------- + + virtual Error serialize(Assembler* assembler, Node* start, Node* stop) = 0; + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Compiler. + Compiler* _compiler; + //! Function. + FuncNode* _func; + + //! Zone allocator. + Zone _baseZone; + + //! \internal + //! + //! Offset (how many bytes to add) to `VarMap` to get `VarAttr` array. Used + //! by liveness analysis shared across all backends. This is needed because + //! `VarMap` is a base class for a specialized version that liveness analysis + //! doesn't use, it just needs `VarAttr` array. + uint32_t _varMapToVaListOffset; + + //! Start of the current active scope. + Node* _start; + //! End of the current active scope. + Node* _end; + + //! Node that is used to insert extra code after the function body. + Node* _extraBlock; + //! Stop node. + Node* _stop; + + //! Unreachable nodes. + PodList _unreachableList; + //! Jump nodes. + PodList _jccList; + + //! All variables used by the current function. + PodVector _contextVd; + + //! Memory used to spill variables. + MemCell* _memVarCells; + //! Memory used to alloc memory on the stack. + MemCell* _memStackCells; + + //! Count of 1-byte cells. + uint32_t _mem1ByteVarsUsed; + //! Count of 2-byte cells. + uint32_t _mem2ByteVarsUsed; + //! Count of 4-byte cells. + uint32_t _mem4ByteVarsUsed; + //! Count of 8-byte cells. + uint32_t _mem8ByteVarsUsed; + //! Count of 16-byte cells. + uint32_t _mem16ByteVarsUsed; + //! Count of 32-byte cells. + uint32_t _mem32ByteVarsUsed; + //! Count of 64-byte cells. + uint32_t _mem64ByteVarsUsed; + //! Count of stack memory cells. + uint32_t _memStackCellsUsed; + + //! Maximum memory alignment used by the function. + uint32_t _memMaxAlign; + //! Count of bytes used by variables. + uint32_t _memVarTotal; + //! Count of bytes used by stack. + uint32_t _memStackTotal; + //! Count of bytes used by variables and stack after alignment. + uint32_t _memAllTotal; + + //! Default lenght of annotated instruction. + uint32_t _annotationLength; + + //! Current state (used by register allocator). + VarState* _state; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_BASE_CONTEXT_P_H diff --git a/libraries/asmjit/base/cpuinfo.cpp b/libraries/asmjit/base/cpuinfo.cpp new file mode 100644 index 000000000..71d6858dd --- /dev/null +++ b/libraries/asmjit/base/cpuinfo.cpp @@ -0,0 +1,79 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/cpuinfo.h" + +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#include "../x86/x86cpuinfo.h" +#else +// ? +#endif // ASMJIT_HOST || ASMJIT_HOST_X64 + +// [Dependencies - Posix] +#if defined(ASMJIT_OS_POSIX) +# include +# include +# include +# include +#endif // ASMJIT_OS_POSIX + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::CpuInfo - DetectHwThreadsCount] +// ============================================================================ + +uint32_t CpuInfo::detectHwThreadsCount() { +#if defined(ASMJIT_OS_WINDOWS) + SYSTEM_INFO info; + ::GetSystemInfo(&info); + return info.dwNumberOfProcessors; +#elif defined(ASMJIT_OS_POSIX) && defined(_SC_NPROCESSORS_ONLN) + // It seems that sysconf returns the number of "logical" processors on both + // mac and linux. So we get the number of "online logical" processors. + long res = ::sysconf(_SC_NPROCESSORS_ONLN); + if (res == -1) return 1; + + return static_cast(res); +#else + return 1; +#endif +} + +// ============================================================================ +// [asmjit::CpuInfo - GetHost] +// ============================================================================ + +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +struct AutoX86CpuInfo : public X86CpuInfo { + ASMJIT_INLINE AutoX86CpuInfo() : X86CpuInfo() { + X86CpuUtil::detect(this); + } +}; +#else +#error "AsmJit - Unsupported CPU." +#endif // ASMJIT_HOST || ASMJIT_HOST_X64 + +const CpuInfo* CpuInfo::getHost() { +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) + static AutoX86CpuInfo cpuInfo; +#else +#error "AsmJit - Unsupported CPU." +#endif // ASMJIT_HOST || ASMJIT_HOST_X64 + return &cpuInfo; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/cpuinfo.h b/libraries/asmjit/base/cpuinfo.h new file mode 100644 index 000000000..06ff636c5 --- /dev/null +++ b/libraries/asmjit/base/cpuinfo.h @@ -0,0 +1,147 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_CPUINFO_H +#define _ASMJIT_BASE_CPUINFO_H + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_general +//! \{ + +// ============================================================================ +// [asmjit::kCpuVendor] +// ============================================================================ + +//! Cpu vendor ID. +//! +//! Vendor IDs are specific to AsmJit library. During the library initialization +//! AsmJit checks host CPU and tries to identify the vendor based on the CPUID +//! calls. Some manufacturers changed their vendor strings and AsmJit is aware +//! of that - it checks multiple combinations and decides which vendor ID should +//! be used. +ASMJIT_ENUM(kCpuVendor) { + //! No/Unknown vendor. + kCpuVendorNone = 0, + + //! Intel vendor. + kCpuVendorIntel = 1, + //! AMD vendor. + kCpuVendorAmd = 2, + //! VIA vendor. + kCpuVendorVia = 3 +}; + +// ============================================================================ +// [asmjit::CpuInfo] +// ============================================================================ + +//! Base cpu information. +struct CpuInfo { + ASMJIT_NO_COPY(CpuInfo) + + //! \internal + enum { + kFeaturesPerUInt32 = static_cast(sizeof(uint32_t)) * 8 + }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE CpuInfo(uint32_t size = sizeof(CpuInfo)) : _size(size) {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get CPU vendor string. + ASMJIT_INLINE const char* getVendorString() const { return _vendorString; } + //! Get CPU brand string. + ASMJIT_INLINE const char* getBrandString() const { return _brandString; } + + //! Get CPU vendor ID. + ASMJIT_INLINE uint32_t getVendorId() const { return _vendorId; } + //! Get CPU family ID. + ASMJIT_INLINE uint32_t getFamily() const { return _family; } + //! Get CPU model ID. + ASMJIT_INLINE uint32_t getModel() const { return _model; } + //! Get CPU stepping. + ASMJIT_INLINE uint32_t getStepping() const { return _stepping; } + + //! Get number of hardware threads available. + ASMJIT_INLINE uint32_t getHwThreadsCount() const { return _hwThreadsCount; } + + //! Get whether CPU has a `feature`. + ASMJIT_INLINE bool hasFeature(uint32_t feature) const { + ASMJIT_ASSERT(feature < sizeof(_features) * 8); + + return static_cast( + (_features[feature / kFeaturesPerUInt32] >> (feature % kFeaturesPerUInt32)) & 0x1); + } + + //! Add a CPU `feature`. + ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) { + ASMJIT_ASSERT(feature < sizeof(_features) * 8); + + _features[feature / kFeaturesPerUInt32] |= (1U << (feature % kFeaturesPerUInt32)); + return *this; + } + + // -------------------------------------------------------------------------- + // [Statics] + // -------------------------------------------------------------------------- + + //! Detect the number of hardware threads. + static ASMJIT_API uint32_t detectHwThreadsCount(); + + //! Get host cpu. + static ASMJIT_API const CpuInfo* getHost(); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Size of the structure in bytes. + uint32_t _size; + + //! Cpu short vendor string. + char _vendorString[16]; + //! Cpu long vendor string (brand). + char _brandString[64]; + + //! Cpu vendor id, see `asmjit::kCpuVendor`. + uint32_t _vendorId; + //! Cpu family ID. + uint32_t _family; + //! Cpu model ID. + uint32_t _model; + //! Cpu stepping. + uint32_t _stepping; + + //! Number of hardware threads. + uint32_t _hwThreadsCount; + + //! Cpu features bitfield. + uint32_t _features[4]; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_CPUINFO_H diff --git a/libraries/asmjit/base/cputicks.cpp b/libraries/asmjit/base/cputicks.cpp new file mode 100644 index 000000000..cb10ff14f --- /dev/null +++ b/libraries/asmjit/base/cputicks.cpp @@ -0,0 +1,131 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/cputicks.h" + +// [Dependencies - Posix] +#if defined(ASMJIT_OS_POSIX) +# include +# include +#endif // ASMJIT_OS_POSIX + +// [Dependencies - Mac] +#if defined(ASMJIT_OS_MAC) +# include +#endif // ASMJIT_OS_MAC + +// [Dependencies - Windows] +#if defined(ASMJIT_OS_WINDOWS) +// `_InterlockedCompareExchange` is only available as intrinsic (MS Compiler). +# if defined(_MSC_VER) +# include +# pragma intrinsic(_InterlockedCompareExchange) +# else +# define _InterlockedCompareExchange InterlockedCompareExchange +# endif // _MSC_VER +#endif // ASMJIT_OS_WINDOWS + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::CpuTicks - Windows] +// ============================================================================ + +#if defined(ASMJIT_OS_WINDOWS) +static volatile uint32_t CpuTicks_hiResOk; +static volatile double CpuTicks_hiResFreq; + +uint32_t CpuTicks::now() { + do { + uint32_t hiResOk = CpuTicks_hiResOk; + + if (hiResOk == 1) { + LARGE_INTEGER now; + if (!::QueryPerformanceCounter(&now)) + break; + return (int64_t)(double(now.QuadPart) / CpuTicks_hiResFreq); + } + + if (hiResOk == 0) { + LARGE_INTEGER qpf; + if (!::QueryPerformanceFrequency(&qpf)) { + _InterlockedCompareExchange((LONG*)&CpuTicks_hiResOk, 0xFFFFFFFF, 0); + break; + } + + LARGE_INTEGER now; + if (!::QueryPerformanceCounter(&now)) { + _InterlockedCompareExchange((LONG*)&CpuTicks_hiResOk, 0xFFFFFFFF, 0); + break; + } + + double freqDouble = double(qpf.QuadPart) / 1000.0; + + CpuTicks_hiResFreq = freqDouble; + _InterlockedCompareExchange((LONG*)&CpuTicks_hiResOk, 1, 0); + + return static_cast( + static_cast(double(now.QuadPart) / freqDouble) & 0xFFFFFFFF); + } + } while (0); + + // Bail to a less precise GetTickCount(). + return ::GetTickCount(); +} + +// ============================================================================ +// [asmjit::CpuTicks - Mac] +// ============================================================================ + +#elif defined(ASMJIT_OS_MAC) +static mach_timebase_info_data_t CpuTicks_machTime; + +uint32_t CpuTicks::now() { + // Initialize the first time CpuTicks::now() is called (See Apple's QA1398). + if (CpuTicks_machTime.denom == 0) { + if (mach_timebase_info(&CpuTicks_machTime) != KERN_SUCCESS); + return 0; + } + + // mach_absolute_time() returns nanoseconds, we need just milliseconds. + uint64_t t = mach_absolute_time() / 1000000; + + t = t * CpuTicks_machTime.numer / CpuTicks_machTime.denom; + return static_cast(t & 0xFFFFFFFFU); +} + +// ============================================================================ +// [asmjit::CpuTicks - Posix] +// ============================================================================ + +#else +uint32_t CpuTicks::now() { +#if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + return 0; + + uint64_t t = (uint64_t(ts.tv_sec ) * 1000) + (uint64_t(ts.tv_nsec) / 1000000); + return static_cast(t & 0xFFFFFFFFU); +#else // _POSIX_MONOTONIC_CLOCK +#error "AsmJit - Unsupported OS." + return 0; +#endif // _POSIX_MONOTONIC_CLOCK +} +#endif // ASMJIT_OS + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/cputicks.h b/libraries/asmjit/base/cputicks.h new file mode 100644 index 000000000..1732c2eb6 --- /dev/null +++ b/libraries/asmjit/base/cputicks.h @@ -0,0 +1,40 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_CPUTICKS_H +#define _ASMJIT_BASE_CPUTICKS_H + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::CpuTicks] +// ============================================================================ + +//! CPU ticks utilities. +struct CpuTicks { + //! Get the current CPU ticks for benchmarking (1ms resolution). + static ASMJIT_API uint32_t now(); +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_CPUTICKS_H diff --git a/libraries/asmjit/base/error.cpp b/libraries/asmjit/base/error.cpp new file mode 100644 index 000000000..3df410e40 --- /dev/null +++ b/libraries/asmjit/base/error.cpp @@ -0,0 +1,81 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/error.h" +#include "../base/intutil.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::ErrorHandler - Construction / Destruction] +// ============================================================================ + +ErrorHandler::ErrorHandler() {} +ErrorHandler::~ErrorHandler() {} + +// ============================================================================ +// [asmjit::ErrorHandler - Interface] +// ============================================================================ + +ErrorHandler* ErrorHandler::addRef() const { + return const_cast(this); +} + +void ErrorHandler::release() {} + +// ============================================================================ +// [asmjit::ErrorUtil - AsString] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_NAMES) +static const char errorMessages[] = { + "Ok\0" + "No heap memory\0" + "No virtual memory\0" + "Invalid argument\0" + "Invalid state\0" + "No code generated\0" + "Code too large\0" + "Label already bound\0" + "Unknown instruction\0" + "Illegal instruction\0" + "Illegal addressing\0" + "Illegal displacement\0" + "Overlapped arguments\0" + "Unknown error\0" +}; + +static const char* findPackedString(const char* p, uint32_t id, uint32_t maxId) { + uint32_t i = 0; + + if (id > maxId) + id = maxId; + + while (i < id) { + while (p[0]) + p++; + p++; + } + + return p; +} + +const char* ErrorUtil::asString(Error e) { + return findPackedString(errorMessages, e, kErrorCount); +} +#endif // ASMJIT_DISABLE_NAMES + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/error.h b/libraries/asmjit/base/error.h new file mode 100644 index 000000000..46b40892f --- /dev/null +++ b/libraries/asmjit/base/error.h @@ -0,0 +1,218 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_ERROR_H +#define _ASMJIT_BASE_ERROR_H + +// [Api-Begin] +#include "../apibegin.h" + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_general +//! \{ + +// ============================================================================ +// [asmjit::kError] +// ============================================================================ + +//! AsmJit error codes. +ASMJIT_ENUM(kError) { + //! No error (success). + //! + //! This is default state and state you want. + kErrorOk = 0, + + //! Heap memory allocation failed. + kErrorNoHeapMemory = 1, + + //! Virtual memory allocation failed. + kErrorNoVirtualMemory = 2, + + //! Invalid argument. + kErrorInvalidArgument = 3, + + //! Invalid state. + kErrorInvalidState = 4, + + //! No code generated. + //! + //! Returned by runtime if the code-generator contains no code. + kErrorNoCodeGenerated = 5, + + //! Code generated is too large to fit in memory reserved. + //! + //! Returned by `StaticRuntime` in case that the code generated is too large + //! to fit in the memory already reserved for it. + kErrorCodeTooLarge = 6, + + //! Label is already bound. + kErrorLabelAlreadyBound = 7, + + //! Unknown instruction (an instruction ID is out of bounds or instruction + //! name is invalid). + kErrorUnknownInst = 8, + + //! Illegal instruction. + //! + //! This status code can also be returned in X64 mode if AH, BH, CH or DH + //! registers have been used together with a REX prefix. The instruction + //! is not encodable in such case. + //! + //! Example of raising `kErrorIllegalInst` error. + //! + //! ~~~ + //! // Invalid address size. + //! a.mov(dword_ptr(eax), al); + //! + //! // Undecodable instruction - AH used with R10, however R10 can only be + //! // encoded by using REX prefix, which conflicts with AH. + //! a.mov(byte_ptr(r10), ah); + //! ~~~ + //! + //! \note In debug mode assertion is raised instead of returning an error. + kErrorIllegalInst = 9, + + //! Illegal (unencodable) addressing used. + kErrorIllegalAddresing = 10, + + //! Illegal (unencodable) displacement used. + //! + //! X86/X64 + //! ------- + //! + //! Short form of jump instruction has been used, but the displacement is out + //! of bounds. + kErrorIllegalDisplacement = 11, + + //! A variable has been assigned more than once to a function argument (Compiler). + kErrorOverlappedArgs = 12, + + //! Count of AsmJit error codes. + kErrorCount = 13 +}; + +// ============================================================================ +// [asmjit::Error] +// ============================================================================ + +//! AsmJit error type (unsigned integer). +typedef uint32_t Error; + +// ============================================================================ +// [asmjit::ErrorHandler] +// ============================================================================ + +//! Error handler. +//! +//! Error handler can be used to override the default behavior of `CodeGen` +//! error handling and propagation. See `handleError` on how to override it. +//! +//! Please note that `addRef` and `release` functions are used, but there is +//! no reference counting implemented by default, reimplement to change the +//! default behavior. +struct ASMJIT_VCLASS ErrorHandler { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `ErrorHandler` instance. + ASMJIT_API ErrorHandler(); + //! Destroy the `ErrorHandler` instance. + ASMJIT_API virtual ~ErrorHandler(); + + // -------------------------------------------------------------------------- + // [Interface] + // -------------------------------------------------------------------------- + + //! Reference this error handler. + //! + //! \note This member function is provided for convenience. The default + //! implementation does nothing. If you are working in environment where + //! multiple `ErrorHandler` instances are used by a different code generators + //! you may provide your own functionality for reference counting. In that + //! case `addRef()` and `release()` functions should be overridden. + ASMJIT_API virtual ErrorHandler* addRef() const; + + //! Release this error handler. + //! + //! \note This member function is provided for convenience. See `addRef()` + //! for more detailed information related to reference counting. + ASMJIT_API virtual void release(); + + //! Error handler (pure). + //! + //! Error handler is called when an error happened. An error can happen in + //! many places, but error handler is mostly used by `Assembler` and + //! `Compiler` classes to report anything that may cause incorrect code + //! generation. There are multiple ways how the error handler can be used + //! and each has it's pros/cons. + //! + //! AsmJit library doesn't use exceptions and can be compiled with or without + //! exception handling support. Even if the AsmJit library is compiled without + //! exceptions it is exception-safe and handleError() can report an incoming + //! error by throwing an exception of any type. It's guaranteed that the + //! exception won't be catched by AsmJit and will be propagated to the code + //! calling AsmJit `Assembler` or `Compiler` methods. Alternative to + //! throwing an exception is using `setjmp()` and `longjmp()` pair available + //! in the standard C library. + //! + //! If the exception or setjmp() / longjmp() mechanism is used, the state of + //! the `BaseAssember` or `Compiler` is unchanged and if it's possible the + //! execution (instruction serialization) can continue. However if the error + //! happened during any phase that translates or modifies the stored code + //! (for example relocation done by `Assembler` or analysis/translation + //! done by `Compiler`) the execution can't continue and the error will + //! be also stored in `Assembler` or `Compiler`. + //! + //! Finally, if no exceptions nor setjmp() / longjmp() mechanisms were used, + //! you can still implement a compatible handling by returning from your + //! error handler. Returning `true` means that error was reported and AsmJit + //! should continue execution, but `false` sets the rror immediately to the + //! `Assembler` or `Compiler` and execution shouldn't continue (this + //! is the default behavior in case no error handler is used). + virtual bool handleError(Error code, const char* message) = 0; +}; + +// ============================================================================ +// [asmjit::ErrorUtil] +// ============================================================================ + +//! Error utilities. +struct ErrorUtil { +#if !defined(ASMJIT_DISABLE_NAMES) + //! Get printable version of AsmJit `kError` code. + static ASMJIT_API const char* asString(Error code); +#endif // ASMJIT_DISABLE_NAMES +}; + +//! \} + +// ============================================================================ +// [ASMJIT_PROPAGATE_ERROR] +// ============================================================================ + +//! \internal +//! +//! Used by AsmJit to return the `_Exp_` result if it's an error. +#define ASMJIT_PROPAGATE_ERROR(_Exp_) \ + do { \ + ::asmjit::Error errval_ = (_Exp_); \ + if (errval_ != ::asmjit::kErrorOk) \ + return errval_; \ + } while (0) + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_ERROR_H diff --git a/libraries/asmjit/base/globals.cpp b/libraries/asmjit/base/globals.cpp new file mode 100644 index 000000000..2971e002b --- /dev/null +++ b/libraries/asmjit/base/globals.cpp @@ -0,0 +1,30 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::Assert] +// ============================================================================ + +void assertionFailed(const char* exp, const char* file, int line) { + ::fprintf(stderr, "Assertion failed: %s\n, file %s, line %d\n", exp, file, line); + ::abort(); +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/globals.h b/libraries/asmjit/base/globals.h new file mode 100644 index 000000000..036457895 --- /dev/null +++ b/libraries/asmjit/base/globals.h @@ -0,0 +1,177 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_GLOBALS_H +#define _ASMJIT_BASE_GLOBALS_H + +// [Dependencies - AsmJit] +#include "../build.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_general +//! \{ + +// ============================================================================ +// [asmjit::Ptr / SignedPtr] +// ============================================================================ + +//! 64-bit unsigned pointer, compatible with JIT and non-JIT generators. +//! +//! This is the preferred pointer type to use with AsmJit library. It has a +//! capability to hold any pointer for any architecture making it an ideal +//! candidate for cross-platform code generation. +typedef uint64_t Ptr; + +//! 64-bit signed pointer, like \ref Ptr, but made signed. +typedef int64_t SignedPtr; + +// ============================================================================ +// [asmjit::kGlobals] +// ============================================================================ + +//! Invalid index +//! +//! Invalid index is the last possible index that is never used in practice. In +//! AsmJit it is used exclusively with strings to indicate the the length of the +//! string is not known and has to be determined. +static const size_t kInvalidIndex = ~static_cast(0); + +//! Invalid base address. +static const Ptr kNoBaseAddress = static_cast(static_cast(-1)); + +//! Global constants. +ASMJIT_ENUM(kGlobals) { + //! Invalid value or operand id. + kInvalidValue = 0xFFFFFFFF, + + //! Invalid register index. + kInvalidReg = 0xFF, + //! Invalid variable type. + kInvalidVar = 0xFF, + + //! Host memory allocator overhead. + //! + //! The overhead is decremented from all zone allocators so the operating + //! system doesn't have allocate extra virtual page to keep tract of the + //! requested memory block. + //! + //! The number is actually a guess. + kMemAllocOverhead = sizeof(intptr_t) * 4, + + //! Memory grow threshold. + //! + //! After the grow threshold is reached the capacity won't be doubled + //! anymore. + kMemAllocGrowMax = 8192 * 1024 +}; + +// ============================================================================ +// [asmjit::kArch] +// ============================================================================ + +//! Architecture. +ASMJIT_ENUM(kArch) { + //! No/Unknown architecture. + kArchNone = 0, + + //! X86 architecture. + kArchX86 = 1, + //! X64 architecture, also called AMD64. + kArchX64 = 2, + + //! Arm architecture. + kArchArm = 4, + +#if defined(ASMJIT_HOST_X86) + kArchHost = kArchX86, +#endif // ASMJIT_HOST_X86 + +#if defined(ASMJIT_HOST_X64) + kArchHost = kArchX64, +#endif // ASMJIT_HOST_X64 + +#if defined(ASMJIT_HOST_ARM) + kArchHost = kArchArm, +#endif // ASMJIT_HOST_ARM + + //! Whether the host is 64-bit. + kArchHost64Bit = sizeof(intptr_t) >= 8 +}; + +//! \} + +// ============================================================================ +// [asmjit::Init / NoInit] +// ============================================================================ + +#if !defined(ASMJIT_DOCGEN) +struct _Init {}; +static const _Init Init = {}; + +struct _NoInit {}; +static const _NoInit NoInit = {}; +#endif // !ASMJIT_DOCGEN + +// ============================================================================ +// [asmjit::Assert] +// ============================================================================ + +//! \addtogroup asmjit_base_general +//! \{ + +//! Called in debug build on assertion failure. +//! +//! \param exp Expression that failed. +//! \param file Source file name where it happened. +//! \param line Line in the source file. +//! +//! If you have problems with assertions put a breakpoint at assertionFailed() +//! function (asmjit/base/globals.cpp) and check the call stack to locate the +//! failing code. +ASMJIT_API void assertionFailed(const char* exp, const char* file, int line); + +#if defined(ASMJIT_DEBUG) +#define ASMJIT_ASSERT(_Exp_) \ + do { \ + if (!(_Exp_)) ::asmjit::assertionFailed(#_Exp_, __FILE__, __LINE__); \ + } while (0) +#else +#define ASMJIT_ASSERT(_Exp_) ASMJIT_NOP() +#endif // DEBUG + +//! \} + +} // asmjit namespace + +// ============================================================================ +// [asmjit_cast<>] +// ============================================================================ + +//! \addtogroup asmjit_base_util +//! \{ + +//! Cast used to cast pointer to function. It's like reinterpret_cast<>, +//! but uses internally C style cast to work with MinGW. +//! +//! If you are using single compiler and `reinterpret_cast<>` works for you, +//! there is no reason to use `asmjit_cast<>`. If you are writing +//! cross-platform software with various compiler support, consider using +//! `asmjit_cast<>` instead of `reinterpret_cast<>`. +template +static ASMJIT_INLINE T asmjit_cast(Z* p) { return (T)p; } + +//! \} + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_GLOBALS_H diff --git a/libraries/asmjit/base/intutil.cpp b/libraries/asmjit/base/intutil.cpp new file mode 100644 index 000000000..3a811b66e --- /dev/null +++ b/libraries/asmjit/base/intutil.cpp @@ -0,0 +1,210 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/intutil.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +#if defined(ASMJIT_TEST) +UNIT(base_intutil) { + uint32_t i; + + INFO("IntTraits<>."); + EXPECT(IntTraits::kIsSigned, + "IntTraits should report signed."); + EXPECT(IntTraits::kIsUnsigned, + "IntTraits should report unsigned."); + + EXPECT(IntTraits::kIsSigned, + "IntTraits should report signed."); + EXPECT(IntTraits::kIsUnsigned, + "IntTraits should report unsigned."); + + EXPECT(IntTraits::kIsSigned, + "IntTraits should report signed."); + EXPECT(IntTraits::kIsUnsigned, + "IntTraits should report unsigned."); + + EXPECT(IntTraits::kIsSigned, + "IntTraits should report signed."); + EXPECT(IntTraits::kIsUnsigned, + "IntTraits should report unsigned."); + + EXPECT(IntTraits::kIsSigned, + "IntTraits should report signed."); + EXPECT(IntTraits::kIsUnsigned, + "IntTraits should report unsigned."); + + EXPECT(IntTraits::kIsIntPtr, + "IntTraits should report intptr_t type."); + EXPECT(IntTraits::kIsIntPtr, + "IntTraits should report intptr_t type."); + + INFO("IntUtil::iMin()/iMax()."); + EXPECT(IntUtil::iMin(0, -1) == -1, + "IntUtil::iMin should return a minimum value."); + EXPECT(IntUtil::iMin(-1, -2) == -2, + "IntUtil::iMin should return a minimum value."); + EXPECT(IntUtil::iMin(1, 2) == 1, + "IntUtil::iMin should return a minimum value."); + + EXPECT(IntUtil::iMax(0, -1) == 0, + "IntUtil::iMax should return a maximum value."); + EXPECT(IntUtil::iMax(-1, -2) == -1, + "IntUtil::iMax should return a maximum value."); + EXPECT(IntUtil::iMax(1, 2) == 2, + "IntUtil::iMax should return a maximum value."); + + INFO("IntUtil::inInterval()."); + EXPECT(IntUtil::inInterval(11, 10, 20) == true, + "IntUtil::inInterval should return true if inside."); + EXPECT(IntUtil::inInterval(101, 10, 20) == false, + "IntUtil::inInterval should return false if outside."); + + INFO("IntUtil::isInt8()."); + EXPECT(IntUtil::isInt8(-128) == true, + "IntUtil::isInt8<> should return true if inside."); + EXPECT(IntUtil::isInt8(127) == true, + "IntUtil::isInt8<> should return true if inside."); + EXPECT(IntUtil::isInt8(-129) == false, + "IntUtil::isInt8<> should return false if outside."); + EXPECT(IntUtil::isInt8(128) == false, + "IntUtil::isInt8<> should return false if outside."); + + INFO("IntUtil::isUInt8()."); + EXPECT(IntUtil::isUInt8(255) == true, + "IntUtil::isUInt8<> should return true if inside."); + EXPECT(IntUtil::isUInt8(256) == false, + "IntUtil::isUInt8<> should return false if outside."); + EXPECT(IntUtil::isUInt8(-1) == false, + "IntUtil::isUInt8<> should return false if negative."); + + INFO("IntUtil::isInt16()."); + EXPECT(IntUtil::isInt16(-32768) == true, + "IntUtil::isInt16<> should return true if inside."); + EXPECT(IntUtil::isInt16(32767) == true, + "IntUtil::isInt16<> should return true if inside."); + EXPECT(IntUtil::isInt16(-32769) == false, + "IntUtil::isInt16<> should return false if outside."); + EXPECT(IntUtil::isInt16(32768) == false, + "IntUtil::isInt16<> should return false if outside."); + + INFO("IntUtil::isUInt16()."); + EXPECT(IntUtil::isUInt16(65535) == true, + "IntUtil::isUInt16<> should return true if inside."); + EXPECT(IntUtil::isUInt16(65536) == false, + "IntUtil::isUInt16<> should return false if outside."); + EXPECT(IntUtil::isUInt16(-1) == false, + "IntUtil::isUInt16<> should return false if negative."); + + INFO("IntUtil::isInt32()."); + EXPECT(IntUtil::isInt32(2147483647) == true, + "IntUtil::isInt32 should return true if inside."); + EXPECT(IntUtil::isInt32(-2147483647 - 1) == true, + "IntUtil::isInt32 should return true if inside."); + EXPECT(IntUtil::isInt32(ASMJIT_UINT64_C(2147483648)) == false, + "IntUtil::isInt32 should return false if outside."); + EXPECT(IntUtil::isInt32(ASMJIT_UINT64_C(0xFFFFFFFF)) == false, + "IntUtil::isInt32 should return false if outside."); + EXPECT(IntUtil::isInt32(ASMJIT_UINT64_C(0xFFFFFFFF) + 1) == false, + "IntUtil::isInt32 should return false if outside."); + + INFO("IntUtil::isUInt32()."); + EXPECT(IntUtil::isUInt32(ASMJIT_UINT64_C(0xFFFFFFFF)) == true, + "IntUtil::isUInt32 should return true if inside."); + EXPECT(IntUtil::isUInt32(ASMJIT_UINT64_C(0xFFFFFFFF) + 1) == false, + "IntUtil::isUInt32 should return false if outside."); + EXPECT(IntUtil::isUInt32(-1) == false, + "IntUtil::isUInt32 should return false if negative."); + + INFO("IntUtil::isPower2()."); + for (i = 0; i < 64; i++) { + EXPECT(IntUtil::isPowerOf2(static_cast(1) << i) == true, + "IntUtil::isPower2() didn't report power of 2."); + EXPECT(IntUtil::isPowerOf2((static_cast(1) << i) ^ 0x001101) == false, + "IntUtil::isPower2() didn't report not power of 2."); + } + + INFO("IntUtil::mask()."); + for (i = 0; i < 32; i++) { + EXPECT(IntUtil::mask(i) == (1 << i), + "IntUtil::mask(%u) should return %X.", i, (1 << i)); + } + + INFO("IntUtil::bits()."); + for (i = 0; i < 32; i++) { + uint32_t expectedBits = 0; + + for (uint32_t b = 0; b < i; b++) + expectedBits |= static_cast(1) << b; + + EXPECT(IntUtil::bits(i) == expectedBits, + "IntUtil::bits(%u) should return %X.", i, expectedBits); + } + + INFO("IntUtil::hasBit()."); + for (i = 0; i < 32; i++) { + EXPECT(IntUtil::hasBit((1 << i), i) == true, + "IntUtil::hasBit(%X, %u) should return true.", (1 << i), i); + } + + INFO("IntUtil::bitCount()."); + for (i = 0; i < 32; i++) { + EXPECT(IntUtil::bitCount((1 << i)) == 1, + "IntUtil::bitCount(%X) should return true.", (1 << i)); + } + EXPECT(IntUtil::bitCount(0x000000F0) == 4, ""); + EXPECT(IntUtil::bitCount(0x10101010) == 4, ""); + EXPECT(IntUtil::bitCount(0xFF000000) == 8, ""); + EXPECT(IntUtil::bitCount(0xFFFFFFF7) == 31, ""); + EXPECT(IntUtil::bitCount(0x7FFFFFFF) == 31, ""); + + INFO("IntUtil::findFirstBit()."); + for (i = 0; i < 32; i++) { + EXPECT(IntUtil::findFirstBit((1 << i)) == i, + "IntUtil::findFirstBit(%X) should return %u.", (1 << i), i); + } + + INFO("IntUtil::isAligned()."); + EXPECT(IntUtil::isAligned(0xFFFF, 4) == false, ""); + EXPECT(IntUtil::isAligned(0xFFF4, 4) == true , ""); + EXPECT(IntUtil::isAligned(0xFFF8, 8) == true , ""); + EXPECT(IntUtil::isAligned(0xFFF0, 16) == true , ""); + + INFO("IntUtil::alignTo()."); + EXPECT(IntUtil::alignTo(0xFFFF, 4) == 0x10000, ""); + EXPECT(IntUtil::alignTo(0xFFF4, 4) == 0x0FFF4, ""); + EXPECT(IntUtil::alignTo(0xFFF8, 8) == 0x0FFF8, ""); + EXPECT(IntUtil::alignTo(0xFFF0, 16) == 0x0FFF0, ""); + EXPECT(IntUtil::alignTo(0xFFF0, 32) == 0x10000, ""); + + INFO("IntUtil::alignToPowerOf2()."); + EXPECT(IntUtil::alignToPowerOf2(0xFFFF) == 0x10000, ""); + EXPECT(IntUtil::alignToPowerOf2(0xF123) == 0x10000, ""); + EXPECT(IntUtil::alignToPowerOf2(0x0F00) == 0x01000, ""); + EXPECT(IntUtil::alignToPowerOf2(0x0100) == 0x00100, ""); + EXPECT(IntUtil::alignToPowerOf2(0x1001) == 0x02000, ""); + + INFO("IntUtil::deltaTo()."); + EXPECT(IntUtil::deltaTo(0xFFFF, 4) == 1, ""); + EXPECT(IntUtil::deltaTo(0xFFF4, 4) == 0, ""); + EXPECT(IntUtil::deltaTo(0xFFF8, 8) == 0, ""); + EXPECT(IntUtil::deltaTo(0xFFF0, 16) == 0, ""); + EXPECT(IntUtil::deltaTo(0xFFF0, 32) == 16, ""); +} +#endif // ASMJIT_TEST + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/intutil.h b/libraries/asmjit/base/intutil.h new file mode 100644 index 000000000..fe56479b7 --- /dev/null +++ b/libraries/asmjit/base/intutil.h @@ -0,0 +1,713 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_INTUTIL_H +#define _ASMJIT_BASE_INTUTIL_H + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +#if defined(_MSC_VER) +#pragma intrinsic(_BitScanForward) +#endif // ASMJIT_OS_WINDOWS + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::IntTraits] +// ============================================================================ + +//! \internal +template +struct IntTraits { + enum { + kIsSigned = static_cast(~static_cast(0)) < static_cast(0), + kIsUnsigned = !kIsSigned, + + kIs8Bit = sizeof(T) == 1, + kIs16Bit = sizeof(T) == 2, + kIs32Bit = sizeof(T) == 4, + kIs64Bit = sizeof(T) == 8, + + kIsIntPtr = sizeof(T) == sizeof(intptr_t) + }; +}; + +// ============================================================================ +// [asmjit::IntUtil] +// ============================================================================ + +//! Integer utilities. +struct IntUtil { + // -------------------------------------------------------------------------- + // [Float <-> Int] + // -------------------------------------------------------------------------- + + //! \internal + union Float { + int32_t i; + float f; + }; + + //! \internal + union Double { + int64_t i; + double d; + }; + + //! Bit-cast `float` to 32-bit integer. + static ASMJIT_INLINE int32_t floatAsInt(float f) { Float m; m.f = f; return m.i; } + //! Bit-cast 32-bit integer to `float`. + static ASMJIT_INLINE float intAsFloat(int32_t i) { Float m; m.i = i; return m.f; } + + //! Bit-cast `double` to 64-bit integer. + static ASMJIT_INLINE int64_t doubleAsInt(double d) { Double m; m.d = d; return m.i; } + //! Bit-cast 64-bit integer to `double`. + static ASMJIT_INLINE double intAsDouble(int64_t i) { Double m; m.i = i; return m.d; } + + // -------------------------------------------------------------------------- + // [AsmJit - Pack / Unpack] + // -------------------------------------------------------------------------- + + //! Pack two 8-bit integer and one 16-bit integer into a 32-bit integer as it + //! is an array of `{u0,u1,w2}`. + static ASMJIT_INLINE uint32_t pack32_2x8_1x16(uint32_t u0, uint32_t u1, uint32_t w2) { +#if defined(ASMJIT_HOST_LE) + return u0 + (u1 << 8) + (w2 << 16); +#else + return (u0 << 24) + (u1 << 16) + (w2); +#endif // ASMJIT_HOST + } + + //! Pack four 8-bit integer into a 32-bit integer as it is an array of `{u0,u1,u2,u3}`. + static ASMJIT_INLINE uint32_t pack32_4x8(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) { +#if defined(ASMJIT_HOST_LE) + return u0 + (u1 << 8) + (u2 << 16) + (u3 << 24); +#else + return (u0 << 24) + (u1 << 16) + (u2 << 8) + u3; +#endif // ASMJIT_HOST + } + + //! Pack two 32-bit integer into a 64-bit integer as it is an array of `{u0,u1}`. + static ASMJIT_INLINE uint64_t pack64_2x32(uint32_t u0, uint32_t u1) { +#if defined(ASMJIT_HOST_LE) + return (static_cast(u1) << 32) + u0; +#else + return (static_cast(u0) << 32) + u1; +#endif // ASMJIT_HOST + } + + // -------------------------------------------------------------------------- + // [AsmJit - Min/Max] + // -------------------------------------------------------------------------- + + // NOTE: Because some environments declare min() and max() as macros, it has + // been decided to use different name so we never collide with them. + + //! Get minimum value of `a` and `b`. + template + static ASMJIT_INLINE T iMin(const T& a, const T& b) { return a < b ? a : b; } + + //! Get maximum value of `a` and `b`. + template + static ASMJIT_INLINE T iMax(const T& a, const T& b) { return a > b ? a : b; } + + // -------------------------------------------------------------------------- + // [AsmJit - MaxUInt] + // -------------------------------------------------------------------------- + + //! Get maximum unsigned value of `T`. + template + static ASMJIT_INLINE T maxUInt() { return ~T(0); } + + // -------------------------------------------------------------------------- + // [AsmJit - InInterval] + // -------------------------------------------------------------------------- + + //! Get whether `x` is greater or equal than `start` and less or equal than `end`. + template + static ASMJIT_INLINE bool inInterval(const T& x, const T& start, const T& end) { + return x >= start && x <= end; + } + + // -------------------------------------------------------------------------- + // [AsmJit - IsInt/IsUInt] + // -------------------------------------------------------------------------- + + //! Get whether the given integer `x` can be casted to 8-bit signed integer. + template + static ASMJIT_INLINE bool isInt8(T x) { + if (IntTraits::kIsSigned) + return sizeof(T) <= sizeof(int8_t) ? true : x >= T(-128) && x <= T(127); + else + return x <= T(127); + } + + //! Get whether the given integer `x` can be casted to 8-bit unsigned integer. + template + static ASMJIT_INLINE bool isUInt8(T x) { + if (IntTraits::kIsSigned) + return x >= T(0) && (sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255)); + else + return sizeof(T) <= sizeof(uint8_t) ? true : x <= T(255); + } + + //! Get whether the given integer `x` can be casted to 16-bit signed integer. + template + static ASMJIT_INLINE bool isInt16(T x) { + if (IntTraits::kIsSigned) + return sizeof(T) <= sizeof(int16_t) ? true : x >= T(-32768) && x <= T(32767); + else + return x >= T(0) && (sizeof(T) <= sizeof(int16_t) ? true : x <= T(32767)); + } + + //! Get whether the given integer `x` can be casted to 16-bit unsigned integer. + template + static ASMJIT_INLINE bool isUInt16(T x) { + if (IntTraits::kIsSigned) + return x >= T(0) && (sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535)); + else + return sizeof(T) <= sizeof(uint16_t) ? true : x <= T(65535); + } + + //! Get whether the given integer `x` can be casted to 32-bit signed integer. + template + static ASMJIT_INLINE bool isInt32(T x) { + if (IntTraits::kIsSigned) + return sizeof(T) <= sizeof(int32_t) ? true : x >= T(-2147483647) - 1 && x <= T(2147483647); + else + return x >= T(0) && (sizeof(T) <= sizeof(int32_t) ? true : x <= T(2147483647)); + } + + //! Get whether the given integer `x` can be casted to 32-bit unsigned integer. + template + static ASMJIT_INLINE bool isUInt32(T x) { + if (IntTraits::kIsSigned) + return x >= T(0) && (sizeof(T) <= sizeof(uint32_t) ? true : x <= T(4294967295U)); + else + return sizeof(T) <= sizeof(uint32_t) ? true : x <= T(4294967295U); + } + + // -------------------------------------------------------------------------- + // [AsmJit - IsPowerOf2] + // -------------------------------------------------------------------------- + + //! Get whether the `n` value is a power of two (only one bit is set). + template + static ASMJIT_INLINE bool isPowerOf2(T n) { + return n != 0 && (n & (n - 1)) == 0; + } + + // -------------------------------------------------------------------------- + // [AsmJit - Mask] + // -------------------------------------------------------------------------- + + //! Generate a bit-mask that has `x` bit set. + static ASMJIT_INLINE uint32_t mask(uint32_t x) { + ASMJIT_ASSERT(x < 32); + return (1U << x); + } + + //! Generate a bit-mask that has `x0` and `x1` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1) { + return mask(x0) | mask(x1); + } + + //! Generate a bit-mask that has `x0`, `x1` and `x2` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2) { + return mask(x0) | mask(x1) | mask(x2); + } + + //! Generate a bit-mask that has `x0`, `x1`, `x2` and `x3` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) { + return mask(x0) | mask(x1) | mask(x2) | mask(x3); + } + + //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3` and `x4` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4) { + return mask(x0) | mask(x1) | mask(x2) | mask(x3) | + mask(x4) ; + } + + //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4` and `x5` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5) { + return mask(x0) | mask(x1) | mask(x2) | mask(x3) | + mask(x4) | mask(x5) ; + } + + //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5` and `x6` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6) { + return mask(x0) | mask(x1) | mask(x2) | mask(x3) | + mask(x4) | mask(x5) | mask(x6) ; + } + + //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6` and `x7` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) { + return mask(x0) | mask(x1) | mask(x2) | mask(x3) | + mask(x4) | mask(x5) | mask(x6) | mask(x7) ; + } + + //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7` and `x8` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8) { + return mask(x0) | mask(x1) | mask(x2) | mask(x3) | + mask(x4) | mask(x5) | mask(x6) | mask(x7) | + mask(x8) ; + } + + //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7`, `x8` and `x9` bits set. + static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8, uint32_t x9) { + return mask(x0) | mask(x1) | mask(x2) | mask(x3) | + mask(x4) | mask(x5) | mask(x6) | mask(x7) | + mask(x8) | mask(x9) ; + } + + // -------------------------------------------------------------------------- + // [AsmJit - Bits] + // -------------------------------------------------------------------------- + + //! Generate a bit-mask that has `x` most significant bits set. + static ASMJIT_INLINE uint32_t bits(uint32_t x) { + // Shifting more bits that the type has has undefined behavior. Everything + // we need is that application shouldn't crash because of that, but the + // content of register after shift is not defined. So in case that the + // requested shift is too large for the type we correct this undefined + // behavior by setting all bits to ones (this is why we generate an overflow + // mask). + uint32_t overflow = static_cast( + -static_cast(x >= sizeof(uint32_t) * 8)); + + return ((static_cast(1) << x) - 1U) | overflow; + } + + // -------------------------------------------------------------------------- + // [AsmJit - HasBit] + // -------------------------------------------------------------------------- + + //! Get whether `x` has bit `n` set. + static ASMJIT_INLINE bool hasBit(uint32_t x, uint32_t n) { + return static_cast((x >> n) & 0x1); + } + + // -------------------------------------------------------------------------- + // [AsmJit - BitCount] + // -------------------------------------------------------------------------- + + //! Get count of bits in `x`. + //! + //! Taken from http://graphics.stanford.edu/~seander/bithacks.html . + static ASMJIT_INLINE uint32_t bitCount(uint32_t x) { + x = x - ((x >> 1) & 0x55555555U); + x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U); + return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24; + } + + // -------------------------------------------------------------------------- + // [AsmJit - FindFirstBit] + // -------------------------------------------------------------------------- + + //! \internal + static ASMJIT_INLINE uint32_t findFirstBitSlow(uint32_t mask) { + // This is a reference (slow) implementation of findFirstBit(), used when + // we don't have compiler support for this task. The implementation speed + // has been improved to check for 2 bits per iteration. + uint32_t i = 1; + + while (mask != 0) { + uint32_t two = mask & 0x3; + if (two != 0x0) + return i - (two & 0x1); + + i += 2; + mask >>= 2; + } + + return 0xFFFFFFFFU; + } + + //! Find a first bit in `mask`. + static ASMJIT_INLINE uint32_t findFirstBit(uint32_t mask) { +#if defined(_MSC_VER) + DWORD i; + if (_BitScanForward(&i, mask)) { + ASMJIT_ASSERT(findFirstBitSlow(mask) == i); + return static_cast(i); + } + return 0xFFFFFFFFU; +#else + return findFirstBitSlow(mask); +#endif + } + + // -------------------------------------------------------------------------- + // [AsmJit - Misc] + // -------------------------------------------------------------------------- + + static ASMJIT_INLINE uint32_t keepNOnesFromRight(uint32_t mask, uint32_t nBits) { + uint32_t m = 0x1; + + do { + nBits -= (mask & m) == 0; + m <<= 1; + if (nBits == 0) { + m -= 1; + mask &= m; + break; + } + } while (m); + + return mask; + } + + static ASMJIT_INLINE uint32_t indexNOnesFromRight(uint8_t* dst, uint32_t mask, uint32_t nBits) { + uint32_t totalBits = nBits; + uint8_t i = 0; + uint32_t m = 0x1; + + do { + if (mask & m) { + *dst++ = i; + if (--nBits == 0) + break; + } + + m <<= 1; + i++; + } while (m); + + return totalBits - nBits; + } + + // -------------------------------------------------------------------------- + // [AsmJit - Alignment] + // -------------------------------------------------------------------------- + + template + static ASMJIT_INLINE bool isAligned(T base, T alignment) { + return (base % alignment) == 0; + } + + //! Align `base` to `alignment`. + template + static ASMJIT_INLINE T alignTo(T base, T alignment) { + return (base + (alignment - 1)) & ~(alignment - 1); + } + + template + static ASMJIT_INLINE T alignToPowerOf2(T base) { + // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr. + base -= 1; + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4293) +#endif // _MSC_VER + + base = base | (base >> 1); + base = base | (base >> 2); + base = base | (base >> 4); + + // 8/16/32 constants are multiplied by the condition to prevent a compiler + // complaining about the 'shift count >= type width' (GCC). + if (sizeof(T) >= 2) base = base | (base >> ( 8 * (sizeof(T) >= 2))); // Base >> 8. + if (sizeof(T) >= 4) base = base | (base >> (16 * (sizeof(T) >= 4))); // Base >> 16. + if (sizeof(T) >= 8) base = base | (base >> (32 * (sizeof(T) >= 8))); // Base >> 32. + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif // _MSC_VER + + return base + 1; + } + + //! Get delta required to align `base` to `alignment`. + template + static ASMJIT_INLINE T deltaTo(T base, T alignment) { + return alignTo(base, alignment) - base; + } +}; + +// ============================================================================ +// [asmjit::UInt64] +// ============================================================================ + +union UInt64 { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64 fromUInt64(uint64_t val) { + UInt64 data; + data.setUInt64(val); + return data; + } + + ASMJIT_INLINE UInt64 fromUInt64(const UInt64& val) { + UInt64 data; + data.setUInt64(val); + return data; + } + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + if (kArchHost64Bit) { + u64 = 0; + } + else { + u32[0] = 0; + u32[1] = 0; + } + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint64_t getUInt64() const { + return u64; + } + + ASMJIT_INLINE UInt64& setUInt64(uint64_t val) { + u64 = val; + return *this; + } + + ASMJIT_INLINE UInt64& setUInt64(const UInt64& val) { + if (kArchHost64Bit) { + u64 = val.u64; + } + else { + u32[0] = val.u32[0]; + u32[1] = val.u32[1]; + } + return *this; + } + + ASMJIT_INLINE UInt64& setPacked_2x32(uint32_t u0, uint32_t u1) { + if (kArchHost64Bit) { + u64 = IntUtil::pack64_2x32(u0, u1); + } + else { + u32[0] = u0; + u32[1] = u1; + } + return *this; + } + + // -------------------------------------------------------------------------- + // [Add] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& add(uint64_t val) { + u64 += val; + return *this; + } + + ASMJIT_INLINE UInt64& add(const UInt64& val) { + if (kArchHost64Bit) { + u64 += val.u64; + } + else { + u32[0] += val.u32[0]; + u32[1] += val.u32[1]; + } + return *this; + } + + // -------------------------------------------------------------------------- + // [Sub] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& sub(uint64_t val) { + u64 -= val; + return *this; + } + + ASMJIT_INLINE UInt64& sub(const UInt64& val) { + if (kArchHost64Bit) { + u64 -= val.u64; + } + else { + u32[0] -= val.u32[0]; + u32[1] -= val.u32[1]; + } + return *this; + } + + // -------------------------------------------------------------------------- + // [And] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& and_(uint64_t val) { + u64 &= val; + return *this; + } + + ASMJIT_INLINE UInt64& and_(const UInt64& val) { + if (kArchHost64Bit) { + u64 &= val.u64; + } + else { + u32[0] &= val.u32[0]; + u32[1] &= val.u32[1]; + } + return *this; + } + + // -------------------------------------------------------------------------- + // [Or] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& or_(uint64_t val) { + u64 |= val; + return *this; + } + + ASMJIT_INLINE UInt64& or_(const UInt64& val) { + if (kArchHost64Bit) { + u64 |= val.u64; + } + else { + u32[0] |= val.u32[0]; + u32[1] |= val.u32[1]; + } + return *this; + } + + // -------------------------------------------------------------------------- + // [Xor] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& xor_(uint64_t val) { + u64 ^= val; + return *this; + } + + ASMJIT_INLINE UInt64& xor_(const UInt64& val) { + if (kArchHost64Bit) { + u64 ^= val.u64; + } + else { + u32[0] ^= val.u32[0]; + u32[1] ^= val.u32[1]; + } + return *this; + } + + // -------------------------------------------------------------------------- + // [Del] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& del(uint64_t val) { + u64 &= ~val; + return *this; + } + + ASMJIT_INLINE UInt64& del(const UInt64& val) { + if (kArchHost64Bit) { + u64 &= ~val.u64; + } + else { + u32[0] &= ~val.u32[0]; + u32[1] &= ~val.u32[1]; + } + return *this; + } + + // -------------------------------------------------------------------------- + // [Eq] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isZero() const { + return kArchHost64Bit ? u64 == 0 : (u32[0] | u32[1]) == 0; + } + + ASMJIT_INLINE bool isNonZero() const { + return kArchHost64Bit ? u64 != 0 : (u32[0] | u32[1]) != 0; + } + + ASMJIT_INLINE bool eq(uint64_t val) const { + return u64 == val; + } + + ASMJIT_INLINE bool eq(const UInt64& val) const { + return kArchHost64Bit ? u64 == val.u64 : (u32[0] == val.u32[0]) & (u32[1] == val.u32[1]); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& operator+=(uint64_t val) { return add(val); } + ASMJIT_INLINE UInt64& operator+=(const UInt64& val) { return add(val); } + + ASMJIT_INLINE UInt64& operator-=(uint64_t val) { return sub(val); } + ASMJIT_INLINE UInt64& operator-=(const UInt64& val) { return sub(val); } + + ASMJIT_INLINE UInt64& operator&=(uint64_t val) { return and_(val); } + ASMJIT_INLINE UInt64& operator&=(const UInt64& val) { return and_(val); } + + ASMJIT_INLINE UInt64& operator|=(uint64_t val) { return or_(val); } + ASMJIT_INLINE UInt64& operator|=(const UInt64& val) { return or_(val); } + + ASMJIT_INLINE UInt64& operator^=(uint64_t val) { return xor_(val); } + ASMJIT_INLINE UInt64& operator^=(const UInt64& val) { return xor_(val); } + + ASMJIT_INLINE bool operator==(uint64_t val) const { return eq(val); } + ASMJIT_INLINE bool operator==(const UInt64& val) const { return eq(val); } + + ASMJIT_INLINE bool operator!=(uint64_t val) const { return !eq(val); } + ASMJIT_INLINE bool operator!=(const UInt64& val) const { return !eq(val); } + + ASMJIT_INLINE bool operator<(uint64_t val) const { return u64 < val; } + ASMJIT_INLINE bool operator<(const UInt64& val) const { return u64 < val.u64; } + + ASMJIT_INLINE bool operator<=(uint64_t val) const { return u64 <= val; } + ASMJIT_INLINE bool operator<=(const UInt64& val) const { return u64 <= val.u64; } + + ASMJIT_INLINE bool operator>(uint64_t val) const { return u64 > val; } + ASMJIT_INLINE bool operator>(const UInt64& val) const { return u64 > val.u64; } + + ASMJIT_INLINE bool operator>=(uint64_t val) const { return u64 >= val; } + ASMJIT_INLINE bool operator>=(const UInt64& val) const { return u64 >= val.u64; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uint64_t u64; + + uint32_t u32[2]; + uint16_t u16[4]; + uint8_t u8[8]; + + struct { +#if defined(ASMJIT_HOST_LE) + uint32_t lo, hi; +#else + uint32_t hi, lo; +#endif // ASMJIT_HOST_LE + }; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_INTUTIL_H diff --git a/libraries/asmjit/base/lock.h b/libraries/asmjit/base/lock.h new file mode 100644 index 000000000..f2e2042ac --- /dev/null +++ b/libraries/asmjit/base/lock.h @@ -0,0 +1,131 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_LOCK_H +#define _ASMJIT_BASE_LOCK_H + +// [Dependencies - AsmJit] +#include "../build.h" + +// [Dependencies - Posix] +#if defined(ASMJIT_OS_POSIX) +# include +#endif // ASMJIT_OS_POSIX + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::Lock] +// ============================================================================ + +//! Lock - used in thread-safe code for locking. +struct Lock { + ASMJIT_NO_COPY(Lock) + + // -------------------------------------------------------------------------- + // [Windows] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_OS_WINDOWS) + typedef CRITICAL_SECTION Handle; + + //! Create a new `Lock` instance. + ASMJIT_INLINE Lock() { InitializeCriticalSection(&_handle); } + //! Destroy the `Lock` instance. + ASMJIT_INLINE ~Lock() { DeleteCriticalSection(&_handle); } + + //! Lock. + ASMJIT_INLINE void lock() { EnterCriticalSection(&_handle); } + //! Unlock. + ASMJIT_INLINE void unlock() { LeaveCriticalSection(&_handle); } + +#endif // ASMJIT_OS_WINDOWS + + // -------------------------------------------------------------------------- + // [Posix] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_OS_POSIX) + typedef pthread_mutex_t Handle; + + //! Create a new `Lock` instance. + ASMJIT_INLINE Lock() { pthread_mutex_init(&_handle, NULL); } + //! Destroy the `Lock` instance. + ASMJIT_INLINE ~Lock() { pthread_mutex_destroy(&_handle); } + + //! Lock. + ASMJIT_INLINE void lock() { pthread_mutex_lock(&_handle); } + //! Unlock. + ASMJIT_INLINE void unlock() { pthread_mutex_unlock(&_handle); } +#endif // ASMJIT_OS_POSIX + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get handle. + ASMJIT_INLINE Handle& getHandle() { + return _handle; + } + //! \overload + ASMJIT_INLINE const Handle& getHandle() const { + return _handle; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Handle. + Handle _handle; +}; + +// ============================================================================ +// [asmjit::AutoLock] +// ============================================================================ + +//! Scoped lock. +struct AutoLock { + ASMJIT_NO_COPY(AutoLock) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Autolock `target`, scoped. + ASMJIT_INLINE AutoLock(Lock& target) : _target(target) { + _target.lock(); + } + + //! Autounlock `target`. + ASMJIT_INLINE ~AutoLock() { + _target.unlock(); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Pointer to target (lock). + Lock& _target; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_LOCK_H diff --git a/libraries/asmjit/base/logger.cpp b/libraries/asmjit/base/logger.cpp new file mode 100644 index 000000000..23a4de333 --- /dev/null +++ b/libraries/asmjit/base/logger.cpp @@ -0,0 +1,167 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if !defined(ASMJIT_DISABLE_LOGGER) + +// [Dependencies - AsmJit] +#include "../base/intutil.h" +#include "../base/logger.h" +#include "../base/string.h" + +// [Dependencies - C] +#include + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::Logger - Construction / Destruction] +// ============================================================================ + +Logger::Logger() { + _options = 0; + ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation)); +} + +Logger::~Logger() {} + +// ============================================================================ +// [asmjit::Logger - Logging] +// ============================================================================ + +void Logger::logFormat(uint32_t style, const char* fmt, ...) { + char buf[1024]; + size_t len; + + va_list ap; + va_start(ap, fmt); + len = vsnprintf(buf, 1023, fmt, ap); + va_end(ap); + + logString(style, buf, len); +} + +void Logger::logBinary(uint32_t style, const void* data, size_t size) { + static const char prefix[] = ".data "; + static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + const uint8_t* s = static_cast(data); + size_t i = size; + + char buffer[128]; + ::memcpy(buffer, prefix, ASMJIT_ARRAY_SIZE(prefix) - 1); + + while (i) { + uint32_t n = static_cast(IntUtil::iMin(i, 16)); + char* p = buffer + ASMJIT_ARRAY_SIZE(prefix) - 1; + + i -= n; + do { + uint32_t c = s[0]; + + p[0] = hex[c >> 4]; + p[1] = hex[c & 15]; + + p += 2; + s += 1; + } while (--n); + + *p++ = '\n'; + logString(style, buffer, (size_t)(p - buffer)); + } +} + +// ============================================================================ +// [asmjit::Logger - LogBinary] +// ============================================================================ + +void Logger::setOption(uint32_t id, bool value) { + if (id >= kLoggerOptionCount) + return; + + uint32_t mask = 1 << id; + + if (value) + _options |= mask; + else + _options &= ~mask; +} + +// ============================================================================ +// [asmjit::Logger - Indentation] +// ============================================================================ + +void Logger::setIndentation(const char* indentation) { + ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation)); + if (!indentation) + return; + + size_t length = StringUtil::nlen(indentation, ASMJIT_ARRAY_SIZE(_indentation) - 1); + ::memcpy(_indentation, indentation, length); +} + +// ============================================================================ +// [asmjit::FileLogger - Construction / Destruction] +// ============================================================================ + +FileLogger::FileLogger(FILE* stream) : _stream(NULL) { + setStream(stream); +} + +FileLogger::~FileLogger() {} + +// ============================================================================ +// [asmjit::FileLogger - Accessors] +// ============================================================================ + +//! Set file stream. +void FileLogger::setStream(FILE* stream) { + _stream = stream; +} + +// ============================================================================ +// [asmjit::FileLogger - Logging] +// ============================================================================ + +void FileLogger::logString(uint32_t style, const char* buf, size_t len) { + if (!_stream) + return; + + if (len == kInvalidIndex) + len = strlen(buf); + + fwrite(buf, 1, len, _stream); +} + +// ============================================================================ +// [asmjit::StringLogger - Construction / Destruction] +// ============================================================================ + +StringLogger::StringLogger() {} +StringLogger::~StringLogger() {} + +// ============================================================================ +// [asmjit::StringLogger - Logging] +// ============================================================================ + +void StringLogger::logString(uint32_t style, const char* buf, size_t len) { + _stringBuilder.appendString(buf, len); +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_LOGGER diff --git a/libraries/asmjit/base/logger.h b/libraries/asmjit/base/logger.h new file mode 100644 index 000000000..eb940b823 --- /dev/null +++ b/libraries/asmjit/base/logger.h @@ -0,0 +1,246 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_LOGGER_H +#define _ASMJIT_BASE_LOGGER_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_LOGGER) + +// [Dependencies - AsmJit] +#include "../base/string.h" + +// [Dependencies - C] +#include + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::kLoggerOption] +// ============================================================================ + +//! Logger options. +ASMJIT_ENUM(kLoggerOption) { + //! Whether to output instructions also in binary form. + kLoggerOptionBinaryForm = 0, + + //! Whether to output immediates as hexadecimal numbers. + kLoggerOptionHexImmediate = 1, + //! Whether to output displacements as hexadecimal numbers. + kLoggerOptionHexDisplacement = 2, + + //! Count of logger options. + kLoggerOptionCount = 3 +}; + +// ============================================================================ +// [asmjit::kLoggerStyle] +// ============================================================================ + +//! Logger style. +ASMJIT_ENUM(kLoggerStyle) { + kLoggerStyleDefault = 0, + kLoggerStyleDirective = 1, + kLoggerStyleLabel = 2, + kLoggerStyleData = 3, + kLoggerStyleComment = 4, + + kLoggerStyleCount = 5 +}; + +// ============================================================================ +// [asmjit::Logger] +// ============================================================================ + +//! Abstract logging class. +//! +//! This class can be inherited and reimplemented to fit into your logging +//! subsystem. When reimplementing use `Logger::log()` method to log into +//! a custom stream. +//! +//! This class also contain `_enabled` member that can be used to enable +//! or disable logging. +struct ASMJIT_VCLASS Logger { + ASMJIT_NO_COPY(Logger) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `Logger` instance. + ASMJIT_API Logger(); + //! Destroy the `Logger` instance. + ASMJIT_API virtual ~Logger(); + + // -------------------------------------------------------------------------- + // [Logging] + // -------------------------------------------------------------------------- + + //! Log output. + virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex) = 0; + + //! Log formatter message (like sprintf) sending output to `logString()` method. + ASMJIT_API void logFormat(uint32_t style, const char* fmt, ...); + //! Log binary data. + ASMJIT_API void logBinary(uint32_t style, const void* data, size_t size); + + // -------------------------------------------------------------------------- + // [Options] + // -------------------------------------------------------------------------- + + //! Get all logger options as a single integer. + ASMJIT_INLINE uint32_t getOptions() const { + return _options; + } + + //! Get the given logger option. + ASMJIT_INLINE bool getOption(uint32_t id) const { + ASMJIT_ASSERT(id < kLoggerOptionCount); + return static_cast((_options >> id) & 0x1); + } + + //! Set the given logger option. + ASMJIT_API void setOption(uint32_t id, bool value); + + // -------------------------------------------------------------------------- + // [Indentation] + // -------------------------------------------------------------------------- + + //! Get indentation. + ASMJIT_INLINE const char* getIndentation() const { + return _indentation; + } + + //! Set indentation. + ASMJIT_API void setIndentation(const char* indentation); + + //! Reset indentation. + ASMJIT_INLINE void resetIndentation() { + setIndentation(NULL); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Options, see `kLoggerOption`. + uint32_t _options; + + //! Indentation. + char _indentation[12]; +}; + +// ============================================================================ +// [asmjit::FileLogger] +// ============================================================================ + +//! Logger that can log to standard C `FILE*` stream. +struct ASMJIT_VCLASS FileLogger : public Logger { + ASMJIT_NO_COPY(FileLogger) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `FileLogger` that logs to a `FILE` stream. + ASMJIT_API FileLogger(FILE* stream = NULL); + + //! Destroy the `FileLogger`. + ASMJIT_API virtual ~FileLogger(); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get `FILE*` stream. + //! + //! \note Return value can be `NULL`. + ASMJIT_INLINE FILE* getStream() const { return _stream; } + + //! Set `FILE*` stream, can be set to `NULL` to disable logging, although + //! the `CodeGen` will still call `logString` even if there is no stream. + ASMJIT_API void setStream(FILE* stream); + + // -------------------------------------------------------------------------- + // [Logging] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! C file stream. + FILE* _stream; +}; + +// ============================================================================ +// [asmjit::StringLogger] +// ============================================================================ + +//! String logger. +struct ASMJIT_VCLASS StringLogger : public Logger { + ASMJIT_NO_COPY(StringLogger) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create new `StringLogger`. + ASMJIT_API StringLogger(); + + //! Destroy the `StringLogger`. + ASMJIT_API virtual ~StringLogger(); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get char* pointer which represents the resulting + //! string. + //! + //! The pointer is owned by `StringLogger`, it can't be modified or freed. + ASMJIT_INLINE const char* getString() const { + return _stringBuilder.getData(); + } + + //! Clear the resulting string. + ASMJIT_INLINE void clearString() { + _stringBuilder.clear(); + } + + // -------------------------------------------------------------------------- + // [Logging] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual void logString(uint32_t style, const char* buf, size_t len = kInvalidIndex); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Output. + StringBuilder _stringBuilder; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_LOGGER +#endif // _ASMJIT_BASE_LOGGER_H diff --git a/libraries/asmjit/base/operand.cpp b/libraries/asmjit/base/operand.cpp new file mode 100644 index 000000000..04a84936e --- /dev/null +++ b/libraries/asmjit/base/operand.cpp @@ -0,0 +1,38 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::Operand] +// ============================================================================ + +// Prevent static initialization. +struct Operand { + uint8_t op; + uint8_t size; + uint8_t reserved_2_1; + uint8_t reserved_3_1; + uint32_t id; + uint64_t reserved_8_8; +}; + +ASMJIT_VAR const Operand noOperand; +const Operand noOperand = { 0, 0, 0, 0, kInvalidValue, 0 }; + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/operand.h b/libraries/asmjit/base/operand.h new file mode 100644 index 000000000..4553e3399 --- /dev/null +++ b/libraries/asmjit/base/operand.h @@ -0,0 +1,1090 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_OPERAND_H +#define _ASMJIT_BASE_OPERAND_H + +// [Dependencies - AsmJit] +#include "../base/intutil.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct Assembler; +struct Compiler; + +//! \addtogroup asmjit_base_general +//! \{ + +// ============================================================================ +// [asmjit::kOperandType] +// ============================================================================ + +//! Operand types that can be encoded in `Operand`. +ASMJIT_ENUM(kOperandType) { + //! Invalid operand, used only internally (not initialized Operand). + kOperandTypeNone = 0, + //! Operand is a register. + kOperandTypeReg = 1, + //! Operand is a variable. + kOperandTypeVar = 2, + //! Operand is a memory. + kOperandTypeMem = 3, + //! Operand is an immediate value. + kOperandTypeImm = 4, + //! Operand is a label. + kOperandTypeLabel = 5 +}; + +// ============================================================================ +// [asmjit::kOperandId] +// ============================================================================ + +//! Operand id masks used to determine the operand type. +ASMJIT_ENUM(kOperandId) { + //! Operand id refers to `Var`. + kOperandIdVar = 0x80000000U, + //! Operand id to real index mask. + kOperandIdNum = 0x7FFFFFFFU +}; + +// ============================================================================ +// [asmjit::kRegClass] +// ============================================================================ + +//! Register class. +ASMJIT_ENUM(kRegClass) { + //! Gp register class, compatible with all architectures. + kRegClassGp = 0 +}; + +// ============================================================================ +// [asmjit::kSize] +// ============================================================================ + +//! Common size of registers and pointers. +ASMJIT_ENUM(kSize) { + //! 1 byte size (BYTE). + kSizeByte = 1, + //! 2 bytes size (WORD). + kSizeWord = 2, + //! 4 bytes size (DWORD). + kSizeDWord = 4, + //! 8 bytes size (QWORD). + kSizeQWord = 8, + //! 10 bytes size (TWORD). + kSizeTWord = 10, + //! 16 bytes size (OWORD / DQWORD). + kSizeOWord = 16, + //! 32 bytes size (YWORD / QQWORD). + kSizeYWord = 32 +}; + +// ============================================================================ +// [asmjit::kMemType] +// ============================================================================ + +//! Type of memory operand. +ASMJIT_ENUM(kMemType) { + //! Memory operand is a combination of base register and optional index register + //! and displacement. + //! + //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex` + //! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as + //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`. + kMemTypeBaseIndex = 0, + + //! Memory operand is a combination of variable's memory location, + //! optional index register and displacement. + //! + //! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex` + //! types in the same way, but `Compiler` interprets `kMemTypeBaseIndex` as + //! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`. + kMemTypeStackIndex = 1, + + //! Memory operand refers to the memory location specified by a label. + kMemTypeLabel = 2, + //! Memory operand is an absolute memory location. + //! + //! Supported mostly by x86, truncated to a 32-bit value when running in + //! 64-bit mode (x64). + kMemTypeAbsolute = 3 +}; + +// ============================================================================ +// [asmjit::Operand] +// ============================================================================ + +//! Operand can contain register, memory location, immediate, or label. +struct Operand { + // -------------------------------------------------------------------------- + // [Structs] + // -------------------------------------------------------------------------- + + //! \internal + //! + //! Base operand data. + struct BaseOp { + //! Type of operand, see `kOperandType`. + uint8_t op; + //! Size of operand (register, address, immediate, or variable). + uint8_t size; + //! \internal + uint8_t reserved_2_1; + //! \internal + uint8_t reserved_3_1; + + //! Operand id, identifier used by `Assembler` and `Compiler`. + //! + //! \note Uninitialized operand has always set id to `kInvalidValue`. + uint32_t id; + + //! \internal + uint32_t reserved_8_4; + //! \internal + uint32_t reserved_12_4; + }; + + //! \internal + //! + //! Register or Variable operand data. + struct VRegOp { + //! Type of operand, `kOperandTypeReg`. + uint8_t op; + //! Size of register or variable. + uint8_t size; + + union { + //! Register code = (type << 8) | index. + uint16_t code; + + //! Register type and index access. + struct { +#if defined(ASMJIT_HOST_LE) + //! Register index. + uint8_t index; + //! Register type. + uint8_t type; +#else + //! Register type. + uint8_t type; + //! Register index. + uint8_t index; +#endif // ASMJIT_HOST + }; + }; + + //! Variable id, used by `Compiler` to identify variables. + uint32_t id; + + union { + struct { + //! Variable type. + uint32_t vType; + //! \internal + uint32_t reserved_12_4; + }; + + //! \internal + //! + //! This is not needed or used, it's just to force compiler to always + //! align this struct to 8-bytes (so the struct is compatible to others + //! when it comes to alignment). It should fix VS linker warning as well. + uint64_t reserved8_8; + }; + }; + + //! \internal + //! + //! Memory or Variable operand data. + struct VMemOp { + //! Type of operand, `kOperandTypeMem`. + uint8_t op; + //! Size of the pointer in bytes. + uint8_t size; + //! Type of the memory operand, see `kMemType`. + uint8_t type; + //! X86/X64 layout: + //! - segment [3 bits], see `kX86Seg`. + //! - shift [2 bits], index register shift (0 to 3). + uint8_t flags; + + //! Base register, variable or label id. + uint32_t base; + //! Index register or variable. + uint32_t index; + //! 32-bit displacement or absolute address. + int32_t displacement; + }; + + //! \internal + //! + //! Immediate operand data. + struct ImmOp { + //! Type of operand, `kOperandTypeImm`. + uint8_t op; + //! Size of immediate (or 0 to autodetect). + uint8_t size; + //! \internal + uint8_t reserved_2_1; + //! \internal + uint8_t reserved_3_1; + + //! Operand id, always set to `kInvalidValue` (immediates don't have IDs). + uint32_t id; + + union { + //! 8x8-bit signed immediate values. + int8_t _i8[8]; + //! 8x8-bit unsigned immediate values. + uint8_t _u8[8]; + + //! 4x16-bit signed immediate values. + int16_t _i16[4]; + //! 4x16-bit unsigned immediate values. + uint16_t _u16[4]; + + //! 2x32-bit signed immediate values. + int32_t _i32[2]; + //! 2x32-bit unsigned immediate values. + uint32_t _u32[2]; + + //! 1x64-bit signed immediate value. + int64_t _i64[1]; + //! 1x64-bit unsigned immediate value. + uint64_t _u64[1]; + + //! 2x SP-FP values. + float _f32[2]; + //! 1x DP-FP value. + double _f64[1]; + } value; + }; + + //! \internal + //! + //! Label operand data. + struct LabelOp { + //! Type of operand, `kOperandTypeLabel`. + uint8_t op; + //! Always zero, labels don't have size. + uint8_t size; + //! \internal + uint8_t reserved_2_1; + //! \internal + uint8_t reserved_3_1; + + //! Operand id (`kInvalidValue` if the label is not initialized by code + //! generator). + uint32_t id; + + //! \internal + uint32_t reserved_8_4; + //! \internal + uint32_t reserved_12_4; + }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create an uninitialized operand. + ASMJIT_INLINE Operand() { + _init_packed_op_sz_b0_b1_id(kOperandTypeNone, 0, 0, 0, kInvalidValue); + _init_packed_d2_d3(0, 0); + } + + //! Create a reference to `other` operand. + ASMJIT_INLINE Operand(const Operand& other) { + _init(other); + } + + explicit ASMJIT_INLINE Operand(const _NoInit&) {} + + // -------------------------------------------------------------------------- + // [Operand] + // -------------------------------------------------------------------------- + + //! Clone `Operand`. + ASMJIT_INLINE Operand clone() const { + return Operand(*this); + } + + // -------------------------------------------------------------------------- + // [Init & Copy] + // -------------------------------------------------------------------------- + + //! \internal + //! + //! Initialize operand to `other` (used by constructors). + ASMJIT_INLINE void _init(const Operand& other) { + ::memcpy(this, &other, sizeof(Operand)); + } + + ASMJIT_INLINE void _init_packed_op_sz_b0_b1_id(uint32_t op, uint32_t sz, uint32_t r0, uint32_t r1, uint32_t id) { + // This hack is not for performance, but to decrease the size of the binary + // generated when constructing AsmJit operands (mostly for third parties). + // Some compilers are not able to join four BYTE writes to a single DWORD + // write. Because the 'a', 'b', 'c' and 'd' variables are usually compile + // time constants the compiler can do a really nice job if they are joined + // by using bitwise operations. + _packed[0].setPacked_2x32(IntUtil::pack32_4x8(op, sz, r0, r1), id); + } + + ASMJIT_INLINE void _init_packed_op_sz_w0_id(uint32_t op, uint32_t sz, uint32_t w0, uint32_t id) { + _packed[0].setPacked_2x32(IntUtil::pack32_2x8_1x16(op, sz, w0), id); + } + + ASMJIT_INLINE void _init_packed_d0_d1(uint32_t u0, uint32_t u1) { + _packed[0].setPacked_2x32(u0, u1); + } + + ASMJIT_INLINE void _init_packed_d2_d3(uint32_t u2, uint32_t u3) { + _packed[1].setPacked_2x32(u2, u3); + } + + //! \internal + //! + //! Initialize operand to `other` (used by assign operators). + ASMJIT_INLINE void _copy(const Operand& other) { + ::memcpy(this, &other, sizeof(Operand)); + } + + // -------------------------------------------------------------------------- + // [Data] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE T& getData() { + return reinterpret_cast(_base); + } + + template + ASMJIT_INLINE const T& getData() const { + return reinterpret_cast(_base); + } + + // -------------------------------------------------------------------------- + // [Type] + // -------------------------------------------------------------------------- + + //! Get type of the operand, see `kOperandType`. + ASMJIT_INLINE uint32_t getOp() const { return _base.op; } + + //! Get whether the operand is none - `kOperandTypeNone`. + ASMJIT_INLINE bool isNone() const { return (_base.op == kOperandTypeNone); } + //! Get whether the operand is a register - `kOperandTypeReg`. + ASMJIT_INLINE bool isReg() const { return (_base.op == kOperandTypeReg); } + //! Get whether the operand is a variable - `kOperandTypeVar`. + ASMJIT_INLINE bool isVar() const { return (_base.op == kOperandTypeVar); } + //! Get whether the operand is a memory address - `kOperandTypeMem`. + ASMJIT_INLINE bool isMem() const { return (_base.op == kOperandTypeMem); } + //! Get whether the operand is an immediate value - `kOperandTypeImm`. + ASMJIT_INLINE bool isImm() const { return (_base.op == kOperandTypeImm); } + //! Get whether the operand is a label - `kOperandTypeLabel`. + ASMJIT_INLINE bool isLabel() const { return (_base.op == kOperandTypeLabel); } + + // -------------------------------------------------------------------------- + // [Type - Combined] + // -------------------------------------------------------------------------- + + //! Get register type. + ASMJIT_INLINE uint32_t getRegType() const { + return _vreg.type; + } + + //! Get register index. + ASMJIT_INLINE uint32_t getRegIndex() const { + return _vreg.index; + } + + //! Get whether the operand is register of `type`. + ASMJIT_INLINE bool isRegType(uint32_t type) const { + return (_packed[0].u32[0] & IntUtil::pack32_2x8_1x16(0xFF, 0, 0xFF00)) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 0, (type << 8)); + } + + //! Get whether the operand is register and of `type` and `index`. + ASMJIT_INLINE bool isRegCode(uint32_t type, uint32_t index) const { + return (_packed[0].u32[0] & IntUtil::pack32_2x8_1x16(0xFF, 0, 0xFFFF)) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 0, (type << 8) + index); + } + + //! Get whether the operand is a register or memory. + ASMJIT_INLINE bool isRegOrMem() const { + ASMJIT_ASSERT(kOperandTypeReg == 1); + ASMJIT_ASSERT(kOperandTypeMem == 3); + return (static_cast(_base.op) | 0x2U) == 0x3U; + } + + //! Get whether the operand is variable or memory. + ASMJIT_INLINE bool isVarOrMem() const { + ASMJIT_ASSERT(kOperandTypeVar == 2); + ASMJIT_ASSERT(kOperandTypeMem == 3); + return (static_cast(_base.op) - 2U) <= 1; + } + + // -------------------------------------------------------------------------- + // [Size] + // -------------------------------------------------------------------------- + + //! Get size of the operand in bytes. + ASMJIT_INLINE uint32_t getSize() const { + return _base.size; + } + + // -------------------------------------------------------------------------- + // [Id] + // -------------------------------------------------------------------------- + + //! Get operand id. + //! + //! Operand id's are used internally by `Assembler` and `Compiler`. + //! + //! There is no way to change or remove operand id. Unneeded operands can be + //! simply reassigned by `operator=`. + ASMJIT_INLINE uint32_t getId() const { + return _base.id; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + //! Base data. + BaseOp _base; + //! Register or variable data. + VRegOp _vreg; + //! Memory data. + VMemOp _vmem; + //! Immediate data. + ImmOp _imm; + //! Label data. + LabelOp _label; + + //! Packed operand as two 64-bit integers. + UInt64 _packed[2]; + }; +}; + +// ============================================================================ +// [asmjit::OperandUtil] +// ============================================================================ + +//! Operand utilities. +struct OperandUtil { + //! Make variable id. + static ASMJIT_INLINE uint32_t makeVarId(uint32_t id) { + return id | kOperandIdVar; + } + + //! Make label id. + static ASMJIT_INLINE uint32_t makeLabelId(uint32_t id) { + return id; + } + + //! Strip variable id bit so it becomes a pure index to `VarData[]` array. + static ASMJIT_INLINE uint32_t stripVarId(uint32_t id) { + return id & 0x7FFFFFFFU; + } + + //! Get whether the id refers to `Var`. + //! + //! \note The function will never return `true` if the id is `kInvalidValue`. + //! The trick is to compare a given id to -1 (kInvalidValue) so we check both + //! using only one comparison. + static ASMJIT_INLINE bool isVarId(uint32_t id) { + return static_cast(id) < -1; + } + + //! Get whether the id refers to `Label`. + //! + //! \note The function will never return `true` if the id is `kInvalidValue`. + static ASMJIT_INLINE bool isLabelId(uint32_t id) { + return static_cast(id) >= 0; + } +}; + +// ============================================================================ +// [asmjit::Reg] +// ============================================================================ + +//! Base class for all register operands. +struct Reg : public Operand { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy base register. + ASMJIT_INLINE Reg() : Operand(NoInit) { + _init_packed_op_sz_w0_id(kOperandTypeReg, 0, (kInvalidReg << 8) + kInvalidReg, kInvalidValue); + _init_packed_d2_d3(kInvalidVar, 0); + } + + //! Create a new base register. + ASMJIT_INLINE Reg(uint32_t type, uint32_t index, uint32_t size) : Operand(NoInit) { + _init_packed_op_sz_w0_id(kOperandTypeReg, size, (type << 8) + index, kInvalidValue); + _init_packed_d2_d3(kInvalidVar, 0); + } + + //! Create a new reference to `other`. + ASMJIT_INLINE Reg(const Reg& other) : Operand(other) {} + + //! Create a new reference to `other` and change the index to `index`. + ASMJIT_INLINE Reg(const Reg& other, uint32_t index) : Operand(other) { + _vreg.index = static_cast(index); + } + + explicit ASMJIT_INLINE Reg(const _NoInit&) : Operand(NoInit) {} + + // -------------------------------------------------------------------------- + // [Reg Specific] + // -------------------------------------------------------------------------- + + //! Clone `Reg` operand. + ASMJIT_INLINE Reg clone() const { + return Reg(*this); + } + + //! Get whether register code is equal to `type`. + ASMJIT_INLINE bool isRegType(uint32_t type) const { + return _vreg.type == type; + } + + //! Get whether register code is equal to `type`. + ASMJIT_INLINE bool isRegCode(uint32_t code) const { + return _vreg.code == code; + } + + //! Get whether register code is equal to `type`. + ASMJIT_INLINE bool isRegCode(uint32_t type, uint32_t index) const { + return _vreg.code == (type << 8) + index; + } + + //! Get register code that equals to '(type << 8) + index'. + ASMJIT_INLINE uint32_t getRegCode() const { + return _vreg.code; + } + + //! Get register type. + ASMJIT_INLINE uint32_t getRegType() const { + return _vreg.type; + } + + //! Get register index. + ASMJIT_INLINE uint32_t getRegIndex() const { + return _vreg.index; + } + +#define ASMJIT_REG_OP(_Type_) \ + ASMJIT_INLINE _Type_ clone() const { \ + return _Type_(*this); \ + } \ + \ + /*! Set register `size`. */ \ + ASMJIT_INLINE _Type_& setSize(uint32_t size) { \ + _vreg.size = static_cast(size); \ + return *this; \ + } \ + \ + /*! Set register `code`. */ \ + ASMJIT_INLINE _Type_& setCode(uint32_t code) { \ + _vreg.code = static_cast(code); \ + return *this; \ + } \ + \ + /*! Set register `type` and `index`. */ \ + ASMJIT_INLINE _Type_& setCode(uint32_t type, uint32_t index) { \ + _vreg.type = static_cast(type); \ + _vreg.index = static_cast(index); \ + return *this; \ + } \ + \ + /*! Set register `type`. */ \ + ASMJIT_INLINE _Type_& setType(uint32_t type) { \ + _vreg.type = static_cast(type); \ + return *this; \ + } \ + \ + /*! Set register `index`. */ \ + ASMJIT_INLINE _Type_& setIndex(uint32_t index) { \ + _vreg.index = static_cast(index); \ + return *this; \ + } \ + \ + ASMJIT_INLINE _Type_& operator=(const _Type_& other) { _copy(other); return *this; } \ + \ + ASMJIT_INLINE bool operator==(const _Type_& other) const { return _packed[0].u32[0] == other._packed[0].u32[0]; } \ + ASMJIT_INLINE bool operator!=(const _Type_& other) const { return !operator==(other); } +}; + +// ============================================================================ +// [asmjit::BaseMem] +// ============================================================================ + +//! Base class for all memory operands. +struct BaseMem : public Operand { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE BaseMem() : Operand(NoInit) { + reset(); + } + + ASMJIT_INLINE BaseMem(const BaseMem& other) : Operand(other) {} + explicit ASMJIT_INLINE BaseMem(const _NoInit&) : Operand(NoInit) {} + + // -------------------------------------------------------------------------- + // [BaseMem Specific] + // -------------------------------------------------------------------------- + + //! Clone `BaseMem` operand. + ASMJIT_INLINE BaseMem clone() const { + return BaseMem(*this); + } + + //! Reset `BaseMem` operand. + ASMJIT_INLINE void reset() { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, 0, kMemTypeBaseIndex, 0, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, 0); + } + + //! Get the type of the memory operand, see `kMemType`. + ASMJIT_INLINE uint32_t getMemType() const { + return _vmem.type; + } + + //! Get whether the type of the memory operand is either `kMemTypeBaseIndex` + //! or `kMemTypeStackIndex`. + ASMJIT_INLINE bool isBaseIndexType() const { + return _vmem.type <= kMemTypeStackIndex; + } + + //! Get whether the memory operand has base register. + ASMJIT_INLINE bool hasBase() const { + return _vmem.base != kInvalidValue; + } + + //! Get memory operand base id, or `kInvalidValue`. + ASMJIT_INLINE uint32_t getBase() const { + return _vmem.base; + } + + //! Set memory operand size. + ASMJIT_INLINE BaseMem& setSize(uint32_t size) { + _vmem.size = static_cast(size); + return *this; + } + + //! Get memory operand relative displacement. + ASMJIT_INLINE int32_t getDisplacement() const { + return _vmem.displacement; + } + + //! Set memory operand relative displacement. + ASMJIT_INLINE BaseMem& setDisplacement(int32_t disp) { + _vmem.displacement = disp; + return *this; + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE BaseMem& operator=(const BaseMem& other) { + _copy(other); + return *this; + } + + ASMJIT_INLINE bool operator==(const BaseMem& other) const { + return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]); + } + + ASMJIT_INLINE bool operator!=(const BaseMem& other) const { + return !(*this == other); + } +}; + +// ============================================================================ +// [asmjit::Imm] +// ============================================================================ + +//! Immediate operand. +//! +//! Immediate operand is usually part of instruction itself. It's inlined after +//! or before the instruction opcode. Immediates can be only signed or unsigned +//! integers. +//! +//! To create immediate operand use `imm()` or `imm_u()` non-members or `Imm` +//! constructors. +struct Imm : public Operand { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new immediate value (initial value is 0). + Imm() : Operand(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeImm, 0, 0, 0, kInvalidValue); + _imm.value._i64[0] = 0; + } + + //! Create a new signed immediate value, assigning the value to `val`. + explicit Imm(int64_t val) : Operand(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeImm, 0, 0, 0, kInvalidValue); + _imm.value._i64[0] = val; + } + + //! Create a new immediate value from `other`. + ASMJIT_INLINE Imm(const Imm& other) : Operand(other) {} + + explicit ASMJIT_INLINE Imm(const _NoInit&) : Operand(NoInit) {} + + // -------------------------------------------------------------------------- + // [Immediate Specific] + // -------------------------------------------------------------------------- + + //! Clone `Imm` operand. + ASMJIT_INLINE Imm clone() const { + return Imm(*this); + } + + //! Get whether the immediate can be casted to 8-bit signed integer. + ASMJIT_INLINE bool isInt8() const { return IntUtil::isInt8(_imm.value._i64[0]); } + //! Get whether the immediate can be casted to 8-bit unsigned integer. + ASMJIT_INLINE bool isUInt8() const { return IntUtil::isUInt8(_imm.value._i64[0]); } + + //! Get whether the immediate can be casted to 16-bit signed integer. + ASMJIT_INLINE bool isInt16() const { return IntUtil::isInt16(_imm.value._i64[0]); } + //! Get whether the immediate can be casted to 16-bit unsigned integer. + ASMJIT_INLINE bool isUInt16() const { return IntUtil::isUInt16(_imm.value._i64[0]); } + + //! Get whether the immediate can be casted to 32-bit signed integer. + ASMJIT_INLINE bool isInt32() const { return IntUtil::isInt32(_imm.value._i64[0]); } + //! Get whether the immediate can be casted to 32-bit unsigned integer. + ASMJIT_INLINE bool isUInt32() const { return IntUtil::isUInt32(_imm.value._i64[0]); } + + //! Get immediate value as 8-bit signed integer. + ASMJIT_INLINE int8_t getInt8() const { return _imm.value._i8[_ASMJIT_HOST_INDEX(8, 0)]; } + //! Get immediate value as 8-bit unsigned integer. + ASMJIT_INLINE uint8_t getUInt8() const { return _imm.value._u8[_ASMJIT_HOST_INDEX(8, 0)]; } + //! Get immediate value as 16-bit signed integer. + ASMJIT_INLINE int16_t getInt16() const { return _imm.value._i16[_ASMJIT_HOST_INDEX(4, 0)]; } + //! Get immediate value as 16-bit unsigned integer. + ASMJIT_INLINE uint16_t getUInt16() const { return _imm.value._u16[_ASMJIT_HOST_INDEX(4, 0)]; } + //! Get immediate value as 32-bit signed integer. + ASMJIT_INLINE int32_t getInt32() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; } + //! Get immediate value as 32-bit unsigned integer. + ASMJIT_INLINE uint32_t getUInt32() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; } + //! Get immediate value as 64-bit signed integer. + ASMJIT_INLINE int64_t getInt64() const { return _imm.value._i64[0]; } + //! Get immediate value as 64-bit unsigned integer. + ASMJIT_INLINE uint64_t getUInt64() const { return _imm.value._u64[0]; } + + //! Get immediate value as `intptr_t`. + ASMJIT_INLINE intptr_t getIntPtr() const { + if (sizeof(intptr_t) == sizeof(int64_t)) + return static_cast(getInt64()); + else + return static_cast(getInt32()); + } + + //! Get immediate value as `uintptr_t`. + ASMJIT_INLINE uintptr_t getUIntPtr() const { + if (sizeof(uintptr_t) == sizeof(uint64_t)) + return static_cast(getUInt64()); + else + return static_cast(getUInt32()); + } + + //! Get low 32-bit signed integer. + ASMJIT_INLINE int32_t getInt32Lo() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; } + //! Get low 32-bit signed integer. + ASMJIT_INLINE uint32_t getUInt32Lo() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; } + //! Get high 32-bit signed integer. + ASMJIT_INLINE int32_t getInt32Hi() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)]; } + //! Get high 32-bit signed integer. + ASMJIT_INLINE uint32_t getUInt32Hi() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)]; } + + //! Set immediate value to 8-bit signed integer `val`. + ASMJIT_INLINE Imm& setInt8(int8_t val) { + if (kArchHost64Bit) { + _imm.value._i64[0] = static_cast(val); + } + else { + int32_t val32 = static_cast(val); + _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32; + _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31; + } + return *this; + } + + //! Set immediate value to 8-bit unsigned integer `val`. + ASMJIT_INLINE Imm& setUInt8(uint8_t val) { + if (kArchHost64Bit) { + _imm.value._u64[0] = static_cast(val); + } + else { + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast(val); + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + } + return *this; + } + + //! Set immediate value to 16-bit signed integer `val`. + ASMJIT_INLINE Imm& setInt16(int16_t val) { + if (kArchHost64Bit) { + _imm.value._i64[0] = static_cast(val); + } + else { + int32_t val32 = static_cast(val); + _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32; + _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31; + } + return *this; + } + + //! Set immediate value to 16-bit unsigned integer `val`. + ASMJIT_INLINE Imm& setUInt16(uint16_t val) { + if (kArchHost64Bit) { + _imm.value._u64[0] = static_cast(val); + } + else { + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast(val); + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + } + return *this; + } + + //! Set immediate value to 32-bit signed integer `val`. + ASMJIT_INLINE Imm& setInt32(int32_t val) { + if (kArchHost64Bit) { + _imm.value._i64[0] = static_cast(val); + } + else { + _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val; + _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val >> 31; + } + return *this; + } + + //! Set immediate value to 32-bit unsigned integer `val`. + ASMJIT_INLINE Imm& setUInt32(uint32_t val) { + if (kArchHost64Bit) { + _imm.value._u64[0] = static_cast(val); + } + else { + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = val; + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + } + return *this; + } + + //! Set immediate value to 64-bit signed integer `val`. + ASMJIT_INLINE Imm& setInt64(int64_t val) { + _imm.value._i64[0] = val; + return *this; + } + + //! Set immediate value to 64-bit unsigned integer `val`. + ASMJIT_INLINE Imm& setUInt64(uint64_t val) { + _imm.value._u64[0] = val; + return *this; + } + + //! Set immediate value to intptr_t `val`. + ASMJIT_INLINE Imm& setIntPtr(intptr_t val) { + _imm.value._i64[0] = static_cast(val); + return *this; + } + + //! Set immediate value to uintptr_t `val`. + ASMJIT_INLINE Imm& setUIntPtr(uintptr_t val) { + _imm.value._u64[0] = static_cast(val); + return *this; + } + + //! Set immediate value as unsigned type to `val`. + ASMJIT_INLINE Imm& setPtr(void* p) { return setIntPtr((intptr_t)p); } + + // -------------------------------------------------------------------------- + // [Float] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Imm& setFloat(float f) { + _imm.value._f32[_ASMJIT_HOST_INDEX(2, 0)] = f; + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + return *this; + } + + ASMJIT_INLINE Imm& setDouble(double d) { + _imm.value._f64[0] = d; + return *this; + } + + // -------------------------------------------------------------------------- + // [Truncate] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Imm& truncateTo8Bits() { + if (kArchHost64Bit) { + _imm.value._u64[0] &= static_cast(0x000000FFU); + } + else { + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x000000FFU; + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + } + return *this; + } + + ASMJIT_INLINE Imm& truncateTo16Bits() { + if (kArchHost64Bit) { + _imm.value._u64[0] &= static_cast(0x0000FFFFU); + } + else { + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x0000FFFFU; + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + } + return *this; + } + + ASMJIT_INLINE Imm& truncateTo32Bits() { + _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + return *this; + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + //! Assign `other` to the immediate operand. + ASMJIT_INLINE Imm& operator=(const Imm& other) { + _copy(other); + return *this; + } +}; + +// ============================================================================ +// [asmjit::Label] +// ============================================================================ + +//! Label (jump target or data location). +//! +//! Label represents a location in code typically used as jump targets, but may +//! be also reference data or static variables. Label has to be explicitly +//! created by a code-generator by calling `CodeGen::newLabel()` where `CodeGen` +//! is your code generator, which derives from `Assembler` or `Compiler`. +//! +//! Example of using labels: +//! +//! ~~~ +//! // Create Assembler/Compiler. +//! host::Assembler a; +//! +//! // Create Label instance. +//! Label L_1(a); +//! +//! // ... your code ... +//! +//! // Using label. +//! a.jump(L_1); +//! +//! // ... your code ... +//! +//! // Bind label to the current position, see `CodeGen::bind()`. +//! a.bind(L_1); +//! ~~~ +struct Label : public Operand { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create new, unassociated label. + ASMJIT_INLINE Label() : Operand(NoInit) { + reset(); + } + + explicit ASMJIT_INLINE Label(uint32_t id) : Operand(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, id); + _init_packed_d2_d3(0, 0); + } + + //! Create new initialized label. + explicit ASMJIT_INLINE Label(Assembler& a); + //! Create new initialized label. + explicit ASMJIT_INLINE Label(Compiler& c); + + //! Create reference to another label. + ASMJIT_INLINE Label(const Label& other) : Operand(other) {} + + explicit ASMJIT_INLINE Label(const _NoInit&) : Operand(NoInit) {} + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + _init_packed_op_sz_b0_b1_id(kOperandTypeLabel, 0, 0, 0, kInvalidValue); + _init_packed_d2_d3(0, 0); + } + + // -------------------------------------------------------------------------- + // [Label Specific] + // -------------------------------------------------------------------------- + + //! Get whether the label has been initialized by `Assembler` or `Compiler`. + ASMJIT_INLINE bool isInitialized() const { + return _label.id != kInvalidValue; + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Label& operator=(const Label& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const Label& other) const { return _base.id == other._base.id; } + ASMJIT_INLINE bool operator!=(const Label& other) const { return _base.id != other._base.id; } +}; + +// ============================================================================ +// [asmjit::Operand - Globals] +// ============================================================================ + +//! No operand, can be used to reset an operand by assignment or to refer to an +//! operand that doesn't exist. +ASMJIT_VAR const Operand noOperand; + +//! Create signed immediate value operand. +static ASMJIT_INLINE Imm imm(int64_t val) { + return Imm(val); +} + +//! Create unsigned immediate value operand. +static ASMJIT_INLINE Imm imm_u(uint64_t val) { + return Imm(static_cast(val)); +} + +//! Create void* pointer immediate value operand. +static ASMJIT_INLINE Imm imm_ptr(void* p) { + return Imm(static_cast((intptr_t)p)); +} + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_OPERAND_H diff --git a/libraries/asmjit/base/runtime.cpp b/libraries/asmjit/base/runtime.cpp new file mode 100644 index 000000000..258dbd1e5 --- /dev/null +++ b/libraries/asmjit/base/runtime.cpp @@ -0,0 +1,191 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/cpuinfo.h" +#include "../base/error.h" +#include "../base/runtime.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::Runtime - Construction / Destruction] +// ============================================================================ + +Runtime::Runtime() { + _sizeLimit = 0; + + _runtimeType = kRuntimeTypeNone; + _allocType = kVMemAllocFreeable; + ::memset(_reserved, 0, sizeof(_reserved)); + + _baseAddress = kNoBaseAddress; +} + +Runtime::~Runtime() {} + +// ============================================================================ +// [asmjit::HostRuntime - Construction / Destruction] +// ============================================================================ + +HostRuntime::HostRuntime() { + _runtimeType = kRuntimeTypeJit; +} + +HostRuntime::~HostRuntime() {} + +// ============================================================================ +// [asmjit::HostRuntime - Interface] +// ============================================================================ + +const CpuInfo* HostRuntime::getCpuInfo() { + return CpuInfo::getHost(); +} + +uint32_t HostRuntime::getStackAlignment() { + uint32_t alignment = sizeof(intptr_t); + +#if defined(ASMJIT_HOST_X86) + // Modern Linux, APPLE and UNIX guarantees 16-byte stack alignment, but I'm + // not sure about all other UNIX operating systems, because 16-byte alignment + // is addition to an older specification. +# if (defined(__linux__) || \ + defined(__linux) || \ + defined(__unix__) || \ + defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__OpenBSD__) || \ + defined(__DARWIN__) || \ + defined(__APPLE__) ) + alignment = 16; +# endif +#elif defined(ASMJIT_HOST_X64) + alignment = 16; +#endif + + return alignment; +} + +void HostRuntime::flush(void* p, size_t size) { + // Only useful on non-x86 architectures. +#if !defined(ASMJIT_HOST_X86) && !defined(ASMJIT_HOST_X64) + + // Windows has built-in support in kernel32.dll. +#if defined(ASMJIT_OS_WINDOWS) + ::FlushInstructionCache(_memMgr.getProcessHandle(), p, size); +#endif // ASMJIT_OS_WINDOWS + +#endif // !ASMJIT_HOST_X86 && !ASMJIT_HOST_X64 +} + +// ============================================================================ +// [asmjit::StaticRuntime - Construction / Destruction] +// ============================================================================ + +StaticRuntime::StaticRuntime(void* baseAddress, size_t sizeLimit) { + _sizeLimit = sizeLimit; + _baseAddress = static_cast((uintptr_t)baseAddress); +} + +StaticRuntime::~StaticRuntime() {} + +// ============================================================================ +// [asmjit::StaticRuntime - Interface] +// ============================================================================ + +Error StaticRuntime::add(void** dst, Assembler* assembler) { + size_t codeSize = assembler->getCodeSize(); + size_t sizeLimit = _sizeLimit; + + if (codeSize == 0) { + *dst = NULL; + return kErrorNoCodeGenerated; + } + + if (sizeLimit != 0 && sizeLimit < codeSize) { + *dst = NULL; + return kErrorCodeTooLarge; + } + + Ptr baseAddress = _baseAddress; + uint8_t* p = static_cast((void*)static_cast(baseAddress)); + + // Since the base address is known the `relocSize` returned should be equal + // to `codeSize`. It's better to fail if they don't match instead of passsing + // silently. + size_t relocSize = assembler->relocCode(p, baseAddress); + if (relocSize == 0 || codeSize != relocSize) { + *dst = NULL; + return kErrorInvalidState; + } + + _baseAddress += codeSize; + if (sizeLimit) + sizeLimit -= codeSize; + + flush(p, codeSize); + *dst = p; + + return kErrorOk; +} + +Error StaticRuntime::release(void* p) { + // There is nothing to release as `StaticRuntime` doesn't manage any memory. + ASMJIT_UNUSED(p); + return kErrorOk; +} + +// ============================================================================ +// [asmjit::JitRuntime - Construction / Destruction] +// ============================================================================ + +JitRuntime::JitRuntime() {} +JitRuntime::~JitRuntime() {} + +// ============================================================================ +// [asmjit::JitRuntime - Interface] +// ============================================================================ + +Error JitRuntime::add(void** dst, Assembler* assembler) { + size_t codeSize = assembler->getCodeSize(); + if (codeSize == 0) { + *dst = NULL; + return kErrorNoCodeGenerated; + } + + void* p = _memMgr.alloc(codeSize, getAllocType()); + if (p == NULL) { + *dst = NULL; + return kErrorNoVirtualMemory; + } + + // Relocate the code and release the unused memory back to `VMemMgr`. + size_t relocSize = assembler->relocCode(p); + if (relocSize < codeSize) { + _memMgr.shrink(p, relocSize); + } + + flush(p, relocSize); + *dst = p; + + return kErrorOk; +} + +Error JitRuntime::release(void* p) { + return _memMgr.release(p); +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/runtime.h b/libraries/asmjit/base/runtime.h new file mode 100644 index 000000000..b355fc4a7 --- /dev/null +++ b/libraries/asmjit/base/runtime.h @@ -0,0 +1,262 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_RUNTIME_H +#define _ASMJIT_BASE_RUNTIME_H + +// [Dependencies - AsmJit] +#include "../base/error.h" +#include "../base/vmem.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct Assembler; +struct CpuInfo; + +//! \addtogroup asmjit_base_general +//! \{ + +// ============================================================================ +// [asmjit::kRuntimeType] +// ============================================================================ + +ASMJIT_ENUM(kRuntimeType) { + kRuntimeTypeNone = 0, + + kRuntimeTypeJit = 1, + kRuntimeTypeRemote = 2 +}; + +// ============================================================================ +// [asmjit::Runtime] +// ============================================================================ + +//! Base runtime. +struct ASMJIT_VCLASS Runtime { + ASMJIT_NO_COPY(Runtime) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `Runtime` instance. + ASMJIT_API Runtime(); + //! Destroy the `Runtime` instance. + ASMJIT_API virtual ~Runtime(); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get runtime type. + ASMJIT_INLINE uint32_t getRuntimeType() const { + return _runtimeType; + } + + //! Get whether the runtime has a base address. + //! + //! \sa \ref getBaseAddress() + ASMJIT_INLINE bool hasBaseAddress() const { + return _baseAddress == kNoBaseAddress; + } + + //! Get the base address. + ASMJIT_INLINE Ptr getBaseAddress() const { + return _baseAddress; + } + + // -------------------------------------------------------------------------- + // [Interface] + // -------------------------------------------------------------------------- + + //! Get CPU information. + virtual const CpuInfo* getCpuInfo() = 0; + + //! Get stack alignment of target runtime. + virtual uint32_t getStackAlignment() = 0; + + //! Allocate a memory needed for a code generated by `assembler` and + //! relocate it to the target location. + //! + //! The beginning of the memory allocated for the function is returned in + //! `dst`. Returns Status code as \ref kError, on failure `dst` is set to + //! `NULL`. + virtual Error add(void** dst, Assembler* assembler) = 0; + + //! Release memory allocated by `add`. + virtual Error release(void* p) = 0; + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Maximum size of the code that can be added to the runtime (0=unlimited). + size_t _sizeLimit; + //! Base address (-1 means no base address). + Ptr _baseAddress; + + //! Type of the runtime. + uint8_t _runtimeType; + //! Type of the allocation. + uint8_t _allocType; + //! \internal + uint8_t _reserved[sizeof(intptr_t) - 2]; +}; + +// ============================================================================ +// [asmjit::HostRuntime] +// ============================================================================ + +//! Base runtime for JIT code generation. +struct ASMJIT_VCLASS HostRuntime : public Runtime { + ASMJIT_NO_COPY(HostRuntime) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `HostRuntime` instance. + ASMJIT_API HostRuntime(); + //! Destroy the `HostRuntime` instance. + ASMJIT_API virtual ~HostRuntime(); + + // -------------------------------------------------------------------------- + // [Interface] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual const CpuInfo* getCpuInfo(); + ASMJIT_API virtual uint32_t getStackAlignment(); + + //! Flush an instruction cache. + //! + //! This member function is called after the code has been copied to the + //! destination buffer. It is only useful for JIT code generation as it + //! causes a flush of the processor cache. + //! + //! Flushing is basically a NOP under X86/X64, but is needed by architectures + //! that do not have a transparent instruction cache. + //! + //! This function can also be overridden to improve compatibility with tools + //! such as Valgrind, however, it's not an official part of AsmJit. + ASMJIT_API virtual void flush(void* p, size_t size); +}; + +// ============================================================================ +// [asmjit::StaticRuntime] +// ============================================================================ + +//! JIT static runtime. +//! +//! JIT static runtime can be used to generate code to a memory location that +//! is known. +struct ASMJIT_VCLASS StaticRuntime : public HostRuntime { + ASMJIT_NO_COPY(StaticRuntime) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `StaticRuntime` instance. + //! + //! The `address` specifies a fixed target address, which will be used as a + //! base address for relocation, and `sizeLimit` specified the maximum size + //! of a code that can be copied to it. If there is no limit `sizeLimit` + //! should be zero. + ASMJIT_API StaticRuntime(void* baseAddress, size_t sizeLimit = 0); + //! Destroy the `StaticRuntime` instance. + ASMJIT_API virtual ~StaticRuntime(); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the base address. + ASMJIT_INLINE Ptr getBaseAddress() const { + return _baseAddress; + } + + //! Get the maximum size of the code that can be relocated to the target + //! address or zero if unlimited. + ASMJIT_INLINE size_t getSizeLimit() const { + return _sizeLimit; + } + + // -------------------------------------------------------------------------- + // [Interface] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error add(void** dst, Assembler* assembler); + ASMJIT_API virtual Error release(void* p); +}; + +// ============================================================================ +// [asmjit::JitRuntime] +// ============================================================================ + +//! JIT runtime. +struct ASMJIT_VCLASS JitRuntime : public HostRuntime { + ASMJIT_NO_COPY(JitRuntime) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `JitRuntime` instance. + ASMJIT_API JitRuntime(); + //! Destroy the `JitRuntime` instance. + ASMJIT_API virtual ~JitRuntime(); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the type of allocation. + ASMJIT_INLINE uint32_t getAllocType() const { + return _allocType; + } + + //! Set the type of allocation. + ASMJIT_INLINE void setAllocType(uint32_t allocType) { + _allocType = allocType; + } + + //! Get the virtual memory manager. + ASMJIT_INLINE VMemMgr* getMemMgr() const { + return const_cast(&_memMgr); + } + + // -------------------------------------------------------------------------- + // [Interface] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error add(void** dst, Assembler* assembler); + ASMJIT_API virtual Error release(void* p); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Virtual memory manager. + VMemMgr _memMgr; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_RUNTIME_H diff --git a/libraries/asmjit/base/string.cpp b/libraries/asmjit/base/string.cpp new file mode 100644 index 000000000..aa65dbea6 --- /dev/null +++ b/libraries/asmjit/base/string.cpp @@ -0,0 +1,374 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/intutil.h" +#include "../base/string.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// Should be placed in read-only memory. +static const char StringBuilder_empty[4] = { 0 }; + +// ============================================================================ +// [asmjit::StringBuilder - Construction / Destruction] +// ============================================================================ + +StringBuilder::StringBuilder() : + _data(const_cast(StringBuilder_empty)), + _length(0), + _capacity(0), + _canFree(false) {} + +StringBuilder::~StringBuilder() { + if (_canFree) + ASMJIT_FREE(_data); +} + +// ============================================================================ +// [asmjit::StringBuilder - Prepare / Reserve] +// ============================================================================ + +char* StringBuilder::prepare(uint32_t op, size_t len) { + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + if (op == kStringOpSet) { + // We don't care here, but we can't return a NULL pointer since it indicates + // failure in memory allocation. + if (len == 0) { + if (_data != StringBuilder_empty) + _data[0] = 0; + + _length = 0; + return _data; + } + + if (_capacity < len) { + if (len >= IntUtil::maxUInt() - sizeof(intptr_t) * 2) + return NULL; + + size_t to = IntUtil::alignTo(len, sizeof(intptr_t)); + if (to < 256 - sizeof(intptr_t)) + to = 256 - sizeof(intptr_t); + + char* newData = static_cast(ASMJIT_ALLOC(to + sizeof(intptr_t))); + if (newData == NULL) { + clear(); + return NULL; + } + + if (_canFree) + ASMJIT_FREE(_data); + + _data = newData; + _capacity = to + sizeof(intptr_t) - 1; + _canFree = true; + } + + _data[len] = 0; + _length = len; + + ASMJIT_ASSERT(_length <= _capacity); + return _data; + } + + // -------------------------------------------------------------------------- + // [Append] + // -------------------------------------------------------------------------- + + else { + // We don't care here, but we can't return a NULL pointer since it indicates + // failure in memory allocation. + if (len == 0) + return _data + _length; + + // Overflow. + if (IntUtil::maxUInt() - sizeof(intptr_t) * 2 - _length < len) + return NULL; + + size_t after = _length + len; + if (_capacity < after) { + size_t to = _capacity; + + if (to < 256) + to = 256; + + while (to < 1024 * 1024 && to < after) + to *= 2; + + if (to < after) { + to = after; + if (to < (IntUtil::maxUInt() - 1024 * 32)) + to = IntUtil::alignTo(to, 1024 * 32); + } + + to = IntUtil::alignTo(to, sizeof(intptr_t)); + char* newData = static_cast(ASMJIT_ALLOC(to + sizeof(intptr_t))); + + if (newData == NULL) + return NULL; + + ::memcpy(newData, _data, _length); + if (_canFree) + ASMJIT_FREE(_data); + + _data = newData; + _capacity = to + sizeof(intptr_t) - 1; + _canFree = true; + } + + char* ret = _data + _length; + _data[after] = 0; + _length = after; + + ASMJIT_ASSERT(_length <= _capacity); + return ret; + } +} + +bool StringBuilder::reserve(size_t to) { + if (_capacity >= to) + return true; + + if (to >= IntUtil::maxUInt() - sizeof(intptr_t) * 2) + return false; + + to = IntUtil::alignTo(to, sizeof(intptr_t)); + + char* newData = static_cast(ASMJIT_ALLOC(to + sizeof(intptr_t))); + if (newData == NULL) + return false; + + ::memcpy(newData, _data, _length + 1); + if (_canFree) + ASMJIT_FREE(_data); + + _data = newData; + _capacity = to + sizeof(intptr_t) - 1; + _canFree = true; + return true; +} + +// ============================================================================ +// [asmjit::StringBuilder - Clear] +// ============================================================================ + +void StringBuilder::clear() { + if (_data != StringBuilder_empty) + _data[0] = 0; + _length = 0; +} + +// ============================================================================ +// [asmjit::StringBuilder - Methods] +// ============================================================================ + +bool StringBuilder::_opString(uint32_t op, const char* str, size_t len) { + if (len == kInvalidIndex) + len = str != NULL ? ::strlen(str) : static_cast(0); + + char* p = prepare(op, len); + if (p == NULL) + return false; + + ::memcpy(p, str, len); + return true; +} + +bool StringBuilder::_opChar(uint32_t op, char c) { + char* p = prepare(op, 1); + if (p == NULL) + return false; + + *p = c; + return true; +} + +bool StringBuilder::_opChars(uint32_t op, char c, size_t len) { + char* p = prepare(op, len); + if (p == NULL) + return false; + + ::memset(p, c, len); + return true; +} + +static const char StringBuilder_numbers[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +bool StringBuilder::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags) { + if (base < 2 || base > 36) + base = 10; + + char buf[128]; + char* p = buf + ASMJIT_ARRAY_SIZE(buf); + + uint64_t orig = i; + char sign = '\0'; + + // -------------------------------------------------------------------------- + // [Sign] + // -------------------------------------------------------------------------- + + if ((flags & kStringFormatSigned) != 0 && static_cast(i) < 0) { + i = static_cast(-static_cast(i)); + sign = '-'; + } + else if ((flags & kStringFormatShowSign) != 0) { + sign = '+'; + } + else if ((flags & kStringFormatShowSpace) != 0) { + sign = ' '; + } + + // -------------------------------------------------------------------------- + // [Number] + // -------------------------------------------------------------------------- + + do { + uint64_t d = i / base; + uint64_t r = i % base; + + *--p = StringBuilder_numbers[r]; + i = d; + } while (i); + + size_t numberLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p); + + // -------------------------------------------------------------------------- + // [Alternate Form] + // -------------------------------------------------------------------------- + + if ((flags & kStringFormatAlternate) != 0) { + if (base == 8) { + if (orig != 0) + *--p = '0'; + } + if (base == 16) { + *--p = 'x'; + *--p = '0'; + } + } + + // -------------------------------------------------------------------------- + // [Width] + // -------------------------------------------------------------------------- + + if (sign != 0) + *--p = sign; + + if (width > 256) + width = 256; + + if (width <= numberLength) + width = 0; + else + width -= numberLength; + + // -------------------------------------------------------------------------- + // Write] + // -------------------------------------------------------------------------- + + size_t prefixLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberLength; + char* data = prepare(op, prefixLength + width + numberLength); + + if (data == NULL) + return false; + + ::memcpy(data, p, prefixLength); + data += prefixLength; + + ::memset(data, '0', width); + data += width; + + ::memcpy(data, p + prefixLength, numberLength); + return true; +} + +bool StringBuilder::_opHex(uint32_t op, const void* data, size_t len) { + if (len >= IntUtil::maxUInt() / 2) + return false; + + char* dst = prepare(op, len * 2); + if (dst == NULL) + return false; + + const char* src = static_cast(data); + for (size_t i = 0; i < len; i++, dst += 2, src += 1) + { + dst[0] = StringBuilder_numbers[(src[0] >> 4) & 0xF]; + dst[1] = StringBuilder_numbers[(src[0] ) & 0xF]; + } + + return true; +} + +bool StringBuilder::_opVFormat(uint32_t op, const char* fmt, va_list ap) { + char buf[1024]; + + vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap); + buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0'; + + return _opString(op, buf); +} + +bool StringBuilder::setFormat(const char* fmt, ...) { + bool result; + + va_list ap; + va_start(ap, fmt); + result = _opVFormat(kStringOpSet, fmt, ap); + va_end(ap); + + return result; +} + +bool StringBuilder::appendFormat(const char* fmt, ...) { + bool result; + + va_list ap; + va_start(ap, fmt); + result = _opVFormat(kStringOpAppend, fmt, ap); + va_end(ap); + + return result; +} + +bool StringBuilder::eq(const char* str, size_t len) const { + const char* aData = _data; + const char* bData = str; + + size_t aLength = _length; + size_t bLength = len; + + if (bLength == kInvalidIndex) { + size_t i; + for (i = 0; i < aLength; i++) { + if (aData[i] != bData[i] || bData[i] == 0) + return false; + } + + return bData[i] == 0; + } + else { + if (aLength != bLength) + return false; + + return ::memcmp(aData, bData, aLength) == 0; + } +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/string.h b/libraries/asmjit/base/string.h new file mode 100644 index 000000000..145a68978 --- /dev/null +++ b/libraries/asmjit/base/string.h @@ -0,0 +1,372 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_STRING_H +#define _ASMJIT_BASE_STRING_H + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +// [Dependencies - C] +#include + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::kStringOp] +// ============================================================================ + +//! \internal +//! +//! String operation. +ASMJIT_ENUM(kStringOp) { + //! Replace the current string by a given content. + kStringOpSet = 0, + //! Append a given content to the current string. + kStringOpAppend = 1 +}; + +// ============================================================================ +// [asmjit::kStringFormat] +// ============================================================================ + +//! \internal +//! +//! String format flags. +ASMJIT_ENUM(kStringFormat) { + kStringFormatShowSign = 0x00000001, + kStringFormatShowSpace = 0x00000002, + kStringFormatAlternate = 0x00000004, + kStringFormatSigned = 0x80000000 +}; + +// ============================================================================ +// [asmjit::StringUtil] +// ============================================================================ + +//! String utilities. +struct StringUtil { + static ASMJIT_INLINE size_t nlen(const char* s, size_t maxlen) { + size_t i; + for (i = 0; i < maxlen; i++) + if (!s[i]) + break; + return i; + } +}; + +// ============================================================================ +// [asmjit::StringBuilder] +// ============================================================================ + +//! String builder. +//! +//! String builder was designed to be able to build a string using append like +//! operation to append numbers, other strings, or signle characters. It can +//! allocate it's own buffer or use a buffer created on the stack. +//! +//! String builder contains method specific to AsmJit functionality, used for +//! logging or HTML output. +struct StringBuilder { + ASMJIT_NO_COPY(StringBuilder) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_API StringBuilder(); + ASMJIT_API ~StringBuilder(); + + ASMJIT_INLINE StringBuilder(const _NoInit&) {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get string builder capacity. + ASMJIT_INLINE size_t getCapacity() const { return _capacity; } + //! Get length. + ASMJIT_INLINE size_t getLength() const { return _length; } + + //! Get null-terminated string data. + ASMJIT_INLINE char* getData() { return _data; } + //! Get null-terminated string data (const). + ASMJIT_INLINE const char* getData() const { return _data; } + + // -------------------------------------------------------------------------- + // [Prepare / Reserve] + // -------------------------------------------------------------------------- + + //! Prepare to set/append. + ASMJIT_API char* prepare(uint32_t op, size_t len); + + //! Reserve `to` bytes in string builder. + ASMJIT_API bool reserve(size_t to); + + // -------------------------------------------------------------------------- + // [Clear] + // -------------------------------------------------------------------------- + + //! Clear the content in String builder. + ASMJIT_API void clear(); + + // -------------------------------------------------------------------------- + // [Op] + // -------------------------------------------------------------------------- + + ASMJIT_API bool _opString(uint32_t op, const char* str, size_t len = kInvalidIndex); + ASMJIT_API bool _opVFormat(uint32_t op, const char* fmt, va_list ap); + ASMJIT_API bool _opChar(uint32_t op, char c); + ASMJIT_API bool _opChars(uint32_t op, char c, size_t len); + ASMJIT_API bool _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0); + ASMJIT_API bool _opHex(uint32_t op, const void* data, size_t len); + + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + //! Replace the current content by `str` of `len`. + ASMJIT_INLINE bool setString(const char* str, size_t len = kInvalidIndex) { + return _opString(kStringOpSet, str, len); + } + + //! Replace the current content by formatted string `fmt`. + ASMJIT_INLINE bool setVFormat(const char* fmt, va_list ap) { + return _opVFormat(kStringOpSet, fmt, ap); + } + + //! Replace the current content by formatted string `fmt`. + ASMJIT_API bool setFormat(const char* fmt, ...); + + //! Replace the current content by `c` character. + ASMJIT_INLINE bool setChar(char c) { + return _opChar(kStringOpSet, c); + } + + //! Replace the current content by `c` of `len`. + ASMJIT_INLINE bool setChars(char c, size_t len) { + return _opChars(kStringOpSet, c, len); + } + + //! Replace the current content by formatted integer `i`. + ASMJIT_INLINE bool setInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) { + return _opNumber(kStringOpSet, i, base, width, flags | kStringFormatSigned); + } + + //! Replace the current content by formatted integer `i`. + ASMJIT_INLINE bool setUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) { + return _opNumber(kStringOpSet, i, base, width, flags); + } + + //! Replace the current content by the given `data` converted to a HEX string. + ASMJIT_INLINE bool setHex(const void* data, size_t len) { + return _opHex(kStringOpSet, data, len); + } + + // -------------------------------------------------------------------------- + // [Append] + // -------------------------------------------------------------------------- + + //! Append `str` of `len`. + ASMJIT_INLINE bool appendString(const char* str, size_t len = kInvalidIndex) { + return _opString(kStringOpAppend, str, len); + } + + //! Append a formatted string `fmt` to the current content. + ASMJIT_INLINE bool appendVFormat(const char* fmt, va_list ap) { + return _opVFormat(kStringOpAppend, fmt, ap); + } + + //! Append a formatted string `fmt` to the current content. + ASMJIT_API bool appendFormat(const char* fmt, ...); + + //! Append `c` character. + ASMJIT_INLINE bool appendChar(char c) { + return _opChar(kStringOpAppend, c); + } + + //! Append `c` of `len`. + ASMJIT_INLINE bool appendChars(char c, size_t len) { + return _opChars(kStringOpAppend, c, len); + } + + //! Append `i`. + ASMJIT_INLINE bool appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) { + return _opNumber(kStringOpAppend, static_cast(i), base, width, flags | kStringFormatSigned); + } + + //! Append `i`. + ASMJIT_INLINE bool appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) { + return _opNumber(kStringOpAppend, i, base, width, flags); + } + + //! Append the given `data` converted to a HEX string. + ASMJIT_INLINE bool appendHex(const void* data, size_t len) { + return _opHex(kStringOpAppend, data, len); + } + + // -------------------------------------------------------------------------- + // [_Append] + // -------------------------------------------------------------------------- + + //! Append `str` of `len`, inlined, without buffer overflow check. + ASMJIT_INLINE void _appendString(const char* str, size_t len = kInvalidIndex) { + // len should be a constant if we are inlining. + if (len == kInvalidIndex) { + char* p = &_data[_length]; + + while (*str) { + ASMJIT_ASSERT(p < _data + _capacity); + *p++ = *str++; + } + + *p = '\0'; + _length = (size_t)(p - _data); + } + else { + ASMJIT_ASSERT(_capacity - _length >= len); + + char* p = &_data[_length]; + char* pEnd = p + len; + + while (p < pEnd) + *p++ = *str++; + + *p = '\0'; + _length += len; + } + } + + //! Append `c` character, inlined, without buffer overflow check. + ASMJIT_INLINE void _appendChar(char c) { + ASMJIT_ASSERT(_capacity - _length >= 1); + + _data[_length] = c; + _length++; + _data[_length] = '\0'; + } + + //! Append `c` of `len`, inlined, without buffer overflow check. + ASMJIT_INLINE void _appendChars(char c, size_t len) { + ASMJIT_ASSERT(_capacity - _length >= len); + + char* p = &_data[_length]; + char* pEnd = p + len; + + while (p < pEnd) + *p++ = c; + + *p = '\0'; + _length += len; + } + + ASMJIT_INLINE void _appendUInt32(uint32_t i) { + char buf_[32]; + + char* pEnd = buf_ + ASMJIT_ARRAY_SIZE(buf_); + char* pBuf = pEnd; + + do { + uint32_t d = i / 10; + uint32_t r = i % 10; + + *--pBuf = static_cast(r + '0'); + i = d; + } while (i); + + ASMJIT_ASSERT(_capacity - _length >= (size_t)(pEnd - pBuf)); + char* p = &_data[_length]; + + do { + *p++ = *pBuf; + } while (++pBuf != pEnd); + + *p = '\0'; + _length = (size_t)(p - _data); + } + + // -------------------------------------------------------------------------- + // [Eq] + // -------------------------------------------------------------------------- + + //! Check for equality with other `str` of `len`. + ASMJIT_API bool eq(const char* str, size_t len = kInvalidIndex) const; + //! Check for equality with `other`. + ASMJIT_INLINE bool eq(const StringBuilder& other) const { + return eq(other._data); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool operator==(const StringBuilder& other) const { return eq(other); } + ASMJIT_INLINE bool operator!=(const StringBuilder& other) const { return !eq(other); } + + ASMJIT_INLINE bool operator==(const char* str) const { return eq(str); } + ASMJIT_INLINE bool operator!=(const char* str) const { return !eq(str); } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! String data. + char* _data; + //! Length. + size_t _length; + //! Capacity. + size_t _capacity; + //! Whether the string can be freed. + size_t _canFree; +}; + +// ============================================================================ +// [asmjit::StringBuilderT] +// ============================================================================ + +//! \internal +template +struct StringBuilderT : public StringBuilder { + ASMJIT_NO_COPY(StringBuilderT) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE StringBuilderT() : StringBuilder(NoInit) { + _data = _embeddedData; + _data[0] = 0; + + _length = 0; + _capacity = N; + _canFree = false; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Embedded data. + char _embeddedData[static_cast( + N + 1 + sizeof(intptr_t)) & ~static_cast(sizeof(intptr_t) - 1)]; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_STRING_H diff --git a/libraries/asmjit/base/vectypes.h b/libraries/asmjit/base/vectypes.h new file mode 100644 index 000000000..d675ec208 --- /dev/null +++ b/libraries/asmjit/base/vectypes.h @@ -0,0 +1,1251 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_VECTYPES_H +#define _ASMJIT_BASE_VECTYPES_H + +// [Dependencies - AsmJit] +#include "../base/globals.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::Vec64] +// ============================================================================ + +//! 64-bit vector register data. +union Vec64 { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Set all eight 8-bit signed integers. + static ASMJIT_INLINE Vec64 fromSb( + int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) + { + Vec64 self; + self.setSb(x0, x1, x2, x3, x4, x5, x6, x7); + return self; + } + + //! Set all eight 8-bit signed integers. + static ASMJIT_INLINE Vec64 fromSb( + int8_t x0) + { + Vec64 self; + self.setSb(x0); + return self; + } + + //! Set all eight 8-bit unsigned integers. + static ASMJIT_INLINE Vec64 fromUb( + uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) + { + Vec64 self; + self.setUb(x0, x1, x2, x3, x4, x5, x6, x7); + return self; + } + + //! Set all eight 8-bit unsigned integers. + static ASMJIT_INLINE Vec64 fromUb( + uint8_t x0) + { + Vec64 self; + self.setUb(x0); + return self; + } + + //! Set all four 16-bit signed integers. + static ASMJIT_INLINE Vec64 fromSw( + int16_t x0, int16_t x1, int16_t x2, int16_t x3) + { + Vec64 self; + self.setSw(x0, x1, x2, x3); + return self; + } + + //! Set all four 16-bit signed integers. + static ASMJIT_INLINE Vec64 fromSw( + int16_t x0) + { + Vec64 self; + self.setSw(x0); + return self; + } + + //! Set all four 16-bit unsigned integers. + static ASMJIT_INLINE Vec64 fromUw( + uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) + { + Vec64 self; + self.setUw(x0, x1, x2, x3); + return self; + } + + //! Set all four 16-bit unsigned integers. + static ASMJIT_INLINE Vec64 fromUw( + uint16_t x0) + { + Vec64 self; + self.setUw(x0); + return self; + } + + //! Set all two 32-bit signed integers. + static ASMJIT_INLINE Vec64 fromSd( + int32_t x0, int32_t x1) + { + Vec64 self; + self.setSd(x0, x1); + return self; + } + + //! Set all two 32-bit signed integers. + static ASMJIT_INLINE Vec64 fromSd( + int32_t x0) + { + Vec64 self; + self.setSd(x0); + return self; + } + + //! Set all two 32-bit unsigned integers. + static ASMJIT_INLINE Vec64 fromUd( + uint32_t x0, uint32_t x1) + { + Vec64 self; + self.setUd(x0, x1); + return self; + } + + //! Set all two 32-bit unsigned integers. + static ASMJIT_INLINE Vec64 fromUd( + uint32_t x0) + { + Vec64 self; + self.setUd(x0); + return self; + } + + //! Set 64-bit signed integer. + static ASMJIT_INLINE Vec64 fromSq( + int64_t x0) + { + Vec64 self; + self.setSq(x0); + return self; + } + + //! Set 64-bit unsigned integer. + static ASMJIT_INLINE Vec64 fromUq( + uint64_t x0) + { + Vec64 self; + self.setUq(x0); + return self; + } + + //! Set all two SP-FP values. + static ASMJIT_INLINE Vec64 fromSf( + float x0, float x1) + { + Vec64 self; + self.setSf(x0, x1); + return self; + } + + //! Set all two SP-FP values. + static ASMJIT_INLINE Vec64 fromSf( + float x0) + { + Vec64 self; + self.setSf(x0); + return self; + } + + //! Set all two SP-FP values. + static ASMJIT_INLINE Vec64 fromDf( + double x0) + { + Vec64 self; + self.setDf(x0); + return self; + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Set all eight 8-bit signed integers. + ASMJIT_INLINE void setSb( + int8_t x0, int8_t x1, int8_t x2, int8_t x3, int8_t x4, int8_t x5, int8_t x6, int8_t x7) + { + sb[0] = x0; sb[1] = x1; sb[2] = x2; sb[3] = x3; + sb[4] = x4; sb[5] = x5; sb[6] = x6; sb[7] = x7; + } + + //! Set all eight 8-bit signed integers. + ASMJIT_INLINE void setSb( + int8_t x0) + { + setUb(static_cast(x0)); + } + + //! Set all eight 8-bit unsigned integers. + ASMJIT_INLINE void setUb( + uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7) + { + ub[0] = x0; ub[1] = x1; ub[2] = x2; ub[3] = x3; + ub[4] = x4; ub[5] = x5; ub[6] = x6; ub[7] = x7; + } + + //! Set all eight 8-bit unsigned integers. + ASMJIT_INLINE void setUb( + uint8_t x0) + { + if (kArchHost64Bit) { + uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0101010101010101); + uq[0] = t; + } + else { + uint32_t t = static_cast(x0) * static_cast(0x01010101U); + ud[0] = t; + ud[1] = t; + } + } + + //! Set all four 16-bit signed integers. + ASMJIT_INLINE void setSw( + int16_t x0, int16_t x1, int16_t x2, int16_t x3) + { + sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; + } + + //! Set all four 16-bit signed integers. + ASMJIT_INLINE void setSw( + int16_t x0) + { + setUw(static_cast(x0)); + } + + //! Set all four 16-bit unsigned integers. + ASMJIT_INLINE void setUw( + uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3) + { + uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; + } + + //! Set all four 16-bit unsigned integers. + ASMJIT_INLINE void setUw( + uint16_t x0) + { + if (kArchHost64Bit) { + uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0001000100010001); + uq[0] = t; + } + else { + uint32_t t = static_cast(x0) * static_cast(0x00010001U); + ud[0] = t; + ud[1] = t; + } + } + + //! Set all two 32-bit signed integers. + ASMJIT_INLINE void setSd( + int32_t x0, int32_t x1) + { + sd[0] = x0; sd[1] = x1; + } + + //! Set all two 32-bit signed integers. + ASMJIT_INLINE void setSd( + int32_t x0) + { + sd[0] = x0; sd[1] = x0; + } + + //! Set all two 32-bit unsigned integers. + ASMJIT_INLINE void setUd( + uint32_t x0, uint32_t x1) + { + ud[0] = x0; ud[1] = x1; + } + + //! Set all two 32-bit unsigned integers. + ASMJIT_INLINE void setUd( + uint32_t x0) + { + ud[0] = x0; ud[1] = x0; + } + + //! Set 64-bit signed integer. + ASMJIT_INLINE void setSq( + int64_t x0) + { + sq[0] = x0; + } + + //! Set 64-bit unsigned integer. + ASMJIT_INLINE void setUq( + uint64_t x0) + { + uq[0] = x0; + } + + //! Set all two SP-FP values. + ASMJIT_INLINE void setSf( + float x0, float x1) + { + sf[0] = x0; sf[1] = x1; + } + + //! Set all two SP-FP values. + ASMJIT_INLINE void setSf( + float x0) + { + sf[0] = x0; sf[1] = x0; + } + + //! Set all two SP-FP values. + ASMJIT_INLINE void setDf( + double x0) + { + df[0] = x0; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Array of eight 8-bit signed integers. + int8_t sb[8]; + //! Array of eight 8-bit unsigned integers. + uint8_t ub[8]; + //! Array of four 16-bit signed integers. + int16_t sw[4]; + //! Array of four 16-bit unsigned integers. + uint16_t uw[4]; + //! Array of two 32-bit signed integers. + int32_t sd[2]; + //! Array of two 32-bit unsigned integers. + uint32_t ud[2]; + //! Array of one 64-bit signed integer. + int64_t sq[1]; + //! Array of one 64-bit unsigned integer. + uint64_t uq[1]; + + //! Array of two SP-FP values. + float sf[2]; + //! Array of one DP-FP value. + double df[1]; +}; + +// ============================================================================ +// [asmjit::Vec128] +// ============================================================================ + +//! 128-bit vector register data. +union Vec128 { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Set all sixteen 8-bit signed integers. + static ASMJIT_INLINE Vec128 fromSb( + int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , + int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , + int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, + int8_t x12, int8_t x13, int8_t x14, int8_t x15) + { + Vec128 self; + self.setSb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); + return self; + } + + //! Set all sixteen 8-bit signed integers. + static ASMJIT_INLINE Vec128 fromSb( + int8_t x0) + { + Vec128 self; + self.setSb(x0); + return self; + } + + //! Set all sixteen 8-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUb( + uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , + uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , + uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, + uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15) + { + Vec128 self; + self.setUb(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); + return self; + } + + //! Set all sixteen 8-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUb( + uint8_t x0) + { + Vec128 self; + self.setUb(x0); + return self; + } + + //! Set all eight 16-bit signed integers. + static ASMJIT_INLINE Vec128 fromSw( + int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) + { + Vec128 self; + self.setSw(x0, x1, x2, x3, x4, x5, x6, x7); + return self; + } + + //! Set all eight 16-bit signed integers. + static ASMJIT_INLINE Vec128 fromSw( + int16_t x0) + { + Vec128 self; + self.setSw(x0); + return self; + } + + //! Set all eight 16-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUw( + uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) + { + Vec128 self; + self.setUw(x0, x1, x2, x3, x4, x5, x6, x7); + return self; + } + + //! Set all eight 16-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUw( + uint16_t x0) + { + Vec128 self; + self.setUw(x0); + return self; + } + + //! Set all four 32-bit signed integers. + static ASMJIT_INLINE Vec128 fromSd( + int32_t x0, int32_t x1, int32_t x2, int32_t x3) + { + Vec128 self; + self.setSd(x0, x1, x2, x3); + return self; + } + + //! Set all four 32-bit signed integers. + static ASMJIT_INLINE Vec128 fromSd( + int32_t x0) + { + Vec128 self; + self.setSd(x0); + return self; + } + + //! Set all four 32-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUd( + uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) + { + Vec128 self; + self.setUd(x0, x1, x2, x3); + return self; + } + + //! Set all four 32-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUd( + uint32_t x0) + { + Vec128 self; + self.setUd(x0); + return self; + } + + //! Set all two 64-bit signed integers. + static ASMJIT_INLINE Vec128 fromSq( + int64_t x0, int64_t x1) + { + Vec128 self; + self.setSq(x0, x1); + return self; + } + + //! Set all two 64-bit signed integers. + static ASMJIT_INLINE Vec128 fromSq( + int64_t x0) + { + Vec128 self; + self.setSq(x0); + return self; + } + + //! Set all two 64-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUq( + uint64_t x0, uint64_t x1) + { + Vec128 self; + self.setUq(x0, x1); + return self; + } + + //! Set all two 64-bit unsigned integers. + static ASMJIT_INLINE Vec128 fromUq( + uint64_t x0) + { + Vec128 self; + self.setUq(x0); + return self; + } + + //! Set all four SP-FP floats. + static ASMJIT_INLINE Vec128 fromSf( + float x0, float x1, float x2, float x3) + { + Vec128 self; + self.setSf(x0, x1, x2, x3); + return self; + } + + //! Set all four SP-FP floats. + static ASMJIT_INLINE Vec128 fromSf( + float x0) + { + Vec128 self; + self.setSf(x0); + return self; + } + + //! Set all two DP-FP floats. + static ASMJIT_INLINE Vec128 fromDf( + double x0, double x1) + { + Vec128 self; + self.setDf(x0, x1); + return self; + } + + //! Set all two DP-FP floats. + static ASMJIT_INLINE Vec128 fromDf( + double x0) + { + Vec128 self; + self.setDf(x0); + return self; + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Set all sixteen 8-bit signed integers. + ASMJIT_INLINE void setSb( + int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , + int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , + int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, + int8_t x12, int8_t x13, int8_t x14, int8_t x15) + { + sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ; + sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ; + sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11; + sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15; + } + + //! Set all sixteen 8-bit signed integers. + ASMJIT_INLINE void setSb( + int8_t x0) + { + setUb(static_cast(x0)); + } + + //! Set all sixteen 8-bit unsigned integers. + ASMJIT_INLINE void setUb( + uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , + uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , + uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, + uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15) + { + ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ; + ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ; + ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11; + ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15; + } + + //! Set all sixteen 8-bit unsigned integers. + ASMJIT_INLINE void setUb( + uint8_t x0) + { + if (kArchHost64Bit) { + uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0101010101010101); + uq[0] = t; + uq[1] = t; + } + else { + uint32_t t = static_cast(x0) * static_cast(0x01010101U); + ud[0] = t; + ud[1] = t; + ud[2] = t; + ud[3] = t; + } + } + + //! Set all eight 16-bit signed integers. + ASMJIT_INLINE void setSw( + int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7) + { + sw[0] = x0; sw[1] = x1; sw[2] = x2; sw[3] = x3; + sw[4] = x4; sw[5] = x5; sw[6] = x6; sw[7] = x7; + } + + //! Set all eight 16-bit signed integers. + ASMJIT_INLINE void setSw( + int16_t x0) + { + setUw(static_cast(x0)); + } + + //! Set all eight 16-bit unsigned integers. + ASMJIT_INLINE void setUw( + uint16_t x0, uint16_t x1, uint16_t x2, uint16_t x3, uint16_t x4, uint16_t x5, uint16_t x6, uint16_t x7) + { + uw[0] = x0; uw[1] = x1; uw[2] = x2; uw[3] = x3; + uw[4] = x4; uw[5] = x5; uw[6] = x6; uw[7] = x7; + } + + //! Set all eight 16-bit unsigned integers. + ASMJIT_INLINE void setUw( + uint16_t x0) + { + if (kArchHost64Bit) { + uint64_t t = static_cast(x0) * ASMJIT_UINT64_C(0x0001000100010001); + uq[0] = t; + uq[1] = t; + } + else { + uint32_t t = static_cast(x0) * static_cast(0x00010001U); + ud[0] = t; + ud[1] = t; + ud[2] = t; + ud[3] = t; + } + } + + //! Set all four 32-bit signed integers. + ASMJIT_INLINE void setSd( + int32_t x0, int32_t x1, int32_t x2, int32_t x3) + { + sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3; + } + + //! Set all four 32-bit signed integers. + ASMJIT_INLINE void setSd( + int32_t x0) + { + setUd(static_cast(x0)); + } + + //! Set all four 32-bit unsigned integers. + ASMJIT_INLINE void setUd( + uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) + { + ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3; + } + + //! Set all four 32-bit unsigned integers. + ASMJIT_INLINE void setUd( + uint32_t x0) + { + if (kArchHost64Bit) { + uint64_t t = (static_cast(x0) << 32) + x0; + uq[0] = t; + uq[1] = t; + } + else { + ud[0] = x0; + ud[1] = x0; + ud[2] = x0; + ud[3] = x0; + } + } + + //! Set all two 64-bit signed integers. + ASMJIT_INLINE void setSq( + int64_t x0, int64_t x1) + { + sq[0] = x0; sq[1] = x1; + } + + //! Set all two 64-bit signed integers. + ASMJIT_INLINE void setSq( + int64_t x0) + { + sq[0] = x0; sq[1] = x0; + } + + //! Set all two 64-bit unsigned integers. + ASMJIT_INLINE void setUq( + uint64_t x0, uint64_t x1) + { + uq[0] = x0; uq[1] = x1; + } + + //! Set all two 64-bit unsigned integers. + ASMJIT_INLINE void setUq( + uint64_t x0) + { + uq[0] = x0; uq[1] = x0; + } + + //! Set all four SP-FP floats. + ASMJIT_INLINE void setSf( + float x0, float x1, float x2, float x3) + { + sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3; + } + + //! Set all four SP-FP floats. + ASMJIT_INLINE void setSf( + float x0) + { + sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0; + } + + //! Set all two DP-FP floats. + ASMJIT_INLINE void setDf( + double x0, double x1) + { + df[0] = x0; df[1] = x1; + } + + //! Set all two DP-FP floats. + ASMJIT_INLINE void setDf( + double x0) + { + df[0] = x0; df[1] = x0; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Array of sixteen 8-bit signed integers. + int8_t sb[16]; + //! Array of sixteen 8-bit unsigned integers. + uint8_t ub[16]; + //! Array of eight 16-bit signed integers. + int16_t sw[8]; + //! Array of eight 16-bit unsigned integers. + uint16_t uw[8]; + //! Array of four 32-bit signed integers. + int32_t sd[4]; + //! Array of four 32-bit unsigned integers. + uint32_t ud[4]; + //! Array of two 64-bit signed integers. + int64_t sq[2]; + //! Array of two 64-bit unsigned integers. + uint64_t uq[2]; + + //! Array of four 32-bit single precision floating points. + float sf[4]; + //! Array of two 64-bit double precision floating points. + double df[2]; +}; + +// ============================================================================ +// [asmjit::Vec256] +// ============================================================================ + +//! 256-bit vector register data. +union Vec256 { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Set all thirty two 8-bit signed integers. + static ASMJIT_INLINE Vec256 fromSb( + int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , + int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , + int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, + int8_t x12, int8_t x13, int8_t x14, int8_t x15, + int8_t x16, int8_t x17, int8_t x18, int8_t x19, + int8_t x20, int8_t x21, int8_t x22, int8_t x23, + int8_t x24, int8_t x25, int8_t x26, int8_t x27, + int8_t x28, int8_t x29, int8_t x30, int8_t x31) + { + Vec256 self; + self.setSb( + x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15, + x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31); + return self; + } + + //! Set all thirty two 8-bit signed integers. + static ASMJIT_INLINE Vec256 fromSb( + int8_t x0) + { + Vec256 self; + self.setSb(x0); + return self; + } + + //! Set all thirty two 8-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUb( + uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , + uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , + uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, + uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15, + uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19, + uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23, + uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27, + uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31) + { + Vec256 self; + self.setUb( + x0, x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , x9 , x10, x11, x12, x13, x14, x15, + x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31); + return self; + } + + //! Set all thirty two 8-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUb( + uint8_t x0) + { + Vec256 self; + self.setUb(x0); + return self; + } + + //! Set all sixteen 16-bit signed integers. + static ASMJIT_INLINE Vec256 fromSw( + int16_t x0, int16_t x1, int16_t x2 , int16_t x3 , int16_t x4 , int16_t x5 , int16_t x6 , int16_t x7 , + int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15) + { + Vec256 self; + self.setSw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); + return self; + } + + //! Set all sixteen 16-bit signed integers. + static ASMJIT_INLINE Vec256 fromSw( + int16_t x0) + { + Vec256 self; + self.setSw(x0); + return self; + } + + //! Set all sixteen 16-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUw( + uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 , + uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15) + { + Vec256 self; + self.setUw(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15); + return self; + } + + //! Set all sixteen 16-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUw( + uint16_t x0) + { + Vec256 self; + self.setUw(x0); + return self; + } + + //! Set all eight 32-bit signed integers. + static ASMJIT_INLINE Vec256 fromSd( + int32_t x0, int32_t x1, int32_t x2, int32_t x3, + int32_t x4, int32_t x5, int32_t x6, int32_t x7) + { + Vec256 self; + self.setSd(x0, x1, x2, x3, x4, x5, x6, x7); + return self; + } + + //! Set all eight 32-bit signed integers. + static ASMJIT_INLINE Vec256 fromSd( + int32_t x0) + { + Vec256 self; + self.setSd(x0); + return self; + } + + //! Set all eight 32-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUd( + uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, + uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) + { + Vec256 self; + self.setUd(x0, x1, x2, x3, x4, x5, x6, x7); + return self; + } + + //! Set all eight 32-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUd( + uint32_t x0) + { + Vec256 self; + self.setUd(x0); + return self; + } + + //! Set all four 64-bit signed integers. + static ASMJIT_INLINE Vec256 fromSq( + int64_t x0, int64_t x1, int64_t x2, int64_t x3) + { + Vec256 self; + self.setSq(x0, x1, x2, x3); + return self; + } + + //! Set all four 64-bit signed integers. + static ASMJIT_INLINE Vec256 fromSq( + int64_t x0) + { + Vec256 self; + self.setSq(x0); + return self; + } + + //! Set all four 64-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUq( + uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) + { + Vec256 self; + self.setUq(x0, x1, x2, x3); + return self; + } + + //! Set all four 64-bit unsigned integers. + static ASMJIT_INLINE Vec256 fromUq( + uint64_t x0) + { + Vec256 self; + self.setUq(x0); + return self; + } + + //! Set all eight SP-FP floats. + static ASMJIT_INLINE Vec256 fromSf( + float x0, float x1, float x2, float x3, + float x4, float x5, float x6, float x7) + { + Vec256 self; + self.setSf(x0, x1, x2, x3, x4, x5, x6, x7); + return self; + } + + //! Set all eight SP-FP floats. + static ASMJIT_INLINE Vec256 fromSf( + float x0) + { + Vec256 self; + self.setSf(x0); + return self; + } + + //! Set all four DP-FP floats. + static ASMJIT_INLINE Vec256 fromDf( + double x0, double x1, double x2, double x3) + { + Vec256 self; + self.setDf(x0, x1, x2, x3); + return self; + } + + //! Set all four DP-FP floats. + static ASMJIT_INLINE Vec256 fromDf( + double x0) + { + Vec256 self; + self.setDf(x0); + return self; + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Set all thirty two 8-bit signed integers. + ASMJIT_INLINE void setSb( + int8_t x0 , int8_t x1 , int8_t x2 , int8_t x3 , + int8_t x4 , int8_t x5 , int8_t x6 , int8_t x7 , + int8_t x8 , int8_t x9 , int8_t x10, int8_t x11, + int8_t x12, int8_t x13, int8_t x14, int8_t x15, + int8_t x16, int8_t x17, int8_t x18, int8_t x19, + int8_t x20, int8_t x21, int8_t x22, int8_t x23, + int8_t x24, int8_t x25, int8_t x26, int8_t x27, + int8_t x28, int8_t x29, int8_t x30, int8_t x31) + { + sb[0 ] = x0 ; sb[1 ] = x1 ; sb[2 ] = x2 ; sb[3 ] = x3 ; + sb[4 ] = x4 ; sb[5 ] = x5 ; sb[6 ] = x6 ; sb[7 ] = x7 ; + sb[8 ] = x8 ; sb[9 ] = x9 ; sb[10] = x10; sb[11] = x11; + sb[12] = x12; sb[13] = x13; sb[14] = x14; sb[15] = x15; + sb[16] = x16; sb[17] = x17; sb[18] = x18; sb[19] = x19; + sb[20] = x20; sb[21] = x21; sb[22] = x22; sb[23] = x23; + sb[24] = x24; sb[25] = x25; sb[26] = x26; sb[27] = x27; + sb[28] = x28; sb[29] = x29; sb[30] = x30; sb[31] = x31; + } + + //! Set all thirty two 8-bit signed integers. + ASMJIT_INLINE void setSb( + int8_t x0) + { + setUb(static_cast(x0)); + } + + //! Set all thirty two 8-bit unsigned integers. + ASMJIT_INLINE void setUb( + uint8_t x0 , uint8_t x1 , uint8_t x2 , uint8_t x3 , + uint8_t x4 , uint8_t x5 , uint8_t x6 , uint8_t x7 , + uint8_t x8 , uint8_t x9 , uint8_t x10, uint8_t x11, + uint8_t x12, uint8_t x13, uint8_t x14, uint8_t x15, + uint8_t x16, uint8_t x17, uint8_t x18, uint8_t x19, + uint8_t x20, uint8_t x21, uint8_t x22, uint8_t x23, + uint8_t x24, uint8_t x25, uint8_t x26, uint8_t x27, + uint8_t x28, uint8_t x29, uint8_t x30, uint8_t x31) + { + ub[0 ] = x0 ; ub[1 ] = x1 ; ub[2 ] = x2 ; ub[3 ] = x3 ; + ub[4 ] = x4 ; ub[5 ] = x5 ; ub[6 ] = x6 ; ub[7 ] = x7 ; + ub[8 ] = x8 ; ub[9 ] = x9 ; ub[10] = x10; ub[11] = x11; + ub[12] = x12; ub[13] = x13; ub[14] = x14; ub[15] = x15; + ub[16] = x16; ub[17] = x17; ub[18] = x18; ub[19] = x19; + ub[20] = x20; ub[21] = x21; ub[22] = x22; ub[23] = x23; + ub[24] = x24; ub[25] = x25; ub[26] = x26; ub[27] = x27; + ub[28] = x28; ub[29] = x29; ub[30] = x30; ub[31] = x31; + } + + //! Set all thirty two 8-bit unsigned integers. + ASMJIT_INLINE void setUb( + uint8_t x0) + { + if (kArchHost64Bit) { + uint64_t t = static_cast(x0)* ASMJIT_UINT64_C(0x0101010101010101); + uq[0] = t; + uq[1] = t; + uq[2] = t; + uq[3] = t; + } + else { + uint32_t t = static_cast(x0)* static_cast(0x01010101U); + ud[0] = t; + ud[1] = t; + ud[2] = t; + ud[3] = t; + ud[4] = t; + ud[5] = t; + ud[6] = t; + ud[7] = t; + } + } + + //! Set all sixteen 16-bit signed integers. + ASMJIT_INLINE void setSw( + int16_t x0, int16_t x1, int16_t x2, int16_t x3, int16_t x4, int16_t x5, int16_t x6, int16_t x7, + int16_t x8, int16_t x9, int16_t x10, int16_t x11, int16_t x12, int16_t x13, int16_t x14, int16_t x15) + { + sw[0 ] = x0 ; sw[1 ] = x1 ; sw[2 ] = x2 ; sw[3 ] = x3 ; + sw[4 ] = x4 ; sw[5 ] = x5 ; sw[6 ] = x6 ; sw[7 ] = x7 ; + sw[8 ] = x8 ; sw[9 ] = x9 ; sw[10] = x10; sw[11] = x11; + sw[12] = x12; sw[13] = x13; sw[14] = x14; sw[15] = x15; + } + + //! Set all sixteen 16-bit signed integers. + ASMJIT_INLINE void setSw( + int16_t x0) + { + setUw(static_cast(x0)); + } + + //! Set all sixteen 16-bit unsigned integers. + ASMJIT_INLINE void setUw( + uint16_t x0, uint16_t x1, uint16_t x2 , uint16_t x3 , uint16_t x4 , uint16_t x5 , uint16_t x6 , uint16_t x7 , + uint16_t x8, uint16_t x9, uint16_t x10, uint16_t x11, uint16_t x12, uint16_t x13, uint16_t x14, uint16_t x15) + { + uw[0 ] = x0 ; uw[1 ] = x1 ; uw[2 ] = x2 ; uw[3 ] = x3 ; + uw[4 ] = x4 ; uw[5 ] = x5 ; uw[6 ] = x6 ; uw[7 ] = x7 ; + uw[8 ] = x8 ; uw[9 ] = x9 ; uw[10] = x10; uw[11] = x11; + uw[12] = x12; uw[13] = x13; uw[14] = x14; uw[15] = x15; + } + + //! Set all eight 16-bit unsigned integers. + ASMJIT_INLINE void setUw( + uint16_t x0) + { + if (kArchHost64Bit) { + uint64_t t = static_cast(x0)* ASMJIT_UINT64_C(0x0001000100010001); + uq[0] = t; + uq[1] = t; + uq[2] = t; + uq[3] = t; + } + else { + uint32_t t = static_cast(x0)* static_cast(0x00010001U); + ud[0] = t; + ud[1] = t; + ud[2] = t; + ud[3] = t; + ud[4] = t; + ud[5] = t; + ud[6] = t; + ud[7] = t; + } + } + + //! Set all eight 32-bit signed integers. + ASMJIT_INLINE void setSd( + int32_t x0, int32_t x1, int32_t x2, int32_t x3, + int32_t x4, int32_t x5, int32_t x6, int32_t x7) + { + sd[0] = x0; sd[1] = x1; sd[2] = x2; sd[3] = x3; + sd[4] = x4; sd[5] = x5; sd[6] = x6; sd[7] = x7; + } + + //! Set all eight 32-bit signed integers. + ASMJIT_INLINE void setSd( + int32_t x0) + { + setUd(static_cast(x0)); + } + + //! Set all eight 32-bit unsigned integers. + ASMJIT_INLINE void setUd( + uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, + uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) + { + ud[0] = x0; ud[1] = x1; ud[2] = x2; ud[3] = x3; + ud[4] = x4; ud[5] = x5; ud[6] = x6; ud[7] = x7; + } + + //! Set all eight 32-bit unsigned integers. + ASMJIT_INLINE void setUd( + uint32_t x0) + { + if (kArchHost64Bit) { + uint64_t t = (static_cast(x0) << 32) + x0; + uq[0] = t; + uq[1] = t; + uq[2] = t; + uq[3] = t; + } + else { + ud[0] = x0; + ud[1] = x0; + ud[2] = x0; + ud[3] = x0; + ud[4] = x0; + ud[5] = x0; + ud[6] = x0; + ud[7] = x0; + } + } + + //! Set all four 64-bit signed integers. + ASMJIT_INLINE void setSq( + int64_t x0, int64_t x1, int64_t x2, int64_t x3) + { + sq[0] = x0; sq[1] = x1; sq[2] = x2; sq[3] = x3; + } + + //! Set all four 64-bit signed integers. + ASMJIT_INLINE void setSq( + int64_t x0) + { + sq[0] = x0; sq[1] = x0; sq[2] = x0; sq[3] = x0; + } + + //! Set all four 64-bit unsigned integers. + ASMJIT_INLINE void setUq( + uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3) + { + uq[0] = x0; uq[1] = x1; uq[2] = x2; uq[3] = x3; + } + + //! Set all four 64-bit unsigned integers. + ASMJIT_INLINE void setUq( + uint64_t x0) + { + uq[0] = x0; uq[1] = x0; uq[2] = x0; uq[3] = x0; + } + + //! Set all eight SP-FP floats. + ASMJIT_INLINE void setSf( + float x0, float x1, float x2, float x3, + float x4, float x5, float x6, float x7) + { + sf[0] = x0; sf[1] = x1; sf[2] = x2; sf[3] = x3; + sf[4] = x4; sf[5] = x5; sf[6] = x6; sf[7] = x7; + } + + //! Set all eight SP-FP floats. + ASMJIT_INLINE void setSf( + float x0) + { + sf[0] = x0; sf[1] = x0; sf[2] = x0; sf[3] = x0; + sf[4] = x0; sf[5] = x0; sf[6] = x0; sf[7] = x0; + } + + //! Set all four DP-FP floats. + ASMJIT_INLINE void setDf( + double x0, double x1, double x2, double x3) + { + df[0] = x0; df[1] = x1; df[2] = x2; df[3] = x3; + } + + //! Set all four DP-FP floats. + ASMJIT_INLINE void setDf( + double x0) + { + df[0] = x0; df[1] = x0; df[2] = x0; df[3] = x0; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Array of thirty two 8-bit signed integers. + int8_t sb[32]; + //! Array of thirty two 8-bit unsigned integers. + uint8_t ub[32]; + //! Array of sixteen 16-bit signed integers. + int16_t sw[16]; + //! Array of sixteen 16-bit unsigned integers. + uint16_t uw[16]; + //! Array of eight 32-bit signed integers. + int32_t sd[8]; + //! Array of eight 32-bit unsigned integers. + uint32_t ud[8]; + //! Array of four 64-bit signed integers. + int64_t sq[4]; + //! Array of four 64-bit unsigned integers. + uint64_t uq[4]; + + //! Array of eight 32-bit single precision floating points. + float sf[8]; + //! Array of four 64-bit double precision floating points. + double df[4]; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_VECTYPES_H diff --git a/libraries/asmjit/base/vmem.cpp b/libraries/asmjit/base/vmem.cpp new file mode 100644 index 000000000..f0c45d946 --- /dev/null +++ b/libraries/asmjit/base/vmem.cpp @@ -0,0 +1,1286 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/error.h" +#include "../base/globals.h" +#include "../base/intutil.h" +#include "../base/lock.h" +#include "../base/vmem.h" + +// [Dependencies - Posix] +#if defined(ASMJIT_OS_POSIX) +# include +# include +# include +#endif // ASMJIT_OS_POSIX + +// [Api-Begin] +#include "../apibegin.h" + +// This file contains implementation of virtual memory management for AsmJit +// library. The initial concept is to keep this implementation simple but +// efficient. There are several goals I decided to write implementation myself. +// +// Goals: +// +// - Granularity of allocated blocks is different than granularity for a typical +// C malloc. It is at least 64-bytes so Assembler/Compiler can guarantee the +// alignment required. Alignment requirements can grow in the future, but at +// the moment 64 bytes is safe (we may jump to 128 bytes if necessary or make +// it configurable). +// +// - Keep memory manager information outside of the allocated virtual memory +// pages, because these pages allow executing of machine code and there should +// not be data required to keep track of these blocks. Another reason is that +// some environments (i.e. iOS) allow to generate and run JIT code, but this +// code has to be set to [Executable, but not Writable]. +// +// - Keep implementation simple and easy to follow. +// +// Implementation is based on bit arrays and binary trees. Bit arrays contain +// information related to allocated and unused blocks of memory. The size of +// a block is described by `MemNode::density`. Count of blocks is stored in +// `MemNode::blocks`. For example if density is 64 and count of blocks is 20, +// memory node contains 64*20 bytes of memory and smallest possible allocation +// (and also alignment) is 64 bytes. So density is also related to memory +// alignment. Binary trees (RB) are used to enable fast lookup into all addresses +// allocated by memory manager instance. This is used mainly by `VMemPrivate::release()`. +// +// Bit array looks like this (empty = unused, X = used) - Size of block 64: +// +// ------------------------------------------------------------------------- +// | |X|X| | | | | |X|X|X|X|X|X| | | | | | | | | | | | |X| | | | |X|X|X| | | +// ------------------------------------------------------------------------- +// (Maximum continuous block) +// +// These bits show that there are 12 allocated blocks (X) of 64 bytes, so total +// size allocated is 768 bytes. Maximum count of continuous memory is 12 * 64. + +namespace asmjit { + +// ============================================================================ +// [asmjit::VMemUtil - Windows] +// ============================================================================ + +// Windows specific implementation using `VirtualAllocEx` and `VirtualFree`. +#if defined(ASMJIT_OS_WINDOWS) +struct VMemLocal { + // AsmJit allows to pass a `NULL` handle to `VMemUtil`. This function is just + // a convenient way to convert such handle to the current process one. + ASMJIT_INLINE HANDLE getSafeProcessHandle(HANDLE hParam) const { + return hParam != NULL ? hParam : hProcess; + } + + size_t pageSize; + size_t pageGranularity; + HANDLE hProcess; +}; +static VMemLocal vMemLocal; + +static const VMemLocal& vMemGet() { + VMemLocal& vMem = vMemLocal; + + if (!vMem.hProcess) { + SYSTEM_INFO info; + ::GetSystemInfo(&info); + + vMem.pageSize = IntUtil::alignToPowerOf2(info.dwPageSize); + vMem.pageGranularity = info.dwAllocationGranularity; + + vMem.hProcess = ::GetCurrentProcess(); + } + + return vMem; +}; + +size_t VMemUtil::getPageSize() { + const VMemLocal& vMem = vMemGet(); + return vMem.pageSize; +} + +size_t VMemUtil::getPageGranularity() { + const VMemLocal& vMem = vMemGet(); + return vMem.pageGranularity; +} + +void* VMemUtil::alloc(size_t length, size_t* allocated, uint32_t flags) { + return allocProcessMemory(static_cast(0), length, allocated, flags); +} + +void* VMemUtil::allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, uint32_t flags) { + if (length == 0) + return NULL; + + const VMemLocal& vMem = vMemGet(); + hProcess = vMem.getSafeProcessHandle(hProcess); + + // VirtualAlloc rounds allocated size to a page size automatically. + size_t mSize = IntUtil::alignTo(length, vMem.pageSize); + + // Windows XP SP2 / Vista allow Data Excution Prevention (DEP). + DWORD protectFlags = 0; + + if (flags & kVMemFlagExecutable) + protectFlags |= (flags & kVMemFlagWritable) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + else + protectFlags |= (flags & kVMemFlagWritable) ? PAGE_READWRITE : PAGE_READONLY; + + LPVOID mBase = ::VirtualAllocEx(hProcess, NULL, mSize, MEM_COMMIT | MEM_RESERVE, protectFlags); + if (mBase == NULL) + return NULL; + + ASMJIT_ASSERT(IntUtil::isAligned( + reinterpret_cast(mBase), vMem.pageSize)); + + if (allocated != NULL) + *allocated = mSize; + return mBase; +} + +Error VMemUtil::release(void* addr, size_t length) { + return releaseProcessMemory(static_cast(0), addr, length); +} + +Error VMemUtil::releaseProcessMemory(HANDLE hProcess, void* addr, size_t /* length */) { + hProcess = vMemGet().getSafeProcessHandle(hProcess); + if (!::VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE)) + return kErrorInvalidState; + return kErrorOk; +} +#endif // ASMJIT_OS_WINDOWS + +// ============================================================================ +// [asmjit::VMemUtil - Posix] +// ============================================================================ + +// Posix specific implementation using `mmap` and `munmap`. +#if defined(ASMJIT_OS_POSIX) + +// MacOS uses MAP_ANON instead of MAP_ANONYMOUS. +#if !defined(MAP_ANONYMOUS) +# define MAP_ANONYMOUS MAP_ANON +#endif // MAP_ANONYMOUS + +struct VMemLocal { + size_t pageSize; + size_t pageGranularity; +}; +static VMemLocal vMemLocal; + +static const VMemLocal& vMemGet() { + VMemLocal& vMem = vMemLocal; + + if (!vMem.pageSize) { + size_t pageSize = ::getpagesize(); + vMem.pageSize = pageSize; + vMem.pageGranularity = IntUtil::iMax(pageSize, 65536); + } + + return vMem; +}; + +size_t VMemUtil::getPageSize() { + const VMemLocal& vMem = vMemGet(); + return vMem.pageSize; +} + +size_t VMemUtil::getPageGranularity() { + const VMemLocal& vMem = vMemGet(); + return vMem.pageGranularity; +} + +void* VMemUtil::alloc(size_t length, size_t* allocated, uint32_t flags) { + const VMemLocal& vMem = vMemGet(); + size_t msize = IntUtil::alignTo(length, vMem.pageSize); + int protection = PROT_READ; + + if (flags & kVMemFlagWritable ) protection |= PROT_WRITE; + if (flags & kVMemFlagExecutable) protection |= PROT_EXEC; + + void* mbase = ::mmap(NULL, msize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (mbase == MAP_FAILED) + return NULL; + + if (allocated != NULL) + *allocated = msize; + return mbase; +} + +Error VMemUtil::release(void* addr, size_t length) { + if (::munmap(addr, length) != 0) + return kErrorInvalidState; + + return kErrorOk; +} +#endif // ASMJIT_OS_POSIX + +// ============================================================================ +// [asmjit::VMemMgr - BitOps] +// ============================================================================ + +#define M_DIV(x, y) ((x) / (y)) +#define M_MOD(x, y) ((x) % (y)) + +//! \internal +enum { + kBitsPerEntity = (sizeof(size_t) * 8) +}; + +//! \internal +//! +//! Set `len` bits in `buf` starting at `index` bit index. +static void _SetBits(size_t* buf, size_t index, size_t len) { + if (len == 0) + return; + + size_t i = index / kBitsPerEntity; // size_t[] + size_t j = index % kBitsPerEntity; // size_t[][] bit index + + // How many bytes process in the first group. + size_t c = kBitsPerEntity - j; + if (c > len) + c = len; + + // Offset. + buf += i; + + *buf++ |= ((~(size_t)0) >> (kBitsPerEntity - c)) << j; + len -= c; + + while (len >= kBitsPerEntity) { + *buf++ = ~(size_t)0; + len -= kBitsPerEntity; + } + + if (len) + *buf |= ((~(size_t)0) >> (kBitsPerEntity - len)); +} + +// ============================================================================ +// [asmjit::VMemMgr::TypeDefs] +// ============================================================================ + +typedef VMemMgr::RbNode RbNode; +typedef VMemMgr::MemNode MemNode; +typedef VMemMgr::PermanentNode PermanentNode; + +// ============================================================================ +// [asmjit::VMemMgr::RbNode] +// ============================================================================ + +//! \internal +//! +//! Base red-black tree node. +struct VMemMgr::RbNode { + // Implementation is based on article by Julienne Walker (Public Domain), + // including C code and original comments. Thanks for the excellent article. + + // Left[0] and right[1] nodes. + RbNode* node[2]; + // Virtual memory address. + uint8_t* mem; + // Whether the node is RED. + uint32_t red; +}; + +//! \internal +//! +//! Get whether the node is red (NULL or node with red flag). +static ASMJIT_INLINE bool rbIsRed(RbNode* node) { + return node != NULL && node->red; +} + +//! \internal +//! +//! Check whether the RB tree is valid. +static int rbAssert(RbNode* root) { + if (root == NULL) + return 1; + + RbNode* ln = root->node[0]; + RbNode* rn = root->node[1]; + + // Red violation. + ASMJIT_ASSERT( !(rbIsRed(root) && (rbIsRed(ln) || rbIsRed(rn))) ); + + int lh = rbAssert(ln); + int rh = rbAssert(rn); + + // Invalid btree. + ASMJIT_ASSERT(ln == NULL || ln->mem < root->mem); + ASMJIT_ASSERT(rn == NULL || rn->mem > root->mem); + + // Black violation. + ASMJIT_ASSERT( !(lh != 0 && rh != 0 && lh != rh) ); + + // Only count black links. + if (lh != 0 && rh != 0) + return rbIsRed(root) ? lh : lh + 1; + else + return 0; +} + +//! \internal +//! +//! Single rotation. +static ASMJIT_INLINE RbNode* rbRotateSingle(RbNode* root, int dir) { + RbNode* save = root->node[!dir]; + + root->node[!dir] = save->node[dir]; + save->node[dir] = root; + + root->red = 1; + save->red = 0; + + return save; +} + +//! \internal +//! +//! Double rotation. +static ASMJIT_INLINE RbNode* rbRotateDouble(RbNode* root, int dir) { + root->node[!dir] = rbRotateSingle(root->node[!dir], !dir); + return rbRotateSingle(root, dir); +} + +// ============================================================================ +// [asmjit::VMemMgr::MemNode] +// ============================================================================ + +struct VMemMgr::MemNode : public RbNode { + // -------------------------------------------------------------------------- + // [Helpers] + // -------------------------------------------------------------------------- + + // Get available space. + ASMJIT_INLINE size_t getAvailable() const { + return size - used; + } + + ASMJIT_INLINE void fillData(MemNode* other) { + mem = other->mem; + + size = other->size; + used = other->used; + blocks = other->blocks; + density = other->density; + largestBlock = other->largestBlock; + + baUsed = other->baUsed; + baCont = other->baCont; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + MemNode* prev; // Prev node in list. + MemNode* next; // Next node in list. + + size_t size; // How many bytes contain this node. + size_t used; // How many bytes are used in this node. + size_t blocks; // How many blocks are here. + size_t density; // Minimum count of allocated bytes in this node (also alignment). + size_t largestBlock; // Contains largest block that can be allocated. + + size_t* baUsed; // Contains bits about used blocks (0 = unused, 1 = used). + size_t* baCont; // Contains bits about continuous blocks (0 = stop , 1 = continue). +}; + +// ============================================================================ +// [asmjit::VMemMgr::PermanentNode] +// ============================================================================ + +//! \internal +//! +//! Permanent node. +struct VMemMgr::PermanentNode { + // -------------------------------------------------------------------------- + // [Helpers] + // -------------------------------------------------------------------------- + + //! Get available space. + ASMJIT_INLINE size_t getAvailable() const { + return size - used; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + PermanentNode* prev; // Pointer to prev chunk or NULL. + uint8_t* mem; // Base pointer (virtual memory address). + size_t size; // Count of bytes allocated. + size_t used; // Count of bytes used. +}; + +// ============================================================================ +// [asmjit::VMemMgr - Private] +// ============================================================================ + +//! \internal +//! +//! Helper to avoid `#ifdef`s in the code. +ASMJIT_INLINE uint8_t* vMemMgrAllocVMem(VMemMgr* self, size_t size, size_t* vSize) { + uint32_t flags = kVMemFlagWritable | kVMemFlagExecutable; +#if !defined(ASMJIT_OS_WINDOWS) + return static_cast(VMemUtil::alloc(size, vSize, flags)); +#else + return static_cast(VMemUtil::allocProcessMemory(self->_hProcess, size, vSize, flags)); +#endif +} + +//! \internal +//! +//! Helper to avoid `#ifdef`s in the code. +ASMJIT_INLINE Error vMemMgrReleaseVMem(VMemMgr* self, void* p, size_t vSize) { +#if !defined(ASMJIT_OS_WINDOWS) + return VMemUtil::release(p, vSize); +#else + return VMemUtil::releaseProcessMemory(self->_hProcess, p, vSize); +#endif +} + +//! \internal +//! +//! Check whether the Red-Black tree is valid. +static bool vMemMgrCheckTree(VMemMgr* self) { + return rbAssert(self->_root) > 0; +} + +//! \internal +//! +//! Alloc virtual memory including a heap memory needed for `MemNode` data. +//! +//! Returns set-up `MemNode*` or NULL if allocation failed. +static MemNode* vMemMgrCreateNode(VMemMgr* self, size_t size, size_t density) { + size_t vSize; + uint8_t* vmem = vMemMgrAllocVMem(self, size, &vSize); + + // Out of memory. + if (vmem == NULL) + return NULL; + + size_t blocks = (vSize / density); + size_t bsize = (((blocks + 7) >> 3) + sizeof(size_t) - 1) & ~(size_t)(sizeof(size_t) - 1); + + MemNode* node = static_cast(ASMJIT_ALLOC(sizeof(MemNode))); + uint8_t* data = static_cast(ASMJIT_ALLOC(bsize * 2)); + + // Out of memory. + if (node == NULL || data == NULL) { + vMemMgrReleaseVMem(self, vmem, vSize); + if (node) ASMJIT_FREE(node); + if (data) ASMJIT_FREE(data); + return NULL; + } + + // Initialize RbNode data. + node->node[0] = NULL; + node->node[1] = NULL; + node->mem = vmem; + node->red = 1; + + // Initialize MemNode data. + node->prev = NULL; + node->next = NULL; + + node->size = vSize; + node->used = 0; + node->blocks = blocks; + node->density = density; + node->largestBlock = vSize; + + ::memset(data, 0, bsize * 2); + node->baUsed = reinterpret_cast(data); + node->baCont = reinterpret_cast(data + bsize); + + return node; +} + +static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { + if (self->_root == NULL) { + // Empty tree case. + self->_root = node; + } + else { + // False tree root. + RbNode head = { 0 }; + + // Grandparent & parent. + RbNode* g = NULL; + RbNode* t = &head; + + // Iterator & parent. + RbNode* p = NULL; + RbNode* q = t->node[1] = self->_root; + + int dir = 0, last; + + // Search down the tree. + for (;;) { + if (q == NULL) { + // Insert new node at the bottom. + q = node; + p->node[dir] = node; + } + else if (rbIsRed(q->node[0]) && rbIsRed(q->node[1])) { + // Color flip. + q->red = 1; + q->node[0]->red = 0; + q->node[1]->red = 0; + } + + // Fix red violation. + if (rbIsRed(q) && rbIsRed(p)) { + int dir2 = t->node[1] == g; + t->node[dir2] = q == p->node[last] ? rbRotateSingle(g, !last) : rbRotateDouble(g, !last); + } + + // Stop if found. + if (q == node) + break; + + last = dir; + dir = q->mem < node->mem; + + // Update helpers. + if (g != NULL) + t = g; + + g = p; + p = q; + q = q->node[dir]; + } + + // Update root. + self->_root = static_cast(head.node[1]); + } + + // Make root black. + self->_root->red = 0; + + // Link with others. + node->prev = self->_last; + + if (self->_first == NULL) { + self->_first = node; + self->_last = node; + self->_optimal = node; + } + else { + node->prev = self->_last; + self->_last->next = node; + self->_last = node; + } +} + +//! \internal +//! +//! Remove node from Red-Black tree. +//! +//! Returns node that should be freed, but it doesn't have to be necessarily +//! the `node` passed. +static MemNode* vMemMgrRemoveNode(VMemMgr* self, MemNode* node) { + // False tree root. + RbNode head = { 0 }; + + // Helpers. + RbNode* q = &head; + RbNode* p = NULL; + RbNode* g = NULL; + + // Found item. + RbNode* f = NULL; + int dir = 1; + + // Set up. + q->node[1] = self->_root; + + // Search and push a red down. + while (q->node[dir] != NULL) { + int last = dir; + + // Update helpers. + g = p; + p = q; + q = q->node[dir]; + dir = q->mem < node->mem; + + // Save found node. + if (q == node) + f = q; + + // Push the red node down. + if (!rbIsRed(q) && !rbIsRed(q->node[dir])) { + if (rbIsRed(q->node[!dir])) { + p = p->node[last] = rbRotateSingle(q, dir); + } + else if (!rbIsRed(q->node[!dir])) { + RbNode* s = p->node[!last]; + + if (s != NULL) { + if (!rbIsRed(s->node[!last]) && !rbIsRed(s->node[last])) { + // Color flip. + p->red = 0; + s->red = 1; + q->red = 1; + } + else { + int dir2 = g->node[1] == p; + + if (rbIsRed(s->node[last])) + g->node[dir2] = rbRotateDouble(p, last); + else if (rbIsRed(s->node[!last])) + g->node[dir2] = rbRotateSingle(p, last); + + // Ensure correct coloring. + q->red = g->node[dir2]->red = 1; + g->node[dir2]->node[0]->red = 0; + g->node[dir2]->node[1]->red = 0; + } + } + } + } + } + + // Replace and remove. + ASMJIT_ASSERT(f != NULL); + ASMJIT_ASSERT(f != &head); + ASMJIT_ASSERT(q != &head); + + if (f != q) { + ASMJIT_ASSERT(f != &head); + static_cast(f)->fillData(static_cast(q)); + } + + p->node[p->node[1] == q] = q->node[q->node[0] == NULL]; + + // Update root and make it black. + self->_root = static_cast(head.node[1]); + if (self->_root != NULL) + self->_root->red = 0; + + // Unlink. + MemNode* next = static_cast(q)->next; + MemNode* prev = static_cast(q)->prev; + + if (prev) + prev->next = next; + else + self->_first = next; + + if (next) + next->prev = prev; + else + self->_last = prev; + + if (self->_optimal == q) + self->_optimal = prev ? prev : next; + + return static_cast(q); +} + +static MemNode* vMemMgrFindNodeByPtr(VMemMgr* self, uint8_t* mem) { + MemNode* node = self->_root; + while (node != NULL) { + uint8_t* nodeMem = node->mem; + + // Go left. + if (mem < nodeMem) { + node = static_cast(node->node[0]); + continue; + } + + // Go right. + uint8_t* nodeEnd = nodeMem + node->size; + if (mem >= nodeEnd) { + node = static_cast(node->node[1]); + continue; + } + + // Match. + break; + } + return node; +} + +static void* vMemMgrAllocPermanent(VMemMgr* self, size_t vSize) { + static const size_t permanentAlignment = 32; + static const size_t permanentNodeSize = 32768; + + vSize = IntUtil::alignTo(vSize, permanentAlignment); + + AutoLock locked(self->_lock); + PermanentNode* node = self->_permanent; + + // Try to find space in allocated chunks. + while (node && vSize > node->getAvailable()) + node = node->prev; + + // Or allocate new node. + if (node == NULL) { + size_t nodeSize = permanentNodeSize; + + if (nodeSize < vSize) + nodeSize = vSize; + + node = static_cast(ASMJIT_ALLOC(sizeof(PermanentNode))); + + // Out of memory. + if (node == NULL) + return NULL; + + node->mem = vMemMgrAllocVMem(self, nodeSize, &node->size); + + // Out of memory. + if (node->mem == NULL) { + ASMJIT_FREE(node); + return NULL; + } + + node->used = 0; + node->prev = self->_permanent; + self->_permanent = node; + } + + // Finally, copy function code to our space we reserved for. + uint8_t* result = node->mem + node->used; + + // Update Statistics. + node->used += vSize; + self->_usedBytes += vSize; + + // Code can be null to only reserve space for code. + return static_cast(result); +} + +static void* vMemMgrAllocFreeable(VMemMgr* self, size_t vSize) { + // Current index. + size_t i; + + // How many we need to be freed. + size_t need; + size_t minVSize; + + // Align to 32 bytes by default. + vSize = IntUtil::alignTo(vSize, 32); + if (vSize == 0) + return NULL; + + AutoLock locked(self->_lock); + MemNode* node = self->_optimal; + minVSize = self->_blockSize; + + // Try to find memory block in existing nodes. + while (node) { + // Skip this node? + if ((node->getAvailable() < vSize) || (node->largestBlock < vSize && node->largestBlock != 0)) { + MemNode* next = node->next; + + if (node->getAvailable() < minVSize && node == self->_optimal && next) + self->_optimal = next; + + node = next; + continue; + } + + size_t* up = node->baUsed; // Current ubits address. + size_t ubits; // Current ubits[0] value. + size_t bit; // Current bit mask. + size_t blocks = node->blocks; // Count of blocks in node. + size_t cont = 0; // How many bits are currently freed in find loop. + size_t maxCont = 0; // Largest continuous block (bits count). + size_t j; + + need = M_DIV((vSize + node->density - 1), node->density); + i = 0; + + // Try to find node that is large enough. + while (i < blocks) { + ubits = *up++; + + // Fast skip used blocks. + if (ubits == ~(size_t)0) { + if (cont > maxCont) + maxCont = cont; + cont = 0; + + i += kBitsPerEntity; + continue; + } + + size_t max = kBitsPerEntity; + if (i + max > blocks) + max = blocks - i; + + for (j = 0, bit = 1; j < max; bit <<= 1) { + j++; + if ((ubits & bit) == 0) { + if (++cont == need) { + i += j; + i -= cont; + goto _Found; + } + + continue; + } + + if (cont > maxCont) maxCont = cont; + cont = 0; + } + + i += kBitsPerEntity; + } + + // Because we traversed the entire node, we can set largest node size that + // will be used to cache next traversing. + node->largestBlock = maxCont * node->density; + + node = node->next; + } + + // If we are here, we failed to find existing memory block and we must + // allocate a new one. + { + size_t blockSize = self->_blockSize; + if (blockSize < vSize) + blockSize = vSize; + + node = vMemMgrCreateNode(self, blockSize, self->_blockDensity); + if (node == NULL) + return NULL; + + // Update binary tree. + vMemMgrInsertNode(self, node); + ASMJIT_ASSERT(vMemMgrCheckTree(self)); + + // Alloc first node at start. + i = 0; + need = (vSize + node->density - 1) / node->density; + + // Update statistics. + self->_allocatedBytes += node->size; + } + +_Found: + // Update bits. + _SetBits(node->baUsed, i, need); + _SetBits(node->baCont, i, need - 1); + + // Update statistics. + { + size_t u = need * node->density; + node->used += u; + node->largestBlock = 0; + self->_usedBytes += u; + } + + // And return pointer to allocated memory. + uint8_t* result = node->mem + i * node->density; + ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vSize); + return result; +} + +//! \internal +//! +//! Reset the whole `VMemMgr` instance, freeing all heap memory allocated an +//! virtual memory allocated unless `keepVirtualMemory` is true (and this is +//! only used when writing data to a remote process). +static void vMemMgrReset(VMemMgr* self, bool keepVirtualMemory) { + MemNode* node = self->_first; + + while (node != NULL) { + MemNode* next = node->next; + + if (!keepVirtualMemory) + vMemMgrReleaseVMem(self, node->mem, node->size); + + ASMJIT_FREE(node->baUsed); + ASMJIT_FREE(node); + + node = next; + } + + self->_allocatedBytes = 0; + self->_usedBytes = 0; + + self->_root = NULL; + self->_first = NULL; + self->_last = NULL; + self->_optimal = NULL; +} + +// ============================================================================ +// [asmjit::VMemMgr - Construction / Destruction] +// ============================================================================ + +#if !defined(ASMJIT_OS_WINDOWS) +VMemMgr::VMemMgr() +#else +VMemMgr::VMemMgr(HANDLE hProcess) : + _hProcess(vMemGet().getSafeProcessHandle(hProcess)) +#endif // ASMJIT_OS_WINDOWS +{ + + _blockSize = VMemUtil::getPageGranularity(); + _blockDensity = 64; + + _allocatedBytes = 0; + _usedBytes = 0; + + _root = NULL; + _first = NULL; + _last = NULL; + _optimal = NULL; + + _permanent = NULL; + _keepVirtualMemory = false; +} + +VMemMgr::~VMemMgr() { + // Freeable memory cleanup - Also frees the virtual memory if configured to. + vMemMgrReset(this, _keepVirtualMemory); + + // Permanent memory cleanup - Never frees the virtual memory. + PermanentNode* node = _permanent; + while (node) { + PermanentNode* prev = node->prev; + ASMJIT_FREE(node); + node = prev; + } +} + +// ============================================================================ +// [asmjit::VMemMgr - Reset] +// ============================================================================ + +void VMemMgr::reset() { + vMemMgrReset(this, false); +} + +// ============================================================================ +// [asmjit::VMemMgr - Alloc / Release] +// ============================================================================ + +void* VMemMgr::alloc(size_t size, uint32_t type) { + if (type == kVMemAllocPermanent) + return vMemMgrAllocPermanent(this, size); + else + return vMemMgrAllocFreeable(this, size); +} + +Error VMemMgr::release(void* p) { + if (p == NULL) + return kErrorOk; + + AutoLock locked(_lock); + MemNode* node = vMemMgrFindNodeByPtr(this, static_cast(p)); + + if (node == NULL) + return kErrorInvalidArgument; + + size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem); + size_t bitpos = M_DIV(offset, node->density); + size_t i = (bitpos / kBitsPerEntity); + + size_t* up = node->baUsed + i; // Current ubits address. + size_t* cp = node->baCont + i; // Current cbits address. + size_t ubits = *up; // Current ubits[0] value. + size_t cbits = *cp; // Current cbits[0] value. + size_t bit = (size_t)1 << (bitpos % kBitsPerEntity); + + size_t cont = 0; + bool stop; + + for (;;) { + stop = (cbits & bit) == 0; + ubits &= ~bit; + cbits &= ~bit; + + bit <<= 1; + cont++; + + if (stop || bit == 0) { + *up = ubits; + *cp = cbits; + if (stop) + break; + + ubits = *++up; + cbits = *++cp; + bit = 1; + } + } + + // If the freed block is fully allocated node then it's needed to + // update 'optimal' pointer in memory manager. + if (node->used == node->size) { + MemNode* cur = _optimal; + + do { + cur = cur->prev; + if (cur == node) { + _optimal = node; + break; + } + } while (cur); + } + + // Statistics. + cont *= node->density; + if (node->largestBlock < cont) + node->largestBlock = cont; + + node->used -= cont; + _usedBytes -= cont; + + // If page is empty, we can free it. + if (node->used == 0) { + // Free memory associated with node (this memory is not accessed + // anymore so it's safe). + vMemMgrReleaseVMem(this, node->mem, node->size); + ASMJIT_FREE(node->baUsed); + + node->baUsed = NULL; + node->baCont = NULL; + + // Statistics. + _allocatedBytes -= node->size; + + // Remove node. This function can return different node than + // passed into, but data is copied into previous node if needed. + ASMJIT_FREE(vMemMgrRemoveNode(this, node)); + ASMJIT_ASSERT(vMemMgrCheckTree(this)); + } + + return kErrorOk; +} + +Error VMemMgr::shrink(void* p, size_t used) { + if (p == NULL) + return kErrorOk; + + if (used == 0) + return release(p); + + AutoLock locked(_lock); + + MemNode* node = vMemMgrFindNodeByPtr(this, (uint8_t*)p); + if (node == NULL) + return kErrorInvalidArgument; + + size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem); + size_t bitpos = M_DIV(offset, node->density); + size_t i = (bitpos / kBitsPerEntity); + + size_t* up = node->baUsed + i; // Current ubits address. + size_t* cp = node->baCont + i; // Current cbits address. + size_t ubits = *up; // Current ubits[0] value. + size_t cbits = *cp; // Current cbits[0] value. + size_t bit = (size_t)1 << (bitpos % kBitsPerEntity); + + size_t cont = 0; + size_t usedBlocks = (used + node->density - 1) / node->density; + + bool stop; + + // Find the first block we can mark as free. + for (;;) { + stop = (cbits & bit) == 0; + if (stop) + return kErrorOk; + + if (++cont == usedBlocks) + break; + + bit <<= 1; + if (bit == 0) { + ubits = *++up; + cbits = *++cp; + bit = 1; + } + } + + // Free the tail blocks. + cont = ~(size_t)0; + goto _EnterFreeLoop; + + for (;;) { + stop = (cbits & bit) == 0; + ubits &= ~bit; + +_EnterFreeLoop: + cbits &= ~bit; + + bit <<= 1; + cont++; + + if (stop || bit == 0) { + *up = ubits; + *cp = cbits; + if (stop) + break; + + ubits = *++up; + cbits = *++cp; + bit = 1; + } + } + + // Statistics. + cont *= node->density; + if (node->largestBlock < cont) + node->largestBlock = cont; + + node->used -= cont; + _usedBytes -= cont; + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::VMem - Test] +// ============================================================================ + +#if defined(ASMJIT_TEST) +static void VMemTest_fill(void* a, void* b, int i) { + int pattern = rand() % 256; + *(int *)a = i; + *(int *)b = i; + ::memset((char*)a + sizeof(int), pattern, i - sizeof(int)); + ::memset((char*)b + sizeof(int), pattern, i - sizeof(int)); +} + +static void VMemTest_verify(void* a, void* b) { + int ai = *(int*)a; + int bi = *(int*)b; + + EXPECT(ai == bi, + "The length of 'a' (%d) and 'b' (%d) should be same", ai, bi); + + EXPECT(::memcmp(a, b, ai) == 0, + "Pattern (%p) doesn't match", a); +} + +static void VMemTest_stats(VMemMgr& memmgr) { + INFO("Used : %u", static_cast(memmgr.getUsedBytes())); + INFO("Allocated: %u", static_cast(memmgr.getAllocatedBytes())); +} + +static void VMemTest_shuffle(void **a, void **b, size_t count) { + for (size_t i = 0; i < count; ++i) { + size_t si = (size_t)rand() % count; + + void *ta = a[i]; + void *tb = b[i]; + + a[i] = a[si]; + b[i] = b[si]; + + a[si] = ta; + b[si] = tb; + } +} + +UNIT(base_vmem) { + VMemMgr memmgr; + + // Should be predictible. + srand(100); + + int i; + int kCount = 200000; + + INFO("Memory alloc/free test - %d allocations.", static_cast(kCount)); + + void** a = (void**)ASMJIT_ALLOC(sizeof(void*) * kCount); + void** b = (void**)ASMJIT_ALLOC(sizeof(void*) * kCount); + + EXPECT(a != NULL && b != NULL, + "Couldn't allocate %u bytes on heap.", kCount * 2); + + INFO("Allocating virtual memory..."); + for (i = 0; i < kCount; i++) { + int r = (rand() % 1000) + 4; + + a[i] = memmgr.alloc(r); + EXPECT(a[i] != NULL, + "Couldn't allocate %d bytes of virtual memory", r); + ::memset(a[i], 0, r); + } + VMemTest_stats(memmgr); + + INFO("Freeing virtual memory..."); + for (i = 0; i < kCount; i++) { + EXPECT(memmgr.release(a[i]) == kErrorOk, + "Failed to free %p.", b[i]); + } + VMemTest_stats(memmgr); + + INFO("Verified alloc/free test - %d allocations.", static_cast(kCount)); + for (i = 0; i < kCount; i++) { + int r = (rand() % 1000) + 4; + + a[i] = memmgr.alloc(r); + EXPECT(a[i] != NULL, + "Couldn't allocate %d bytes of virtual memory.", r); + + b[i] = ASMJIT_ALLOC(r); + EXPECT(b[i] != NULL, + "Couldn't allocate %d bytes on heap.", r); + + VMemTest_fill(a[i], b[i], r); + } + VMemTest_stats(memmgr); + + INFO("Shuffling..."); + VMemTest_shuffle(a, b, kCount); + + INFO("Verify and free..."); + for (i = 0; i < kCount / 2; i++) { + VMemTest_verify(a[i], b[i]); + EXPECT(memmgr.release(a[i]) == kErrorOk, + "Failed to free %p.", a[i]); + ASMJIT_FREE(b[i]); + } + VMemTest_stats(memmgr); + + INFO("Alloc again."); + for (i = 0; i < kCount / 2; i++) { + int r = (rand() % 1000) + 4; + + a[i] = memmgr.alloc(r); + EXPECT(a[i] != NULL, + "Couldn't allocate %d bytes of virtual memory.", r); + + b[i] = ASMJIT_ALLOC(r); + EXPECT(b[i] != NULL, + "Couldn't allocate %d bytes on heap."); + + VMemTest_fill(a[i], b[i], r); + } + VMemTest_stats(memmgr); + + INFO("Verify and free..."); + for (i = 0; i < kCount; i++) { + VMemTest_verify(a[i], b[i]); + EXPECT(memmgr.release(a[i]) == kErrorOk, + "Failed to free %p.", a[i]); + ASMJIT_FREE(b[i]); + } + VMemTest_stats(memmgr); + + ASMJIT_FREE(a); + ASMJIT_FREE(b); +} +#endif // ASMJIT_TEST + +} // asmjit namespace diff --git a/libraries/asmjit/base/vmem.h b/libraries/asmjit/base/vmem.h new file mode 100644 index 000000000..998a49bb6 --- /dev/null +++ b/libraries/asmjit/base/vmem.h @@ -0,0 +1,240 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_VMEM_H +#define _ASMJIT_BASE_VMEM_H + +// [Dependencies] +#include "../base/error.h" +#include "../base/lock.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::kVMemAlloc] +// ============================================================================ + +//! Type of virtual memory allocation, see `VMemMgr::alloc()`. +ASMJIT_ENUM(kVMemAlloc) { + //! Normal memory allocation, has to be freed by `VMemMgr::release()`. + kVMemAllocFreeable = 0, + //! Allocate permanent memory, can't be freed. + kVMemAllocPermanent = 1 +}; + +// ============================================================================ +// [asmjit::kVMemFlags] +// ============================================================================ + +//! Type of virtual memory allocation, see `VMemMgr::alloc()`. +ASMJIT_ENUM(kVMemFlags) { + //! Memory is writable. + kVMemFlagWritable = 0x00000001, + //! Memory is executable. + kVMemFlagExecutable = 0x00000002 +}; + +// ============================================================================ +// [asmjit::VMemUtil] +// ============================================================================ + +//! Virtual memory utilities. +//! +//! Defines functions that provide facility to allocate and free memory that is +//! executable in a platform independent manner. If both the processor and host +//! operating system support data-execution-prevention then the only way how to +//! run machine code is to allocate it to a memory that has marked as executable. +//! VMemUtil is just unified interface to platform dependent APIs. +//! +//! `VirtualAlloc()` function is used on Windows operating system and `mmap()` +//! on POSIX. `VirtualAlloc()` and `mmap()` documentation provide a detailed +//! overview on how to use a platform specific APIs. +struct VMemUtil { + //! Get a size/alignment of a single virtual memory page. + static ASMJIT_API size_t getPageSize(); + + //! Get a recommended granularity for a single `alloc` call. + static ASMJIT_API size_t getPageGranularity(); + + //! Allocate virtual memory. + //! + //! Pages are readable/writeable, but they are not guaranteed to be + //! executable unless 'canExecute' is true. Returns the address of + //! allocated memory, or NULL on failure. + static ASMJIT_API void* alloc(size_t length, size_t* allocated, uint32_t flags); + +#if defined(ASMJIT_OS_WINDOWS) + //! Allocate virtual memory of `hProcess`. + //! + //! \note This function is Windows specific. + static ASMJIT_API void* allocProcessMemory(HANDLE hProcess, size_t length, size_t* allocated, uint32_t flags); +#endif // ASMJIT_OS_WINDOWS + + //! Free memory allocated by `alloc()`. + static ASMJIT_API Error release(void* addr, size_t length); + +#if defined(ASMJIT_OS_WINDOWS) + //! Release virtual memory of `hProcess`. + //! + //! \note This function is Windows specific. + static ASMJIT_API Error releaseProcessMemory(HANDLE hProcess, void* addr, size_t length); +#endif // ASMJIT_OS_WINDOWS +}; + +// ============================================================================ +// [asmjit::VMemMgr] +// ============================================================================ + +//! Reference implementation of memory manager that uses `VMemUtil` to allocate +//! chunks of virtual memory and bit arrays to manage it. +struct VMemMgr { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + +#if !defined(ASMJIT_OS_WINDOWS) + //! Create a `VMemMgr` instance. + ASMJIT_API VMemMgr(); +#else + //! Create a `VMemMgr` instance. + //! + //! \note When running on Windows it's possible to specify a `hProcess` to + //! be used for memory allocation. This allows to allocate memory of remote + //! process. + ASMJIT_API VMemMgr(HANDLE hProcess = static_cast(0)); +#endif // ASMJIT_OS_WINDOWS + + //! Destroy the `VMemMgr` instance and free all blocks. + ASMJIT_API ~VMemMgr(); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Free all allocated memory. + ASMJIT_API void reset(); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_OS_WINDOWS) + //! Get the handle of the process memory manager is bound to. + ASMJIT_INLINE HANDLE getProcessHandle() const { + return _hProcess; + } +#endif // ASMJIT_OS_WINDOWS + + //! Get how many bytes are currently allocated. + ASMJIT_INLINE size_t getAllocatedBytes() const { + return _allocatedBytes; + } + + //! Get how many bytes are currently used. + ASMJIT_INLINE size_t getUsedBytes() const { + return _usedBytes; + } + + //! Get whether to keep allocated memory after the `VMemMgr` is destroyed. + //! + //! \sa \ref setKeepVirtualMemory. + ASMJIT_INLINE bool getKeepVirtualMemory() const { + return _keepVirtualMemory; + } + + //! Set whether to keep allocated memory after memory manager is + //! destroyed. + //! + //! This method is usable when patching code of remote process. You need to + //! allocate process memory, store generated assembler into it and patch the + //! method you want to redirect (into your code). This method affects only + //! VMemMgr destructor. After destruction all internal + //! structures are freed, only the process virtual memory remains. + //! + //! \note Memory allocated with kVMemAllocPermanent is always kept. + //! + //! \sa \ref getKeepVirtualMemory. + ASMJIT_INLINE void setKeepVirtualMemory(bool keepVirtualMemory) { + _keepVirtualMemory = keepVirtualMemory; + } + + // -------------------------------------------------------------------------- + // [Alloc / Release] + // -------------------------------------------------------------------------- + + //! Allocate a `size` bytes of virtual memory. + //! + //! Note that if you are implementing your own virtual memory manager then you + //! can quitly ignore type of allocation. This is mainly for AsmJit to memory + //! manager that allocated memory will be never freed. + ASMJIT_API void* alloc(size_t size, uint32_t type = kVMemAllocFreeable); + + //! Free previously allocated memory at a given `address`. + ASMJIT_API Error release(void* p); + + //! Free extra memory allocated with `p`. + ASMJIT_API Error shrink(void* p, size_t used); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_OS_WINDOWS) + //! Process passed to `VirtualAllocEx` and `VirtualFree`. + HANDLE _hProcess; +#endif // ASMJIT_OS_WINDOWS + + //! Lock to enable thread-safe functionality. + Lock _lock; + + //! Default block size. + size_t _blockSize; + //! Default block density. + size_t _blockDensity; + + // Whether to keep virtual memory after destroy. + bool _keepVirtualMemory; + + //! How many bytes are currently allocated. + size_t _allocatedBytes; + //! How many bytes are currently used. + size_t _usedBytes; + + //! \internal + //! \{ + + struct RbNode; + struct MemNode; + struct PermanentNode; + + // Memory nodes root. + MemNode* _root; + // Memory nodes list. + MemNode* _first; + MemNode* _last; + MemNode* _optimal; + // Permanent memory. + PermanentNode* _permanent; + + //! \} +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_VMEM_H diff --git a/libraries/asmjit/base/zone.cpp b/libraries/asmjit/base/zone.cpp new file mode 100644 index 000000000..f182392af --- /dev/null +++ b/libraries/asmjit/base/zone.cpp @@ -0,0 +1,195 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base/intutil.h" +#include "../base/zone.h" + +// [Dependencies - C] +#include + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! Zero size block used by `Zone` that doesn't have any memory allocated. +static const Zone::Block Zone_zeroBlock = { + NULL, NULL, NULL, NULL, { 0 } +}; + +// ============================================================================ +// [asmjit::Zone - Construction / Destruction] +// ============================================================================ + +Zone::Zone(size_t blockSize) { + _block = const_cast(&Zone_zeroBlock); + _blockSize = blockSize; +} + +Zone::~Zone() { + reset(true); +} + +// ============================================================================ +// [asmjit::Zone - Reset] +// ============================================================================ + +void Zone::reset(bool releaseMemory) { + Block* cur = _block; + + // Can't be altered. + if (cur == &Zone_zeroBlock) + return; + + if (releaseMemory) { + // Since cur can be in the middle of the double-linked list, we have to + // traverse to both directions `prev` and `next` separately. + Block* next = cur->next; + do { + Block* prev = cur->prev; + ASMJIT_FREE(cur); + cur = prev; + } while (cur != NULL); + + cur = next; + while (cur != NULL) { + next = cur->next; + ASMJIT_FREE(cur); + cur = next; + } + + _block = const_cast(&Zone_zeroBlock); + } + else { + while (cur->prev != NULL) + cur = cur->prev; + + cur->pos = cur->data; + _block = cur; + } +} + +// ============================================================================ +// [asmjit::Zone - Alloc] +// ============================================================================ + +void* Zone::_alloc(size_t size) { + Block* curBlock = _block; + size_t blockSize = IntUtil::iMax(_blockSize, size); + + // The `_alloc()` method can only be called if there is not enough space + // in the current block, see `alloc()` implementation for more details. + ASMJIT_ASSERT(curBlock == &Zone_zeroBlock || curBlock->getRemainingSize() < size); + + // If the `Zone` has been reset the current block doesn't have to be the + // last one. Check if there is a block that can be used instead of allocating + // a new one. If there is a `next` block it's completely unused, we don't have + // to check for remaining bytes. + Block* next = curBlock->next; + if (next != NULL && next->getBlockSize() >= size) { + next->pos = next->data + size; + _block = next; + return static_cast(next->data); + } + + // Prevent arithmetic overflow. + if (blockSize > ~static_cast(0) - sizeof(Block)) + return NULL; + + Block* newBlock = static_cast(ASMJIT_ALLOC(sizeof(Block) - sizeof(void*) + blockSize)); + if (newBlock == NULL) + return NULL; + + newBlock->pos = newBlock->data + size; + newBlock->end = newBlock->data + blockSize; + newBlock->prev = NULL; + newBlock->next = NULL; + + if (curBlock != &Zone_zeroBlock) { + newBlock->prev = curBlock; + curBlock->next = newBlock; + + // Does only happen if there is a next block, but the requested memory + // can't fit into it. In this case a new buffer is allocated and inserted + // between the current block and the next one. + if (next != NULL) { + newBlock->next = next; + next->prev = newBlock; + } + } + + _block = newBlock; + return static_cast(newBlock->data); +} + +void* Zone::allocZeroed(size_t size) { + void* p = alloc(size); + if (p != NULL) + ::memset(p, 0, size); + return p; +} + +void* Zone::dup(const void* data, size_t size) { + if (data == NULL) + return NULL; + + if (size == 0) + return NULL; + + void* m = alloc(size); + if (m == NULL) + return NULL; + + ::memcpy(m, data, size); + return m; +} + +char* Zone::sdup(const char* str) { + if (str == NULL) + return NULL; + + size_t len = ::strlen(str); + if (len == 0) + return NULL; + + // Include NULL terminator and limit string length. + if (++len > 256) + len = 256; + + char* m = static_cast(alloc(len)); + if (m == NULL) + return NULL; + + ::memcpy(m, str, len); + m[len - 1] = '\0'; + return m; +} + +char* Zone::sformat(const char* fmt, ...) { + if (fmt == NULL) + return NULL; + + char buf[512]; + size_t len; + + va_list ap; + va_start(ap, fmt); + + len = vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf) - 1, fmt, ap); + buf[len++] = 0; + + va_end(ap); + return static_cast(dup(buf, len)); +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" diff --git a/libraries/asmjit/base/zone.h b/libraries/asmjit/base/zone.h new file mode 100644 index 000000000..357890274 --- /dev/null +++ b/libraries/asmjit/base/zone.h @@ -0,0 +1,221 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BASE_ZONE_H +#define _ASMJIT_BASE_ZONE_H + +// [Dependencies] +#include "../base/globals.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_base_util +//! \{ + +// ============================================================================ +// [asmjit::Zone] +// ============================================================================ + +//! Zone memory allocator. +//! +//! Zone is an incremental memory allocator that allocates memory by simply +//! incrementing a pointer. It allocates blocks of memory by using standard +//! C library `malloc/free`, but divides these blocks into smaller segments +//! requirested by calling `Zone::alloc()` and friends. +//! +//! Zone memory allocators are designed to allocate data of short lifetime. The +//! data used by `Assembler` and `Compiler` has a very short lifetime, thus, is +//! allocated by `Zone`. The advantage is that `Zone` can free all of the data +//! allocated at once by calling `reset()` or by `Zone` destructor. +struct Zone { + // -------------------------------------------------------------------------- + // [Block] + // -------------------------------------------------------------------------- + + //! \internal + //! + //! A single block of memory. + struct Block { + // ------------------------------------------------------------------------ + // [Accessors] + // ------------------------------------------------------------------------ + + //! Get the size of the block. + ASMJIT_INLINE size_t getBlockSize() const { + return (size_t)(end - data); + } + + //! Get count of remaining bytes in the block. + ASMJIT_INLINE size_t getRemainingSize() const { + return (size_t)(end - pos); + } + + // ------------------------------------------------------------------------ + // [Members] + // ------------------------------------------------------------------------ + + //! Current data pointer (pointer to the first available byte). + uint8_t* pos; + //! End data pointer (pointer to the first invalid byte). + uint8_t* end; + + //! Link to the previous block. + Block* prev; + //! Link to the next block. + Block* next; + + //! Data. + uint8_t data[sizeof(void*)]; + }; + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new instance of `Zone` allocator. + //! + //! The `blockSize` parameter describes the default size of the block. If the + //! `size` parameter passed to `alloc()` is greater than the default size + //! `Zone` will allocate and use a larger block, but it will not change the + //! default `blockSize`. + //! + //! It's not required, but it's good practice to set `blockSize` to a + //! reasonable value that depends on the usage of `Zone`. Greater block sizes + //! are generally safer and performs better than unreasonably low values. + ASMJIT_API Zone(size_t blockSize); + + //! Destroy the `Zone` instance. + //! + //! This will destroy the `Zone` instance and release all blocks of memory + //! allocated by it. It performs implicit `reset(true)`. + ASMJIT_API ~Zone(); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + //! Reset the `Zone` invalidating all blocks allocated. + //! + //! If `releaseMemory` is true all buffers will be released to the system. + ASMJIT_API void reset(bool releaseMemory = false); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the default block size. + ASMJIT_INLINE size_t getBlockSize() const { + return _blockSize; + } + + // -------------------------------------------------------------------------- + // [Alloc] + // -------------------------------------------------------------------------- + + //! Allocate `size` bytes of memory. + //! + //! Pointer returned is valid until the `Zone` instance is destroyed or reset + //! by calling `reset()`. If you plan to make an instance of C++ from the + //! given pointer use placement `new` and `delete` operators: + //! + //! ~~~ + //! using namespace asmjit; + //! + //! class SomeObject { ... }; + //! + //! // Create Zone with default block size of 65536 bytes. + //! Zone zone(65536); + //! + //! // Create your objects using zone object allocating, for example: + //! Object* obj = static_cast( zone.alloc(sizeof(SomeClass)) ); + // + //! if (obj == NULL) { + //! // Handle out of memory error. + //! } + //! + //! // To instantiate class placement `new` and `delete` operators can be used. + //! new(obj) Object(); + //! + //! // ... lifetime of your objects ... + //! + //! // To destroy the instance (if required). + //! obj->~Object(); + //! + //! // Reset of destroy `Zone`. + //! zone.reset(); + //! ~~~ + ASMJIT_INLINE void* alloc(size_t size) { + Block* cur = _block; + + uint8_t* ptr = cur->pos; + size_t remainingBytes = (size_t)(cur->end - ptr); + + if (remainingBytes < size) + return _alloc(size); + + cur->pos += size; + ASMJIT_ASSERT(cur->pos <= cur->end); + + return (void*)ptr; + } + + //! Allocate `size` bytes of zeroed memory. + //! + //! See \ref alloc() for more details. + ASMJIT_API void* allocZeroed(size_t size); + + //! Like `alloc()`, but the return pointer is casted to `T*`. + template + ASMJIT_INLINE T* allocT(size_t size = sizeof(T)) { + return static_cast(alloc(size)); + } + + //! Like `allocZeroed()`, but the return pointer is casted to `T*`. + template + ASMJIT_INLINE T* allocZeroedT(size_t size = sizeof(T)) { + return static_cast(allocZeroed(size)); + } + + //! \internal + ASMJIT_API void* _alloc(size_t size); + + //! Helper to duplicate data. + ASMJIT_API void* dup(const void* data, size_t size); + + //! Helper to duplicate string. + ASMJIT_API char* sdup(const char* str); + + //! Helper to duplicate formatted string, maximum length is 256 bytes. + ASMJIT_API char* sformat(const char* str, ...); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! The current block. + Block* _block; + //! Default block size. + size_t _blockSize; +}; + +enum { + //! Zone allocator overhead. + kZoneOverhead = static_cast(sizeof(Zone::Block) - sizeof(void*)) + kMemAllocOverhead +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_BASE_ZONE_H diff --git a/libraries/asmjit/build.h b/libraries/asmjit/build.h new file mode 100644 index 000000000..e73b5551f --- /dev/null +++ b/libraries/asmjit/build.h @@ -0,0 +1,385 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_BUILD_H +#define _ASMJIT_BUILD_H + +// [Include] +#if defined(ASMJIT_CONFIG_FILE) +# include ASMJIT_CONFIG_FILE +#else +# include "./config.h" +#endif // ASMJIT_CONFIG_FILE + +// Turn off deprecation warnings when compiling AsmJit. +#if defined(ASMJIT_EXPORTS) && defined(_MSC_VER) +# if !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +# endif // !_CRT_SECURE_NO_DEPRECATE +# if !defined(_CRT_SECURE_NO_WARNINGS) +# define _CRT_SECURE_NO_WARNINGS +# endif // !_CRT_SECURE_NO_WARNINGS +#endif // ASMJIT_EXPORTS + +// [Dependencies - C] +#include +#include +#include + +// [Dependencies - C++] +#include + +// ============================================================================ +// [asmjit::build - Sanity] +// ============================================================================ + +#if defined(ASMJIT_DISABLE_NAMES) && !defined(ASMJIT_DISABLE_LOGGER) +# error "ASMJIT_DISABLE_NAMES requires ASMJIT_DISABLE_LOGGER to be defined." +#endif // ASMJIT_DISABLE_NAMES && !ASMJIT_DISABLE_LOGGER + +// ============================================================================ +// [asmjit::build - OS] +// ============================================================================ + +#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64) +# define ASMJIT_OS_WINDOWS +#elif defined(__linux) || defined(__linux__) +# define ASMJIT_OS_POSIX +# define ASMJIT_OS_LINUX +#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +# define ASMJIT_OS_POSIX +# define ASMJIT_OS_BSD +#elif defined(__APPLE__) +# define ASMJIT_OS_POSIX +# define ASMJIT_OS_MAC +#else +# warning "AsmJit - Unable to detect host operating system, using ASMJIT_OS_POSIX" +# define ASMJIT_OS_POSIX +#endif + +// ============================================================================ +// [asmjit::build - Arch] +// ============================================================================ + +#if defined(_M_X64 ) || \ + defined(_M_AMD64 ) || \ + defined(_WIN64 ) || \ + defined(__amd64__ ) || \ + defined(__LP64 ) || \ + defined(__x86_64__) +# define ASMJIT_HOST_X64 +# define ASMJIT_HOST_LE +# define ASMJIT_HOST_UNALIGNED_16 +# define ASMJIT_HOST_UNALIGNED_32 +# define ASMJIT_HOST_UNALIGNED_64 +#elif \ + defined(_M_IX86 ) || \ + defined(__INTEL__) || \ + defined(__i386__ ) +# define ASMJIT_HOST_X86 +# define ASMJIT_HOST_LE +# define ASMJIT_HOST_UNALIGNED_16 +# define ASMJIT_HOST_UNALIGNED_32 +# define ASMJIT_HOST_UNALIGNED_64 +#elif \ + defined(_ARM ) || \ + defined(_M_ARM_FP ) || \ + defined(__ARM_NEON__ ) || \ + defined(__arm ) || \ + defined(__arm__ ) || \ + defined(__TARGET_ARCH_ARM ) || \ + defined(__TARGET_ARCH_THUMB) || \ + defined(__thumb__ ) +# define ASMJIT_HOST_ARM +# define ASMJIT_HOST_LE +#else +# warning "AsmJit - Unable to detect host architecture" +#endif + +// ============================================================================ +// [asmjit::build - Build] +// ============================================================================ + +// Build host architecture if no architecture is selected. +#if !defined(ASMJIT_BUILD_HOST) && \ + !defined(ASMJIT_BUILD_X86) && \ + !defined(ASMJIT_BUILD_X64) +# define ASMJIT_BUILD_HOST +#endif + +// Autodetect host architecture if enabled. +#if defined(ASMJIT_BUILD_HOST) +# if defined(ASMJIT_HOST_X86) && !defined(ASMJIT_BUILD_X86) +# define ASMJIT_BUILD_X86 +# endif // ASMJIT_HOST_X86 && !ASMJIT_BUILD_X86 +# if defined(ASMJIT_HOST_X64) && !defined(ASMJIT_BUILD_X64) +# define ASMJIT_BUILD_X64 +# endif // ASMJIT_HOST_X64 && !ASMJIT_BUILD_X64 +#endif // ASMJIT_BUILD_HOST + +// ============================================================================ +// [asmjit::build - Decorators] +// ============================================================================ + +#if defined(ASMJIT_EMBED) && !defined(ASMJIT_STATIC) +# define ASMJIT_STATIC +#endif // ASMJIT_EMBED && !ASMJIT_STATIC + +#if defined(ASMJIT_STATIC) +# define ASMJIT_API +#elif defined(ASMJIT_OS_WINDOWS) +# if (defined(__GNUC__) || defined(__clang__)) && !defined(__MINGW32__) +# if defined(ASMJIT_EXPORTS) +# define ASMJIT_API __attribute__((dllexport)) +# else +# define ASMJIT_API __attribute__((dllimport)) +# endif // ASMJIT_EXPORTS +# else +# if defined(ASMJIT_EXPORTS) +# define ASMJIT_API __declspec(dllexport) +# else +# define ASMJIT_API __declspec(dllimport) +# endif +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) +# define ASMJIT_API __attribute__((visibility("default"))) +#endif + +#if !defined(ASMJIT_API) +# define ASMJIT_API +#endif // ASMJIT_API + +// This is basically a workaround. When using MSVC and marking class as DLL +// export everything is exported, which is unwanted since there are many +// inlines which mimic instructions. MSVC automatically exports typeinfo and +// vtable if at least one symbol of that class is exported. However, GCC has +// some strange behavior that even if one or more symbol is exported it doesn't +// export `typeinfo` unless the class itself is marked as "visibility(default)". +#if !defined(ASMJIT_OS_WINDOWS) && (defined(__GNUC__) || defined (__clang__)) +# define ASMJIT_VCLASS ASMJIT_API +#else +# define ASMJIT_VCLASS +#endif + +#if !defined(ASMJIT_VAR) +# define ASMJIT_VAR extern ASMJIT_API +#endif // !ASMJIT_VAR + +#if defined(_MSC_VER) +# define ASMJIT_INLINE __forceinline +#elif defined(__clang__) +# define ASMJIT_INLINE inline __attribute__((always_inline)) __attribute__((visibility("hidden"))) +#elif defined(__GNUC__) +# define ASMJIT_INLINE inline __attribute__((always_inline)) +#else +# define ASMJIT_INLINE inline +#endif + +#if defined(ASMJIT_HOST_X86) +# if defined(__GNUC__) || defined(__clang__) +# define ASMJIT_REGPARM_1 __attribute__((regparm(1))) +# define ASMJIT_REGPARM_2 __attribute__((regparm(2))) +# define ASMJIT_REGPARM_3 __attribute__((regparm(3))) +# define ASMJIT_FASTCALL __attribute__((fastcall)) +# define ASMJIT_STDCALL __attribute__((stdcall)) +# define ASMJIT_CDECL __attribute__((cdecl)) +# else +# define ASMJIT_FASTCALL __fastcall +# define ASMJIT_STDCALL __stdcall +# define ASMJIT_CDECL __cdecl +# endif +#else +# define ASMJIT_FASTCALL +# define ASMJIT_STDCALL +# define ASMJIT_CDECL +#endif // ASMJIT_HOST_X86 + +// ============================================================================ +// [asmjit::build - Enum] +// ============================================================================ + +#if defined(_MSC_VER) +# define ASMJIT_ENUM(_Name_) enum _Name_ : uint32_t +#else +# define ASMJIT_ENUM(_Name_) enum _Name_ +#endif + +// ============================================================================ +// [asmjit::build - Memory Management] +// ============================================================================ + +#if !defined(ASMJIT_ALLOC) && !defined(ASMJIT_REALLOC) && !defined(ASMJIT_FREE) +# define ASMJIT_ALLOC(_Size_) ::malloc(_Size_) +# define ASMJIT_REALLOC(_Ptr_, _Size_) ::realloc(_Ptr_, _Size_) +# define ASMJIT_FREE(_Ptr_) ::free(_Ptr_) +#else +# if !defined(ASMJIT_ALLOC) || !defined(ASMJIT_REALLOC) || !defined(ASMJIT_FREE) +# error "AsmJit - You must redefine ASMJIT_ALLOC, ASMJIT_REALLOC and ASMJIT_FREE." +# endif +#endif // !ASMJIT_ALLOC && !ASMJIT_REALLOC && !ASMJIT_FREE + +// ============================================================================ +// [asmjit::build - _ASMJIT_HOST_INDEX] +// ============================================================================ + +#if defined(ASMJIT_HOST_LE) +# define _ASMJIT_HOST_INDEX(_Total_, _Index_) (_Index_) +#else +# define _ASMJIT_HOST_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_)) +#endif + +// ============================================================================ +// [asmjit::build - BLEND_OFFSET_OF] +// ============================================================================ + +//! Cross-platform solution to get offset of `_Field_` in `_Struct_`. +#define ASMJIT_OFFSET_OF(_Struct_, _Field_) \ + ((size_t) ((const uint8_t*) &((const _Struct_*)0x1)->_Field_) - 1) + +// ============================================================================ +// [asmjit::build - ASMJIT_ARRAY_SIZE] +// ============================================================================ + +#define ASMJIT_ARRAY_SIZE(_Array_) \ + (sizeof(_Array_) / sizeof(*_Array_)) + +// ============================================================================ +// [asmjit::build - ASMJIT_DEBUG / ASMJIT_TRACE] +// ============================================================================ + +// If ASMJIT_DEBUG and ASMJIT_RELEASE is not defined ASMJIT_DEBUG will be +// detected using the compiler specific macros. This enables to set the build +// type using IDE. +#if !defined(ASMJIT_DEBUG) && !defined(ASMJIT_RELEASE) +# if defined(_DEBUG) +# define ASMJIT_DEBUG +# endif // _DEBUG +#endif // !ASMJIT_DEBUG && !ASMJIT_RELEASE + +// ASMJIT_TRACE is only used by sources and private headers. It's safe to make +// it unavailable outside of AsmJit. +#if defined(ASMJIT_EXPORTS) +namespace asmjit { static inline int disabledTrace(...) {} } +# if defined(ASMJIT_TRACE) +# define ASMJIT_TSEC(_Section_) _Section_ +# define ASMJIT_TLOG ::printf(__VA_ARGS__) +# else +# define ASMJIT_TSEC(_Section_) do {} while(0) +# define ASMJIT_TLOG 0 && ::asmjit::disabledTrace +# endif // ASMJIT_TRACE +#endif // ASMJIT_EXPORTS + +// ============================================================================ +// [asmjit::build - ASMJIT_UNUSED] +// ============================================================================ + +#if !defined(ASMJIT_UNUSED) +# define ASMJIT_UNUSED(_Var_) ((void)_Var_) +#endif // ASMJIT_UNUSED + +// ============================================================================ +// [asmjit::build - ASMJIT_NOP] +// ============================================================================ + +#if !defined(ASMJIT_NOP) +# define ASMJIT_NOP() ((void)0) +#endif // ASMJIT_NOP + +// ============================================================================ +// [asmjit::build - ASMJIT_NO_COPY] +// ============================================================================ + +#define ASMJIT_NO_COPY(_Type_) \ +private: \ + ASMJIT_INLINE _Type_(const _Type_& other); \ + ASMJIT_INLINE _Type_& operator=(const _Type_& other); \ +public: + +// ============================================================================ +// [asmjit::build - StdInt] +// ============================================================================ + +#if defined(__MINGW32__) +# include +#endif // __MINGW32__ + +#if defined(_MSC_VER) && (_MSC_VER < 1600) +# if !defined(ASMJIT_SUPRESS_STD_TYPES) +# if (_MSC_VER < 1300) +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed __int64 int64_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; +# else +typedef signed __int8 int8_t; +typedef signed __int16 int16_t; +typedef signed __int32 int32_t; +typedef signed __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +# endif // _MSC_VER +# endif // ASMJIT_SUPRESS_STD_TYPES +#else +# include +# include +#endif + +#if defined(_MSC_VER) +# define ASMJIT_INT64_C(_Num_) _Num_##i64 +# define ASMJIT_UINT64_C(_Num_) _Num_##ui64 +#else +# define ASMJIT_INT64_C(_Num_) _Num_##LL +# define ASMJIT_UINT64_C(_Num_) _Num_##ULL +#endif + +// ============================================================================ +// [asmjit::build - Windows] +// ============================================================================ + +#if defined(ASMJIT_OS_WINDOWS) && !defined(ASMJIT_SUPRESS_WINDOWS_H) + +# if !defined(WIN32_LEAN_AND_MEAN) +# define WIN32_LEAN_AND_MEAN +# define ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN +# endif // !WIN32_LEAN_AND_MEAN + +# if !defined(NOMINMAX) +# define NOMINMAX +# define ASMJIT_UNDEF_NOMINMAX +# endif // !NOMINMAX + +# include + +# if defined(ASMJIT_UNDEF_NOMINMAX) +# undef NOMINMAX +# undef ASMJIT_UNDEF_NOMINMAX +# endif + +# if defined(ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN) +# undef WIN32_LEAN_AND_MEAN +# undef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN +# endif + +#endif // ASMJIT_OS_WINDOWS && !ASMJIT_SUPRESS_WINDOWS_H + +// ============================================================================ +// [asmjit::build - Test] +// ============================================================================ + +// Include a unit testing package if this is a `asmjit_test` build. +#if defined(ASMJIT_TEST) +#include "./test/broken.h" +#endif // ASMJIT_TEST + +// [Guard] +#endif // _ASMJIT_BUILD_H diff --git a/libraries/asmjit/config.h b/libraries/asmjit/config.h new file mode 100644 index 000000000..4fd4d2a33 --- /dev/null +++ b/libraries/asmjit/config.h @@ -0,0 +1,53 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_CONFIG_H +#define _ASMJIT_CONFIG_H + +// This file can be used to modify built-in features of AsmJit. AsmJit is by +// default compiled only for host processor to enable JIT compilation. Both +// Assembler and Compiler code generators are compiled by default. +// +// ASMJIT_BUILD_... flags can be defined to build additional backends that can +// be used for remote code generation. +// +// ASMJIT_DISABLE_... flags can be defined to disable standard features. These +// are handy especially when building asmjit statically and some features are +// not needed or unwanted (like Compiler). + +// ============================================================================ +// [AsmJit - Build-Type] +// ============================================================================ + +// #define ASMJIT_EMBED // Asmjit is embedded (implies ASMJIT_STATIC). +// #define ASMJIT_STATIC // Define to enable static-library build. + +// ============================================================================ +// [AsmJit - Build-Mode] +// ============================================================================ + +// #define ASMJIT_DEBUG // Define to enable debug-mode. +// #define ASMJIT_RELEASE // Define to enable release-mode. +// #define ASMJIT_TRACE // Define to enable tracing. + +// ============================================================================ +// [AsmJit - Features] +// ============================================================================ + +// If none of these is defined AsmJit will select host architecture by default. +// #define ASMJIT_BUILD_X86 // Define to enable x86 instruction set (32-bit). +// #define ASMJIT_BUILD_X64 // Define to enable x64 instruction set (64-bit). +// #define ASMJIT_BUILD_HOST // Define to enable host instruction set. + +// AsmJit features are enabled by default. +// #define ASMJIT_DISABLE_COMPILER // Disable Compiler (completely). +// #define ASMJIT_DISABLE_LOGGER // Disable Logger (completely). +// #define ASMJIT_DISABLE_NAMES // Disable everything that uses strings + // (instruction names, error names, ...). + +// [Guard] +#endif // _ASMJIT_CONFIG_H diff --git a/libraries/asmjit/contrib.h b/libraries/asmjit/contrib.h new file mode 100644 index 000000000..dece8b362 --- /dev/null +++ b/libraries/asmjit/contrib.h @@ -0,0 +1,18 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in this package. + +// [Guard] +#ifndef _ASMJIT_CONTRIB_H +#define _ASMJIT_CONTRIB_H + +// [Dependencies - Core] +#include "base.h" + +// [Dependencies - Contrib] +#include "contrib/winremoteruntime.h" + +// [Guard] +#endif // _ASMJIT_CONTRIB_H diff --git a/libraries/asmjit/contrib/winremoteruntime.cpp b/libraries/asmjit/contrib/winremoteruntime.cpp new file mode 100644 index 000000000..3a2fe53c5 --- /dev/null +++ b/libraries/asmjit/contrib/winremoteruntime.cpp @@ -0,0 +1,79 @@ +// [AsmJit/WinRemoteRuntime] +// Contribution for remote process handling. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Dependencies - AsmJit] +#include "../base.h" + +// [Guard - Windows] +#if defined(ASMJIT_OS_WINDOWS) +#include "winremoteruntime.h" + +namespace asmjit { +namespace contrib { + +// ============================================================================ +// [asmjit::contrib::WinRemoteRuntime - Construction / Destruction] +// ============================================================================ + +WinRemoteRuntime::WinRemoteRuntime(HANDLE hProcess) : + _memMgr(hProcess) { + + // We are patching another process so enable keep-virtual-memory option. + _memMgr.setKeepVirtualMemory(true); +} + +WinRemoteRuntime::~WinRemoteRuntime() {} + +// ============================================================================ +// [asmjit::contrib::WinRemoteRuntime - Interface] +// ============================================================================ + +uint32_t WinRemoteRuntime::add(void** dest, BaseAssembler* assembler) { + // Disallow generation of no code. + size_t codeSize = assembler->getCodeSize(); + if (codeSize == 0) { + *dest = NULL; + return kErrorInvalidState; + } + + // Allocate temporary memory where the code will be stored and relocated. + void* codeData = ASMJIT_ALLOC(codeSize); + if (codeData == NULL) { + *dest = NULL; + return kErrorNoHeapMemory; + } + + // Allocate a permanent remote process memory. + void* processMemPtr = _memMgr.alloc(codeSize, kVMemAllocPermanent); + if (processMemPtr == NULL) { + ASMJIT_FREE(codeData); + *dest = NULL; + return kErrorNoVirtualMemory; + } + + // Relocate and write the code to the process memory. + assembler->relocCode(codeData, (uintptr_t)processMemPtr); + + ::WriteProcessMemory(getProcessHandle(), processMemPtr, codeData, codeSize, NULL); + ASMJIT_FREE(codeData); + + *dest = processMemPtr; + return kErrorOk; +} + +// NOP. +Error WinRemoteRuntime::release(void* p) { + return kErrorOk; +} + +} // contrib namespace +} // asmjit namespace + +// [Guard - Windows] +#endif // ASMJIT_OS_WINDOWS diff --git a/libraries/asmjit/contrib/winremoteruntime.h b/libraries/asmjit/contrib/winremoteruntime.h new file mode 100644 index 000000000..da393444e --- /dev/null +++ b/libraries/asmjit/contrib/winremoteruntime.h @@ -0,0 +1,74 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_CONTRIB_WINREMOTERUNTIME_H +#define _ASMJIT_CONTRIB_WINREMOTERUNTIME_H + +#include "../base.h" +#if defined(ASMJIT_OS_WINDOWS) + +namespace asmjit { +namespace contrib { + +//! \addtogroup asmjit_contrib +//! \{ + +// ============================================================================ +// [asmjit::contrib::WinRemoteRuntime] +// ============================================================================ + +//! WinRemoteRuntime can be used to inject code to a remote process. +struct WinRemoteRuntime : public Runtime { + ASMJIT_NO_COPY(WinRemoteRuntime) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `WinRemoteRuntime` instance for a given `hProcess`. + ASMJIT_API WinRemoteRuntime(HANDLE hProcess); + + //! Destroy the `WinRemoteRuntime` instance. + ASMJIT_API virtual ~WinRemoteRuntime(); + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the remote process handle. + ASMJIT_INLINE HANDLE getProcessHandle() const { + return _memMgr.getProcessHandle(); + } + + //! Get the remote memory manager. + ASMJIT_INLINE VMemMgr* getMemMgr() const { + return const_cast(&_memMgr); + } + + // -------------------------------------------------------------------------- + // [Interface] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual uint32_t add(void** dest, BaseAssembler* assembler); + ASMJIT_API virtual Error release(void* p); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Remove memory manager. + VMemMgr _memMgr; +}; + +//! \} + +} // contrib namespace +} // asmjit namespace + +// [Guard] +#endif // ASMJIT_OS_WINDOWS +#endif // _ASMJIT_CONTRIB_WINREMOTERUNTIME_H diff --git a/libraries/asmjit/host.h b/libraries/asmjit/host.h new file mode 100644 index 000000000..48d8ce4b1 --- /dev/null +++ b/libraries/asmjit/host.h @@ -0,0 +1,59 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_HOST_H +#define _ASMJIT_HOST_H + +// [Dependencies - Core] +#include "base.h" + +// ============================================================================ +// [asmjit::host - X86 / X64] +// ============================================================================ + +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#include "x86.h" + +namespace asmjit { + +// Define `asmjit::host` namespace wrapping `asmjit::x86`. +namespace host { using namespace ::asmjit::x86; } + +// Define host assembler. +typedef X86Assembler HostAssembler; + +// Define host operands. +typedef X86GpReg GpReg; +typedef X86FpReg FpReg; +typedef X86MmReg MmReg; +typedef X86XmmReg XmmReg; +typedef X86YmmReg YmmReg; +typedef X86SegReg SegReg; +typedef X86Mem Mem; + +// Define host utilities. +typedef X86CpuInfo HostCpuInfo; + +// Define host compiler and related. +#if !defined(ASMJIT_DISABLE_COMPILER) +typedef X86Compiler HostCompiler; +typedef X86CallNode HostCallNode; +typedef X86FuncDecl HostFuncDecl; +typedef X86FuncNode HostFuncNode; + +typedef X86GpVar GpVar; +typedef X86MmVar MmVar; +typedef X86XmmVar XmmVar; +typedef X86YmmVar YmmVar; +#endif // !ASMJIT_DISABLE_COMPILER + +} // asmjit namespace + +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + +// [Guard] +#endif // _ASMJIT_HOST_H diff --git a/libraries/asmjit/x86.h b/libraries/asmjit/x86.h new file mode 100644 index 000000000..ef5e00664 --- /dev/null +++ b/libraries/asmjit/x86.h @@ -0,0 +1,21 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_H +#define _ASMJIT_X86_H + +// [Dependencies - AsmJit] +#include "base.h" + +#include "x86/x86assembler.h" +#include "x86/x86compiler.h" +#include "x86/x86cpuinfo.h" +#include "x86/x86inst.h" +#include "x86/x86operand.h" + +// [Guard] +#endif // _ASMJIT_X86_H diff --git a/libraries/asmjit/x86/x86assembler.cpp b/libraries/asmjit/x86/x86assembler.cpp new file mode 100644 index 000000000..29d084c79 --- /dev/null +++ b/libraries/asmjit/x86/x86assembler.cpp @@ -0,0 +1,4189 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) + +// [Dependencies - AsmJit] +#include "../base/intutil.h" +#include "../base/logger.h" +#include "../base/runtime.h" +#include "../base/string.h" +#include "../base/vmem.h" +#include "../x86/x86assembler.h" +#include "../x86/x86cpuinfo.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Constants] +// ============================================================================ + +enum { kRexShift = 6 }; +enum { kRexForbidden = 0x80 }; +enum { kMaxCommentLength = 80 }; + +// 2-byte VEX prefix. +// [0] kVex2Byte. +// [1] RvvvvLpp. +enum { kVex2Byte = 0xC5 }; + +// 3-byte VEX prefix. +// [0] kVex3Byte. +// [1] RXBmmmmm. +// [2] WvvvvLpp. +enum { kVex3Byte = 0xC4 }; + +// 3-byte XOP prefix. +// [0] kXopByte +// [1] RXBmmmmm +// [2] WvvvvLpp +enum { kXopByte = 0x8F }; + +// AsmJit specific (used to encode VVVV field in XOP/VEX). +enum kVexVVVV { + kVexVVVVShift = 12, + kVexVVVVMask = 0xF << kVexVVVVShift +}; + +//! \internal +//! +//! Instruction 2-byte/3-byte opcode prefix definition. +struct X86OpCodeMM { + uint8_t len; + uint8_t data[3]; +}; + +//! \internal +//! +//! Mandatory prefixes encoded in 'asmjit' opcode [66, F3, F2] and asmjit +//! extensions +static const uint8_t x86OpCodePP[8] = { + 0x00, + 0x66, + 0xF3, + 0xF2, + 0x00, + 0x00, + 0x00, + 0x9B +}; + +//! \internal +//! +//! Instruction 2-byte/3-byte opcode prefix data. +static const X86OpCodeMM x86OpCodeMM[] = { + { 0, { 0x00, 0x00, 0 } }, + { 1, { 0x0F, 0x00, 0 } }, + { 2, { 0x0F, 0x38, 0 } }, + { 2, { 0x0F, 0x3A, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 0, { 0x00, 0x00, 0 } }, + { 2, { 0x0F, 0x01, 0 } } +}; + +static const uint8_t x86SegmentPrefix[8] = { 0x00, 0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65 }; +static const uint8_t x86OpCodePushSeg[8] = { 0x00, 0x06, 0x0E, 0x16, 0x1E, 0xA0, 0xA8 }; +static const uint8_t x86OpCodePopSeg[8] = { 0x00, 0x07, 0x00, 0x17, 0x1F, 0xA1, 0xA9 }; + +// ============================================================================ +// [Utils] +// ============================================================================ + +//! Encode MODR/M. +static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) { + return (m << 6) + (o << 3) + rm; +} + +//! Encode SIB. +static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) { + return (s << 6) + (i << 3) + b; +} + +//! Get whether the two pointers `a` and `b` can be encoded by using relative +//! displacement, which fits into a signed 32-bit integer. +static ASMJIT_INLINE bool x64IsRelative(Ptr a, Ptr b) { + SignedPtr diff = static_cast(a) - static_cast(b); + return IntUtil::isInt32(diff); +} + +// ============================================================================ +// [Macros] +// ============================================================================ + +#define ENC_OPS(_Op0_, _Op1_, _Op2_) \ + ((kOperandType##_Op0_) + ((kOperandType##_Op1_) << 3) + ((kOperandType##_Op2_) << 6)) + +#define ADD_66H_P(_Exp_) \ + do { \ + opCode |= (static_cast(_Exp_) << kX86InstOpCode_PP_Shift); \ + } while (0) + +#define ADD_66H_P_BY_SIZE(_Size_) \ + do { \ + opCode |= (static_cast(_Size_) & 0x02) << (kX86InstOpCode_PP_Shift - 1); \ + } while (0) + +#define ADD_REX_W(_Exp_) \ + do { \ + if (Arch == kArchX64) \ + opX |= static_cast(_Exp_) << 3; \ + } while (0) + +#define ADD_REX_W_BY_SIZE(_Size_) \ + do { \ + if (Arch == kArchX64) \ + opX |= static_cast(_Size_) & 0x08; \ + } while (0) + +#define ADD_REX_B(_Reg_) \ + do { \ + if (Arch == kArchX64) \ + opX |= static_cast(_Reg_) >> 3; \ + } while (0) + +#define ADD_VEX_W(_Exp_) \ + do { \ + opX |= static_cast(_Exp_) << 3; \ + } while (0) + +#define ADD_VEX_L(_Exp_) \ + do { \ + opCode |= static_cast(_Exp_) << kX86InstOpCode_L_Shift; \ + } while (0) + +#define EMIT_BYTE(_Val_) \ + do { \ + cursor[0] = static_cast(_Val_); \ + cursor += 1; \ + } while (0) + +#define EMIT_WORD(_Val_) \ + do { \ + reinterpret_cast(cursor)[0] = static_cast(_Val_); \ + cursor += 2; \ + } while (0) + +#define EMIT_DWORD(_Val_) \ + do { \ + reinterpret_cast(cursor)[0] = static_cast(_Val_); \ + cursor += 4; \ + } while (0) + +#define EMIT_QWORD(_Val_) \ + do { \ + reinterpret_cast(cursor)[0] = static_cast(_Val_); \ + cursor += 8; \ + } while (0) + +#define EMIT_OP(_Val_) \ + do { \ + EMIT_BYTE((_Val_) & 0xFF); \ + } while (0) + +#define EMIT_PP(_Val_) \ + do { \ + uint32_t ppIndex = ((_Val_) >> kX86InstOpCode_PP_Shift) & (kX86InstOpCode_PP_Mask >> kX86InstOpCode_PP_Shift); \ + uint8_t ppCode = x86OpCodePP[ppIndex]; \ + \ + if (!ppIndex) \ + break; \ + \ + cursor[0] = ppCode; \ + cursor++; \ + } while (0) + +#define EMIT_MM(_Val_) \ + do { \ + uint32_t mmIndex = ((_Val_) >> kX86InstOpCode_MM_Shift) & (kX86InstOpCode_MM_Mask >> kX86InstOpCode_MM_Shift); \ + const X86OpCodeMM& mmCode = x86OpCodeMM[mmIndex]; \ + \ + if (!mmIndex) \ + break; \ + \ + cursor[0] = mmCode.data[0]; \ + cursor[1] = mmCode.data[1]; \ + cursor += mmCode.len; \ + } while (0) + +// ============================================================================ +// [asmjit::X86Assembler - Construction / Destruction] +// ============================================================================ + +X86Assembler::X86Assembler(Runtime* runtime, uint32_t arch) : + Assembler(runtime), + zax(NoInit), + zcx(NoInit), + zdx(NoInit), + zbx(NoInit), + zsp(NoInit), + zbp(NoInit), + zsi(NoInit), + zdi(NoInit) { + + setArch(arch); +} + +X86Assembler::~X86Assembler() {} + +// ============================================================================ +// [asmjit::X86Assembler - Arch] +// ============================================================================ + +Error X86Assembler::setArch(uint32_t arch) { +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + _arch = kArchX86; + _regSize = 4; + + _regCount.reset(); + _regCount._gp = 8; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 8; + + zax = x86::eax; + zcx = x86::ecx; + zdx = x86::edx; + zbx = x86::ebx; + zsp = x86::esp; + zbp = x86::ebp; + zsi = x86::esi; + zdi = x86::edi; + + return kErrorOk; + } +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) { + _arch = kArchX64; + _regSize = 8; + + _regCount.reset(); + _regCount._gp = 16; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 16; + + zax = x86::rax; + zcx = x86::rcx; + zdx = x86::rdx; + zbx = x86::rbx; + zsp = x86::rsp; + zbp = x86::rbp; + zsi = x86::rsi; + zdi = x86::rdi; + + return kErrorOk; + } +#endif // ASMJIT_BUILD_X64 + + ASMJIT_ASSERT(!"Reached"); + return kErrorInvalidArgument; +} + +// ============================================================================ +// [asmjit::X86Assembler - Embed] +// ============================================================================ + +Error X86Assembler::embedLabel(const Label& op) { + ASMJIT_ASSERT(op.getId() != kInvalidValue); + uint32_t regSize = _regSize; + + if (getRemainingSpace() < regSize) + ASMJIT_PROPAGATE_ERROR(_grow(regSize)); + + uint8_t* cursor = getCursor(); + + LabelData* label = getLabelData(op.getId()); + RelocData reloc; + +#if !defined(ASMJIT_DISABLE_LOGGER) + if (_logger) + _logger->logFormat(kLoggerStyleData, regSize == 4 ? ".dd L%u\n" : ".dq L%u\n", op.getId()); +#endif // !ASMJIT_DISABLE_LOGGER + + reloc.type = kRelocRelToAbs; + reloc.size = regSize; + reloc.from = static_cast(getOffset()); + reloc.data = 0; + + if (label->offset != -1) { + // Bound label. + reloc.data = static_cast(static_cast(label->offset)); + } + else { + // Non-bound label. Need to chain. + LabelLink* link = _newLabelLink(); + + link->prev = (LabelLink*)label->links; + link->offset = getOffset(); + link->displacement = 0; + link->relocId = _relocList.getLength(); + + label->links = link; + } + + if (_relocList.append(reloc) != kErrorOk) + return setError(kErrorNoHeapMemory); + + // Emit dummy intptr_t (4 or 8 bytes; depends on the address size). + if (regSize == 4) + EMIT_DWORD(0); + else + EMIT_QWORD(0); + + setCursor(cursor); + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Assembler - Align] +// ============================================================================ + +Error X86Assembler::align(uint32_t mode, uint32_t offset) { +#if !defined(ASMJIT_DISABLE_LOGGER) + if (_logger) + _logger->logFormat(kLoggerStyleDirective, + "%s.align %u\n", _logger->getIndentation(), static_cast(offset)); +#endif // !ASMJIT_DISABLE_LOGGER + + if (offset <= 1 || !IntUtil::isPowerOf2(offset) || offset > 64) + return setError(kErrorInvalidArgument); + + uint32_t i = static_cast(IntUtil::deltaTo(getOffset(), offset)); + if (i == 0) + return kErrorOk; + + if (getRemainingSpace() < i) + ASMJIT_PROPAGATE_ERROR(_grow(i)); + + uint8_t* cursor = getCursor(); + uint8_t alignPattern = 0xCC; + + if (mode == kAlignCode) { + alignPattern = 0x90; + + if (hasFeature(kCodeGenOptimizedAlign)) { + const X86CpuInfo* cpuInfo = static_cast(getRuntime()->getCpuInfo()); + + // NOPs optimized for Intel: + // Intel 64 and IA-32 Architectures Software Developer's Manual + // - Volume 2B + // - Instruction Set Reference N-Z + // - NOP + + // NOPs optimized for AMD: + // Software Optimization Guide for AMD Family 10h Processors (Quad-Core) + // - 4.13 - Code Padding with Operand-Size Override and Multibyte NOP + + // Intel and AMD. + static const uint8_t nop1[] = { 0x90 }; + static const uint8_t nop2[] = { 0x66, 0x90 }; + static const uint8_t nop3[] = { 0x0F, 0x1F, 0x00 }; + static const uint8_t nop4[] = { 0x0F, 0x1F, 0x40, 0x00 }; + static const uint8_t nop5[] = { 0x0F, 0x1F, 0x44, 0x00, 0x00 }; + static const uint8_t nop6[] = { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 }; + static const uint8_t nop7[] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 }; + static const uint8_t nop8[] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static const uint8_t nop9[] = { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + // AMD. + static const uint8_t nop10[] = { 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static const uint8_t nop11[] = { 0x66, 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + const uint8_t* p; + uint32_t n; + + if (cpuInfo->getVendorId() == kCpuVendorIntel && ( + (cpuInfo->getFamily() & 0x0F) == 0x06 || + (cpuInfo->getFamily() & 0x0F) == 0x0F)) { + do { + switch (i) { + case 1: p = nop1; n = 1; break; + case 2: p = nop2; n = 2; break; + case 3: p = nop3; n = 3; break; + case 4: p = nop4; n = 4; break; + case 5: p = nop5; n = 5; break; + case 6: p = nop6; n = 6; break; + case 7: p = nop7; n = 7; break; + case 8: p = nop8; n = 8; break; + default: p = nop9; n = 9; break; + } + + i -= n; + do { + EMIT_BYTE(*p++); + } while (--n); + } while (i); + } + else if (cpuInfo->getVendorId() == kCpuVendorAmd && cpuInfo->getFamily() >= 0x0F) { + do { + switch (i) { + case 1: p = nop1 ; n = 1; break; + case 2: p = nop2 ; n = 2; break; + case 3: p = nop3 ; n = 3; break; + case 4: p = nop4 ; n = 4; break; + case 5: p = nop5 ; n = 5; break; + case 6: p = nop6 ; n = 6; break; + case 7: p = nop7 ; n = 7; break; + case 8: p = nop8 ; n = 8; break; + case 9: p = nop9 ; n = 9; break; + case 10: p = nop10; n = 10; break; + default: p = nop11; n = 11; break; + } + + i -= n; + do { + EMIT_BYTE(*p++); + } while (--n); + } while (i); + } + } + } + + while (i) { + EMIT_BYTE(alignPattern); + i--; + } + + setCursor(cursor); + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Assembler - Reloc] +// ============================================================================ + +size_t X86Assembler::_relocCode(void* _dst, Ptr baseAddress) const { + uint32_t arch = getArch(); + uint8_t* dst = static_cast(_dst); + +#if !defined(ASMJIT_DISABLE_LOGGER) + Logger* logger = getLogger(); +#endif // ASMJIT_DISABLE_LOGGER + + size_t minCodeSize = getOffset(); // Current offset is the minimum code size. + size_t maxCodeSize = getCodeSize(); // Includes all possible trampolines. + + // We will copy the exact size of the generated code. Extra code for trampolines + // is generated on-the-fly by the relocator (this code doesn't exist at the moment). + ::memcpy(dst, _buffer, minCodeSize); + + // Trampoline pointer. + uint8_t* tramp = dst + minCodeSize; + + // Relocate all recorded locations. + size_t relocCount = _relocList.getLength(); + const RelocData* relocData = _relocList.getData(); + + for (size_t i = 0; i < relocCount; i++) { + const RelocData& r = relocData[i]; + + // Make sure that the `RelocData` is correct. + Ptr ptr = r.data; + + size_t offset = static_cast(r.from); + ASMJIT_ASSERT(offset + r.size <= static_cast(maxCodeSize)); + + // Whether to use trampoline, can be only used if relocation type is + // kRelocAbsToRel on 64-bit. + bool useTrampoline = false; + + switch (r.type) { + case kRelocAbsToAbs: + break; + + case kRelocRelToAbs: + ptr += baseAddress; + break; + + case kRelocAbsToRel: + ptr -= baseAddress + r.from + 4; + break; + + case kRelocTrampoline: + ptr -= baseAddress + r.from + 4; + if (!IntUtil::isInt32(static_cast(ptr))) { + ptr = (Ptr)tramp - (baseAddress + r.from + 4); + useTrampoline = true; + } + break; + + default: + ASMJIT_ASSERT(!"Reached"); + } + + switch (r.size) { + case 8: + *reinterpret_cast(dst + offset) = static_cast(ptr); + break; + + case 4: + *reinterpret_cast(dst + offset) = static_cast(static_cast(ptr)); + break; + + default: + ASMJIT_ASSERT(!"Reached"); + } + + // Handle the case where trampoline has been used. + if (useTrampoline) { + // Bytes that replace [REX, OPCODE] bytes. + uint32_t byte0 = 0xFF; + uint32_t byte1 = dst[offset - 1]; + + // Call, patch to FF/2 (-> 0x15). + if (byte1 == 0xE8) + byte1 = x86EncodeMod(0, 2, 5); + // Jmp, patch to FF/4 (-> 0x25). + else if (byte1 == 0xE9) + byte1 = x86EncodeMod(0, 4, 5); + + // Patch `jmp/call` instruction. + ASMJIT_ASSERT(offset >= 2); + dst[offset - 2] = byte0; + dst[offset - 1] = byte1; + + // Absolute address. + ((uint64_t*)tramp)[0] = static_cast(r.data); + + // Advance trampoline pointer. + tramp += 8; + +#if !defined(ASMJIT_DISABLE_LOGGER) + if (logger) + logger->logFormat(kLoggerStyleComment, "; Trampoline %llX\n", r.data); +#endif // !ASMJIT_DISABLE_LOGGER + } + } + + if (arch == kArchX64) + return (size_t)(tramp - dst); + else + return (size_t)(minCodeSize); +} + +// ============================================================================ +// [asmjit::X86Assembler - Logging] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_LOGGER) +// Logging helpers. +static const char* AssemblerX86_operandSize[] = { + "", + "byte ptr ", + "word ptr ", + NULL, + "dword ptr ", + NULL, + NULL, + NULL, + "qword ptr ", + NULL, + "tword ptr ", + NULL, + NULL, + NULL, + NULL, + NULL, + "oword ptr " +}; + +static const char X86Assembler_segName[] = + "\0\0\0\0" + "es:\0" + "cs:\0" + "ss:\0" + "ds:\0" + "fs:\0" + "gs:\0" + "\0\0\0\0"; + +static void X86Assembler_dumpRegister(StringBuilder& sb, uint32_t type, uint32_t index) { + // -- (Not-Encodable). + static const char reg8l[] = "al\0\0" "cl\0\0" "dl\0\0" "bl\0\0" "spl\0" "bpl\0" "sil\0" "dil\0" ; + static const char reg8h[] = "ah\0\0" "ch\0\0" "dh\0\0" "bh\0\0" "--\0\0" "--\0\0" "--\0\0" "--\0\0"; + static const char reg16[] = "ax\0\0" "cx\0\0" "dx\0\0" "bx\0\0" "sp\0\0" "bp\0\0" "si\0\0" "di\0\0"; + + char suffix = '\0'; + + switch (type) { + case kX86RegTypeGpbLo: + if (index >= 8) { + sb._appendChar('r'); + suffix = 'b'; + goto _EmitID; + } + + sb._appendString(®8l[index * 4]); + return; + + case _kX86RegTypePatchedGpbHi: + if (index < 4) + goto _EmitNE; + + index -= 4; + // ... Fall through ... + + case kX86RegTypeGpbHi: + if (index >= 4) + goto _EmitNE; + + sb._appendString(®8h[index * 4]); + return; + +_EmitNE: + sb._appendString("--", 2); + return; + + case kX86RegTypeGpw: + if (index >= 8) { + sb._appendChar('r'); + suffix = 'w'; + goto _EmitID; + } + + sb._appendString(®16[index * 4]); + return; + + case kX86RegTypeGpd: + if (index >= 8) { + sb._appendChar('r'); + suffix = 'd'; + goto _EmitID; + } + + sb._appendChar('e'); + sb._appendString(®16[index * 4]); + return; + + case kX86RegTypeGpq: + sb._appendChar('r'); + if (index >= 8) + goto _EmitID; + + sb._appendString(®16[index * 4]); + return; + + case kX86RegTypeFp: + sb._appendString("fp", 2); + goto _EmitID; + + case kX86RegTypeMm: + sb._appendString("mm", 2); + goto _EmitID; + + case kX86RegTypeXmm: + sb._appendString("xmm", 3); + goto _EmitID; + + case kX86RegTypeYmm: + sb._appendString("ymm", 3); + goto _EmitID; + + case kX86RegTypeSeg: + if (index >= kX86SegCount) + goto _EmitNE; + + sb._appendString(&X86Assembler_segName[index * 4], 2); + return; + + default: + return; + } + +_EmitID: + sb._appendUInt32(index); + + if (suffix) + sb._appendChar(suffix); +} + +static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Operand* op, uint32_t loggerOptions) { + if (op->isReg()) { + X86Assembler_dumpRegister(sb, + static_cast(op)->getRegType(), + static_cast(op)->getRegIndex()); + } + else if (op->isMem()) { + const X86Mem* m = static_cast(op); + + uint32_t type = kX86RegTypeGpd; + uint32_t seg = m->getSegment(); + bool isAbsolute = false; + + if (arch == kArchX86) { + if (!m->hasGpdBase()) + type = kX86RegTypeGpw; + } + else { + if (!m->hasGpdBase()) + type = kX86RegTypeGpq; + } + + if (op->getSize() <= 16) + sb._appendString(AssemblerX86_operandSize[op->getSize()]); + + if (seg < kX86SegCount) + sb._appendString(&X86Assembler_segName[seg * 4]); + + sb._appendChar('['); + switch (m->getMemType()) { + case kMemTypeBaseIndex: + case kMemTypeStackIndex: + // [base + index << shift + displacement] + X86Assembler_dumpRegister(sb, type, m->getBase()); + break; + + case kMemTypeLabel: + // [label + index << shift + displacement] + sb.appendFormat("L%u", m->getBase()); + break; + + case kMemTypeAbsolute: + // [absolute] + isAbsolute = true; + sb.appendUInt(static_cast(m->getDisplacement()), 16); + break; + } + + if (m->hasIndex()) { + switch (m->getVSib()) { + case kX86MemVSibXmm: type = kX86RegTypeXmm; break; + case kX86MemVSibYmm: type = kX86RegTypeYmm; break; + } + + sb._appendChar('+'); + X86Assembler_dumpRegister(sb, type, m->getIndex()); + + if (m->getShift()) { + sb._appendChar('*'); + sb._appendChar("1248"[m->getShift() & 3]); + } + } + + if (m->getDisplacement() && !isAbsolute) { + uint32_t base = 10; + int32_t dispOffset = m->getDisplacement(); + + char prefix = '+'; + if (dispOffset < 0) { + dispOffset = -dispOffset; + prefix = '-'; + } + + sb._appendChar(prefix); + if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) { + sb._appendString("0x", 2); + base = 16; + } + sb.appendUInt(static_cast(dispOffset), base); + } + + sb._appendChar(']'); + } + else if (op->isImm()) { + const Imm* i = static_cast(op); + int64_t val = i->getInt64(); + + if ((loggerOptions & (1 << kLoggerOptionHexImmediate)) && static_cast(val) > 9) + sb.appendUInt(static_cast(val), 16); + else + sb.appendInt(val, 10); + } + else if (op->isLabel()) { + sb.appendFormat("L%u", op->getId()); + } + else { + sb._appendString("None", 4); + } +} + +static bool X86Assembler_dumpInstruction(StringBuilder& sb, + uint32_t arch, + uint32_t code, uint32_t options, + const Operand* o0, + const Operand* o1, + const Operand* o2, + const Operand* o3, + uint32_t loggerOptions) { + + if (!sb.reserve(sb.getLength() + 128)) + return false; + + // Rex, lock and short prefix. + if (options & kX86InstOptionRex) + sb._appendString("rex ", 4); + + if (options & kX86InstOptionLock) + sb._appendString("lock ", 5); + + if (options & kInstOptionShortForm) + sb._appendString("short ", 6); + + // Dump instruction name. + sb._appendString(_x86InstInfo[code].getInstName()); + + // Dump operands. + if (!o0->isNone()) { + sb._appendChar(' '); + X86Assembler_dumpOperand(sb, arch, o0, loggerOptions); + } + + if (!o1->isNone()) { + sb._appendString(", ", 2); + X86Assembler_dumpOperand(sb, arch, o1, loggerOptions); + } + + if (!o2->isNone()) { + sb._appendString(", ", 2); + X86Assembler_dumpOperand(sb, arch, o2, loggerOptions); + } + + if (!o3->isNone()) { + sb._appendString(", ", 2); + X86Assembler_dumpOperand(sb, arch, o3, loggerOptions); + } + + return true; +} + +static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_t* binData, size_t binLength, size_t dispSize, const char* comment) { + size_t currentLength = len; + size_t commentLength = comment ? StringUtil::nlen(comment, kMaxCommentLength) : 0; + + ASMJIT_ASSERT(binLength >= dispSize); + + if (binLength || commentLength) { + size_t align = 36; + char sep = ';'; + + for (size_t i = (binLength == 0); i < 2; i++) { + size_t begin = sb.getLength(); + + // Append align. + if (currentLength < align) { + if (!sb.appendChars(' ', align - currentLength)) + return false; + } + + // Append separator. + if (sep) { + if (!(sb.appendChar(sep) & sb.appendChar(' '))) + return false; + } + + // Append binary data or comment. + if (i == 0) { + if (!sb.appendHex(binData, binLength - dispSize)) + return false; + if (!sb.appendChars('.', dispSize * 2)) + return false; + if (commentLength == 0) + break; + } + else { + if (!sb.appendString(comment, commentLength)) + return false; + } + + currentLength += sb.getLength() - begin; + align += 22; + sep = '|'; + } + } + + return sb.appendChar('\n'); +} +#endif // !ASMJIT_DISABLE_LOGGER + +// ============================================================================ +// [asmjit::X86Assembler - Emit] +// ============================================================================ + +//! \internal +static const Operand::VRegOp x86PatchedHiRegs[4] = { + // --------------+---+--------------------------------+--------------+------+ + // Operand | S | Register Code | OperandId |Unused| + // --------------+---+--------------------------------+--------------+------+ + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 4, kInvalidValue, 0, 0 }, + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 5, kInvalidValue, 0, 0 }, + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 6, kInvalidValue, 0, 0 }, + { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 7, kInvalidValue, 0, 0 } +}; + +template +static Error ASMJIT_CDECL X86Assembler_emit(Assembler* self_, uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2, const Operand* o3) { + X86Assembler* self = static_cast(self_); + + uint8_t* cursor = self->getCursor(); + uint32_t encoded = o0->getOp() + (o1->getOp() << 3) + (o2->getOp() << 6); + uint32_t options = self->getInstOptionsAndReset(); + + // Invalid instruction. + if (code >= _kX86InstIdCount) { + self->_comment = NULL; + return self->setError(kErrorUnknownInst); + } + + // Instruction opcode. + uint32_t opCode; + // MODR/R opcode or register code. + uint32_t opReg; + + // REX or VEX prefix data. + // + // REX: + // 0x0008 - REX.W. + // 0x0040 - Always emit REX prefix. + // + // AVX: + // 0x0008 - AVX.W. + // 0xF000 - VVVV, zeros by default, see `kVexVVVV`. + // + uint32_t opX; + + // MOD/RM, both rmReg and rmMem should refer to the same variable since they + // are never used together - either rmReg or rmMem. + union { + // MODR/M - register code. + uintptr_t rmReg; + // MODR/M - Memory operand. + const X86Mem* rmMem; + }; + + // Immediate value. + int64_t imVal; + // Immediate length. + uint32_t imLen = 0; + + // Memory operand base register index. + uint32_t mBase; + // Memory operand index register index. + uint32_t mIndex; + + // Label. + LabelData* label; + // Displacement offset + int32_t dispOffset; + // Displacement size. + uint32_t dispSize = 0; + // Displacement relocation id. + intptr_t relocId; + +#if defined(ASMJIT_DEBUG) + bool assertIllegal = false; +#endif // ASMJIT_DEBUG + + const X86InstInfo& info = _x86InstInfo[code]; + const X86InstExtendedInfo& extendedInfo = info.getExtendedInfo(); + + // Grow request happens rarely. C++ compiler generates better code if it is + // handled at the end of the function. + if ((size_t)(self->_end - cursor) < 16) + goto _GrowBuffer; + + // -------------------------------------------------------------------------- + // [Prepare] + // -------------------------------------------------------------------------- + +_Prepare: + opCode = info.getPrimaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + opX = extendedInfo.getInstFlags() >> (15 - 3); + + if (Arch == kArchX86) { + // AVX.W prefix. + opX &= 0x08; + + // Check if one or more register operand is one of AH, BH, CH, or DH and + // patch them to ensure that the binary code with correct byte-index (4-7) + // is generated. + if (o0->isRegType(kX86RegTypeGpbHi)) + o0 = (const Operand*)(&x86PatchedHiRegs[static_cast(o0)->getRegIndex()]); + + if (o1->isRegType(kX86RegTypeGpbHi)) + o1 = (const Operand*)(&x86PatchedHiRegs[static_cast(o1)->getRegIndex()]); + } + else { + ASMJIT_ASSERT(kX86InstOptionRex == 0x40); + + // AVX.W prefix and REX prefix. + opX |= options; + opX &= 0x48; + + // Check if one or more register operand is one of BPL, SPL, SIL, DIL and + // force a REX prefix in such case. + if (X86Reg::isGpbReg(*o0)) { + uint32_t index = static_cast(o0)->getRegIndex(); + if (static_cast(o0)->isGpbLo()) { + opX |= (index >= 4) << kRexShift; + } + else { + opX |= kRexForbidden; + o0 = reinterpret_cast(&x86PatchedHiRegs[index]); + } + } + + if (X86Reg::isGpbReg(*o1)) { + uint32_t index = static_cast(o1)->getRegIndex(); + if (static_cast(o1)->isGpbLo()) { + opX |= (index >= 4) << kRexShift; + } + else { + opX |= kRexForbidden; + o1 = reinterpret_cast(&x86PatchedHiRegs[index]); + } + } + } + + // -------------------------------------------------------------------------- + // [Lock-Prefix] + // -------------------------------------------------------------------------- + + if (options & kX86InstOptionLock) { + if (!extendedInfo.isLockable()) + goto _IllegalInst; + EMIT_BYTE(0xF0); + } + + // -------------------------------------------------------------------------- + // [Group] + // -------------------------------------------------------------------------- + + switch (info.getInstGroup()) { + // ------------------------------------------------------------------------ + // [None] + // ------------------------------------------------------------------------ + + case kX86InstGroupNone: + goto _EmitDone; + + // ------------------------------------------------------------------------ + // [X86] + // ------------------------------------------------------------------------ + + case kX86InstGroupX86Op_66H: + ADD_66H_P(true); + // ... Fall through ... + + case kX86InstGroupX86Op: + goto _EmitX86Op; + + case kX86InstGroupX86Rm_B: + opCode += o0->getSize() != 1; + // ... Fall through ... + + case kX86InstGroupX86Rm: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + if (encoded == ENC_OPS(Reg, None, None)) { + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86RmReg: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opCode += o0->getSize() != 1; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opCode += o1->getSize() != 1; + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86RegRm: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + if (encoded == ENC_OPS(Reg, Reg, None)) { + ASMJIT_ASSERT(o0->getSize() != 1); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + ASMJIT_ASSERT(o0->getSize() != 1); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86M: + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Arith: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opCode +=(o0->getSize() != 1) + 2; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opCode +=(o0->getSize() != 1) + 2; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opCode += o1->getSize() != 1; + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + + // The remaining instructions use 0x80 opcode. + opCode = 0x80; + + if (encoded == ENC_OPS(Reg, Imm, None)) { + imVal = static_cast(o1)->getInt64(); + imLen = IntUtil::isInt8(imVal) ? static_cast(1) : IntUtil::iMin(o0->getSize(), 4); + rmReg = static_cast(o0)->getRegIndex(); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + // Alternate Form - AL, AX, EAX, RAX. + if (rmReg == 0 && (o0->getSize() == 1 || imLen != 1)) { + opCode = ((opReg << 3) | (0x04 + (o0->getSize() != 1))); + imLen = IntUtil::iMin(o0->getSize(), 4); + goto _EmitX86OpI; + } + + opCode += o0->getSize() != 1 ? (imLen != 1 ? 1 : 3) : 0; + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Imm, None)) { + uint32_t memSize = o0->getSize(); + + if (memSize == 0) + goto _IllegalInst; + + imVal = static_cast(o1)->getInt64(); + imLen = IntUtil::isInt8(imVal) ? static_cast(1) : IntUtil::iMin(memSize, 4); + + opCode += memSize != 1 ? (imLen != 1 ? 1 : 3) : 0; + ADD_66H_P_BY_SIZE(memSize); + ADD_REX_W_BY_SIZE(memSize); + + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86BSwap: + if (encoded == ENC_OPS(Reg, None, None)) { + opReg = static_cast(o0)->getRegIndex(); + opCode += opReg & 0x7; + + ADD_REX_W_BY_SIZE(o0->getSize()); + ADD_REX_B(opReg); + goto _EmitX86Op; + } + break; + + case kX86InstGroupX86BTest: + if (encoded == ENC_OPS(Reg, Reg, None)) { + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + + // The remaining instructions use the secondary opcode/r. + imVal = static_cast(o1)->getInt64(); + imLen = 1; + + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + if (encoded == ENC_OPS(Reg, Imm, None)) { + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Imm, None)) { + if (o0->getSize() == 0) + goto _IllegalInst; + + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Call: + if (encoded == ENC_OPS(Reg, None, None)) { + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + goto _EmitX86M; + } + + // The following instructions use the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Imm, None, None)) { + imVal = static_cast(o0)->getInt64(); + goto _EmitJmpOrCallAbs; + } + + if (encoded == ENC_OPS(Label, None, None)) { + label = self->getLabelData(static_cast(o0)->getId()); + if (label->offset != -1) { + // Bound label. + static const intptr_t kRel32Size = 5; + intptr_t offs = label->offset - (intptr_t)(cursor - self->_buffer); + + ASMJIT_ASSERT(offs <= 0); + EMIT_OP(opCode); + EMIT_DWORD(static_cast(offs - kRel32Size)); + } + else { + // Non-bound label. + EMIT_OP(opCode); + dispOffset = -4; + dispSize = 4; + relocId = -1; + goto _EmitDisplacement; + } + goto _EmitDone; + } + break; + + case kX86InstGroupX86Enter: + if (encoded == ENC_OPS(Imm, Imm, None)) { + EMIT_BYTE(0xC8); + EMIT_WORD(static_cast(o1)->getUInt16()); + EMIT_BYTE(static_cast(o0)->getUInt8()); + goto _EmitDone; + } + break; + + case kX86InstGroupX86Imul: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + if (encoded == ENC_OPS(Reg, None, None)) { + opCode = 0xF6 + (o0->getSize() != 1); + + opReg = 5; + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, None, None)) { + opCode = 0xF6 + (o0->getSize() != 1); + + opReg = 5; + rmMem = static_cast(o0); + goto _EmitX86M; + } + + // The following instructions use 0x0FAF opcode. + opCode &= kX86InstOpCode_PP_66; + opCode |= kX86InstOpCode_MM_0F | 0xAF; + + if (encoded == ENC_OPS(Reg, Reg, None)) { + ASMJIT_ASSERT(o0->getSize() != 1); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + ASMJIT_ASSERT(o0->getSize() != 1); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + + goto _EmitX86M; + } + + // The following instructions use 0x69/0x6B opcode. + opCode &= kX86InstOpCode_PP_66; + opCode |= 0x6B; + + if (encoded == ENC_OPS(Reg, Imm, None)) { + ASMJIT_ASSERT(o0->getSize() != 1); + + imVal = static_cast(o1)->getInt64(); + imLen = 1; + + if (!IntUtil::isInt8(imVal)) { + opCode -= 2; + imLen = o0->getSize() == 2 ? 2 : 4; + } + + opReg = static_cast(o0)->getRegIndex(); + rmReg = opReg; + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + ASMJIT_ASSERT(o0->getSize() != 1); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (!IntUtil::isInt8(imVal)) { + opCode -= 2; + imLen = o0->getSize() == 2 ? 2 : 4; + } + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + ASMJIT_ASSERT(o0->getSize() != 1); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (!IntUtil::isInt8(imVal)) { + opCode -= 2; + imLen = o0->getSize() == 2 ? 2 : 4; + } + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86IncDec: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + if (encoded == ENC_OPS(Reg, None, None)) { + rmReg = static_cast(o0)->getRegIndex(); + + // INC r16|r32 is not encodable in 64-bit mode. + if (Arch == kArchX86 && (o0->getSize() == 2 || o0->getSize() == 4)) { + opCode &= kX86InstOpCode_PP_66; + opCode |= extendedInfo.getSecondaryOpCode() + (static_cast(rmReg) & 0x7); + goto _EmitX86Op; + } + else { + opCode += o0->getSize() != 1; + goto _EmitX86R; + } + } + + if (encoded == ENC_OPS(Mem, None, None)) { + opCode += o0->getSize() != 1; + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Int: + if (encoded == ENC_OPS(Imm, None, None)) { + imVal = static_cast(o0)->getInt64(); + uint8_t imm8 = static_cast(imVal & 0xFF); + + if (imm8 == 0x03) { + EMIT_OP(opCode); + } + else { + EMIT_OP(opCode + 1); + EMIT_BYTE(imm8); + } + goto _EmitDone; + } + break; + + case kX86InstGroupX86Jcc: + if (encoded == ENC_OPS(Label, None, None)) { + label = self->getLabelData(static_cast(o0)->getId()); + + if (self->hasFeature(kCodeGenPredictedJumps)) { + if (options & kInstOptionTaken) + EMIT_BYTE(0x3E); + if (options & kInstOptionNotTaken) + EMIT_BYTE(0x2E); + } + + if (label->offset != -1) { + // Bound label. + static const intptr_t kRel8Size = 2; + static const intptr_t kRel32Size = 6; + + intptr_t offs = label->offset - (intptr_t)(cursor - self->_buffer); + ASMJIT_ASSERT(offs <= 0); + + if ((options & kInstOptionLongForm) == 0 && IntUtil::isInt8(offs - kRel8Size)) { + EMIT_OP(opCode); + EMIT_BYTE(offs - kRel8Size); + + options |= kInstOptionShortForm; + goto _EmitDone; + } + else { + EMIT_BYTE(0x0F); + EMIT_OP(opCode + 0x10); + EMIT_DWORD(static_cast(offs - kRel32Size)); + + options &= ~kInstOptionShortForm; + goto _EmitDone; + } + } + else { + // Non-bound label. + if (options & kInstOptionShortForm) { + EMIT_OP(opCode); + dispOffset = -1; + dispSize = 1; + relocId = -1; + goto _EmitDisplacement; + } + else { + EMIT_BYTE(0x0F); + EMIT_OP(opCode + 0x10); + dispOffset = -4; + dispSize = 4; + relocId = -1; + goto _EmitDisplacement; + } + } + } + break; + + case kX86InstGroupX86Jecxz: + if (encoded == ENC_OPS(Reg, Label, None)) { + ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == kX86RegIndexCx); + + if ((Arch == kArchX86 && o0->getSize() == 2) || + (Arch == kArchX64 && o0->getSize() == 4)) { + EMIT_BYTE(0x67); + } + + EMIT_BYTE(0xE3); + label = self->getLabelData(static_cast(o1)->getId()); + + if (label->offset != -1) { + // Bound label. + intptr_t offs = label->offset - (intptr_t)(cursor - self->_buffer) - 1; + if (!IntUtil::isInt8(offs)) + goto _IllegalInst; + + EMIT_BYTE(offs); + goto _EmitDone; + } + else { + // Non-bound label. + dispOffset = -1; + dispSize = 1; + relocId = -1; + goto _EmitDisplacement; + } + } + break; + + case kX86InstGroupX86Jmp: + if (encoded == ENC_OPS(Reg, None, None)) { + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + goto _EmitX86M; + } + + // The following instructions use the secondary opcode (0xE9). + opCode = 0xE9; + + if (encoded == ENC_OPS(Imm, None, None)) { + imVal = static_cast(o0)->getInt64(); + goto _EmitJmpOrCallAbs; + } + + if (encoded == ENC_OPS(Label, None, None)) { + label = self->getLabelData(static_cast(o0)->getId()); + if (label->offset != -1) { + // Bound label. + const intptr_t kRel8Size = 2; + const intptr_t kRel32Size = 5; + + intptr_t offs = label->offset - (intptr_t)(cursor - self->_buffer); + + if ((options & kInstOptionLongForm) == 0 && IntUtil::isInt8(offs - kRel8Size)) { + options |= kInstOptionShortForm; + + EMIT_BYTE(0xEB); + EMIT_BYTE(offs - kRel8Size); + goto _EmitDone; + } + else { + options &= ~kInstOptionShortForm; + + EMIT_BYTE(0xE9); + EMIT_DWORD(static_cast(offs - kRel32Size)); + goto _EmitDone; + } + } + else { + // Non-bound label. + if ((options & kInstOptionShortForm) != 0) { + EMIT_BYTE(0xEB); + dispOffset = -1; + dispSize = 1; + relocId = -1; + goto _EmitDisplacement; + } + else { + EMIT_BYTE(0xE9); + dispOffset = -4; + dispSize = 4; + relocId = -1; + goto _EmitDisplacement; + } + } + } + break; + + case kX86InstGroupX86Lea: + if (encoded == ENC_OPS(Reg, Mem, None)) { + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Mov: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + + // Sreg <- Reg + if (static_cast(o0)->isSeg()) { + ASMJIT_ASSERT(static_cast(o1)->isGpw() || + static_cast(o1)->isGpd() || + static_cast(o1)->isGpq() ); + opCode = 0x8E; + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + goto _EmitX86R; + } + + // Reg <- Sreg + if (static_cast(o1)->isSeg()) { + ASMJIT_ASSERT(static_cast(o0)->isGpw() || + static_cast(o0)->isGpd() || + static_cast(o0)->isGpq() ); + opCode = 0x8C; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + goto _EmitX86R; + } + // Reg <- Reg + else { + ASMJIT_ASSERT(static_cast(o0)->isGpb() || + static_cast(o0)->isGpw() || + static_cast(o0)->isGpd() || + static_cast(o0)->isGpq() ); + opCode = 0x8A + (o0->getSize() != 1); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + goto _EmitX86R; + } + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + + // Sreg <- Mem + if (static_cast(o0)->isRegType(kX86RegTypeSeg)) { + opCode = 0x8E; + opReg--; + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + goto _EmitX86M; + } + // Reg <- Mem + else { + ASMJIT_ASSERT(static_cast(o0)->isGpb() || + static_cast(o0)->isGpw() || + static_cast(o0)->isGpd() || + static_cast(o0)->isGpq() ); + opCode = 0x8A + (o0->getSize() != 1); + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + goto _EmitX86M; + } + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + + // X86Mem <- Sreg + if (static_cast(o1)->isSeg()) { + opCode = 0x8C; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + goto _EmitX86M; + } + // X86Mem <- Reg + else { + ASMJIT_ASSERT(static_cast(o1)->isGpb() || + static_cast(o1)->isGpw() || + static_cast(o1)->isGpd() || + static_cast(o1)->isGpq() ); + opCode = 0x88 + (o1->getSize() != 1); + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + goto _EmitX86M; + } + } + + if (encoded == ENC_OPS(Reg, Imm, None)) { + // 64-bit immediate in 64-bit mode is allowed. + imVal = static_cast(o1)->getInt64(); + imLen = o0->getSize(); + + opReg = 0; + rmReg = static_cast(o0)->getRegIndex(); + + // Optimize instruction size by using 32-bit immediate if possible. + if (Arch == kArchX64 && imLen == 8 && IntUtil::isInt32(imVal)) { + opCode = 0xC7; + ADD_REX_W(1); + imLen = 4; + goto _EmitX86R; + } + else { + opCode = 0xB0 + (static_cast(o0->getSize() != 1) << 3) + (static_cast(rmReg) & 0x7); + ADD_REX_W_BY_SIZE(imLen); + ADD_REX_B(rmReg); + goto _EmitX86OpI; + } + } + + if (encoded == ENC_OPS(Mem, Imm, None)) { + uint32_t memSize = o0->getSize(); + + if (memSize == 0) + goto _IllegalInst; + + imVal = static_cast(o1)->getInt64(); + imLen = IntUtil::iMin(memSize, 4); + + opCode = 0xC6 + (memSize != 1); + opReg = 0; + ADD_66H_P_BY_SIZE(memSize); + ADD_REX_W_BY_SIZE(memSize); + + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86MovSxZx: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opCode += o1->getSize() != 1; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opCode += o1->getSize() != 1; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86MovSxd: + if (encoded == ENC_OPS(Reg, Reg, None)) { + ADD_REX_W(true); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + ADD_REX_W(true); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86MovPtr: + if (encoded == ENC_OPS(Reg, Imm, None)) { + ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == 0); + + opCode += o0->getSize() != 1; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + imVal = static_cast(o1)->getInt64(); + imLen = self->_regSize; + goto _EmitX86OpI; + } + + // The following instruction uses the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Imm, Reg, None)) { + ASMJIT_ASSERT(static_cast(o1)->getRegIndex() == 0); + + opCode += o1->getSize() != 1; + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + imVal = static_cast(o0)->getInt64(); + imLen = self->_regSize; + goto _EmitX86OpI; + } + break; + + case kX86InstGroupX86Push: + if (encoded == ENC_OPS(Reg, None, None)) { + if (o0->isRegType(kX86RegTypeSeg)) { + uint32_t segment = static_cast(o0)->getRegIndex(); + ASMJIT_ASSERT(segment < kX86SegCount); + + if (segment >= kX86SegFs) + EMIT_BYTE(0x0F); + + EMIT_BYTE(x86OpCodePushSeg[segment]); + goto _EmitDone; + } + else { + goto _GroupPop_Gp; + } + } + + if (encoded == ENC_OPS(Imm, None, None)) { + imVal = static_cast(o0)->getInt64(); + imLen = IntUtil::isInt8(imVal) ? 1 : 4; + + EMIT_BYTE(imLen == 1 ? 0x6A : 0x68); + goto _EmitImm; + } + // ... Fall through ... + + case kX86InstGroupX86Pop: + if (encoded == ENC_OPS(Reg, None, None)) { + if (o0->isRegType(kX86RegTypeSeg)) { + uint32_t segment = static_cast(o0)->getRegIndex(); + ASMJIT_ASSERT(segment < kX86SegCount); + + if (segment >= kX86SegFs) + EMIT_BYTE(0x0F); + + EMIT_BYTE(x86OpCodePopSeg[segment]); + goto _EmitDone; + } + else { +_GroupPop_Gp: + ASMJIT_ASSERT(static_cast(o0)->getSize() == 2 || + static_cast(o0)->getSize() == self->_regSize); + + opReg = static_cast(o0)->getRegIndex(); + opCode = extendedInfo.getSecondaryOpCode() + (opReg & 7); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_B(opReg); + + goto _EmitX86Op; + } + } + + if (encoded == ENC_OPS(Mem, None, None)) { + ADD_66H_P_BY_SIZE(o0->getSize()); + + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Rep: + // Emit REP 0xF2 or 0xF3 prefix first. + EMIT_BYTE(0xF2 + opReg); + goto _EmitX86Op; + + case kX86InstGroupX86Ret: + if (encoded == ENC_OPS(None, None, None)) { + EMIT_BYTE(0xC3); + goto _EmitDone; + } + + if (encoded == ENC_OPS(Imm, None, None)) { + imVal = static_cast(o0)->getInt64(); + if (imVal == 0) { + EMIT_BYTE(0xC3); + goto _EmitDone; + } + else { + EMIT_BYTE(0xC2); + imLen = 2; + goto _EmitImm; + } + } + break; + + case kX86InstGroupX86Rot: + opCode += o0->getSize() != 1; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + if (encoded == ENC_OPS(Reg, Reg, None)) { + ASMJIT_ASSERT(static_cast(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); + opCode += 2; + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + ASMJIT_ASSERT(static_cast(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); + opCode += 2; + rmMem = static_cast(o0); + goto _EmitX86M; + } + + if (encoded == ENC_OPS(Reg, Imm, None)) { + imVal = static_cast(o1)->getInt64() & 0xFF; + imLen = imVal != 1; + if (imLen) + opCode -= 0x10; + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Imm, None)) { + if (o0->getSize() == 0) + goto _IllegalInst; + + imVal = static_cast(o1)->getInt64() & 0xFF; + imLen = imVal != 1; + if (imLen) + opCode -= 0x10; + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Set: + if (encoded == ENC_OPS(Reg, None, None)) { + ASMJIT_ASSERT(o0->getSize() == 1); + + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, None, None)) { + ASMJIT_ASSERT(o0->getSize() <= 1); + + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Shlrd: + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + ASMJIT_ASSERT(o0->getSize() == o1->getSize()); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, Imm)) { + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + + // The following instructions use opCode + 1. + opCode++; + + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + ASMJIT_ASSERT(static_cast(o2)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); + ASMJIT_ASSERT(o0->getSize() == o1->getSize()); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, Reg)) { + ASMJIT_ASSERT(static_cast(o2)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); + + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Test: + if (encoded == ENC_OPS(Reg, Reg, None)) { + ASMJIT_ASSERT(o0->getSize() == o1->getSize()); + + opCode += o0->getSize() != 1; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opCode += o1->getSize() != 1; + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + + // The following instructions use the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode() + (o0->getSize() != 1); + opReg = opCode >> kX86InstOpCode_O_Shift; + + if (encoded == ENC_OPS(Reg, Imm, None)) { + imVal = static_cast(o1)->getInt64(); + imLen = IntUtil::iMin(o0->getSize(), 4); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + // Alternate Form - AL, AX, EAX, RAX. + if (static_cast(o0)->getRegIndex() == 0) { + opCode &= kX86InstOpCode_PP_66; + opCode |= 0xA8 + (o0->getSize() != 1); + goto _EmitX86OpI; + } + + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Imm, None)) { + if (o0->getSize() == 0) + goto _IllegalInst; + + imVal = static_cast(o1)->getInt64(); + imLen = IntUtil::iMin(o0->getSize(), 4); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupX86Xchg: + if (encoded == ENC_OPS(Reg, Mem, None)) { + opCode += o0->getSize() != 1; + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + // ... fall through ... + + case kX86InstGroupX86Xadd: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + // Special opcode for 'xchg ?ax, reg'. + if (code == kX86InstIdXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) { + // One of them is zero, it doesn't matter if the instruction's form is + // 'xchg ?ax, reg' or 'xchg reg, ?ax'. + opReg += rmReg; + + // Rex.B (0x01). + if (Arch == kArchX64) { + opX += opReg >> 3; + opReg &= 0x7; + } + + opCode &= kX86InstOpCode_PP_66; + opCode |= 0x90 + opReg; + goto _EmitX86Op; + } + + opCode += o0->getSize() != 1; + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opCode += o1->getSize() != 1; + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + // ------------------------------------------------------------------------ + // [Fpu] + // ------------------------------------------------------------------------ + + case kX86InstGroupFpuOp: + goto _EmitFpuOp; + + case kX86InstGroupFpuArith: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + rmReg += opReg; + + // We switch to the alternative opcode if the first operand is zero. + if (opReg == 0) { +_EmitFpArith_Reg: + opCode = 0xD800 + ((opCode >> 8) & 0xFF) + static_cast(rmReg); + goto _EmitFpuOp; + } + else { + opCode = 0xDC00 + ((opCode >> 0) & 0xFF) + static_cast(rmReg); + goto _EmitFpuOp; + } + } + + if (encoded == ENC_OPS(Mem, None, None)) { + // 0xD8/0xDC, depends on the size of the memory operand; opReg has been + // set already. +_EmitFpArith_Mem: + opCode = (o0->getSize() == 4) ? 0xD8 : 0xDC; + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupFpuCom: + if (encoded == ENC_OPS(None, None, None)) { + rmReg = 1; + goto _EmitFpArith_Reg; + } + + if (encoded == ENC_OPS(Reg, None, None)) { + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitFpArith_Reg; + } + + if (encoded == ENC_OPS(Mem, None, None)) { + goto _EmitFpArith_Mem; + } + break; + + case kX86InstGroupFpuFldFst: + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + + if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) { + goto _EmitX86M; + } + + if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) { + opCode += 4; + goto _EmitX86M; + } + + if (o0->getSize() == 10 && info.hasInstFlag(kX86InstFlagMem10)) { + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + goto _EmitX86M; + } + } + + if (encoded == ENC_OPS(Reg, None, None)) { + if (code == kX86InstIdFld) { + opCode = 0xD9C0 + static_cast(o0)->getRegIndex(); + goto _EmitFpuOp; + } + + if (code == kX86InstIdFst) { + opCode = 0xDDD0 + static_cast(o0)->getRegIndex(); + goto _EmitFpuOp; + } + + if (code == kX86InstIdFstp) { + opCode = 0xDDD8 + static_cast(o0)->getRegIndex(); + goto _EmitFpuOp; + } + } + break; + + + case kX86InstGroupFpuM: + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + + if (o0->getSize() == 2 && info.hasInstFlag(kX86InstFlagMem2)) { + opCode += 4; + goto _EmitX86M; + } + + if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) { + goto _EmitX86M; + } + + if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) { + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + goto _EmitX86M; + } + } + break; + + case kX86InstGroupFpuRDef: + if (encoded == ENC_OPS(None, None, None)) { + opCode += 1; + goto _EmitFpuOp; + } + // ... Fall through ... + + case kX86InstGroupFpuR: + if (encoded == ENC_OPS(Reg, None, None)) { + opCode += static_cast(o0)->getRegIndex(); + goto _EmitFpuOp; + } + break; + + case kX86InstGroupFpuStsw: + if (encoded == ENC_OPS(Reg, None, None)) { + if (static_cast(o0)->getRegIndex() != 0) + goto _IllegalInst; + + opCode = extendedInfo.getSecondaryOpCode(); + goto _EmitX86Op; + } + + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + // ------------------------------------------------------------------------ + // [Ext] + // ------------------------------------------------------------------------ + + case kX86InstGroupExtCrc: + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + if (encoded == ENC_OPS(Reg, Reg, None)) { + ASMJIT_ASSERT(static_cast(o0)->getRegType() == kX86RegTypeGpd || + static_cast(o0)->getRegType() == kX86RegTypeGpq); + + opCode += o0->getSize() != 1; + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + ASMJIT_ASSERT(static_cast(o0)->getRegType() == kX86RegTypeGpd || + static_cast(o0)->getRegType() == kX86RegTypeGpq); + + opCode += o0->getSize() != 1; + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtExtract: + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + ADD_66H_P(static_cast(o1)->isXmm()); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Mem, Reg, Imm)) { + // Secondary opcode for 'pextrw' instruction (SSE2). + opCode = extendedInfo.getSecondaryOpCode(); + ADD_66H_P(static_cast(o1)->isXmm()); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtFence: + if (Arch == kArchX64 && opX) { + EMIT_BYTE(0x40 | opX); + } + + EMIT_BYTE(0x0F); + EMIT_OP(opCode); + EMIT_BYTE(0xC0 | (opReg << 3)); + goto _EmitDone; + + case kX86InstGroupExtMov: + case kX86InstGroupExtMovNoRexW: + ASMJIT_ASSERT(extendedInfo._opFlags[0] != 0); + ASMJIT_ASSERT(extendedInfo._opFlags[1] != 0); + + // Check parameters Gpd|Gpq|Mm|Xmm <- Gpd|Gpq|Mm|Xmm|X86Mem|Imm. + ASMJIT_ASSERT(!((o0->isMem() && (extendedInfo._opFlags[0] & kX86InstOpMem) == 0) || + (o0->isRegType(kX86RegTypeMm ) && (extendedInfo._opFlags[0] & kX86InstOpMm ) == 0) || + (o0->isRegType(kX86RegTypeXmm) && (extendedInfo._opFlags[0] & kX86InstOpXmm) == 0) || + (o0->isRegType(kX86RegTypeGpd) && (extendedInfo._opFlags[0] & kX86InstOpGd ) == 0) || + (o0->isRegType(kX86RegTypeGpq) && (extendedInfo._opFlags[0] & kX86InstOpGq ) == 0) || + (o1->isMem() && (extendedInfo._opFlags[1] & kX86InstOpMem) == 0) || + (o1->isRegType(kX86RegTypeMm ) && (extendedInfo._opFlags[1] & kX86InstOpMm ) == 0) || + (o1->isRegType(kX86RegTypeXmm) && (extendedInfo._opFlags[1] & kX86InstOpXmm) == 0) || + (o1->isRegType(kX86RegTypeGpd) && (extendedInfo._opFlags[1] & kX86InstOpGd ) == 0) || + (o1->isRegType(kX86RegTypeGpq) && (extendedInfo._opFlags[1] & kX86InstOpGq ) == 0) )); + + // Gp|Mm|Xmm <- Gp|Mm|Xmm + if (encoded == ENC_OPS(Reg, Reg, None)) { + ADD_REX_W(static_cast(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + // Gp|Mm|Xmm <- Mem + if (encoded == ENC_OPS(Reg, Mem, None)) { + ADD_REX_W(static_cast(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + + // The following instruction uses opCode[1]. + opCode = extendedInfo.getSecondaryOpCode(); + + // X86Mem <- Gp|Mm|Xmm + if (encoded == ENC_OPS(Mem, Reg, None)) { + ADD_REX_W(static_cast(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtMovBe: + if (encoded == ENC_OPS(Reg, Mem, None)) { + ADD_66H_P_BY_SIZE(o0->getSize()); + ADD_REX_W_BY_SIZE(o0->getSize()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + + // The following instruction uses the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Mem, Reg, None)) { + ADD_66H_P_BY_SIZE(o1->getSize()); + ADD_REX_W_BY_SIZE(o1->getSize()); + + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtMovD: +_EmitMmMovD: + opReg = static_cast(o0)->getRegIndex(); + ADD_66H_P(static_cast(o0)->isXmm()); + + // Mm/Xmm <- Gp + if (encoded == ENC_OPS(Reg, Reg, None) && static_cast(o1)->isGp()) { + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + // Mm/Xmm <- Mem + if (encoded == ENC_OPS(Reg, Mem, None)) { + rmMem = static_cast(o1); + goto _EmitX86M; + } + + // The following instructions use the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + opReg = static_cast(o1)->getRegIndex(); + ADD_66H_P(static_cast(o1)->isXmm()); + + // Gp <- Mm/Xmm + if (encoded == ENC_OPS(Reg, Reg, None) && static_cast(o0)->isGp()) { + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + + // X86Mem <- Mm/Xmm + if (encoded == ENC_OPS(Mem, Reg, None)) { + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtMovQ: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + + // Mm <- Mm + if (static_cast(o0)->isMm() && static_cast(o1)->isMm()) { + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F; + goto _EmitX86R; + } + + // Xmm <- Xmm + if (static_cast(o0)->isXmm() && static_cast(o1)->isXmm()) { + opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E; + goto _EmitX86R; + } + + // Mm <- Xmm (Movdq2q) + if (static_cast(o0)->isMm() && static_cast(o1)->isXmm()) { + opCode = kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | 0xD6; + goto _EmitX86R; + } + + // Xmm <- Mm (Movq2dq) + if (static_cast(o0)->isXmm() && static_cast(o1)->isMm()) { + opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0xD6; + goto _EmitX86R; + } + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + + // Mm <- Mem + if (static_cast(o0)->isMm()) { + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6F; + goto _EmitX86M; + } + + // Xmm <- Mem + if (static_cast(o0)->isXmm()) { + opCode = kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | 0x7E; + goto _EmitX86M; + } + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + + // X86Mem <- Mm + if (static_cast(o1)->isMm()) { + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x7F; + goto _EmitX86M; + } + + // X86Mem <- Xmm + if (static_cast(o1)->isXmm()) { + opCode = kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | 0xD6; + goto _EmitX86M; + } + } + + if (Arch == kArchX64) { + // Movq in other case is simply a promoted MOVD instruction to 64-bit. + ADD_REX_W(true); + + opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6E; + goto _EmitMmMovD; + } + break; + + case kX86InstGroupExtPrefetch: + if (encoded == ENC_OPS(Mem, Imm, None)) { + opReg = static_cast(o1)->getUInt32() & 0x3; + rmMem = static_cast(o0); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtRm_PQ: + ADD_66H_P(o0->isRegType(kX86RegTypeXmm) || o1->isRegType(kX86RegTypeXmm)); + // ... Fall through ... + + case kX86InstGroupExtRm_Q: + ADD_REX_W(o0->isRegType(kX86RegTypeGpq) || o1->isRegType(kX86RegTypeGpq) || (o1->isMem() && o1->getSize() == 8)); + // ... Fall through ... + + case kX86InstGroupExtRm: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtRm_P: + if (encoded == ENC_OPS(Reg, Reg, None)) { + ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + ADD_66H_P(static_cast(o0)->isXmm()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtRmRi: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + + // The following instruction uses the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + + if (encoded == ENC_OPS(Reg, Imm, None)) { + imVal = static_cast(o1)->getInt64(); + imLen = 1; + + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + break; + + case kX86InstGroupExtRmRi_P: + if (encoded == ENC_OPS(Reg, Reg, None)) { + ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + ADD_66H_P(static_cast(o0)->isXmm()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + + // The following instruction uses the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + + if (encoded == ENC_OPS(Reg, Imm, None)) { + ADD_66H_P(static_cast(o0)->isXmm()); + + imVal = static_cast(o1)->getInt64(); + imLen = 1; + + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitX86R; + } + break; + + case kX86InstGroupExtRmi: + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + case kX86InstGroupExtRmi_P: + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); + + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + ADD_66H_P(static_cast(o0)->isXmm()); + + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + // ------------------------------------------------------------------------ + // [Group - 3dNow] + // ------------------------------------------------------------------------ + + case kX86InstGroup3dNow: + // Every 3dNow instruction starts with 0x0F0F and the actual opcode is + // stored as 8-bit immediate. + imVal = opCode & 0xFF; + imLen = 1; + + opCode = kX86InstOpCode_MM_0F | 0x0F; + opReg = static_cast(o0)->getRegIndex(); + + if (encoded == ENC_OPS(Reg, Reg, None)) { + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitX86R; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + rmMem = static_cast(o1); + goto _EmitX86M; + } + break; + + // ------------------------------------------------------------------------ + // [Avx] + // ------------------------------------------------------------------------ + + case kX86InstGroupAvxOp: + goto _EmitAvxOp; + + case kX86InstGroupAvxM: + if (encoded == ENC_OPS(Mem, None, None)) { + rmMem = static_cast(o0); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxMr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxMr: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxMri_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxMri: + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Mem, Reg, Imm)) { + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRm_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRm: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRmi: + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvm_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRvm: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { +_EmitAvxRvm: + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRvmr: + if (!o3->isReg()) + goto _IllegalInst; + + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRvmi: + if (!o3->isImm()) + goto _IllegalInst; + + imVal = static_cast(o3)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRmv: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRmvi: + if (!o3->isImm()) + goto _IllegalInst; + + imVal = static_cast(o3)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRmMr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRmMr: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitAvxM; + } + + // The following instruction uses the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvmRmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRvmRmi: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitAvxM; + } + + // The following instructions use the secondary opcode. + opCode &= kX86InstOpCode_L_Mask; + opCode |= extendedInfo.getSecondaryOpCode(); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvmMr: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitAvxM; + } + + // The following instructions use the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmReg = static_cast(o0)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvmMvr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRvmMvr: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitAvxM; + } + + // The following instruction uses the secondary opcode. + opCode &= kX86InstOpCode_L_Mask; + opCode |= extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Mem, Reg, Reg)) { + opReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o0); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvmVmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRvmVmi: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitAvxM; + } + + // The following instruction uses the secondary opcode. + opCode &= kX86InstOpCode_L_Mask; + opCode |= extendedInfo.getSecondaryOpCode(); + opReg = opCode >> kX86InstOpCode_O_Shift; + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxVm: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxVmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxVmi: + imVal = static_cast(o3)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxRvrmRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupAvxRvrmRvmr: + if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o2)->getRegIndex(); + + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) { + imVal = static_cast(o2)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o3); + + ADD_VEX_W(true); + goto _EmitAvxM; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) { + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxMovSsSd: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + goto _EmitAvxRvm; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + goto _EmitAvxM; + } + + if (encoded == ENC_OPS(Mem, Reg, None)) { + opReg = static_cast(o1)->getRegIndex(); + rmMem = static_cast(o0); + goto _EmitAvxM; + } + break; + + case kX86InstGroupAvxGatherEx: + if (encoded == ENC_OPS(Reg, Mem, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + + uint32_t vSib = rmMem->getVSib(); + if (vSib == kX86MemVSibGpz) + goto _IllegalInst; + + ADD_VEX_L(vSib == kX86MemVSibYmm); + goto _EmitAvxV; + } + break; + + case kX86InstGroupAvxGather: + if (encoded == ENC_OPS(Reg, Mem, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + + uint32_t vSib = rmMem->getVSib(); + if (vSib == kX86MemVSibGpz) + goto _IllegalInst; + + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o2)->isYmm()); + goto _EmitAvxV; + } + break; + + // ------------------------------------------------------------------------ + // [FMA4] + // ------------------------------------------------------------------------ + + case kX86InstGroupFma4_P: + // It's fine to just check the first operand, second is just for sanity. + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupFma4: + if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o2)->getRegIndex(); + + goto _EmitAvxR; + } + + if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) { + imVal = static_cast(o2)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o3); + + ADD_VEX_W(true); + goto _EmitAvxM; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) { + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + + goto _EmitAvxM; + } + break; + + // ------------------------------------------------------------------------ + // [XOP] + // ------------------------------------------------------------------------ + + case kX86InstGroupXopRm_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupXopRm: + if (encoded == ENC_OPS(Reg, Reg, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitXopR; + } + + if (encoded == ENC_OPS(Reg, Mem, None)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitXopM; + } + break; + + case kX86InstGroupXopRvmRmv: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o1)->getRegIndex(); + + goto _EmitXopR; + } + + if (encoded == ENC_OPS(Reg, Mem, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + + goto _EmitXopM; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + + ADD_VEX_W(true); + goto _EmitXopM; + } + + break; + + case kX86InstGroupXopRvmRmi: + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitXopR; + } + + if (encoded == ENC_OPS(Reg, Mem, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o1); + + goto _EmitXopM; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + + ADD_VEX_W(true); + goto _EmitXopM; + } + + // The following instructions use the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + imVal = static_cast(o2)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o1)->getRegIndex(); + goto _EmitXopR; + } + + if (encoded == ENC_OPS(Reg, Mem, Imm)) { + opReg = static_cast(o0)->getRegIndex(); + rmMem = static_cast(o1); + goto _EmitXopM; + } + break; + + case kX86InstGroupXopRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupXopRvmr: + if (!o3->isReg()) + goto _IllegalInst; + + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitXopR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitXopM; + } + break; + + case kX86InstGroupXopRvmi_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupXopRvmi: + if (!o3->isImm()) + goto _IllegalInst; + + imVal = static_cast(o3)->getInt64(); + imLen = 1; + + if (encoded == ENC_OPS(Reg, Reg, Reg)) { + opReg = static_cast(o0)->getRegIndex(); + rmReg = static_cast(o2)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + goto _EmitXopR; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem)) { + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + goto _EmitXopM; + } + break; + + case kX86InstGroupXopRvrmRvmr_P: + ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); + // ... Fall through ... + + case kX86InstGroupXopRvrmRvmr: + if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmReg = static_cast(o2)->getRegIndex(); + + goto _EmitXopR; + } + + if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) { + imVal = static_cast(o2)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o3); + + ADD_VEX_W(true); + goto _EmitXopM; + } + + if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) { + imVal = static_cast(o3)->getRegIndex() << 4; + imLen = 1; + + opReg = static_cast(o0)->getRegIndex(); + opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + rmMem = static_cast(o2); + + goto _EmitXopM; + } + break; + } + + // -------------------------------------------------------------------------- + // [Illegal] + // -------------------------------------------------------------------------- + +_IllegalInst: + self->setError(kErrorIllegalInst); +#if defined(ASMJIT_DEBUG) + assertIllegal = true; +#endif // ASMJIT_DEBUG + goto _EmitDone; + +_IllegalAddr: + self->setError(kErrorIllegalAddresing); +#if defined(ASMJIT_DEBUG) + assertIllegal = true; +#endif // ASMJIT_DEBUG + goto _EmitDone; + +_IllegalDisp: + self->setError(kErrorIllegalDisplacement); +#if defined(ASMJIT_DEBUG) + assertIllegal = true; +#endif // ASMJIT_DEBUG + goto _EmitDone; + + // -------------------------------------------------------------------------- + // [Emit - X86] + // -------------------------------------------------------------------------- + +_EmitX86Op: + // Mandatory instruction prefix. + EMIT_PP(opCode); + + // Rex prefix (64-bit only). + if (Arch == kArchX64 && opX) { + opX |= 0x40; + EMIT_BYTE(opX); + if (opX >= kRexForbidden) + goto _IllegalInst; + } + + // Instruction opcodes. + EMIT_MM(opCode); + EMIT_OP(opCode); + goto _EmitDone; + +_EmitX86OpI: + // Mandatory instruction prefix. + EMIT_PP(opCode); + + // Rex prefix (64-bit only). + if (Arch == kArchX64 && opX) { + opX |= 0x40; + EMIT_BYTE(opX); + if (opX >= kRexForbidden) + goto _IllegalInst; + } + + // Instruction opcodes. + EMIT_MM(opCode); + EMIT_OP(opCode); + goto _EmitImm; + +_EmitX86R: + // Mandatory instruction prefix. + EMIT_PP(opCode); + + // Rex prefix (64-bit only). + if (Arch == kArchX64) { + opX += static_cast(opReg & 0x08) >> 1; // Rex.R (0x04). + opX += static_cast(rmReg) >> 3; // Rex.B (0x01). + + if (opX) { + opX |= 0x40; + EMIT_BYTE(opX); + + if (opX >= kRexForbidden) + goto _IllegalInst; + + opReg &= 0x7; + rmReg &= 0x7; + } + } + + // Instruction opcodes. + EMIT_MM(opCode); + EMIT_OP(opCode); + + // ModR. + EMIT_BYTE(x86EncodeMod(3, opReg, static_cast(rmReg))); + + if (imLen != 0) + goto _EmitImm; + else + goto _EmitDone; + +_EmitX86M: + ASMJIT_ASSERT(rmMem != NULL); + ASMJIT_ASSERT(rmMem->getOp() == kOperandTypeMem); + + mBase = rmMem->getBase(); + mIndex = rmMem->getIndex(); + + // Size override prefix. + if (rmMem->hasBaseOrIndex() && rmMem->getMemType() != kMemTypeLabel) { + if (Arch == kArchX86) { + if (!rmMem->hasGpdBase()) + EMIT_BYTE(0x67); + } + else { + if (rmMem->hasGpdBase()) + EMIT_BYTE(0x67); + } + } + + // Segment override prefix. + if (rmMem->hasSegment()) { + EMIT_BYTE(x86SegmentPrefix[rmMem->getSegment()]); + } + + // Mandatory instruction prefix. + EMIT_PP(opCode); + + // Rex prefix (64-bit only). + if (Arch == kArchX64) { + opX += static_cast(opReg & 8) >> 1; // Rex.R (0x04). + opX += static_cast(mIndex - 8 < 8) << 1; // Rex.X (0x02). + opX += static_cast(mBase - 8 < 8); // Rex.B (0x01). + + if (opX) { + opX |= 0x40; + EMIT_BYTE(opX); + + if (opX >= kRexForbidden) + goto _IllegalInst; + + opReg &= 0x7; + } + + mBase &= 0x7; + } + + // Instruction opcodes. + EMIT_MM(opCode); + EMIT_OP(opCode); + // ... Fall through ... + + // -------------------------------------------------------------------------- + // [Emit - SIB] + // -------------------------------------------------------------------------- + +_EmitSib: + dispOffset = rmMem->getDisplacement(); + if (rmMem->isBaseIndexType()) { + if (mIndex >= kInvalidReg) { + if (mBase == kX86RegIndexSp) { + if (dispOffset == 0) { + // [Esp/Rsp/R12]. + EMIT_BYTE(x86EncodeMod(0, opReg, 4)); + EMIT_BYTE(x86EncodeSib(0, 4, 4)); + } + else if (IntUtil::isInt8(dispOffset)) { + // [Esp/Rsp/R12 + Disp8]. + EMIT_BYTE(x86EncodeMod(1, opReg, 4)); + EMIT_BYTE(x86EncodeSib(0, 4, 4)); + EMIT_BYTE(static_cast(dispOffset)); + } + else { + // [Esp/Rsp/R12 + Disp32]. + EMIT_BYTE(x86EncodeMod(2, opReg, 4)); + EMIT_BYTE(x86EncodeSib(0, 4, 4)); + EMIT_DWORD(static_cast(dispOffset)); + } + } + else if (mBase != kX86RegIndexBp && dispOffset == 0) { + // [Base]. + EMIT_BYTE(x86EncodeMod(0, opReg, mBase)); + } + else if (IntUtil::isInt8(dispOffset)) { + // [Base + Disp8]. + EMIT_BYTE(x86EncodeMod(1, opReg, mBase)); + EMIT_BYTE(static_cast(dispOffset)); + } + else { + // [Base + Disp32]. + EMIT_BYTE(x86EncodeMod(2, opReg, mBase)); + EMIT_DWORD(static_cast(dispOffset)); + } + } + else { + uint32_t shift = rmMem->getShift(); + + // Esp/Rsp/R12 register can't be used as an index. + mIndex &= 0x7; + ASMJIT_ASSERT(mIndex != kX86RegIndexSp); + + if (mBase != kX86RegIndexBp && dispOffset == 0) { + // [Base + Index * Scale]. + EMIT_BYTE(x86EncodeMod(0, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); + } + else if (IntUtil::isInt8(dispOffset)) { + // [Base + Index * Scale + Disp8]. + EMIT_BYTE(x86EncodeMod(1, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); + EMIT_BYTE(static_cast(dispOffset)); + } + else { + // [Base + Index * Scale + Disp32]. + EMIT_BYTE(x86EncodeMod(2, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); + EMIT_DWORD(static_cast(dispOffset)); + } + } + } + else if (Arch == kArchX86) { + if (mIndex >= kInvalidReg) { + // [Disp32]. + EMIT_BYTE(x86EncodeMod(0, opReg, 5)); + } + else { + // [Index * Scale + Disp32]. + uint32_t shift = rmMem->getShift(); + ASMJIT_ASSERT(mIndex != kX86RegIndexSp); + + EMIT_BYTE(x86EncodeMod(0, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, 5)); + } + + if (rmMem->getMemType() == kMemTypeLabel) { + // Relative->Absolute [x86 mode]. + label = self->getLabelData(rmMem->_vmem.base); + relocId = self->_relocList.getLength(); + + RelocData reloc; + reloc.type = kRelocRelToAbs; + reloc.size = 4; + reloc.from = static_cast((uintptr_t)(cursor - self->_buffer)); + reloc.data = static_cast(dispOffset); + + if (self->_relocList.append(reloc) != kErrorOk) + return self->setError(kErrorNoHeapMemory); + + if (label->offset != -1) { + // Bound label. + reloc.data += static_cast(label->offset); + EMIT_DWORD(0); + } + else { + // Non-bound label. + dispOffset = -4 - imLen; + dispSize = 4; + goto _EmitDisplacement; + } + } + else { + // [Disp32]. + EMIT_DWORD(static_cast(dispOffset)); + } + } + else /* if (Arch === kArchX64) */ { + if (rmMem->getMemType() == kMemTypeLabel) { + // [RIP + Disp32]. + label = self->getLabelData(rmMem->_vmem.base); + + // Indexing is invalid. + if (mIndex < kInvalidReg) + goto _IllegalDisp; + + EMIT_BYTE(x86EncodeMod(0, opReg, 5)); + dispOffset -= (4 + imLen); + + if (label->offset != -1) { + // Bound label. + dispOffset += label->offset - static_cast((intptr_t)(cursor - self->_buffer)); + EMIT_DWORD(static_cast(dispOffset)); + } + else { + // Non-bound label. + dispSize = 4; + relocId = -1; + goto _EmitDisplacement; + } + } + else { + EMIT_BYTE(x86EncodeMod(0, opReg, 4)); + if (mIndex >= kInvalidReg) { + // [Disp32]. + EMIT_BYTE(x86EncodeSib(0, 4, 5)); + } + else { + // [Disp32 + Index * Scale]. + mIndex &= 0x7; + ASMJIT_ASSERT(mIndex != kX86RegIndexSp); + + uint32_t shift = rmMem->getShift(); + EMIT_BYTE(x86EncodeSib(shift, mIndex, 5)); + } + + EMIT_DWORD(static_cast(dispOffset)); + } + } + + if (imLen == 0) + goto _EmitDone; + + // -------------------------------------------------------------------------- + // [Emit - Imm] + // -------------------------------------------------------------------------- + +_EmitImm: + switch (imLen) { + case 1: EMIT_BYTE (imVal & 0x000000FF); break; + case 2: EMIT_WORD (imVal & 0x0000FFFF); break; + case 4: EMIT_DWORD(imVal & 0xFFFFFFFF); break; + case 8: EMIT_QWORD(imVal ); break; + + default: + ASMJIT_ASSERT(!"Reached"); + } + goto _EmitDone; + + // -------------------------------------------------------------------------- + // [Emit - Fpu] + // -------------------------------------------------------------------------- + +_EmitFpuOp: + // Mandatory instruction prefix. + EMIT_PP(opCode); + + // Instruction opcodes. + EMIT_OP(opCode >> 8); + EMIT_OP(opCode); + goto _EmitDone; + + // -------------------------------------------------------------------------- + // [Emit - Avx] + // -------------------------------------------------------------------------- + +#define EMIT_AVX_M \ + ASMJIT_ASSERT(rmMem != NULL); \ + ASMJIT_ASSERT(rmMem->getOp() == kOperandTypeMem); \ + \ + if (rmMem->hasSegment()) { \ + EMIT_BYTE(x86SegmentPrefix[rmMem->getSegment()]); \ + } \ + \ + mBase = rmMem->getBase(); \ + mIndex = rmMem->getIndex(); \ + \ + { \ + uint32_t vex_XvvvvLpp; \ + uint32_t vex_rxbmmmmm; \ + \ + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \ + vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \ + vex_XvvvvLpp += (opX << 4) & 0x80; \ + \ + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \ + vex_rxbmmmmm += static_cast(mBase - 8 < 8) << 5; \ + vex_rxbmmmmm += static_cast(mIndex - 8 < 8) << 6; \ + \ + if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) { \ + vex_rxbmmmmm |= static_cast(opReg << 4) & 0x80; \ + vex_rxbmmmmm ^= 0xE0; \ + vex_XvvvvLpp ^= 0x78; \ + \ + EMIT_BYTE(kVex3Byte); \ + EMIT_BYTE(vex_rxbmmmmm); \ + EMIT_BYTE(vex_XvvvvLpp); \ + EMIT_OP(opCode); \ + } \ + else { \ + vex_XvvvvLpp |= static_cast(opReg << 4) & 0x80; \ + vex_XvvvvLpp ^= 0xF8; \ + \ + EMIT_BYTE(kVex2Byte); \ + EMIT_BYTE(vex_XvvvvLpp); \ + EMIT_OP(opCode); \ + } \ + } \ + \ + mBase &= 0x7; \ + opReg &= 0x7; + +_EmitAvxOp: + { + uint32_t vex_XvvvvLpp; + + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + vex_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); + vex_XvvvvLpp |= 0xF8; + + // Encode 3-byte VEX prefix only if specified in options. + if ((options & kX86InstOptionVex3) != 0) { + uint32_t vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) | 0xE0; + + EMIT_BYTE(kVex3Byte); + EMIT_OP(vex_rxbmmmmm); + EMIT_OP(vex_XvvvvLpp); + EMIT_OP(opCode); + } + else { + EMIT_BYTE(kVex2Byte); + EMIT_OP(vex_XvvvvLpp); + EMIT_OP(opCode); + } + } + goto _EmitDone; + +_EmitAvxR: + { + uint32_t vex_XvvvvLpp; + uint32_t vex_rxbmmmmm; + + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + vex_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); + vex_XvvvvLpp |= (opX >> (kVexVVVVShift - 3)); + vex_XvvvvLpp |= (opX << 4) & 0x80; + + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; + vex_rxbmmmmm |= (rmReg << 2) & 0x20; + + if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) { + vex_rxbmmmmm |= static_cast(opReg & 0x08) << 4; + vex_rxbmmmmm ^= 0xE0; + vex_XvvvvLpp ^= 0x78; + + EMIT_BYTE(kVex3Byte); + EMIT_OP(vex_rxbmmmmm); + EMIT_OP(vex_XvvvvLpp); + EMIT_OP(opCode); + + rmReg &= 0x07; + } + else { + vex_XvvvvLpp += static_cast(opReg & 0x08) << 4; + vex_XvvvvLpp ^= 0xF8; + + EMIT_BYTE(kVex2Byte); + EMIT_OP(vex_XvvvvLpp); + EMIT_OP(opCode); + } + } + + EMIT_BYTE(x86EncodeMod(3, opReg, static_cast(rmReg))); + + if (imLen == 0) + goto _EmitDone; + + EMIT_BYTE(imVal & 0xFF); + goto _EmitDone; + +_EmitAvxM: + EMIT_AVX_M + goto _EmitSib; + +_EmitAvxV: + EMIT_AVX_M + + if (mIndex >= kInvalidReg) + goto _IllegalInst; + + if (Arch == kArchX64) + mIndex &= 0x7; + + dispOffset = rmMem->getDisplacement(); + if (rmMem->isBaseIndexType()) { + uint32_t shift = rmMem->getShift(); + + if (mBase != kX86RegIndexBp && dispOffset == 0) { + // [Base + Index * Scale]. + EMIT_BYTE(x86EncodeMod(0, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); + } + else if (IntUtil::isInt8(dispOffset)) { + // [Base + Index * Scale + Disp8]. + EMIT_BYTE(x86EncodeMod(1, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); + EMIT_BYTE(static_cast(dispOffset)); + } + else { + // [Base + Index * Scale + Disp32]. + EMIT_BYTE(x86EncodeMod(2, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, mBase)); + EMIT_DWORD(static_cast(dispOffset)); + } + } + else { + // [Index * Scale + Disp32]. + uint32_t shift = rmMem->getShift(); + + EMIT_BYTE(x86EncodeMod(0, opReg, 4)); + EMIT_BYTE(x86EncodeSib(shift, mIndex, 5)); + + if (rmMem->getMemType() == kMemTypeLabel) { + if (Arch == kArchX64) + goto _IllegalAddr; + + // Relative->Absolute [x86 mode]. + label = self->getLabelData(rmMem->_vmem.base); + relocId = self->_relocList.getLength(); + + RelocData reloc; + reloc.type = kRelocRelToAbs; + reloc.size = 4; + reloc.from = static_cast((uintptr_t)(cursor - self->_buffer)); + reloc.data = static_cast(dispOffset); + + if (self->_relocList.append(reloc) != kErrorOk) + return self->setError(kErrorNoHeapMemory); + + if (label->offset != -1) { + // Bound label. + reloc.data += static_cast(label->offset); + EMIT_DWORD(0); + } + else { + // Non-bound label. + dispOffset = -4 - imLen; + dispSize = 4; + goto _EmitDisplacement; + } + } + else { + // [Disp32]. + EMIT_DWORD(static_cast(dispOffset)); + } + } + goto _EmitDone; + + // -------------------------------------------------------------------------- + // [Xop] + // -------------------------------------------------------------------------- + +#define EMIT_XOP_M \ + ASMJIT_ASSERT(rmMem != NULL); \ + ASMJIT_ASSERT(rmMem->getOp() == kOperandTypeMem); \ + \ + if (rmMem->hasSegment()) { \ + EMIT_BYTE(x86SegmentPrefix[rmMem->getSegment()]); \ + } \ + \ + mBase = rmMem->getBase(); \ + mIndex = rmMem->getIndex(); \ + \ + { \ + uint32_t vex_XvvvvLpp; \ + uint32_t vex_rxbmmmmm; \ + \ + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \ + vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \ + vex_XvvvvLpp += (opX << 4) & 0x80; \ + \ + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \ + vex_rxbmmmmm += static_cast(mBase - 8 < 8) << 5; \ + vex_rxbmmmmm += static_cast(mIndex - 8 < 8) << 6; \ + \ + vex_rxbmmmmm |= static_cast(opReg << 4) & 0x80; \ + vex_rxbmmmmm ^= 0xE0; \ + vex_XvvvvLpp ^= 0x78; \ + \ + EMIT_BYTE(kXopByte); \ + EMIT_BYTE(vex_rxbmmmmm); \ + EMIT_BYTE(vex_XvvvvLpp); \ + EMIT_OP(opCode); \ + } \ + \ + mBase &= 0x7; \ + opReg &= 0x7; + +_EmitXopR: + { + uint32_t xop_XvvvvLpp; + uint32_t xop_rxbmmmmm; + + xop_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + xop_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); + xop_XvvvvLpp |= (opX >> (kVexVVVVShift - 3)); + xop_XvvvvLpp |= (opX << 4) & 0x80; + + xop_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; + xop_rxbmmmmm |= (rmReg << 2) & 0x20; + + xop_rxbmmmmm |= static_cast(opReg & 0x08) << 4; + xop_rxbmmmmm ^= 0xE0; + xop_XvvvvLpp ^= 0x78; + + EMIT_BYTE(kXopByte); + EMIT_OP(xop_rxbmmmmm); + EMIT_OP(xop_XvvvvLpp); + EMIT_OP(opCode); + + rmReg &= 0x07; + } + + EMIT_BYTE(x86EncodeMod(3, opReg, static_cast(rmReg))); + + if (imLen == 0) + goto _EmitDone; + + EMIT_BYTE(imVal & 0xFF); + goto _EmitDone; + +_EmitXopM: + EMIT_XOP_M + goto _EmitSib; + + // -------------------------------------------------------------------------- + // [Emit - Jump/Call to an Immediate] + // -------------------------------------------------------------------------- + + // 64-bit mode requires a trampoline if a relative displacement doesn't fit + // into a 32-bit address. Old version of AsmJit used to emit jump to a section + // which contained another jump followed by an address (it worked well for + // both `jmp` and `call`), but it required to reserve 14-bytes for a possible + // trampoline. + // + // Instead of using 5-byte `jmp/call` and reserving 14 bytes required by the + // trampoline, it's better to use 6-byte `jmp/call` (prefixing it with REX + // prefix) and to patch the `jmp/call` instruction to read the address from + // a memory in case the trampoline is needed. + // +_EmitJmpOrCallAbs: + { + RelocData rd; + rd.type = kRelocAbsToRel; + rd.size = 4; + rd.from = (intptr_t)(cursor - self->_buffer) + 1; + rd.data = static_cast(imVal); + + uint32_t trampolineSize = 0; + + if (Arch == kArchX64) { + Ptr baseAddress = self->getBaseAddress(); + Ptr diff = rd.data - (baseAddress + rd.from + 4); + + // If the base address of the output is known, it's possible to determine + // the need for a trampoline here. This saves possible REX prefix in + // 64-bit mode and prevents reserving space needed for an absolute address. + if (baseAddress == kNoBaseAddress || !x64IsRelative(rd.data, baseAddress + rd.from + 4)) { + // Emit REX prefix so the instruction can be patched later on. The REX + // prefix does nothing if not patched after, but allows to patch the + // instruction in case where the trampoline is needed. + rd.type = kRelocTrampoline; + rd.from++; + + EMIT_OP(0x40); + trampolineSize = 8; + } + } + + // Both `jmp` and `call` instructions have a single-byte opcode and are + // followed by a 32-bit displacement. + EMIT_OP(opCode); + EMIT_DWORD(0); + + if (self->_relocList.append(rd) != kErrorOk) + return self->setError(kErrorNoHeapMemory); + + // Reserve space for a possible trampoline. + self->_trampolineSize += trampolineSize; + } + goto _EmitDone; + + // -------------------------------------------------------------------------- + // [Emit - Displacement] + // -------------------------------------------------------------------------- + +_EmitDisplacement: + { + ASMJIT_ASSERT(label->offset == -1); + ASMJIT_ASSERT(dispSize == 1 || dispSize == 4); + + // Chain with label. + LabelLink* link = self->_newLabelLink(); + link->prev = label->links; + link->offset = (intptr_t)(cursor - self->_buffer); + link->displacement = dispOffset; + link->relocId = relocId; + label->links = link; + + // Emit label size as dummy data. + if (dispSize == 1) + EMIT_BYTE(0x01); + else // if (dispSize == 4) + EMIT_DWORD(0x04040404); + } + + // -------------------------------------------------------------------------- + // [Logging] + // -------------------------------------------------------------------------- + +_EmitDone: +#if !defined(ASMJIT_DISABLE_LOGGER) +# if defined(ASMJIT_DEBUG) + if (self->_logger || assertIllegal) { +# else + if (self->_logger) { +# endif // ASMJIT_DEBUG + StringBuilderT<512> sb; + uint32_t loggerOptions = 0; + + if (self->_logger) { + sb.appendString(self->_logger->getIndentation()); + loggerOptions = self->_logger->getOptions(); + } + + X86Assembler_dumpInstruction(sb, Arch, code, options, o0, o1, o2, o3, loggerOptions); + + if ((loggerOptions & (1 << kLoggerOptionBinaryForm)) != 0) + X86Assembler_dumpComment(sb, sb.getLength(), self->_cursor, (intptr_t)(cursor - self->_cursor), dispSize, self->_comment); + else + X86Assembler_dumpComment(sb, sb.getLength(), NULL, 0, 0, self->_comment); + +# if defined(ASMJIT_DEBUG) + if (self->_logger) +# endif // ASMJIT_DEBUG + self->_logger->logString(kLoggerStyleDefault, sb.getData(), sb.getLength()); + +# if defined(ASMJIT_DEBUG) + // Raise an assertion failure, because this situation shouldn't happen. + if (assertIllegal) + assertionFailed(sb.getData(), __FILE__, __LINE__); +# endif // ASMJIT_DEBUG + } +#else +# if defined(ASMJIT_DEBUG) + ASMJIT_ASSERT(!assertIllegal); +# endif // ASMJIT_DEBUG +#endif // !ASMJIT_DISABLE_LOGGER + + self->_comment = NULL; + self->setCursor(cursor); + + return kErrorOk; + +_GrowBuffer: + ASMJIT_PROPAGATE_ERROR(self->_grow(16)); + + cursor = self->getCursor(); + goto _Prepare; +} + +Error X86Assembler::_emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { +#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64) + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); +#elif !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64) + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); +#else + if (_arch == kArchX86) + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); + else + return X86Assembler_emit(this, code, &o0, &o1, &o2, &o3); +#endif +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/libraries/asmjit/x86/x86assembler.h b/libraries/asmjit/x86/x86assembler.h new file mode 100644 index 000000000..223ae4aa0 --- /dev/null +++ b/libraries/asmjit/x86/x86assembler.h @@ -0,0 +1,6520 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86ASSEMBLER_H +#define _ASMJIT_X86_X86ASSEMBLER_H + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../x86/x86inst.h" +#include "../x86/x86operand.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_x86_general +//! \{ + +// ============================================================================ +// [asmjit::X86Assembler] +// ============================================================================ + +// \internal +#define ASMJIT_X86_EMIT_OPTIONS(_Class_) \ + /*! Force short form of jmp/jcc instruction. */ \ + ASMJIT_INLINE _Class_& short_() { \ + _instOptions |= kInstOptionShortForm; \ + return *this; \ + } \ + \ + /*! Force long form of jmp/jcc instruction. */ \ + ASMJIT_INLINE _Class_& long_() { \ + _instOptions |= kInstOptionLongForm; \ + return *this; \ + } \ + \ + /*! Condition is likely to be taken (has only benefit on P4). */ \ + ASMJIT_INLINE _Class_& taken() { \ + _instOptions |= kInstOptionTaken; \ + return *this; \ + } \ + \ + /*! Condition is unlikely to be taken (has only benefit on P4). */ \ + ASMJIT_INLINE _Class_& notTaken() { \ + _instOptions |= kInstOptionNotTaken; \ + return *this; \ + } \ + \ + /*! Use LOCK prefix. */ \ + ASMJIT_INLINE _Class_& lock() { \ + _instOptions |= kX86InstOptionLock; \ + return *this; \ + } \ + \ + /*! Force REX prefix. */ \ + ASMJIT_INLINE _Class_& rex() { \ + _instOptions |= kX86InstOptionRex; \ + return *this; \ + } \ + \ + /*! Force 3-byte VEX prefix. */ \ + ASMJIT_INLINE _Class_& vex3() { \ + _instOptions |= kX86InstOptionVex3; \ + return *this; \ + } + +//! X86/X64 assembler. +//! +//! Assembler is the main class in AsmJit that can encode instructions and their +//! operands to a binary stream runnable by CPU. It creates internal buffer +//! where the encodes instructions are stored and it contains intrinsics that +//! can be used to emit the code in a convenent way. Code generation is in +//! general safe, because the intrinsics uses method overloading so even the +//! code is emitted it can be checked by a C++ compiler. It's nearly impossible +//! to create invalid instruction, for example `mov [eax], [eax]`, because such +//! overload doesn't exist. +//! +//! Each call to an assembler intrinsic function emits instruction directly +//! to the binary stream. There are also runtime checks that prevent invalid +//! code to be emitted. It will assert in debug mode and put the `Assembler` +//! instance to an error state in production mode. +//! +//! Code Generation +//! --------------- +//! +//! To generate code is only needed to create instance of `Assembler` +//! and to use intrinsics. See example how to do that: +//! +//! ~~~ +//! // Use asmjit namespace. +//! using namespace asmjit; +//! using namespace asmjit::host; +//! +//! // Create Assembler instance. +//! Assembler a; +//! +//! // Prolog. +//! a.push(ebp); +//! a.mov(ebp, esp); +//! +//! // Mov 1024 to EAX, EAX is also return value. +//! a.mov(eax, 1024); +//! +//! // Epilog. +//! a.mov(esp, ebp); +//! a.pop(ebp); +//! +//! // Return. +//! a.ret(); +//! ~~~ +//! +//! You can see that syntax is very close to Intel one. Only difference is that +//! you are calling functions that emits the binary code for you. All registers +//! are in `asmjit` namespace, so it's very comfortable to use it (look at +//! first line). There is also used method `imm()` to create an immediate value. +//! Use `imm_u()` to create unsigned immediate value. +//! +//! There is also possibility to use memory addresses and immediates. Use +//! `ptr()`, `byte_ptr()`, `word_ptr()`, `dword_ptr()` and similar functions to +//! build a memory address operand. In most cases `ptr()` is enough, because an +//! information related to the operand size is needed only in rare cases, that +//! is an instruction without having any register operands, such as `inc [mem]`. +//! +//! for example, `a` is `x86::Assembler` instance: +//! +//! ~~~ +//! a.mov(ptr(eax), 0); // mov ptr [eax], 0 +//! a.mov(ptr(eax), edx); // mov ptr [eax], edx +//! ~~~ +//! +//! But it's also possible to create complex addresses: +//! +//! ~~~ +//! // eax + ecx*x addresses +//! a.mov(ptr(eax, ecx, 0), 0); // mov ptr [eax + ecx], 0 +//! a.mov(ptr(eax, ecx, 1), 0); // mov ptr [eax + ecx * 2], 0 +//! a.mov(ptr(eax, ecx, 2), 0); // mov ptr [eax + ecx * 4], 0 +//! a.mov(ptr(eax, ecx, 3), 0); // mov ptr [eax + ecx * 8], 0 +//! // eax + ecx*x + disp addresses +//! a.mov(ptr(eax, ecx, 0, 4), 0); // mov ptr [eax + ecx + 4], 0 +//! a.mov(ptr(eax, ecx, 1, 8), 0); // mov ptr [eax + ecx * 2 + 8], 0 +//! a.mov(ptr(eax, ecx, 2, 12), 0); // mov ptr [eax + ecx * 4 + 12], 0 +//! a.mov(ptr(eax, ecx, 3, 16), 0); // mov ptr [eax + ecx * 8 + 16], 0 +//! ~~~ +//! +//! All addresses shown are using `ptr()` to make memory operand. Some assembler +//! instructions (single operand ones) needs to have specified memory operand +//! size. For example `a.inc(ptr(eax))` can't be called, because the meaning is +//! ambiguous, see the code below. +//! +//! ~~~ +//! // [byte] address. +//! a.inc(byte_ptr(eax)); // Inc byte ptr [eax]. +//! a.dec(byte_ptr(eax)); // Dec byte ptr [eax]. +//! // [word] address. +//! a.inc(word_ptr(eax)); // Inc word ptr [eax]. +//! a.dec(word_ptr(eax)); // Dec word ptr [eax]. +//! // [dword] address. +//! a.inc(dword_ptr(eax)); // Inc dword ptr [eax]. +//! a.dec(dword_ptr(eax)); // Dec dword ptr [eax]. +//! ~~~ +//! +//! Calling JIT Code +//! ---------------- +//! +//! While you are over from emitting instructions, you can make your function +//! by using `Assembler::make()` method. This method will use memory +//! manager to allocate virtual memory and relocates generated code to it. For +//! memory allocation is used global memory manager by default and memory is +//! freeable, but of course this default behavior can be overridden specifying +//! your memory manager and allocation type. If you want to do with code +//! something else you can always override make() method and do what you want. +//! +//! You can get size of generated code by `getCodeSize()` or `getOffset()` +//! methods. These methods returns you code size or more precisely the current +//! code offset in bytes. The `takeCode()` function can be used to take the +//! internal buffer and reset the code generator, but the buffer taken has to +//! be freed manually in such case. +//! +//! Machine code can be executed only in memory that is marked executable. This +//! mark is usually not set for memory returned by a C/C++ `malloc` function. +//! The `VMem::alloc()` function can be used allocate a memory where the code can +//! be executed or more preferably `VMemMgr` which has interface +//! similar to `malloc/free` and can allocate chunks of various sizes. +//! +//! The next example shows how to allocate memory where the code can be executed: +//! +//! ~~~ +//! using namespace asmjit; +//! +//! JitRuntime runtime; +//! Assembler a(&runtime); +//! +//! // ... Your code generation ... +//! +//! // The function prototype +//! typedef void (*MyFunc)(); +//! +//! // make your function +//! MyFunc func = asmjit_cast(a.make()); +//! +//! // call your function +//! func(); +//! +//! // If you don't need your function again, free it. +//! runtime.release(func); +//! ~~~ +//! +//! This was a very primitive showing how the generated code can be executed. +//! In production noone will probably generate a function that is only called +//! once and nobody will probably free the function right after it was executed. +//! The code just shows the proper way of code generation and cleanup. +//! +//! Labels +//! ------ +//! +//! While generating assembler code, you will usually need to create complex +//! code with labels. Labels are fully supported and you can call `jmp` or +//! `je` (and similar) instructions to initialized or yet uninitialized label. +//! Each label expects to be bound into offset. To bind label to specific +//! offset, use `CodeGen::bind()` method. +//! +//! See next example that contains complete code that creates simple memory +//! copy function (in DWord entities). +//! +//! ~~~ +//! // Example: Usage of Label (32-bit code). +//! // +//! // Create simple DWord memory copy function: +//! // ASMJIT_STDCALL void copy32(uint32_t* dst, const uint32_t* src, size_t count); +//! using namespace asmjit; +//! +//! // Assembler instance. +//! JitRuntime runtime; +//! Assembler a(&runtime); +//! +//! // Constants. +//! const int arg_offset = 8; // Arguments offset (STDCALL EBP). +//! const int arg_size = 12; // Arguments size. +//! +//! // Labels. +//! Label L_Loop(a); +//! +//! // Prolog. +//! a.push(ebp); +//! a.mov(ebp, esp); +//! a.push(esi); +//! a.push(edi); +//! +//! // Fetch arguments +//! a.mov(esi, dword_ptr(ebp, arg_offset + 0)); // Get dst. +//! a.mov(edi, dword_ptr(ebp, arg_offset + 4)); // Get src. +//! a.mov(ecx, dword_ptr(ebp, arg_offset + 8)); // Get count. +//! +//! // Bind L_Loop label to here. +//! a.bind(L_Loop); +//! +//! Copy 4 bytes. +//! a.mov(eax, dword_ptr(esi)); +//! a.mov(dword_ptr(edi), eax); +//! +//! // Increment pointers. +//! a.add(esi, 4); +//! a.add(edi, 4); +//! +//! // Repeat loop until (--ecx != 0). +//! a.dec(ecx); +//! a.jz(L_Loop); +//! +//! // Epilog. +//! a.pop(edi); +//! a.pop(esi); +//! a.mov(esp, ebp); +//! a.pop(ebp); +//! +//! // Return: STDCALL convention is to pop stack in called function. +//! a.ret(arg_size); +//! ~~~ +//! +//! If you need more abstraction for generating assembler code and you want +//! to hide calling conventions between 32-bit and 64-bit operating systems, +//! look at `Compiler` class that is designed for higher level code +//! generation. +//! +//! Advanced Code Generation +//! ------------------------ +//! +//! This section describes some advanced generation features of `Assembler` +//! class which can be simply overlooked. The first thing that is very likely +//! needed is generic register support. In previous example the named registers +//! were used. AsmJit contains functions which can convert register index into +//! operand and back. +//! +//! Let's define function which can be used to generate some abstract code: +//! +//! ~~~ +//! // Simple function that generates dword copy. +//! void genCopyDWord(Assembler& a, const X86GpReg& dst, const X86GpReg& src, const X86GpReg& tmp) { +//! a.mov(tmp, dword_ptr(src)); +//! a.mov(dword_ptr(dst), tmp); +//! } +//! ~~~ +//! +//! This function can be called like `genCopyDWord(a, edi, esi, ebx)` or by +//! using existing `X86GpReg` instances. This abstraction allows to join more +//! code sections together without rewriting each to use specific registers. +//! You need to take care only about implicit registers which may be used by +//! several instructions (like mul, imul, div, idiv, shifting, etc...). +//! +//! Next, more advanced, but often needed technique is that you can build your +//! own registers allocator. X86 architecture contains 8 general purpose +//! registers, 8 Mm registers and 8 Xmm/Ymm/Zmm registers. X64 architecture +//! extends the count of Gp registers and Xmm/Ymm/Zmm registers to 16 or 32 +//! when AVX512 is available. +//! +//! To create a general purpose register operand from register index use +//! `gpb_lo()`, `gpb_hi()`, `gpw()`, `gpd()`, `gpq()`. To create registers of +//! other types there are functions `fp()`, `mm()`, `xmm()`, `ymm()` and `zmm()` +//! available. +//! +//! \sa X86Compiler. +struct ASMJIT_VCLASS X86Assembler : public Assembler { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_API X86Assembler(Runtime* runtime, uint32_t arch +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) + = kArchHost +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + ); + ASMJIT_API virtual ~X86Assembler(); + + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + //! Get count of registers of the current architecture. + ASMJIT_INLINE const X86RegCount& getRegCount() const { + return _regCount; + } + + //! Get Gpd or Gpq register depending on the current architecture. + ASMJIT_INLINE X86GpReg gpz(uint32_t index) const { + return X86GpReg(zax, index); + } + + //! Create an architecture dependent intptr_t memory operand. + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, int32_t disp = 0) const { + return x86::ptr(base, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) const { + return x86::ptr(base, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, int32_t disp = 0) const { + return x86::ptr(label, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr(label, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, index, shift, disp, _regSize); + } + + ASMJIT_API Error setArch(uint32_t arch); + + // -------------------------------------------------------------------------- + // [Embed] + // -------------------------------------------------------------------------- + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE void db(uint8_t x) { embed(&x, 1); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE void dw(uint16_t x) { embed(&x, 2); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE void dd(uint32_t x) { embed(&x, 4); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE void dq(uint64_t x) { embed(&x, 8); } + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE void dint8(int8_t x) { embed(&x, sizeof(int8_t)); } + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE void duint8(uint8_t x) { embed(&x, sizeof(uint8_t)); } + + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE void dint16(int16_t x) { embed(&x, sizeof(int16_t)); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE void duint16(uint16_t x) { embed(&x, sizeof(uint16_t)); } + + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE void dint32(int32_t x) { embed(&x, sizeof(int32_t)); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE void duint32(uint32_t x) { embed(&x, sizeof(uint32_t)); } + + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE void dint64(int64_t x) { embed(&x, sizeof(int64_t)); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE void duint64(uint64_t x) { embed(&x, sizeof(uint64_t)); } + + //! Add float data to the instruction stream. + ASMJIT_INLINE void dfloat(float x) { embed(&x, sizeof(float)); } + //! Add double data to the instruction stream. + ASMJIT_INLINE void ddouble(double x) { embed(&x, sizeof(double)); } + + //! Add Mm data to the instruction stream. + ASMJIT_INLINE void dmm(const Vec64& x) { embed(&x, sizeof(Vec64)); } + //! Add Xmm data to the instruction stream. + ASMJIT_INLINE void dxmm(const Vec128& x) { embed(&x, sizeof(Vec128)); } + //! Add Ymm data to the instruction stream. + ASMJIT_INLINE void dymm(const Vec256& x) { embed(&x, sizeof(Vec256)); } + + //! Add data in a given structure instance to the instruction stream. + template + ASMJIT_INLINE void dstruct(const T& x) { embed(&x, static_cast(sizeof(T))); } + + //! Embed absolute label pointer (4 or 8 bytes). + ASMJIT_API Error embedLabel(const Label& op); + + // -------------------------------------------------------------------------- + // [Align] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error align(uint32_t mode, uint32_t offset); + + // -------------------------------------------------------------------------- + // [Reloc] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual size_t _relocCode(void* dst, Ptr baseAddress) const; + + // -------------------------------------------------------------------------- + // [Emit] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); + + // ------------------------------------------------------------------------- + // [Options] + // ------------------------------------------------------------------------- + + ASMJIT_X86_EMIT_OPTIONS(X86Assembler) + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Count of registers depending on the current architecture. + X86RegCount _regCount; + + //! EAX or RAX register depending on the current architecture. + X86GpReg zax; + //! ECX or RCX register depending on the current architecture. + X86GpReg zcx; + //! EDX or RDX register depending on the current architecture. + X86GpReg zdx; + //! EBX or RBX register depending on the current architecture. + X86GpReg zbx; + //! ESP or RSP register depending on the current architecture. + X86GpReg zsp; + //! EBP or RBP register depending on the current architecture. + X86GpReg zbp; + //! ESI or RSI register depending on the current architecture. + X86GpReg zsi; + //! EDI or RDI register depending on the current architecture. + X86GpReg zdi; + + // -------------------------------------------------------------------------- + // [Base Instructions] + // -------------------------------------------------------------------------- + +#define INST_0x(_Inst_, _Code_) \ + ASMJIT_INLINE Error _Inst_() { \ + return emit(_Code_); \ + } + +#define INST_1x(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1x_(_Inst_, _Code_, _Op0_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0); \ + } + +#define INST_1i(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(int o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(unsigned int o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(int64_t o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(uint64_t o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1cc(_Inst_, _Code_, _Translate_, _Op0_) \ + ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0) { \ + return emit(_Translate_(cc), o0); \ + } \ + \ + ASMJIT_INLINE Error _Inst_##a(const _Op0_& o0) { return emit(_Code_##a, o0); } \ + ASMJIT_INLINE Error _Inst_##ae(const _Op0_& o0) { return emit(_Code_##ae, o0); } \ + ASMJIT_INLINE Error _Inst_##b(const _Op0_& o0) { return emit(_Code_##b, o0); } \ + ASMJIT_INLINE Error _Inst_##be(const _Op0_& o0) { return emit(_Code_##be, o0); } \ + ASMJIT_INLINE Error _Inst_##c(const _Op0_& o0) { return emit(_Code_##c, o0); } \ + ASMJIT_INLINE Error _Inst_##e(const _Op0_& o0) { return emit(_Code_##e, o0); } \ + ASMJIT_INLINE Error _Inst_##g(const _Op0_& o0) { return emit(_Code_##g, o0); } \ + ASMJIT_INLINE Error _Inst_##ge(const _Op0_& o0) { return emit(_Code_##ge, o0); } \ + ASMJIT_INLINE Error _Inst_##l(const _Op0_& o0) { return emit(_Code_##l, o0); } \ + ASMJIT_INLINE Error _Inst_##le(const _Op0_& o0) { return emit(_Code_##le, o0); } \ + ASMJIT_INLINE Error _Inst_##na(const _Op0_& o0) { return emit(_Code_##na, o0); } \ + ASMJIT_INLINE Error _Inst_##nae(const _Op0_& o0) { return emit(_Code_##nae, o0); } \ + ASMJIT_INLINE Error _Inst_##nb(const _Op0_& o0) { return emit(_Code_##nb, o0); } \ + ASMJIT_INLINE Error _Inst_##nbe(const _Op0_& o0) { return emit(_Code_##nbe, o0); } \ + ASMJIT_INLINE Error _Inst_##nc(const _Op0_& o0) { return emit(_Code_##nc, o0); } \ + ASMJIT_INLINE Error _Inst_##ne(const _Op0_& o0) { return emit(_Code_##ne, o0); } \ + ASMJIT_INLINE Error _Inst_##ng(const _Op0_& o0) { return emit(_Code_##ng, o0); } \ + ASMJIT_INLINE Error _Inst_##nge(const _Op0_& o0) { return emit(_Code_##nge, o0); } \ + ASMJIT_INLINE Error _Inst_##nl(const _Op0_& o0) { return emit(_Code_##nl, o0); } \ + ASMJIT_INLINE Error _Inst_##nle(const _Op0_& o0) { return emit(_Code_##nle, o0); } \ + ASMJIT_INLINE Error _Inst_##no(const _Op0_& o0) { return emit(_Code_##no, o0); } \ + ASMJIT_INLINE Error _Inst_##np(const _Op0_& o0) { return emit(_Code_##np, o0); } \ + ASMJIT_INLINE Error _Inst_##ns(const _Op0_& o0) { return emit(_Code_##ns, o0); } \ + ASMJIT_INLINE Error _Inst_##nz(const _Op0_& o0) { return emit(_Code_##nz, o0); } \ + ASMJIT_INLINE Error _Inst_##o(const _Op0_& o0) { return emit(_Code_##o, o0); } \ + ASMJIT_INLINE Error _Inst_##p(const _Op0_& o0) { return emit(_Code_##p, o0); } \ + ASMJIT_INLINE Error _Inst_##pe(const _Op0_& o0) { return emit(_Code_##pe, o0); } \ + ASMJIT_INLINE Error _Inst_##po(const _Op0_& o0) { return emit(_Code_##po, o0); } \ + ASMJIT_INLINE Error _Inst_##s(const _Op0_& o0) { return emit(_Code_##s, o0); } \ + ASMJIT_INLINE Error _Inst_##z(const _Op0_& o0) { return emit(_Code_##z, o0); } + +#define INST_2x(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2x_(_Inst_, _Code_, _Op0_, _Op1_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2i(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, unsigned int o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int64_t o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, uint64_t o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2cc(_Inst_, _Code_, _Translate_, _Op0_, _Op1_) \ + ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Translate_(cc), o0, o1); \ + } \ + \ + ASMJIT_INLINE Error _Inst_##a(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##a, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ae, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##b(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##b, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##be(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##be, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##c(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##c, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##e(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##e, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##g(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##g, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ge, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##l(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##l, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##le(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##le, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##na(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##na, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nae, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nb(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nb, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nbe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nbe, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nc(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nc, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ne(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ne, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ng(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ng, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nge, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nl(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nl, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nle(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nle, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##no(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##no, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##np(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##np, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##ns(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ns, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##nz(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nz, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##o(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##o, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##p(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##p, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##pe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##pe, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##po(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##po, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##s(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##s, o0, o1); } \ + ASMJIT_INLINE Error _Inst_##z(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##z, o0, o1); } + +#define INST_3x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_, _Cond_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + + //! Add with Carry. + INST_2x(adc, kX86InstIdAdc, X86GpReg, X86GpReg) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86GpReg, X86Mem) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86GpReg, Imm) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpReg) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86Mem, Imm) + + //! Add. + INST_2x(add, kX86InstIdAdd, X86GpReg, X86GpReg) + //! \overload + INST_2x(add, kX86InstIdAdd, X86GpReg, X86Mem) + //! \overload + INST_2i(add, kX86InstIdAdd, X86GpReg, Imm) + //! \overload + INST_2x(add, kX86InstIdAdd, X86Mem, X86GpReg) + //! \overload + INST_2i(add, kX86InstIdAdd, X86Mem, Imm) + + //! And. + INST_2x(and_, kX86InstIdAnd, X86GpReg, X86GpReg) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86GpReg, X86Mem) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86GpReg, Imm) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpReg) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86Mem, Imm) + + //! Bit scan forward. + INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86GpReg, !o0.isGpb()) + //! \overload + INST_2x_(bsf, kX86InstIdBsf, X86GpReg, X86Mem, !o0.isGpb()) + + //! Bit scan reverse. + INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86GpReg, !o0.isGpb()) + //! \overload + INST_2x_(bsr, kX86InstIdBsr, X86GpReg, X86Mem, !o0.isGpb()) + + //! Byte swap (32-bit or 64-bit registers only) (i486). + INST_1x_(bswap, kX86InstIdBswap, X86GpReg, o0.getSize() >= 4) + + //! Bit test. + INST_2x(bt, kX86InstIdBt, X86GpReg, X86GpReg) + //! \overload + INST_2i(bt, kX86InstIdBt, X86GpReg, Imm) + //! \overload + INST_2x(bt, kX86InstIdBt, X86Mem, X86GpReg) + //! \overload + INST_2i(bt, kX86InstIdBt, X86Mem, Imm) + + //! Bit test and complement. + INST_2x(btc, kX86InstIdBtc, X86GpReg, X86GpReg) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86GpReg, Imm) + //! \overload + INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpReg) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86Mem, Imm) + + //! Bit test and reset. + INST_2x(btr, kX86InstIdBtr, X86GpReg, X86GpReg) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86GpReg, Imm) + //! \overload + INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpReg) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86Mem, Imm) + + //! Bit test and set. + INST_2x(bts, kX86InstIdBts, X86GpReg, X86GpReg) + //! \overload + INST_2i(bts, kX86InstIdBts, X86GpReg, Imm) + //! \overload + INST_2x(bts, kX86InstIdBts, X86Mem, X86GpReg) + //! \overload + INST_2i(bts, kX86InstIdBts, X86Mem, Imm) + + //! Call. + INST_1x(call, kX86InstIdCall, X86GpReg) + //! \overload + INST_1x(call, kX86InstIdCall, X86Mem) + //! \overload + INST_1x(call, kX86InstIdCall, Label) + //! \overload + INST_1x(call, kX86InstIdCall, Imm) + //! \overload + ASMJIT_INLINE Error call(Ptr o0) { return call(Imm(o0)); } + + //! Clear carry flag. + INST_0x(clc, kX86InstIdClc) + //! Clear direction flag. + INST_0x(cld, kX86InstIdCld) + //! Complement carry flag. + INST_0x(cmc, kX86InstIdCmc) + + //! Convert BYTE to WORD (AX <- Sign Extend AL). + INST_0x(cbw, kX86InstIdCbw) + //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX). + INST_0x(cdq, kX86InstIdCdq) + //! Convert DWORD to QWORD (RAX <- Sign Extend EAX) (X64 Only). + INST_0x(cdqe, kX86InstIdCdqe) + //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX) (X64 Only). + INST_0x(cqo, kX86InstIdCqo) + //! Convert WORD to DWORD (DX:AX <- Sign Extend AX). + INST_0x(cwd, kX86InstIdCwd) + //! Convert WORD to DWORD (EAX <- Sign Extend AX). + INST_0x(cwde, kX86InstIdCwde) + + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86GpReg) + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpReg, X86Mem) + + //! Compare two operands. + INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86GpReg) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86GpReg, X86Mem) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86GpReg, Imm) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpReg) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86Mem, Imm) + + //! Compare BYTE in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(cmpsb, kX86InstIdCmpsB) + //! Compare DWORD in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(cmpsd, kX86InstIdCmpsD) + //! Compare QWORD in ES:[RDI] and DS:[RDI] (X64 Only). + INST_0x(cmpsq, kX86InstIdCmpsQ) + //! Compare WORD in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(cmpsw, kX86InstIdCmpsW) + + //! Compare and exchange (i486). + INST_2x(cmpxchg, kX86InstIdCmpxchg, X86GpReg, X86GpReg) + //! \overload + INST_2x(cmpxchg, kX86InstIdCmpxchg, X86Mem, X86GpReg) + + //! Compare and exchange 128-bit value in RDX:RAX with the memory operand (X64 Only). + INST_1x(cmpxchg16b, kX86InstIdCmpxchg16b, X86Mem) + //! Compare and exchange 64-bit value in EDX:EAX with the memory operand (Pentium). + INST_1x(cmpxchg8b, kX86InstIdCmpxchg8b, X86Mem) + + //! CPU identification (i486). + INST_0x(cpuid, kX86InstIdCpuid) + + //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86GpReg, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! \overload + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + + //! Decimal adjust AL after addition (X86 Only). + INST_0x(daa, kX86InstIdDaa) + //! Decimal adjust AL after subtraction (X86 Only). + INST_0x(das, kX86InstIdDas) + + //! Decrement by 1. + INST_1x(dec, kX86InstIdDec, X86GpReg) + //! \overload + INST_1x(dec, kX86InstIdDec, X86Mem) + + //! Unsigned divide (xDX:xAX <- xDX:xAX / o0). + INST_1x(div, kX86InstIdDiv, X86GpReg) + //! \overload + INST_1x(div, kX86InstIdDiv, X86Mem) + + //! Make stack frame for procedure parameters. + INST_2x(enter, kX86InstIdEnter, Imm, Imm) + + //! Signed divide (xDX:xAX <- xDX:xAX / op). + INST_1x(idiv, kX86InstIdIdiv, X86GpReg) + //! \overload + INST_1x(idiv, kX86InstIdIdiv, X86Mem) + + //! Signed multiply (xDX:xAX <- xAX * o0). + INST_1x(imul, kX86InstIdImul, X86GpReg) + //! \overload + INST_1x(imul, kX86InstIdImul, X86Mem) + + //! Signed multiply. + INST_2x(imul, kX86InstIdImul, X86GpReg, X86GpReg) + //! \overload + INST_2x(imul, kX86InstIdImul, X86GpReg, X86Mem) + //! \overload + INST_2i(imul, kX86InstIdImul, X86GpReg, Imm) + + //! Signed multiply. + INST_3i(imul, kX86InstIdImul, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(imul, kX86InstIdImul, X86GpReg, X86Mem, Imm) + + //! Increment by 1. + INST_1x(inc, kX86InstIdInc, X86GpReg) + //! \overload + INST_1x(inc, kX86InstIdInc, X86Mem) + + //! Interrupt. + INST_1i(int_, kX86InstIdInt, Imm) + //! Interrupt 3 - trap to debugger. + ASMJIT_INLINE Error int3() { return int_(3); } + + //! Jump to `label` if condition `cc` is met. + INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label) + + //! Short jump if CX/ECX/RCX is zero. + INST_2x_(jecxz, kX86InstIdJecxz, X86GpReg, Label, o0.getRegIndex() == kX86RegIndexCx) + + //! Jump. + INST_1x(jmp, kX86InstIdJmp, X86GpReg) + //! \overload + INST_1x(jmp, kX86InstIdJmp, X86Mem) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Label) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Imm) + //! \overload + ASMJIT_INLINE Error jmp(Ptr dst) { return jmp(Imm(dst)); } + + //! Load AH from flags. + INST_0x(lahf, kX86InstIdLahf) + + //! Load effective address + INST_2x(lea, kX86InstIdLea, X86GpReg, X86Mem) + + //! High level procedure exit. + INST_0x(leave, kX86InstIdLeave) + + //! Load BYTE from DS:[ESI/RSI] to AL. + INST_0x(lodsb, kX86InstIdLodsB) + //! Load DWORD from DS:[ESI/RSI] to EAX. + INST_0x(lodsd, kX86InstIdLodsD) + //! Load QWORD from DS:[RDI] to RAX (X64 Only). + INST_0x(lodsq, kX86InstIdLodsQ) + //! Load WORD from DS:[ESI/RSI] to AX. + INST_0x(lodsw, kX86InstIdLodsW) + + //! Move. + INST_2x(mov, kX86InstIdMov, X86GpReg, X86GpReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86GpReg, X86Mem) + //! \overload + INST_2i(mov, kX86InstIdMov, X86GpReg, Imm) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86GpReg) + //! \overload + INST_2i(mov, kX86InstIdMov, X86Mem, Imm) + + //! Move from segment register. + INST_2x(mov, kX86InstIdMov, X86GpReg, X86SegReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg) + //! Move to segment register. + INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem) + + //! Move (AL|AX|EAX|RAX <- absolute address in immediate). + INST_2x_(mov_ptr, kX86InstIdMovPtr, X86GpReg, Imm, o0.getRegIndex() == 0); + //! \overload + ASMJIT_INLINE Error mov_ptr(const X86GpReg& o0, Ptr o1) { + ASMJIT_ASSERT(o0.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, o0, Imm(o1)); + } + + //! Move (absolute address in immediate <- AL|AX|EAX|RAX). + INST_2x_(mov_ptr, kX86InstIdMovPtr, Imm, X86GpReg, o1.getRegIndex() == 0); + //! \overload + ASMJIT_INLINE Error mov_ptr(Ptr o0, const X86GpReg& o1) { + ASMJIT_ASSERT(o1.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, Imm(o0), o1); + } + + //! Move data after dwapping bytes (SSE3 - Atom). + INST_2x_(movbe, kX86InstIdMovbe, X86GpReg, X86Mem, !o0.isGpb()); + //! \overload + INST_2x_(movbe, kX86InstIdMovbe, X86Mem, X86GpReg, !o1.isGpb()); + + //! Move BYTE from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(movsb, kX86InstIdMovsB) + //! Move DWORD from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(movsd, kX86InstIdMovsD) + //! Move QWORD from DS:[RSI] to ES:[RDI] (X64 Only). + INST_0x(movsq, kX86InstIdMovsQ) + //! Move WORD from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(movsw, kX86InstIdMovsW) + + //! Move with sign-extension. + INST_2x(movsx, kX86InstIdMovsx, X86GpReg, X86GpReg) + //! \overload + INST_2x(movsx, kX86InstIdMovsx, X86GpReg, X86Mem) + + //! Move DWORD to QWORD with sign-extension (X64 Only). + INST_2x(movsxd, kX86InstIdMovsxd, X86GpReg, X86GpReg) + //! \overload + INST_2x(movsxd, kX86InstIdMovsxd, X86GpReg, X86Mem) + + //! Move with zero-extension. + INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86GpReg) + //! \overload + INST_2x(movzx, kX86InstIdMovzx, X86GpReg, X86Mem) + + //! Unsigned multiply (xDX:xAX <- xAX * o0). + INST_1x(mul, kX86InstIdMul, X86GpReg) + //! \overload + INST_1x(mul, kX86InstIdMul, X86Mem) + + //! Two's complement negation. + INST_1x(neg, kX86InstIdNeg, X86GpReg) + //! \overload + INST_1x(neg, kX86InstIdNeg, X86Mem) + + //! No operation. + INST_0x(nop, kX86InstIdNop) + + //! One's complement negation. + INST_1x(not_, kX86InstIdNot, X86GpReg) + //! \overload + INST_1x(not_, kX86InstIdNot, X86Mem) + + //! Or. + INST_2x(or_, kX86InstIdOr, X86GpReg, X86GpReg) + //! \overload + INST_2x(or_, kX86InstIdOr, X86GpReg, X86Mem) + //! \overload + INST_2i(or_, kX86InstIdOr, X86GpReg, Imm) + //! \overload + INST_2x(or_, kX86InstIdOr, X86Mem, X86GpReg) + //! \overload + INST_2i(or_, kX86InstIdOr, X86Mem, Imm) + + //! Pop a value from the stack. + INST_1x_(pop, kX86InstIdPop, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) + //! \overload + INST_1x_(pop, kX86InstIdPop, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + + //! Pop a segment register from the stack. + //! + //! \note There is no instruction to pop a cs segment register. + INST_1x_(pop, kX86InstIdPop, X86SegReg, o0.getRegIndex() != kX86SegCs); + + //! Pop all Gp registers - EDI|ESI|EBP|Ign|EBX|EDX|ECX|EAX (X86 Only). + INST_0x(popa, kX86InstIdPopa) + + //! Pop stack into EFLAGS register (32-bit or 64-bit). + INST_0x(popf, kX86InstIdPopf) + + //! Return the count of number of bits set to 1 (SSE4.2). + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86GpReg, !o0.isGpb() && o0.getRegType() == o1.getRegType()) + //! \overload + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86Mem, !o0.isGpb()) + + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push segment register on the stack. + INST_1x(push, kX86InstIdPush, X86SegReg) + //! Push WORD or DWORD/QWORD on the stack. + INST_1i(push, kX86InstIdPush, Imm) + + //! Push all Gp registers - EAX|ECX|EDX|EBX|ESP|EBP|ESI|EDI (X86 Only). + INST_0x(pusha, kX86InstIdPusha) + + //! Push EFLAGS register (32-bit or 64-bit) on the stack. + INST_0x(pushf, kX86InstIdPushf) + + //! Rotate bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(rcl, kX86InstIdRcl, X86GpReg, X86GpReg) + //! \overload + INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpReg) + //! Rotate bits left. + INST_2i(rcl, kX86InstIdRcl, X86GpReg, Imm) + //! \overload + INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm) + + //! Rotate bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(rcr, kX86InstIdRcr, X86GpReg, X86GpReg) + //! \overload + INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpReg) + //! Rotate bits right. + INST_2i(rcr, kX86InstIdRcr, X86GpReg, Imm) + //! \overload + INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm) + + //! Read time-stamp counter (Pentium). + INST_0x(rdtsc, kX86InstIdRdtsc) + //! Read time-stamp counter and processor id (Pentium). + INST_0x(rdtscp, kX86InstIdRdtscp) + + //! Repeated load ECX/RCX BYTEs from DS:[ESI/RSI] to AL. + INST_0x(rep_lodsb, kX86InstIdRepLodsB) + //! Repeated load ECX/RCX DWORDs from DS:[ESI/RSI] to EAX. + INST_0x(rep_lodsd, kX86InstIdRepLodsD) + //! Repeated load ECX/RCX QWORDs from DS:[RDI] to RAX (X64 Only). + INST_0x(rep_lodsq, kX86InstIdRepLodsQ) + //! Repeated load ECX/RCX WORDs from DS:[ESI/RSI] to AX. + INST_0x(rep_lodsw, kX86InstIdRepLodsW) + + //! Repeated move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(rep_movsb, kX86InstIdRepMovsB) + //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(rep_movsd, kX86InstIdRepMovsD) + //! Repeated move ECX/RCX QWORDs from DS:[RSI] to ES:[RDI] (X64 Only). + INST_0x(rep_movsq, kX86InstIdRepMovsQ) + //! Repeated move ECX/RCX WORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_0x(rep_movsw, kX86InstIdRepMovsW) + + //! Repeated fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL. + INST_0x(rep_stosb, kX86InstIdRepStosB) + //! Repeated fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX. + INST_0x(rep_stosd, kX86InstIdRepStosD) + //! Repeated fill ECX/RCX QWORDs at ES:[RDI] with RAX (X64 Only). + INST_0x(rep_stosq, kX86InstIdRepStosQ) + //! Repeated fill ECX/RCX WORDs at ES:[EDI/RDI] with AX. + INST_0x(rep_stosw, kX86InstIdRepStosW) + + //! Repeated find non-AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repe_cmpsb, kX86InstIdRepeCmpsB) + //! Repeated find non-EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repe_cmpsd, kX86InstIdRepeCmpsD) + //! Repeated find non-RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only). + INST_0x(repe_cmpsq, kX86InstIdRepeCmpsQ) + //! Repeated find non-AX WORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repe_cmpsw, kX86InstIdRepeCmpsW) + + //! Repeated find non-AL BYTE starting at ES:[EDI/RDI]. + INST_0x(repe_scasb, kX86InstIdRepeScasB) + //! Repeated find non-EAX DWORD starting at ES:[EDI/RDI]. + INST_0x(repe_scasd, kX86InstIdRepeScasD) + //! Repeated find non-RAX QWORD starting at ES:[RDI] (X64 Only). + INST_0x(repe_scasq, kX86InstIdRepeScasQ) + //! Repeated find non-AX WORD starting at ES:[EDI/RDI]. + INST_0x(repe_scasw, kX86InstIdRepeScasW) + + //! Repeated find AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repne_cmpsb, kX86InstIdRepneCmpsB) + //! Repeated find EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repne_cmpsd, kX86InstIdRepneCmpsD) + //! Repeated find RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only). + INST_0x(repne_cmpsq, kX86InstIdRepneCmpsQ) + //! Repeated find AX WORDs in ES:[EDI/RDI] and DS:[ESI/RSI]. + INST_0x(repne_cmpsw, kX86InstIdRepneCmpsW) + + //! Repeated find AL BYTEs starting at ES:[EDI/RDI]. + INST_0x(repne_scasb, kX86InstIdRepneScasB) + //! Repeated find EAX DWORDs starting at ES:[EDI/RDI]. + INST_0x(repne_scasd, kX86InstIdRepneScasD) + //! Repeated find RAX QWORDs starting at ES:[RDI] (X64 Only). + INST_0x(repne_scasq, kX86InstIdRepneScasQ) + //! Repeated find AX WORDs starting at ES:[EDI/RDI]. + INST_0x(repne_scasw, kX86InstIdRepneScasW) + + //! Return. + INST_0x(ret, kX86InstIdRet) + //! \overload + INST_1i(ret, kX86InstIdRet, Imm) + + //! Rotate bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(rol, kX86InstIdRol, X86GpReg, X86GpReg) + //! \overload + INST_2x(rol, kX86InstIdRol, X86Mem, X86GpReg) + //! Rotate bits left. + INST_2i(rol, kX86InstIdRol, X86GpReg, Imm) + //! \overload + INST_2i(rol, kX86InstIdRol, X86Mem, Imm) + + //! Rotate bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(ror, kX86InstIdRor, X86GpReg, X86GpReg) + //! \overload + INST_2x(ror, kX86InstIdRor, X86Mem, X86GpReg) + //! Rotate bits right. + INST_2i(ror, kX86InstIdRor, X86GpReg, Imm) + //! \overload + INST_2i(ror, kX86InstIdRor, X86Mem, Imm) + + //! Store AH into flags. + INST_0x(sahf, kX86InstIdSahf) + + //! Integer subtraction with borrow. + INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86GpReg) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86GpReg, X86Mem) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86GpReg, Imm) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpReg) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm) + + //! Shift bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(sal, kX86InstIdSal, X86GpReg, X86GpReg) + //! \overload + INST_2x(sal, kX86InstIdSal, X86Mem, X86GpReg) + //! Shift bits left. + INST_2i(sal, kX86InstIdSal, X86GpReg, Imm) + //! \overload + INST_2i(sal, kX86InstIdSal, X86Mem, Imm) + + //! Shift bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(sar, kX86InstIdSar, X86GpReg, X86GpReg) + //! \overload + INST_2x(sar, kX86InstIdSar, X86Mem, X86GpReg) + //! Shift bits right. + INST_2i(sar, kX86InstIdSar, X86GpReg, Imm) + //! \overload + INST_2i(sar, kX86InstIdSar, X86Mem, Imm) + + //! Find non-AL BYTE starting at ES:[EDI/RDI]. + INST_0x(scasb, kX86InstIdScasB) + //! Find non-EAX DWORD starting at ES:[EDI/RDI]. + INST_0x(scasd, kX86InstIdScasD) + //! Find non-rax QWORD starting at ES:[RDI] (X64 Only). + INST_0x(scasq, kX86InstIdScasQ) + //! Find non-AX WORD starting at ES:[EDI/RDI]. + INST_0x(scasw, kX86InstIdScasW) + + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpReg) + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem) + + //! Shift bits left. + //! + //! \note `o1` register can be only `cl`. + INST_2x(shl, kX86InstIdShl, X86GpReg, X86GpReg) + //! \overload + INST_2x(shl, kX86InstIdShl, X86Mem, X86GpReg) + //! Shift bits left. + INST_2i(shl, kX86InstIdShl, X86GpReg, Imm) + //! \overload + INST_2i(shl, kX86InstIdShl, X86Mem, Imm) + + //! Shift bits right. + //! + //! \note `o1` register can be only `cl`. + INST_2x(shr, kX86InstIdShr, X86GpReg, X86GpReg) + //! \overload + INST_2x(shr, kX86InstIdShr, X86Mem, X86GpReg) + //! Shift bits right. + INST_2i(shr, kX86InstIdShr, X86GpReg, Imm) + //! \overload + INST_2i(shr, kX86InstIdShr, X86Mem, Imm) + + //! Double precision shift left. + //! + //! \note `o2` register can be only `cl` register. + INST_3x(shld, kX86InstIdShld, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shld, kX86InstIdShld, X86Mem, X86GpReg, X86GpReg) + //! Double precision shift left. + INST_3i(shld, kX86InstIdShld, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(shld, kX86InstIdShld, X86Mem, X86GpReg, Imm) + + //! Double precision shift right. + //! + //! \note `o2` register can be only `cl` register. + INST_3x(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpReg, X86GpReg) + //! Double precision shift right. + INST_3i(shrd, kX86InstIdShrd, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpReg, Imm) + + //! Set carry flag to 1. + INST_0x(stc, kX86InstIdStc) + //! Set direction flag to 1. + INST_0x(std, kX86InstIdStd) + + //! Fill BYTE at ES:[EDI/RDI] with AL. + INST_0x(stosb, kX86InstIdStosB) + //! Fill DWORD at ES:[EDI/RDI] with EAX. + INST_0x(stosd, kX86InstIdStosD) + //! Fill QWORD at ES:[RDI] with RAX (X64 Only). + INST_0x(stosq, kX86InstIdStosQ) + //! Fill WORD at ES:[EDI/RDI] with AX. + INST_0x(stosw, kX86InstIdStosW) + + //! Subtract. + INST_2x(sub, kX86InstIdSub, X86GpReg, X86GpReg) + //! \overload + INST_2x(sub, kX86InstIdSub, X86GpReg, X86Mem) + //! \overload + INST_2i(sub, kX86InstIdSub, X86GpReg, Imm) + //! \overload + INST_2x(sub, kX86InstIdSub, X86Mem, X86GpReg) + //! \overload + INST_2i(sub, kX86InstIdSub, X86Mem, Imm) + + //! Logical compare. + INST_2x(test, kX86InstIdTest, X86GpReg, X86GpReg) + //! \overload + INST_2i(test, kX86InstIdTest, X86GpReg, Imm) + //! \overload + INST_2x(test, kX86InstIdTest, X86Mem, X86GpReg) + //! \overload + INST_2i(test, kX86InstIdTest, X86Mem, Imm) + + //! Undefined instruction - Raise #UD exception. + INST_0x(ud2, kX86InstIdUd2) + + //! Exchange and Add. + INST_2x(xadd, kX86InstIdXadd, X86GpReg, X86GpReg) + //! \overload + INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpReg) + + //! Exchange register/memory with register. + INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86GpReg) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpReg) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86GpReg, X86Mem) + + //! Xor. + INST_2x(xor_, kX86InstIdXor, X86GpReg, X86GpReg) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86GpReg, X86Mem) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86GpReg, Imm) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpReg) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [Fpu] + // -------------------------------------------------------------------------- + + //! Compute 2^x - 1 (FPU). + INST_0x(f2xm1, kX86InstIdF2xm1) + //! Absolute value of fp0 (FPU). + INST_0x(fabs, kX86InstIdFabs) + + //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU). + INST_1x(fadd, kX86InstIdFadd, X86Mem) + //! Add fp0 to `o0` and pop the FPU stack (FPU). + INST_1x(faddp, kX86InstIdFaddp, X86FpReg) + //! \overload + INST_0x(faddp, kX86InstIdFaddp) + + //! Load binary coded decimal (FPU). + INST_1x(fbld, kX86InstIdFbld, X86Mem) + //! Store BCD integer and Pop (FPU). + INST_1x(fbstp, kX86InstIdFbstp, X86Mem) + //! Change fp0 sign (FPU). + INST_0x(fchs, kX86InstIdFchs) + //! Clear exceptions (FPU). + INST_0x(fclex, kX86InstIdFclex) + + //! Conditional move (FPU). + INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg) + + //! Compare fp0 with `o0` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86FpReg) + //! Compare fp0 with fp1 (FPU). + INST_0x(fcom, kX86InstIdFcom) + //! Compare fp0 with 4-byte or 8-byte FP at `src` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86Mem) + //! Compare fp0 with `o0` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) + //! Compare fp0 with fp1 and pop the FPU stack (FPU). + INST_0x(fcomp, kX86InstIdFcomp) + //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86Mem) + //! Compare fp0 with fp1 and pop the FPU stack twice (FPU). + INST_0x(fcompp, kX86InstIdFcompp) + //! Compare fp0 and `o0` and Set EFLAGS (FPU). + INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) + //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU). + INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) + + //! Calculate cosine of fp0 and store result in fp0 (FPU). + INST_0x(fcos, kX86InstIdFcos) + //! Decrement FPU stack-top pointer (FPU). + INST_0x(fdecstp, kX86InstIdFdecstp) + + //! Divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Divide fp0 by 32-bit or 64-bit FP value (FPU). + INST_1x(fdiv, kX86InstIdFdiv, X86Mem) + //! Divide `o0` by fp0 (FPU). + INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) + //! \overload + INST_0x(fdivp, kX86InstIdFdivp) + + //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU). + INST_1x(fdivr, kX86InstIdFdivr, X86Mem) + //! Reverse divide `o0` by fp0 (FPU). + INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) + //! \overload + INST_0x(fdivrp, kX86InstIdFdivrp) + + //! Free FP register (FPU). + INST_1x(ffree, kX86InstIdFfree, X86FpReg) + + //! Add 16-bit or 32-bit integer to fp0 (FPU). + INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare fp0 with 16-bit or 32-bit Integer (FPU). + INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU). + INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU). + INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU). + INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Increment FPU stack-top pointer (FPU). + INST_0x(fincstp, kX86InstIdFincstp) + //! Initialize FPU (FPU). + INST_0x(finit, kX86InstIdFinit) + + //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Initialize FPU without checking for pending unmasked exceptions (FPU). + INST_0x(fninit, kX86InstIdFninit) + + //! Store fp0 as 16-bit or 32-bit Integer to `o0` (FPU). + INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU). + INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU). + INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Push `o0` on the FPU stack (FPU). + INST_1x(fld, kX86InstIdFld, X86FpReg) + + //! Push +1.0 on the FPU stack (FPU). + INST_0x(fld1, kX86InstIdFld1) + //! Push log2(10) on the FPU stack (FPU). + INST_0x(fldl2t, kX86InstIdFldl2t) + //! Push log2(e) on the FPU stack (FPU). + INST_0x(fldl2e, kX86InstIdFldl2e) + //! Push pi on the FPU stack (FPU). + INST_0x(fldpi, kX86InstIdFldpi) + //! Push log10(2) on the FPU stack (FPU). + INST_0x(fldlg2, kX86InstIdFldlg2) + //! Push ln(2) on the FPU stack (FPU). + INST_0x(fldln2, kX86InstIdFldln2) + //! Push +0.0 on the FPU stack (FPU). + INST_0x(fldz, kX86InstIdFldz) + + //! Load x87 FPU control word (2 bytes) (FPU). + INST_1x(fldcw, kX86InstIdFldcw, X86Mem) + //! Load x87 FPU environment (14 or 28 bytes) (FPU). + INST_1x(fldenv, kX86InstIdFldenv, X86Mem) + + //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU). + INST_1x(fmul, kX86InstIdFmul, X86Mem) + //! Multiply fp0 by `o0` and pop the FPU stack (FPU). + INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) + //! \overload + INST_0x(fmulp, kX86InstIdFmulp) + + //! Clear exceptions (FPU). + INST_0x(fnclex, kX86InstIdFnclex) + //! No operation (FPU). + INST_0x(fnop, kX86InstIdFnop) + //! Save FPU state (FPU). + INST_1x(fnsave, kX86InstIdFnsave, X86Mem) + //! Store x87 FPU environment (FPU). + INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) + //! Store x87 FPU control word (FPU). + INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem) + + //! Store x87 FPU status word to `o0` (AX) (FPU). + INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx)) + //! Store x87 FPU status word to `o0` (2 bytes) (FPU). + INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) + + //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU). + INST_0x(fpatan, kX86InstIdFpatan) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem, kX86InstIdFprem) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem1, kX86InstIdFprem1) + //! Arctan(`fp0`) and pop the FPU stack (FPU). + INST_0x(fptan, kX86InstIdFptan) + //! Round `fp0` to Integer (FPU). + INST_0x(frndint, kX86InstIdFrndint) + + //! Restore FPU state from `o0` (94 or 108 bytes) (FPU). + INST_1x(frstor, kX86InstIdFrstor, X86Mem) + //! Save FPU state to `o0` (94 or 108 bytes) (FPU). + INST_1x(fsave, kX86InstIdFsave, X86Mem) + + //! Scale `fp0` by `fp1` (FPU). + INST_0x(fscale, kX86InstIdFscale) + //! Sine of `fp0` and store result in `fp0` (FPU). + INST_0x(fsin, kX86InstIdFsin) + //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU). + INST_0x(fsincos, kX86InstIdFsincos) + //! Square root of `fp0` and store it in `fp0` (FPU). + INST_0x(fsqrt, kX86InstIdFsqrt) + + //! Store floating point value to 32-bit or 64-bit memory location (FPU). + INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Store floating point value to `o0` (FPU). + INST_1x(fst, kX86InstIdFst, X86FpReg) + //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU). + INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Store floating point value to `o0` and pop the FPU stack (FPU). + INST_1x(fstp, kX86InstIdFstp, X86FpReg) + + //! Store x87 FPU control word to `o0` (2 bytes) (FPU). + INST_1x(fstcw, kX86InstIdFstcw, X86Mem) + //! Store x87 FPU environment to `o0` (14 or 28 bytes) (FPU). + INST_1x(fstenv, kX86InstIdFstenv, X86Mem) + //! Store x87 FPU status word to AX (FPU). + INST_1x_(fstsw, kX86InstIdFstsw, X86GpReg, o0.getRegIndex() == kX86RegIndexAx) + //! Store x87 FPU status word (2 bytes) (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86Mem) + + //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU). + INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Subtract fp0 from `o0` and pop FPU stack (FPU). + INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) + //! \overload + INST_0x(fsubp, kX86InstIdFsubp) + + //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU). + INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU). + INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) + //! \overload + INST_0x(fsubrp, kX86InstIdFsubrp) + + //! Floating point test - Compare `fp0` with 0.0. (FPU). + INST_0x(ftst, kX86InstIdFtst) + + //! Unordered compare `fp0` with `o0` (FPU). + INST_1x(fucom, kX86InstIdFucom, X86FpReg) + //! Unordered compare `fp0` with `fp1` (FPU). + INST_0x(fucom, kX86InstIdFucom) + //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS (FPU). + INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) + //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU). + INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) + //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU). + INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU). + INST_0x(fucomp, kX86InstIdFucomp) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU). + INST_0x(fucompp, kX86InstIdFucompp) + + INST_0x(fwait, kX86InstIdFwait) + + //! Examine fp0 (FPU). + INST_0x(fxam, kX86InstIdFxam) + //! Exchange content of fp0 with `o0` (FPU). + INST_1x(fxch, kX86InstIdFxch, X86FpReg) + + //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem) + //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxsave, kX86InstIdFxsave, X86Mem) + //! Extract exponent and store to `fp0` and push significand on the FPU stack (FPU). + INST_0x(fxtract, kX86InstIdFxtract) + + //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2x, kX86InstIdFyl2x) + //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2xp1, kX86InstIdFyl2xp1) + + // -------------------------------------------------------------------------- + // [MMX] + // -------------------------------------------------------------------------- + + //! Move DWORD (MMX). + INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpReg, X86MmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmReg, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmReg, X86GpReg) + + //! Move QWORD (MMX). + INST_2x(movq, kX86InstIdMovq, X86MmReg, X86MmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmReg, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpReg, X86MmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmReg, X86GpReg) + + //! Pack DWORDs to WORDs with signed saturation (MMX). + INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86MmReg) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86MmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (MMX). + INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86MmReg) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86MmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (MMX). + INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86MmReg) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86MmReg, X86Mem) + + //! Packed BYTE add (MMX). + INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86MmReg, X86Mem) + + //! Packed DWORD add (MMX). + INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86MmReg, X86Mem) + + //! Packed BYTE add with saturation (MMX). + INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86MmReg, X86Mem) + + //! Packed WORD add with saturation (MMX). + INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86MmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (MMX). + INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86MmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (MMX). + INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86MmReg, X86Mem) + + //! Packed WORD add (MMX). + INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86MmReg, X86Mem) + + //! Packed bitwise and (MMX). + INST_2x(pand, kX86InstIdPand, X86MmReg, X86MmReg) + //! \overload + INST_2x(pand, kX86InstIdPand, X86MmReg, X86Mem) + + //! Packed bitwise and-not (MMX). + INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86MmReg) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86MmReg, X86Mem) + + //! Packed BYTEs compare for equality (MMX). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmReg, X86Mem) + + //! Packed DWORDs compare for equality (MMX). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmReg, X86Mem) + + //! Packed WORDs compare for equality (MMX). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmReg, X86Mem) + + //! Packed BYTEs compare if greater than (MMX). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmReg, X86Mem) + + //! Packed DWORDs compare if greater than (MMX). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmReg, X86Mem) + + //! Packed WORDs compare if greater than (MMX). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmReg, X86Mem) + + //! Packed WORDs multiply high (MMX). + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmReg, X86Mem) + + //! Packed WORDs multiply low (MMX). + INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86MmReg, X86Mem) + + //! Pakced bitwise or (MMX). + INST_2x(por, kX86InstIdPor, X86MmReg, X86MmReg) + //! \overload + INST_2x(por, kX86InstIdPor, X86MmReg, X86Mem) + + //! Packed WORD multiply and add to packed DWORD (MMX). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmReg, X86Mem) + + //! Packed DWORD shift left logical (MMX). + INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86MmReg) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86MmReg, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86MmReg, Imm) + + //! Packed QWORD shift left logical (MMX). + INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86MmReg) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86MmReg, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86MmReg, Imm) + + //! Packed WORD shift left logical (MMX). + INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86MmReg, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86MmReg, Imm) + + //! Packed DWORD shift right arithmetic (MMX). + INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86MmReg, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86MmReg, Imm) + + //! Packed WORD shift right arithmetic (MMX). + INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86MmReg, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86MmReg, Imm) + + //! Packed DWORD shift right logical (MMX). + INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86MmReg, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86MmReg, Imm) + + //! Packed QWORD shift right logical (MMX). + INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86MmReg, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86MmReg, Imm) + + //! Packed WORD shift right logical (MMX). + INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86MmReg, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86MmReg, Imm) + + //! Packed BYTE subtract (MMX). + INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86MmReg, X86Mem) + + //! Packed DWORD subtract (MMX). + INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86MmReg, X86Mem) + + //! Packed BYTE subtract with saturation (MMX). + INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86MmReg, X86Mem) + + //! Packed WORD subtract with saturation (MMX). + INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86MmReg, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (MMX). + INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86MmReg, X86Mem) + + //! Packed WORD subtract with unsigned saturation (MMX). + INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86MmReg, X86Mem) + + //! Packed WORD subtract (MMX). + INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86MmReg, X86Mem) + + //! Unpack high packed BYTEs to WORDs (MMX). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmReg, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (MMX). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmReg, X86Mem) + + //! Unpack high packed WORDs to DWORDs (MMX). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmReg, X86Mem) + + //! Unpack low packed BYTEs to WORDs (MMX). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmReg, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (MMX). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmReg, X86Mem) + + //! Unpack low packed WORDs to DWORDs (MMX). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86MmReg) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmReg, X86Mem) + + //! Packed bitwise xor (MMX). + INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86MmReg) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86MmReg, X86Mem) + + //! Empty MMX state. + INST_0x(emms, kX86InstIdEmms) + + // ------------------------------------------------------------------------- + // [3dNow] + // ------------------------------------------------------------------------- + + //! Packed SP-FP to DWORD convert (3dNow!). + INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86MmReg) + //! \overload + INST_2x(pf2id, kX86InstIdPf2id, X86MmReg, X86Mem) + + //! Packed SP-FP to WORD convert (3dNow!). + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmReg, X86Mem) + + //! Packed SP-FP accumulate (3dNow!). + INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfacc, kX86InstIdPfacc, X86MmReg, X86Mem) + + //! Packed SP-FP addition (3dNow!). + INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfadd, kX86InstIdPfadd, X86MmReg, X86Mem) + + //! Packed SP-FP compare - dst == src (3dNow!). + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmReg, X86Mem) + + //! Packed SP-FP compare - dst >= src (3dNow!). + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmReg, X86Mem) + + //! Packed SP-FP compare - dst > src (3dNow!). + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmReg, X86Mem) + + //! Packed SP-FP maximum (3dNow!). + INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfmax, kX86InstIdPfmax, X86MmReg, X86Mem) + + //! Packed SP-FP minimum (3dNow!). + INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfmin, kX86InstIdPfmin, X86MmReg, X86Mem) + + //! Packed SP-FP multiply (3dNow!). + INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfmul, kX86InstIdPfmul, X86MmReg, X86Mem) + + //! Packed SP-FP negative accumulate (3dNow!). + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmReg, X86Mem) + + //! Packed SP-FP mixed accumulate (3dNow!). + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal Approximation (3dNow!). + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal, first iteration step (3dNow!). + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal, second iteration step (3dNow!). + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal square root, first iteration step (3dNow!). + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmReg, X86Mem) + + //! Packed SP-FP reciprocal square root approximation (3dNow!). + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmReg, X86Mem) + + //! Packed SP-FP subtract (3dNow!). + INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfsub, kX86InstIdPfsub, X86MmReg, X86Mem) + + //! Packed SP-FP reverse subtract (3dNow!). + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86MmReg) + //! \overload + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmReg, X86Mem) + + //! Packed DWORDs to SP-FP (3dNow!). + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmReg, X86Mem) + + //! Packed WORDs to SP-FP (3dNow!). + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmReg, X86Mem) + + //! Packed swap DWORDs (3dNow!) + INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pswapd, kX86InstIdPswapd, X86MmReg, X86Mem) + + //! Prefetch (3dNow!). + INST_1x(prefetch3dnow, kX86InstIdPrefetch3dNow, X86Mem) + + //! Prefetch and set cache to modified (3dNow!). + INST_1x(prefetchw3dnow, kX86InstIdPrefetchw3dNow, X86Mem) + + //! Faster EMMS (3dNow!). + INST_0x(femms, kX86InstIdFemms) + + // -------------------------------------------------------------------------- + // [SSE] + // -------------------------------------------------------------------------- + + //! Packed SP-FP add (SSE). + INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addps, kX86InstIdAddps, X86XmmReg, X86Mem) + + //! Scalar SP-FP add (SSE). + INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addss, kX86InstIdAddss, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise and-not (SSE). + INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andnps, kX86InstIdAndnps, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise and (SSE). + INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andps, kX86InstIdAndps, X86XmmReg, X86Mem) + + //! Packed SP-FP compare (SSE). + INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmpps, kX86InstIdCmpps, X86XmmReg, X86Mem, Imm) + + //! Compare scalar SP-FP (SSE). + INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmpss, kX86InstIdCmpss, X86XmmReg, X86Mem, Imm) + + //! Scalar ordered SP-FP compare and set EFLAGS (SSE). + INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(comiss, kX86InstIdComiss, X86XmmReg, X86Mem) + + //! Packed signed INT32 to packed SP-FP conversion (SSE). + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86MmReg) + //! \overload + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmReg, X86Mem) + + //! Packed SP-FP to packed INT32 conversion (SSE). + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmReg, X86Mem) + + //! Convert scalar INT32 to SP-FP (SSE). + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86GpReg) + //! \overload + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to INT32 (SSE). + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpReg, X86Mem) + + //! Convert with truncation packed SP-FP to packed INT32 (SSE). + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmReg, X86Mem) + + //! Convert with truncation scalar SP-FP to INT32 (SSE). + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpReg, X86Mem) + + //! Packed SP-FP divide (SSE). + INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divps, kX86InstIdDivps, X86XmmReg, X86Mem) + + //! Scalar SP-FP divide (SSE). + INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divss, kX86InstIdDivss, X86XmmReg, X86Mem) + + //! Load streaming SIMD extension control/status (SSE). + INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem) + + //! Byte mask write to DS:EDI/RDI (SSE). + INST_2x(maskmovq, kX86InstIdMaskmovq, X86MmReg, X86MmReg) + + //! Packed SP-FP maximum (SSE). + INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxps, kX86InstIdMaxps, X86XmmReg, X86Mem) + + //! Scalar SP-FP maximum (SSE). + INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxss, kX86InstIdMaxss, X86XmmReg, X86Mem) + + //! Packed SP-FP minimum (SSE). + INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minps, kX86InstIdMinps, X86XmmReg, X86Mem) + + //! Scalar SP-FP minimum (SSE). + INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minss, kX86InstIdMinss, X86XmmReg, X86Mem) + + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movaps, kX86InstIdMovaps, X86XmmReg, X86Mem) + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmReg) + + //! Move DWORD. + INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpReg, X86XmmReg) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmReg, X86GpReg) + + //! Move QWORD (SSE). + INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpReg, X86XmmReg) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmReg, X86GpReg) + + //! Move QWORD using NT hint (SSE). + INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmReg) + + //! Move high to low packed SP-FP (SSE). + INST_2x(movhlps, kX86InstIdMovhlps, X86XmmReg, X86XmmReg) + + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86XmmReg, X86Mem) + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmReg) + + //! Move low to high packed SP-FP (SSE). + INST_2x(movlhps, kX86InstIdMovlhps, X86XmmReg, X86XmmReg) + + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86XmmReg, X86Mem) + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmReg) + + //! Move aligned packed SP-FP using NT hint (SSE). + INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmReg) + + //! Move scalar SP-FP (SSE). + INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86XmmReg, X86Mem) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmReg) + + //! Move unaligned packed SP-FP (SSE). + INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86XmmReg, X86Mem) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmReg) + + //! Packed SP-FP multiply (SSE). + INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulps, kX86InstIdMulps, X86XmmReg, X86Mem) + + //! Scalar SP-FP multiply (SSE). + INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulss, kX86InstIdMulss, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise or (SSE). + INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(orps, kX86InstIdOrps, X86XmmReg, X86Mem) + + //! Packed BYTE average (SSE). + INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86MmReg, X86Mem) + + //! Packed WORD average (SSE). + INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86MmReg, X86Mem) + + //! Extract WORD based on selector (SSE). + INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86MmReg, Imm) + + //! Insert WORD based on selector (SSE). + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmReg, X86Mem, Imm) + + //! Packed WORD maximum (SSE). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmReg, X86Mem) + + //! Packed BYTE unsigned maximum (SSE). + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmReg, X86Mem) + + //! Packed WORD minimum (SSE). + INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86MmReg, X86Mem) + + //! Packed BYTE unsigned minimum (SSE). + INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86MmReg) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86MmReg, X86Mem) + + //! Move Byte mask to integer (SSE). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86MmReg) + + //! Packed WORD unsigned multiply high (SSE). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmReg, X86Mem) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86MmReg, X86Mem) + + //! Packed WORD shuffle (SSE). + INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86MmReg, Imm) + //! \overload + INST_3i(pshufw, kX86InstIdPshufw, X86MmReg, X86Mem, Imm) + + //! Packed SP-FP reciprocal (SSE). + INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rcpps, kX86InstIdRcpps, X86XmmReg, X86Mem) + + //! Scalar SP-FP reciprocal (SSE). + INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rcpss, kX86InstIdRcpss, X86XmmReg, X86Mem) + + //! Prefetch (SSE). + INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmReg, X86Mem) + + //! Packed SP-FP square root reciprocal (SSE). + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmReg, X86Mem) + + //! Scalar SP-FP square root reciprocal (SSE). + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmReg, X86Mem) + + //! Store fence (SSE). + INST_0x(sfence, kX86InstIdSfence) + + //! Shuffle SP-FP (SSE). + INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(shufps, kX86InstIdShufps, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP square root (SSE). + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmReg, X86Mem) + + //! Scalar SP-FP square root (SSE). + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmReg, X86Mem) + + //! Store streaming SIMD extension control/status (SSE). + INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem) + + //! Packed SP-FP subtract (SSE). + INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subps, kX86InstIdSubps, X86XmmReg, X86Mem) + + //! Scalar SP-FP subtract (SSE). + INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subss, kX86InstIdSubss, X86XmmReg, X86Mem) + + //! Unordered scalar SP-FP compare and set EFLAGS (SSE). + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmReg, X86Mem) + + //! Unpack high packed SP-FP data (SSE). + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmReg, X86Mem) + + //! Unpack low packed SP-FP data (SSE). + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmReg, X86Mem) + + //! Packed SP-FP bitwise xor (SSE). + INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(xorps, kX86InstIdXorps, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE2] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add (SSE2). + INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addpd, kX86InstIdAddpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP add (SSE2). + INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addsd, kX86InstIdAddsd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise and-not (SSE2). + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise and (SSE2). + INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(andpd, kX86InstIdAndpd, X86XmmReg, X86Mem) + + //! Flush cache line (SSE2). + INST_1x(clflush, kX86InstIdClflush, X86Mem) + + //! Packed DP-FP compare (SSE2). + INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmppd, kX86InstIdCmppd, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP compare (SSE2). + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmReg, X86Mem, Imm) + + //! Scalar ordered DP-FP compare and set EFLAGS (SSE2). + INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(comisd, kX86InstIdComisd, X86XmmReg, X86Mem) + + //! Convert packed QWORDs to packed DP-FP (SSE2). + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmReg, X86Mem) + + //! Convert packed QWORDs to packed SP-FP (SSE2). + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86Mem) + + //! Convert packed DP-FP to packed QWORDs (SSE2). + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86Mem) + + //! Convert packed DP-FP to packed QRODSs (SSE2). + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86Mem) + + //! Convert packed DP-FP to packed SP-FP (SSE2). + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmReg, X86Mem) + + //! Convert packed DWORDs integers to packed DP-FP (SSE2). + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86MmReg) + //! \overload + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86Mem) + + //! Convert packed SP-FP to packed QWORDs (SSE2). + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86Mem) + + //! Convert packed SP-FP to packed DP-FP (SSE2). + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmReg, X86Mem) + + //! Convert scalar DP-FP to DWORD integer (SSE2). + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpReg, X86Mem) + + //! Convert scalar DP-FP to scalar SP-FP (SSE2). + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmReg, X86Mem) + + //! Convert DWORD integer to scalar DP-FP (SSE2). + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86GpReg) + //! \overload + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to DP-FP (SSE2). + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmReg, X86Mem) + + //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86XmmReg) + //! \overload + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86Mem) + + //! Convert with truncation packed DP-FP to packed QWORDs (SSE2). + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86Mem) + + //! Convert with truncation packed SP-FP to packed QWORDs (SSE2). + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86Mem) + + //! Convert with truncation scalar DP-FP to signed DWORDs (SSE2). + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpReg, X86Mem) + + //! Packed DP-FP divide (SSE2). + INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divpd, kX86InstIdDivpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP divide (SSE2). + INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(divsd, kX86InstIdDivsd, X86XmmReg, X86Mem) + + //! Load fence (SSE2). + INST_0x(lfence, kX86InstIdLfence) + + //! Store selected bytes of OWORD to DS:EDI/RDI (SSE2). + INST_2x(maskmovdqu, kX86InstIdMaskmovdqu, X86XmmReg, X86XmmReg) + + //! Packed DP-FP maximum (SSE2). + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP maximum (SSE2). + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmReg, X86Mem) + + //! Memory fence (SSE2). + INST_0x(mfence, kX86InstIdMfence) + + //! Packed DP-FP minimum (SSE2). + INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minpd, kX86InstIdMinpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP minimum (SSE2). + INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(minsd, kX86InstIdMinsd, X86XmmReg, X86Mem) + + //! Move aligned OWORD (SSE2). + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmReg, X86Mem) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmReg) + + //! Move unaligned OWORD (SSE2). + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmReg, X86Mem) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmReg) + + //! Extract packed SP-FP sign mask (SSE2). + INST_2x(movmskps, kX86InstIdMovmskps, X86GpReg, X86XmmReg) + + //! Extract packed DP-FP sign mask (SSE2). + INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpReg, X86XmmReg) + + //! Move scalar DP-FP (SSE2). + INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmReg) + + //! Move aligned packed DP-FP (SSE2). + INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmReg) + + //! Move QWORD from Xmm to Mm register (SSE2). + INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmReg, X86XmmReg) + + //! Move QWORD from Mm to Xmm register (SSE2). + INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmReg, X86MmReg) + + //! Move high packed DP-FP (SSE2). + INST_2x(movhpd, kX86InstIdMovhpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmReg) + + //! Move low packed DP-FP (SSE2). + INST_2x(movlpd, kX86InstIdMovlpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmReg) + + //! Store OWORD using NT hint (SSE2). + INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmReg) + + //! Store DWORD using NT hint (SSE2). + INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpReg) + + //! Store packed DP-FP using NT hint (SSE2). + INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmReg) + + //! Move unaligned packed DP-FP (SSE2). + INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86XmmReg, X86Mem) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmReg) + + //! Packed DP-FP multiply (SSE2). + INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulpd, kX86InstIdMulpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP multiply (SSE2). + INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(mulsd, kX86InstIdMulsd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise or (SSE2). + INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(orpd, kX86InstIdOrpd, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (SSE2). + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmReg, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (SSE2). + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (SSE2). + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmReg, X86Mem) + + //! Packed BYTE Add (SSE2). + INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86XmmReg, X86Mem) + + //! Packed WORD add (SSE2). + INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86XmmReg, X86Mem) + + //! Packed DWORD add (SSE2). + INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86XmmReg, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86MmReg) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86MmReg, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86XmmReg, X86Mem) + + //! Packed BYTE add with saturation (SSE2). + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmReg, X86Mem) + + //! Packed WORD add with saturation (SSE2). + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (SSE2). + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (SSE2). + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmReg, X86Mem) + + //! Packed bitwise and (SSE2). + INST_2x(pand, kX86InstIdPand, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pand, kX86InstIdPand, X86XmmReg, X86Mem) + + //! Packed bitwise and-not (SSE2). + INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86XmmReg, X86Mem) + + //! Spin loop hint (SSE2). + INST_0x(pause, kX86InstIdPause) + + //! Packed BYTE average (SSE2). + INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86XmmReg, X86Mem) + + //! Packed WORD average (SSE2). + INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86XmmReg, X86Mem) + + //! Packed BYTE compare for equality (SSE2). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmReg, X86Mem) + + //! Packed WORD compare for equality (SSE2). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmReg, X86Mem) + + //! Packed DWORD compare for equality (SSE2). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmReg, X86Mem) + + //! Packed BYTE compare if greater than (SSE2). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmReg, X86Mem) + + //! Packed WORD compare if greater than (SSE2). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmReg, X86Mem) + + //! Packed DWORD compare if greater than (SSE2). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmReg, X86Mem) + + //! Extract WORD based on selector (SSE2). + INST_3i(pextrw, kX86InstIdPextrw, X86GpReg, X86XmmReg, Imm) + + //! Insert WORD based on selector (SSE2). + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmReg, X86Mem, Imm) + + //! Packed WORD maximum (SSE2). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned maximum (SSE2). + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmReg, X86Mem) + + //! Packed WORD minimum (SSE2). + INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned minimum (SSE2). + INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86XmmReg, X86Mem) + + //! Move byte mask (SSE2). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpReg, X86XmmReg) + + //! Packed WORD multiply high (SSE2). + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmReg, X86Mem) + + //! Packed WORD unsigned multiply high (SSE2). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmReg, X86Mem) + + //! Packed WORD multiply low (SSE2). + INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86XmmReg, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmReg, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmReg, X86Mem) + + //! Packed bitwise or (SSE2). + INST_2x(por, kX86InstIdPor, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(por, kX86InstIdPor, X86XmmReg, X86Mem) + + //! Packed DWORD shift left logical (SSE2). + INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86XmmReg, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86XmmReg, Imm) + + //! Packed QWORD shift left logical (SSE2). + INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86XmmReg, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86XmmReg, Imm) + + //! Packed WORD shift left logical (SSE2). + INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86XmmReg, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86XmmReg, Imm) + + //! Packed OWORD shift left logical (SSE2). + INST_2i(pslldq, kX86InstIdPslldq, X86XmmReg, Imm) + + //! Packed DWORD shift right arithmetic (SSE2). + INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86XmmReg, Imm) + + //! Packed WORD shift right arithmetic (SSE2). + INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86XmmReg, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86XmmReg, Imm) + + //! Packed BYTE subtract (SSE2). + INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86XmmReg, X86Mem) + + //! Packed DWORD subtract (SSE2). + INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86XmmReg, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86MmReg) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86MmReg, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86XmmReg, X86Mem) + + //! Packed WORD subtract (SSE2). + INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD multiply and add (SSE2). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmReg, X86Mem) + + //! Packed DWORD shuffle (SSE2). + INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pshufd, kX86InstIdPshufd, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle high (SSE2). + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle low (SSE2). + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmReg, X86Mem, Imm) + + //! Packed DWORD shift right logical (SSE2). + INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86XmmReg, Imm) + + //! Packed QWORD shift right logical (SSE2). + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86XmmReg, Imm) + + //! Scalar OWORD shift right logical (SSE2). + INST_2i(psrldq, kX86InstIdPsrldq, X86XmmReg, Imm) + + //! Packed WORD shift right logical (SSE2). + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmReg, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86XmmReg, Imm) + + //! Packed BYTE subtract with saturation (SSE2). + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmReg, X86Mem) + + //! Packed WORD subtract with saturation (SSE2). + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmReg, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (SSE2). + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmReg, X86Mem) + + //! Packed WORD subtract with unsigned saturation (SSE2). + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmReg, X86Mem) + + //! Unpack high packed BYTEs to WORDs (SSE2). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmReg, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (SSE2). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmReg, X86Mem) + + //! Unpack high packed QWORDs to OWORD (SSE2). + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmReg, X86Mem) + + //! Unpack high packed WORDs to DWORDs (SSE2). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmReg, X86Mem) + + //! Unpack low packed BYTEs to WORDs (SSE2). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmReg, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (SSE2). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmReg, X86Mem) + + //! Unpack low packed QWORDs to OWORD (SSE2). + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmReg, X86Mem) + + //! Unpack low packed WORDs to DWORDs (SSE2). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmReg, X86Mem) + + //! Packed bitwise xor (SSE2). + INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86XmmReg, X86Mem) + + //! Shuffle DP-FP (SSE2). + INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(shufpd, kX86InstIdShufpd, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP square root (SSE2). + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP square root (SSE2). + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmReg, X86Mem) + + //! Packed DP-FP subtract (SSE2). + INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subpd, kX86InstIdSubpd, X86XmmReg, X86Mem) + + //! Scalar DP-FP subtract (SSE2). + INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(subsd, kX86InstIdSubsd, X86XmmReg, X86Mem) + + //! Scalar DP-FP unordered compare and set EFLAGS (SSE2). + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmReg, X86Mem) + + //! Unpack and interleave high packed DP-FP (SSE2). + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmReg, X86Mem) + + //! Unpack and interleave low packed DP-FP (SSE2). + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise xor (SSE2). + INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(xorpd, kX86InstIdXorpd, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE3] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add/subtract (SSE3). + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmReg, X86Mem) + + //! Packed SP-FP add/subtract (SSE3). + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86Mem) + + //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop + //! the FPU stack (FPU / SSE3). + INST_1x(fisttp, kX86InstIdFisttp, X86Mem) + + //! Packed DP-FP horizontal add (SSE3). + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmReg, X86Mem) + + //! Packed SP-FP horizontal add (SSE3). + INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(haddps, kX86InstIdHaddps, X86XmmReg, X86Mem) + + //! Packed DP-FP horizontal subtract (SSE3). + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmReg, X86Mem) + + //! Packed SP-FP horizontal subtract (SSE3). + INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(hsubps, kX86InstIdHsubps, X86XmmReg, X86Mem) + + //! Load 128-bits unaligned (SSE3). + INST_2x(lddqu, kX86InstIdLddqu, X86XmmReg, X86Mem) + + //! Setup monitor address (SSE3). + INST_0x(monitor, kX86InstIdMonitor) + + //! Move one DP-FP and duplicate (SSE3). + INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movddup, kX86InstIdMovddup, X86XmmReg, X86Mem) + + //! Move packed SP-FP high and duplicate (SSE3). + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmReg, X86Mem) + + //! Move packed SP-FP low and duplicate (SSE3). + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmReg, X86Mem) + + //! Monitor wait (SSE3). + INST_0x(mwait, kX86InstIdMwait) + + // -------------------------------------------------------------------------- + // [SSSE3] + // -------------------------------------------------------------------------- + + //! Packed BYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86MmReg) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86MmReg, X86Mem) + + //! Packed BYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86XmmReg, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86MmReg) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86MmReg, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86XmmReg, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86MmReg) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86MmReg, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86XmmReg, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86MmReg) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86MmReg, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmReg, X86Mem) + + //! Packed WORD horizontal add with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86MmReg, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmReg, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86MmReg) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86MmReg, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmReg, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86MmReg) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86MmReg, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmReg, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmReg, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmReg, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86MmReg, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86XmmReg, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86MmReg) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86MmReg, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86XmmReg, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86MmReg, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86XmmReg, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86MmReg) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmReg, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmReg, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86MmReg) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86MmReg, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86XmmReg, X86Mem) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86MmReg, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86MmReg, X86Mem, Imm) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.1] + // -------------------------------------------------------------------------- + + //! Packed DP-FP blend (SSE4.1). + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP blend (SSE4.1). + INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(blendps, kX86InstIdBlendps, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP variable blend (SSE4.1). + INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(blendvpd, kX86InstIdBlendvpd, X86XmmReg, X86Mem) + + //! Packed SP-FP variable blend (SSE4.1). + INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(blendvps, kX86InstIdBlendvps, X86XmmReg, X86Mem) + + //! Packed DP-FP dot product (SSE4.1). + INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(dppd, kX86InstIdDppd, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP dot product (SSE4.1). + INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(dpps, kX86InstIdDpps, X86XmmReg, X86Mem, Imm) + + //! Extract SP-FP based on selector (SSE4.1). + INST_3i(extractps, kX86InstIdExtractps, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmReg, Imm) + + //! Insert SP-FP based on selector (SSE4.1). + INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(insertps, kX86InstIdInsertps, X86XmmReg, X86Mem, Imm) + + //! Load OWORD aligned using NT hint (SSE4.1). + INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmReg, X86Mem) + + //! Packed WORD sums of absolute difference (SSE4.1). + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmReg, X86Mem, Imm) + + //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1). + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmReg, X86Mem) + + //! Packed BYTE variable blend (SSE4.1). + INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pblendvb, kX86InstIdPblendvb, X86XmmReg, X86Mem) + + //! Packed WORD blend (SSE4.1). + INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pblendw, kX86InstIdPblendw, X86XmmReg, X86Mem, Imm) + + //! Packed QWORD compare for equality (SSE4.1). + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmReg, X86Mem) + + //! Extract BYTE based on selector (SSE4.1). + INST_3i(pextrb, kX86InstIdPextrb, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmReg, Imm) + + //! Extract DWORD based on selector (SSE4.1). + INST_3i(pextrd, kX86InstIdPextrd, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmReg, Imm) + + //! Extract QWORD based on selector (SSE4.1). + INST_3i(pextrq, kX86InstIdPextrq, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmReg, Imm) + + //! Extract WORD based on selector (SSE4.1). + INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmReg, Imm) + + //! Packed WORD horizontal minimum (SSE4.1). + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmReg, X86Mem) + + //! Insert BYTE based on selector (SSE4.1). + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmReg, X86Mem, Imm) + + //! Insert DWORD based on selector (SSE4.1). + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmReg, X86Mem, Imm) + + //! Insert QWORD based on selector (SSE4.1). + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmReg, X86Mem, Imm) + + //! Packed BYTE maximum (SSE4.1). + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmReg, X86Mem) + + //! Packed DWORD maximum (SSE4.1). + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned maximum (SSE4.1). + INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmReg, X86Mem) + + //! Packed WORD unsigned maximum (SSE4.1). + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmReg, X86Mem) + + //! Packed BYTE minimum (SSE4.1). + INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminsb, kX86InstIdPminsb, X86XmmReg, X86Mem) + + //! Packed DWORD minimum (SSE4.1). + INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminsd, kX86InstIdPminsd, X86XmmReg, X86Mem) + + //! Packed WORD unsigned minimum (SSE4.1). + INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminuw, kX86InstIdPminuw, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned minimum (SSE4.1). + INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pminud, kX86InstIdPminud, X86XmmReg, X86Mem) + + //! BYTE to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmReg, X86Mem) + + //! Packed BYTE to WORD with sign extend (SSE4.1). + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmReg, X86Mem) + + //! BYTE to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmReg, X86Mem) + + //! BYTE to WORD with zero extend (SSE4.1). + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD multiply (SSE4.1). + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmReg, X86Mem) + + //! Packed DWORD multiply low (SSE4.1). + INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pmulld, kX86InstIdPmulld, X86XmmReg, X86Mem) + + //! Logical compare (SSE4.1). + INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(ptest, kX86InstIdPtest, X86XmmReg, X86Mem) + + //! Packed DP-FP round (SSE4.1). + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP round (SSE4.1). + INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundps, kX86InstIdRoundps, X86XmmReg, X86Mem, Imm) + + //! Scalar DP-FP round (SSE4.1). + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP round (SSE4.1). + INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(roundss, kX86InstIdRoundss, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.2] + // -------------------------------------------------------------------------- + + //! Packed compare explicit length strings, return index (SSE4.2). + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86Mem, Imm) + + //! Packed compare explicit length strings, return mask (SSE4.2). + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return index (SSE4.2). + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return mask (SSE4.2). + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmReg, X86Mem, Imm) + + //! Packed QWORD compare if greater than (SSE4.2). + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [AESNI] + // -------------------------------------------------------------------------- + + //! Perform a single round of the AES decryption flow (AESNI). + INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesdec, kX86InstIdAesdec, X86XmmReg, X86Mem) + + //! Perform the last round of the AES decryption flow (AESNI). + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmReg, X86Mem) + + //! Perform a single round of the AES encryption flow (AESNI). + INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesenc, kX86InstIdAesenc, X86XmmReg, X86Mem) + + //! Perform the last round of the AES encryption flow (AESNI). + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmReg, X86Mem) + + //! Perform the InvMixColumns transformation (AESNI). + INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(aesimc, kX86InstIdAesimc, X86XmmReg, X86Mem) + + //! Assist in expanding the AES cipher key (AESNI). + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [PCLMULQDQ] + // -------------------------------------------------------------------------- + + //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ). + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [AVX] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add (AVX). + INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddpd, kX86InstIdVaddpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddpd, kX86InstIdVaddpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP add (AVX). + INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddps, kX86InstIdVaddps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddps, kX86InstIdVaddps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP add (AVX) + INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddsd, kX86InstIdVaddsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP add (AVX) + INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddss, kX86InstIdVaddss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP add/subtract (AVX). + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddsubpd, kX86InstIdVaddsubpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP add/subtract (AVX). + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vaddsubps, kX86InstIdVaddsubps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP bitwise and (AVX). + INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandpd, kX86InstIdVandpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandpd, kX86InstIdVandpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise and (AVX). + INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandps, kX86InstIdVandps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandps, kX86InstIdVandps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP bitwise and-not (AVX). + INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandnpd, kX86InstIdVandnpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandnpd, kX86InstIdVandnpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise and-not (AVX). + INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vandnps, kX86InstIdVandnps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vandnps, kX86InstIdVandnps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP blend (AVX). + INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vblendpd, kX86InstIdVblendpd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vblendpd, kX86InstIdVblendpd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP blend (AVX). + INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vblendps, kX86InstIdVblendps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vblendps, kX86InstIdVblendps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DP-FP variable blend (AVX). + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_4x(vblendvpd, kX86InstIdVblendvpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + + //! Packed SP-FP variable blend (AVX). + INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_4x(vblendvps, kX86InstIdVblendvps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_4x(vblendvps, kX86InstIdVblendvps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_4x(vblendvps, kX86InstIdVblendvps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + + //! Broadcast 128-bits of FP data in `o1` to low and high 128-bits in `o0` (AVX). + INST_2x(vbroadcastf128, kX86InstIdVbroadcastf128, X86YmmReg, X86Mem) + //! Broadcast DP-FP element in `o1` to four locations in `o0` (AVX). + INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86Mem) + //! Broadcast SP-FP element in `o1` to four locations in `o0` (AVX). + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86Mem) + //! Broadcast SP-FP element in `o1` to eight locations in `o0` (AVX). + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86Mem) + + //! Packed DP-FP compare (AVX). + INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmppd, kX86InstIdVcmppd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vcmppd, kX86InstIdVcmppd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP compare (AVX). + INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmpps, kX86InstIdVcmpps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vcmpps, kX86InstIdVcmpps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Scalar DP-FP compare (AVX). + INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmpsd, kX86InstIdVcmpsd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP compare (AVX). + INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vcmpss, kX86InstIdVcmpss, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Scalar DP-FP ordered compare and set EFLAGS (AVX). + INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcomisd, kX86InstIdVcomisd, X86XmmReg, X86Mem) + + //! Scalar SP-FP ordered compare and set EFLAGS (AVX). + INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcomiss, kX86InstIdVcomiss, X86XmmReg, X86Mem) + + //! Convert packed QWORDs to packed DP-FP (AVX). + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtdq2pd, kX86InstIdVcvtdq2pd, X86YmmReg, X86Mem) + + //! Convert packed QWORDs to packed SP-FP (AVX). + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86Mem) + + //! Convert packed DP-FP to packed QWORDs (AVX). + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86Mem) + + //! Convert packed DP-FP to packed SP-FP (AVX). + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86Mem) + + //! Convert packed SP-FP to packed QWORDs (AVX). + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86YmmReg, X86Mem) + + //! Convert packed SP-FP to packed DP-FP (AVX). + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtps2pd, kX86InstIdVcvtps2pd, X86YmmReg, X86Mem) + + //! Convert scalar DP-FP to DWORD (AVX). + INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvtsd2si, kX86InstIdVcvtsd2si, X86GpReg, X86Mem) + + //! Convert scalar DP-FP to scalar SP-FP (AVX). + INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vcvtsd2ss, kX86InstIdVcvtsd2ss, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert DWORD integer to scalar DP-FP (AVX). + INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86GpReg) + //! \overload + INST_3x(vcvtsi2sd, kX86InstIdVcvtsi2sd, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert scalar INT32 to SP-FP (AVX). + INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86GpReg) + //! \overload + INST_3x(vcvtsi2ss, kX86InstIdVcvtsi2ss, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to DP-FP (AVX). + INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vcvtss2sd, kX86InstIdVcvtss2sd, X86XmmReg, X86XmmReg, X86Mem) + + //! Convert scalar SP-FP to INT32 (AVX). + INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86Mem) + + //! Convert with truncation packed DP-FP to packed QWORDs (AVX). + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86YmmReg) + //! \overload + INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86Mem) + + //! Convert with truncation packed SP-FP to packed QWORDs (AVX). + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86Mem) + + //! Convert with truncation scalar DP-FP to DWORD (AVX). + INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86Mem) + + //! Convert with truncation scalar SP-FP to INT32 (AVX). + INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vcvttss2si, kX86InstIdVcvttss2si, X86GpReg, X86Mem) + + //! Packed DP-FP divide (AVX). + INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivpd, kX86InstIdVdivpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vdivpd, kX86InstIdVdivpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP divide (AVX). + INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivps, kX86InstIdVdivps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vdivps, kX86InstIdVdivps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP divide (AVX). + INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivsd, kX86InstIdVdivsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP divide (AVX). + INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vdivss, kX86InstIdVdivss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP dot product (AVX). + INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vdppd, kX86InstIdVdppd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed SP-FP dot product (AVX). + INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vdpps, kX86InstIdVdpps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vdpps, kX86InstIdVdpps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vdpps, kX86InstIdVdpps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Extract 128 bits of packed FP data from `o1` and store results in `o0` (AVX). + INST_3i(vextractf128, kX86InstIdVextractf128, X86XmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vextractf128, kX86InstIdVextractf128, X86Mem, X86YmmReg, Imm) + + //! Extract SP-FP based on selector (AVX). + INST_3i(vextractps, kX86InstIdVextractps, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vextractps, kX86InstIdVextractps, X86Mem, X86XmmReg, Imm) + + //! Packed DP-FP horizontal add (AVX). + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhaddpd, kX86InstIdVhaddpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP horizontal add (AVX). + INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhaddps, kX86InstIdVhaddps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhaddps, kX86InstIdVhaddps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP horizontal subtract (AVX). + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhsubpd, kX86InstIdVhsubpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP horizontal subtract (AVX). + INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vhsubps, kX86InstIdVhsubps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vhsubps, kX86InstIdVhsubps, X86YmmReg, X86YmmReg, X86Mem) + + //! Insert 128-bit of packed FP data based on selector (AVX). + INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vinsertf128, kX86InstIdVinsertf128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Insert SP-FP based on selector (AVX). + INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vinsertps, kX86InstIdVinsertps, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Load 128-bits unaligned (AVX). + INST_2x(vlddqu, kX86InstIdVlddqu, X86XmmReg, X86Mem) + //! Load 256-bits unaligned (AVX). + INST_2x(vlddqu, kX86InstIdVlddqu, X86YmmReg, X86Mem) + + //! Load streaming SIMD extension control/status (AVX). + INST_1x(vldmxcsr, kX86InstIdVldmxcsr, X86Mem) + + //! Store selected bytes of OWORD to DS:EDI/RDI (AVX). + INST_2x(vmaskmovdqu, kX86InstIdVmaskmovdqu, X86XmmReg, X86XmmReg) + + //! Conditionally load packed DP-FP from `o2` using mask in `o1 and store in `o0` (AVX). + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86Mem, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaskmovpd, kX86InstIdVmaskmovpd, X86Mem, X86YmmReg, X86YmmReg) + + //! Conditionally load packed SP-FP from `o2` using mask in `o1 and store in `o0` (AVX). + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaskmovps, kX86InstIdVmaskmovps, X86Mem, X86YmmReg, X86YmmReg) + + //! Packed DP-FP maximum (AVX). + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmaxpd, kX86InstIdVmaxpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP maximum (AVX). + INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxps, kX86InstIdVmaxps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmaxps, kX86InstIdVmaxps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP maximum (AVX). + INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxsd, kX86InstIdVmaxsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP maximum (AVX). + INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmaxss, kX86InstIdVmaxss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP minimum (AVX). + INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminpd, kX86InstIdVminpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vminpd, kX86InstIdVminpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP minimum (AVX). + INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminps, kX86InstIdVminps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vminps, kX86InstIdVminps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP minimum (AVX). + INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminsd, kX86InstIdVminsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP minimum (AVX). + INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vminss, kX86InstIdVminss, X86XmmReg, X86XmmReg, X86Mem) + + //! Move 128-bits of aligned packed DP-FP (AVX). + INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86XmmReg) + //! Move 256-bits of aligned packed DP-FP (AVX). + INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovapd, kX86InstIdVmovapd, X86Mem, X86YmmReg) + + //! Move 128-bits of aligned packed SP-FP (AVX). + INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86XmmReg) + //! Move 256-bits of aligned packed SP-FP (AVX). + INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovaps, kX86InstIdVmovaps, X86Mem, X86YmmReg) + + //! Move DWORD (AVX). + INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86GpReg) + //! \overload + INST_2x(vmovd, kX86InstIdVmovd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovd, kX86InstIdVmovd, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vmovd, kX86InstIdVmovd, X86Mem, X86XmmReg) + + //! Move QWORD (AVX). + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovq, kX86InstIdVmovq, X86Mem, X86XmmReg) + + //! Move QWORD (AVX and X64 Only). + INST_2x(vmovq, kX86InstIdVmovq, X86XmmReg, X86GpReg) + //! \overload + INST_2x(vmovq, kX86InstIdVmovq, X86GpReg, X86XmmReg) + + //! Move one DP-FP and duplicate (AVX). + INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovddup, kX86InstIdVmovddup, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovddup, kX86InstIdVmovddup, X86YmmReg, X86Mem) + + //! Move 128-bits aligned (AVX). + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86XmmReg) + //! Move 256-bits aligned (AVX). + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovdqa, kX86InstIdVmovdqa, X86Mem, X86YmmReg) + + //! Move 128-bits unaligned (AVX). + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86XmmReg) + //! Move 256-bits unaligned (AVX). + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovdqu, kX86InstIdVmovdqu, X86Mem, X86YmmReg) + + //! High to low packed SP-FP (AVX). + INST_3x(vmovhlps, kX86InstIdVmovhlps, X86XmmReg, X86XmmReg, X86XmmReg) + + //! Move high packed DP-FP (AVX). + INST_3x(vmovhpd, kX86InstIdVmovhpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovhpd, kX86InstIdVmovhpd, X86Mem, X86XmmReg) + + //! Move high packed SP-FP (AVX). + INST_3x(vmovhps, kX86InstIdVmovhps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovhps, kX86InstIdVmovhps, X86Mem, X86XmmReg) + + //! Move low to high packed SP-FP (AVX). + INST_3x(vmovlhps, kX86InstIdVmovlhps, X86XmmReg, X86XmmReg, X86XmmReg) + + //! Move low packed DP-FP (AVX). + INST_3x(vmovlpd, kX86InstIdVmovlpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovlpd, kX86InstIdVmovlpd, X86Mem, X86XmmReg) + + //! Move low packed SP-FP (AVX). + INST_3x(vmovlps, kX86InstIdVmovlps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovlps, kX86InstIdVmovlps, X86Mem, X86XmmReg) + + //! Extract packed DP-FP sign mask (AVX). + INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vmovmskpd, kX86InstIdVmovmskpd, X86GpReg, X86YmmReg) + + //! Extract packed SP-FP sign mask (AVX). + INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86XmmReg) + //! \overload + INST_2x(vmovmskps, kX86InstIdVmovmskps, X86GpReg, X86YmmReg) + + //! Store 128-bits using NT hint (AVX). + INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86XmmReg) + //! Store 256-bits using NT hint (AVX). + INST_2x(vmovntdq, kX86InstIdVmovntdq, X86Mem, X86YmmReg) + + //! Store 128-bits aligned using NT hint (AVX). + INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86XmmReg, X86Mem) + + //! Store packed DP-FP (128-bits) using NT hint (AVX). + INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86XmmReg) + //! Store packed DP-FP (256-bits) using NT hint (AVX). + INST_2x(vmovntpd, kX86InstIdVmovntpd, X86Mem, X86YmmReg) + + //! Store packed SP-FP (128-bits) using NT hint (AVX). + INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86XmmReg) + //! Store packed SP-FP (256-bits) using NT hint (AVX). + INST_2x(vmovntps, kX86InstIdVmovntps, X86Mem, X86YmmReg) + + //! Move scalar DP-FP (AVX). + INST_3x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovsd, kX86InstIdVmovsd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovsd, kX86InstIdVmovsd, X86Mem, X86XmmReg) + + //! Move packed SP-FP high and duplicate (AVX). + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovshdup, kX86InstIdVmovshdup, X86YmmReg, X86Mem) + + //! Move packed SP-FP low and duplicate (AVX). + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovsldup, kX86InstIdVmovsldup, X86YmmReg, X86Mem) + + //! Move scalar SP-FP (AVX). + INST_3x(vmovss, kX86InstIdVmovss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovss, kX86InstIdVmovss, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovss, kX86InstIdVmovss, X86Mem, X86XmmReg) + + //! Move 128-bits of unaligned packed DP-FP (AVX). + INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86XmmReg) + //! Move 256-bits of unaligned packed DP-FP (AVX). + INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovupd, kX86InstIdVmovupd, X86Mem, X86YmmReg) + + //! Move 128-bits of unaligned packed SP-FP (AVX). + INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86XmmReg, X86Mem) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86XmmReg) + //! Move 256-bits of unaligned packed SP-FP (AVX). + INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86YmmReg, X86Mem) + //! \overload + INST_2x(vmovups, kX86InstIdVmovups, X86Mem, X86YmmReg) + + //! Packed WORD sums of absolute difference (AVX). + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP multiply (AVX). + INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulpd, kX86InstIdVmulpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmulpd, kX86InstIdVmulpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP multiply (AVX). + INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulps, kX86InstIdVmulps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vmulps, kX86InstIdVmulps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP multiply (AVX). + INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulsd, kX86InstIdVmulsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP multiply (AVX). + INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vmulss, kX86InstIdVmulss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP bitwise or (AVX). + INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vorpd, kX86InstIdVorpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vorpd, kX86InstIdVorpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise or (AVX). + INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vorps, kX86InstIdVorps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vorps, kX86InstIdVorps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE absolute value (AVX). + INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpabsb, kX86InstIdVpabsb, X86XmmReg, X86Mem) + + //! Packed DWORD absolute value (AVX). + INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpabsd, kX86InstIdVpabsd, X86XmmReg, X86Mem) + + //! Packed WORD absolute value (AVX). + INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpabsw, kX86InstIdVpabsw, X86XmmReg, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (AVX). + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86XmmReg, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (AVX). + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86XmmReg, X86XmmReg, X86Mem) + + //! Pack DWORDs to WORDs with unsigned saturation (AVX). + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86XmmReg, X86XmmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (AVX). + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE add (AVX). + INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddb, kX86InstIdVpaddb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD add (AVX). + INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddd, kX86InstIdVpaddd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORD add (AVX). + INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddq, kX86InstIdVpaddq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD add (AVX). + INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddw, kX86InstIdVpaddw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE add with saturation (AVX). + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD add with saturation (AVX). + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (AVX). + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (AVX). + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed align right (AVX). + INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpalignr, kX86InstIdVpalignr, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed bitwise and (AVX). + INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpand, kX86InstIdVpand, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed bitwise and-not (AVX). + INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpandn, kX86InstIdVpandn, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE average (AVX). + INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpavgb, kX86InstIdVpavgb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD average (AVX). + INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpavgw, kX86InstIdVpavgw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE variable blend (AVX). + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + //! Packed WORD blend (AVX). + INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpblendw, kX86InstIdVpblendw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed BYTEs compare for equality (AVX). + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORDs compare for equality (AVX). + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORDs compare for equality (AVX). + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORDs compare for equality (AVX). + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTEs compare if greater than (AVX). + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORDs compare if greater than (AVX). + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORDs compare if greater than (AVX). + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORDs compare if greater than (AVX). + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed compare explicit length strings, return index (AVX). + INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpestri, kX86InstIdVpcmpestri, X86XmmReg, X86Mem, Imm) + + //! Packed compare explicit length strings, return mask (AVX). + INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpestrm, kX86InstIdVpcmpestrm, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return index (AVX). + INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpistri, kX86InstIdVpcmpistri, X86XmmReg, X86Mem, Imm) + + //! Packed compare implicit length strings, return mask (AVX). + INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpcmpistrm, kX86InstIdVpcmpistrm, X86XmmReg, X86Mem, Imm) + + //! Packed DP-FP permute (AVX). + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermilpd, kX86InstIdVpermilpd, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP permute (AVX). + INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermilps, kX86InstIdVpermilps, X86YmmReg, X86Mem, Imm) + + //! Packed 128-bit FP permute (AVX). + INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vperm2f128, kX86InstIdVperm2f128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Extract BYTE (AVX). + INST_3i(vpextrb, kX86InstIdVpextrb, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrb, kX86InstIdVpextrb, X86Mem, X86XmmReg, Imm) + + //! Extract DWORD (AVX). + INST_3i(vpextrd, kX86InstIdVpextrd, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrd, kX86InstIdVpextrd, X86Mem, X86XmmReg, Imm) + + //! Extract QWORD (AVX and X64 Only). + INST_3i(vpextrq, kX86InstIdVpextrq, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrq, kX86InstIdVpextrq, X86Mem, X86XmmReg, Imm) + + //! Extract WORD (AVX). + INST_3i(vpextrw, kX86InstIdVpextrw, X86GpReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpextrw, kX86InstIdVpextrw, X86Mem, X86XmmReg, Imm) + + //! Packed DWORD horizontal add (AVX). + INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphaddd, kX86InstIdVphaddd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add with saturation (AVX). + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal add (AVX). + INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphaddw, kX86InstIdVphaddw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal minimum (AVX). + INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vphminposuw, kX86InstIdVphminposuw, X86XmmReg, X86Mem) + + //! Packed DWORD horizontal subtract (AVX). + INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphsubd, kX86InstIdVphsubd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract with saturation (AVX). + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD horizontal subtract (AVX). + INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vphsubw, kX86InstIdVphsubw, X86XmmReg, X86XmmReg, X86Mem) + + //! Insert BYTE based on selector (AVX). + INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrb, kX86InstIdVpinsrb, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Insert DWORD based on selector (AVX). + INST_4i(vpinsrd, kX86InstIdVpinsrd, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrd, kX86InstIdVpinsrd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Insert QWORD based on selector (AVX and X64 Only). + INST_4i(vpinsrq, kX86InstIdVpinsrq, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrq, kX86InstIdVpinsrq, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Insert WORD based on selector (AVX). + INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86GpReg, Imm) + //! \overload + INST_4i(vpinsrw, kX86InstIdVpinsrw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Packed multiply and add signed and unsigned bytes (AVX). + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD multiply and add to packed DWORD (AVX). + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE maximum (AVX). + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD maximum (AVX). + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD maximum (AVX). + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned maximum (AVX). + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned maximum (AVX). + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD unsigned maximum (AVX). + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE minimum (AVX). + INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminsb, kX86InstIdVpminsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD minimum (AVX). + INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminsd, kX86InstIdVpminsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD minimum (AVX). + INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminsw, kX86InstIdVpminsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE unsigned minimum (AVX). + INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminub, kX86InstIdVpminub, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD unsigned minimum (AVX). + INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminud, kX86InstIdVpminud, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD unsigned minimum (AVX). + INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpminuw, kX86InstIdVpminuw, X86XmmReg, X86XmmReg, X86Mem) + + //! Move Byte mask to integer (AVX). + INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86XmmReg) + + //! BYTE to DWORD with sign extend (AVX). + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with sign extend (AVX). + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86XmmReg, X86Mem) + + //! Packed BYTE to WORD with sign extend (AVX). + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with sign extend (AVX). + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with sign extend (AVX). + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with sign extend (AVX). + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86XmmReg, X86Mem) + + //! BYTE to DWORD with zero extend (AVX). + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86XmmReg, X86Mem) + + //! Packed BYTE to QWORD with zero extend (AVX). + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86XmmReg, X86Mem) + + //! BYTE to WORD with zero extend (AVX). + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD with zero extend (AVX). + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86XmmReg, X86Mem) + + //! Packed WORD to DWORD with zero extend (AVX). + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86XmmReg, X86Mem) + + //! Packed WORD to QWORD with zero extend (AVX). + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86XmmReg, X86Mem) + + //! Packed DWORD to QWORD multiply (AVX). + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD multiply high, round and scale (AVX). + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD unsigned multiply high (AVX). + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD multiply high (AVX). + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD multiply low (AVX). + INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmulld, kX86InstIdVpmulld, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORDs multiply low (AVX). + INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmullw, kX86InstIdVpmullw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD multiply to QWORD (AVX). + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed bitwise or (AVX). + INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpor, kX86InstIdVpor, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD sum of absolute differences (AVX). + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE shuffle (AVX). + INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpshufb, kX86InstIdVpshufb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD shuffle (AVX). + INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpshufd, kX86InstIdVpshufd, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle high (AVX). + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86XmmReg, X86Mem, Imm) + + //! Packed WORD shuffle low (AVX). + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86XmmReg, X86Mem, Imm) + + //! Packed BYTE sign (AVX). + INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsignb, kX86InstIdVpsignb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD sign (AVX). + INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsignd, kX86InstIdVpsignd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD sign (AVX). + INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsignw, kX86InstIdVpsignw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD shift left logical (AVX). + INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpslld, kX86InstIdVpslld, X86XmmReg, X86XmmReg, Imm) + + //! Packed OWORD shift left logical (AVX). + INST_3i(vpslldq, kX86InstIdVpslldq, X86XmmReg, X86XmmReg, Imm) + + //! Packed QWORD shift left logical (AVX). + INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsllq, kX86InstIdVpsllq, X86XmmReg, X86XmmReg, Imm) + + //! Packed WORD shift left logical (AVX). + INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsllw, kX86InstIdVpsllw, X86XmmReg, X86XmmReg, Imm) + + //! Packed DWORD shift right arithmetic (AVX). + INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrad, kX86InstIdVpsrad, X86XmmReg, X86XmmReg, Imm) + + //! Packed WORD shift right arithmetic (AVX). + INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsraw, kX86InstIdVpsraw, X86XmmReg, X86XmmReg, Imm) + + //! Packed DWORD shift right logical (AVX). + INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrld, kX86InstIdVpsrld, X86XmmReg, X86XmmReg, Imm) + + //! Scalar OWORD shift right logical (AVX). + INST_3i(vpsrldq, kX86InstIdVpsrldq, X86XmmReg, X86XmmReg, Imm) + + //! Packed QWORD shift right logical (AVX). + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrlq, kX86InstIdVpsrlq, X86XmmReg, X86XmmReg, Imm) + + //! Packed WORD shift right logical (AVX). + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3i(vpsrlw, kX86InstIdVpsrlw, X86XmmReg, X86XmmReg, Imm) + + //! Packed BYTE subtract (AVX). + INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubb, kX86InstIdVpsubb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DWORD subtract (AVX). + INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubd, kX86InstIdVpsubd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed QWORD subtract (AVX). + INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubq, kX86InstIdVpsubq, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD subtract (AVX). + INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubw, kX86InstIdVpsubw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE subtract with saturation (AVX). + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD subtract with saturation (AVX). + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (AVX). + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed WORD subtract with unsigned saturation (AVX). + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86XmmReg, X86XmmReg, X86Mem) + + //! Logical compare (AVX). + INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vptest, kX86InstIdVptest, X86XmmReg, X86Mem) + //! \overload + INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vptest, kX86InstIdVptest, X86YmmReg, X86Mem) + + //! Unpack high packed BYTEs to WORDs (AVX). + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (AVX). + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack high packed QWORDs to OWORD (AVX). + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack high packed WORDs to DWORDs (AVX). + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed BYTEs to WORDs (AVX). + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (AVX). + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed QWORDs to OWORD (AVX). + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86XmmReg, X86XmmReg, X86Mem) + + //! Unpack low packed WORDs to DWORDs (AVX). + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed bitwise xor (AVX). + INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vpxor, kX86InstIdVpxor, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed SP-FP reciprocal (AVX). + INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vrcpps, kX86InstIdVrcpps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vrcpps, kX86InstIdVrcpps, X86YmmReg, X86Mem) + + //! Scalar SP-FP reciprocal (AVX). + INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vrcpss, kX86InstIdVrcpss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed SP-FP square root reciprocal (AVX). + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vrsqrtps, kX86InstIdVrsqrtps, X86YmmReg, X86Mem) + + //! Scalar SP-FP square root reciprocal (AVX). + INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vrsqrtss, kX86InstIdVrsqrtss, X86XmmReg, X86XmmReg, X86Mem) + + //! Packed DP-FP round (AVX). + INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vroundpd, kX86InstIdVroundpd, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vroundpd, kX86InstIdVroundpd, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP round (AVX). + INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vroundps, kX86InstIdVroundps, X86XmmReg, X86Mem, Imm) + //! \overload + INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vroundps, kX86InstIdVroundps, X86YmmReg, X86Mem, Imm) + + //! Scalar DP-FP round (AVX). + INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vroundsd, kX86InstIdVroundsd, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Scalar SP-FP round (AVX). + INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vroundss, kX86InstIdVroundss, X86XmmReg, X86XmmReg, X86Mem, Imm) + + //! Shuffle DP-FP (AVX). + INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vshufpd, kX86InstIdVshufpd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vshufpd, kX86InstIdVshufpd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Shuffle SP-FP (AVX). + INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vshufps, kX86InstIdVshufps, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vshufps, kX86InstIdVshufps, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DP-FP square root (AVX). + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vsqrtpd, kX86InstIdVsqrtpd, X86YmmReg, X86Mem) + + //! Packed SP-FP square root (AVX). + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vsqrtps, kX86InstIdVsqrtps, X86YmmReg, X86Mem) + + //! Scalar DP-FP square root (AVX). + INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsqrtsd, kX86InstIdVsqrtsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP square root (AVX). + INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsqrtss, kX86InstIdVsqrtss, X86XmmReg, X86XmmReg, X86Mem) + + //! Store streaming SIMD extension control/status (AVX). + INST_1x(vstmxcsr, kX86InstIdVstmxcsr, X86Mem) + + //! Packed DP-FP subtract (AVX). + INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubpd, kX86InstIdVsubpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vsubpd, kX86InstIdVsubpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP subtract (AVX). + INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubps, kX86InstIdVsubps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vsubps, kX86InstIdVsubps, X86YmmReg, X86YmmReg, X86Mem) + + //! Scalar DP-FP subtract (AVX). + INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubsd, kX86InstIdVsubsd, X86XmmReg, X86XmmReg, X86Mem) + + //! Scalar SP-FP subtract (AVX). + INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vsubss, kX86InstIdVsubss, X86XmmReg, X86XmmReg, X86Mem) + + //! Logical compare DP-FP (AVX). + INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vtestpd, kX86InstIdVtestpd, X86XmmReg, X86Mem) + //! \overload + INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vtestpd, kX86InstIdVtestpd, X86YmmReg, X86Mem) + + //! Logical compare SP-FP (AVX). + INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vtestps, kX86InstIdVtestps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vtestps, kX86InstIdVtestps, X86YmmReg, X86Mem) + + //! Scalar DP-FP unordered compare and set EFLAGS (AVX). + INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vucomisd, kX86InstIdVucomisd, X86XmmReg, X86Mem) + + //! Unordered scalar SP-FP compare and set EFLAGS (AVX). + INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vucomiss, kX86InstIdVucomiss, X86XmmReg, X86Mem) + + //! Unpack and interleave high packed DP-FP (AVX). + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpckhpd, kX86InstIdVunpckhpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Unpack high packed SP-FP data (AVX). + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpckhps, kX86InstIdVunpckhps, X86YmmReg, X86YmmReg, X86Mem) + + //! Unpack and interleave low packed DP-FP (AVX). + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpcklpd, kX86InstIdVunpcklpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Unpack low packed SP-FP data (AVX). + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vunpcklps, kX86InstIdVunpcklps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP bitwise xor (AVX). + INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vxorpd, kX86InstIdVxorpd, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vxorpd, kX86InstIdVxorpd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed SP-FP bitwise xor (AVX). + INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vxorps, kX86InstIdVxorps, X86XmmReg, X86XmmReg, X86Mem) + //! \overload + INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vxorps, kX86InstIdVxorps, X86YmmReg, X86YmmReg, X86Mem) + + //! Zero all Ymm registers. + INST_0x(vzeroall, kX86InstIdVzeroall) + //! Zero upper 128-bits of all Ymm registers. + INST_0x(vzeroupper, kX86InstIdVzeroupper) + + // -------------------------------------------------------------------------- + // [AVX+AESNI] + // -------------------------------------------------------------------------- + + //! Perform a single round of the AES decryption flow (AVX+AESNI). + INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesdec, kX86InstIdVaesdec, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform the last round of the AES decryption flow (AVX+AESNI). + INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesdeclast, kX86InstIdVaesdeclast, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform a single round of the AES encryption flow (AVX+AESNI). + INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesenc, kX86InstIdVaesenc, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform the last round of the AES encryption flow (AVX+AESNI). + INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86XmmReg) + //! \overload + INST_3x(vaesenclast, kX86InstIdVaesenclast, X86XmmReg, X86XmmReg, X86Mem) + + //! Perform the InvMixColumns transformation (AVX+AESNI). + INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vaesimc, kX86InstIdVaesimc, X86XmmReg, X86Mem) + + //! Assist in expanding the AES cipher key (AVX+AESNI). + INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vaeskeygenassist, kX86InstIdVaeskeygenassist, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [AVX+PCLMULQDQ] + // -------------------------------------------------------------------------- + + //! Carry-less multiplication QWORD (AVX+PCLMULQDQ). + INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpclmulqdq, kX86InstIdVpclmulqdq, X86XmmReg, X86XmmReg, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [AVX2] + // -------------------------------------------------------------------------- + + //! Broadcast low 128-bit element in `o1` to `o0` (AVX2). + INST_2x(vbroadcasti128, kX86InstIdVbroadcasti128, X86YmmReg, X86Mem) + //! Broadcast low DP-FP element in `o1` to `o0` (AVX2). + INST_2x(vbroadcastsd, kX86InstIdVbroadcastsd, X86YmmReg, X86XmmReg) + //! Broadcast low SP-FP element in `o1` to `o0` (AVX2). + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vbroadcastss, kX86InstIdVbroadcastss, X86YmmReg, X86XmmReg) + + //! Extract 128-bit element from `o1` to `o0` based on selector (AVX2). + INST_3i(vextracti128, kX86InstIdVextracti128, X86XmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vextracti128, kX86InstIdVextracti128, X86Mem, X86YmmReg, Imm) + + //! Gather DP-FP from DWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_3x(vgatherdpd, kX86InstIdVgatherdpd, X86YmmReg, X86Mem, X86YmmReg) + + //! Gather SP-FP from DWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherdps, kX86InstIdVgatherdps, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_3x(vgatherdps, kX86InstIdVgatherdps, X86YmmReg, X86Mem, X86YmmReg) + + //! Gather DP-FP from QWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86XmmReg, X86Mem, X86XmmReg) + //! \overload + INST_3x(vgatherqpd, kX86InstIdVgatherqpd, X86YmmReg, X86Mem, X86YmmReg) + + //! Gather SP-FP from QWORD indicies specified in `o1`s VSIB (AVX2). + INST_3x(vgatherqps, kX86InstIdVgatherqps, X86XmmReg, X86Mem, X86XmmReg) + + //! Insert 128-bit of packed data based on selector (AVX2). + INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vinserti128, kX86InstIdVinserti128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Load 256-bits aligned using NT hint (AVX2). + INST_2x(vmovntdqa, kX86InstIdVmovntdqa, X86YmmReg, X86Mem) + + //! Packed WORD sums of absolute difference (AVX2). + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vmpsadbw, kX86InstIdVmpsadbw, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed BYTE absolute value (AVX2). + INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vpabsb, kX86InstIdVpabsb, X86YmmReg, X86Mem) + + //! Packed DWORD absolute value (AVX2). + INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vpabsd, kX86InstIdVpabsd, X86YmmReg, X86Mem) + + //! Packed WORD absolute value (AVX2). + INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86YmmReg) + //! \overload + INST_2x(vpabsw, kX86InstIdVpabsw, X86YmmReg, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (AVX2). + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpackssdw, kX86InstIdVpackssdw, X86YmmReg, X86YmmReg, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (AVX2). + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpacksswb, kX86InstIdVpacksswb, X86YmmReg, X86YmmReg, X86Mem) + + //! Pack DWORDs to WORDs with unsigned saturation (AVX2). + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpackusdw, kX86InstIdVpackusdw, X86YmmReg, X86YmmReg, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (AVX2). + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpackuswb, kX86InstIdVpackuswb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE add (AVX2). + INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddb, kX86InstIdVpaddb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORD add (AVX2). + INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddd, kX86InstIdVpaddd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QDWORD add (AVX2). + INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddq, kX86InstIdVpaddq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD add (AVX2). + INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddw, kX86InstIdVpaddw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE add with saturation (AVX2). + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddsb, kX86InstIdVpaddsb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD add with saturation (AVX2). + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddsw, kX86InstIdVpaddsw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE add with unsigned saturation (AVX2). + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddusb, kX86InstIdVpaddusb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD add with unsigned saturation (AVX2). + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpaddusw, kX86InstIdVpaddusw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed align right (AVX2). + INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vpalignr, kX86InstIdVpalignr, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed bitwise and (AVX2). + INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpand, kX86InstIdVpand, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed bitwise and-not (AVX2). + INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpandn, kX86InstIdVpandn, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE average (AVX2). + INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpavgb, kX86InstIdVpavgb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORD average (AVX2). + INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpavgw, kX86InstIdVpavgw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORD blend (AVX2). + INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_4i(vpblendd, kX86InstIdVpblendd, X86XmmReg, X86XmmReg, X86Mem, Imm) + //! \overload + INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vpblendd, kX86InstIdVpblendd, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DWORD variable blend (AVX2). + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_4x(vpblendvb, kX86InstIdVpblendvb, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + + //! Packed WORD blend (AVX2). + INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vpblendw, kX86InstIdVpblendw, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Broadcast BYTE from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86XmmReg, X86Mem) + //! Broadcast BYTE from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastb, kX86InstIdVpbroadcastb, X86YmmReg, X86Mem) + + //! Broadcast DWORD from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86XmmReg, X86Mem) + //! Broadcast DWORD from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastd, kX86InstIdVpbroadcastd, X86YmmReg, X86Mem) + + //! Broadcast QWORD from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86XmmReg, X86Mem) + //! Broadcast QWORD from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastq, kX86InstIdVpbroadcastq, X86YmmReg, X86Mem) + + //! Broadcast WORD from `o1` to 128-bits in `o0` (AVX2). + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86XmmReg, X86Mem) + //! Broadcast WORD from `o1` to 256-bits in `o0` (AVX2). + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vpbroadcastw, kX86InstIdVpbroadcastw, X86YmmReg, X86Mem) + + //! Packed BYTEs compare for equality (AVX2). + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqb, kX86InstIdVpcmpeqb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORDs compare for equality (AVX2). + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqd, kX86InstIdVpcmpeqd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QWORDs compare for equality (AVX2). + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqq, kX86InstIdVpcmpeqq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORDs compare for equality (AVX2). + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpeqw, kX86InstIdVpcmpeqw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTEs compare if greater than (AVX2). + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtb, kX86InstIdVpcmpgtb, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DWORDs compare if greater than (AVX2). + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtd, kX86InstIdVpcmpgtd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QWORDs compare if greater than (AVX2). + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtq, kX86InstIdVpcmpgtq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed WORDs compare if greater than (AVX2). + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpcmpgtw, kX86InstIdVpcmpgtw, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed OWORD permute (AVX2). + INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_4i(vperm2i128, kX86InstIdVperm2i128, X86YmmReg, X86YmmReg, X86Mem, Imm) + + //! Packed DWORD permute (AVX2). + INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermd, kX86InstIdVpermd, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed DP-FP permute (AVX2). + INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermpd, kX86InstIdVpermpd, X86YmmReg, X86Mem, Imm) + + //! Packed SP-FP permute (AVX2). + INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86YmmReg) + //! \overload + INST_3x(vpermps, kX86InstIdVpermps, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed QWORD permute (AVX2). + INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vpermq, kX86InstIdVpermq, X86YmmReg, X86Mem, Imm) + + INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherdd, kX86InstIdVpgatherdd, X86YmmReg, X86Mem, X86YmmReg) + + INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherdq, kX86InstIdVpgatherdq, X86YmmReg, X86Mem, X86YmmReg) + + INST_3x(vpgatherqd, kX86InstIdVpgatherqd, X86XmmReg, X86Mem, X86XmmReg) + + INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpgatherqq, kX86InstIdVpgatherqq, X86YmmReg, X86Mem, X86YmmReg) + + //! Packed DWORD horizontal add (AVX2). + INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphaddd, kX86InstIdVphaddd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal add with saturation (AVX2). + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphaddsw, kX86InstIdVphaddsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal add (AVX2). + INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphaddw, kX86InstIdVphaddw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD horizontal subtract (AVX2). + INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphsubd, kX86InstIdVphsubd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal subtract with saturation (AVX2). + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphsubsw, kX86InstIdVphsubsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD horizontal subtract (AVX2). + INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vphsubw, kX86InstIdVphsubw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Move Byte mask to integer (AVX2). + INST_2x(vpmovmskb, kX86InstIdVpmovmskb, X86GpReg, X86YmmReg) + + //! BYTE to DWORD with sign extend (AVX). + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxbd, kX86InstIdVpmovsxbd, X86YmmReg, X86XmmReg) + + //! Packed BYTE to QWORD with sign extend (AVX2). + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxbq, kX86InstIdVpmovsxbq, X86YmmReg, X86XmmReg) + + //! Packed BYTE to WORD with sign extend (AVX2). + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxbw, kX86InstIdVpmovsxbw, X86YmmReg, X86XmmReg) + + //! Packed DWORD to QWORD with sign extend (AVX2). + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxdq, kX86InstIdVpmovsxdq, X86YmmReg, X86XmmReg) + + //! Packed WORD to DWORD with sign extend (AVX2). + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxwd, kX86InstIdVpmovsxwd, X86YmmReg, X86XmmReg) + + //! Packed WORD to QWORD with sign extend (AVX2). + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovsxwq, kX86InstIdVpmovsxwq, X86YmmReg, X86XmmReg) + + //! BYTE to DWORD with zero extend (AVX2). + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxbd, kX86InstIdVpmovzxbd, X86YmmReg, X86XmmReg) + + //! Packed BYTE to QWORD with zero extend (AVX2). + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxbq, kX86InstIdVpmovzxbq, X86YmmReg, X86XmmReg) + + //! BYTE to WORD with zero extend (AVX2). + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxbw, kX86InstIdVpmovzxbw, X86YmmReg, X86XmmReg) + + //! Packed DWORD to QWORD with zero extend (AVX2). + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxdq, kX86InstIdVpmovzxdq, X86YmmReg, X86XmmReg) + + //! Packed WORD to DWORD with zero extend (AVX2). + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxwd, kX86InstIdVpmovzxwd, X86YmmReg, X86XmmReg) + + //! Packed WORD to QWORD with zero extend (AVX2). + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86Mem) + //! \overload + INST_2x(vpmovzxwq, kX86InstIdVpmovzxwq, X86YmmReg, X86XmmReg) + + //! Packed multiply and add signed and unsigned bytes (AVX2). + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaddubsw, kX86InstIdVpmaddubsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD multiply and add to packed DWORD (AVX2). + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaddwd, kX86InstIdVpmaddwd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86Mem, X86XmmReg, X86XmmReg) + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86Mem, X86YmmReg, X86YmmReg) + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpmaskmovd, kX86InstIdVpmaskmovd, X86YmmReg, X86YmmReg, X86Mem) + + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86Mem, X86XmmReg, X86XmmReg) + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86Mem, X86YmmReg, X86YmmReg) + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpmaskmovq, kX86InstIdVpmaskmovq, X86YmmReg, X86YmmReg, X86Mem) + + //! Packed BYTE maximum (AVX2). + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxsb, kX86InstIdVpmaxsb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD maximum (AVX2). + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxsd, kX86InstIdVpmaxsd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD maximum (AVX2). + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxsw, kX86InstIdVpmaxsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE unsigned maximum (AVX2). + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxub, kX86InstIdVpmaxub, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD unsigned maximum (AVX2). + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxud, kX86InstIdVpmaxud, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD unsigned maximum (AVX2). + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmaxuw, kX86InstIdVpmaxuw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE minimum (AVX2). + INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminsb, kX86InstIdVpminsb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD minimum (AVX2). + INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminsd, kX86InstIdVpminsd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD minimum (AVX2). + INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminsw, kX86InstIdVpminsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE unsigned minimum (AVX2). + INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminub, kX86InstIdVpminub, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD unsigned minimum (AVX2). + INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminud, kX86InstIdVpminud, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD unsigned minimum (AVX2). + INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpminuw, kX86InstIdVpminuw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD to QWORD multiply (AVX2). + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmuldq, kX86InstIdVpmuldq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD multiply high, round and scale (AVX2). + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulhrsw, kX86InstIdVpmulhrsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD unsigned multiply high (AVX2). + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulhuw, kX86InstIdVpmulhuw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD multiply high (AVX2). + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulhw, kX86InstIdVpmulhw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD multiply low (AVX2). + INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmulld, kX86InstIdVpmulld, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORDs multiply low (AVX2). + INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmullw, kX86InstIdVpmullw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD multiply to QWORD (AVX2). + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpmuludq, kX86InstIdVpmuludq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed bitwise or (AVX2). + INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpor, kX86InstIdVpor, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD sum of absolute differences (AVX2). + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsadbw, kX86InstIdVpsadbw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE shuffle (AVX2). + INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpshufb, kX86InstIdVpshufb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD shuffle (AVX2). + INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpshufd, kX86InstIdVpshufd, X86YmmReg, X86YmmReg, Imm) + + //! Packed WORD shuffle high (AVX2). + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpshufhw, kX86InstIdVpshufhw, X86YmmReg, X86YmmReg, Imm) + + //! Packed WORD shuffle low (AVX2). + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86Mem, Imm) + //! \overload + INST_3i(vpshuflw, kX86InstIdVpshuflw, X86YmmReg, X86YmmReg, Imm) + + //! Packed BYTE sign (AVX2). + INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsignb, kX86InstIdVpsignb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD sign (AVX2). + INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsignd, kX86InstIdVpsignd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD sign (AVX2). + INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsignw, kX86InstIdVpsignw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD shift left logical (AVX2). + INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpslld, kX86InstIdVpslld, X86YmmReg, X86YmmReg, Imm) + + //! Packed OWORD shift left logical (AVX2). + INST_3i(vpslldq, kX86InstIdVpslldq, X86YmmReg, X86YmmReg, Imm) + + //! Packed QWORD shift left logical (AVX2). + INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsllq, kX86InstIdVpsllq, X86YmmReg, X86YmmReg, Imm) + + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsllvd, kX86InstIdVpsllvd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsllvq, kX86InstIdVpsllvq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD shift left logical (AVX2). + INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, X86XmmReg) + //! Packed WORD shift left logical (AVX2). + INST_3i(vpsllw, kX86InstIdVpsllw, X86YmmReg, X86YmmReg, Imm) + + //! Packed DWORD shift right arithmetic (AVX2). + INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrad, kX86InstIdVpsrad, X86YmmReg, X86YmmReg, Imm) + + INST_3x(vpsravd, kX86InstIdVpsravd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsravd, kX86InstIdVpsravd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsravd, kX86InstIdVpsravd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsravd, kX86InstIdVpsravd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD shift right arithmetic (AVX2). + INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsraw, kX86InstIdVpsraw, X86YmmReg, X86YmmReg, Imm) + + //! Packed DWORD shift right logical (AVX2). + INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrld, kX86InstIdVpsrld, X86YmmReg, X86YmmReg, Imm) + + //! Scalar OWORD shift right logical (AVX2). + INST_3i(vpsrldq, kX86InstIdVpsrldq, X86YmmReg, X86YmmReg, Imm) + + //! Packed QWORD shift right logical (AVX2). + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrlq, kX86InstIdVpsrlq, X86YmmReg, X86YmmReg, Imm) + + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsrlvd, kX86InstIdVpsrlvd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsrlvq, kX86InstIdVpsrlvq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD shift right logical (AVX2). + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, X86XmmReg) + //! \overload + INST_3i(vpsrlw, kX86InstIdVpsrlw, X86YmmReg, X86YmmReg, Imm) + + //! Packed BYTE subtract (AVX2). + INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vpsubb, kX86InstIdVpsubb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed DWORD subtract (AVX2). + INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubd, kX86InstIdVpsubd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed QWORD subtract (AVX2). + INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubq, kX86InstIdVpsubq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE subtract with saturation (AVX2). + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubsb, kX86InstIdVpsubsb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD subtract with saturation (AVX2). + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubsw, kX86InstIdVpsubsw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed BYTE subtract with unsigned saturation (AVX2). + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubusb, kX86InstIdVpsubusb, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD subtract with unsigned saturation (AVX2). + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubusw, kX86InstIdVpsubusw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed WORD subtract (AVX2). + INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpsubw, kX86InstIdVpsubw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed BYTEs to WORDs (AVX2). + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhbw, kX86InstIdVpunpckhbw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed DWORDs to QWORDs (AVX2). + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhdq, kX86InstIdVpunpckhdq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed QWORDs to OWORD (AVX2). + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhqdq, kX86InstIdVpunpckhqdq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack high packed WORDs to DWORDs (AVX2). + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckhwd, kX86InstIdVpunpckhwd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed BYTEs to WORDs (AVX2). + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpcklbw, kX86InstIdVpunpcklbw, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed DWORDs to QWORDs (AVX2). + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpckldq, kX86InstIdVpunpckldq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed QWORDs to OWORD (AVX2). + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpcklqdq, kX86InstIdVpunpcklqdq, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Unpack low packed WORDs to DWORDs (AVX2). + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpunpcklwd, kX86InstIdVpunpcklwd, X86YmmReg, X86YmmReg, X86YmmReg) + + //! Packed bitwise xor (AVX2). + INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86Mem) + //! \overload + INST_3x(vpxor, kX86InstIdVpxor, X86YmmReg, X86YmmReg, X86YmmReg) + + // -------------------------------------------------------------------------- + // [FMA3] + // -------------------------------------------------------------------------- + + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd132pd, kX86InstIdVfmadd132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd132ps, kX86InstIdVfmadd132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132sd, kX86InstIdVfmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd132ss, kX86InstIdVfmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd213pd, kX86InstIdVfmadd213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd213ps, kX86InstIdVfmadd213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213sd, kX86InstIdVfmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd213ss, kX86InstIdVfmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd231pd, kX86InstIdVfmadd231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmadd231ps, kX86InstIdVfmadd231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231sd, kX86InstIdVfmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmadd231ss, kX86InstIdVfmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub132pd, kX86InstIdVfmaddsub132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub132ps, kX86InstIdVfmaddsub132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub213pd, kX86InstIdVfmaddsub213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub213ps, kX86InstIdVfmaddsub213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub231pd, kX86InstIdVfmaddsub231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmaddsub231ps, kX86InstIdVfmaddsub231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub132pd, kX86InstIdVfmsub132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub132ps, kX86InstIdVfmsub132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132sd, kX86InstIdVfmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub132ss, kX86InstIdVfmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub213pd, kX86InstIdVfmsub213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub213ps, kX86InstIdVfmsub213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213sd, kX86InstIdVfmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub213ss, kX86InstIdVfmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub231pd, kX86InstIdVfmsub231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsub231ps, kX86InstIdVfmsub231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231sd, kX86InstIdVfmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsub231ss, kX86InstIdVfmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd132pd, kX86InstIdVfmsubadd132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd132ps, kX86InstIdVfmsubadd132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd213pd, kX86InstIdVfmsubadd213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd213ps, kX86InstIdVfmsubadd213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd231pd, kX86InstIdVfmsubadd231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfmsubadd231ps, kX86InstIdVfmsubadd231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd132pd, kX86InstIdVfnmadd132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd132ps, kX86InstIdVfnmadd132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132sd, kX86InstIdVfnmadd132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd132ss, kX86InstIdVfnmadd132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd213pd, kX86InstIdVfnmadd213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd213ps, kX86InstIdVfnmadd213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213sd, kX86InstIdVfnmadd213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd213ss, kX86InstIdVfnmadd213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd231pd, kX86InstIdVfnmadd231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmadd231ps, kX86InstIdVfnmadd231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231sd, kX86InstIdVfnmadd231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmadd231ss, kX86InstIdVfnmadd231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub132pd, kX86InstIdVfnmsub132pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub132ps, kX86InstIdVfnmsub132ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132sd, kX86InstIdVfnmsub132sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub132ss, kX86InstIdVfnmsub132ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub213pd, kX86InstIdVfnmsub213pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub213ps, kX86InstIdVfnmsub213ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213sd, kX86InstIdVfnmsub213sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub213ss, kX86InstIdVfnmsub213ss, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub231pd, kX86InstIdVfnmsub231pd, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86YmmReg, X86YmmReg, X86Mem) + INST_3x(vfnmsub231ps, kX86InstIdVfnmsub231ps, X86YmmReg, X86YmmReg, X86YmmReg) + + INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231sd, kX86InstIdVfnmsub231sd, X86XmmReg, X86XmmReg, X86XmmReg) + + INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86Mem) + INST_3x(vfnmsub231ss, kX86InstIdVfnmsub231ss, X86XmmReg, X86XmmReg, X86XmmReg) + + // -------------------------------------------------------------------------- + // [FMA4] + // -------------------------------------------------------------------------- + + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddpd, kX86InstIdVfmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddps, kX86InstIdVfmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddsd, kX86InstIdVfmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddss, kX86InstIdVfmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddsubpd, kX86InstIdVfmaddsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmaddsubps, kX86InstIdVfmaddsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubaddpd, kX86InstIdVfmsubaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubaddps, kX86InstIdVfmsubaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubpd, kX86InstIdVfmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfmsubps, kX86InstIdVfmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubsd, kX86InstIdVfmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfmsubss, kX86InstIdVfmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmaddpd, kX86InstIdVfnmaddpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmaddps, kX86InstIdVfnmaddps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddsd, kX86InstIdVfnmaddsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmaddss, kX86InstIdVfnmaddss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmsubpd, kX86InstIdVfnmsubpd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vfnmsubps, kX86InstIdVfnmsubps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubsd, kX86InstIdVfnmsubsd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vfnmsubss, kX86InstIdVfnmsubss, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [XOP] + // -------------------------------------------------------------------------- + + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86XmmReg, X86XmmReg) + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86XmmReg, X86Mem) + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86YmmReg, X86YmmReg) + INST_2x(vfrczpd, kX86InstIdVfrczpd, X86YmmReg, X86Mem) + + INST_2x(vfrczps, kX86InstIdVfrczps, X86XmmReg, X86XmmReg) + INST_2x(vfrczps, kX86InstIdVfrczps, X86XmmReg, X86Mem) + INST_2x(vfrczps, kX86InstIdVfrczps, X86YmmReg, X86YmmReg) + INST_2x(vfrczps, kX86InstIdVfrczps, X86YmmReg, X86Mem) + + INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86XmmReg) + INST_2x(vfrczsd, kX86InstIdVfrczsd, X86XmmReg, X86Mem) + + INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86XmmReg) + INST_2x(vfrczss, kX86InstIdVfrczss, X86XmmReg, X86Mem) + + INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vpcmov, kX86InstIdVpcmov, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4i(vpcomb, kX86InstIdVpcomb, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomb, kX86InstIdVpcomb, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomd, kX86InstIdVpcomd, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomd, kX86InstIdVpcomd, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomq, kX86InstIdVpcomq, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomq, kX86InstIdVpcomq, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomw, kX86InstIdVpcomw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomw, kX86InstIdVpcomw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + INST_4i(vpcomub, kX86InstIdVpcomub, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomub, kX86InstIdVpcomub, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomud, kX86InstIdVpcomud, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomud, kX86InstIdVpcomud, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomuq, kX86InstIdVpcomuq, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomuq, kX86InstIdVpcomuq, X86XmmReg, X86XmmReg, X86Mem, Imm) + INST_4i(vpcomuw, kX86InstIdVpcomuw, X86XmmReg, X86XmmReg, X86XmmReg, Imm) + INST_4i(vpcomuw, kX86InstIdVpcomuw, X86XmmReg, X86XmmReg, X86Mem, Imm) + + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vpermil2pd, kX86InstIdVpermil2pd, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86YmmReg, X86YmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86Mem, X86YmmReg) + INST_4x(vpermil2ps, kX86InstIdVpermil2ps, X86YmmReg, X86YmmReg, X86YmmReg, X86Mem) + + INST_2x(vphaddbd, kX86InstIdVphaddbd, X86XmmReg, X86XmmReg) + INST_2x(vphaddbd, kX86InstIdVphaddbd, X86XmmReg, X86Mem) + INST_2x(vphaddbq, kX86InstIdVphaddbq, X86XmmReg, X86XmmReg) + INST_2x(vphaddbq, kX86InstIdVphaddbq, X86XmmReg, X86Mem) + INST_2x(vphaddbw, kX86InstIdVphaddbw, X86XmmReg, X86XmmReg) + INST_2x(vphaddbw, kX86InstIdVphaddbw, X86XmmReg, X86Mem) + INST_2x(vphadddq, kX86InstIdVphadddq, X86XmmReg, X86XmmReg) + INST_2x(vphadddq, kX86InstIdVphadddq, X86XmmReg, X86Mem) + INST_2x(vphaddwd, kX86InstIdVphaddwd, X86XmmReg, X86XmmReg) + INST_2x(vphaddwd, kX86InstIdVphaddwd, X86XmmReg, X86Mem) + INST_2x(vphaddwq, kX86InstIdVphaddwq, X86XmmReg, X86XmmReg) + INST_2x(vphaddwq, kX86InstIdVphaddwq, X86XmmReg, X86Mem) + + INST_2x(vphaddubd, kX86InstIdVphaddubd, X86XmmReg, X86XmmReg) + INST_2x(vphaddubd, kX86InstIdVphaddubd, X86XmmReg, X86Mem) + INST_2x(vphaddubq, kX86InstIdVphaddubq, X86XmmReg, X86XmmReg) + INST_2x(vphaddubq, kX86InstIdVphaddubq, X86XmmReg, X86Mem) + INST_2x(vphaddubw, kX86InstIdVphaddubw, X86XmmReg, X86XmmReg) + INST_2x(vphaddubw, kX86InstIdVphaddubw, X86XmmReg, X86Mem) + INST_2x(vphaddudq, kX86InstIdVphaddudq, X86XmmReg, X86XmmReg) + INST_2x(vphaddudq, kX86InstIdVphaddudq, X86XmmReg, X86Mem) + INST_2x(vphadduwd, kX86InstIdVphadduwd, X86XmmReg, X86XmmReg) + INST_2x(vphadduwd, kX86InstIdVphadduwd, X86XmmReg, X86Mem) + INST_2x(vphadduwq, kX86InstIdVphadduwq, X86XmmReg, X86XmmReg) + INST_2x(vphadduwq, kX86InstIdVphadduwq, X86XmmReg, X86Mem) + + INST_2x(vphsubbw, kX86InstIdVphsubbw, X86XmmReg, X86XmmReg) + INST_2x(vphsubbw, kX86InstIdVphsubbw, X86XmmReg, X86Mem) + INST_2x(vphsubdq, kX86InstIdVphsubdq, X86XmmReg, X86XmmReg) + INST_2x(vphsubdq, kX86InstIdVphsubdq, X86XmmReg, X86Mem) + INST_2x(vphsubwd, kX86InstIdVphsubwd, X86XmmReg, X86XmmReg) + INST_2x(vphsubwd, kX86InstIdVphsubwd, X86XmmReg, X86Mem) + + INST_4x(vpmacsdd, kX86InstIdVpmacsdd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsdd, kX86InstIdVpmacsdd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsdqh, kX86InstIdVpmacsdqh, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsdqh, kX86InstIdVpmacsdqh, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsdql, kX86InstIdVpmacsdql, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsdql, kX86InstIdVpmacsdql, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacswd, kX86InstIdVpmacswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacswd, kX86InstIdVpmacswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsww, kX86InstIdVpmacsww, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsww, kX86InstIdVpmacsww, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpmacssdd, kX86InstIdVpmacssdd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssdd, kX86InstIdVpmacssdd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacssdqh, kX86InstIdVpmacssdqh, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssdqh, kX86InstIdVpmacssdqh, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacssdql, kX86InstIdVpmacssdql, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssdql, kX86InstIdVpmacssdql, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacsswd, kX86InstIdVpmacsswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacsswd, kX86InstIdVpmacsswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpmacssww, kX86InstIdVpmacssww, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmacssww, kX86InstIdVpmacssww, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmadcsswd, kX86InstIdVpmadcsswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpmadcswd, kX86InstIdVpmadcswd, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + + INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86XmmReg, X86XmmReg) + INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86Mem, X86XmmReg) + INST_4x(vpperm, kX86InstIdVpperm, X86XmmReg, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotb, kX86InstIdVprotb, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotb, kX86InstIdVprotb, X86XmmReg, X86Mem, Imm) + + INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotd, kX86InstIdVprotd, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotd, kX86InstIdVprotd, X86XmmReg, X86Mem, Imm) + + INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotq, kX86InstIdVprotq, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotq, kX86InstIdVprotq, X86XmmReg, X86Mem, Imm) + + INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, X86Mem) + INST_3i(vprotw, kX86InstIdVprotw, X86XmmReg, X86XmmReg, Imm) + INST_3i(vprotw, kX86InstIdVprotw, X86XmmReg, X86Mem, Imm) + + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshab, kX86InstIdVpshab, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshad, kX86InstIdVpshad, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshaq, kX86InstIdVpshaq, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshaw, kX86InstIdVpshaw, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlb, kX86InstIdVpshlb, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshld, kX86InstIdVpshld, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlq, kX86InstIdVpshlq, X86XmmReg, X86XmmReg, X86Mem) + + INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86XmmReg, X86XmmReg) + INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86Mem, X86XmmReg) + INST_3x(vpshlw, kX86InstIdVpshlw, X86XmmReg, X86XmmReg, X86Mem) + + // -------------------------------------------------------------------------- + // [BMI] + // -------------------------------------------------------------------------- + + //! Bitwise and-not (BMI). + INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(andn, kX86InstIdAndn, X86GpReg, X86GpReg, X86Mem) + + //! Bit field extract (BMI). + INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(bextr, kX86InstIdBextr, X86GpReg, X86Mem, X86GpReg) + + //! Extract lower set isolated bit (BMI). + INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86GpReg) + //! \overload + INST_2x(blsi, kX86InstIdBlsi, X86GpReg, X86Mem) + + //! Get mask up to lowest set bit (BMI). + INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86GpReg) + //! \overload + INST_2x(blsmsk, kX86InstIdBlsmsk, X86GpReg, X86Mem) + + //! Reset lowest set bit (BMI). + INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86GpReg) + //! \overload + INST_2x(blsr, kX86InstIdBlsr, X86GpReg, X86Mem) + + //! Count the number of trailing zero bits (BMI). + INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86GpReg) + //! \overload + INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86Mem) + + // -------------------------------------------------------------------------- + // [LZCNT] + // -------------------------------------------------------------------------- + + //! Count the number of leading zero bits (LZCNT). + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86GpReg) + //! \overload + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86Mem) + + // -------------------------------------------------------------------------- + // [BMI2] + // -------------------------------------------------------------------------- + + //! Zero high bits starting with specified bit position (BMI2). + INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(bzhi, kX86InstIdBzhi, X86GpReg, X86Mem, X86GpReg) + + //! Unsigned multiply without affecting flags (BMI2). + INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(mulx, kX86InstIdMulx, X86GpReg, X86GpReg, X86Mem) + + //! Parallel bits deposit (BMI2). + INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(pdep, kX86InstIdPdep, X86GpReg, X86GpReg, X86Mem) + + //! Parallel bits extract (BMI2). + INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(pext, kX86InstIdPext, X86GpReg, X86GpReg, X86Mem) + + //! Rotate right without affecting flags (BMI2). + INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86GpReg, Imm) + //! \overload + INST_3i(rorx, kX86InstIdRorx, X86GpReg, X86Mem, Imm) + + //! Shift arithmetic right without affecting flags (BMI2). + INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(sarx, kX86InstIdSarx, X86GpReg, X86Mem, X86GpReg) + + //! Shift logical left without affecting flags (BMI2). + INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shlx, kX86InstIdShlx, X86GpReg, X86Mem, X86GpReg) + + //! Shift logical right without affecting flags (BMI2). + INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86GpReg, X86GpReg) + //! \overload + INST_3x(shrx, kX86InstIdShrx, X86GpReg, X86Mem, X86GpReg) + + // -------------------------------------------------------------------------- + // [RDRAND] + // -------------------------------------------------------------------------- + + //! Store a random number in destination register. + //! + //! Please do not use this instruction in cryptographic software. The result + //! doesn't necessarily have to be random which may cause a major security + //! issue in the software that relies on it. + INST_1x(rdrand, kX86InstIdRdrand, X86GpReg) + + // -------------------------------------------------------------------------- + // [F16C] + // -------------------------------------------------------------------------- + + //! Convert packed HP-FP to SP-FP. + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86XmmReg, X86Mem) + //! \overload + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86XmmReg) + //! \overload + INST_2x(vcvtph2ps, kX86InstIdVcvtph2ps, X86YmmReg, X86Mem) + + //! Convert packed SP-FP to HP-FP. + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86XmmReg, Imm) + //! \overload + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86XmmReg, Imm) + //! \overload + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86XmmReg, X86YmmReg, Imm) + //! \overload + INST_3i(vcvtps2ph, kX86InstIdVcvtps2ph, X86Mem, X86YmmReg, Imm) + + // -------------------------------------------------------------------------- + // [FSGSBASE] + // -------------------------------------------------------------------------- + + INST_1x(rdfsbase, kX86InstIdRdfsbase, X86GpReg) + INST_1x(rdgsbase, kX86InstIdRdgsbase, X86GpReg) + INST_1x(wrfsbase, kX86InstIdWrfsbase, X86GpReg) + INST_1x(wrgsbase, kX86InstIdWrgsbase, X86GpReg) + +#undef INST_0x + +#undef INST_1x +#undef INST_1x_ +#undef INST_1i +#undef INST_1cc + +#undef INST_2x +#undef INST_2x_ +#undef INST_2i +#undef INST_2cc + +#undef INST_3x +#undef INST_3x_ +#undef INST_3i + +#undef INST_4x +#undef INST_4x_ +#undef INST_4i +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86ASSEMBLER_H diff --git a/libraries/asmjit/x86/x86compiler.cpp b/libraries/asmjit/x86/x86compiler.cpp new file mode 100644 index 000000000..d82efda04 --- /dev/null +++ b/libraries/asmjit/x86/x86compiler.cpp @@ -0,0 +1,1370 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)) + +// [Dependencies - AsmJit] +#include "../base/intutil.h" +#include "../base/string.h" +#include "../x86/x86assembler.h" +#include "../x86/x86compiler.h" +#include "../x86/x86context_p.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Debug] +// ============================================================================ + +#if !defined(ASMJIT_DEBUG) +#define ASMJIT_ASSERT_UNINITIALIZED(op) \ + do {} while(0) +#else +#define ASMJIT_ASSERT_UNINITIALIZED(op) \ + do { \ + if (op.isVar() || op.isLabel()) { \ + ASMJIT_ASSERT(op.getId() != kInvalidValue); \ + } \ + } while(0) +#endif + +// ============================================================================ +// [asmjit::X86VarInfo] +// ============================================================================ + +#define C(_Class_) kX86RegClass##_Class_ +#define D(_Desc_) kVarFlag##_Desc_ + +const X86VarInfo _x86VarInfo[] = { + /* 00: kVarTypeInt8 */ { kX86RegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" }, + /* 01: kVarTypeUInt8 */ { kX86RegTypeGpbLo, 1 , C(Gp) , 0 , "gpb" }, + /* 02: kVarTypeInt16 */ { kX86RegTypeGpw , 2 , C(Gp) , 0 , "gpw" }, + /* 03: kVarTypeUInt16 */ { kX86RegTypeGpw , 2 , C(Gp) , 0 , "gpw" }, + /* 04: kVarTypeInt32 */ { kX86RegTypeGpd , 4 , C(Gp) , 0 , "gpd" }, + /* 05: kVarTypeUInt32 */ { kX86RegTypeGpd , 4 , C(Gp) , 0 , "gpd" }, + /* 06: kVarTypeInt64 */ { kX86RegTypeGpq , 8 , C(Gp) , 0 , "gpq" }, + /* 07: kVarTypeUInt64 */ { kX86RegTypeGpq , 8 , C(Gp) , 0 , "gpq" }, + /* 08: kVarTypeIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped. + /* 09: kVarTypeUIntPtr */ { 0 , 0 , C(Gp) , 0 , "" }, // Remapped. + /* 10: kVarTypeFp32 */ { kX86RegTypeFp , 4 , C(Fp) , D(Sp) , "fp" }, + /* 11: kVarTypeFp64 */ { kX86RegTypeFp , 8 , C(Fp) , D(Dp) , "fp" }, + /* 12: kX86VarTypeMm */ { kX86RegTypeMm , 8 , C(Mm) , 0 , "mm" }, + /* 13: kX86VarTypeXmm */ { kX86RegTypeXmm , 16, C(Xyz), 0 , "xmm" }, + /* 14: kX86VarTypeXmmSs */ { kX86RegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" }, + /* 15: kX86VarTypeXmmPs */ { kX86RegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" }, + /* 16: kX86VarTypeXmmSd */ { kX86RegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" }, + /* 17: kX86VarTypeXmmPd */ { kX86RegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" }, + /* 18: kX86VarTypeYmm */ { kX86RegTypeYmm , 32, C(Xyz), 0 , "ymm" }, + /* 19: kX86VarTypeYmmPs */ { kX86RegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" }, + /* 20: kX86VarTypeYmmPd */ { kX86RegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" } +}; + +#undef D +#undef C + +#if defined(ASMJIT_BUILD_X86) +const uint8_t _x86VarMapping[kX86VarTypeCount] = { + /* 00: kVarTypeInt8 */ kVarTypeInt8, + /* 01: kVarTypeUInt8 */ kVarTypeUInt8, + /* 02: kVarTypeInt16 */ kVarTypeInt16, + /* 03: kVarTypeUInt16 */ kVarTypeUInt16, + /* 04: kVarTypeInt32 */ kVarTypeInt32, + /* 05: kVarTypeUInt32 */ kVarTypeUInt32, + /* 06: kVarTypeInt64 */ kInvalidVar, // Invalid in 32-bit mode. + /* 07: kVarTypeUInt64 */ kInvalidVar, // Invalid in 32-bit mode. + /* 08: kVarTypeIntPtr */ kVarTypeInt32, // Remapped to Int32. + /* 09: kVarTypeUIntPtr */ kVarTypeUInt32, // Remapped to UInt32. + /* 10: kVarTypeFp32 */ kVarTypeFp32, + /* 11: kVarTypeFp64 */ kVarTypeFp64, + /* 12: kX86VarTypeMm */ kX86VarTypeMm, + /* 13: kX86VarTypeXmm */ kX86VarTypeXmm, + /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, + /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, + /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, + /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, + /* 18: kX86VarTypeYmm */ kX86VarTypeYmm, + /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, + /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd +}; +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) +const uint8_t _x64VarMapping[kX86VarTypeCount] = { + /* 00: kVarTypeInt8 */ kVarTypeInt8, + /* 01: kVarTypeUInt8 */ kVarTypeUInt8, + /* 02: kVarTypeInt16 */ kVarTypeInt16, + /* 03: kVarTypeUInt16 */ kVarTypeUInt16, + /* 04: kVarTypeInt32 */ kVarTypeInt32, + /* 05: kVarTypeUInt32 */ kVarTypeUInt32, + /* 06: kVarTypeInt64 */ kVarTypeInt64, + /* 07: kVarTypeUInt64 */ kVarTypeUInt64, + /* 08: kVarTypeIntPtr */ kVarTypeInt64, // Remapped to Int64. + /* 09: kVarTypeUIntPtr */ kVarTypeUInt64, // Remapped to UInt64. + /* 10: kVarTypeFp32 */ kVarTypeFp32, + /* 11: kVarTypeFp64 */ kVarTypeFp64, + /* 12: kX86VarTypeMm */ kX86VarTypeMm, + /* 13: kX86VarTypeXmm */ kX86VarTypeXmm, + /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, + /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, + /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, + /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, + /* 18: kX86VarTypeYmm */ kX86VarTypeYmm, + /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, + /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd +}; +#endif // ASMJIT_BUILD_X64 + +// ============================================================================ +// [asmjit::X86FuncDecl - Helpers] +// ============================================================================ + +static ASMJIT_INLINE bool x86ArgIsInt(uint32_t aType) { + ASMJIT_ASSERT(aType < kX86VarTypeCount); + return IntUtil::inInterval(aType, _kVarTypeIntStart, _kVarTypeIntEnd); +} + +static ASMJIT_INLINE bool x86ArgIsFp(uint32_t aType) { + ASMJIT_ASSERT(aType < kX86VarTypeCount); + return IntUtil::inInterval(aType, _kVarTypeFpStart, _kVarTypeFpEnd); +} + +static ASMJIT_INLINE uint32_t x86ArgTypeToXmmType(uint32_t aType) { + if (aType == kVarTypeFp32) + return kX86VarTypeXmmSs; + if (aType == kVarTypeFp64) + return kX86VarTypeXmmSd; + return aType; +} + +//! Get an architecture from calling convention. +//! +//! Returns `kArchX86` or `kArchX64` depending on `conv`. +static ASMJIT_INLINE uint32_t x86GetArchFromCConv(uint32_t conv) { + return IntUtil::inInterval(conv, kX86FuncConvW64, kX86FuncConvU64) ? kArchX64 : kArchX86; +} + +// ============================================================================ +// [asmjit::X86FuncDecl - SetPrototype] +// ============================================================================ + +#define R(_Index_) kX86RegIndex##_Index_ +static uint32_t X86FuncDecl_initConv(X86FuncDecl* self, uint32_t arch, uint32_t conv) { + // Setup defaults. + self->_argStackSize = 0; + self->_redZoneSize = 0; + self->_spillZoneSize = 0; + + self->_convention = static_cast(conv); + self->_calleePopsStack = false; + self->_direction = kFuncDirRtl; + + self->_passed.reset(); + self->_preserved.reset(); + + ::memset(self->_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderGp)); + ::memset(self->_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)); + + // -------------------------------------------------------------------------- + // [X86 Support] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + self->_preserved.set(kX86RegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di))); + + switch (conv) { + case kX86FuncConvCDecl: + break; + + case kX86FuncConvStdCall: + self->_calleePopsStack = true; + break; + + case kX86FuncConvMsThisCall: + self->_calleePopsStack = true; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx))); + self->_passedOrderGp[0] = R(Cx); + break; + + case kX86FuncConvMsFastCall: + self->_calleePopsStack = true; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Cx))); + self->_passedOrderGp[0] = R(Cx); + self->_passedOrderGp[1] = R(Dx); + break; + + case kX86FuncConvBorlandFastCall: + self->_calleePopsStack = true; + self->_direction = kFuncDirLtr; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx))); + self->_passedOrderGp[0] = R(Ax); + self->_passedOrderGp[1] = R(Dx); + self->_passedOrderGp[2] = R(Cx); + break; + + case kX86FuncConvGccFastCall: + self->_calleePopsStack = true; + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Dx))); + self->_passedOrderGp[0] = R(Cx); + self->_passedOrderGp[1] = R(Dx); + break; + + case kX86FuncConvGccRegParm1: + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax))); + self->_passedOrderGp[0] = R(Ax); + break; + + case kX86FuncConvGccRegParm2: + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx))); + self->_passedOrderGp[0] = R(Ax); + self->_passedOrderGp[1] = R(Dx); + break; + + case kX86FuncConvGccRegParm3: + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Ax), R(Dx), R(Cx))); + self->_passedOrderGp[0] = R(Ax); + self->_passedOrderGp[1] = R(Dx); + self->_passedOrderGp[2] = R(Cx); + break; + + default: + ASMJIT_ASSERT(!"Reached"); + } + + return kErrorOk; + } +#endif // ASMJIT_BUILD_X86 + + // -------------------------------------------------------------------------- + // [X64 Support] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_BUILD_X64) + switch (conv) { + case kX86FuncConvW64: + self->_spillZoneSize = 32; + + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Cx), R(Dx), 8, 9)); + self->_passedOrderGp[0] = R(Cx); + self->_passedOrderGp[1] = R(Dx); + self->_passedOrderGp[2] = 8; + self->_passedOrderGp[3] = 9; + + self->_passed.set(kX86RegClassXyz, IntUtil::mask(0, 1, 2, 3)); + self->_passedOrderXmm[0] = 0; + self->_passedOrderXmm[1] = 1; + self->_passedOrderXmm[2] = 2; + self->_passedOrderXmm[3] = 3; + + self->_preserved.set(kX86RegClassGp , IntUtil::mask(R(Bx), R(Sp), R(Bp), R(Si), R(Di), 12, 13, 14, 15)); + self->_preserved.set(kX86RegClassXyz, IntUtil::mask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15)); + break; + + case kX86FuncConvU64: + self->_redZoneSize = 128; + + self->_passed.set(kX86RegClassGp, IntUtil::mask(R(Di), R(Si), R(Dx), R(Cx), 8, 9)); + self->_passedOrderGp[0] = R(Di); + self->_passedOrderGp[1] = R(Si); + self->_passedOrderGp[2] = R(Dx); + self->_passedOrderGp[3] = R(Cx); + self->_passedOrderGp[4] = 8; + self->_passedOrderGp[5] = 9; + + self->_passed.set(kX86RegClassXyz, IntUtil::mask(0, 1, 2, 3, 4, 5, 6, 7)); + self->_passedOrderXmm[0] = 0; + self->_passedOrderXmm[1] = 1; + self->_passedOrderXmm[2] = 2; + self->_passedOrderXmm[3] = 3; + self->_passedOrderXmm[4] = 4; + self->_passedOrderXmm[5] = 5; + self->_passedOrderXmm[6] = 6; + self->_passedOrderXmm[7] = 7; + + self->_preserved.set(kX86RegClassGp, IntUtil::mask(R(Bx), R(Sp), R(Bp), 12, 13, 14, 15)); + break; + + default: + ASMJIT_ASSERT(!"Reached"); + } +#endif // ASMJIT_BUILD_X64 + + return kErrorOk; +} +#undef R + +static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, + uint32_t ret, const uint32_t* argList, uint32_t argCount) { + + ASMJIT_ASSERT(argCount <= kFuncArgCount); + + uint32_t conv = self->_convention; + uint32_t regSize = (arch == kArchX86) ? 4 : 8; + + int32_t i = 0; + int32_t gpPos = 0; + int32_t xmmPos = 0; + int32_t stackOffset = 0; + + const uint8_t* varMapping; + +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) + varMapping = _x86VarMapping; +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) + varMapping = _x64VarMapping; +#endif // ASMJIT_BUILD_X64 + + self->_argCount = static_cast(argCount); + self->_retCount = 0; + + for (i = 0; i < static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + arg._varType = static_cast(varMapping[argList[i]]); + arg._regIndex = kInvalidReg; + arg._stackOffset = kFuncStackInvalid; + } + + for (; i < kFuncArgCount; i++) { + self->_argList[i].reset(); + } + + self->_retList[0].reset(); + self->_retList[1].reset(); + self->_argStackSize = 0; + self->_used.reset(); + + if (ret != kInvalidVar) { + ret = varMapping[ret]; + switch (ret) { + case kVarTypeInt64: + case kVarTypeUInt64: + // 64-bit value is returned in EDX:EAX on x86. +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + self->_retCount = 2; + self->_retList[0]._varType = kVarTypeUInt32; + self->_retList[0]._regIndex = kX86RegIndexAx; + self->_retList[1]._varType = static_cast(ret - 2); + self->_retList[1]._regIndex = kX86RegIndexDx; + } +#endif // ASMJIT_BUILD_X86 + // ... Fall through ... + + case kVarTypeInt8: + case kVarTypeUInt8: + case kVarTypeInt16: + case kVarTypeUInt16: + case kVarTypeInt32: + case kVarTypeUInt32: + self->_retCount = 1; + self->_retList[0]._varType = static_cast(ret); + self->_retList[0]._regIndex = kX86RegIndexAx; + break; + + case kX86VarTypeMm: + self->_retCount = 1; + self->_retList[0]._varType = static_cast(ret); + self->_retList[0]._regIndex = 0; + break; + + case kVarTypeFp32: + self->_retCount = 1; + if (arch == kArchX86) { + self->_retList[0]._varType = kVarTypeFp32; + self->_retList[0]._regIndex = 0; + } + else { + self->_retList[0]._varType = kX86VarTypeXmmSs; + self->_retList[0]._regIndex = 0; + } + break; + + case kVarTypeFp64: + self->_retCount = 1; + if (arch == kArchX86) { + self->_retList[0]._varType = kVarTypeFp64; + self->_retList[0]._regIndex = 0; + } + else { + self->_retList[0]._varType = kX86VarTypeXmmSd; + self->_retList[0]._regIndex = 0; + break; + } + break; + + case kX86VarTypeXmm: + case kX86VarTypeXmmSs: + case kX86VarTypeXmmSd: + case kX86VarTypeXmmPs: + case kX86VarTypeXmmPd: + self->_retCount = 1; + self->_retList[0]._varType = static_cast(ret); + self->_retList[0]._regIndex = 0; + break; + } + } + + if (self->_argCount == 0) + return kErrorOk; + +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + // Register arguments (Integer), always left-to-right. + for (i = 0; i != static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (!x86ArgIsInt(varType) || gpPos >= ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) + continue; + + if (self->_passedOrderGp[gpPos] == kInvalidReg) + continue; + + arg._regIndex = self->_passedOrderGp[gpPos++]; + self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + } + + // Stack arguments. + int32_t iStart = static_cast(argCount - 1); + int32_t iEnd = -1; + int32_t iStep = -1; + + if (self->_direction == kFuncDirLtr) { + iStart = 0; + iEnd = static_cast(argCount); + iStep = 1; + } + + for (i = iStart; i != iEnd; i += iStep) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (arg.hasRegIndex()) + continue; + + if (x86ArgIsInt(varType)) { + stackOffset -= 4; + arg._stackOffset = static_cast(stackOffset); + } + else if (x86ArgIsFp(varType)) { + int32_t size = static_cast(_x86VarInfo[varType].getSize()); + stackOffset -= size; + arg._stackOffset = static_cast(stackOffset); + } + } + } +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) { + if (conv == kX86FuncConvW64) { + int32_t argMax = IntUtil::iMin(argCount, 4); + + // Register arguments (Gp/Xmm), always left-to-right. + for (i = 0; i != argMax; i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (x86ArgIsInt(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) { + arg._regIndex = self->_passedOrderGp[i]; + self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + continue; + } + + if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) { + arg._varType = static_cast(x86ArgTypeToXmmType(varType)); + arg._regIndex = self->_passedOrderXmm[i]; + self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); + } + } + + // Stack arguments (always right-to-left). + for (i = argCount - 1; i != -1; i--) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (arg.hasRegIndex()) + continue; + + if (x86ArgIsInt(varType)) { + stackOffset -= 8; // Always 8 bytes. + arg._stackOffset = stackOffset; + } + else if (x86ArgIsFp(varType)) { + stackOffset -= 8; // Always 8 bytes (float/double). + arg._stackOffset = stackOffset; + } + } + + // 32 bytes shadow space (X64W calling convention specific). + stackOffset -= 4 * 8; + } + else { + // Register arguments (Gp), always left-to-right. + for (i = 0; i != static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (!x86ArgIsInt(varType) || gpPos >= ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) + continue; + + if (self->_passedOrderGp[gpPos] == kInvalidReg) + continue; + + arg._regIndex = self->_passedOrderGp[gpPos++]; + self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + } + + // Register arguments (Xmm), always left-to-right. + for (i = 0; i != static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (x86ArgIsFp(varType)) { + arg._varType = static_cast(x86ArgTypeToXmmType(varType)); + arg._regIndex = self->_passedOrderXmm[xmmPos++]; + self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); + } + } + + // Stack arguments. + for (i = argCount - 1; i != -1; i--) { + FuncInOut& arg = self->getArg(i); + uint32_t varType = varMapping[arg.getVarType()]; + + if (arg.hasRegIndex()) + continue; + + if (x86ArgIsInt(varType)) { + stackOffset -= 8; + arg._stackOffset = static_cast(stackOffset); + } + else if (x86ArgIsFp(varType)) { + int32_t size = static_cast(_x86VarInfo[varType].getSize()); + + stackOffset -= size; + arg._stackOffset = static_cast(stackOffset); + } + } + } + } +#endif // ASMJIT_BUILD_X64 + + // Modify the stack offset, thus in result all parameters would have positive + // non-zero stack offset. + for (i = 0; i < static_cast(argCount); i++) { + FuncInOut& arg = self->getArg(i); + if (!arg.hasRegIndex()) { + arg._stackOffset += static_cast(static_cast(regSize) - stackOffset); + } + } + + self->_argStackSize = static_cast(-stackOffset); + return kErrorOk; +} + +Error X86FuncDecl::setPrototype(uint32_t conv, const FuncPrototype& p) { + if (conv == kFuncConvNone || conv >= _kX86FuncConvCount) + return kErrorInvalidArgument; + + if (p.getArgCount() > kFuncArgCount) + return kErrorInvalidArgument; + + // Validate that the required convention is supported by the current asmjit + // configuration, if only one target is compiled. + uint32_t arch = x86GetArchFromCConv(conv); +#if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) + return kErrorInvalidState; +#endif // ASMJIT_BUILD_X86 && !ASMJIT_BUILD_X64 + +#if !defined(ASMJIT_BUILD_X86) && defined(ASMJIT_BUILD_X64) + if (arch == kArchX86) + return kErrorInvalidState; +#endif // !ASMJIT_BUILD_X86 && ASMJIT_BUILD_X64 + + ASMJIT_PROPAGATE_ERROR(X86FuncDecl_initConv(this, arch, conv)); + ASMJIT_PROPAGATE_ERROR(X86FuncDecl_initFunc(this, arch, p.getRet(), p.getArgList(), p.getArgCount())); + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86FuncDecl - Reset] +// ============================================================================ + +void X86FuncDecl::reset() { + uint32_t i; + + _convention = kFuncConvNone; + _calleePopsStack = false; + _direction = kFuncDirRtl; + _reserved0 = 0; + + _argCount = 0; + _retCount = 0; + + _argStackSize = 0; + _redZoneSize = 0; + _spillZoneSize = 0; + + for (i = 0; i < ASMJIT_ARRAY_SIZE(_argList); i++) { + _argList[i].reset(); + } + + _retList[0].reset(); + _retList[1].reset(); + + _used.reset(); + _passed.reset(); + _preserved.reset(); + + ::memset(_passedOrderGp, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderGp)); + ::memset(_passedOrderXmm, kInvalidReg, ASMJIT_ARRAY_SIZE(_passedOrderXmm)); +} + +// ============================================================================ +// [asmjit::X86CallNode - Prototype] +// ============================================================================ + +Error X86CallNode::setPrototype(uint32_t conv, const FuncPrototype& p) { + return _x86Decl.setPrototype(conv, p); +} + +// ============================================================================ +// [asmjit::X86CallNode - Arg / Ret] +// ============================================================================ + +bool X86CallNode::_setArg(uint32_t i, const Operand& op) { + if ((i & ~kFuncArgHi) >= _x86Decl.getArgCount()) + return false; + + _args[i] = op; + return true; +} + +bool X86CallNode::_setRet(uint32_t i, const Operand& op) { + if (i >= 2) + return false; + + _ret[i] = op; + return true; +} + +// ============================================================================ +// [asmjit::X86Compiler - Helpers (Private)] +// ============================================================================ + +static Error X86Compiler_emitConstPool(X86Compiler* self, + Label& label, ConstPool& pool) { + + if (label.getId() == kInvalidValue) + return kErrorOk; + + self->align(kAlignData, static_cast(pool.getAlignment())); + self->bind(label); + + EmbedNode* embedNode = self->embed(NULL, static_cast(pool.getSize())); + if (embedNode == NULL) + return kErrorNoHeapMemory; + + pool.fill(embedNode->getData()); + pool.reset(); + label.reset(); + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Compiler - Construction / Destruction] +// ============================================================================ + +X86Compiler::X86Compiler(Runtime* runtime, uint32_t arch) : + Compiler(runtime), + zax(NoInit), + zcx(NoInit), + zdx(NoInit), + zbx(NoInit), + zsp(NoInit), + zbp(NoInit), + zsi(NoInit), + zdi(NoInit) { + + setArch(arch); +} + +X86Compiler::~X86Compiler() {} + +// ============================================================================ +// [asmjit::X86Compiler - Arch] +// ============================================================================ + +Error X86Compiler::setArch(uint32_t arch) { +#if defined(ASMJIT_BUILD_X86) + if (arch == kArchX86) { + _arch = kArchX86; + _regSize = 4; + + _regCount.reset(); + _regCount._gp = 8; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 8; + + zax = x86::eax; + zcx = x86::ecx; + zdx = x86::edx; + zbx = x86::ebx; + zsp = x86::esp; + zbp = x86::ebp; + zsi = x86::esi; + zdi = x86::edi; + + _targetVarMapping = _x86VarMapping; + return kErrorOk; + } +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) + if (arch == kArchX64) { + _arch = kArchX64; + _regSize = 8; + + _regCount.reset(); + _regCount._gp = 16; + _regCount._fp = 8; + _regCount._mm = 8; + _regCount._xy = 16; + + zax = x86::rax; + zcx = x86::rcx; + zdx = x86::rdx; + zbx = x86::rbx; + zsp = x86::rsp; + zbp = x86::rbp; + zsi = x86::rsi; + zdi = x86::rdi; + + _targetVarMapping = _x64VarMapping; + return kErrorOk; + } +#endif // ASMJIT_BUILD_X64 + + ASMJIT_ASSERT(!"Reached"); + return kErrorInvalidArgument; +} + +// ============================================================================ +// [asmjit::X86Compiler - Inst] +// ============================================================================ + +//! Get compiler instruction item size without operands assigned. +static ASMJIT_INLINE size_t X86Compiler_getInstSize(uint32_t code) { + return IntUtil::inInterval(code, _kX86InstIdJbegin, _kX86InstIdJend) ? sizeof(JumpNode) : sizeof(InstNode); +} + +static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) { + if (IntUtil::inInterval(code, _kX86InstIdJbegin, _kX86InstIdJend)) { + JumpNode* node = new(p) JumpNode(self, code, options, opList, opCount); + TargetNode* jTarget = self->getTargetById(opList[0].getId()); + + node->addFlags(code == kX86InstIdJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc); + node->_target = jTarget; + node->_jumpNext = static_cast(jTarget->_from); + + jTarget->_from = node; + jTarget->addNumRefs(); + + // The 'jmp' is always taken, conditional jump can contain hint, we detect it. + if (code == kX86InstIdJmp) + node->addFlags(kNodeFlagIsTaken); + else if (options & kInstOptionTaken) + node->addFlags(kNodeFlagIsTaken); + + node->addOptions(options); + return node; + } + else { + InstNode* node = new(p) InstNode(self, code, options, opList, opCount); + node->addOptions(options); + return node; + } +} + +InstNode* X86Compiler::newInst(uint32_t code) { + size_t size = X86Compiler_getInstSize(code); + InstNode* inst = static_cast(_baseZone.alloc(size)); + + if (inst == NULL) + goto _NoMemory; + + return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), NULL, 0); + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0) { + size_t size = X86Compiler_getInstSize(code); + InstNode* inst = static_cast(_baseZone.alloc(size + 1 * sizeof(Operand))); + + if (inst == NULL) + goto _NoMemory; + + { + Operand* opList = reinterpret_cast(reinterpret_cast(inst) + size); + opList[0] = o0; + ASMJIT_ASSERT_UNINITIALIZED(o0); + return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 1); + } + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1) { + size_t size = X86Compiler_getInstSize(code); + InstNode* inst = static_cast(_baseZone.alloc(size + 2 * sizeof(Operand))); + + if (inst == NULL) + goto _NoMemory; + + { + Operand* opList = reinterpret_cast(reinterpret_cast(inst) + size); + opList[0] = o0; + opList[1] = o1; + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 2); + } + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { + size_t size = X86Compiler_getInstSize(code); + InstNode* inst = static_cast(_baseZone.alloc(size + 3 * sizeof(Operand))); + + if (inst == NULL) + goto _NoMemory; + + { + Operand* opList = reinterpret_cast(reinterpret_cast(inst) + size); + opList[0] = o0; + opList[1] = o1; + opList[2] = o2; + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + ASMJIT_ASSERT_UNINITIALIZED(o2); + return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 3); + } + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) { + size_t size = X86Compiler_getInstSize(code); + InstNode* inst = static_cast(_baseZone.alloc(size + 4 * sizeof(Operand))); + + if (inst == NULL) + goto _NoMemory; + + { + Operand* opList = reinterpret_cast(reinterpret_cast(inst) + size); + opList[0] = o0; + opList[1] = o1; + opList[2] = o2; + opList[3] = o3; + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + ASMJIT_ASSERT_UNINITIALIZED(o2); + ASMJIT_ASSERT_UNINITIALIZED(o3); + return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 4); + } + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +InstNode* X86Compiler::newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) { + size_t size = X86Compiler_getInstSize(code); + InstNode* inst = static_cast(_baseZone.alloc(size + 5 * sizeof(Operand))); + + if (inst == NULL) + goto _NoMemory; + + { + Operand* opList = reinterpret_cast(reinterpret_cast(inst) + size); + opList[0] = o0; + opList[1] = o1; + opList[2] = o2; + opList[3] = o3; + opList[4] = o4; + ASMJIT_ASSERT_UNINITIALIZED(o0); + ASMJIT_ASSERT_UNINITIALIZED(o1); + ASMJIT_ASSERT_UNINITIALIZED(o2); + ASMJIT_ASSERT_UNINITIALIZED(o3); + ASMJIT_ASSERT_UNINITIALIZED(o4); + return X86Compiler_newInst(this, inst, code, getInstOptionsAndReset(), opList, 5); + } + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +InstNode* X86Compiler::emit(uint32_t code) { + InstNode* node = newInst(code); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0) { + InstNode* node = newInst(code, o0); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1){ + InstNode* node = newInst(code, o0, o1); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2) { + InstNode* node = newInst(code, o0, o1, o2); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3){ + InstNode* node = newInst(code, o0, o1, o2, o3); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4) { + InstNode* node = newInst(code, o0, o1, o2, o3, o4); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, int o0_) { + Imm o0(o0_); + InstNode* node = newInst(code, o0); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, uint64_t o0_) { + Imm o0(o0_); + InstNode* node = newInst(code, o0); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, int o1_) { + Imm o1(o1_); + InstNode* node = newInst(code, o0, o1); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, uint64_t o1_) { + Imm o1(o1_); + InstNode* node = newInst(code, o0, o1); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2_) { + Imm o2(o2_); + InstNode* node = newInst(code, o0, o1, o2); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2_) { + Imm o2(o2_); + InstNode* node = newInst(code, o0, o1, o2); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +// ============================================================================ +// [asmjit::X86Compiler - Func] +// ============================================================================ + +X86FuncNode* X86Compiler::newFunc(uint32_t conv, const FuncPrototype& p) { + X86FuncNode* func = newNode(); + Error error; + + if (func == NULL) + goto _NoMemory; + + // Create helper nodes. + func->_entryNode = newTarget(); + func->_exitNode = newTarget(); + func->_end = newNode(); + + if (func->_entryNode == NULL || func->_exitNode == NULL || func->_end == NULL) + goto _NoMemory; + + // Emit push/pop sequence by default. + func->_funcHints |= IntUtil::mask(kX86FuncHintPushPop); + + // Function prototype. + if ((error = func->_x86Decl.setPrototype(conv, p)) != kErrorOk) { + setError(error); + return NULL; + } + + // Function arguments stack size. Since function requires _argStackSize to be + // set, we have to copy it from X86FuncDecl. + func->_argStackSize = func->_x86Decl.getArgStackSize(); + func->_redZoneSize = static_cast(func->_x86Decl.getRedZoneSize()); + func->_spillZoneSize = static_cast(func->_x86Decl.getSpillZoneSize()); + + // Expected/Required stack alignment. + func->_expectedStackAlignment = getRuntime()->getStackAlignment(); + func->_requiredStackAlignment = 0; + + // Allocate space for function arguments. + func->_argList = NULL; + if (func->getArgCount() != 0) { + func->_argList = _baseZone.allocT(func->getArgCount() * sizeof(VarData*)); + if (func->_argList == NULL) + goto _NoMemory; + ::memset(func->_argList, 0, func->getArgCount() * sizeof(VarData*)); + } + + return func; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +X86FuncNode* X86Compiler::addFunc(uint32_t conv, const FuncPrototype& p) { + X86FuncNode* func = newFunc(conv, p); + + if (func == NULL) { + setError(kErrorNoHeapMemory); + return NULL; + } + + ASMJIT_ASSERT(_func == NULL); + _func = func; + + addNode(func); + addNode(func->getEntryNode()); + + return func; +} + +EndNode* X86Compiler::endFunc() { + X86FuncNode* func = getFunc(); + ASMJIT_ASSERT(func != NULL); + + // App function exit / epilog marker. + addNode(func->getExitNode()); + + // Add local constant pool at the end of the function (if exist). + X86Compiler_emitConstPool(this, _localConstPoolLabel, _localConstPool); + + // Add function end marker. + addNode(func->getEnd()); + + // Finalize... + func->addFuncFlags(kFuncFlagIsFinished); + _func = NULL; + + return func->getEnd(); +} + +// ============================================================================ +// [asmjit::X86Compiler - Ret] +// ============================================================================ + +RetNode* X86Compiler::newRet(const Operand& o0, const Operand& o1) { + RetNode* node = newNode(o0, o1); + if (node == NULL) + goto _NoMemory; + return node; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +RetNode* X86Compiler::addRet(const Operand& o0, const Operand& o1) { + RetNode* node = newRet(o0, o1); + if (node == NULL) + return node; + return static_cast(addNode(node)); +} + +// ============================================================================ +// [asmjit::X86Compiler - Call] +// ============================================================================ + +X86CallNode* X86Compiler::newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) { + X86CallNode* node = newNode(o0); + Error error; + uint32_t nArgs; + + if (node == NULL) + goto _NoMemory; + + if ((error = node->_x86Decl.setPrototype(conv, p)) != kErrorOk) { + setError(error); + return NULL; + } + + // If there are no arguments skip the allocation. + if ((nArgs = p.getArgCount()) == 0) + return node; + + node->_args = static_cast(_baseZone.alloc(nArgs * sizeof(Operand))); + if (node->_args == NULL) + goto _NoMemory; + + ::memset(node->_args, 0, nArgs * sizeof(Operand)); + return node; + +_NoMemory: + setError(kErrorNoHeapMemory); + return NULL; +} + +X86CallNode* X86Compiler::addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p) { + X86CallNode* node = newCall(o0, conv, p); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +// ============================================================================ +// [asmjit::X86Compiler - Vars] +// ============================================================================ + +Error X86Compiler::setArg(uint32_t argIndex, Var& var) { + X86FuncNode* func = getFunc(); + + if (func == NULL) + return kErrorInvalidArgument; + + if (!isVarValid(var)) + return kErrorInvalidState; + + VarData* vd = getVd(var); + func->setArg(argIndex, vd); + + return kErrorOk; +} + +Error X86Compiler::_newVar(Var* var, uint32_t vType, const char* name) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + + vType = _targetVarMapping[vType]; + ASMJIT_ASSERT(vType != kInvalidVar); + + // There is not ASSERT in release mode and this should be checked. + if (vType == kInvalidVar) { + static_cast(var)->reset(); + return kErrorInvalidArgument; + } + + const X86VarInfo& vInfo = _x86VarInfo[vType]; + VarData* vd = _newVd(vType, vInfo.getSize(), vInfo.getClass(), name); + + if (vd == NULL) { + static_cast(var)->reset(); + return getError(); + } + + var->_init_packed_op_sz_w0_id(kOperandTypeVar, vd->getSize(), vInfo.getReg() << 8, vd->getId()); + var->_vreg.vType = vType; + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Compiler - Stack] +// ============================================================================ + +Error X86Compiler::_newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name) { + if (size == 0) + return kErrorInvalidArgument; + + if (alignment > 64) + alignment = 64; + + VarData* vd = _newVd(kInvalidVar, size, kInvalidReg, name); + if (vd == NULL) { + static_cast(mem)->reset(); + return getError(); + } + + vd->_isStack = true; + vd->_alignment = static_cast(alignment); + + static_cast(mem)->_init(kMemTypeStackIndex, vd->getId(), 0, 0); + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Compiler - Const] +// ============================================================================ + +Error X86Compiler::_newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size) { + Error error = kErrorOk; + size_t offset; + + Label* dstLabel; + ConstPool* dstPool; + + if (scope == kConstScopeLocal) { + dstLabel = &_localConstPoolLabel; + dstPool = &_localConstPool; + } + else if (scope == kConstScopeGlobal) { + dstLabel = &_globalConstPoolLabel; + dstPool = &_globalConstPool; + } + else { + error = kErrorInvalidArgument; + goto _OnError; + } + + error = dstPool->add(data, size, offset); + if (error != kErrorOk) + goto _OnError; + + if (dstLabel->getId() == kInvalidValue) { + error = _newLabel(dstLabel); + if (error != kErrorOk) + goto _OnError; + } + + *static_cast(mem) = x86::ptr(*dstLabel, static_cast(offset), static_cast(size)); + return kErrorOk; + +_OnError: + return error; +} + +// ============================================================================ +// [asmjit::X86Compiler - Make] +// ============================================================================ + +void* X86Compiler::make() { + Assembler* assembler = getAssembler(); + if (assembler == NULL) { + setError(kErrorNoHeapMemory); + return NULL; + } + + Error error = serialize(assembler); + if (error != kErrorOk) { + setError(error); + return NULL; + } + + void* result = assembler->make(); + return result; +} + +// ============================================================================ +// [asmjit::X86Compiler - Assembler] +// ============================================================================ + +Assembler* X86Compiler::_newAssembler() { + return new(std::nothrow) X86Assembler(_runtime, _arch); +} + +// ============================================================================ +// [asmjit::X86Compiler - Serialize] +// ============================================================================ + +Error X86Compiler::serialize(Assembler* assembler) { + // Flush the global constant pool. + X86Compiler_emitConstPool(this, _globalConstPoolLabel, _globalConstPool); + + if (_firstNode == NULL) + return kErrorOk; + + X86Context context(this); + Error error = kErrorOk; + + Node* node = _firstNode; + Node* start; + + // Find function and use the context to translate/emit. + do { + start = node; + + if (node->getType() == kNodeTypeFunc) { + node = static_cast(start)->getEnd(); + error = context.compile(static_cast(start)); + + if (error != kErrorOk) + goto _Error; + } + + do { + node = node->getNext(); + } while (node != NULL && node->getType() != kNodeTypeFunc); + + error = context.serialize(assembler, start, node); + if (error != kErrorOk) + goto _Error; + context.cleanup(); + } while (node != NULL); + return kErrorOk; + +_Error: + context.cleanup(); + return error; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64) diff --git a/libraries/asmjit/x86/x86compiler.h b/libraries/asmjit/x86/x86compiler.h new file mode 100644 index 000000000..2a71bcd31 --- /dev/null +++ b/libraries/asmjit/x86/x86compiler.h @@ -0,0 +1,5489 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86COMPILER_H +#define _ASMJIT_X86_X86COMPILER_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/compiler.h" +#include "../base/vectypes.h" +#include "../x86/x86assembler.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86CallNode; +struct X86FuncNode; +struct X86VarState; + +//! \addtogroup asmjit_x86_compiler +//! \{ + +// ============================================================================ +// [asmjit::k86VarType] +// ============================================================================ + +//! X86/X64 variable type. +ASMJIT_ENUM(kX86VarType) { + //! Variable is SP-FP (x87). + kX86VarTypeFp32 = kVarTypeFp32, + //! Variable is DP-FP (x87). + kX86VarTypeFp64 = kVarTypeFp64, + + //! Variable is Mm (MMX). + kX86VarTypeMm = 12, + + //! Variable is Xmm (SSE+). + kX86VarTypeXmm, + //! Variable is scalar Xmm SP-FP number. + kX86VarTypeXmmSs, + //! Variable is packed Xmm SP-FP number (4 floats). + kX86VarTypeXmmPs, + //! Variable is scalar Xmm DP-FP number. + kX86VarTypeXmmSd, + //! Variable is packed Xmm DP-FP number (2 doubles). + kX86VarTypeXmmPd, + + //! Variable is Ymm (AVX+). + kX86VarTypeYmm, + //! Variable is packed Ymm SP-FP number (8 floats). + kX86VarTypeYmmPs, + //! Variable is packed Ymm DP-FP number (4 doubles). + kX86VarTypeYmmPd, + + //! Count of variable types. + kX86VarTypeCount, + + //! \internal + //! \{ + _kX86VarTypeMmStart = kX86VarTypeMm, + _kX86VarTypeMmEnd = kX86VarTypeMm, + + _kX86VarTypeXmmStart = kX86VarTypeXmm, + _kX86VarTypeXmmEnd = kX86VarTypeXmmPd, + + _kX86VarTypeYmmStart = kX86VarTypeYmm, + _kX86VarTypeYmmEnd = kX86VarTypeYmmPd + //! \} +}; + +// ============================================================================ +// [asmjit::kX86VarAttr] +// ============================================================================ + +//! X86/X64 VarAttr flags. +ASMJIT_ENUM(kX86VarAttr) { + kX86VarAttrGpbLo = 0x10000000, + kX86VarAttrGpbHi = 0x20000000 +}; + +// ============================================================================ +// [asmjit::kX86FuncConv] +// ============================================================================ + +//! X86 function calling conventions. +//! +//! Calling convention is scheme how function arguments are passed into +//! function and how functions returns values. In assembler programming +//! it's needed to always comply with function calling conventions, because +//! even small inconsistency can cause undefined behavior or crash. +//! +//! List of calling conventions for 32-bit x86 mode: +//! - `kX86FuncConvCDecl` - Calling convention for C runtime. +//! - `kX86FuncConvStdCall` - Calling convention for WinAPI functions. +//! - `kX86FuncConvMsThisCall` - Calling convention for C++ members under +//! Windows (produced by MSVC and all MSVC compatible compilers). +//! - `kX86FuncConvMsFastCall` - Fastest calling convention that can be used +//! by MSVC compiler. +//! - `kX86FuncConvBorlandFastCall` - Borland fastcall convention. +//! - `kX86FuncConvGccFastCall` - GCC fastcall convention (2 register arguments). +//! - `kX86FuncConvGccRegParm1` - GCC regparm(1) convention. +//! - `kX86FuncConvGccRegParm2` - GCC regparm(2) convention. +//! - `kX86FuncConvGccRegParm3` - GCC regparm(3) convention. +//! +//! List of calling conventions for 64-bit x86 mode (x64): +//! - `kX86FuncConvW64` - Windows 64-bit calling convention (WIN64 ABI). +//! - `kX86FuncConvU64` - Unix 64-bit calling convention (AMD64 ABI). +//! +//! There is also `kFuncConvHost` that is defined to fit the host calling +//! convention. +//! +//! These types are used together with `Compiler::addFunc()` method. +ASMJIT_ENUM(kX86FuncConv) { + // -------------------------------------------------------------------------- + // [X64] + // -------------------------------------------------------------------------- + + //! X64 calling convention for Windows platform (WIN64 ABI). + //! + //! For first four arguments are used these registers: + //! - 1. 32/64-bit integer or floating point argument - rcx/xmm0 + //! - 2. 32/64-bit integer or floating point argument - rdx/xmm1 + //! - 3. 32/64-bit integer or floating point argument - r8/xmm2 + //! - 4. 32/64-bit integer or floating point argument - r9/xmm3 + //! + //! Note first four arguments here means arguments at positions from 1 to 4 + //! (included). For example if second argument is not passed in register then + //! rdx/xmm1 register is unused. + //! + //! All other arguments are pushed on the stack in right-to-left direction. + //! Stack is aligned by 16 bytes. There is 32-byte shadow space on the stack + //! that can be used to save up to four 64-bit registers (probably designed to + //! be used to save first four arguments passed in registers). + //! + //! Arguments direction: + //! - Right to Left (except for first 4 parameters that's in registers) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - Rax register. + //! - Floating points - Xmm0 register. + //! + //! Stack is always aligned by 16 bytes. + //! + //! More information about this calling convention can be found on MSDN: + //! http://msdn.microsoft.com/en-us/library/9b372w95.aspx . + kX86FuncConvW64 = 1, + + //! X64 calling convention for Unix platforms (AMD64 ABI). + //! + //! First six 32 or 64-bit integer arguments are passed in rdi, rsi, rdx, + //! rcx, r8, r9 registers. First eight floating point or Xmm arguments + //! are passed in xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 registers. + //! This means that in registers can be transferred up to 14 arguments total. + //! + //! There is also RED ZONE below the stack pointer that can be used for + //! temporary storage. The red zone is the space from [rsp-128] to [rsp-8]. + //! + //! Arguments direction: + //! - Right to Left (Except for arguments passed in registers). + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - Rax register. + //! - Floating points - Xmm0 register. + //! + //! Stack is always aligned by 16 bytes. + kX86FuncConvU64 = 2, + + // -------------------------------------------------------------------------- + // [X86] + // -------------------------------------------------------------------------- + + //! Cdecl calling convention (used by C runtime). + //! + //! Compatible across MSVC and GCC. + //! + //! Arguments direction: + //! - Right to Left + //! + //! Stack is cleaned by: + //! - Caller. + kX86FuncConvCDecl = 3, + + //! Stdcall calling convention (used by WinAPI). + //! + //! Compatible across MSVC and GCC. + //! + //! Arguments direction: + //! - Right to Left + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvStdCall = 4, + + //! MSVC specific calling convention used by MSVC/Intel compilers + //! for struct/class methods. + //! + //! This is MSVC (and Intel) only calling convention used in Windows + //! world for C++ class methods. Implicit 'this' pointer is stored in + //! ECX register instead of storing it on the stack. + //! + //! Arguments direction: + //! - Right to Left (except this pointer in ECX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! C++ class methods that have variable count of arguments uses different + //! calling convention called cdecl. + //! + //! \note This calling convention is always used by MSVC for class methods, + //! it's implicit and there is no way how to override it. + kX86FuncConvMsThisCall = 5, + + //! MSVC specific fastcall. + //! + //! Two first parameters (evaluated from left-to-right) are in ECX:EDX + //! registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first two integer arguments in ECX:EDX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! \note This calling convention differs to GCC one in stack cleaning + //! mechanism. + kX86FuncConvMsFastCall = 6, + + //! Borland specific fastcall with 2 parameters in registers. + //! + //! Two first parameters (evaluated from left-to-right) are in ECX:EDX + //! registers, all others on the stack in left-to-right order. + //! + //! Arguments direction: + //! - Left to Right (except to first two integer arguments in ECX:EDX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! \note Arguments on the stack are in left-to-right order that differs + //! to other fastcall conventions used in different compilers. + kX86FuncConvBorlandFastCall = 7, + + //! GCC specific fastcall convention. + //! + //! Two first parameters (evaluated from left-to-right) are in ECX:EDX + //! registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first two integer arguments in ECX:EDX) + //! + //! Stack is cleaned by: + //! - Callee. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + //! + //! \note This calling convention should be compatible with `kX86FuncConvMsFastCall`. + kX86FuncConvGccFastCall = 8, + + //! GCC specific regparm(1) convention. + //! + //! The first parameter (evaluated from left-to-right) is in EAX register, + //! all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first one integer argument in EAX) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvGccRegParm1 = 9, + + //! GCC specific regparm(2) convention. + //! + //! Two first parameters (evaluated from left-to-right) are in EAX:EDX + //! registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first two integer arguments in EAX:EDX) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvGccRegParm2 = 10, + + //! GCC specific fastcall with 3 parameters in registers. + //! + //! Three first parameters (evaluated from left-to-right) are in + //! EAX:EDX:ECX registers, all others on the stack in right-to-left order. + //! + //! Arguments direction: + //! - Right to Left (except to first three integer arguments in EAX:EDX:ECX) + //! + //! Stack is cleaned by: + //! - Caller. + //! + //! Return value: + //! - Integer types - EAX:EDX registers. + //! - Floating points - fp0 register. + kX86FuncConvGccRegParm3 = 11, + + //! \internal + //! + //! Count of function calling conventions. + _kX86FuncConvCount = 12 +}; + +#if !defined(ASMJIT_DOCGEN) +// X86/X64 Host Support - documented in base/compiler.h. +#if defined(ASMJIT_HOST_X86) +enum { + // X86. + kFuncConvHost = kX86FuncConvCDecl, + kFuncConvHostCDecl = kX86FuncConvCDecl, + kFuncConvHostStdCall = kX86FuncConvStdCall, +#if defined(_MSC_VER) + kFuncConvHostFastCall = kX86FuncConvMsFastCall +#elif defined(__GNUC__) + kFuncConvHostFastCall = kX86FuncConvGccFastCall +#elif defined(__BORLANDC__) + kFuncConvHostFastCall = kX86FuncConvBorlandFastCall +#else +#error "kFuncConvHostFastCall not determined." +#endif +}; +#endif // ASMJIT_HOST_X86 + +#if defined(ASMJIT_HOST_X64) +enum { +#if defined(ASMJIT_OS_WINDOWS) + kFuncConvHost = kX86FuncConvW64, +#else + kFuncConvHost = kX86FuncConvU64, +#endif + kFuncConvHostCDecl = kFuncConvHost, + kFuncConvHostStdCall = kFuncConvHost, + kFuncConvHostFastCall = kFuncConvHost +}; +#endif // ASMJIT_HOST_X64 +#endif // !ASMJIT_DOCGEN + +// ============================================================================ +// [asmjit::kX86FuncHint] +// ============================================================================ + +//! X86 function hints. +ASMJIT_ENUM(kX86FuncHint) { + //! Use push/pop sequences instead of mov sequences in function prolog + //! and epilog. + kX86FuncHintPushPop = 16, + //! Add emms instruction to the function epilog. + kX86FuncHintEmms = 17, + //! Add sfence instruction to the function epilog. + kX86FuncHintSFence = 18, + //! Add lfence instruction to the function epilog. + kX86FuncHintLFence = 19 +}; + +// ============================================================================ +// [asmjit::kX86FuncFlags] +// ============================================================================ + +//! X86 function flags. +ASMJIT_ENUM(kX86FuncFlags) { + //! Whether to emit register load/save sequence using push/pop pairs. + kX86FuncFlagPushPop = 0x00010000, + + //! Whether to emit `enter` instead of three instructions in case + //! that the function is not naked or misaligned. + kX86FuncFlagEnter = 0x00020000, + + //! Whether to emit `leave` instead of two instructions in case + //! that the function is not naked or misaligned. + kX86FuncFlagLeave = 0x00040000, + + //! Whether it's required to move arguments to a new stack location, + //! because of manual aligning. + kX86FuncFlagMoveArgs = 0x00080000, + + //! Whether to emit `emms` instruction in epilog (auto-detected). + kX86FuncFlagEmms = 0x01000000, + + //! Whether to emit `sfence` instruction in epilog (auto-detected). + //! + //! `kX86FuncFlagSFence` with `kX86FuncFlagLFence` results in emitting `mfence`. + kX86FuncFlagSFence = 0x02000000, + + //! Whether to emit `lfence` instruction in epilog (auto-detected). + //! + //! `kX86FuncFlagSFence` with `kX86FuncFlagLFence` results in emitting `mfence`. + kX86FuncFlagLFence = 0x04000000 +}; + +// ============================================================================ +// [asmjit::X86VarInfo] +// ============================================================================ + +//! \internal +//! +//! X86 variable information. +struct X86VarInfo { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get register type, see `kX86RegType`. + ASMJIT_INLINE uint32_t getReg() const { return _reg; } + //! Get register size in bytes. + ASMJIT_INLINE uint32_t getSize() const { return _size; } + //! Get variable class, see `kRegClass`. + ASMJIT_INLINE uint32_t getClass() const { return _class; } + //! Get variable description, see `kVarFlag`. + ASMJIT_INLINE uint32_t getDesc() const { return _desc; } + //! Get variable type name. + ASMJIT_INLINE const char* getName() const { return _name; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Register type, see `kX86RegType`. + uint8_t _reg; + //! Register size in bytes. + uint8_t _size; + //! Register class, see `kRegClass`. + uint8_t _class; + //! Variable flags, see `kVarFlag`. + uint8_t _desc; + //! Variable type name. + char _name[4]; +}; + +//! \internal +ASMJIT_VAR const X86VarInfo _x86VarInfo[]; + +#if defined(ASMJIT_BUILD_X86) +//! \internal +//! +//! Mapping of x86 variables into their real IDs. +//! +//! This mapping translates the following: +//! - `kVarTypeInt64` to `kInvalidVar`. +//! - `kVarTypeUInt64` to `kInvalidVar`. +//! - `kVarTypeIntPtr` to `kVarTypeInt32`. +//! - `kVarTypeUIntPtr` to `kVarTypeUInt32`. +ASMJIT_VAR const uint8_t _x86VarMapping[kX86VarTypeCount]; +#endif // ASMJIT_BUILD_X86 + +#if defined(ASMJIT_BUILD_X64) +//! \internal +//! +//! Mapping of x64 variables into their real IDs. +//! +//! This mapping translates the following: +//! - `kVarTypeIntPtr` to `kVarTypeInt64`. +//! - `kVarTypeUIntPtr` to `kVarTypeUInt64`. +ASMJIT_VAR const uint8_t _x64VarMapping[kX86VarTypeCount]; +#endif // ASMJIT_BUILD_X64 + +// ============================================================================ +// [asmjit::X86Var] +// ============================================================================ + +//! Base class for all X86 variables. +struct X86Var : public Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Var() : Var(NoInit) { + reset(); + } + + ASMJIT_INLINE X86Var(const X86Var& other) : Var(other) {} + + explicit ASMJIT_INLINE X86Var(const _NoInit&) : Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86Var Specific] + // -------------------------------------------------------------------------- + + //! Clone X86Var operand. + ASMJIT_INLINE X86Var clone() const { + return X86Var(*this); + } + + //! Reset X86Var operand. + ASMJIT_INLINE void reset() { + _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, kInvalidValue); + } + + // -------------------------------------------------------------------------- + // [Type] + // -------------------------------------------------------------------------- + + //! Get register type. + ASMJIT_INLINE uint32_t getRegType() const { return _vreg.type; } + //! Get variable type. + ASMJIT_INLINE uint32_t getVarType() const { return _vreg.vType; } + + //! Get whether the variable is Gp register. + ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; } + //! Get whether the variable is Gpb (8-bit) register. + ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kX86RegTypeGpbHi; } + //! Get whether the variable is Gpb-lo (8-bit) register. + ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; } + //! Get whether the variable is Gpb-hi (8-bit) register. + ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kX86RegTypeGpbHi; } + //! Get whether the variable is Gpw (16-bit) register. + ASMJIT_INLINE bool isGpw() const { return _vreg.type == kX86RegTypeGpw; } + //! Get whether the variable is Gpd (32-bit) register. + ASMJIT_INLINE bool isGpd() const { return _vreg.type == kX86RegTypeGpd; } + //! Get whether the variable is Gpq (64-bit) register. + ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; } + + //! Get whether the variable is Mm (64-bit) register. + ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; } + //! Get whether the variable is Xmm (128-bit) register. + ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; } + //! Get whether the variable is Ymm (256-bit) register. + ASMJIT_INLINE bool isYmm() const { return _vreg.type == kX86RegTypeYmm; } + //! Get whether the variable is Zmm (512-bit) register. + ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; } + + // -------------------------------------------------------------------------- + // [Memory Cast] + // -------------------------------------------------------------------------- + + //! Cast this variable to a memory operand. + //! + //! \note Size of operand depends on native variable type, you can use other + //! variants if you want specific one. + ASMJIT_INLINE X86Mem m(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, getSize()); + } + + //! \overload + ASMJIT_INLINE X86Mem m(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, getSize()); + } + + //! Cast this variable to 8-bit memory operand. + ASMJIT_INLINE X86Mem m8(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 1); + } + + //! \overload + ASMJIT_INLINE X86Mem m8(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 1); + } + + //! Cast this variable to 16-bit memory operand. + ASMJIT_INLINE X86Mem m16(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 2); + } + + //! \overload + ASMJIT_INLINE X86Mem m16(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 2); + } + + //! Cast this variable to 32-bit memory operand. + ASMJIT_INLINE X86Mem m32(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 4); + } + + //! \overload + ASMJIT_INLINE X86Mem m32(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 4); + } + + //! Cast this variable to 64-bit memory operand. + ASMJIT_INLINE X86Mem m64(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 8); + } + + //! \overload + ASMJIT_INLINE X86Mem m64(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 8); + } + + //! Cast this variable to 80-bit memory operand (long double). + ASMJIT_INLINE X86Mem m80(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 10); + } + + //! \overload + ASMJIT_INLINE X86Mem m80(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 10); + } + + //! Cast this variable to 128-bit memory operand. + ASMJIT_INLINE X86Mem m128(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 16); + } + + //! \overload + ASMJIT_INLINE X86Mem m128(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 16); + } + + //! Cast this variable to 256-bit memory operand. + ASMJIT_INLINE X86Mem m256(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 32); + } + + //! \overload + ASMJIT_INLINE X86Mem m256(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 32); + } + + //! Cast this variable to 256-bit memory operand. + ASMJIT_INLINE X86Mem m512(int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, disp, 64); + } + + //! \overload + ASMJIT_INLINE X86Mem m512(const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) const { + return X86Mem(Init, kMemTypeStackIndex, *this, index, shift, disp, 64); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Var& operator=(const X86Var& other) { + _copy(other); + return *this; + } + + ASMJIT_INLINE bool operator==(const X86Var& other) const { + return _packed[0] == other._packed[0]; + } + + ASMJIT_INLINE bool operator!=(const X86Var& other) const { + return _packed[0] != other._packed[0]; + } + + // -------------------------------------------------------------------------- + // [Private] + // -------------------------------------------------------------------------- + +protected: + ASMJIT_INLINE X86Var(const X86Var& other, uint32_t reg, uint32_t size) : Var(NoInit) { + _init_packed_op_sz_w0_id(kOperandTypeVar, size, (reg << 8) + other._vreg.index, other._base.id); + _vreg.vType = other._vreg.vType; + } +}; + +// ============================================================================ +// [asmjit::X86GpVar] +// ============================================================================ + +//! Gp variable. +struct X86GpVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86GpVar` instance. + ASMJIT_INLINE X86GpVar() : X86Var() {} + + //! Create a new initialized `X86GpVar` instance. + ASMJIT_INLINE X86GpVar(Compiler& c, uint32_t type = kVarTypeIntPtr, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86GpVar(const X86GpVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86GpVar` instance (internal). + explicit ASMJIT_INLINE X86GpVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86GpVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86GpVar operand. + ASMJIT_INLINE X86GpVar clone() const { + return X86GpVar(*this); + } + + //! Reset X86GpVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [X86GpVar Cast] + // -------------------------------------------------------------------------- + + //! Cast this variable to 8-bit (LO) part of variable + ASMJIT_INLINE X86GpVar r8() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); } + //! Cast this variable to 8-bit (LO) part of variable + ASMJIT_INLINE X86GpVar r8Lo() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); } + //! Cast this variable to 8-bit (HI) part of variable + ASMJIT_INLINE X86GpVar r8Hi() const { return X86GpVar(*this, kX86RegTypeGpbHi, 1); } + + //! Cast this variable to 16-bit part of variable + ASMJIT_INLINE X86GpVar r16() const { return X86GpVar(*this, kX86RegTypeGpw, 2); } + //! Cast this variable to 32-bit part of variable + ASMJIT_INLINE X86GpVar r32() const { return X86GpVar(*this, kX86RegTypeGpd, 4); } + //! Cast this variable to 64-bit part of variable + ASMJIT_INLINE X86GpVar r64() const { return X86GpVar(*this, kX86RegTypeGpq, 8); } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86GpVar& operator=(const X86GpVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86GpVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86GpVar& other) const { return X86Var::operator!=(other); } + + // -------------------------------------------------------------------------- + // [Private] + // -------------------------------------------------------------------------- + +protected: + ASMJIT_INLINE X86GpVar(const X86GpVar& other, uint32_t reg, uint32_t size) : X86Var(other, reg, size) {} +}; + +// ============================================================================ +// [asmjit::X86MmVar] +// ============================================================================ + +//! Mm variable. +struct X86MmVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86MmVar` instance. + ASMJIT_INLINE X86MmVar() : X86Var() {} + //! Create a new initialized `X86MmVar` instance. + ASMJIT_INLINE X86MmVar(Compiler& c, uint32_t type = kX86VarTypeMm, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86MmVar(const X86MmVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86MmVar` instance (internal). + explicit ASMJIT_INLINE X86MmVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86MmVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86MmVar operand. + ASMJIT_INLINE X86MmVar clone() const { + return X86MmVar(*this); + } + + //! Reset X86MmVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86MmVar& operator=(const X86MmVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86MmVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86MmVar& other) const { return X86Var::operator!=(other); } +}; + +// ============================================================================ +// [asmjit::X86XmmVar] +// ============================================================================ + +//! Xmm variable. +struct X86XmmVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86XmmVar` instance. + ASMJIT_INLINE X86XmmVar() : X86Var() {} + //! Create a new initialized `X86XmmVar` instance. + ASMJIT_INLINE X86XmmVar(Compiler& c, uint32_t type = kX86VarTypeXmm, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86XmmVar(const X86XmmVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86XmmVar` instance (internal). + explicit ASMJIT_INLINE X86XmmVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86XmmVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86XmmVar operand. + ASMJIT_INLINE X86XmmVar clone() const { + return X86XmmVar(*this); + } + + //! Reset X86XmmVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86XmmVar& operator=(const X86XmmVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86XmmVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86XmmVar& other) const { return X86Var::operator!=(other); } +}; + +// ============================================================================ +// [asmjit::X86YmmVar] +// ============================================================================ + +//! Ymm variable. +struct X86YmmVar : public X86Var { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new uninitialized `X86YmmVar` instance. + ASMJIT_INLINE X86YmmVar() : X86Var() {} + //! Create a new initialized `X86YmmVar` instance. + ASMJIT_INLINE X86YmmVar(Compiler& c, uint32_t type = kX86VarTypeYmm, const char* name = NULL) : X86Var(NoInit) { + c._newVar(this, type, name); + } + + //! Create a clone of `other`. + ASMJIT_INLINE X86YmmVar(const X86YmmVar& other) : X86Var(other) {} + + //! Create a new uninitialized `X86YmmVar` instance (internal). + explicit ASMJIT_INLINE X86YmmVar(const _NoInit&) : X86Var(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86YmmVar Specific] + // -------------------------------------------------------------------------- + + //! Clone X86YmmVar operand. + ASMJIT_INLINE X86YmmVar clone() const { + return X86YmmVar(*this); + } + + //! Reset X86YmmVar operand. + ASMJIT_INLINE void reset() { + X86Var::reset(); + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86YmmVar& operator=(const X86YmmVar& other) { _copy(other); return *this; } + + ASMJIT_INLINE bool operator==(const X86YmmVar& other) const { return X86Var::operator==(other); } + ASMJIT_INLINE bool operator!=(const X86YmmVar& other) const { return X86Var::operator!=(other); } +}; + +// ============================================================================ +// [asmjit::X86VarMap] +// ============================================================================ + +struct X86VarMap : public VarMap { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get variable-attributes list as VarAttr data. + ASMJIT_INLINE VarAttr* getVaList() const { + return const_cast(_list); + } + + //! Get variable-attributes list as VarAttr data (by class). + ASMJIT_INLINE VarAttr* getVaListByClass(uint32_t c) const { + return const_cast(_list) + _start.get(c); + } + + //! Get position of variables (by class). + ASMJIT_INLINE uint32_t getVaStart(uint32_t c) const { + return _start.get(c); + } + + //! Get count of variables (by class). + ASMJIT_INLINE uint32_t getVaCountByClass(uint32_t c) const { + return _count.get(c); + } + + //! Get VarAttr at `index`. + ASMJIT_INLINE VarAttr* getVa(uint32_t index) const { + ASMJIT_ASSERT(index < _vaCount); + return getVaList() + index; + } + + //! Get VarAttr of `c` class at `index`. + ASMJIT_INLINE VarAttr* getVaByClass(uint32_t c, uint32_t index) const { + ASMJIT_ASSERT(index < _count._regs[c]); + return getVaListByClass(c) + index; + } + + // -------------------------------------------------------------------------- + // [Utils] + // -------------------------------------------------------------------------- + + //! Find VarAttr. + ASMJIT_INLINE VarAttr* findVa(VarData* vd) const { + VarAttr* list = getVaList(); + uint32_t count = getVaCount(); + + for (uint32_t i = 0; i < count; i++) + if (list[i].getVd() == vd) + return &list[i]; + + return NULL; + } + + //! Find VarAttr (by class). + ASMJIT_INLINE VarAttr* findVaByClass(uint32_t c, VarData* vd) const { + VarAttr* list = getVaListByClass(c); + uint32_t count = getVaCountByClass(c); + + for (uint32_t i = 0; i < count; i++) + if (list[i].getVd() == vd) + return &list[i]; + + return NULL; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Special registers on input. + //! + //! Special register(s) restricted to one or more physical register. If there + //! is more than one special register it means that we have to duplicate the + //! variable content to all of them (it means that the same varible was used + //! by two or more operands). We forget about duplicates after the register + //! allocation finishes and marks all duplicates as non-assigned. + X86RegMask _inRegs; + + //! Special registers on output. + //! + //! Special register(s) used on output. Each variable can have only one + //! special register on the output, 'X86VarMap' contains all registers from + //! all 'VarAttr's. + X86RegMask _outRegs; + + //! Clobbered registers (by a function call). + X86RegMask _clobberedRegs; + + //! Start indexes of variables per register class. + X86RegCount _start; + //! Count of variables per register class. + X86RegCount _count; + + //! VarAttr list. + VarAttr _list[1]; +}; + +// ============================================================================ +// [asmjit::X86StateCell] +// ============================================================================ + +//! X86/X64 state-cell. +union X86StateCell { + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t getState() const { + return _state; + } + + ASMJIT_INLINE void setState(uint32_t state) { + _state = static_cast(state); + } + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { _packed = 0; } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + uint8_t _packed; + + struct { + uint8_t _state : 2; + uint8_t _unused : 6; + }; +}; + +// ============================================================================ +// [asmjit::X86VarState] +// ============================================================================ + +//! X86/X64 state. +struct X86VarState : VarState { + enum { + //! Base index of Gp registers. + kGpIndex = 0, + //! Count of Gp registers. + kGpCount = 16, + + //! Base index of Mm registers. + kMmIndex = kGpIndex + kGpCount, + //! Count of Mm registers. + kMmCount = 8, + + //! Base index of Xmm registers. + kXmmIndex = kMmIndex + kMmCount, + //! Count of Xmm registers. + kXmmCount = 16, + + //! Count of all registers in `X86VarState`. + kAllCount = kXmmIndex + kXmmCount + }; + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE VarData** getList() { + return _list; + } + + ASMJIT_INLINE VarData** getListByClass(uint32_t c) { + switch (c) { + case kX86RegClassGp : return _listGp; + case kX86RegClassMm : return _listMm; + case kX86RegClassXyz: return _listXmm; + + default: + return NULL; + } + } + + // -------------------------------------------------------------------------- + // [Clear] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset(size_t numCells) { + ::memset(this, 0, kAllCount * sizeof(VarData*) + + 2 * sizeof(X86RegMask) + + numCells * sizeof(X86StateCell)); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + //! List of all allocated variables in one array. + VarData* _list[kAllCount]; + + struct { + //! Allocated Gp registers. + VarData* _listGp[kGpCount]; + //! Allocated Mm registers. + VarData* _listMm[kMmCount]; + //! Allocated Xmm registers. + VarData* _listXmm[kXmmCount]; + }; + }; + + //! Occupied registers (mask). + X86RegMask _occupied; + //! Modified registers (mask). + X86RegMask _modified; + + //! Variables data, the length is stored in `X86Context`. + X86StateCell _cells[1]; +}; + +// ============================================================================ +// [asmjit::X86FuncDecl] +// ============================================================================ + +//! X86 function, including calling convention, arguments and their +//! register indices or stack positions. +struct X86FuncDecl : public FuncDecl { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86FuncDecl` instance. + ASMJIT_INLINE X86FuncDecl() { + reset(); + } + + // -------------------------------------------------------------------------- + // [Accessors - X86] + // -------------------------------------------------------------------------- + + //! Get used registers (mask). + //! + //! \note The result depends on the function calling convention AND the + //! function prototype. Returned mask contains only registers actually used + //! to pass function arguments. + ASMJIT_INLINE uint32_t getUsed(uint32_t c) const { + return _used.get(c); + } + + //! Get passed registers (mask). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE uint32_t getPassed(uint32_t c) const { + return _passed.get(c); + } + + //! Get preserved registers (mask). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE uint32_t getPreserved(uint32_t c) const { + return _preserved.get(c); + } + + //! Get ther order of passed registers (Gp). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE const uint8_t* getPassedOrderGp() const { + return _passedOrderGp; + } + + //! Get ther order of passed registers (Xmm). + //! + //! \note The result depends on the function calling convention used; the + //! prototype of the function doesn't affect the mask returned. + ASMJIT_INLINE const uint8_t* getPassedOrderXmm() const { + return _passedOrderXmm; + } + + // -------------------------------------------------------------------------- + // [SetPrototype] + // -------------------------------------------------------------------------- + + //! Set function prototype. + //! + //! This will set function calling convention and setup arguments variables. + //! + //! \note This function will allocate variables, it can be called only once. + ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_API void reset(); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Used registers. + X86RegMask _used; + + //! Passed registers (defined by the calling convention). + X86RegMask _passed; + //! Preserved registers (defined by the calling convention). + X86RegMask _preserved; + + //! Order of registers defined to pass function arguments (Gp). + uint8_t _passedOrderGp[8]; + //! Order of registers defined to pass function arguments (Xmm). + uint8_t _passedOrderXmm[8]; +}; + +// ============================================================================ +// [asmjit::X86FuncNode] +// ============================================================================ + +//! X86/X64 function node. +struct X86FuncNode : public FuncNode { + ASMJIT_NO_COPY(X86FuncNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86FuncNode` instance. + ASMJIT_INLINE X86FuncNode(Compiler* compiler) : FuncNode(compiler) { + _decl = &_x86Decl; + _saveRestoreRegs.reset(); + + _alignStackSize = 0; + _alignedMemStackSize = 0; + _pushPopStackSize = 0; + _moveStackSize = 0; + _extraStackSize = 0; + + _stackFrameRegIndex = kInvalidReg; + _isStackFrameRegPreserved = false; + _stackFrameCopyGpIndex[0] = kInvalidReg; + _stackFrameCopyGpIndex[1] = kInvalidReg; + _stackFrameCopyGpIndex[2] = kInvalidReg; + _stackFrameCopyGpIndex[3] = kInvalidReg; + _stackFrameCopyGpIndex[4] = kInvalidReg; + _stackFrameCopyGpIndex[5] = kInvalidReg; + } + + //! Destroy the `X86FuncNode` instance. + ASMJIT_INLINE ~X86FuncNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function declaration as `X86FuncDecl`. + ASMJIT_INLINE X86FuncDecl* getDecl() const { + return const_cast(&_x86Decl); + } + + //! Get argument. + ASMJIT_INLINE VarData* getArg(uint32_t i) const { + ASMJIT_ASSERT(i < _x86Decl.getArgCount()); + return static_cast(_argList[i]); + } + + //! Get registers which have to be saved in prolog/epilog. + ASMJIT_INLINE uint32_t getSaveRestoreRegs(uint32_t c) { return _saveRestoreRegs.get(c); } + + //! Get stack size needed to align stack back to the nature alignment. + ASMJIT_INLINE uint32_t getAlignStackSize() const { return _alignStackSize; } + //! Set stack size needed to align stack back to the nature alignment. + ASMJIT_INLINE void setAlignStackSize(uint32_t s) { _alignStackSize = s; } + + //! Get aligned stack size used by variables and memory allocated on the stack. + ASMJIT_INLINE uint32_t getAlignedMemStackSize() const { return _alignedMemStackSize; } + + //! Get stack size used by push/pop sequences in prolog/epilog. + ASMJIT_INLINE uint32_t getPushPopStackSize() const { return _pushPopStackSize; } + //! Set stack size used by push/pop sequences in prolog/epilog. + ASMJIT_INLINE void setPushPopStackSize(uint32_t s) { _pushPopStackSize = s; } + + //! Get stack size used by mov sequences in prolog/epilog. + ASMJIT_INLINE uint32_t getMoveStackSize() const { return _moveStackSize; } + //! Set stack size used by mov sequences in prolog/epilog. + ASMJIT_INLINE void setMoveStackSize(uint32_t s) { _moveStackSize = s; } + + //! Get extra stack size. + ASMJIT_INLINE uint32_t getExtraStackSize() const { return _extraStackSize; } + //! Set extra stack size. + ASMJIT_INLINE void setExtraStackSize(uint32_t s) { _extraStackSize = s; } + + //! Get whether the function has stack frame register. + //! + //! \note Stack frame register can be used for both - aligning purposes or + //! generating standard prolog/epilog sequence. + //! + //! \note Used only when stack is misaligned. + ASMJIT_INLINE bool hasStackFrameReg() const { return _stackFrameRegIndex != kInvalidReg; } + //! Get stack frame register index. + //! + //! \note Used only when stack is misaligned. + ASMJIT_INLINE uint32_t getStackFrameRegIndex() const { return _stackFrameRegIndex; } + //! Get whether the stack frame register is preserved. + //! + //! \note Used only when stack is misaligned. + ASMJIT_INLINE bool isStackFrameRegPreserved() const { return static_cast(_isStackFrameRegPreserved); } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! X86 function decl. + X86FuncDecl _x86Decl; + //! Registers which must be saved/restored in prolog/epilog. + X86RegMask _saveRestoreRegs; + + //! Stack size needed to align function back to the nature alignment. + uint32_t _alignStackSize; + //! Like `_memStackSize`, but aligned. + uint32_t _alignedMemStackSize; + + //! Stack required for push/pop in prolog/epilog (X86/X64 specific). + uint32_t _pushPopStackSize; + //! Stack required for movs in prolog/epilog (X86/X64 specific). + uint32_t _moveStackSize; + + //! Stack required to put extra data (for example function arguments + //! when manually aligning to requested alignment). + uint32_t _extraStackSize; + + //! Stack frame register. + uint8_t _stackFrameRegIndex; + //! Whether the stack frame register is preserved. + uint8_t _isStackFrameRegPreserved; + //! Gp registers indexes that can be used to copy function arguments + //! to a new location in case we are doing manual stack alignment. + uint8_t _stackFrameCopyGpIndex[6]; +}; + +// ============================================================================ +// [asmjit::X86CallNode] +// ============================================================================ + +//! X86/X64 function-call node. +struct X86CallNode : public CallNode { + ASMJIT_NO_COPY(X86CallNode) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86CallNode` instance. + ASMJIT_INLINE X86CallNode(Compiler* compiler, const Operand& target) : CallNode(compiler, target) { + _decl = &_x86Decl; + _usedArgs.reset(); + } + + //! Destroy the `X86CallNode` instance. + ASMJIT_INLINE ~X86CallNode() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get function prototype. + ASMJIT_INLINE X86FuncDecl* getDecl() const { + return const_cast(&_x86Decl); + } + + // -------------------------------------------------------------------------- + // [Prototype] + // -------------------------------------------------------------------------- + + //! Set function prototype. + ASMJIT_API Error setPrototype(uint32_t conv, const FuncPrototype& p); + + // -------------------------------------------------------------------------- + // [Arg / Ret] + // -------------------------------------------------------------------------- + + //! Set argument at `i` to `op`. + ASMJIT_API bool _setArg(uint32_t i, const Operand& op); + //! Set return at `i` to `op`. + ASMJIT_API bool _setRet(uint32_t i, const Operand& op); + + //! Set argument at `i` to `var`. + ASMJIT_INLINE bool setArg(uint32_t i, const Var& var) { return _setArg(i, var); } + //! Set argument at `i` to `reg` (FP registers only). + ASMJIT_INLINE bool setArg(uint32_t i, const X86FpReg& reg) { return _setArg(i, reg); } + //! Set argument at `i` to `imm`. + ASMJIT_INLINE bool setArg(uint32_t i, const Imm& imm) { return _setArg(i, imm); } + + //! Set return at `i` to `var`. + ASMJIT_INLINE bool setRet(uint32_t i, const Var& var) { return _setRet(i, var); } + //! Set return at `i` to `reg` (FP registers only). + ASMJIT_INLINE bool setRet(uint32_t i, const X86FpReg& reg) { return _setRet(i, reg); } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! X86 declaration. + X86FuncDecl _x86Decl; + //! Mask of all registers actually used to pass function arguments. + //! + //! \note This bit-mask is not the same as `X86Func::_passed`. It contains + //! only registers actually used to do the call while `X86Func::_passed` + //! mask contains all registers for all function prototype combinations. + X86RegMask _usedArgs; +}; + +// ============================================================================ +// [asmjit::X86TypeId / VarMapping] +// ============================================================================ + +#if !defined(ASMJIT_DOCGEN) +ASMJIT_TYPE_ID(X86MmReg, kX86VarTypeMm); +ASMJIT_TYPE_ID(X86MmVar, kX86VarTypeMm); +ASMJIT_TYPE_ID(X86XmmReg, kX86VarTypeXmm); +ASMJIT_TYPE_ID(X86XmmVar, kX86VarTypeXmm); +ASMJIT_TYPE_ID(X86YmmReg, kX86VarTypeYmm); +ASMJIT_TYPE_ID(X86YmmVar, kX86VarTypeYmm); +#endif // !ASMJIT_DOCGEN + +// ============================================================================ +// [asmjit::X86Compiler] +// ============================================================================ + +//! X86/X64 compiler. +//! +//! This class is used to store instruction stream and allows to modify it on +//! the fly. It uses different concept than `Assembler` class and in fact +//! `Assembler` is only used as a backend. Compiler never emits machine code +//! and each instruction you use is stored to instruction array instead. This +//! allows to modify instruction stream later and for example to reorder +//! instructions to make better performance. +//! +//! `X86Compiler` moves code generation to a higher level. Higher level +//! constructs allows to write more abstract and extensible code that is not +//! possible with pure `X86Assembler`. +//! +//! The Story +//! --------- +//! +//! Before telling you how Compiler works I'd like to write a story. I'd like +//! to cover reasons why this class was created and why I'm recommending to use +//! it. When I released the first version of AsmJit (0.1) it was a toy. The +//! first function I wrote was function which is still available as testjit and +//! which simply returns 1024. The reason why function works for both 32-bit/ +//! 64-bit mode and for Windows/Unix specific calling conventions is luck, no +//! arguments usage and no registers usage except returning value in EAX/RAX. +//! +//! Then I started a project called BlitJit which was targetted to generating +//! JIT code for computer graphics. After writing some lines I decided that I +//! can't join pieces of code together without abstraction, should be +//! pixels source pointer in ESI/RSI or EDI/RDI or it's completelly +//! irrellevant? What about destination pointer and SSE2 register for reading +//! input pixels? The simple answer might be "just pick some one and use it". +//! +//! Another reason for abstraction is function calling-conventions. It's really +//! not easy to write assembler code for 32-bit and 64-bit platform supporting +//! three calling conventions (32-bit is similar between Windows and Unix, but +//! 64-bit calling conventions are different). +//! +//! At this time I realized that I can't write code which uses named registers, +//! I need to abstract it. In most cases you don't need specific register, you +//! need to emit instruction that does something with 'virtual' register(s), +//! memory, immediate or label. +//! +//! The first version of AsmJit with Compiler was 0.5 (or 0.6?, can't remember). +//! There was support for 32-bit and 64-bit mode, function calling conventions, +//! but when emitting instructions the developer needed to decide which +//! registers are changed, which are only read or completely overwritten. This +//! model helped a lot when generating code, especially when joining more +//! code-sections together, but there was also small possibility for mistakes. +//! Simply the first version of Compiler was great improvement over low-level +//! Assembler class, but the API design wasn't perfect. +//! +//! The second version of Compiler, completelly rewritten and based on +//! different goals, is part of AsmJit starting at version 1.0. This version +//! was designed after the first one and it contains serious improvements over +//! the old one. The first improvement is that you just use instructions with +//! virtual registers - called variables. When using compiler there is no way +//! to use native registers, there are variables instead. AsmJit is smarter +//! than before and it knows which register is needed only for read (r), +//! read/write (w) or overwrite (x). Supported are also instructions which +//! are using some registers in implicit way (these registers are not part of +//! instruction definition in string form). For example to use CPUID instruction +//! you must give it four variables which will be automatically allocated in +//! input/output registers (EAX, EBX, ECX, EDX). +//! +//! Another improvement is algorithm used by a register allocator. In first +//! version the registers were allocated when creating instruction stream. In +//! new version registers are allocated after calling `Compiler::make()`, +//! thus register allocator has information about scope of all variables and +//! statistics of their usage. The algorithm to allocate registers is very +//! simple and it's always called as a 'linear scan register allocator'. When +//! you get out of registers the all possible variables are scored and the worst +//! is spilled. Of course algorithm ignores the variables used for current +//! instruction. +//! +//! In addition, because registers are allocated after the code stream is +//! generated, the state switches between jumps are handled by Compiler too. +//! You don't need to worry about jumps, compiler always do this dirty work +//! for you. +//! +//! The nearly last thing I'd like to present is calling other functions from +//! the generated code. AsmJit uses a `FuncPrototype` class to hold function +//! parameters, their position in stack (or register index) and return value. +//! This class is used internally, but it can be used to create your own +//! function calling-convention. All standard function calling conventions are +//! implemented. +//! +//! Please enjoy the new version of Compiler, it was created for writing a +//! low-level code using high-level API, leaving developer to concentrate on +//! real problems and not to solving a register puzzle. +//! +//! Code Generation +//! --------------- +//! +//! First that is needed to know about compiler is that compiler never emits +//! machine code. It's used as a middleware between @c asmjit::Assembler and +//! your code. There is also convenience method @c make() that allows to +//! generate machine code directly without creating @c asmjit::Assembler +//! instance. +//! +//! Comparison of generating machine code through @c Assembler and directly +//! by @c Compiler: +//! +//! ~~~ +//! // Assembler instance is low level code generation class that emits +//! // machine code. +//! Assembler a; +//! +//! // Compiler instance is high level code generation class that stores all +//! // instructions in internal representation. +//! Compiler c; +//! +//! // ... put your code here ... +//! +//! // Final step - generate code. asmjit::Compiler::serialize() will send all +//! // instructions into Assembler and this ensures generating real machine code. +//! c.serialize(&a); +//! +//! // Your function +//! void* fn = a.make(); +//! ~~~ +//! +//! Example how to generate machine code using only @c Compiler (preferred): +//! +//! ~~~ +//! // Compiler instance is enough. +//! Compiler c; +//! +//! // ... put your code here ... +//! +//! // Your function +//! void* fn = c.make(); +//! ~~~ +//! +//! You can see that there is @c asmjit::Compiler::serialize() function that +//! emits instructions into @c asmjit::Assembler(). This layered architecture +//! means that each class is used for something different and there is no code +//! duplication. For convenience there is also @c asmjit::Compiler::make() +//! method that can create your function using @c asmjit::Assembler, but +//! internally (this is preferred bahavior when using @c asmjit::Compiler). +//! +//! The @c make() method allocates memory using `Runtime` instance passed +//! into the @c Compiler constructor. If code generator is used to create JIT +//! function then virtual memory allocated by `VMemMgr` is used. +//! +//! ~~~ +//! JitRuntime runtime; +//! Compiler c(&runtime); +//! +//! // ... put your code using Compiler instance ... +//! +//! // Your function +//! void* fn = c.make(); +//! +//! runtime.release(fn); +//! ~~~ +//! +//! Functions +//! --------- +//! +//! To build functions with @c Compiler, see @c asmjit::Compiler::addFunc() +//! method. +//! +//! Variables +//! --------- +//! +//! Compiler is able to manage variables and function arguments. Function +//! arguments are moved to variables by using @c setArg() method, where the +//! first parameter is argument index and second parameter is the variable +//! instance. To declare variable use @c newGpVar(), @c newMmVar() and @c +//! newXmmVar() methods. The @c newXXX() methods accept also parameter +//! describing the variable type. For example the @c newGpVar() method always +//! creates variable which size matches the target architecture size (for +//! 32-bit target the 32-bit variable is created, for 64-bit target the +//! variable size is 64-bit). To override this behavior the variable type +//! must be specified. +//! +//! ~~~ +//! // Compiler and function declaration - void f(int*); +//! Compiler c; +//! X86GpVar a0(c, kVarTypeIntPtr); +//! +//! c.addFunc(kFuncConvHost, FuncBuilder1()); +//! c.setArg(0, a0); +//! +//! // Create your variables. +//! X86GpVar x0(c, kVarTypeInt32); +//! X86GpVar x1(c, kVarTypeInt32); +//! +//! // Init your variables. +//! c.mov(x0, 1); +//! c.mov(x1, 2); +//! +//! // ... your code ... +//! c.add(x0, x1); +//! // ... your code ... +//! +//! // Store result to a given pointer in first argument +//! c.mov(dword_ptr(a0), x0); +//! +//! // End of function body. +//! c.endFunc(); +//! +//! // Make the function. +//! typedef void (*MyFunc)(int*); +//! MyFunc func = asmjit_cast(c.make()); +//! ~~~ +//! +//! This code snipped needs to be explained. You can see that there are more +//! variable types that can be used by `Compiler`. Most useful variables can +//! be allocated using general purpose registers (`X86GpVar`), MMX registers +//! (`X86MmVar`) or SSE/SSE2 registers (`X86XmmVar`). +//! +//! X86/X64 variable types: +//! +//! - `kVarTypeInt8` - Signed 8-bit integer, mapped to Gpd register (eax, ebx, ...). +//! - `kVarTypeUInt8` - Unsigned 8-bit integer, mapped to Gpd register (eax, ebx, ...). +//! +//! - `kVarTypeInt16` - Signed 16-bit integer, mapped to Gpd register (eax, ebx, ...). +//! - `kVarTypeUInt16` - Unsigned 16-bit integer, mapped to Gpd register (eax, ebx, ...). +//! +//! - `kVarTypeInt32` - Signed 32-bit integer, mapped to Gpd register (eax, ebx, ...). +//! - `kVarTypeUInt32` - Unsigned 32-bit integer, mapped to Gpd register (eax, ebx, ...). +//! +//! - `kVarTypeInt64` - Signed 64-bit integer, mapped to Gpq register (rax, rbx, ...). +//! - `kVarTypeUInt64` - Unsigned 64-bit integer, mapped to Gpq register (rax, rbx, ...). +//! +//! - `kVarTypeIntPtr` - intptr_t, mapped to Gpd/Gpq register; depends on target, not host! +//! - `kVarTypeUIntPtr` - uintptr_t, mapped to Gpd/Gpq register; depends on target, not host! +//! +//! - `kVarTypeFp32` - 32-bit floating point register (fp0, fp1, ...). +//! - `kVarTypeFp64` - 64-bit floating point register (fp0, fp1, ...). +//! +//! - `kX86VarTypeMm` - 64-bit Mm register (mm0, mm1, ...). +//! +//! - `kX86VarTypeXmm` - 128-bit SSE register. +//! - `kX86VarTypeXmmSs` - 128-bit SSE register that contains a scalar 32-bit SP-FP value. +//! - `kX86VarTypeXmmSd` - 128-bit SSE register that contains a scalar 64-bit DP-FP value. +//! - `kX86VarTypeXmmPs` - 128-bit SSE register that contains 4 packed 32-bit SP-FP values. +//! - `kX86VarTypeXmmPd` - 128-bit SSE register that contains 2 packed 64-bit DP-FP values. +//! +//! - `kX86VarTypeYmm` - 256-bit AVX register. +//! - `kX86VarTypeYmmPs` - 256-bit AVX register that contains 4 packed 32-bit SP-FP values. +//! - `kX86VarTypeYmmPd` - 256-bit AVX register that contains 2 packed 64-bit DP-FP values. +//! +//! Variable states: +//! +//! - `kVarStateUnused - State that is assigned to newly created variables or +//! to not used variables (dereferenced to zero). +//! - `kVarStateReg - State that means that variable is currently allocated in +//! register. +//! - `kVarStateMem - State that means that variable is currently only in +//! memory location. +//! +//! When you create new variable, initial state is always `kVarStateUnused`, +//! allocating it to register or spilling to memory changes this state to +//! `kVarStateReg` or `kVarStateMem`, respectively. During variable lifetime +//! it's usual that its state is changed multiple times. To generate better +//! code, you can control allocating and spilling by using up to four types +//! of methods that allows it (see next list). +//! +//! Explicit variable allocating / spilling methods: +//! +//! - `Compiler::alloc()` - Explicit method to alloc variable into register. +//! It can be used to force allocation a variable before a loop for example. +//! +//! - `Compiler::spill()` - Explicit method to spill variable. If variable +//! is in register and you call this method, it's moved to its home memory +//! location. If variable is not in register no operation is performed. +//! +//! - `Compiler::unuse()` - Unuse variable (you can use this to end the +//! variable scope or sub-scope). +//! +//! Please see AsmJit tutorials (testcompiler.cpp and testvariables.cpp) for +//! more complete examples. +//! +//! Memory Management +//! ----------------- +//! +//! Compiler Memory management follows these rules: +//! +//! - Everything created by `Compiler` is always freed by `Compiler`. +//! - To get decent performance, compiler always uses larger memory buffer +//! for objects to allocate and when compiler instance is destroyed, this +//! buffer is freed. Destructors of active objects are called when +//! destroying compiler instance. Destructors of abadonded compiler +//! objects are called immediately after abadonding them. +//! - This type of memory management is called 'zone memory management'. +//! +//! This means that you can't use any `Compiler` object after destructing it, +//! it also means that each object like `Label`, `Var` and others are created +//! and managed by @c Compiler itself. These objects contain ID which is +//! used internally by Compiler to store additional information about these +//! objects. +//! +//! Control-Flow and State Management +//! --------------------------------- +//! +//! The `Compiler` automatically manages state of the variables when using +//! control flow instructions like jumps, conditional jumps and calls. There +//! is minimal heuristics for choosing the method how state is saved or restored. +//! +//! Generally the state can be changed only when using jump or conditional jump +//! instruction. When using non-conditional jump then state change is embedded +//! into the instruction stream before the jump. When using conditional jump +//! the `Compiler` decides whether to restore state before the jump or whether +//! to use another block where state is restored. The last case is that no-code +//! have to be emitted and there is no state change (this is of course ideal). +//! +//! Choosing whether to embed 'restore-state' section before conditional jump +//! is quite simple. If jump is likely to be 'taken' then code is embedded, if +//! jump is unlikely to be taken then the small code section for state-switch +//! will be generated instead. +//! +//! Next example is the situation where the extended code block is used to +//! do state-change: +//! +//! ~~~ +//! Compiler c; +//! +//! c.addFunc(kFuncConvHost, FuncBuilder0()); +//! +//! // Labels. +//! Label L0(c); +//! +//! // Variables. +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! // Cleanup. After these two lines, the var0 and var1 will be always stored +//! // in registers. Our example is very small, but in larger code the var0 can +//! // be spilled by xor(var1, var1). +//! c.xor_(var0, var0); +//! c.xor_(var1, var1); +//! c.cmp(var0, var1); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // We manually spill these variables. +//! c.spill(var0); +//! c.spill(var1); +//! // State: +//! // var0 - memory. +//! // var1 - memory. +//! +//! // Conditional jump to L0. It will be always taken, but compiler thinks that +//! // it is unlikely taken so it will embed state change code somewhere. +//! c.je(L0); +//! +//! // Do something. The variables var0 and var1 will be allocated again. +//! c.add(var0, 1); +//! c.add(var1, 2); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // Bind label here, the state is not changed. +//! c.bind(L0); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // We need to use var0 and var1, because if compiler detects that variables +//! // are out of scope then it optimizes the state-change. +//! c.sub(var0, var1); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! c.endFunc(); +//! ~~~ +//! +//! The output: +//! +//! ~~~ +//! xor eax, eax ; xor var_0, var_0 +//! xor ecx, ecx ; xor var_1, var_1 +//! cmp eax, ecx ; cmp var_0, var_1 +//! mov [esp - 24], eax ; spill var_0 +//! mov [esp - 28], ecx ; spill var_1 +//! je L0_Switch +//! mov eax, [esp - 24] ; alloc var_0 +//! add eax, 1 ; add var_0, 1 +//! mov ecx, [esp - 28] ; alloc var_1 +//! add ecx, 2 ; add var_1, 2 +//! L0: +//! sub eax, ecx ; sub var_0, var_1 +//! ret +//! +//! ; state-switch begin +//! L0_Switch0: +//! mov eax, [esp - 24] ; alloc var_0 +//! mov ecx, [esp - 28] ; alloc var_1 +//! jmp short L0 +//! ; state-switch end +//! ~~~ +//! +//! You can see that the state-switch section was generated (see L0_Switch0). +//! The compiler is unable to restore state immediately when emitting the +//! forward jump (the code is generated from first to last instruction and +//! the target state is simply not known at this time). +//! +//! To tell `Compiler` that you want to embed state-switch code before jump +//! it's needed to create backward jump (where also processor expects that it +//! will be taken). To demonstrate the possibility to embed state-switch before +//! jump we use slightly modified code: +//! +//! ~~~ +//! Compiler c; +//! +//! c.addFunc(kFuncConvHost, FuncBuilder0()); +//! +//! // Labels. +//! Label L0(c); +//! +//! // Variables. +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! // Cleanup. After these two lines, the var0 and var1 will be always stored +//! // in registers. Our example is very small, but in larger code the var0 can +//! // be spilled by xor(var1, var1). +//! c.xor_(var0, var0); +//! c.xor_(var1, var1); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // We manually spill these variables. +//! c.spill(var0); +//! c.spill(var1); +//! // State: +//! // var0 - memory. +//! // var1 - memory. +//! +//! // Bind our label here. +//! c.bind(L0); +//! +//! // Do something, the variables will be allocated again. +//! c.add(var0, 1); +//! c.add(var1, 2); +//! // State: +//! // var0 - register. +//! // var1 - register. +//! +//! // Backward conditional jump to L0. The default behavior is that it is taken +//! // so state-change code will be embedded here. +//! c.je(L0); +//! +//! c.endFunc(); +//! ~~~ +//! +//! The output: +//! +//! ~~~ +//! xor ecx, ecx ; xor var_0, var_0 +//! xor edx, edx ; xor var_1, var_1 +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! L2: +//! mov ecx, [esp - 24] ; alloc var_0 +//! add ecx, 1 ; add var_0, 1 +//! mov edx, [esp - 28] ; alloc var_1 +//! add edx, 2 ; add var_1, 2 +//! +//! ; state-switch begin +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! ; state-switch end +//! +//! je short L2 +//! ret +//! ~~~ +//! +//! Please notice where the state-switch section is located. The `Compiler` +//! decided that jump is likely to be taken so the state change is embedded +//! before the conditional jump. To change this behavior into the previous +//! case it's needed to add an option (kInstOptionTaken/kInstOptionNotTaken). +//! +//! Replacing the c.je(L0) by c.taken(); c.je(L0) +//! will generate code like this: +//! +//! ~~~ +//! xor ecx, ecx ; xor var_0, var_0 +//! xor edx, edx ; xor var_1, var_1 +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! L0: +//! mov ecx, [esp - 24] ; alloc var_0 +//! add ecx, 1 ; add var_0, a +//! mov edx, [esp - 28] ; alloc var_1 +//! add edx, 2 ; add var_1, 2 +//! je L0_Switch, 2 +//! ret +//! +//! ; state-switch begin +//! L0_Switch: +//! mov [esp - 24], ecx ; spill var_0 +//! mov [esp - 28], edx ; spill var_1 +//! jmp short L0 +//! ; state-switch end +//! ~~~ +//! +//! This section provided information about how state-change works. The +//! behavior is deterministic and it can be overridden. +//! +//! Advanced Code Generation +//! ------------------------ +//! +//! This section describes advanced method of code generation available to +//! `Compiler` (but also to `Assembler`). When emitting code to instruction +//! stream the methods like `mov()`, `add()`, `sub()` can be called directly +//! (advantage is static-type control performed also by C++ compiler) or +//! indirectly using `emit()` method. The `emit()` method needs only instruction +//! code and operands. +//! +//! Example of code generating by standard type-safe API: +//! +//! ~~~ +//! Compiler c; +//! +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! ... +//! +//! c.mov(var0, 0); +//! c.add(var0, var1); +//! c.sub(var0, var1); +//! ~~~ +//! +//! The code above can be rewritten as: +//! +//! ~~~ +//! Compiler c; +//! +//! X86GpVar var0(c, kVarTypeInt32); +//! X86GpVar var1(c, kVarTypeInt32); +//! +//! ... +//! +//! c.emit(kX86InstIdMov, var0, 0); +//! c.emit(kX86InstIdAdd, var0, var1); +//! c.emit(kX86InstIdSub, var0, var1); +//! ~~~ +//! +//! The advantage of first snippet is very friendly API and type-safe control +//! that is controlled by the C++ compiler. The advantage of second snippet is +//! availability to replace or generate instruction code in different places. +//! See the next example how the `emit()` method can be used to generate abstract +//! code. +//! +//! Use case: +//! +//! ~~~ +//! bool emitArithmetic(Compiler& c, X86XmmVar& var0, X86XmmVar& var1, const char* op) { +//! uint32_t code = kInstIdNone; +//! +//! if (strcmp(op, "ADD") == 0) +//! code = kX86InstIdAddss; +//! else if (::strcmp(op, "SUBTRACT") == 0) +//! code = kX86InstIdSubss; +//! else if (::strcmp(op, "MULTIPLY") == 0) +//! code = kX86InstIdMulss; +//! else if (::strcmp(op, "DIVIDE") == 0) +//! code = kX86InstIdDivss; +//! else +//! // Invalid parameter? +//! return false; +//! +//! c.emit(code, var0, var1); +//! } +//! ~~~ +//! +//! Other use cases are waiting for you! Be sure that instruction you are +//! emitting is correct and encodable, because if not, Assembler will set +//! status code to `kErrorUnknownInst`. +struct ASMJIT_VCLASS X86Compiler : public Compiler { + ASMJIT_NO_COPY(X86Compiler) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a `X86Compiler` instance. + ASMJIT_API X86Compiler(Runtime* runtime, uint32_t arch +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) + = kArchHost +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + ); + //! Destroy the `X86Compiler` instance. + ASMJIT_API ~X86Compiler(); + + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + //! Get count of registers of the current architecture. + ASMJIT_INLINE const X86RegCount& getRegCount() const { + return _regCount; + } + + //! Get Gpd or Gpq register depending on the current architecture. + ASMJIT_INLINE X86GpReg gpz(uint32_t index) const { + return X86GpReg(zax, index); + } + + //! Create an architecture dependent intptr_t memory operand. + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, int32_t disp = 0) const { + return x86::ptr(base, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) const { + return x86::ptr(base, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, int32_t disp = 0) const { + return x86::ptr(label, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr(label, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift, int32_t disp = 0) const { + return x86::ptr_abs(pAbs, index, shift, disp, _regSize); + } + + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpVar& base, int32_t disp = 0) { + return x86::ptr(base, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { + return x86::ptr(base, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { + return x86::ptr(label, index, shift, disp, _regSize); + } + //! \overload + ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { + return x86::ptr_abs(pAbs, index, shift, disp, _regSize); + } + + ASMJIT_API Error setArch(uint32_t arch); + + // -------------------------------------------------------------------------- + // [Inst / Emit] + // -------------------------------------------------------------------------- + + //! Create a new `InstNode`. + ASMJIT_API InstNode* newInst(uint32_t code); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); + //! \overload + ASMJIT_API InstNode* newInst(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4); + + //! Add a new `InstNode`. + ASMJIT_API InstNode* emit(uint32_t code); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3, const Operand& o4); + + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, int o0); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, uint64_t o0); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, int o1); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, uint64_t o1); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, int o2); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2); + + // -------------------------------------------------------------------------- + // [Func] + // -------------------------------------------------------------------------- + + //! Create a new `X86FuncNode`. + ASMJIT_API X86FuncNode* newFunc(uint32_t conv, const FuncPrototype& p); + + //! Add a new function. + //! + //! \param conv Calling convention to use (see \ref kFuncConv enum) + //! \param params Function arguments prototype. + //! + //! This method is usually used as a first step when generating functions + //! by `Compiler`. First parameter `cconv` specifies function calling + //! convention to use. Second parameter `params` specifies function + //! arguments. To create function arguments are used templates + //! `FuncBuilder0<...>`, `FuncBuilder1<...>`, `FuncBuilder2<...>`, etc... + //! + //! Templates with FuncBuilder prefix are used to generate argument IDs + //! based on real C++ types. See next example how to generate function with + //! two 32-bit integer arguments. + //! + //! ~~~ + //! // Building function using asmjit::Compiler example. + //! + //! // Compiler instance + //! Compiler c; + //! + //! // Begin of function, also emits function prolog. + //! c.addFunc( + //! // Default calling convention (32-bit cdecl or 64-bit for host OS) + //! kFuncConvHost, + //! // Using function builder to generate arguments list + //! FuncBuilder2()); + //! + //! // End of function, also emits function epilog. + //! c.endFunc(); + //! ~~~ + //! + //! You can see that building functions is really easy. Previous code snipped + //! will generate code for function with two 32-bit integer arguments. You + //! can access arguments by `asmjit::Function::getArg()` method. Arguments + //! are indexed from 0 (like everything in C). + //! + //! ~~~ + //! // Accessing function arguments through asmjit::Function example. + //! + //! // Compiler instance + //! Compiler c; + //! X86GpVar a0(c, kVarTypeInt32); + //! X86GpVar a1(c, kVarTypeInt32); + //! + //! // Begin of function (also emits function prolog) + //! c.addFunc( + //! // Default calling convention (32-bit cdecl or 64-bit for host OS) + //! kFuncConvHost, + //! // Using function builder to generate arguments list + //! FuncBuilder2()); + //! + //! c.setArg(0, a0); + //! c.setArg(1, a1); + //! + //! // Use them. + //! c.add(a0, a1); + //! + //! // End of function - emits function epilog and return instruction. + //! c.endFunc(); + //! ~~~ + //! + //! Arguments are like variables. How to manipulate with variables is + //! documented in `Compiler`, variables section. + //! + //! \note To get current function use `getFunc()` method or save pointer to + //! `FuncNode` returned by `Compiler::addFunc<>` method. The recommended way + //! is saving the pointer and using it to specify function arguments and + //! return value. + //! + //! \sa FuncBuilder0, FuncBuilder1, FuncBuilder2, ... + ASMJIT_API X86FuncNode* addFunc(uint32_t conv, const FuncPrototype& p); + + //! End of current function. + ASMJIT_API EndNode* endFunc(); + + //! Get current function as `X86FuncNode`. + //! + //! This method can be called within `addFunc()` and `endFunc()` block to get + //! current function you are working with. It's recommended to store `FuncNode` + //! pointer returned by `addFunc<>` method, because this allows you in future + //! implement function sections outside of function itself. + ASMJIT_INLINE X86FuncNode* getFunc() const { + return static_cast(_func); + } + + // -------------------------------------------------------------------------- + // [Ret] + // -------------------------------------------------------------------------- + + //! Create a new `RetNode`. + ASMJIT_API RetNode* newRet(const Operand& o0, const Operand& o1); + //! Add a new `RetNode`. + ASMJIT_API RetNode* addRet(const Operand& o0, const Operand& o1); + + // -------------------------------------------------------------------------- + // [Call] + // -------------------------------------------------------------------------- + + //! Create a new `X86CallNode`. + ASMJIT_API X86CallNode* newCall(const Operand& o0, uint32_t conv, const FuncPrototype& p); + //! Add a new `X86CallNode`. + ASMJIT_API X86CallNode* addCall(const Operand& o0, uint32_t conv, const FuncPrototype& p); + + // -------------------------------------------------------------------------- + // [Vars] + // -------------------------------------------------------------------------- + + //! Set function argument to `var`. + ASMJIT_API Error setArg(uint32_t argIndex, Var& var); + + ASMJIT_API virtual Error _newVar(Var* var, uint32_t type, const char* name); + + //! Create a new Gp variable. + ASMJIT_INLINE X86GpVar newGpVar(uint32_t vType = kVarTypeIntPtr, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kVarTypeIntStart, _kVarTypeIntEnd)); + + X86GpVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + //! Create a new Mm variable. + ASMJIT_INLINE X86MmVar newMmVar(uint32_t vType = kX86VarTypeMm, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kX86VarTypeMmStart, _kX86VarTypeMmEnd)); + + X86MmVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + //! Create a new Xmm variable. + ASMJIT_INLINE X86XmmVar newXmmVar(uint32_t vType = kX86VarTypeXmm, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kX86VarTypeXmmStart, _kX86VarTypeXmmEnd)); + + X86XmmVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + //! Create a new Ymm variable. + ASMJIT_INLINE X86YmmVar newYmmVar(uint32_t vType = kX86VarTypeYmm, const char* name = NULL) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + ASMJIT_ASSERT(IntUtil::inInterval(vType, _kX86VarTypeYmmStart, _kX86VarTypeYmmEnd)); + + X86YmmVar var(NoInit); + _newVar(&var, vType, name); + return var; + } + + // -------------------------------------------------------------------------- + // [Stack] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error _newStack(BaseMem* mem, uint32_t size, uint32_t alignment, const char* name); + + //! Create a new memory chunk allocated on the current function's stack. + ASMJIT_INLINE X86Mem newStack(uint32_t size, uint32_t alignment, const char* name = NULL) { + X86Mem m(NoInit); + _newStack(&m, size, alignment, name); + return m; + } + + // -------------------------------------------------------------------------- + // [Const] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual Error _newConst(BaseMem* mem, uint32_t scope, const void* data, size_t size); + + //! Put data to a constant-pool and get a memory reference to it. + ASMJIT_INLINE X86Mem newConst(uint32_t scope, const void* data, size_t size) { + X86Mem m(NoInit); + _newConst(&m, scope, data, size); + return m; + } + + //! Put a BYTE `val` to a constant-pool. + ASMJIT_INLINE X86Mem newByteConst(uint32_t scope, uint8_t val) { return newConst(scope, &val, 1); } + //! Put a WORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newWordConst(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); } + //! Put a DWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newDWordConst(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); } + //! Put a QWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newQWordConst(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); } + + //! Put a WORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newInt16Const(uint32_t scope, int16_t val) { return newConst(scope, &val, 2); } + //! Put a WORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newUInt16Const(uint32_t scope, uint16_t val) { return newConst(scope, &val, 2); } + //! Put a DWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newInt32Const(uint32_t scope, int32_t val) { return newConst(scope, &val, 4); } + //! Put a DWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newUInt32Const(uint32_t scope, uint32_t val) { return newConst(scope, &val, 4); } + //! Put a QWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newInt64Const(uint32_t scope, int64_t val) { return newConst(scope, &val, 8); } + //! Put a QWORD `val` to a constant-pool. + ASMJIT_INLINE X86Mem newUInt64Const(uint32_t scope, uint64_t val) { return newConst(scope, &val, 8); } + + //! Put a SP-FP `val` to a constant-pool. + ASMJIT_INLINE X86Mem newFloatConst(uint32_t scope, float val) { return newConst(scope, &val, 4); } + //! Put a DP-FP `val` to a constant-pool. + ASMJIT_INLINE X86Mem newDoubleConst(uint32_t scope, double val) { return newConst(scope, &val, 8); } + + //! Put a MMX `val` to a constant-pool. + ASMJIT_INLINE X86Mem newMmConst(uint32_t scope, const Vec64& val) { return newConst(scope, &val, 8); } + //! Put a XMM `val` to a constant-pool. + ASMJIT_INLINE X86Mem newXmmConst(uint32_t scope, const Vec128& val) { return newConst(scope, &val, 16); } + //! Put a YMM `val` to a constant-pool. + ASMJIT_INLINE X86Mem newYmmConst(uint32_t scope, const Vec256& val) { return newConst(scope, &val, 32); } + + // -------------------------------------------------------------------------- + // [Embed] + // -------------------------------------------------------------------------- + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* db(uint8_t x) { return embed(&x, 1); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dw(uint16_t x) { return embed(&x, 2); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dd(uint32_t x) { return embed(&x, 4); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dq(uint64_t x) { return embed(&x, 8); } + + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint8(int8_t x) { return embed(&x, static_cast(sizeof(int8_t))); } + //! Add 8-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint8(uint8_t x) { return embed(&x, static_cast(sizeof(uint8_t))); } + + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint16(int16_t x) { return embed(&x, static_cast(sizeof(int16_t))); } + //! Add 16-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint16(uint16_t x) { return embed(&x, static_cast(sizeof(uint16_t))); } + + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint32(int32_t x) { return embed(&x, static_cast(sizeof(int32_t))); } + //! Add 32-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint32(uint32_t x) { return embed(&x, static_cast(sizeof(uint32_t))); } + + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* dint64(int64_t x) { return embed(&x, static_cast(sizeof(int64_t))); } + //! Add 64-bit integer data to the instruction stream. + ASMJIT_INLINE EmbedNode* duint64(uint64_t x) { return embed(&x, static_cast(sizeof(uint64_t))); } + + //! Add float data to the instruction stream. + ASMJIT_INLINE EmbedNode* dfloat(float x) { return embed(&x, static_cast(sizeof(float))); } + //! Add double data to the instruction stream. + ASMJIT_INLINE EmbedNode* ddouble(double x) { return embed(&x, static_cast(sizeof(double))); } + + //! Add Mm data to the instruction stream. + ASMJIT_INLINE EmbedNode* dmm(const Vec64& x) { return embed(&x, static_cast(sizeof(Vec64))); } + //! Add Xmm data to the instruction stream. + ASMJIT_INLINE EmbedNode* dxmm(const Vec128& x) { return embed(&x, static_cast(sizeof(Vec128))); } + //! Add Ymm data to the instruction stream. + ASMJIT_INLINE EmbedNode* dymm(const Vec256& x) { return embed(&x, static_cast(sizeof(Vec256))); } + + //! Add data in a given structure instance to the instruction stream. + template + ASMJIT_INLINE EmbedNode* dstruct(const T& x) { return embed(&x, static_cast(sizeof(T))); } + + // -------------------------------------------------------------------------- + // [Make] + // -------------------------------------------------------------------------- + + ASMJIT_API virtual void* make(); + + // ------------------------------------------------------------------------- + // [Assembler] + // ------------------------------------------------------------------------- + + ASMJIT_API virtual Assembler* _newAssembler(); + + // ------------------------------------------------------------------------- + // [Serialize] + // ------------------------------------------------------------------------- + + ASMJIT_API virtual Error serialize(Assembler* assembler); + + // ------------------------------------------------------------------------- + // [Options] + // ------------------------------------------------------------------------- + + ASMJIT_X86_EMIT_OPTIONS(X86Compiler) + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Count of registers depending on the current architecture. + X86RegCount _regCount; + + //! EAX or RAX register depending on the current architecture. + X86GpReg zax; + //! ECX or RCX register depending on the current architecture. + X86GpReg zcx; + //! EDX or RDX register depending on the current architecture. + X86GpReg zdx; + //! EBX or RBX register depending on the current architecture. + X86GpReg zbx; + //! ESP or RSP register depending on the current architecture. + X86GpReg zsp; + //! EBP or RBP register depending on the current architecture. + X86GpReg zbp; + //! ESI or RSI register depending on the current architecture. + X86GpReg zsi; + //! EDI or RDI register depending on the current architecture. + X86GpReg zdi; + + // -------------------------------------------------------------------------- + // [X86 Instructions] + // -------------------------------------------------------------------------- + +#define INST_0x(_Inst_, _Code_) \ + ASMJIT_INLINE InstNode* _Inst_() { \ + return emit(_Code_); \ + } + +#define INST_1x(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1x_(_Inst_, _Code_, _Op0_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0); \ + } + +#define INST_1i(_Inst_, _Code_, _Op0_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(int o0) { \ + return emit(_Code_, o0); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(unsigned int o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(int64_t o0) { \ + return emit(_Code_, static_cast(o0)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(uint64_t o0) { \ + return emit(_Code_, o0); \ + } + +#define INST_1cc(_Inst_, _Code_, _Translate_, _Op0_) \ + ASMJIT_INLINE InstNode* _Inst_(uint32_t cc, const _Op0_& o0) { \ + return emit(_Translate_(cc), o0); \ + } \ + \ + ASMJIT_INLINE InstNode* _Inst_##a(const _Op0_& o0) { return emit(_Code_##a, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ae(const _Op0_& o0) { return emit(_Code_##ae, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##b(const _Op0_& o0) { return emit(_Code_##b, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##be(const _Op0_& o0) { return emit(_Code_##be, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##c(const _Op0_& o0) { return emit(_Code_##c, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##e(const _Op0_& o0) { return emit(_Code_##e, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##g(const _Op0_& o0) { return emit(_Code_##g, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ge(const _Op0_& o0) { return emit(_Code_##ge, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##l(const _Op0_& o0) { return emit(_Code_##l, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##le(const _Op0_& o0) { return emit(_Code_##le, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##na(const _Op0_& o0) { return emit(_Code_##na, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nae(const _Op0_& o0) { return emit(_Code_##nae, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nb(const _Op0_& o0) { return emit(_Code_##nb, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nbe(const _Op0_& o0) { return emit(_Code_##nbe, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nc(const _Op0_& o0) { return emit(_Code_##nc, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ne(const _Op0_& o0) { return emit(_Code_##ne, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ng(const _Op0_& o0) { return emit(_Code_##ng, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nge(const _Op0_& o0) { return emit(_Code_##nge, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nl(const _Op0_& o0) { return emit(_Code_##nl, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nle(const _Op0_& o0) { return emit(_Code_##nle, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##no(const _Op0_& o0) { return emit(_Code_##no, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##np(const _Op0_& o0) { return emit(_Code_##np, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##ns(const _Op0_& o0) { return emit(_Code_##ns, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##nz(const _Op0_& o0) { return emit(_Code_##nz, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##o(const _Op0_& o0) { return emit(_Code_##o, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##p(const _Op0_& o0) { return emit(_Code_##p, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##pe(const _Op0_& o0) { return emit(_Code_##pe, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##po(const _Op0_& o0) { return emit(_Code_##po, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##s(const _Op0_& o0) { return emit(_Code_##s, o0); } \ + ASMJIT_INLINE InstNode* _Inst_##z(const _Op0_& o0) { return emit(_Code_##z, o0); } + +#define INST_2x(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2x_(_Inst_, _Code_, _Op0_, _Op1_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2i(_Inst_, _Code_, _Op0_, _Op1_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int o1) { \ + return emit(_Code_, o0, o1); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, unsigned int o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int64_t o1) { \ + return emit(_Code_, o0, static_cast(o1)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, uint64_t o1) { \ + return emit(_Code_, o0, o1); \ + } + +#define INST_2cc(_Inst_, _Code_, _Translate_, _Op0_, _Op1_) \ + ASMJIT_INLINE InstNode* _Inst_(uint32_t cc, const _Op0_& o0, const _Op1_& o1) { \ + return emit(_Translate_(cc), o0, o1); \ + } \ + \ + ASMJIT_INLINE InstNode* _Inst_##a(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##a, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ae, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##b(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##b, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##be(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##be, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##c(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##c, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##e(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##e, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##g(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##g, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ge, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##l(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##l, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##le(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##le, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##na(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##na, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nae(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nae, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nb(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nb, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nbe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nbe, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nc(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nc, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ne(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ne, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ng(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ng, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nge(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nge, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nl(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nl, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nle(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nle, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##no(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##no, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##np(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##np, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##ns(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##ns, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##nz(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##nz, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##o(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##o, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##p(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##p, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##pe(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##pe, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##po(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##po, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##s(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##s, o0, o1); } \ + ASMJIT_INLINE InstNode* _Inst_##z(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##z, o0, o1); } + +#define INST_3x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_3i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { \ + return emit(_Code_, o0, o1, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { \ + return emit(_Code_, o0, o1, o2); \ + } + +#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + ASMJIT_ASSERT(_Cond_); \ + return emit(_Code_, o0, o1, o2, o3); \ + } + +#define INST_4i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { \ + return emit(_Code_, o0, o1, o2, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } + + //! Add with carry. + INST_2x(adc, kX86InstIdAdc, X86GpVar, X86GpVar) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86GpVar, X86Mem) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86GpVar, Imm) + //! \overload + INST_2x(adc, kX86InstIdAdc, X86Mem, X86GpVar) + //! \overload + INST_2i(adc, kX86InstIdAdc, X86Mem, Imm) + + //! Add. + INST_2x(add, kX86InstIdAdd, X86GpVar, X86GpVar) + //! \overload + INST_2x(add, kX86InstIdAdd, X86GpVar, X86Mem) + //! \overload + INST_2i(add, kX86InstIdAdd, X86GpVar, Imm) + //! \overload + INST_2x(add, kX86InstIdAdd, X86Mem, X86GpVar) + //! \overload + INST_2i(add, kX86InstIdAdd, X86Mem, Imm) + + //! And. + INST_2x(and_, kX86InstIdAnd, X86GpVar, X86GpVar) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86GpVar, X86Mem) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86GpVar, Imm) + //! \overload + INST_2x(and_, kX86InstIdAnd, X86Mem, X86GpVar) + //! \overload + INST_2i(and_, kX86InstIdAnd, X86Mem, Imm) + + //! Bit scan forward. + INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86GpVar, !o0.isGpb()) + //! \overload + INST_2x_(bsf, kX86InstIdBsf, X86GpVar, X86Mem, !o0.isGpb()) + + //! Bit scan reverse. + INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86GpVar, !o0.isGpb()) + //! \overload + INST_2x_(bsr, kX86InstIdBsr, X86GpVar, X86Mem, !o0.isGpb()) + + //! Byte swap (32-bit or 64-bit registers only) (i486). + INST_1x_(bswap, kX86InstIdBswap, X86GpVar, o0.getSize() >= 4) + + //! Bit test. + INST_2x(bt, kX86InstIdBt, X86GpVar, X86GpVar) + //! \overload + INST_2i(bt, kX86InstIdBt, X86GpVar, Imm) + //! \overload + INST_2x(bt, kX86InstIdBt, X86Mem, X86GpVar) + //! \overload + INST_2i(bt, kX86InstIdBt, X86Mem, Imm) + + //! Bit test and complement. + INST_2x(btc, kX86InstIdBtc, X86GpVar, X86GpVar) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86GpVar, Imm) + //! \overload + INST_2x(btc, kX86InstIdBtc, X86Mem, X86GpVar) + //! \overload + INST_2i(btc, kX86InstIdBtc, X86Mem, Imm) + + //! Bit test and reset. + INST_2x(btr, kX86InstIdBtr, X86GpVar, X86GpVar) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86GpVar, Imm) + //! \overload + INST_2x(btr, kX86InstIdBtr, X86Mem, X86GpVar) + //! \overload + INST_2i(btr, kX86InstIdBtr, X86Mem, Imm) + + //! Bit test and set. + INST_2x(bts, kX86InstIdBts, X86GpVar, X86GpVar) + //! \overload + INST_2i(bts, kX86InstIdBts, X86GpVar, Imm) + //! \overload + INST_2x(bts, kX86InstIdBts, X86Mem, X86GpVar) + //! \overload + INST_2i(bts, kX86InstIdBts, X86Mem, Imm) + + //! Call a function. + ASMJIT_INLINE X86CallNode* call(const X86GpVar& dst, uint32_t conv, const FuncPrototype& p) { + return addCall(dst, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(const X86Mem& dst, uint32_t conv, const FuncPrototype& p) { + return addCall(dst, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(const Label& label, uint32_t conv, const FuncPrototype& p) { + return addCall(label, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(const Imm& dst, uint32_t conv, const FuncPrototype& p) { + return addCall(dst, conv, p); + } + //! \overload + ASMJIT_INLINE X86CallNode* call(Ptr dst, uint32_t conv, const FuncPrototype& p) { + return addCall(Imm(dst), conv, p); + } + + //! Clear carry flag + INST_0x(clc, kX86InstIdClc) + //! Clear direction flag + INST_0x(cld, kX86InstIdCld) + //! Complement carry Flag. + INST_0x(cmc, kX86InstIdCmc) + + //! Convert BYTE to WORD (AX <- Sign Extend AL). + INST_1x(cbw, kX86InstIdCbw, X86GpVar /* al */) + //! Convert DWORD to QWORD (EDX:EAX <- Sign Extend EAX). + INST_2x(cdq, kX86InstIdCdq, X86GpVar /* edx */, X86GpVar /* eax */) + //! Convert DWORD to QWORD (RAX <- Sign Extend EAX) (X64 Only). + INST_1x(cdqe, kX86InstIdCdqe, X86GpVar /* eax */) + //! Convert QWORD to OWORD (RDX:RAX <- Sign Extend RAX) (X64 Only). + INST_2x(cqo, kX86InstIdCdq, X86GpVar /* rdx */, X86GpVar /* rax */) + //! Convert WORD to DWORD (DX:AX <- Sign Extend AX). + INST_2x(cwd, kX86InstIdCwd, X86GpVar /* dx */, X86GpVar /* ax */) + //! Convert WORD to DWORD (EAX <- Sign Extend AX). + INST_1x(cwde, kX86InstIdCwde, X86GpVar /* eax */) + + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86GpVar) + //! Conditional move. + INST_2cc(cmov, kX86InstIdCmov, X86Util::condToCmovcc, X86GpVar, X86Mem) + + //! Compare two operands. + INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86GpVar) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86GpVar, X86Mem) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86GpVar, Imm) + //! \overload + INST_2x(cmp, kX86InstIdCmp, X86Mem, X86GpVar) + //! \overload + INST_2i(cmp, kX86InstIdCmp, X86Mem, Imm) + + //! Compare BYTE in ES:`o0` and DS:`o1`. + INST_2x(cmpsb, kX86InstIdCmpsB, X86GpVar, X86GpVar) + //! Compare DWORD in ES:`o0` and DS:`o1`. + INST_2x(cmpsd, kX86InstIdCmpsD, X86GpVar, X86GpVar) + //! Compare QWORD in ES:`o0` and DS:`o1` (X64 Only). + INST_2x(cmpsq, kX86InstIdCmpsQ, X86GpVar, X86GpVar) + //! Compare WORD in ES:`o0` and DS:`o1`. + INST_2x(cmpsw, kX86InstIdCmpsW, X86GpVar, X86GpVar) + + //! Compare and exchange (i486). + INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86GpVar, X86GpVar) + //! \overload + INST_3x(cmpxchg, kX86InstIdCmpxchg, X86GpVar /* eax */, X86Mem, X86GpVar) + + //! Compare and exchange 128-bit value in RDX:RAX with `x_mem` (X64 Only). + ASMJIT_INLINE InstNode* cmpxchg16b( + const X86GpVar& r_edx, const X86GpVar& r_eax, + const X86GpVar& r_ecx, const X86GpVar& r_ebx, + const X86Mem& x_mem) { + + return emit(kX86InstIdCmpxchg16b, r_edx, r_eax, r_ecx, r_ebx, x_mem); + } + + //! Compare and exchange 64-bit value in EDX:EAX with `x_mem` (Pentium). + ASMJIT_INLINE InstNode* cmpxchg8b( + const X86GpVar& r_edx, const X86GpVar& r_eax, + const X86GpVar& r_ecx, const X86GpVar& r_ebx, + const X86Mem& x_mem) { + + return emit(kX86InstIdCmpxchg8b, r_edx, r_eax, r_ecx, r_ebx, x_mem); + } + + //! CPU identification (i486). + ASMJIT_INLINE InstNode* cpuid( + const X86GpVar& x_eax, + const X86GpVar& w_ebx, + const X86GpVar& x_ecx, + const X86GpVar& w_edx) { + + // Destination variables must be different. + ASMJIT_ASSERT(x_eax.getId() != w_ebx.getId() && + w_ebx.getId() != x_ecx.getId() && + x_ecx.getId() != w_edx.getId()); + + return emit(kX86InstIdCpuid, x_eax, w_ebx, x_ecx, w_edx); + } + + //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86GpVar, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! \overload + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + + //! Decimal adjust AL after addition (X86 Only). + INST_1x(daa, kX86InstIdDaa, X86GpVar) + //! Decimal adjust AL after subtraction (X86 Only). + INST_1x(das, kX86InstIdDas, X86GpVar) + + //! Decrement by 1. + INST_1x(dec, kX86InstIdDec, X86GpVar) + //! \overload + INST_1x(dec, kX86InstIdDec, X86Mem) + + //! Unsigned divide (o0:o1 <- o0:o1 / o2). + //! + //! Remainder is stored in `o0`, quotient is stored in `o1`. + INST_3x_(div, kX86InstIdDiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(div, kX86InstIdDiv, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Signed divide (o0:o1 <- o0:o1 / o2). + //! + //! Remainder is stored in `o0`, quotient is stored in `o1`. + INST_3x_(idiv, kX86InstIdIdiv, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(idiv, kX86InstIdIdiv, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Signed multiply (o0:o1 <- o1 * o2). + //! + //! Hi value is stored in `o0`, lo value is stored in `o1`. + INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(imul, kX86InstIdImul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Signed multiply. + INST_2x(imul, kX86InstIdImul, X86GpVar, X86GpVar) + //! \overload + INST_2x(imul, kX86InstIdImul, X86GpVar, X86Mem) + //! \overload + INST_2i(imul, kX86InstIdImul, X86GpVar, Imm) + + //! Signed multiply. + INST_3i(imul, kX86InstIdImul, X86GpVar, X86GpVar, Imm) + //! \overload + INST_3i(imul, kX86InstIdImul, X86GpVar, X86Mem, Imm) + + //! Increment by 1. + INST_1x(inc, kX86InstIdInc, X86GpVar) + //! \overload + INST_1x(inc, kX86InstIdInc, X86Mem) + + //! Interrupt. + INST_1i(int_, kX86InstIdInt, Imm) + //! Interrupt 3 - trap to debugger. + ASMJIT_INLINE InstNode* int3() { return int_(3); } + + //! Jump to label `label` if condition `cc` is met. + INST_1cc(j, kX86InstIdJ, X86Util::condToJcc, Label) + + //! Short jump if CX/ECX/RCX is zero. + INST_2x(jecxz, kX86InstIdJecxz, X86GpVar, Label) + + //! Jump. + INST_1x(jmp, kX86InstIdJmp, X86GpVar) + //! \overload + INST_1x(jmp, kX86InstIdJmp, X86Mem) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Label) + //! \overload + INST_1x(jmp, kX86InstIdJmp, Imm) + //! \overload + ASMJIT_INLINE InstNode* jmp(Ptr dst) { return jmp(Imm(dst)); } + + //! Load AH from flags. + INST_1x(lahf, kX86InstIdLahf, X86GpVar) + + //! Load effective address + INST_2x(lea, kX86InstIdLea, X86GpVar, X86Mem) + + //! Load BYTE from DS:`o1` to `o0`. + INST_2x(lodsb, kX86InstIdLodsB, X86GpVar, X86GpVar) + //! Load DWORD from DS:`o1` to `o0`. + INST_2x(lodsd, kX86InstIdLodsD, X86GpVar, X86GpVar) + //! Load QWORD from DS:`o1` to `o0` (X64 Only). + INST_2x(lodsq, kX86InstIdLodsQ, X86GpVar, X86GpVar) + //! Load WORD from DS:`o1` to `o0`. + INST_2x(lodsw, kX86InstIdLodsW, X86GpVar, X86GpVar) + + //! Move. + INST_2x(mov, kX86InstIdMov, X86GpVar, X86GpVar) + //! \overload + INST_2x(mov, kX86InstIdMov, X86GpVar, X86Mem) + //! \overload + INST_2i(mov, kX86InstIdMov, X86GpVar, Imm) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86GpVar) + //! \overload + INST_2i(mov, kX86InstIdMov, X86Mem, Imm) + + //! Move from segment register. + INST_2x(mov, kX86InstIdMov, X86GpVar, X86SegReg) + //! \overload + INST_2x(mov, kX86InstIdMov, X86Mem, X86SegReg) + //! Move to segment register. + INST_2x(mov, kX86InstIdMov, X86SegReg, X86GpVar) + //! \overload + INST_2x(mov, kX86InstIdMov, X86SegReg, X86Mem) + + //! Move (AL|AX|EAX|RAX <- absolute address in immediate). + INST_2x(mov_ptr, kX86InstIdMovPtr, X86GpReg, Imm); + //! \overload + ASMJIT_INLINE InstNode* mov_ptr(const X86GpReg& o0, Ptr o1) { + ASMJIT_ASSERT(o0.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, o0, Imm(o1)); + } + + //! Move (absolute address in immediate <- AL|AX|EAX|RAX). + INST_2x(mov_ptr, kX86InstIdMovPtr, Imm, X86GpReg); + //! \overload + ASMJIT_INLINE InstNode* mov_ptr(Ptr o0, const X86GpReg& o1) { + ASMJIT_ASSERT(o1.getRegIndex() == 0); + return emit(kX86InstIdMovPtr, Imm(o0), o1); + } + + //! Move data after swapping bytes (SSE3 - Atom). + INST_2x_(movbe, kX86InstIdMovbe, X86GpVar, X86Mem, !o0.isGpb()); + //! \overload + INST_2x_(movbe, kX86InstIdMovbe, X86Mem, X86GpVar, !o1.isGpb()); + + //! Load BYTE from DS:`o1` to ES:`o0`. + INST_2x(movsb, kX86InstIdMovsB, X86GpVar, X86GpVar) + //! Load DWORD from DS:`o1` to ES:`o0`. + INST_2x(movsd, kX86InstIdMovsD, X86GpVar, X86GpVar) + //! Load QWORD from DS:`o1` to ES:`o0` (X64 Only). + INST_2x(movsq, kX86InstIdMovsQ, X86GpVar, X86GpVar) + //! Load WORD from DS:`o1` to ES:`o0`. + INST_2x(movsw, kX86InstIdMovsW, X86GpVar, X86GpVar) + + //! Move with sign-extension. + INST_2x(movsx, kX86InstIdMovsx, X86GpVar, X86GpVar) + //! \overload + INST_2x(movsx, kX86InstIdMovsx, X86GpVar, X86Mem) + + //! Move DWORD to QWORD with sign-extension (X64 Only). + INST_2x(movsxd, kX86InstIdMovsxd, X86GpVar, X86GpVar) + //! \overload + INST_2x(movsxd, kX86InstIdMovsxd, X86GpVar, X86Mem) + + //! Move with zero-extension. + INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86GpVar) + //! \overload + INST_2x(movzx, kX86InstIdMovzx, X86GpVar, X86Mem) + + //! Unsigned multiply (o0:o1 <- o1 * o2). + INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! \overload + INST_3x_(mul, kX86InstIdMul, X86GpVar, X86GpVar, X86Mem, o0.getId() != o1.getId()) + + //! Two's complement negation. + INST_1x(neg, kX86InstIdNeg, X86GpVar) + //! \overload + INST_1x(neg, kX86InstIdNeg, X86Mem) + + //! No operation. + INST_0x(nop, kX86InstIdNop) + + //! One's complement negation. + INST_1x(not_, kX86InstIdNot, X86GpVar) + //! \overload + INST_1x(not_, kX86InstIdNot, X86Mem) + + //! Or. + INST_2x(or_, kX86InstIdOr, X86GpVar, X86GpVar) + //! \overload + INST_2x(or_, kX86InstIdOr, X86GpVar, X86Mem) + //! \overload + INST_2i(or_, kX86InstIdOr, X86GpVar, Imm) + //! \overload + INST_2x(or_, kX86InstIdOr, X86Mem, X86GpVar) + //! \overload + INST_2i(or_, kX86InstIdOr, X86Mem, Imm) + + //! Pop a value from the stack. + INST_1x_(pop, kX86InstIdPop, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) + //! \overload + INST_1x_(pop, kX86InstIdPop, X86Mem, o0.getSize() == 2 || o0.getSize() == _regSize) + + //! Pop stack into EFLAGS Register (32-bit or 64-bit). + INST_0x(popf, kX86InstIdPopf) + + //! Return the count of number of bits set to 1 (SSE4.2). + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86GpVar, !o0.isGpb() && o0.getSize() == o1.getSize()) + //! \overload + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86Mem, !o0.isGpb()) + + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push WORD or DWORD/QWORD on the stack. + INST_1x_(push, kX86InstIdPush, X86Mem,o0.getSize() == 2 || o0.getSize() == _regSize) + //! Push segment register on the stack. + INST_1x(push, kX86InstIdPush, X86SegReg) + //! Push WORD or DWORD/QWORD on the stack. + INST_1i(push, kX86InstIdPush, Imm) + + //! Push EFLAGS register (32-bit or 64-bit) on the stack. + INST_0x(pushf, kX86InstIdPushf) + + //! Rotate bits left. + INST_2x(rcl, kX86InstIdRcl, X86GpVar, X86GpVar) + //! \overload + INST_2x(rcl, kX86InstIdRcl, X86Mem, X86GpVar) + //! Rotate bits left. + INST_2i(rcl, kX86InstIdRcl, X86GpVar, Imm) + //! \overload + INST_2i(rcl, kX86InstIdRcl, X86Mem, Imm) + + //! Rotate bits right. + INST_2x(rcr, kX86InstIdRcr, X86GpVar, X86GpVar) + //! \overload + INST_2x(rcr, kX86InstIdRcr, X86Mem, X86GpVar) + //! Rotate bits right. + INST_2i(rcr, kX86InstIdRcr, X86GpVar, Imm) + //! \overload + INST_2i(rcr, kX86InstIdRcr, X86Mem, Imm) + + //! Read time-stamp counter (Pentium). + INST_2x_(rdtsc, kX86InstIdRdtsc, X86GpVar, X86GpVar, o0.getId() != o1.getId()) + //! Read time-stamp counter and processor id (Pentium). + INST_3x_(rdtscp, kX86InstIdRdtscp, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated load ECX/RCX BYTEs from DS:[ESI/RSI] to AL. + INST_3x_(rep_lodsb, kX86InstIdRepLodsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated load ECX/RCX DWORDs from DS:[ESI/RSI] to AL. + INST_3x_(rep_lodsd, kX86InstIdRepLodsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated load ECX/RCX QWORDs from DS:[RSI] to RAX (X64 Only). + INST_3x_(rep_lodsq, kX86InstIdRepLodsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated load ECX/RCX WORDs from DS:[ESI/RSI] to AX. + INST_3x_(rep_lodsw, kX86InstIdRepLodsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated move ECX/RCX BYTEs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_3x_(rep_movsb, kX86InstIdRepMovsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_3x_(rep_movsd, kX86InstIdRepMovsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated move ECX/RCX QWORDs from DS:[RSI] to ES:[RDI] (X64 Only). + INST_3x_(rep_movsq, kX86InstIdRepMovsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated move ECX/RCX DWORDs from DS:[ESI/RSI] to ES:[EDI/RDI]. + INST_3x_(rep_movsw, kX86InstIdRepMovsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated fill ECX/RCX BYTEs at ES:[EDI/RDI] with AL. + INST_3x_(rep_stosb, kX86InstIdRepStosB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated fill ECX/RCX DWORDs at ES:[EDI/RDI] with EAX. + INST_3x_(rep_stosd, kX86InstIdRepStosD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated fill ECX/RCX QWORDs at ES:[RDI] with RAX (X64 Only). + INST_3x_(rep_stosq, kX86InstIdRepStosQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated fill ECX/RCX WORDs at ES:[EDI/RDI] with AX. + INST_3x_(rep_stosw, kX86InstIdRepStosW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated find non-AL BYTEs in ES:[EDI/RDI] and DS:[ESI/RDI]. + INST_3x_(repe_cmpsb, kX86InstIdRepeCmpsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-EAX DWORDs in ES:[EDI/RDI] and DS:[ESI/RDI]. + INST_3x_(repe_cmpsd, kX86InstIdRepeCmpsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-RAX QWORDs in ES:[RDI] and DS:[RDI] (X64 Only). + INST_3x_(repe_cmpsq, kX86InstIdRepeCmpsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-AX WORDs in ES:[EDI/RDI] and DS:[ESI/RDI]. + INST_3x_(repe_cmpsw, kX86InstIdRepeCmpsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated find non-AL BYTE starting at ES:[EDI/RDI]. + INST_3x_(repe_scasb, kX86InstIdRepeScasB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-EAX DWORD starting at ES:[EDI/RDI]. + INST_3x_(repe_scasd, kX86InstIdRepeScasD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-RAX QWORD starting at ES:[RDI] (X64 Only). + INST_3x_(repe_scasq, kX86InstIdRepeScasQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find non-AX WORD starting at ES:[EDI/RDI]. + INST_3x_(repe_scasw, kX86InstIdRepeScasW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated find AL BYTEs in [RDI] and [RSI]. + INST_3x_(repne_cmpsb, kX86InstIdRepneCmpsB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find EAX DWORDs in [RDI] and [RSI]. + INST_3x_(repne_cmpsd, kX86InstIdRepneCmpsD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find RAX QWORDs in [RDI] and [RSI] (X64 Only). + INST_3x_(repne_cmpsq, kX86InstIdRepneCmpsQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find AX WORDs in [RDI] and [RSI]. + INST_3x_(repne_cmpsw, kX86InstIdRepneCmpsW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Repeated Find AL BYTEs, starting at ES:[EDI/RDI]. + INST_3x_(repne_scasb, kX86InstIdRepneScasB, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find EAX DWORDs, starting at ES:[EDI/RDI]. + INST_3x_(repne_scasd, kX86InstIdRepneScasD, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find RAX QWORDs, starting at ES:[RDI] (X64 Only). + INST_3x_(repne_scasq, kX86InstIdRepneScasQ, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + //! Repeated find AX WORDs, starting at ES:[EDI/RDI]. + INST_3x_(repne_scasw, kX86InstIdRepneScasW, X86GpVar, X86GpVar, X86GpVar, o0.getId() != o1.getId() && o1.getId() != o2.getId()) + + //! Return. + ASMJIT_INLINE RetNode* ret() { return addRet(noOperand, noOperand); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86GpVar& o0) { return addRet(o0, noOperand); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86GpVar& o0, const X86GpVar& o1) { return addRet(o0, o1); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0) { return addRet(o0, noOperand); } + //! \overload + ASMJIT_INLINE RetNode* ret(const X86XmmVar& o0, const X86XmmVar& o1) { return addRet(o0, o1); } + + //! Rotate bits left. + INST_2x(rol, kX86InstIdRol, X86GpVar, X86GpVar) + //! \overload + INST_2x(rol, kX86InstIdRol, X86Mem, X86GpVar) + //! Rotate bits left. + INST_2i(rol, kX86InstIdRol, X86GpVar, Imm) + //! \overload + INST_2i(rol, kX86InstIdRol, X86Mem, Imm) + + //! Rotate bits right. + INST_2x(ror, kX86InstIdRor, X86GpVar, X86GpVar) + //! \overload + INST_2x(ror, kX86InstIdRor, X86Mem, X86GpVar) + //! Rotate bits right. + INST_2i(ror, kX86InstIdRor, X86GpVar, Imm) + //! \overload + INST_2i(ror, kX86InstIdRor, X86Mem, Imm) + + //! Store `a` (allocated in AH/AX/EAX/RAX) into Flags. + INST_1x(sahf, kX86InstIdSahf, X86GpVar) + + //! Integer subtraction with borrow. + INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86GpVar) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86GpVar, X86Mem) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86GpVar, Imm) + //! \overload + INST_2x(sbb, kX86InstIdSbb, X86Mem, X86GpVar) + //! \overload + INST_2i(sbb, kX86InstIdSbb, X86Mem, Imm) + + //! Shift bits left. + INST_2x(sal, kX86InstIdSal, X86GpVar, X86GpVar) + //! \overload + INST_2x(sal, kX86InstIdSal, X86Mem, X86GpVar) + //! Shift bits left. + INST_2i(sal, kX86InstIdSal, X86GpVar, Imm) + //! \overload + INST_2i(sal, kX86InstIdSal, X86Mem, Imm) + + //! Shift bits right. + INST_2x(sar, kX86InstIdSar, X86GpVar, X86GpVar) + //! \overload + INST_2x(sar, kX86InstIdSar, X86Mem, X86GpVar) + //! Shift bits right. + INST_2i(sar, kX86InstIdSar, X86GpVar, Imm) + //! \overload + INST_2i(sar, kX86InstIdSar, X86Mem, Imm) + + //! Find non `o1` BYTE starting at ES:`o0`. + INST_2x(scasb, kX86InstIdScasB, X86GpVar, X86GpVar) + //! Find non `o1` DWORD starting at ES:`o0`. + INST_2x(scasd, kX86InstIdScasD, X86GpVar, X86GpVar) + //! Find non `o1` QWORD starting at ES:`o0` (X64 Only). + INST_2x(scasq, kX86InstIdScasQ, X86GpVar, X86GpVar) + //! Find non `o1` WORD starting at ES:`o0`. + INST_2x(scasw, kX86InstIdScasW, X86GpVar, X86GpVar) + + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86GpVar) + //! Set byte on condition. + INST_1cc(set, kX86InstIdSet, X86Util::condToSetcc, X86Mem) + + //! Shift bits left. + INST_2x(shl, kX86InstIdShl, X86GpVar, X86GpVar) + //! \overload + INST_2x(shl, kX86InstIdShl, X86Mem, X86GpVar) + //! Shift bits left. + INST_2i(shl, kX86InstIdShl, X86GpVar, Imm) + //! \overload + INST_2i(shl, kX86InstIdShl, X86Mem, Imm) + + //! Shift bits right. + INST_2x(shr, kX86InstIdShr, X86GpVar, X86GpVar) + //! \overload + INST_2x(shr, kX86InstIdShr, X86Mem, X86GpVar) + //! Shift bits right. + INST_2i(shr, kX86InstIdShr, X86GpVar, Imm) + //! \overload + INST_2i(shr, kX86InstIdShr, X86Mem, Imm) + + //! Double precision shift left. + INST_3x(shld, kX86InstIdShld, X86GpVar, X86GpVar, X86GpVar) + //! \overload + INST_3x(shld, kX86InstIdShld, X86Mem, X86GpVar, X86GpVar) + //! Double precision shift left. + INST_3i(shld, kX86InstIdShld, X86GpVar, X86GpVar, Imm) + //! \overload + INST_3i(shld, kX86InstIdShld, X86Mem, X86GpVar, Imm) + + //! Double precision shift right. + INST_3x(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, X86GpVar) + //! \overload + INST_3x(shrd, kX86InstIdShrd, X86Mem, X86GpVar, X86GpVar) + //! Double precision shift right. + INST_3i(shrd, kX86InstIdShrd, X86GpVar, X86GpVar, Imm) + //! \overload + INST_3i(shrd, kX86InstIdShrd, X86Mem, X86GpVar, Imm) + + //! Set carry flag to 1. + INST_0x(stc, kX86InstIdStc) + //! Set direction flag to 1. + INST_0x(std, kX86InstIdStd) + + //! Fill BYTE at ES:`o0` with `o1`. + INST_2x(stosb, kX86InstIdStosB, X86GpVar, X86GpVar) + //! Fill DWORD at ES:`o0` with `o1`. + INST_2x(stosd, kX86InstIdStosD, X86GpVar, X86GpVar) + //! Fill QWORD at ES:`o0` with `o1` (X64 Only). + INST_2x(stosq, kX86InstIdStosQ, X86GpVar, X86GpVar) + //! Fill WORD at ES:`o0` with `o1`. + INST_2x(stosw, kX86InstIdStosW, X86GpVar, X86GpVar) + + //! Subtract. + INST_2x(sub, kX86InstIdSub, X86GpVar, X86GpVar) + //! \overload + INST_2x(sub, kX86InstIdSub, X86GpVar, X86Mem) + //! \overload + INST_2i(sub, kX86InstIdSub, X86GpVar, Imm) + //! \overload + INST_2x(sub, kX86InstIdSub, X86Mem, X86GpVar) + //! \overload + INST_2i(sub, kX86InstIdSub, X86Mem, Imm) + + //! Logical compare. + INST_2x(test, kX86InstIdTest, X86GpVar, X86GpVar) + //! \overload + INST_2i(test, kX86InstIdTest, X86GpVar, Imm) + //! \overload + INST_2x(test, kX86InstIdTest, X86Mem, X86GpVar) + //! \overload + INST_2i(test, kX86InstIdTest, X86Mem, Imm) + + //! Undefined instruction - Raise #UD exception. + INST_0x(ud2, kX86InstIdUd2) + + //! Exchange and add. + INST_2x(xadd, kX86InstIdXadd, X86GpVar, X86GpVar) + //! \overload + INST_2x(xadd, kX86InstIdXadd, X86Mem, X86GpVar) + + //! Exchange register/memory with register. + INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86GpVar) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86Mem, X86GpVar) + //! \overload + INST_2x(xchg, kX86InstIdXchg, X86GpVar, X86Mem) + + //! Xor. + INST_2x(xor_, kX86InstIdXor, X86GpVar, X86GpVar) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86GpVar, X86Mem) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86GpVar, Imm) + //! \overload + INST_2x(xor_, kX86InstIdXor, X86Mem, X86GpVar) + //! \overload + INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [Fpu] + // -------------------------------------------------------------------------- + + //! Compute 2^x - 1 (FPU). + INST_0x(f2xm1, kX86InstIdF2xm1) + //! Absolute value of fp0 (FPU). + INST_0x(fabs, kX86InstIdFabs) + + //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU). + INST_1x(fadd, kX86InstIdFadd, X86Mem) + //! Add fp0 to `o0` and pop the FPU stack (FPU). + INST_1x(faddp, kX86InstIdFaddp, X86FpReg) + //! \overload + INST_0x(faddp, kX86InstIdFaddp) + + //! Load binary coded decimal (FPU). + INST_1x(fbld, kX86InstIdFbld, X86Mem) + //! Store BCD integer and Pop (FPU). + INST_1x(fbstp, kX86InstIdFbstp, X86Mem) + //! Change fp0 sign (FPU). + INST_0x(fchs, kX86InstIdFchs) + //! Clear exceptions (FPU). + INST_0x(fclex, kX86InstIdFclex) + + //! Conditional move (FPU). + INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) + //! Conditional move (FPU). + INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg) + + //! Compare fp0 with `o0` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86FpReg) + //! Compare fp0 with fp1 (FPU). + INST_0x(fcom, kX86InstIdFcom) + //! Compare fp0 with 4-byte or 8-byte FP at `src` (FPU). + INST_1x(fcom, kX86InstIdFcom, X86Mem) + //! Compare fp0 with `o0` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) + //! Compare fp0 with fp1 and pop the FPU stack (FPU). + INST_0x(fcomp, kX86InstIdFcomp) + //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU). + INST_1x(fcomp, kX86InstIdFcomp, X86Mem) + //! Compare fp0 with fp1 and pop the FPU stack twice (FPU). + INST_0x(fcompp, kX86InstIdFcompp) + //! Compare fp0 and `o0` and Set EFLAGS (FPU). + INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) + //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU). + INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) + + //! Calculate cosine of fp0 and store result in fp0 (FPU). + INST_0x(fcos, kX86InstIdFcos) + //! Decrement FPU stack-top pointer (FPU). + INST_0x(fdecstp, kX86InstIdFdecstp) + + //! Divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Divide fp0 by 32-bit or 64-bit FP value (FPU). + INST_1x(fdiv, kX86InstIdFdiv, X86Mem) + //! Divide `o0` by fp0 (FPU). + INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) + //! \overload + INST_0x(fdivp, kX86InstIdFdivp) + + //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU). + INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU). + INST_1x(fdivr, kX86InstIdFdivr, X86Mem) + //! Reverse divide `o0` by fp0 (FPU). + INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) + //! \overload + INST_0x(fdivrp, kX86InstIdFdivrp) + + //! Free FP register (FPU). + INST_1x(ffree, kX86InstIdFfree, X86FpReg) + + //! Add 16-bit or 32-bit integer to fp0 (FPU). + INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare fp0 with 16-bit or 32-bit Integer (FPU). + INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU). + INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU). + INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU). + INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Increment FPU stack-top pointer (FPU). + INST_0x(fincstp, kX86InstIdFincstp) + //! Initialize FPU (FPU). + INST_0x(finit, kX86InstIdFinit) + + //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + + //! Initialize FPU without checking for pending unmasked exceptions (FPU). + INST_0x(fninit, kX86InstIdFninit) + + //! Store fp0 as 16-bit or 32-bit Integer to `o0` (FPU). + INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) + //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU). + INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) + //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU). + INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Push `o0` on the FPU stack (FPU). + INST_1x(fld, kX86InstIdFld, X86FpReg) + + //! Push +1.0 on the FPU stack (FPU). + INST_0x(fld1, kX86InstIdFld1) + //! Push log2(10) on the FPU stack (FPU). + INST_0x(fldl2t, kX86InstIdFldl2t) + //! Push log2(e) on the FPU stack (FPU). + INST_0x(fldl2e, kX86InstIdFldl2e) + //! Push pi on the FPU stack (FPU). + INST_0x(fldpi, kX86InstIdFldpi) + //! Push log10(2) on the FPU stack (FPU). + INST_0x(fldlg2, kX86InstIdFldlg2) + //! Push ln(2) on the FPU stack (FPU). + INST_0x(fldln2, kX86InstIdFldln2) + //! Push +0.0 on the FPU stack (FPU). + INST_0x(fldz, kX86InstIdFldz) + + //! Load x87 FPU control word (2 bytes) (FPU). + INST_1x(fldcw, kX86InstIdFldcw, X86Mem) + //! Load x87 FPU environment (14 or 28 bytes) (FPU). + INST_1x(fldenv, kX86InstIdFldenv, X86Mem) + + //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU). + INST_1x(fmul, kX86InstIdFmul, X86Mem) + //! Multiply fp0 by `o0` and pop the FPU stack (FPU). + INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) + //! \overload + INST_0x(fmulp, kX86InstIdFmulp) + + //! Clear exceptions (FPU). + INST_0x(fnclex, kX86InstIdFnclex) + //! No operation (FPU). + INST_0x(fnop, kX86InstIdFnop) + //! Save FPU state (FPU). + INST_1x(fnsave, kX86InstIdFnsave, X86Mem) + //! Store x87 FPU environment (FPU). + INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) + //! Store x87 FPU control word (FPU). + INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem) + + //! Store x87 FPU status word to `o0` (AX) (FPU). + INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx)) + //! Store x87 FPU status word to `o0` (2 bytes) (FPU). + INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) + + //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU). + INST_0x(fpatan, kX86InstIdFpatan) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem, kX86InstIdFprem) + //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + INST_0x(fprem1, kX86InstIdFprem1) + //! Arctan(`fp0`) and pop the FPU stack (FPU). + INST_0x(fptan, kX86InstIdFptan) + //! Round `fp0` to Integer (FPU). + INST_0x(frndint, kX86InstIdFrndint) + + //! Restore FPU state from `o0` (94 or 108 bytes) (FPU). + INST_1x(frstor, kX86InstIdFrstor, X86Mem) + //! Save FPU state to `o0` (94 or 108 bytes) (FPU). + INST_1x(fsave, kX86InstIdFsave, X86Mem) + + //! Scale `fp0` by `fp1` (FPU). + INST_0x(fscale, kX86InstIdFscale) + //! Sine of `fp0` and store result in `fp0` (FPU). + INST_0x(fsin, kX86InstIdFsin) + //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU). + INST_0x(fsincos, kX86InstIdFsincos) + //! Square root of `fp0` and store it in `fp0` (FPU). + INST_0x(fsqrt, kX86InstIdFsqrt) + + //! Store floating point value to 32-bit or 64-bit memory location (FPU). + INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Store floating point value to `o0` (FPU). + INST_1x(fst, kX86InstIdFst, X86FpReg) + //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU). + INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) + //! Store floating point value to `o0` and pop the FPU stack (FPU). + INST_1x(fstp, kX86InstIdFstp, X86FpReg) + + //! Store x87 FPU control word to `o0` (2 bytes) (FPU). + INST_1x(fstcw, kX86InstIdFstcw, X86Mem) + //! Store x87 FPU environment to `o0` (14 or 28 bytes) (FPU). + INST_1x(fstenv, kX86InstIdFstenv, X86Mem) + //! Store x87 FPU status word to `o0` (allocated in AX) (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86GpVar) + //! Store x87 FPU status word (2 bytes) (FPU). + INST_1x(fstsw, kX86InstIdFstsw, X86Mem) + + //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU). + INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Subtract fp0 from `o0` and pop FPU stack (FPU). + INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) + //! \overload + INST_0x(fsubp, kX86InstIdFsubp) + + //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) + //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU). + INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) + //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU). + INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) + //! \overload + INST_0x(fsubrp, kX86InstIdFsubrp) + + //! Floating point test - Compare `fp0` with 0.0. (FPU). + INST_0x(ftst, kX86InstIdFtst) + + //! Unordered compare `fp0` with `o0` (FPU). + INST_1x(fucom, kX86InstIdFucom, X86FpReg) + //! Unordered compare `fp0` with `fp1` (FPU). + INST_0x(fucom, kX86InstIdFucom) + //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS (FPU). + INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) + //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU). + INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) + //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU). + INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU). + INST_0x(fucomp, kX86InstIdFucomp) + //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU). + INST_0x(fucompp, kX86InstIdFucompp) + + INST_0x(fwait, kX86InstIdFwait) + + //! Examine fp0 (FPU). + INST_0x(fxam, kX86InstIdFxam) + //! Exchange content of fp0 with `o0` (FPU). + INST_1x(fxch, kX86InstIdFxch, X86FpReg) + + //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem) + //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). + INST_1x(fxsave, kX86InstIdFxsave, X86Mem) + //! Extract exponent and store to `fp0` and push significand on the FPU stack (FPU). + INST_0x(fxtract, kX86InstIdFxtract) + + //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2x, kX86InstIdFyl2x) + //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU). + INST_0x(fyl2xp1, kX86InstIdFyl2xp1) + + // -------------------------------------------------------------------------- + // [MMX] + // -------------------------------------------------------------------------- + + //! Move DWORD (MMX). + INST_2x(movd, kX86InstIdMovd, X86Mem, X86MmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpVar, X86MmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmVar, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86MmVar, X86GpVar) + + //! Move QWORD (MMX). + INST_2x(movq, kX86InstIdMovq, X86MmVar, X86MmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86MmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmVar, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpVar, X86MmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86MmVar, X86GpVar) + + //! Pack DWORDs to WORDs with signed saturation (MMX). + INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86MmVar) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86MmVar, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (MMX). + INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86MmVar) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86MmVar, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (MMX). + INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86MmVar) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86MmVar, X86Mem) + + //! Packed BYTE add (MMX). + INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86MmVar, X86Mem) + + //! Packed DWORD add (MMX). + INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86MmVar, X86Mem) + + //! Packed BYTE add with saturation (MMX). + INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86MmVar, X86Mem) + + //! Packed WORD add with saturation (MMX). + INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86MmVar, X86Mem) + + //! Packed BYTE add with unsigned saturation (MMX). + INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86MmVar, X86Mem) + + //! Packed WORD add with unsigned saturation (MMX). + INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86MmVar, X86Mem) + + //! Packed WORD add (MMX). + INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86MmVar, X86Mem) + + //! Packed and (MMX). + INST_2x(pand, kX86InstIdPand, X86MmVar, X86MmVar) + //! \overload + INST_2x(pand, kX86InstIdPand, X86MmVar, X86Mem) + + //! Packed and-not (MMX). + INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86MmVar) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86MmVar, X86Mem) + + //! Packed BYTEs compare for equality (MMX). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86MmVar, X86Mem) + + //! Packed DWORDs compare for equality (MMX). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86MmVar, X86Mem) + + //! Packed WORDs compare for equality (MMX). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86MmVar, X86Mem) + + //! Packed BYTEs compare if greater than (MMX). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86MmVar, X86Mem) + + //! Packed DWORDs compare if greater than (MMX). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86MmVar, X86Mem) + + //! Packed WORDs compare if greater than (MMX). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86MmVar, X86Mem) + + //! Packed WORD multiply high (MMX). + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86MmVar, X86Mem) + + //! Packed WORD multiply low (MMX). + INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86MmVar, X86Mem) + + //! Packed bitwise or (MMX). + INST_2x(por, kX86InstIdPor, X86MmVar, X86MmVar) + //! \overload + INST_2x(por, kX86InstIdPor, X86MmVar, X86Mem) + + //! Packed WORD multiply and add to packed DWORD (MMX). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86MmVar, X86Mem) + + //! Packed DWORD shift left logical (MMX). + INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86MmVar) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86MmVar, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86MmVar, Imm) + + //! Packed QWORD shift left logical (MMX). + INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86MmVar) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86MmVar, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86MmVar, Imm) + + //! Packed WORD shift left logical (MMX). + INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86MmVar, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86MmVar, Imm) + + //! Packed DWORD shift right arithmetic (MMX). + INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86MmVar, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86MmVar, Imm) + + //! Packed WORD shift right arithmetic (MMX). + INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86MmVar, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86MmVar, Imm) + + //! Packed DWORD shift right logical (MMX). + INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86MmVar, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86MmVar, Imm) + + //! Packed QWORD shift right logical (MMX). + INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86MmVar, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86MmVar, Imm) + + //! Packed WORD shift right logical (MMX). + INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86MmVar, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86MmVar, Imm) + + //! Packed BYTE subtract (MMX). + INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86MmVar, X86Mem) + + //! Packed DWORD subtract (MMX). + INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86MmVar, X86Mem) + + //! Packed BYTE subtract with saturation (MMX). + INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86MmVar, X86Mem) + + //! Packed WORD subtract with saturation (MMX). + INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86MmVar, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (MMX). + INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86MmVar, X86Mem) + + //! Packed WORD subtract with unsigned saturation (MMX). + INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86MmVar, X86Mem) + + //! Packed WORD subtract (MMX). + INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86MmVar, X86Mem) + + //! Unpack high packed BYTEs to WORDs (MMX). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86MmVar, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (MMX). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86MmVar, X86Mem) + + //! Unpack high packed WORDs to DWORDs (MMX). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86MmVar, X86Mem) + + //! Unpack low packed BYTEs to WORDs (MMX). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86MmVar, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (MMX). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86MmVar, X86Mem) + + //! Unpack low packed WORDs to DWORDs (MMX). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86MmVar) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86MmVar, X86Mem) + + //! Packed bitwise xor (MMX). + INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86MmVar) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86MmVar, X86Mem) + + //! Empty MMX state. + INST_0x(emms, kX86InstIdEmms) + + // -------------------------------------------------------------------------- + // [3dNow] + // -------------------------------------------------------------------------- + + //! Packed SP-FP to DWORD convert (3dNow!). + INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86MmVar) + //! \overload + INST_2x(pf2id, kX86InstIdPf2id, X86MmVar, X86Mem) + + //! Packed SP-FP to WORD convert (3dNow!). + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pf2iw, kX86InstIdPf2iw, X86MmVar, X86Mem) + + //! Packed SP-FP accumulate (3dNow!). + INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfacc, kX86InstIdPfacc, X86MmVar, X86Mem) + + //! Packed SP-FP addition (3dNow!). + INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfadd, kX86InstIdPfadd, X86MmVar, X86Mem) + + //! Packed SP-FP compare - dst == src (3dNow!). + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfcmpeq, kX86InstIdPfcmpeq, X86MmVar, X86Mem) + + //! Packed SP-FP compare - dst >= src (3dNow!). + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfcmpge, kX86InstIdPfcmpge, X86MmVar, X86Mem) + + //! Packed SP-FP compare - dst > src (3dNow!). + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfcmpgt, kX86InstIdPfcmpgt, X86MmVar, X86Mem) + + //! Packed SP-FP maximum (3dNow!). + INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfmax, kX86InstIdPfmax, X86MmVar, X86Mem) + + //! Packed SP-FP minimum (3dNow!). + INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfmin, kX86InstIdPfmin, X86MmVar, X86Mem) + + //! Packed SP-FP multiply (3dNow!). + INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfmul, kX86InstIdPfmul, X86MmVar, X86Mem) + + //! Packed SP-FP negative accumulate (3dNow!). + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfnacc, kX86InstIdPfnacc, X86MmVar, X86Mem) + + //! Packed SP-FP mixed accumulate (3dNow!). + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfpnacc, kX86InstIdPfpnacc, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal approximation (3dNow!). + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrcp, kX86InstIdPfrcp, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal, first iteration step (3dNow!). + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrcpit1, kX86InstIdPfrcpit1, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal, second iteration step (3dNow!). + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrcpit2, kX86InstIdPfrcpit2, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal square root, first iteration step (3dNow!). + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrsqit1, kX86InstIdPfrsqit1, X86MmVar, X86Mem) + + //! Packed SP-FP reciprocal square root approximation (3dNow!). + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfrsqrt, kX86InstIdPfrsqrt, X86MmVar, X86Mem) + + //! Packed SP-FP subtract (3dNow!). + INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfsub, kX86InstIdPfsub, X86MmVar, X86Mem) + + //! Packed SP-FP reverse subtract (3dNow!). + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86MmVar) + //! \overload + INST_2x(pfsubr, kX86InstIdPfsubr, X86MmVar, X86Mem) + + //! Packed DWORDs to SP-FP (3dNow!). + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pi2fd, kX86InstIdPi2fd, X86MmVar, X86Mem) + + //! Packed WORDs to SP-FP (3dNow!). + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pi2fw, kX86InstIdPi2fw, X86MmVar, X86Mem) + + //! Packed swap DWORDs (3dNow!) + INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pswapd, kX86InstIdPswapd, X86MmVar, X86Mem) + + //! Prefetch (3dNow!). + INST_1x(prefetch_3dnow, kX86InstIdPrefetch3dNow, X86Mem) + + //! Prefetch and set cache to modified (3dNow!). + INST_1x(prefetchw_3dnow, kX86InstIdPrefetchw3dNow, X86Mem) + + //! Faster EMMS (3dNow!). + INST_0x(femms, kX86InstIdFemms) + + // -------------------------------------------------------------------------- + // [SSE] + // -------------------------------------------------------------------------- + + //! Packed SP-FP add (SSE). + INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addps, kX86InstIdAddps, X86XmmVar, X86Mem) + + //! Scalar SP-FP add (SSE). + INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addss, kX86InstIdAddss, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise and-not (SSE). + INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andnps, kX86InstIdAndnps, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise and (SSE). + INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andps, kX86InstIdAndps, X86XmmVar, X86Mem) + + //! Packed SP-FP compare (SSE). + INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmpps, kX86InstIdCmpps, X86XmmVar, X86Mem, Imm) + + //! Compare scalar SP-FP Values (SSE). + INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmpss, kX86InstIdCmpss, X86XmmVar, X86Mem, Imm) + + //! Scalar ordered SP-FP compare and set EFLAGS (SSE). + INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(comiss, kX86InstIdComiss, X86XmmVar, X86Mem) + + //! Packed signed INT32 to packed SP-FP conversion (SSE). + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86MmVar) + //! \overload + INST_2x(cvtpi2ps, kX86InstIdCvtpi2ps, X86XmmVar, X86Mem) + + //! Packed SP-FP to packed INT32 conversion (SSE). + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvtps2pi, kX86InstIdCvtps2pi, X86MmVar, X86Mem) + + //! Convert scalar INT32 to SP-FP (SSE). + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86GpVar) + //! \overload + INST_2x(cvtsi2ss, kX86InstIdCvtsi2ss, X86XmmVar, X86Mem) + + //! Convert scalar SP-FP to INT32 (SSE). + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvtss2si, kX86InstIdCvtss2si, X86GpVar, X86Mem) + + //! Convert with truncation packed SP-FP to packed INT32 (SSE). + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvttps2pi, kX86InstIdCvttps2pi, X86MmVar, X86Mem) + + //! Convert with truncation scalar SP-FP to INT32 (SSE). + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvttss2si, kX86InstIdCvttss2si, X86GpVar, X86Mem) + + //! Packed SP-FP divide (SSE). + INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divps, kX86InstIdDivps, X86XmmVar, X86Mem) + + //! Scalar SP-FP divide (SSE). + INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divss, kX86InstIdDivss, X86XmmVar, X86Mem) + + //! Load streaming SIMD extension control/status (SSE). + INST_1x(ldmxcsr, kX86InstIdLdmxcsr, X86Mem) + + //! Byte mask write (SSE). + INST_3x(maskmovq, kX86InstIdMaskmovq, X86GpVar /* zdi */, X86MmVar, X86MmVar) + + //! Packed SP-FP maximum (SSE). + INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxps, kX86InstIdMaxps, X86XmmVar, X86Mem) + + //! Scalar SP-FP maximum (SSE). + INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxss, kX86InstIdMaxss, X86XmmVar, X86Mem) + + //! Packed SP-FP minimum (SSE). + INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minps, kX86InstIdMinps, X86XmmVar, X86Mem) + + //! Scalar SP-FP minimum (SSE). + INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minss, kX86InstIdMinss, X86XmmVar, X86Mem) + + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movaps, kX86InstIdMovaps, X86XmmVar, X86Mem) + //! Move aligned packed SP-FP (SSE). + INST_2x(movaps, kX86InstIdMovaps, X86Mem, X86XmmVar) + + //! Move DWORD. + INST_2x(movd, kX86InstIdMovd, X86Mem, X86XmmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86GpVar, X86XmmVar) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movd, kX86InstIdMovd, X86XmmVar, X86GpVar) + + //! Move QWORD (SSE). + INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86Mem, X86XmmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86Mem) + + //! Move QWORD (X64 Only). + INST_2x(movq, kX86InstIdMovq, X86GpVar, X86XmmVar) + //! \overload + INST_2x(movq, kX86InstIdMovq, X86XmmVar, X86GpVar) + + //! Move QWORD using NT hint (SSE). + INST_2x(movntq, kX86InstIdMovntq, X86Mem, X86MmVar) + + //! Move high to low packed SP-FP (SSE). + INST_2x(movhlps, kX86InstIdMovhlps, X86XmmVar, X86XmmVar) + + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86XmmVar, X86Mem) + //! Move high packed SP-FP (SSE). + INST_2x(movhps, kX86InstIdMovhps, X86Mem, X86XmmVar) + + //! Move low to high packed SP-FP (SSE). + INST_2x(movlhps, kX86InstIdMovlhps, X86XmmVar, X86XmmVar) + + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86XmmVar, X86Mem) + //! Move low packed SP-FP (SSE). + INST_2x(movlps, kX86InstIdMovlps, X86Mem, X86XmmVar) + + //! Move aligned packed SP-FP using NT hint (SSE). + INST_2x(movntps, kX86InstIdMovntps, X86Mem, X86XmmVar) + + //! Move scalar SP-FP (SSE). + INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86XmmVar, X86Mem) + //! \overload + INST_2x(movss, kX86InstIdMovss, X86Mem, X86XmmVar) + + //! Move unaligned packed SP-FP (SSE). + INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86XmmVar, X86Mem) + //! \overload + INST_2x(movups, kX86InstIdMovups, X86Mem, X86XmmVar) + + //! Packed SP-FP multiply (SSE). + INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulps, kX86InstIdMulps, X86XmmVar, X86Mem) + + //! Scalar SP-FP multiply (SSE). + INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulss, kX86InstIdMulss, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise or (SSE). + INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(orps, kX86InstIdOrps, X86XmmVar, X86Mem) + + //! Packed BYTE average (SSE). + INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86MmVar, X86Mem) + + //! Packed WORD average (SSE). + INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86MmVar, X86Mem) + + //! Extract WORD based on selector (SSE). + INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86MmVar, Imm) + + //! Insert WORD based on selector (SSE). + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86MmVar, X86Mem, Imm) + + //! Packed WORD maximum (SSE). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86MmVar, X86Mem) + + //! Packed BYTE unsigned maximum (SSE). + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86MmVar, X86Mem) + + //! Packed WORD minimum (SSE). + INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86MmVar, X86Mem) + + //! Packed BYTE unsigned minimum (SSE). + INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86MmVar) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86MmVar, X86Mem) + + //! Move byte mask to integer (SSE). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86MmVar) + + //! Packed WORD unsigned multiply high (SSE). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86MmVar, X86Mem) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86MmVar, X86Mem) + + //! Packed WORD shuffle (SSE). + INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86MmVar, Imm) + //! \overload + INST_3i(pshufw, kX86InstIdPshufw, X86MmVar, X86Mem, Imm) + + //! Packed SP-FP reciprocal (SSE). + INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rcpps, kX86InstIdRcpps, X86XmmVar, X86Mem) + + //! Scalar SP-FP reciprocal (SSE). + INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rcpss, kX86InstIdRcpss, X86XmmVar, X86Mem) + + //! Prefetch (SSE). + INST_2i(prefetch, kX86InstIdPrefetch, X86Mem, Imm) + + //! Packed WORD sum of absolute differences (SSE). + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psadbw, kX86InstIdPsadbw, X86XmmVar, X86Mem) + + //! Packed SP-FP Square root reciprocal (SSE). + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rsqrtps, kX86InstIdRsqrtps, X86XmmVar, X86Mem) + + //! Scalar SP-FP Square root reciprocal (SSE). + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(rsqrtss, kX86InstIdRsqrtss, X86XmmVar, X86Mem) + + //! Store fence (SSE). + INST_0x(sfence, kX86InstIdSfence) + + //! Shuffle SP-FP (SSE). + INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(shufps, kX86InstIdShufps, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP square root (SSE). + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtps, kX86InstIdSqrtps, X86XmmVar, X86Mem) + + //! Scalar SP-FP square root (SSE). + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtss, kX86InstIdSqrtss, X86XmmVar, X86Mem) + + //! Store streaming SIMD extension control/status (SSE). + INST_1x(stmxcsr, kX86InstIdStmxcsr, X86Mem) + + //! Packed SP-FP subtract (SSE). + INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subps, kX86InstIdSubps, X86XmmVar, X86Mem) + + //! Scalar SP-FP subtract (SSE). + INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subss, kX86InstIdSubss, X86XmmVar, X86Mem) + + //! Unordered scalar SP-FP compare and set EFLAGS (SSE). + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(ucomiss, kX86InstIdUcomiss, X86XmmVar, X86Mem) + + //! Unpack high packed SP-FP data (SSE). + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpckhps, kX86InstIdUnpckhps, X86XmmVar, X86Mem) + + //! Unpack low packed SP-FP data (SSE). + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpcklps, kX86InstIdUnpcklps, X86XmmVar, X86Mem) + + //! Packed SP-FP bitwise xor (SSE). + INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(xorps, kX86InstIdXorps, X86XmmVar, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE2] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add (SSE2). + INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addpd, kX86InstIdAddpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP add (SSE2). + INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addsd, kX86InstIdAddsd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise and-not (SSE2). + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andnpd, kX86InstIdAndnpd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise and (SSE2). + INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(andpd, kX86InstIdAndpd, X86XmmVar, X86Mem) + + //! Flush cache line (SSE2). + INST_1x(clflush, kX86InstIdClflush, X86Mem) + + //! Packed DP-FP compare (SSE2). + INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmppd, kX86InstIdCmppd, X86XmmVar, X86Mem, Imm) + + //! Scalar SP-FP compare (SSE2). + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(cmpsd, kX86InstIdCmpsd, X86XmmVar, X86Mem, Imm) + + //! Scalar ordered DP-FP compare and set EFLAGS (SSE2). + INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(comisd, kX86InstIdComisd, X86XmmVar, X86Mem) + + //! Convert packed DWORD integers to packed DP-FP (SSE2). + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtdq2pd, kX86InstIdCvtdq2pd, X86XmmVar, X86Mem) + + //! Convert packed DWORD integers to packed SP-FP (SSE2). + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmVar, X86Mem) + + //! Convert packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmVar, X86Mem) + + //! Convert packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmVar, X86Mem) + + //! Convert packed DP-FP to packed SP-FP (SSE2). + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtpd2ps, kX86InstIdCvtpd2ps, X86XmmVar, X86Mem) + + //! Convert packed DWORDs to packed DP-FP (SSE2). + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86MmVar) + //! \overload + INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmVar, X86Mem) + + //! Convert packed SP-FP to packed DWORDs (SSE2). + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmVar, X86Mem) + + //! Convert packed SP-FP to packed DP-FP (SSE2). + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtps2pd, kX86InstIdCvtps2pd, X86XmmVar, X86Mem) + + //! Convert scalar DP-FP to DWORD (SSE2). + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvtsd2si, kX86InstIdCvtsd2si, X86GpVar, X86Mem) + + //! Convert scalar DP-FP to scalar SP-FP (SSE2). + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtsd2ss, kX86InstIdCvtsd2ss, X86XmmVar, X86Mem) + + //! Convert DWORD to scalar DP-FP (SSE2). + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86GpVar) + //! \overload + INST_2x(cvtsi2sd, kX86InstIdCvtsi2sd, X86XmmVar, X86Mem) + + //! Convert scalar SP-FP to DP-FP (SSE2). + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvtss2sd, kX86InstIdCvtss2sd, X86XmmVar, X86Mem) + + //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86XmmVar) + //! \overload + INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmVar, X86Mem) + + //! Convert with truncation packed DP-FP to packed QWORDs (SSE2). + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmVar, X86Mem) + + //! Convert with truncation packed SP-FP to packed QWORDs (SSE2). + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmVar, X86Mem) + + //! Convert with truncation scalar DP-FP to DWORD (SSE2). + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86XmmVar) + //! \overload + INST_2x(cvttsd2si, kX86InstIdCvttsd2si, X86GpVar, X86Mem) + + //! Packed DP-FP divide (SSE2). + INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divpd, kX86InstIdDivpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP divide (SSE2). + INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(divsd, kX86InstIdDivsd, X86XmmVar, X86Mem) + + //! Load fence (SSE2). + INST_0x(lfence, kX86InstIdLfence) + + //! Store selected bytes of OWORD (SSE2). + INST_3x(maskmovdqu, kX86InstIdMaskmovdqu, X86GpVar /* zdi */, X86XmmVar, X86XmmVar) + + //! Packed DP-FP maximum (SSE2). + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxpd, kX86InstIdMaxpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP maximum (SSE2). + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(maxsd, kX86InstIdMaxsd, X86XmmVar, X86Mem) + + //! Memory fence (SSE2). + INST_0x(mfence, kX86InstIdMfence) + + //! Packed DP-FP minimum (SSE2). + INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minpd, kX86InstIdMinpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP minimum (SSE2). + INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(minsd, kX86InstIdMinsd, X86XmmVar, X86Mem) + + //! Move aligned OWORD (SSE2). + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86XmmVar, X86Mem) + //! \overload + INST_2x(movdqa, kX86InstIdMovdqa, X86Mem, X86XmmVar) + + //! Move unaligned OWORD (SSE2). + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86XmmVar, X86Mem) + //! \overload + INST_2x(movdqu, kX86InstIdMovdqu, X86Mem, X86XmmVar) + + //! Extract packed SP-FP sign mask (SSE2). + INST_2x(movmskps, kX86InstIdMovmskps, X86GpVar, X86XmmVar) + + //! Extract packed DP-FP sign mask (SSE2). + INST_2x(movmskpd, kX86InstIdMovmskpd, X86GpVar, X86XmmVar) + + //! Move scalar DP-FP (SSE2). + INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movsd, kX86InstIdMovsd, X86Mem, X86XmmVar) + + //! Move aligned packed DP-FP (SSE2). + INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movapd, kX86InstIdMovapd, X86Mem, X86XmmVar) + + //! Move QWORD from Xmm to Mm register (SSE2). + INST_2x(movdq2q, kX86InstIdMovdq2q, X86MmVar, X86XmmVar) + + //! Move QWORD from Mm to Xmm register (SSE2). + INST_2x(movq2dq, kX86InstIdMovq2dq, X86XmmVar, X86MmVar) + + //! Move high packed DP-FP (SSE2). + INST_2x(movhpd, kX86InstIdMovhpd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movhpd, kX86InstIdMovhpd, X86Mem, X86XmmVar) + + //! Move low packed DP-FP (SSE2). + INST_2x(movlpd, kX86InstIdMovlpd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movlpd, kX86InstIdMovlpd, X86Mem, X86XmmVar) + + //! Store OWORD using NT hint (SSE2). + INST_2x(movntdq, kX86InstIdMovntdq, X86Mem, X86XmmVar) + + //! Store DWORD using NT hint (SSE2). + INST_2x(movnti, kX86InstIdMovnti, X86Mem, X86GpVar) + + //! Store packed DP-FP using NT hint (SSE2). + INST_2x(movntpd, kX86InstIdMovntpd, X86Mem, X86XmmVar) + + //! Move unaligned packed DP-FP (SSE2). + INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86XmmVar, X86Mem) + //! \overload + INST_2x(movupd, kX86InstIdMovupd, X86Mem, X86XmmVar) + + //! Packed DP-FP multiply (SSE2). + INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulpd, kX86InstIdMulpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP multiply (SSE2). + INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(mulsd, kX86InstIdMulsd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise or (SSE2). + INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(orpd, kX86InstIdOrpd, X86XmmVar, X86Mem) + + //! Pack WORDs to BYTEs with signed saturation (SSE2). + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packsswb, kX86InstIdPacksswb, X86XmmVar, X86Mem) + + //! Pack DWORDs to WORDs with signed saturation (SSE2). + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packssdw, kX86InstIdPackssdw, X86XmmVar, X86Mem) + + //! Pack WORDs to BYTEs with unsigned saturation (SSE2). + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packuswb, kX86InstIdPackuswb, X86XmmVar, X86Mem) + + //! Packed BYTE add (SSE2). + INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddb, kX86InstIdPaddb, X86XmmVar, X86Mem) + + //! Packed WORD add (SSE2). + INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddw, kX86InstIdPaddw, X86XmmVar, X86Mem) + + //! Packed DWORD add (SSE2). + INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddd, kX86InstIdPaddd, X86XmmVar, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86MmVar) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86MmVar, X86Mem) + + //! Packed QWORD add (SSE2). + INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddq, kX86InstIdPaddq, X86XmmVar, X86Mem) + + //! Packed BYTE add with saturation (SSE2). + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddsb, kX86InstIdPaddsb, X86XmmVar, X86Mem) + + //! Packed WORD add with saturation (SSE2). + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddsw, kX86InstIdPaddsw, X86XmmVar, X86Mem) + + //! Packed BYTE add with unsigned saturation (SSE2). + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddusb, kX86InstIdPaddusb, X86XmmVar, X86Mem) + + //! Packed WORD add with unsigned saturation (SSE2). + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(paddusw, kX86InstIdPaddusw, X86XmmVar, X86Mem) + + //! Packed bitwise and (SSE2). + INST_2x(pand, kX86InstIdPand, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pand, kX86InstIdPand, X86XmmVar, X86Mem) + + //! Packed bitwise and-not (SSE2). + INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pandn, kX86InstIdPandn, X86XmmVar, X86Mem) + + //! Spin loop hint (SSE2). + INST_0x(pause, kX86InstIdPause) + + //! Packed BYTE average (SSE2). + INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pavgb, kX86InstIdPavgb, X86XmmVar, X86Mem) + + //! Packed WORD average (SSE2). + INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pavgw, kX86InstIdPavgw, X86XmmVar, X86Mem) + + //! Packed BYTE compare for equality (SSE2). + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqb, kX86InstIdPcmpeqb, X86XmmVar, X86Mem) + + //! Packed WROD compare for equality (SSE2). + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqw, kX86InstIdPcmpeqw, X86XmmVar, X86Mem) + + //! Packed DWORD compare for equality (SSE2). + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqd, kX86InstIdPcmpeqd, X86XmmVar, X86Mem) + + //! Packed BYTE compare if greater than (SSE2). + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtb, kX86InstIdPcmpgtb, X86XmmVar, X86Mem) + + //! Packed WORD compare if greater than (SSE2). + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtw, kX86InstIdPcmpgtw, X86XmmVar, X86Mem) + + //! Packed DWORD compare if greater than (SSE2). + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtd, kX86InstIdPcmpgtd, X86XmmVar, X86Mem) + + //! Extract WORD based on selector (SSE2). + INST_3i(pextrw, kX86InstIdPextrw, X86GpVar, X86XmmVar, Imm) + + //! Insert WORD based on selector (SSE2). + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrw, kX86InstIdPinsrw, X86XmmVar, X86Mem, Imm) + + //! Packed WORD maximum (SSE2). + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxsw, kX86InstIdPmaxsw, X86XmmVar, X86Mem) + + //! Packed BYTE unsigned maximum (SSE2). + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxub, kX86InstIdPmaxub, X86XmmVar, X86Mem) + + //! Packed WORD minimum (SSE2). + INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminsw, kX86InstIdPminsw, X86XmmVar, X86Mem) + + //! Packed BYTE unsigned minimum (SSE2). + INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminub, kX86InstIdPminub, X86XmmVar, X86Mem) + + //! Move BYTE mask (SSE2). + INST_2x(pmovmskb, kX86InstIdPmovmskb, X86GpVar, X86XmmVar) + + //! Packed WORD multiply high (SSE2). + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulhw, kX86InstIdPmulhw, X86XmmVar, X86Mem) + + //! Packed WORD unsigned multiply high (SSE2). + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulhuw, kX86InstIdPmulhuw, X86XmmVar, X86Mem) + + //! Packed WORD multiply low (SSE2). + INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmullw, kX86InstIdPmullw, X86XmmVar, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86MmVar, X86Mem) + + //! Packed DWORD multiply to QWORD (SSE2). + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmuludq, kX86InstIdPmuludq, X86XmmVar, X86Mem) + + //! Packed bitwise or (SSE2). + INST_2x(por, kX86InstIdPor, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(por, kX86InstIdPor, X86XmmVar, X86Mem) + + //! Packed DWORD shift left logical (SSE2). + INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pslld, kX86InstIdPslld, X86XmmVar, X86Mem) + //! \overload + INST_2i(pslld, kX86InstIdPslld, X86XmmVar, Imm) + + //! Packed QWORD shift left logical (SSE2). + INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psllq, kX86InstIdPsllq, X86XmmVar, X86Mem) + //! \overload + INST_2i(psllq, kX86InstIdPsllq, X86XmmVar, Imm) + + //! Packed WORD shift left logical (SSE2). + INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psllw, kX86InstIdPsllw, X86XmmVar, X86Mem) + //! \overload + INST_2i(psllw, kX86InstIdPsllw, X86XmmVar, Imm) + + //! Packed OWORD shift left logical (SSE2). + INST_2i(pslldq, kX86InstIdPslldq, X86XmmVar, Imm) + + //! Packed DWORD shift right arithmetic (SSE2). + INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrad, kX86InstIdPsrad, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrad, kX86InstIdPsrad, X86XmmVar, Imm) + + //! Packed WORD shift right arithmetic (SSE2). + INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psraw, kX86InstIdPsraw, X86XmmVar, X86Mem) + //! \overload + INST_2i(psraw, kX86InstIdPsraw, X86XmmVar, Imm) + + //! Packed BYTE subtract (SSE2). + INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubb, kX86InstIdPsubb, X86XmmVar, X86Mem) + + //! Packed DWORD subtract (SSE2). + INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubd, kX86InstIdPsubd, X86XmmVar, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86MmVar) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86MmVar, X86Mem) + + //! Packed QWORD subtract (SSE2). + INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubq, kX86InstIdPsubq, X86XmmVar, X86Mem) + + //! Packed WORD subtract (SSE2). + INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubw, kX86InstIdPsubw, X86XmmVar, X86Mem) + + //! Packed WORD to DWORD multiply and add (SSE2). + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaddwd, kX86InstIdPmaddwd, X86XmmVar, X86Mem) + + //! Packed DWORD shuffle (SSE2). + INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pshufd, kX86InstIdPshufd, X86XmmVar, X86Mem, Imm) + + //! Packed WORD shuffle high (SSE2). + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pshufhw, kX86InstIdPshufhw, X86XmmVar, X86Mem, Imm) + + //! Packed WORD shuffle low (SSE2). + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pshuflw, kX86InstIdPshuflw, X86XmmVar, X86Mem, Imm) + + //! Packed DWORD shift right logical (SSE2). + INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrld, kX86InstIdPsrld, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrld, kX86InstIdPsrld, X86XmmVar, Imm) + + //! Packed QWORD shift right logical (SSE2). + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrlq, kX86InstIdPsrlq, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrlq, kX86InstIdPsrlq, X86XmmVar, Imm) + + //! Scalar OWORD shift right logical (SSE2). + INST_2i(psrldq, kX86InstIdPsrldq, X86XmmVar, Imm) + + //! Packed WORD shift right logical (SSE2). + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psrlw, kX86InstIdPsrlw, X86XmmVar, X86Mem) + //! \overload + INST_2i(psrlw, kX86InstIdPsrlw, X86XmmVar, Imm) + + //! Packed BYTE subtract with saturation (SSE2). + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubsb, kX86InstIdPsubsb, X86XmmVar, X86Mem) + + //! Packed WORD subtract with saturation (SSE2). + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubsw, kX86InstIdPsubsw, X86XmmVar, X86Mem) + + //! Packed BYTE subtract with unsigned saturation (SSE2). + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubusb, kX86InstIdPsubusb, X86XmmVar, X86Mem) + + //! Packed WORD subtract with unsigned saturation (SSE2). + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psubusw, kX86InstIdPsubusw, X86XmmVar, X86Mem) + + //! Unpack high packed BYTEs to WORDs (SSE2). + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhbw, kX86InstIdPunpckhbw, X86XmmVar, X86Mem) + + //! Unpack high packed DWORDs to QWORDs (SSE2). + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhdq, kX86InstIdPunpckhdq, X86XmmVar, X86Mem) + + //! Unpack high packed QWORDs to OWORD (SSE2). + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhqdq, kX86InstIdPunpckhqdq, X86XmmVar, X86Mem) + + //! Unpack high packed WORDs to DWORDs (SSE2). + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckhwd, kX86InstIdPunpckhwd, X86XmmVar, X86Mem) + + //! Unpack low packed BYTEs to WORDs (SSE2). + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpcklbw, kX86InstIdPunpcklbw, X86XmmVar, X86Mem) + + //! Unpack low packed DWORDs to QWORDs (SSE2). + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpckldq, kX86InstIdPunpckldq, X86XmmVar, X86Mem) + + //! Unpack low packed QWORDs to OWORD (SSE2). + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpcklqdq, kX86InstIdPunpcklqdq, X86XmmVar, X86Mem) + + //! Unpack low packed WORDs to DWORDs (SSE2). + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(punpcklwd, kX86InstIdPunpcklwd, X86XmmVar, X86Mem) + + //! Packed bitwise xor (SSE2). + INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pxor, kX86InstIdPxor, X86XmmVar, X86Mem) + + //! Shuffle DP-FP (SSE2). + INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(shufpd, kX86InstIdShufpd, X86XmmVar, X86Mem, Imm) + + //! Packed DP-FP square root (SSE2). + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtpd, kX86InstIdSqrtpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP square root (SSE2). + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(sqrtsd, kX86InstIdSqrtsd, X86XmmVar, X86Mem) + + //! Packed DP-FP subtract (SSE2). + INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subpd, kX86InstIdSubpd, X86XmmVar, X86Mem) + + //! Scalar DP-FP subtract (SSE2). + INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(subsd, kX86InstIdSubsd, X86XmmVar, X86Mem) + + //! Scalar DP-FP unordered compare and set EFLAGS (SSE2). + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(ucomisd, kX86InstIdUcomisd, X86XmmVar, X86Mem) + + //! Unpack and interleave high packed DP-FP (SSE2). + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpckhpd, kX86InstIdUnpckhpd, X86XmmVar, X86Mem) + + //! Unpack and interleave low packed DP-FP (SSE2). + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(unpcklpd, kX86InstIdUnpcklpd, X86XmmVar, X86Mem) + + //! Packed DP-FP bitwise xor (SSE2). + INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(xorpd, kX86InstIdXorpd, X86XmmVar, X86Mem) + + // -------------------------------------------------------------------------- + // [SSE3] + // -------------------------------------------------------------------------- + + //! Packed DP-FP add/subtract (SSE3). + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addsubpd, kX86InstIdAddsubpd, X86XmmVar, X86Mem) + + //! Packed SP-FP add/subtract (SSE3). + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86Mem) + + //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop + //! the FPU stack (FPU / SSE3). + INST_1x(fisttp, kX86InstIdFisttp, X86Mem) + + //! Packed DP-FP horizontal add (SSE3). + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(haddpd, kX86InstIdHaddpd, X86XmmVar, X86Mem) + + //! Packed SP-FP horizontal add (SSE3). + INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(haddps, kX86InstIdHaddps, X86XmmVar, X86Mem) + + //! Packed DP-FP horizontal subtract (SSE3). + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(hsubpd, kX86InstIdHsubpd, X86XmmVar, X86Mem) + + //! Packed SP-FP horizontal subtract (SSE3). + INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(hsubps, kX86InstIdHsubps, X86XmmVar, X86Mem) + + //! Load 128-bits unaligned (SSE3). + INST_2x(lddqu, kX86InstIdLddqu, X86XmmVar, X86Mem) + + // //! Setup monitor address (SSE3). + // INST_0x(monitor, kX86InstIdMonitor) + + //! Move one DP-FP and duplicate (SSE3). + INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movddup, kX86InstIdMovddup, X86XmmVar, X86Mem) + + //! Move packed SP-FP high and duplicate (SSE3). + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movshdup, kX86InstIdMovshdup, X86XmmVar, X86Mem) + + //! Move packed SP-FP low and duplicate (SSE3). + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(movsldup, kX86InstIdMovsldup, X86XmmVar, X86Mem) + + // //! Monitor wait (SSE3). + // INST_0x(mwait, kX86InstIdMwait) + + // -------------------------------------------------------------------------- + // [SSSE3] + // -------------------------------------------------------------------------- + + //! Packed BYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86MmVar) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86MmVar, X86Mem) + + //! PackedBYTE sign (SSSE3). + INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psignb, kX86InstIdPsignb, X86XmmVar, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86MmVar) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86MmVar, X86Mem) + + //! Packed DWORD sign (SSSE3). + INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psignd, kX86InstIdPsignd, X86XmmVar, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86MmVar) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86MmVar, X86Mem) + + //! Packed WORD sign (SSSE3). + INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(psignw, kX86InstIdPsignw, X86XmmVar, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86MmVar) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86MmVar, X86Mem) + + //! Packed DWORD horizontal add (SSSE3). + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phaddd, kX86InstIdPhaddd, X86XmmVar, X86Mem) + + //! Packed WORD horizontal add with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86MmVar, X86Mem) + + //! Packed WORD horizontal add with with saturation (SSSE3). + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phaddsw, kX86InstIdPhaddsw, X86XmmVar, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86MmVar, X86Mem) + + //! Packed WORD horizontal add (SSSE3). + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phaddw, kX86InstIdPhaddw, X86XmmVar, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86MmVar) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86MmVar, X86Mem) + + //! Packed DWORD horizontal subtract (SSSE3). + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phsubd, kX86InstIdPhsubd, X86XmmVar, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86MmVar, X86Mem) + + //! Packed WORD horizontal subtract with saturation (SSSE3). + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phsubsw, kX86InstIdPhsubsw, X86XmmVar, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86MmVar) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86MmVar, X86Mem) + + //! Packed WORD horizontal subtract (SSSE3). + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phsubw, kX86InstIdPhsubw, X86XmmVar, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86MmVar, X86Mem) + + //! Packed multiply and add signed and unsigned bytes (SSSE3). + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaddubsw, kX86InstIdPmaddubsw, X86XmmVar, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86MmVar, X86Mem) + + //! Packed BYTE absolute value (SSSE3). + INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pabsb, kX86InstIdPabsb, X86XmmVar, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86MmVar) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86MmVar, X86Mem) + + //! Packed DWORD absolute value (SSSE3). + INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pabsd, kX86InstIdPabsd, X86XmmVar, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86MmVar, X86Mem) + + //! Packed WORD absolute value (SSSE3). + INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pabsw, kX86InstIdPabsw, X86XmmVar, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86MmVar) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86MmVar, X86Mem) + + //! Packed WORD multiply high, round and scale (SSSE3). + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulhrsw, kX86InstIdPmulhrsw, X86XmmVar, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86MmVar) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86MmVar, X86Mem) + + //! Packed BYTE shuffle (SSSE3). + INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pshufb, kX86InstIdPshufb, X86XmmVar, X86Mem) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86MmVar, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86MmVar, X86Mem, Imm) + + //! Packed align right (SSSE3). + INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(palignr, kX86InstIdPalignr, X86XmmVar, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.1] + // -------------------------------------------------------------------------- + + //! Packed DP-FP blend (SSE4.1). + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(blendpd, kX86InstIdBlendpd, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP blend (SSE4.1). + INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(blendps, kX86InstIdBlendps, X86XmmVar, X86Mem, Imm) + + //! Packed DP-FP variable blend (SSE4.1). + INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86XmmVar, X86XmmVar) + //! \overload + INST_3x(blendvpd, kX86InstIdBlendvpd, X86XmmVar, X86Mem, X86XmmVar) + + //! Packed SP-FP variable blend (SSE4.1). + INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86XmmVar, X86XmmVar) + //! \overload + INST_3x(blendvps, kX86InstIdBlendvps, X86XmmVar, X86Mem, X86XmmVar) + + //! Packed DP-FP dot product (SSE4.1). + INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(dppd, kX86InstIdDppd, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP dot product (SSE4.1). + INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(dpps, kX86InstIdDpps, X86XmmVar, X86Mem, Imm) + + //! Extract SP-FP based on selector (SSE4.1). + INST_3i(extractps, kX86InstIdExtractps, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(extractps, kX86InstIdExtractps, X86Mem, X86XmmVar, Imm) + + //! Insert SP-FP based on selector (SSE4.1). + INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(insertps, kX86InstIdInsertps, X86XmmVar, X86Mem, Imm) + + //! Load OWORD aligned using NT hint (SSE4.1). + INST_2x(movntdqa, kX86InstIdMovntdqa, X86XmmVar, X86Mem) + + //! Packed WORD sums of absolute difference (SSE4.1). + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(mpsadbw, kX86InstIdMpsadbw, X86XmmVar, X86Mem, Imm) + + //! Pack DWORDs to WORDs with unsigned saturation (SSE4.1). + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(packusdw, kX86InstIdPackusdw, X86XmmVar, X86Mem) + + //! Packed BYTE variable blend (SSE4.1). + INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86XmmVar, X86XmmVar) + //! \overload + INST_3x(pblendvb, kX86InstIdPblendvb, X86XmmVar, X86Mem, X86XmmVar) + + //! Packed WORD blend (SSE4.1). + INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pblendw, kX86InstIdPblendw, X86XmmVar, X86Mem, Imm) + + //! Packed QWORD compare for equality (SSE4.1). + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpeqq, kX86InstIdPcmpeqq, X86XmmVar, X86Mem) + + //! Extract BYTE based on selector (SSE4.1). + INST_3i(pextrb, kX86InstIdPextrb, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(pextrb, kX86InstIdPextrb, X86Mem, X86XmmVar, Imm) + + //! Extract DWORD based on selector (SSE4.1). + INST_3i(pextrd, kX86InstIdPextrd, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(pextrd, kX86InstIdPextrd, X86Mem, X86XmmVar, Imm) + + //! Extract QWORD based on selector (SSE4.1). + INST_3i(pextrq, kX86InstIdPextrq, X86GpVar, X86XmmVar, Imm) + //! \overload + INST_3i(pextrq, kX86InstIdPextrq, X86Mem, X86XmmVar, Imm) + + //! Extract WORD based on selector (SSE4.1). + INST_3i(pextrw, kX86InstIdPextrw, X86Mem, X86XmmVar, Imm) + + //! Packed WORD horizontal minimum (SSE4.1). + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(phminposuw, kX86InstIdPhminposuw, X86XmmVar, X86Mem) + + //! Insert BYTE based on selector (SSE4.1). + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrb, kX86InstIdPinsrb, X86XmmVar, X86Mem, Imm) + + //! Insert DWORD based on selector (SSE4.1). + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrd, kX86InstIdPinsrd, X86XmmVar, X86Mem, Imm) + + //! Insert QWORD based on selector (SSE4.1). + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86GpVar, Imm) + //! \overload + INST_3i(pinsrq, kX86InstIdPinsrq, X86XmmVar, X86Mem, Imm) + + //! Packed BYTE maximum (SSE4.1). + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxsb, kX86InstIdPmaxsb, X86XmmVar, X86Mem) + + //! Packed DWORD maximum (SSE4.1). + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxsd, kX86InstIdPmaxsd, X86XmmVar, X86Mem) + + //! Packed DWORD unsigned maximum (SSE4.1). + INST_2x(pmaxud, kX86InstIdPmaxud, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxud,kX86InstIdPmaxud , X86XmmVar, X86Mem) + + //! Packed WORD unsigned maximum (SSE4.1). + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmaxuw, kX86InstIdPmaxuw, X86XmmVar, X86Mem) + + //! Packed BYTE minimum (SSE4.1). + INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminsb, kX86InstIdPminsb, X86XmmVar, X86Mem) + + //! Packed DWORD minimum (SSE4.1). + INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminsd, kX86InstIdPminsd, X86XmmVar, X86Mem) + + //! Packed WORD unsigned minimum (SSE4.1). + INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminuw, kX86InstIdPminuw, X86XmmVar, X86Mem) + + //! Packed DWORD unsigned minimum (SSE4.1). + INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pminud, kX86InstIdPminud, X86XmmVar, X86Mem) + + //! Packed BYTE to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxbd, kX86InstIdPmovsxbd, X86XmmVar, X86Mem) + + //! Packed BYTE to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxbq, kX86InstIdPmovsxbq, X86XmmVar, X86Mem) + + //! Packed BYTE to WORD with sign extend (SSE4.1). + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxbw, kX86InstIdPmovsxbw, X86XmmVar, X86Mem) + + //! Packed DWORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxdq, kX86InstIdPmovsxdq, X86XmmVar, X86Mem) + + //! Packed WORD to DWORD with sign extend (SSE4.1). + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxwd, kX86InstIdPmovsxwd, X86XmmVar, X86Mem) + + //! Packed WORD to QWORD with sign extend (SSE4.1). + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovsxwq, kX86InstIdPmovsxwq, X86XmmVar, X86Mem) + + //! BYTE to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxbd, kX86InstIdPmovzxbd, X86XmmVar, X86Mem) + + //! Packed BYTE to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxbq, kX86InstIdPmovzxbq, X86XmmVar, X86Mem) + + //! BYTE to WORD with zero extend (SSE4.1). + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxbw, kX86InstIdPmovzxbw, X86XmmVar, X86Mem) + + //! Packed DWORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxdq, kX86InstIdPmovzxdq, X86XmmVar, X86Mem) + + //! Packed WORD to DWORD with zero extend (SSE4.1). + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxwd, kX86InstIdPmovzxwd, X86XmmVar, X86Mem) + + //! Packed WORD to QWORD with zero extend (SSE4.1). + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmovzxwq, kX86InstIdPmovzxwq, X86XmmVar, X86Mem) + + //! Packed DWORD to QWORD multiply (SSE4.1). + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmuldq, kX86InstIdPmuldq, X86XmmVar, X86Mem) + + //! Packed DWORD multiply low (SSE4.1). + INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pmulld, kX86InstIdPmulld, X86XmmVar, X86Mem) + + //! Logical compare (SSE4.1). + INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(ptest, kX86InstIdPtest, X86XmmVar, X86Mem) + + //! Packed DP-FP round (SSE4.1). + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundpd, kX86InstIdRoundpd, X86XmmVar, X86Mem, Imm) + + //! Packed SP-FP round (SSE4.1). + INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundps, kX86InstIdRoundps, X86XmmVar, X86Mem, Imm) + + //! Scalar DP-FP round (SSE4.1). + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundsd, kX86InstIdRoundsd, X86XmmVar, X86Mem, Imm) + + //! Scalar SP-FP round (SSE4.1). + INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(roundss, kX86InstIdRoundss, X86XmmVar, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [SSE4.2] + // -------------------------------------------------------------------------- + + //! Packed compare explicit length strings, return index (SSE4.2). + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86Mem, Imm) + + //! Packed compare explicit length strings, return mask (SSE4.2). + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpestrm, kX86InstIdPcmpestrm, X86XmmVar, X86Mem, Imm) + + //! Packed compare implicit length strings, return index (SSE4.2). + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpistri, kX86InstIdPcmpistri, X86XmmVar, X86Mem, Imm) + + //! Packed compare implicit length strings, return mask (SSE4.2). + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(pcmpistrm, kX86InstIdPcmpistrm, X86XmmVar, X86Mem, Imm) + + //! Packed QWORD compare if greater than (SSE4.2). + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86Mem) + + // -------------------------------------------------------------------------- + // [AESNI] + // -------------------------------------------------------------------------- + + //! Perform a single round of the AES decryption flow. + INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesdec, kX86InstIdAesdec, X86XmmVar, X86Mem) + + //! Perform the last round of the AES decryption flow. + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesdeclast, kX86InstIdAesdeclast, X86XmmVar, X86Mem) + + //! Perform a single round of the AES encryption flow. + INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesenc, kX86InstIdAesenc, X86XmmVar, X86Mem) + + //! Perform the last round of the AES encryption flow. + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesenclast, kX86InstIdAesenclast, X86XmmVar, X86Mem) + + //! Perform the InvMixColumns transformation. + INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86XmmVar) + //! \overload + INST_2x(aesimc, kX86InstIdAesimc, X86XmmVar, X86Mem) + + //! Assist in expanding the AES cipher key. + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86XmmVar, Imm) + //! \overload + INST_3i(aeskeygenassist, kX86InstIdAeskeygenassist, X86XmmVar, X86Mem, Imm) + + // -------------------------------------------------------------------------- + // [PCLMULQDQ] + // -------------------------------------------------------------------------- + + //! Packed QWORD to OWORD carry-less multiply (PCLMULQDQ). + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86XmmVar, Imm); + //! \overload + INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86Mem, Imm); + +#undef INST_0x + +#undef INST_1x +#undef INST_1x_ +#undef INST_1i +#undef INST_1cc + +#undef INST_2x +#undef INST_2x_ +#undef INST_2i +#undef INST_2cc + +#undef INST_3x +#undef INST_3x_ +#undef INST_3i + +#undef INST_4x +#undef INST_4x_ +#undef INST_4i +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_X86_X86COMPILER_H diff --git a/libraries/asmjit/x86/x86context.cpp b/libraries/asmjit/x86/x86context.cpp new file mode 100644 index 000000000..6dabc0f30 --- /dev/null +++ b/libraries/asmjit/x86/x86context.cpp @@ -0,0 +1,5691 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)) + +// [Dependencies - AsmJit] +#include "../base/intutil.h" +#include "../base/string.h" +#include "../x86/x86assembler.h" +#include "../x86/x86compiler.h" +#include "../x86/x86context_p.h" +#include "../x86/x86cpuinfo.h" +#include "../x86/x86scheduler_p.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +static Error X86Context_translateOperands(X86Context* self, Operand* opList, uint32_t opCount); + +// ============================================================================ +// [asmjit::X86Context - Utils] +// ============================================================================ + +// Getting `VarClass` is the only safe operation when dealing with denormalized +// `varType`. Any other property would require to map vType to the architecture +// specific type. +static ASMJIT_INLINE uint32_t x86VarTypeToClass(uint32_t vType) { + ASMJIT_ASSERT(vType < kX86VarTypeCount); + return _x86VarInfo[vType].getClass(); +} + +// ============================================================================ +// [asmjit::X86Context - Annotate] +// ============================================================================ + +// Annotation is also used by ASMJIT_TRACE. +#if !defined(ASMJIT_DISABLE_LOGGER) +static void X86Context_annotateVariable(X86Context* self, + StringBuilder& sb, const VarData* vd) { + + const char* name = vd->getName(); + if (name != NULL && name[0] != '\0') { + sb.appendString(name); + } + else { + sb.appendChar('v'); + sb.appendUInt(vd->getId() & kOperandIdNum); + } +} + +static void X86Context_annotateOperand(X86Context* self, + StringBuilder& sb, const Operand* op) { + + if (op->isVar()) { + X86Context_annotateVariable(self, sb, self->_compiler->getVdById(op->getId())); + } + else if (op->isMem()) { + const X86Mem* m = static_cast(op); + bool isAbsolute = false; + + sb.appendChar('['); + switch (m->getMemType()) { + case kMemTypeBaseIndex: + case kMemTypeStackIndex: + // [base + index << shift + displacement] + X86Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getBase())); + break; + + case kMemTypeLabel: + // [label + index << shift + displacement] + sb.appendFormat("L%u", m->getBase()); + break; + + case kMemTypeAbsolute: + // [absolute] + isAbsolute = true; + sb.appendUInt(static_cast(m->getDisplacement()), 16); + break; + } + + if (m->hasIndex()) { + sb.appendChar('+'); + X86Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex())); + + if (m->getShift()) { + sb.appendChar('*'); + sb.appendChar("1248"[m->getShift() & 3]); + } + } + + if (m->getDisplacement() && !isAbsolute) { + uint32_t base = 10; + int32_t dispOffset = m->getDisplacement(); + + char prefix = '+'; + if (dispOffset < 0) { + dispOffset = -dispOffset; + prefix = '-'; + } + + sb.appendChar(prefix); + /* + if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) { + sb.appendString("0x", 2); + base = 16; + } + */ + sb.appendUInt(static_cast(dispOffset), base); + } + + sb.appendChar(']'); + } + else if (op->isImm()) { + const Imm* i = static_cast(op); + int64_t val = i->getInt64(); + + /* + if ((loggerOptions & (1 << kLoggerOptionHexImmediate)) && static_cast(val) > 9) + sb.appendUInt(static_cast(val), 16); + else*/ + sb.appendInt(val, 10); + } + else if (op->isLabel()) { + sb.appendFormat("L%u", op->getId()); + } + else { + sb.appendString("None", 4); + } +} + +static bool X86Context_annotateInstruction(X86Context* self, + StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) { + + sb.appendString(_x86InstInfo[code].getInstName()); + for (uint32_t i = 0; i < opCount; i++) { + if (i == 0) + sb.appendChar(' '); + else + sb.appendString(", ", 2); + X86Context_annotateOperand(self, sb, &opList[i]); + } + return true; +} +#endif // !ASMJIT_DISABLE_LOGGER + +#if defined(ASMJIT_TRACE) +static void X86Context_traceNode(X86Context* self, Node* node_) { + StringBuilderT<256> sb; + + switch (node_->getType()) { + case kNodeTypeAlign: { + AlignNode* node = static_cast(node_); + sb.appendFormat(".align %u (%s)", + node->getOffset(), + node->getMode() == kAlignCode ? "code" : "data"); + break; + } + + case kNodeTypeEmbed: { + EmbedNode* node = static_cast(node_); + sb.appendFormat(".embed (%u bytes)", node->getSize()); + break; + } + + case kNodeTypeComment: { + CommentNode* node = static_cast(node_); + sb.appendFormat("; %s", node->getComment()); + break; + } + + case kNodeTypeHint: { + HintNode* node = static_cast(node_); + static const char* hint[16] = { + "alloc", + "spill", + "save", + "save-unuse", + "unuse" + }; + sb.appendFormat("[%s] %s", + hint[node->getHint()], node->getVd()->getName()); + break; + } + + case kNodeTypeTarget: { + TargetNode* node = static_cast(node_); + sb.appendFormat("L%u: (NumRefs=%u)", + node->getLabelId(), + node->getNumRefs()); + break; + } + + case kNodeTypeInst: { + InstNode* node = static_cast(node_); + X86Context_annotateInstruction(self, sb, + node->getCode(), node->getOpList(), node->getOpCount()); + break; + } + + case kNodeTypeFunc: { + FuncNode* node = static_cast(node_); + sb.appendFormat("[func]"); + break; + } + + case kNodeTypeEnd: { + EndNode* node = static_cast(node_); + sb.appendFormat("[end]"); + break; + } + + case kNodeTypeRet: { + RetNode* node = static_cast(node_); + sb.appendFormat("[ret]"); + break; + } + + case kNodeTypeCall: { + CallNode* node = static_cast(node_); + sb.appendFormat("[call]"); + break; + } + + case kNodeTypeSArg: { + SArgNode* node = static_cast(node_); + sb.appendFormat("[sarg]"); + break; + } + + default: { + sb.appendFormat("[unknown]"); + break; + } + } + + ASMJIT_TLOG("[%05u] %s\n", node_->getFlowId(), sb.getData()); +} +#endif // ASMJIT_TRACE + +// ============================================================================ +// [asmjit::X86Context - Construction / Destruction] +// ============================================================================ + +X86Context::X86Context(X86Compiler* compiler) : Context(compiler) { + _varMapToVaListOffset = ASMJIT_OFFSET_OF(X86VarMap, _list); + _regCount = compiler->_regCount; + + _zsp = compiler->zsp; + _zbp = compiler->zbp; + + _memSlot._vmem.type = kMemTypeStackIndex; + _memSlot.setGpdBase(compiler->getArch() == kArchX86); + +#if !defined(ASMJIT_DISABLE_LOGGER) + _emitComments = compiler->hasLogger(); +#endif // !ASMJIT_DISABLE_LOGGER + + _state = &_x86State; + reset(); +} + +X86Context::~X86Context() {} + +// ============================================================================ +// [asmjit::X86Context - Reset] +// ============================================================================ + +void X86Context::reset() { + Context::reset(); + + _x86State.reset(0); + _clobberedRegs.reset(); + + _stackFrameCell = NULL; + _gaRegs[kX86RegClassGp ] = IntUtil::bits(_regCount.getGp()) & ~IntUtil::mask(kX86RegIndexSp); + _gaRegs[kX86RegClassFp ] = IntUtil::bits(_regCount.getFp()); + _gaRegs[kX86RegClassMm ] = IntUtil::bits(_regCount.getMm()); + _gaRegs[kX86RegClassXyz] = IntUtil::bits(_regCount.getXyz()); + + _argBaseReg = kInvalidReg; // Used by patcher. + _varBaseReg = kInvalidReg; // Used by patcher. + + _argBaseOffset = 0; // Used by patcher. + _varBaseOffset = 0; // Used by patcher. + + _argActualDisp = 0; // Used by translator. + _varActualDisp = 0; // Used by translator. +} + +// ============================================================================ +// [asmjit::X86SpecialInst] +// ============================================================================ + +struct X86SpecialInst { + uint8_t inReg; + uint8_t outReg; + uint16_t flags; +}; + +static const X86SpecialInst x86SpecialInstCpuid[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kX86RegIndexBx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexCx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg } +}; + +static const X86SpecialInst x86SpecialInstCbwCdqeCwde[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg } +}; + +static const X86SpecialInst x86SpecialInstCdqCwdCqo[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstCmpxchg[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstCmpxchg8b16b[] = { + { kX86RegIndexDx, kX86RegIndexDx, kVarAttrInOutReg }, + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexBx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstDaaDas[] = { + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg } +}; + +static const X86SpecialInst x86SpecialInstDiv[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrInOutReg }, + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstJecxz[] = { + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstLods[] = { + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg }, + { kX86RegIndexSi, kX86RegIndexSi, kVarAttrInOutReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } +}; + +static const X86SpecialInst x86SpecialInstMul[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }, + { kX86RegIndexAx, kX86RegIndexAx, kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstMovPtr[] = { + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstMovsCmps[] = { + { kX86RegIndexDi, kX86RegIndexDi, kVarAttrInOutReg }, + { kX86RegIndexSi, kX86RegIndexSi, kVarAttrInOutReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } +}; + +static const X86SpecialInst x86SpecialInstLahf[] = { + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg } +}; + +static const X86SpecialInst x86SpecialInstSahf[] = { + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstMaskmovqMaskmovdqu[] = { + { kInvalidReg , kX86RegIndexDi, kVarAttrInReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstRdtscRdtscp[] = { + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexCx, kVarAttrOutReg } +}; + +static const X86SpecialInst x86SpecialInstRot[] = { + { kInvalidReg , kInvalidReg , kVarAttrInOutReg }, + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstScas[] = { + { kX86RegIndexDi, kX86RegIndexDi, kVarAttrInOutReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } +}; + +static const X86SpecialInst x86SpecialInstShlrd[] = { + { kInvalidReg , kInvalidReg , kVarAttrInOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg }, + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstStos[] = { + { kX86RegIndexDi, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexCx, kX86RegIndexCx, kVarAttrInOutReg } +}; + +static const X86SpecialInst x86SpecialInstBlend[] = { + { kInvalidReg , kInvalidReg , kVarAttrOutReg }, + { kInvalidReg , kInvalidReg , kVarAttrInReg }, + { 0 , kInvalidReg , kVarAttrInReg } +}; + +static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t code, const Operand* opList, uint32_t opCount) { + switch (code) { + case kX86InstIdCpuid: + return x86SpecialInstCpuid; + + case kX86InstIdCbw: + case kX86InstIdCdqe: + case kX86InstIdCwde: + return x86SpecialInstCbwCdqeCwde; + + case kX86InstIdCdq: + case kX86InstIdCwd: + case kX86InstIdCqo: + return x86SpecialInstCdqCwdCqo; + + case kX86InstIdCmpsB: + case kX86InstIdCmpsD: + case kX86InstIdCmpsQ: + case kX86InstIdCmpsW: + case kX86InstIdRepeCmpsB: + case kX86InstIdRepeCmpsD: + case kX86InstIdRepeCmpsQ: + case kX86InstIdRepeCmpsW: + case kX86InstIdRepneCmpsB: + case kX86InstIdRepneCmpsD: + case kX86InstIdRepneCmpsQ: + case kX86InstIdRepneCmpsW: + return x86SpecialInstMovsCmps; + + case kX86InstIdCmpxchg: + return x86SpecialInstCmpxchg; + + case kX86InstIdCmpxchg8b: + case kX86InstIdCmpxchg16b: + return x86SpecialInstCmpxchg8b16b; + + case kX86InstIdDaa: + case kX86InstIdDas: + return x86SpecialInstDaaDas; + + case kX86InstIdJecxz: + return x86SpecialInstJecxz; + + case kX86InstIdIdiv: + case kX86InstIdDiv: + return x86SpecialInstDiv; + + case kX86InstIdImul: + if (opCount == 2) + return NULL; + if (opCount == 3 && !(opList[0].isVar() && opList[1].isVar() && opList[2].isVarOrMem())) + return NULL; + // ... Fall through ... + case kX86InstIdMul: + return x86SpecialInstMul; + + case kX86InstIdMovPtr: + return x86SpecialInstMovPtr; + + case kX86InstIdLodsB: + case kX86InstIdLodsD: + case kX86InstIdLodsQ: + case kX86InstIdLodsW: + case kX86InstIdRepLodsB: + case kX86InstIdRepLodsD: + case kX86InstIdRepLodsQ: + case kX86InstIdRepLodsW: + return x86SpecialInstLods; + + case kX86InstIdMovsB: + case kX86InstIdMovsD: + case kX86InstIdMovsQ: + case kX86InstIdMovsW: + case kX86InstIdRepMovsB: + case kX86InstIdRepMovsD: + case kX86InstIdRepMovsQ: + case kX86InstIdRepMovsW: + return x86SpecialInstMovsCmps; + + case kX86InstIdLahf: + return x86SpecialInstLahf; + + case kX86InstIdSahf: + return x86SpecialInstSahf; + + case kX86InstIdMaskmovq: + case kX86InstIdMaskmovdqu: + return x86SpecialInstMaskmovqMaskmovdqu; + + // Not supported. + case kX86InstIdEnter: + case kX86InstIdLeave: + return NULL; + + // Not supported. + case kX86InstIdRet: + return NULL; + + case kX86InstIdMonitor: + case kX86InstIdMwait: + // TODO: [COMPILER] Monitor/MWait. + return NULL; + + case kX86InstIdPop: + // TODO: [COMPILER] Pop. + return NULL; + + // Not supported. + case kX86InstIdPopa: + case kX86InstIdPopf: + return NULL; + + case kX86InstIdPush: + // TODO: [COMPILER] Push. + return NULL; + + // Not supported. + case kX86InstIdPusha: + case kX86InstIdPushf: + return NULL; + + // Rot instruction is special only if the last operand is a variable. + case kX86InstIdRcl: + case kX86InstIdRcr: + case kX86InstIdRol: + case kX86InstIdRor: + case kX86InstIdSal: + case kX86InstIdSar: + case kX86InstIdShl: + case kX86InstIdShr: + if (!opList[1].isVar()) + return NULL; + return x86SpecialInstRot; + + // Shld/Shrd instruction is special only if the last operand is a variable. + case kX86InstIdShld: + case kX86InstIdShrd: + if (!opList[2].isVar()) + return NULL; + return x86SpecialInstShlrd; + + case kX86InstIdRdtsc: + case kX86InstIdRdtscp: + return x86SpecialInstRdtscRdtscp; + + case kX86InstIdScasB: + case kX86InstIdScasD: + case kX86InstIdScasQ: + case kX86InstIdScasW: + case kX86InstIdRepeScasB: + case kX86InstIdRepeScasD: + case kX86InstIdRepeScasQ: + case kX86InstIdRepeScasW: + case kX86InstIdRepneScasB: + case kX86InstIdRepneScasD: + case kX86InstIdRepneScasQ: + case kX86InstIdRepneScasW: + return x86SpecialInstScas; + + case kX86InstIdStosB: + case kX86InstIdStosD: + case kX86InstIdStosQ: + case kX86InstIdStosW: + case kX86InstIdRepStosB: + case kX86InstIdRepStosD: + case kX86InstIdRepStosQ: + case kX86InstIdRepStosW: + return x86SpecialInstStos; + + case kX86InstIdBlendvpd: + case kX86InstIdBlendvps: + case kX86InstIdPblendvb: + return x86SpecialInstBlend; + + default: + return NULL; + } +} + +// ============================================================================ +// [asmjit::X86Context - EmitLoad] +// ============================================================================ + +void X86Context::emitLoad(VarData* vd, uint32_t regIndex, const char* reason) { + ASMJIT_ASSERT(regIndex != kInvalidReg); + + X86Compiler* compiler = getCompiler(); + X86Mem m = getVarMem(vd); + + Node* node = NULL; + bool comment = _emitComments; + + switch (vd->getType()) { + case kVarTypeInt8: + case kVarTypeUInt8: + node = compiler->emit(kX86InstIdMov, x86::gpb_lo(regIndex), m); + if (comment) goto _Comment; + break; + + case kVarTypeInt16: + case kVarTypeUInt16: + node = compiler->emit(kX86InstIdMov, x86::gpw(regIndex), m); + if (comment) goto _Comment; + break; + + case kVarTypeInt32: + case kVarTypeUInt32: + node = compiler->emit(kX86InstIdMov, x86::gpd(regIndex), m); + if (comment) goto _Comment; + break; + +#if defined(ASMJIT_BUILD_X64) + case kVarTypeInt64: + case kVarTypeUInt64: + node = compiler->emit(kX86InstIdMov, x86::gpq(regIndex), m); + if (comment) goto _Comment; + break; +#endif // ASMJIT_BUILD_X64 + + case kVarTypeFp32: + case kVarTypeFp64: + // TODO: [COMPILER] FPU. + break; + + case kX86VarTypeMm: + node = compiler->emit(kX86InstIdMovq, x86::mm(regIndex), m); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmm: + node = compiler->emit(kX86InstIdMovdqa, x86::xmm(regIndex), m); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmSs: + node = compiler->emit(kX86InstIdMovss, x86::xmm(regIndex), m); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmSd: + node = compiler->emit(kX86InstIdMovsd, x86::xmm(regIndex), m); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmPs: + node = compiler->emit(kX86InstIdMovaps, x86::xmm(regIndex), m); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmPd: + node = compiler->emit(kX86InstIdMovapd, x86::xmm(regIndex), m); + if (comment) goto _Comment; + break; + } + return; + +_Comment: + node->setComment(compiler->_stringZone.sformat("[%s] %s", reason, vd->getName())); +} + +// ============================================================================ +// [asmjit::X86Context - EmitSave] +// ============================================================================ + +void X86Context::emitSave(VarData* vd, uint32_t regIndex, const char* reason) { + ASMJIT_ASSERT(regIndex != kInvalidReg); + + X86Compiler* compiler = getCompiler(); + X86Mem m = getVarMem(vd); + + Node* node = NULL; + bool comment = _emitComments; + + switch (vd->getType()) { + case kVarTypeInt8: + case kVarTypeUInt8: + node = compiler->emit(kX86InstIdMov, m, x86::gpb_lo(regIndex)); + if (comment) goto _Comment; + break; + + case kVarTypeInt16: + case kVarTypeUInt16: + node = compiler->emit(kX86InstIdMov, m, x86::gpw(regIndex)); + if (comment) goto _Comment; + break; + + case kVarTypeInt32: + case kVarTypeUInt32: + node = compiler->emit(kX86InstIdMov, m, x86::gpd(regIndex)); + if (comment) goto _Comment; + break; + +#if defined(ASMJIT_BUILD_X64) + case kVarTypeInt64: + case kVarTypeUInt64: + node = compiler->emit(kX86InstIdMov, m, x86::gpq(regIndex)); + if (comment) goto _Comment; + break; +#endif // ASMJIT_BUILD_X64 + + case kVarTypeFp32: + case kVarTypeFp64: + // TODO: [COMPILER] FPU. + break; + + case kX86VarTypeMm: + node = compiler->emit(kX86InstIdMovq, m, x86::mm(regIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmm: + node = compiler->emit(kX86InstIdMovdqa, m, x86::xmm(regIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmSs: + node = compiler->emit(kX86InstIdMovss, m, x86::xmm(regIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmSd: + node = compiler->emit(kX86InstIdMovsd, m, x86::xmm(regIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmPs: + node = compiler->emit(kX86InstIdMovaps, m, x86::xmm(regIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmPd: + node = compiler->emit(kX86InstIdMovapd, m, x86::xmm(regIndex)); + if (comment) goto _Comment; + break; + } + return; + +_Comment: + node->setComment(compiler->_stringZone.sformat("[%s] %s", reason, vd->getName())); +} + +// ============================================================================ +// [asmjit::X86Context - EmitMove] +// ============================================================================ + +void X86Context::emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason) { + ASMJIT_ASSERT(toRegIndex != kInvalidReg); + ASMJIT_ASSERT(fromRegIndex != kInvalidReg); + + X86Compiler* compiler = getCompiler(); + + Node* node = NULL; + bool comment = _emitComments; + + switch (vd->getType()) { + case kVarTypeInt8: + case kVarTypeUInt8: + case kVarTypeInt16: + case kVarTypeUInt16: + case kVarTypeInt32: + case kVarTypeUInt32: + node = compiler->emit(kX86InstIdMov, x86::gpd(toRegIndex), x86::gpd(fromRegIndex)); + if (comment) goto _Comment; + break; + +#if defined(ASMJIT_BUILD_X64) + case kVarTypeInt64: + case kVarTypeUInt64: + node = compiler->emit(kX86InstIdMov, x86::gpq(toRegIndex), x86::gpq(fromRegIndex)); + if (comment) goto _Comment; + break; +#endif // ASMJIT_BUILD_X64 + + case kVarTypeFp32: + case kVarTypeFp64: + // TODO: [COMPILER] FPU. + break; + + case kX86VarTypeMm: + node = compiler->emit(kX86InstIdMovq, x86::mm(toRegIndex), x86::mm(fromRegIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmm: + node = compiler->emit(kX86InstIdMovaps, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmSs: + node = compiler->emit(kX86InstIdMovss, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmSd: + node = compiler->emit(kX86InstIdMovsd, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); + if (comment) goto _Comment; + break; + + case kX86VarTypeXmmPs: + case kX86VarTypeXmmPd: + node = compiler->emit(kX86InstIdMovaps, x86::xmm(toRegIndex), x86::xmm(fromRegIndex)); + if (comment) goto _Comment; + break; + } + return; + +_Comment: + node->setComment(compiler->_stringZone.sformat("[%s] %s", reason, vd->getName())); +} + +// ============================================================================ +// [asmjit::X86Context - EmitSwap] +// ============================================================================ + +void X86Context::emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason) { + ASMJIT_ASSERT(aIndex != kInvalidReg); + ASMJIT_ASSERT(bIndex != kInvalidReg); + + X86Compiler* compiler = getCompiler(); + + Node* node = NULL; + bool comment = _emitComments; + +#if defined(ASMJIT_BUILD_X64) + uint32_t vType = IntUtil::iMax(aVd->getType(), bVd->getType()); + + if (vType == kVarTypeInt64 || vType == kVarTypeUInt64) { + node = compiler->emit(kX86InstIdXchg, x86::gpq(aIndex), x86::gpq(bIndex)); + if (comment) goto _Comment; + return; + } +#endif // ASMJIT_BUILD_X64 + + node = compiler->emit(kX86InstIdXchg, x86::gpd(aIndex), x86::gpd(bIndex)); + if (comment) goto _Comment; + return; + +_Comment: + node->setComment(compiler->_stringZone.sformat("[%s] %s, %s", reason, aVd->getName(), bVd->getName())); +} + +// ============================================================================ +// [asmjit::X86Context - EmitPushSequence / EmitPopSequence] +// ============================================================================ + +void X86Context::emitPushSequence(uint32_t regs) { + X86Compiler* compiler = getCompiler(); + uint32_t i = 0; + + X86GpReg gpReg(_zsp); + while (regs != 0) { + ASMJIT_ASSERT(i < _regCount.getGp()); + if ((regs & 0x1) != 0) + compiler->emit(kX86InstIdPush, gpReg.setIndex(i)); + i++; + regs >>= 1; + } +} + +void X86Context::emitPopSequence(uint32_t regs) { + X86Compiler* compiler = getCompiler(); + + if (regs == 0) + return; + + uint32_t i = static_cast(_regCount.getGp()); + uint32_t mask = 0x1 << static_cast(i - 1); + + X86GpReg gpReg(_zsp); + while (i) { + i--; + if ((regs & mask) != 0) + compiler->emit(kX86InstIdPop, gpReg.setIndex(i)); + mask >>= 1; + } +} + +// ============================================================================ +// [asmjit::X86Context - EmitConvertVarToVar] +// ============================================================================ + +void X86Context::emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex) { + X86Compiler* compiler = getCompiler(); + + switch (dstType) { + case kVarTypeInt8: + case kVarTypeUInt8: + case kVarTypeInt16: + case kVarTypeUInt16: + case kVarTypeInt32: + case kVarTypeUInt32: + case kVarTypeInt64: + case kVarTypeUInt64: + break; + + case kX86VarTypeXmmPs: + if (srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeYmmPd) { + compiler->emit(kX86InstIdCvtpd2ps, x86::xmm(dstIndex), x86::xmm(srcIndex)); + return; + } + // ... Fall through ... + + case kX86VarTypeXmmSs: + if (srcType == kX86VarTypeXmmSd || srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeYmmPd) { + compiler->emit(kX86InstIdCvtsd2ss, x86::xmm(dstIndex), x86::xmm(srcIndex)); + return; + } + + if (IntUtil::inInterval(srcType, _kVarTypeIntStart, _kVarTypeIntEnd)) { + // TODO: + ASMJIT_ASSERT(!"Reached"); + } + break; + + case kX86VarTypeXmmPd: + if (srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeYmmPs) { + compiler->emit(kX86InstIdCvtps2pd, x86::xmm(dstIndex), x86::xmm(srcIndex)); + return; + } + // ... Fall through ... + + case kX86VarTypeXmmSd: + if (srcType == kX86VarTypeXmmSs || srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeYmmPs) { + compiler->emit(kX86InstIdCvtss2sd, x86::xmm(dstIndex), x86::xmm(srcIndex)); + return; + } + + if (IntUtil::inInterval(srcType, _kVarTypeIntStart, _kVarTypeIntEnd)) { + // TODO: + ASMJIT_ASSERT(!"Reached"); + } + break; + } +} + +// ============================================================================ +// [asmjit::X86Context - EmitMoveVarOnStack / EmitMoveImmOnStack] +// ============================================================================ + +void X86Context::emitMoveVarOnStack( + uint32_t dstType, const X86Mem* dst, + uint32_t srcType, uint32_t srcIndex) { + + ASMJIT_ASSERT(srcIndex != kInvalidReg); + X86Compiler* compiler = getCompiler(); + + X86Mem m0(*dst); + X86Reg r0, r1; + + uint32_t regSize = compiler->getRegSize(); + uint32_t instCode; + + switch (dstType) { + case kVarTypeInt8: + case kVarTypeUInt8: + // Move DWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt64)) + goto _MovGpD; + + // Move DWORD (Mm). + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) + goto _MovMmD; + + // Move DWORD (Xmm). + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) + goto _MovXmmD; + + break; + + case kVarTypeInt16: + case kVarTypeUInt16: + // Extend BYTE->WORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { + r1.setSize(1); + r1.setCode(kX86RegTypeGpbLo, srcIndex); + + instCode = (dstType == kVarTypeInt16 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; + goto _ExtendMovGpD; + } + + // Move DWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt16, kVarTypeUInt64)) + goto _MovGpD; + + // Move DWORD (Mm). + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) + goto _MovMmD; + + // Move DWORD (Xmm). + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) + goto _MovXmmD; + + break; + + case kVarTypeInt32: + case kVarTypeUInt32: + // Extend BYTE->DWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { + r1.setSize(1); + r1.setCode(kX86RegTypeGpbLo, srcIndex); + + instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; + goto _ExtendMovGpD; + } + + // Extend WORD->DWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt16, kVarTypeUInt16)) { + r1.setSize(2); + r1.setCode(kX86RegTypeGpw, srcIndex); + + instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; + goto _ExtendMovGpD; + } + + // Move DWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt32, kVarTypeUInt64)) + goto _MovGpD; + + // Move DWORD (Mm). + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) + goto _MovMmD; + + // Move DWORD (Xmm). + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) + goto _MovXmmD; + break; + + case kVarTypeInt64: + case kVarTypeUInt64: + // Extend BYTE->QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { + r1.setSize(1); + r1.setCode(kX86RegTypeGpbLo, srcIndex); + + instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; + goto _ExtendMovGpXQ; + } + + // Extend WORD->QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt16, kVarTypeUInt16)) { + r1.setSize(2); + r1.setCode(kX86RegTypeGpw, srcIndex); + + instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; + goto _ExtendMovGpXQ; + } + + // Extend DWORD->QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt32, kVarTypeUInt32)) { + r1.setSize(4); + r1.setCode(kX86RegTypeGpd, srcIndex); + + instCode = kX86InstIdMovsxd; + if (dstType == kVarTypeInt64 && srcType == kVarTypeInt32) + goto _ExtendMovGpXQ; + else + goto _ZeroExtendGpDQ; + } + + // Move QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt64, kVarTypeUInt64)) + goto _MovGpQ; + + // Move QWORD (Mm). + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) + goto _MovMmQ; + + // Move QWORD (Xmm). + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) + goto _MovXmmQ; + break; + + case kX86VarTypeMm: + // Extend BYTE->QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt8, kVarTypeUInt8)) { + r1.setSize(1); + r1.setCode(kX86RegTypeGpbLo, srcIndex); + + instCode = kX86InstIdMovzx; + goto _ExtendMovGpXQ; + } + + // Extend WORD->QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt16, kVarTypeUInt16)) { + r1.setSize(2); + r1.setCode(kX86RegTypeGpw, srcIndex); + + instCode = kX86InstIdMovzx; + goto _ExtendMovGpXQ; + } + + // Extend DWORD->QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt32, kVarTypeUInt32)) + goto _ExtendMovGpDQ; + + // Move QWORD (Gp). + if (IntUtil::inInterval(srcType, kVarTypeInt64, kVarTypeUInt64)) + goto _MovGpQ; + + // Move QWORD (Mm). + if (IntUtil::inInterval(srcType, kX86VarTypeMm, kX86VarTypeMm)) + goto _MovMmQ; + + // Move QWORD (Xmm). + if (IntUtil::inInterval(srcType, kX86VarTypeXmm, kX86VarTypeXmmPd)) + goto _MovXmmQ; + break; + + case kVarTypeFp32: + case kX86VarTypeXmmSs: + // Move FLOAT. + if (srcType == kX86VarTypeXmmSs || srcType == kX86VarTypeXmmPs || srcType == kX86VarTypeXmm) + goto _MovXmmD; + + ASMJIT_ASSERT(!"Reached"); + break; + + case kVarTypeFp64: + case kX86VarTypeXmmSd: + // Move DOUBLE. + if (srcType == kX86VarTypeXmmSd || srcType == kX86VarTypeXmmPd || srcType == kX86VarTypeXmm) + goto _MovXmmQ; + + ASMJIT_ASSERT(!"Reached"); + break; + + case kX86VarTypeXmm: + // TODO: [COMPILER]. + ASMJIT_ASSERT(!"Reached"); + break; + + case kX86VarTypeXmmPs: + // TODO: [COMPILER]. + ASMJIT_ASSERT(!"Reached"); + break; + + case kX86VarTypeXmmPd: + // TODO: [COMPILER]. + ASMJIT_ASSERT(!"Reached"); + break; + } + return; + + // Extend+Move Gp. +_ExtendMovGpD: + m0.setSize(4); + r0.setSize(4); + r0.setCode(kX86RegTypeGpd, srcIndex); + + compiler->emit(instCode, r0, r1); + compiler->emit(kX86InstIdMov, m0, r0); + return; + +_ExtendMovGpXQ: + if (regSize == 8) { + m0.setSize(8); + r0.setSize(8); + r0.setCode(kX86RegTypeGpq, srcIndex); + + compiler->emit(instCode, r0, r1); + compiler->emit(kX86InstIdMov, m0, r0); + } + else { + m0.setSize(4); + r0.setSize(4); + r0.setCode(kX86RegTypeGpd, srcIndex); + + compiler->emit(instCode, r0, r1); + +_ExtendMovGpDQ: + compiler->emit(kX86InstIdMov, m0, r0); + m0.adjust(4); + compiler->emit(kX86InstIdAnd, m0, 0); + } + return; + +_ZeroExtendGpDQ: + m0.setSize(4); + r0.setSize(4); + r0.setCode(kX86RegTypeGpd, srcIndex); + goto _ExtendMovGpDQ; + + // Move Gp. +_MovGpD: + m0.setSize(4); + r0.setSize(4); + r0.setCode(kX86RegTypeGpd, srcIndex); + compiler->emit(kX86InstIdMov, m0, r0); + return; + +_MovGpQ: + m0.setSize(8); + r0.setSize(8); + r0.setCode(kX86RegTypeGpq, srcIndex); + compiler->emit(kX86InstIdMov, m0, r0); + return; + + // Move Mm. +_MovMmD: + m0.setSize(4); + r0.setSize(8); + r0.setCode(kX86RegTypeMm, srcIndex); + compiler->emit(kX86InstIdMovd, m0, r0); + return; + +_MovMmQ: + m0.setSize(8); + r0.setSize(8); + r0.setCode(kX86RegTypeMm, srcIndex); + compiler->emit(kX86InstIdMovq, m0, r0); + return; + + // Move Xmm. +_MovXmmD: + m0.setSize(4); + r0.setSize(16); + r0.setCode(kX86RegTypeXmm, srcIndex); + compiler->emit(kX86InstIdMovss, m0, r0); + return; + +_MovXmmQ: + m0.setSize(8); + r0.setSize(16); + r0.setCode(kX86RegTypeXmm, srcIndex); + compiler->emit(kX86InstIdMovlps, m0, r0); +} + +void X86Context::emitMoveImmOnStack(uint32_t dstType, const X86Mem* dst, const Imm* src) { + X86Compiler* compiler = getCompiler(); + + X86Mem mem(*dst); + Imm imm(*src); + + uint32_t regSize = compiler->getRegSize(); + + // One stack entry is equal to the native register size. That means that if + // we want to move 32-bit integer on the stack, we need to extend it to 64-bit + // integer. + mem.setSize(regSize); + + switch (dstType) { + case kVarTypeInt8: + case kVarTypeUInt8: + imm.truncateTo8Bits(); + goto _Move32; + + case kVarTypeInt16: + case kVarTypeUInt16: + imm.truncateTo16Bits(); + goto _Move32; + + case kVarTypeInt32: + case kVarTypeUInt32: +_Move32: + imm.truncateTo32Bits(); + compiler->emit(kX86InstIdMov, mem, imm); + break; + + case kVarTypeInt64: + case kVarTypeUInt64: +_Move64: + if (regSize == 4) { + uint32_t hi = imm.getUInt32Hi(); + + // Lo-Part. + compiler->emit(kX86InstIdMov, mem, imm.truncateTo32Bits()); + mem.adjust(regSize); + + // Hi-Part. + compiler->emit(kX86InstIdMov, mem, imm.setUInt32(hi)); + } + else { + compiler->emit(kX86InstIdMov, mem, imm); + } + break; + + case kVarTypeFp32: + goto _Move32; + + case kVarTypeFp64: + goto _Move64; + + case kX86VarTypeMm: + goto _Move64; + + case kX86VarTypeXmm: + case kX86VarTypeXmmSs: + case kX86VarTypeXmmPs: + case kX86VarTypeXmmSd: + case kX86VarTypeXmmPd: + if (regSize == 4) { + uint32_t hi = imm.getUInt32Hi(); + + // Lo part. + compiler->emit(kX86InstIdMov, mem, imm.truncateTo32Bits()); + mem.adjust(regSize); + + // Hi part. + compiler->emit(kX86InstIdMov, mem, imm.setUInt32(hi)); + mem.adjust(regSize); + + // Zero part. + compiler->emit(kX86InstIdMov, mem, imm.setUInt32(0)); + mem.adjust(regSize); + + compiler->emit(kX86InstIdMov, mem, imm); + } + else { + // Lo/Hi parts. + compiler->emit(kX86InstIdMov, mem, imm); + mem.adjust(regSize); + + // Zero part. + compiler->emit(kX86InstIdMov, mem, imm.setUInt32(0)); + } + break; + + default: + ASMJIT_ASSERT(!"Reached"); + break; + } +} + +// ============================================================================ +// [asmjit::X86Context - EmitMoveImmToReg] +// ============================================================================ + +void X86Context::emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src) { + ASMJIT_ASSERT(dstIndex != kInvalidReg); + X86Compiler* compiler = getCompiler(); + + X86Reg r0; + Imm imm(*src); + + switch (dstType) { + case kVarTypeInt8: + case kVarTypeUInt8: + imm.truncateTo8Bits(); + goto _Move32; + + case kVarTypeInt16: + case kVarTypeUInt16: + imm.truncateTo16Bits(); + goto _Move32; + + case kVarTypeInt32: + case kVarTypeUInt32: +_Move32Truncate: + imm.truncateTo32Bits(); +_Move32: + r0.setSize(4); + r0.setCode(kX86RegTypeGpd, dstIndex); + compiler->emit(kX86InstIdMov, r0, imm); + break; + + case kVarTypeInt64: + case kVarTypeUInt64: + // Move to Gpd register will also clear high DWORD of Gpq register in + // 64-bit mode. + if (imm.isUInt32()) + goto _Move32Truncate; + + r0.setSize(8); + r0.setCode(kX86RegTypeGpq, dstIndex); + compiler->emit(kX86InstIdMov, r0, imm); + break; + + case kVarTypeFp32: + case kVarTypeFp64: + // TODO: [COMPILER] EmitMoveImmToReg. + break; + + case kX86VarTypeMm: + // TODO: [COMPILER] EmitMoveImmToReg. + break; + + case kX86VarTypeXmm: + case kX86VarTypeXmmSs: + case kX86VarTypeXmmSd: + case kX86VarTypeXmmPs: + case kX86VarTypeXmmPd: + // TODO: [COMPILER] EmitMoveImmToReg. + break; + + default: + ASMJIT_ASSERT(!"Reached"); + break; + } +} + +// ============================================================================ +// [asmjit::X86Context - Register Management] +// ============================================================================ + +#if defined(ASMJIT_DEBUG) +template +static ASMJIT_INLINE void X86Context_checkStateVars(X86Context* self) { + X86VarState* state = self->getState(); + VarData** sVars = state->getListByClass(C); + + uint32_t regIndex; + uint32_t regMask; + uint32_t regCount = self->_regCount.get(C); + + uint32_t occupied = state->_occupied.get(C); + uint32_t modified = state->_modified.get(C); + + for (regIndex = 0, regMask = 1; regIndex < regCount; regIndex++, regMask <<= 1) { + VarData* vd = sVars[regIndex]; + + if (vd == NULL) { + ASMJIT_ASSERT((occupied & regMask) == 0); + ASMJIT_ASSERT((modified & regMask) == 0); + } + else { + ASMJIT_ASSERT((occupied & regMask) != 0); + ASMJIT_ASSERT((modified & regMask) == (static_cast(vd->isModified()) << regIndex)); + + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getState() == kVarStateReg); + ASMJIT_ASSERT(vd->getRegIndex() == regIndex); + } + } +} + +void X86Context::_checkState() { + X86Context_checkStateVars(this); + X86Context_checkStateVars(this); + X86Context_checkStateVars(this); +} +#else +void X86Context::_checkState() {} +#endif // ASMJIT_DEBUG + +// ============================================================================ +// [asmjit::X86Context - State - Load] +// ============================================================================ + +template +static ASMJIT_INLINE void X86Context_loadStateVars(X86Context* self, X86VarState* src) { + X86VarState* cur = self->getState(); + + VarData** cVars = cur->getListByClass(C); + VarData** sVars = src->getListByClass(C); + + uint32_t regIndex; + uint32_t modified = src->_modified.get(C); + uint32_t regCount = self->_regCount.get(C); + + for (regIndex = 0; regIndex < regCount; regIndex++, modified >>= 1) { + VarData* vd = sVars[regIndex]; + cVars[regIndex] = vd; + + if (vd == NULL) + continue; + + vd->setState(kVarStateReg); + vd->setRegIndex(regIndex); + vd->setModified(modified & 0x1); + } +} + +void X86Context::loadState(VarState* src_) { + X86VarState* cur = getState(); + X86VarState* src = static_cast(src_); + + VarData** vdArray = _contextVd.getData(); + uint32_t vdCount = static_cast(_contextVd.getLength()); + + // Load allocated variables. + X86Context_loadStateVars(this, src); + X86Context_loadStateVars(this, src); + X86Context_loadStateVars(this, src); + + // Load masks. + cur->_occupied = src->_occupied; + cur->_modified = src->_modified; + + // Load states of other variables and clear their 'Modified' flags. + for (uint32_t i = 0; i < vdCount; i++) { + uint32_t vState = src->_cells[i].getState(); + + if (vState == kVarStateReg) + continue; + + vdArray[i]->setState(vState); + vdArray[i]->setRegIndex(kInvalidReg); + vdArray[i]->setModified(false); + } + + ASMJIT_X86_CHECK_STATE +} + +// ============================================================================ +// [asmjit::X86Context - State - Save] +// ============================================================================ + +VarState* X86Context::saveState() { + VarData** vdArray = _contextVd.getData(); + uint32_t vdCount = static_cast(_contextVd.getLength()); + + size_t size = IntUtil::alignTo( + sizeof(X86VarState) + vdCount * sizeof(X86StateCell), sizeof(void*)); + + X86VarState* cur = getState(); + X86VarState* dst = _baseZone.allocT(size); + + if (dst == NULL) + return NULL; + + // Store links. + ::memcpy(dst->_list, cur->_list, X86VarState::kAllCount * sizeof(VarData*)); + + // Store masks. + dst->_occupied = cur->_occupied; + dst->_modified = cur->_modified; + + // Store cells. + for (uint32_t i = 0; i < vdCount; i++) { + VarData* vd = static_cast(vdArray[i]); + X86StateCell& cell = dst->_cells[i]; + + cell.reset(); + cell.setState(vd->getState()); + } + + return dst; +} + +// ============================================================================ +// [asmjit::X86Context - State - Switch] +// ============================================================================ + +template +static ASMJIT_INLINE void X86Context_switchStateVars(X86Context* self, X86VarState* src) { + X86VarState* dst = self->getState(); + + VarData** dstVars = dst->getListByClass(C); + VarData** srcVars = src->getListByClass(C); + + uint32_t regIndex; + uint32_t regMask; + uint32_t regCount = self->_regCount.get(C); + + X86StateCell* cells = src->_cells; + + bool didWork; + do { + didWork = false; + + for (regIndex = 0, regMask = 0x1; regIndex < regCount; regIndex++, regMask <<= 1) { + VarData* dVd = dstVars[regIndex]; + VarData* sVd = srcVars[regIndex]; + + if (dVd == sVd) + continue; + + if (dVd != NULL) { + X86StateCell& cell = cells[dVd->getContextId()]; + + if (cell.getState() != kVarStateReg) { + if (cell.getState() == kVarStateMem) + self->spill(dVd); + else + self->unuse(dVd); + + dVd = NULL; + didWork = true; + + if (sVd == NULL) + continue; + } + } + + if (dVd == NULL && sVd != NULL) { +_MoveOrLoad: + if (sVd->getRegIndex() != kInvalidReg) + self->move(sVd, regIndex); + else + self->load(sVd, regIndex); + + didWork = true; + continue; + } + + if (dVd != NULL && sVd == NULL) { + X86StateCell& cell = cells[dVd->getContextId()]; + if (cell.getState() == kVarStateReg) + continue; + + if (cell.getState() == kVarStateMem) + self->spill(dVd); + else + self->unuse(dVd); + + didWork = true; + continue; + } + else { + X86StateCell& cell = cells[dVd->getContextId()]; + + if (cell.getState() == kVarStateReg) { + if (dVd->getRegIndex() != kInvalidReg && sVd->getRegIndex() != kInvalidReg) { + if (C == kX86RegClassGp) { + self->swapGp(dVd, sVd); + } + else { + self->spill(dVd); + self->move(sVd, regIndex); + } + + didWork = true; + continue; + } + else { + didWork = true; + continue; + } + } + + if (cell.getState() == kVarStateMem) + self->spill(dVd); + else + self->unuse(dVd); + goto _MoveOrLoad; + } + } + } while (didWork); + + uint32_t dstModified = dst->_modified.get(C); + uint32_t srcModified = src->_modified.get(C); + + if (dstModified != srcModified) { + for (regIndex = 0, regMask = 0x1; regIndex < regCount; regIndex++, regMask <<= 1) { + VarData* vd = dstVars[regIndex]; + + if (vd == NULL) + continue; + + if ((dstModified & regMask) && !(srcModified & regMask)) { + self->save(vd); + continue; + } + + if (!(dstModified & regMask) && (srcModified & regMask)) { + self->modify(vd); + continue; + } + } + } +} + +void X86Context::switchState(VarState* src_) { + ASMJIT_ASSERT(src_ != NULL); + + X86VarState* cur = getState(); + X86VarState* src = static_cast(src_); + + // Ignore if both states are equal. + if (cur == src) + return; + + // Switch variables. + X86Context_switchStateVars(this, src); + X86Context_switchStateVars(this, src); + X86Context_switchStateVars(this, src); + + // Calculate changed state. + VarData** vdArray = _contextVd.getData(); + uint32_t vdCount = static_cast(_contextVd.getLength()); + + X86StateCell* cells = src->_cells; + for (uint32_t i = 0; i < vdCount; i++) { + VarData* vd = static_cast(vdArray[i]); + X86StateCell& cell = cells[i]; + + uint32_t vState = cell.getState(); + if (vState != kVarStateReg) { + vd->setState(vState); + vd->setModified(false); + } + } + + ASMJIT_X86_CHECK_STATE +} + +// ============================================================================ +// [asmjit::X86Context - State - Intersect] +// ============================================================================ + +void X86Context::intersectStates(VarState* a_, VarState* b_) { + X86VarState* aState = static_cast(a_); + X86VarState* bState = static_cast(b_); + + // TODO: [COMPILER] Intersect states. + ASMJIT_X86_CHECK_STATE +} + +// ============================================================================ +// [asmjit::X86Context - GetJccFlow / GetOppositeJccFlow] +// ============================================================================ + +//! \internal +static ASMJIT_INLINE Node* X86Context_getJccFlow(JumpNode* jNode) { + if (jNode->isTaken()) + return jNode->getTarget(); + else + return jNode->getNext(); +} + +//! \internal +static ASMJIT_INLINE Node* X86Context_getOppositeJccFlow(JumpNode* jNode) { + if (jNode->isTaken()) + return jNode->getNext(); + else + return jNode->getTarget(); +} + +// ============================================================================ +// [asmjit::X86Context - SingleVarInst] +// ============================================================================ + +//! \internal +static void X86Context_prepareSingleVarInst(uint32_t code, VarAttr* va) { + switch (code) { + // - andn reg, reg ; Set all bits in reg to 0. + // - xor/pxor reg, reg ; Set all bits in reg to 0. + // - sub/psub reg, reg ; Set all bits in reg to 0. + // - pcmpgt reg, reg ; Set all bits in reg to 0. + // - pcmpeq reg, reg ; Set all bits in reg to 1. + case kX86InstIdPandn : + case kX86InstIdXor : case kX86InstIdXorpd : case kX86InstIdXorps : case kX86InstIdPxor : + case kX86InstIdSub: + case kX86InstIdPsubb : case kX86InstIdPsubw : case kX86InstIdPsubd : case kX86InstIdPsubq : + case kX86InstIdPsubsb : case kX86InstIdPsubsw : case kX86InstIdPsubusb : case kX86InstIdPsubusw : + case kX86InstIdPcmpeqb : case kX86InstIdPcmpeqw : case kX86InstIdPcmpeqd : case kX86InstIdPcmpeqq : + case kX86InstIdPcmpgtb : case kX86InstIdPcmpgtw : case kX86InstIdPcmpgtd : case kX86InstIdPcmpgtq : + va->delFlags(kVarAttrInReg); + break; + + // - and reg, reg ; Nop. + // - or reg, reg ; Nop. + // - xchg reg, reg ; Nop. + case kX86InstIdAnd : case kX86InstIdAndpd : case kX86InstIdAndps : case kX86InstIdPand : + case kX86InstIdOr : case kX86InstIdOrpd : case kX86InstIdOrps : case kX86InstIdPor : + case kX86InstIdXchg : + va->delFlags(kVarAttrOutReg); + break; + } +} + +// ============================================================================ +// [asmjit::X86Context - Helpers] +// ============================================================================ + +//! \internal +//! +//! Add unreachable-flow data to the unreachable flow list. +static ASMJIT_INLINE Error X86Context_addUnreachableNode(X86Context* self, Node* node) { + PodList::Link* link = self->_baseZone.allocT::Link>(); + if (link == NULL) + return self->setError(kErrorNoHeapMemory); + + link->setValue(node); + self->_unreachableList.append(link); + + return kErrorOk; +} + +//! \internal +//! +//! Add jump-flow data to the jcc flow list. +static ASMJIT_INLINE Error X86Context_addJccNode(X86Context* self, Node* node) { + PodList::Link* link = self->_baseZone.allocT::Link>(); + + if (link == NULL) + ASMJIT_PROPAGATE_ERROR(self->setError(kErrorNoHeapMemory)); + + link->setValue(node); + self->_jccList.append(link); + + return kErrorOk; +} + +//! \internal +//! +//! Get mask of all registers actually used to pass function arguments. +static ASMJIT_INLINE X86RegMask X86Context_getUsedArgs(X86Context* self, X86CallNode* node, X86FuncDecl* decl) { + X86RegMask regs; + regs.reset(); + + uint32_t i; + uint32_t argCount = decl->getArgCount(); + + for (i = 0; i < argCount; i++) { + const FuncInOut& arg = decl->getArg(i); + if (!arg.hasRegIndex()) + continue; + regs.add(x86VarTypeToClass(arg.getVarType()), IntUtil::mask(arg.getRegIndex())); + } + + return regs; +} + +// ============================================================================ +// [asmjit::X86Context - SArg Insertion] +// ============================================================================ + +struct SArgData { + VarData* sVd; + VarData* cVd; + SArgNode* sArg; + uint32_t aType; +}; + +#define SARG(_Dst_, S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20) \ + (S0 << 0) | (S1 << 1) | (S2 << 2) | (S3 << 3) | \ + (S4 << 4) | (S5 << 5) | (S6 << 6) | (S7 << 7) | \ + (S8 << 8) | (S9 << 9) | (S10 << 10) | (S11 << 11) | \ + (S12 << 12) | (S13 << 13) | (S14 << 14) | (S15 << 15) | \ + (S16 << 16) | (S17 << 17) | (S18 << 18) | (S19 << 19) | \ + (S20 << 20) +#define A 0 /* Auto-convert (doesn't need conversion step). */ +static const uint32_t X86Context_sArgConvTable[kX86VarTypeCount] = { + // dst <- | i8| u8|i16|u16|i32|u32|i64|u64| iP| uP|f32|f64|mmx|xmm|xSs|xPs|xSd|xPd|ymm|yPs|yPd| + //--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + SARG(i8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(u8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(i16 , A , A , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(u16 , A , A , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(i32 , A , A , A , A , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(u32 , A , A , A , A , 0 , 0 , 0 , 0 , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(i64 , A , A , A , A , A , A , 0 , 0 , A , A , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(u64 , A , A , A , A , A , A , 0 , 0 , A , A , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(iPtr , A , A , A , A , A , A , A , A , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(uPtr , A , A , A , A , A , A , A , A , 0 , 0 , A , A , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 ), + SARG(f32 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , A , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ), + SARG(f64 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , A , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 ), + SARG(mmx , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ), + SARG(xmm , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ), + SARG(xSs , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ), + SARG(xPs , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ), + SARG(xSd , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 ), + SARG(xPd , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 ), + SARG(ymm , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ), + SARG(yPs , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 ), + SARG(yPd , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 ) +}; +#undef A +#undef SARG + +static ASMJIT_INLINE bool X86Context_mustConvertSArg(X86Context* self, uint32_t aType, uint32_t sType) { + return (X86Context_sArgConvTable[aType] & (1 << sType)) != 0; +} + +static ASMJIT_INLINE uint32_t X86Context_typeOfConvertedSArg(X86Context* self, uint32_t aType, uint32_t sType) { + ASMJIT_ASSERT(X86Context_mustConvertSArg(self, aType, sType)); + + if (IntUtil::inInterval(aType, _kVarTypeIntStart, _kVarTypeIntEnd)) + return aType; + + if (aType == kVarTypeFp32) + return kX86VarTypeXmmSs; + + if (aType == kVarTypeFp64) + return kX86VarTypeXmmSd; + + if (IntUtil::inInterval(aType, _kX86VarTypeXmmStart, _kX86VarTypeXmmEnd)) + return aType; + + if (IntUtil::inInterval(aType, _kX86VarTypeYmmStart, _kX86VarTypeYmmEnd)) + return aType; + + ASMJIT_ASSERT(!"Reached"); + return aType; +} + +static ASMJIT_INLINE Error X86Context_insertSArgNode( + X86Context* self, X86CallNode* call, + VarData* sVd, const uint32_t* gaRegs, + const FuncInOut& arg, uint32_t argIndex, + SArgData* sArgList, uint32_t& sArgCount) { + + X86Compiler* compiler = self->getCompiler(); + uint32_t i; + + uint32_t aType = arg.getVarType(); + uint32_t sType = sVd->getType(); + + // First locate or create sArgBase. + for (i = 0; i < sArgCount; i++) { + if (sArgList[i].sVd == sVd && sArgList[i].cVd == NULL) + break; + } + + SArgData* sArgData = &sArgList[i]; + + if (i == sArgCount) { + sArgData->sVd = sVd; + sArgData->cVd = NULL; + sArgData->sArg = NULL; + sArgData->aType = 0xFF; + sArgCount++; + } + + const X86VarInfo& sInfo = _x86VarInfo[sType]; + uint32_t sClass = sInfo.getClass(); + + if (X86Context_mustConvertSArg(self, aType, sType)) { + uint32_t cType = X86Context_typeOfConvertedSArg(self, aType, sType); + + const X86VarInfo& cInfo = _x86VarInfo[cType]; + uint32_t cClass = cInfo.getClass(); + + while (++i < sArgCount) { + sArgData = &sArgList[i]; + if (sArgData->sVd != sVd) + break; + + if (sArgData->cVd->getType() != cType || sArgData->aType != aType) + continue; + + sArgData->sArg->_args |= IntUtil::mask(argIndex); + return kErrorOk; + } + + VarData* cVd = compiler->_newVd(cType, cInfo.getSize(), cInfo.getClass(), NULL); + if (cVd == NULL) + return kErrorNoHeapMemory; + + SArgNode* sArg = compiler->newNode(call, sVd, cVd); + if (sArg == NULL) + return kErrorNoHeapMemory; + + X86VarMap* map = self->newVarMap(2); + if (map == NULL) + return kErrorNoHeapMemory; + + ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(cVd)); + ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(sVd)); + + map->_vaCount = 2; + map->_count.reset(); + map->_count.add(sClass); + map->_count.add(cClass); + + map->_start.reset(); + map->_inRegs.reset(); + map->_outRegs.reset(); + map->_clobberedRegs.reset(); + + if (sClass <= cClass) { + map->_list[0].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]); + map->_list[1].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]); + map->_start.set(cClass, sClass != cClass); + } + else { + map->_list[0].setup(cVd, kVarAttrOutReg, 0, gaRegs[cClass]); + map->_list[1].setup(sVd, kVarAttrInReg , 0, gaRegs[sClass]); + map->_start.set(sClass, 1); + } + + sArg->setMap(map); + sArg->_args |= IntUtil::mask(argIndex); + + compiler->addNodeBefore(sArg, call); + ::memmove(sArgData + 1, sArgData, (sArgCount - i) * sizeof(SArgData)); + + sArgData->sVd = sVd; + sArgData->cVd = cVd; + sArgData->sArg = sArg; + sArgData->aType = aType; + + sArgCount++; + return kErrorOk; + } + else { + SArgNode* sArg = sArgData->sArg; + ASMJIT_PROPAGATE_ERROR(self->_registerContextVar(sVd)); + + if (sArg == NULL) { + sArg = compiler->newNode(call, sVd, (VarData*)NULL); + if (sArg == NULL) + return kErrorNoHeapMemory; + + X86VarMap* map = self->newVarMap(1); + if (map == NULL) + return kErrorNoHeapMemory; + + map->_vaCount = 1; + map->_count.reset(); + map->_count.add(sClass); + map->_start.reset(); + map->_inRegs.reset(); + map->_outRegs.reset(); + map->_clobberedRegs.reset(); + map->_list[0].setup(sVd, kVarAttrInReg, 0, gaRegs[sClass]); + + sArg->setMap(map); + sArgData->sArg = sArg; + + compiler->addNodeBefore(sArg, call); + } + + sArg->_args |= IntUtil::mask(argIndex); + return kErrorOk; + } +} + +// ============================================================================ +// [asmjit::X86Context - Fetch] +// ============================================================================ + +//! \internal +//! +//! Prepare the given function `func`. +//! +//! For each node: +//! - Create and assign groupId and flowId. +//! - Collect all variables and merge them to vaList. +Error X86Context::fetch() { + ASMJIT_TLOG("[Fetch] === Begin ===\n"); + + X86Compiler* compiler = getCompiler(); + X86FuncNode* func = getFunc(); + + uint32_t arch = compiler->getArch(); + + Node* node_ = func; + Node* next = NULL; + Node* stop = getStop(); + + uint32_t groupId = 1; + uint32_t flowId = 0; + + VarAttr vaTmpList[80]; + SArgData sArgList[80]; + + PodList::Link* jLink = NULL; + + // Function flags. + func->clearFuncFlags( + kFuncFlagIsNaked | + kX86FuncFlagPushPop | + kX86FuncFlagEmms | + kX86FuncFlagSFence | + kX86FuncFlagLFence ); + + if (func->getHint(kFuncHintNaked ) != 0) func->addFuncFlags(kFuncFlagIsNaked ); + if (func->getHint(kFuncHintCompact ) != 0) func->addFuncFlags(kX86FuncFlagPushPop | kX86FuncFlagEnter | kX86FuncFlagLeave); + if (func->getHint(kX86FuncHintPushPop) != 0) func->addFuncFlags(kX86FuncFlagPushPop); + if (func->getHint(kX86FuncHintEmms ) != 0) func->addFuncFlags(kX86FuncFlagEmms ); + if (func->getHint(kX86FuncHintSFence ) != 0) func->addFuncFlags(kX86FuncFlagSFence ); + if (func->getHint(kX86FuncHintLFence ) != 0) func->addFuncFlags(kX86FuncFlagLFence ); + + // Global allocable registers. + uint32_t* gaRegs = _gaRegs; + + if (!func->hasFuncFlag(kFuncFlagIsNaked)) + gaRegs[kX86RegClassGp] &= ~IntUtil::mask(kX86RegIndexBp); + + // Allowed index registers (Gp/Xmm/Ymm). + const uint32_t indexMask = IntUtil::bits(_regCount.getGp()) & ~(IntUtil::mask(4, 12)); + + // -------------------------------------------------------------------------- + // [VI Macros] + // -------------------------------------------------------------------------- + +#define VI_BEGIN() \ + do { \ + uint32_t vaCount = 0; \ + X86RegCount regCount; \ + \ + X86RegMask inRegs; \ + X86RegMask outRegs; \ + X86RegMask clobberedRegs; \ + \ + regCount.reset(); \ + inRegs.reset(); \ + outRegs.reset(); \ + clobberedRegs.reset() + +#define VI_END(_Node_) \ + if (vaCount == 0 && clobberedRegs.isEmpty()) \ + break; \ + \ + X86VarMap* map = newVarMap(vaCount); \ + if (map == NULL) \ + goto _NoMemory; \ + \ + X86RegCount vaIndex; \ + vaIndex.makeIndex(regCount); \ + \ + map->_vaCount = vaCount; \ + map->_count = regCount; \ + map->_start = vaIndex; \ + \ + map->_inRegs = inRegs; \ + map->_outRegs = outRegs; \ + map->_clobberedRegs = clobberedRegs; \ + \ + VarAttr* va = vaTmpList; \ + while (vaCount) { \ + VarData* vd = va->getVd(); \ + \ + uint32_t class_ = vd->getClass(); \ + uint32_t index = vaIndex.get(class_); \ + \ + vaIndex.add(class_); \ + \ + if (va->_inRegs) \ + va->_allocableRegs = va->_inRegs; \ + else if (va->_outRegIndex != kInvalidReg) \ + va->_allocableRegs = IntUtil::mask(va->_outRegIndex); \ + else \ + va->_allocableRegs &= ~inRegs.get(class_); \ + \ + vd->_va = NULL; \ + map->getVa(index)[0] = va[0]; \ + \ + va++; \ + vaCount--; \ + } \ + \ + _Node_->setMap(map); \ + } while (0) + +#define VI_ADD_VAR(_Vd_, _Va_, _Flags_, _NewAllocable_) \ + do { \ + ASMJIT_ASSERT(_Vd_->_va == NULL); \ + \ + _Va_ = &vaTmpList[vaCount++]; \ + _Va_->setup(_Vd_, _Flags_, 0, _NewAllocable_); \ + _Va_->addVarCount(1); \ + _Vd_->setVa(_Va_); \ + \ + if (_registerContextVar(_Vd_) != kErrorOk) \ + goto _NoMemory; \ + regCount.add(_Vd_->getClass()); \ + } while (0) + +#define VI_MERGE_VAR(_Vd_, _Va_, _Flags_, _NewAllocable_) \ + do { \ + _Va_ = _Vd_->getVa(); \ + \ + if (_Va_ == NULL) { \ + _Va_ = &vaTmpList[vaCount++]; \ + _Va_->setup(_Vd_, 0, 0, _NewAllocable_); \ + _Vd_->setVa(_Va_); \ + \ + if (_registerContextVar(_Vd_) != kErrorOk) \ + goto _NoMemory; \ + regCount.add(_Vd_->getClass()); \ + } \ + \ + _Va_->addFlags(_Flags_); \ + _Va_->addVarCount(1); \ + } while (0) + + // -------------------------------------------------------------------------- + // [Loop] + // -------------------------------------------------------------------------- + + do { +_Do: + while (node_->isFetched()) { +_NextGroup: + if (jLink == NULL) + jLink = _jccList.getFirst(); + else + jLink = jLink->getNext(); + + if (jLink == NULL) + goto _Done; + node_ = X86Context_getOppositeJccFlow(static_cast(jLink->getValue())); + } + + flowId++; + + next = node_->getNext(); + node_->setFlowId(flowId); + + ASMJIT_TSEC({ + X86Context_traceNode(this, node_); + }); + + switch (node_->getType()) { + // ---------------------------------------------------------------------- + // [Align/Embed] + // ---------------------------------------------------------------------- + + case kNodeTypeAlign: + case kNodeTypeEmbed: + break; + + // ---------------------------------------------------------------------- + // [Hint] + // ---------------------------------------------------------------------- + + case kNodeTypeHint: { + HintNode* node = static_cast(node_); + VI_BEGIN(); + + if (node->getHint() == kVarHintAlloc) { + uint32_t remain[kX86RegClassCount]; + HintNode* cur = node; + + remain[kX86RegClassGp ] = _regCount.getGp() - 1 - func->hasFuncFlag(kFuncFlagIsNaked); + remain[kX86RegClassFp ] = _regCount.getFp(); + remain[kX86RegClassMm ] = _regCount.getMm(); + + // Correct. Instead of using `getXyz()` which may be 32 in 64-bit + // mode we use `getGp()`. The reason is that not all registers are + // accessible by all instructions when using AVX512, this makes the + // algorithm safe. + remain[kX86RegClassXyz] = _regCount.getGp(); + + // Merge as many alloc-hints as possible. + for (;;) { + VarData* vd = static_cast(cur->getVd()); + VarAttr* va = vd->getVa(); + + uint32_t regClass = vd->getClass(); + uint32_t regIndex = cur->getValue(); + uint32_t regMask = 0; + + // We handle both kInvalidReg and kInvalidValue. + if (regIndex < kInvalidReg) + regMask = IntUtil::mask(regIndex); + + if (va == NULL) { + if (inRegs.has(regClass, regMask)) + break; + if (remain[regClass] == 0) + break; + VI_ADD_VAR(vd, va, kVarAttrInReg, gaRegs[regClass]); + + if (regMask != 0) { + inRegs.xor_(regClass, regMask); + va->setInRegs(regMask); + va->setInRegIndex(regIndex); + } + + remain[regClass]--; + } + else if (regMask != 0) { + if (inRegs.has(regClass, regMask) && va->getInRegs() != regMask) + break; + + inRegs.xor_(regClass, va->getInRegs() | regMask); + va->setInRegs(regMask); + va->setInRegIndex(regIndex); + } + + if (cur != node) + compiler->removeNode(cur); + + cur = static_cast(node->getNext()); + if (cur == NULL || cur->getType() != kNodeTypeHint || cur->getHint() != kVarHintAlloc) + break; + } + + next = node->getNext(); + } + else { + VarData* vd = static_cast(node->getVd()); + VarAttr* va; + + uint32_t flags = 0; + + switch (node->getHint()) { + case kVarHintSpill: + flags = kVarAttrInMem | kVarAttrSpill; + break; + case kVarHintSave: + flags = kVarAttrInMem; + break; + case kVarHintSaveAndUnuse: + flags = kVarAttrInMem | kVarAttrUnuse; + break; + case kVarHintUnuse: + flags = kVarAttrUnuse; + break; + } + + VI_ADD_VAR(vd, va, flags, 0); + } + + VI_END(node_); + break; + } + + // ---------------------------------------------------------------------- + // [Target] + // ---------------------------------------------------------------------- + + case kNodeTypeTarget: { + break; + } + + // ---------------------------------------------------------------------- + // [Inst] + // ---------------------------------------------------------------------- + + case kNodeTypeInst: { + InstNode* node = static_cast(node_); + + uint32_t code = node->getCode(); + uint32_t flags = node->getFlags(); + + Operand* opList = node->getOpList(); + uint32_t opCount = node->getOpCount(); + + if (opCount) { + const X86InstExtendedInfo& extendedInfo = _x86InstInfo[code].getExtendedInfo(); + const X86SpecialInst* special = NULL; + VI_BEGIN(); + + // Collect instruction flags and merge all 'VarAttr's. + if (extendedInfo.isFp()) + flags |= kNodeFlagIsFp; + + if (extendedInfo.isSpecial() && (special = X86SpecialInst_get(code, opList, opCount)) != NULL) + flags |= kNodeFlagIsSpecial; + + uint32_t gpAllowedMask = 0xFFFFFFFF; + + for (uint32_t i = 0; i < opCount; i++) { + Operand* op = &opList[i]; + VarData* vd; + VarAttr* va; + + if (op->isVar()) { + vd = compiler->getVdById(op->getId()); + VI_MERGE_VAR(vd, va, 0, gaRegs[vd->getClass()] & gpAllowedMask); + + if (static_cast(op)->isGpb()) { + va->addFlags(static_cast(op)->isGpbLo() ? kX86VarAttrGpbLo : kX86VarAttrGpbHi); + if (arch == kArchX86) { + // If a byte register is accessed in 32-bit mode we have to limit + // all allocable registers for that variable to eax/ebx/ecx/edx. + // Other variables are not affected. + va->_allocableRegs &= 0x0F; + } + else { + // It's fine if lo-byte register is accessed in 64-bit mode; + // however, hi-byte has to be checked and if it's used all + // registers (Gp/Xmm) could be only allocated in the lower eight + // half. To do that, we patch 'allocableRegs' of all variables + // we collected until now and change the allocable restriction + // for variables that come after. + if (static_cast(op)->isGpbHi()) { + va->_allocableRegs &= 0x0F; + + if (gpAllowedMask != 0xFF) { + for (uint32_t j = 0; j < i; j++) + vaTmpList[j]._allocableRegs &= vaTmpList[j].hasFlag(kX86VarAttrGpbHi) ? 0x0F : 0xFF; + gpAllowedMask = 0xFF; + } + } + } + } + + if (special != NULL) { + uint32_t inReg = special[i].inReg; + uint32_t outReg = special[i].outReg; + uint32_t c; + + if (static_cast(op)->isGp()) + c = kX86RegClassGp; + else + c = kX86RegClassXyz; + + if (inReg != kInvalidReg) { + uint32_t mask = IntUtil::mask(inReg); + inRegs.add(c, mask); + va->addInRegs(mask); + } + + if (outReg != kInvalidReg) { + uint32_t mask = IntUtil::mask(outReg); + outRegs.add(c, mask); + va->setOutRegIndex(outReg); + } + + va->addFlags(special[i].flags); + } + else { + uint32_t inFlags = kVarAttrInReg; + uint32_t outFlags = kVarAttrOutReg; + uint32_t combinedFlags; + + if (i == 0) { + // Read/Write is usualy the combination of the first operand. + combinedFlags = inFlags | outFlags; + + // Move instructions typically overwrite the first operand, + // but there are some exceptions based on the operands' size + // and type. + if (extendedInfo.isMove()) { + uint32_t movSize = extendedInfo.getMoveSize(); + uint32_t varSize = vd->getSize(); + + // Exception - If the source operand is a memory location + // promote move size into 16 bytes. + if (extendedInfo.isZeroIfMem() && opList[1].isMem()) + movSize = 16; + + if (movSize >= varSize) { + // If move size is greater than or equal to the size of + // the variable there is nothing to do, because the move + // will overwrite the variable in all cases. + combinedFlags = outFlags; + } + else if (static_cast(op)->isGp()) { + uint32_t opSize = static_cast(op)->getSize(); + + // Move size is zero in case that it should be determined + // from the destination register. + if (movSize == 0) + movSize = opSize; + + // Handle the case that a 32-bit operation in 64-bit mode + // always zeroes the rest of the destination register and + // the case that move size is actually greater than or + // equal to the size of the variable. + if (movSize >= 4 || movSize >= varSize) + combinedFlags = outFlags; + } + } + // Comparison/Test instructions don't modify any operand. + else if (extendedInfo.isTest()) { + combinedFlags = inFlags; + } + // Imul. + else if (code == kX86InstIdImul && opCount == 3) { + combinedFlags = outFlags; + } + } + else { + // Read-Only is usualy the combination of the second/third/fourth operands. + combinedFlags = inFlags; + + // Idiv is a special instruction, never handled here. + ASMJIT_ASSERT(code != kX86InstIdIdiv); + + // Xchg/Xadd/Imul. + if (extendedInfo.isXchg() || (code == kX86InstIdImul && opCount == 3 && i == 1)) + combinedFlags = inFlags | outFlags; + } + va->addFlags(combinedFlags); + } + } + else if (op->isMem()) { + X86Mem* m = static_cast(op); + node->setMemOpIndex(i); + + if (OperandUtil::isVarId(m->getBase()) && m->isBaseIndexType()) { + vd = compiler->getVdById(m->getBase()); + if (!vd->isStack()) { + VI_MERGE_VAR(vd, va, 0, gaRegs[vd->getClass()] & gpAllowedMask); + if (m->getMemType() == kMemTypeBaseIndex) { + va->addFlags(kVarAttrInReg); + } + else { + uint32_t inFlags = kVarAttrInMem; + uint32_t outFlags = kVarAttrOutMem; + uint32_t combinedFlags; + + if (i == 0) { + // Default for the first operand. + combinedFlags = inFlags | outFlags; + + // Move to memory - setting the right flags is important + // as if it's just move to the register. It's just a bit + // simpler as there are no special cases. + if (extendedInfo.isMove()) { + uint32_t movSize = IntUtil::iMax(extendedInfo.getMoveSize(), m->getSize()); + uint32_t varSize = vd->getSize(); + + if (movSize >= varSize) + combinedFlags = outFlags; + } + // Comparison/Test instructions don't modify any operand. + else if (extendedInfo.isTest()) { + combinedFlags = inFlags; + } + } + else { + // Default for the second operand. + combinedFlags = inFlags; + + // Handle Xchg instruction (modifies both operands). + if (extendedInfo.isXchg()) + combinedFlags = inFlags | outFlags; + } + + va->addFlags(combinedFlags); + } + } + } + + if (OperandUtil::isVarId(m->getIndex())) { + // Restrict allocation to all registers except ESP/RSP/R12. + vd = compiler->getVdById(m->getIndex()); + VI_MERGE_VAR(vd, va, 0, gaRegs[kX86RegClassGp] & gpAllowedMask); + va->andAllocableRegs(indexMask); + va->addFlags(kVarAttrInReg); + } + } + } + + node->setFlags(flags); + if (vaCount) { + // Handle instructions which result in zeros/ones or nop if used with the + // same destination and source operand. + if (vaCount == 1 && opCount >= 2 && opList[0].isVar() && opList[1].isVar() && !node->hasMemOp()) + X86Context_prepareSingleVarInst(code, &vaTmpList[0]); + } + + VI_END(node_); + } + + // Handle conditional/unconditional jump. + if (node->isJmpOrJcc()) { + JumpNode* jNode = static_cast(node); + + Node* jNext = jNode->getNext(); + TargetNode* jTarget = jNode->getTarget(); + + // If this jump is unconditional we put next node to unreachable node + // list so we can eliminate possible dead code. We have to do this in + // all cases since we are unable to translate without fetch() step. + // + // We also advance our node pointer to the target node to simulate + // natural flow of the function. + if (jNode->isJmp()) { + if (!jNext->isFetched()) + ASMJIT_PROPAGATE_ERROR(X86Context_addUnreachableNode(this, jNext)); + + node_ = jTarget; + goto _Do; + } + else { + if (jTarget->isFetched()) { + uint32_t jTargetFlowId = jTarget->getFlowId(); + + // Update kNodeFlagIsTaken flag to true if this is a conditional + // backward jump. This behavior can be overridden by using + // `kInstOptionTaken` when the instruction is created. + if (!jNode->isTaken() && opCount == 1 && jTargetFlowId <= flowId) { + jNode->addFlags(kNodeFlagIsTaken); + } + } + else if (jNext->isFetched()) { + node_ = jTarget; + goto _Do; + } + else { + ASMJIT_PROPAGATE_ERROR(X86Context_addJccNode(this, jNode)); + + node_ = X86Context_getJccFlow(jNode); + goto _Do; + } + } + } + break; + } + + // ---------------------------------------------------------------------- + // [Func] + // ---------------------------------------------------------------------- + + case kNodeTypeFunc: { + ASMJIT_ASSERT(node_ == func); + X86FuncDecl* decl = func->getDecl(); + + VI_BEGIN(); + for (uint32_t i = 0, argCount = decl->getArgCount(); i < argCount; i++) { + const FuncInOut& arg = decl->getArg(i); + + VarData* vd = func->getArg(i); + VarAttr* va; + + if (vd == NULL) + continue; + + // Overlapped function arguments. + if (vd->getVa() != NULL) + return compiler->setError(kErrorOverlappedArgs); + VI_ADD_VAR(vd, va, 0, 0); + + uint32_t aType = arg.getVarType(); + uint32_t vType = vd->getType(); + + if (arg.hasRegIndex()) { + if (x86VarTypeToClass(aType) == vd->getClass()) { + va->addFlags(kVarAttrOutReg); + va->setOutRegIndex(arg.getRegIndex()); + } + else { + va->addFlags(kVarAttrOutConv); + } + } + else { + if ((x86VarTypeToClass(aType) == vd->getClass()) || + (vType == kX86VarTypeXmmSs && aType == kVarTypeFp32) || + (vType == kX86VarTypeXmmSd && aType == kVarTypeFp64)) { + va->addFlags(kVarAttrOutMem); + } + else { + // TODO: [COMPILER] Not implemented. + ASMJIT_ASSERT(!"Implemented"); + } + } + } + VI_END(node_); + break; + } + + // ---------------------------------------------------------------------- + // [End] + // ---------------------------------------------------------------------- + + case kNodeTypeEnd: { + goto _NextGroup; + } + + // ---------------------------------------------------------------------- + // [Ret] + // ---------------------------------------------------------------------- + + case kNodeTypeRet: { + RetNode* node = static_cast(node_); + X86FuncDecl* decl = func->getDecl(); + + if (decl->hasRet()) { + const FuncInOut& ret = decl->getRet(0); + uint32_t retClass = x86VarTypeToClass(ret.getVarType()); + + VI_BEGIN(); + for (uint32_t i = 0; i < 2; i++) { + Operand* op = &node->_ret[i]; + + if (op->isVar()) { + VarData* vd = compiler->getVdById(op->getId()); + VarAttr* va; + + if (vd->getClass() == retClass) { + // TODO: [COMPILER] Fix RetNode fetch. + VI_MERGE_VAR(vd, va, 0, 0); + va->setInRegs(i == 0 ? IntUtil::mask(kX86RegIndexAx) : IntUtil::mask(kX86RegIndexDx)); + va->addFlags(kVarAttrInReg); + inRegs.add(retClass, va->getInRegs()); + } + } + } + VI_END(node_); + } + break; + } + + // ---------------------------------------------------------------------- + // [Call] + // ---------------------------------------------------------------------- + + case kNodeTypeCall: { + X86CallNode* node = static_cast(node_); + X86FuncDecl* decl = node->getDecl(); + + Operand* target = &node->_target; + Operand* argList = node->_args; + Operand* retList = node->_ret; + + func->addFuncFlags(kFuncFlagIsCaller); + func->mergeCallStackSize(node->_x86Decl.getArgStackSize()); + node->_usedArgs = X86Context_getUsedArgs(this, node, decl); + + uint32_t i; + uint32_t argCount = decl->getArgCount(); + uint32_t sArgCount = 0; + uint32_t gpAllocableMask = gaRegs[kX86RegClassGp] & ~node->_usedArgs.get(kX86RegClassGp); + + VarData* vd; + VarAttr* va; + + VI_BEGIN(); + + // Function-call operand. + if (target->isVar()) { + vd = compiler->getVdById(target->getId()); + VI_MERGE_VAR(vd, va, 0, 0); + + va->addFlags(kVarAttrInReg | kVarAttrInCall); + if (va->getInRegs() == 0) + va->addAllocableRegs(gpAllocableMask); + } + else if (target->isMem()) { + X86Mem* m = static_cast(target); + + if (OperandUtil::isVarId(m->getBase()) && m->isBaseIndexType()) { + vd = compiler->getVdById(m->getBase()); + if (!vd->isStack()) { + VI_MERGE_VAR(vd, va, 0, 0); + if (m->getMemType() == kMemTypeBaseIndex) { + va->addFlags(kVarAttrInReg | kVarAttrInCall); + if (va->getInRegs() == 0) + va->addAllocableRegs(gpAllocableMask); + } + else { + va->addFlags(kVarAttrInMem | kVarAttrInCall); + } + } + } + + if (OperandUtil::isVarId(m->getIndex())) { + // Restrict allocation to all registers except ESP/RSP/R12. + vd = compiler->getVdById(m->getIndex()); + VI_MERGE_VAR(vd, va, 0, 0); + + va->addFlags(kVarAttrInReg | kVarAttrInCall); + if ((va->getInRegs() & ~indexMask) == 0) + va->andAllocableRegs(gpAllocableMask & indexMask); + } + } + + // Function-call arguments. + for (i = 0; i < argCount; i++) { + Operand* op = &argList[i]; + if (!op->isVar()) + continue; + + vd = compiler->getVdById(op->getId()); + const FuncInOut& arg = decl->getArg(i); + + if (arg.hasRegIndex()) { + VI_MERGE_VAR(vd, va, 0, 0); + + uint32_t argType = arg.getVarType(); + uint32_t argClass = x86VarTypeToClass(argType); + + if (vd->getClass() == argClass) { + va->addInRegs(IntUtil::mask(arg.getRegIndex())); + va->addFlags(kVarAttrInReg | kVarAttrInArg); + } + else { + va->addFlags(kVarAttrInConv | kVarAttrInArg); + } + } + // If this is a stack-based argument we insert SArgNode instead of + // using VarAttr. It improves the code, because the argument can be + // moved onto stack as soon as it is ready and the register used by + // the variable can be reused for something else. It is also much + // easier to handle argument conversions, because there will be at + // most only one node per conversion. + else { + if (X86Context_insertSArgNode(this, node, vd, gaRegs, arg, i, sArgList, sArgCount) != kErrorOk) + goto _NoMemory; + } + } + + // Function-call return(s). + for (i = 0; i < 2; i++) { + Operand* op = &retList[i]; + if (!op->isVar()) + continue; + + const FuncInOut& ret = decl->getRet(i); + if (ret.hasRegIndex()) { + uint32_t retType = ret.getVarType(); + uint32_t retClass = x86VarTypeToClass(retType); + + vd = compiler->getVdById(op->getId()); + VI_MERGE_VAR(vd, va, 0, 0); + + if (vd->getClass() == retClass) { + va->setOutRegIndex(ret.getRegIndex()); + va->addFlags(kVarAttrOutReg | kVarAttrOutRet); + } + else { + va->addFlags(kVarAttrOutConv | kVarAttrOutRet); + } + } + } + + // Init clobbered. + clobberedRegs.set(kX86RegClassGp , IntUtil::bits(_regCount.getGp()) & (~decl->getPreserved(kX86RegClassGp))); + clobberedRegs.set(kX86RegClassFp , IntUtil::bits(_regCount.getFp())); + clobberedRegs.set(kX86RegClassMm , IntUtil::bits(_regCount.getMm()) & (~decl->getPreserved(kX86RegClassMm))); + clobberedRegs.set(kX86RegClassXyz, IntUtil::bits(_regCount.getXyz()) & (~decl->getPreserved(kX86RegClassXyz))); + + VI_END(node_); + break; + } + + default: + break; + } + + node_ = next; + } while (node_ != stop); + +_Done: + ASMJIT_TLOG("[Fetch] === Done ===\n\n"); + return kErrorOk; + + // -------------------------------------------------------------------------- + // [Failure] + // -------------------------------------------------------------------------- + +_NoMemory: + ASMJIT_TLOG("[Fetch] === Out of Memory ===\n"); + return compiler->setError(kErrorNoHeapMemory); +} + +// ============================================================================ +// [asmjit::X86Context - Annotate] +// ============================================================================ + +Error X86Context::annotate() { +#if !defined(ASMJIT_DISABLE_LOGGER) + FuncNode* func = getFunc(); + + Node* node_ = func; + Node* end = func->getEnd(); + + Zone& sa = _compiler->_stringZone; + StringBuilderT<128> sb; + + uint32_t maxLen = 0; + while (node_ != end) { + if (node_->getComment() == NULL) { + if (node_->getType() == kNodeTypeInst) { + InstNode* node = static_cast(node_); + X86Context_annotateInstruction(this, sb, node->getCode(), node->getOpList(), node->getOpCount()); + + node_->setComment(static_cast(sa.dup(sb.getData(), sb.getLength() + 1))); + maxLen = IntUtil::iMax(maxLen, static_cast(sb.getLength())); + + sb.clear(); + } + } + + node_ = node_->getNext(); + } + _annotationLength = maxLen + 1; +#endif // !ASMJIT_DISABLE_LOGGER + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86BaseAlloc] +// ============================================================================ + +struct X86BaseAlloc { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86BaseAlloc(X86Context* context) { + _context = context; + _compiler = context->getCompiler(); + } + ASMJIT_INLINE ~X86BaseAlloc() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the context. + ASMJIT_INLINE X86Context* getContext() const { return _context; } + //! Get the current state (always the same instance as X86Context::_x86State). + ASMJIT_INLINE X86VarState* getState() const { return _context->getState(); } + + //! Get the node. + ASMJIT_INLINE Node* getNode() const { return _node; } + + //! Get VarAttr list (all). + ASMJIT_INLINE VarAttr* getVaList() const { return _vaList[0]; } + //! Get VarAttr list (per class). + ASMJIT_INLINE VarAttr* getVaListByClass(uint32_t c) const { return _vaList[c]; } + + //! Get VarAttr count (all). + ASMJIT_INLINE uint32_t getVaCount() const { return _vaCount; } + //! Get VarAttr count (per class). + ASMJIT_INLINE uint32_t getVaCountByClass(uint32_t c) const { return _count.get(c); } + + //! Get whether all variables of class `c` are done. + ASMJIT_INLINE bool isVaDone(uint32_t c) const { return _done.get(c) == _count.get(c); } + + //! Get how many variables have been allocated. + ASMJIT_INLINE uint32_t getVaDone(uint32_t c) const { return _done.get(c); } + + ASMJIT_INLINE void addVaDone(uint32_t c, uint32_t n = 1) { _done.add(c, n); } + + //! Get number of allocable registers per class. + ASMJIT_INLINE uint32_t getGaRegs(uint32_t c) const { + return _context->_gaRegs[c]; + } + + // -------------------------------------------------------------------------- + // [Init / Cleanup] + // -------------------------------------------------------------------------- + +protected: + // Just to prevent calling these methods by X86Context::translate(). + + ASMJIT_INLINE void init(Node* node, X86VarMap* map); + ASMJIT_INLINE void cleanup(); + + // -------------------------------------------------------------------------- + // [Unuse] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void unuseBefore(); + + template + ASMJIT_INLINE void unuseAfter(); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Context. + X86Context* _context; + //! Compiler. + X86Compiler* _compiler; + + //! Node. + Node* _node; + + //! Variable map. + X86VarMap* _map; + //! VarAttr list (per register class). + VarAttr* _vaList[4]; + + //! Count of all VarAttr's. + uint32_t _vaCount; + + //! VarAttr's total counter. + X86RegCount _count; + //! VarAttr's done counter. + X86RegCount _done; +}; + +// ============================================================================ +// [asmjit::X86BaseAlloc - Init / Cleanup] +// ============================================================================ + +ASMJIT_INLINE void X86BaseAlloc::init(Node* node, X86VarMap* map) { + _node = node; + _map = map; + + // We have to set the correct cursor in case any instruction is emitted + // during the allocation phase; it has to be emitted before the current + // instruction. + _compiler->_setCursor(node->getPrev()); + + // Setup the lists of variables. + { + VarAttr* va = map->getVaList(); + _vaList[kX86RegClassGp ] = va; + _vaList[kX86RegClassFp ] = va + map->getVaStart(kX86RegClassFp ); + _vaList[kX86RegClassMm ] = va + map->getVaStart(kX86RegClassMm ); + _vaList[kX86RegClassXyz] = va + map->getVaStart(kX86RegClassXyz); + } + + // Setup counters. + _vaCount = map->getVaCount(); + + _count = map->_count; + _done.reset(); + + // Connect Vd->Va. + for (uint32_t i = 0; i < _vaCount; i++) { + VarAttr* va = &_vaList[0][i]; + VarData* vd = va->getVd(); + + vd->setVa(va); + } +} + +ASMJIT_INLINE void X86BaseAlloc::cleanup() { + // Disconnect Vd->Va. + for (uint32_t i = 0; i < _vaCount; i++) { + VarAttr* va = &_vaList[0][i]; + VarData* vd = va->getVd(); + + vd->setVa(NULL); + } +} + +// ============================================================================ +// [asmjit::X86BaseAlloc - Unuse] +// ============================================================================ + +template +ASMJIT_INLINE void X86BaseAlloc::unuseBefore() { + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + const uint32_t checkFlags = + kVarAttrInOutReg | + kVarAttrInMem | + kVarAttrInArg | + kVarAttrInCall | + kVarAttrInConv ; + + for (uint32_t i = 0; i < count; i++) { + VarAttr* va = &list[i]; + + if ((va->getFlags() & checkFlags) == kVarAttrOutReg) { + _context->unuse(va->getVd()); + } + } +} + +template +ASMJIT_INLINE void X86BaseAlloc::unuseAfter() { + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + for (uint32_t i = 0; i < count; i++) { + VarAttr* va = &list[i]; + + if (va->getFlags() & kVarAttrUnuse) + _context->unuse(va->getVd()); + } +} + +// ============================================================================ +// [asmjit::X86VarAlloc] +// ============================================================================ + +//! \internal +//! +//! Register allocator context (asm instructions). +struct X86VarAlloc : public X86BaseAlloc { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86VarAlloc(X86Context* context) : X86BaseAlloc(context) {} + ASMJIT_INLINE ~X86VarAlloc() {} + + // -------------------------------------------------------------------------- + // [Run] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Error run(Node* node); + + // -------------------------------------------------------------------------- + // [Init / Cleanup] + // -------------------------------------------------------------------------- + +protected: + // Just to prevent calling these methods by X86Context::translate(). + + ASMJIT_INLINE void init(Node* node, X86VarMap* map); + ASMJIT_INLINE void cleanup(); + + // -------------------------------------------------------------------------- + // [Plan / Spill / Alloc] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void plan(); + + template + ASMJIT_INLINE void spill(); + + template + ASMJIT_INLINE void alloc(); + + // -------------------------------------------------------------------------- + // [GuessAlloc / GuessSpill] + // -------------------------------------------------------------------------- + + //! Guess which register is the best candidate for 'vd' from + //! 'allocableRegs'. + //! + //! The guess is based on looking ahead and inspecting register allocator + //! instructions. The main reason is to prevent allocation to a register + //! which is needed by next instruction(s). The guess look tries to go as far + //! as possible, after the remaining registers are zero, the mask of previous + //! registers (called 'safeRegs') is returned. + template + ASMJIT_INLINE uint32_t guessAlloc(VarData* vd, uint32_t allocableRegs); + + //! Guess whether to move the given 'vd' instead of spill. + template + ASMJIT_INLINE uint32_t guessSpill(VarData* vd, uint32_t allocableRegs); + + // -------------------------------------------------------------------------- + // [Modified] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void modified(); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Will alloc to these registers. + X86RegMask _willAlloc; + //! Will spill these registers. + X86RegMask _willSpill; +}; + +// ============================================================================ +// [asmjit::X86VarAlloc - Run] +// ============================================================================ + +ASMJIT_INLINE Error X86VarAlloc::run(Node* node_) { + // Initialize. + X86VarMap* map = node_->getMap(); + if (map == NULL) + return kErrorOk; + + // Initialize the allocator; connect Vd->Va. + init(node_, map); + + // Unuse overwritten variables. + unuseBefore(); + unuseBefore(); + unuseBefore(); + + // Plan the allocation. Planner assigns input/output registers for each + // variable and decides whether to allocate it in register or stack. + plan(); + plan(); + plan(); + + // Spill all variables marked by plan(). + spill(); + spill(); + spill(); + + // Alloc all variables marked by plan(). + alloc(); + alloc(); + alloc(); + + // Translate node operands. + if (node_->getType() == kNodeTypeInst) { + InstNode* node = static_cast(node_); + ASMJIT_PROPAGATE_ERROR(X86Context_translateOperands(_context, node->getOpList(), node->getOpCount())); + } + else if (node_->getType() == kNodeTypeSArg) { + SArgNode* node = static_cast(node_); + + X86CallNode* call = static_cast(node->getCall()); + X86FuncDecl* decl = call->getDecl(); + + uint32_t argIndex = 0; + uint32_t argMask = node->_args; + + VarData* sVd = node->getSVd(); + VarData* cVd = node->getCVd(); + + // Convert first. + ASMJIT_ASSERT(sVd->getRegIndex() != kInvalidReg); + + if (cVd != NULL) { + ASMJIT_ASSERT(cVd->getRegIndex() != kInvalidReg); + _context->emitConvertVarToVar( + cVd->getType(), cVd->getRegIndex(), + sVd->getType(), sVd->getRegIndex()); + sVd = cVd; + } + + while (argMask != 0) { + if (argMask & 0x1) { + FuncInOut& arg = decl->getArg(argIndex); + ASMJIT_ASSERT(arg.hasStackOffset()); + + X86Mem dst = x86::ptr(_context->_zsp, -static_cast(_context->getRegSize()) + arg.getStackOffset()); + _context->emitMoveVarOnStack(arg.getVarType(), &dst, sVd->getType(), sVd->getRegIndex()); + } + + argIndex++; + argMask >>= 1; + } + } + + // Mark variables as modified. + modified(); + modified(); + modified(); + + // Cleanup; disconnect Vd->Va. + cleanup(); + + // Update clobbered mask. + _context->_clobberedRegs.add(_willAlloc); + _context->_clobberedRegs.add(map->_clobberedRegs); + + // Unuse. + unuseAfter(); + unuseAfter(); + unuseAfter(); + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86VarAlloc - Init / Cleanup] +// ============================================================================ + +ASMJIT_INLINE void X86VarAlloc::init(Node* node, X86VarMap* map) { + X86BaseAlloc::init(node, map); + + // These will block planner from assigning them during planning. Planner will + // add more registers when assigning registers to variables that don't need + // any specific register. + _willAlloc = map->_inRegs; + _willAlloc.add(map->_outRegs); + _willSpill.reset(); +} + +ASMJIT_INLINE void X86VarAlloc::cleanup() { + X86BaseAlloc::cleanup(); +} + +// ============================================================================ +// [asmjit::X86VarAlloc - Plan / Spill / Alloc] +// ============================================================================ + +template +ASMJIT_INLINE void X86VarAlloc::plan() { + if (isVaDone(C)) + return; + + uint32_t i; + + uint32_t willAlloc = _willAlloc.get(C); + uint32_t willFree = 0; + + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks. + for (i = 0; i < count; i++) { + VarAttr* va = &list[i]; + VarData* vd = va->getVd(); + + uint32_t vaFlags = va->getFlags(); + uint32_t regIndex = vd->getRegIndex(); + uint32_t regMask = (regIndex != kInvalidReg) ? IntUtil::mask(regIndex) : 0; + + if ((vaFlags & kVarAttrInOutReg) != 0) { + // Planning register allocation. First check whether the variable is + // already allocated in register and if it can stay allocated there. + // + // The following conditions may happen: + // + // a) Allocated register is one of the mandatoryRegs. + // b) Allocated register is one of the allocableRegs. + uint32_t mandatoryRegs = va->getInRegs(); + uint32_t allocableRegs = va->getAllocableRegs(); + + ASMJIT_TLOG("[RA-PLAN ] %s (%s)\n", + vd->getName(), + (vaFlags & kVarAttrInOutReg) == kVarAttrOutReg ? "Out Reg" : "In/Out Reg"); + + ASMJIT_TLOG("[RA-PLAN ] RegMask=%08X Mandatory=%08X Allocable=%08X\n", + regMask, mandatoryRegs, allocableRegs); + + if (regMask != 0) { + // Special path for planning output-only registers. + if ((vaFlags & kVarAttrInOutReg) == kVarAttrOutReg) { + uint32_t outRegIndex = va->getOutRegIndex(); + mandatoryRegs = (outRegIndex != kInvalidReg) ? IntUtil::mask(outRegIndex) : 0; + + if ((mandatoryRegs | allocableRegs) & regMask) { + va->setOutRegIndex(regIndex); + va->addFlags(kVarAttrAllocOutDone); + + if (mandatoryRegs & regMask) { + // Case 'a' - 'willAlloc' contains initially all inRegs from all VarAttr's. + ASMJIT_ASSERT((willAlloc & regMask) != 0); + } + else { + // Case 'b'. + va->setOutRegIndex(regIndex); + willAlloc |= regMask; + } + + ASMJIT_TLOG("[RA-PLAN ] WillAlloc\n"); + addVaDone(C); + + continue; + } + } + else { + if ((mandatoryRegs | allocableRegs) & regMask) { + va->setInRegIndex(regIndex); + va->addFlags(kVarAttrAllocInDone); + + if (mandatoryRegs & regMask) { + // Case 'a' - 'willAlloc' contains initially all inRegs from all VarAttr's. + ASMJIT_ASSERT((willAlloc & regMask) != 0); + } + else { + // Case 'b'. + va->addInRegs(regMask); + willAlloc |= regMask; + } + + ASMJIT_TLOG("[RA-PLAN ] WillAlloc\n"); + addVaDone(C); + + continue; + } + } + + // Trace it here so we don't pollute log by `WillFree` of zero regMask. + ASMJIT_TLOG("[RA-PLAN ] WillFree\n"); + } + + // Variable is not allocated or allocated in register that doesn't + // match inRegs or allocableRegs. The next step is to pick the best + // register for this variable. If `inRegs` contains any register the + // decision is simple - we have to follow, in other case will use + // the advantage of `guessAlloc()` to find a register (or registers) + // by looking ahead. But the best way to find a good register is not + // here since now we have no information about the registers that + // will be freed. So instead of finding register here, we just mark + // the current register (if variable is allocated) as `willFree` so + // the planner can use this information in second step to plan other + // allocation of other variables. + willFree |= regMask; + continue; + } + else { + // Memory access - if variable is allocated it has to be freed. + ASMJIT_TLOG("[RA-PLAN ] %s (Memory)\n", vd->getName()); + + if (regMask != 0) { + ASMJIT_TLOG("[RA-PLAN ] WillFree\n"); + willFree |= regMask; + continue; + } + else { + ASMJIT_TLOG("[RA-PLAN ] Done\n"); + va->addFlags(kVarAttrAllocInDone); + addVaDone(C); + continue; + } + } + } + + // Occupied registers without 'willFree' registers; contains basically + // all the registers we can use to allocate variables without inRegs + // speficied. + uint32_t occupied = state->_occupied.get(C) & ~willFree; + uint32_t willSpill = 0; + + // Find the best registers for variables that are not allocated yet. + for (i = 0; i < count; i++) { + VarAttr* va = &list[i]; + VarData* vd = va->getVd(); + + uint32_t vaFlags = va->getFlags(); + + if ((vaFlags & kVarAttrInOutReg) != 0) { + if ((vaFlags & kVarAttrInOutReg) == kVarAttrOutReg) { + if (vaFlags & kVarAttrAllocOutDone) + continue; + + // Skip all registers that have assigned outRegIndex. Spill if occupied. + if (va->hasOutRegIndex()) { + uint32_t outRegs = IntUtil::mask(va->getOutRegIndex()); + willSpill |= occupied & outRegs; + continue; + } + } + else { + if (vaFlags & kVarAttrAllocInDone) + continue; + + // We skip all registers that have assigned inRegIndex, indicates that + // the register to allocate in is known. + if (va->hasInRegIndex()) { + uint32_t inRegs = va->getInRegs(); + willSpill |= occupied & inRegs; + continue; + } + } + + uint32_t m = va->getInRegs(); + if (va->hasOutRegIndex()) + m |= IntUtil::mask(va->getOutRegIndex()); + + m = va->getAllocableRegs() & ~(willAlloc ^ m); + m = guessAlloc(vd, m); + ASMJIT_ASSERT(m != 0); + + uint32_t candidateRegs = m & ~occupied; + uint32_t homeMask = vd->getHomeMask(); + + uint32_t regIndex; + uint32_t regMask; + + if (candidateRegs == 0) { + candidateRegs = m & occupied & ~state->_modified.get(C); + if (candidateRegs == 0) + candidateRegs = m; + } + + if (candidateRegs & homeMask) + candidateRegs &= homeMask; + + regIndex = IntUtil::findFirstBit(candidateRegs); + regMask = IntUtil::mask(regIndex); + + if ((vaFlags & kVarAttrInOutReg) == kVarAttrOutReg) { + va->setOutRegIndex(regIndex); + } + else { + va->setInRegIndex(regIndex); + va->setInRegs(regMask); + } + + willAlloc |= regMask; + willSpill |= regMask & occupied; + willFree &=~regMask; + occupied |= regMask; + + continue; + } + else if ((vaFlags & kVarAttrInOutMem) != 0) { + uint32_t regIndex = vd->getRegIndex(); + if (regIndex != kInvalidReg && (vaFlags & kVarAttrInOutMem) != kVarAttrOutMem) { + willSpill |= IntUtil::mask(regIndex); + } + } + } + + // Set calculated masks back to the allocator; needed by spill() and alloc(). + _willSpill.set(C, willSpill); + _willAlloc.set(C, willAlloc); +} + +template +ASMJIT_INLINE void X86VarAlloc::spill() { + uint32_t m = _willSpill.get(C); + uint32_t i = static_cast(0) - 1; + + if (m == 0) + return; + + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + // Available registers for decision if move has any benefit over spill. + uint32_t availableRegs = getGaRegs(C) & ~(state->_occupied.get(C) | m | _willAlloc.get(C)); + + do { + // We always advance one more to destroy the bit that we have found. + uint32_t bitIndex = IntUtil::findFirstBit(m) + 1; + + i += bitIndex; + m >>= bitIndex; + + VarData* vd = sVars[i]; + ASMJIT_ASSERT(vd != NULL); + + VarAttr* va = vd->getVa(); + ASMJIT_ASSERT(va == NULL || !va->hasFlag(kVarAttrInOutReg)); + + if (vd->isModified() && availableRegs) { + // Don't check for alternatives if the variable has to be spilled. + if (va == NULL || !va->hasFlag(kVarAttrSpill)) { + uint32_t altRegs = guessSpill(vd, availableRegs); + + if (altRegs != 0) { + uint32_t regIndex = IntUtil::findFirstBit(altRegs); + uint32_t regMask = IntUtil::mask(regIndex); + + _context->move(vd, regIndex); + availableRegs ^= regMask; + continue; + } + } + } + + _context->spill(vd); + } while (m != 0); +} + +template +ASMJIT_INLINE void X86VarAlloc::alloc() { + if (isVaDone(C)) + return; + + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + uint32_t i; + bool didWork; + + // Alloc 'in' regs. + do { + didWork = false; + for (i = 0; i < count; i++) { + VarAttr* aVa = &list[i]; + VarData* aVd = aVa->getVd(); + + if ((aVa->getFlags() & (kVarAttrInReg | kVarAttrAllocInDone)) != kVarAttrInReg) + continue; + + uint32_t aIndex = aVd->getRegIndex(); + uint32_t bIndex = aVa->getInRegIndex(); + + // Shouldn't be the same. + ASMJIT_ASSERT(aIndex != bIndex); + + VarData* bVd = getState()->getListByClass(C)[bIndex]; + if (bVd != NULL) { + // Gp registers only - Swap two registers if we can solve two + // allocation tasks by a single 'xchg' instruction, swapping + // two registers required by the instruction/node or one register + // required with another non-required. + if (C == kX86RegClassGp && aIndex != kInvalidReg) { + VarAttr* bVa = bVd->getVa(); + _context->swapGp(aVd, bVd); + + aVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + + // Doublehit, two registers allocated by a single swap. + if (bVa != NULL && bVa->getInRegIndex() == aIndex) { + bVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + } + + didWork = true; + continue; + } + } + else if (aIndex != kInvalidReg) { + _context->move(aVd, bIndex); + + aVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + + didWork = true; + continue; + } + else { + _context->alloc(aVd, bIndex); + + aVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + + didWork = true; + continue; + } + } + } while (didWork); + + // Alloc 'out' regs. + for (i = 0; i < count; i++) { + VarAttr* va = &list[i]; + VarData* vd = va->getVd(); + + if ((va->getFlags() & (kVarAttrInOutReg | kVarAttrAllocOutDone)) != kVarAttrOutReg) + continue; + + uint32_t regIndex = va->getOutRegIndex(); + ASMJIT_ASSERT(regIndex != kInvalidReg); + + if (vd->getRegIndex() != regIndex) { + ASMJIT_ASSERT(sVars[regIndex] == NULL); + _context->attach(vd, regIndex, false); + } + + va->addFlags(kVarAttrAllocOutDone); + addVaDone(C); + } +} + +// ============================================================================ +// [asmjit::X86VarAlloc - GuessAlloc / GuessSpill] +// ============================================================================ + +template +ASMJIT_INLINE uint32_t X86VarAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) { + ASMJIT_ASSERT(allocableRegs != 0); + + // Stop now if there is only one bit (register) set in `allocableRegs` mask. + if (IntUtil::isPowerOf2(allocableRegs)) + return allocableRegs; + + uint32_t cId = vd->getContextId(); + uint32_t safeRegs = allocableRegs; + + uint32_t i; + uint32_t maxLookAhead = _compiler->getMaxLookAhead(); + + // Look ahead and calculate mask of special registers on both - input/output. + Node* node = _node; + for (i = 0; i < maxLookAhead; i++) { + VarBits* liveness = node->getLiveness(); + + // If the variable becomes dead it doesn't make sense to continue. + if (liveness != NULL && !liveness->getBit(cId)) + break; + + // Stop on 'RetNode' and 'EndNode. + if (node->hasFlag(kNodeFlagIsRet)) + break; + + // Stop on conditional jump, we don't follow them. + if (node->hasFlag(kNodeFlagIsJcc)) + break; + + // Advance on non-conditional jump. + if (node->hasFlag(kNodeFlagIsJmp)) + node = static_cast(node)->getTarget(); + + node = node->getNext(); + ASMJIT_ASSERT(node != NULL); + + X86VarMap* map = node->getMap(); + if (map != NULL) { + VarAttr* va = map->findVaByClass(C, vd); + uint32_t mask; + + if (va != NULL) { + // If the variable is overwritten it doesn't mase sense to continue. + if (!(va->getFlags() & kVarAttrInAll)) + break; + + mask = va->getAllocableRegs(); + if (mask != 0) { + allocableRegs &= mask; + if (allocableRegs == 0) + break; + safeRegs = allocableRegs; + } + + mask = va->getInRegs(); + if (mask != 0) { + allocableRegs &= mask; + if (allocableRegs == 0) + break; + safeRegs = allocableRegs; + break; + } + + allocableRegs &= ~(map->_outRegs.get(C) | map->_clobberedRegs.get(C)); + if (allocableRegs == 0) + break; + } + else { + allocableRegs &= ~(map->_inRegs.get(C) | map->_outRegs.get(C) | map->_clobberedRegs.get(C)); + if (allocableRegs == 0) + break; + } + + safeRegs = allocableRegs; + } + } + + return safeRegs; +} + +template +ASMJIT_INLINE uint32_t X86VarAlloc::guessSpill(VarData* vd, uint32_t allocableRegs) { + ASMJIT_ASSERT(allocableRegs != 0); + + return 0; +} + +// ============================================================================ +// [asmjit::X86VarAlloc - Modified] +// ============================================================================ + +template +ASMJIT_INLINE void X86VarAlloc::modified() { + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + for (uint32_t i = 0; i < count; i++) { + VarAttr* va = &list[i]; + + if (va->hasFlag(kVarAttrOutReg)) { + VarData* vd = va->getVd(); + + uint32_t regIndex = vd->getRegIndex(); + uint32_t regMask = IntUtil::mask(regIndex); + + vd->setModified(true); + _context->_x86State._modified.add(C, regMask); + } + } +} + +// ============================================================================ +// [asmjit::X86CallAlloc] +// ============================================================================ + +//! \internal +//! +//! Register allocator context (function call). +struct X86CallAlloc : public X86BaseAlloc { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86CallAlloc(X86Context* context) : X86BaseAlloc(context) {} + ASMJIT_INLINE ~X86CallAlloc() {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get the node. + ASMJIT_INLINE X86CallNode* getNode() const { return static_cast(_node); } + + // -------------------------------------------------------------------------- + // [Run] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE Error run(X86CallNode* node); + + // -------------------------------------------------------------------------- + // [Init / Cleanup] + // -------------------------------------------------------------------------- + +protected: + // Just to prevent calling these methods from X86Context::translate(). + + ASMJIT_INLINE void init(X86CallNode* node, X86VarMap* map); + ASMJIT_INLINE void cleanup(); + + // -------------------------------------------------------------------------- + // [Plan / Alloc / Spill / Move] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void plan(); + + template + ASMJIT_INLINE void spill(); + + template + ASMJIT_INLINE void alloc(); + + // -------------------------------------------------------------------------- + // [AllocImmsOnStack] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void allocImmsOnStack(); + + // -------------------------------------------------------------------------- + // [Duplicate] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void duplicate(); + + // -------------------------------------------------------------------------- + // [GuessAlloc / GuessSpill] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE uint32_t guessAlloc(VarData* vd, uint32_t allocableRegs); + + template + ASMJIT_INLINE uint32_t guessSpill(VarData* vd, uint32_t allocableRegs); + + // -------------------------------------------------------------------------- + // [Save] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void save(); + + // -------------------------------------------------------------------------- + // [Clobber] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void clobber(); + + // -------------------------------------------------------------------------- + // [Ret] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void ret(); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Will alloc to these registers. + X86RegMask _willAlloc; + //! Will spill these registers. + X86RegMask _willSpill; +}; + +// ============================================================================ +// [asmjit::X86CallAlloc - Run] +// ============================================================================ + +ASMJIT_INLINE Error X86CallAlloc::run(X86CallNode* node) { + // Initialize. + X86VarMap* map = node->getMap(); + if (map == NULL) + return kErrorOk; + + // Initialize the allocator; prepare basics and connect Vd->Va. + init(node, map); + + // Plan register allocation. Planner is only able to assign one register per + // variable. If any variable is used multiple times it will be handled later. + plan(); + plan(); + plan(); + + // Spill. + spill(); + spill(); + spill(); + + // Alloc. + alloc(); + alloc(); + alloc(); + + // Unuse clobbered registers that are not used to pass function arguments and + // save variables used to pass function arguments that will be reused later on. + save(); + save(); + save(); + + // Allocate immediates in registers and on the stack. + allocImmsOnStack(); + + // Duplicate. + duplicate(); + duplicate(); + duplicate(); + + // Translate call operand. + ASMJIT_PROPAGATE_ERROR(X86Context_translateOperands(_context, &node->_target, 1)); + + // To emit instructions after call. + _compiler->_setCursor(node); + + // If the callee pops stack it has to be manually adjusted back. + X86FuncDecl* decl = node->getDecl(); + if (decl->getCalleePopsStack() && decl->getArgStackSize() != 0) { + _compiler->emit(kX86InstIdSub, _context->_zsp, static_cast(decl->getArgStackSize())); + } + + // Clobber. + clobber(); + clobber(); + clobber(); + + // Return. + ret(); + + // Unuse. + unuseAfter(); + unuseAfter(); + unuseAfter(); + + // Cleanup; disconnect Vd->Va. + cleanup(); + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86CallAlloc - Init / Cleanup] +// ============================================================================ + +ASMJIT_INLINE void X86CallAlloc::init(X86CallNode* node, X86VarMap* map) { + X86BaseAlloc::init(node, map); + + // Create mask of all registers that will be used to pass function arguments. + _willAlloc = node->_usedArgs; + _willSpill.reset(); +} + +ASMJIT_INLINE void X86CallAlloc::cleanup() { + X86BaseAlloc::cleanup(); +} + +// ============================================================================ +// [asmjit::X86CallAlloc - Plan / Spill / Alloc] +// ============================================================================ + +template +ASMJIT_INLINE void X86CallAlloc::plan() { + uint32_t i; + uint32_t clobbered = _map->_clobberedRegs.get(C); + + uint32_t willAlloc = _willAlloc.get(C); + uint32_t willFree = clobbered & ~willAlloc; + + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks. + for (i = 0; i < count; i++) { + VarAttr* va = &list[i]; + VarData* vd = va->getVd(); + + uint32_t vaFlags = va->getFlags(); + uint32_t regIndex = vd->getRegIndex(); + uint32_t regMask = (regIndex != kInvalidReg) ? IntUtil::mask(regIndex) : 0; + + if ((vaFlags & kVarAttrInReg) != 0) { + // Planning register allocation. First check whether the variable is + // already allocated in register and if it can stay there. Function + // arguments are passed either in a specific register or in stack so + // we care mostly of mandatory registers. + uint32_t inRegs = va->getInRegs(); + + if (inRegs == 0) { + inRegs = va->getAllocableRegs(); + } + + // Optimize situation where the variable has to be allocated in a + // mandatory register, but it's already allocated in register that + // is not clobbered (i.e. it will survive function call). + if ((regMask & inRegs) != 0 || ((regMask & ~clobbered) != 0 && (vaFlags & kVarAttrUnuse) == 0)) { + va->setInRegIndex(regIndex); + va->addFlags(kVarAttrAllocInDone); + addVaDone(C); + } + else { + willFree |= regMask; + } + } + else { + // Memory access - if variable is allocated it has to be freed. + if (regMask != 0) { + willFree |= regMask; + } + else { + va->addFlags(kVarAttrAllocInDone); + addVaDone(C); + } + } + } + + // Occupied registers without 'willFree' registers; contains basically + // all the registers we can use to allocate variables without inRegs + // speficied. + uint32_t occupied = state->_occupied.get(C) & ~willFree; + uint32_t willSpill = 0; + + // Find the best registers for variables that are not allocated yet. Only + // useful for Gp registers used as call operand. + for (i = 0; i < count; i++) { + VarAttr* va = &list[i]; + VarData* vd = va->getVd(); + + uint32_t vaFlags = va->getFlags(); + if ((vaFlags & kVarAttrAllocInDone) != 0 || (vaFlags & kVarAttrInReg) == 0) + continue; + + // All registers except Gp used by call itself must have inRegIndex. + uint32_t m = va->getInRegs(); + if (C != kX86RegClassGp || m) { + ASMJIT_ASSERT(m != 0); + va->setInRegIndex(IntUtil::findFirstBit(m)); + willSpill |= occupied & m; + continue; + } + + m = va->getAllocableRegs() & ~(willAlloc ^ m); + m = guessAlloc(vd, m); + ASMJIT_ASSERT(m != 0); + + uint32_t candidateRegs = m & ~occupied; + if (candidateRegs == 0) { + candidateRegs = m & occupied & ~state->_modified.get(C); + if (candidateRegs == 0) + candidateRegs = m; + } + + if (!(vaFlags & (kVarAttrOutReg | kVarAttrUnuse)) && (candidateRegs & ~clobbered)) + candidateRegs &= ~clobbered; + + uint32_t regIndex = IntUtil::findFirstBit(candidateRegs); + uint32_t regMask = IntUtil::mask(regIndex); + + va->setInRegIndex(regIndex); + va->setInRegs(regMask); + + willAlloc |= regMask; + willSpill |= regMask & occupied; + willFree &= ~regMask; + + occupied |= regMask; + continue; + } + + // Set calculated masks back to the allocator; needed by spill() and alloc(). + _willSpill.set(C, willSpill); + _willAlloc.set(C, willAlloc); +} + +template +ASMJIT_INLINE void X86CallAlloc::spill() { + uint32_t m = _willSpill.get(C); + uint32_t i = static_cast(0) - 1; + + if (m == 0) + return; + + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + // Available registers for decision if move has any benefit over spill. + uint32_t availableRegs = getGaRegs(C) & ~(state->_occupied.get(C) | m | _willAlloc.get(C)); + + do { + // We always advance one more to destroy the bit that we have found. + uint32_t bitIndex = IntUtil::findFirstBit(m) + 1; + + i += bitIndex; + m >>= bitIndex; + + VarData* vd = sVars[i]; + ASMJIT_ASSERT(vd != NULL); + ASMJIT_ASSERT(vd->getVa() == NULL); + + if (vd->isModified() && availableRegs) { + uint32_t m = guessSpill(vd, availableRegs); + + if (m != 0) { + uint32_t regIndex = IntUtil::findFirstBit(m); + uint32_t regMask = IntUtil::mask(regIndex); + + _context->move(vd, regIndex); + availableRegs ^= regMask; + continue; + } + } + + _context->spill(vd); + } while (m != 0); +} + +template +ASMJIT_INLINE void X86CallAlloc::alloc() { + if (isVaDone(C)) + return; + + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + uint32_t i; + bool didWork; + + do { + didWork = false; + for (i = 0; i < count; i++) { + VarAttr* aVa = &list[i]; + VarData* aVd = aVa->getVd(); + + if ((aVa->getFlags() & (kVarAttrInReg | kVarAttrAllocInDone)) != kVarAttrInReg) + continue; + + uint32_t aIndex = aVd->getRegIndex(); + uint32_t bIndex = aVa->getInRegIndex(); + + // Shouldn't be the same. + ASMJIT_ASSERT(aIndex != bIndex); + + VarData* bVd = getState()->getListByClass(C)[bIndex]; + if (bVd != NULL) { + VarAttr* bVa = bVd->getVa(); + + // Gp registers only - Swap two registers if we can solve two + // allocation tasks by a single 'xchg' instruction, swapping + // two registers required by the instruction/node or one register + // required with another non-required. + if (C == kX86RegClassGp) { + _context->swapGp(aVd, bVd); + + aVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + + // Doublehit, two registers allocated by a single swap. + if (bVa != NULL && bVa->getInRegIndex() == aIndex) { + bVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + } + + didWork = true; + continue; + } + } + else if (aIndex != kInvalidReg) { + _context->move(aVd, bIndex); + + aVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + + didWork = true; + continue; + } + else { + _context->alloc(aVd, bIndex); + + aVa->addFlags(kVarAttrAllocInDone); + addVaDone(C); + + didWork = true; + continue; + } + } + } while (didWork); +} + +// ============================================================================ +// [asmjit::X86CallAlloc - AllocImmsOnStack] +// ============================================================================ + +ASMJIT_INLINE void X86CallAlloc::allocImmsOnStack() { + X86CallNode* node = getNode(); + X86FuncDecl* decl = node->getDecl(); + + uint32_t argCount = decl->getArgCount(); + Operand* argList = node->_args; + + for (uint32_t i = 0; i < argCount; i++) { + Operand& op = argList[i]; + + if (!op.isImm()) + continue; + + const Imm& imm = static_cast(op); + const FuncInOut& arg = decl->getArg(i); + uint32_t varType = arg.getVarType(); + + if (arg.hasStackOffset()) { + X86Mem dst = x86::ptr(_context->_zsp, -static_cast(_context->getRegSize()) + arg.getStackOffset()); + _context->emitMoveImmOnStack(varType, &dst, &imm); + } + else { + _context->emitMoveImmToReg(varType, arg.getRegIndex(), &imm); + } + } +} + +// ============================================================================ +// [asmjit::X86CallAlloc - Duplicate] +// ============================================================================ + +template +ASMJIT_INLINE void X86CallAlloc::duplicate() { + VarAttr* list = getVaListByClass(C); + uint32_t count = getVaCountByClass(C); + + for (uint32_t i = 0; i < count; i++) { + VarAttr* va = &list[i]; + if (!va->hasFlag(kVarAttrInReg)) + continue; + + uint32_t inRegs = va->getInRegs(); + if (!inRegs) + continue; + + VarData* vd = va->getVd(); + uint32_t regIndex = vd->getRegIndex(); + + ASMJIT_ASSERT(regIndex != kInvalidReg); + + inRegs &= ~IntUtil::mask(regIndex); + if (!inRegs) + continue; + + for (uint32_t dupIndex = 0; inRegs != 0; dupIndex++, inRegs >>= 1) { + if (inRegs & 0x1) { + _context->emitMove(vd, dupIndex, regIndex, "Duplicate"); + _context->_clobberedRegs.add(C, IntUtil::mask(dupIndex)); + } + } + } +} + +// ============================================================================ +// [asmjit::X86CallAlloc - GuessAlloc / GuessSpill] +// ============================================================================ + +template +ASMJIT_INLINE uint32_t X86CallAlloc::guessAlloc(VarData* vd, uint32_t allocableRegs) { + ASMJIT_ASSERT(allocableRegs != 0); + + // Stop now if there is only one bit (register) set in 'allocableRegs' mask. + if (IntUtil::isPowerOf2(allocableRegs)) + return allocableRegs; + + uint32_t i; + uint32_t safeRegs = allocableRegs; + uint32_t maxLookAhead = _compiler->getMaxLookAhead(); + + // Look ahead and calculate mask of special registers on both - input/output. + Node* node = _node; + for (i = 0; i < maxLookAhead; i++) { + // Stop on 'RetNode' and 'EndNode. + if (node->hasFlag(kNodeFlagIsRet)) + break; + + // Stop on conditional jump, we don't follow them. + if (node->hasFlag(kNodeFlagIsJcc)) + break; + + // Advance on non-conditional jump. + if (node->hasFlag(kNodeFlagIsJmp)) + node = static_cast(node)->getTarget(); + + node = node->getNext(); + ASMJIT_ASSERT(node != NULL); + + X86VarMap* map = node->getMap(); + if (map != NULL) { + VarAttr* va = map->findVaByClass(C, vd); + if (va != NULL) { + uint32_t inRegs = va->getInRegs(); + if (inRegs != 0) { + safeRegs = allocableRegs; + allocableRegs &= inRegs; + + if (allocableRegs == 0) + goto _UseSafeRegs; + else + return allocableRegs; + } + } + + safeRegs = allocableRegs; + allocableRegs &= ~(map->_inRegs.get(C) | map->_outRegs.get(C) | map->_clobberedRegs.get(C)); + + if (allocableRegs == 0) + break; + } + } + +_UseSafeRegs: + return safeRegs; +} + +template +ASMJIT_INLINE uint32_t X86CallAlloc::guessSpill(VarData* vd, uint32_t allocableRegs) { + ASMJIT_ASSERT(allocableRegs != 0); + + return 0; +} + +// ============================================================================ +// [asmjit::X86CallAlloc - Save] +// ============================================================================ + +template +ASMJIT_INLINE void X86CallAlloc::save() { + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + uint32_t i; + uint32_t affected = _map->_clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C); + + for (i = 0; affected != 0; i++, affected >>= 1) { + if (affected & 0x1) { + VarData* vd = sVars[i]; + ASMJIT_ASSERT(vd != NULL); + ASMJIT_ASSERT(vd->isModified()); + + VarAttr* va = vd->getVa(); + if (va == NULL || (va->getFlags() & (kVarAttrOutReg | kVarAttrUnuse)) == 0) { + _context->save(vd); + } + } + } +} + +// ============================================================================ +// [asmjit::X86CallAlloc - Clobber] +// ============================================================================ + +template +ASMJIT_INLINE void X86CallAlloc::clobber() { + X86VarState* state = getState(); + VarData** sVars = state->getListByClass(C); + + uint32_t i; + uint32_t affected = _map->_clobberedRegs.get(C) & state->_occupied.get(C); + + for (i = 0; affected != 0; i++, affected >>= 1) { + if (affected & 0x1) { + VarData* vd = sVars[i]; + ASMJIT_ASSERT(vd != NULL); + + VarAttr* va = vd->getVa(); + uint32_t vdState = kVarStateUnused; + + if (!vd->isModified() || (va != NULL && (va->getFlags() & (kVarAttrOutAll | kVarAttrUnuse)) != 0)) { + vdState = kVarStateMem; + } + + _context->unuse(vd, vdState); + } + } +} + +// ============================================================================ +// [asmjit::X86CallAlloc - Ret] +// ============================================================================ + +ASMJIT_INLINE void X86CallAlloc::ret() { + X86CallNode* node = getNode(); + X86FuncDecl* decl = node->getDecl(); + + uint32_t i; + Operand* retList = node->_ret; + + for (i = 0; i < 2; i++) { + const FuncInOut& ret = decl->getRet(i); + Operand* op = &retList[i]; + + if (!ret.hasRegIndex() || !op->isVar()) + continue; + + VarData* vd = _compiler->getVdById(op->getId()); + uint32_t regIndex = ret.getRegIndex(); + + switch (vd->getClass()) { + case kX86RegClassGp: + if (vd->getRegIndex() != kInvalidReg) + _context->unuse(vd); + _context->attach(vd, regIndex, true); + break; + case kX86RegClassMm: + if (vd->getRegIndex() != kInvalidReg) + _context->unuse(vd); + _context->attach(vd, regIndex, true); + break; + case kX86RegClassXyz: + if (vd->getRegIndex() != kInvalidReg) + _context->unuse(vd); + _context->attach(vd, regIndex, true); + break; + } + } +} + +// ============================================================================ +// [asmjit::X86Context - TranslateOperands] +// ============================================================================ + +//! \internal +static Error X86Context_translateOperands(X86Context* self, Operand* opList, uint32_t opCount) { + X86Compiler* compiler = self->getCompiler(); + const X86VarInfo* varInfo = _x86VarInfo; + + uint32_t hasGpdBase = compiler->getRegSize() == 4; + + // Translate variables into registers. + for (uint32_t i = 0; i < opCount; i++) { + Operand* op = &opList[i]; + + if (op->isVar()) { + VarData* vd = compiler->getVdById(op->getId()); + ASMJIT_ASSERT(vd != NULL); + ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); + + op->_vreg.op = kOperandTypeReg; + op->_vreg.index = vd->getRegIndex(); + } + else if (op->isMem()) { + X86Mem* m = static_cast(op); + + if (m->isBaseIndexType() && OperandUtil::isVarId(m->getBase())) { + VarData* vd = compiler->getVdById(m->getBase()); + + if (m->getMemType() == kMemTypeBaseIndex) { + ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); + op->_vmem.base = vd->getRegIndex(); + } + else { + if (!vd->isMemArg()) + self->getVarCell(vd); + + // Offset will be patched later by X86Context_patchFuncMem(). + m->setGpdBase(hasGpdBase); + m->adjust(vd->isMemArg() ? self->_argActualDisp : self->_varActualDisp); + } + } + + if (OperandUtil::isVarId(m->getIndex())) { + VarData* vd = compiler->getVdById(m->getIndex()); + ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); + ASMJIT_ASSERT(vd->getRegIndex() != kX86RegIndexR12); + op->_vmem.index = vd->getRegIndex(); + } + } + } + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Context - TranslatePrologEpilog] +// ============================================================================ + +//! \internal +static Error X86Context_initFunc(X86Context* self, X86FuncNode* func) { + X86Compiler* compiler = self->getCompiler(); + X86FuncDecl* decl = func->getDecl(); + + X86RegMask& clobberedRegs = self->_clobberedRegs; + uint32_t regSize = compiler->getRegSize(); + + // Setup "Save-Restore" registers. + func->_saveRestoreRegs.set(kX86RegClassGp , clobberedRegs.get(kX86RegClassGp ) & decl->getPreserved(kX86RegClassGp )); + func->_saveRestoreRegs.set(kX86RegClassFp , 0); + func->_saveRestoreRegs.set(kX86RegClassMm , clobberedRegs.get(kX86RegClassMm ) & decl->getPreserved(kX86RegClassMm )); + func->_saveRestoreRegs.set(kX86RegClassXyz, clobberedRegs.get(kX86RegClassXyz) & decl->getPreserved(kX86RegClassXyz)); + + ASMJIT_ASSERT(!func->_saveRestoreRegs.has(kX86RegClassGp, IntUtil::mask(kX86RegIndexSp))); + + // Setup required stack alignment and kFuncFlagIsStackMisaligned. + { + uint32_t requiredStackAlignment = IntUtil::iMax(self->_memMaxAlign, self->getRegSize()); + + if (requiredStackAlignment < 16) { + // Require 16-byte alignment if 8-byte vars are used. + if (self->_mem8ByteVarsUsed) + requiredStackAlignment = 16; + else if (func->_saveRestoreRegs.get(kX86RegClassMm) || func->_saveRestoreRegs.get(kX86RegClassXyz)) + requiredStackAlignment = 16; + else if (IntUtil::inInterval(func->getRequiredStackAlignment(), 8, 16)) + requiredStackAlignment = 16; + } + + if (func->getRequiredStackAlignment() < requiredStackAlignment) + func->setRequiredStackAlignment(requiredStackAlignment); + + func->updateRequiredStackAlignment(); + } + + // Adjust stack pointer if function is caller. + if (func->isCaller()) { + func->addFuncFlags(kFuncFlagIsStackAdjusted); + } + + // Adjust stack pointer if manual stack alignment is needed. + if (func->isStackMisaligned() && func->isNaked()) { + // Get a memory cell where the original stack frame will be stored. + MemCell* cell = self->_newStackCell(regSize, regSize); + if (cell == NULL) + return self->getError(); + + func->addFuncFlags(kFuncFlagIsStackAdjusted); + self->_stackFrameCell = cell; + + if (decl->getArgStackSize() > 0) { + func->addFuncFlags(kX86FuncFlagMoveArgs); + func->setExtraStackSize(decl->getArgStackSize()); + } + + // Get temporary register which will be used to align the stack frame. + uint32_t fRegMask = IntUtil::bits(self->_regCount.getGp()); + uint32_t stackFrameCopyRegs; + + fRegMask &= ~(decl->getUsed(kX86RegClassGp) | IntUtil::mask(kX86RegIndexSp)); + stackFrameCopyRegs = fRegMask; + + // Try to remove modified registers from the mask. + uint32_t tRegMask = fRegMask & ~self->getClobberedRegs(kX86RegClassGp); + if (tRegMask != 0) + fRegMask = tRegMask; + + // Try to remove preserved registers from the mask. + tRegMask = fRegMask & ~decl->getPreserved(kX86RegClassGp); + if (tRegMask != 0) + fRegMask = tRegMask; + + ASMJIT_ASSERT(fRegMask != 0); + + uint32_t fRegIndex = IntUtil::findFirstBit(fRegMask); + func->_stackFrameRegIndex = static_cast(fRegIndex); + + // We have to save the register on the stack (it will be the part of prolog + // and epilog), however we shouldn't save it twice, so we will remove it + // from '_saveRestoreRegs' in case that it is preserved. + fRegMask = IntUtil::mask(fRegIndex); + if ((fRegMask & decl->getPreserved(kX86RegClassGp)) != 0) { + func->_saveRestoreRegs.del(kX86RegClassGp, fRegMask); + func->_isStackFrameRegPreserved = true; + } + + if (func->hasFuncFlag(kX86FuncFlagMoveArgs)) { + uint32_t maxRegs = (func->getArgStackSize() + regSize - 1) / regSize; + stackFrameCopyRegs &= ~fRegMask; + + tRegMask = stackFrameCopyRegs & self->getClobberedRegs(kX86RegClassGp); + uint32_t tRegCnt = IntUtil::bitCount(tRegMask); + + if (tRegCnt > 1 || (tRegCnt > 0 && tRegCnt <= maxRegs)) + stackFrameCopyRegs = tRegMask; + else + stackFrameCopyRegs = IntUtil::keepNOnesFromRight(stackFrameCopyRegs, IntUtil::iMin(maxRegs, 2)); + + func->_saveRestoreRegs.add(kX86RegClassGp, stackFrameCopyRegs & decl->getPreserved(kX86RegClassGp)); + IntUtil::indexNOnesFromRight(func->_stackFrameCopyGpIndex, stackFrameCopyRegs, maxRegs); + } + } + // If function is not naked we generate standard "EBP/RBP" stack frame. + else if (!func->isNaked()) { + uint32_t fRegIndex = kX86RegIndexBp; + + func->_stackFrameRegIndex = static_cast(fRegIndex); + func->_isStackFrameRegPreserved = true; + } + + ASMJIT_PROPAGATE_ERROR(self->resolveCellOffsets()); + + // Adjust stack pointer if requested memory can't fit into "Red Zone" or "Spill Zone". + if (self->_memAllTotal > IntUtil::iMax(func->getRedZoneSize(), func->getSpillZoneSize())) { + func->addFuncFlags(kFuncFlagIsStackAdjusted); + } + + // Setup stack size used to save preserved registers. + { + uint32_t memGpSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassGp )) * regSize; + uint32_t memMmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassMm )) * 8; + uint32_t memXmmSize = IntUtil::bitCount(func->_saveRestoreRegs.get(kX86RegClassXyz)) * 16; + + if (func->hasFuncFlag(kX86FuncFlagPushPop)) { + func->_pushPopStackSize = memGpSize; + func->_moveStackSize = memXmmSize + IntUtil::alignTo(memMmSize, 16); + } + else { + func->_pushPopStackSize = 0; + func->_moveStackSize = memXmmSize + IntUtil::alignTo(memMmSize + memGpSize, 16); + } + } + + // Setup adjusted stack size. + if (func->isStackMisaligned()) { + func->_alignStackSize = 0; + } + else { + // If function is aligned, the RETURN address is stored in the aligned + // [ZSP - PtrSize] which makes current ZSP unaligned. + int32_t v = static_cast(regSize); + + // If we have to store function frame pointer we have to count it as well, + // because it is the first thing pushed on the stack. + if (func->hasStackFrameReg() && func->isStackFrameRegPreserved()) + v += regSize; + + // Count push/pop sequence. + v += func->getPushPopStackSize(); + + // Calculate the final offset to keep stack alignment. + func->_alignStackSize = IntUtil::deltaTo(v, func->getRequiredStackAlignment()); + } + + // Memory stack size. + func->_memStackSize = self->_memAllTotal; + func->_alignedMemStackSize = IntUtil::alignTo(func->_memStackSize, func->_requiredStackAlignment); + + if (func->isNaked()) { + self->_argBaseReg = kX86RegIndexSp; + + if (func->isStackAdjusted()) { + if (func->isStackMisaligned()) { + self->_argBaseOffset = static_cast( + func->getCallStackSize() + + func->getAlignedMemStackSize() + + func->getMoveStackSize() + + func->getAlignStackSize()); + self->_argBaseOffset -= regSize; + } + else { + self->_argBaseOffset = static_cast( + func->getCallStackSize() + + func->getAlignedMemStackSize() + + func->getMoveStackSize() + + func->getPushPopStackSize() + + func->getExtraStackSize() + + func->getAlignStackSize()); + } + } + else { + self->_argBaseOffset = func->getPushPopStackSize(); + } + } + else { + self->_argBaseReg = kX86RegIndexBp; + // Caused by "push zbp". + self->_argBaseOffset = regSize; + } + + self->_varBaseReg = kX86RegIndexSp; + self->_varBaseOffset = func->getCallStackSize(); + + if (!func->isStackAdjusted()) { + self->_varBaseOffset = -static_cast( + func->_alignStackSize + + func->_alignedMemStackSize + + func->_moveStackSize); + } + + return kErrorOk; +} + +//! \internal +static Error X86Context_patchFuncMem(X86Context* self, X86FuncNode* func, Node* stop) { + X86Compiler* compiler = self->getCompiler(); + Node* node = func; + + do { + if (node->getType() == kNodeTypeInst) { + InstNode* iNode = static_cast(node); + + if (iNode->hasMemOp()) { + X86Mem* m = iNode->getMemOp(); + + if (m->getMemType() == kMemTypeStackIndex && OperandUtil::isVarId(m->getBase())) { + VarData* vd = compiler->getVdById(m->getBase()); + ASMJIT_ASSERT(vd != NULL); + + if (vd->isMemArg()) { + m->_vmem.base = self->_argBaseReg; + m->_vmem.displacement += vd->getMemOffset(); + m->_vmem.displacement += self->_argBaseOffset; + } + else { + MemCell* cell = vd->getMemCell(); + ASMJIT_ASSERT(cell != NULL); + + m->_vmem.base = self->_varBaseReg; + m->_vmem.displacement += cell->getOffset(); + m->_vmem.displacement += self->_varBaseOffset; + } + } + } + } + + node = node->getNext(); + } while (node != stop); + + return kErrorOk; +} + +//! \internal +static Error X86Context_translatePrologEpilog(X86Context* self, X86FuncNode* func) { + X86Compiler* compiler = self->getCompiler(); + X86FuncDecl* decl = func->getDecl(); + + uint32_t regSize = compiler->getRegSize(); + + int32_t stackSize = static_cast( + func->getAlignStackSize() + + func->getCallStackSize() + + func->getAlignedMemStackSize() + + func->getMoveStackSize() + + func->getExtraStackSize()); + int32_t stackAlignment = func->getRequiredStackAlignment(); + + int32_t stackBase; + int32_t stackPtr; + + if (func->isStackAdjusted()) { + stackBase = static_cast( + func->getCallStackSize() + + func->getAlignedMemStackSize()); + } + else { + stackBase = -static_cast( + func->getAlignedMemStackSize() + + func->getAlignStackSize() + + func->getExtraStackSize()); + } + + uint32_t i, mask; + uint32_t regsGp = func->getSaveRestoreRegs(kX86RegClassGp ); + uint32_t regsMm = func->getSaveRestoreRegs(kX86RegClassMm ); + uint32_t regsXmm = func->getSaveRestoreRegs(kX86RegClassXyz); + + bool earlyPushPop = false; + bool useLeaEpilog = false; + + X86GpReg gpReg(self->_zsp); + X86GpReg fpReg(self->_zbp); + + X86Mem fpOffset; + + // -------------------------------------------------------------------------- + // [Prolog] + // -------------------------------------------------------------------------- + + compiler->_setCursor(func->getEntryNode()); + + // Entry. + if (func->isNaked()) { + if (func->isStackMisaligned()) { + fpReg.setIndex(func->getStackFrameRegIndex()); + fpOffset = x86::ptr(self->_zsp, static_cast(self->_stackFrameCell->getOffset())); + + earlyPushPop = func->hasFuncFlag(kX86FuncFlagPushPop); + if (earlyPushPop) + self->emitPushSequence(regsGp); + + if (func->isStackFrameRegPreserved()) + compiler->emit(kX86InstIdPush, fpReg); + + compiler->emit(kX86InstIdMov, fpReg, self->_zsp); + } + } + else { + compiler->emit(kX86InstIdPush, fpReg); + compiler->emit(kX86InstIdMov, fpReg, self->_zsp); + } + + if (func->hasFuncFlag(kX86FuncFlagPushPop) && !earlyPushPop) { + self->emitPushSequence(regsGp); + if (func->isStackMisaligned() && regsGp != 0) + useLeaEpilog = true; + } + + // Adjust stack pointer. + if (func->isStackAdjusted()) { + stackBase = static_cast(func->getAlignedMemStackSize() + func->getCallStackSize()); + + if (stackSize) + compiler->emit(kX86InstIdSub, self->_zsp, stackSize); + + if (func->isStackMisaligned()) + compiler->emit(kX86InstIdAnd, self->_zsp, -stackAlignment); + + if (func->isStackMisaligned() && func->isNaked()) + compiler->emit(kX86InstIdMov, fpOffset, fpReg); + } + else { + stackBase = -static_cast(func->getAlignStackSize() + func->getMoveStackSize()); + } + + // Save Xmm/Mm/Gp (Mov). + stackPtr = stackBase; + for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) { + if (mask & 0x1) { + compiler->emit(kX86InstIdMovaps, x86::oword_ptr(self->_zsp, stackPtr), x86::xmm(i)); + stackPtr += 16; + } + } + + for (i = 0, mask = regsMm; mask != 0; i++, mask >>= 1) { + if (mask & 0x1) { + compiler->emit(kX86InstIdMovq, x86::qword_ptr(self->_zsp, stackPtr), x86::mm(i)); + stackPtr += 8; + } + } + + if (!func->hasFuncFlag(kX86FuncFlagPushPop)) { + for (i = 0, mask = regsGp; mask != 0; i++, mask >>= 1) { + if (mask & 0x1) { + compiler->emit(kX86InstIdMov, x86::ptr(self->_zsp, stackPtr), gpReg.setIndex(i)); + stackPtr += regSize; + } + } + } + + // -------------------------------------------------------------------------- + // [Move-Args] + // -------------------------------------------------------------------------- + + if (func->hasFuncFlag(kX86FuncFlagMoveArgs)) { + uint32_t argStackPos = 0; + uint32_t argStackSize = decl->getArgStackSize(); + + uint32_t moveIndex = 0; + uint32_t moveCount = (argStackSize + regSize - 1) / regSize; + + X86GpReg r[8]; + uint32_t numRegs = 0; + + for (i = 0; i < 6; i++) + if (func->_stackFrameCopyGpIndex[i] != kInvalidReg) + r[numRegs++] = gpReg.setIndex(func->_stackFrameCopyGpIndex[i]); + + int32_t dSrc = func->getPushPopStackSize() + regSize; + int32_t dDst = func->getAlignStackSize() + + func->getCallStackSize() + + func->getAlignedMemStackSize() + + func->getMoveStackSize(); + + if (func->isStackFrameRegPreserved()) + dSrc += regSize; + + X86Mem mSrc = x86::ptr(fpReg, dSrc); + X86Mem mDst = x86::ptr(self->_zsp, dDst); + + while (moveIndex < moveCount) { + uint32_t numMovs = IntUtil::iMin(moveCount - moveIndex, numRegs); + + for (i = 0; i < numMovs; i++) + compiler->emit(kX86InstIdMov, r[i], mSrc.adjusted((moveIndex + i) * regSize)); + for (i = 0; i < numMovs; i++) + compiler->emit(kX86InstIdMov, mDst.adjusted((moveIndex + i) * regSize), r[i]); + + argStackPos += numMovs * regSize; + moveIndex += numMovs; + } + } + + // -------------------------------------------------------------------------- + // [Epilog] + // -------------------------------------------------------------------------- + + compiler->_setCursor(func->getExitNode()); + + // Restore Xmm/Mm/Gp (Mov). + stackPtr = stackBase; + for (i = 0, mask = regsXmm; mask != 0; i++, mask >>= 1) { + if (mask & 0x1) { + compiler->emit(kX86InstIdMovaps, x86::xmm(i), x86::oword_ptr(self->_zsp, stackPtr)); + stackPtr += 16; + } + } + + for (i = 0, mask = regsMm; mask != 0; i++, mask >>= 1) { + if (mask & 0x1) { + compiler->emit(kX86InstIdMovq, x86::mm(i), x86::qword_ptr(self->_zsp, stackPtr)); + stackPtr += 8; + } + } + + if (!func->hasFuncFlag(kX86FuncFlagPushPop)) { + for (i = 0, mask = regsGp; mask != 0; i++, mask >>= 1) { + if (mask & 0x1) { + compiler->emit(kX86InstIdMov, gpReg.setIndex(i), x86::ptr(self->_zsp, stackPtr)); + stackPtr += regSize; + } + } + } + + // Adjust stack. + if (useLeaEpilog) { + compiler->emit(kX86InstIdLea, self->_zsp, x86::ptr(fpReg, -static_cast(func->getPushPopStackSize()))); + } + else if (!func->isStackMisaligned()) { + if (func->isStackAdjusted() && stackSize != 0) + compiler->emit(kX86InstIdAdd, self->_zsp, stackSize); + } + + // Restore Gp (Push/Pop). + if (func->hasFuncFlag(kX86FuncFlagPushPop) && !earlyPushPop) + self->emitPopSequence(regsGp); + + // Emms. + if (func->hasFuncFlag(kX86FuncFlagEmms)) + compiler->emit(kX86InstIdEmms); + + // MFence/SFence/LFence. + if (func->hasFuncFlag(kX86FuncFlagSFence) & func->hasFuncFlag(kX86FuncFlagLFence)) + compiler->emit(kX86InstIdMfence); + else if (func->hasFuncFlag(kX86FuncFlagSFence)) + compiler->emit(kX86InstIdSfence); + else if (func->hasFuncFlag(kX86FuncFlagLFence)) + compiler->emit(kX86InstIdLfence); + + // Leave. + if (func->isNaked()) { + if (func->isStackMisaligned()) { + compiler->emit(kX86InstIdMov, self->_zsp, fpOffset); + + if (func->isStackFrameRegPreserved()) + compiler->emit(kX86InstIdPop, fpReg); + + if (earlyPushPop) + self->emitPopSequence(regsGp); + } + } + else { + if (useLeaEpilog) { + compiler->emit(kX86InstIdPop, fpReg); + } + else if (func->hasFuncFlag(kX86FuncFlagLeave)) { + compiler->emit(kX86InstIdLeave); + } + else { + compiler->emit(kX86InstIdMov, self->_zsp, fpReg); + compiler->emit(kX86InstIdPop, fpReg); + } + } + + // Emit return. + if (decl->getCalleePopsStack()) + compiler->emit(kX86InstIdRet, static_cast(decl->getArgStackSize())); + else + compiler->emit(kX86InstIdRet); + + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Context - Translate - Jump] +// ============================================================================ + +//! \internal +static void X86Context_translateJump(X86Context* self, JumpNode* jNode, TargetNode* jTarget) { + X86Compiler* compiler = self->getCompiler(); + Node* extNode = self->getExtraBlock(); + + // TODO: [COMPILER] State Change. + compiler->_setCursor(extNode); + self->switchState(jTarget->getState()); + + // If one or more instruction has been added during switchState() it will be + // moved at the end of the function body. + if (compiler->getCursor() != extNode) { + TargetNode* jTrampolineTarget = compiler->newTarget(); + + // Add the jump to the target. + compiler->jmp(jTarget->getLabel()); + + // Add the trampoline-label we jump to change the state. + extNode = compiler->setCursor(extNode); + compiler->addNode(jTrampolineTarget); + + // Finally, patch the jump target. + ASMJIT_ASSERT(jNode->getOpCount() > 0); + jNode->_opList[0] = jTrampolineTarget->getLabel(); + jNode->_target = jTrampolineTarget; + } + + // Store the extNode and load the state back. + self->setExtraBlock(extNode); + self->loadState(jNode->_state); +} + +// ============================================================================ +// [asmjit::X86Context - Translate - Ret] +// ============================================================================ + +static Error X86Context_translateRet(X86Context* self, RetNode* rNode, TargetNode* exitTarget) { + Node* node = rNode->getNext(); + + while (node != NULL) { + switch (node->getType()) { + // If we have found an exit label we just return, there is no need to + // emit jump to that. + case kNodeTypeTarget: + if (static_cast(node) == exitTarget) + return kErrorOk; + goto _EmitRet; + + case kNodeTypeEmbed: + case kNodeTypeInst: + case kNodeTypeCall: + case kNodeTypeRet: + goto _EmitRet; + + // Continue iterating. + case kNodeTypeComment: + case kNodeTypeAlign: + case kNodeTypeHint: + break; + + // Invalid node to be here. + case kNodeTypeFunc: + return self->getCompiler()->setError(kErrorInvalidState); + + // We can't go forward from here. + case kNodeTypeEnd: + return kErrorOk; + } + + node = node->getNext(); + } + +_EmitRet: + { + X86Compiler* compiler = self->getCompiler(); + + compiler->_setCursor(rNode); + compiler->jmp(exitTarget->getLabel()); + } + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Context - Translate - Func] +// ============================================================================ + +Error X86Context::translate() { + ASMJIT_TLOG("[Translate] === Begin ===\n"); + + X86Compiler* compiler = getCompiler(); + X86FuncNode* func = getFunc(); + + // Register allocator contexts. + X86VarAlloc vAlloc(this); + X86CallAlloc cAlloc(this); + + // Flow. + Node* node_ = func; + Node* next = NULL; + Node* stop = getStop(); + + PodList::Link* jLink = _jccList.getFirst(); + + for (;;) { + while (node_->isTranslated()) { + // Switch state if we went to the already translated node. + if (node_->getType() == kNodeTypeTarget) { + TargetNode* node = static_cast(node_); + compiler->_setCursor(node->getPrev()); + switchState(node->getState()); + } + +_NextGroup: + if (jLink == NULL) { + goto _Done; + } + else { + node_ = jLink->getValue(); + jLink = jLink->getNext(); + + Node* jFlow = X86Context_getOppositeJccFlow(static_cast(node_)); + loadState(node_->getState()); + + if (jFlow->getState()) { + X86Context_translateJump(this, + static_cast(node_), + static_cast(jFlow)); + + node_ = jFlow; + if (node_->isTranslated()) + goto _NextGroup; + } + else { + node_ = jFlow; + } + + break; + } + } + + next = node_->getNext(); + node_->addFlags(kNodeFlagIsTranslated); + + ASMJIT_TSEC({ + X86Context_traceNode(this, node_); + }); + + switch (node_->getType()) { + // ---------------------------------------------------------------------- + // [Align / Embed] + // ---------------------------------------------------------------------- + + case kNodeTypeAlign: + case kNodeTypeEmbed: + break; + + // ---------------------------------------------------------------------- + // [Target] + // ---------------------------------------------------------------------- + + case kNodeTypeTarget: { + TargetNode* node = static_cast(node_); + ASMJIT_ASSERT(!node->hasState()); + node->setState(saveState()); + break; + } + + // ---------------------------------------------------------------------- + // [Inst/Call/SArg/Ret] + // ---------------------------------------------------------------------- + + case kNodeTypeInst: + case kNodeTypeCall: + case kNodeTypeSArg: + // Update VarAttr's unuse flags based on liveness of the next node. + if (!node_->isJcc()) { + X86VarMap* map = static_cast(node_->getMap()); + VarBits* liveness = next->getLiveness(); + + if (map != NULL && liveness != NULL) { + VarAttr* vaList = map->getVaList(); + uint32_t vaCount = map->getVaCount(); + + for (uint32_t i = 0; i < vaCount; i++) { + VarAttr* va = &vaList[i]; + VarData* vd = va->getVd(); + + if (!liveness->getBit(vd->getContextId())) + va->addFlags(kVarAttrUnuse); + } + } + } + + if (node_->getType() == kNodeTypeCall) { + ASMJIT_PROPAGATE_ERROR(cAlloc.run(static_cast(node_))); + break; + } + // ... Fall through ... + + case kNodeTypeHint: + case kNodeTypeRet: { + ASMJIT_PROPAGATE_ERROR(vAlloc.run(node_)); + + // Handle conditional/unconditional jump. + if (node_->isJmpOrJcc()) { + JumpNode* node = static_cast(node_); + TargetNode* jTarget = node->getTarget(); + + if (node->isJmp()) { + if (jTarget->hasState()) { + compiler->_setCursor(node->getPrev()); + switchState(jTarget->getState()); + + goto _NextGroup; + } + else { + next = jTarget; + } + } + else { + Node* jNext = node->getNext(); + + if (jTarget->isTranslated()) { + if (jNext->isTranslated()) { + ASMJIT_ASSERT(jNext->getType() == kNodeTypeTarget); + // TODO: [COMPILER] State - Do intersection of two states if possible. + } + + VarState* savedState = saveState(); + node->setState(savedState); + + X86Context_translateJump(this, node, jTarget); + next = jNext; + } + else if (jNext->isTranslated()) { + ASMJIT_ASSERT(jNext->getType() == kNodeTypeTarget); + + VarState* savedState = saveState(); + node->setState(savedState); + + compiler->_setCursor(node); + switchState(static_cast(jNext)->getState()); + + next = jTarget; + } + else { + node->setState(saveState()); + next = X86Context_getJccFlow(node); + } + } + } + else if (node_->isRet()) { + ASMJIT_PROPAGATE_ERROR( + X86Context_translateRet(this, static_cast(node_), func->getExitNode())); + } + break; + } + + // ---------------------------------------------------------------------- + // [Func] + // ---------------------------------------------------------------------- + + case kNodeTypeFunc: { + ASMJIT_ASSERT(node_ == func); + + X86FuncDecl* decl = func->getDecl(); + X86VarMap* map = func->getMap(); + + if (map != NULL) { + uint32_t i; + uint32_t argCount = func->_x86Decl.getArgCount(); + + for (i = 0; i < argCount; i++) { + const FuncInOut& arg = decl->getArg(i); + + VarData* vd = func->getArg(i); + VarAttr* va = map->findVa(vd); + ASMJIT_ASSERT(va != NULL); + + if (va->getFlags() & kVarAttrUnuse) + continue; + + uint32_t regIndex = va->getOutRegIndex(); + if (regIndex != kInvalidReg && (va->getFlags() & kVarAttrOutConv) == 0) { + switch (vd->getClass()) { + case kX86RegClassGp : attach(vd, regIndex, true); break; + case kX86RegClassMm : attach(vd, regIndex, true); break; + case kX86RegClassXyz: attach(vd, regIndex, true); break; + } + } + else if (va->hasFlag(kVarAttrOutConv)) { + // TODO: [COMPILER] Function Argument Conversion. + ASMJIT_ASSERT(!"Reached"); + } + else { + vd->_isMemArg = true; + vd->setMemOffset(arg.getStackOffset()); + vd->setState(kVarStateMem); + } + } + } + break; + } + + // ---------------------------------------------------------------------- + // [End] + // ---------------------------------------------------------------------- + + case kNodeTypeEnd: { + goto _NextGroup; + } + + default: + break; + } + + if (next == stop) + goto _NextGroup; + node_ = next; + } + +_Done: + ASMJIT_PROPAGATE_ERROR(X86Context_initFunc(this, func)); + ASMJIT_PROPAGATE_ERROR(X86Context_patchFuncMem(this, func, stop)); + ASMJIT_PROPAGATE_ERROR(X86Context_translatePrologEpilog(this, func)); + + ASMJIT_TLOG("[Translate] === Done ===\n\n"); + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Context - Schedule] +// ============================================================================ + +Error X86Context::schedule() { + X86Compiler* compiler = getCompiler(); + X86Scheduler scheduler(compiler, + static_cast(compiler->getRuntime()->getCpuInfo())); + + Node* node_ = getFunc(); + Node* stop = getStop(); + + PodList::Link* jLink = _jccList.getFirst(); + + // -------------------------------------------------------------------------- + // [Loop] + // -------------------------------------------------------------------------- + +_Advance: + while (node_->isScheduled()) { +_NextGroup: + if (jLink == NULL) + goto _Done; + + // We always go to the next instruction in the main loop so we have to + // jump to the `jcc` target here. + node_ = static_cast(jLink->getValue())->getTarget(); + jLink = jLink->getNext(); + } + + // Find interval that can be passed to scheduler. + for (;;) { + Node* schedStart = node_; + + for (;;) { + Node* next = node_->getNext(); + node_->addFlags(kNodeFlagIsScheduled); + + // Shouldn't happen here, investigate if hit. + ASMJIT_ASSERT(node_ != stop); + + uint32_t nodeType = node_->getType(); + if (nodeType != kNodeTypeInst) { + // If we didn't reach any instruction node we simply advance. In this + // case no informative nodes will be removed and everything else just + // skipped. + if (schedStart == node_) { + node_ = next; + if (nodeType == kNodeTypeEnd || nodeType == kNodeTypeRet) + goto _NextGroup; + else + goto _Advance; + } + + // Remove informative nodes if we are in a middle of instruction stream. + // + // TODO: Shouldn't be there an option for this? Maybe it can be useful + // to stop if there is a comment or something. I'm not sure if it's + // good to always remove. + if (node_->isInformative()) { + compiler->removeNode(node_); + node_ = next; + continue; + } + + break; + } + + // Stop if `node_` is `jmp` or `jcc`. + if (node_->isJmpOrJcc()) + break; + + node_ = next; + } + + // If the stream is less than 3 instructions it will not be passed to + // scheduler. + if (schedStart != node_ && + schedStart->getNext() != node_ && + schedStart->getNext() != node_->getPrev()) { + + scheduler.run(schedStart, node_); + } + + // If node is `jmp` we follow it as well. + if (node_->isJmp()) { + node_ = static_cast(node_)->getTarget(); + goto _Advance; + } + + // Handle stop nodes. + { + uint32_t nodeType = node_->getType(); + if (nodeType == kNodeTypeEnd || nodeType == kNodeTypeRet) + goto _NextGroup; + } + + node_ = node_->getNext(); + goto _Advance; + } + +_Done: + return kErrorOk; +} + +// ============================================================================ +// [asmjit::X86Context - Serialize] +// ============================================================================ + +template +static ASMJIT_INLINE Error X86Context_serialize(X86Context* self, X86Assembler* assembler, Node* start, Node* stop) { + Node* node_ = start; + StringBuilder& sb = self->_stringBuilder; + +#if !defined(ASMJIT_DISABLE_LOGGER) + uint32_t vdCount; + uint32_t annotationLength; + + Logger* logger; + + if (LoggingEnabled) { + logger = assembler->getLogger(); + + vdCount = static_cast(self->_contextVd.getLength()); + annotationLength = self->_annotationLength; + } +#endif // !ASMJIT_DISABLE_LOGGER + + // Create labels on Assembler side. + ASMJIT_PROPAGATE_ERROR( + assembler->_registerIndexedLabels(self->getCompiler()->_targetList.getLength())); + + do { +#if !defined(ASMJIT_DISABLE_LOGGER) + if (LoggingEnabled) { + sb.clear(); + + if (node_->getComment()) { + sb.appendString(node_->getComment()); + } + + if (sb.getLength() < annotationLength) + sb.appendChars(' ', annotationLength - sb.getLength()); + + size_t offset = sb.getLength(); + sb.appendChars(' ', vdCount); + + if (node_->hasLiveness()) { + VarBits* liveness = node_->getLiveness(); + X86VarMap* map = static_cast(node_->getMap()); + + uint32_t i; + for (i = 0; i < vdCount; i++) { + if (liveness->getBit(i)) + sb.getData()[offset + i] = '.'; + } + + if (map != NULL) { + uint32_t vaCount = map->getVaCount(); + + for (i = 0; i < vaCount; i++) { + VarAttr* va = map->getVa(i); + VarData* vd = va->getVd(); + + uint32_t flags = va->getFlags(); + char c = 'u'; + + if ( (flags & kVarAttrInAll) && !(flags & kVarAttrOutAll)) c = 'r'; + if (!(flags & kVarAttrInAll) && (flags & kVarAttrOutAll)) c = 'w'; + if ( (flags & kVarAttrInAll) && (flags & kVarAttrOutAll)) c = 'x'; + + if ((flags & kVarAttrUnuse)) + c -= 'a' - 'A'; + + sb.getData()[offset + vd->getContextId()] = c; + } + } + } + + assembler->_comment = sb.getData(); + } +#endif // !ASMJIT_DISABLE_LOGGER + + switch (node_->getType()) { + case kNodeTypeAlign: { + AlignNode* node = static_cast(node_); + assembler->align(node->getMode(), node->getOffset()); + break; + } + + case kNodeTypeEmbed: { + EmbedNode* node = static_cast(node_); + assembler->embed(node->getData(), node->getSize()); + break; + } + + case kNodeTypeComment: { + CommentNode* node = static_cast(node_); + +#if !defined(ASMJIT_DISABLE_LOGGER) + if (LoggingEnabled) + logger->logFormat(kLoggerStyleComment, + "%s; %s\n", logger->getIndentation(), node->getComment()); +#endif // !ASMJIT_DISABLE_LOGGER + + break; + } + + case kNodeTypeHint: { + break; + } + + case kNodeTypeTarget: { + TargetNode* node = static_cast(node_); + + node->setOffset(assembler->getOffset()); + assembler->bind(node->getLabel()); + break; + } + + case kNodeTypeInst: { + InstNode* node = static_cast(node_); + + uint32_t code = node->getCode(); + uint32_t opCount = node->getOpCount(); + + const Operand* opList = node->getOpList(); + assembler->_instOptions = node->getOptions(); + + const Operand* o0 = &noOperand; + const Operand* o1 = &noOperand; + const Operand* o2 = &noOperand; + + if (node->isSpecial()) { + switch (code) { + case kX86InstIdCpuid: + break; + + case kX86InstIdCbw: + case kX86InstIdCdq: + case kX86InstIdCdqe: + case kX86InstIdCwd: + case kX86InstIdCwde: + case kX86InstIdCqo: + break; + + case kX86InstIdCmpxchg: + o0 = &opList[1]; + o1 = &opList[2]; + break; + + case kX86InstIdCmpxchg8b : + case kX86InstIdCmpxchg16b: + o0 = &opList[4]; + break; + + case kX86InstIdDaa: + case kX86InstIdDas: + break; + + case kX86InstIdImul: + case kX86InstIdMul: + case kX86InstIdIdiv: + case kX86InstIdDiv: + // Assume "Mul/Div dst_hi (implicit), dst_lo (implicit), src (explicit)". + ASMJIT_ASSERT(opCount == 3); + o0 = &opList[2]; + break; + + case kX86InstIdMovPtr: + break; + + case kX86InstIdLahf: + case kX86InstIdSahf: + break; + + case kX86InstIdMaskmovq: + case kX86InstIdMaskmovdqu: + o0 = &opList[1]; + o1 = &opList[2]; + break; + + case kX86InstIdEnter: + o0 = &opList[0]; + o1 = &opList[1]; + break; + + case kX86InstIdLeave: + break; + + case kX86InstIdRet: + if (opCount > 0) + o0 = &opList[0]; + break; + + case kX86InstIdMonitor: + case kX86InstIdMwait: + break; + + case kX86InstIdPop: + o0 = &opList[0]; + break; + + case kX86InstIdPopa: + case kX86InstIdPopf: + break; + + case kX86InstIdPush: + o0 = &opList[0]; + break; + + case kX86InstIdPusha: + case kX86InstIdPushf: + break; + + case kX86InstIdRcl: + case kX86InstIdRcr: + case kX86InstIdRol: + case kX86InstIdRor: + case kX86InstIdSal: + case kX86InstIdSar: + case kX86InstIdShl: + case kX86InstIdShr: + o0 = &opList[0]; + o1 = &x86::cl; + break; + + case kX86InstIdShld: + case kX86InstIdShrd: + o0 = &opList[0]; + o1 = &opList[1]; + o2 = &x86::cl; + break; + + case kX86InstIdRdtsc: + case kX86InstIdRdtscp: + break; + + case kX86InstIdRepLodsB : case kX86InstIdRepLodsD : case kX86InstIdRepLodsQ : case kX86InstIdRepLodsW : + case kX86InstIdRepMovsB : case kX86InstIdRepMovsD : case kX86InstIdRepMovsQ : case kX86InstIdRepMovsW : + case kX86InstIdRepStosB : case kX86InstIdRepStosD : case kX86InstIdRepStosQ : case kX86InstIdRepStosW : + case kX86InstIdRepeCmpsB : case kX86InstIdRepeCmpsD : case kX86InstIdRepeCmpsQ : case kX86InstIdRepeCmpsW : + case kX86InstIdRepeScasB : case kX86InstIdRepeScasD : case kX86InstIdRepeScasQ : case kX86InstIdRepeScasW : + case kX86InstIdRepneCmpsB: case kX86InstIdRepneCmpsD: case kX86InstIdRepneCmpsQ: case kX86InstIdRepneCmpsW: + case kX86InstIdRepneScasB: case kX86InstIdRepneScasD: case kX86InstIdRepneScasQ: case kX86InstIdRepneScasW: + break; + + default: + ASMJIT_ASSERT(!"Reached"); + } + } + else { + if (opCount > 0) o0 = &opList[0]; + if (opCount > 1) o1 = &opList[1]; + if (opCount > 2) o2 = &opList[2]; + } + + // We use this form, because it is the main one. + assembler->emit(code, *o0, *o1, *o2); + break; + } + + // Function scope and return is translated to another nodes, no special + // handling is required at this point. + case kNodeTypeFunc: + case kNodeTypeEnd: + case kNodeTypeRet: { + break; + } + + // Function call adds nodes before and after, but it's required to emit + // the call instruction by itself. + case kNodeTypeCall: { + X86CallNode* node = static_cast(node_); + assembler->emit(kX86InstIdCall, node->_target, noOperand, noOperand); + break; + } + + default: + break; + } + + node_ = node_->getNext(); + } while (node_ != stop); + + return kErrorOk; +} + +Error X86Context::serialize(Assembler* assembler, Node* start, Node* stop) { +#if !defined(ASMJIT_DISABLE_LOGGER) + if (assembler->hasLogger()) + return X86Context_serialize<1>(this, static_cast(assembler), start, stop); +#endif // !ASMJIT_DISABLE_LOGGER + + return X86Context_serialize<0>(this, static_cast(assembler), start, stop); +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64) diff --git a/libraries/asmjit/x86/x86context_p.h b/libraries/asmjit/x86/x86context_p.h new file mode 100644 index 000000000..64bfc11fa --- /dev/null +++ b/libraries/asmjit/x86/x86context_p.h @@ -0,0 +1,523 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86CONTEXT_P_H +#define _ASMJIT_X86_X86CONTEXT_P_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../base/compiler.h" +#include "../base/context_p.h" +#include "../base/intutil.h" +#include "../x86/x86assembler.h" +#include "../x86/x86compiler.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +//! \addtogroup asmjit_x86_compiler +//! \{ + +// ============================================================================ +// [asmjit::X86Context] +// ============================================================================ + +#if defined(ASMJIT_DEBUG) +# define ASMJIT_X86_CHECK_STATE _checkState(); +#else +# define ASMJIT_X86_CHECK_STATE +#endif // ASMJIT_DEBUG + +//! \internal +//! +//! Compiler context is used by `X86Compiler`. +//! +//! Compiler context is used during compilation and normally developer doesn't +//! need access to it. The context is user per function (it's reset after each +//! function is generated). +struct X86Context : public Context { + ASMJIT_NO_COPY(X86Context) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a new `X86Context` instance. + X86Context(X86Compiler* compiler); + //! Destroy the `X86Context` instance. + virtual ~X86Context(); + + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + virtual void reset(); + + // -------------------------------------------------------------------------- + // [Arch] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isX64() const { + return _zsp.getSize() == 16; + } + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get compiler as `X86Compiler`. + ASMJIT_INLINE X86Compiler* getCompiler() const { + return static_cast(_compiler); + } + + //! Get function as `X86FuncNode`. + ASMJIT_INLINE X86FuncNode* getFunc() const { + return reinterpret_cast(_func); + } + + //! Get clobbered registers (global). + ASMJIT_INLINE uint32_t getClobberedRegs(uint32_t c) { + return _clobberedRegs.get(c); + } + + // -------------------------------------------------------------------------- + // [Helpers] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86VarMap* newVarMap(uint32_t vaCount) { + return static_cast( + _baseZone.alloc(sizeof(X86VarMap) + vaCount * sizeof(VarAttr))); + } + + // -------------------------------------------------------------------------- + // [Emit] + // -------------------------------------------------------------------------- + + void emitLoad(VarData* vd, uint32_t regIndex, const char* reason); + void emitSave(VarData* vd, uint32_t regIndex, const char* reason); + void emitMove(VarData* vd, uint32_t toRegIndex, uint32_t fromRegIndex, const char* reason); + void emitSwapGp(VarData* aVd, VarData* bVd, uint32_t aIndex, uint32_t bIndex, const char* reason); + + void emitPushSequence(uint32_t regs); + void emitPopSequence(uint32_t regs); + + void emitConvertVarToVar(uint32_t dstType, uint32_t dstIndex, uint32_t srcType, uint32_t srcIndex); + void emitMoveVarOnStack(uint32_t dstType, const X86Mem* dst, uint32_t srcType, uint32_t srcIndex); + void emitMoveImmOnStack(uint32_t dstType, const X86Mem* dst, const Imm* src); + + void emitMoveImmToReg(uint32_t dstType, uint32_t dstIndex, const Imm* src); + + // -------------------------------------------------------------------------- + // [Register Management] + // -------------------------------------------------------------------------- + + void _checkState(); + + ASMJIT_INLINE uint32_t getRegSize() const { + return _zsp.getSize(); + } + + // -------------------------------------------------------------------------- + // [Attach / Detach] + // -------------------------------------------------------------------------- + + //! Attach. + //! + //! Attach a register to the 'VarData', changing 'VarData' members to show + //! that the variable is currently alive and linking variable with the + //! current 'X86VarState'. + template + ASMJIT_INLINE void attach(VarData* vd, uint32_t regIndex, bool modified) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(regIndex != kInvalidReg); + + // Prevent Esp allocation if C==Gp. + ASMJIT_ASSERT(C != kX86RegClassGp || regIndex != kX86RegIndexSp); + + uint32_t regMask = IntUtil::mask(regIndex); + + vd->setState(kVarStateReg); + vd->setRegIndex(regIndex); + vd->addHomeIndex(regIndex); + vd->setModified(modified); + + _x86State.getListByClass(C)[regIndex] = vd; + _x86State._occupied.add(C, regMask); + _x86State._modified.add(C, static_cast(modified) << regIndex); + + ASMJIT_X86_CHECK_STATE + } + + //! Detach. + //! + //! The opposite of 'Attach'. Detach resets the members in 'VarData' + //! (regIndex, state and changed flags) and unlinks the variable with the + //! current 'X86VarState'. + template + ASMJIT_INLINE void detach(VarData* vd, uint32_t regIndex, uint32_t vState) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getRegIndex() == regIndex); + ASMJIT_ASSERT(vState != kVarStateReg); + + uint32_t regMask = IntUtil::mask(regIndex); + + vd->setState(vState); + vd->resetRegIndex(); + vd->setModified(false); + + _x86State.getListByClass(C)[regIndex] = NULL; + _x86State._occupied.del(C, regMask); + _x86State._modified.del(C, regMask); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Rebase] + // -------------------------------------------------------------------------- + + //! Rebase. + //! + //! Change the register of the 'VarData' changing also the current 'X86VarState'. + //! Rebase is nearly identical to 'Detach' and 'Attach' sequence, but doesn't + // change the 'VarData' modified flag. + template + ASMJIT_INLINE void rebase(VarData* vd, uint32_t newRegIndex, uint32_t oldRegIndex) { + ASMJIT_ASSERT(vd->getClass() == C); + + uint32_t newRegMask = IntUtil::mask(newRegIndex); + uint32_t oldRegMask = IntUtil::mask(oldRegIndex); + uint32_t bothRegMask = newRegMask ^ oldRegMask; + + vd->setRegIndex(newRegIndex); + + _x86State.getListByClass(C)[oldRegIndex] = NULL; + _x86State.getListByClass(C)[newRegIndex] = vd; + + _x86State._occupied.xor_(C, bothRegMask); + _x86State._modified.xor_(C, bothRegMask & -static_cast(vd->isModified())); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Load / Save] + // -------------------------------------------------------------------------- + + //! Load. + //! + //! Load variable from its memory slot to a register, emitting 'Load' + //! instruction and changing the variable state to allocated. + template + ASMJIT_INLINE void load(VarData* vd, uint32_t regIndex) { + // Can be only called if variable is not allocated. + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getState() != kVarStateReg); + ASMJIT_ASSERT(vd->getRegIndex() == kInvalidReg); + + emitLoad(vd, regIndex, "Load"); + attach(vd, regIndex, false); + + ASMJIT_X86_CHECK_STATE + } + + //! Save. + //! + //! Save the variable into its home location, but keep it as allocated. + template + ASMJIT_INLINE void save(VarData* vd) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getState() == kVarStateReg); + ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); + + uint32_t regIndex = vd->getRegIndex(); + uint32_t regMask = IntUtil::mask(regIndex); + + emitSave(vd, regIndex, "Save"); + + vd->setModified(false); + _x86State._modified.del(C, regMask); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Move / Swap] + // -------------------------------------------------------------------------- + + //! Move a register. + //! + //! Move register from one index to another, emitting 'Move' if needed. This + //! function does nothing if register is already at the given index. + template + ASMJIT_INLINE void move(VarData* vd, uint32_t regIndex) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vd->getState() == kVarStateReg); + ASMJIT_ASSERT(vd->getRegIndex() != kInvalidReg); + + uint32_t oldIndex = vd->getRegIndex(); + if (regIndex != oldIndex) { + emitMove(vd, regIndex, oldIndex, "Move"); + rebase(vd, regIndex, oldIndex); + } + + ASMJIT_X86_CHECK_STATE + } + + //! Swap two registers + //! + //! It's only possible to swap Gp registers. + ASMJIT_INLINE void swapGp(VarData* aVd, VarData* bVd) { + ASMJIT_ASSERT(aVd != bVd); + + ASMJIT_ASSERT(aVd->getClass() == kX86RegClassGp); + ASMJIT_ASSERT(aVd->getState() == kVarStateReg); + ASMJIT_ASSERT(aVd->getRegIndex() != kInvalidReg); + + ASMJIT_ASSERT(bVd->getClass() == kX86RegClassGp); + ASMJIT_ASSERT(bVd->getState() == kVarStateReg); + ASMJIT_ASSERT(bVd->getRegIndex() != kInvalidReg); + + uint32_t aIndex = aVd->getRegIndex(); + uint32_t bIndex = bVd->getRegIndex(); + + emitSwapGp(aVd, bVd, aIndex, bIndex, "Swap"); + + aVd->setRegIndex(bIndex); + bVd->setRegIndex(aIndex); + + _x86State.getListByClass(kX86RegClassGp)[aIndex] = bVd; + _x86State.getListByClass(kX86RegClassGp)[bIndex] = aVd; + + uint32_t m = aVd->isModified() ^ bVd->isModified(); + _x86State._modified.xor_(kX86RegClassGp, (m << aIndex) | (m << bIndex)); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Alloc / Spill] + // -------------------------------------------------------------------------- + + //! Alloc. + template + ASMJIT_INLINE void alloc(VarData* vd, uint32_t regIndex) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(regIndex != kInvalidReg); + + uint32_t oldRegIndex = vd->getRegIndex(); + uint32_t oldState = vd->getState(); + uint32_t regMask = IntUtil::mask(regIndex); + + ASMJIT_ASSERT(_x86State.getListByClass(C)[regIndex] == NULL || regIndex == oldRegIndex); + + if (oldState != kVarStateReg) { + if (oldState == kVarStateMem) + emitLoad(vd, regIndex, "Alloc"); + vd->setModified(false); + } + else if (oldRegIndex != regIndex) { + emitMove(vd, regIndex, oldRegIndex, "Alloc"); + + _x86State.getListByClass(C)[oldRegIndex] = NULL; + regMask ^= IntUtil::mask(oldRegIndex); + } + else { + ASMJIT_X86_CHECK_STATE + return; + } + + vd->setState(kVarStateReg); + vd->setRegIndex(regIndex); + + _x86State.getListByClass(C)[regIndex] = vd; + _x86State._occupied.xor_(C, regMask); + _x86State._modified.xor_(C, regMask & -static_cast(vd->isModified())); + + ASMJIT_X86_CHECK_STATE + } + + //! Spill. + //! + //! Spill variable/register, saves the content to the memory-home if modified. + template + ASMJIT_INLINE void spill(VarData* vd) { + ASMJIT_ASSERT(vd->getClass() == C); + + if (vd->getState() != kVarStateReg) { + ASMJIT_X86_CHECK_STATE + return; + } + + uint32_t regIndex = vd->getRegIndex(); + + ASMJIT_ASSERT(regIndex != kInvalidReg); + ASMJIT_ASSERT(_x86State.getListByClass(C)[regIndex] == vd); + + if (vd->isModified()) + emitSave(vd, regIndex, "Spill"); + detach(vd, regIndex, kVarStateMem); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Modify] + // -------------------------------------------------------------------------- + + template + ASMJIT_INLINE void modify(VarData* vd) { + ASMJIT_ASSERT(vd->getClass() == C); + + uint32_t regIndex = vd->getRegIndex(); + uint32_t regMask = IntUtil::mask(regIndex); + + vd->setModified(true); + _x86State._modified.add(C, regMask); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [Unuse] + // -------------------------------------------------------------------------- + + //! Unuse. + //! + //! Unuse variable, it will be detached it if it's allocated then its state + //! will be changed to kVarStateUnused. + template + ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateUnused) { + ASMJIT_ASSERT(vd->getClass() == C); + ASMJIT_ASSERT(vState != kVarStateReg); + + uint32_t regIndex = vd->getRegIndex(); + if (regIndex != kInvalidReg) + detach(vd, regIndex, vState); + else + vd->setState(vState); + + ASMJIT_X86_CHECK_STATE + } + + // -------------------------------------------------------------------------- + // [State] + // -------------------------------------------------------------------------- + + //! Get state as `X86VarState`. + ASMJIT_INLINE X86VarState* getState() const { + return const_cast(&_x86State); + } + + virtual void loadState(VarState* src); + virtual VarState* saveState(); + + virtual void switchState(VarState* src); + virtual void intersectStates(VarState* a, VarState* b); + + // -------------------------------------------------------------------------- + // [Memory] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Mem getVarMem(VarData* vd) { + (void)getVarCell(vd); + + X86Mem mem(_memSlot); + mem.setBase(vd->getId()); + return mem; + } + + // -------------------------------------------------------------------------- + // [Fetch] + // -------------------------------------------------------------------------- + + virtual Error fetch(); + + // -------------------------------------------------------------------------- + // [Annotate] + // -------------------------------------------------------------------------- + + virtual Error annotate(); + + // -------------------------------------------------------------------------- + // [Translate] + // -------------------------------------------------------------------------- + + virtual Error translate(); + + // -------------------------------------------------------------------------- + // [Schedule] + // -------------------------------------------------------------------------- + + virtual Error schedule(); + + // -------------------------------------------------------------------------- + // [Serialize] + // -------------------------------------------------------------------------- + + virtual Error serialize(Assembler* assembler, Node* start, Node* stop); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Count of X86/X64 registers. + X86RegCount _regCount; + //! X86/X64 stack-pointer (esp or rsp). + X86GpReg _zsp; + //! X86/X64 frame-pointer (ebp or rbp). + X86GpReg _zbp; + //! Temporary memory operand. + X86Mem _memSlot; + + //! X86/X64 specific compiler state, linked to `_state`. + X86VarState _x86State; + //! Clobbered registers (for the whole function). + X86RegMask _clobberedRegs; + + //! Memory cell where is stored address used to restore manually + //! aligned stack. + MemCell* _stackFrameCell; + + //! Global allocable registers mask. + uint32_t _gaRegs[kX86RegClassCount]; + + //! Function arguments base pointer (register). + uint8_t _argBaseReg; + //! Function variables base pointer (register). + uint8_t _varBaseReg; + //! Whether to emit comments. + uint8_t _emitComments; + + //! Function arguments base offset. + int32_t _argBaseOffset; + //! Function variables base offset. + int32_t _varBaseOffset; + + //! Function arguments displacement. + int32_t _argActualDisp; + //! Function variables displacement. + int32_t _varActualDisp; + + //! Temporary string builder used for logging. + StringBuilderT<256> _stringBuilder; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_X86_X86CONTEXT_P_H diff --git a/libraries/asmjit/x86/x86cpuinfo.cpp b/libraries/asmjit/x86/x86cpuinfo.cpp new file mode 100644 index 000000000..75ed0b06f --- /dev/null +++ b/libraries/asmjit/x86/x86cpuinfo.cpp @@ -0,0 +1,303 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) + +// [Dependencies - AsmJit] +#include "../base/intutil.h" +#include "../x86/x86cpuinfo.h" + +// 2009-02-05: Thanks to Mike Tajmajer for VC7.1 compiler support. It shouldn't +// affect x64 compilation, because x64 compiler starts with VS2005 (VC8.0). +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#include +#endif // _MSC_VER >= 1400 + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::X86CpuVendor] +// ============================================================================ + +struct X86CpuVendor { + uint32_t id; + char text[12]; +}; + +static const X86CpuVendor x86CpuVendorList[] = { + { kCpuVendorIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } }, + { kCpuVendorAmd , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } }, + { kCpuVendorVia , { 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 , 'V', 'I', 'A', 0 } }, + { kCpuVendorVia , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } } +}; + +static ASMJIT_INLINE bool x86CpuVendorEq(const X86CpuVendor& info, const char* vendorString) { + const uint32_t* a = reinterpret_cast(info.text); + const uint32_t* b = reinterpret_cast(vendorString); + + return (a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]); +} + +static ASMJIT_INLINE void x86SimplifyBrandString(char* s) { + // Always clear the current character in the buffer. It ensures that there + // is no garbage after the string NULL terminator. + char* d = s; + + char prev = 0; + char curr = s[0]; + s[0] = '\0'; + + for (;;) { + if (curr == 0) + break; + + if (curr == ' ') { + if (prev == '@' || s[1] == ' ' || s[1] == '@') + goto _Skip; + } + + d[0] = curr; + d++; + prev = curr; + +_Skip: + curr = *++s; + s[0] = '\0'; + } + + d[0] = '\0'; +} + +// ============================================================================ +// [asmjit::X86CpuUtil] +// ============================================================================ + +// This is messy, I know. Cpuid is implemented as intrinsic in VS2005, but +// we should support other compilers as well. Main problem is that MS compilers +// in 64-bit mode not allows to use inline assembler, so we need intrinsic and +// we need also asm version. + +// callCpuId() and detectCpuInfo() for x86 and x64 platforms begins here. +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) { + +#if defined(_MSC_VER) +// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler. +// ASMJIT_HOST_X64 is here only for readibility, only VS2005 can compile 64-bit code. +# if _MSC_VER >= 1400 || defined(ASMJIT_HOST_X64) + // Done by intrinsics. + __cpuidex(reinterpret_cast(outResult->i), inEax, inEcx); +# else // _MSC_VER < 1400 + uint32_t cpuid_eax = inEax; + uint32_t cpuid_ecx = inCax; + uint32_t* cpuid_out = outResult->i; + + __asm { + mov eax, cpuid_eax + mov ecx, cpuid_ecx + mov edi, cpuid_out + cpuid + mov dword ptr[edi + 0], eax + mov dword ptr[edi + 4], ebx + mov dword ptr[edi + 8], ecx + mov dword ptr[edi + 12], edx + } +# endif // _MSC_VER < 1400 + +#elif defined(__GNUC__) +// Note, patched to preserve ebx/rbx register which is used by GCC. +# if defined(ASMJIT_HOST_X86) +# define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \ + asm ("mov %%ebx, %%edi\n" \ + "cpuid\n" \ + "xchg %%edi, %%ebx\n" \ + : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx)) +# else +# define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \ + asm ("mov %%rbx, %%rdi\n" \ + "cpuid\n" \ + "xchg %%rdi, %%rbx\n" \ + : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx)) +# endif + __myCpuId(inEax, inEcx, outResult->eax, outResult->ebx, outResult->ecx, outResult->edx); +#endif // COMPILER +} + +void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { + X86CpuId regs; + + uint32_t i; + uint32_t maxId; + + // Clear everything except the '_size' member. + ::memset(reinterpret_cast(cpuInfo) + sizeof(uint32_t), + 0, sizeof(CpuInfo) - sizeof(uint32_t)); + + // Fill safe defaults. + cpuInfo->_hwThreadsCount = CpuInfo::detectHwThreadsCount(); + + // -------------------------------------------------------------------------- + // [CPUID EAX=0x00000000] + // -------------------------------------------------------------------------- + + // Get vendor string/id. + callCpuId(0, 0, ®s); + + maxId = regs.eax; + + ::memcpy(cpuInfo->_vendorString, ®s.ebx, 4); + ::memcpy(cpuInfo->_vendorString + 4, ®s.edx, 4); + ::memcpy(cpuInfo->_vendorString + 8, ®s.ecx, 4); + + for (i = 0; i < ASMJIT_ARRAY_SIZE(x86CpuVendorList); i++) { + if (x86CpuVendorEq(x86CpuVendorList[i], cpuInfo->_vendorString)) { + cpuInfo->_vendorId = x86CpuVendorList[i].id; + break; + } + } + + // -------------------------------------------------------------------------- + // [CPUID EAX=0x00000001] + // -------------------------------------------------------------------------- + + // Get feature flags in ecx/edx and family/model in eax. + callCpuId(1, 0, ®s); + + // Fill family and model fields. + cpuInfo->_family = (regs.eax >> 8) & 0x0F; + cpuInfo->_model = (regs.eax >> 4) & 0x0F; + cpuInfo->_stepping = (regs.eax ) & 0x0F; + + // Use extended family and model fields. + if (cpuInfo->_family == 0x0F) { + cpuInfo->_family += ((regs.eax >> 20) & 0xFF); + cpuInfo->_model += ((regs.eax >> 16) & 0x0F) << 4; + } + + cpuInfo->_processorType = ((regs.eax >> 12) & 0x03); + cpuInfo->_brandIndex = ((regs.ebx ) & 0xFF); + cpuInfo->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8; + cpuInfo->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF); + + if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureSse3); + if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kX86CpuFeaturePclmulqdq); + if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureMonitorMWait); + if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureSsse3); + if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg16B); + if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureSse41); + if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureSse42); + if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMovbe); + if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeaturePopcnt); + if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureAesni); + if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureRdrand); + + if (regs.edx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureRdtsc); + if (regs.edx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg8B); + if (regs.edx & 0x00008000U) cpuInfo->addFeature(kX86CpuFeatureCmov); + if (regs.edx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureMmx); + if (regs.edx & 0x01000000U) cpuInfo->addFeature(kX86CpuFeatureFxsr); + if (regs.edx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureMmxExt); + if (regs.edx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureSse2); + if (regs.edx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureMultithreading); + + if (cpuInfo->_vendorId == kCpuVendorAmd && (regs.edx & 0x10000000U)) { + // AMD sets Multithreading to ON if it has more cores. + if (cpuInfo->_hwThreadsCount == 1) + cpuInfo->_hwThreadsCount = 2; + } + + // Detect AVX. + if (regs.ecx & 0x10000000U) { + cpuInfo->addFeature(kX86CpuFeatureAvx); + + if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureXop); + if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kX86CpuFeatureFma3); + if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kX86CpuFeatureFma4); + if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureF16C); + } + + // Detect new features if the processor supports CPUID-07. + if (maxId >= 7) { + callCpuId(7, 0, ®s); + + if (regs.ebx & 0x00000001) cpuInfo->addFeature(kX86CpuFeatureFsGsBase); + if (regs.ebx & 0x00000008) cpuInfo->addFeature(kX86CpuFeatureBmi); + if (regs.ebx & 0x00000010) cpuInfo->addFeature(kX86CpuFeatureHle); + if (regs.ebx & 0x00000100) cpuInfo->addFeature(kX86CpuFeatureBmi2); + if (regs.ebx & 0x00000200) cpuInfo->addFeature(kX86CpuFeatureRepMovsbStosbExt); + if (regs.ebx & 0x00000800) cpuInfo->addFeature(kX86CpuFeatureRtm); + + // AVX2 depends on AVX. + if (cpuInfo->hasFeature(kX86CpuFeatureAvx)) { + if (regs.ebx & 0x00000020) cpuInfo->addFeature(kX86CpuFeatureAvx2); + } + } + + // -------------------------------------------------------------------------- + // [CPUID EAX=0x80000000] + // -------------------------------------------------------------------------- + + // Calling cpuid with 0x80000000 as the in argument gets the number of valid + // extended IDs. + callCpuId(0x80000000, 0, ®s); + + uint32_t maxExtId = IntUtil::iMin(regs.eax, 0x80000004); + uint32_t* brand = reinterpret_cast(cpuInfo->_brandString); + + for (i = 0x80000001; i <= maxExtId; i++) { + callCpuId(i, 0, ®s); + + switch (i) { + case 0x80000001: + if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureLahfSahf); + if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureLzcnt); + if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kX86CpuFeatureSse4A); + if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kX86CpuFeatureMsse); + if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeaturePrefetch); + + if (regs.edx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureExecuteDisableBit); + if (regs.edx & 0x00200000U) cpuInfo->addFeature(kX86CpuFeatureFfxsr); + if (regs.edx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMmxExt); + if (regs.edx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureRdtscp); + if (regs.edx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeature3dNowExt).addFeature(kX86CpuFeatureMmxExt); + if (regs.edx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeature3dNow); + break; + + case 0x80000002: + case 0x80000003: + case 0x80000004: + *brand++ = regs.eax; + *brand++ = regs.ebx; + *brand++ = regs.ecx; + *brand++ = regs.edx; + break; + + default: + // Additional features can be detected in the future. + break; + } + } + + // Simplify the brand string (remove unnecessary spaces to make printing nicer). + x86SimplifyBrandString(cpuInfo->_brandString); +} +#endif + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/libraries/asmjit/x86/x86cpuinfo.h b/libraries/asmjit/x86/x86cpuinfo.h new file mode 100644 index 000000000..7e71f2c46 --- /dev/null +++ b/libraries/asmjit/x86/x86cpuinfo.h @@ -0,0 +1,232 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86CPUINFO_H +#define _ASMJIT_X86_X86CPUINFO_H + +// [Dependencies - AsmJit] +#include "../base/cpuinfo.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86CpuInfo; + +//! \addtogroup asmjit_x86_general +//! \{ + +// ============================================================================ +// [asmjit::kX86CpuFeature] +// ============================================================================ + +//! X86 CPU features. +ASMJIT_ENUM(kX86CpuFeature) { + //! Cpu has multithreading. + kX86CpuFeatureMultithreading = 1, + //! Cpu has execute disable bit. + kX86CpuFeatureExecuteDisableBit, + //! Cpu has RDTSC. + kX86CpuFeatureRdtsc, + //! Cpu has RDTSCP. + kX86CpuFeatureRdtscp, + //! Cpu has CMOV. + kX86CpuFeatureCmov, + //! Cpu has CMPXCHG8B. + kX86CpuFeatureCmpXchg8B, + //! Cpu has CMPXCHG16B (x64). + kX86CpuFeatureCmpXchg16B, + //! Cpu has CLFUSH. + kX86CpuFeatureClflush, + //! Cpu has PREFETCH. + kX86CpuFeaturePrefetch, + //! Cpu has LAHF/SAHF. + kX86CpuFeatureLahfSahf, + //! Cpu has FXSAVE/FXRSTOR. + kX86CpuFeatureFxsr, + //! Cpu has FXSAVE/FXRSTOR optimizations. + kX86CpuFeatureFfxsr, + //! Cpu has MMX. + kX86CpuFeatureMmx, + //! Cpu has extended MMX. + kX86CpuFeatureMmxExt, + //! Cpu has 3dNow! + kX86CpuFeature3dNow, + //! Cpu has enchanced 3dNow! + kX86CpuFeature3dNowExt, + //! Cpu has SSE. + kX86CpuFeatureSse, + //! Cpu has SSE2. + kX86CpuFeatureSse2, + //! Cpu has SSE3. + kX86CpuFeatureSse3, + //! Cpu has Supplemental SSE3 (SSSE3). + kX86CpuFeatureSsse3, + //! Cpu has SSE4.A. + kX86CpuFeatureSse4A, + //! Cpu has SSE4.1. + kX86CpuFeatureSse41, + //! Cpu has SSE4.2. + kX86CpuFeatureSse42, + //! Cpu has Misaligned SSE (MSSE). + kX86CpuFeatureMsse, + //! Cpu has MONITOR and MWAIT. + kX86CpuFeatureMonitorMWait, + //! Cpu has MOVBE. + kX86CpuFeatureMovbe, + //! Cpu has POPCNT. + kX86CpuFeaturePopcnt, + //! Cpu has LZCNT. + kX86CpuFeatureLzcnt, + //! Cpu has AESNI. + kX86CpuFeatureAesni, + //! Cpu has PCLMULQDQ. + kX86CpuFeaturePclmulqdq, + //! Cpu has RDRAND. + kX86CpuFeatureRdrand, + //! Cpu has AVX. + kX86CpuFeatureAvx, + //! Cpu has AVX2. + kX86CpuFeatureAvx2, + //! Cpu has F16C. + kX86CpuFeatureF16C, + //! Cpu has FMA3. + kX86CpuFeatureFma3, + //! Cpu has FMA4. + kX86CpuFeatureFma4, + //! Cpu has XOP. + kX86CpuFeatureXop, + //! Cpu has BMI. + kX86CpuFeatureBmi, + //! Cpu has BMI2. + kX86CpuFeatureBmi2, + //! Cpu has HLE. + kX86CpuFeatureHle, + //! Cpu has RTM. + kX86CpuFeatureRtm, + //! Cpu has FSGSBASE. + kX86CpuFeatureFsGsBase, + //! Cpu has enhanced REP MOVSB/STOSB. + kX86CpuFeatureRepMovsbStosbExt, + + //! Count of X86/X64 Cpu features. + kX86CpuFeatureCount +}; + +// ============================================================================ +// [asmjit::X86CpuId] +// ============================================================================ + +//! X86/X64 CPUID output. +union X86CpuId { + //! EAX/EBX/ECX/EDX output. + uint32_t i[4]; + + struct { + //! EAX output. + uint32_t eax; + //! EBX output. + uint32_t ebx; + //! ECX output. + uint32_t ecx; + //! EDX output. + uint32_t edx; + }; +}; + +// ============================================================================ +// [asmjit::X86CpuUtil] +// ============================================================================ + +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +//! CPU utilities available only if the host processor is X86/X64. +struct X86CpuUtil { + //! Get the result of calling CPUID instruction to `out`. + ASMJIT_API static void callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* out); + + //! Detect the Host CPU. + ASMJIT_API static void detect(X86CpuInfo* cpuInfo); +}; +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + +// ============================================================================ +// [asmjit::X86CpuInfo] +// ============================================================================ + +struct X86CpuInfo : public CpuInfo { + ASMJIT_NO_COPY(X86CpuInfo) + + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) : + CpuInfo(size) {} + + // -------------------------------------------------------------------------- + // [Accessors] + // -------------------------------------------------------------------------- + + //! Get processor type. + ASMJIT_INLINE uint32_t getProcessorType() const { + return _processorType; + } + + //! Get brand index. + ASMJIT_INLINE uint32_t getBrandIndex() const { + return _brandIndex; + } + + //! Get flush cache line size. + ASMJIT_INLINE uint32_t getFlushCacheLineSize() const { + return _flushCacheLineSize; + } + + //! Get maximum logical processors count. + ASMJIT_INLINE uint32_t getMaxLogicalProcessors() const { + return _maxLogicalProcessors; + } + + // -------------------------------------------------------------------------- + // [Statics] + // -------------------------------------------------------------------------- + +#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) + //! Get global instance of `X86CpuInfo`. + static ASMJIT_INLINE const X86CpuInfo* getHost() { + return static_cast(CpuInfo::getHost()); + } +#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Processor type. + uint32_t _processorType; + //! Brand index. + uint32_t _brandIndex; + //! Flush cache line size in bytes. + uint32_t _flushCacheLineSize; + //! Maximum number of addressable IDs for logical processors. + uint32_t _maxLogicalProcessors; +}; + +//! \} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86CPUINFO_H diff --git a/libraries/asmjit/x86/x86inst.cpp b/libraries/asmjit/x86/x86inst.cpp new file mode 100644 index 000000000..39beacc44 --- /dev/null +++ b/libraries/asmjit/x86/x86inst.cpp @@ -0,0 +1,4850 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) + +// [Dependencies - AsmJit] +#include "../x86/x86inst.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Macros] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_NAMES) +# define INST_NAME_INDEX(_Code_) _Code_##_NameIndex +#else +# define INST_NAME_INDEX(_Code_) 0 +#endif + +#define G(_Group_) kX86InstGroup##_Group_ +#define F(_Flags_) kX86InstFlag##_Flags_ +#define O(_Op_) kX86InstOp##_Op_ +#define E(_Flags_) 0 + +#define U 0 +#define L kX86InstOpCode_L_True + +#define O_000000(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F00(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F01(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F01 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F0F(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F38(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_000F3A(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660000(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660F00(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660F38(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_660F3A(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_9B0000(_OpCode_, _R_) (kX86InstOpCode_PP_9B | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20000(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20F00(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20F38(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F20F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30000(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30F00(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30F38(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_F30F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define O_00_M03(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_00_M08(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_00_M09(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define O_66_M03(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_66_M08(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_66_M09(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define O_00_X(_OpCode_, _R_) (kX86InstOpCode_PP_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define O_9B_X(_OpCode_, _R_) (kX86InstOpCode_PP_9B | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) + +#define INST(_Code_, _Name_, _Group_, _Flags_, _MoveSize_, _OpFlags0_, _OpFlags1_, _OpFlags2_, _OpFlags3_, _EFlags_, _OpCode0_, _OpCode1_) \ + { INST_NAME_INDEX(_Code_), _Code_##_ExtendedIndex, _OpCode0_ } + +// ============================================================================ +// [asmjit::X86Inst] +// ============================================================================ + +// ${X86InstData:Begin} +// Automatically generated, do not edit. +#if !defined(ASMJIT_DISABLE_NAMES) +const char _x86InstName[] = + "\0" + "adc\0" + "add\0" + "addpd\0" + "addps\0" + "addsd\0" + "addss\0" + "addsubpd\0" + "addsubps\0" + "aesdec\0" + "aesdeclast\0" + "aesenc\0" + "aesenclast\0" + "aesimc\0" + "aeskeygenassist\0" + "and\0" + "andn\0" + "andnpd\0" + "andnps\0" + "andpd\0" + "andps\0" + "bextr\0" + "blendpd\0" + "blendps\0" + "blendvpd\0" + "blendvps\0" + "blsi\0" + "blsmsk\0" + "blsr\0" + "bsf\0" + "bsr\0" + "bswap\0" + "bt\0" + "btc\0" + "btr\0" + "bts\0" + "bzhi\0" + "call\0" + "cbw\0" + "cdq\0" + "cdqe\0" + "clc\0" + "cld\0" + "clflush\0" + "cmc\0" + "cmova\0" + "cmovae\0" + "cmovb\0" + "cmovbe\0" + "cmovc\0" + "cmove\0" + "cmovg\0" + "cmovge\0" + "cmovl\0" + "cmovle\0" + "cmovna\0" + "cmovnae\0" + "cmovnb\0" + "cmovnbe\0" + "cmovnc\0" + "cmovne\0" + "cmovng\0" + "cmovnge\0" + "cmovnl\0" + "cmovnle\0" + "cmovno\0" + "cmovnp\0" + "cmovns\0" + "cmovnz\0" + "cmovo\0" + "cmovp\0" + "cmovpe\0" + "cmovpo\0" + "cmovs\0" + "cmovz\0" + "cmp\0" + "cmppd\0" + "cmpps\0" + "cmps_b\0" + "cmps_d\0" + "cmps_q\0" + "cmps_w\0" + "cmpsd\0" + "cmpss\0" + "cmpxchg\0" + "cmpxchg16b\0" + "cmpxchg8b\0" + "comisd\0" + "comiss\0" + "cpuid\0" + "cqo\0" + "crc32\0" + "cvtdq2pd\0" + "cvtdq2ps\0" + "cvtpd2dq\0" + "cvtpd2pi\0" + "cvtpd2ps\0" + "cvtpi2pd\0" + "cvtpi2ps\0" + "cvtps2dq\0" + "cvtps2pd\0" + "cvtps2pi\0" + "cvtsd2si\0" + "cvtsd2ss\0" + "cvtsi2sd\0" + "cvtsi2ss\0" + "cvtss2sd\0" + "cvtss2si\0" + "cvttpd2dq\0" + "cvttpd2pi\0" + "cvttps2dq\0" + "cvttps2pi\0" + "cvttsd2si\0" + "cvttss2si\0" + "cwd\0" + "cwde\0" + "daa\0" + "das\0" + "dec\0" + "div\0" + "divpd\0" + "divps\0" + "divsd\0" + "divss\0" + "dppd\0" + "dpps\0" + "emms\0" + "enter\0" + "extractps\0" + "f2xm1\0" + "fabs\0" + "fadd\0" + "faddp\0" + "fbld\0" + "fbstp\0" + "fchs\0" + "fclex\0" + "fcmovb\0" + "fcmovbe\0" + "fcmove\0" + "fcmovnb\0" + "fcmovnbe\0" + "fcmovne\0" + "fcmovnu\0" + "fcmovu\0" + "fcom\0" + "fcomi\0" + "fcomip\0" + "fcomp\0" + "fcompp\0" + "fcos\0" + "fdecstp\0" + "fdiv\0" + "fdivp\0" + "fdivr\0" + "fdivrp\0" + "femms\0" + "ffree\0" + "fiadd\0" + "ficom\0" + "ficomp\0" + "fidiv\0" + "fidivr\0" + "fild\0" + "fimul\0" + "fincstp\0" + "finit\0" + "fist\0" + "fistp\0" + "fisttp\0" + "fisub\0" + "fisubr\0" + "fld\0" + "fld1\0" + "fldcw\0" + "fldenv\0" + "fldl2e\0" + "fldl2t\0" + "fldlg2\0" + "fldln2\0" + "fldpi\0" + "fldz\0" + "fmul\0" + "fmulp\0" + "fnclex\0" + "fninit\0" + "fnop\0" + "fnsave\0" + "fnstcw\0" + "fnstenv\0" + "fnstsw\0" + "fpatan\0" + "fprem\0" + "fprem1\0" + "fptan\0" + "frndint\0" + "frstor\0" + "fsave\0" + "fscale\0" + "fsin\0" + "fsincos\0" + "fsqrt\0" + "fst\0" + "fstcw\0" + "fstenv\0" + "fstp\0" + "fstsw\0" + "fsub\0" + "fsubp\0" + "fsubr\0" + "fsubrp\0" + "ftst\0" + "fucom\0" + "fucomi\0" + "fucomip\0" + "fucomp\0" + "fucompp\0" + "fwait\0" + "fxam\0" + "fxch\0" + "fxrstor\0" + "fxsave\0" + "fxtract\0" + "fyl2x\0" + "fyl2xp1\0" + "haddpd\0" + "haddps\0" + "hsubpd\0" + "hsubps\0" + "idiv\0" + "imul\0" + "inc\0" + "insertps\0" + "int\0" + "ja\0" + "jae\0" + "jb\0" + "jbe\0" + "jc\0" + "je\0" + "jg\0" + "jge\0" + "jl\0" + "jle\0" + "jna\0" + "jnae\0" + "jnb\0" + "jnbe\0" + "jnc\0" + "jne\0" + "jng\0" + "jnge\0" + "jnl\0" + "jnle\0" + "jno\0" + "jnp\0" + "jns\0" + "jnz\0" + "jo\0" + "jp\0" + "jpe\0" + "jpo\0" + "js\0" + "jz\0" + "jecxz\0" + "jmp\0" + "lahf\0" + "lddqu\0" + "ldmxcsr\0" + "lea\0" + "leave\0" + "lfence\0" + "lods_b\0" + "lods_d\0" + "lods_q\0" + "lods_w\0" + "lzcnt\0" + "maskmovdqu\0" + "maskmovq\0" + "maxpd\0" + "maxps\0" + "maxsd\0" + "maxss\0" + "mfence\0" + "minpd\0" + "minps\0" + "minsd\0" + "minss\0" + "monitor\0" + "mov\0" + "mov_ptr\0" + "movapd\0" + "movaps\0" + "movbe\0" + "movd\0" + "movddup\0" + "movdq2q\0" + "movdqa\0" + "movdqu\0" + "movhlps\0" + "movhpd\0" + "movhps\0" + "movlhps\0" + "movlpd\0" + "movlps\0" + "movmskpd\0" + "movmskps\0" + "movntdq\0" + "movntdqa\0" + "movnti\0" + "movntpd\0" + "movntps\0" + "movntq\0" + "movq\0" + "movq2dq\0" + "movs_b\0" + "movs_d\0" + "movs_q\0" + "movs_w\0" + "movsd\0" + "movshdup\0" + "movsldup\0" + "movss\0" + "movsx\0" + "movsxd\0" + "movupd\0" + "movups\0" + "movzx\0" + "mpsadbw\0" + "mul\0" + "mulpd\0" + "mulps\0" + "mulsd\0" + "mulss\0" + "mulx\0" + "mwait\0" + "neg\0" + "nop\0" + "not\0" + "or\0" + "orpd\0" + "orps\0" + "pabsb\0" + "pabsd\0" + "pabsw\0" + "packssdw\0" + "packsswb\0" + "packusdw\0" + "packuswb\0" + "paddb\0" + "paddd\0" + "paddq\0" + "paddsb\0" + "paddsw\0" + "paddusb\0" + "paddusw\0" + "paddw\0" + "palignr\0" + "pand\0" + "pandn\0" + "pause\0" + "pavgb\0" + "pavgw\0" + "pblendvb\0" + "pblendw\0" + "pclmulqdq\0" + "pcmpeqb\0" + "pcmpeqd\0" + "pcmpeqq\0" + "pcmpeqw\0" + "pcmpestri\0" + "pcmpestrm\0" + "pcmpgtb\0" + "pcmpgtd\0" + "pcmpgtq\0" + "pcmpgtw\0" + "pcmpistri\0" + "pcmpistrm\0" + "pdep\0" + "pext\0" + "pextrb\0" + "pextrd\0" + "pextrq\0" + "pextrw\0" + "pf2id\0" + "pf2iw\0" + "pfacc\0" + "pfadd\0" + "pfcmpeq\0" + "pfcmpge\0" + "pfcmpgt\0" + "pfmax\0" + "pfmin\0" + "pfmul\0" + "pfnacc\0" + "pfpnacc\0" + "pfrcp\0" + "pfrcpit1\0" + "pfrcpit2\0" + "pfrsqit1\0" + "pfrsqrt\0" + "pfsub\0" + "pfsubr\0" + "phaddd\0" + "phaddsw\0" + "phaddw\0" + "phminposuw\0" + "phsubd\0" + "phsubsw\0" + "phsubw\0" + "pi2fd\0" + "pi2fw\0" + "pinsrb\0" + "pinsrd\0" + "pinsrq\0" + "pinsrw\0" + "pmaddubsw\0" + "pmaddwd\0" + "pmaxsb\0" + "pmaxsd\0" + "pmaxsw\0" + "pmaxub\0" + "pmaxud\0" + "pmaxuw\0" + "pminsb\0" + "pminsd\0" + "pminsw\0" + "pminub\0" + "pminud\0" + "pminuw\0" + "pmovmskb\0" + "pmovsxbd\0" + "pmovsxbq\0" + "pmovsxbw\0" + "pmovsxdq\0" + "pmovsxwd\0" + "pmovsxwq\0" + "pmovzxbd\0" + "pmovzxbq\0" + "pmovzxbw\0" + "pmovzxdq\0" + "pmovzxwd\0" + "pmovzxwq\0" + "pmuldq\0" + "pmulhrsw\0" + "pmulhuw\0" + "pmulhw\0" + "pmulld\0" + "pmullw\0" + "pmuludq\0" + "pop\0" + "popa\0" + "popcnt\0" + "popf\0" + "por\0" + "prefetch\0" + "prefetch_3dnow\0" + "prefetchw_3dnow\0" + "psadbw\0" + "pshufb\0" + "pshufd\0" + "pshufhw\0" + "pshuflw\0" + "pshufw\0" + "psignb\0" + "psignd\0" + "psignw\0" + "pslld\0" + "pslldq\0" + "psllq\0" + "psllw\0" + "psrad\0" + "psraw\0" + "psrld\0" + "psrldq\0" + "psrlq\0" + "psrlw\0" + "psubb\0" + "psubd\0" + "psubq\0" + "psubsb\0" + "psubsw\0" + "psubusb\0" + "psubusw\0" + "psubw\0" + "pswapd\0" + "ptest\0" + "punpckhbw\0" + "punpckhdq\0" + "punpckhqdq\0" + "punpckhwd\0" + "punpcklbw\0" + "punpckldq\0" + "punpcklqdq\0" + "punpcklwd\0" + "push\0" + "pusha\0" + "pushf\0" + "pxor\0" + "rcl\0" + "rcpps\0" + "rcpss\0" + "rcr\0" + "rdfsbase\0" + "rdgsbase\0" + "rdrand\0" + "rdtsc\0" + "rdtscp\0" + "rep lods_b\0" + "rep lods_d\0" + "rep lods_q\0" + "rep lods_w\0" + "rep movs_b\0" + "rep movs_d\0" + "rep movs_q\0" + "rep movs_w\0" + "rep stos_b\0" + "rep stos_d\0" + "rep stos_q\0" + "rep stos_w\0" + "repe cmps_b\0" + "repe cmps_d\0" + "repe cmps_q\0" + "repe cmps_w\0" + "repe scas_b\0" + "repe scas_d\0" + "repe scas_q\0" + "repe scas_w\0" + "repne cmps_b\0" + "repne cmps_d\0" + "repne cmps_q\0" + "repne cmps_w\0" + "repne scas_b\0" + "repne scas_d\0" + "repne scas_q\0" + "repne scas_w\0" + "ret\0" + "rol\0" + "ror\0" + "rorx\0" + "roundpd\0" + "roundps\0" + "roundsd\0" + "roundss\0" + "rsqrtps\0" + "rsqrtss\0" + "sahf\0" + "sal\0" + "sar\0" + "sarx\0" + "sbb\0" + "scas_b\0" + "scas_d\0" + "scas_q\0" + "scas_w\0" + "seta\0" + "setae\0" + "setb\0" + "setbe\0" + "setc\0" + "sete\0" + "setg\0" + "setge\0" + "setl\0" + "setle\0" + "setna\0" + "setnae\0" + "setnb\0" + "setnbe\0" + "setnc\0" + "setne\0" + "setng\0" + "setnge\0" + "setnl\0" + "setnle\0" + "setno\0" + "setnp\0" + "setns\0" + "setnz\0" + "seto\0" + "setp\0" + "setpe\0" + "setpo\0" + "sets\0" + "setz\0" + "sfence\0" + "shl\0" + "shld\0" + "shlx\0" + "shr\0" + "shrd\0" + "shrx\0" + "shufpd\0" + "shufps\0" + "sqrtpd\0" + "sqrtps\0" + "sqrtsd\0" + "sqrtss\0" + "stc\0" + "std\0" + "stmxcsr\0" + "stos_b\0" + "stos_d\0" + "stos_q\0" + "stos_w\0" + "sub\0" + "subpd\0" + "subps\0" + "subsd\0" + "subss\0" + "test\0" + "tzcnt\0" + "ucomisd\0" + "ucomiss\0" + "ud2\0" + "unpckhpd\0" + "unpckhps\0" + "unpcklpd\0" + "unpcklps\0" + "vaddpd\0" + "vaddps\0" + "vaddsd\0" + "vaddss\0" + "vaddsubpd\0" + "vaddsubps\0" + "vaesdec\0" + "vaesdeclast\0" + "vaesenc\0" + "vaesenclast\0" + "vaesimc\0" + "vaeskeygenassist\0" + "vandnpd\0" + "vandnps\0" + "vandpd\0" + "vandps\0" + "vblendpd\0" + "vblendps\0" + "vblendvpd\0" + "vblendvps\0" + "vbroadcastf128\0" + "vbroadcasti128\0" + "vbroadcastsd\0" + "vbroadcastss\0" + "vcmppd\0" + "vcmpps\0" + "vcmpsd\0" + "vcmpss\0" + "vcomisd\0" + "vcomiss\0" + "vcvtdq2pd\0" + "vcvtdq2ps\0" + "vcvtpd2dq\0" + "vcvtpd2ps\0" + "vcvtph2ps\0" + "vcvtps2dq\0" + "vcvtps2pd\0" + "vcvtps2ph\0" + "vcvtsd2si\0" + "vcvtsd2ss\0" + "vcvtsi2sd\0" + "vcvtsi2ss\0" + "vcvtss2sd\0" + "vcvtss2si\0" + "vcvttpd2dq\0" + "vcvttps2dq\0" + "vcvttsd2si\0" + "vcvttss2si\0" + "vdivpd\0" + "vdivps\0" + "vdivsd\0" + "vdivss\0" + "vdppd\0" + "vdpps\0" + "vextractf128\0" + "vextracti128\0" + "vextractps\0" + "vfmadd132pd\0" + "vfmadd132ps\0" + "vfmadd132sd\0" + "vfmadd132ss\0" + "vfmadd213pd\0" + "vfmadd213ps\0" + "vfmadd213sd\0" + "vfmadd213ss\0" + "vfmadd231pd\0" + "vfmadd231ps\0" + "vfmadd231sd\0" + "vfmadd231ss\0" + "vfmaddpd\0" + "vfmaddps\0" + "vfmaddsd\0" + "vfmaddss\0" + "vfmaddsub132pd\0" + "vfmaddsub132ps\0" + "vfmaddsub213pd\0" + "vfmaddsub213ps\0" + "vfmaddsub231pd\0" + "vfmaddsub231ps\0" + "vfmaddsubpd\0" + "vfmaddsubps\0" + "vfmsub132pd\0" + "vfmsub132ps\0" + "vfmsub132sd\0" + "vfmsub132ss\0" + "vfmsub213pd\0" + "vfmsub213ps\0" + "vfmsub213sd\0" + "vfmsub213ss\0" + "vfmsub231pd\0" + "vfmsub231ps\0" + "vfmsub231sd\0" + "vfmsub231ss\0" + "vfmsubadd132pd\0" + "vfmsubadd132ps\0" + "vfmsubadd213pd\0" + "vfmsubadd213ps\0" + "vfmsubadd231pd\0" + "vfmsubadd231ps\0" + "vfmsubaddpd\0" + "vfmsubaddps\0" + "vfmsubpd\0" + "vfmsubps\0" + "vfmsubsd\0" + "vfmsubss\0" + "vfnmadd132pd\0" + "vfnmadd132ps\0" + "vfnmadd132sd\0" + "vfnmadd132ss\0" + "vfnmadd213pd\0" + "vfnmadd213ps\0" + "vfnmadd213sd\0" + "vfnmadd213ss\0" + "vfnmadd231pd\0" + "vfnmadd231ps\0" + "vfnmadd231sd\0" + "vfnmadd231ss\0" + "vfnmaddpd\0" + "vfnmaddps\0" + "vfnmaddsd\0" + "vfnmaddss\0" + "vfnmsub132pd\0" + "vfnmsub132ps\0" + "vfnmsub132sd\0" + "vfnmsub132ss\0" + "vfnmsub213pd\0" + "vfnmsub213ps\0" + "vfnmsub213sd\0" + "vfnmsub213ss\0" + "vfnmsub231pd\0" + "vfnmsub231ps\0" + "vfnmsub231sd\0" + "vfnmsub231ss\0" + "vfnmsubpd\0" + "vfnmsubps\0" + "vfnmsubsd\0" + "vfnmsubss\0" + "vfrczpd\0" + "vfrczps\0" + "vfrczsd\0" + "vfrczss\0" + "vgatherdpd\0" + "vgatherdps\0" + "vgatherqpd\0" + "vgatherqps\0" + "vhaddpd\0" + "vhaddps\0" + "vhsubpd\0" + "vhsubps\0" + "vinsertf128\0" + "vinserti128\0" + "vinsertps\0" + "vlddqu\0" + "vldmxcsr\0" + "vmaskmovdqu\0" + "vmaskmovpd\0" + "vmaskmovps\0" + "vmaxpd\0" + "vmaxps\0" + "vmaxsd\0" + "vmaxss\0" + "vminpd\0" + "vminps\0" + "vminsd\0" + "vminss\0" + "vmovapd\0" + "vmovaps\0" + "vmovd\0" + "vmovddup\0" + "vmovdqa\0" + "vmovdqu\0" + "vmovhlps\0" + "vmovhpd\0" + "vmovhps\0" + "vmovlhps\0" + "vmovlpd\0" + "vmovlps\0" + "vmovmskpd\0" + "vmovmskps\0" + "vmovntdq\0" + "vmovntdqa\0" + "vmovntpd\0" + "vmovntps\0" + "vmovq\0" + "vmovsd\0" + "vmovshdup\0" + "vmovsldup\0" + "vmovss\0" + "vmovupd\0" + "vmovups\0" + "vmpsadbw\0" + "vmulpd\0" + "vmulps\0" + "vmulsd\0" + "vmulss\0" + "vorpd\0" + "vorps\0" + "vpabsb\0" + "vpabsd\0" + "vpabsw\0" + "vpackssdw\0" + "vpacksswb\0" + "vpackusdw\0" + "vpackuswb\0" + "vpaddb\0" + "vpaddd\0" + "vpaddq\0" + "vpaddsb\0" + "vpaddsw\0" + "vpaddusb\0" + "vpaddusw\0" + "vpaddw\0" + "vpalignr\0" + "vpand\0" + "vpandn\0" + "vpavgb\0" + "vpavgw\0" + "vpblendd\0" + "vpblendvb\0" + "vpblendw\0" + "vpbroadcastb\0" + "vpbroadcastd\0" + "vpbroadcastq\0" + "vpbroadcastw\0" + "vpclmulqdq\0" + "vpcmov\0" + "vpcmpeqb\0" + "vpcmpeqd\0" + "vpcmpeqq\0" + "vpcmpeqw\0" + "vpcmpestri\0" + "vpcmpestrm\0" + "vpcmpgtb\0" + "vpcmpgtd\0" + "vpcmpgtq\0" + "vpcmpgtw\0" + "vpcmpistri\0" + "vpcmpistrm\0" + "vpcomb\0" + "vpcomd\0" + "vpcomq\0" + "vpcomub\0" + "vpcomud\0" + "vpcomuq\0" + "vpcomuw\0" + "vpcomw\0" + "vperm2f128\0" + "vperm2i128\0" + "vpermd\0" + "vpermil2pd\0" + "vpermil2ps\0" + "vpermilpd\0" + "vpermilps\0" + "vpermpd\0" + "vpermps\0" + "vpermq\0" + "vpextrb\0" + "vpextrd\0" + "vpextrq\0" + "vpextrw\0" + "vpgatherdd\0" + "vpgatherdq\0" + "vpgatherqd\0" + "vpgatherqq\0" + "vphaddbd\0" + "vphaddbq\0" + "vphaddbw\0" + "vphaddd\0" + "vphadddq\0" + "vphaddsw\0" + "vphaddubd\0" + "vphaddubq\0" + "vphaddubw\0" + "vphaddudq\0" + "vphadduwd\0" + "vphadduwq\0" + "vphaddw\0" + "vphaddwd\0" + "vphaddwq\0" + "vphminposuw\0" + "vphsubbw\0" + "vphsubd\0" + "vphsubdq\0" + "vphsubsw\0" + "vphsubw\0" + "vphsubwd\0" + "vpinsrb\0" + "vpinsrd\0" + "vpinsrq\0" + "vpinsrw\0" + "vpmacsdd\0" + "vpmacsdqh\0" + "vpmacsdql\0" + "vpmacssdd\0" + "vpmacssdqh\0" + "vpmacssdql\0" + "vpmacsswd\0" + "vpmacssww\0" + "vpmacswd\0" + "vpmacsww\0" + "vpmadcsswd\0" + "vpmadcswd\0" + "vpmaddubsw\0" + "vpmaddwd\0" + "vpmaskmovd\0" + "vpmaskmovq\0" + "vpmaxsb\0" + "vpmaxsd\0" + "vpmaxsw\0" + "vpmaxub\0" + "vpmaxud\0" + "vpmaxuw\0" + "vpminsb\0" + "vpminsd\0" + "vpminsw\0" + "vpminub\0" + "vpminud\0" + "vpminuw\0" + "vpmovmskb\0" + "vpmovsxbd\0" + "vpmovsxbq\0" + "vpmovsxbw\0" + "vpmovsxdq\0" + "vpmovsxwd\0" + "vpmovsxwq\0" + "vpmovzxbd\0" + "vpmovzxbq\0" + "vpmovzxbw\0" + "vpmovzxdq\0" + "vpmovzxwd\0" + "vpmovzxwq\0" + "vpmuldq\0" + "vpmulhrsw\0" + "vpmulhuw\0" + "vpmulhw\0" + "vpmulld\0" + "vpmullw\0" + "vpmuludq\0" + "vpor\0" + "vpperm\0" + "vprotb\0" + "vprotd\0" + "vprotq\0" + "vprotw\0" + "vpsadbw\0" + "vpshab\0" + "vpshad\0" + "vpshaq\0" + "vpshaw\0" + "vpshlb\0" + "vpshld\0" + "vpshlq\0" + "vpshlw\0" + "vpshufb\0" + "vpshufd\0" + "vpshufhw\0" + "vpshuflw\0" + "vpsignb\0" + "vpsignd\0" + "vpsignw\0" + "vpslld\0" + "vpslldq\0" + "vpsllq\0" + "vpsllvd\0" + "vpsllvq\0" + "vpsllw\0" + "vpsrad\0" + "vpsravd\0" + "vpsraw\0" + "vpsrld\0" + "vpsrldq\0" + "vpsrlq\0" + "vpsrlvd\0" + "vpsrlvq\0" + "vpsrlw\0" + "vpsubb\0" + "vpsubd\0" + "vpsubq\0" + "vpsubsb\0" + "vpsubsw\0" + "vpsubusb\0" + "vpsubusw\0" + "vpsubw\0" + "vptest\0" + "vpunpckhbw\0" + "vpunpckhdq\0" + "vpunpckhqdq\0" + "vpunpckhwd\0" + "vpunpcklbw\0" + "vpunpckldq\0" + "vpunpcklqdq\0" + "vpunpcklwd\0" + "vpxor\0" + "vrcpps\0" + "vrcpss\0" + "vroundpd\0" + "vroundps\0" + "vroundsd\0" + "vroundss\0" + "vrsqrtps\0" + "vrsqrtss\0" + "vshufpd\0" + "vshufps\0" + "vsqrtpd\0" + "vsqrtps\0" + "vsqrtsd\0" + "vsqrtss\0" + "vstmxcsr\0" + "vsubpd\0" + "vsubps\0" + "vsubsd\0" + "vsubss\0" + "vtestpd\0" + "vtestps\0" + "vucomisd\0" + "vucomiss\0" + "vunpckhpd\0" + "vunpckhps\0" + "vunpcklpd\0" + "vunpcklps\0" + "vxorpd\0" + "vxorps\0" + "vzeroall\0" + "vzeroupper\0" + "wrfsbase\0" + "wrgsbase\0" + "xadd\0" + "xchg\0" + "xor\0" + "xorpd\0" + "xorps\0"; + +// Automatically generated, do not edit. +enum kX86InstAlphaIndex { + kX86InstAlphaIndexFirst = 'a', + kX86InstAlphaIndexLast = 'z', + kX86InstAlphaIndexInvalid = 0xFFFF +}; + +// Automatically generated, do not edit. +static const uint16_t _x86InstAlphaIndex[26] = { + kX86InstIdAdc, + kX86InstIdBextr, + kX86InstIdCall, + kX86InstIdDaa, + kX86InstIdEmms, + kX86InstIdF2xm1, + 0xFFFF, + kX86InstIdHaddpd, + kX86InstIdIdiv, + kX86InstIdJa, + 0xFFFF, + kX86InstIdLahf, + kX86InstIdMaskmovdqu, + kX86InstIdNeg, + kX86InstIdOr, + kX86InstIdPabsb, + 0xFFFF, + kX86InstIdRcl, + kX86InstIdSahf, + kX86InstIdTest, + kX86InstIdUcomisd, + kX86InstIdVaddpd, + kX86InstIdWrfsbase, + kX86InstIdXadd, + 0xFFFF, + 0xFFFF +}; + +// Automatically generated, do not edit. +enum kX86InstData_NameIndex { + kInstIdNone_NameIndex = 0, + kX86InstIdAdc_NameIndex = 1, + kX86InstIdAdd_NameIndex = 5, + kX86InstIdAddpd_NameIndex = 9, + kX86InstIdAddps_NameIndex = 15, + kX86InstIdAddsd_NameIndex = 21, + kX86InstIdAddss_NameIndex = 27, + kX86InstIdAddsubpd_NameIndex = 33, + kX86InstIdAddsubps_NameIndex = 42, + kX86InstIdAesdec_NameIndex = 51, + kX86InstIdAesdeclast_NameIndex = 58, + kX86InstIdAesenc_NameIndex = 69, + kX86InstIdAesenclast_NameIndex = 76, + kX86InstIdAesimc_NameIndex = 87, + kX86InstIdAeskeygenassist_NameIndex = 94, + kX86InstIdAnd_NameIndex = 110, + kX86InstIdAndn_NameIndex = 114, + kX86InstIdAndnpd_NameIndex = 119, + kX86InstIdAndnps_NameIndex = 126, + kX86InstIdAndpd_NameIndex = 133, + kX86InstIdAndps_NameIndex = 139, + kX86InstIdBextr_NameIndex = 145, + kX86InstIdBlendpd_NameIndex = 151, + kX86InstIdBlendps_NameIndex = 159, + kX86InstIdBlendvpd_NameIndex = 167, + kX86InstIdBlendvps_NameIndex = 176, + kX86InstIdBlsi_NameIndex = 185, + kX86InstIdBlsmsk_NameIndex = 190, + kX86InstIdBlsr_NameIndex = 197, + kX86InstIdBsf_NameIndex = 202, + kX86InstIdBsr_NameIndex = 206, + kX86InstIdBswap_NameIndex = 210, + kX86InstIdBt_NameIndex = 216, + kX86InstIdBtc_NameIndex = 219, + kX86InstIdBtr_NameIndex = 223, + kX86InstIdBts_NameIndex = 227, + kX86InstIdBzhi_NameIndex = 231, + kX86InstIdCall_NameIndex = 236, + kX86InstIdCbw_NameIndex = 241, + kX86InstIdCdq_NameIndex = 245, + kX86InstIdCdqe_NameIndex = 249, + kX86InstIdClc_NameIndex = 254, + kX86InstIdCld_NameIndex = 258, + kX86InstIdClflush_NameIndex = 262, + kX86InstIdCmc_NameIndex = 270, + kX86InstIdCmova_NameIndex = 274, + kX86InstIdCmovae_NameIndex = 280, + kX86InstIdCmovb_NameIndex = 287, + kX86InstIdCmovbe_NameIndex = 293, + kX86InstIdCmovc_NameIndex = 300, + kX86InstIdCmove_NameIndex = 306, + kX86InstIdCmovg_NameIndex = 312, + kX86InstIdCmovge_NameIndex = 318, + kX86InstIdCmovl_NameIndex = 325, + kX86InstIdCmovle_NameIndex = 331, + kX86InstIdCmovna_NameIndex = 338, + kX86InstIdCmovnae_NameIndex = 345, + kX86InstIdCmovnb_NameIndex = 353, + kX86InstIdCmovnbe_NameIndex = 360, + kX86InstIdCmovnc_NameIndex = 368, + kX86InstIdCmovne_NameIndex = 375, + kX86InstIdCmovng_NameIndex = 382, + kX86InstIdCmovnge_NameIndex = 389, + kX86InstIdCmovnl_NameIndex = 397, + kX86InstIdCmovnle_NameIndex = 404, + kX86InstIdCmovno_NameIndex = 412, + kX86InstIdCmovnp_NameIndex = 419, + kX86InstIdCmovns_NameIndex = 426, + kX86InstIdCmovnz_NameIndex = 433, + kX86InstIdCmovo_NameIndex = 440, + kX86InstIdCmovp_NameIndex = 446, + kX86InstIdCmovpe_NameIndex = 452, + kX86InstIdCmovpo_NameIndex = 459, + kX86InstIdCmovs_NameIndex = 466, + kX86InstIdCmovz_NameIndex = 472, + kX86InstIdCmp_NameIndex = 478, + kX86InstIdCmppd_NameIndex = 482, + kX86InstIdCmpps_NameIndex = 488, + kX86InstIdCmpsB_NameIndex = 494, + kX86InstIdCmpsD_NameIndex = 501, + kX86InstIdCmpsQ_NameIndex = 508, + kX86InstIdCmpsW_NameIndex = 515, + kX86InstIdCmpsd_NameIndex = 522, + kX86InstIdCmpss_NameIndex = 528, + kX86InstIdCmpxchg_NameIndex = 534, + kX86InstIdCmpxchg16b_NameIndex = 542, + kX86InstIdCmpxchg8b_NameIndex = 553, + kX86InstIdComisd_NameIndex = 563, + kX86InstIdComiss_NameIndex = 570, + kX86InstIdCpuid_NameIndex = 577, + kX86InstIdCqo_NameIndex = 583, + kX86InstIdCrc32_NameIndex = 587, + kX86InstIdCvtdq2pd_NameIndex = 593, + kX86InstIdCvtdq2ps_NameIndex = 602, + kX86InstIdCvtpd2dq_NameIndex = 611, + kX86InstIdCvtpd2pi_NameIndex = 620, + kX86InstIdCvtpd2ps_NameIndex = 629, + kX86InstIdCvtpi2pd_NameIndex = 638, + kX86InstIdCvtpi2ps_NameIndex = 647, + kX86InstIdCvtps2dq_NameIndex = 656, + kX86InstIdCvtps2pd_NameIndex = 665, + kX86InstIdCvtps2pi_NameIndex = 674, + kX86InstIdCvtsd2si_NameIndex = 683, + kX86InstIdCvtsd2ss_NameIndex = 692, + kX86InstIdCvtsi2sd_NameIndex = 701, + kX86InstIdCvtsi2ss_NameIndex = 710, + kX86InstIdCvtss2sd_NameIndex = 719, + kX86InstIdCvtss2si_NameIndex = 728, + kX86InstIdCvttpd2dq_NameIndex = 737, + kX86InstIdCvttpd2pi_NameIndex = 747, + kX86InstIdCvttps2dq_NameIndex = 757, + kX86InstIdCvttps2pi_NameIndex = 767, + kX86InstIdCvttsd2si_NameIndex = 777, + kX86InstIdCvttss2si_NameIndex = 787, + kX86InstIdCwd_NameIndex = 797, + kX86InstIdCwde_NameIndex = 801, + kX86InstIdDaa_NameIndex = 806, + kX86InstIdDas_NameIndex = 810, + kX86InstIdDec_NameIndex = 814, + kX86InstIdDiv_NameIndex = 818, + kX86InstIdDivpd_NameIndex = 822, + kX86InstIdDivps_NameIndex = 828, + kX86InstIdDivsd_NameIndex = 834, + kX86InstIdDivss_NameIndex = 840, + kX86InstIdDppd_NameIndex = 846, + kX86InstIdDpps_NameIndex = 851, + kX86InstIdEmms_NameIndex = 856, + kX86InstIdEnter_NameIndex = 861, + kX86InstIdExtractps_NameIndex = 867, + kX86InstIdF2xm1_NameIndex = 877, + kX86InstIdFabs_NameIndex = 883, + kX86InstIdFadd_NameIndex = 888, + kX86InstIdFaddp_NameIndex = 893, + kX86InstIdFbld_NameIndex = 899, + kX86InstIdFbstp_NameIndex = 904, + kX86InstIdFchs_NameIndex = 910, + kX86InstIdFclex_NameIndex = 915, + kX86InstIdFcmovb_NameIndex = 921, + kX86InstIdFcmovbe_NameIndex = 928, + kX86InstIdFcmove_NameIndex = 936, + kX86InstIdFcmovnb_NameIndex = 943, + kX86InstIdFcmovnbe_NameIndex = 951, + kX86InstIdFcmovne_NameIndex = 960, + kX86InstIdFcmovnu_NameIndex = 968, + kX86InstIdFcmovu_NameIndex = 976, + kX86InstIdFcom_NameIndex = 983, + kX86InstIdFcomi_NameIndex = 988, + kX86InstIdFcomip_NameIndex = 994, + kX86InstIdFcomp_NameIndex = 1001, + kX86InstIdFcompp_NameIndex = 1007, + kX86InstIdFcos_NameIndex = 1014, + kX86InstIdFdecstp_NameIndex = 1019, + kX86InstIdFdiv_NameIndex = 1027, + kX86InstIdFdivp_NameIndex = 1032, + kX86InstIdFdivr_NameIndex = 1038, + kX86InstIdFdivrp_NameIndex = 1044, + kX86InstIdFemms_NameIndex = 1051, + kX86InstIdFfree_NameIndex = 1057, + kX86InstIdFiadd_NameIndex = 1063, + kX86InstIdFicom_NameIndex = 1069, + kX86InstIdFicomp_NameIndex = 1075, + kX86InstIdFidiv_NameIndex = 1082, + kX86InstIdFidivr_NameIndex = 1088, + kX86InstIdFild_NameIndex = 1095, + kX86InstIdFimul_NameIndex = 1100, + kX86InstIdFincstp_NameIndex = 1106, + kX86InstIdFinit_NameIndex = 1114, + kX86InstIdFist_NameIndex = 1120, + kX86InstIdFistp_NameIndex = 1125, + kX86InstIdFisttp_NameIndex = 1131, + kX86InstIdFisub_NameIndex = 1138, + kX86InstIdFisubr_NameIndex = 1144, + kX86InstIdFld_NameIndex = 1151, + kX86InstIdFld1_NameIndex = 1155, + kX86InstIdFldcw_NameIndex = 1160, + kX86InstIdFldenv_NameIndex = 1166, + kX86InstIdFldl2e_NameIndex = 1173, + kX86InstIdFldl2t_NameIndex = 1180, + kX86InstIdFldlg2_NameIndex = 1187, + kX86InstIdFldln2_NameIndex = 1194, + kX86InstIdFldpi_NameIndex = 1201, + kX86InstIdFldz_NameIndex = 1207, + kX86InstIdFmul_NameIndex = 1212, + kX86InstIdFmulp_NameIndex = 1217, + kX86InstIdFnclex_NameIndex = 1223, + kX86InstIdFninit_NameIndex = 1230, + kX86InstIdFnop_NameIndex = 1237, + kX86InstIdFnsave_NameIndex = 1242, + kX86InstIdFnstcw_NameIndex = 1249, + kX86InstIdFnstenv_NameIndex = 1256, + kX86InstIdFnstsw_NameIndex = 1264, + kX86InstIdFpatan_NameIndex = 1271, + kX86InstIdFprem_NameIndex = 1278, + kX86InstIdFprem1_NameIndex = 1284, + kX86InstIdFptan_NameIndex = 1291, + kX86InstIdFrndint_NameIndex = 1297, + kX86InstIdFrstor_NameIndex = 1305, + kX86InstIdFsave_NameIndex = 1312, + kX86InstIdFscale_NameIndex = 1318, + kX86InstIdFsin_NameIndex = 1325, + kX86InstIdFsincos_NameIndex = 1330, + kX86InstIdFsqrt_NameIndex = 1338, + kX86InstIdFst_NameIndex = 1344, + kX86InstIdFstcw_NameIndex = 1348, + kX86InstIdFstenv_NameIndex = 1354, + kX86InstIdFstp_NameIndex = 1361, + kX86InstIdFstsw_NameIndex = 1366, + kX86InstIdFsub_NameIndex = 1372, + kX86InstIdFsubp_NameIndex = 1377, + kX86InstIdFsubr_NameIndex = 1383, + kX86InstIdFsubrp_NameIndex = 1389, + kX86InstIdFtst_NameIndex = 1396, + kX86InstIdFucom_NameIndex = 1401, + kX86InstIdFucomi_NameIndex = 1407, + kX86InstIdFucomip_NameIndex = 1414, + kX86InstIdFucomp_NameIndex = 1422, + kX86InstIdFucompp_NameIndex = 1429, + kX86InstIdFwait_NameIndex = 1437, + kX86InstIdFxam_NameIndex = 1443, + kX86InstIdFxch_NameIndex = 1448, + kX86InstIdFxrstor_NameIndex = 1453, + kX86InstIdFxsave_NameIndex = 1461, + kX86InstIdFxtract_NameIndex = 1468, + kX86InstIdFyl2x_NameIndex = 1476, + kX86InstIdFyl2xp1_NameIndex = 1482, + kX86InstIdHaddpd_NameIndex = 1490, + kX86InstIdHaddps_NameIndex = 1497, + kX86InstIdHsubpd_NameIndex = 1504, + kX86InstIdHsubps_NameIndex = 1511, + kX86InstIdIdiv_NameIndex = 1518, + kX86InstIdImul_NameIndex = 1523, + kX86InstIdInc_NameIndex = 1528, + kX86InstIdInsertps_NameIndex = 1532, + kX86InstIdInt_NameIndex = 1541, + kX86InstIdJa_NameIndex = 1545, + kX86InstIdJae_NameIndex = 1548, + kX86InstIdJb_NameIndex = 1552, + kX86InstIdJbe_NameIndex = 1555, + kX86InstIdJc_NameIndex = 1559, + kX86InstIdJe_NameIndex = 1562, + kX86InstIdJg_NameIndex = 1565, + kX86InstIdJge_NameIndex = 1568, + kX86InstIdJl_NameIndex = 1572, + kX86InstIdJle_NameIndex = 1575, + kX86InstIdJna_NameIndex = 1579, + kX86InstIdJnae_NameIndex = 1583, + kX86InstIdJnb_NameIndex = 1588, + kX86InstIdJnbe_NameIndex = 1592, + kX86InstIdJnc_NameIndex = 1597, + kX86InstIdJne_NameIndex = 1601, + kX86InstIdJng_NameIndex = 1605, + kX86InstIdJnge_NameIndex = 1609, + kX86InstIdJnl_NameIndex = 1614, + kX86InstIdJnle_NameIndex = 1618, + kX86InstIdJno_NameIndex = 1623, + kX86InstIdJnp_NameIndex = 1627, + kX86InstIdJns_NameIndex = 1631, + kX86InstIdJnz_NameIndex = 1635, + kX86InstIdJo_NameIndex = 1639, + kX86InstIdJp_NameIndex = 1642, + kX86InstIdJpe_NameIndex = 1645, + kX86InstIdJpo_NameIndex = 1649, + kX86InstIdJs_NameIndex = 1653, + kX86InstIdJz_NameIndex = 1656, + kX86InstIdJecxz_NameIndex = 1659, + kX86InstIdJmp_NameIndex = 1665, + kX86InstIdLahf_NameIndex = 1669, + kX86InstIdLddqu_NameIndex = 1674, + kX86InstIdLdmxcsr_NameIndex = 1680, + kX86InstIdLea_NameIndex = 1688, + kX86InstIdLeave_NameIndex = 1692, + kX86InstIdLfence_NameIndex = 1698, + kX86InstIdLodsB_NameIndex = 1705, + kX86InstIdLodsD_NameIndex = 1712, + kX86InstIdLodsQ_NameIndex = 1719, + kX86InstIdLodsW_NameIndex = 1726, + kX86InstIdLzcnt_NameIndex = 1733, + kX86InstIdMaskmovdqu_NameIndex = 1739, + kX86InstIdMaskmovq_NameIndex = 1750, + kX86InstIdMaxpd_NameIndex = 1759, + kX86InstIdMaxps_NameIndex = 1765, + kX86InstIdMaxsd_NameIndex = 1771, + kX86InstIdMaxss_NameIndex = 1777, + kX86InstIdMfence_NameIndex = 1783, + kX86InstIdMinpd_NameIndex = 1790, + kX86InstIdMinps_NameIndex = 1796, + kX86InstIdMinsd_NameIndex = 1802, + kX86InstIdMinss_NameIndex = 1808, + kX86InstIdMonitor_NameIndex = 1814, + kX86InstIdMov_NameIndex = 1822, + kX86InstIdMovPtr_NameIndex = 1826, + kX86InstIdMovapd_NameIndex = 1834, + kX86InstIdMovaps_NameIndex = 1841, + kX86InstIdMovbe_NameIndex = 1848, + kX86InstIdMovd_NameIndex = 1854, + kX86InstIdMovddup_NameIndex = 1859, + kX86InstIdMovdq2q_NameIndex = 1867, + kX86InstIdMovdqa_NameIndex = 1875, + kX86InstIdMovdqu_NameIndex = 1882, + kX86InstIdMovhlps_NameIndex = 1889, + kX86InstIdMovhpd_NameIndex = 1897, + kX86InstIdMovhps_NameIndex = 1904, + kX86InstIdMovlhps_NameIndex = 1911, + kX86InstIdMovlpd_NameIndex = 1919, + kX86InstIdMovlps_NameIndex = 1926, + kX86InstIdMovmskpd_NameIndex = 1933, + kX86InstIdMovmskps_NameIndex = 1942, + kX86InstIdMovntdq_NameIndex = 1951, + kX86InstIdMovntdqa_NameIndex = 1959, + kX86InstIdMovnti_NameIndex = 1968, + kX86InstIdMovntpd_NameIndex = 1975, + kX86InstIdMovntps_NameIndex = 1983, + kX86InstIdMovntq_NameIndex = 1991, + kX86InstIdMovq_NameIndex = 1998, + kX86InstIdMovq2dq_NameIndex = 2003, + kX86InstIdMovsB_NameIndex = 2011, + kX86InstIdMovsD_NameIndex = 2018, + kX86InstIdMovsQ_NameIndex = 2025, + kX86InstIdMovsW_NameIndex = 2032, + kX86InstIdMovsd_NameIndex = 2039, + kX86InstIdMovshdup_NameIndex = 2045, + kX86InstIdMovsldup_NameIndex = 2054, + kX86InstIdMovss_NameIndex = 2063, + kX86InstIdMovsx_NameIndex = 2069, + kX86InstIdMovsxd_NameIndex = 2075, + kX86InstIdMovupd_NameIndex = 2082, + kX86InstIdMovups_NameIndex = 2089, + kX86InstIdMovzx_NameIndex = 2096, + kX86InstIdMpsadbw_NameIndex = 2102, + kX86InstIdMul_NameIndex = 2110, + kX86InstIdMulpd_NameIndex = 2114, + kX86InstIdMulps_NameIndex = 2120, + kX86InstIdMulsd_NameIndex = 2126, + kX86InstIdMulss_NameIndex = 2132, + kX86InstIdMulx_NameIndex = 2138, + kX86InstIdMwait_NameIndex = 2143, + kX86InstIdNeg_NameIndex = 2149, + kX86InstIdNop_NameIndex = 2153, + kX86InstIdNot_NameIndex = 2157, + kX86InstIdOr_NameIndex = 2161, + kX86InstIdOrpd_NameIndex = 2164, + kX86InstIdOrps_NameIndex = 2169, + kX86InstIdPabsb_NameIndex = 2174, + kX86InstIdPabsd_NameIndex = 2180, + kX86InstIdPabsw_NameIndex = 2186, + kX86InstIdPackssdw_NameIndex = 2192, + kX86InstIdPacksswb_NameIndex = 2201, + kX86InstIdPackusdw_NameIndex = 2210, + kX86InstIdPackuswb_NameIndex = 2219, + kX86InstIdPaddb_NameIndex = 2228, + kX86InstIdPaddd_NameIndex = 2234, + kX86InstIdPaddq_NameIndex = 2240, + kX86InstIdPaddsb_NameIndex = 2246, + kX86InstIdPaddsw_NameIndex = 2253, + kX86InstIdPaddusb_NameIndex = 2260, + kX86InstIdPaddusw_NameIndex = 2268, + kX86InstIdPaddw_NameIndex = 2276, + kX86InstIdPalignr_NameIndex = 2282, + kX86InstIdPand_NameIndex = 2290, + kX86InstIdPandn_NameIndex = 2295, + kX86InstIdPause_NameIndex = 2301, + kX86InstIdPavgb_NameIndex = 2307, + kX86InstIdPavgw_NameIndex = 2313, + kX86InstIdPblendvb_NameIndex = 2319, + kX86InstIdPblendw_NameIndex = 2328, + kX86InstIdPclmulqdq_NameIndex = 2336, + kX86InstIdPcmpeqb_NameIndex = 2346, + kX86InstIdPcmpeqd_NameIndex = 2354, + kX86InstIdPcmpeqq_NameIndex = 2362, + kX86InstIdPcmpeqw_NameIndex = 2370, + kX86InstIdPcmpestri_NameIndex = 2378, + kX86InstIdPcmpestrm_NameIndex = 2388, + kX86InstIdPcmpgtb_NameIndex = 2398, + kX86InstIdPcmpgtd_NameIndex = 2406, + kX86InstIdPcmpgtq_NameIndex = 2414, + kX86InstIdPcmpgtw_NameIndex = 2422, + kX86InstIdPcmpistri_NameIndex = 2430, + kX86InstIdPcmpistrm_NameIndex = 2440, + kX86InstIdPdep_NameIndex = 2450, + kX86InstIdPext_NameIndex = 2455, + kX86InstIdPextrb_NameIndex = 2460, + kX86InstIdPextrd_NameIndex = 2467, + kX86InstIdPextrq_NameIndex = 2474, + kX86InstIdPextrw_NameIndex = 2481, + kX86InstIdPf2id_NameIndex = 2488, + kX86InstIdPf2iw_NameIndex = 2494, + kX86InstIdPfacc_NameIndex = 2500, + kX86InstIdPfadd_NameIndex = 2506, + kX86InstIdPfcmpeq_NameIndex = 2512, + kX86InstIdPfcmpge_NameIndex = 2520, + kX86InstIdPfcmpgt_NameIndex = 2528, + kX86InstIdPfmax_NameIndex = 2536, + kX86InstIdPfmin_NameIndex = 2542, + kX86InstIdPfmul_NameIndex = 2548, + kX86InstIdPfnacc_NameIndex = 2554, + kX86InstIdPfpnacc_NameIndex = 2561, + kX86InstIdPfrcp_NameIndex = 2569, + kX86InstIdPfrcpit1_NameIndex = 2575, + kX86InstIdPfrcpit2_NameIndex = 2584, + kX86InstIdPfrsqit1_NameIndex = 2593, + kX86InstIdPfrsqrt_NameIndex = 2602, + kX86InstIdPfsub_NameIndex = 2610, + kX86InstIdPfsubr_NameIndex = 2616, + kX86InstIdPhaddd_NameIndex = 2623, + kX86InstIdPhaddsw_NameIndex = 2630, + kX86InstIdPhaddw_NameIndex = 2638, + kX86InstIdPhminposuw_NameIndex = 2645, + kX86InstIdPhsubd_NameIndex = 2656, + kX86InstIdPhsubsw_NameIndex = 2663, + kX86InstIdPhsubw_NameIndex = 2671, + kX86InstIdPi2fd_NameIndex = 2678, + kX86InstIdPi2fw_NameIndex = 2684, + kX86InstIdPinsrb_NameIndex = 2690, + kX86InstIdPinsrd_NameIndex = 2697, + kX86InstIdPinsrq_NameIndex = 2704, + kX86InstIdPinsrw_NameIndex = 2711, + kX86InstIdPmaddubsw_NameIndex = 2718, + kX86InstIdPmaddwd_NameIndex = 2728, + kX86InstIdPmaxsb_NameIndex = 2736, + kX86InstIdPmaxsd_NameIndex = 2743, + kX86InstIdPmaxsw_NameIndex = 2750, + kX86InstIdPmaxub_NameIndex = 2757, + kX86InstIdPmaxud_NameIndex = 2764, + kX86InstIdPmaxuw_NameIndex = 2771, + kX86InstIdPminsb_NameIndex = 2778, + kX86InstIdPminsd_NameIndex = 2785, + kX86InstIdPminsw_NameIndex = 2792, + kX86InstIdPminub_NameIndex = 2799, + kX86InstIdPminud_NameIndex = 2806, + kX86InstIdPminuw_NameIndex = 2813, + kX86InstIdPmovmskb_NameIndex = 2820, + kX86InstIdPmovsxbd_NameIndex = 2829, + kX86InstIdPmovsxbq_NameIndex = 2838, + kX86InstIdPmovsxbw_NameIndex = 2847, + kX86InstIdPmovsxdq_NameIndex = 2856, + kX86InstIdPmovsxwd_NameIndex = 2865, + kX86InstIdPmovsxwq_NameIndex = 2874, + kX86InstIdPmovzxbd_NameIndex = 2883, + kX86InstIdPmovzxbq_NameIndex = 2892, + kX86InstIdPmovzxbw_NameIndex = 2901, + kX86InstIdPmovzxdq_NameIndex = 2910, + kX86InstIdPmovzxwd_NameIndex = 2919, + kX86InstIdPmovzxwq_NameIndex = 2928, + kX86InstIdPmuldq_NameIndex = 2937, + kX86InstIdPmulhrsw_NameIndex = 2944, + kX86InstIdPmulhuw_NameIndex = 2953, + kX86InstIdPmulhw_NameIndex = 2961, + kX86InstIdPmulld_NameIndex = 2968, + kX86InstIdPmullw_NameIndex = 2975, + kX86InstIdPmuludq_NameIndex = 2982, + kX86InstIdPop_NameIndex = 2990, + kX86InstIdPopa_NameIndex = 2994, + kX86InstIdPopcnt_NameIndex = 2999, + kX86InstIdPopf_NameIndex = 3006, + kX86InstIdPor_NameIndex = 3011, + kX86InstIdPrefetch_NameIndex = 3015, + kX86InstIdPrefetch3dNow_NameIndex = 3024, + kX86InstIdPrefetchw3dNow_NameIndex = 3039, + kX86InstIdPsadbw_NameIndex = 3055, + kX86InstIdPshufb_NameIndex = 3062, + kX86InstIdPshufd_NameIndex = 3069, + kX86InstIdPshufhw_NameIndex = 3076, + kX86InstIdPshuflw_NameIndex = 3084, + kX86InstIdPshufw_NameIndex = 3092, + kX86InstIdPsignb_NameIndex = 3099, + kX86InstIdPsignd_NameIndex = 3106, + kX86InstIdPsignw_NameIndex = 3113, + kX86InstIdPslld_NameIndex = 3120, + kX86InstIdPslldq_NameIndex = 3126, + kX86InstIdPsllq_NameIndex = 3133, + kX86InstIdPsllw_NameIndex = 3139, + kX86InstIdPsrad_NameIndex = 3145, + kX86InstIdPsraw_NameIndex = 3151, + kX86InstIdPsrld_NameIndex = 3157, + kX86InstIdPsrldq_NameIndex = 3163, + kX86InstIdPsrlq_NameIndex = 3170, + kX86InstIdPsrlw_NameIndex = 3176, + kX86InstIdPsubb_NameIndex = 3182, + kX86InstIdPsubd_NameIndex = 3188, + kX86InstIdPsubq_NameIndex = 3194, + kX86InstIdPsubsb_NameIndex = 3200, + kX86InstIdPsubsw_NameIndex = 3207, + kX86InstIdPsubusb_NameIndex = 3214, + kX86InstIdPsubusw_NameIndex = 3222, + kX86InstIdPsubw_NameIndex = 3230, + kX86InstIdPswapd_NameIndex = 3236, + kX86InstIdPtest_NameIndex = 3243, + kX86InstIdPunpckhbw_NameIndex = 3249, + kX86InstIdPunpckhdq_NameIndex = 3259, + kX86InstIdPunpckhqdq_NameIndex = 3269, + kX86InstIdPunpckhwd_NameIndex = 3280, + kX86InstIdPunpcklbw_NameIndex = 3290, + kX86InstIdPunpckldq_NameIndex = 3300, + kX86InstIdPunpcklqdq_NameIndex = 3310, + kX86InstIdPunpcklwd_NameIndex = 3321, + kX86InstIdPush_NameIndex = 3331, + kX86InstIdPusha_NameIndex = 3336, + kX86InstIdPushf_NameIndex = 3342, + kX86InstIdPxor_NameIndex = 3348, + kX86InstIdRcl_NameIndex = 3353, + kX86InstIdRcpps_NameIndex = 3357, + kX86InstIdRcpss_NameIndex = 3363, + kX86InstIdRcr_NameIndex = 3369, + kX86InstIdRdfsbase_NameIndex = 3373, + kX86InstIdRdgsbase_NameIndex = 3382, + kX86InstIdRdrand_NameIndex = 3391, + kX86InstIdRdtsc_NameIndex = 3398, + kX86InstIdRdtscp_NameIndex = 3404, + kX86InstIdRepLodsB_NameIndex = 3411, + kX86InstIdRepLodsD_NameIndex = 3422, + kX86InstIdRepLodsQ_NameIndex = 3433, + kX86InstIdRepLodsW_NameIndex = 3444, + kX86InstIdRepMovsB_NameIndex = 3455, + kX86InstIdRepMovsD_NameIndex = 3466, + kX86InstIdRepMovsQ_NameIndex = 3477, + kX86InstIdRepMovsW_NameIndex = 3488, + kX86InstIdRepStosB_NameIndex = 3499, + kX86InstIdRepStosD_NameIndex = 3510, + kX86InstIdRepStosQ_NameIndex = 3521, + kX86InstIdRepStosW_NameIndex = 3532, + kX86InstIdRepeCmpsB_NameIndex = 3543, + kX86InstIdRepeCmpsD_NameIndex = 3555, + kX86InstIdRepeCmpsQ_NameIndex = 3567, + kX86InstIdRepeCmpsW_NameIndex = 3579, + kX86InstIdRepeScasB_NameIndex = 3591, + kX86InstIdRepeScasD_NameIndex = 3603, + kX86InstIdRepeScasQ_NameIndex = 3615, + kX86InstIdRepeScasW_NameIndex = 3627, + kX86InstIdRepneCmpsB_NameIndex = 3639, + kX86InstIdRepneCmpsD_NameIndex = 3652, + kX86InstIdRepneCmpsQ_NameIndex = 3665, + kX86InstIdRepneCmpsW_NameIndex = 3678, + kX86InstIdRepneScasB_NameIndex = 3691, + kX86InstIdRepneScasD_NameIndex = 3704, + kX86InstIdRepneScasQ_NameIndex = 3717, + kX86InstIdRepneScasW_NameIndex = 3730, + kX86InstIdRet_NameIndex = 3743, + kX86InstIdRol_NameIndex = 3747, + kX86InstIdRor_NameIndex = 3751, + kX86InstIdRorx_NameIndex = 3755, + kX86InstIdRoundpd_NameIndex = 3760, + kX86InstIdRoundps_NameIndex = 3768, + kX86InstIdRoundsd_NameIndex = 3776, + kX86InstIdRoundss_NameIndex = 3784, + kX86InstIdRsqrtps_NameIndex = 3792, + kX86InstIdRsqrtss_NameIndex = 3800, + kX86InstIdSahf_NameIndex = 3808, + kX86InstIdSal_NameIndex = 3813, + kX86InstIdSar_NameIndex = 3817, + kX86InstIdSarx_NameIndex = 3821, + kX86InstIdSbb_NameIndex = 3826, + kX86InstIdScasB_NameIndex = 3830, + kX86InstIdScasD_NameIndex = 3837, + kX86InstIdScasQ_NameIndex = 3844, + kX86InstIdScasW_NameIndex = 3851, + kX86InstIdSeta_NameIndex = 3858, + kX86InstIdSetae_NameIndex = 3863, + kX86InstIdSetb_NameIndex = 3869, + kX86InstIdSetbe_NameIndex = 3874, + kX86InstIdSetc_NameIndex = 3880, + kX86InstIdSete_NameIndex = 3885, + kX86InstIdSetg_NameIndex = 3890, + kX86InstIdSetge_NameIndex = 3895, + kX86InstIdSetl_NameIndex = 3901, + kX86InstIdSetle_NameIndex = 3906, + kX86InstIdSetna_NameIndex = 3912, + kX86InstIdSetnae_NameIndex = 3918, + kX86InstIdSetnb_NameIndex = 3925, + kX86InstIdSetnbe_NameIndex = 3931, + kX86InstIdSetnc_NameIndex = 3938, + kX86InstIdSetne_NameIndex = 3944, + kX86InstIdSetng_NameIndex = 3950, + kX86InstIdSetnge_NameIndex = 3956, + kX86InstIdSetnl_NameIndex = 3963, + kX86InstIdSetnle_NameIndex = 3969, + kX86InstIdSetno_NameIndex = 3976, + kX86InstIdSetnp_NameIndex = 3982, + kX86InstIdSetns_NameIndex = 3988, + kX86InstIdSetnz_NameIndex = 3994, + kX86InstIdSeto_NameIndex = 4000, + kX86InstIdSetp_NameIndex = 4005, + kX86InstIdSetpe_NameIndex = 4010, + kX86InstIdSetpo_NameIndex = 4016, + kX86InstIdSets_NameIndex = 4022, + kX86InstIdSetz_NameIndex = 4027, + kX86InstIdSfence_NameIndex = 4032, + kX86InstIdShl_NameIndex = 4039, + kX86InstIdShld_NameIndex = 4043, + kX86InstIdShlx_NameIndex = 4048, + kX86InstIdShr_NameIndex = 4053, + kX86InstIdShrd_NameIndex = 4057, + kX86InstIdShrx_NameIndex = 4062, + kX86InstIdShufpd_NameIndex = 4067, + kX86InstIdShufps_NameIndex = 4074, + kX86InstIdSqrtpd_NameIndex = 4081, + kX86InstIdSqrtps_NameIndex = 4088, + kX86InstIdSqrtsd_NameIndex = 4095, + kX86InstIdSqrtss_NameIndex = 4102, + kX86InstIdStc_NameIndex = 4109, + kX86InstIdStd_NameIndex = 4113, + kX86InstIdStmxcsr_NameIndex = 4117, + kX86InstIdStosB_NameIndex = 4125, + kX86InstIdStosD_NameIndex = 4132, + kX86InstIdStosQ_NameIndex = 4139, + kX86InstIdStosW_NameIndex = 4146, + kX86InstIdSub_NameIndex = 4153, + kX86InstIdSubpd_NameIndex = 4157, + kX86InstIdSubps_NameIndex = 4163, + kX86InstIdSubsd_NameIndex = 4169, + kX86InstIdSubss_NameIndex = 4175, + kX86InstIdTest_NameIndex = 4181, + kX86InstIdTzcnt_NameIndex = 4186, + kX86InstIdUcomisd_NameIndex = 4192, + kX86InstIdUcomiss_NameIndex = 4200, + kX86InstIdUd2_NameIndex = 4208, + kX86InstIdUnpckhpd_NameIndex = 4212, + kX86InstIdUnpckhps_NameIndex = 4221, + kX86InstIdUnpcklpd_NameIndex = 4230, + kX86InstIdUnpcklps_NameIndex = 4239, + kX86InstIdVaddpd_NameIndex = 4248, + kX86InstIdVaddps_NameIndex = 4255, + kX86InstIdVaddsd_NameIndex = 4262, + kX86InstIdVaddss_NameIndex = 4269, + kX86InstIdVaddsubpd_NameIndex = 4276, + kX86InstIdVaddsubps_NameIndex = 4286, + kX86InstIdVaesdec_NameIndex = 4296, + kX86InstIdVaesdeclast_NameIndex = 4304, + kX86InstIdVaesenc_NameIndex = 4316, + kX86InstIdVaesenclast_NameIndex = 4324, + kX86InstIdVaesimc_NameIndex = 4336, + kX86InstIdVaeskeygenassist_NameIndex = 4344, + kX86InstIdVandnpd_NameIndex = 4361, + kX86InstIdVandnps_NameIndex = 4369, + kX86InstIdVandpd_NameIndex = 4377, + kX86InstIdVandps_NameIndex = 4384, + kX86InstIdVblendpd_NameIndex = 4391, + kX86InstIdVblendps_NameIndex = 4400, + kX86InstIdVblendvpd_NameIndex = 4409, + kX86InstIdVblendvps_NameIndex = 4419, + kX86InstIdVbroadcastf128_NameIndex = 4429, + kX86InstIdVbroadcasti128_NameIndex = 4444, + kX86InstIdVbroadcastsd_NameIndex = 4459, + kX86InstIdVbroadcastss_NameIndex = 4472, + kX86InstIdVcmppd_NameIndex = 4485, + kX86InstIdVcmpps_NameIndex = 4492, + kX86InstIdVcmpsd_NameIndex = 4499, + kX86InstIdVcmpss_NameIndex = 4506, + kX86InstIdVcomisd_NameIndex = 4513, + kX86InstIdVcomiss_NameIndex = 4521, + kX86InstIdVcvtdq2pd_NameIndex = 4529, + kX86InstIdVcvtdq2ps_NameIndex = 4539, + kX86InstIdVcvtpd2dq_NameIndex = 4549, + kX86InstIdVcvtpd2ps_NameIndex = 4559, + kX86InstIdVcvtph2ps_NameIndex = 4569, + kX86InstIdVcvtps2dq_NameIndex = 4579, + kX86InstIdVcvtps2pd_NameIndex = 4589, + kX86InstIdVcvtps2ph_NameIndex = 4599, + kX86InstIdVcvtsd2si_NameIndex = 4609, + kX86InstIdVcvtsd2ss_NameIndex = 4619, + kX86InstIdVcvtsi2sd_NameIndex = 4629, + kX86InstIdVcvtsi2ss_NameIndex = 4639, + kX86InstIdVcvtss2sd_NameIndex = 4649, + kX86InstIdVcvtss2si_NameIndex = 4659, + kX86InstIdVcvttpd2dq_NameIndex = 4669, + kX86InstIdVcvttps2dq_NameIndex = 4680, + kX86InstIdVcvttsd2si_NameIndex = 4691, + kX86InstIdVcvttss2si_NameIndex = 4702, + kX86InstIdVdivpd_NameIndex = 4713, + kX86InstIdVdivps_NameIndex = 4720, + kX86InstIdVdivsd_NameIndex = 4727, + kX86InstIdVdivss_NameIndex = 4734, + kX86InstIdVdppd_NameIndex = 4741, + kX86InstIdVdpps_NameIndex = 4747, + kX86InstIdVextractf128_NameIndex = 4753, + kX86InstIdVextracti128_NameIndex = 4766, + kX86InstIdVextractps_NameIndex = 4779, + kX86InstIdVfmadd132pd_NameIndex = 4790, + kX86InstIdVfmadd132ps_NameIndex = 4802, + kX86InstIdVfmadd132sd_NameIndex = 4814, + kX86InstIdVfmadd132ss_NameIndex = 4826, + kX86InstIdVfmadd213pd_NameIndex = 4838, + kX86InstIdVfmadd213ps_NameIndex = 4850, + kX86InstIdVfmadd213sd_NameIndex = 4862, + kX86InstIdVfmadd213ss_NameIndex = 4874, + kX86InstIdVfmadd231pd_NameIndex = 4886, + kX86InstIdVfmadd231ps_NameIndex = 4898, + kX86InstIdVfmadd231sd_NameIndex = 4910, + kX86InstIdVfmadd231ss_NameIndex = 4922, + kX86InstIdVfmaddpd_NameIndex = 4934, + kX86InstIdVfmaddps_NameIndex = 4943, + kX86InstIdVfmaddsd_NameIndex = 4952, + kX86InstIdVfmaddss_NameIndex = 4961, + kX86InstIdVfmaddsub132pd_NameIndex = 4970, + kX86InstIdVfmaddsub132ps_NameIndex = 4985, + kX86InstIdVfmaddsub213pd_NameIndex = 5000, + kX86InstIdVfmaddsub213ps_NameIndex = 5015, + kX86InstIdVfmaddsub231pd_NameIndex = 5030, + kX86InstIdVfmaddsub231ps_NameIndex = 5045, + kX86InstIdVfmaddsubpd_NameIndex = 5060, + kX86InstIdVfmaddsubps_NameIndex = 5072, + kX86InstIdVfmsub132pd_NameIndex = 5084, + kX86InstIdVfmsub132ps_NameIndex = 5096, + kX86InstIdVfmsub132sd_NameIndex = 5108, + kX86InstIdVfmsub132ss_NameIndex = 5120, + kX86InstIdVfmsub213pd_NameIndex = 5132, + kX86InstIdVfmsub213ps_NameIndex = 5144, + kX86InstIdVfmsub213sd_NameIndex = 5156, + kX86InstIdVfmsub213ss_NameIndex = 5168, + kX86InstIdVfmsub231pd_NameIndex = 5180, + kX86InstIdVfmsub231ps_NameIndex = 5192, + kX86InstIdVfmsub231sd_NameIndex = 5204, + kX86InstIdVfmsub231ss_NameIndex = 5216, + kX86InstIdVfmsubadd132pd_NameIndex = 5228, + kX86InstIdVfmsubadd132ps_NameIndex = 5243, + kX86InstIdVfmsubadd213pd_NameIndex = 5258, + kX86InstIdVfmsubadd213ps_NameIndex = 5273, + kX86InstIdVfmsubadd231pd_NameIndex = 5288, + kX86InstIdVfmsubadd231ps_NameIndex = 5303, + kX86InstIdVfmsubaddpd_NameIndex = 5318, + kX86InstIdVfmsubaddps_NameIndex = 5330, + kX86InstIdVfmsubpd_NameIndex = 5342, + kX86InstIdVfmsubps_NameIndex = 5351, + kX86InstIdVfmsubsd_NameIndex = 5360, + kX86InstIdVfmsubss_NameIndex = 5369, + kX86InstIdVfnmadd132pd_NameIndex = 5378, + kX86InstIdVfnmadd132ps_NameIndex = 5391, + kX86InstIdVfnmadd132sd_NameIndex = 5404, + kX86InstIdVfnmadd132ss_NameIndex = 5417, + kX86InstIdVfnmadd213pd_NameIndex = 5430, + kX86InstIdVfnmadd213ps_NameIndex = 5443, + kX86InstIdVfnmadd213sd_NameIndex = 5456, + kX86InstIdVfnmadd213ss_NameIndex = 5469, + kX86InstIdVfnmadd231pd_NameIndex = 5482, + kX86InstIdVfnmadd231ps_NameIndex = 5495, + kX86InstIdVfnmadd231sd_NameIndex = 5508, + kX86InstIdVfnmadd231ss_NameIndex = 5521, + kX86InstIdVfnmaddpd_NameIndex = 5534, + kX86InstIdVfnmaddps_NameIndex = 5544, + kX86InstIdVfnmaddsd_NameIndex = 5554, + kX86InstIdVfnmaddss_NameIndex = 5564, + kX86InstIdVfnmsub132pd_NameIndex = 5574, + kX86InstIdVfnmsub132ps_NameIndex = 5587, + kX86InstIdVfnmsub132sd_NameIndex = 5600, + kX86InstIdVfnmsub132ss_NameIndex = 5613, + kX86InstIdVfnmsub213pd_NameIndex = 5626, + kX86InstIdVfnmsub213ps_NameIndex = 5639, + kX86InstIdVfnmsub213sd_NameIndex = 5652, + kX86InstIdVfnmsub213ss_NameIndex = 5665, + kX86InstIdVfnmsub231pd_NameIndex = 5678, + kX86InstIdVfnmsub231ps_NameIndex = 5691, + kX86InstIdVfnmsub231sd_NameIndex = 5704, + kX86InstIdVfnmsub231ss_NameIndex = 5717, + kX86InstIdVfnmsubpd_NameIndex = 5730, + kX86InstIdVfnmsubps_NameIndex = 5740, + kX86InstIdVfnmsubsd_NameIndex = 5750, + kX86InstIdVfnmsubss_NameIndex = 5760, + kX86InstIdVfrczpd_NameIndex = 5770, + kX86InstIdVfrczps_NameIndex = 5778, + kX86InstIdVfrczsd_NameIndex = 5786, + kX86InstIdVfrczss_NameIndex = 5794, + kX86InstIdVgatherdpd_NameIndex = 5802, + kX86InstIdVgatherdps_NameIndex = 5813, + kX86InstIdVgatherqpd_NameIndex = 5824, + kX86InstIdVgatherqps_NameIndex = 5835, + kX86InstIdVhaddpd_NameIndex = 5846, + kX86InstIdVhaddps_NameIndex = 5854, + kX86InstIdVhsubpd_NameIndex = 5862, + kX86InstIdVhsubps_NameIndex = 5870, + kX86InstIdVinsertf128_NameIndex = 5878, + kX86InstIdVinserti128_NameIndex = 5890, + kX86InstIdVinsertps_NameIndex = 5902, + kX86InstIdVlddqu_NameIndex = 5912, + kX86InstIdVldmxcsr_NameIndex = 5919, + kX86InstIdVmaskmovdqu_NameIndex = 5928, + kX86InstIdVmaskmovpd_NameIndex = 5940, + kX86InstIdVmaskmovps_NameIndex = 5951, + kX86InstIdVmaxpd_NameIndex = 5962, + kX86InstIdVmaxps_NameIndex = 5969, + kX86InstIdVmaxsd_NameIndex = 5976, + kX86InstIdVmaxss_NameIndex = 5983, + kX86InstIdVminpd_NameIndex = 5990, + kX86InstIdVminps_NameIndex = 5997, + kX86InstIdVminsd_NameIndex = 6004, + kX86InstIdVminss_NameIndex = 6011, + kX86InstIdVmovapd_NameIndex = 6018, + kX86InstIdVmovaps_NameIndex = 6026, + kX86InstIdVmovd_NameIndex = 6034, + kX86InstIdVmovddup_NameIndex = 6040, + kX86InstIdVmovdqa_NameIndex = 6049, + kX86InstIdVmovdqu_NameIndex = 6057, + kX86InstIdVmovhlps_NameIndex = 6065, + kX86InstIdVmovhpd_NameIndex = 6074, + kX86InstIdVmovhps_NameIndex = 6082, + kX86InstIdVmovlhps_NameIndex = 6090, + kX86InstIdVmovlpd_NameIndex = 6099, + kX86InstIdVmovlps_NameIndex = 6107, + kX86InstIdVmovmskpd_NameIndex = 6115, + kX86InstIdVmovmskps_NameIndex = 6125, + kX86InstIdVmovntdq_NameIndex = 6135, + kX86InstIdVmovntdqa_NameIndex = 6144, + kX86InstIdVmovntpd_NameIndex = 6154, + kX86InstIdVmovntps_NameIndex = 6163, + kX86InstIdVmovq_NameIndex = 6172, + kX86InstIdVmovsd_NameIndex = 6178, + kX86InstIdVmovshdup_NameIndex = 6185, + kX86InstIdVmovsldup_NameIndex = 6195, + kX86InstIdVmovss_NameIndex = 6205, + kX86InstIdVmovupd_NameIndex = 6212, + kX86InstIdVmovups_NameIndex = 6220, + kX86InstIdVmpsadbw_NameIndex = 6228, + kX86InstIdVmulpd_NameIndex = 6237, + kX86InstIdVmulps_NameIndex = 6244, + kX86InstIdVmulsd_NameIndex = 6251, + kX86InstIdVmulss_NameIndex = 6258, + kX86InstIdVorpd_NameIndex = 6265, + kX86InstIdVorps_NameIndex = 6271, + kX86InstIdVpabsb_NameIndex = 6277, + kX86InstIdVpabsd_NameIndex = 6284, + kX86InstIdVpabsw_NameIndex = 6291, + kX86InstIdVpackssdw_NameIndex = 6298, + kX86InstIdVpacksswb_NameIndex = 6308, + kX86InstIdVpackusdw_NameIndex = 6318, + kX86InstIdVpackuswb_NameIndex = 6328, + kX86InstIdVpaddb_NameIndex = 6338, + kX86InstIdVpaddd_NameIndex = 6345, + kX86InstIdVpaddq_NameIndex = 6352, + kX86InstIdVpaddsb_NameIndex = 6359, + kX86InstIdVpaddsw_NameIndex = 6367, + kX86InstIdVpaddusb_NameIndex = 6375, + kX86InstIdVpaddusw_NameIndex = 6384, + kX86InstIdVpaddw_NameIndex = 6393, + kX86InstIdVpalignr_NameIndex = 6400, + kX86InstIdVpand_NameIndex = 6409, + kX86InstIdVpandn_NameIndex = 6415, + kX86InstIdVpavgb_NameIndex = 6422, + kX86InstIdVpavgw_NameIndex = 6429, + kX86InstIdVpblendd_NameIndex = 6436, + kX86InstIdVpblendvb_NameIndex = 6445, + kX86InstIdVpblendw_NameIndex = 6455, + kX86InstIdVpbroadcastb_NameIndex = 6464, + kX86InstIdVpbroadcastd_NameIndex = 6477, + kX86InstIdVpbroadcastq_NameIndex = 6490, + kX86InstIdVpbroadcastw_NameIndex = 6503, + kX86InstIdVpclmulqdq_NameIndex = 6516, + kX86InstIdVpcmov_NameIndex = 6527, + kX86InstIdVpcmpeqb_NameIndex = 6534, + kX86InstIdVpcmpeqd_NameIndex = 6543, + kX86InstIdVpcmpeqq_NameIndex = 6552, + kX86InstIdVpcmpeqw_NameIndex = 6561, + kX86InstIdVpcmpestri_NameIndex = 6570, + kX86InstIdVpcmpestrm_NameIndex = 6581, + kX86InstIdVpcmpgtb_NameIndex = 6592, + kX86InstIdVpcmpgtd_NameIndex = 6601, + kX86InstIdVpcmpgtq_NameIndex = 6610, + kX86InstIdVpcmpgtw_NameIndex = 6619, + kX86InstIdVpcmpistri_NameIndex = 6628, + kX86InstIdVpcmpistrm_NameIndex = 6639, + kX86InstIdVpcomb_NameIndex = 6650, + kX86InstIdVpcomd_NameIndex = 6657, + kX86InstIdVpcomq_NameIndex = 6664, + kX86InstIdVpcomub_NameIndex = 6671, + kX86InstIdVpcomud_NameIndex = 6679, + kX86InstIdVpcomuq_NameIndex = 6687, + kX86InstIdVpcomuw_NameIndex = 6695, + kX86InstIdVpcomw_NameIndex = 6703, + kX86InstIdVperm2f128_NameIndex = 6710, + kX86InstIdVperm2i128_NameIndex = 6721, + kX86InstIdVpermd_NameIndex = 6732, + kX86InstIdVpermil2pd_NameIndex = 6739, + kX86InstIdVpermil2ps_NameIndex = 6750, + kX86InstIdVpermilpd_NameIndex = 6761, + kX86InstIdVpermilps_NameIndex = 6771, + kX86InstIdVpermpd_NameIndex = 6781, + kX86InstIdVpermps_NameIndex = 6789, + kX86InstIdVpermq_NameIndex = 6797, + kX86InstIdVpextrb_NameIndex = 6804, + kX86InstIdVpextrd_NameIndex = 6812, + kX86InstIdVpextrq_NameIndex = 6820, + kX86InstIdVpextrw_NameIndex = 6828, + kX86InstIdVpgatherdd_NameIndex = 6836, + kX86InstIdVpgatherdq_NameIndex = 6847, + kX86InstIdVpgatherqd_NameIndex = 6858, + kX86InstIdVpgatherqq_NameIndex = 6869, + kX86InstIdVphaddbd_NameIndex = 6880, + kX86InstIdVphaddbq_NameIndex = 6889, + kX86InstIdVphaddbw_NameIndex = 6898, + kX86InstIdVphaddd_NameIndex = 6907, + kX86InstIdVphadddq_NameIndex = 6915, + kX86InstIdVphaddsw_NameIndex = 6924, + kX86InstIdVphaddubd_NameIndex = 6933, + kX86InstIdVphaddubq_NameIndex = 6943, + kX86InstIdVphaddubw_NameIndex = 6953, + kX86InstIdVphaddudq_NameIndex = 6963, + kX86InstIdVphadduwd_NameIndex = 6973, + kX86InstIdVphadduwq_NameIndex = 6983, + kX86InstIdVphaddw_NameIndex = 6993, + kX86InstIdVphaddwd_NameIndex = 7001, + kX86InstIdVphaddwq_NameIndex = 7010, + kX86InstIdVphminposuw_NameIndex = 7019, + kX86InstIdVphsubbw_NameIndex = 7031, + kX86InstIdVphsubd_NameIndex = 7040, + kX86InstIdVphsubdq_NameIndex = 7048, + kX86InstIdVphsubsw_NameIndex = 7057, + kX86InstIdVphsubw_NameIndex = 7066, + kX86InstIdVphsubwd_NameIndex = 7074, + kX86InstIdVpinsrb_NameIndex = 7083, + kX86InstIdVpinsrd_NameIndex = 7091, + kX86InstIdVpinsrq_NameIndex = 7099, + kX86InstIdVpinsrw_NameIndex = 7107, + kX86InstIdVpmacsdd_NameIndex = 7115, + kX86InstIdVpmacsdqh_NameIndex = 7124, + kX86InstIdVpmacsdql_NameIndex = 7134, + kX86InstIdVpmacssdd_NameIndex = 7144, + kX86InstIdVpmacssdqh_NameIndex = 7154, + kX86InstIdVpmacssdql_NameIndex = 7165, + kX86InstIdVpmacsswd_NameIndex = 7176, + kX86InstIdVpmacssww_NameIndex = 7186, + kX86InstIdVpmacswd_NameIndex = 7196, + kX86InstIdVpmacsww_NameIndex = 7205, + kX86InstIdVpmadcsswd_NameIndex = 7214, + kX86InstIdVpmadcswd_NameIndex = 7225, + kX86InstIdVpmaddubsw_NameIndex = 7235, + kX86InstIdVpmaddwd_NameIndex = 7246, + kX86InstIdVpmaskmovd_NameIndex = 7255, + kX86InstIdVpmaskmovq_NameIndex = 7266, + kX86InstIdVpmaxsb_NameIndex = 7277, + kX86InstIdVpmaxsd_NameIndex = 7285, + kX86InstIdVpmaxsw_NameIndex = 7293, + kX86InstIdVpmaxub_NameIndex = 7301, + kX86InstIdVpmaxud_NameIndex = 7309, + kX86InstIdVpmaxuw_NameIndex = 7317, + kX86InstIdVpminsb_NameIndex = 7325, + kX86InstIdVpminsd_NameIndex = 7333, + kX86InstIdVpminsw_NameIndex = 7341, + kX86InstIdVpminub_NameIndex = 7349, + kX86InstIdVpminud_NameIndex = 7357, + kX86InstIdVpminuw_NameIndex = 7365, + kX86InstIdVpmovmskb_NameIndex = 7373, + kX86InstIdVpmovsxbd_NameIndex = 7383, + kX86InstIdVpmovsxbq_NameIndex = 7393, + kX86InstIdVpmovsxbw_NameIndex = 7403, + kX86InstIdVpmovsxdq_NameIndex = 7413, + kX86InstIdVpmovsxwd_NameIndex = 7423, + kX86InstIdVpmovsxwq_NameIndex = 7433, + kX86InstIdVpmovzxbd_NameIndex = 7443, + kX86InstIdVpmovzxbq_NameIndex = 7453, + kX86InstIdVpmovzxbw_NameIndex = 7463, + kX86InstIdVpmovzxdq_NameIndex = 7473, + kX86InstIdVpmovzxwd_NameIndex = 7483, + kX86InstIdVpmovzxwq_NameIndex = 7493, + kX86InstIdVpmuldq_NameIndex = 7503, + kX86InstIdVpmulhrsw_NameIndex = 7511, + kX86InstIdVpmulhuw_NameIndex = 7521, + kX86InstIdVpmulhw_NameIndex = 7530, + kX86InstIdVpmulld_NameIndex = 7538, + kX86InstIdVpmullw_NameIndex = 7546, + kX86InstIdVpmuludq_NameIndex = 7554, + kX86InstIdVpor_NameIndex = 7563, + kX86InstIdVpperm_NameIndex = 7568, + kX86InstIdVprotb_NameIndex = 7575, + kX86InstIdVprotd_NameIndex = 7582, + kX86InstIdVprotq_NameIndex = 7589, + kX86InstIdVprotw_NameIndex = 7596, + kX86InstIdVpsadbw_NameIndex = 7603, + kX86InstIdVpshab_NameIndex = 7611, + kX86InstIdVpshad_NameIndex = 7618, + kX86InstIdVpshaq_NameIndex = 7625, + kX86InstIdVpshaw_NameIndex = 7632, + kX86InstIdVpshlb_NameIndex = 7639, + kX86InstIdVpshld_NameIndex = 7646, + kX86InstIdVpshlq_NameIndex = 7653, + kX86InstIdVpshlw_NameIndex = 7660, + kX86InstIdVpshufb_NameIndex = 7667, + kX86InstIdVpshufd_NameIndex = 7675, + kX86InstIdVpshufhw_NameIndex = 7683, + kX86InstIdVpshuflw_NameIndex = 7692, + kX86InstIdVpsignb_NameIndex = 7701, + kX86InstIdVpsignd_NameIndex = 7709, + kX86InstIdVpsignw_NameIndex = 7717, + kX86InstIdVpslld_NameIndex = 7725, + kX86InstIdVpslldq_NameIndex = 7732, + kX86InstIdVpsllq_NameIndex = 7740, + kX86InstIdVpsllvd_NameIndex = 7747, + kX86InstIdVpsllvq_NameIndex = 7755, + kX86InstIdVpsllw_NameIndex = 7763, + kX86InstIdVpsrad_NameIndex = 7770, + kX86InstIdVpsravd_NameIndex = 7777, + kX86InstIdVpsraw_NameIndex = 7785, + kX86InstIdVpsrld_NameIndex = 7792, + kX86InstIdVpsrldq_NameIndex = 7799, + kX86InstIdVpsrlq_NameIndex = 7807, + kX86InstIdVpsrlvd_NameIndex = 7814, + kX86InstIdVpsrlvq_NameIndex = 7822, + kX86InstIdVpsrlw_NameIndex = 7830, + kX86InstIdVpsubb_NameIndex = 7837, + kX86InstIdVpsubd_NameIndex = 7844, + kX86InstIdVpsubq_NameIndex = 7851, + kX86InstIdVpsubsb_NameIndex = 7858, + kX86InstIdVpsubsw_NameIndex = 7866, + kX86InstIdVpsubusb_NameIndex = 7874, + kX86InstIdVpsubusw_NameIndex = 7883, + kX86InstIdVpsubw_NameIndex = 7892, + kX86InstIdVptest_NameIndex = 7899, + kX86InstIdVpunpckhbw_NameIndex = 7906, + kX86InstIdVpunpckhdq_NameIndex = 7917, + kX86InstIdVpunpckhqdq_NameIndex = 7928, + kX86InstIdVpunpckhwd_NameIndex = 7940, + kX86InstIdVpunpcklbw_NameIndex = 7951, + kX86InstIdVpunpckldq_NameIndex = 7962, + kX86InstIdVpunpcklqdq_NameIndex = 7973, + kX86InstIdVpunpcklwd_NameIndex = 7985, + kX86InstIdVpxor_NameIndex = 7996, + kX86InstIdVrcpps_NameIndex = 8002, + kX86InstIdVrcpss_NameIndex = 8009, + kX86InstIdVroundpd_NameIndex = 8016, + kX86InstIdVroundps_NameIndex = 8025, + kX86InstIdVroundsd_NameIndex = 8034, + kX86InstIdVroundss_NameIndex = 8043, + kX86InstIdVrsqrtps_NameIndex = 8052, + kX86InstIdVrsqrtss_NameIndex = 8061, + kX86InstIdVshufpd_NameIndex = 8070, + kX86InstIdVshufps_NameIndex = 8078, + kX86InstIdVsqrtpd_NameIndex = 8086, + kX86InstIdVsqrtps_NameIndex = 8094, + kX86InstIdVsqrtsd_NameIndex = 8102, + kX86InstIdVsqrtss_NameIndex = 8110, + kX86InstIdVstmxcsr_NameIndex = 8118, + kX86InstIdVsubpd_NameIndex = 8127, + kX86InstIdVsubps_NameIndex = 8134, + kX86InstIdVsubsd_NameIndex = 8141, + kX86InstIdVsubss_NameIndex = 8148, + kX86InstIdVtestpd_NameIndex = 8155, + kX86InstIdVtestps_NameIndex = 8163, + kX86InstIdVucomisd_NameIndex = 8171, + kX86InstIdVucomiss_NameIndex = 8180, + kX86InstIdVunpckhpd_NameIndex = 8189, + kX86InstIdVunpckhps_NameIndex = 8199, + kX86InstIdVunpcklpd_NameIndex = 8209, + kX86InstIdVunpcklps_NameIndex = 8219, + kX86InstIdVxorpd_NameIndex = 8229, + kX86InstIdVxorps_NameIndex = 8236, + kX86InstIdVzeroall_NameIndex = 8243, + kX86InstIdVzeroupper_NameIndex = 8252, + kX86InstIdWrfsbase_NameIndex = 8263, + kX86InstIdWrgsbase_NameIndex = 8272, + kX86InstIdXadd_NameIndex = 8281, + kX86InstIdXchg_NameIndex = 8286, + kX86InstIdXor_NameIndex = 8291, + kX86InstIdXorpd_NameIndex = 8295, + kX86InstIdXorps_NameIndex = 8301 +}; +#endif // !ASMJIT_DISABLE_NAMES + +// Automatically generated, do not edit. +const X86InstExtendedInfo _x86InstExtendedInfo[] = { + { G(None) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Arith) , 0 , 0x20, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(X86Arith) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U }, + { G(AvxRmv) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxVm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x00, 0x3F, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86BSwap) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Test) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,4) }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,7) }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,6) }, + { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,5) }, + { G(X86Call) , 0 , 0x00, 0x00, F(Flow) , { O(GqdMem)|O(Imm)|O(Label), U , U , U , U }, O_000000(E8,U) }, + { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x20, F(None) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x40, F(None) , { U , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x20, 0x20, F(None) , { U , U , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x24, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x20, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x04, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x07, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x03, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x01, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x10, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86RegRm) , 0 , 0x02, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(X86Arith) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op_66H) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86RmReg) , 0 , 0x00, 0x3F, F(Lock)|F(Special) , { U , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x3F, F(Test) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtCrc) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdwbMem) , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U }, + { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U }, + { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U }, + { G(ExtRm_Q) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U }, + { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(X86Op) , 0 , 0x28, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(48,U) }, + { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Enter) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GqdMem) , O(Xmm) , U , U , U }, O_660F3A(17,U) }, + { G(FpuOp) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U }, + { G(FpuArith) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(FpMem) , O(Fp) , U , U , U }, U }, + { G(FpuRDef) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(X86M) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x20, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x24, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x04, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x10, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuCom) , 0 , 0x00, 0x00, F(Fp) , { O(Fp)|O(Mem) , O(Fp) , U , U , U }, U }, + { G(FpuR) , 0 , 0x00, 0x3F, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U }, + { G(FpuR) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4) , { O(Mem) , U , U , U , U }, U }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,5) }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,7) }, + { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DD,1) }, + { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,5) }, + { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_00_X(DFE0,U) }, + { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(Mem) , U , U , U , U }, U }, + { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,7) }, + { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_9B_X(DFE0,U) }, + { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U }, + { G(X86Imul) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U }, + { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(40,U) }, + { G(X86Int) , 0 , 0x00, 0x80, F(None) , { U , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x24, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x20, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x04, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x07, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x03, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x01, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x10, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jcc) , 0 , 0x02, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, + { G(X86Jecxz) , 0 , 0x00, 0x00, F(Flow)|F(Special) , { O(Gqdw) , O(Label) , U , U , U }, U }, + { G(X86Jmp) , 0 , 0x00, 0x00, F(Flow) , { O(Imm)|O(Label) , U , U , U , U }, O_000000(E9,U) }, + { G(X86Op) , 0 , 0x3E, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U }, + { G(X86Lea) , 0 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Mem) , U , U , U }, U }, + { G(ExtFence) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Op) , 1 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 4 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 8 , 0x40, 0x00, F(Move)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op_66H) , 2 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Mm) , O(Mm) , U , U , U }, U }, + { G(X86Mov) , 0 , 0x00, 0x00, F(Move) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, + { G(X86MovPtr) , 0 , 0x00, 0x00, F(Move)|F(Special) , { O(Gqdwb) , O(Imm) , U , U , U }, O_000000(A2,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(29,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(29,U) }, + { G(ExtMovBe) , 0 , 0x00, 0x00, F(Move) , { O(GqdwMem) , O(GqdwMem) , U , U , U }, O_000F38(F1,U) }, + { G(ExtMovD) , 16, 0x00, 0x00, F(Move) , { O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , U }, O_000F00(7E,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7F,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(7F,U) }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(17,U) }, + { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(17,U) }, + { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(13,U) }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(13,U) }, + { G(ExtMovNoRexW) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Xmm) , U , U , U }, U }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(E7,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Gqd) , U , U , U }, O_000F00(C3,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(2B,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_000F00(2B,U) }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Mm) , U , U , U }, O_000F00(E7,U) }, + { G(ExtMovQ) , 16, 0x00, 0x00, F(Move) , { O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U }, U }, + { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mm) , U , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op_66H) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtMov) , 8 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F20F00(11,U) }, + { G(ExtMov) , 4 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(11,U) }, + { G(X86MovSxZx) , 0 , 0x00, 0x00, F(Move) , { O(Gqdw) , O(GwbMem) , U , U , U }, U }, + { G(X86MovSxd) , 0 , 0x00, 0x00, F(Move) , { O(Gq) , O(GdMem) , U , U , U }, U }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(11,U) }, + { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(11,U) }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U }, + { G(X86Rm_B) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U }, + { G(X86Rm_B) , 0 , 0x00, 0x00, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U }, + { G(ExtRm_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , U , U , U }, U }, + { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , O(Imm) , U , U }, U }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , U }, O_000F3A(14,U) }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) |F(W), { O(GqdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) }, + { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(MmXmm) , U , U , U }, O_000F3A(15,U) }, + { G(3dNow) , 0 , 0x00, 0x00, F(None) , { O(Mm) , O(MmMem) , U , U , U }, U }, + { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(GdMem) , O(Imm) , U , U }, U }, + { G(ExtRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(GqMem) , O(Imm) , U , U }, U }, + { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(GdMem) , O(Imm) , U , U }, U }, + { G(ExtRm_PQ) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(MmXmm) , U , U , U }, U }, + { G(X86Pop) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(58,U) }, + { G(X86Op) , 0 , 0x00, 0xFF, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(ExtPrefetch) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(Imm) , U , U , U }, U }, + { G(ExtRmi) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(ExtRmi_P) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(MmMem) , O(Imm) , U , U }, U }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,6) }, + { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,7) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,6) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,6) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,4) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,4) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,2) }, + { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,3) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,2) }, + { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,2) }, + { G(X86Push) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(50,U) }, + { G(X86Op) , 0 , 0xFF, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Rot) , 0 , 0x20, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, + { G(X86Rm) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , U , U , U , U }, U }, + { G(X86Rm) , 8 , 0x00, 0x3F, F(Move) , { O(Gqdw) , U , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U }, + { G(X86Ret) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Rot) , 0 , 0x00, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, + { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Imm) , U , U }, U }, + { G(ExtRmi) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(ExtRmi) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(X86Op) , 0 , 0x00, 0x3E, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Rot) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, + { G(AvxRmv) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U }, + { G(X86Set) , 1 , 0x24, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x20, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x04, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x07, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x03, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x01, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x10, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Set) , 1 , 0x02, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, + { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb) , U , U , U }, U }, + { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, + { G(X86Op_66H) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, + { G(X86Test) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , U }, O_000000(F6,U) }, + { G(X86RegRm) , 0 , 0x00, 0x3F, F(Move) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, + { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U }, U }, + { G(AvxRvmr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Mem) , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(XmmMem) , U , U , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxMri_P) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmYmm) , O(Imm) , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmMem) , U , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , U , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Ymm) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U }, + { G(Fma4_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, + { G(Fma4) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U }, + { G(XopRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(XopRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxGather) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U }, + { G(AvxGather) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U }, + { G(AvxGatherEx) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Mem) , O(Xmm) , U , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , U , U , U }, U }, + { G(AvxM) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2F,U) }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2E,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(29,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(29,U) }, + { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(7F,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_F30F00(7F,U) }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(Xmm) , U , U }, U }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(17,U) }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(17,U) }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(13,U) }, + { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(13,U) }, + { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmYmm) , U , U , U }, U }, + { G(AvxMr) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U }, + { G(AvxMr_P) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U }, + { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) }, + { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , O(Xmm) , U , U }, O_F20F00(11,U) }, + { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Xmm) , U , U }, O_F30F00(11,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(11,U) }, + { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(11,U) }, + { G(AvxRvmr) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U }, + { G(XopRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, + { G(XopRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , U }, U }, + { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , U , U }, U }, + { G(AvxRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, + { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(05,U) }, + { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(04,U) }, + { G(AvxRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Ymm) , O(YmmMem) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwbMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) |F(W), { O(GqMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwMem) , O(Xmm) , O(Imm) , U , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , U }, U }, + { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , U }, U }, + { G(XopRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U }, U }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) }, + { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) }, + { G(XopRvrmRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C0,U) }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C2,U) }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C3,U) }, + { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C1,U) }, + { G(XopRvmRmv) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem) , U , U }, U }, + { G(AvxRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,6) }, + { G(AvxVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,6) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,6) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,4) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,4) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,2) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,2) }, + { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,2) }, + { G(AvxRm_P) , 0 , 0x00, 0x3F, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxRm_P) , 0 , 0x00, 0x3F, F(Test) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, + { G(AvxRm) , 0 , 0x00, 0x3F, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, + { G(AvxOp) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, + { G(X86Rm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U }, + { G(X86Xadd) , 0 , 0x00, 0x3F, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U }, + { G(X86Xchg) , 0 , 0x00, 0x00, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U } +}; + +// Automatically generated, do not edit. +enum kX86InstData_ExtendedIndex { + kInstIdNone_ExtendedIndex = 0, + kX86InstIdAdc_ExtendedIndex = 1, + kX86InstIdAdd_ExtendedIndex = 2, + kX86InstIdAddpd_ExtendedIndex = 3, + kX86InstIdAddps_ExtendedIndex = 3, + kX86InstIdAddsd_ExtendedIndex = 3, + kX86InstIdAddss_ExtendedIndex = 3, + kX86InstIdAddsubpd_ExtendedIndex = 3, + kX86InstIdAddsubps_ExtendedIndex = 3, + kX86InstIdAesdec_ExtendedIndex = 3, + kX86InstIdAesdeclast_ExtendedIndex = 3, + kX86InstIdAesenc_ExtendedIndex = 3, + kX86InstIdAesenclast_ExtendedIndex = 3, + kX86InstIdAesimc_ExtendedIndex = 3, + kX86InstIdAeskeygenassist_ExtendedIndex = 4, + kX86InstIdAnd_ExtendedIndex = 2, + kX86InstIdAndn_ExtendedIndex = 5, + kX86InstIdAndnpd_ExtendedIndex = 3, + kX86InstIdAndnps_ExtendedIndex = 3, + kX86InstIdAndpd_ExtendedIndex = 3, + kX86InstIdAndps_ExtendedIndex = 3, + kX86InstIdBextr_ExtendedIndex = 6, + kX86InstIdBlendpd_ExtendedIndex = 4, + kX86InstIdBlendps_ExtendedIndex = 4, + kX86InstIdBlendvpd_ExtendedIndex = 7, + kX86InstIdBlendvps_ExtendedIndex = 7, + kX86InstIdBlsi_ExtendedIndex = 8, + kX86InstIdBlsmsk_ExtendedIndex = 8, + kX86InstIdBlsr_ExtendedIndex = 8, + kX86InstIdBsf_ExtendedIndex = 9, + kX86InstIdBsr_ExtendedIndex = 9, + kX86InstIdBswap_ExtendedIndex = 10, + kX86InstIdBt_ExtendedIndex = 11, + kX86InstIdBtc_ExtendedIndex = 12, + kX86InstIdBtr_ExtendedIndex = 13, + kX86InstIdBts_ExtendedIndex = 14, + kX86InstIdBzhi_ExtendedIndex = 6, + kX86InstIdCall_ExtendedIndex = 15, + kX86InstIdCbw_ExtendedIndex = 16, + kX86InstIdCdq_ExtendedIndex = 16, + kX86InstIdCdqe_ExtendedIndex = 17, + kX86InstIdClc_ExtendedIndex = 18, + kX86InstIdCld_ExtendedIndex = 19, + kX86InstIdClflush_ExtendedIndex = 20, + kX86InstIdCmc_ExtendedIndex = 21, + kX86InstIdCmova_ExtendedIndex = 22, + kX86InstIdCmovae_ExtendedIndex = 23, + kX86InstIdCmovb_ExtendedIndex = 23, + kX86InstIdCmovbe_ExtendedIndex = 22, + kX86InstIdCmovc_ExtendedIndex = 23, + kX86InstIdCmove_ExtendedIndex = 24, + kX86InstIdCmovg_ExtendedIndex = 25, + kX86InstIdCmovge_ExtendedIndex = 26, + kX86InstIdCmovl_ExtendedIndex = 26, + kX86InstIdCmovle_ExtendedIndex = 25, + kX86InstIdCmovna_ExtendedIndex = 22, + kX86InstIdCmovnae_ExtendedIndex = 23, + kX86InstIdCmovnb_ExtendedIndex = 23, + kX86InstIdCmovnbe_ExtendedIndex = 22, + kX86InstIdCmovnc_ExtendedIndex = 23, + kX86InstIdCmovne_ExtendedIndex = 24, + kX86InstIdCmovng_ExtendedIndex = 25, + kX86InstIdCmovnge_ExtendedIndex = 26, + kX86InstIdCmovnl_ExtendedIndex = 26, + kX86InstIdCmovnle_ExtendedIndex = 25, + kX86InstIdCmovno_ExtendedIndex = 27, + kX86InstIdCmovnp_ExtendedIndex = 28, + kX86InstIdCmovns_ExtendedIndex = 29, + kX86InstIdCmovnz_ExtendedIndex = 24, + kX86InstIdCmovo_ExtendedIndex = 27, + kX86InstIdCmovp_ExtendedIndex = 28, + kX86InstIdCmovpe_ExtendedIndex = 28, + kX86InstIdCmovpo_ExtendedIndex = 28, + kX86InstIdCmovs_ExtendedIndex = 29, + kX86InstIdCmovz_ExtendedIndex = 24, + kX86InstIdCmp_ExtendedIndex = 30, + kX86InstIdCmppd_ExtendedIndex = 4, + kX86InstIdCmpps_ExtendedIndex = 4, + kX86InstIdCmpsB_ExtendedIndex = 31, + kX86InstIdCmpsD_ExtendedIndex = 31, + kX86InstIdCmpsQ_ExtendedIndex = 32, + kX86InstIdCmpsW_ExtendedIndex = 33, + kX86InstIdCmpsd_ExtendedIndex = 4, + kX86InstIdCmpss_ExtendedIndex = 4, + kX86InstIdCmpxchg_ExtendedIndex = 34, + kX86InstIdCmpxchg16b_ExtendedIndex = 35, + kX86InstIdCmpxchg8b_ExtendedIndex = 36, + kX86InstIdComisd_ExtendedIndex = 37, + kX86InstIdComiss_ExtendedIndex = 37, + kX86InstIdCpuid_ExtendedIndex = 16, + kX86InstIdCqo_ExtendedIndex = 17, + kX86InstIdCrc32_ExtendedIndex = 38, + kX86InstIdCvtdq2pd_ExtendedIndex = 39, + kX86InstIdCvtdq2ps_ExtendedIndex = 39, + kX86InstIdCvtpd2dq_ExtendedIndex = 39, + kX86InstIdCvtpd2pi_ExtendedIndex = 40, + kX86InstIdCvtpd2ps_ExtendedIndex = 39, + kX86InstIdCvtpi2pd_ExtendedIndex = 41, + kX86InstIdCvtpi2ps_ExtendedIndex = 42, + kX86InstIdCvtps2dq_ExtendedIndex = 39, + kX86InstIdCvtps2pd_ExtendedIndex = 39, + kX86InstIdCvtps2pi_ExtendedIndex = 40, + kX86InstIdCvtsd2si_ExtendedIndex = 43, + kX86InstIdCvtsd2ss_ExtendedIndex = 44, + kX86InstIdCvtsi2sd_ExtendedIndex = 45, + kX86InstIdCvtsi2ss_ExtendedIndex = 46, + kX86InstIdCvtss2sd_ExtendedIndex = 47, + kX86InstIdCvtss2si_ExtendedIndex = 43, + kX86InstIdCvttpd2dq_ExtendedIndex = 39, + kX86InstIdCvttpd2pi_ExtendedIndex = 40, + kX86InstIdCvttps2dq_ExtendedIndex = 39, + kX86InstIdCvttps2pi_ExtendedIndex = 40, + kX86InstIdCvttsd2si_ExtendedIndex = 43, + kX86InstIdCvttss2si_ExtendedIndex = 43, + kX86InstIdCwd_ExtendedIndex = 16, + kX86InstIdCwde_ExtendedIndex = 16, + kX86InstIdDaa_ExtendedIndex = 48, + kX86InstIdDas_ExtendedIndex = 48, + kX86InstIdDec_ExtendedIndex = 49, + kX86InstIdDiv_ExtendedIndex = 50, + kX86InstIdDivpd_ExtendedIndex = 3, + kX86InstIdDivps_ExtendedIndex = 3, + kX86InstIdDivsd_ExtendedIndex = 3, + kX86InstIdDivss_ExtendedIndex = 3, + kX86InstIdDppd_ExtendedIndex = 4, + kX86InstIdDpps_ExtendedIndex = 4, + kX86InstIdEmms_ExtendedIndex = 51, + kX86InstIdEnter_ExtendedIndex = 52, + kX86InstIdExtractps_ExtendedIndex = 53, + kX86InstIdF2xm1_ExtendedIndex = 54, + kX86InstIdFabs_ExtendedIndex = 54, + kX86InstIdFadd_ExtendedIndex = 55, + kX86InstIdFaddp_ExtendedIndex = 56, + kX86InstIdFbld_ExtendedIndex = 57, + kX86InstIdFbstp_ExtendedIndex = 57, + kX86InstIdFchs_ExtendedIndex = 54, + kX86InstIdFclex_ExtendedIndex = 54, + kX86InstIdFcmovb_ExtendedIndex = 58, + kX86InstIdFcmovbe_ExtendedIndex = 59, + kX86InstIdFcmove_ExtendedIndex = 60, + kX86InstIdFcmovnb_ExtendedIndex = 58, + kX86InstIdFcmovnbe_ExtendedIndex = 59, + kX86InstIdFcmovne_ExtendedIndex = 60, + kX86InstIdFcmovnu_ExtendedIndex = 61, + kX86InstIdFcmovu_ExtendedIndex = 61, + kX86InstIdFcom_ExtendedIndex = 62, + kX86InstIdFcomi_ExtendedIndex = 63, + kX86InstIdFcomip_ExtendedIndex = 63, + kX86InstIdFcomp_ExtendedIndex = 62, + kX86InstIdFcompp_ExtendedIndex = 54, + kX86InstIdFcos_ExtendedIndex = 54, + kX86InstIdFdecstp_ExtendedIndex = 54, + kX86InstIdFdiv_ExtendedIndex = 55, + kX86InstIdFdivp_ExtendedIndex = 56, + kX86InstIdFdivr_ExtendedIndex = 55, + kX86InstIdFdivrp_ExtendedIndex = 56, + kX86InstIdFemms_ExtendedIndex = 64, + kX86InstIdFfree_ExtendedIndex = 65, + kX86InstIdFiadd_ExtendedIndex = 66, + kX86InstIdFicom_ExtendedIndex = 66, + kX86InstIdFicomp_ExtendedIndex = 66, + kX86InstIdFidiv_ExtendedIndex = 66, + kX86InstIdFidivr_ExtendedIndex = 66, + kX86InstIdFild_ExtendedIndex = 67, + kX86InstIdFimul_ExtendedIndex = 66, + kX86InstIdFincstp_ExtendedIndex = 54, + kX86InstIdFinit_ExtendedIndex = 54, + kX86InstIdFist_ExtendedIndex = 66, + kX86InstIdFistp_ExtendedIndex = 68, + kX86InstIdFisttp_ExtendedIndex = 69, + kX86InstIdFisub_ExtendedIndex = 66, + kX86InstIdFisubr_ExtendedIndex = 66, + kX86InstIdFld_ExtendedIndex = 70, + kX86InstIdFld1_ExtendedIndex = 54, + kX86InstIdFldcw_ExtendedIndex = 57, + kX86InstIdFldenv_ExtendedIndex = 57, + kX86InstIdFldl2e_ExtendedIndex = 54, + kX86InstIdFldl2t_ExtendedIndex = 54, + kX86InstIdFldlg2_ExtendedIndex = 54, + kX86InstIdFldln2_ExtendedIndex = 54, + kX86InstIdFldpi_ExtendedIndex = 54, + kX86InstIdFldz_ExtendedIndex = 54, + kX86InstIdFmul_ExtendedIndex = 55, + kX86InstIdFmulp_ExtendedIndex = 56, + kX86InstIdFnclex_ExtendedIndex = 54, + kX86InstIdFninit_ExtendedIndex = 54, + kX86InstIdFnop_ExtendedIndex = 54, + kX86InstIdFnsave_ExtendedIndex = 57, + kX86InstIdFnstcw_ExtendedIndex = 57, + kX86InstIdFnstenv_ExtendedIndex = 57, + kX86InstIdFnstsw_ExtendedIndex = 71, + kX86InstIdFpatan_ExtendedIndex = 54, + kX86InstIdFprem_ExtendedIndex = 54, + kX86InstIdFprem1_ExtendedIndex = 54, + kX86InstIdFptan_ExtendedIndex = 54, + kX86InstIdFrndint_ExtendedIndex = 54, + kX86InstIdFrstor_ExtendedIndex = 57, + kX86InstIdFsave_ExtendedIndex = 57, + kX86InstIdFscale_ExtendedIndex = 54, + kX86InstIdFsin_ExtendedIndex = 54, + kX86InstIdFsincos_ExtendedIndex = 54, + kX86InstIdFsqrt_ExtendedIndex = 54, + kX86InstIdFst_ExtendedIndex = 72, + kX86InstIdFstcw_ExtendedIndex = 57, + kX86InstIdFstenv_ExtendedIndex = 57, + kX86InstIdFstp_ExtendedIndex = 73, + kX86InstIdFstsw_ExtendedIndex = 74, + kX86InstIdFsub_ExtendedIndex = 55, + kX86InstIdFsubp_ExtendedIndex = 56, + kX86InstIdFsubr_ExtendedIndex = 55, + kX86InstIdFsubrp_ExtendedIndex = 56, + kX86InstIdFtst_ExtendedIndex = 54, + kX86InstIdFucom_ExtendedIndex = 56, + kX86InstIdFucomi_ExtendedIndex = 63, + kX86InstIdFucomip_ExtendedIndex = 63, + kX86InstIdFucomp_ExtendedIndex = 56, + kX86InstIdFucompp_ExtendedIndex = 54, + kX86InstIdFwait_ExtendedIndex = 64, + kX86InstIdFxam_ExtendedIndex = 54, + kX86InstIdFxch_ExtendedIndex = 65, + kX86InstIdFxrstor_ExtendedIndex = 57, + kX86InstIdFxsave_ExtendedIndex = 57, + kX86InstIdFxtract_ExtendedIndex = 54, + kX86InstIdFyl2x_ExtendedIndex = 54, + kX86InstIdFyl2xp1_ExtendedIndex = 54, + kX86InstIdHaddpd_ExtendedIndex = 3, + kX86InstIdHaddps_ExtendedIndex = 3, + kX86InstIdHsubpd_ExtendedIndex = 3, + kX86InstIdHsubps_ExtendedIndex = 3, + kX86InstIdIdiv_ExtendedIndex = 75, + kX86InstIdImul_ExtendedIndex = 76, + kX86InstIdInc_ExtendedIndex = 77, + kX86InstIdInsertps_ExtendedIndex = 4, + kX86InstIdInt_ExtendedIndex = 78, + kX86InstIdJa_ExtendedIndex = 79, + kX86InstIdJae_ExtendedIndex = 80, + kX86InstIdJb_ExtendedIndex = 80, + kX86InstIdJbe_ExtendedIndex = 79, + kX86InstIdJc_ExtendedIndex = 80, + kX86InstIdJe_ExtendedIndex = 81, + kX86InstIdJg_ExtendedIndex = 82, + kX86InstIdJge_ExtendedIndex = 83, + kX86InstIdJl_ExtendedIndex = 83, + kX86InstIdJle_ExtendedIndex = 82, + kX86InstIdJna_ExtendedIndex = 79, + kX86InstIdJnae_ExtendedIndex = 80, + kX86InstIdJnb_ExtendedIndex = 80, + kX86InstIdJnbe_ExtendedIndex = 79, + kX86InstIdJnc_ExtendedIndex = 80, + kX86InstIdJne_ExtendedIndex = 81, + kX86InstIdJng_ExtendedIndex = 82, + kX86InstIdJnge_ExtendedIndex = 83, + kX86InstIdJnl_ExtendedIndex = 83, + kX86InstIdJnle_ExtendedIndex = 82, + kX86InstIdJno_ExtendedIndex = 84, + kX86InstIdJnp_ExtendedIndex = 85, + kX86InstIdJns_ExtendedIndex = 86, + kX86InstIdJnz_ExtendedIndex = 81, + kX86InstIdJo_ExtendedIndex = 84, + kX86InstIdJp_ExtendedIndex = 85, + kX86InstIdJpe_ExtendedIndex = 85, + kX86InstIdJpo_ExtendedIndex = 85, + kX86InstIdJs_ExtendedIndex = 86, + kX86InstIdJz_ExtendedIndex = 81, + kX86InstIdJecxz_ExtendedIndex = 87, + kX86InstIdJmp_ExtendedIndex = 88, + kX86InstIdLahf_ExtendedIndex = 89, + kX86InstIdLddqu_ExtendedIndex = 90, + kX86InstIdLdmxcsr_ExtendedIndex = 20, + kX86InstIdLea_ExtendedIndex = 91, + kX86InstIdLeave_ExtendedIndex = 16, + kX86InstIdLfence_ExtendedIndex = 92, + kX86InstIdLodsB_ExtendedIndex = 93, + kX86InstIdLodsD_ExtendedIndex = 94, + kX86InstIdLodsQ_ExtendedIndex = 95, + kX86InstIdLodsW_ExtendedIndex = 96, + kX86InstIdLzcnt_ExtendedIndex = 9, + kX86InstIdMaskmovdqu_ExtendedIndex = 97, + kX86InstIdMaskmovq_ExtendedIndex = 98, + kX86InstIdMaxpd_ExtendedIndex = 3, + kX86InstIdMaxps_ExtendedIndex = 3, + kX86InstIdMaxsd_ExtendedIndex = 3, + kX86InstIdMaxss_ExtendedIndex = 3, + kX86InstIdMfence_ExtendedIndex = 92, + kX86InstIdMinpd_ExtendedIndex = 3, + kX86InstIdMinps_ExtendedIndex = 3, + kX86InstIdMinsd_ExtendedIndex = 3, + kX86InstIdMinss_ExtendedIndex = 3, + kX86InstIdMonitor_ExtendedIndex = 16, + kX86InstIdMov_ExtendedIndex = 99, + kX86InstIdMovPtr_ExtendedIndex = 100, + kX86InstIdMovapd_ExtendedIndex = 101, + kX86InstIdMovaps_ExtendedIndex = 102, + kX86InstIdMovbe_ExtendedIndex = 103, + kX86InstIdMovd_ExtendedIndex = 104, + kX86InstIdMovddup_ExtendedIndex = 105, + kX86InstIdMovdq2q_ExtendedIndex = 106, + kX86InstIdMovdqa_ExtendedIndex = 107, + kX86InstIdMovdqu_ExtendedIndex = 108, + kX86InstIdMovhlps_ExtendedIndex = 109, + kX86InstIdMovhpd_ExtendedIndex = 110, + kX86InstIdMovhps_ExtendedIndex = 111, + kX86InstIdMovlhps_ExtendedIndex = 112, + kX86InstIdMovlpd_ExtendedIndex = 113, + kX86InstIdMovlps_ExtendedIndex = 114, + kX86InstIdMovmskpd_ExtendedIndex = 115, + kX86InstIdMovmskps_ExtendedIndex = 115, + kX86InstIdMovntdq_ExtendedIndex = 116, + kX86InstIdMovntdqa_ExtendedIndex = 117, + kX86InstIdMovnti_ExtendedIndex = 118, + kX86InstIdMovntpd_ExtendedIndex = 119, + kX86InstIdMovntps_ExtendedIndex = 120, + kX86InstIdMovntq_ExtendedIndex = 121, + kX86InstIdMovq_ExtendedIndex = 122, + kX86InstIdMovq2dq_ExtendedIndex = 123, + kX86InstIdMovsB_ExtendedIndex = 16, + kX86InstIdMovsD_ExtendedIndex = 124, + kX86InstIdMovsQ_ExtendedIndex = 17, + kX86InstIdMovsW_ExtendedIndex = 125, + kX86InstIdMovsd_ExtendedIndex = 126, + kX86InstIdMovshdup_ExtendedIndex = 39, + kX86InstIdMovsldup_ExtendedIndex = 39, + kX86InstIdMovss_ExtendedIndex = 127, + kX86InstIdMovsx_ExtendedIndex = 128, + kX86InstIdMovsxd_ExtendedIndex = 129, + kX86InstIdMovupd_ExtendedIndex = 130, + kX86InstIdMovups_ExtendedIndex = 131, + kX86InstIdMovzx_ExtendedIndex = 128, + kX86InstIdMpsadbw_ExtendedIndex = 4, + kX86InstIdMul_ExtendedIndex = 75, + kX86InstIdMulpd_ExtendedIndex = 3, + kX86InstIdMulps_ExtendedIndex = 3, + kX86InstIdMulsd_ExtendedIndex = 3, + kX86InstIdMulss_ExtendedIndex = 3, + kX86InstIdMulx_ExtendedIndex = 132, + kX86InstIdMwait_ExtendedIndex = 16, + kX86InstIdNeg_ExtendedIndex = 133, + kX86InstIdNop_ExtendedIndex = 51, + kX86InstIdNot_ExtendedIndex = 134, + kX86InstIdOr_ExtendedIndex = 2, + kX86InstIdOrpd_ExtendedIndex = 3, + kX86InstIdOrps_ExtendedIndex = 3, + kX86InstIdPabsb_ExtendedIndex = 135, + kX86InstIdPabsd_ExtendedIndex = 135, + kX86InstIdPabsw_ExtendedIndex = 135, + kX86InstIdPackssdw_ExtendedIndex = 135, + kX86InstIdPacksswb_ExtendedIndex = 135, + kX86InstIdPackusdw_ExtendedIndex = 3, + kX86InstIdPackuswb_ExtendedIndex = 135, + kX86InstIdPaddb_ExtendedIndex = 135, + kX86InstIdPaddd_ExtendedIndex = 135, + kX86InstIdPaddq_ExtendedIndex = 135, + kX86InstIdPaddsb_ExtendedIndex = 135, + kX86InstIdPaddsw_ExtendedIndex = 135, + kX86InstIdPaddusb_ExtendedIndex = 135, + kX86InstIdPaddusw_ExtendedIndex = 135, + kX86InstIdPaddw_ExtendedIndex = 135, + kX86InstIdPalignr_ExtendedIndex = 136, + kX86InstIdPand_ExtendedIndex = 135, + kX86InstIdPandn_ExtendedIndex = 135, + kX86InstIdPause_ExtendedIndex = 51, + kX86InstIdPavgb_ExtendedIndex = 135, + kX86InstIdPavgw_ExtendedIndex = 135, + kX86InstIdPblendvb_ExtendedIndex = 7, + kX86InstIdPblendw_ExtendedIndex = 4, + kX86InstIdPclmulqdq_ExtendedIndex = 4, + kX86InstIdPcmpeqb_ExtendedIndex = 135, + kX86InstIdPcmpeqd_ExtendedIndex = 135, + kX86InstIdPcmpeqq_ExtendedIndex = 3, + kX86InstIdPcmpeqw_ExtendedIndex = 135, + kX86InstIdPcmpestri_ExtendedIndex = 4, + kX86InstIdPcmpestrm_ExtendedIndex = 4, + kX86InstIdPcmpgtb_ExtendedIndex = 135, + kX86InstIdPcmpgtd_ExtendedIndex = 135, + kX86InstIdPcmpgtq_ExtendedIndex = 3, + kX86InstIdPcmpgtw_ExtendedIndex = 135, + kX86InstIdPcmpistri_ExtendedIndex = 4, + kX86InstIdPcmpistrm_ExtendedIndex = 4, + kX86InstIdPdep_ExtendedIndex = 132, + kX86InstIdPext_ExtendedIndex = 132, + kX86InstIdPextrb_ExtendedIndex = 137, + kX86InstIdPextrd_ExtendedIndex = 138, + kX86InstIdPextrq_ExtendedIndex = 139, + kX86InstIdPextrw_ExtendedIndex = 140, + kX86InstIdPf2id_ExtendedIndex = 141, + kX86InstIdPf2iw_ExtendedIndex = 141, + kX86InstIdPfacc_ExtendedIndex = 141, + kX86InstIdPfadd_ExtendedIndex = 141, + kX86InstIdPfcmpeq_ExtendedIndex = 141, + kX86InstIdPfcmpge_ExtendedIndex = 141, + kX86InstIdPfcmpgt_ExtendedIndex = 141, + kX86InstIdPfmax_ExtendedIndex = 141, + kX86InstIdPfmin_ExtendedIndex = 141, + kX86InstIdPfmul_ExtendedIndex = 141, + kX86InstIdPfnacc_ExtendedIndex = 141, + kX86InstIdPfpnacc_ExtendedIndex = 141, + kX86InstIdPfrcp_ExtendedIndex = 141, + kX86InstIdPfrcpit1_ExtendedIndex = 141, + kX86InstIdPfrcpit2_ExtendedIndex = 141, + kX86InstIdPfrsqit1_ExtendedIndex = 141, + kX86InstIdPfrsqrt_ExtendedIndex = 141, + kX86InstIdPfsub_ExtendedIndex = 141, + kX86InstIdPfsubr_ExtendedIndex = 141, + kX86InstIdPhaddd_ExtendedIndex = 135, + kX86InstIdPhaddsw_ExtendedIndex = 135, + kX86InstIdPhaddw_ExtendedIndex = 135, + kX86InstIdPhminposuw_ExtendedIndex = 3, + kX86InstIdPhsubd_ExtendedIndex = 135, + kX86InstIdPhsubsw_ExtendedIndex = 135, + kX86InstIdPhsubw_ExtendedIndex = 135, + kX86InstIdPi2fd_ExtendedIndex = 141, + kX86InstIdPi2fw_ExtendedIndex = 141, + kX86InstIdPinsrb_ExtendedIndex = 142, + kX86InstIdPinsrd_ExtendedIndex = 142, + kX86InstIdPinsrq_ExtendedIndex = 143, + kX86InstIdPinsrw_ExtendedIndex = 144, + kX86InstIdPmaddubsw_ExtendedIndex = 135, + kX86InstIdPmaddwd_ExtendedIndex = 135, + kX86InstIdPmaxsb_ExtendedIndex = 3, + kX86InstIdPmaxsd_ExtendedIndex = 3, + kX86InstIdPmaxsw_ExtendedIndex = 135, + kX86InstIdPmaxub_ExtendedIndex = 135, + kX86InstIdPmaxud_ExtendedIndex = 3, + kX86InstIdPmaxuw_ExtendedIndex = 3, + kX86InstIdPminsb_ExtendedIndex = 3, + kX86InstIdPminsd_ExtendedIndex = 3, + kX86InstIdPminsw_ExtendedIndex = 135, + kX86InstIdPminub_ExtendedIndex = 135, + kX86InstIdPminud_ExtendedIndex = 3, + kX86InstIdPminuw_ExtendedIndex = 3, + kX86InstIdPmovmskb_ExtendedIndex = 145, + kX86InstIdPmovsxbd_ExtendedIndex = 39, + kX86InstIdPmovsxbq_ExtendedIndex = 39, + kX86InstIdPmovsxbw_ExtendedIndex = 39, + kX86InstIdPmovsxdq_ExtendedIndex = 39, + kX86InstIdPmovsxwd_ExtendedIndex = 39, + kX86InstIdPmovsxwq_ExtendedIndex = 39, + kX86InstIdPmovzxbd_ExtendedIndex = 39, + kX86InstIdPmovzxbq_ExtendedIndex = 39, + kX86InstIdPmovzxbw_ExtendedIndex = 39, + kX86InstIdPmovzxdq_ExtendedIndex = 39, + kX86InstIdPmovzxwd_ExtendedIndex = 39, + kX86InstIdPmovzxwq_ExtendedIndex = 39, + kX86InstIdPmuldq_ExtendedIndex = 3, + kX86InstIdPmulhrsw_ExtendedIndex = 135, + kX86InstIdPmulhuw_ExtendedIndex = 135, + kX86InstIdPmulhw_ExtendedIndex = 135, + kX86InstIdPmulld_ExtendedIndex = 3, + kX86InstIdPmullw_ExtendedIndex = 135, + kX86InstIdPmuludq_ExtendedIndex = 135, + kX86InstIdPop_ExtendedIndex = 146, + kX86InstIdPopa_ExtendedIndex = 16, + kX86InstIdPopcnt_ExtendedIndex = 9, + kX86InstIdPopf_ExtendedIndex = 147, + kX86InstIdPor_ExtendedIndex = 135, + kX86InstIdPrefetch_ExtendedIndex = 148, + kX86InstIdPrefetch3dNow_ExtendedIndex = 20, + kX86InstIdPrefetchw3dNow_ExtendedIndex = 20, + kX86InstIdPsadbw_ExtendedIndex = 135, + kX86InstIdPshufb_ExtendedIndex = 135, + kX86InstIdPshufd_ExtendedIndex = 149, + kX86InstIdPshufhw_ExtendedIndex = 149, + kX86InstIdPshuflw_ExtendedIndex = 149, + kX86InstIdPshufw_ExtendedIndex = 150, + kX86InstIdPsignb_ExtendedIndex = 135, + kX86InstIdPsignd_ExtendedIndex = 135, + kX86InstIdPsignw_ExtendedIndex = 135, + kX86InstIdPslld_ExtendedIndex = 151, + kX86InstIdPslldq_ExtendedIndex = 152, + kX86InstIdPsllq_ExtendedIndex = 153, + kX86InstIdPsllw_ExtendedIndex = 154, + kX86InstIdPsrad_ExtendedIndex = 155, + kX86InstIdPsraw_ExtendedIndex = 156, + kX86InstIdPsrld_ExtendedIndex = 157, + kX86InstIdPsrldq_ExtendedIndex = 158, + kX86InstIdPsrlq_ExtendedIndex = 159, + kX86InstIdPsrlw_ExtendedIndex = 160, + kX86InstIdPsubb_ExtendedIndex = 135, + kX86InstIdPsubd_ExtendedIndex = 135, + kX86InstIdPsubq_ExtendedIndex = 135, + kX86InstIdPsubsb_ExtendedIndex = 135, + kX86InstIdPsubsw_ExtendedIndex = 135, + kX86InstIdPsubusb_ExtendedIndex = 135, + kX86InstIdPsubusw_ExtendedIndex = 135, + kX86InstIdPsubw_ExtendedIndex = 135, + kX86InstIdPswapd_ExtendedIndex = 141, + kX86InstIdPtest_ExtendedIndex = 37, + kX86InstIdPunpckhbw_ExtendedIndex = 135, + kX86InstIdPunpckhdq_ExtendedIndex = 135, + kX86InstIdPunpckhqdq_ExtendedIndex = 3, + kX86InstIdPunpckhwd_ExtendedIndex = 135, + kX86InstIdPunpcklbw_ExtendedIndex = 135, + kX86InstIdPunpckldq_ExtendedIndex = 135, + kX86InstIdPunpcklqdq_ExtendedIndex = 3, + kX86InstIdPunpcklwd_ExtendedIndex = 135, + kX86InstIdPush_ExtendedIndex = 161, + kX86InstIdPusha_ExtendedIndex = 16, + kX86InstIdPushf_ExtendedIndex = 162, + kX86InstIdPxor_ExtendedIndex = 135, + kX86InstIdRcl_ExtendedIndex = 163, + kX86InstIdRcpps_ExtendedIndex = 39, + kX86InstIdRcpss_ExtendedIndex = 44, + kX86InstIdRcr_ExtendedIndex = 163, + kX86InstIdRdfsbase_ExtendedIndex = 164, + kX86InstIdRdgsbase_ExtendedIndex = 164, + kX86InstIdRdrand_ExtendedIndex = 165, + kX86InstIdRdtsc_ExtendedIndex = 16, + kX86InstIdRdtscp_ExtendedIndex = 16, + kX86InstIdRepLodsB_ExtendedIndex = 166, + kX86InstIdRepLodsD_ExtendedIndex = 166, + kX86InstIdRepLodsQ_ExtendedIndex = 167, + kX86InstIdRepLodsW_ExtendedIndex = 166, + kX86InstIdRepMovsB_ExtendedIndex = 168, + kX86InstIdRepMovsD_ExtendedIndex = 168, + kX86InstIdRepMovsQ_ExtendedIndex = 169, + kX86InstIdRepMovsW_ExtendedIndex = 168, + kX86InstIdRepStosB_ExtendedIndex = 166, + kX86InstIdRepStosD_ExtendedIndex = 166, + kX86InstIdRepStosQ_ExtendedIndex = 167, + kX86InstIdRepStosW_ExtendedIndex = 166, + kX86InstIdRepeCmpsB_ExtendedIndex = 170, + kX86InstIdRepeCmpsD_ExtendedIndex = 170, + kX86InstIdRepeCmpsQ_ExtendedIndex = 171, + kX86InstIdRepeCmpsW_ExtendedIndex = 170, + kX86InstIdRepeScasB_ExtendedIndex = 170, + kX86InstIdRepeScasD_ExtendedIndex = 170, + kX86InstIdRepeScasQ_ExtendedIndex = 171, + kX86InstIdRepeScasW_ExtendedIndex = 170, + kX86InstIdRepneCmpsB_ExtendedIndex = 170, + kX86InstIdRepneCmpsD_ExtendedIndex = 170, + kX86InstIdRepneCmpsQ_ExtendedIndex = 171, + kX86InstIdRepneCmpsW_ExtendedIndex = 170, + kX86InstIdRepneScasB_ExtendedIndex = 170, + kX86InstIdRepneScasD_ExtendedIndex = 170, + kX86InstIdRepneScasQ_ExtendedIndex = 171, + kX86InstIdRepneScasW_ExtendedIndex = 170, + kX86InstIdRet_ExtendedIndex = 172, + kX86InstIdRol_ExtendedIndex = 173, + kX86InstIdRor_ExtendedIndex = 173, + kX86InstIdRorx_ExtendedIndex = 174, + kX86InstIdRoundpd_ExtendedIndex = 149, + kX86InstIdRoundps_ExtendedIndex = 149, + kX86InstIdRoundsd_ExtendedIndex = 175, + kX86InstIdRoundss_ExtendedIndex = 176, + kX86InstIdRsqrtps_ExtendedIndex = 39, + kX86InstIdRsqrtss_ExtendedIndex = 44, + kX86InstIdSahf_ExtendedIndex = 177, + kX86InstIdSal_ExtendedIndex = 178, + kX86InstIdSar_ExtendedIndex = 178, + kX86InstIdSarx_ExtendedIndex = 179, + kX86InstIdSbb_ExtendedIndex = 1, + kX86InstIdScasB_ExtendedIndex = 31, + kX86InstIdScasD_ExtendedIndex = 31, + kX86InstIdScasQ_ExtendedIndex = 32, + kX86InstIdScasW_ExtendedIndex = 33, + kX86InstIdSeta_ExtendedIndex = 180, + kX86InstIdSetae_ExtendedIndex = 181, + kX86InstIdSetb_ExtendedIndex = 181, + kX86InstIdSetbe_ExtendedIndex = 180, + kX86InstIdSetc_ExtendedIndex = 181, + kX86InstIdSete_ExtendedIndex = 182, + kX86InstIdSetg_ExtendedIndex = 183, + kX86InstIdSetge_ExtendedIndex = 184, + kX86InstIdSetl_ExtendedIndex = 184, + kX86InstIdSetle_ExtendedIndex = 183, + kX86InstIdSetna_ExtendedIndex = 180, + kX86InstIdSetnae_ExtendedIndex = 181, + kX86InstIdSetnb_ExtendedIndex = 181, + kX86InstIdSetnbe_ExtendedIndex = 180, + kX86InstIdSetnc_ExtendedIndex = 181, + kX86InstIdSetne_ExtendedIndex = 182, + kX86InstIdSetng_ExtendedIndex = 183, + kX86InstIdSetnge_ExtendedIndex = 184, + kX86InstIdSetnl_ExtendedIndex = 184, + kX86InstIdSetnle_ExtendedIndex = 183, + kX86InstIdSetno_ExtendedIndex = 185, + kX86InstIdSetnp_ExtendedIndex = 186, + kX86InstIdSetns_ExtendedIndex = 187, + kX86InstIdSetnz_ExtendedIndex = 182, + kX86InstIdSeto_ExtendedIndex = 185, + kX86InstIdSetp_ExtendedIndex = 186, + kX86InstIdSetpe_ExtendedIndex = 186, + kX86InstIdSetpo_ExtendedIndex = 186, + kX86InstIdSets_ExtendedIndex = 187, + kX86InstIdSetz_ExtendedIndex = 182, + kX86InstIdSfence_ExtendedIndex = 92, + kX86InstIdShl_ExtendedIndex = 178, + kX86InstIdShld_ExtendedIndex = 188, + kX86InstIdShlx_ExtendedIndex = 179, + kX86InstIdShr_ExtendedIndex = 178, + kX86InstIdShrd_ExtendedIndex = 189, + kX86InstIdShrx_ExtendedIndex = 179, + kX86InstIdShufpd_ExtendedIndex = 4, + kX86InstIdShufps_ExtendedIndex = 4, + kX86InstIdSqrtpd_ExtendedIndex = 39, + kX86InstIdSqrtps_ExtendedIndex = 39, + kX86InstIdSqrtsd_ExtendedIndex = 47, + kX86InstIdSqrtss_ExtendedIndex = 44, + kX86InstIdStc_ExtendedIndex = 18, + kX86InstIdStd_ExtendedIndex = 19, + kX86InstIdStmxcsr_ExtendedIndex = 20, + kX86InstIdStosB_ExtendedIndex = 190, + kX86InstIdStosD_ExtendedIndex = 190, + kX86InstIdStosQ_ExtendedIndex = 191, + kX86InstIdStosW_ExtendedIndex = 192, + kX86InstIdSub_ExtendedIndex = 2, + kX86InstIdSubpd_ExtendedIndex = 3, + kX86InstIdSubps_ExtendedIndex = 3, + kX86InstIdSubsd_ExtendedIndex = 3, + kX86InstIdSubss_ExtendedIndex = 3, + kX86InstIdTest_ExtendedIndex = 193, + kX86InstIdTzcnt_ExtendedIndex = 194, + kX86InstIdUcomisd_ExtendedIndex = 37, + kX86InstIdUcomiss_ExtendedIndex = 37, + kX86InstIdUd2_ExtendedIndex = 51, + kX86InstIdUnpckhpd_ExtendedIndex = 3, + kX86InstIdUnpckhps_ExtendedIndex = 3, + kX86InstIdUnpcklpd_ExtendedIndex = 3, + kX86InstIdUnpcklps_ExtendedIndex = 3, + kX86InstIdVaddpd_ExtendedIndex = 195, + kX86InstIdVaddps_ExtendedIndex = 195, + kX86InstIdVaddsd_ExtendedIndex = 195, + kX86InstIdVaddss_ExtendedIndex = 195, + kX86InstIdVaddsubpd_ExtendedIndex = 195, + kX86InstIdVaddsubps_ExtendedIndex = 195, + kX86InstIdVaesdec_ExtendedIndex = 196, + kX86InstIdVaesdeclast_ExtendedIndex = 196, + kX86InstIdVaesenc_ExtendedIndex = 196, + kX86InstIdVaesenclast_ExtendedIndex = 196, + kX86InstIdVaesimc_ExtendedIndex = 197, + kX86InstIdVaeskeygenassist_ExtendedIndex = 198, + kX86InstIdVandnpd_ExtendedIndex = 195, + kX86InstIdVandnps_ExtendedIndex = 195, + kX86InstIdVandpd_ExtendedIndex = 195, + kX86InstIdVandps_ExtendedIndex = 195, + kX86InstIdVblendpd_ExtendedIndex = 199, + kX86InstIdVblendps_ExtendedIndex = 199, + kX86InstIdVblendvpd_ExtendedIndex = 200, + kX86InstIdVblendvps_ExtendedIndex = 200, + kX86InstIdVbroadcastf128_ExtendedIndex = 201, + kX86InstIdVbroadcasti128_ExtendedIndex = 201, + kX86InstIdVbroadcastsd_ExtendedIndex = 202, + kX86InstIdVbroadcastss_ExtendedIndex = 202, + kX86InstIdVcmppd_ExtendedIndex = 199, + kX86InstIdVcmpps_ExtendedIndex = 199, + kX86InstIdVcmpsd_ExtendedIndex = 203, + kX86InstIdVcmpss_ExtendedIndex = 203, + kX86InstIdVcomisd_ExtendedIndex = 197, + kX86InstIdVcomiss_ExtendedIndex = 197, + kX86InstIdVcvtdq2pd_ExtendedIndex = 204, + kX86InstIdVcvtdq2ps_ExtendedIndex = 205, + kX86InstIdVcvtpd2dq_ExtendedIndex = 206, + kX86InstIdVcvtpd2ps_ExtendedIndex = 206, + kX86InstIdVcvtph2ps_ExtendedIndex = 204, + kX86InstIdVcvtps2dq_ExtendedIndex = 205, + kX86InstIdVcvtps2pd_ExtendedIndex = 204, + kX86InstIdVcvtps2ph_ExtendedIndex = 207, + kX86InstIdVcvtsd2si_ExtendedIndex = 208, + kX86InstIdVcvtsd2ss_ExtendedIndex = 196, + kX86InstIdVcvtsi2sd_ExtendedIndex = 209, + kX86InstIdVcvtsi2ss_ExtendedIndex = 209, + kX86InstIdVcvtss2sd_ExtendedIndex = 196, + kX86InstIdVcvtss2si_ExtendedIndex = 208, + kX86InstIdVcvttpd2dq_ExtendedIndex = 210, + kX86InstIdVcvttps2dq_ExtendedIndex = 205, + kX86InstIdVcvttsd2si_ExtendedIndex = 208, + kX86InstIdVcvttss2si_ExtendedIndex = 208, + kX86InstIdVdivpd_ExtendedIndex = 195, + kX86InstIdVdivps_ExtendedIndex = 195, + kX86InstIdVdivsd_ExtendedIndex = 196, + kX86InstIdVdivss_ExtendedIndex = 196, + kX86InstIdVdppd_ExtendedIndex = 203, + kX86InstIdVdpps_ExtendedIndex = 199, + kX86InstIdVextractf128_ExtendedIndex = 211, + kX86InstIdVextracti128_ExtendedIndex = 211, + kX86InstIdVextractps_ExtendedIndex = 212, + kX86InstIdVfmadd132pd_ExtendedIndex = 213, + kX86InstIdVfmadd132ps_ExtendedIndex = 195, + kX86InstIdVfmadd132sd_ExtendedIndex = 214, + kX86InstIdVfmadd132ss_ExtendedIndex = 196, + kX86InstIdVfmadd213pd_ExtendedIndex = 213, + kX86InstIdVfmadd213ps_ExtendedIndex = 195, + kX86InstIdVfmadd213sd_ExtendedIndex = 214, + kX86InstIdVfmadd213ss_ExtendedIndex = 196, + kX86InstIdVfmadd231pd_ExtendedIndex = 213, + kX86InstIdVfmadd231ps_ExtendedIndex = 195, + kX86InstIdVfmadd231sd_ExtendedIndex = 214, + kX86InstIdVfmadd231ss_ExtendedIndex = 196, + kX86InstIdVfmaddpd_ExtendedIndex = 215, + kX86InstIdVfmaddps_ExtendedIndex = 215, + kX86InstIdVfmaddsd_ExtendedIndex = 216, + kX86InstIdVfmaddss_ExtendedIndex = 216, + kX86InstIdVfmaddsub132pd_ExtendedIndex = 213, + kX86InstIdVfmaddsub132ps_ExtendedIndex = 195, + kX86InstIdVfmaddsub213pd_ExtendedIndex = 213, + kX86InstIdVfmaddsub213ps_ExtendedIndex = 195, + kX86InstIdVfmaddsub231pd_ExtendedIndex = 213, + kX86InstIdVfmaddsub231ps_ExtendedIndex = 195, + kX86InstIdVfmaddsubpd_ExtendedIndex = 215, + kX86InstIdVfmaddsubps_ExtendedIndex = 215, + kX86InstIdVfmsub132pd_ExtendedIndex = 213, + kX86InstIdVfmsub132ps_ExtendedIndex = 195, + kX86InstIdVfmsub132sd_ExtendedIndex = 214, + kX86InstIdVfmsub132ss_ExtendedIndex = 196, + kX86InstIdVfmsub213pd_ExtendedIndex = 213, + kX86InstIdVfmsub213ps_ExtendedIndex = 195, + kX86InstIdVfmsub213sd_ExtendedIndex = 214, + kX86InstIdVfmsub213ss_ExtendedIndex = 196, + kX86InstIdVfmsub231pd_ExtendedIndex = 213, + kX86InstIdVfmsub231ps_ExtendedIndex = 195, + kX86InstIdVfmsub231sd_ExtendedIndex = 214, + kX86InstIdVfmsub231ss_ExtendedIndex = 196, + kX86InstIdVfmsubadd132pd_ExtendedIndex = 213, + kX86InstIdVfmsubadd132ps_ExtendedIndex = 195, + kX86InstIdVfmsubadd213pd_ExtendedIndex = 213, + kX86InstIdVfmsubadd213ps_ExtendedIndex = 195, + kX86InstIdVfmsubadd231pd_ExtendedIndex = 213, + kX86InstIdVfmsubadd231ps_ExtendedIndex = 195, + kX86InstIdVfmsubaddpd_ExtendedIndex = 215, + kX86InstIdVfmsubaddps_ExtendedIndex = 215, + kX86InstIdVfmsubpd_ExtendedIndex = 215, + kX86InstIdVfmsubps_ExtendedIndex = 215, + kX86InstIdVfmsubsd_ExtendedIndex = 216, + kX86InstIdVfmsubss_ExtendedIndex = 216, + kX86InstIdVfnmadd132pd_ExtendedIndex = 213, + kX86InstIdVfnmadd132ps_ExtendedIndex = 195, + kX86InstIdVfnmadd132sd_ExtendedIndex = 214, + kX86InstIdVfnmadd132ss_ExtendedIndex = 196, + kX86InstIdVfnmadd213pd_ExtendedIndex = 213, + kX86InstIdVfnmadd213ps_ExtendedIndex = 195, + kX86InstIdVfnmadd213sd_ExtendedIndex = 214, + kX86InstIdVfnmadd213ss_ExtendedIndex = 196, + kX86InstIdVfnmadd231pd_ExtendedIndex = 213, + kX86InstIdVfnmadd231ps_ExtendedIndex = 195, + kX86InstIdVfnmadd231sd_ExtendedIndex = 214, + kX86InstIdVfnmadd231ss_ExtendedIndex = 196, + kX86InstIdVfnmaddpd_ExtendedIndex = 215, + kX86InstIdVfnmaddps_ExtendedIndex = 215, + kX86InstIdVfnmaddsd_ExtendedIndex = 216, + kX86InstIdVfnmaddss_ExtendedIndex = 216, + kX86InstIdVfnmsub132pd_ExtendedIndex = 213, + kX86InstIdVfnmsub132ps_ExtendedIndex = 195, + kX86InstIdVfnmsub132sd_ExtendedIndex = 214, + kX86InstIdVfnmsub132ss_ExtendedIndex = 196, + kX86InstIdVfnmsub213pd_ExtendedIndex = 213, + kX86InstIdVfnmsub213ps_ExtendedIndex = 195, + kX86InstIdVfnmsub213sd_ExtendedIndex = 214, + kX86InstIdVfnmsub213ss_ExtendedIndex = 196, + kX86InstIdVfnmsub231pd_ExtendedIndex = 213, + kX86InstIdVfnmsub231ps_ExtendedIndex = 195, + kX86InstIdVfnmsub231sd_ExtendedIndex = 214, + kX86InstIdVfnmsub231ss_ExtendedIndex = 196, + kX86InstIdVfnmsubpd_ExtendedIndex = 215, + kX86InstIdVfnmsubps_ExtendedIndex = 215, + kX86InstIdVfnmsubsd_ExtendedIndex = 216, + kX86InstIdVfnmsubss_ExtendedIndex = 216, + kX86InstIdVfrczpd_ExtendedIndex = 217, + kX86InstIdVfrczps_ExtendedIndex = 217, + kX86InstIdVfrczsd_ExtendedIndex = 218, + kX86InstIdVfrczss_ExtendedIndex = 218, + kX86InstIdVgatherdpd_ExtendedIndex = 219, + kX86InstIdVgatherdps_ExtendedIndex = 220, + kX86InstIdVgatherqpd_ExtendedIndex = 219, + kX86InstIdVgatherqps_ExtendedIndex = 221, + kX86InstIdVhaddpd_ExtendedIndex = 195, + kX86InstIdVhaddps_ExtendedIndex = 195, + kX86InstIdVhsubpd_ExtendedIndex = 195, + kX86InstIdVhsubps_ExtendedIndex = 195, + kX86InstIdVinsertf128_ExtendedIndex = 222, + kX86InstIdVinserti128_ExtendedIndex = 222, + kX86InstIdVinsertps_ExtendedIndex = 203, + kX86InstIdVlddqu_ExtendedIndex = 223, + kX86InstIdVldmxcsr_ExtendedIndex = 224, + kX86InstIdVmaskmovdqu_ExtendedIndex = 225, + kX86InstIdVmaskmovpd_ExtendedIndex = 226, + kX86InstIdVmaskmovps_ExtendedIndex = 227, + kX86InstIdVmaxpd_ExtendedIndex = 195, + kX86InstIdVmaxps_ExtendedIndex = 195, + kX86InstIdVmaxsd_ExtendedIndex = 195, + kX86InstIdVmaxss_ExtendedIndex = 195, + kX86InstIdVminpd_ExtendedIndex = 195, + kX86InstIdVminps_ExtendedIndex = 195, + kX86InstIdVminsd_ExtendedIndex = 195, + kX86InstIdVminss_ExtendedIndex = 195, + kX86InstIdVmovapd_ExtendedIndex = 228, + kX86InstIdVmovaps_ExtendedIndex = 229, + kX86InstIdVmovd_ExtendedIndex = 230, + kX86InstIdVmovddup_ExtendedIndex = 205, + kX86InstIdVmovdqa_ExtendedIndex = 231, + kX86InstIdVmovdqu_ExtendedIndex = 232, + kX86InstIdVmovhlps_ExtendedIndex = 233, + kX86InstIdVmovhpd_ExtendedIndex = 234, + kX86InstIdVmovhps_ExtendedIndex = 235, + kX86InstIdVmovlhps_ExtendedIndex = 233, + kX86InstIdVmovlpd_ExtendedIndex = 236, + kX86InstIdVmovlps_ExtendedIndex = 237, + kX86InstIdVmovmskpd_ExtendedIndex = 238, + kX86InstIdVmovmskps_ExtendedIndex = 238, + kX86InstIdVmovntdq_ExtendedIndex = 239, + kX86InstIdVmovntdqa_ExtendedIndex = 223, + kX86InstIdVmovntpd_ExtendedIndex = 240, + kX86InstIdVmovntps_ExtendedIndex = 240, + kX86InstIdVmovq_ExtendedIndex = 241, + kX86InstIdVmovsd_ExtendedIndex = 242, + kX86InstIdVmovshdup_ExtendedIndex = 205, + kX86InstIdVmovsldup_ExtendedIndex = 205, + kX86InstIdVmovss_ExtendedIndex = 243, + kX86InstIdVmovupd_ExtendedIndex = 244, + kX86InstIdVmovups_ExtendedIndex = 245, + kX86InstIdVmpsadbw_ExtendedIndex = 199, + kX86InstIdVmulpd_ExtendedIndex = 195, + kX86InstIdVmulps_ExtendedIndex = 195, + kX86InstIdVmulsd_ExtendedIndex = 195, + kX86InstIdVmulss_ExtendedIndex = 195, + kX86InstIdVorpd_ExtendedIndex = 195, + kX86InstIdVorps_ExtendedIndex = 195, + kX86InstIdVpabsb_ExtendedIndex = 205, + kX86InstIdVpabsd_ExtendedIndex = 205, + kX86InstIdVpabsw_ExtendedIndex = 205, + kX86InstIdVpackssdw_ExtendedIndex = 195, + kX86InstIdVpacksswb_ExtendedIndex = 195, + kX86InstIdVpackusdw_ExtendedIndex = 195, + kX86InstIdVpackuswb_ExtendedIndex = 195, + kX86InstIdVpaddb_ExtendedIndex = 195, + kX86InstIdVpaddd_ExtendedIndex = 195, + kX86InstIdVpaddq_ExtendedIndex = 195, + kX86InstIdVpaddsb_ExtendedIndex = 195, + kX86InstIdVpaddsw_ExtendedIndex = 195, + kX86InstIdVpaddusb_ExtendedIndex = 195, + kX86InstIdVpaddusw_ExtendedIndex = 195, + kX86InstIdVpaddw_ExtendedIndex = 195, + kX86InstIdVpalignr_ExtendedIndex = 199, + kX86InstIdVpand_ExtendedIndex = 195, + kX86InstIdVpandn_ExtendedIndex = 195, + kX86InstIdVpavgb_ExtendedIndex = 195, + kX86InstIdVpavgw_ExtendedIndex = 195, + kX86InstIdVpblendd_ExtendedIndex = 199, + kX86InstIdVpblendvb_ExtendedIndex = 246, + kX86InstIdVpblendw_ExtendedIndex = 199, + kX86InstIdVpbroadcastb_ExtendedIndex = 204, + kX86InstIdVpbroadcastd_ExtendedIndex = 204, + kX86InstIdVpbroadcastq_ExtendedIndex = 204, + kX86InstIdVpbroadcastw_ExtendedIndex = 204, + kX86InstIdVpclmulqdq_ExtendedIndex = 203, + kX86InstIdVpcmov_ExtendedIndex = 247, + kX86InstIdVpcmpeqb_ExtendedIndex = 195, + kX86InstIdVpcmpeqd_ExtendedIndex = 195, + kX86InstIdVpcmpeqq_ExtendedIndex = 195, + kX86InstIdVpcmpeqw_ExtendedIndex = 195, + kX86InstIdVpcmpestri_ExtendedIndex = 198, + kX86InstIdVpcmpestrm_ExtendedIndex = 198, + kX86InstIdVpcmpgtb_ExtendedIndex = 195, + kX86InstIdVpcmpgtd_ExtendedIndex = 195, + kX86InstIdVpcmpgtq_ExtendedIndex = 195, + kX86InstIdVpcmpgtw_ExtendedIndex = 195, + kX86InstIdVpcmpistri_ExtendedIndex = 198, + kX86InstIdVpcmpistrm_ExtendedIndex = 198, + kX86InstIdVpcomb_ExtendedIndex = 248, + kX86InstIdVpcomd_ExtendedIndex = 248, + kX86InstIdVpcomq_ExtendedIndex = 248, + kX86InstIdVpcomub_ExtendedIndex = 248, + kX86InstIdVpcomud_ExtendedIndex = 248, + kX86InstIdVpcomuq_ExtendedIndex = 248, + kX86InstIdVpcomuw_ExtendedIndex = 248, + kX86InstIdVpcomw_ExtendedIndex = 248, + kX86InstIdVperm2f128_ExtendedIndex = 249, + kX86InstIdVperm2i128_ExtendedIndex = 249, + kX86InstIdVpermd_ExtendedIndex = 250, + kX86InstIdVpermil2pd_ExtendedIndex = 251, + kX86InstIdVpermil2ps_ExtendedIndex = 251, + kX86InstIdVpermilpd_ExtendedIndex = 252, + kX86InstIdVpermilps_ExtendedIndex = 253, + kX86InstIdVpermpd_ExtendedIndex = 254, + kX86InstIdVpermps_ExtendedIndex = 250, + kX86InstIdVpermq_ExtendedIndex = 254, + kX86InstIdVpextrb_ExtendedIndex = 255, + kX86InstIdVpextrd_ExtendedIndex = 212, + kX86InstIdVpextrq_ExtendedIndex = 256, + kX86InstIdVpextrw_ExtendedIndex = 257, + kX86InstIdVpgatherdd_ExtendedIndex = 220, + kX86InstIdVpgatherdq_ExtendedIndex = 219, + kX86InstIdVpgatherqd_ExtendedIndex = 221, + kX86InstIdVpgatherqq_ExtendedIndex = 219, + kX86InstIdVphaddbd_ExtendedIndex = 218, + kX86InstIdVphaddbq_ExtendedIndex = 218, + kX86InstIdVphaddbw_ExtendedIndex = 218, + kX86InstIdVphaddd_ExtendedIndex = 195, + kX86InstIdVphadddq_ExtendedIndex = 218, + kX86InstIdVphaddsw_ExtendedIndex = 195, + kX86InstIdVphaddubd_ExtendedIndex = 218, + kX86InstIdVphaddubq_ExtendedIndex = 218, + kX86InstIdVphaddubw_ExtendedIndex = 218, + kX86InstIdVphaddudq_ExtendedIndex = 218, + kX86InstIdVphadduwd_ExtendedIndex = 218, + kX86InstIdVphadduwq_ExtendedIndex = 218, + kX86InstIdVphaddw_ExtendedIndex = 195, + kX86InstIdVphaddwd_ExtendedIndex = 218, + kX86InstIdVphaddwq_ExtendedIndex = 218, + kX86InstIdVphminposuw_ExtendedIndex = 197, + kX86InstIdVphsubbw_ExtendedIndex = 218, + kX86InstIdVphsubd_ExtendedIndex = 195, + kX86InstIdVphsubdq_ExtendedIndex = 218, + kX86InstIdVphsubsw_ExtendedIndex = 195, + kX86InstIdVphsubw_ExtendedIndex = 195, + kX86InstIdVphsubwd_ExtendedIndex = 218, + kX86InstIdVpinsrb_ExtendedIndex = 258, + kX86InstIdVpinsrd_ExtendedIndex = 259, + kX86InstIdVpinsrq_ExtendedIndex = 260, + kX86InstIdVpinsrw_ExtendedIndex = 261, + kX86InstIdVpmacsdd_ExtendedIndex = 262, + kX86InstIdVpmacsdqh_ExtendedIndex = 262, + kX86InstIdVpmacsdql_ExtendedIndex = 262, + kX86InstIdVpmacssdd_ExtendedIndex = 262, + kX86InstIdVpmacssdqh_ExtendedIndex = 262, + kX86InstIdVpmacssdql_ExtendedIndex = 262, + kX86InstIdVpmacsswd_ExtendedIndex = 262, + kX86InstIdVpmacssww_ExtendedIndex = 262, + kX86InstIdVpmacswd_ExtendedIndex = 262, + kX86InstIdVpmacsww_ExtendedIndex = 262, + kX86InstIdVpmadcsswd_ExtendedIndex = 262, + kX86InstIdVpmadcswd_ExtendedIndex = 262, + kX86InstIdVpmaddubsw_ExtendedIndex = 195, + kX86InstIdVpmaddwd_ExtendedIndex = 195, + kX86InstIdVpmaskmovd_ExtendedIndex = 263, + kX86InstIdVpmaskmovq_ExtendedIndex = 264, + kX86InstIdVpmaxsb_ExtendedIndex = 195, + kX86InstIdVpmaxsd_ExtendedIndex = 195, + kX86InstIdVpmaxsw_ExtendedIndex = 195, + kX86InstIdVpmaxub_ExtendedIndex = 195, + kX86InstIdVpmaxud_ExtendedIndex = 195, + kX86InstIdVpmaxuw_ExtendedIndex = 195, + kX86InstIdVpminsb_ExtendedIndex = 195, + kX86InstIdVpminsd_ExtendedIndex = 195, + kX86InstIdVpminsw_ExtendedIndex = 195, + kX86InstIdVpminub_ExtendedIndex = 195, + kX86InstIdVpminud_ExtendedIndex = 195, + kX86InstIdVpminuw_ExtendedIndex = 195, + kX86InstIdVpmovmskb_ExtendedIndex = 238, + kX86InstIdVpmovsxbd_ExtendedIndex = 205, + kX86InstIdVpmovsxbq_ExtendedIndex = 205, + kX86InstIdVpmovsxbw_ExtendedIndex = 205, + kX86InstIdVpmovsxdq_ExtendedIndex = 205, + kX86InstIdVpmovsxwd_ExtendedIndex = 205, + kX86InstIdVpmovsxwq_ExtendedIndex = 205, + kX86InstIdVpmovzxbd_ExtendedIndex = 205, + kX86InstIdVpmovzxbq_ExtendedIndex = 205, + kX86InstIdVpmovzxbw_ExtendedIndex = 205, + kX86InstIdVpmovzxdq_ExtendedIndex = 205, + kX86InstIdVpmovzxwd_ExtendedIndex = 205, + kX86InstIdVpmovzxwq_ExtendedIndex = 205, + kX86InstIdVpmuldq_ExtendedIndex = 195, + kX86InstIdVpmulhrsw_ExtendedIndex = 195, + kX86InstIdVpmulhuw_ExtendedIndex = 195, + kX86InstIdVpmulhw_ExtendedIndex = 195, + kX86InstIdVpmulld_ExtendedIndex = 195, + kX86InstIdVpmullw_ExtendedIndex = 195, + kX86InstIdVpmuludq_ExtendedIndex = 195, + kX86InstIdVpor_ExtendedIndex = 195, + kX86InstIdVpperm_ExtendedIndex = 265, + kX86InstIdVprotb_ExtendedIndex = 266, + kX86InstIdVprotd_ExtendedIndex = 267, + kX86InstIdVprotq_ExtendedIndex = 268, + kX86InstIdVprotw_ExtendedIndex = 269, + kX86InstIdVpsadbw_ExtendedIndex = 195, + kX86InstIdVpshab_ExtendedIndex = 270, + kX86InstIdVpshad_ExtendedIndex = 270, + kX86InstIdVpshaq_ExtendedIndex = 270, + kX86InstIdVpshaw_ExtendedIndex = 270, + kX86InstIdVpshlb_ExtendedIndex = 270, + kX86InstIdVpshld_ExtendedIndex = 270, + kX86InstIdVpshlq_ExtendedIndex = 270, + kX86InstIdVpshlw_ExtendedIndex = 270, + kX86InstIdVpshufb_ExtendedIndex = 195, + kX86InstIdVpshufd_ExtendedIndex = 271, + kX86InstIdVpshufhw_ExtendedIndex = 271, + kX86InstIdVpshuflw_ExtendedIndex = 271, + kX86InstIdVpsignb_ExtendedIndex = 195, + kX86InstIdVpsignd_ExtendedIndex = 195, + kX86InstIdVpsignw_ExtendedIndex = 195, + kX86InstIdVpslld_ExtendedIndex = 272, + kX86InstIdVpslldq_ExtendedIndex = 273, + kX86InstIdVpsllq_ExtendedIndex = 274, + kX86InstIdVpsllvd_ExtendedIndex = 195, + kX86InstIdVpsllvq_ExtendedIndex = 213, + kX86InstIdVpsllw_ExtendedIndex = 275, + kX86InstIdVpsrad_ExtendedIndex = 276, + kX86InstIdVpsravd_ExtendedIndex = 195, + kX86InstIdVpsraw_ExtendedIndex = 277, + kX86InstIdVpsrld_ExtendedIndex = 278, + kX86InstIdVpsrldq_ExtendedIndex = 273, + kX86InstIdVpsrlq_ExtendedIndex = 279, + kX86InstIdVpsrlvd_ExtendedIndex = 195, + kX86InstIdVpsrlvq_ExtendedIndex = 213, + kX86InstIdVpsrlw_ExtendedIndex = 280, + kX86InstIdVpsubb_ExtendedIndex = 195, + kX86InstIdVpsubd_ExtendedIndex = 195, + kX86InstIdVpsubq_ExtendedIndex = 195, + kX86InstIdVpsubsb_ExtendedIndex = 195, + kX86InstIdVpsubsw_ExtendedIndex = 195, + kX86InstIdVpsubusb_ExtendedIndex = 195, + kX86InstIdVpsubusw_ExtendedIndex = 195, + kX86InstIdVpsubw_ExtendedIndex = 195, + kX86InstIdVptest_ExtendedIndex = 281, + kX86InstIdVpunpckhbw_ExtendedIndex = 195, + kX86InstIdVpunpckhdq_ExtendedIndex = 195, + kX86InstIdVpunpckhqdq_ExtendedIndex = 195, + kX86InstIdVpunpckhwd_ExtendedIndex = 195, + kX86InstIdVpunpcklbw_ExtendedIndex = 195, + kX86InstIdVpunpckldq_ExtendedIndex = 195, + kX86InstIdVpunpcklqdq_ExtendedIndex = 195, + kX86InstIdVpunpcklwd_ExtendedIndex = 195, + kX86InstIdVpxor_ExtendedIndex = 195, + kX86InstIdVrcpps_ExtendedIndex = 205, + kX86InstIdVrcpss_ExtendedIndex = 196, + kX86InstIdVroundpd_ExtendedIndex = 271, + kX86InstIdVroundps_ExtendedIndex = 271, + kX86InstIdVroundsd_ExtendedIndex = 203, + kX86InstIdVroundss_ExtendedIndex = 203, + kX86InstIdVrsqrtps_ExtendedIndex = 205, + kX86InstIdVrsqrtss_ExtendedIndex = 196, + kX86InstIdVshufpd_ExtendedIndex = 199, + kX86InstIdVshufps_ExtendedIndex = 199, + kX86InstIdVsqrtpd_ExtendedIndex = 205, + kX86InstIdVsqrtps_ExtendedIndex = 205, + kX86InstIdVsqrtsd_ExtendedIndex = 196, + kX86InstIdVsqrtss_ExtendedIndex = 196, + kX86InstIdVstmxcsr_ExtendedIndex = 224, + kX86InstIdVsubpd_ExtendedIndex = 195, + kX86InstIdVsubps_ExtendedIndex = 195, + kX86InstIdVsubsd_ExtendedIndex = 196, + kX86InstIdVsubss_ExtendedIndex = 196, + kX86InstIdVtestpd_ExtendedIndex = 282, + kX86InstIdVtestps_ExtendedIndex = 282, + kX86InstIdVucomisd_ExtendedIndex = 283, + kX86InstIdVucomiss_ExtendedIndex = 283, + kX86InstIdVunpckhpd_ExtendedIndex = 195, + kX86InstIdVunpckhps_ExtendedIndex = 195, + kX86InstIdVunpcklpd_ExtendedIndex = 195, + kX86InstIdVunpcklps_ExtendedIndex = 195, + kX86InstIdVxorpd_ExtendedIndex = 195, + kX86InstIdVxorps_ExtendedIndex = 195, + kX86InstIdVzeroall_ExtendedIndex = 284, + kX86InstIdVzeroupper_ExtendedIndex = 284, + kX86InstIdWrfsbase_ExtendedIndex = 285, + kX86InstIdWrgsbase_ExtendedIndex = 285, + kX86InstIdXadd_ExtendedIndex = 286, + kX86InstIdXchg_ExtendedIndex = 287, + kX86InstIdXor_ExtendedIndex = 2, + kX86InstIdXorpd_ExtendedIndex = 3, + kX86InstIdXorps_ExtendedIndex = 3 +}; +// ${X86InstData:End} + +// Instruction data. +// +// Please rerun tools/src-gendefs.js (by using node.js) to regenerate instruction +// names and extended info tables. +const X86InstInfo _x86InstInfo[] = { + // Inst-Code | Inst-Name | Inst-Group | Inst-Flags | M | Op-Flags[0] | Op-Flags[1] | Op-Flags[2] | Op-Flags[2] | E-OSZAPCDX | OpCode[0] | OpCode[1] | + INST(kInstIdNone , "" , G(None) , F(None) , 0 , U , U , U , U , E(________) , U , U ), + INST(kX86InstIdAdc , "adc" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(10,2) , U ), + INST(kX86InstIdAdd , "add" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(00,0) , U ), + INST(kX86InstIdAddpd , "addpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(58,U) , U ), + INST(kX86InstIdAddps , "addps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(58,U) , U ), + INST(kX86InstIdAddsd , "addsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(58,U) , U ), + INST(kX86InstIdAddss , "addss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(58,U) , U ), + INST(kX86InstIdAddsubpd , "addsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(D0,U) , U ), + INST(kX86InstIdAddsubps , "addsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(D0,U) , U ), + INST(kX86InstIdAesdec , "aesdec" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DE,U) , U ), + INST(kX86InstIdAesdeclast , "aesdeclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DF,U) , U ), + INST(kX86InstIdAesenc , "aesenc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DC,U) , U ), + INST(kX86InstIdAesenclast , "aesenclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DD,U) , U ), + INST(kX86InstIdAesimc , "aesimc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ), + INST(kX86InstIdAeskeygenassist , "aeskeygenassist" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ), + INST(kX86InstIdAnd , "and" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(20,4) , U ), + INST(kX86InstIdAndn , "andn" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(WWWUUW__) , O_000F38(F2,U) , U ), + INST(kX86InstIdAndnpd , "andnpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(55,U) , U ), + INST(kX86InstIdAndnps , "andnps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(55,U) , U ), + INST(kX86InstIdAndpd , "andpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(54,U) , U ), + INST(kX86InstIdAndps , "andps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(54,U) , U ), + INST(kX86InstIdBextr , "bextr" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WUWUUW__) , O_000F38(F7,U) , U ), + INST(kX86InstIdBlendpd , "blendpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0D,U) , U ), + INST(kX86InstIdBlendps , "blendps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0C,U) , U ), + INST(kX86InstIdBlendvpd , "blendvpd" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(15,U) , U ), + INST(kX86InstIdBlendvps , "blendvps" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(14,U) , U ), + INST(kX86InstIdBlsi , "blsi" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,3) , U ), + INST(kX86InstIdBlsmsk , "blsmsk" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,2) , U ), + INST(kX86InstIdBlsr , "blsr" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,1) , U ), + INST(kX86InstIdBsf , "bsf" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BC,U) , U ), + INST(kX86InstIdBsr , "bsr" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BD,U) , U ), + INST(kX86InstIdBswap , "bswap" , G(X86BSwap) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_000F00(C8,U) , U ), + INST(kX86InstIdBt , "bt" , G(X86BTest) , F(Test) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(A3,U) , O_000F00(BA,4) ), + INST(kX86InstIdBtc , "btc" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(BB,U) , O_000F00(BA,7) ), + INST(kX86InstIdBtr , "btr" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(B3,U) , O_000F00(BA,6) ), + INST(kX86InstIdBts , "bts" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(AB,U) , O_000F00(BA,5) ), + INST(kX86InstIdBzhi , "bzhi" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WWWUUW__) , O_000F38(F5,U) , U ), + INST(kX86InstIdCall , "call" , G(X86Call) , F(Flow) , 0 , O(GqdMem)|O(Imm)|O(Label), U , U , U , E(________) , O_000000(FF,2) , O_000000(E8,U) ), + INST(kX86InstIdCbw , "cbw" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(98,U) , U ), + INST(kX86InstIdCdq , "cdq" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(99,U) , U ), + INST(kX86InstIdCdqe , "cdqe" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(98,U) , U ), + INST(kX86InstIdClc , "clc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F8,U) , U ), + INST(kX86InstIdCld , "cld" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FC,U) , U ), + INST(kX86InstIdClflush , "clflush" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,7) , U ), + INST(kX86InstIdCmc , "cmc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____X__) , O_000000(F5,U) , U ), + INST(kX86InstIdCmova , "cmova" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ), + INST(kX86InstIdCmovae , "cmovae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), + INST(kX86InstIdCmovb , "cmovb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), + INST(kX86InstIdCmovbe , "cmovbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ), + INST(kX86InstIdCmovc , "cmovc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), + INST(kX86InstIdCmove , "cmove" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ), + INST(kX86InstIdCmovg , "cmovg" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ), + INST(kX86InstIdCmovge , "cmovge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ), + INST(kX86InstIdCmovl , "cmovl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ), + INST(kX86InstIdCmovle , "cmovle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ), + INST(kX86InstIdCmovna , "cmovna" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ), + INST(kX86InstIdCmovnae , "cmovnae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), + INST(kX86InstIdCmovnb , "cmovnb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), + INST(kX86InstIdCmovnbe , "cmovnbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ), + INST(kX86InstIdCmovnc , "cmovnc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), + INST(kX86InstIdCmovne , "cmovne" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ), + INST(kX86InstIdCmovng , "cmovng" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ), + INST(kX86InstIdCmovnge , "cmovnge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ), + INST(kX86InstIdCmovnl , "cmovnl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ), + INST(kX86InstIdCmovnle , "cmovnle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ), + INST(kX86InstIdCmovno , "cmovno" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(41,U) , U ), + INST(kX86InstIdCmovnp , "cmovnp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ), + INST(kX86InstIdCmovns , "cmovns" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(49,U) , U ), + INST(kX86InstIdCmovnz , "cmovnz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ), + INST(kX86InstIdCmovo , "cmovo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(40,U) , U ), + INST(kX86InstIdCmovp , "cmovp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ), + INST(kX86InstIdCmovpe , "cmovpe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ), + INST(kX86InstIdCmovpo , "cmovpo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ), + INST(kX86InstIdCmovs , "cmovs" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(48,U) , U ), + INST(kX86InstIdCmovz , "cmovz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ), + INST(kX86InstIdCmp , "cmp" , G(X86Arith) , F(Test) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(38,7) , U ), + INST(kX86InstIdCmppd , "cmppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C2,U) , U ), + INST(kX86InstIdCmpps , "cmpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C2,U) , U ), + INST(kX86InstIdCmpsB , "cmps_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A6,U) , U ), + INST(kX86InstIdCmpsD , "cmps_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), + INST(kX86InstIdCmpsQ , "cmps_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), + INST(kX86InstIdCmpsW , "cmps_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), + INST(kX86InstIdCmpsd , "cmpsd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(C2,U) , U ), + INST(kX86InstIdCmpss , "cmpss" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(C2,U) , U ), + INST(kX86InstIdCmpxchg , "cmpxchg" , G(X86RmReg) , F(Lock)|F(Special) , 0 , U , U , U , U , E(WWWWWW__) , O_000F00(B0,U) , U ), + INST(kX86InstIdCmpxchg16b , "cmpxchg16b" , G(X86M) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ), + INST(kX86InstIdCmpxchg8b , "cmpxchg8b" , G(X86M) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ), + INST(kX86InstIdComisd , "comisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2F,U) , U ), + INST(kX86InstIdComiss , "comiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2F,U) , U ), + INST(kX86InstIdCpuid , "cpuid" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(A2,U) , U ), + INST(kX86InstIdCqo , "cqo" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(99,U) , U ), + INST(kX86InstIdCrc32 , "crc32" , G(ExtCrc) , F(None) , 0 , O(Gqd) , O(GqdwbMem) , U , U , E(________) , O_F20F38(F0,U) , U ), + INST(kX86InstIdCvtdq2pd , "cvtdq2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ), + INST(kX86InstIdCvtdq2ps , "cvtdq2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5B,U) , U ), + INST(kX86InstIdCvtpd2dq , "cvtpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ), + INST(kX86InstIdCvtpd2pi , "cvtpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2D,U) , U ), + INST(kX86InstIdCvtpd2ps , "cvtpd2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5A,U) , U ), + INST(kX86InstIdCvtpi2pd , "cvtpi2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(MmMem) , U , U , E(________) , O_660F00(2A,U) , U ), + INST(kX86InstIdCvtpi2ps , "cvtpi2ps" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(MmMem) , U , U , E(________) , O_000F00(2A,U) , U ), + INST(kX86InstIdCvtps2dq , "cvtps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5B,U) , U ), + INST(kX86InstIdCvtps2pd , "cvtps2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ), + INST(kX86InstIdCvtps2pi , "cvtps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2D,U) , U ), + INST(kX86InstIdCvtsd2si , "cvtsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), + INST(kX86InstIdCvtsd2ss , "cvtsd2ss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5A,U) , U ), + INST(kX86InstIdCvtsi2sd , "cvtsi2sd" , G(ExtRm_Q) , F(Move) , 8 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F20F00(2A,U) , U ), + INST(kX86InstIdCvtsi2ss , "cvtsi2ss" , G(ExtRm_Q) , F(Move) , 4 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F30F00(2A,U) , U ), + INST(kX86InstIdCvtss2sd , "cvtss2sd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5A,U) , U ), + INST(kX86InstIdCvtss2si , "cvtss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2D,U) , U ), + INST(kX86InstIdCvttpd2dq , "cvttpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(E6,U) , U ), + INST(kX86InstIdCvttpd2pi , "cvttpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2C,U) , U ), + INST(kX86InstIdCvttps2dq , "cvttps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ), + INST(kX86InstIdCvttps2pi , "cvttps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2C,U) , U ), + INST(kX86InstIdCvttsd2si , "cvttsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ), + INST(kX86InstIdCvttss2si , "cvttss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ), + INST(kX86InstIdCwd , "cwd" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(99,U) , U ), + INST(kX86InstIdCwde , "cwde" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(98,U) , U ), + INST(kX86InstIdDaa , "daa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(27,U) , U ), + INST(kX86InstIdDas , "das" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(2F,U) , U ), + INST(kX86InstIdDec , "dec" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,1) , O_000000(48,U) ), + INST(kX86InstIdDiv , "div" , G(X86Rm_B) , F(None)|F(Special) , 0 , U , U , U , U , E(UUUUUU__) , O_000000(F6,6) , U ), + INST(kX86InstIdDivpd , "divpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5E,U) , U ), + INST(kX86InstIdDivps , "divps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5E,U) , U ), + INST(kX86InstIdDivsd , "divsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5E,U) , U ), + INST(kX86InstIdDivss , "divss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5E,U) , U ), + INST(kX86InstIdDppd , "dppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(41,U) , U ), + INST(kX86InstIdDpps , "dpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(40,U) , U ), + INST(kX86InstIdEmms , "emms" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ), + INST(kX86InstIdEnter , "enter" , G(X86Enter) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C8,U) , U ), + INST(kX86InstIdExtractps , "extractps" , G(ExtExtract) , F(Move) , 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_660F3A(17,U) , O_660F3A(17,U) ), + INST(kX86InstIdF2xm1 , "f2xm1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F0,U) , U ), + INST(kX86InstIdFabs , "fabs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E1,U) , U ), + INST(kX86InstIdFadd , "fadd" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C0C0,0) , U ), + INST(kX86InstIdFaddp , "faddp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC0,U) , U ), + INST(kX86InstIdFbld , "fbld" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,4) , U ), + INST(kX86InstIdFbstp , "fbstp" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,6) , U ), + INST(kX86InstIdFchs , "fchs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E0,U) , U ), + INST(kX86InstIdFclex , "fclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE2,U) , U ), + INST(kX86InstIdFcmovb , "fcmovb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DAC0,U) , U ), + INST(kX86InstIdFcmovbe , "fcmovbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DAD0,U) , U ), + INST(kX86InstIdFcmove , "fcmove" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DAC8,U) , U ), + INST(kX86InstIdFcmovnb , "fcmovnb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DBC0,U) , U ), + INST(kX86InstIdFcmovnbe , "fcmovnbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DBD0,U) , U ), + INST(kX86InstIdFcmovne , "fcmovne" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DBC8,U) , U ), + INST(kX86InstIdFcmovnu , "fcmovnu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DBD8,U) , U ), + INST(kX86InstIdFcmovu , "fcmovu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DAD8,U) , U ), + INST(kX86InstIdFcom , "fcom" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D0D0,2) , U ), + INST(kX86InstIdFcomi , "fcomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBF0,U) , U ), + INST(kX86InstIdFcomip , "fcomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFF0,U) , U ), + INST(kX86InstIdFcomp , "fcomp" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D8D8,3) , U ), + INST(kX86InstIdFcompp , "fcompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DED9,U) , U ), + INST(kX86InstIdFcos , "fcos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FF,U) , U ), + INST(kX86InstIdFdecstp , "fdecstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F6,U) , U ), + INST(kX86InstIdFdiv , "fdiv" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F0F8,6) , U ), + INST(kX86InstIdFdivp , "fdivp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF8,U) , U ), + INST(kX86InstIdFdivr , "fdivr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F8F0,7) , U ), + INST(kX86InstIdFdivrp , "fdivrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF0,U) , U ), + INST(kX86InstIdFemms , "femms" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000F00(0E,U) , U ), + INST(kX86InstIdFfree , "ffree" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDC0,U) , U ), + INST(kX86InstIdFiadd , "fiadd" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,0) , U ), + INST(kX86InstIdFicom , "ficom" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,2) , U ), + INST(kX86InstIdFicomp , "ficomp" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,3) , U ), + INST(kX86InstIdFidiv , "fidiv" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,6) , U ), + INST(kX86InstIdFidivr , "fidivr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,7) , U ), + INST(kX86InstIdFild , "fild" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,0) , O_000000(DF,5) ), + INST(kX86InstIdFimul , "fimul" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,1) , U ), + INST(kX86InstIdFincstp , "fincstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F7,U) , U ), + INST(kX86InstIdFinit , "finit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE3,U) , U ), + INST(kX86InstIdFist , "fist" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,2) , U ), + INST(kX86InstIdFistp , "fistp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,3) , O_000000(DF,7) ), + INST(kX86InstIdFisttp , "fisttp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,1) , O_000000(DD,1) ), + INST(kX86InstIdFisub , "fisub" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,4) , U ), + INST(kX86InstIdFisubr , "fisubr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,5) , U ), + INST(kX86InstIdFld , "fld" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,0) , O_000000(DB,5) ), + INST(kX86InstIdFld1 , "fld1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E8,U) , U ), + INST(kX86InstIdFldcw , "fldcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,5) , U ), + INST(kX86InstIdFldenv , "fldenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,4) , U ), + INST(kX86InstIdFldl2e , "fldl2e" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EA,U) , U ), + INST(kX86InstIdFldl2t , "fldl2t" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E9,U) , U ), + INST(kX86InstIdFldlg2 , "fldlg2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EC,U) , U ), + INST(kX86InstIdFldln2 , "fldln2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9ED,U) , U ), + INST(kX86InstIdFldpi , "fldpi" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EB,U) , U ), + INST(kX86InstIdFldz , "fldz" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EE,U) , U ), + INST(kX86InstIdFmul , "fmul" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C8C8,1) , U ), + INST(kX86InstIdFmulp , "fmulp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC8,U) , U ), + INST(kX86InstIdFnclex , "fnclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE2,U) , U ), + INST(kX86InstIdFninit , "fninit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE3,U) , U ), + INST(kX86InstIdFnop , "fnop" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9D0,U) , U ), + INST(kX86InstIdFnsave , "fnsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,6) , U ), + INST(kX86InstIdFnstcw , "fnstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,7) , U ), + INST(kX86InstIdFnstenv , "fnstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,6) , U ), + INST(kX86InstIdFnstsw , "fnstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,7) , O_00_X(DFE0,U) ), + INST(kX86InstIdFpatan , "fpatan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F3,U) , U ), + INST(kX86InstIdFprem , "fprem" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F8,U) , U ), + INST(kX86InstIdFprem1 , "fprem1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F5,U) , U ), + INST(kX86InstIdFptan , "fptan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F2,U) , U ), + INST(kX86InstIdFrndint , "frndint" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FC,U) , U ), + INST(kX86InstIdFrstor , "frstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,4) , U ), + INST(kX86InstIdFsave , "fsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,6) , U ), + INST(kX86InstIdFscale , "fscale" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FD,U) , U ), + INST(kX86InstIdFsin , "fsin" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FE,U) , U ), + INST(kX86InstIdFsincos , "fsincos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FB,U) , U ), + INST(kX86InstIdFsqrt , "fsqrt" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FA,U) , U ), + INST(kX86InstIdFst , "fst" , G(FpuFldFst) , F(Fp)|F(Mem4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,2) , U ), + INST(kX86InstIdFstcw , "fstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,7) , U ), + INST(kX86InstIdFstenv , "fstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,6) , U ), + INST(kX86InstIdFstp , "fstp" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,3) , O_000000(DB,7) ), + INST(kX86InstIdFstsw , "fstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,7) , O_9B_X(DFE0,U) ), + INST(kX86InstIdFsub , "fsub" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E0E8,4) , U ), + INST(kX86InstIdFsubp , "fsubp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE8,U) , U ), + INST(kX86InstIdFsubr , "fsubr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E8E0,5) , U ), + INST(kX86InstIdFsubrp , "fsubrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE0,U) , U ), + INST(kX86InstIdFtst , "ftst" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E4,U) , U ), + INST(kX86InstIdFucom , "fucom" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE0,U) , U ), + INST(kX86InstIdFucomi , "fucomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBE8,U) , U ), + INST(kX86InstIdFucomip , "fucomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFE8,U) , U ), + INST(kX86InstIdFucomp , "fucomp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE8,U) , U ), + INST(kX86InstIdFucompp , "fucompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DAE9,U) , U ), + INST(kX86InstIdFwait , "fwait" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000000(DB,U) , U ), + INST(kX86InstIdFxam , "fxam" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E5,U) , U ), + INST(kX86InstIdFxch , "fxch" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(D9C8,U) , U ), + INST(kX86InstIdFxrstor , "fxrstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,1) , U ), + INST(kX86InstIdFxsave , "fxsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,0) , U ), + INST(kX86InstIdFxtract , "fxtract" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F4,U) , U ), + INST(kX86InstIdFyl2x , "fyl2x" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F1,U) , U ), + INST(kX86InstIdFyl2xp1 , "fyl2xp1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F9,U) , U ), + INST(kX86InstIdHaddpd , "haddpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7C,U) , U ), + INST(kX86InstIdHaddps , "haddps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7C,U) , U ), + INST(kX86InstIdHsubpd , "hsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7D,U) , U ), + INST(kX86InstIdHsubps , "hsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7D,U) , U ), + INST(kX86InstIdIdiv , "idiv" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(UUUUUU__) , O_000000(F6,7) , U ), + INST(kX86InstIdImul , "imul" , G(X86Imul) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , U , U ), + INST(kX86InstIdInc , "inc" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,0) , O_000000(40,U) ), + INST(kX86InstIdInsertps , "insertps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(21,U) , U ), + INST(kX86InstIdInt , "int" , G(X86Int) , F(None) , 0 , U , U , U , U , E(_______W) , O_000000(CC,U) , U ), + INST(kX86InstIdJa , "ja" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ), + INST(kX86InstIdJae , "jae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), + INST(kX86InstIdJb , "jb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), + INST(kX86InstIdJbe , "jbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ), + INST(kX86InstIdJc , "jc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), + INST(kX86InstIdJe , "je" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ), + INST(kX86InstIdJg , "jg" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ), + INST(kX86InstIdJge , "jge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ), + INST(kX86InstIdJl , "jl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ), + INST(kX86InstIdJle , "jle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ), + INST(kX86InstIdJna , "jna" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ), + INST(kX86InstIdJnae , "jnae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), + INST(kX86InstIdJnb , "jnb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), + INST(kX86InstIdJnbe , "jnbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ), + INST(kX86InstIdJnc , "jnc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), + INST(kX86InstIdJne , "jne" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ), + INST(kX86InstIdJng , "jng" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ), + INST(kX86InstIdJnge , "jnge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ), + INST(kX86InstIdJnl , "jnl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ), + INST(kX86InstIdJnle , "jnle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ), + INST(kX86InstIdJno , "jno" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(71,U) , U ), + INST(kX86InstIdJnp , "jnp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ), + INST(kX86InstIdJns , "jns" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(79,U) , U ), + INST(kX86InstIdJnz , "jnz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ), + INST(kX86InstIdJo , "jo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(70,U) , U ), + INST(kX86InstIdJp , "jp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ), + INST(kX86InstIdJpe , "jpe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ), + INST(kX86InstIdJpo , "jpo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ), + INST(kX86InstIdJs , "js" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(78,U) , U ), + INST(kX86InstIdJz , "jz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ), + INST(kX86InstIdJecxz , "jecxz" , G(X86Jecxz) , F(Flow)|F(Special) , 0 , O(Gqdw) , O(Label) , U , U , E(________) , O_000000(E3,U) , U ), + INST(kX86InstIdJmp , "jmp" , G(X86Jmp) , F(Flow) , 0 , O(Imm)|O(Label) , U , U , U , E(________) , O_000000(FF,4) , O_000000(E9,U) ), + INST(kX86InstIdLahf , "lahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_RRRRR__) , O_000000(9F,U) , U ), + INST(kX86InstIdLddqu , "lddqu" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ), + INST(kX86InstIdLdmxcsr , "ldmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ), + INST(kX86InstIdLea , "lea" , G(X86Lea) , F(Move) , 0 , O(Gqd) , O(Mem) , U , U , E(________) , O_000000(8D,U) , U ), + INST(kX86InstIdLeave , "leave" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C9,U) , U ), + INST(kX86InstIdLfence , "lfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,5) , U ), + INST(kX86InstIdLodsB , "lods_b" , G(X86Op) , F(Move)|F(Special) , 1 , U , U , U , U , E(______R_) , O_000000(AC,U) , U ), + INST(kX86InstIdLodsD , "lods_d" , G(X86Op) , F(Move)|F(Special) , 4 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), + INST(kX86InstIdLodsQ , "lods_q" , G(X86Op) , F(Move)|F(Special)|F(W), 8 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), + INST(kX86InstIdLodsW , "lods_w" , G(X86Op_66H) , F(Move)|F(Special) , 2 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), + INST(kX86InstIdLzcnt , "lzcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BD,U) , U ), + INST(kX86InstIdMaskmovdqu , "maskmovdqu" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(57,U) , U ), + INST(kX86InstIdMaskmovq , "maskmovq" , G(ExtRm) , F(None)|F(Special) , 0 , O(Mm) , O(Mm) , U , U , E(________) , O_000F00(F7,U) , U ), + INST(kX86InstIdMaxpd , "maxpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5F,U) , U ), + INST(kX86InstIdMaxps , "maxps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5F,U) , U ), + INST(kX86InstIdMaxsd , "maxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5F,U) , U ), + INST(kX86InstIdMaxss , "maxss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5F,U) , U ), + INST(kX86InstIdMfence , "mfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,6) , U ), + INST(kX86InstIdMinpd , "minpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5D,U) , U ), + INST(kX86InstIdMinps , "minps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5D,U) , U ), + INST(kX86InstIdMinsd , "minsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5D,U) , U ), + INST(kX86InstIdMinss , "minss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5D,U) , U ), + INST(kX86InstIdMonitor , "monitor" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C8,U) , U ), + INST(kX86InstIdMov , "mov" , G(X86Mov) , F(Move) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(________) , U , U ), + INST(kX86InstIdMovPtr , "mov_ptr" , G(X86MovPtr) , F(Move)|F(Special) , 0 , O(Gqdwb) , O(Imm) , U , U , E(________) , O_000000(A0,U) , O_000000(A2,U) ), + INST(kX86InstIdMovapd , "movapd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ), + INST(kX86InstIdMovaps , "movaps" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ), + INST(kX86InstIdMovbe , "movbe" , G(ExtMovBe) , F(Move) , 0 , O(GqdwMem) , O(GqdwMem) , U , U , E(________) , O_000F38(F0,U) , O_000F38(F1,U) ), + INST(kX86InstIdMovd , "movd" , G(ExtMovD) , F(Move) , 16, O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , E(________) , O_000F00(6E,U) , O_000F00(7E,U) ), + INST(kX86InstIdMovddup , "movddup" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(12,U) , U ), + INST(kX86InstIdMovdq2q , "movdq2q" , G(ExtMov) , F(Move) , 8 , O(Mm) , O(Xmm) , U , U , E(________) , O_F20F00(D6,U) , U ), + INST(kX86InstIdMovdqa , "movdqa" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ), + INST(kX86InstIdMovdqu , "movdqu" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ), + INST(kX86InstIdMovhlps , "movhlps" , G(ExtMov) , F(Move) , 8 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(12,U) , U ), + INST(kX86InstIdMovhpd , "movhpd" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ), + INST(kX86InstIdMovhps , "movhps" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ), + INST(kX86InstIdMovlhps , "movlhps" , G(ExtMov) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(16,U) , U ), + INST(kX86InstIdMovlpd , "movlpd" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ), + INST(kX86InstIdMovlps , "movlps" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ), + INST(kX86InstIdMovmskpd , "movmskpd" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_660F00(50,U) , U ), + INST(kX86InstIdMovmskps , "movmskps" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_000F00(50,U) , U ), + INST(kX86InstIdMovntdq , "movntdq" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(E7,U) ), + INST(kX86InstIdMovntdqa , "movntdqa" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ), + INST(kX86InstIdMovnti , "movnti" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Gqd) , U , U , E(________) , U , O_000F00(C3,U) ), + INST(kX86InstIdMovntpd , "movntpd" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(2B,U) ), + INST(kX86InstIdMovntps , "movntps" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_000F00(2B,U) ), + INST(kX86InstIdMovntq , "movntq" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Mm) , U , U , E(________) , U , O_000F00(E7,U) ), + INST(kX86InstIdMovq , "movq" , G(ExtMovQ) , F(Move) , 16, O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , E(________) , U , U ), + INST(kX86InstIdMovq2dq , "movq2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mm) , U , U , E(________) , O_F30F00(D6,U) , U ), + INST(kX86InstIdMovsB , "movs_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A4,U) , U ), + INST(kX86InstIdMovsD , "movs_d" , G(X86Op) , F(Move)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), + INST(kX86InstIdMovsQ , "movs_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), + INST(kX86InstIdMovsW , "movs_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), + INST(kX86InstIdMovsd , "movsd" , G(ExtMov) , F(Move) |F(Z), 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ), + INST(kX86InstIdMovshdup , "movshdup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(16,U) , U ), + INST(kX86InstIdMovsldup , "movsldup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(12,U) , U ), + INST(kX86InstIdMovss , "movss" , G(ExtMov) , F(Move) |F(Z), 4 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ), + INST(kX86InstIdMovsx , "movsx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(BE,U) , U ), + INST(kX86InstIdMovsxd , "movsxd" , G(X86MovSxd) , F(Move) , 0 , O(Gq) , O(GdMem) , U , U , E(________) , O_000000(63,U) , U ), + INST(kX86InstIdMovupd , "movupd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ), + INST(kX86InstIdMovups , "movups" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ), + INST(kX86InstIdMovzx , "movzx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(B6,U) , U ), + INST(kX86InstIdMpsadbw , "mpsadbw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(42,U) , U ), + INST(kX86InstIdMul , "mul" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , O_000000(F6,4) , U ), + INST(kX86InstIdMulpd , "mulpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(59,U) , U ), + INST(kX86InstIdMulps , "mulps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(59,U) , U ), + INST(kX86InstIdMulsd , "mulsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(59,U) , U ), + INST(kX86InstIdMulss , "mulss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(59,U) , U ), + INST(kX86InstIdMulx , "mulx" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F6,U) , U ), + INST(kX86InstIdMwait , "mwait" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C9,U) , U ), + INST(kX86InstIdNeg , "neg" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWWW__) , O_000000(F6,3) , U ), + INST(kX86InstIdNop , "nop" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000000(90,U) , U ), + INST(kX86InstIdNot , "not" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(________) , O_000000(F6,2) , U ), + INST(kX86InstIdOr , "or" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(08,1) , U ), + INST(kX86InstIdOrpd , "orpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(56,U) , U ), + INST(kX86InstIdOrps , "orps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(56,U) , U ), + INST(kX86InstIdPabsb , "pabsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1C,U) , U ), + INST(kX86InstIdPabsd , "pabsd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1E,U) , U ), + INST(kX86InstIdPabsw , "pabsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1D,U) , U ), + INST(kX86InstIdPackssdw , "packssdw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6B,U) , U ), + INST(kX86InstIdPacksswb , "packsswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(63,U) , U ), + INST(kX86InstIdPackusdw , "packusdw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(2B,U) , U ), + INST(kX86InstIdPackuswb , "packuswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(67,U) , U ), + INST(kX86InstIdPaddb , "paddb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FC,U) , U ), + INST(kX86InstIdPaddd , "paddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FE,U) , U ), + INST(kX86InstIdPaddq , "paddq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D4,U) , U ), + INST(kX86InstIdPaddsb , "paddsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EC,U) , U ), + INST(kX86InstIdPaddsw , "paddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(ED,U) , U ), + INST(kX86InstIdPaddusb , "paddusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DC,U) , U ), + INST(kX86InstIdPaddusw , "paddusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DD,U) , U ), + INST(kX86InstIdPaddw , "paddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FD,U) , U ), + INST(kX86InstIdPalignr , "palignr" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , O(Imm) , U , E(________) , O_000F3A(0F,U) , U ), + INST(kX86InstIdPand , "pand" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DB,U) , U ), + INST(kX86InstIdPandn , "pandn" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DF,U) , U ), + INST(kX86InstIdPause , "pause" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_F30000(90,U) , U ), + INST(kX86InstIdPavgb , "pavgb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E0,U) , U ), + INST(kX86InstIdPavgw , "pavgw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E3,U) , U ), + INST(kX86InstIdPblendvb , "pblendvb" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(10,U) , U ), + INST(kX86InstIdPblendw , "pblendw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0E,U) , U ), + INST(kX86InstIdPclmulqdq , "pclmulqdq" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(44,U) , U ), + INST(kX86InstIdPcmpeqb , "pcmpeqb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(74,U) , U ), + INST(kX86InstIdPcmpeqd , "pcmpeqd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(76,U) , U ), + INST(kX86InstIdPcmpeqq , "pcmpeqq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(29,U) , U ), + INST(kX86InstIdPcmpeqw , "pcmpeqw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(75,U) , U ), + INST(kX86InstIdPcmpestri , "pcmpestri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ), + INST(kX86InstIdPcmpestrm , "pcmpestrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ), + INST(kX86InstIdPcmpgtb , "pcmpgtb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(64,U) , U ), + INST(kX86InstIdPcmpgtd , "pcmpgtd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(66,U) , U ), + INST(kX86InstIdPcmpgtq , "pcmpgtq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(37,U) , U ), + INST(kX86InstIdPcmpgtw , "pcmpgtw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(65,U) , U ), + INST(kX86InstIdPcmpistri , "pcmpistri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ), + INST(kX86InstIdPcmpistrm , "pcmpistrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ), + INST(kX86InstIdPdep , "pdep" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F5,U) , U ), + INST(kX86InstIdPext , "pext" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F30F38(F5,U) , U ), + INST(kX86InstIdPextrb , "pextrb" , G(ExtExtract) , F(Move) , 8 , O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , E(________) , O_000F3A(14,U) , O_000F3A(14,U) ), + INST(kX86InstIdPextrd , "pextrd" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ), + INST(kX86InstIdPextrq , "pextrq" , G(ExtExtract) , F(Move) |F(W), 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ), + INST(kX86InstIdPextrw , "pextrw" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(MmXmm) , U , U , E(________) , O_000F00(C5,U) , O_000F3A(15,U) ), + INST(kX86InstIdPf2id , "pf2id" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1D,U) , U ), + INST(kX86InstIdPf2iw , "pf2iw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1C,U) , U ), + INST(kX86InstIdPfacc , "pfacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AE,U) , U ), + INST(kX86InstIdPfadd , "pfadd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9E,U) , U ), + INST(kX86InstIdPfcmpeq , "pfcmpeq" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B0,U) , U ), + INST(kX86InstIdPfcmpge , "pfcmpge" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(90,U) , U ), + INST(kX86InstIdPfcmpgt , "pfcmpgt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A0,U) , U ), + INST(kX86InstIdPfmax , "pfmax" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A4,U) , U ), + INST(kX86InstIdPfmin , "pfmin" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(94,U) , U ), + INST(kX86InstIdPfmul , "pfmul" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B4,U) , U ), + INST(kX86InstIdPfnacc , "pfnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8A,U) , U ), + INST(kX86InstIdPfpnacc , "pfpnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8E,U) , U ), + INST(kX86InstIdPfrcp , "pfrcp" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(96,U) , U ), + INST(kX86InstIdPfrcpit1 , "pfrcpit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A6,U) , U ), + INST(kX86InstIdPfrcpit2 , "pfrcpit2" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B6,U) , U ), + INST(kX86InstIdPfrsqit1 , "pfrsqit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A7,U) , U ), + INST(kX86InstIdPfrsqrt , "pfrsqrt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(97,U) , U ), + INST(kX86InstIdPfsub , "pfsub" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9A,U) , U ), + INST(kX86InstIdPfsubr , "pfsubr" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AA,U) , U ), + INST(kX86InstIdPhaddd , "phaddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(02,U) , U ), + INST(kX86InstIdPhaddsw , "phaddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(03,U) , U ), + INST(kX86InstIdPhaddw , "phaddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(01,U) , U ), + INST(kX86InstIdPhminposuw , "phminposuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ), + INST(kX86InstIdPhsubd , "phsubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(06,U) , U ), + INST(kX86InstIdPhsubsw , "phsubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(07,U) , U ), + INST(kX86InstIdPhsubw , "phsubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(05,U) , U ), + INST(kX86InstIdPi2fd , "pi2fd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0D,U) , U ), + INST(kX86InstIdPi2fw , "pi2fw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0C,U) , U ), + INST(kX86InstIdPinsrb , "pinsrb" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(20,U) , U ), + INST(kX86InstIdPinsrd , "pinsrd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdPinsrq , "pinsrq" , G(ExtRmi) , F(None) |F(W), 0 , O(Xmm) , O(GqMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdPinsrw , "pinsrw" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(GdMem) , O(Imm) , U , E(________) , O_000F00(C4,U) , U ), + INST(kX86InstIdPmaddubsw , "pmaddubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(04,U) , U ), + INST(kX86InstIdPmaddwd , "pmaddwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F5,U) , U ), + INST(kX86InstIdPmaxsb , "pmaxsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3C,U) , U ), + INST(kX86InstIdPmaxsd , "pmaxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3D,U) , U ), + INST(kX86InstIdPmaxsw , "pmaxsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EE,U) , U ), + INST(kX86InstIdPmaxub , "pmaxub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DE,U) , U ), + INST(kX86InstIdPmaxud , "pmaxud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3F,U) , U ), + INST(kX86InstIdPmaxuw , "pmaxuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3E,U) , U ), + INST(kX86InstIdPminsb , "pminsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(38,U) , U ), + INST(kX86InstIdPminsd , "pminsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(39,U) , U ), + INST(kX86InstIdPminsw , "pminsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EA,U) , U ), + INST(kX86InstIdPminub , "pminub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DA,U) , U ), + INST(kX86InstIdPminud , "pminud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3B,U) , U ), + INST(kX86InstIdPminuw , "pminuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3A,U) , U ), + INST(kX86InstIdPmovmskb , "pmovmskb" , G(ExtRm_PQ) , F(Move) , 8 , O(Gqd) , O(MmXmm) , U , U , E(________) , O_000F00(D7,U) , U ), + INST(kX86InstIdPmovsxbd , "pmovsxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(21,U) , U ), + INST(kX86InstIdPmovsxbq , "pmovsxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(22,U) , U ), + INST(kX86InstIdPmovsxbw , "pmovsxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(20,U) , U ), + INST(kX86InstIdPmovsxdq , "pmovsxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(25,U) , U ), + INST(kX86InstIdPmovsxwd , "pmovsxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(23,U) , U ), + INST(kX86InstIdPmovsxwq , "pmovsxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(24,U) , U ), + INST(kX86InstIdPmovzxbd , "pmovzxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(31,U) , U ), + INST(kX86InstIdPmovzxbq , "pmovzxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(32,U) , U ), + INST(kX86InstIdPmovzxbw , "pmovzxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(30,U) , U ), + INST(kX86InstIdPmovzxdq , "pmovzxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(35,U) , U ), + INST(kX86InstIdPmovzxwd , "pmovzxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(33,U) , U ), + INST(kX86InstIdPmovzxwq , "pmovzxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(34,U) , U ), + INST(kX86InstIdPmuldq , "pmuldq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(28,U) , U ), + INST(kX86InstIdPmulhrsw , "pmulhrsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0B,U) , U ), + INST(kX86InstIdPmulhuw , "pmulhuw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E4,U) , U ), + INST(kX86InstIdPmulhw , "pmulhw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E5,U) , U ), + INST(kX86InstIdPmulld , "pmulld" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(40,U) , U ), + INST(kX86InstIdPmullw , "pmullw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D5,U) , U ), + INST(kX86InstIdPmuludq , "pmuludq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F4,U) , U ), + INST(kX86InstIdPop , "pop" , G(X86Pop) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(8F,0) , O_000000(58,U) ), + INST(kX86InstIdPopa , "popa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(61,U) , U ), + INST(kX86InstIdPopcnt , "popcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(WWWWWW__) , O_F30F00(B8,U) , U ), + INST(kX86InstIdPopf , "popf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWWW) , O_000000(9D,U) , U ), + INST(kX86InstIdPor , "por" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EB,U) , U ), + INST(kX86InstIdPrefetch , "prefetch" , G(ExtPrefetch) , F(None) , 0 , O(Mem) , O(Imm) , U , U , E(________) , O_000F00(18,U) , U ), + INST(kX86InstIdPrefetch3dNow , "prefetch_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,0) , U ), + INST(kX86InstIdPrefetchw3dNow , "prefetchw_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,1) , U ), + INST(kX86InstIdPsadbw , "psadbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F6,U) , U ), + INST(kX86InstIdPshufb , "pshufb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(00,U) , U ), + INST(kX86InstIdPshufd , "pshufd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ), + INST(kX86InstIdPshufhw , "pshufhw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ), + INST(kX86InstIdPshuflw , "pshuflw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ), + INST(kX86InstIdPshufw , "pshufw" , G(ExtRmi_P) , F(Move) , 8 , O(Mm) , O(MmMem) , O(Imm) , U , E(________) , O_000F00(70,U) , U ), + INST(kX86InstIdPsignb , "psignb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(08,U) , U ), + INST(kX86InstIdPsignd , "psignd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0A,U) , U ), + INST(kX86InstIdPsignw , "psignw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(09,U) , U ), + INST(kX86InstIdPslld , "pslld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F2,U) , O_000F00(72,6) ), + INST(kX86InstIdPslldq , "pslldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,7) ), + INST(kX86InstIdPsllq , "psllq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F3,U) , O_000F00(73,6) ), + INST(kX86InstIdPsllw , "psllw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F1,U) , O_000F00(71,6) ), + INST(kX86InstIdPsrad , "psrad" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E2,U) , O_000F00(72,4) ), + INST(kX86InstIdPsraw , "psraw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E1,U) , O_000F00(71,4) ), + INST(kX86InstIdPsrld , "psrld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D2,U) , O_000F00(72,2) ), + INST(kX86InstIdPsrldq , "psrldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,3) ), + INST(kX86InstIdPsrlq , "psrlq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D3,U) , O_000F00(73,2) ), + INST(kX86InstIdPsrlw , "psrlw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D1,U) , O_000F00(71,2) ), + INST(kX86InstIdPsubb , "psubb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F8,U) , U ), + INST(kX86InstIdPsubd , "psubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FA,U) , U ), + INST(kX86InstIdPsubq , "psubq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FB,U) , U ), + INST(kX86InstIdPsubsb , "psubsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E8,U) , U ), + INST(kX86InstIdPsubsw , "psubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E9,U) , U ), + INST(kX86InstIdPsubusb , "psubusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D8,U) , U ), + INST(kX86InstIdPsubusw , "psubusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D9,U) , U ), + INST(kX86InstIdPsubw , "psubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F9,U) , U ), + INST(kX86InstIdPswapd , "pswapd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(BB,U) , U ), + INST(kX86InstIdPtest , "ptest" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ), + INST(kX86InstIdPunpckhbw , "punpckhbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(68,U) , U ), + INST(kX86InstIdPunpckhdq , "punpckhdq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6A,U) , U ), + INST(kX86InstIdPunpckhqdq , "punpckhqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6D,U) , U ), + INST(kX86InstIdPunpckhwd , "punpckhwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(69,U) , U ), + INST(kX86InstIdPunpcklbw , "punpcklbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(60,U) , U ), + INST(kX86InstIdPunpckldq , "punpckldq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(62,U) , U ), + INST(kX86InstIdPunpcklqdq , "punpcklqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6C,U) , U ), + INST(kX86InstIdPunpcklwd , "punpcklwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(61,U) , U ), + INST(kX86InstIdPush , "push" , G(X86Push) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(FF,6) , O_000000(50,U) ), + INST(kX86InstIdPusha , "pusha" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(60,U) , U ), + INST(kX86InstIdPushf , "pushf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(RRRRRRRR) , O_000000(9C,U) , U ), + INST(kX86InstIdPxor , "pxor" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EF,U) , U ), + INST(kX86InstIdRcl , "rcl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,2) , U ), + INST(kX86InstIdRcpps , "rcpps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(53,U) , U ), + INST(kX86InstIdRcpss , "rcpss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(53,U) , U ), + INST(kX86InstIdRcr , "rcr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,3) , U ), + INST(kX86InstIdRdfsbase , "rdfsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,0) , U ), + INST(kX86InstIdRdgsbase , "rdgsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,1) , U ), + INST(kX86InstIdRdrand , "rdrand" , G(X86Rm) , F(Move) , 8 , O(Gqdw) , U , U , U , E(WWWWWW__) , O_000F00(C7,6) , U ), + INST(kX86InstIdRdtsc , "rdtsc" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(31,U) , U ), + INST(kX86InstIdRdtscp , "rdtscp" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(F9,U) , U ), + INST(kX86InstIdRepLodsB , "rep lods_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AC,1) , U ), + INST(kX86InstIdRepLodsD , "rep lods_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ), + INST(kX86InstIdRepLodsQ , "rep lods_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ), + INST(kX86InstIdRepLodsW , "rep lods_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AD,1) , U ), + INST(kX86InstIdRepMovsB , "rep movs_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A4,1) , U ), + INST(kX86InstIdRepMovsD , "rep movs_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ), + INST(kX86InstIdRepMovsQ , "rep movs_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ), + INST(kX86InstIdRepMovsW , "rep movs_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_660000(A5,1) , U ), + INST(kX86InstIdRepStosB , "rep stos_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AA,1) , U ), + INST(kX86InstIdRepStosD , "rep stos_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ), + INST(kX86InstIdRepStosQ , "rep stos_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ), + INST(kX86InstIdRepStosW , "rep stos_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AB,1) , U ), + INST(kX86InstIdRepeCmpsB , "repe cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,1) , U ), + INST(kX86InstIdRepeCmpsD , "repe cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ), + INST(kX86InstIdRepeCmpsQ , "repe cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ), + INST(kX86InstIdRepeCmpsW , "repe cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,1) , U ), + INST(kX86InstIdRepeScasB , "repe scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,1) , U ), + INST(kX86InstIdRepeScasD , "repe scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ), + INST(kX86InstIdRepeScasQ , "repe scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ), + INST(kX86InstIdRepeScasW , "repe scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,1) , U ), + INST(kX86InstIdRepneCmpsB , "repne cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,0) , U ), + INST(kX86InstIdRepneCmpsD , "repne cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ), + INST(kX86InstIdRepneCmpsQ , "repne cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ), + INST(kX86InstIdRepneCmpsW , "repne cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,0) , U ), + INST(kX86InstIdRepneScasB , "repne scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,0) , U ), + INST(kX86InstIdRepneScasD , "repne scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ), + INST(kX86InstIdRepneScasQ , "repne scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ), + INST(kX86InstIdRepneScasW , "repne scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,0) , U ), + INST(kX86InstIdRet , "ret" , G(X86Ret) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C2,U) , U ), + INST(kX86InstIdRol , "rol" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,0) , U ), + INST(kX86InstIdRor , "ror" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,1) , U ), + INST(kX86InstIdRorx , "rorx" , G(AvxRmi) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Imm) , U , E(________) , O_F20F3A(F0,U) , U ), + INST(kX86InstIdRoundpd , "roundpd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ), + INST(kX86InstIdRoundps , "roundps" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ), + INST(kX86InstIdRoundsd , "roundsd" , G(ExtRmi) , F(Move) , 8 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0B,U) , U ), + INST(kX86InstIdRoundss , "roundss" , G(ExtRmi) , F(Move) , 4 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0A,U) , U ), + INST(kX86InstIdRsqrtps , "rsqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(52,U) , U ), + INST(kX86InstIdRsqrtss , "rsqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(52,U) , U ), + INST(kX86InstIdSahf , "sahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_WWWWW__) , O_000000(9E,U) , U ), + INST(kX86InstIdSal , "sal" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ), + INST(kX86InstIdSar , "sar" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,7) , U ), + INST(kX86InstIdSarx , "sarx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F30F38(F7,U) , U ), + INST(kX86InstIdSbb , "sbb" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(18,3) , U ), + INST(kX86InstIdScasB , "scas_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AE,U) , U ), + INST(kX86InstIdScasD , "scas_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), + INST(kX86InstIdScasQ , "scas_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), + INST(kX86InstIdScasW , "scas_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), + INST(kX86InstIdSeta , "seta" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ), + INST(kX86InstIdSetae , "setae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), + INST(kX86InstIdSetb , "setb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), + INST(kX86InstIdSetbe , "setbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ), + INST(kX86InstIdSetc , "setc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), + INST(kX86InstIdSete , "sete" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ), + INST(kX86InstIdSetg , "setg" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ), + INST(kX86InstIdSetge , "setge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ), + INST(kX86InstIdSetl , "setl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ), + INST(kX86InstIdSetle , "setle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ), + INST(kX86InstIdSetna , "setna" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ), + INST(kX86InstIdSetnae , "setnae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), + INST(kX86InstIdSetnb , "setnb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), + INST(kX86InstIdSetnbe , "setnbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ), + INST(kX86InstIdSetnc , "setnc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), + INST(kX86InstIdSetne , "setne" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ), + INST(kX86InstIdSetng , "setng" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ), + INST(kX86InstIdSetnge , "setnge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ), + INST(kX86InstIdSetnl , "setnl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ), + INST(kX86InstIdSetnle , "setnle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ), + INST(kX86InstIdSetno , "setno" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(91,U) , U ), + INST(kX86InstIdSetnp , "setnp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ), + INST(kX86InstIdSetns , "setns" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(99,U) , U ), + INST(kX86InstIdSetnz , "setnz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ), + INST(kX86InstIdSeto , "seto" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(90,U) , U ), + INST(kX86InstIdSetp , "setp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ), + INST(kX86InstIdSetpe , "setpe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ), + INST(kX86InstIdSetpo , "setpo" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ), + INST(kX86InstIdSets , "sets" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(98,U) , U ), + INST(kX86InstIdSetz , "setz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ), + INST(kX86InstIdSfence , "sfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,7) , U ), + INST(kX86InstIdShl , "shl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ), + INST(kX86InstIdShld , "shld" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb) , U , U , E(UWWUWW__) , O_000F00(A4,U) , U ), + INST(kX86InstIdShlx , "shlx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_660F38(F7,U) , U ), + INST(kX86InstIdShr , "shr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,5) , U ), + INST(kX86InstIdShrd , "shrd" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(UWWUWW__) , O_000F00(AC,U) , U ), + INST(kX86InstIdShrx , "shrx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F20F38(F7,U) , U ), + INST(kX86InstIdShufpd , "shufpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C6,U) , U ), + INST(kX86InstIdShufps , "shufps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C6,U) , U ), + INST(kX86InstIdSqrtpd , "sqrtpd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(51,U) , U ), + INST(kX86InstIdSqrtps , "sqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(51,U) , U ), + INST(kX86InstIdSqrtsd , "sqrtsd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(51,U) , U ), + INST(kX86InstIdSqrtss , "sqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(51,U) , U ), + INST(kX86InstIdStc , "stc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F9,U) , U ), + INST(kX86InstIdStd , "std" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FD,U) , U ), + INST(kX86InstIdStmxcsr , "stmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ), + INST(kX86InstIdStosB , "stos_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AA,U) , U ), + INST(kX86InstIdStosD , "stos_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), + INST(kX86InstIdStosQ , "stos_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), + INST(kX86InstIdStosW , "stos_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), + INST(kX86InstIdSub , "sub" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(28,5) , U ), + INST(kX86InstIdSubpd , "subpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5C,U) , U ), + INST(kX86InstIdSubps , "subps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5C,U) , U ), + INST(kX86InstIdSubsd , "subsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5C,U) , U ), + INST(kX86InstIdSubss , "subss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5C,U) , U ), + INST(kX86InstIdTest , "test" , G(X86Test) , F(Test) , 0 , O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(84,U) , O_000000(F6,U) ), + INST(kX86InstIdTzcnt , "tzcnt" , G(X86RegRm) , F(Move) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BC,U) , U ), + INST(kX86InstIdUcomisd , "ucomisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ), + INST(kX86InstIdUcomiss , "ucomiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ), + INST(kX86InstIdUd2 , "ud2" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(0B,U) , U ), + INST(kX86InstIdUnpckhpd , "unpckhpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(15,U) , U ), + INST(kX86InstIdUnpckhps , "unpckhps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(15,U) , U ), + INST(kX86InstIdUnpcklpd , "unpcklpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(14,U) , U ), + INST(kX86InstIdUnpcklps , "unpcklps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(14,U) , U ), + INST(kX86InstIdVaddpd , "vaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(58,U) , U ), + INST(kX86InstIdVaddps , "vaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(58,U) , U ), + INST(kX86InstIdVaddsd , "vaddsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(58,U) , U ), + INST(kX86InstIdVaddss , "vaddss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(58,U) , U ), + INST(kX86InstIdVaddsubpd , "vaddsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D0,U) , U ), + INST(kX86InstIdVaddsubps , "vaddsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(D0,U) , U ), + INST(kX86InstIdVaesdec , "vaesdec" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DE,U) , U ), + INST(kX86InstIdVaesdeclast , "vaesdeclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DF,U) , U ), + INST(kX86InstIdVaesenc , "vaesenc" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DC,U) , U ), + INST(kX86InstIdVaesenclast , "vaesenclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DD,U) , U ), + INST(kX86InstIdVaesimc , "vaesimc" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ), + INST(kX86InstIdVaeskeygenassist , "vaeskeygenassist" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ), + INST(kX86InstIdVandnpd , "vandnpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(55,U) , U ), + INST(kX86InstIdVandnps , "vandnps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(55,U) , U ), + INST(kX86InstIdVandpd , "vandpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(54,U) , U ), + INST(kX86InstIdVandps , "vandps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(54,U) , U ), + INST(kX86InstIdVblendpd , "vblendpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0D,U) , U ), + INST(kX86InstIdVblendps , "vblendps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0C,U) , U ), + INST(kX86InstIdVblendvpd , "vblendvpd" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4B,U) , U ), + INST(kX86InstIdVblendvps , "vblendvps" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4A,U) , U ), + INST(kX86InstIdVbroadcastf128 , "vbroadcastf128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(1A,U)|L, U ), + INST(kX86InstIdVbroadcasti128 , "vbroadcasti128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(5A,U)|L, U ), + INST(kX86InstIdVbroadcastsd , "vbroadcastsd" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(19,U)|L, U ), + INST(kX86InstIdVbroadcastss , "vbroadcastss" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(18,U) , U ), + INST(kX86InstIdVcmppd , "vcmppd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C2,U) , U ), + INST(kX86InstIdVcmpps , "vcmpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C2,U) , U ), + INST(kX86InstIdVcmpsd , "vcmpsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F20F00(C2,U) , U ), + INST(kX86InstIdVcmpss , "vcmpss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F30F00(C2,U) , U ), + INST(kX86InstIdVcomisd , "vcomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(2F,U) , U ), + INST(kX86InstIdVcomiss , "vcomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(2F,U) , U ), + INST(kX86InstIdVcvtdq2pd , "vcvtdq2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ), + INST(kX86InstIdVcvtdq2ps , "vcvtdq2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(5B,U) , U ), + INST(kX86InstIdVcvtpd2dq , "vcvtpd2dq" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ), + INST(kX86InstIdVcvtpd2ps , "vcvtpd2ps" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5A,U) , U ), + INST(kX86InstIdVcvtph2ps , "vcvtph2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(13,U) , U ), + INST(kX86InstIdVcvtps2dq , "vcvtps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5B,U) , U ), + INST(kX86InstIdVcvtps2pd , "vcvtps2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ), + INST(kX86InstIdVcvtps2ph , "vcvtps2ph" , G(AvxMri_P) , F(None) , 0 , O(XmmMem) , O(XmmYmm) , O(Imm) , U , E(________) , O_660F3A(1D,U) , U ), + INST(kX86InstIdVcvtsd2si , "vcvtsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), + INST(kX86InstIdVcvtsd2ss , "vcvtsd2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5A,U) , U ), + INST(kX86InstIdVcvtsi2sd , "vcvtsi2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F20F00(2A,U) , U ), + INST(kX86InstIdVcvtsi2ss , "vcvtsi2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F30F00(2A,U) , U ), + INST(kX86InstIdVcvtss2sd , "vcvtss2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5A,U) , U ), + INST(kX86InstIdVcvtss2si , "vcvtss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), + INST(kX86InstIdVcvttpd2dq , "vcvttpd2dq" , G(AvxRm_P) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(E6,U) , U ), + INST(kX86InstIdVcvttps2dq , "vcvttps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ), + INST(kX86InstIdVcvttsd2si , "vcvttsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ), + INST(kX86InstIdVcvttss2si , "vcvttss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ), + INST(kX86InstIdVdivpd , "vdivpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5E,U) , U ), + INST(kX86InstIdVdivps , "vdivps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5E,U) , U ), + INST(kX86InstIdVdivsd , "vdivsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5E,U) , U ), + INST(kX86InstIdVdivss , "vdivss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5E,U) , U ), + INST(kX86InstIdVdppd , "vdppd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(41,U) , U ), + INST(kX86InstIdVdpps , "vdpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(40,U) , U ), + INST(kX86InstIdVextractf128 , "vextractf128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(19,U)|L, U ), + INST(kX86InstIdVextracti128 , "vextracti128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(39,U)|L, U ), + INST(kX86InstIdVextractps , "vextractps" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(17,U) , U ), + INST(kX86InstIdVfmadd132pd , "vfmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ), + INST(kX86InstIdVfmadd132ps , "vfmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ), + INST(kX86InstIdVfmadd132sd , "vfmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ), + INST(kX86InstIdVfmadd132ss , "vfmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ), + INST(kX86InstIdVfmadd213pd , "vfmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ), + INST(kX86InstIdVfmadd213ps , "vfmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ), + INST(kX86InstIdVfmadd213sd , "vfmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ), + INST(kX86InstIdVfmadd213ss , "vfmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ), + INST(kX86InstIdVfmadd231pd , "vfmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ), + INST(kX86InstIdVfmadd231ps , "vfmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ), + INST(kX86InstIdVfmadd231sd , "vfmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ), + INST(kX86InstIdVfmadd231ss , "vfmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ), + INST(kX86InstIdVfmaddpd , "vfmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(69,U) , U ), + INST(kX86InstIdVfmaddps , "vfmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(68,U) , U ), + INST(kX86InstIdVfmaddsd , "vfmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6B,U) , U ), + INST(kX86InstIdVfmaddss , "vfmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6A,U) , U ), + INST(kX86InstIdVfmaddsub132pd , "vfmaddsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ), + INST(kX86InstIdVfmaddsub132ps , "vfmaddsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ), + INST(kX86InstIdVfmaddsub213pd , "vfmaddsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ), + INST(kX86InstIdVfmaddsub213ps , "vfmaddsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ), + INST(kX86InstIdVfmaddsub231pd , "vfmaddsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ), + INST(kX86InstIdVfmaddsub231ps , "vfmaddsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ), + INST(kX86InstIdVfmaddsubpd , "vfmaddsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5D,U) , U ), + INST(kX86InstIdVfmaddsubps , "vfmaddsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5C,U) , U ), + INST(kX86InstIdVfmsub132pd , "vfmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ), + INST(kX86InstIdVfmsub132ps , "vfmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ), + INST(kX86InstIdVfmsub132sd , "vfmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ), + INST(kX86InstIdVfmsub132ss , "vfmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ), + INST(kX86InstIdVfmsub213pd , "vfmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ), + INST(kX86InstIdVfmsub213ps , "vfmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ), + INST(kX86InstIdVfmsub213sd , "vfmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ), + INST(kX86InstIdVfmsub213ss , "vfmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ), + INST(kX86InstIdVfmsub231pd , "vfmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ), + INST(kX86InstIdVfmsub231ps , "vfmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ), + INST(kX86InstIdVfmsub231sd , "vfmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ), + INST(kX86InstIdVfmsub231ss , "vfmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ), + INST(kX86InstIdVfmsubadd132pd , "vfmsubadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ), + INST(kX86InstIdVfmsubadd132ps , "vfmsubadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ), + INST(kX86InstIdVfmsubadd213pd , "vfmsubadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ), + INST(kX86InstIdVfmsubadd213ps , "vfmsubadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ), + INST(kX86InstIdVfmsubadd231pd , "vfmsubadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ), + INST(kX86InstIdVfmsubadd231ps , "vfmsubadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ), + INST(kX86InstIdVfmsubaddpd , "vfmsubaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5F,U) , U ), + INST(kX86InstIdVfmsubaddps , "vfmsubaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5E,U) , U ), + INST(kX86InstIdVfmsubpd , "vfmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6D,U) , U ), + INST(kX86InstIdVfmsubps , "vfmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6C,U) , U ), + INST(kX86InstIdVfmsubsd , "vfmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6F,U) , U ), + INST(kX86InstIdVfmsubss , "vfmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6E,U) , U ), + INST(kX86InstIdVfnmadd132pd , "vfnmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ), + INST(kX86InstIdVfnmadd132ps , "vfnmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ), + INST(kX86InstIdVfnmadd132sd , "vfnmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ), + INST(kX86InstIdVfnmadd132ss , "vfnmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ), + INST(kX86InstIdVfnmadd213pd , "vfnmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ), + INST(kX86InstIdVfnmadd213ps , "vfnmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ), + INST(kX86InstIdVfnmadd213sd , "vfnmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ), + INST(kX86InstIdVfnmadd213ss , "vfnmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ), + INST(kX86InstIdVfnmadd231pd , "vfnmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmadd231ps , "vfnmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmadd231sd , "vfnmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmadd231ss , "vfnmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ), + INST(kX86InstIdVfnmaddpd , "vfnmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(79,U) , U ), + INST(kX86InstIdVfnmaddps , "vfnmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(78,U) , U ), + INST(kX86InstIdVfnmaddsd , "vfnmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7B,U) , U ), + INST(kX86InstIdVfnmaddss , "vfnmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7A,U) , U ), + INST(kX86InstIdVfnmsub132pd , "vfnmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ), + INST(kX86InstIdVfnmsub132ps , "vfnmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ), + INST(kX86InstIdVfnmsub132sd , "vfnmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ), + INST(kX86InstIdVfnmsub132ss , "vfnmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ), + INST(kX86InstIdVfnmsub213pd , "vfnmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ), + INST(kX86InstIdVfnmsub213ps , "vfnmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ), + INST(kX86InstIdVfnmsub213sd , "vfnmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ), + INST(kX86InstIdVfnmsub213ss , "vfnmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ), + INST(kX86InstIdVfnmsub231pd , "vfnmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ), + INST(kX86InstIdVfnmsub231ps , "vfnmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ), + INST(kX86InstIdVfnmsub231sd , "vfnmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ), + INST(kX86InstIdVfnmsub231ss , "vfnmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ), + INST(kX86InstIdVfnmsubpd , "vfnmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7D,U) , U ), + INST(kX86InstIdVfnmsubps , "vfnmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7C,U) , U ), + INST(kX86InstIdVfnmsubsd , "vfnmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7F,U) , U ), + INST(kX86InstIdVfnmsubss , "vfnmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7E,U) , U ), + INST(kX86InstIdVfrczpd , "vfrczpd" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(81,U) , U ), + INST(kX86InstIdVfrczps , "vfrczps" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(80,U) , U ), + INST(kX86InstIdVfrczsd , "vfrczsd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(83,U) , U ), + INST(kX86InstIdVfrczss , "vfrczss" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(82,U) , U ), + INST(kX86InstIdVgatherdpd , "vgatherdpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ), + INST(kX86InstIdVgatherdps , "vgatherdps" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ), + INST(kX86InstIdVgatherqpd , "vgatherqpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(93,U) , U ), + INST(kX86InstIdVgatherqps , "vgatherqps" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(93,U) , U ), + INST(kX86InstIdVhaddpd , "vhaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7C,U) , U ), + INST(kX86InstIdVhaddps , "vhaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7C,U) , U ), + INST(kX86InstIdVhsubpd , "vhsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7D,U) , U ), + INST(kX86InstIdVhsubps , "vhsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7D,U) , U ), + INST(kX86InstIdVinsertf128 , "vinsertf128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(18,U)|L, U ), + INST(kX86InstIdVinserti128 , "vinserti128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(38,U)|L, U ), + INST(kX86InstIdVinsertps , "vinsertps" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(21,U) , U ), + INST(kX86InstIdVlddqu , "vlddqu" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ), + INST(kX86InstIdVldmxcsr , "vldmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ), + INST(kX86InstIdVmaskmovdqu , "vmaskmovdqu" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(F7,U) , U ), + INST(kX86InstIdVmaskmovpd , "vmaskmovpd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2D,U) , O_660F38(2F,U) ), + INST(kX86InstIdVmaskmovps , "vmaskmovps" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2C,U) , O_660F38(2E,U) ), + INST(kX86InstIdVmaxpd , "vmaxpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5F,U) , U ), + INST(kX86InstIdVmaxps , "vmaxps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5F,U) , U ), + INST(kX86InstIdVmaxsd , "vmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5F,U) , U ), + INST(kX86InstIdVmaxss , "vmaxss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5F,U) , U ), + INST(kX86InstIdVminpd , "vminpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5D,U) , U ), + INST(kX86InstIdVminps , "vminps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5D,U) , U ), + INST(kX86InstIdVminsd , "vminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5D,U) , U ), + INST(kX86InstIdVminss , "vminss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5D,U) , U ), + INST(kX86InstIdVmovapd , "vmovapd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ), + INST(kX86InstIdVmovaps , "vmovaps" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ), + INST(kX86InstIdVmovd , "vmovd" , G(AvxRmMr) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ), + INST(kX86InstIdVmovddup , "vmovddup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(12,U) , U ), + INST(kX86InstIdVmovdqa , "vmovdqa" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ), + INST(kX86InstIdVmovdqu , "vmovdqu" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ), + INST(kX86InstIdVmovhlps , "vmovhlps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(12,U) , U ), + INST(kX86InstIdVmovhpd , "vmovhpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ), + INST(kX86InstIdVmovhps , "vmovhps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ), + INST(kX86InstIdVmovlhps , "vmovlhps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(16,U) , U ), + INST(kX86InstIdVmovlpd , "vmovlpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ), + INST(kX86InstIdVmovlps , "vmovlps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ), + INST(kX86InstIdVmovmskpd , "vmovmskpd" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(50,U) , U ), + INST(kX86InstIdVmovmskps , "vmovmskps" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_000F00(50,U) , U ), + INST(kX86InstIdVmovntdq , "vmovntdq" , G(AvxMr) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(E7,U) , U ), + INST(kX86InstIdVmovntdqa , "vmovntdqa" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ), + INST(kX86InstIdVmovntpd , "vmovntpd" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(2B,U) , U ), + INST(kX86InstIdVmovntps , "vmovntps" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_000F00(2B,U) , U ), + INST(kX86InstIdVmovq , "vmovq" , G(AvxRmMr) , F(None) |F(W), 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ), + INST(kX86InstIdVmovsd , "vmovsd" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(XmmMem) , O(Xmm) , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ), + INST(kX86InstIdVmovshdup , "vmovshdup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(16,U) , U ), + INST(kX86InstIdVmovsldup , "vmovsldup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(12,U) , U ), + INST(kX86InstIdVmovss , "vmovss" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Xmm) , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ), + INST(kX86InstIdVmovupd , "vmovupd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ), + INST(kX86InstIdVmovups , "vmovups" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ), + INST(kX86InstIdVmpsadbw , "vmpsadbw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(42,U) , U ), + INST(kX86InstIdVmulpd , "vmulpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(59,U) , U ), + INST(kX86InstIdVmulps , "vmulps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(59,U) , U ), + INST(kX86InstIdVmulsd , "vmulsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(59,U) , U ), + INST(kX86InstIdVmulss , "vmulss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(59,U) , U ), + INST(kX86InstIdVorpd , "vorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(56,U) , U ), + INST(kX86InstIdVorps , "vorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(56,U) , U ), + INST(kX86InstIdVpabsb , "vpabsb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1C,U) , U ), + INST(kX86InstIdVpabsd , "vpabsd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1E,U) , U ), + INST(kX86InstIdVpabsw , "vpabsw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1D,U) , U ), + INST(kX86InstIdVpackssdw , "vpackssdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6B,U) , U ), + INST(kX86InstIdVpacksswb , "vpacksswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(63,U) , U ), + INST(kX86InstIdVpackusdw , "vpackusdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2B,U) , U ), + INST(kX86InstIdVpackuswb , "vpackuswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(67,U) , U ), + INST(kX86InstIdVpaddb , "vpaddb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FC,U) , U ), + INST(kX86InstIdVpaddd , "vpaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FE,U) , U ), + INST(kX86InstIdVpaddq , "vpaddq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D4,U) , U ), + INST(kX86InstIdVpaddsb , "vpaddsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EC,U) , U ), + INST(kX86InstIdVpaddsw , "vpaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(ED,U) , U ), + INST(kX86InstIdVpaddusb , "vpaddusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DC,U) , U ), + INST(kX86InstIdVpaddusw , "vpaddusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DD,U) , U ), + INST(kX86InstIdVpaddw , "vpaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FD,U) , U ), + INST(kX86InstIdVpalignr , "vpalignr" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0F,U) , U ), + INST(kX86InstIdVpand , "vpand" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DB,U) , U ), + INST(kX86InstIdVpandn , "vpandn" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DF,U) , U ), + INST(kX86InstIdVpavgb , "vpavgb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E0,U) , U ), + INST(kX86InstIdVpavgw , "vpavgw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E3,U) , U ), + INST(kX86InstIdVpblendd , "vpblendd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(02,U) , U ), + INST(kX86InstIdVpblendvb , "vpblendvb" , G(AvxRvmr) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4C,U) , U ), + INST(kX86InstIdVpblendw , "vpblendw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0E,U) , U ), + INST(kX86InstIdVpbroadcastb , "vpbroadcastb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(78,U) , U ), + INST(kX86InstIdVpbroadcastd , "vpbroadcastd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(58,U) , U ), + INST(kX86InstIdVpbroadcastq , "vpbroadcastq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(59,U) , U ), + INST(kX86InstIdVpbroadcastw , "vpbroadcastw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(79,U) , U ), + INST(kX86InstIdVpclmulqdq , "vpclmulqdq" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(44,U) , U ), + INST(kX86InstIdVpcmov , "vpcmov" , G(XopRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_00_M08(A2,U) , U ), + INST(kX86InstIdVpcmpeqb , "vpcmpeqb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(74,U) , U ), + INST(kX86InstIdVpcmpeqd , "vpcmpeqd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(76,U) , U ), + INST(kX86InstIdVpcmpeqq , "vpcmpeqq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(29,U) , U ), + INST(kX86InstIdVpcmpeqw , "vpcmpeqw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(75,U) , U ), + INST(kX86InstIdVpcmpestri , "vpcmpestri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ), + INST(kX86InstIdVpcmpestrm , "vpcmpestrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ), + INST(kX86InstIdVpcmpgtb , "vpcmpgtb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(64,U) , U ), + INST(kX86InstIdVpcmpgtd , "vpcmpgtd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(66,U) , U ), + INST(kX86InstIdVpcmpgtq , "vpcmpgtq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(37,U) , U ), + INST(kX86InstIdVpcmpgtw , "vpcmpgtw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(65,U) , U ), + INST(kX86InstIdVpcmpistri , "vpcmpistri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ), + INST(kX86InstIdVpcmpistrm , "vpcmpistrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ), + INST(kX86InstIdVpcomb , "vpcomb" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CC,U) , U ), + INST(kX86InstIdVpcomd , "vpcomd" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CE,U) , U ), + INST(kX86InstIdVpcomq , "vpcomq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CF,U) , U ), + INST(kX86InstIdVpcomub , "vpcomub" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EC,U) , U ), + INST(kX86InstIdVpcomud , "vpcomud" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EE,U) , U ), + INST(kX86InstIdVpcomuq , "vpcomuq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EF,U) , U ), + INST(kX86InstIdVpcomuw , "vpcomuw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(ED,U) , U ), + INST(kX86InstIdVpcomw , "vpcomw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CD,U) , U ), + INST(kX86InstIdVperm2f128 , "vperm2f128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(06,U)|L, U ), + INST(kX86InstIdVperm2i128 , "vperm2i128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(46,U)|L, U ), + INST(kX86InstIdVpermd , "vpermd" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(36,U)|L, U ), + INST(kX86InstIdVpermil2pd , "vpermil2pd" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(49,U) , U ), + INST(kX86InstIdVpermil2ps , "vpermil2ps" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(48,U) , U ), + INST(kX86InstIdVpermilpd , "vpermilpd" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0D,U) , O_660F3A(05,U) ), + INST(kX86InstIdVpermilps , "vpermilps" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0C,U) , O_660F3A(04,U) ), + INST(kX86InstIdVpermpd , "vpermpd" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(01,U)|L, U ), + INST(kX86InstIdVpermps , "vpermps" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(16,U)|L, U ), + INST(kX86InstIdVpermq , "vpermq" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(00,U)|L, U ), + INST(kX86InstIdVpextrb , "vpextrb" , G(AvxMri) , F(None) , 0 , O(GqdwbMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(14,U) , U ), + INST(kX86InstIdVpextrd , "vpextrd" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ), + INST(kX86InstIdVpextrq , "vpextrq" , G(AvxMri) , F(None) |F(W), 0 , O(GqMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ), + INST(kX86InstIdVpextrw , "vpextrw" , G(AvxMri) , F(None) , 0 , O(GqdwMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(15,U) , U ), + INST(kX86InstIdVpgatherdd , "vpgatherdd" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ), + INST(kX86InstIdVpgatherdq , "vpgatherdq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ), + INST(kX86InstIdVpgatherqd , "vpgatherqd" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(91,U) , U ), + INST(kX86InstIdVpgatherqq , "vpgatherqq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(91,U) , U ), + INST(kX86InstIdVphaddbd , "vphaddbd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C2,U) , U ), + INST(kX86InstIdVphaddbq , "vphaddbq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C3,U) , U ), + INST(kX86InstIdVphaddbw , "vphaddbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C1,U) , U ), + INST(kX86InstIdVphaddd , "vphaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(02,U) , U ), + INST(kX86InstIdVphadddq , "vphadddq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(CB,U) , U ), + INST(kX86InstIdVphaddsw , "vphaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(03,U) , U ), + INST(kX86InstIdVphaddubd , "vphaddubd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D2,U) , U ), + INST(kX86InstIdVphaddubq , "vphaddubq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D3,U) , U ), + INST(kX86InstIdVphaddubw , "vphaddubw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D1,U) , U ), + INST(kX86InstIdVphaddudq , "vphaddudq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(DB,U) , U ), + INST(kX86InstIdVphadduwd , "vphadduwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D6,U) , U ), + INST(kX86InstIdVphadduwq , "vphadduwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D7,U) , U ), + INST(kX86InstIdVphaddw , "vphaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(01,U) , U ), + INST(kX86InstIdVphaddwd , "vphaddwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C6,U) , U ), + INST(kX86InstIdVphaddwq , "vphaddwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C7,U) , U ), + INST(kX86InstIdVphminposuw , "vphminposuw" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ), + INST(kX86InstIdVphsubbw , "vphsubbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E1,U) , U ), + INST(kX86InstIdVphsubd , "vphsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(06,U) , U ), + INST(kX86InstIdVphsubdq , "vphsubdq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E3,U) , U ), + INST(kX86InstIdVphsubsw , "vphsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(07,U) , U ), + INST(kX86InstIdVphsubw , "vphsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(05,U) , U ), + INST(kX86InstIdVphsubwd , "vphsubwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E2,U) , U ), + INST(kX86InstIdVpinsrb , "vpinsrb" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , E(________) , O_660F3A(20,U) , U ), + INST(kX86InstIdVpinsrd , "vpinsrd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdVpinsrq , "vpinsrq" , G(AvxRvmi) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ), + INST(kX86InstIdVpinsrw , "vpinsrw" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , E(________) , O_660F00(C4,U) , U ), + INST(kX86InstIdVpmacsdd , "vpmacsdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9E,U) , U ), + INST(kX86InstIdVpmacsdqh , "vpmacsdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9F,U) , U ), + INST(kX86InstIdVpmacsdql , "vpmacsdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(97,U) , U ), + INST(kX86InstIdVpmacssdd , "vpmacssdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8E,U) , U ), + INST(kX86InstIdVpmacssdqh , "vpmacssdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8F,U) , U ), + INST(kX86InstIdVpmacssdql , "vpmacssdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(87,U) , U ), + INST(kX86InstIdVpmacsswd , "vpmacsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(86,U) , U ), + INST(kX86InstIdVpmacssww , "vpmacssww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(85,U) , U ), + INST(kX86InstIdVpmacswd , "vpmacswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(96,U) , U ), + INST(kX86InstIdVpmacsww , "vpmacsww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(95,U) , U ), + INST(kX86InstIdVpmadcsswd , "vpmadcsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(A6,U) , U ), + INST(kX86InstIdVpmadcswd , "vpmadcswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(B6,U) , U ), + INST(kX86InstIdVpmaddubsw , "vpmaddubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(04,U) , U ), + INST(kX86InstIdVpmaddwd , "vpmaddwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F5,U) , U ), + INST(kX86InstIdVpmaskmovd , "vpmaskmovd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ), + INST(kX86InstIdVpmaskmovq , "vpmaskmovq" , G(AvxRvmMvr_P) , F(None) |F(W), 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ), + INST(kX86InstIdVpmaxsb , "vpmaxsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3C,U) , U ), + INST(kX86InstIdVpmaxsd , "vpmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3D,U) , U ), + INST(kX86InstIdVpmaxsw , "vpmaxsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EE,U) , U ), + INST(kX86InstIdVpmaxub , "vpmaxub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DE,U) , U ), + INST(kX86InstIdVpmaxud , "vpmaxud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3F,U) , U ), + INST(kX86InstIdVpmaxuw , "vpmaxuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3E,U) , U ), + INST(kX86InstIdVpminsb , "vpminsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(38,U) , U ), + INST(kX86InstIdVpminsd , "vpminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(39,U) , U ), + INST(kX86InstIdVpminsw , "vpminsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EA,U) , U ), + INST(kX86InstIdVpminub , "vpminub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DA,U) , U ), + INST(kX86InstIdVpminud , "vpminud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3B,U) , U ), + INST(kX86InstIdVpminuw , "vpminuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3A,U) , U ), + INST(kX86InstIdVpmovmskb , "vpmovmskb" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(D7,U) , U ), + INST(kX86InstIdVpmovsxbd , "vpmovsxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(21,U) , U ), + INST(kX86InstIdVpmovsxbq , "vpmovsxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(22,U) , U ), + INST(kX86InstIdVpmovsxbw , "vpmovsxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(20,U) , U ), + INST(kX86InstIdVpmovsxdq , "vpmovsxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(25,U) , U ), + INST(kX86InstIdVpmovsxwd , "vpmovsxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(23,U) , U ), + INST(kX86InstIdVpmovsxwq , "vpmovsxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(24,U) , U ), + INST(kX86InstIdVpmovzxbd , "vpmovzxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(31,U) , U ), + INST(kX86InstIdVpmovzxbq , "vpmovzxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(32,U) , U ), + INST(kX86InstIdVpmovzxbw , "vpmovzxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(30,U) , U ), + INST(kX86InstIdVpmovzxdq , "vpmovzxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(35,U) , U ), + INST(kX86InstIdVpmovzxwd , "vpmovzxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(33,U) , U ), + INST(kX86InstIdVpmovzxwq , "vpmovzxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(34,U) , U ), + INST(kX86InstIdVpmuldq , "vpmuldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(28,U) , U ), + INST(kX86InstIdVpmulhrsw , "vpmulhrsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0B,U) , U ), + INST(kX86InstIdVpmulhuw , "vpmulhuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E4,U) , U ), + INST(kX86InstIdVpmulhw , "vpmulhw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E5,U) , U ), + INST(kX86InstIdVpmulld , "vpmulld" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(40,U) , U ), + INST(kX86InstIdVpmullw , "vpmullw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D5,U) , U ), + INST(kX86InstIdVpmuludq , "vpmuludq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F4,U) , U ), + INST(kX86InstIdVpor , "vpor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EB,U) , U ), + INST(kX86InstIdVpperm , "vpperm" , G(XopRvrmRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_00_M08(A3,U) , U ), + INST(kX86InstIdVprotb , "vprotb" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(90,U) , O_00_M08(C0,U) ), + INST(kX86InstIdVprotd , "vprotd" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(92,U) , O_00_M08(C2,U) ), + INST(kX86InstIdVprotq , "vprotq" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(93,U) , O_00_M08(C3,U) ), + INST(kX86InstIdVprotw , "vprotw" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(91,U) , O_00_M08(C1,U) ), + INST(kX86InstIdVpsadbw , "vpsadbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F6,U) , U ), + INST(kX86InstIdVpshab , "vpshab" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(98,U) , U ), + INST(kX86InstIdVpshad , "vpshad" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9A,U) , U ), + INST(kX86InstIdVpshaq , "vpshaq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9B,U) , U ), + INST(kX86InstIdVpshaw , "vpshaw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(99,U) , U ), + INST(kX86InstIdVpshlb , "vpshlb" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(94,U) , U ), + INST(kX86InstIdVpshld , "vpshld" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(96,U) , U ), + INST(kX86InstIdVpshlq , "vpshlq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(97,U) , U ), + INST(kX86InstIdVpshlw , "vpshlw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(95,U) , U ), + INST(kX86InstIdVpshufb , "vpshufb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(00,U) , U ), + INST(kX86InstIdVpshufd , "vpshufd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ), + INST(kX86InstIdVpshufhw , "vpshufhw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ), + INST(kX86InstIdVpshuflw , "vpshuflw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ), + INST(kX86InstIdVpsignb , "vpsignb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(08,U) , U ), + INST(kX86InstIdVpsignd , "vpsignd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0A,U) , U ), + INST(kX86InstIdVpsignw , "vpsignw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(09,U) , U ), + INST(kX86InstIdVpslld , "vpslld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F2,U) , O_660F00(72,6) ), + INST(kX86InstIdVpslldq , "vpslldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,7) , U ), + INST(kX86InstIdVpsllq , "vpsllq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F3,U) , O_660F00(73,6) ), + INST(kX86InstIdVpsllvd , "vpsllvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ), + INST(kX86InstIdVpsllvq , "vpsllvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ), + INST(kX86InstIdVpsllw , "vpsllw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F1,U) , O_660F00(71,6) ), + INST(kX86InstIdVpsrad , "vpsrad" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E2,U) , O_660F00(72,4) ), + INST(kX86InstIdVpsravd , "vpsravd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(46,U) , U ), + INST(kX86InstIdVpsraw , "vpsraw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E1,U) , O_660F00(71,4) ), + INST(kX86InstIdVpsrld , "vpsrld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D2,U) , O_660F00(72,2) ), + INST(kX86InstIdVpsrldq , "vpsrldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,3) , U ), + INST(kX86InstIdVpsrlq , "vpsrlq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D3,U) , O_660F00(73,2) ), + INST(kX86InstIdVpsrlvd , "vpsrlvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ), + INST(kX86InstIdVpsrlvq , "vpsrlvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ), + INST(kX86InstIdVpsrlw , "vpsrlw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D1,U) , O_660F00(71,2) ), + INST(kX86InstIdVpsubb , "vpsubb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F8,U) , U ), + INST(kX86InstIdVpsubd , "vpsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FA,U) , U ), + INST(kX86InstIdVpsubq , "vpsubq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FB,U) , U ), + INST(kX86InstIdVpsubsb , "vpsubsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E8,U) , U ), + INST(kX86InstIdVpsubsw , "vpsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E9,U) , U ), + INST(kX86InstIdVpsubusb , "vpsubusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D8,U) , U ), + INST(kX86InstIdVpsubusw , "vpsubusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D9,U) , U ), + INST(kX86InstIdVpsubw , "vpsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F9,U) , U ), + INST(kX86InstIdVptest , "vptest" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ), + INST(kX86InstIdVpunpckhbw , "vpunpckhbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(68,U) , U ), + INST(kX86InstIdVpunpckhdq , "vpunpckhdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6A,U) , U ), + INST(kX86InstIdVpunpckhqdq , "vpunpckhqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6D,U) , U ), + INST(kX86InstIdVpunpckhwd , "vpunpckhwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(69,U) , U ), + INST(kX86InstIdVpunpcklbw , "vpunpcklbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(60,U) , U ), + INST(kX86InstIdVpunpckldq , "vpunpckldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(62,U) , U ), + INST(kX86InstIdVpunpcklqdq , "vpunpcklqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6C,U) , U ), + INST(kX86InstIdVpunpcklwd , "vpunpcklwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(61,U) , U ), + INST(kX86InstIdVpxor , "vpxor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EF,U) , U ), + INST(kX86InstIdVrcpps , "vrcpps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(53,U) , U ), + INST(kX86InstIdVrcpss , "vrcpss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(53,U) , U ), + INST(kX86InstIdVroundpd , "vroundpd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ), + INST(kX86InstIdVroundps , "vroundps" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ), + INST(kX86InstIdVroundsd , "vroundsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0B,U) , U ), + INST(kX86InstIdVroundss , "vroundss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0A,U) , U ), + INST(kX86InstIdVrsqrtps , "vrsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(52,U) , U ), + INST(kX86InstIdVrsqrtss , "vrsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(52,U) , U ), + INST(kX86InstIdVshufpd , "vshufpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C6,U) , U ), + INST(kX86InstIdVshufps , "vshufps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C6,U) , U ), + INST(kX86InstIdVsqrtpd , "vsqrtpd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(51,U) , U ), + INST(kX86InstIdVsqrtps , "vsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(51,U) , U ), + INST(kX86InstIdVsqrtsd , "vsqrtsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(51,U) , U ), + INST(kX86InstIdVsqrtss , "vsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(51,U) , U ), + INST(kX86InstIdVstmxcsr , "vstmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ), + INST(kX86InstIdVsubpd , "vsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5C,U) , U ), + INST(kX86InstIdVsubps , "vsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5C,U) , U ), + INST(kX86InstIdVsubsd , "vsubsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5C,U) , U ), + INST(kX86InstIdVsubss , "vsubss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5C,U) , U ), + INST(kX86InstIdVtestpd , "vtestpd" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0F,U) , U ), + INST(kX86InstIdVtestps , "vtestps" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0E,U) , U ), + INST(kX86InstIdVucomisd , "vucomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ), + INST(kX86InstIdVucomiss , "vucomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ), + INST(kX86InstIdVunpckhpd , "vunpckhpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(15,U) , U ), + INST(kX86InstIdVunpckhps , "vunpckhps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(15,U) , U ), + INST(kX86InstIdVunpcklpd , "vunpcklpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(14,U) , U ), + INST(kX86InstIdVunpcklps , "vunpcklps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(14,U) , U ), + INST(kX86InstIdVxorpd , "vxorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(57,U) , U ), + INST(kX86InstIdVxorps , "vxorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(57,U) , U ), + INST(kX86InstIdVzeroall , "vzeroall" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U)|L, U ), + INST(kX86InstIdVzeroupper , "vzeroupper" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ), + INST(kX86InstIdWrfsbase , "wrfsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,2) , U ), + INST(kX86InstIdWrgsbase , "wrgsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,3) , U ), + INST(kX86InstIdXadd , "xadd" , G(X86Xadd) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(WWWWWW__) , O_000F00(C0,U) , U ), + INST(kX86InstIdXchg , "xchg" , G(X86Xchg) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(________) , O_000000(86,U) , U ), + INST(kX86InstIdXor , "xor" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(30,6) , U ), + INST(kX86InstIdXorpd , "xorpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(57,U) , U ), + INST(kX86InstIdXorps , "xorps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(57,U) , U ) +}; + +#undef INST + +#undef O_00_X +#undef O_9B_X + +#undef O_66_M09 +#undef O_66_M08 +#undef O_66_M03 + +#undef O_00_M09 +#undef O_00_M08 +#undef O_00_M03 + +#undef O_F30F3A +#undef O_F30F38 +#undef O_F30F00 +#undef O_F30000 +#undef O_F20F3A +#undef O_F20F38 +#undef O_F20F00 +#undef O_F20000 +#undef O_9B0000 +#undef O_660F3A +#undef O_660F38 +#undef O_660F00 +#undef O_660000 +#undef O_000F3A +#undef O_000F38 +#undef O_000F0F +#undef O_000F01 +#undef O_000F00 +#undef O_000000 + +#undef L +#undef U + +#undef E +#undef O +#undef F +#undef G + +// ============================================================================ +// [asmjit::X86Cond] +// ============================================================================ + +#define CC_TO_INST(_Inst_) { \ + _Inst_##o, \ + _Inst_##no, \ + _Inst_##b, \ + _Inst_##ae, \ + _Inst_##e, \ + _Inst_##ne, \ + _Inst_##be, \ + _Inst_##a, \ + _Inst_##s, \ + _Inst_##ns, \ + _Inst_##pe, \ + _Inst_##po, \ + _Inst_##l, \ + _Inst_##ge, \ + _Inst_##le, \ + _Inst_##g, \ + \ + kInstIdNone, \ + kInstIdNone, \ + kInstIdNone, \ + kInstIdNone \ +} + +const uint32_t _x86ReverseCond[20] = { + /* kX86CondO -> */ kX86CondO, + /* kX86CondNO -> */ kX86CondNO, + /* kX86CondB -> */ kX86CondA, + /* kX86CondAE -> */ kX86CondBE, + /* kX86CondE -> */ kX86CondE, + /* kX86CondNE -> */ kX86CondNE, + /* kX86CondBE -> */ kX86CondAE, + /* kX86CondA -> */ kX86CondB, + /* kX86CondS -> */ kX86CondS, + /* kX86CondNS -> */ kX86CondNS, + /* kX86CondPE -> */ kX86CondPE, + /* kX86CondPO -> */ kX86CondPO, + /* kX86CondL -> */ kX86CondG, + /* kX86CondGE -> */ kX86CondLE, + /* kX86CondLE -> */ kX86CondGE, + /* kX86CondG -> */ kX86CondL, + + /* kX86CondFpuUnordered -> */ kX86CondFpuUnordered, + /* kX86CondFpuNotUnordered -> */ kX86CondFpuNotUnordered, + + 0x12, + 0x13 +}; + +const uint32_t _x86CondToCmovcc[20] = CC_TO_INST(kX86InstIdCmov); +const uint32_t _x86CondToJcc [20] = CC_TO_INST(kX86InstIdJ ); +const uint32_t _x86CondToSetcc [20] = CC_TO_INST(kX86InstIdSet ); + +#undef CC_TO_INST + +// ============================================================================ +// [asmjit::X86Util] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_NAMES) +// Compare two instruction names. +// +// `a` is null terminated instruction name from `_x86InstName[]` table. +// `b` is non-null terminated instruction name passed to `getInstIdByName()`. +static ASMJIT_INLINE int X86Util_cmpInstName(const char* a, const char* b, size_t len) { + for (size_t i = 0; i < len; i++) { + int c = static_cast(static_cast(a[i])) - + static_cast(static_cast(b[i])) ; + if (c != 0) + return c; + } + + return static_cast(a[len]); +} + +uint32_t X86Util::getInstIdByName(const char* name, size_t len) { + if (name == NULL) + return kInstIdNone; + + if (len == kInvalidIndex) + len = ::strlen(name); + + if (len == 0) + return kInstIdNone; + + uint32_t prefix = name[0] - kX86InstAlphaIndexFirst; + if (prefix > kX86InstAlphaIndexLast - kX86InstAlphaIndexFirst) + return kInstIdNone; + + uint32_t index = _x86InstAlphaIndex[prefix]; + if (index == kX86InstAlphaIndexInvalid) + return kInstIdNone; + + const X86InstInfo* base = _x86InstInfo + index; + const X86InstInfo* end = _x86InstInfo + _kX86InstIdCount; + + // Handle instructions starting with 'j' specially. `jcc` instruction breaks + // the sorting, because of the suffixes (it's considered as one instruction), + // so basically `jecxz` and `jmp` are stored after all `jcc` instructions. + bool linearSearch = prefix == ('j' - kX86InstAlphaIndexFirst); + + while (++prefix <= kX86InstAlphaIndexLast - kX86InstAlphaIndexFirst) { + index = _x86InstAlphaIndex[prefix]; + if (index == kX86InstAlphaIndexInvalid) + continue; + end = _x86InstInfo + index; + break; + } + + if (linearSearch) { + while (base != end) { + if (X86Util_cmpInstName(base->getInstName(), name, len) == 0) + return static_cast((size_t)(base - _x86InstInfo)); + base++; + } + } + else { + for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) { + const X86InstInfo* cur = base + (lim >> 1); + int result = X86Util_cmpInstName(cur->getInstName(), name, len); + + if (result < 0) { + base = cur + 1; + lim--; + continue; + } + + if (result > 0) + continue; + + return static_cast((size_t)(cur - _x86InstInfo)); + } + } + + return kInstIdNone; +} +#endif // ASMJIT_DISABLE_NAMES + +// ============================================================================ +// [asmjit::X86Util - Test] +// ============================================================================ + +#if defined(ASMJIT_TEST) && !defined(ASMJIT_DISABLE_NAMES) +UNIT(x86_inst_name) { + // All known instructions should be matched. + for (uint32_t a = 0; a < _kX86InstIdCount; a++) { + uint32_t b = X86Util::getInstIdByName(_x86InstInfo[a].getInstName()); + + EXPECT(a == b, + "Should match existing instruction \"%s\" {id:%u} != \"%s\" {id:%u}.", + _x86InstInfo[a].getInstName(), a, + _x86InstInfo[b].getInstName(), b); + } + + // Everything else should return kInstIdNone + EXPECT(X86Util::getInstIdByName(NULL) == kInstIdNone, + "Should return kInstIdNone for NULL input."); + + EXPECT(X86Util::getInstIdByName("") == kInstIdNone, + "Should return kInstIdNone for empty string."); + + EXPECT(X86Util::getInstIdByName("_") == kInstIdNone, + "Should return kInstIdNone for unknown instruction."); + + EXPECT(X86Util::getInstIdByName("123xyz") == kInstIdNone, + "Should return kInstIdNone for unknown instruction."); +} +#endif // ASMJIT_TEST && !ASMJIT_DISABLE_NAMES + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/libraries/asmjit/x86/x86inst.h b/libraries/asmjit/x86/x86inst.h new file mode 100644 index 000000000..be6ceaa7f --- /dev/null +++ b/libraries/asmjit/x86/x86inst.h @@ -0,0 +1,2211 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86INST_H +#define _ASMJIT_X86_X86INST_H + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/compiler.h" +#include "../base/globals.h" +#include "../base/intutil.h" +#include "../base/operand.h" +#include "../base/vectypes.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86InstInfo; +struct X86InstExtendedInfo; + +//! \addtogroup asmjit_x86_inst +//! \{ + +// ============================================================================ +// [asmjit::X86Inst/X86Cond - Globals] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_NAMES) +//! \internal +//! +//! X86/X64 instructions' names, accessible through `X86InstInfo`. +ASMJIT_VAR const char _x86InstName[]; +#endif // !ASMJIT_DISABLE_NAMES + +//! \internal +//! +//! X86/X64 instructions' extended information, accessible through `X86InstInfo`. +ASMJIT_VAR const X86InstExtendedInfo _x86InstExtendedInfo[]; + +//! \internal +//! +//! X86/X64 instructions' information. +ASMJIT_VAR const X86InstInfo _x86InstInfo[]; + +//! \internal +//! +//! X86/X64 condition codes to reversed condition codes map. +ASMJIT_VAR const uint32_t _x86ReverseCond[20]; + +//! \internal +//! +//! X86/X64 condition codes to "cmovcc" group map. +ASMJIT_VAR const uint32_t _x86CondToCmovcc[20]; + +//! \internal +//! +//! X86/X64 condition codes to "jcc" group map. +ASMJIT_VAR const uint32_t _x86CondToJcc[20]; + +//! \internal +//! +//! X86/X64 condition codes to "setcc" group map. +ASMJIT_VAR const uint32_t _x86CondToSetcc[20]; + +// ============================================================================ +// [asmjit::kX86InstId] +// ============================================================================ + +//! X86/X64 instruction codes. +//! +//! Note that these instruction codes are AsmJit specific. Each instruction has +//! a unique ID that is used as an index to AsmJit instruction table. +ASMJIT_ENUM(kX86InstId) { + kX86InstIdAdc = 1, // X86/X64 + kX86InstIdAdd, // X86/X64 + kX86InstIdAddpd, // SSE2 + kX86InstIdAddps, // SSE + kX86InstIdAddsd, // SSE2 + kX86InstIdAddss, // SSE + kX86InstIdAddsubpd, // SSE3 + kX86InstIdAddsubps, // SSE3 + kX86InstIdAesdec, // AESNI + kX86InstIdAesdeclast, // AESNI + kX86InstIdAesenc, // AESNI + kX86InstIdAesenclast, // AESNI + kX86InstIdAesimc, // AESNI + kX86InstIdAeskeygenassist, // AESNI + kX86InstIdAnd, // X86/X64 + kX86InstIdAndn, // BMI + kX86InstIdAndnpd, // SSE2 + kX86InstIdAndnps, // SSE + kX86InstIdAndpd, // SSE2 + kX86InstIdAndps, // SSE + kX86InstIdBextr, // BMI + kX86InstIdBlendpd, // SSE4.1 + kX86InstIdBlendps, // SSE4.1 + kX86InstIdBlendvpd, // SSE4.1 + kX86InstIdBlendvps, // SSE4.1 + kX86InstIdBlsi, // BMI + kX86InstIdBlsmsk, // BMI + kX86InstIdBlsr, // BMI + kX86InstIdBsf, // X86/X64 + kX86InstIdBsr, // X86/X64 + kX86InstIdBswap, // X86/X64 (i486) + kX86InstIdBt, // X86/X64 + kX86InstIdBtc, // X86/X64 + kX86InstIdBtr, // X86/X64 + kX86InstIdBts, // X86/X64 + kX86InstIdBzhi, // BMI2 + kX86InstIdCall, // X86/X64 + kX86InstIdCbw, // X86/X64 + kX86InstIdCdq, // X86/X64 + kX86InstIdCdqe, // X64 only + kX86InstIdClc, // X86/X64 + kX86InstIdCld, // X86/X64 + kX86InstIdClflush, // SSE2 + kX86InstIdCmc, // X86/X64 + kX86InstIdCmova, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovae, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovb, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovbe, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovc, // X86/X64 (cmovcc) (i586) + kX86InstIdCmove, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovg, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovge, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovl, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovle, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovna, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnae, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnb, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnbe, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnc, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovne, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovng, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnge, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnl, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnle, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovno, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnp, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovns, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovnz, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovo, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovp, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovpe, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovpo, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovs, // X86/X64 (cmovcc) (i586) + kX86InstIdCmovz, // X86/X64 (cmovcc) (i586) + kX86InstIdCmp, // X86/X64 + kX86InstIdCmppd, // SSE2 + kX86InstIdCmpps, // SSE + kX86InstIdCmpsB, // CMPS - X86/X64 + kX86InstIdCmpsD, // CMPS - X86/X64 + kX86InstIdCmpsQ, // CMPS - X64 + kX86InstIdCmpsW, // CMPS - X86/X64 + kX86InstIdCmpsd, // SSE2 + kX86InstIdCmpss, // SSE + kX86InstIdCmpxchg, // X86/X64 (i486) + kX86InstIdCmpxchg16b, // X64 only + kX86InstIdCmpxchg8b, // X86/X64 (i586) + kX86InstIdComisd, // SSE2 + kX86InstIdComiss, // SSE + kX86InstIdCpuid, // X86/X64 (i486) + kX86InstIdCqo, // X64 only + kX86InstIdCrc32, // SSE4.2 + kX86InstIdCvtdq2pd, // SSE2 + kX86InstIdCvtdq2ps, // SSE2 + kX86InstIdCvtpd2dq, // SSE2 + kX86InstIdCvtpd2pi, // SSE2 + kX86InstIdCvtpd2ps, // SSE2 + kX86InstIdCvtpi2pd, // SSE2 + kX86InstIdCvtpi2ps, // SSE + kX86InstIdCvtps2dq, // SSE2 + kX86InstIdCvtps2pd, // SSE2 + kX86InstIdCvtps2pi, // SSE + kX86InstIdCvtsd2si, // SSE2 + kX86InstIdCvtsd2ss, // SSE2 + kX86InstIdCvtsi2sd, // SSE2 + kX86InstIdCvtsi2ss, // SSE + kX86InstIdCvtss2sd, // SSE2 + kX86InstIdCvtss2si, // SSE + kX86InstIdCvttpd2dq, // SSE2 + kX86InstIdCvttpd2pi, // SSE2 + kX86InstIdCvttps2dq, // SSE2 + kX86InstIdCvttps2pi, // SSE + kX86InstIdCvttsd2si, // SSE2 + kX86InstIdCvttss2si, // SSE + kX86InstIdCwd, // X86/X64 + kX86InstIdCwde, // X86/X64 + kX86InstIdDaa, // X86 only + kX86InstIdDas, // X86 only + kX86InstIdDec, // X86/X64 + kX86InstIdDiv, // X86/X64 + kX86InstIdDivpd, // SSE2 + kX86InstIdDivps, // SSE + kX86InstIdDivsd, // SSE2 + kX86InstIdDivss, // SSE + kX86InstIdDppd, // SSE4.1 + kX86InstIdDpps, // SSE4.1 + kX86InstIdEmms, // MMX + kX86InstIdEnter, // X86/X64 + kX86InstIdExtractps, // SSE4.1 + kX86InstIdF2xm1, // FPU + kX86InstIdFabs, // FPU + kX86InstIdFadd, // FPU + kX86InstIdFaddp, // FPU + kX86InstIdFbld, // FPU + kX86InstIdFbstp, // FPU + kX86InstIdFchs, // FPU + kX86InstIdFclex, // FPU + kX86InstIdFcmovb, // FPU + kX86InstIdFcmovbe, // FPU + kX86InstIdFcmove, // FPU + kX86InstIdFcmovnb, // FPU + kX86InstIdFcmovnbe, // FPU + kX86InstIdFcmovne, // FPU + kX86InstIdFcmovnu, // FPU + kX86InstIdFcmovu, // FPU + kX86InstIdFcom, // FPU + kX86InstIdFcomi, // FPU + kX86InstIdFcomip, // FPU + kX86InstIdFcomp, // FPU + kX86InstIdFcompp, // FPU + kX86InstIdFcos, // FPU + kX86InstIdFdecstp, // FPU + kX86InstIdFdiv, // FPU + kX86InstIdFdivp, // FPU + kX86InstIdFdivr, // FPU + kX86InstIdFdivrp, // FPU + kX86InstIdFemms, // 3dNow! + kX86InstIdFfree, // FPU + kX86InstIdFiadd, // FPU + kX86InstIdFicom, // FPU + kX86InstIdFicomp, // FPU + kX86InstIdFidiv, // FPU + kX86InstIdFidivr, // FPU + kX86InstIdFild, // FPU + kX86InstIdFimul, // FPU + kX86InstIdFincstp, // FPU + kX86InstIdFinit, // FPU + kX86InstIdFist, // FPU + kX86InstIdFistp, // FPU + kX86InstIdFisttp, // SSE3 + kX86InstIdFisub, // FPU + kX86InstIdFisubr, // FPU + kX86InstIdFld, // FPU + kX86InstIdFld1, // FPU + kX86InstIdFldcw, // FPU + kX86InstIdFldenv, // FPU + kX86InstIdFldl2e, // FPU + kX86InstIdFldl2t, // FPU + kX86InstIdFldlg2, // FPU + kX86InstIdFldln2, // FPU + kX86InstIdFldpi, // FPU + kX86InstIdFldz, // FPU + kX86InstIdFmul, // FPU + kX86InstIdFmulp, // FPU + kX86InstIdFnclex, // FPU + kX86InstIdFninit, // FPU + kX86InstIdFnop, // FPU + kX86InstIdFnsave, // FPU + kX86InstIdFnstcw, // FPU + kX86InstIdFnstenv, // FPU + kX86InstIdFnstsw, // FPU + kX86InstIdFpatan, // FPU + kX86InstIdFprem, // FPU + kX86InstIdFprem1, // FPU + kX86InstIdFptan, // FPU + kX86InstIdFrndint, // FPU + kX86InstIdFrstor, // FPU + kX86InstIdFsave, // FPU + kX86InstIdFscale, // FPU + kX86InstIdFsin, // FPU + kX86InstIdFsincos, // FPU + kX86InstIdFsqrt, // FPU + kX86InstIdFst, // FPU + kX86InstIdFstcw, // FPU + kX86InstIdFstenv, // FPU + kX86InstIdFstp, // FPU + kX86InstIdFstsw, // FPU + kX86InstIdFsub, // FPU + kX86InstIdFsubp, // FPU + kX86InstIdFsubr, // FPU + kX86InstIdFsubrp, // FPU + kX86InstIdFtst, // FPU + kX86InstIdFucom, // FPU + kX86InstIdFucomi, // FPU + kX86InstIdFucomip, // FPU + kX86InstIdFucomp, // FPU + kX86InstIdFucompp, // FPU + kX86InstIdFwait, // FPU + kX86InstIdFxam, // FPU + kX86InstIdFxch, // FPU + kX86InstIdFxrstor, // FPU + kX86InstIdFxsave, // FPU + kX86InstIdFxtract, // FPU + kX86InstIdFyl2x, // FPU + kX86InstIdFyl2xp1, // FPU + kX86InstIdHaddpd, // SSE3 + kX86InstIdHaddps, // SSE3 + kX86InstIdHsubpd, // SSE3 + kX86InstIdHsubps, // SSE3 + kX86InstIdIdiv, // X86/X64 + kX86InstIdImul, // X86/X64 + kX86InstIdInc, // X86/X64 + kX86InstIdInsertps, // SSE4.1 + kX86InstIdInt, // X86/X64 + kX86InstIdJa, // X86/X64 (jcc) + kX86InstIdJae, // X86/X64 (jcc) + kX86InstIdJb, // X86/X64 (jcc) + kX86InstIdJbe, // X86/X64 (jcc) + kX86InstIdJc, // X86/X64 (jcc) + kX86InstIdJe, // X86/X64 (jcc) + kX86InstIdJg, // X86/X64 (jcc) + kX86InstIdJge, // X86/X64 (jcc) + kX86InstIdJl, // X86/X64 (jcc) + kX86InstIdJle, // X86/X64 (jcc) + kX86InstIdJna, // X86/X64 (jcc) + kX86InstIdJnae, // X86/X64 (jcc) + kX86InstIdJnb, // X86/X64 (jcc) + kX86InstIdJnbe, // X86/X64 (jcc) + kX86InstIdJnc, // X86/X64 (jcc) + kX86InstIdJne, // X86/X64 (jcc) + kX86InstIdJng, // X86/X64 (jcc) + kX86InstIdJnge, // X86/X64 (jcc) + kX86InstIdJnl, // X86/X64 (jcc) + kX86InstIdJnle, // X86/X64 (jcc) + kX86InstIdJno, // X86/X64 (jcc) + kX86InstIdJnp, // X86/X64 (jcc) + kX86InstIdJns, // X86/X64 (jcc) + kX86InstIdJnz, // X86/X64 (jcc) + kX86InstIdJo, // X86/X64 (jcc) + kX86InstIdJp, // X86/X64 (jcc) + kX86InstIdJpe, // X86/X64 (jcc) + kX86InstIdJpo, // X86/X64 (jcc) + kX86InstIdJs, // X86/X64 (jcc) + kX86InstIdJz, // X86/X64 (jcc) + kX86InstIdJecxz, // X86/X64 (jcxz/jecxz/jrcxz) + kX86InstIdJmp, // X86/X64 (jmp) + kX86InstIdLahf, // X86/X64 (CPUID NEEDED) + kX86InstIdLddqu, // SSE3 + kX86InstIdLdmxcsr, // SSE + kX86InstIdLea, // X86/X64 + kX86InstIdLeave, // X86/X64 + kX86InstIdLfence, // SSE2 + kX86InstIdLodsB, // LODS - X86/X64 + kX86InstIdLodsD, // LODS - X86/X64 + kX86InstIdLodsQ, // LODS - X86/X64 + kX86InstIdLodsW, // LODS - X86/X64 + kX86InstIdLzcnt, // LZCNT + kX86InstIdMaskmovdqu, // SSE2 + kX86InstIdMaskmovq, // MMX-Ext + kX86InstIdMaxpd, // SSE2 + kX86InstIdMaxps, // SSE + kX86InstIdMaxsd, // SSE2 + kX86InstIdMaxss, // SSE + kX86InstIdMfence, // SSE2 + kX86InstIdMinpd, // SSE2 + kX86InstIdMinps, // SSE + kX86InstIdMinsd, // SSE2 + kX86InstIdMinss, // SSE + kX86InstIdMonitor, // SSE3 + kX86InstIdMov, // X86/X64 + kX86InstIdMovPtr, // X86/X64 + kX86InstIdMovapd, // SSE2 + kX86InstIdMovaps, // SSE + kX86InstIdMovbe, // SSE3 - Intel-Atom + kX86InstIdMovd, // MMX/SSE2 + kX86InstIdMovddup, // SSE3 + kX86InstIdMovdq2q, // SSE2 + kX86InstIdMovdqa, // SSE2 + kX86InstIdMovdqu, // SSE2 + kX86InstIdMovhlps, // SSE + kX86InstIdMovhpd, // SSE2 + kX86InstIdMovhps, // SSE + kX86InstIdMovlhps, // SSE + kX86InstIdMovlpd, // SSE2 + kX86InstIdMovlps, // SSE + kX86InstIdMovmskpd, // SSE2 + kX86InstIdMovmskps, // SSE2 + kX86InstIdMovntdq, // SSE2 + kX86InstIdMovntdqa, // SSE4.1 + kX86InstIdMovnti, // SSE2 + kX86InstIdMovntpd, // SSE2 + kX86InstIdMovntps, // SSE + kX86InstIdMovntq, // MMX-Ext + kX86InstIdMovq, // MMX/SSE/SSE2 + kX86InstIdMovq2dq, // SSE2 + kX86InstIdMovsB, // MOVS - X86/X64 + kX86InstIdMovsD, // MOVS - X86/X64 + kX86InstIdMovsQ, // MOVS - X64 + kX86InstIdMovsW, // MOVS - X86/X64 + kX86InstIdMovsd, // SSE2 + kX86InstIdMovshdup, // SSE3 + kX86InstIdMovsldup, // SSE3 + kX86InstIdMovss, // SSE + kX86InstIdMovsx, // X86/X64 + kX86InstIdMovsxd, // X86/X64 + kX86InstIdMovupd, // SSE2 + kX86InstIdMovups, // SSE + kX86InstIdMovzx, // X86/X64 + kX86InstIdMpsadbw, // SSE4.1 + kX86InstIdMul, // X86/X64 + kX86InstIdMulpd, // SSE2 + kX86InstIdMulps, // SSE + kX86InstIdMulsd, // SSE2 + kX86InstIdMulss, // SSE + kX86InstIdMulx, // BMI2 + kX86InstIdMwait, // SSE3 + kX86InstIdNeg, // X86/X64 + kX86InstIdNop, // X86/X64 + kX86InstIdNot, // X86/X64 + kX86InstIdOr, // X86/X64 + kX86InstIdOrpd, // SSE2 + kX86InstIdOrps, // SSE + kX86InstIdPabsb, // SSSE3 + kX86InstIdPabsd, // SSSE3 + kX86InstIdPabsw, // SSSE3 + kX86InstIdPackssdw, // MMX/SSE2 + kX86InstIdPacksswb, // MMX/SSE2 + kX86InstIdPackusdw, // SSE4.1 + kX86InstIdPackuswb, // MMX/SSE2 + kX86InstIdPaddb, // MMX/SSE2 + kX86InstIdPaddd, // MMX/SSE2 + kX86InstIdPaddq, // SSE2 + kX86InstIdPaddsb, // MMX/SSE2 + kX86InstIdPaddsw, // MMX/SSE2 + kX86InstIdPaddusb, // MMX/SSE2 + kX86InstIdPaddusw, // MMX/SSE2 + kX86InstIdPaddw, // MMX/SSE2 + kX86InstIdPalignr, // SSSE3 + kX86InstIdPand, // MMX/SSE2 + kX86InstIdPandn, // MMX/SSE2 + kX86InstIdPause, // SSE2. + kX86InstIdPavgb, // MMX-Ext + kX86InstIdPavgw, // MMX-Ext + kX86InstIdPblendvb, // SSE4.1 + kX86InstIdPblendw, // SSE4.1 + kX86InstIdPclmulqdq, // PCLMULQDQ + kX86InstIdPcmpeqb, // MMX/SSE2 + kX86InstIdPcmpeqd, // MMX/SSE2 + kX86InstIdPcmpeqq, // SSE4.1 + kX86InstIdPcmpeqw, // MMX/SSE2 + kX86InstIdPcmpestri, // SSE4.2 + kX86InstIdPcmpestrm, // SSE4.2 + kX86InstIdPcmpgtb, // MMX/SSE2 + kX86InstIdPcmpgtd, // MMX/SSE2 + kX86InstIdPcmpgtq, // SSE4.2 + kX86InstIdPcmpgtw, // MMX/SSE2 + kX86InstIdPcmpistri, // SSE4.2 + kX86InstIdPcmpistrm, // SSE4.2 + kX86InstIdPdep, // BMI2 + kX86InstIdPext, // BMI2 + kX86InstIdPextrb, // SSE4.1 + kX86InstIdPextrd, // SSE4.1 + kX86InstIdPextrq, // SSE4.1 + kX86InstIdPextrw, // MMX-Ext/SSE2 + kX86InstIdPf2id, // 3dNow! + kX86InstIdPf2iw, // Enhanced 3dNow! + kX86InstIdPfacc, // 3dNow! + kX86InstIdPfadd, // 3dNow! + kX86InstIdPfcmpeq, // 3dNow! + kX86InstIdPfcmpge, // 3dNow! + kX86InstIdPfcmpgt, // 3dNow! + kX86InstIdPfmax, // 3dNow! + kX86InstIdPfmin, // 3dNow! + kX86InstIdPfmul, // 3dNow! + kX86InstIdPfnacc, // Enhanced 3dNow! + kX86InstIdPfpnacc, // Enhanced 3dNow! + kX86InstIdPfrcp, // 3dNow! + kX86InstIdPfrcpit1, // 3dNow! + kX86InstIdPfrcpit2, // 3dNow! + kX86InstIdPfrsqit1, // 3dNow! + kX86InstIdPfrsqrt, // 3dNow! + kX86InstIdPfsub, // 3dNow! + kX86InstIdPfsubr, // 3dNow! + kX86InstIdPhaddd, // SSSE3 + kX86InstIdPhaddsw, // SSSE3 + kX86InstIdPhaddw, // SSSE3 + kX86InstIdPhminposuw, // SSE4.1 + kX86InstIdPhsubd, // SSSE3 + kX86InstIdPhsubsw, // SSSE3 + kX86InstIdPhsubw, // SSSE3 + kX86InstIdPi2fd, // 3dNow! + kX86InstIdPi2fw, // Enhanced 3dNow! + kX86InstIdPinsrb, // SSE4.1 + kX86InstIdPinsrd, // SSE4.1 + kX86InstIdPinsrq, // SSE4.1 + kX86InstIdPinsrw, // MMX-Ext + kX86InstIdPmaddubsw, // SSSE3 + kX86InstIdPmaddwd, // MMX/SSE2 + kX86InstIdPmaxsb, // SSE4.1 + kX86InstIdPmaxsd, // SSE4.1 + kX86InstIdPmaxsw, // MMX-Ext + kX86InstIdPmaxub, // MMX-Ext + kX86InstIdPmaxud, // SSE4.1 + kX86InstIdPmaxuw, // SSE4.1 + kX86InstIdPminsb, // SSE4.1 + kX86InstIdPminsd, // SSE4.1 + kX86InstIdPminsw, // MMX-Ext + kX86InstIdPminub, // MMX-Ext + kX86InstIdPminud, // SSE4.1 + kX86InstIdPminuw, // SSE4.1 + kX86InstIdPmovmskb, // MMX-Ext + kX86InstIdPmovsxbd, // SSE4.1 + kX86InstIdPmovsxbq, // SSE4.1 + kX86InstIdPmovsxbw, // SSE4.1 + kX86InstIdPmovsxdq, // SSE4.1 + kX86InstIdPmovsxwd, // SSE4.1 + kX86InstIdPmovsxwq, // SSE4.1 + kX86InstIdPmovzxbd, // SSE4.1 + kX86InstIdPmovzxbq, // SSE4.1 + kX86InstIdPmovzxbw, // SSE4.1 + kX86InstIdPmovzxdq, // SSE4.1 + kX86InstIdPmovzxwd, // SSE4.1 + kX86InstIdPmovzxwq, // SSE4.1 + kX86InstIdPmuldq, // SSE4.1 + kX86InstIdPmulhrsw, // SSSE3 + kX86InstIdPmulhuw, // MMX-Ext + kX86InstIdPmulhw, // MMX/SSE2 + kX86InstIdPmulld, // SSE4.1 + kX86InstIdPmullw, // MMX/SSE2 + kX86InstIdPmuludq, // SSE2 + kX86InstIdPop, // X86/X64 + kX86InstIdPopa, // X86 only + kX86InstIdPopcnt, // SSE4.2 + kX86InstIdPopf, // X86/X64 + kX86InstIdPor, // MMX/SSE2 + kX86InstIdPrefetch, // MMX-Ext/SSE + kX86InstIdPrefetch3dNow, // 3dNow! + kX86InstIdPrefetchw3dNow, // 3dNow! + kX86InstIdPsadbw, // MMX-Ext + kX86InstIdPshufb, // SSSE3 + kX86InstIdPshufd, // SSE2 + kX86InstIdPshufhw, // SSE2 + kX86InstIdPshuflw, // SSE2 + kX86InstIdPshufw, // MMX-Ext + kX86InstIdPsignb, // SSSE3 + kX86InstIdPsignd, // SSSE3 + kX86InstIdPsignw, // SSSE3 + kX86InstIdPslld, // MMX/SSE2 + kX86InstIdPslldq, // SSE2 + kX86InstIdPsllq, // MMX/SSE2 + kX86InstIdPsllw, // MMX/SSE2 + kX86InstIdPsrad, // MMX/SSE2 + kX86InstIdPsraw, // MMX/SSE2 + kX86InstIdPsrld, // MMX/SSE2 + kX86InstIdPsrldq, // SSE2 + kX86InstIdPsrlq, // MMX/SSE2 + kX86InstIdPsrlw, // MMX/SSE2 + kX86InstIdPsubb, // MMX/SSE2 + kX86InstIdPsubd, // MMX/SSE2 + kX86InstIdPsubq, // SSE2 + kX86InstIdPsubsb, // MMX/SSE2 + kX86InstIdPsubsw, // MMX/SSE2 + kX86InstIdPsubusb, // MMX/SSE2 + kX86InstIdPsubusw, // MMX/SSE2 + kX86InstIdPsubw, // MMX/SSE2 + kX86InstIdPswapd, // Enhanced 3dNow! + kX86InstIdPtest, // SSE4.1 + kX86InstIdPunpckhbw, // MMX/SSE2 + kX86InstIdPunpckhdq, // MMX/SSE2 + kX86InstIdPunpckhqdq, // SSE2 + kX86InstIdPunpckhwd, // MMX/SSE2 + kX86InstIdPunpcklbw, // MMX/SSE2 + kX86InstIdPunpckldq, // MMX/SSE2 + kX86InstIdPunpcklqdq, // SSE2 + kX86InstIdPunpcklwd, // MMX/SSE2 + kX86InstIdPush, // X86/X64 + kX86InstIdPusha, // X86 only + kX86InstIdPushf, // X86/X64 + kX86InstIdPxor, // MMX/SSE2 + kX86InstIdRcl, // X86/X64 + kX86InstIdRcpps, // SSE + kX86InstIdRcpss, // SSE + kX86InstIdRcr, // X86/X64 + kX86InstIdRdfsbase, // FSGSBASE (x64) + kX86InstIdRdgsbase, // FSGSBASE (x64) + kX86InstIdRdrand, // RDRAND + kX86InstIdRdtsc, // X86/X64 + kX86InstIdRdtscp, // X86/X64 + kX86InstIdRepLodsB, // X86/X64 (REP) + kX86InstIdRepLodsD, // X86/X64 (REP) + kX86InstIdRepLodsQ, // X64 only (REP) + kX86InstIdRepLodsW, // X86/X64 (REP) + kX86InstIdRepMovsB, // X86/X64 (REP) + kX86InstIdRepMovsD, // X86/X64 (REP) + kX86InstIdRepMovsQ, // X64 only (REP) + kX86InstIdRepMovsW, // X86/X64 (REP) + kX86InstIdRepStosB, // X86/X64 (REP) + kX86InstIdRepStosD, // X86/X64 (REP) + kX86InstIdRepStosQ, // X64 only (REP) + kX86InstIdRepStosW, // X86/X64 (REP) + kX86InstIdRepeCmpsB, // X86/X64 (REP) + kX86InstIdRepeCmpsD, // X86/X64 (REP) + kX86InstIdRepeCmpsQ, // X64 only (REP) + kX86InstIdRepeCmpsW, // X86/X64 (REP) + kX86InstIdRepeScasB, // X86/X64 (REP) + kX86InstIdRepeScasD, // X86/X64 (REP) + kX86InstIdRepeScasQ, // X64 only (REP) + kX86InstIdRepeScasW, // X86/X64 (REP) + kX86InstIdRepneCmpsB, // X86/X64 (REP) + kX86InstIdRepneCmpsD, // X86/X64 (REP) + kX86InstIdRepneCmpsQ, // X64 only (REP) + kX86InstIdRepneCmpsW, // X86/X64 (REP) + kX86InstIdRepneScasB, // X86/X64 (REP) + kX86InstIdRepneScasD, // X86/X64 (REP) + kX86InstIdRepneScasQ, // X64 only (REP) + kX86InstIdRepneScasW, // X86/X64 (REP) + kX86InstIdRet, // X86/X64 + kX86InstIdRol, // X86/X64 + kX86InstIdRor, // X86/X64 + kX86InstIdRorx, // BMI2 + kX86InstIdRoundpd, // SSE4.1 + kX86InstIdRoundps, // SSE4.1 + kX86InstIdRoundsd, // SSE4.1 + kX86InstIdRoundss, // SSE4.1 + kX86InstIdRsqrtps, // SSE + kX86InstIdRsqrtss, // SSE + kX86InstIdSahf, // X86/X64 (CPUID NEEDED) + kX86InstIdSal, // X86/X64 + kX86InstIdSar, // X86/X64 + kX86InstIdSarx, // BMI2 + kX86InstIdSbb, // X86/X64 + kX86InstIdScasB, // SCAS - X86/X64 + kX86InstIdScasD, // SCAS - X86/X64 + kX86InstIdScasQ, // SCAS - X64 + kX86InstIdScasW, // SCAS - X86/X64 + kX86InstIdSeta, // X86/X64 (setcc) + kX86InstIdSetae, // X86/X64 (setcc) + kX86InstIdSetb, // X86/X64 (setcc) + kX86InstIdSetbe, // X86/X64 (setcc) + kX86InstIdSetc, // X86/X64 (setcc) + kX86InstIdSete, // X86/X64 (setcc) + kX86InstIdSetg, // X86/X64 (setcc) + kX86InstIdSetge, // X86/X64 (setcc) + kX86InstIdSetl, // X86/X64 (setcc) + kX86InstIdSetle, // X86/X64 (setcc) + kX86InstIdSetna, // X86/X64 (setcc) + kX86InstIdSetnae, // X86/X64 (setcc) + kX86InstIdSetnb, // X86/X64 (setcc) + kX86InstIdSetnbe, // X86/X64 (setcc) + kX86InstIdSetnc, // X86/X64 (setcc) + kX86InstIdSetne, // X86/X64 (setcc) + kX86InstIdSetng, // X86/X64 (setcc) + kX86InstIdSetnge, // X86/X64 (setcc) + kX86InstIdSetnl, // X86/X64 (setcc) + kX86InstIdSetnle, // X86/X64 (setcc) + kX86InstIdSetno, // X86/X64 (setcc) + kX86InstIdSetnp, // X86/X64 (setcc) + kX86InstIdSetns, // X86/X64 (setcc) + kX86InstIdSetnz, // X86/X64 (setcc) + kX86InstIdSeto, // X86/X64 (setcc) + kX86InstIdSetp, // X86/X64 (setcc) + kX86InstIdSetpe, // X86/X64 (setcc) + kX86InstIdSetpo, // X86/X64 (setcc) + kX86InstIdSets, // X86/X64 (setcc) + kX86InstIdSetz, // X86/X64 (setcc) + kX86InstIdSfence, // MMX-Ext/SSE + kX86InstIdShl, // X86/X64 + kX86InstIdShld, // X86/X64 + kX86InstIdShlx, // BMI2 + kX86InstIdShr, // X86/X64 + kX86InstIdShrd, // X86/X64 + kX86InstIdShrx, // BMI2 + kX86InstIdShufpd, // SSE2 + kX86InstIdShufps, // SSE + kX86InstIdSqrtpd, // SSE2 + kX86InstIdSqrtps, // SSE + kX86InstIdSqrtsd, // SSE2 + kX86InstIdSqrtss, // SSE + kX86InstIdStc, // X86/X64 + kX86InstIdStd, // X86/X64 + kX86InstIdStmxcsr, // SSE + kX86InstIdStosB, // STOS - X86/X64 + kX86InstIdStosD, // STOS - X86/X64 + kX86InstIdStosQ, // STOS - X64 + kX86InstIdStosW, // STOS - X86/X64 + kX86InstIdSub, // X86/X64 + kX86InstIdSubpd, // SSE2 + kX86InstIdSubps, // SSE + kX86InstIdSubsd, // SSE2 + kX86InstIdSubss, // SSE + kX86InstIdTest, // X86/X64 + kX86InstIdTzcnt, // TZCNT + kX86InstIdUcomisd, // SSE2 + kX86InstIdUcomiss, // SSE + kX86InstIdUd2, // X86/X64 + kX86InstIdUnpckhpd, // SSE2 + kX86InstIdUnpckhps, // SSE + kX86InstIdUnpcklpd, // SSE2 + kX86InstIdUnpcklps, // SSE + kX86InstIdVaddpd, // AVX + kX86InstIdVaddps, // AVX + kX86InstIdVaddsd, // AVX + kX86InstIdVaddss, // AVX + kX86InstIdVaddsubpd, // AVX + kX86InstIdVaddsubps, // AVX + kX86InstIdVaesdec, // AVX+AESNI + kX86InstIdVaesdeclast, // AVX+AESNI + kX86InstIdVaesenc, // AVX+AESNI + kX86InstIdVaesenclast, // AVX+AESNI + kX86InstIdVaesimc, // AVX+AESNI + kX86InstIdVaeskeygenassist,// AVX+AESNI + kX86InstIdVandnpd, // AVX + kX86InstIdVandnps, // AVX + kX86InstIdVandpd, // AVX + kX86InstIdVandps, // AVX + kX86InstIdVblendpd, // AVX + kX86InstIdVblendps, // AVX + kX86InstIdVblendvpd, // AVX + kX86InstIdVblendvps, // AVX + kX86InstIdVbroadcastf128, // AVX + kX86InstIdVbroadcasti128, // AVX2 + kX86InstIdVbroadcastsd, // AVX/AVX2 + kX86InstIdVbroadcastss, // AVX/AVX2 + kX86InstIdVcmppd, // AVX + kX86InstIdVcmpps, // AVX + kX86InstIdVcmpsd, // AVX + kX86InstIdVcmpss, // AVX + kX86InstIdVcomisd, // AVX + kX86InstIdVcomiss, // AVX + kX86InstIdVcvtdq2pd, // AVX + kX86InstIdVcvtdq2ps, // AVX + kX86InstIdVcvtpd2dq, // AVX + kX86InstIdVcvtpd2ps, // AVX + kX86InstIdVcvtph2ps, // F16C + kX86InstIdVcvtps2dq, // AVX + kX86InstIdVcvtps2pd, // AVX + kX86InstIdVcvtps2ph, // F16C + kX86InstIdVcvtsd2si, // AVX + kX86InstIdVcvtsd2ss, // AVX + kX86InstIdVcvtsi2sd, // AVX + kX86InstIdVcvtsi2ss, // AVX + kX86InstIdVcvtss2sd, // AVX + kX86InstIdVcvtss2si, // AVX + kX86InstIdVcvttpd2dq, // AVX + kX86InstIdVcvttps2dq, // AVX + kX86InstIdVcvttsd2si, // AVX + kX86InstIdVcvttss2si, // AVX + kX86InstIdVdivpd, // AVX + kX86InstIdVdivps, // AVX + kX86InstIdVdivsd, // AVX + kX86InstIdVdivss, // AVX + kX86InstIdVdppd, // AVX + kX86InstIdVdpps, // AVX + kX86InstIdVextractf128, // AVX + kX86InstIdVextracti128, // AVX2 + kX86InstIdVextractps, // AVX + kX86InstIdVfmadd132pd, // FMA3 + kX86InstIdVfmadd132ps, // FMA3 + kX86InstIdVfmadd132sd, // FMA3 + kX86InstIdVfmadd132ss, // FMA3 + kX86InstIdVfmadd213pd, // FMA3 + kX86InstIdVfmadd213ps, // FMA3 + kX86InstIdVfmadd213sd, // FMA3 + kX86InstIdVfmadd213ss, // FMA3 + kX86InstIdVfmadd231pd, // FMA3 + kX86InstIdVfmadd231ps, // FMA3 + kX86InstIdVfmadd231sd, // FMA3 + kX86InstIdVfmadd231ss, // FMA3 + kX86InstIdVfmaddpd, // FMA4 + kX86InstIdVfmaddps, // FMA4 + kX86InstIdVfmaddsd, // FMA4 + kX86InstIdVfmaddss, // FMA4 + kX86InstIdVfmaddsub132pd, // FMA3 + kX86InstIdVfmaddsub132ps, // FMA3 + kX86InstIdVfmaddsub213pd, // FMA3 + kX86InstIdVfmaddsub213ps, // FMA3 + kX86InstIdVfmaddsub231pd, // FMA3 + kX86InstIdVfmaddsub231ps, // FMA3 + kX86InstIdVfmaddsubpd, // FMA4 + kX86InstIdVfmaddsubps, // FMA4 + kX86InstIdVfmsub132pd, // FMA3 + kX86InstIdVfmsub132ps, // FMA3 + kX86InstIdVfmsub132sd, // FMA3 + kX86InstIdVfmsub132ss, // FMA3 + kX86InstIdVfmsub213pd, // FMA3 + kX86InstIdVfmsub213ps, // FMA3 + kX86InstIdVfmsub213sd, // FMA3 + kX86InstIdVfmsub213ss, // FMA3 + kX86InstIdVfmsub231pd, // FMA3 + kX86InstIdVfmsub231ps, // FMA3 + kX86InstIdVfmsub231sd, // FMA3 + kX86InstIdVfmsub231ss, // FMA3 + kX86InstIdVfmsubadd132pd, // FMA3 + kX86InstIdVfmsubadd132ps, // FMA3 + kX86InstIdVfmsubadd213pd, // FMA3 + kX86InstIdVfmsubadd213ps, // FMA3 + kX86InstIdVfmsubadd231pd, // FMA3 + kX86InstIdVfmsubadd231ps, // FMA3 + kX86InstIdVfmsubaddpd, // FMA4 + kX86InstIdVfmsubaddps, // FMA4 + kX86InstIdVfmsubpd, // FMA4 + kX86InstIdVfmsubps, // FMA4 + kX86InstIdVfmsubsd, // FMA4 + kX86InstIdVfmsubss, // FMA4 + kX86InstIdVfnmadd132pd, // FMA3 + kX86InstIdVfnmadd132ps, // FMA3 + kX86InstIdVfnmadd132sd, // FMA3 + kX86InstIdVfnmadd132ss, // FMA3 + kX86InstIdVfnmadd213pd, // FMA3 + kX86InstIdVfnmadd213ps, // FMA3 + kX86InstIdVfnmadd213sd, // FMA3 + kX86InstIdVfnmadd213ss, // FMA3 + kX86InstIdVfnmadd231pd, // FMA3 + kX86InstIdVfnmadd231ps, // FMA3 + kX86InstIdVfnmadd231sd, // FMA3 + kX86InstIdVfnmadd231ss, // FMA3 + kX86InstIdVfnmaddpd, // FMA4 + kX86InstIdVfnmaddps, // FMA4 + kX86InstIdVfnmaddsd, // FMA4 + kX86InstIdVfnmaddss, // FMA4 + kX86InstIdVfnmsub132pd, // FMA3 + kX86InstIdVfnmsub132ps, // FMA3 + kX86InstIdVfnmsub132sd, // FMA3 + kX86InstIdVfnmsub132ss, // FMA3 + kX86InstIdVfnmsub213pd, // FMA3 + kX86InstIdVfnmsub213ps, // FMA3 + kX86InstIdVfnmsub213sd, // FMA3 + kX86InstIdVfnmsub213ss, // FMA3 + kX86InstIdVfnmsub231pd, // FMA3 + kX86InstIdVfnmsub231ps, // FMA3 + kX86InstIdVfnmsub231sd, // FMA3 + kX86InstIdVfnmsub231ss, // FMA3 + kX86InstIdVfnmsubpd, // FMA4 + kX86InstIdVfnmsubps, // FMA4 + kX86InstIdVfnmsubsd, // FMA4 + kX86InstIdVfnmsubss, // FMA4 + kX86InstIdVfrczpd, // XOP + kX86InstIdVfrczps, // XOP + kX86InstIdVfrczsd, // XOP + kX86InstIdVfrczss, // XOP + kX86InstIdVgatherdpd, // AVX2 + kX86InstIdVgatherdps, // AVX2 + kX86InstIdVgatherqpd, // AVX2 + kX86InstIdVgatherqps, // AVX2 + kX86InstIdVhaddpd, // AVX + kX86InstIdVhaddps, // AVX + kX86InstIdVhsubpd, // AVX + kX86InstIdVhsubps, // AVX + kX86InstIdVinsertf128, // AVX + kX86InstIdVinserti128, // AVX2 + kX86InstIdVinsertps, // AVX + kX86InstIdVlddqu, // AVX + kX86InstIdVldmxcsr, // AVX + kX86InstIdVmaskmovdqu, // AVX + kX86InstIdVmaskmovpd, // AVX + kX86InstIdVmaskmovps, // AVX + kX86InstIdVmaxpd, // AVX + kX86InstIdVmaxps, // AVX + kX86InstIdVmaxsd, // AVX + kX86InstIdVmaxss, // AVX + kX86InstIdVminpd, // AVX + kX86InstIdVminps, // AVX + kX86InstIdVminsd, // AVX + kX86InstIdVminss, // AVX + kX86InstIdVmovapd, // AVX + kX86InstIdVmovaps, // AVX + kX86InstIdVmovd, // AVX + kX86InstIdVmovddup, // AVX + kX86InstIdVmovdqa, // AVX + kX86InstIdVmovdqu, // AVX + kX86InstIdVmovhlps, // AVX + kX86InstIdVmovhpd, // AVX + kX86InstIdVmovhps, // AVX + kX86InstIdVmovlhps, // AVX + kX86InstIdVmovlpd, // AVX + kX86InstIdVmovlps, // AVX + kX86InstIdVmovmskpd, // AVX + kX86InstIdVmovmskps, // AVX + kX86InstIdVmovntdq, // AVX + kX86InstIdVmovntdqa, // AVX/AVX2 + kX86InstIdVmovntpd, // AVX + kX86InstIdVmovntps, // AVX + kX86InstIdVmovq, // AVX + kX86InstIdVmovsd, // AVX + kX86InstIdVmovshdup, // AVX + kX86InstIdVmovsldup, // AVX + kX86InstIdVmovss, // AVX + kX86InstIdVmovupd, // AVX + kX86InstIdVmovups, // AVX + kX86InstIdVmpsadbw, // AVX/AVX2 + kX86InstIdVmulpd, // AVX + kX86InstIdVmulps, // AVX + kX86InstIdVmulsd, // AVX + kX86InstIdVmulss, // AVX + kX86InstIdVorpd, // AVX + kX86InstIdVorps, // AVX + kX86InstIdVpabsb, // AVX2 + kX86InstIdVpabsd, // AVX2 + kX86InstIdVpabsw, // AVX2 + kX86InstIdVpackssdw, // AVX2 + kX86InstIdVpacksswb, // AVX2 + kX86InstIdVpackusdw, // AVX2 + kX86InstIdVpackuswb, // AVX2 + kX86InstIdVpaddb, // AVX2 + kX86InstIdVpaddd, // AVX2 + kX86InstIdVpaddq, // AVX2 + kX86InstIdVpaddsb, // AVX2 + kX86InstIdVpaddsw, // AVX2 + kX86InstIdVpaddusb, // AVX2 + kX86InstIdVpaddusw, // AVX2 + kX86InstIdVpaddw, // AVX2 + kX86InstIdVpalignr, // AVX2 + kX86InstIdVpand, // AVX2 + kX86InstIdVpandn, // AVX2 + kX86InstIdVpavgb, // AVX2 + kX86InstIdVpavgw, // AVX2 + kX86InstIdVpblendd, // AVX2 + kX86InstIdVpblendvb, // AVX2 + kX86InstIdVpblendw, // AVX2 + kX86InstIdVpbroadcastb, // AVX2 + kX86InstIdVpbroadcastd, // AVX2 + kX86InstIdVpbroadcastq, // AVX2 + kX86InstIdVpbroadcastw, // AVX2 + kX86InstIdVpclmulqdq, // AVX+PCLMULQDQ + kX86InstIdVpcmov, // XOP + kX86InstIdVpcmpeqb, // AVX2 + kX86InstIdVpcmpeqd, // AVX2 + kX86InstIdVpcmpeqq, // AVX2 + kX86InstIdVpcmpeqw, // AVX2 + kX86InstIdVpcmpestri, // AVX + kX86InstIdVpcmpestrm, // AVX + kX86InstIdVpcmpgtb, // AVX2 + kX86InstIdVpcmpgtd, // AVX2 + kX86InstIdVpcmpgtq, // AVX2 + kX86InstIdVpcmpgtw, // AVX2 + kX86InstIdVpcmpistri, // AVX + kX86InstIdVpcmpistrm, // AVX + kX86InstIdVpcomb, // XOP + kX86InstIdVpcomd, // XOP + kX86InstIdVpcomq, // XOP + kX86InstIdVpcomub, // XOP + kX86InstIdVpcomud, // XOP + kX86InstIdVpcomuq, // XOP + kX86InstIdVpcomuw, // XOP + kX86InstIdVpcomw, // XOP + kX86InstIdVperm2f128, // AVX + kX86InstIdVperm2i128, // AVX2 + kX86InstIdVpermd, // AVX2 + kX86InstIdVpermil2pd, // XOP + kX86InstIdVpermil2ps, // XOP + kX86InstIdVpermilpd, // AVX + kX86InstIdVpermilps, // AVX + kX86InstIdVpermpd, // AVX2 + kX86InstIdVpermps, // AVX2 + kX86InstIdVpermq, // AVX2 + kX86InstIdVpextrb, // AVX + kX86InstIdVpextrd, // AVX + kX86InstIdVpextrq, // AVX (x64 only) + kX86InstIdVpextrw, // AVX + kX86InstIdVpgatherdd, // AVX2 + kX86InstIdVpgatherdq, // AVX2 + kX86InstIdVpgatherqd, // AVX2 + kX86InstIdVpgatherqq, // AVX2 + kX86InstIdVphaddbd, // XOP + kX86InstIdVphaddbq, // XOP + kX86InstIdVphaddbw, // XOP + kX86InstIdVphaddd, // AVX2 + kX86InstIdVphadddq, // XOP + kX86InstIdVphaddsw, // AVX2 + kX86InstIdVphaddubd, // XOP + kX86InstIdVphaddubq, // XOP + kX86InstIdVphaddubw, // XOP + kX86InstIdVphaddudq, // XOP + kX86InstIdVphadduwd, // XOP + kX86InstIdVphadduwq, // XOP + kX86InstIdVphaddw, // AVX2 + kX86InstIdVphaddwd, // XOP + kX86InstIdVphaddwq, // XOP + kX86InstIdVphminposuw, // AVX + kX86InstIdVphsubbw, // XOP + kX86InstIdVphsubd, // AVX2 + kX86InstIdVphsubdq, // XOP + kX86InstIdVphsubsw, // AVX2 + kX86InstIdVphsubw, // AVX2 + kX86InstIdVphsubwd, // XOP + kX86InstIdVpinsrb, // AVX + kX86InstIdVpinsrd, // AVX + kX86InstIdVpinsrq, // AVX (x64 only) + kX86InstIdVpinsrw, // AVX + kX86InstIdVpmacsdd, // XOP + kX86InstIdVpmacsdqh, // XOP + kX86InstIdVpmacsdql, // XOP + kX86InstIdVpmacssdd, // XOP + kX86InstIdVpmacssdqh, // XOP + kX86InstIdVpmacssdql, // XOP + kX86InstIdVpmacsswd, // XOP + kX86InstIdVpmacssww, // XOP + kX86InstIdVpmacswd, // XOP + kX86InstIdVpmacsww, // XOP + kX86InstIdVpmadcsswd, // XOP + kX86InstIdVpmadcswd, // XOP + kX86InstIdVpmaddubsw, // AVX/AVX2 + kX86InstIdVpmaddwd, // AVX/AVX2 + kX86InstIdVpmaskmovd, // AVX2 + kX86InstIdVpmaskmovq, // AVX2 + kX86InstIdVpmaxsb, // AVX/AVX2 + kX86InstIdVpmaxsd, // AVX/AVX2 + kX86InstIdVpmaxsw, // AVX/AVX2 + kX86InstIdVpmaxub, // AVX/AVX2 + kX86InstIdVpmaxud, // AVX/AVX2 + kX86InstIdVpmaxuw, // AVX/AVX2 + kX86InstIdVpminsb, // AVX/AVX2 + kX86InstIdVpminsd, // AVX/AVX2 + kX86InstIdVpminsw, // AVX/AVX2 + kX86InstIdVpminub, // AVX/AVX2 + kX86InstIdVpminud, // AVX/AVX2 + kX86InstIdVpminuw, // AVX/AVX2 + kX86InstIdVpmovmskb, // AVX/AVX2 + kX86InstIdVpmovsxbd, // AVX/AVX2 + kX86InstIdVpmovsxbq, // AVX/AVX2 + kX86InstIdVpmovsxbw, // AVX/AVX2 + kX86InstIdVpmovsxdq, // AVX/AVX2 + kX86InstIdVpmovsxwd, // AVX/AVX2 + kX86InstIdVpmovsxwq, // AVX/AVX2 + kX86InstIdVpmovzxbd, // AVX/AVX2 + kX86InstIdVpmovzxbq, // AVX/AVX2 + kX86InstIdVpmovzxbw, // AVX/AVX2 + kX86InstIdVpmovzxdq, // AVX/AVX2 + kX86InstIdVpmovzxwd, // AVX/AVX2 + kX86InstIdVpmovzxwq, // AVX/AVX2 + kX86InstIdVpmuldq, // AVX/AVX2 + kX86InstIdVpmulhrsw, // AVX/AVX2 + kX86InstIdVpmulhuw, // AVX/AVX2 + kX86InstIdVpmulhw, // AVX/AVX2 + kX86InstIdVpmulld, // AVX/AVX2 + kX86InstIdVpmullw, // AVX/AVX2 + kX86InstIdVpmuludq, // AVX/AVX2 + kX86InstIdVpor, // AVX/AVX2 + kX86InstIdVpperm, // XOP + kX86InstIdVprotb, // XOP + kX86InstIdVprotd, // XOP + kX86InstIdVprotq, // XOP + kX86InstIdVprotw, // XOP + kX86InstIdVpsadbw, // AVX/AVX2 + kX86InstIdVpshab, // XOP + kX86InstIdVpshad, // XOP + kX86InstIdVpshaq, // XOP + kX86InstIdVpshaw, // XOP + kX86InstIdVpshlb, // XOP + kX86InstIdVpshld, // XOP + kX86InstIdVpshlq, // XOP + kX86InstIdVpshlw, // XOP + kX86InstIdVpshufb, // AVX/AVX2 + kX86InstIdVpshufd, // AVX/AVX2 + kX86InstIdVpshufhw, // AVX/AVX2 + kX86InstIdVpshuflw, // AVX/AVX2 + kX86InstIdVpsignb, // AVX/AVX2 + kX86InstIdVpsignd, // AVX/AVX2 + kX86InstIdVpsignw, // AVX/AVX2 + kX86InstIdVpslld, // AVX/AVX2 + kX86InstIdVpslldq, // AVX/AVX2 + kX86InstIdVpsllq, // AVX/AVX2 + kX86InstIdVpsllvd, // AVX2 + kX86InstIdVpsllvq, // AVX2 + kX86InstIdVpsllw, // AVX/AVX2 + kX86InstIdVpsrad, // AVX/AVX2 + kX86InstIdVpsravd, // AVX2 + kX86InstIdVpsraw, // AVX/AVX2 + kX86InstIdVpsrld, // AVX/AVX2 + kX86InstIdVpsrldq, // AVX/AVX2 + kX86InstIdVpsrlq, // AVX/AVX2 + kX86InstIdVpsrlvd, // AVX2 + kX86InstIdVpsrlvq, // AVX2 + kX86InstIdVpsrlw, // AVX/AVX2 + kX86InstIdVpsubb, // AVX/AVX2 + kX86InstIdVpsubd, // AVX/AVX2 + kX86InstIdVpsubq, // AVX/AVX2 + kX86InstIdVpsubsb, // AVX/AVX2 + kX86InstIdVpsubsw, // AVX/AVX2 + kX86InstIdVpsubusb, // AVX/AVX2 + kX86InstIdVpsubusw, // AVX/AVX2 + kX86InstIdVpsubw, // AVX/AVX2 + kX86InstIdVptest, // AVX + kX86InstIdVpunpckhbw, // AVX/AVX2 + kX86InstIdVpunpckhdq, // AVX/AVX2 + kX86InstIdVpunpckhqdq, // AVX/AVX2 + kX86InstIdVpunpckhwd, // AVX/AVX2 + kX86InstIdVpunpcklbw, // AVX/AVX2 + kX86InstIdVpunpckldq, // AVX/AVX2 + kX86InstIdVpunpcklqdq, // AVX/AVX2 + kX86InstIdVpunpcklwd, // AVX/AVX2 + kX86InstIdVpxor, // AVX/AVX2 + kX86InstIdVrcpps, // AVX + kX86InstIdVrcpss, // AVX + kX86InstIdVroundpd, // AVX + kX86InstIdVroundps, // AVX + kX86InstIdVroundsd, // AVX + kX86InstIdVroundss, // AVX + kX86InstIdVrsqrtps, // AVX + kX86InstIdVrsqrtss, // AVX + kX86InstIdVshufpd, // AVX + kX86InstIdVshufps, // AVX + kX86InstIdVsqrtpd, // AVX + kX86InstIdVsqrtps, // AVX + kX86InstIdVsqrtsd, // AVX + kX86InstIdVsqrtss, // AVX + kX86InstIdVstmxcsr, // AVX + kX86InstIdVsubpd, // AVX + kX86InstIdVsubps, // AVX + kX86InstIdVsubsd, // AVX + kX86InstIdVsubss, // AVX + kX86InstIdVtestpd, // AVX + kX86InstIdVtestps, // AVX + kX86InstIdVucomisd, // AVX + kX86InstIdVucomiss, // AVX + kX86InstIdVunpckhpd, // AVX + kX86InstIdVunpckhps, // AVX + kX86InstIdVunpcklpd, // AVX + kX86InstIdVunpcklps, // AVX + kX86InstIdVxorpd, // AVX + kX86InstIdVxorps, // AVX + kX86InstIdVzeroall, // AVX + kX86InstIdVzeroupper, // AVX + kX86InstIdWrfsbase, // FSGSBASE (x64) + kX86InstIdWrgsbase, // FSGSBASE (x64) + kX86InstIdXadd, // X86/X64 (i486) + kX86InstIdXchg, // X86/X64 (i386) + kX86InstIdXor, // X86/X64 + kX86InstIdXorpd, // SSE2 + kX86InstIdXorps, // SSE + + _kX86InstIdCount, + + _kX86InstIdCmovcc = kX86InstIdCmova, + _kX86InstIdJcc = kX86InstIdJa, + _kX86InstIdSetcc = kX86InstIdSeta, + + _kX86InstIdJbegin = kX86InstIdJa, + _kX86InstIdJend = kX86InstIdJmp +}; + +// ============================================================================ +// [asmjit::kX86InstOptions] +// ============================================================================ + +//! X86/X64 instruction emit options, mainly for internal purposes. +ASMJIT_ENUM(kX86InstOptions) { + //! Emit instruction with LOCK prefix. + //! + //! If this option is used and instruction doesn't support LOCK prefix an + //! invalid instruction error is generated. + kX86InstOptionLock = 0x10, + + //! Force REX prefix to be emitted. + //! + //! This option should be used carefully, because there are unencodable + //! combinations. If you want to access ah, bh, ch or dh registers the REX + //! prefix can't be emitted, otherwise illegal instruction error will be + //! returned. + kX86InstOptionRex = 0x40, + + //! Force three-byte VEX prefix to be emitted (instead of more compact + //! two-byte VEX prefix). + //! + //! Ignored if the instruction doesn't use VEX prefix. + kX86InstOptionVex3 = 0x80 +}; + +// ============================================================================ +// [asmjit::kX86InstGroup] +// ============================================================================ + +//! \internal +//! +//! X86/X64 instruction groups. +//! +//! This group is specific to AsmJit and only used by `X86Assembler`. +ASMJIT_ENUM(kX86InstGroup) { + //! Never used. + kX86InstGroupNone, + + kX86InstGroupX86Op, + kX86InstGroupX86Op_66H, + kX86InstGroupX86Rm, + kX86InstGroupX86Rm_B, + kX86InstGroupX86RmReg, + kX86InstGroupX86RegRm, + kX86InstGroupX86M, + //! Adc/Add/And/Cmp/Or/Sbb/Sub/Xor. + kX86InstGroupX86Arith, + //! Bswap. + kX86InstGroupX86BSwap, + //! Bt/Btc/Btr/Bts. + kX86InstGroupX86BTest, + //! Call. + kX86InstGroupX86Call, + //! Enter. + kX86InstGroupX86Enter, + //! Imul. + kX86InstGroupX86Imul, + //! Inc/Dec. + kX86InstGroupX86IncDec, + //! Int. + kX86InstGroupX86Int, + //! Jcc. + kX86InstGroupX86Jcc, + //! Jcxz/Jecxz/Jrcxz. + kX86InstGroupX86Jecxz, + //! Jmp. + kX86InstGroupX86Jmp, + //! Lea. + kX86InstGroupX86Lea, + //! Mov. + kX86InstGroupX86Mov, + //! Movsx/Movzx. + kX86InstGroupX86MovSxZx, + //! Movsxd. + kX86InstGroupX86MovSxd, + //! Mov having absolute memory operand (x86/x64). + kX86InstGroupX86MovPtr, + //! Push. + kX86InstGroupX86Push, + //! Pop. + kX86InstGroupX86Pop, + //! Rep/Repe/Repne LodsX/MovsX/StosX/CmpsX/ScasX. + kX86InstGroupX86Rep, + //! Ret. + kX86InstGroupX86Ret, + //! Rcl/Rcr/Rol/Ror/Sal/Sar/Shl/Shr. + kX86InstGroupX86Rot, + //! Setcc. + kX86InstGroupX86Set, + //! Shld/Rhrd. + kX86InstGroupX86Shlrd, + //! Test. + kX86InstGroupX86Test, + //! Xadd. + kX86InstGroupX86Xadd, + //! Xchg. + kX86InstGroupX86Xchg, + + //! Fincstp/Finit/FldX/Fnclex/Fninit/Fnop/Fpatan/Fprem/Fprem1/Fptan/Frndint/Fscale/Fsin/Fsincos/Fsqrt/Ftst/Fucompp/Fxam/Fxtract/Fyl2x/Fyl2xp1. + kX86InstGroupFpuOp, + //! Fadd/Fdiv/Fdivr/Fmul/Fsub/Fsubr. + kX86InstGroupFpuArith, + //! Fcom/Fcomp. + kX86InstGroupFpuCom, + //! Fld/Fst/Fstp. + kX86InstGroupFpuFldFst, + //! Fiadd/Ficom/Ficomp/Fidiv/Fidivr/Fild/Fimul/Fist/Fistp/Fisttp/Fisub/Fisubr. + kX86InstGroupFpuM, + //! Fcmov/Fcomi/Fcomip/Ffree/Fucom/Fucomi/Fucomip/Fucomp/Fxch. + kX86InstGroupFpuR, + //! Faddp/Fdivp/Fdivrp/Fmulp/Fsubp/Fsubrp. + kX86InstGroupFpuRDef, + //! Fnstsw/Fstsw. + kX86InstGroupFpuStsw, + + //! Mm/Xmm instruction. + kX86InstGroupExtRm, + //! Mm/Xmm instruction (propagates 66H if the instruction uses Xmm register). + kX86InstGroupExtRm_P, + //! Mm/Xmm instruction (propagates REX.W if GPQ is used). + kX86InstGroupExtRm_Q, + //! Mm/Xmm instruction (propagates 66H and REX.W). + kX86InstGroupExtRm_PQ, + //! Mm/Xmm instruction having Rm/Ri encodings. + kX86InstGroupExtRmRi, + //! Mm/Xmm instruction having Rm/Ri encodings (propagates 66H if the instruction uses Xmm register). + kX86InstGroupExtRmRi_P, + //! Mm/Xmm instruction having Rmi encoding. + kX86InstGroupExtRmi, + //! Mm/Xmm instruction having Rmi encoding (propagates 66H if the instruction uses Xmm register). + kX86InstGroupExtRmi_P, + //! Crc32. + kX86InstGroupExtCrc, + //! Pextrb/Pextrw/Pextrd/Pextrq/Extractps. + kX86InstGroupExtExtract, + //! Lfence/Mfence/Sfence. + kX86InstGroupExtFence, + //! Mov Mm/Xmm. + //! + //! 0x66 prefix must be set manually in opcodes. + //! + //! - Primary opcode is used for instructions in (X)Mm <- (X)Mm/X86Mem format, + //! - Secondary opcode is used for instructions in (X)Mm/X86Mem <- (X)Mm format. + kX86InstGroupExtMov, + //! Mov Mm/Xmm. + kX86InstGroupExtMovNoRexW, + //! Movbe. + kX86InstGroupExtMovBe, + //! Movd. + kX86InstGroupExtMovD, + //! Movq. + kX86InstGroupExtMovQ, + //! Prefetch. + kX86InstGroupExtPrefetch, + + //! 3dNow instruction. + kX86InstGroup3dNow, + + //! AVX instruction without operands. + kX86InstGroupAvxOp, + //! AVX instruction encoded as 'M'. + kX86InstGroupAvxM, + //! AVX instruction encoded as 'MR'. + kX86InstGroupAvxMr, + //! AVX instruction encoded as 'MR' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxMr_P, + //! AVX instruction encoded as 'MRI'. + kX86InstGroupAvxMri, + //! AVX instruction encoded as 'MRI' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxMri_P, + //! AVX instruction encoded as 'RM'. + kX86InstGroupAvxRm, + //! AVX instruction encoded as 'RM' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRm_P, + //! AVX instruction encoded as 'RMI'. + kX86InstGroupAvxRmi, + //! AVX instruction encoded as 'RMI' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRmi_P, + //! AVX instruction encoded as 'RVM'. + kX86InstGroupAvxRvm, + //! AVX instruction encoded as 'RVM' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRvm_P, + //! AVX instruction encoded as 'RVMR'. + kX86InstGroupAvxRvmr, + //! AVX instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRvmr_P, + //! AVX instruction encoded as 'RVMI'. + kX86InstGroupAvxRvmi, + //! AVX instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRvmi_P, + //! AVX instruction encoded as 'RMV'. + kX86InstGroupAvxRmv, + //! AVX instruction encoded as 'RMVI'. + kX86InstGroupAvxRmvi, + //! AVX instruction encoded as 'RM' or 'MR'. + kX86InstGroupAvxRmMr, + //! AVX instruction encoded as 'RM' or 'MR' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRmMr_P, + //! AVX instruction encoded as 'RVM' or 'RMI'. + kX86InstGroupAvxRvmRmi, + //! AVX instruction encoded as 'RVM' or 'RMI' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRvmRmi_P, + //! AVX instruction encoded as 'RVM' or 'MR'. + kX86InstGroupAvxRvmMr, + //! AVX instruction encoded as 'RVM' or 'MVR'. + kX86InstGroupAvxRvmMvr, + //! AVX instruction encoded as 'RVM' or 'MVR' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRvmMvr_P, + //! AVX instruction encoded as 'RVM' or 'VMI'. + kX86InstGroupAvxRvmVmi, + //! AVX instruction encoded as 'RVM' or 'VMI' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRvmVmi_P, + //! AVX instruction encoded as 'VM'. + kX86InstGroupAvxVm, + //! AVX instruction encoded as 'VMI'. + kX86InstGroupAvxVmi, + //! AVX instruction encoded as 'VMI' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxVmi_P, + //! AVX instruction encoded as 'RVRM' or 'RVMR'. + kX86InstGroupAvxRvrmRvmr, + //! AVX instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstGroupAvxRvrmRvmr_P, + //! Vmovss/Vmovsd. + kX86InstGroupAvxMovSsSd, + //! AVX2 gather family instructions (VSIB). + kX86InstGroupAvxGather, + //! AVX2 gather family instructions (VSIB), differs only in mem operand. + kX86InstGroupAvxGatherEx, + + //! FMA4 instruction in form [R, R, R/M, R/M]. + kX86InstGroupFma4, + //! FMA4 instruction in form [R, R, R/M, R/M] (Propagates AVX.L if Ymm used). + kX86InstGroupFma4_P, + + //! XOP instruction encoded as 'RM'. + kX86InstGroupXopRm, + //! XOP instruction encoded as 'RM' (Propagates AVX.L if Ymm used). + kX86InstGroupXopRm_P, + //! XOP instruction encoded as 'RVM' or 'RMV'. + kX86InstGroupXopRvmRmv, + //! XOP instruction encoded as 'RVM' or 'RMI'. + kX86InstGroupXopRvmRmi, + //! XOP instruction encoded as 'RVMR'. + kX86InstGroupXopRvmr, + //! XOP instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstGroupXopRvmr_P, + //! XOP instruction encoded as 'RVMI'. + kX86InstGroupXopRvmi, + //! XOP instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). + kX86InstGroupXopRvmi_P, + //! XOP instruction encoded as 'RVRM' or 'RVMR'. + kX86InstGroupXopRvrmRvmr, + //! XOP instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). + kX86InstGroupXopRvrmRvmr_P, + + //! Count of X86 instruction groups. + _kX86InstGroupCount +}; + +// ============================================================================ +// [asmjit::kX86InstOpCode] +// ============================================================================ + +//! \internal +//! +//! Instruction OpCode encoding used by asmjit 'X86InstInfo' table. +//! +//! The schema was inspired by AVX/AVX2 features. +ASMJIT_ENUM(kX86InstOpCode) { + // 'MMMMM' field in AVX/XOP instruction. + // 'OpCode' leading bytes in legacy encoding. + kX86InstOpCode_MM_Shift = 16, + kX86InstOpCode_MM_Mask = 0x0FU << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_00 = 0x00U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F = 0x01U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F38 = 0x02U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F3A = 0x03U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // Ext/Not part of AVX. + + kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift, + + // 'PP' field in AVX/XOP instruction. + // 'Mandatory Prefix' in legacy encoding. + kX86InstOpCode_PP_Shift = 21, + kX86InstOpCode_PP_Mask = 0x07U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_00 = 0x00U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_66 = 0x01U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_F3 = 0x02U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_F2 = 0x03U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_9B = 0x07U << kX86InstOpCode_PP_Shift, // Ext/Not part of AVX. + + // 'L' field in AVX/XOP instruction. + kX86InstOpCode_L_Shift = 24, + kX86InstOpCode_L_Mask = 0x01U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_False = 0x00U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_True = 0x01U << kX86InstOpCode_L_Shift, + + // 'O' field. + kX86InstOpCode_O_Shift = 29, + kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_Shift +}; + +// ============================================================================ +// [asmjit::kX86InstFlags] +// ============================================================================ + +//! \internal +//! +//! X86/X64 instruction type flags. +ASMJIT_ENUM(kX86InstFlags) { + //! No flags. + kX86InstFlagNone = 0x0000, + + //! Instruction is a control-flow instruction. + //! + //! Control flow instructions are jmp, jcc, call and ret. + kX86InstFlagFlow = 0x0001, + + //! Instruction is a compare/test like instruction. + kX86InstFlagTest = 0x0002, + + //! Instruction is a move like instruction. + //! + //! Move instructions typically overwrite the first operand by the second + //! operand. The first operand can be the exact copy of the second operand + //! or it can be any kind of conversion or shuffling. + //! + //! Mov instructions are 'mov', 'movd', 'movq', movdq', 'lea', multimedia + //! instructions like 'cvtdq2pd', shuffle instructions like 'pshufb' and + //! SSE/SSE2 mathematic instructions like 'rcp?', 'round?' and 'rsqrt?'. + //! + //! There are some MOV instructions that do only a partial move (for example + //! 'cvtsi2ss'), register allocator has to know the variable size and use + //! the flag accordingly to it. + kX86InstFlagMove = 0x0004, + + //! Instruction is an exchange like instruction. + //! + //! Exchange instruction typically overwrite first and second operand. So + //! far only the instructions 'xchg' and 'xadd' are considered. + kX86InstFlagXchg = 0x0008, + + //! Instruction accesses Fp register(s). + kX86InstFlagFp = 0x0010, + + //! Instruction can be prefixed by using the LOCK prefix. + kX86InstFlagLock = 0x0020, + + //! Instruction is special, this is for `Compiler`. + kX86InstFlagSpecial = 0x0040, + + //! Instruction always performs memory access. + //! + //! This flag is always combined with `kX86InstFlagSpecial` and signalizes + //! that there is an implicit address which is accessed (usually EDI/RDI or + //! ESI/EDI). + kX86InstFlagSpecialMem = 0x0080, + + //! Instruction memory operand can refer to 16-bit address (used by FPU). + kX86InstFlagMem2 = 0x0100, + //! Instruction memory operand can refer to 32-bit address (used by FPU). + kX86InstFlagMem4 = 0x0200, + //! Instruction memory operand can refer to 64-bit address (used by FPU). + kX86InstFlagMem8 = 0x0400, + //! Instruction memory operand can refer to 80-bit address (used by FPU). + kX86InstFlagMem10 = 0x0800, + + //! \internal + //! + //! Combination of `kX86InstFlagMem2` and `kX86InstFlagMem4`. + kX86InstFlagMem2_4 = kX86InstFlagMem2 | kX86InstFlagMem4, + + //! \internal + //! + //! Combination of `kX86InstFlagMem2`, `kX86InstFlagMem4` and `kX86InstFlagMem8`. + kX86InstFlagMem2_4_8 = kX86InstFlagMem2_4 | kX86InstFlagMem8, + + //! \internal + //! + //! Combination of `kX86InstFlagMem4` and `kX86InstFlagMem8`. + kX86InstFlagMem4_8 = kX86InstFlagMem4 | kX86InstFlagMem8, + + //! \internal + //! + //! Combination of `kX86InstFlagMem4`, `kX86InstFlagMem8` and `kX86InstFlagMem10`. + kX86InstFlagMem4_8_10 = kX86InstFlagMem4_8 | kX86InstFlagMem10, + + //! Zeroes the rest of the register if the source operand is memory. + //! + //! Special behavior related to some SIMD load instructions. + kX86InstFlagZ = 0x1000, + + //! REX.W/VEX.W by default. + kX86InstFlagW = 0x8000 +}; + +// ============================================================================ +// [asmjit::kX86InstOp] +// ============================================================================ + +//! \internal +//! +//! X86/X64 instruction operand flags. +ASMJIT_ENUM(kX86InstOp) { + //! Instruction operand can be 8-bit Gpb register. + kX86InstOpGb = 0x0001, + //! Instruction operand can be 16-bit Gpw register. + kX86InstOpGw = 0x0002, + //! Instruction operand can be 32-bit Gpd register. + kX86InstOpGd = 0x0004, + //! Instruction operand can be 64-bit Gpq register. + kX86InstOpGq = 0x0008, + //! Instruction operand can be Fp register. + kX86InstOpFp = 0x0010, + //! Instruction operand can be 64-bit Mmx register. + kX86InstOpMm = 0x0020, + //! Instruction operand can be 128-bit Xmm register. + kX86InstOpXmm = 0x0100, + //! Instruction operand can be 256-bit Ymm register. + kX86InstOpYmm = 0x0200, + //! Instruction operand can be 512-bit Zmm register. + kX86InstOpZmm = 0x0400, + + //! Instruction operand can be memory. + kX86InstOpMem = 0x2000, + //! Instruction operand can be immediate. + kX86InstOpImm = 0x4000, + //! Instruction operand can be label. + kX86InstOpLabel = 0x8000, + + //! \internal + //! + //! Combined flags. + //! + //! \{ + + kX86InstOpGwb = kX86InstOpGw | kX86InstOpGb, + kX86InstOpGqd = kX86InstOpGq | kX86InstOpGd, + kX86InstOpGqdw = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw, + kX86InstOpGqdwb = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb, + + kX86InstOpGbMem = kX86InstOpGb | kX86InstOpMem, + kX86InstOpGwMem = kX86InstOpGw | kX86InstOpMem, + kX86InstOpGdMem = kX86InstOpGd | kX86InstOpMem, + kX86InstOpGqMem = kX86InstOpGq | kX86InstOpMem, + kX86InstOpGwbMem = kX86InstOpGwb | kX86InstOpMem, + kX86InstOpGqdMem = kX86InstOpGqd | kX86InstOpMem, + kX86InstOpGqdwMem = kX86InstOpGqdw | kX86InstOpMem, + kX86InstOpGqdwbMem = kX86InstOpGqdwb | kX86InstOpMem, + + kX86InstOpFpMem = kX86InstOpFp | kX86InstOpMem, + kX86InstOpMmMem = kX86InstOpMm | kX86InstOpMem, + kX86InstOpXmmMem = kX86InstOpXmm | kX86InstOpMem, + kX86InstOpYmmMem = kX86InstOpYmm | kX86InstOpMem, + + kX86InstOpMmXmm = kX86InstOpMm | kX86InstOpXmm, + kX86InstOpMmXmmMem = kX86InstOpMmXmm | kX86InstOpMem, + + kX86InstOpXmmYmm = kX86InstOpXmm | kX86InstOpYmm, + kX86InstOpXmmYmmMem = kX86InstOpXmmYmm | kX86InstOpMem + + //! \} +}; + +// ============================================================================ +// [asmjit::kX86Cond] +// ============================================================================ + +//! X86/X64 Condition codes. +ASMJIT_ENUM(kX86Cond) { + kX86CondA = 0x07, // CF==0 & ZF==0 (unsigned) + kX86CondAE = 0x03, // CF==0 (unsigned) + kX86CondB = 0x02, // CF==1 (unsigned) + kX86CondBE = 0x06, // CF==1 | ZF==1 (unsigned) + kX86CondC = 0x02, // CF==1 + kX86CondE = 0x04, // ZF==1 (signed/unsigned) + kX86CondG = 0x0F, // ZF==0 & SF==OF (signed) + kX86CondGE = 0x0D, // SF==OF (signed) + kX86CondL = 0x0C, // SF!=OF (signed) + kX86CondLE = 0x0E, // ZF==1 | SF!=OF (signed) + kX86CondNA = 0x06, // CF==1 | ZF==1 (unsigned) + kX86CondNAE = 0x02, // CF==1 (unsigned) + kX86CondNB = 0x03, // CF==0 (unsigned) + kX86CondNBE = 0x07, // CF==0 & ZF==0 (unsigned) + kX86CondNC = 0x03, // CF==0 + kX86CondNE = 0x05, // ZF==0 (signed/unsigned) + kX86CondNG = 0x0E, // ZF==1 | SF!=OF (signed) + kX86CondNGE = 0x0C, // SF!=OF (signed) + kX86CondNL = 0x0D, // SF==OF (signed) + kX86CondNLE = 0x0F, // ZF==0 & SF==OF (signed) + kX86CondNO = 0x01, // OF==0 + kX86CondNP = 0x0B, // PF==0 + kX86CondNS = 0x09, // SF==0 + kX86CondNZ = 0x05, // ZF==0 + kX86CondO = 0x00, // OF==1 + kX86CondP = 0x0A, // PF==1 + kX86CondPE = 0x0A, // PF==1 + kX86CondPO = 0x0B, // PF==0 + kX86CondS = 0x08, // SF==1 + kX86CondZ = 0x04, // ZF==1 + + // Simplified condition codes. + kX86CondOverflow = 0x00, + kX86CondNotOverflow = 0x01, + kX86CondBelow = 0x02, //!< Unsigned comparison. + kX86CondAboveEqual = 0x03, //!< Unsigned comparison. + kX86CondEqual = 0x04, + kX86CondNotEqual = 0x05, + kX86CondBelowEqual = 0x06, //!< Unsigned comparison. + kX86CondAbove = 0x07, //!< Unsigned comparison. + kX86CondSign = 0x08, + kX86CondNotSign = 0x09, + kX86CondParityEven = 0x0A, + kX86CondParityOdd = 0x0B, + kX86CondLess = 0x0C, //!< Signed comparison. + kX86CondGreaterEqual = 0x0D, //!< Signed comparison. + kX86CondLessEqual = 0x0E, //!< Signed comparison. + kX86CondGreater = 0x0F, //!< Signed comparison. + + // Aliases. + kX86CondZero = 0x04, + kX86CondNotZero = 0x05, + kX86CondNegative = 0x08, + kX86CondPositive = 0x09, + + // Fpu-only. + kX86CondFpuUnordered = 0x10, + kX86CondFpuNotUnordered = 0x11, + + //! No condition code. + kX86CondNone = 0x12 +}; + +// ============================================================================ +// [asmjit::kX86EFlags] +// ============================================================================ + +//! X86/X64 EFLAGs bits (AsmJit specific). +//! +//! Each instruction stored in AsmJit database contains flags that instruction +//! uses (reads) and flags that instruction modifies (writes). This is used by +//! instruction reordering, but can be used by third parties as the API and +//! definitions are public. +//! +//! \note Flags defined here doesn't correspond to real flags used by X86/X64 +//! architecture defined in Intel's Manual Section `3.4.3 - EFLAGS Register`. +//! +//! \note Flags are designed to fit in 8-bit integer. +ASMJIT_ENUM(kX86EFlags) { + // -------------------------------------------------------------------------- + // src-gendefs.js relies on the values of these masks, to modify them the + // tool has to be changed as well. + // -------------------------------------------------------------------------- + + //! Overflow flag (OF). + //! + //! Set if the integer result is too large a positive number or too small a + //! negative number (excluding the sign-bit) to fit in the destination + //! operand; cleared otherwise. This flag indicates an overflow condition for + //! signed-integer arithmetic. + kX86EFlagO = 0x01, + + //! Sign flag (SF). + //! + //! Set equal to the most-significant bit of the result, which is the sign + //! bit of a signed integer (0 == positive value, 1 == negative value). + kX86EFlagS = 0x02, + + //! Zero flag (ZF). + //! + //! Set if the result is zero; cleared otherwise. + kX86EFlagZ = 0x04, + + //! Adjust flag (AF). + //! + //! Set if an arithmetic operation generates a carry or a borrow out of bit + //! 3 of the result; cleared otherwise. This flag is used in binary-coded + //! decimal (BCD) arithmetic. + kX86EFlagA = 0x08, + + //! Parity flag (PF). + //! + //! Set if the least-significant byte of the result contains an even number + //! of 1 bits; cleared otherwise. + kX86EFlagP = 0x10, + + //! Carry flag (CF). + //! + //! Set if an arithmetic operation generates a carry or a borrow out of the + //! mostsignificant bit of the result; cleared otherwise. + kX86EFlagC = 0x20, + + //! Direction flag (DF). + //! + //! The direction flag controls string instructions `movs`, `cmps`, `scas, + //! `lods` and `stos`. + kX86EFlagD = 0x40, + + //! Any other flag that AsmJit doesn't use to keep track of it. + kX86EFlagX = 0x80 +}; + +// ============================================================================ +// [asmjit::kX86FpSw] +// ============================================================================ + +//! X86/X64 FPU status Word. +ASMJIT_ENUM(kX86FpSw) { + kX86FpSw_Invalid = 0x0001, + kX86FpSw_Denormalized = 0x0002, + kX86FpSw_DivByZero = 0x0004, + kX86FpSw_Overflow = 0x0008, + kX86FpSw_Underflow = 0x0010, + kX86FpSw_Precision = 0x0020, + kX86FpSw_StackFault = 0x0040, + kX86FpSw_Interrupt = 0x0080, + kX86FpSw_C0 = 0x0100, + kX86FpSw_C1 = 0x0200, + kX86FpSw_C2 = 0x0400, + kX86FpSw_Top = 0x3800, + kX86FpSw_C3 = 0x4000, + kX86FpSw_Busy = 0x8000 +}; + +// ============================================================================ +// [asmjit::kX86FpCw] +// ============================================================================ + +//! X86/X64 FPU control Word. +ASMJIT_ENUM(kX86FpCw) { + kX86FpCw_EM_Mask = 0x003F, // Bits 0-5. + kX86FpCw_EM_Invalid = 0x0001, + kX86FpCw_EM_Denormal = 0x0002, + kX86FpCw_EM_DivByZero = 0x0004, + kX86FpCw_EM_Overflow = 0x0008, + kX86FpCw_EM_Underflow = 0x0010, + kX86FpCw_EM_Inexact = 0x0020, + + kX86FpCw_PC_Mask = 0x0300, // Bits 8-9. + kX86FpCw_PC_Float = 0x0000, + kX86FpCw_PC_Reserved = 0x0100, + kX86FpCw_PC_Double = 0x0200, + kX86FpCw_PC_Extended = 0x0300, + + kX86FpCw_RC_Mask = 0x0C00, // Bits 10-11. + kX86FpCw_RC_Nearest = 0x0000, + kX86FpCw_RC_Down = 0x0400, + kX86FpCw_RC_Up = 0x0800, + kX86FpCw_RC_Truncate = 0x0C00, + + kX86FpCw_IC_Mask = 0x1000, // Bit 12. + kX86FpCw_IC_Projective = 0x0000, + kX86FpCw_IC_Affine = 0x1000 +}; + +// ============================================================================ +// [asmjit::kX86Prefetch] +// ============================================================================ + +//! X86/X64 Prefetch hints. +ASMJIT_ENUM(kX86Prefetch) { + //! Prefetch using NT hint. + kX86PrefetchNta = 0, + //! Prefetch to L0 cache. + kX86PrefetchT0 = 1, + //! Prefetch to L1 cache. + kX86PrefetchT1 = 2, + //! Prefetch to L2 cache. + kX86PrefetchT2 = 3 +}; + +// ============================================================================ +// [asmjit::X86InstExtendedInfo] +// ============================================================================ + +//! X86/X64 instruction extended information. +//! +//! Extended information has been introduced to minimize data needed for a +//! single instruction, because two or more instructions can share the common +//! data, for example operands definition or secondary opcode, which is only +//! used by few instructions. +struct X86InstExtendedInfo { + // -------------------------------------------------------------------------- + // [Accessors - InstGroup] + // -------------------------------------------------------------------------- + + //! Get instruction group, see \ref kX86InstGroup. + ASMJIT_INLINE uint32_t getInstGroup() const { + return _instGroup; + } + + // -------------------------------------------------------------------------- + // [Accessors - InstFlags] + // -------------------------------------------------------------------------- + + //! Get whether the instruction has flag `flag`, see `kX86InstFlags`. + ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const { + return (_instFlags & flag) != 0; + } + + //! Get instruction flags, see `kX86InstFlags`. + ASMJIT_INLINE uint32_t getInstFlags() const { + return _instFlags; + } + + //! Get whether the instruction is a control-flow intruction. + //! + //! Control flow instruction is instruction that modifies instruction pointer, + //! typically jmp, jcc, call, or ret. + ASMJIT_INLINE bool isFlow() const { + return (getInstFlags() & kX86InstFlagFlow) != 0; + } + + //! Get whether the instruction is a compare/test like intruction. + ASMJIT_INLINE bool isTest() const { + return (getInstFlags() & kX86InstFlagTest) != 0; + } + + //! Get whether the instruction is a typical move instruction. + //! + //! Move instructions overwrite the first operand or at least part of it, + //! This is a very useful hint that is used by variable liveness analysis + //! and `Compiler` in general to know which variable is completely + //! overwritten. + //! + //! All AVX/XOP instructions that have 3 or more operands are considered to + //! have move semantics move by default. + ASMJIT_INLINE bool isMove() const { + return (getInstFlags() & kX86InstFlagMove) != 0; + } + + //! Get whether the instruction is a typical Exchange instruction. + //! + //! Exchange instructios are 'xchg' and 'xadd'. + ASMJIT_INLINE bool isXchg() const { + return (getInstFlags() & kX86InstFlagXchg) != 0; + } + + //! Get whether the instruction accesses Fp register(s). + ASMJIT_INLINE bool isFp() const { + return (getInstFlags() & kX86InstFlagFp) != 0; + } + + //! Get whether the instruction can be prefixed by LOCK prefix. + ASMJIT_INLINE bool isLockable() const { + return (getInstFlags() & kX86InstFlagLock) != 0; + } + + //! Get whether the instruction is special type (this is used by + //! `Compiler` to manage additional variables or functionality). + ASMJIT_INLINE bool isSpecial() const { + return (getInstFlags() & kX86InstFlagSpecial) != 0; + } + + //! Get whether the instruction is special type and it performs + //! memory access. + ASMJIT_INLINE bool isSpecialMem() const { + return (getInstFlags() & kX86InstFlagSpecialMem) != 0; + } + + //! Get whether the move instruction zeroes the rest of the register + //! if the source is memory operand. + //! + //! Basically flag needed only to support `movsd` and `movss` instructions. + ASMJIT_INLINE bool isZeroIfMem() const { + return (getInstFlags() & kX86InstFlagZ) != 0; + } + + // -------------------------------------------------------------------------- + // [Accessors - EFlags] + // -------------------------------------------------------------------------- + + //! Get EFLAGS that the instruction reads. + ASMJIT_INLINE uint32_t getEFlagsIn() const { + return _eflagsIn; + } + + //! Get EFLAGS that the instruction writes. + ASMJIT_INLINE uint32_t getEFlagsOut() const { + return _eflagsOut; + } + + // -------------------------------------------------------------------------- + // [Accessors - Move-Size] + // -------------------------------------------------------------------------- + + //! Get size of move instruction in bytes. + //! + //! See \ref X86InstInfo::getMoveSize() for more details. + ASMJIT_INLINE uint32_t getMoveSize() const { + return _moveSize; + } + + // -------------------------------------------------------------------------- + // [Accessors - Operand-Flags] + // -------------------------------------------------------------------------- + + //! Get flags of operand at index `index`. + //! + //! See \ref X86InstInfo::getOperandFlags() for more details. + ASMJIT_INLINE uint16_t getOperandFlags(uint32_t index) const { + ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_opFlags)); + return _opFlags[index]; + } + + // -------------------------------------------------------------------------- + // [Accessors - OpCode] + // -------------------------------------------------------------------------- + + //! Get the secondary instruction opcode, see \ref kX86InstOpCode. + //! + //! See \ref X86InstInfo::getSecondaryOpCode() for more details. + ASMJIT_INLINE uint32_t getSecondaryOpCode() const { + return _secondaryOpCode; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Instruction group. + uint8_t _instGroup; + + //! Count of bytes overwritten by a move instruction. + //! + //! Only used with `kX86InstFlagMove` flag. If this value is zero move depends + //! on size of the destination register. + uint8_t _moveSize; + + //! EFlags read by the instruction. + uint8_t _eflagsIn; + //! EFlags modified by the instruction. + uint8_t _eflagsOut; + + //! Instruction flags. + uint16_t _instFlags; + + //! Operands' flags. + uint16_t _opFlags[5]; + + //! Secondary opcode. + uint32_t _secondaryOpCode; +}; + +// ============================================================================ +// [asmjit::X86InstInfo] +// ============================================================================ + +//! X86/X64 instruction information. +struct X86InstInfo { + // -------------------------------------------------------------------------- + // [Accessors - Instruction Name] + // -------------------------------------------------------------------------- + +#if !defined(ASMJIT_DISABLE_NAMES) + //! Get instruction name string (null terminated). + ASMJIT_INLINE const char* getInstName() const { + return _x86InstName + static_cast(_nameIndex); + } + + //! Get instruction name index to `_x86InstName` array. + ASMJIT_INLINE uint32_t _getNameIndex() const { + return _nameIndex; + } +#endif // !ASMJIT_DISABLE_NAMES + + // -------------------------------------------------------------------------- + // [Accessors - Extended-Info] + // -------------------------------------------------------------------------- + + //! Get `X86InstExtendedInfo` for this instruction. + ASMJIT_INLINE const X86InstExtendedInfo& getExtendedInfo() const { + return _x86InstExtendedInfo[_extendedIndex]; + } + + //! Get index to the `_x86InstExtendedInfo` table. + ASMJIT_INLINE uint32_t _getExtendedIndex() const { + return _extendedIndex; + } + + // -------------------------------------------------------------------------- + // [Accessors - Group] + // -------------------------------------------------------------------------- + + //! Get instruction group, see \ref kX86InstGroup. + ASMJIT_INLINE uint32_t getInstGroup() const { + return getExtendedInfo().getInstGroup(); + } + + // -------------------------------------------------------------------------- + // [Accessors - Flags] + // -------------------------------------------------------------------------- + + //! Get instruction flags, see `kX86InstFlags`. + ASMJIT_INLINE uint32_t getInstFlags() const { + return getExtendedInfo().getInstFlags(); + } + + //! Get whether the instruction has flag `flag`, see `kX86InstFlags`. + ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const { + return (getInstFlags() & flag) != 0; + } + + // -------------------------------------------------------------------------- + // [Accessors - Move-Size] + // -------------------------------------------------------------------------- + + //! Get size of move instruction in bytes. + //! + //! If zero, the size of MOV instruction is determined by the size of the + //! destination register (applies mostly for x86 arithmetic). This value is + //! useful for register allocator when determining if a variable is going to + //! be overwritten or not. Basically if the move size is equal or greater + //! than a variable itself it is considered overwritten. + ASMJIT_INLINE uint32_t getMoveSize() const { + return getExtendedInfo().getMoveSize(); + } + + // -------------------------------------------------------------------------- + // [Accessors - Operand-Flags] + // -------------------------------------------------------------------------- + + //! Get flags of operand at index `index`. + ASMJIT_INLINE uint32_t getOperandFlags(uint32_t index) const { + return getExtendedInfo().getOperandFlags(index); + } + + // -------------------------------------------------------------------------- + // [Accessors - OpCode] + // -------------------------------------------------------------------------- + + //! Get the primary instruction opcode, see \ref kX86InstOpCode. + ASMJIT_INLINE uint32_t getPrimaryOpCode() const { + return _primaryOpCode; + } + + //! Get the secondary instruction opcode, see \ref kX86InstOpCode. + ASMJIT_INLINE uint32_t getSecondaryOpCode() const { + return getExtendedInfo().getSecondaryOpCode(); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Instruction name index in `_x86InstName[]` array. + uint16_t _nameIndex; + //! Extended information name index in `_x86InstExtendedInfo[]` array. + uint16_t _extendedIndex; + + //! Primary opcode, secondary opcode is stored in `X86InstExtendedInfo` table. + uint32_t _primaryOpCode; +}; + +// ============================================================================ +// [asmjit::X86Util] +// ============================================================================ + +struct X86Util { + // -------------------------------------------------------------------------- + // [Instruction Info] + // -------------------------------------------------------------------------- + + //! Get instruction information based on `instId`. + //! + //! \note `instId` has to be valid instruction ID, it can't be greater than + //! or equal to `_kX86InstIdCount`. It asserts in debug mode. + static ASMJIT_INLINE const X86InstInfo& getInstInfo(uint32_t instId) { + ASMJIT_ASSERT(instId < _kX86InstIdCount); + return _x86InstInfo[instId]; + } + +#if !defined(ASMJIT_DISABLE_NAMES) + //! Get an instruction ID from a given instruction `name`. + //! + //! If there is an exact match the instruction id is returned, otherwise + //! `kInstIdNone` (zero) is returned. + //! + //! The given `name` doesn't have to be null-terminated if `len` is provided. + ASMJIT_API static uint32_t getInstIdByName( + const char* name, size_t len = kInvalidIndex); +#endif // !ASMJIT_DISABLE_NAMES + + // -------------------------------------------------------------------------- + // [Condition Codes] + // -------------------------------------------------------------------------- + + //! Corresponds to transposing the operands of a comparison. + static ASMJIT_INLINE uint32_t reverseCond(uint32_t cond) { + ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond)); + return _x86ReverseCond[cond]; + } + + //! Get the equivalent of negated condition code. + static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) { + ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond)); + return static_cast(cond ^ static_cast(cond < kX86CondNone)); + } + + //! Translate condition code `cc` to `cmovcc` instruction code. + //! \sa \ref kX86InstId, \ref _kX86InstIdCmovcc. + static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) { + ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToCmovcc)); + return _x86CondToCmovcc[cond]; + } + + //! Translate condition code `cc` to `jcc` instruction code. + //! \sa \ref kX86InstId, \ref _kX86InstIdJcc. + static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) { + ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToJcc)); + return _x86CondToJcc[cond]; + } + + //! Translate condition code `cc` to `setcc` instruction code. + //! \sa \ref kX86InstId, \ref _kX86InstIdSetcc. + static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) { + ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToSetcc)); + return _x86CondToSetcc[cond]; + } + + // -------------------------------------------------------------------------- + // [MmShuffle] + // -------------------------------------------------------------------------- + + //! Pack a shuffle constant to be used with multimedia instrutions (2 values). + //! + //! \param x First component position, number at interval [0, 1] inclusive. + //! \param y Second component position, number at interval [0, 1] inclusive. + //! + //! Shuffle constants can be used to make immediate value for these intrinsics: + //! - `X86Assembler::shufpd()` and `X86Compiler::shufpd()` + static ASMJIT_INLINE int mmShuffle(uint32_t x, uint32_t y) { + return static_cast((x << 1) | y); + } + + //! Pack a shuffle constant to be used with multimedia instrutions (4 values). + //! + //! \param z First component position, number at interval [0, 3] inclusive. + //! \param x Second component position, number at interval [0, 3] inclusive. + //! \param y Third component position, number at interval [0, 3] inclusive. + //! \param w Fourth component position, number at interval [0, 3] inclusive. + //! + //! Shuffle constants can be used to make immediate value for these intrinsics: + //! - `X86Assembler::pshufw()` and `X86Compiler::pshufw()` + //! - `X86Assembler::pshufd()` and `X86Compiler::pshufd()` + //! - `X86Assembler::pshufhw()` and `X86Compiler::pshufhw()` + //! - `X86Assembler::pshuflw()` and `X86Compiler::pshuflw()` + //! - `X86Assembler::shufps()` and `X86Compiler::shufps()` + static ASMJIT_INLINE int mmShuffle(uint32_t z, uint32_t y, uint32_t x, uint32_t w) { + return static_cast((z << 6) | (y << 4) | (x << 2) | w); + } +}; + +//! \} + +} // asmjit namespace + +#undef _OP_ID + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86INST_H diff --git a/libraries/asmjit/x86/x86operand.cpp b/libraries/asmjit/x86/x86operand.cpp new file mode 100644 index 000000000..7e300ee94 --- /dev/null +++ b/libraries/asmjit/x86/x86operand.cpp @@ -0,0 +1,85 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) + +// [Dependencies - AsmJit] +#include "../x86/x86operand.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { +namespace x86 { + +// ============================================================================ +// [asmjit::X86Mem - abs[]] +// ============================================================================ + +X86Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) { + X86Mem m(NoInit); + + m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, 0, kInvalidValue); + m._vmem.index = kInvalidValue; + m._vmem.displacement = static_cast((intptr_t)(pAbs + disp)); + + return m; +} + +X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_t size) { + X86Mem m(NoInit); + uint32_t flags = shift << kX86MemShiftIndex; + + if (index.isGp()) + flags |= X86Mem::_getGpdFlags(index); + else if (index.isXmm()) + flags |= kX86MemVSibXmm << kX86MemVSibIndex; + else if (index.isYmm()) + flags |= kX86MemVSibYmm << kX86MemVSibIndex; + + m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue); + m._vmem.index = index.getRegIndex(); + m._vmem.displacement = static_cast((intptr_t)(pAbs + disp)); + + return m; +} + +#if !defined(ASMJIT_DISABLE_COMPILER) +X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift, int32_t disp, uint32_t size) { + X86Mem m(NoInit); + uint32_t flags = shift << kX86MemShiftIndex; + + const Var& index_ = reinterpret_cast(index); + uint32_t indexRegType = index_.getRegType(); + + if (indexRegType <= kX86RegTypeGpq) + flags |= X86Mem::_getGpdFlags(reinterpret_cast(index)); + else if (indexRegType == kX86RegTypeXmm) + flags |= kX86MemVSibXmm << kX86MemVSibIndex; + else if (indexRegType == kX86RegTypeYmm) + flags |= kX86MemVSibYmm << kX86MemVSibIndex; + + m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue); + m._vmem.index = index_.getId(); + m._vmem.displacement = static_cast((intptr_t)(pAbs + disp)); + + return m; +} +#endif // !ASMJIT_DISABLE_COMPILER + +} // x86 namespace +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/libraries/asmjit/x86/x86operand.h b/libraries/asmjit/x86/x86operand.h new file mode 100644 index 000000000..f40ab12fa --- /dev/null +++ b/libraries/asmjit/x86/x86operand.h @@ -0,0 +1,1531 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86OPERAND_H +#define _ASMJIT_X86_X86OPERAND_H + +// [Dependencies - AsmJit] +#include "../base/assembler.h" +#include "../base/compiler.h" +#include "../base/globals.h" +#include "../base/intutil.h" +#include "../base/operand.h" +#include "../base/vectypes.h" + +// [Api-Begin] +#include "../apibegin.h" + +//! \internal +//! +//! Internal macro to get an operand ID casting it to `Operand`. Basically +//! allows to get an id of operand that has been just 'typedef'ed. +#define _OP_ID(_Op_) reinterpret_cast(_Op_).getId() + +namespace asmjit { + +// ============================================================================ +// [Forward Declarations] +// ============================================================================ + +struct X86Reg; +struct X86GpReg; +struct X86FpReg; +struct X86MmReg; +struct X86XmmReg; +struct X86YmmReg; +struct X86SegReg; + +#if !defined(ASMJIT_DISABLE_COMPILER) +struct X86Var; +struct X86GpVar; +struct X86MmVar; +struct X86XmmVar; +struct X86YmmVar; +#endif // !ASMJIT_DISABLE_COMPILER + +//! \addtogroup asmjit_x86_general +//! \{ + +// ============================================================================ +// [asmjit::kX86RegClass] +// ============================================================================ + +//! X86/X64 variable class. +ASMJIT_ENUM(kX86RegClass) { + //! X86/X64 Gp register class (compatible with universal \ref kRegClassGp). + kX86RegClassGp = kRegClassGp, + //! X86/X64 Fp register class. + kX86RegClassFp = 1, + //! X86/X64 Mm register class. + kX86RegClassMm = 2, + //! X86/X64 Xmm/Ymm/Zmm register class. + kX86RegClassXyz = 3, + + //! Count of X86/X64 register classes. + kX86RegClassCount = 4 +}; + +// ============================================================================ +// [asmjit::kX86RegType] +// ============================================================================ + +//! X86/X64 register type. +ASMJIT_ENUM(kX86RegType) { + //! Gpb-lo register (AL, BL, CL, DL, ...). + kX86RegTypeGpbLo = 0x01, + //! Gpb-hi register (AH, BH, CH, DH only). + kX86RegTypeGpbHi = 0x02, + + //! \internal + //! + //! Gpb-hi register patched to native index (4-7). + _kX86RegTypePatchedGpbHi = kX86RegTypeGpbLo | kX86RegTypeGpbHi, + + //! Gpw register. + kX86RegTypeGpw = 0x10, + //! Gpd register. + kX86RegTypeGpd = 0x20, + //! Gpq register. + kX86RegTypeGpq = 0x30, + + //! Fp register. + kX86RegTypeFp = 0x50, + //! Mm register. + kX86RegTypeMm = 0x60, + + //! Xmm register. + kX86RegTypeXmm = 0x70, + //! Ymm register. + kX86RegTypeYmm = 0x80, + //! Zmm register. + kX86RegTypeZmm = 0x90, + + //! Segment register. + kX86RegTypeSeg = 0xF0 +}; + +// ============================================================================ +// [asmjit::kX86RegIndex] +// ============================================================================ + +//! X86/X64 register indexes. +//! +//! \note Register indexes have been reduced to only support general purpose +//! registers. There is no need to have enumerations with number suffix that +//! expands to the exactly same value as the suffix value itself. +ASMJIT_ENUM(kX86RegIndex) { + //! Index of Al/Ah/Ax/Eax/Rax registers. + kX86RegIndexAx = 0, + //! Index of Cl/Ch/Cx/Ecx/Rcx registers. + kX86RegIndexCx = 1, + //! Index of Dl/Dh/Dx/Edx/Rdx registers. + kX86RegIndexDx = 2, + //! Index of Bl/Bh/Bx/Ebx/Rbx registers. + kX86RegIndexBx = 3, + //! Index of Spl/Sp/Esp/Rsp registers. + kX86RegIndexSp = 4, + //! Index of Bpl/Bp/Ebp/Rbp registers. + kX86RegIndexBp = 5, + //! Index of Sil/Si/Esi/Rsi registers. + kX86RegIndexSi = 6, + //! Index of Dil/Di/Edi/Rdi registers. + kX86RegIndexDi = 7, + //! Index of R8b/R8w/R8d/R8 registers (64-bit only). + kX86RegIndexR8 = 8, + //! Index of R9B/R9w/R9d/R9 registers (64-bit only). + kX86RegIndexR9 = 9, + //! Index of R10B/R10w/R10D/R10 registers (64-bit only). + kX86RegIndexR10 = 10, + //! Index of R11B/R11w/R11d/R11 registers (64-bit only). + kX86RegIndexR11 = 11, + //! Index of R12B/R12w/R12d/R12 registers (64-bit only). + kX86RegIndexR12 = 12, + //! Index of R13B/R13w/R13d/R13 registers (64-bit only). + kX86RegIndexR13 = 13, + //! Index of R14B/R14w/R14d/R14 registers (64-bit only). + kX86RegIndexR14 = 14, + //! Index of R15B/R15w/R15d/R15 registers (64-bit only). + kX86RegIndexR15 = 15 +}; + +// ============================================================================ +// [asmjit::kX86Seg] +// ============================================================================ + +//! X86/X64 segment codes. +ASMJIT_ENUM(kX86Seg) { + //! No/Default segment. + kX86SegDefault = 0, + //! Es segment. + kX86SegEs = 1, + //! Cs segment. + kX86SegCs = 2, + //! Ss segment. + kX86SegSs = 3, + //! Ds segment. + kX86SegDs = 4, + //! Fs segment. + kX86SegFs = 5, + //! Gs segment. + kX86SegGs = 6, + + //! Count of X86 segment registers supported by AsmJit. + //! + //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS. + //! X64 architecture lowers them down to just FS and GS. AsmJit supports 7 + //! segment registers - all addressable in both X86 and X64 modes and one + //! extra called `kX86SegDefault`, which is AsmJit specific and means that there + //! is no segment register specified so the segment prefix will not be emitted. + kX86SegCount = 7 +}; + +// ============================================================================ +// [asmjit::kX86MemVSib] +// ============================================================================ + +//! X86/X64 index register legacy and AVX2 (VSIB) support. +ASMJIT_ENUM(kX86MemVSib) { + //! Memory operand uses Gp or no index register. + kX86MemVSibGpz = 0, + //! Memory operand uses Xmm or no index register. + kX86MemVSibXmm = 1, + //! Memory operand uses Ymm or no index register. + kX86MemVSibYmm = 2 +}; + +// ============================================================================ +// [asmjit::kX86MemFlags] +// ============================================================================ + +//! \internal +//! +//! X86/X64 specific memory flags. +ASMJIT_ENUM(kX86MemFlags) { + kX86MemSegBits = 0x7, + kX86MemSegIndex = 0, + kX86MemSegMask = kX86MemSegBits << kX86MemSegIndex, + + kX86MemGpdBits = 0x1, + kX86MemGpdIndex = 3, + kX86MemGpdMask = kX86MemGpdBits << kX86MemGpdIndex, + + kX86MemVSibBits = 0x3, + kX86MemVSibIndex = 4, + kX86MemVSibMask = kX86MemVSibBits << kX86MemVSibIndex, + + kX86MemShiftBits = 0x3, + kX86MemShiftIndex = 6, + kX86MemShiftMask = kX86MemShiftBits << kX86MemShiftIndex +}; + +// This is only defined by `x86operand_regs.cpp` when exporting registers. +#if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS) + +// ============================================================================ +// [asmjit::X86RegCount] +// ============================================================================ + +//! \internal +//! +//! X86/X64 registers count (Gp, Fp, Mm, Xmm). +struct X86RegCount { + // -------------------------------------------------------------------------- + // [Zero] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + _packed = 0; + } + + // -------------------------------------------------------------------------- + // [Get] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t get(uint32_t c) const { + ASMJIT_ASSERT(c < kX86RegClassCount); + return _regs[c]; + } + + ASMJIT_INLINE uint32_t getGp() const { return _regs[kX86RegClassGp]; } + ASMJIT_INLINE uint32_t getFp() const { return _regs[kX86RegClassFp]; } + ASMJIT_INLINE uint32_t getMm() const { return _regs[kX86RegClassMm]; } + ASMJIT_INLINE uint32_t getXyz() const { return _regs[kX86RegClassXyz]; } + + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void set(uint32_t c, uint32_t n) { + ASMJIT_ASSERT(c < kX86RegClassCount); + ASMJIT_ASSERT(n < 0x100); + + _regs[c] = static_cast(n); + } + + ASMJIT_INLINE void setGp(uint32_t n) { set(kX86RegClassGp, n); } + ASMJIT_INLINE void setFp(uint32_t n) { set(kX86RegClassFp, n); } + ASMJIT_INLINE void setMm(uint32_t n) { set(kX86RegClassMm, n); } + ASMJIT_INLINE void setXyz(uint32_t n) { set(kX86RegClassXyz, n); } + + // -------------------------------------------------------------------------- + // [Add] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void add(uint32_t c, uint32_t n = 1) { + ASMJIT_ASSERT(c < kX86RegClassCount); + ASMJIT_ASSERT(n < 0x100); + + _regs[c] += static_cast(n); + } + + ASMJIT_INLINE void addGp(uint32_t n) { add(kX86RegClassGp, n); } + ASMJIT_INLINE void addFp(uint32_t n) { add(kX86RegClassFp, n); } + ASMJIT_INLINE void addMm(uint32_t n) { add(kX86RegClassMm, n); } + ASMJIT_INLINE void addXyz(uint32_t n) { add(kX86RegClassXyz, n); } + + // -------------------------------------------------------------------------- + // [Misc] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void makeIndex(const X86RegCount& count) { + uint8_t a = count._regs[0]; + uint8_t b = count._regs[1]; + uint8_t c = count._regs[2]; + + _regs[0] = 0; + _regs[1] = a; + _regs[2] = a + b; + _regs[3] = a + b + c; + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + struct { + uint8_t _gp; + uint8_t _fp; + uint8_t _mm; + uint8_t _xy; + }; + + uint8_t _regs[4]; + uint32_t _packed; + }; +}; + +// ============================================================================ +// [asmjit::X86RegMask] +// ============================================================================ + +//! \internal +//! +//! X86/X64 registers mask (Gp, Fp, Mm, Xmm/Ymm/Zmm). +struct X86RegMask { + // -------------------------------------------------------------------------- + // [Reset] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void reset() { + _packed.reset(); + } + + // -------------------------------------------------------------------------- + // [IsEmpty / Has] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE bool isEmpty() const { + return _packed.isZero(); + } + + ASMJIT_INLINE bool has(uint32_t c, uint32_t mask = 0xFFFFFFFF) const { + switch (c) { + case kX86RegClassGp : return (static_cast(_gp ) & mask) != 0; + case kX86RegClassFp : return (static_cast(_fp ) & mask) != 0; + case kX86RegClassMm : return (static_cast(_mm ) & mask) != 0; + case kX86RegClassXyz: return (static_cast(_xyz) & mask) != 0; + } + + ASMJIT_ASSERT(!"Reached"); + return false; + } + + // -------------------------------------------------------------------------- + // [Zero] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void zero(uint32_t c) { + switch (c) { + case kX86RegClassGp : _gp = 0; break; + case kX86RegClassFp : _fp = 0; break; + case kX86RegClassMm : _mm = 0; break; + case kX86RegClassXyz: _xyz = 0; break; + } + } + + // -------------------------------------------------------------------------- + // [Get] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE uint32_t get(uint32_t c) const { + switch (c) { + case kX86RegClassGp : return _gp; + case kX86RegClassFp : return _fp; + case kX86RegClassMm : return _mm; + case kX86RegClassXyz: return _xyz; + } + + ASMJIT_ASSERT(!"Reached"); + return 0; + } + + // -------------------------------------------------------------------------- + // [Set] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void set(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp = static_cast(mask); break; + case kX86RegClassFp : _fp = static_cast(mask); break; + case kX86RegClassMm : _mm = static_cast(mask); break; + case kX86RegClassXyz: _xyz = static_cast(mask); break; + } + } + + ASMJIT_INLINE void set(const X86RegMask& other) { + _packed.setUInt64(other._packed); + } + + // -------------------------------------------------------------------------- + // [Add] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void add(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp |= static_cast(mask); break; + case kX86RegClassFp : _fp |= static_cast(mask); break; + case kX86RegClassMm : _mm |= static_cast(mask); break; + case kX86RegClassXyz: _xyz |= static_cast(mask); break; + } + } + + ASMJIT_INLINE void add(const X86RegMask& other) { + _packed.or_(other._packed); + } + + // -------------------------------------------------------------------------- + // [Del] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void del(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp &= ~static_cast(mask); break; + case kX86RegClassFp : _fp &= ~static_cast(mask); break; + case kX86RegClassMm : _mm &= ~static_cast(mask); break; + case kX86RegClassXyz: _xyz &= ~static_cast(mask); break; + } + } + + ASMJIT_INLINE void del(const X86RegMask& other) { + _packed.del(other._packed); + } + + // -------------------------------------------------------------------------- + // [And] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void and_(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp &= static_cast(mask); break; + case kX86RegClassFp : _fp &= static_cast(mask); break; + case kX86RegClassMm : _mm &= static_cast(mask); break; + case kX86RegClassXyz: _xyz &= static_cast(mask); break; + } + } + + ASMJIT_INLINE void and_(const X86RegMask& other) { + _packed.and_(other._packed); + } + + // -------------------------------------------------------------------------- + // [Xor] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void xor_(uint32_t c, uint32_t mask) { + switch (c) { + case kX86RegClassGp : _gp ^= static_cast(mask); break; + case kX86RegClassFp : _fp ^= static_cast(mask); break; + case kX86RegClassMm : _mm ^= static_cast(mask); break; + case kX86RegClassXyz: _xyz ^= static_cast(mask); break; + } + } + + ASMJIT_INLINE void xor_(const X86RegMask& other) { + _packed.xor_(other._packed); + } + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + union { + struct { + //! Gp mask (16-bit). + uint16_t _gp; + //! Fp mask (8-bit). + uint8_t _fp; + //! Mm mask (8-bit). + uint8_t _mm; + //! Xmm/Ymm/Zmm mask (32-bit). + uint32_t _xyz; + }; + + //! All masks as 64-bit integer. + UInt64 _packed; + }; +}; + +// ============================================================================ +// [asmjit::X86Reg] +// ============================================================================ + +//! Base class for all X86 registers. +struct X86Reg : public Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy X86 register. + ASMJIT_INLINE X86Reg() : Reg() {} + //! Create a reference to `other` X86 register. + ASMJIT_INLINE X86Reg(const X86Reg& other) : Reg(other) {} + //! Create a reference to `other` X86 register and change the index to `index`. + ASMJIT_INLINE X86Reg(const X86Reg& other, uint32_t index) : Reg(other, index) {} + //! Create a custom X86 register. + ASMJIT_INLINE X86Reg(uint32_t type, uint32_t index, uint32_t size) : Reg(type, index, size) {} + //! Create non-initialized X86 register. + explicit ASMJIT_INLINE X86Reg(const _NoInit&) : Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86Reg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86Reg) + + //! Get whether the register is Gp register. + ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; } + //! Get whether the register is Gp byte (8-bit) register. + ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kX86RegTypeGpbHi; } + //! Get whether the register is Gp lo-byte (8-bit) register. + ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; } + //! Get whether the register is Gp hi-byte (8-bit) register. + ASMJIT_INLINE bool isGpbHi() const { return _vreg.type == kX86RegTypeGpbHi; } + //! Get whether the register is Gp word (16-bit) register. + ASMJIT_INLINE bool isGpw() const { return _vreg.type == kX86RegTypeGpw; } + //! Get whether the register is Gp dword (32-bit) register. + ASMJIT_INLINE bool isGpd() const { return _vreg.type == kX86RegTypeGpd; } + //! Get whether the register is Gp qword (64-bit) register. + ASMJIT_INLINE bool isGpq() const { return _vreg.type == kX86RegTypeGpq; } + + //! Get whether the register is Fp register. + ASMJIT_INLINE bool isFp() const { return _vreg.type == kX86RegTypeFp; } + //! Get whether the register is Mm (64-bit) register. + ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; } + //! Get whether the register is Xmm (128-bit) register. + ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; } + //! Get whether the register is Ymm (256-bit) register. + ASMJIT_INLINE bool isYmm() const { return _vreg.type == kX86RegTypeYmm; } + //! Get whether the register is Zmm (512-bit) register. + ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; } + + //! Get whether the register is a segment. + ASMJIT_INLINE bool isSeg() const { return _vreg.type == kX86RegTypeSeg; } + + // -------------------------------------------------------------------------- + // [Statics] + // -------------------------------------------------------------------------- + + //! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register. + static ASMJIT_INLINE bool isGpbReg(const Operand& op) { + const uint32_t mask = IntUtil::pack32_2x8_1x16( + 0xFF, 0xFF, ~(_kX86RegTypePatchedGpbHi << 8) & 0xFF00); + + return (op._packed[0].u32[0] & mask) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 1, 0x0000); + } +}; + +// ============================================================================ +// [asmjit::X86GpReg] +// ============================================================================ + +//! X86/X64 Gpb/Gpw/Gpd/Gpq register. +struct X86GpReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Gp register. + ASMJIT_INLINE X86GpReg() : X86Reg() {} + //! Create a reference to `other` Gp register. + ASMJIT_INLINE X86GpReg(const X86GpReg& other) : X86Reg(other) {} + //! Create a reference to `other` Gp register and change the index to `index`. + ASMJIT_INLINE X86GpReg(const X86GpReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Gp register. + ASMJIT_INLINE X86GpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Gp register. + explicit ASMJIT_INLINE X86GpReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86GpReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86GpReg) +}; + +// ============================================================================ +// [asmjit::X86FpReg] +// ============================================================================ + +//! X86/X64 80-bit Fp register. +struct X86FpReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Fp register. + ASMJIT_INLINE X86FpReg() : X86Reg() {} + //! Create a reference to `other` Fp register. + ASMJIT_INLINE X86FpReg(const X86FpReg& other) : X86Reg(other) {} + //! Create a reference to `other` Fp register and change the index to `index`. + ASMJIT_INLINE X86FpReg(const X86FpReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Fp register. + ASMJIT_INLINE X86FpReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Fp register. + explicit ASMJIT_INLINE X86FpReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86FpReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86FpReg) +}; + +// ============================================================================ +// [asmjit::X86MmReg] +// ============================================================================ + +//! X86/X64 64-bit Mm register. +struct X86MmReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Mm register. + ASMJIT_INLINE X86MmReg() : X86Reg() {} + //! Create a reference to `other` Mm register. + ASMJIT_INLINE X86MmReg(const X86MmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Mm register and change the index to `index`. + ASMJIT_INLINE X86MmReg(const X86MmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Mm register. + ASMJIT_INLINE X86MmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Mm register. + explicit ASMJIT_INLINE X86MmReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86MmReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86MmReg) +}; + +// ============================================================================ +// [asmjit::X86XmmReg] +// ============================================================================ + +//! X86/X64 128-bit Xmm register. +struct X86XmmReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Xmm register. + ASMJIT_INLINE X86XmmReg() : X86Reg() {} + //! Create a reference to `other` Xmm register. + ASMJIT_INLINE X86XmmReg(const X86XmmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Xmm register and change the index to `index`. + ASMJIT_INLINE X86XmmReg(const X86XmmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Xmm register. + ASMJIT_INLINE X86XmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Xmm register. + explicit ASMJIT_INLINE X86XmmReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86XmmReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86XmmReg) +}; + +// ============================================================================ +// [asmjit::X86YmmReg] +// ============================================================================ + +//! X86/X64 256-bit Ymm register. +struct X86YmmReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy Ymm register. + ASMJIT_INLINE X86YmmReg() : X86Reg() {} + //! Create a reference to `other` Xmm register. + ASMJIT_INLINE X86YmmReg(const X86YmmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Ymm register and change the index to `index`. + ASMJIT_INLINE X86YmmReg(const X86YmmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Ymm register. + ASMJIT_INLINE X86YmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Ymm register. + explicit ASMJIT_INLINE X86YmmReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86YmmReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86YmmReg) +}; + +// ============================================================================ +// [asmjit::X86SegReg] +// ============================================================================ + +//! X86/X64 segment register. +struct X86SegReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy segment register. + ASMJIT_INLINE X86SegReg() : X86Reg() {} + //! Create a reference to `other` segment register. + ASMJIT_INLINE X86SegReg(const X86SegReg& other) : X86Reg(other) {} + //! Create a reference to `other` segment register and change the index to `index`. + ASMJIT_INLINE X86SegReg(const X86SegReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom segment register. + ASMJIT_INLINE X86SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized segment register. + explicit ASMJIT_INLINE X86SegReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86SegReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86SegReg) +}; + +// ============================================================================ +// [asmjit::X86Mem] +// ============================================================================ + +//! X86 memory operand. +struct X86Mem : public BaseMem { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Mem() : BaseMem(NoInit) { + reset(); + } + + ASMJIT_INLINE X86Mem(const Label& label, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, 0, label._base.id); + _init_packed_d2_d3(kInvalidValue, disp); + } + + ASMJIT_INLINE X86Mem(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, + (kX86MemVSibGpz << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + label.getId()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + + (kX86MemVSibGpz << kX86MemVSibIndex), + base.getRegIndex()); + _init_packed_d2_d3(kInvalidValue, disp); + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86GpReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + (shift << kX86MemShiftIndex), + base.getRegIndex()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86XmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + + (kX86MemVSibXmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + base.getRegIndex()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpReg& base, const X86YmmReg& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(base) + + (kX86MemVSibYmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + base.getRegIndex()); + _vmem.index = index.getRegIndex(); + _vmem.displacement = disp; + } + +#if !defined(ASMJIT_DISABLE_COMPILER) + ASMJIT_INLINE X86Mem(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeLabel, + (kX86MemVSibGpz << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + label.getId()); + _vmem.index = _OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibGpz << kX86MemVSibIndex), + _OP_ID(base)); + _init_packed_d2_d3(kInvalidValue, disp); + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (shift << kX86MemShiftIndex), + _OP_ID(base)); + _vmem.index = _OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86XmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibXmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + _OP_ID(base)); + _vmem.index = _OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const X86GpVar& base, const X86YmmVar& index, uint32_t shift, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, + _getGpdFlags(reinterpret_cast(base)) + + (kX86MemVSibYmm << kX86MemVSibIndex) + + (shift << kX86MemShiftIndex), + _OP_ID(base)); + _vmem.index = _OP_ID(index); + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, int32_t disp, uint32_t size) : BaseMem(NoInit) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, _OP_ID(base)); + _vmem.index = kInvalidValue; + _vmem.displacement = disp; + } + + ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size) : BaseMem(NoInit) { + ASMJIT_ASSERT(shift <= 3); + + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, shift << kX86MemShiftIndex, _OP_ID(base)); + _vmem.index = _OP_ID(index); + _vmem.displacement = disp; + } +#endif // !ASMJIT_DISABLE_COMPILER + + ASMJIT_INLINE X86Mem(const X86Mem& other) : BaseMem(other) {} + explicit ASMJIT_INLINE X86Mem(const _NoInit&) : BaseMem(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86Mem Specific] + // -------------------------------------------------------------------------- + + //! Clone X86Mem operand. + ASMJIT_INLINE X86Mem clone() const { + return X86Mem(*this); + } + + //! Reset X86Mem operand. + ASMJIT_INLINE void reset() { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, 0, kMemTypeBaseIndex, 0, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, 0); + } + + //! \internal + ASMJIT_INLINE void _init(uint32_t memType, uint32_t base, int32_t disp, uint32_t size) { + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, base); + _vmem.index = kInvalidValue; + _vmem.displacement = disp; + } + + // -------------------------------------------------------------------------- + // [Segment] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has segment override prefix. + ASMJIT_INLINE bool hasSegment() const { + return (_vmem.flags & kX86MemSegMask) != (kX86SegDefault << kX86MemSegIndex); + } + + //! Get memory operand segment, see `kX86Seg`. + ASMJIT_INLINE uint32_t getSegment() const { + return (static_cast(_vmem.flags) >> kX86MemSegIndex) & kX86MemSegBits; + } + + //! Set memory operand segment, see `kX86Seg`. + ASMJIT_INLINE X86Mem& setSegment(uint32_t segIndex) { + _vmem.flags = static_cast( + (static_cast(_vmem.flags) & kX86MemSegMask) + (segIndex << kX86MemSegIndex)); + return *this; + } + + //! Set memory operand segment, see `kX86Seg`. + ASMJIT_INLINE X86Mem& setSegment(const X86SegReg& seg) { + return setSegment(seg.getRegIndex()); + } + + // -------------------------------------------------------------------------- + // [Gpd] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has 32-bit GP base. + ASMJIT_INLINE bool hasGpdBase() const { + return (_packed[0].u32[0] & IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask)) != 0; + } + + //! Set whether the memory operand has 32-bit GP base. + ASMJIT_INLINE X86Mem& setGpdBase() { + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask); + return *this; + } + + //! Set whether the memory operand has 32-bit GP base to `b`. + ASMJIT_INLINE X86Mem& setGpdBase(uint32_t b) { + _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemGpdMask); + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, b << kX86MemGpdIndex); + return *this; + } + + // -------------------------------------------------------------------------- + // [VSib] + // -------------------------------------------------------------------------- + + //! Get SIB type. + ASMJIT_INLINE uint32_t getVSib() const { + return (static_cast(_vmem.flags) >> kX86MemVSibIndex) & kX86MemVSibBits; + } + + //! Set SIB type. + ASMJIT_INLINE X86Mem& _setVSib(uint32_t vsib) { + _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemVSibMask); + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, vsib << kX86MemVSibIndex); + return *this; + } + + // -------------------------------------------------------------------------- + // [Size] + // -------------------------------------------------------------------------- + + //! Set memory operand size. + ASMJIT_INLINE X86Mem& setSize(uint32_t size) { + _vmem.size = static_cast(size); + return *this; + } + + // -------------------------------------------------------------------------- + // [Base] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has base register. + ASMJIT_INLINE bool hasBase() const { + return _vmem.base != kInvalidValue; + } + + //! Get memory operand base register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE uint32_t getBase() const { + return _vmem.base; + } + + //! Set memory operand base register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE X86Mem& setBase(uint32_t base) { + _vmem.base = base; + return *this; + } + + // -------------------------------------------------------------------------- + // [Index] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has index. + ASMJIT_INLINE bool hasIndex() const { + return _vmem.index != kInvalidValue; + } + + //! Get memory operand index register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE uint32_t getIndex() const { + return _vmem.index; + } + + //! Set memory operand index register code, variable id, or `kInvalidValue`. + ASMJIT_INLINE X86Mem& setIndex(uint32_t index) { + _vmem.index = index; + return *this; + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibGpz); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpReg& index, uint32_t shift) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibGpz).setShift(shift); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibXmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmReg& index, uint32_t shift) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibXmm).setShift(shift); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibYmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmReg& index, uint32_t shift) { + _vmem.index = index.getRegIndex(); + return _setVSib(kX86MemVSibYmm).setShift(shift); + } + +#if !defined(ASMJIT_DISABLE_COMPILER) + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibGpz); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index, uint32_t shift) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibGpz).setShift(shift); + } + + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibXmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index, uint32_t shift) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibXmm).setShift(shift); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibYmm); + } + + //! Set memory index. + ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index, uint32_t shift) { + _vmem.index = _OP_ID(index); + return _setVSib(kX86MemVSibYmm).setShift(shift); + } +#endif // !ASMJIT_DISABLE_COMPILER + + //! Reset memory index. + ASMJIT_INLINE X86Mem& resetIndex() { + _vmem.index = kInvalidValue; + return _setVSib(kX86MemVSibGpz); + } + + // -------------------------------------------------------------------------- + // [Misc] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has base and index register. + ASMJIT_INLINE bool hasBaseOrIndex() const { + return _vmem.base != kInvalidValue || _vmem.index != kInvalidValue; + } + + //! Get whether the memory operand has base and index register. + ASMJIT_INLINE bool hasBaseAndIndex() const { + return _vmem.base != kInvalidValue && _vmem.index != kInvalidValue; + } + + // -------------------------------------------------------------------------- + // [Shift] + // -------------------------------------------------------------------------- + + //! Get whether the memory operand has shift used. + ASMJIT_INLINE bool hasShift() const { + return (_vmem.flags & kX86MemShiftMask) != 0; + } + + //! Get memory operand index scale (0, 1, 2 or 3). + ASMJIT_INLINE uint32_t getShift() const { + return _vmem.flags >> kX86MemShiftIndex; + } + + //! Set memory operand index scale (0, 1, 2 or 3). + ASMJIT_INLINE X86Mem& setShift(uint32_t shift) { + _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemShiftMask); + _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, shift << kX86MemShiftIndex); + return *this; + } + + // -------------------------------------------------------------------------- + // [Displacement] + // -------------------------------------------------------------------------- + + //! Get memory operand relative displacement. + ASMJIT_INLINE int32_t getDisplacement() const { + return _vmem.displacement; + } + + //! Set memory operand relative displacement. + ASMJIT_INLINE X86Mem& setDisplacement(int32_t disp) { + _vmem.displacement = disp; + return *this; + } + + //! Reset memory operand relative displacement. + ASMJIT_INLINE X86Mem& resetDisplacement(int32_t disp) { + _vmem.displacement = 0; + return *this; + } + + //! Adjust memory operand relative displacement by `disp`. + ASMJIT_INLINE X86Mem& adjust(int32_t disp) { + _vmem.displacement += disp; + return *this; + } + + //! Get new memory operand adjusted by `disp`. + ASMJIT_INLINE X86Mem adjusted(int32_t disp) const { + X86Mem result(*this); + result.adjust(disp); + return result; + } + + // -------------------------------------------------------------------------- + // [Operator Overload] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE X86Mem& operator=(const X86Mem& other) { + _copy(other); + return *this; + } + + ASMJIT_INLINE bool operator==(const X86Mem& other) const { + return (_packed[0] == other._packed[0]) & (_packed[1] == other._packed[1]) ; + } + + ASMJIT_INLINE bool operator!=(const X86Mem& other) const { + return !(*this == other); + } + + // -------------------------------------------------------------------------- + // [Static] + // -------------------------------------------------------------------------- + + static ASMJIT_INLINE uint32_t _getGpdFlags(const Operand& base) { + return (base._vreg.size & 0x4) << (kX86MemGpdIndex - 2); + } +}; +#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS + +// ============================================================================ +// [asmjit::x86] +// ============================================================================ + +namespace x86 { + +// ============================================================================ +// [asmjit::x86 - Reg] +// ============================================================================ + +//! No Gp register, can be used only within `X86Mem` operand. +ASMJIT_VAR const X86GpReg noGpReg; + +ASMJIT_VAR const X86GpReg al; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg cl; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg dl; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg bl; //!< 8-bit Gpb-lo register. +ASMJIT_VAR const X86GpReg spl; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg bpl; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg sil; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg dil; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r8b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r9b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r10b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r11b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r12b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r13b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r14b; //!< 8-bit Gpb-lo register (X64). +ASMJIT_VAR const X86GpReg r15b; //!< 8-bit Gpb-lo register (X64). + +ASMJIT_VAR const X86GpReg ah; //!< 8-bit Gpb-hi register. +ASMJIT_VAR const X86GpReg ch; //!< 8-bit Gpb-hi register. +ASMJIT_VAR const X86GpReg dh; //!< 8-bit Gpb-hi register. +ASMJIT_VAR const X86GpReg bh; //!< 8-bit Gpb-hi register. + +ASMJIT_VAR const X86GpReg ax; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg cx; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg dx; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg bx; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg sp; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg bp; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg si; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg di; //!< 16-bit Gpw register. +ASMJIT_VAR const X86GpReg r8w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r9w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r10w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r11w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r12w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r13w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r14w; //!< 16-bit Gpw register (X64). +ASMJIT_VAR const X86GpReg r15w; //!< 16-bit Gpw register (X64). + +ASMJIT_VAR const X86GpReg eax; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg ecx; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg edx; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg ebx; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg esp; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg ebp; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg esi; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg edi; //!< 32-bit Gpd register. +ASMJIT_VAR const X86GpReg r8d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r9d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r10d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r11d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r12d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r13d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r14d; //!< 32-bit Gpd register (X64). +ASMJIT_VAR const X86GpReg r15d; //!< 32-bit Gpd register (X64). + +ASMJIT_VAR const X86GpReg rax; //!< 64-bit Gpq register (X64). +ASMJIT_VAR const X86GpReg rcx; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rdx; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rbx; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rsp; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rbp; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rsi; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg rdi; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r8; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r9; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r10; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r11; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r12; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r13; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r14; //!< 64-bit Gpq register (X64) +ASMJIT_VAR const X86GpReg r15; //!< 64-bit Gpq register (X64) + +ASMJIT_VAR const X86FpReg fp0; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp1; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp2; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp3; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp4; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp5; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp6; //!< 80-bit Fp register. +ASMJIT_VAR const X86FpReg fp7; //!< 80-bit Fp register. + +ASMJIT_VAR const X86MmReg mm0; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm1; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm2; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm3; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm4; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm5; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm6; //!< 64-bit Mm register. +ASMJIT_VAR const X86MmReg mm7; //!< 64-bit Mm register. + +ASMJIT_VAR const X86XmmReg xmm0; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm1; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm2; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm3; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm4; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm5; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm6; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm7; //!< 128-bit Xmm register. +ASMJIT_VAR const X86XmmReg xmm8; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm9; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm10; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm11; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm12; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm13; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm14; //!< 128-bit Xmm register (X64). +ASMJIT_VAR const X86XmmReg xmm15; //!< 128-bit Xmm register (X64). + +ASMJIT_VAR const X86YmmReg ymm0; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm1; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm2; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm3; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm4; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm5; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm6; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm7; //!< 256-bit Ymm register. +ASMJIT_VAR const X86YmmReg ymm8; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm9; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm10; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm11; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm12; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm13; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm14; //!< 256-bit Ymm register (X64). +ASMJIT_VAR const X86YmmReg ymm15; //!< 256-bit Ymm register (X64). + +ASMJIT_VAR const X86SegReg cs; //!< Cs segment register. +ASMJIT_VAR const X86SegReg ss; //!< Ss segment register. +ASMJIT_VAR const X86SegReg ds; //!< Ds segment register. +ASMJIT_VAR const X86SegReg es; //!< Es segment register. +ASMJIT_VAR const X86SegReg fs; //!< Fs segment register. +ASMJIT_VAR const X86SegReg gs; //!< Gs segment register. + +// This is only defined by `x86operand_regs.cpp` when exporting registers. +#if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS) + +//! Create 8-bit Gpb-lo register operand. +static ASMJIT_INLINE X86GpReg gpb_lo(uint32_t index) { return X86GpReg(kX86RegTypeGpbLo, index, 1); } +//! Create 8-bit Gpb-hi register operand. +static ASMJIT_INLINE X86GpReg gpb_hi(uint32_t index) { return X86GpReg(kX86RegTypeGpbHi, index, 1); } +//! Create 16-bit Gpw register operand. +static ASMJIT_INLINE X86GpReg gpw(uint32_t index) { return X86GpReg(kX86RegTypeGpw, index, 2); } +//! Create 32-bit Gpd register operand. +static ASMJIT_INLINE X86GpReg gpd(uint32_t index) { return X86GpReg(kX86RegTypeGpd, index, 4); } +//! Create 64-bit Gpq register operand (X64). +static ASMJIT_INLINE X86GpReg gpq(uint32_t index) { return X86GpReg(kX86RegTypeGpq, index, 8); } +//! Create 80-bit Fp register operand. +static ASMJIT_INLINE X86FpReg fp(uint32_t index) { return X86FpReg(kX86RegTypeFp, index, 10); } +//! Create 64-bit Mm register operand. +static ASMJIT_INLINE X86MmReg mm(uint32_t index) { return X86MmReg(kX86RegTypeMm, index, 8); } +//! Create 128-bit Xmm register operand. +static ASMJIT_INLINE X86XmmReg xmm(uint32_t index) { return X86XmmReg(kX86RegTypeXmm, index, 16); } +//! Create 256-bit Ymm register operand. +static ASMJIT_INLINE X86YmmReg ymm(uint32_t index) { return X86YmmReg(kX86RegTypeYmm, index, 32); } + +// ============================================================================ +// [asmjit::x86 - Ptr (Reg)] +// ============================================================================ + +//! Create `[base.reg + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, disp, size); +} +//! Create `[base.reg + (index.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[label + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const Label& label, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(label, disp, size); +} +//! Create `[label + (index.reg << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \ + return X86Mem(label, index, shift, disp, size); \ +} + +//! Create `[pAbs + disp]` absolute memory operand with no/custom size information. +ASMJIT_API X86Mem ptr_abs(Ptr pAbs, int32_t disp = 0, uint32_t size = 0); +//! Create `[pAbs + (index.reg << shift) + disp]` absolute memory operand with no/custom size information. +ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0); + +//! \internal +#define ASMJIT_EXPAND_PTR_REG(_Prefix_, _Size_) \ + /*! Create `[base.reg + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, int32_t disp = 0) { \ + return X86Mem(base, disp, _Size_); \ + } \ + /*! Create `[base.reg + (index.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.reg + (xmm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.reg + (ymm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[label + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, int32_t disp = 0) { \ + return ptr(label, disp, _Size_); \ + } \ + /*! Create `[label + (index.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) { \ + return ptr(label, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \ + return ptr_abs(pAbs, disp, _Size_); \ + } \ + /*! Create `[pAbs + (index.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (xmm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (ymm.reg << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, index, shift, disp, _Size_); \ + } + +ASMJIT_EXPAND_PTR_REG(byte, 1) +ASMJIT_EXPAND_PTR_REG(word, 2) +ASMJIT_EXPAND_PTR_REG(dword, 4) +ASMJIT_EXPAND_PTR_REG(qword, 8) +ASMJIT_EXPAND_PTR_REG(tword, 10) +ASMJIT_EXPAND_PTR_REG(oword, 16) +ASMJIT_EXPAND_PTR_REG(yword, 32) +ASMJIT_EXPAND_PTR_REG(zword, 64) +#undef ASMJIT_EXPAND_PTR_REG + +// ============================================================================ +// [asmjit::x86 - Ptr (Var)] +// ============================================================================ + +#if !defined(ASMJIT_DISABLE_COMPILER) +//! Create `[base.var + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, disp, size); +} +//! Create `[base.var + (index.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.var + (xmm.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[base.var + (ymm.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) { + return X86Mem(base, index, shift, disp, size); +} +//! Create `[label + (index.var << shift) + disp]` memory operand with no/custom size information. +static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0, uint32_t size = 0) { \ + return X86Mem(label, index, shift, disp, size); \ +} + +//! Create `[pAbs + (index.var << shift) + disp]` absolute memory operand with no/custom size information. +ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0); + +//! \internal +#define ASMJIT_EXPAND_PTR_VAR(_Prefix_, _Size_) \ + /*! Create `[base.var + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, int32_t disp = 0) { \ + return X86Mem(base, disp, _Size_); \ + } \ + /*! Create `[base.var + (index.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.var + (xmm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[base.var + (ymm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const X86GpVar& base, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr(base, index, shift, disp, _Size_); \ + } \ + /*! Create `[label + (index.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpVar& index, uint32_t shift, int32_t disp = 0) { \ + return ptr(label, index, shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (index.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86GpVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, reinterpret_cast(index), shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (xmm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86XmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, reinterpret_cast(index), shift, disp, _Size_); \ + } \ + /*! Create `[pAbs + (ymm.var << shift) + disp]` memory operand. */ \ + static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, const X86YmmVar& index, uint32_t shift = 0, int32_t disp = 0) { \ + return ptr_abs(pAbs, reinterpret_cast(index), shift, disp, _Size_); \ + } + +ASMJIT_EXPAND_PTR_VAR(byte, 1) +ASMJIT_EXPAND_PTR_VAR(word, 2) +ASMJIT_EXPAND_PTR_VAR(dword, 4) +ASMJIT_EXPAND_PTR_VAR(qword, 8) +ASMJIT_EXPAND_PTR_VAR(tword, 10) +ASMJIT_EXPAND_PTR_VAR(oword, 16) +ASMJIT_EXPAND_PTR_VAR(yword, 32) +ASMJIT_EXPAND_PTR_VAR(zword, 64) +#undef ASMJIT_EXPAND_PTR_VAR +#endif // !ASMJIT_DISABLE_COMPILER + +#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS + +} // x86 namespace + +//! \} + +} // asmjit namespace + +#undef _OP_ID + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // _ASMJIT_X86_X86OPERAND_H diff --git a/libraries/asmjit/x86/x86operand_regs.cpp b/libraries/asmjit/x86/x86operand_regs.cpp new file mode 100644 index 000000000..b215ae4ad --- /dev/null +++ b/libraries/asmjit/x86/x86operand_regs.cpp @@ -0,0 +1,188 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS +#define ASMJIT_EXPORTS_X86OPERAND_REGS + +// [Guard] +#include "../build.h" +#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) + +// [Dependencies - AsmJit] +#include "../x86/x86operand.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// Prevent static initialization. +// +// Remap all classes to POD structs so they can be statically initialized +// without calling a constructor. Compiler will store these in data section. +struct X86GpReg { Operand::VRegOp data; }; +struct X86FpReg { Operand::VRegOp data; }; +struct X86MmReg { Operand::VRegOp data; }; +struct X86XmmReg { Operand::VRegOp data; }; +struct X86YmmReg { Operand::VRegOp data; }; +struct X86SegReg { Operand::VRegOp data; }; + +namespace x86 { + +// ============================================================================ +// [asmjit::x86::Registers] +// ============================================================================ + +#define REG(_Class_, _Name_, _Type_, _Index_, _Size_) \ + const _Class_ _Name_ = {{ \ + kOperandTypeReg, _Size_, { ((_Type_) << 8) + _Index_ }, kInvalidValue, {{ kInvalidVar, 0 }} \ + }} + +REG(X86GpReg, noGpReg, kInvalidReg, kInvalidReg, 0); + +REG(X86GpReg, al, kX86RegTypeGpbLo, kX86RegIndexAx, 1); +REG(X86GpReg, cl, kX86RegTypeGpbLo, kX86RegIndexCx, 1); +REG(X86GpReg, dl, kX86RegTypeGpbLo, kX86RegIndexDx, 1); +REG(X86GpReg, bl, kX86RegTypeGpbLo, kX86RegIndexBx, 1); +REG(X86GpReg, spl, kX86RegTypeGpbLo, kX86RegIndexSp, 1); +REG(X86GpReg, bpl, kX86RegTypeGpbLo, kX86RegIndexBp, 1); +REG(X86GpReg, sil, kX86RegTypeGpbLo, kX86RegIndexSi, 1); +REG(X86GpReg, dil, kX86RegTypeGpbLo, kX86RegIndexDi, 1); +REG(X86GpReg, r8b, kX86RegTypeGpbLo, 8, 1); +REG(X86GpReg, r9b, kX86RegTypeGpbLo, 9, 1); +REG(X86GpReg, r10b, kX86RegTypeGpbLo, 10, 1); +REG(X86GpReg, r11b, kX86RegTypeGpbLo, 11, 1); +REG(X86GpReg, r12b, kX86RegTypeGpbLo, 12, 1); +REG(X86GpReg, r13b, kX86RegTypeGpbLo, 13, 1); +REG(X86GpReg, r14b, kX86RegTypeGpbLo, 14, 1); +REG(X86GpReg, r15b, kX86RegTypeGpbLo, 15, 1); + +REG(X86GpReg, ah, kX86RegTypeGpbHi, kX86RegIndexAx, 1); +REG(X86GpReg, ch, kX86RegTypeGpbHi, kX86RegIndexCx, 1); +REG(X86GpReg, dh, kX86RegTypeGpbHi, kX86RegIndexDx, 1); +REG(X86GpReg, bh, kX86RegTypeGpbHi, kX86RegIndexBx, 1); + +REG(X86GpReg, ax, kX86RegTypeGpw, kX86RegIndexAx, 2); +REG(X86GpReg, cx, kX86RegTypeGpw, kX86RegIndexCx, 2); +REG(X86GpReg, dx, kX86RegTypeGpw, kX86RegIndexDx, 2); +REG(X86GpReg, bx, kX86RegTypeGpw, kX86RegIndexBx, 2); +REG(X86GpReg, sp, kX86RegTypeGpw, kX86RegIndexSp, 2); +REG(X86GpReg, bp, kX86RegTypeGpw, kX86RegIndexBp, 2); +REG(X86GpReg, si, kX86RegTypeGpw, kX86RegIndexSi, 2); +REG(X86GpReg, di, kX86RegTypeGpw, kX86RegIndexDi, 2); +REG(X86GpReg, r8w, kX86RegTypeGpw, 8, 2); +REG(X86GpReg, r9w, kX86RegTypeGpw, 9, 2); +REG(X86GpReg, r10w, kX86RegTypeGpw, 10, 2); +REG(X86GpReg, r11w, kX86RegTypeGpw, 11, 2); +REG(X86GpReg, r12w, kX86RegTypeGpw, 12, 2); +REG(X86GpReg, r13w, kX86RegTypeGpw, 13, 2); +REG(X86GpReg, r14w, kX86RegTypeGpw, 14, 2); +REG(X86GpReg, r15w, kX86RegTypeGpw, 15, 2); + +REG(X86GpReg, eax, kX86RegTypeGpd, kX86RegIndexAx, 4); +REG(X86GpReg, ecx, kX86RegTypeGpd, kX86RegIndexCx, 4); +REG(X86GpReg, edx, kX86RegTypeGpd, kX86RegIndexDx, 4); +REG(X86GpReg, ebx, kX86RegTypeGpd, kX86RegIndexBx, 4); +REG(X86GpReg, esp, kX86RegTypeGpd, kX86RegIndexSp, 4); +REG(X86GpReg, ebp, kX86RegTypeGpd, kX86RegIndexBp, 4); +REG(X86GpReg, esi, kX86RegTypeGpd, kX86RegIndexSi, 4); +REG(X86GpReg, edi, kX86RegTypeGpd, kX86RegIndexDi, 4); +REG(X86GpReg, r8d, kX86RegTypeGpd, 8, 4); +REG(X86GpReg, r9d, kX86RegTypeGpd, 9, 4); +REG(X86GpReg, r10d, kX86RegTypeGpd, 10, 4); +REG(X86GpReg, r11d, kX86RegTypeGpd, 11, 4); +REG(X86GpReg, r12d, kX86RegTypeGpd, 12, 4); +REG(X86GpReg, r13d, kX86RegTypeGpd, 13, 4); +REG(X86GpReg, r14d, kX86RegTypeGpd, 14, 4); +REG(X86GpReg, r15d, kX86RegTypeGpd, 15, 4); + +REG(X86GpReg, rax, kX86RegTypeGpq, kX86RegIndexAx, 8); +REG(X86GpReg, rcx, kX86RegTypeGpq, kX86RegIndexCx, 8); +REG(X86GpReg, rdx, kX86RegTypeGpq, kX86RegIndexDx, 8); +REG(X86GpReg, rbx, kX86RegTypeGpq, kX86RegIndexBx, 8); +REG(X86GpReg, rsp, kX86RegTypeGpq, kX86RegIndexSp, 8); +REG(X86GpReg, rbp, kX86RegTypeGpq, kX86RegIndexBp, 8); +REG(X86GpReg, rsi, kX86RegTypeGpq, kX86RegIndexSi, 8); +REG(X86GpReg, rdi, kX86RegTypeGpq, kX86RegIndexDi, 8); +REG(X86GpReg, r8, kX86RegTypeGpq, 8, 8); +REG(X86GpReg, r9, kX86RegTypeGpq, 9, 8); +REG(X86GpReg, r10, kX86RegTypeGpq, 10, 8); +REG(X86GpReg, r11, kX86RegTypeGpq, 11, 8); +REG(X86GpReg, r12, kX86RegTypeGpq, 12, 8); +REG(X86GpReg, r13, kX86RegTypeGpq, 13, 8); +REG(X86GpReg, r14, kX86RegTypeGpq, 14, 8); +REG(X86GpReg, r15, kX86RegTypeGpq, 15, 8); + +REG(X86FpReg, fp0, kX86RegTypeFp, 0, 10); +REG(X86FpReg, fp1, kX86RegTypeFp, 1, 10); +REG(X86FpReg, fp2, kX86RegTypeFp, 2, 10); +REG(X86FpReg, fp3, kX86RegTypeFp, 3, 10); +REG(X86FpReg, fp4, kX86RegTypeFp, 4, 10); +REG(X86FpReg, fp5, kX86RegTypeFp, 5, 10); +REG(X86FpReg, fp6, kX86RegTypeFp, 6, 10); +REG(X86FpReg, fp7, kX86RegTypeFp, 7, 10); + +REG(X86MmReg, mm0, kX86RegTypeMm, 0, 8); +REG(X86MmReg, mm1, kX86RegTypeMm, 1, 8); +REG(X86MmReg, mm2, kX86RegTypeMm, 2, 8); +REG(X86MmReg, mm3, kX86RegTypeMm, 3, 8); +REG(X86MmReg, mm4, kX86RegTypeMm, 4, 8); +REG(X86MmReg, mm5, kX86RegTypeMm, 5, 8); +REG(X86MmReg, mm6, kX86RegTypeMm, 6, 8); +REG(X86MmReg, mm7, kX86RegTypeMm, 7, 8); + +REG(X86XmmReg, xmm0, kX86RegTypeXmm, 0, 16); +REG(X86XmmReg, xmm1, kX86RegTypeXmm, 1, 16); +REG(X86XmmReg, xmm2, kX86RegTypeXmm, 2, 16); +REG(X86XmmReg, xmm3, kX86RegTypeXmm, 3, 16); +REG(X86XmmReg, xmm4, kX86RegTypeXmm, 4, 16); +REG(X86XmmReg, xmm5, kX86RegTypeXmm, 5, 16); +REG(X86XmmReg, xmm6, kX86RegTypeXmm, 6, 16); +REG(X86XmmReg, xmm7, kX86RegTypeXmm, 7, 16); +REG(X86XmmReg, xmm8, kX86RegTypeXmm, 8, 16); +REG(X86XmmReg, xmm9, kX86RegTypeXmm, 9, 16); +REG(X86XmmReg, xmm10, kX86RegTypeXmm, 10, 16); +REG(X86XmmReg, xmm11, kX86RegTypeXmm, 11, 16); +REG(X86XmmReg, xmm12, kX86RegTypeXmm, 12, 16); +REG(X86XmmReg, xmm13, kX86RegTypeXmm, 13, 16); +REG(X86XmmReg, xmm14, kX86RegTypeXmm, 14, 16); +REG(X86XmmReg, xmm15, kX86RegTypeXmm, 15, 16); + +REG(X86YmmReg, ymm0, kX86RegTypeYmm, 0, 32); +REG(X86YmmReg, ymm1, kX86RegTypeYmm, 1, 32); +REG(X86YmmReg, ymm2, kX86RegTypeYmm, 2, 32); +REG(X86YmmReg, ymm3, kX86RegTypeYmm, 3, 32); +REG(X86YmmReg, ymm4, kX86RegTypeYmm, 4, 32); +REG(X86YmmReg, ymm5, kX86RegTypeYmm, 5, 32); +REG(X86YmmReg, ymm6, kX86RegTypeYmm, 6, 32); +REG(X86YmmReg, ymm7, kX86RegTypeYmm, 7, 32); +REG(X86YmmReg, ymm8, kX86RegTypeYmm, 8, 32); +REG(X86YmmReg, ymm9, kX86RegTypeYmm, 9, 32); +REG(X86YmmReg, ymm10, kX86RegTypeYmm, 10, 32); +REG(X86YmmReg, ymm11, kX86RegTypeYmm, 11, 32); +REG(X86YmmReg, ymm12, kX86RegTypeYmm, 12, 32); +REG(X86YmmReg, ymm13, kX86RegTypeYmm, 13, 32); +REG(X86YmmReg, ymm14, kX86RegTypeYmm, 14, 32); +REG(X86YmmReg, ymm15, kX86RegTypeYmm, 15, 32); + +REG(X86SegReg, cs, kX86RegTypeSeg, kX86SegCs, 2); +REG(X86SegReg, ss, kX86RegTypeSeg, kX86SegSs, 2); +REG(X86SegReg, ds, kX86RegTypeSeg, kX86SegDs, 2); +REG(X86SegReg, es, kX86RegTypeSeg, kX86SegEs, 2); +REG(X86SegReg, fs, kX86RegTypeSeg, kX86SegFs, 2); +REG(X86SegReg, gs, kX86RegTypeSeg, kX86SegGs, 2); + +#undef REG + +} // x86 namespace +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 diff --git a/libraries/asmjit/x86/x86scheduler.cpp b/libraries/asmjit/x86/x86scheduler.cpp new file mode 100644 index 000000000..33ddb6197 --- /dev/null +++ b/libraries/asmjit/x86/x86scheduler.cpp @@ -0,0 +1,94 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Export] +#define ASMJIT_EXPORTS + +// [Guard] +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)) + +// [Dependencies - AsmJit] +#include "../base/containers.h" +#include "../x86/x86scheduler_p.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [Internals] +// ============================================================================ + +//! \internal +struct X86ScheduleData { + //! Registers read by the instruction. + X86RegMask regsIn; + //! Registers written by the instruction. + X86RegMask regsOut; + + //! Flags read by the instruction. + uint8_t flagsIn; + //! Flags written by the instruction. + uint8_t flagsOut; + + //! How many `uops` or `cycles` the instruction takes. + uint8_t ops; + //! Instruction latency. + uint8_t latency; + + //! Which ports the instruction can run at. + uint16_t ports; + //! \internal + uint16_t reserved; + + //! All instructions that this instruction depends on. + PodList::Link* dependsOn; + //! All instructions that use the result of this instruction. + PodList::Link* usedBy; +}; + +// ============================================================================ +// [asmjit::X86Scheduler - Construction / Destruction] +// ============================================================================ + +X86Scheduler::X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo) : + _compiler(compiler), + _cpuInfo(cpuInfo) {} +X86Scheduler::~X86Scheduler() {} + +// ============================================================================ +// [asmjit::X86Scheduler - Run] +// ============================================================================ + +Error X86Scheduler::run(Node* start, Node* stop) { + /* + ASMJIT_TLOG("[Schedule] === Begin ==="); + + Zone zone(8096 - kZoneOverhead); + Node* node_ = start; + + while (node_ != stop) { + Node* next = node_->getNext(); + ASMJIT_ASSERT(node_->getType() == kNodeTypeInst); + + printf(" %s\n", X86Util::getInstInfo(static_cast(node_)->getCode()).getInstName()); + node_ = next; + } + + ASMJIT_TLOG("[Schedule] === End ==="); + */ + return kErrorOk; +} + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64) diff --git a/libraries/asmjit/x86/x86scheduler_p.h b/libraries/asmjit/x86/x86scheduler_p.h new file mode 100644 index 000000000..1afeb90d3 --- /dev/null +++ b/libraries/asmjit/x86/x86scheduler_p.h @@ -0,0 +1,63 @@ +// [AsmJit] +// Complete x86/x64 JIT and Remote Assembler for C++. +// +// [License] +// Zlib - See LICENSE.md file in the package. + +// [Guard] +#ifndef _ASMJIT_X86_X86SCHEDULER_P_H +#define _ASMJIT_X86_X86SCHEDULER_P_H + +#include "../build.h" +#if !defined(ASMJIT_DISABLE_COMPILER) + +// [Dependencies - AsmJit] +#include "../x86/x86compiler.h" +#include "../x86/x86context_p.h" +#include "../x86/x86cpuinfo.h" +#include "../x86/x86inst.h" + +// [Api-Begin] +#include "../apibegin.h" + +namespace asmjit { + +// ============================================================================ +// [asmjit::X86Scheduler] +// ============================================================================ + +//! \internal +//! +//! X86 scheduler. +struct X86Scheduler { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo); + ~X86Scheduler(); + + // -------------------------------------------------------------------------- + // [Run] + // -------------------------------------------------------------------------- + + Error run(Node* start, Node* stop); + + // -------------------------------------------------------------------------- + // [Members] + // -------------------------------------------------------------------------- + + //! Attached compiler. + X86Compiler* _compiler; + //! CPU information used for scheduling. + const X86CpuInfo* _cpuInfo; +}; + +} // asmjit namespace + +// [Api-End] +#include "../apiend.h" + +// [Guard] +#endif // !ASMJIT_DISABLE_COMPILER +#endif // _ASMJIT_X86_X86SCHEDULER_P_H diff --git a/libraries/lepton/include/lepton/CompiledExpression.h b/libraries/lepton/include/lepton/CompiledExpression.h index 54473d4a5..4e16f4004 100644 --- a/libraries/lepton/include/lepton/CompiledExpression.h +++ b/libraries/lepton/include/lepton/CompiledExpression.h @@ -34,6 +34,7 @@ #include "ExpressionTreeNode.h" #include "windowsIncludes.h" +#include "asmjit.h" #include #include #include @@ -78,6 +79,7 @@ private: friend class ParsedExpression; CompiledExpression(const ParsedExpression& expression); void compileExpression(const ExpressionTreeNode& node, std::vector >& temps); + void generateJitCode(); int findTempIndex(const ExpressionTreeNode& node, std::vector >& temps); std::vector > arguments; std::vector target; @@ -87,6 +89,8 @@ private: mutable std::vector workspace; mutable std::vector argValues; std::map dummyVariables; + asmjit::JitRuntime runtime; + void* jitCode; }; } // namespace Lepton diff --git a/libraries/lepton/src/CompiledExpression.cpp b/libraries/lepton/src/CompiledExpression.cpp index 0c54af93c..5f1d173b9 100644 --- a/libraries/lepton/src/CompiledExpression.cpp +++ b/libraries/lepton/src/CompiledExpression.cpp @@ -36,14 +36,21 @@ using namespace Lepton; using namespace std; +using namespace asmjit; -CompiledExpression::CompiledExpression() { +CompiledExpression::CompiledExpression() : jitCode(NULL) { } -CompiledExpression::CompiledExpression(const ParsedExpression& expression) { +CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jitCode(NULL) { ParsedExpression expr = expression.optimize(); // Just in case it wasn't already optimized. vector > temps; compileExpression(expr.getRootNode(), temps); + int maxArguments = 1; + for (int i = 0; i < (int) operation.size(); i++) + if (operation[i]->getNumArguments() > maxArguments) + maxArguments = operation[i]->getNumArguments(); + argValues.resize(maxArguments); + generateJitCode(); } CompiledExpression::~CompiledExpression() { @@ -52,7 +59,7 @@ CompiledExpression::~CompiledExpression() { delete operation[i]; } -CompiledExpression::CompiledExpression(const CompiledExpression& expression) { +CompiledExpression::CompiledExpression(const CompiledExpression& expression) : jitCode(NULL) { *this = expression; } @@ -66,6 +73,7 @@ CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expr operation.resize(expression.operation.size()); for (int i = 0; i < (int) operation.size(); i++) operation[i] = expression.operation[i]->clone(); + generateJitCode(); return *this; } @@ -103,11 +111,8 @@ void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vecto sequential = false; if (sequential) arguments[stepIndex].push_back(args[0]); - else { + else arguments[stepIndex] = args; - if (args.size() > argValues.size()) - argValues.resize(args.size(), 0.0); - } } } temps.push_back(make_pair(node, workspace.size())); @@ -133,6 +138,9 @@ double& CompiledExpression::getVariableReference(const string& name) { } double CompiledExpression::evaluate() const { + if (jitCode != NULL) + return ((double (*)()) jitCode)(); + // Loop over the operations and evaluate each one. for (int step = 0; step < operation.size(); step++) { @@ -147,3 +155,54 @@ double CompiledExpression::evaluate() const { } return workspace[workspace.size()-1]; } + +static double evaluateOperation(Operation* op, double* args) { + map* dummyVariables = NULL; + return op->evaluate(args, *dummyVariables); +} + +void CompiledExpression::generateJitCode() { + X86Compiler c(&runtime); + c.addFunc(kFuncConvHost, FuncBuilder0()); + vector workspaceVar(workspace.size()); + for (int i = 0; i < (int) workspaceVar.size(); i++) + workspaceVar[i] = c.newXmmVar(kX86VarTypeXmmSd); + X86GpVar workspacePointer(c); + X86GpVar argsPointer(c); + c.mov(workspacePointer, imm_ptr(&workspace[0])); + c.mov(argsPointer, imm_ptr(&argValues[0])); + + // Load the variables. + + for (set::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) { + map::iterator index = variableIndices.find(*iter); + c.movsd(workspaceVar[index->second], x86::ptr(workspacePointer, 8*index->second, 0)); + } + + // Evaluate the operations. + + for (int step = 0; step < (int) operation.size(); step++) { + const vector& args = arguments[step]; + if (args.size() == 1) { + // One or more sequential arguments. + + for (int i = 0; i < operation[step]->getNumArguments(); i++) + c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[0]+i]); + } + else { + // Two or more non-sequential arguments. + + for (int i = 0; i < (int) args.size(); i++) + c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]); + } + X86GpVar fn(c, kVarTypeIntPtr); + c.mov(fn, imm_ptr((void*) evaluateOperation)); + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder2()); + call->setArg(0, imm_ptr(operation[step])); + call->setArg(1, imm_ptr(&argValues[0])); + call->setRet(0, workspaceVar[target[step]]); + } + c.ret(workspacePointer); + c.endFunc(); + jitCode = c.make(); +} -- GitLab From 9e4b043fa8422cc4271cfda1090297f2fa2d982c Mon Sep 17 00:00:00 2001 From: Christian Schwantes Date: Tue, 16 Sep 2014 14:21:47 -0700 Subject: [PATCH 003/338] Update AmoebaMultipoleForceImpl.cpp @rmcgibbo and @mpharrigan convinced me I should have just fixed it myself. --- plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp index 56a395ba0..146501de3 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp @@ -192,8 +192,8 @@ void AmoebaMultipoleForceImpl::getElectrostaticPotential( ContextImpl& context, kernel.getAs().getElectrostaticPotential(context, inputGrid, outputElectrostaticPotential); } -void AmoebaMultipoleForceImpl::getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMonents ){ - kernel.getAs().getSystemMultipoleMoments(context, outputMultipoleMonents); +void AmoebaMultipoleForceImpl::getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMoments ){ + kernel.getAs().getSystemMultipoleMoments(context, outputMultipoleMoments); } void AmoebaMultipoleForceImpl::updateParametersInContext(ContextImpl& context) { -- GitLab From a6fe70d299579b6eb24abbe7b0b7025fc591fc91 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 16 Sep 2014 14:49:52 -0700 Subject: [PATCH 004/338] JIT compilation uses optimized calculations for many of the most common operations --- .../include/lepton/CompiledExpression.h | 1 + libraries/lepton/src/CompiledExpression.cpp | 123 +++++++++++++++--- 2 files changed, 107 insertions(+), 17 deletions(-) diff --git a/libraries/lepton/include/lepton/CompiledExpression.h b/libraries/lepton/include/lepton/CompiledExpression.h index 4e16f4004..f720b116d 100644 --- a/libraries/lepton/include/lepton/CompiledExpression.h +++ b/libraries/lepton/include/lepton/CompiledExpression.h @@ -89,6 +89,7 @@ private: mutable std::vector workspace; mutable std::vector argValues; std::map dummyVariables; + std::vector constants; asmjit::JitRuntime runtime; void* jitCode; }; diff --git a/libraries/lepton/src/CompiledExpression.cpp b/libraries/lepton/src/CompiledExpression.cpp index 5f1d173b9..b287a835b 100644 --- a/libraries/lepton/src/CompiledExpression.cpp +++ b/libraries/lepton/src/CompiledExpression.cpp @@ -172,37 +172,126 @@ void CompiledExpression::generateJitCode() { c.mov(workspacePointer, imm_ptr(&workspace[0])); c.mov(argsPointer, imm_ptr(&argValues[0])); - // Load the variables. + // Load the arguments into variables. for (set::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) { map::iterator index = variableIndices.find(*iter); c.movsd(workspaceVar[index->second], x86::ptr(workspacePointer, 8*index->second, 0)); } + + // Make a list of all constants that will be needed for evaluation. + + vector operationConstantIndex(operation.size(), -1); + for (int step = 0; step < (int) operation.size(); step++) { + // Find the constant value (if any) used by this operation. + + Operation& op = *operation[step]; + double value; + if (op.getId() == Operation::CONSTANT) + value = dynamic_cast(op).getValue(); + else if (op.getId() == Operation::ADD_CONSTANT) + value = dynamic_cast(op).getValue(); + else if (op.getId() == Operation::MULTIPLY_CONSTANT) + value = dynamic_cast(op).getValue(); + else if (op.getId() == Operation::RECIPROCAL) + value = 1.0; + else + continue; + + // See if we already have a variable for this constant. + + for (int i = 0; i < (int) constants.size(); i++) + if (value == constants[i]) { + operationConstantIndex[step] = i; + break; + } + if (operationConstantIndex[step] == -1) { + operationConstantIndex[step] = constants.size(); + constants.push_back(value); + } + } + + // Load constants into variables. + + vector constantVar(constants.size()); + X86GpVar constantsPointer(c); + c.mov(constantsPointer, imm_ptr(&constants[0])); + for (int i = 0; i < (constants.size()); i++) { + constantVar[i] = c.newXmmVar(kX86VarTypeXmmSd); + c.movsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0)); + } // Evaluate the operations. for (int step = 0; step < (int) operation.size(); step++) { - const vector& args = arguments[step]; + Operation& op = *operation[step]; + vector args = arguments[step]; if (args.size() == 1) { - // One or more sequential arguments. + // One or more sequential arguments. Fill out the list. - for (int i = 0; i < operation[step]->getNumArguments(); i++) - c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[0]+i]); + for (int i = 1; i < op.getNumArguments(); i++) + args.push_back(args[0]+i); } - else { - // Two or more non-sequential arguments. - - for (int i = 0; i < (int) args.size(); i++) - c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]); + switch (op.getId()) { + case Operation::CONSTANT: + c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::ADD: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.addsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::SUBTRACT: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.subsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::MULTIPLY: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::DIVIDE: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.divsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::NEGATE: + c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); + c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::SQRT: + c.sqrtsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::SQUARE: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::CUBE: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::RECIPROCAL: + c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::ADD_CONSTANT: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::MULTIPLY_CONSTANT: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + default: + for (int i = 0; i < (int) args.size(); i++) + c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]); + X86GpVar fn(c, kVarTypeIntPtr); + c.mov(fn, imm_ptr((void*) evaluateOperation)); + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder2()); + call->setArg(0, imm_ptr(&op)); + call->setArg(1, imm_ptr(&argValues[0])); + call->setRet(0, workspaceVar[target[step]]); } - X86GpVar fn(c, kVarTypeIntPtr); - c.mov(fn, imm_ptr((void*) evaluateOperation)); - X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder2()); - call->setArg(0, imm_ptr(operation[step])); - call->setArg(1, imm_ptr(&argValues[0])); - call->setRet(0, workspaceVar[target[step]]); } - c.ret(workspacePointer); + c.ret(workspaceVar[workspace.size()-1]); c.endFunc(); jitCode = c.make(); } -- GitLab From 4a25dc798cbc106b2f3f3c21041634975a4cb56d Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 16 Sep 2014 16:32:42 -0700 Subject: [PATCH 005/338] Added more optimized operations to JIT compilation --- .../include/lepton/CompiledExpression.h | 1 + libraries/lepton/src/CompiledExpression.cpp | 87 ++++++++++++++++--- tests/TestParser.cpp | 42 +++++++-- 3 files changed, 109 insertions(+), 21 deletions(-) diff --git a/libraries/lepton/include/lepton/CompiledExpression.h b/libraries/lepton/include/lepton/CompiledExpression.h index f720b116d..ff1c17594 100644 --- a/libraries/lepton/include/lepton/CompiledExpression.h +++ b/libraries/lepton/include/lepton/CompiledExpression.h @@ -80,6 +80,7 @@ private: CompiledExpression(const ParsedExpression& expression); void compileExpression(const ExpressionTreeNode& node, std::vector >& temps); void generateJitCode(); + void generateSingleArgCall(asmjit::X86Compiler& c, asmjit::X86XmmVar& dest, asmjit::X86XmmVar& arg, double (*function)(double)); int findTempIndex(const ExpressionTreeNode& node, std::vector >& temps); std::vector > arguments; std::vector target; diff --git a/libraries/lepton/src/CompiledExpression.cpp b/libraries/lepton/src/CompiledExpression.cpp index b287a835b..e14d17c51 100644 --- a/libraries/lepton/src/CompiledExpression.cpp +++ b/libraries/lepton/src/CompiledExpression.cpp @@ -195,6 +195,10 @@ void CompiledExpression::generateJitCode() { value = dynamic_cast(op).getValue(); else if (op.getId() == Operation::RECIPROCAL) value = 1.0; + else if (op.getId() == Operation::STEP) + value = 1.0; + else if (op.getId() == Operation::DELTA) + value = 1.0; else continue; @@ -232,55 +236,106 @@ void CompiledExpression::generateJitCode() { for (int i = 1; i < op.getNumArguments(); i++) args.push_back(args[0]+i); } + + // Generate instructions to execute this operation. + switch (op.getId()) { case Operation::CONSTANT: c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); break; case Operation::ADD: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.addsd(workspaceVar[target[step]], workspaceVar[args[1]]); + c.addsd(workspaceVar[target[step]], workspaceVar[args[1]]); break; case Operation::SUBTRACT: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.subsd(workspaceVar[target[step]], workspaceVar[args[1]]); + c.subsd(workspaceVar[target[step]], workspaceVar[args[1]]); break; case Operation::MULTIPLY: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]); break; case Operation::DIVIDE: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.divsd(workspaceVar[target[step]], workspaceVar[args[1]]); + c.divsd(workspaceVar[target[step]], workspaceVar[args[1]]); break; case Operation::NEGATE: c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); - c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]); break; case Operation::SQRT: - c.sqrtsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.sqrtsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::EXP: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], exp); + break; + case Operation::LOG: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], log); + break; + case Operation::SIN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sin); + break; + case Operation::COS: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cos); + break; + case Operation::TAN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tan); + break; + case Operation::ASIN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], asin); + break; + case Operation::ACOS: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], acos); + break; + case Operation::ATAN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], atan); + break; + case Operation::SINH: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sinh); + break; + case Operation::COSH: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cosh); + break; + case Operation::TANH: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tanh); + break; + case Operation::STEP: + c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); + c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(18)); // Comparison mode is _CMP_LE_OQ = 18 + c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::DELTA: + c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); + c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(16)); // Comparison mode is _CMP_EQ_OS = 16 + c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); break; case Operation::SQUARE: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); break; case Operation::CUBE: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); break; case Operation::RECIPROCAL: c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); - c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]); break; case Operation::ADD_CONSTANT: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); break; case Operation::MULTIPLY_CONSTANT: c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + c.mulsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::ABS: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], fabs); break; default: + // Just invoke evaluateOperation(). + for (int i = 0; i < (int) args.size(); i++) c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]); X86GpVar fn(c, kVarTypeIntPtr); @@ -295,3 +350,11 @@ void CompiledExpression::generateJitCode() { c.endFunc(); jitCode = c.make(); } + +void CompiledExpression::generateSingleArgCall(X86Compiler& c, X86XmmVar& dest, X86XmmVar& arg, double (*function)(double)) { + X86GpVar fn(c, kVarTypeIntPtr); + c.mov(fn, imm_ptr((void*) function)); + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1()); + call->setArg(0, arg); + call->setRet(0, dest); +} diff --git a/tests/TestParser.cpp b/tests/TestParser.cpp index 8a55eb225..63c7a7735 100644 --- a/tests/TestParser.cpp +++ b/tests/TestParser.cpp @@ -127,6 +127,18 @@ void verifyInvalidExpression(const string& expression) { throw exception(); } +/** + * Verify that two numbers have the same value. + */ + +void assertNumbersEqual(double val1, double val2) { + const double inf = numeric_limits::infinity(); + if (val1 == val1 || val2 == val2) // If both are NaN, that's fine. + if (val1 != inf || val2 != inf) // Both infinity is also fine. + if (val1 != -inf || val2 != -inf) // Same for -infinity. + ASSERT_EQUAL_TOL(val1, val2, 1e-10); +} + /** * Verify that two expressions give the same value. */ @@ -137,11 +149,22 @@ void verifySameValue(const ParsedExpression& exp1, const ParsedExpression& exp2, variables["y"] = y; double val1 = exp1.evaluate(variables); double val2 = exp2.evaluate(variables); - const double inf = numeric_limits::infinity(); - if (val1 == val1 || val2 == val2) // If both are NaN, that's fine. - if (val1 != inf || val2 != inf) // Both infinity is also fine. - if (val1 != -inf || val2 != -inf) // Same for -infinity. - ASSERT_EQUAL_TOL(val1, val2, 1e-10); + assertNumbersEqual(val1, val2); + + // Now create CompiledExpressions from them and see if those also match. + + CompiledExpression compiled1 = exp1.createCompiledExpression(); + CompiledExpression compiled2 = exp2.createCompiledExpression(); + if (compiled1.getVariables().find("x") != compiled1.getVariables().end()) + compiled1.getVariableReference("x") = x; + if (compiled1.getVariables().find("y") != compiled1.getVariables().end()) + compiled1.getVariableReference("y") = y; + if (compiled2.getVariables().find("x") != compiled2.getVariables().end()) + compiled2.getVariableReference("x") = x; + if (compiled2.getVariables().find("y") != compiled2.getVariables().end()) + compiled2.getVariableReference("y") = y; + assertNumbersEqual(val1, compiled1.evaluate()); + assertNumbersEqual(val2, compiled2.evaluate()); } /** @@ -171,14 +194,14 @@ void testCustomFunction(const string& expression, const string& equivalent) { verifySameValue(exp1, exp2, 2.0, 3.0); verifySameValue(exp1, exp2, -2.0, 3.0); verifySameValue(exp1, exp2, 2.0, -3.0); - ParsedExpression deriv1 = exp1.differentiate("x"); - ParsedExpression deriv2 = exp2.differentiate("x"); + ParsedExpression deriv1 = exp1.differentiate("x").optimize(); + ParsedExpression deriv2 = exp2.differentiate("x").optimize(); verifySameValue(deriv1, deriv2, 1.0, 2.0); verifySameValue(deriv1, deriv2, 2.0, 3.0); verifySameValue(deriv1, deriv2, -2.0, 3.0); verifySameValue(deriv1, deriv2, 2.0, -3.0); - ParsedExpression deriv3 = deriv1.differentiate("y"); - ParsedExpression deriv4 = deriv2.differentiate("y"); + ParsedExpression deriv3 = deriv1.differentiate("y").optimize(); + ParsedExpression deriv4 = deriv2.differentiate("y").optimize(); verifySameValue(deriv3, deriv4, 1.0, 2.0); verifySameValue(deriv3, deriv4, 2.0, 3.0); verifySameValue(deriv3, deriv4, -2.0, 3.0); @@ -223,6 +246,7 @@ int main() { verifyEvaluation("max(x, -1)", 2.0, 3.0, 2.0); verifyEvaluation("abs(x-y)", 2.0, 3.0, 1.0); verifyEvaluation("delta(x)+3*delta(y-1.5)", 2.0, 1.5, 3.0); + verifyEvaluation("step(x-3)+y*step(x)", 2.0, 3.0, 3.0); verifyInvalidExpression("1..2"); verifyInvalidExpression("1*(2+3"); verifyInvalidExpression("5++4"); -- GitLab From 6c8c0dd36dff340429926d3e088349ffc6a878e6 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 16 Sep 2014 16:58:42 -0700 Subject: [PATCH 006/338] Added #ifdefs and CMake logic for deciding when to use JIT --- CMakeLists.txt | 8 ++++++++ .../lepton/include/lepton/CompiledExpression.h | 12 ++++++++---- libraries/lepton/src/CompiledExpression.cpp | 17 +++++++++++++---- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6cd196b3..ecd15a985 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,6 +269,14 @@ IF (ANDROID OR PNACL) ELSE (ANDROID OR PNACL) SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/libraries/sfmt/src/SFMT.cpp PROPERTIES COMPILE_FLAGS "-DHAVE_SSE2=1") ENDIF(ANDROID OR PNACL) +IF (NOT (ANDROID OR PNACL)) + FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*/*.cpp) + FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*.h) + SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) + SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) + INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit") + SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DLEPTON_USE_JIT") +ENDIF (NOT (ANDROID OR PNACL)) # If API wrappers are being generated, and add them to the build. SET(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS ON CACHE BOOL "Build wrappers for C and Fortran") diff --git a/libraries/lepton/include/lepton/CompiledExpression.h b/libraries/lepton/include/lepton/CompiledExpression.h index ff1c17594..38721a980 100644 --- a/libraries/lepton/include/lepton/CompiledExpression.h +++ b/libraries/lepton/include/lepton/CompiledExpression.h @@ -34,11 +34,13 @@ #include "ExpressionTreeNode.h" #include "windowsIncludes.h" -#include "asmjit.h" #include #include #include #include +#ifdef LEPTON_USE_JIT + #include "asmjit.h" +#endif namespace Lepton { @@ -79,8 +81,6 @@ private: friend class ParsedExpression; CompiledExpression(const ParsedExpression& expression); void compileExpression(const ExpressionTreeNode& node, std::vector >& temps); - void generateJitCode(); - void generateSingleArgCall(asmjit::X86Compiler& c, asmjit::X86XmmVar& dest, asmjit::X86XmmVar& arg, double (*function)(double)); int findTempIndex(const ExpressionTreeNode& node, std::vector >& temps); std::vector > arguments; std::vector target; @@ -90,9 +90,13 @@ private: mutable std::vector workspace; mutable std::vector argValues; std::map dummyVariables; + void* jitCode; +#ifdef LEPTON_USE_JIT + void generateJitCode(); + void generateSingleArgCall(asmjit::X86Compiler& c, asmjit::X86XmmVar& dest, asmjit::X86XmmVar& arg, double (*function)(double)); std::vector constants; asmjit::JitRuntime runtime; - void* jitCode; +#endif }; } // namespace Lepton diff --git a/libraries/lepton/src/CompiledExpression.cpp b/libraries/lepton/src/CompiledExpression.cpp index e14d17c51..76f8ba087 100644 --- a/libraries/lepton/src/CompiledExpression.cpp +++ b/libraries/lepton/src/CompiledExpression.cpp @@ -36,7 +36,9 @@ using namespace Lepton; using namespace std; -using namespace asmjit; +#ifdef LEPTON_USE_JIT + using namespace asmjit; +#endif CompiledExpression::CompiledExpression() : jitCode(NULL) { } @@ -50,7 +52,9 @@ CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jit if (operation[i]->getNumArguments() > maxArguments) maxArguments = operation[i]->getNumArguments(); argValues.resize(maxArguments); +#ifdef LEPTON_USE_JIT generateJitCode(); +#endif } CompiledExpression::~CompiledExpression() { @@ -73,7 +77,9 @@ CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expr operation.resize(expression.operation.size()); for (int i = 0; i < (int) operation.size(); i++) operation[i] = expression.operation[i]->clone(); +#ifdef LEPTON_USE_JIT generateJitCode(); +#endif return *this; } @@ -138,9 +144,9 @@ double& CompiledExpression::getVariableReference(const string& name) { } double CompiledExpression::evaluate() const { - if (jitCode != NULL) - return ((double (*)()) jitCode)(); - +#ifdef LEPTON_USE_JIT + return ((double (*)()) jitCode)(); +#else // Loop over the operations and evaluate each one. for (int step = 0; step < operation.size(); step++) { @@ -154,8 +160,10 @@ double CompiledExpression::evaluate() const { } } return workspace[workspace.size()-1]; +#endif } +#ifdef LEPTON_USE_JIT static double evaluateOperation(Operation* op, double* args) { map* dummyVariables = NULL; return op->evaluate(args, *dummyVariables); @@ -358,3 +366,4 @@ void CompiledExpression::generateSingleArgCall(X86Compiler& c, X86XmmVar& dest, call->setArg(0, arg); call->setRet(0, dest); } +#endif \ No newline at end of file -- GitLab From 96b61389de9b3bfa9d9b0fc7bf769fc093c39453 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 16 Sep 2014 17:35:03 -0700 Subject: [PATCH 007/338] Fixed compilation error on Linux --- CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecd15a985..45c976a3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -290,9 +290,14 @@ INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src) SET(OPENMM_BUILD_SHARED_LIB ON CACHE BOOL "Whether to build shared OpenMM libraries") +SET(EXTRA_LINK_FLAGS ${EXTRA_COMPILE_FLAGS}) +IF (CMAKE_SYSTEM_NAME MATCHES "Linux") + SET(EXTRA_LINK_FLAGS "${EXTRA_LINK_FLAGS} -lrt") +ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux") + IF(OPENMM_BUILD_SHARED_LIB) ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES}) - SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY -DLEPTON_BUILDING_SHARED_LIBRARY -DOPENMM_VALIDATE_BUILDING_SHARED_LIBRARY") + SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY -DLEPTON_BUILDING_SHARED_LIBRARY -DOPENMM_VALIDATE_BUILDING_SHARED_LIBRARY") IF(WIN32) ADD_DEPENDENCIES(${SHARED_TARGET} PthreadsLibraries) ENDIF(WIN32) @@ -302,7 +307,7 @@ SET(OPENMM_BUILD_STATIC_LIB OFF CACHE BOOL "Whether to build static OpenMM libra IF(OPENMM_BUILD_STATIC_LIB) ADD_LIBRARY(${STATIC_TARGET} STATIC ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES}) SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_USE_STATIC_LIBRARIES -DLEPTON_USE_STATIC_LIBRARIES -DPTW32_STATIC_LIB") - SET_TARGET_PROPERTIES(${STATIC_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_STATIC_LIBRARY -DLEPTON_BUILDING_STATIC_LIBRARY -DOPENMMM_VALIDATE_BUILDING_STATIC_LIBRARY -DOPENMM_VALIDATE_BUILDING_STATIC_LIBRARY") + SET_TARGET_PROPERTIES(${STATIC_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_STATIC_LIBRARY -DLEPTON_BUILDING_STATIC_LIBRARY -DOPENMMM_VALIDATE_BUILDING_STATIC_LIBRARY -DOPENMM_VALIDATE_BUILDING_STATIC_LIBRARY") ENDIF(OPENMM_BUILD_STATIC_LIB) IF(OPENMM_BUILD_C_AND_FORTRAN_WRAPPERS) -- GitLab From abe3e901e6d6fe27fbc1f23e4c49ac8460e19eff Mon Sep 17 00:00:00 2001 From: Christian Schwantes Date: Tue, 16 Sep 2014 19:54:08 -0700 Subject: [PATCH 008/338] Update AmoebaMultipoleForceImpl.h typo fix --- .../include/openmm/internal/AmoebaMultipoleForceImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h index 5e2407fc0..cb0583663 100644 --- a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h +++ b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h @@ -87,7 +87,7 @@ public: void getElectrostaticPotential( ContextImpl& context, const std::vector< Vec3 >& inputGrid, std::vector< double >& outputElectrostaticPotential ); - void getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMonents ); + void getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMoments ); void updateParametersInContext(ContextImpl& context); -- GitLab From e03fe920e55bffe547a92b722fe9cef5255b61fe Mon Sep 17 00:00:00 2001 From: Christian Schwantes Date: Tue, 16 Sep 2014 19:55:23 -0700 Subject: [PATCH 009/338] Update AmoebaMultipoleForce.cpp typo fix --- plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp index 5f1079b08..0ac8d5f79 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp @@ -234,8 +234,8 @@ void AmoebaMultipoleForce::getElectrostaticPotential( const std::vector< Vec3 >& dynamic_cast(getImplInContext(context)).getElectrostaticPotential(getContextImpl(context), inputGrid, outputElectrostaticPotential); } -void AmoebaMultipoleForce::getSystemMultipoleMoments(Context& context, std::vector< double >& outputMultipoleMonents ){ - dynamic_cast(getImplInContext(context)).getSystemMultipoleMoments(getContextImpl(context), outputMultipoleMonents); +void AmoebaMultipoleForce::getSystemMultipoleMoments(Context& context, std::vector< double >& outputMultipoleMoments ){ + dynamic_cast(getImplInContext(context)).getSystemMultipoleMoments(getContextImpl(context), outputMultipoleMoments); } ForceImpl* AmoebaMultipoleForce::createImpl() const { -- GitLab From c4dbd03e3fcbfda3abb417db603d391079425696 Mon Sep 17 00:00:00 2001 From: Christian Schwantes Date: Tue, 16 Sep 2014 19:57:55 -0700 Subject: [PATCH 010/338] Update AmoebaMultipoleForce.h typo fix --- plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h index d97c8a529..ef7cf29b1 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h @@ -330,7 +330,7 @@ public: * the quadrupole moment is still undefined and should be ignored. * * @param context context - * @param outputMultipoleMonents (charge, + * @param outputMultipoleMoments (charge, dipole_x, dipole_y, dipole_z, quadrupole_xx, quadrupole_xy, quadrupole_xz, quadrupole_yx, quadrupole_yy, quadrupole_yz, -- GitLab From bad2b091bd13f1d872b930d655806dbfa82bcb44 Mon Sep 17 00:00:00 2001 From: Christian Schwantes Date: Tue, 16 Sep 2014 19:58:40 -0700 Subject: [PATCH 011/338] Update amoebaKernels.h typo fix --- plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h b/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h index 433fec2aa..30c4ddba4 100644 --- a/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h +++ b/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h @@ -353,7 +353,7 @@ public: virtual void getElectrostaticPotential( ContextImpl& context, const std::vector< Vec3 >& inputGrid, std::vector< double >& outputElectrostaticPotential ) = 0; - virtual void getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMonents ) = 0; + virtual void getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMoments ) = 0; /** * Copy changed parameters over to a context. * -- GitLab From b9b55b047883236ce63ff44a1f00a0d8106307f7 Mon Sep 17 00:00:00 2001 From: Christian Schwantes Date: Tue, 16 Sep 2014 19:59:47 -0700 Subject: [PATCH 012/338] Update AmoebaReferenceKernels.h typo fix --- plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h index 7cb4442bd..dd0359e37 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h @@ -387,7 +387,7 @@ public: * Get the system multipole moments. * * @param context context - * @param outputMultipoleMonents vector of multipole moments: + * @param outputMultipoleMoments vector of multipole moments: (charge, dipole_x, dipole_y, dipole_z, quadrupole_xx, quadrupole_xy, quadrupole_xz, -- GitLab From 400b2a2492bf5a734c534f8bccb99b6e127b35e0 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 17 Sep 2014 15:02:10 -0400 Subject: [PATCH 013/338] Fix issue where the last CMAP defined in a parameter file is not added to the parameter set. --- wrappers/python/simtk/openmm/app/charmmparameterset.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/charmmparameterset.py b/wrappers/python/simtk/openmm/app/charmmparameterset.py index 2b142141a..ab827cd41 100644 --- a/wrappers/python/simtk/openmm/app/charmmparameterset.py +++ b/wrappers/python/simtk/openmm/app/charmmparameterset.py @@ -13,7 +13,7 @@ Copyright (c) 2014 the Authors Author: Jason M. Swails Contributors: -Date: July 17, 2014 +Date: Sep. 17, 2014 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -473,6 +473,11 @@ class CharmmParameterSet(object): self.nbfix_types[(min(at1, at2), max(at1, at2))] = (emin, rmin) # Now we're done. Load the nonbonded types into the relevant AtomType # instances. In order for this to work, all keys in nonbonded_types + if current_cmap is not None: + ty = CmapType(current_cmap_res, current_cmap_data) + self.cmap_types[current_cmap] = ty + # Now we're done. Load the nonbonded types into the relevant AtomType + # instances. In order for this to work, all keys in nonbonded_types # must be in the self.atom_types_str dict. Raise a RuntimeError if this # is not satisfied try: -- GitLab From 94ac0e3c49dcf13b035216e0f3ff128f60b07d60 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 17 Sep 2014 19:19:36 -0400 Subject: [PATCH 014/338] Fix comments. --- wrappers/python/simtk/openmm/app/charmmparameterset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/charmmparameterset.py b/wrappers/python/simtk/openmm/app/charmmparameterset.py index ab827cd41..4740dc004 100644 --- a/wrappers/python/simtk/openmm/app/charmmparameterset.py +++ b/wrappers/python/simtk/openmm/app/charmmparameterset.py @@ -471,8 +471,8 @@ class CharmmParameterSet(object): except IndexError: raise CharmmFileError('Could not parse NBFIX terms.') self.nbfix_types[(min(at1, at2), max(at1, at2))] = (emin, rmin) - # Now we're done. Load the nonbonded types into the relevant AtomType - # instances. In order for this to work, all keys in nonbonded_types + # If there were any CMAP terms stored in the parameter set, the last one + # defined will not have been added to the set. Add it now. if current_cmap is not None: ty = CmapType(current_cmap_res, current_cmap_data) self.cmap_types[current_cmap] = ty -- GitLab From 2f2357f617650873de0a00f685aa07455f9725e6 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 18 Sep 2014 14:34:29 -0700 Subject: [PATCH 015/338] Fixed an illegal memory access --- libraries/lepton/src/CompiledExpression.cpp | 738 ++++++++++---------- 1 file changed, 370 insertions(+), 368 deletions(-) diff --git a/libraries/lepton/src/CompiledExpression.cpp b/libraries/lepton/src/CompiledExpression.cpp index 76f8ba087..bce301050 100644 --- a/libraries/lepton/src/CompiledExpression.cpp +++ b/libraries/lepton/src/CompiledExpression.cpp @@ -1,369 +1,371 @@ -/* -------------------------------------------------------------------------- * - * Lepton * - * -------------------------------------------------------------------------- * - * This is part of the Lepton expression parser 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) 2013 Stanford University and the Authors. * - * Authors: Peter Eastman * - * 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 "lepton/CompiledExpression.h" -#include "lepton/Operation.h" -#include "lepton/ParsedExpression.h" -#include - -using namespace Lepton; -using namespace std; -#ifdef LEPTON_USE_JIT - using namespace asmjit; -#endif - -CompiledExpression::CompiledExpression() : jitCode(NULL) { -} - -CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jitCode(NULL) { - ParsedExpression expr = expression.optimize(); // Just in case it wasn't already optimized. - vector > temps; - compileExpression(expr.getRootNode(), temps); - int maxArguments = 1; - for (int i = 0; i < (int) operation.size(); i++) - if (operation[i]->getNumArguments() > maxArguments) - maxArguments = operation[i]->getNumArguments(); - argValues.resize(maxArguments); -#ifdef LEPTON_USE_JIT - generateJitCode(); -#endif -} - -CompiledExpression::~CompiledExpression() { - for (int i = 0; i < (int) operation.size(); i++) - if (operation[i] != NULL) - delete operation[i]; -} - -CompiledExpression::CompiledExpression(const CompiledExpression& expression) : jitCode(NULL) { - *this = expression; -} - -CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expression) { - arguments = expression.arguments; - target = expression.target; - variableIndices = expression.variableIndices; - variableNames = expression.variableNames; - workspace.resize(expression.workspace.size()); - argValues.resize(expression.argValues.size()); - operation.resize(expression.operation.size()); - for (int i = 0; i < (int) operation.size(); i++) - operation[i] = expression.operation[i]->clone(); -#ifdef LEPTON_USE_JIT - generateJitCode(); -#endif - return *this; -} - -void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector >& temps) { - if (findTempIndex(node, temps) != -1) - return; // We have already processed a node identical to this one. - - // Process the child nodes. - - vector args; - for (int i = 0; i < node.getChildren().size(); i++) { - compileExpression(node.getChildren()[i], temps); - args.push_back(findTempIndex(node.getChildren()[i], temps)); - } - - // Process this node. - - if (node.getOperation().getId() == Operation::VARIABLE) { - variableIndices[node.getOperation().getName()] = (int) workspace.size(); - variableNames.insert(node.getOperation().getName()); - } - else { - int stepIndex = (int) arguments.size(); - arguments.push_back(vector()); - target.push_back((int) workspace.size()); - operation.push_back(node.getOperation().clone()); - if (args.size() == 0) - arguments[stepIndex].push_back(0); // The value won't actually be used. We just need something there. - else { - // If the arguments are sequential, we can just pass a pointer to the first one. - - bool sequential = true; - for (int i = 1; i < args.size(); i++) - if (args[i] != args[i-1]+1) - sequential = false; - if (sequential) - arguments[stepIndex].push_back(args[0]); - else - arguments[stepIndex] = args; - } - } - temps.push_back(make_pair(node, workspace.size())); - workspace.push_back(0.0); -} - -int CompiledExpression::findTempIndex(const ExpressionTreeNode& node, vector >& temps) { - for (int i = 0; i < (int) temps.size(); i++) - if (temps[i].first == node) - return i; - return -1; -} - -const set& CompiledExpression::getVariables() const { - return variableNames; -} - -double& CompiledExpression::getVariableReference(const string& name) { - map::iterator index = variableIndices.find(name); - if (index == variableIndices.end()) - throw Exception("getVariableReference: Unknown variable '"+name+"'"); - return workspace[index->second]; -} - -double CompiledExpression::evaluate() const { -#ifdef LEPTON_USE_JIT - return ((double (*)()) jitCode)(); -#else - // Loop over the operations and evaluate each one. - - for (int step = 0; step < operation.size(); step++) { - const vector& args = arguments[step]; - if (args.size() == 1) - workspace[target[step]] = operation[step]->evaluate(&workspace[args[0]], dummyVariables); - else { - for (int i = 0; i < args.size(); i++) - argValues[i] = workspace[args[i]]; - workspace[target[step]] = operation[step]->evaluate(&argValues[0], dummyVariables); - } - } - return workspace[workspace.size()-1]; -#endif -} - -#ifdef LEPTON_USE_JIT -static double evaluateOperation(Operation* op, double* args) { - map* dummyVariables = NULL; - return op->evaluate(args, *dummyVariables); -} - -void CompiledExpression::generateJitCode() { - X86Compiler c(&runtime); - c.addFunc(kFuncConvHost, FuncBuilder0()); - vector workspaceVar(workspace.size()); - for (int i = 0; i < (int) workspaceVar.size(); i++) - workspaceVar[i] = c.newXmmVar(kX86VarTypeXmmSd); - X86GpVar workspacePointer(c); - X86GpVar argsPointer(c); - c.mov(workspacePointer, imm_ptr(&workspace[0])); - c.mov(argsPointer, imm_ptr(&argValues[0])); - - // Load the arguments into variables. - - for (set::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) { - map::iterator index = variableIndices.find(*iter); - c.movsd(workspaceVar[index->second], x86::ptr(workspacePointer, 8*index->second, 0)); - } - - // Make a list of all constants that will be needed for evaluation. - - vector operationConstantIndex(operation.size(), -1); - for (int step = 0; step < (int) operation.size(); step++) { - // Find the constant value (if any) used by this operation. - - Operation& op = *operation[step]; - double value; - if (op.getId() == Operation::CONSTANT) - value = dynamic_cast(op).getValue(); - else if (op.getId() == Operation::ADD_CONSTANT) - value = dynamic_cast(op).getValue(); - else if (op.getId() == Operation::MULTIPLY_CONSTANT) - value = dynamic_cast(op).getValue(); - else if (op.getId() == Operation::RECIPROCAL) - value = 1.0; - else if (op.getId() == Operation::STEP) - value = 1.0; - else if (op.getId() == Operation::DELTA) - value = 1.0; - else - continue; - - // See if we already have a variable for this constant. - - for (int i = 0; i < (int) constants.size(); i++) - if (value == constants[i]) { - operationConstantIndex[step] = i; - break; - } - if (operationConstantIndex[step] == -1) { - operationConstantIndex[step] = constants.size(); - constants.push_back(value); - } - } - - // Load constants into variables. - - vector constantVar(constants.size()); - X86GpVar constantsPointer(c); - c.mov(constantsPointer, imm_ptr(&constants[0])); - for (int i = 0; i < (constants.size()); i++) { - constantVar[i] = c.newXmmVar(kX86VarTypeXmmSd); - c.movsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0)); - } - - // Evaluate the operations. - - for (int step = 0; step < (int) operation.size(); step++) { - Operation& op = *operation[step]; - vector args = arguments[step]; - if (args.size() == 1) { - // One or more sequential arguments. Fill out the list. - - for (int i = 1; i < op.getNumArguments(); i++) - args.push_back(args[0]+i); - } - - // Generate instructions to execute this operation. - - switch (op.getId()) { - case Operation::CONSTANT: - c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); - break; - case Operation::ADD: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.addsd(workspaceVar[target[step]], workspaceVar[args[1]]); - break; - case Operation::SUBTRACT: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.subsd(workspaceVar[target[step]], workspaceVar[args[1]]); - break; - case Operation::MULTIPLY: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]); - break; - case Operation::DIVIDE: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.divsd(workspaceVar[target[step]], workspaceVar[args[1]]); - break; - case Operation::NEGATE: - c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); - c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]); - break; - case Operation::SQRT: - c.sqrtsd(workspaceVar[target[step]], workspaceVar[args[0]]); - break; - case Operation::EXP: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], exp); - break; - case Operation::LOG: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], log); - break; - case Operation::SIN: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sin); - break; - case Operation::COS: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cos); - break; - case Operation::TAN: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tan); - break; - case Operation::ASIN: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], asin); - break; - case Operation::ACOS: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], acos); - break; - case Operation::ATAN: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], atan); - break; - case Operation::SINH: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sinh); - break; - case Operation::COSH: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cosh); - break; - case Operation::TANH: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tanh); - break; - case Operation::STEP: - c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); - c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(18)); // Comparison mode is _CMP_LE_OQ = 18 - c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); - break; - case Operation::DELTA: - c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); - c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(16)); // Comparison mode is _CMP_EQ_OS = 16 - c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); - break; - case Operation::SQUARE: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); - break; - case Operation::CUBE: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); - break; - case Operation::RECIPROCAL: - c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); - c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]); - break; - case Operation::ADD_CONSTANT: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); - break; - case Operation::MULTIPLY_CONSTANT: - c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); - c.mulsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); - break; - case Operation::ABS: - generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], fabs); - break; - default: - // Just invoke evaluateOperation(). - - for (int i = 0; i < (int) args.size(); i++) - c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]); - X86GpVar fn(c, kVarTypeIntPtr); - c.mov(fn, imm_ptr((void*) evaluateOperation)); - X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder2()); - call->setArg(0, imm_ptr(&op)); - call->setArg(1, imm_ptr(&argValues[0])); - call->setRet(0, workspaceVar[target[step]]); - } - } - c.ret(workspaceVar[workspace.size()-1]); - c.endFunc(); - jitCode = c.make(); -} - -void CompiledExpression::generateSingleArgCall(X86Compiler& c, X86XmmVar& dest, X86XmmVar& arg, double (*function)(double)) { - X86GpVar fn(c, kVarTypeIntPtr); - c.mov(fn, imm_ptr((void*) function)); - X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1()); - call->setArg(0, arg); - call->setRet(0, dest); -} +/* -------------------------------------------------------------------------- * + * Lepton * + * -------------------------------------------------------------------------- * + * This is part of the Lepton expression parser 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) 2013 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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 "lepton/CompiledExpression.h" +#include "lepton/Operation.h" +#include "lepton/ParsedExpression.h" +#include + +using namespace Lepton; +using namespace std; +#ifdef LEPTON_USE_JIT + using namespace asmjit; +#endif + +CompiledExpression::CompiledExpression() : jitCode(NULL) { +} + +CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jitCode(NULL) { + ParsedExpression expr = expression.optimize(); // Just in case it wasn't already optimized. + vector > temps; + compileExpression(expr.getRootNode(), temps); + int maxArguments = 1; + for (int i = 0; i < (int) operation.size(); i++) + if (operation[i]->getNumArguments() > maxArguments) + maxArguments = operation[i]->getNumArguments(); + argValues.resize(maxArguments); +#ifdef LEPTON_USE_JIT + generateJitCode(); +#endif +} + +CompiledExpression::~CompiledExpression() { + for (int i = 0; i < (int) operation.size(); i++) + if (operation[i] != NULL) + delete operation[i]; +} + +CompiledExpression::CompiledExpression(const CompiledExpression& expression) : jitCode(NULL) { + *this = expression; +} + +CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expression) { + arguments = expression.arguments; + target = expression.target; + variableIndices = expression.variableIndices; + variableNames = expression.variableNames; + workspace.resize(expression.workspace.size()); + argValues.resize(expression.argValues.size()); + operation.resize(expression.operation.size()); + for (int i = 0; i < (int) operation.size(); i++) + operation[i] = expression.operation[i]->clone(); +#ifdef LEPTON_USE_JIT + generateJitCode(); +#endif + return *this; +} + +void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector >& temps) { + if (findTempIndex(node, temps) != -1) + return; // We have already processed a node identical to this one. + + // Process the child nodes. + + vector args; + for (int i = 0; i < node.getChildren().size(); i++) { + compileExpression(node.getChildren()[i], temps); + args.push_back(findTempIndex(node.getChildren()[i], temps)); + } + + // Process this node. + + if (node.getOperation().getId() == Operation::VARIABLE) { + variableIndices[node.getOperation().getName()] = (int) workspace.size(); + variableNames.insert(node.getOperation().getName()); + } + else { + int stepIndex = (int) arguments.size(); + arguments.push_back(vector()); + target.push_back((int) workspace.size()); + operation.push_back(node.getOperation().clone()); + if (args.size() == 0) + arguments[stepIndex].push_back(0); // The value won't actually be used. We just need something there. + else { + // If the arguments are sequential, we can just pass a pointer to the first one. + + bool sequential = true; + for (int i = 1; i < args.size(); i++) + if (args[i] != args[i-1]+1) + sequential = false; + if (sequential) + arguments[stepIndex].push_back(args[0]); + else + arguments[stepIndex] = args; + } + } + temps.push_back(make_pair(node, workspace.size())); + workspace.push_back(0.0); +} + +int CompiledExpression::findTempIndex(const ExpressionTreeNode& node, vector >& temps) { + for (int i = 0; i < (int) temps.size(); i++) + if (temps[i].first == node) + return i; + return -1; +} + +const set& CompiledExpression::getVariables() const { + return variableNames; +} + +double& CompiledExpression::getVariableReference(const string& name) { + map::iterator index = variableIndices.find(name); + if (index == variableIndices.end()) + throw Exception("getVariableReference: Unknown variable '"+name+"'"); + return workspace[index->second]; +} + +double CompiledExpression::evaluate() const { +#ifdef LEPTON_USE_JIT + return ((double (*)()) jitCode)(); +#else + // Loop over the operations and evaluate each one. + + for (int step = 0; step < operation.size(); step++) { + const vector& args = arguments[step]; + if (args.size() == 1) + workspace[target[step]] = operation[step]->evaluate(&workspace[args[0]], dummyVariables); + else { + for (int i = 0; i < args.size(); i++) + argValues[i] = workspace[args[i]]; + workspace[target[step]] = operation[step]->evaluate(&argValues[0], dummyVariables); + } + } + return workspace[workspace.size()-1]; +#endif +} + +#ifdef LEPTON_USE_JIT +static double evaluateOperation(Operation* op, double* args) { + map* dummyVariables = NULL; + return op->evaluate(args, *dummyVariables); +} + +void CompiledExpression::generateJitCode() { + X86Compiler c(&runtime); + c.addFunc(kFuncConvHost, FuncBuilder0()); + vector workspaceVar(workspace.size()); + for (int i = 0; i < (int) workspaceVar.size(); i++) + workspaceVar[i] = c.newXmmVar(kX86VarTypeXmmSd); + X86GpVar workspacePointer(c); + X86GpVar argsPointer(c); + c.mov(workspacePointer, imm_ptr(&workspace[0])); + c.mov(argsPointer, imm_ptr(&argValues[0])); + + // Load the arguments into variables. + + for (set::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) { + map::iterator index = variableIndices.find(*iter); + c.movsd(workspaceVar[index->second], x86::ptr(workspacePointer, 8*index->second, 0)); + } + + // Make a list of all constants that will be needed for evaluation. + + vector operationConstantIndex(operation.size(), -1); + for (int step = 0; step < (int) operation.size(); step++) { + // Find the constant value (if any) used by this operation. + + Operation& op = *operation[step]; + double value; + if (op.getId() == Operation::CONSTANT) + value = dynamic_cast(op).getValue(); + else if (op.getId() == Operation::ADD_CONSTANT) + value = dynamic_cast(op).getValue(); + else if (op.getId() == Operation::MULTIPLY_CONSTANT) + value = dynamic_cast(op).getValue(); + else if (op.getId() == Operation::RECIPROCAL) + value = 1.0; + else if (op.getId() == Operation::STEP) + value = 1.0; + else if (op.getId() == Operation::DELTA) + value = 1.0; + else + continue; + + // See if we already have a variable for this constant. + + for (int i = 0; i < (int) constants.size(); i++) + if (value == constants[i]) { + operationConstantIndex[step] = i; + break; + } + if (operationConstantIndex[step] == -1) { + operationConstantIndex[step] = constants.size(); + constants.push_back(value); + } + } + + // Load constants into variables. + + vector constantVar(constants.size()); + if (constants.size() > 0) { + X86GpVar constantsPointer(c); + c.mov(constantsPointer, imm_ptr(&constants[0])); + for (int i = 0; i < (int) constants.size(); i++) { + constantVar[i] = c.newXmmVar(kX86VarTypeXmmSd); + c.movsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0)); + } + } + + // Evaluate the operations. + + for (int step = 0; step < (int) operation.size(); step++) { + Operation& op = *operation[step]; + vector args = arguments[step]; + if (args.size() == 1) { + // One or more sequential arguments. Fill out the list. + + for (int i = 1; i < op.getNumArguments(); i++) + args.push_back(args[0]+i); + } + + // Generate instructions to execute this operation. + + switch (op.getId()) { + case Operation::CONSTANT: + c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::ADD: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.addsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::SUBTRACT: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.subsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::MULTIPLY: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::DIVIDE: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.divsd(workspaceVar[target[step]], workspaceVar[args[1]]); + break; + case Operation::NEGATE: + c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); + c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::SQRT: + c.sqrtsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::EXP: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], exp); + break; + case Operation::LOG: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], log); + break; + case Operation::SIN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sin); + break; + case Operation::COS: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cos); + break; + case Operation::TAN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tan); + break; + case Operation::ASIN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], asin); + break; + case Operation::ACOS: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], acos); + break; + case Operation::ATAN: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], atan); + break; + case Operation::SINH: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sinh); + break; + case Operation::COSH: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cosh); + break; + case Operation::TANH: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tanh); + break; + case Operation::STEP: + c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); + c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(18)); // Comparison mode is _CMP_LE_OQ = 18 + c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::DELTA: + c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]); + c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(16)); // Comparison mode is _CMP_EQ_OS = 16 + c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::SQUARE: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::CUBE: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::RECIPROCAL: + c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]); + break; + case Operation::ADD_CONSTANT: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::MULTIPLY_CONSTANT: + c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]); + c.mulsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]); + break; + case Operation::ABS: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], fabs); + break; + default: + // Just invoke evaluateOperation(). + + for (int i = 0; i < (int) args.size(); i++) + c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]); + X86GpVar fn(c, kVarTypeIntPtr); + c.mov(fn, imm_ptr((void*) evaluateOperation)); + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder2()); + call->setArg(0, imm_ptr(&op)); + call->setArg(1, imm_ptr(&argValues[0])); + call->setRet(0, workspaceVar[target[step]]); + } + } + c.ret(workspaceVar[workspace.size()-1]); + c.endFunc(); + jitCode = c.make(); +} + +void CompiledExpression::generateSingleArgCall(X86Compiler& c, X86XmmVar& dest, X86XmmVar& arg, double (*function)(double)) { + X86GpVar fn(c, kVarTypeIntPtr); + c.mov(fn, imm_ptr((void*) function)); + X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1()); + call->setArg(0, arg); + call->setRet(0, dest); +} #endif \ No newline at end of file -- GitLab From 173f7b1080e8eb31852b1944be8fc6e3984d826d Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 22 Sep 2014 16:51:35 -0700 Subject: [PATCH 016/338] Push docs to S3 --- .travis.yml | 12 ++++++++++++ devtools/ci/push-docs-to-s3.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 devtools/ci/push-docs-to-s3.py diff --git a/.travis.yml b/.travis.yml index ce0d1c328..ee821236f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,12 @@ language: cpp compiler: - clang +env: + global: + # encrypted AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to push docs to s3 + - secure: "VVKz+yOMbKsskR+PfU1HfKBWdGYYrmIXNWQz4nqXCjtg2MRCQmjDulFZaPVDvsBzis9BUhnzAQrBYUrAtN8bZSTYRg7ADFVGdPFicg3Sv0owcghTQwokIvbw3G+HDz/WAnFmqEhqm3t5pNVWNinyHpMM3zYZOVKagyj53cwAM0M=" + - secure: "W2iPU6ooMujfzJNw9ElaEB8Go1rlNFJ5zEldr3FaH7SDRwqtqNOEp9CegCeG/hHtjg1j8TMyytQtvW+OaMKFIbq7Qqu7nIfwIFTV45vBHW6uwT/jAq/J3EgZ8K7JGyysVVHk86D8jT+xu90YVH5Tx/w97luxHOQGfSK8alhCszw=" + before_install: - sudo apt-get update -qq - sudo apt-get install -qq libpcre3 libpcre3-dev gromacs @@ -24,3 +30,9 @@ script: - # run the python tests too - cd python/tests - nosetests -vv --processes=-1 --process-timeout=200 + +after_success: + - make DoxygenApiDocs + - make sphinxhtml + - sudo pip install boto + - python devtools/ci/push-docs-to-s3.py diff --git a/devtools/ci/push-docs-to-s3.py b/devtools/ci/push-docs-to-s3.py new file mode 100644 index 000000000..f2aad5a2f --- /dev/null +++ b/devtools/ci/push-docs-to-s3.py @@ -0,0 +1,34 @@ +from __future__ import print_function +import os +import boto +import simtk +from boto.s3.key import Key + +# The secret key is available as a secure environment variable +# on travis-ci to push the build documentation to Amazon S3. +AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID'] +AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY'] +BUCKET_NAME = 'docs.openmm.org' + +bucket_name = AWS_ACCESS_KEY_ID.lower() + '-' + BUCKET_NAME +conn = boto.connect_s3(AWS_ACCESS_KEY_ID, + AWS_SECRET_ACCESS_KEY) +bucket = conn.get_bucket(BUCKET_NAME) + +def upload(path, root=None, prefix='', versioned=True): + if root is None: + root = path + for dirpath, dirnames, filenames in os.walk(path): + for filename in filenames: + fn = os.path.join(dirpath, filename) + k = Key(bucket) + k.key = os.path.join(prefix, os.path.relpath(fn, root)) + if versioned: + k.key = os.path.join(simtk.version.short_version, k.key) + print('Uploading', k.key, '...') + k.set_contents_from_filename(fn) + +upload('api-c++/', 'build') +upload('api-python/', 'build') +upload('sphinx-docs/developerguide/html', prefix='developerguide') +upload('sphinx-docs/userguide/html', prefix='userguide') -- GitLab From f77a7019590a004868c66a04d325556614ede76b Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 22 Sep 2014 18:46:26 -0700 Subject: [PATCH 017/338] sphinx install --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ee821236f..2f967a533 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,10 @@ script: - nosetests -vv --processes=-1 --process-timeout=200 after_success: + # Get libraries necessary for building docs and pushing + # them to S3 + - sudo apt-get install python-sphinx python-yaml + - sudo pip install sphinxcontrib-bibtex boto - make DoxygenApiDocs - make sphinxhtml - - sudo pip install boto - python devtools/ci/push-docs-to-s3.py -- GitLab From a162c89e2dc7046d96602655a891bd620e61b99f Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 22 Sep 2014 21:33:10 -0700 Subject: [PATCH 018/338] Add by-name getters to CustomIntegrator API --- openmmapi/include/openmm/CustomIntegrator.h | 15 +++++++++++++++ openmmapi/src/CustomIntegrator.cpp | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/openmmapi/include/openmm/CustomIntegrator.h b/openmmapi/include/openmm/CustomIntegrator.h index 3c252d7a9..8e3731796 100644 --- a/openmmapi/include/openmm/CustomIntegrator.h +++ b/openmmapi/include/openmm/CustomIntegrator.h @@ -302,6 +302,13 @@ public: * @return the current value of the variable */ double getGlobalVariable(int index) const; + /** + * Get the current value of a global variable, specified by name. + * + * @param name the name of the variable to get + * @return the current value of the parameter + */ + double getGlobalVariableByName(const std::string& name); /** * Set the value of a global variable. * @@ -324,6 +331,14 @@ public: * are stored into this */ void getPerDofVariable(int index, std::vector& values) const; + /** + * Get the value of a per-DOF variable, specified by name. + * + * @param name the name of the variable to get + * @param values the values of the variable for all degrees of freedom + * are stored into this + */ + void getPerDofVariableByName(const std::string& name, std::vector& values) const; /** * Set the value of a per-DOF variable. * diff --git a/openmmapi/src/CustomIntegrator.cpp b/openmmapi/src/CustomIntegrator.cpp index db7a33119..7e083aec4 100644 --- a/openmmapi/src/CustomIntegrator.cpp +++ b/openmmapi/src/CustomIntegrator.cpp @@ -124,6 +124,15 @@ double CustomIntegrator::getGlobalVariable(int index) const { return globalValues[index]; } +double CustomIntegrator::getGlobalVariableByName(const string& name) const { + for (int i = 0; i < (int) globalNames.size(); i++) + if (name == globalNames[i]) { + return getGlobalVariable(i); + } + } + throw OpenMMException("Illegal global variable name: "+name); +} + void CustomIntegrator::setGlobalVariable(int index, double value) { ASSERT_VALID_INDEX(index, globalValues); if (owner != NULL && !globalsAreCurrent) { @@ -152,6 +161,16 @@ void CustomIntegrator::getPerDofVariable(int index, vector& values) const kernel.getAs().getPerDofVariable(*context, index, values); } +void CustomIntegrator::getPerDofVariableByName(const string& name, vector& values) const { + for (int i = 0; i < (int) perDofNames.size(); i++) + if (name == perDofNames[i]) { + getPerDofVariable(i, values); + return; + } + } + throw OpenMMException("Illegal per-DOF variable name: "+name); +} + void CustomIntegrator::setPerDofVariable(int index, const vector& values) { ASSERT_VALID_INDEX(index, perDofValues); if (owner != NULL && values.size() != context->getSystem().getNumParticles()) -- GitLab From 1b245565d6c9533de9cb2b9494cd56866236bc8a Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 22 Sep 2014 21:48:03 -0700 Subject: [PATCH 019/338] Fix to compile --- openmmapi/include/openmm/CustomIntegrator.h | 2 +- openmmapi/src/CustomIntegrator.cpp | 7 ++++--- wrappers/python/src/swig_doxygen/swigInputConfig.py | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/openmmapi/include/openmm/CustomIntegrator.h b/openmmapi/include/openmm/CustomIntegrator.h index 8e3731796..4045fbc91 100644 --- a/openmmapi/include/openmm/CustomIntegrator.h +++ b/openmmapi/include/openmm/CustomIntegrator.h @@ -308,7 +308,7 @@ public: * @param name the name of the variable to get * @return the current value of the parameter */ - double getGlobalVariableByName(const std::string& name); + double getGlobalVariableByName(const std::string& name) const; /** * Set the value of a global variable. * diff --git a/openmmapi/src/CustomIntegrator.cpp b/openmmapi/src/CustomIntegrator.cpp index 7e083aec4..305e7f51d 100644 --- a/openmmapi/src/CustomIntegrator.cpp +++ b/openmmapi/src/CustomIntegrator.cpp @@ -125,7 +125,7 @@ double CustomIntegrator::getGlobalVariable(int index) const { } double CustomIntegrator::getGlobalVariableByName(const string& name) const { - for (int i = 0; i < (int) globalNames.size(); i++) + for (int i = 0; i < (int) globalNames.size(); i++) { if (name == globalNames[i]) { return getGlobalVariable(i); } @@ -145,11 +145,12 @@ void CustomIntegrator::setGlobalVariable(int index, double value) { } void CustomIntegrator::setGlobalVariableByName(const string& name, double value) { - for (int i = 0; i < (int) globalNames.size(); i++) + for (int i = 0; i < (int) globalNames.size(); i++) { if (name == globalNames[i]) { setGlobalVariable(i, value); return; } + } throw OpenMMException("Illegal global variable name: "+name); } @@ -162,7 +163,7 @@ void CustomIntegrator::getPerDofVariable(int index, vector& values) const } void CustomIntegrator::getPerDofVariableByName(const string& name, vector& values) const { - for (int i = 0; i < (int) perDofNames.size(); i++) + for (int i = 0; i < (int) perDofNames.size(); i++) { if (name == perDofNames[i]) { getPerDofVariable(i, values); return; diff --git a/wrappers/python/src/swig_doxygen/swigInputConfig.py b/wrappers/python/src/swig_doxygen/swigInputConfig.py index 25a1e7c0a..3f61803cf 100755 --- a/wrappers/python/src/swig_doxygen/swigInputConfig.py +++ b/wrappers/python/src/swig_doxygen/swigInputConfig.py @@ -161,6 +161,7 @@ UNITS = { ("*", "getEwaldErrorTolerance") : (None, ()), ("*", "getFriction") : ("1/unit.picosecond", ()), ("*", "getGlobalVariable") : (None, ()), +("*", "getGlobalVariableByName") : (None, ()), ("*", "getIntegrator") : (None, ()), ("*", "getMapParameters") : (None, ()), ("*", "getName") : (None, ()), -- GitLab From 8ab5b90736e4e44de72a58300923301e4d309997 Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 22 Sep 2014 21:55:34 -0700 Subject: [PATCH 020/338] revert change to other function --- openmmapi/src/CustomIntegrator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openmmapi/src/CustomIntegrator.cpp b/openmmapi/src/CustomIntegrator.cpp index 305e7f51d..cba9558fb 100644 --- a/openmmapi/src/CustomIntegrator.cpp +++ b/openmmapi/src/CustomIntegrator.cpp @@ -145,12 +145,11 @@ void CustomIntegrator::setGlobalVariable(int index, double value) { } void CustomIntegrator::setGlobalVariableByName(const string& name, double value) { - for (int i = 0; i < (int) globalNames.size(); i++) { + for (int i = 0; i < (int) globalNames.size(); i++) if (name == globalNames[i]) { setGlobalVariable(i, value); return; } - } throw OpenMMException("Illegal global variable name: "+name); } -- GitLab From 40bd2a2f13bf5756b2e5f132a8ef1cea5d86a827 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 29 Sep 2014 16:48:06 -0700 Subject: [PATCH 021/338] Do not use JIT compilation in 32 bit mode, since AsmJit currently doesn't support that properly --- CMakeLists.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45c976a3e..3213c7d29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,12 +270,14 @@ ELSE (ANDROID OR PNACL) SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/libraries/sfmt/src/SFMT.cpp PROPERTIES COMPILE_FLAGS "-DHAVE_SSE2=1") ENDIF(ANDROID OR PNACL) IF (NOT (ANDROID OR PNACL)) - FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*/*.cpp) - FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*.h) - SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) - SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) - INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit") - SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DLEPTON_USE_JIT") + IF (CMAKE_SIZEOF_VOID_P EQUAL 8) + FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*/*.cpp) + FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*.h) + SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) + SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) + INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit") + SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DLEPTON_USE_JIT") + ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 8) ENDIF (NOT (ANDROID OR PNACL)) # If API wrappers are being generated, and add them to the build. @@ -292,7 +294,7 @@ SET(OPENMM_BUILD_SHARED_LIB ON CACHE BOOL "Whether to build shared OpenMM librar SET(EXTRA_LINK_FLAGS ${EXTRA_COMPILE_FLAGS}) IF (CMAKE_SYSTEM_NAME MATCHES "Linux") - SET(EXTRA_LINK_FLAGS "${EXTRA_LINK_FLAGS} -lrt") + SET(EXTRA_LINK_FLAGS "${EXTRA_LINK_FLAGS} -Wl,--no-as-needed -lrt") ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux") IF(OPENMM_BUILD_SHARED_LIB) -- GitLab From 5a98c0a131ea61338cb397f1f6bfbe2b93b425ed Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 29 Sep 2014 17:16:25 -0700 Subject: [PATCH 022/338] Added AsmJit to Licenses.txt --- docs-source/licenses/Licenses.txt | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/docs-source/licenses/Licenses.txt b/docs-source/licenses/Licenses.txt index 0c53a4416..031c669e7 100644 --- a/docs-source/licenses/Licenses.txt +++ b/docs-source/licenses/Licenses.txt @@ -2,16 +2,16 @@ OpenMM was developed by 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 © 2008-2009 Stanford University and the Authors. +Portions copyright © 2008-2014 Stanford University and the Authors. There are several licenses which cover different parts of OpenMM as described below. -1. API and Reference Platform +1. API, Reference Platform, CPU Platform -The OpenMM API and the Reference Platform may be used under the terms of the -MIT License: +The OpenMM API, the Reference Platform, and the CPU platform may be used under +the terms of the MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -99,10 +99,23 @@ name of the person performing the modification, the date of modification, and the reason for such modification. -5. GPU-BBSort +5. AsmJit -The CUDA platform uses the GPU-BBSort library written by Chen Shifu. It -includes the following license statement: +OpenMM uses the AsmJit library which is copyright 2008-2014 by Petr Kobalicek. +It may be used under the following terms: -The code is distributed under BSD license, you are allowed to use, modify -or sell this code, but a statement is required if you used this code any where. \ No newline at end of file +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. -- GitLab From 252bf5c70140e5772a396076e57235e7af7c851f Mon Sep 17 00:00:00 2001 From: Kyle Beauchamp Date: Wed, 1 Oct 2014 00:21:42 -0400 Subject: [PATCH 023/338] Added fix for #632 --- wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i index 001e20c5d..3753ebc47 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i @@ -75,12 +75,12 @@ class State(_object): self._paramMap=paramMap def __getstate__(self): - serializationString = XmlSerializer.serializeState(self) + serializationString = XmlSerializer.serialize(self) return serializationString def __setstate__(self, serializationString): print 'calling set state' - dState = XmlSerializer.deserializeState(serializationString) + dState = XmlSerializer.deserialize(serializationString) # Safe provided no __slots__ or other weird things are used self.__dict__.update(dState.__dict__) -- GitLab From 771842ac6965fae76128eb960776b5b223860230 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Wed, 1 Oct 2014 12:58:49 -0400 Subject: [PATCH 024/338] Added test for python serialize --- wrappers/python/tests/TestSerialize.py | 54 ++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 wrappers/python/tests/TestSerialize.py diff --git a/wrappers/python/tests/TestSerialize.py b/wrappers/python/tests/TestSerialize.py new file mode 100644 index 000000000..75f65a43d --- /dev/null +++ b/wrappers/python/tests/TestSerialize.py @@ -0,0 +1,54 @@ +import unittest +from validateConstraints import * +from simtk.openmm.app import * +from simtk.openmm import * +from simtk.unit import * +import simtk.openmm.app.element as elem +import simtk.openmm.app.forcefield as forcefield +import copy +import pickle + +class TestSerialize(unittest.TestCase): + """Test serialization wrappers in Python.""" + + def setUp(self): + """Set up the tests by loading the input pdb files and force field + xml files. + + """ + # alanine dipeptide with explicit water + self.pdb1 = PDBFile('systems/alanine-dipeptide-explicit.pdb') + self.forcefield1 = ForceField('amber99sb.xml', 'tip3p.xml') + self.topology1 = self.pdb1.topology + self.topology1.setUnitCellDimensions(Vec3(2, 2, 2)) + + # alalnine dipeptide with implicit water + self.pdb2 = PDBFile('systems/alanine-dipeptide-implicit.pdb') + self.forcefield2 = ForceField('amber99sb.xml', 'amber99_obc.xml') + + + def test_deepcopy(self): + """Test that serialization/deserialization works (via deepcopy).""" + + system = self.forcefield1.createSystem(self.pdb1.topology) + integrator = VerletIntegrator(2*femtosecond) + context = Context(system, integrator) + context.setPositions(self.pdb1.positions) + state = context.getState(getPositions=True, getForces=True, getEnergy=True) + + system2 = copy.deepcopy(system) + #integrator2 = copy.deepcopy(integrator) + state2 = copy.deepcopy(state) + + str_state = pickle.dumps(state) + #str_integrator = pickle.dumps(integrator) + + state3 = pickle.loads(str_state) + context.setState(state3) + + + del context, integrator + +if __name__ == '__main__': + unittest.main() + -- GitLab From 3f2150d35dbba150089d56789a7fbc3b943f7ac0 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Wed, 1 Oct 2014 13:37:18 -0400 Subject: [PATCH 025/338] Renamed test to TestPickle --- wrappers/python/tests/{TestSerialize.py => TestPickle.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename wrappers/python/tests/{TestSerialize.py => TestPickle.py} (100%) diff --git a/wrappers/python/tests/TestSerialize.py b/wrappers/python/tests/TestPickle.py similarity index 100% rename from wrappers/python/tests/TestSerialize.py rename to wrappers/python/tests/TestPickle.py -- GitLab From 321f64a455aa5c3950035f14eced1e1e5f68c4a7 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Wed, 1 Oct 2014 13:41:35 -0400 Subject: [PATCH 026/338] Changed name of test to TestPickle. --- wrappers/python/tests/TestPickle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/tests/TestPickle.py b/wrappers/python/tests/TestPickle.py index 75f65a43d..95ff63a83 100644 --- a/wrappers/python/tests/TestPickle.py +++ b/wrappers/python/tests/TestPickle.py @@ -8,7 +8,7 @@ import simtk.openmm.app.forcefield as forcefield import copy import pickle -class TestSerialize(unittest.TestCase): +class TestPickle(unittest.TestCase): """Test serialization wrappers in Python.""" def setUp(self): -- GitLab From 168aaa4962d4b3b4351ebafb91e766743882133e Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Wed, 1 Oct 2014 13:42:29 -0400 Subject: [PATCH 027/338] Updated docstring. --- wrappers/python/tests/TestPickle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/tests/TestPickle.py b/wrappers/python/tests/TestPickle.py index 95ff63a83..38405fbab 100644 --- a/wrappers/python/tests/TestPickle.py +++ b/wrappers/python/tests/TestPickle.py @@ -9,7 +9,7 @@ import copy import pickle class TestPickle(unittest.TestCase): - """Test serialization wrappers in Python.""" + """Pickling / deepcopy of OpenMM state and integrator objects.""" def setUp(self): """Set up the tests by loading the input pdb files and force field -- GitLab From 9c7c79a1c4e4ea6c371a6b3d02606e14b0e4cb9c Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Wed, 1 Oct 2014 13:59:58 -0400 Subject: [PATCH 028/338] Added pickler for integrators and test. --- .../python/src/swig_doxygen/swig_lib/python/extend.i | 12 ++++++++++++ wrappers/python/tests/TestPickle.py | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i b/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i index 9158c60f8..21615bcac 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i @@ -454,3 +454,15 @@ Parameters: return self.__copy__() } } + +%extend OpenMM::Integrator { + %pythoncode { + def __getstate__(self): + serializationString = XmlSerializer.serialize(self) + return serializationString + + def __setstate__(self, serializationString): + system = XmlSerializer.deserialize(serializationString) + self.this = system.this + } +} diff --git a/wrappers/python/tests/TestPickle.py b/wrappers/python/tests/TestPickle.py index 38405fbab..0d3dd47bd 100644 --- a/wrappers/python/tests/TestPickle.py +++ b/wrappers/python/tests/TestPickle.py @@ -37,11 +37,11 @@ class TestPickle(unittest.TestCase): state = context.getState(getPositions=True, getForces=True, getEnergy=True) system2 = copy.deepcopy(system) - #integrator2 = copy.deepcopy(integrator) + integrator2 = copy.deepcopy(integrator) state2 = copy.deepcopy(state) str_state = pickle.dumps(state) - #str_integrator = pickle.dumps(integrator) + str_integrator = pickle.dumps(integrator) state3 = pickle.loads(str_state) context.setState(state3) -- GitLab From cc298d6dc1c895c9ef29e0c701e84ae5f25527c2 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Fri, 3 Oct 2014 12:51:12 -0400 Subject: [PATCH 029/338] Updated vagrant scripts for conda build and upload --- .../linux/build_conda_package_vagrant.sh | 18 +++++++++++++++--- devtools/build-vm/linux/setup_centos_vm.sh | 14 ++++++++------ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/devtools/build-vm/linux/build_conda_package_vagrant.sh b/devtools/build-vm/linux/build_conda_package_vagrant.sh index 4b8fa278b..7a3ecb339 100644 --- a/devtools/build-vm/linux/build_conda_package_vagrant.sh +++ b/devtools/build-vm/linux/build_conda_package_vagrant.sh @@ -2,7 +2,19 @@ export PATH=$HOME/miniconda/bin:$PATH export SWIG_LIB=$HOME/miniconda/share/swig/ export CC="clang++" -git clone -b vagrant https://github.com/simtk/openmm.git +git clone https://github.com/simtk/openmm.git cd openmm -conda install --file tools/ci/requirements-conda.txt --yes -conda build tools/conda-recipe +git checkout tags/6.1 # To checkout specific release for packaging. +conda install --file devtools/ci/requirements-conda.txt --yes + +# For CI build: +conda build devtools/conda-recipe + +# For release build: +cd ../ +git clone https://github.com/omnia-md/conda-recipes.git +conda build conda-recipes/openmm + +# To upload the file, do something the following command but with the package version changed: + +binstar upload -u omnia /home/vagrant/miniconda/conda-bld/linux-64/openmm-6.1-py27_0.tar.bz2 diff --git a/devtools/build-vm/linux/setup_centos_vm.sh b/devtools/build-vm/linux/setup_centos_vm.sh index ca46b1e36..eb83e26be 100644 --- a/devtools/build-vm/linux/setup_centos_vm.sh +++ b/devtools/build-vm/linux/setup_centos_vm.sh @@ -9,13 +9,14 @@ mkdir ~/Software cd Software sudo yum install wget -y -wget http://mirror.umd.edu/fedora/epel/6/i386/epel-release-6-8.noarch.rpm +wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm sudo rpm -i epel-release-6-8.noarch.rpm sudo yum update -y # Several of these come from the EPEL repo -sudo yum install clang-3.4 cmake28 graphviz perl flex bison rpm-build texlive texlive-latex ghostscript gcc gcc-c++ git vim -y +sudo yum install clang cmake28 graphviz perl flex bison rpm-build texlive texlive-latex ghostscript gcc gcc-c++ git vim -y +# Note: changed from clang-3.4 to clang because the package has apparently been renamed. KAB Oct 2 2014. # Probably can't use RHEL6 version of doxygen because it's very old. wget http://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.7.src.tar.gz @@ -35,25 +36,26 @@ sudo yum clean expire-cache sudo yum install cuda -y rm cuda-repo-rhel6-6.0-37.x86_64.rpm +sudo yum update -y # Force a second update, in case CUDA has necessary patches. # Install Conda cd ~/Software -wget http://repo.continuum.io/miniconda/Miniconda-3.0.5-Linux-x86_64.sh -bash Miniconda-3.0.5-Linux-x86_64.sh -b +wget http://repo.continuum.io/miniconda/Miniconda-3.7.0-Linux-x86_64.sh +bash Miniconda-3.7.0-Linux-x86_64.sh -b # So there is a bug in some versions of anaconda where the path to swig files is HARDCODED. Below is workaround. See https://github.com/ContinuumIO/anaconda-issues/issues/48 sudo ln -s ~/miniconda/ /opt/anaconda1anaconda2anaconda3 export PATH=$HOME/miniconda/bin:$PATH conda config --add channels http://conda.binstar.org/omnia -conda install --yes fftw3f jinja2 swig sphinx conda-build cmake +conda install --yes fftw3f jinja2 swig sphinx conda-build cmake binstar # Download AMD APP SDK from here, requires click agreement: http://developer.amd.com/amd-license-agreement-appsdk/ # Ideally we could cache this on AWS or something... mkdir ~/Software/AMD cd ~/Software/AMD -# Copy the tarball to this directory from wherever you got it. +# Copy the tarball to the directory containing VagrantFile, which will be shared on the guest as /vagrant/ cp /vagrant/AMD-APP-SDK-v2.9-lnx64.tgz ./ tar -zxvf /vagrant/AMD-APP-SDK-v2.9-lnx64.tgz sudo ./Install-AMD-APP.sh -- GitLab From 7d1e3fc46e9c568525dc593c1bc266d5d0284e65 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 3 Oct 2014 14:18:23 -0700 Subject: [PATCH 030/338] Created MonteCarloMembraneBarostat --- .../openmm/MonteCarloMembraneBarostat.h | 238 ++++++++++++++++++ .../internal/MonteCarloMembraneBarostatImpl.h | 71 ++++++ openmmapi/src/MonteCarloMembraneBarostat.cpp | 46 ++++ .../src/MonteCarloMembraneBarostatImpl.cpp | 154 ++++++++++++ ...estReferenceMonteCarloMembraneBarostat.cpp | 197 +++++++++++++++ 5 files changed, 706 insertions(+) create mode 100644 openmmapi/include/openmm/MonteCarloMembraneBarostat.h create mode 100644 openmmapi/include/openmm/internal/MonteCarloMembraneBarostatImpl.h create mode 100644 openmmapi/src/MonteCarloMembraneBarostat.cpp create mode 100644 openmmapi/src/MonteCarloMembraneBarostatImpl.cpp create mode 100644 platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h new file mode 100644 index 000000000..a65d0793c --- /dev/null +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -0,0 +1,238 @@ +#ifndef OPENMM_MONTECARLOMEMBRANEBAROSTAT_H_ +#define OPENMM_MONTECARLOMEMBRANEBAROSTAT_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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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 "Force.h" +#include +#include "internal/windowsExport.h" + +namespace OpenMM { + +/** + * This is a Monte Carlo barostat designed specifically for membrane simulations. It assumes the + * membrane lies in the XY plane. The Monte Carlo acceptance criterion includes a term to model + * isotropic pressure, which depends on the volume of the periodic box, and a second term to model + * surface tension, which depends on the cross sectional area of the box in the XY plane. Note + * that pressure and surface tension are defined with opposite senses: a larger pressure tends to + * make the box smaller, but a larger surface tension tends to make the box larger. + * + * There are options for configuring exactly how the various box dimensions are allowed to change: + * + *
    + *
  • The X and Y axes may be treated isotropically, in which case they always scale by the same + * amount and remain in proportion to each other; or they may be treated anisotropically, in which + * case they can vary independently of each other.
  • + *
  • The Z axis can be allowed to vary independently of the other axes; or held fixed; or constrained + * to vary in inverse proportion to the other two axes, so that the total box volume remains fixed.
  • + *
+ * + * This class assumes the simulation is also being run at constant temperature, and requires you + * to specify the system temperature (since it affects the acceptance probability for Monte Carlo + * moves). It does not actually perform temperature regulation, however. You must use another + * mechanism along with it to maintain the temperature, such as LangevinIntegrator or AndersenThermostat. + */ + +class OPENMM_EXPORT MonteCarloMembraneBarostat : public Force { +public: + /** + * This is an enumeration of the different behaviors for the X and Y axes. + */ + enum XYMode { + /** + * The X and Y axes are always scaled by the same amount, so the ratio of their lengths remains constant. + */ + XYIsotropic = 0, + /** + * The X and Y axes are allowed to vary independently of each other. + */ + XYAnisotropic = 1 + }; + /** + * This is an enumeration of the different behaviors for Z axis. + */ + enum ZMode { + /** + * The Z axis is allowed to vary freely, independent of the other two axes. + */ + ZFree = 0, + /** + * The Z axis is held fixed and does not change. + */ + ZFixed = 1, + /** + * The Z axis is always scaled in inverse proportion to the other two axes so the box volume remains + * fixed. Note that in this mode pressure has no effect on the system, only surface tension. + */ + ConstantVolume = 2 + }; + /** + * This is the name of the parameter which stores the current pressure acting on + * the system (in bar). + */ + static const std::string& Pressure() { + static const std::string key = "MembraneMonteCarloPressure"; + return key; + } + /** + * This is the name of the parameter which stores the current surface tension acting on + * the system (in bar*nm). + */ + static const std::string& SurfaceTension() { + static const std::string key = "MembraneMonteCarloSurfaceTension"; + return key; + } + /** + * Create a MonteCarloMembraneBarostat. + * + * @param defaultPressure the default pressure acting on the system (in bar) + * @param defaultSurfaceTension the default surface tension acting on the system (in bar*nm) + * @param temperature the temperature at which the system is being maintained (in Kelvin) + * @param xymode the mode specifying the behavior of the X and Y axes + * @param zmode the mode specifying the behavior of the Z axis + * @param frequency the frequency at which Monte Carlo volume changes should be attempted (in time steps) + */ + MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double temperature, XYMode xymode, ZMode zmode, int frequency = 25); + /** + * Get the default pressure acting on the system (in bar). + * + * @return the default pressure acting on the system, measured in bar. + */ + double getDefaultPressure() const { + return defaultPressure; + } + /** + * Set the default pressure acting on the system. This will affect any new Contexts you create, + * but not ones that already exist. + * + * @param pressure the default pressure acting on the system, measured in bar. + */ + void setDefaultPressure(double pressure) { + defaultPressure = pressure; + } + /** + * Get the default surface tension acting on the system (in bar*nm). + * + * @return the default surface tension acting on the system, measured in bar*nm. + */ + double getDefaultSurfaceTension() const { + return defaultSurfaceTension; + } + /** + * Set the default surface tension acting on the system. This will affect any new Contexts you create, + * but not ones that already exist. + * + * @param surfaceTension the default surface tension acting on the system, measured in bar. + */ + void setDefaultSurfaceTension(double surfaceTension) { + defaultSurfaceTension = surfaceTension; + } + /** + * Get the frequency (in time steps) at which Monte Carlo volume changes should be attempted. If this is set to + * 0, the barostat is disabled. + */ + int getFrequency() const { + return frequency; + } + /** + * Set the frequency (in time steps) at which Monte Carlo volume changes should be attempted. If this is set to + * 0, the barostat is disabled. + */ + void setFrequency(int freq) { + frequency = freq; + } + /** + * Get the temperature at which the system is being maintained, measured in Kelvin. + */ + double getTemperature() const { + return temperature; + } + /** + * Set the temperature at which the system is being maintained. + * + * @param temp the system temperature, measured in Kelvin. + */ + void setTemperature(double temp) { + temperature = temp; + } + /** + * Get the mode specifying the behavior of the X and Y axes. + */ + XYMode getXYMode() const { + return xymode; + } + /** + * Set the mode specifying the behavior of the X and Y axes. + */ + void setXYMode(XYMode mode) { + xymode = mode; + } + /** + * Get the mode specifying the behavior of the Z axis. + */ + ZMode getZMode() const { + return zmode; + } + /** + * Set the mode specifying the behavior of the Z axis. + */ + void setZMode(ZMode mode) { + zmode = mode; + } + /** + * Get the random number seed. See setRandomNumberSeed() for details. + */ + int getRandomNumberSeed() const { + return randomNumberSeed; + } + /** + * Set the random number seed. It is guaranteed that if two simulations are run + * with different random number seeds, the sequence of Monte Carlo steps will be different. On + * the other hand, no guarantees are made about the behavior of simulations that use the same seed. + * In particular, Platforms are permitted to use non-deterministic algorithms which produce different + * results on successive runs, even if those runs were initialized identically. + */ + void setRandomNumberSeed(int seed) { + randomNumberSeed = seed; + } +protected: + ForceImpl* createImpl() const; +private: + double defaultPressure, defaultSurfaceTension, temperature; + XYMode xymode; + ZMode zmode; + int frequency, randomNumberSeed; +}; + +} // namespace OpenMM + +#endif /*OPENMM_MONTECARLOMEMBRANEBAROSTAT_H_*/ diff --git a/openmmapi/include/openmm/internal/MonteCarloMembraneBarostatImpl.h b/openmmapi/include/openmm/internal/MonteCarloMembraneBarostatImpl.h new file mode 100644 index 000000000..141cc420c --- /dev/null +++ b/openmmapi/include/openmm/internal/MonteCarloMembraneBarostatImpl.h @@ -0,0 +1,71 @@ +#ifndef OPENMM_MONTECARLOMEMBRANEBAROSTATIMPL_H_ +#define OPENMM_MONTECARLOMEMBRANEBAROSTATIMPL_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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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 "ForceImpl.h" +#include "openmm/MonteCarloMembraneBarostat.h" +#include "openmm/Kernel.h" +#include "sfmt/SFMT.h" +#include + +namespace OpenMM { + +/** + * This is the internal implementation of MonteCarloMembraneBarostat. + */ + +class MonteCarloMembraneBarostatImpl : public ForceImpl { +public: + MonteCarloMembraneBarostatImpl(const MonteCarloMembraneBarostat& owner); + void initialize(ContextImpl& context); + const MonteCarloMembraneBarostat& getOwner() const { + return owner; + } + void updateContextState(ContextImpl& context); + double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) { + // This force doesn't apply forces to particles. + return 0.0; + } + std::map getDefaultParameters(); + std::vector getKernelNames(); +private: + const MonteCarloMembraneBarostat& owner; + int step, numAttempted[3], numAccepted[3]; + double volumeScale[3]; + OpenMM_SFMT::SFMT random; + Kernel kernel; +}; + +} // namespace OpenMM + +#endif /*OPENMM_MONTECARLOMEMBRANEBAROSTATIMPL_H_*/ diff --git a/openmmapi/src/MonteCarloMembraneBarostat.cpp b/openmmapi/src/MonteCarloMembraneBarostat.cpp new file mode 100644 index 000000000..24f153564 --- /dev/null +++ b/openmmapi/src/MonteCarloMembraneBarostat.cpp @@ -0,0 +1,46 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/MonteCarloMembraneBarostat.h" +#include "openmm/internal/MonteCarloMembraneBarostatImpl.h" +#include "openmm/internal/OSRngSeed.h" + +using namespace OpenMM; + +MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double temperature, XYMode xymode, ZMode zmode, int frequency) : + defaultPressure(defaultPressure), defaultSurfaceTension(defaultSurfaceTension), temperature(temperature), + xymode(xymode), zmode(zmode), frequency(frequency) { + setRandomNumberSeed(osrngseed()); +} + +ForceImpl* MonteCarloMembraneBarostat::createImpl() const { + return new MonteCarloMembraneBarostatImpl(*this); +} diff --git a/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp new file mode 100644 index 000000000..bd6eff28d --- /dev/null +++ b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp @@ -0,0 +1,154 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman, Lee-Ping Wang * + * 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/internal/MonteCarloMembraneBarostatImpl.h" +#include "openmm/internal/ContextImpl.h" +#include "openmm/Context.h" +#include "openmm/kernels.h" +#include +#include +#include + +using namespace OpenMM; +using namespace OpenMM_SFMT; +using std::vector; + +const float BOLTZMANN = 1.380658e-23f; // (J/K) +const float AVOGADRO = 6.0221367e23f; +const float RGAS = BOLTZMANN*AVOGADRO; // (J/(mol K)) +const float BOLTZ = RGAS/1000; // (kJ/(mol K)) + +MonteCarloMembraneBarostatImpl::MonteCarloMembraneBarostatImpl(const MonteCarloMembraneBarostat& owner) : owner(owner), step(0) { +} + +void MonteCarloMembraneBarostatImpl::initialize(ContextImpl& context) { + kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); + kernel.getAs().initialize(context.getSystem(), owner); + Vec3 box[3]; + context.getPeriodicBoxVectors(box[0], box[1], box[2]); + double volume = box[0][0]*box[1][1]*box[2][2]; + for (int i=0; i<3; i++) { + volumeScale[i] = 0.01*volume; + numAttempted[i] = 0; + numAccepted[i] = 0; + } + init_gen_rand(owner.getRandomNumberSeed(), random); +} + +void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) { + if (++step < owner.getFrequency() || owner.getFrequency() == 0) + return; + step = 0; + + // Compute the current potential energy. + + double initialEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy(); + double pressure = context.getParameter(MonteCarloMembraneBarostat::Pressure())*(AVOGADRO*1e-25); + double tension = context.getParameter(MonteCarloMembraneBarostat::SurfaceTension())*(AVOGADRO*1e-25); + + // Choose which axis to modify at random. + int axis; + while (true) { + double rnd = genrand_real2(random)*3.0; + if (rnd < 1.0) { + axis = 0; + break; + } else if (rnd < 2.0) { + axis = (owner.getXYMode() == MonteCarloMembraneBarostat::XYIsotropic ? 0 : 1); + break; + } else if (owner.getZMode() == MonteCarloMembraneBarostat::ZFree) { + axis = 2; + break; + } + } + + // Modify the periodic box size. + + Vec3 box[3]; + context.getPeriodicBoxVectors(box[0], box[1], box[2]); + double volume = box[0][0]*box[1][1]*box[2][2]; + double deltaVolume = volumeScale[axis]*2*(genrand_real2(random)-0.5); + double newVolume = volume+deltaVolume; + Vec3 lengthScale(1.0, 1.0, 1.0); + if ((axis == 0 || axis == 1) && owner.getXYMode() == MonteCarloMembraneBarostat::XYIsotropic) + lengthScale[0] = lengthScale[1] = sqrt(newVolume/volume); + else + lengthScale[axis] = newVolume/volume; + if (owner.getZMode() == MonteCarloMembraneBarostat::ConstantVolume) { + lengthScale[2] = 1.0/(lengthScale[0]*lengthScale[1]); + newVolume = volume; + deltaVolume = 0; + } + double deltaArea = box[0][0]*lengthScale[0]*box[1][1]*lengthScale[1] - box[0][0]*box[1][1]; + kernel.getAs().scaleCoordinates(context, lengthScale[0], lengthScale[1], lengthScale[2]); + context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale[0], box[1]*lengthScale[1], box[2]*lengthScale[2]); + + // Compute the energy of the modified system. + + double finalEnergy = context.getOwner().getState(State::Energy).getPotentialEnergy(); + double kT = BOLTZ*owner.getTemperature(); + double w = finalEnergy-initialEnergy + pressure*deltaVolume - tension*deltaArea - context.getMolecules().size()*kT*std::log(newVolume/volume); + if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) { + // Reject the step. + + kernel.getAs().restoreCoordinates(context); + context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]); + volume = newVolume; + } + else + numAccepted[axis]++; + numAttempted[axis]++; + if (numAttempted[axis] >= 10) { + if (numAccepted[axis] < 0.25*numAttempted[axis]) { + volumeScale[axis] /= 1.1; + numAttempted[axis] = 0; + numAccepted[axis] = 0; + } + else if (numAccepted[axis] > 0.75*numAttempted[axis]) { + volumeScale[axis] = std::min(volumeScale[axis]*1.1, volume*0.3); + numAttempted[axis] = 0; + numAccepted[axis] = 0; + } + } +} + +std::map MonteCarloMembraneBarostatImpl::getDefaultParameters() { + std::map parameters; + parameters[MonteCarloMembraneBarostat::Pressure()] = getOwner().getDefaultPressure(); + parameters[MonteCarloMembraneBarostat::SurfaceTension()] = getOwner().getDefaultSurfaceTension(); + return parameters; +} + +std::vector MonteCarloMembraneBarostatImpl::getKernelNames() { + std::vector names; + names.push_back(ApplyMonteCarloBarostatKernel::Name()); + return names; +} diff --git a/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp new file mode 100644 index 000000000..fa8ea8ddf --- /dev/null +++ b/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp @@ -0,0 +1,197 @@ +/* -------------------------------------------------------------------------- * + * 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-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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. * + * -------------------------------------------------------------------------- */ + +/** + * This tests the reference implementation of MonteCarloMembraneBarostat. + */ + +#include "openmm/internal/AssertionUtilities.h" +#include "openmm/MonteCarloMembraneBarostat.h" +#include "openmm/Context.h" +#include "ReferencePlatform.h" +#include "openmm/NonbondedForce.h" +#include "openmm/System.h" +#include "openmm/LangevinIntegrator.h" +#include "openmm/VerletIntegrator.h" +#include "sfmt/SFMT.h" +#include "SimTKOpenMMRealType.h" +#include +#include + +using namespace OpenMM; +using namespace std; + +void testIdealGas(MonteCarloMembraneBarostat::XYMode xymode, MonteCarloMembraneBarostat::ZMode zmode) { + const int numParticles = 64; + const int frequency = 1; + const int steps = 5000; + const double pressure = 1.5; + const double pressureInMD = pressure*(AVOGADRO*1e-25); // pressure in kJ/mol/nm^3 + const double tension = (zmode == MonteCarloMembraneBarostat::ZFixed ? 0.2 : 0.0); + const double tensionInMD = tension*(AVOGADRO*1e-25); // surface tension in kJ/mol/nm^2 + const double temp[] = {300.0, 600.0, 1000.0}; + const double initialVolume = numParticles*BOLTZ*temp[1]/pressureInMD; + const double initialLength = std::pow(initialVolume, 1.0/3.0); + + // Create a gas of noninteracting particles. + + ReferencePlatform platform; + System system; + system.setDefaultPeriodicBoxVectors(Vec3(initialLength, 0, 0), Vec3(0, 0.5*initialLength, 0), Vec3(0, 0, 2*initialLength)); + vector positions(numParticles); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int i = 0; i < numParticles; ++i) { + system.addParticle(1.0); + positions[i] = Vec3(initialLength*genrand_real2(sfmt), 0.5*initialLength*genrand_real2(sfmt), 2*initialLength*genrand_real2(sfmt)); + } + MonteCarloMembraneBarostat* barostat = new MonteCarloMembraneBarostat(pressure, tension, temp[0], xymode, zmode, frequency); + system.addForce(barostat); + + // Test it for three different temperatures. + + for (int i = 0; i < 3; i++) { + barostat->setTemperature(temp[i]); + LangevinIntegrator integrator(temp[i], 0.1, 0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + + // Let it equilibrate. + + integrator.step(1000); + + // Now run it for a while and see if the volume is correct. + + double volume = 0.0, zsize = 0.0; + for (int j = 0; j < steps; ++j) { + Vec3 box[3]; + context.getState(0).getPeriodicBoxVectors(box[0], box[1], box[2]); + volume += box[0][0]*box[1][1]*box[2][2]; + zsize += box[2][2]; + if (xymode == MonteCarloMembraneBarostat::XYIsotropic) + ASSERT_EQUAL_TOL(0.5*box[0][0], box[1][1], 1e-5); + if (zmode == MonteCarloMembraneBarostat::ZFixed) + ASSERT_EQUAL_TOL(2*initialLength, box[2][2], 1e-5); + if (zmode == MonteCarloMembraneBarostat::ConstantVolume) + ASSERT_EQUAL_TOL(initialVolume, box[0][0]*box[1][1]*box[2][2], 1e-5); + integrator.step(frequency); + } + volume /= steps; + zsize /= steps; + if (zmode != MonteCarloMembraneBarostat::ConstantVolume) { + double effectivePressure = pressureInMD-tensionInMD/zsize; + double expected = (numParticles+1)*BOLTZ*temp[i]/effectivePressure; + ASSERT_USUALLY_EQUAL_TOL(expected, volume, 0.05); + } + } +} + +void testRandomSeed() { + const int numParticles = 8; + const double temp = 100.0; + const double pressure = 1.5; + const double tension = 0.3; + ReferencePlatform platform; + System system; + system.setDefaultPeriodicBoxVectors(Vec3(8, 0, 0), Vec3(0, 8, 0), Vec3(0, 0, 8)); + VerletIntegrator integrator(0.01); + NonbondedForce* forceField = new NonbondedForce(); + forceField->setNonbondedMethod(NonbondedForce::CutoffPeriodic); + for (int i = 0; i < numParticles; ++i) { + system.addParticle(2.0); + forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0); + } + system.addForce(forceField); + MonteCarloMembraneBarostat* barostat = new MonteCarloMembraneBarostat(pressure, tension, temp, MonteCarloMembraneBarostat::XYAnisotropic, MonteCarloMembraneBarostat::ZFree, 1); + system.addForce(barostat); + vector positions(numParticles); + vector velocities(numParticles); + for (int i = 0; i < numParticles; ++i) { + positions[i] = Vec3((i%2 == 0 ? 2 : -2), (i%4 < 2 ? 2 : -2), (i < 4 ? 2 : -2)); + velocities[i] = Vec3(0, 0, 0); + } + + // Try twice with the same random seed. + + barostat->setRandomNumberSeed(5); + Context context(system, integrator, platform); + context.setPositions(positions); + context.setVelocities(velocities); + integrator.step(10); + State state1 = context.getState(State::Positions); + context.reinitialize(); + context.setPositions(positions); + context.setVelocities(velocities); + integrator.step(10); + State state2 = context.getState(State::Positions); + + // Try twice with a different random seed. + + barostat->setRandomNumberSeed(10); + context.reinitialize(); + context.setPositions(positions); + context.setVelocities(velocities); + integrator.step(10); + State state3 = context.getState(State::Positions); + context.reinitialize(); + context.setPositions(positions); + context.setVelocities(velocities); + integrator.step(10); + State state4 = context.getState(State::Positions); + + // Compare the results. + + for (int i = 0; i < numParticles; i++) { + for (int j = 0; j < 3; j++) { + ASSERT(state1.getPositions()[i][j] == state2.getPositions()[i][j]); + ASSERT(state3.getPositions()[i][j] == state4.getPositions()[i][j]); + ASSERT(state1.getPositions()[i][j] != state3.getPositions()[i][j]); + } + } +} + +int main() { + try { + testIdealGas(MonteCarloMembraneBarostat::XYIsotropic, MonteCarloMembraneBarostat::ZFree); + testIdealGas(MonteCarloMembraneBarostat::XYIsotropic, MonteCarloMembraneBarostat::ZFixed); + testIdealGas(MonteCarloMembraneBarostat::XYIsotropic, MonteCarloMembraneBarostat::ConstantVolume); + testIdealGas(MonteCarloMembraneBarostat::XYAnisotropic, MonteCarloMembraneBarostat::ZFree); + testIdealGas(MonteCarloMembraneBarostat::XYAnisotropic, MonteCarloMembraneBarostat::ZFixed); + testIdealGas(MonteCarloMembraneBarostat::XYAnisotropic, MonteCarloMembraneBarostat::ConstantVolume); + testRandomSeed(); + } + catch(const exception& e) { + cout << "exception: " << e.what() << endl; + return 1; + } + cout << "Done" << endl; + return 0; +} -- GitLab From 832ff70536733f7b5e5c3767f0d5ec6144f0f2cc Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Fri, 3 Oct 2014 19:26:42 -0400 Subject: [PATCH 031/338] Use CUDA 6.5 --- devtools/build-vm/linux/setup_centos_vm.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/devtools/build-vm/linux/setup_centos_vm.sh b/devtools/build-vm/linux/setup_centos_vm.sh index eb83e26be..8ed71ddd7 100644 --- a/devtools/build-vm/linux/setup_centos_vm.sh +++ b/devtools/build-vm/linux/setup_centos_vm.sh @@ -30,11 +30,10 @@ sudo yum clean packages # Install CUDA6 for RHEL6 cd ~/Software -wget http://developer.download.nvidia.com/compute/cuda/repos/rhel6/x86_64/cuda-repo-rhel6-6.0-37.x86_64.rpm -sudo rpm -i cuda-repo-rhel6-6.0-37.x86_64.rpm +wget http://developer.download.nvidia.com/compute/cuda/repos/rhel6/x86_64/cuda-repo-rhel6-6.5-14.x86_64.rpm +sudo rpm -i cuda-repo-rhel6-6.5-14.x86_64.rpm sudo yum clean expire-cache sudo yum install cuda -y -rm cuda-repo-rhel6-6.0-37.x86_64.rpm sudo yum update -y # Force a second update, in case CUDA has necessary patches. -- GitLab From a4bda3503f891b4f5029ab42b21dc2e43bd9459b Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Fri, 3 Oct 2014 19:29:14 -0400 Subject: [PATCH 032/338] Add comment warning about NVIDIA pushing new releases without warning. --- devtools/build-vm/linux/setup_centos_vm.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devtools/build-vm/linux/setup_centos_vm.sh b/devtools/build-vm/linux/setup_centos_vm.sh index 8ed71ddd7..7fd12f2b7 100644 --- a/devtools/build-vm/linux/setup_centos_vm.sh +++ b/devtools/build-vm/linux/setup_centos_vm.sh @@ -28,12 +28,14 @@ rm ~/rpmbuild -r sudo yum clean headers sudo yum clean packages -# Install CUDA6 for RHEL6 +# Install CUDA6.5 for RHEL6 cd ~/Software wget http://developer.download.nvidia.com/compute/cuda/repos/rhel6/x86_64/cuda-repo-rhel6-6.5-14.x86_64.rpm sudo rpm -i cuda-repo-rhel6-6.5-14.x86_64.rpm sudo yum clean expire-cache sudo yum install cuda -y +# NOTE: NVIDIA may push new MAJOR release versions of CUDA without warning. +# This is even *before* doing the below update. Beware. sudo yum update -y # Force a second update, in case CUDA has necessary patches. -- GitLab From 08eefd668d61211f9a2178adbac073c97d57cfc9 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 3 Oct 2014 16:58:24 -0700 Subject: [PATCH 033/338] Created Python API for MonteCarloMembraneBarostat --- openmmapi/include/OpenMM.h | 1 + wrappers/python/src/swig_doxygen/swigInputConfig.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/openmmapi/include/OpenMM.h b/openmmapi/include/OpenMM.h index 50015b99b..dcd8a2113 100644 --- a/openmmapi/include/OpenMM.h +++ b/openmmapi/include/OpenMM.h @@ -56,6 +56,7 @@ #include "openmm/LocalEnergyMinimizer.h" #include "openmm/MonteCarloAnisotropicBarostat.h" #include "openmm/MonteCarloBarostat.h" +#include "openmm/MonteCarloMembraneBarostat.h" #include "openmm/NonbondedForce.h" #include "openmm/Context.h" #include "openmm/OpenMMException.h" diff --git a/wrappers/python/src/swig_doxygen/swigInputConfig.py b/wrappers/python/src/swig_doxygen/swigInputConfig.py index 3f61803cf..07fa9f617 100755 --- a/wrappers/python/src/swig_doxygen/swigInputConfig.py +++ b/wrappers/python/src/swig_doxygen/swigInputConfig.py @@ -156,6 +156,7 @@ UNITS = { ("*", "getDefaultPressureX") : ("unit.bar", ()), ("*", "getDefaultPressureY") : ("unit.bar", ()), ("*", "getDefaultPressureZ") : ("unit.bar", ()), +("*", "getDefaultSurfaceTension") : ("unit.bar*unit.nanometer", ()), ("*", "getDefaultTemperature") : ("unit.kelvin", ()), ("*", "getErrorTolerance") : (None, ()), ("*", "getEwaldErrorTolerance") : (None, ()), @@ -416,6 +417,8 @@ UNITS = { ("System", "getForce") : (None, ()), ("System", "getVirtualSite") : (None, ()), ("DrudeLangevinIntegrator", "getDrudeTemperature") : ("unit.kelvin", ()), +("MonteCarloMembraneBarostat", "getXYMode") : (None, ()), +("MonteCarloMembraneBarostat", "getZMode") : (None, ()), ("DrudeLangevinIntegrator", "getDrudeFriction") : ("1/unit.picosecond", ()), ("DrudeSCFIntegrator", "getMinimizationErrorTolerance") : ("unit.kilojoules_per_mole/unit.nanometer", ()), ("RPMDIntegrator", "getContractions") : (None, ()), -- GitLab From 77c40022487b493acd489c3002387fa37b4809e7 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 3 Oct 2014 17:20:10 -0700 Subject: [PATCH 034/338] Added MonteCarloMembraneBarostat to the manual --- docs-source/usersguide/theory.rst | 41 ++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index dd51c1aee..4b76dd3d9 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -534,18 +534,18 @@ of the periodic box to vary with time.\ :cite:`Chow1995`\ :cite:`Aqvist2004` At regular intervals, it attempts a Monte Carlo step by scaling the box vectors and the coordinates of each molecule’s center by a factor *s*\ . The scale factor *s* is chosen to change the volume of the periodic box from *V* -to *V*\ +\ :math:`\delta`\ *V*\ : +to *V*\ +\ :math:`\Delta`\ *V*\ : .. math:: - s={\left(\frac{V+\delta V}{V}\right)}^{1/3} + s={\left(\frac{V+\Delta V}{V}\right)}^{1/3} The change in volume is chosen randomly as .. math:: - \delta V=A\cdot r + \Delta V=A\cdot r where *A* is a scale factor and *r* is a random number uniformly @@ -554,7 +554,7 @@ weight function .. math:: - \Delta W=\Delta E+P\delta V-Nk_{B}T \text{ln}\left(\frac{V+\delta V}{V}\right) + \Delta W=\Delta E+P\Delta V-Nk_{B}T \text{ln}\left(\frac{V+\Delta V}{V}\right) where :math:`\Delta E` is the change in potential energy resulting from the step, @@ -602,6 +602,39 @@ You can specify that the barostat should only be applied to certain axes of the box, keeping the other axes fixed. This is useful, for example, when doing constant surface area simulations of membranes. +MonteCarloMembraneBarostat +************************** + +MonteCarloMembraneBarostat is very similar to MonteCarloBarostat, but it is +specialized for simulations of membranes. It assumes the membrane lies in the +XY plane. In addition to applying a uniform pressure to regulate the volume of +the periodic box, it also applies a uniform surface tension to regulate the +cross sectional area of the periodic box in the XY plane. The weight function +for deciding whether to accept a step is + +.. math:: + \Delta W=\Delta E+P\Delta V-S\Delta A-Nk_{B}T \text{ln}\left(\frac{V+\Delta V}{V}\right) + +where *S* is the surface tension and :math:`\Delta`\ *A* is the change in cross +sectional area. Notice that pressure and surface tension are defined with +opposite senses: a larger pressure tends to make the box smaller, but a larger +surface tension tends to make the box larger. + +MonteCarloMembraneBarostat offers some additional options to customize the +behavior of the periodic box: + +* The X and Y axes can be either + + * isotropic (they are always scaled by the same amount, so their ratio remains fixed) + * anisotropic (they can change size independently) + +* The Z axis can be either + + * free (its size changes independently of the X and Y axes) + * fixed (its size does not change) + * inversely varying with the X and Y axes (so the total box volume does not + change) + CMMotionRemover *************** -- GitLab From 3439d8736b0e909a40b9bf8d22ca6cad56483f9f Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 6 Oct 2014 10:56:29 -0700 Subject: [PATCH 035/338] Serialization support for MonteCarloMembraneBarostat and MonteCarloAnisotropicBarostat --- .../MonteCarloAnisotropicBarostatProxy.h | 53 +++++++++++++ .../MonteCarloMembraneBarostatProxy.h | 53 +++++++++++++ .../MonteCarloAnisotropicBarostatProxy.cpp | 77 +++++++++++++++++++ serialization/src/MonteCarloBarostatProxy.cpp | 2 +- .../src/MonteCarloMembraneBarostatProxy.cpp | 75 ++++++++++++++++++ .../src/SerializationProxyRegistration.cpp | 8 +- ...SerializeMonteCarloAnisotropicBarostat.cpp | 77 +++++++++++++++++++ ...estSerializeMonteCarloMembraneBarostat.cpp | 77 +++++++++++++++++++ 8 files changed, 420 insertions(+), 2 deletions(-) create mode 100644 serialization/include/openmm/serialization/MonteCarloAnisotropicBarostatProxy.h create mode 100644 serialization/include/openmm/serialization/MonteCarloMembraneBarostatProxy.h create mode 100644 serialization/src/MonteCarloAnisotropicBarostatProxy.cpp create mode 100644 serialization/src/MonteCarloMembraneBarostatProxy.cpp create mode 100644 serialization/tests/TestSerializeMonteCarloAnisotropicBarostat.cpp create mode 100644 serialization/tests/TestSerializeMonteCarloMembraneBarostat.cpp diff --git a/serialization/include/openmm/serialization/MonteCarloAnisotropicBarostatProxy.h b/serialization/include/openmm/serialization/MonteCarloAnisotropicBarostatProxy.h new file mode 100644 index 000000000..36791d320 --- /dev/null +++ b/serialization/include/openmm/serialization/MonteCarloAnisotropicBarostatProxy.h @@ -0,0 +1,53 @@ +#ifndef OPENMM_MONTECARLOANISOTROPICBAROSTAT_PROXY_H_ +#define OPENMM_MONTECARLOANISOTROPICBAROSTAT_PROXY_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) 2010=2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/internal/windowsExport.h" +#include "openmm/serialization/SerializationProxy.h" + +namespace OpenMM { + +/** + * This is a proxy for serializing MonteCarloAnisotropicBarostat objects. + */ + +class OPENMM_EXPORT MonteCarloAnisotropicBarostatProxy : public SerializationProxy { +public: + MonteCarloAnisotropicBarostatProxy(); + void serialize(const void* object, SerializationNode& node) const; + void* deserialize(const SerializationNode& node) const; +}; + +} // namespace OpenMM + +#endif /*OPENMM_MONTECARLOANISOTROPICBAROSTAT_PROXY_H_*/ diff --git a/serialization/include/openmm/serialization/MonteCarloMembraneBarostatProxy.h b/serialization/include/openmm/serialization/MonteCarloMembraneBarostatProxy.h new file mode 100644 index 000000000..9b6b54af9 --- /dev/null +++ b/serialization/include/openmm/serialization/MonteCarloMembraneBarostatProxy.h @@ -0,0 +1,53 @@ +#ifndef OPENMM_MONTECARLOMEMBRANEBAROSTAT_PROXY_H_ +#define OPENMM_MONTECARLOMEMBRANEBAROSTAT_PROXY_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) 2010=2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/internal/windowsExport.h" +#include "openmm/serialization/SerializationProxy.h" + +namespace OpenMM { + +/** + * This is a proxy for serializing MonteCarloMembraneBarostat objects. + */ + +class OPENMM_EXPORT MonteCarloMembraneBarostatProxy : public SerializationProxy { +public: + MonteCarloMembraneBarostatProxy(); + void serialize(const void* object, SerializationNode& node) const; + void* deserialize(const SerializationNode& node) const; +}; + +} // namespace OpenMM + +#endif /*OPENMM_MONTECARLOMEMBRANEBAROSTAT_PROXY_H_*/ diff --git a/serialization/src/MonteCarloAnisotropicBarostatProxy.cpp b/serialization/src/MonteCarloAnisotropicBarostatProxy.cpp new file mode 100644 index 000000000..8101fc7d6 --- /dev/null +++ b/serialization/src/MonteCarloAnisotropicBarostatProxy.cpp @@ -0,0 +1,77 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/serialization/MonteCarloAnisotropicBarostatProxy.h" +#include "openmm/serialization/SerializationNode.h" +#include "openmm/Force.h" +#include "openmm/MonteCarloAnisotropicBarostat.h" +#include + +using namespace OpenMM; +using namespace std; + +MonteCarloAnisotropicBarostatProxy::MonteCarloAnisotropicBarostatProxy() : SerializationProxy("MonteCarloAnisotropicBarostat") { +} + +void MonteCarloAnisotropicBarostatProxy::serialize(const void* object, SerializationNode& node) const { + node.setIntProperty("version", 1); + const MonteCarloAnisotropicBarostat& force = *reinterpret_cast(object); + node.setIntProperty("forceGroup", force.getForceGroup()); + Vec3 pressure = force.getDefaultPressure(); + node.setDoubleProperty("pressurex", pressure[0]); + node.setDoubleProperty("pressurey", pressure[1]); + node.setDoubleProperty("pressurez", pressure[2]); + node.setBoolProperty("scalex", force.getScaleX()); + node.setBoolProperty("scaley", force.getScaleY()); + node.setBoolProperty("scalez", force.getScaleZ()); + node.setDoubleProperty("temperature", force.getTemperature()); + node.setIntProperty("frequency", force.getFrequency()); + node.setIntProperty("randomSeed", force.getRandomNumberSeed()); +} + +void* MonteCarloAnisotropicBarostatProxy::deserialize(const SerializationNode& node) const { + if (node.getIntProperty("version") != 1) + throw OpenMMException("Unsupported version number"); + MonteCarloAnisotropicBarostat* force = NULL; + try { + Vec3 pressure(node.getDoubleProperty("pressurex"), node.getDoubleProperty("pressurey"), node.getDoubleProperty("pressurez")); + force = new MonteCarloAnisotropicBarostat(pressure, node.getDoubleProperty("temperature"), node.getBoolProperty("scalex"), + node.getBoolProperty("scaley"), node.getBoolProperty("scalez"), node.getIntProperty("frequency")); + force->setForceGroup(node.getIntProperty("forceGroup", 0)); + force->setRandomNumberSeed(node.getIntProperty("randomSeed")); + return force; + } + catch (...) { + if (force != NULL) + delete force; + throw; + } +} diff --git a/serialization/src/MonteCarloBarostatProxy.cpp b/serialization/src/MonteCarloBarostatProxy.cpp index 655d60c69..94cca733c 100644 --- a/serialization/src/MonteCarloBarostatProxy.cpp +++ b/serialization/src/MonteCarloBarostatProxy.cpp @@ -56,7 +56,7 @@ void* MonteCarloBarostatProxy::deserialize(const SerializationNode& node) const throw OpenMMException("Unsupported version number"); MonteCarloBarostat* force = NULL; try { - MonteCarloBarostat* force = new MonteCarloBarostat(node.getDoubleProperty("pressure"), node.getDoubleProperty("temperature"), node.getIntProperty("frequency")); + force = new MonteCarloBarostat(node.getDoubleProperty("pressure"), node.getDoubleProperty("temperature"), node.getIntProperty("frequency")); force->setForceGroup(node.getIntProperty("forceGroup", 0)); force->setRandomNumberSeed(node.getIntProperty("randomSeed")); return force; diff --git a/serialization/src/MonteCarloMembraneBarostatProxy.cpp b/serialization/src/MonteCarloMembraneBarostatProxy.cpp new file mode 100644 index 000000000..20a846a86 --- /dev/null +++ b/serialization/src/MonteCarloMembraneBarostatProxy.cpp @@ -0,0 +1,75 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/serialization/MonteCarloMembraneBarostatProxy.h" +#include "openmm/serialization/SerializationNode.h" +#include "openmm/Force.h" +#include "openmm/MonteCarloMembraneBarostat.h" +#include + +using namespace OpenMM; +using namespace std; + +MonteCarloMembraneBarostatProxy::MonteCarloMembraneBarostatProxy() : SerializationProxy("MonteCarloMembraneBarostat") { +} + +void MonteCarloMembraneBarostatProxy::serialize(const void* object, SerializationNode& node) const { + node.setIntProperty("version", 1); + const MonteCarloMembraneBarostat& force = *reinterpret_cast(object); + node.setIntProperty("forceGroup", force.getForceGroup()); + node.setDoubleProperty("pressure", force.getDefaultPressure()); + node.setDoubleProperty("surfaceTension", force.getDefaultSurfaceTension()); + node.setDoubleProperty("temperature", force.getTemperature()); + node.setIntProperty("xymode", force.getXYMode()); + node.setIntProperty("zmode", force.getZMode()); + node.setIntProperty("frequency", force.getFrequency()); + node.setIntProperty("randomSeed", force.getRandomNumberSeed()); +} + +void* MonteCarloMembraneBarostatProxy::deserialize(const SerializationNode& node) const { + if (node.getIntProperty("version") != 1) + throw OpenMMException("Unsupported version number"); + MonteCarloMembraneBarostat* force = NULL; + try { + MonteCarloMembraneBarostat::XYMode xymode = (MonteCarloMembraneBarostat::XYMode) node.getIntProperty("xymode"); + MonteCarloMembraneBarostat::ZMode zmode = (MonteCarloMembraneBarostat::ZMode) node.getIntProperty("zmode"); + force = new MonteCarloMembraneBarostat(node.getDoubleProperty("pressure"), node.getDoubleProperty("surfaceTension"), + node.getDoubleProperty("temperature"), xymode, zmode, node.getIntProperty("frequency")); + force->setForceGroup(node.getIntProperty("forceGroup", 0)); + force->setRandomNumberSeed(node.getIntProperty("randomSeed")); + return force; + } + catch (...) { + if (force != NULL) + delete force; + throw; + } +} diff --git a/serialization/src/SerializationProxyRegistration.cpp b/serialization/src/SerializationProxyRegistration.cpp index 2f1ea7d71..2624436a0 100644 --- a/serialization/src/SerializationProxyRegistration.cpp +++ b/serialization/src/SerializationProxyRegistration.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010 Stanford University and the Authors. * + * Portions copyright (c) 2010-2014 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -48,7 +48,9 @@ #include "openmm/HarmonicAngleForce.h" #include "openmm/HarmonicBondForce.h" #include "openmm/LangevinIntegrator.h" +#include "openmm/MonteCarloAnisotropicBarostat.h" #include "openmm/MonteCarloBarostat.h" +#include "openmm/MonteCarloMembraneBarostat.h" #include "openmm/NonbondedForce.h" #include "openmm/PeriodicTorsionForce.h" #include "openmm/RBTorsionForce.h" @@ -78,7 +80,9 @@ #include "openmm/serialization/HarmonicAngleForceProxy.h" #include "openmm/serialization/HarmonicBondForceProxy.h" #include "openmm/serialization/LangevinIntegratorProxy.h" +#include "openmm/serialization/MonteCarloAnisotropicBarostatProxy.h" #include "openmm/serialization/MonteCarloBarostatProxy.h" +#include "openmm/serialization/MonteCarloMembraneBarostatProxy.h" #include "openmm/serialization/NonbondedForceProxy.h" #include "openmm/serialization/PeriodicTorsionForceProxy.h" #include "openmm/serialization/RBTorsionForceProxy.h" @@ -129,7 +133,9 @@ extern "C" void registerSerializationProxies() { SerializationProxy::registerProxy(typeid(HarmonicAngleForce), new HarmonicAngleForceProxy()); SerializationProxy::registerProxy(typeid(HarmonicBondForce), new HarmonicBondForceProxy()); SerializationProxy::registerProxy(typeid(LangevinIntegrator), new LangevinIntegratorProxy()); + SerializationProxy::registerProxy(typeid(MonteCarloAnisotropicBarostat), new MonteCarloAnisotropicBarostatProxy()); SerializationProxy::registerProxy(typeid(MonteCarloBarostat), new MonteCarloBarostatProxy()); + SerializationProxy::registerProxy(typeid(MonteCarloMembraneBarostat), new MonteCarloMembraneBarostatProxy()); SerializationProxy::registerProxy(typeid(NonbondedForce), new NonbondedForceProxy()); SerializationProxy::registerProxy(typeid(PeriodicTorsionForce), new PeriodicTorsionForceProxy()); SerializationProxy::registerProxy(typeid(RBTorsionForce), new RBTorsionForceProxy()); diff --git a/serialization/tests/TestSerializeMonteCarloAnisotropicBarostat.cpp b/serialization/tests/TestSerializeMonteCarloAnisotropicBarostat.cpp new file mode 100644 index 000000000..d4506d168 --- /dev/null +++ b/serialization/tests/TestSerializeMonteCarloAnisotropicBarostat.cpp @@ -0,0 +1,77 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/internal/AssertionUtilities.h" +#include "openmm/MonteCarloAnisotropicBarostat.h" +#include "openmm/serialization/XmlSerializer.h" +#include +#include + +using namespace OpenMM; +using namespace std; + +void testSerialization() { + // Create a Force. + + MonteCarloAnisotropicBarostat force(Vec3(15.1, 18.2, 19.3), 250.0, true, false, true, 14); + force.setForceGroup(3); + force.setRandomNumberSeed(3); + + // Serialize and then deserialize it. + + stringstream buffer; + XmlSerializer::serialize(&force, "Force", buffer); + MonteCarloAnisotropicBarostat* copy = XmlSerializer::deserialize(buffer); + + // Compare the two forces to see if they are identical. + + MonteCarloAnisotropicBarostat& force2 = *copy; + ASSERT_EQUAL(force.getForceGroup(), force2.getForceGroup()); + ASSERT_EQUAL_VEC(force.getDefaultPressure(), force2.getDefaultPressure(), 0.0); + ASSERT_EQUAL(force.getTemperature(), force2.getTemperature()); + ASSERT_EQUAL(force.getScaleX(), force2.getScaleX()); + ASSERT_EQUAL(force.getScaleY(), force2.getScaleY()); + ASSERT_EQUAL(force.getScaleZ(), force2.getScaleZ()); + ASSERT_EQUAL(force.getFrequency(), force2.getFrequency()); + ASSERT_EQUAL(force.getRandomNumberSeed(), force2.getRandomNumberSeed()); +} + +int main() { + try { + testSerialization(); + } + catch(const exception& e) { + cout << "exception: " << e.what() << endl; + return 1; + } + cout << "Done" << endl; + return 0; +} diff --git a/serialization/tests/TestSerializeMonteCarloMembraneBarostat.cpp b/serialization/tests/TestSerializeMonteCarloMembraneBarostat.cpp new file mode 100644 index 000000000..9de12915e --- /dev/null +++ b/serialization/tests/TestSerializeMonteCarloMembraneBarostat.cpp @@ -0,0 +1,77 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/internal/AssertionUtilities.h" +#include "openmm/MonteCarloMembraneBarostat.h" +#include "openmm/serialization/XmlSerializer.h" +#include +#include + +using namespace OpenMM; +using namespace std; + +void testSerialization() { + // Create a Force. + + MonteCarloMembraneBarostat force(25.5, 11.2, 250.0, MonteCarloMembraneBarostat::XYAnisotropic, MonteCarloMembraneBarostat::ZFixed, 14); + force.setForceGroup(3); + force.setRandomNumberSeed(3); + + // Serialize and then deserialize it. + + stringstream buffer; + XmlSerializer::serialize(&force, "Force", buffer); + MonteCarloMembraneBarostat* copy = XmlSerializer::deserialize(buffer); + + // Compare the two forces to see if they are identical. + + MonteCarloMembraneBarostat& force2 = *copy; + ASSERT_EQUAL(force.getForceGroup(), force2.getForceGroup()); + ASSERT_EQUAL(force.getDefaultPressure(), force2.getDefaultPressure()); + ASSERT_EQUAL(force.getDefaultSurfaceTension(), force2.getDefaultSurfaceTension()); + ASSERT_EQUAL(force.getTemperature(), force2.getTemperature()); + ASSERT_EQUAL(force.getXYMode(), force2.getXYMode()); + ASSERT_EQUAL(force.getZMode(), force2.getZMode()); + ASSERT_EQUAL(force.getFrequency(), force2.getFrequency()); + ASSERT_EQUAL(force.getRandomNumberSeed(), force2.getRandomNumberSeed()); +} + +int main() { + try { + testSerialization(); + } + catch(const exception& e) { + cout << "exception: " << e.what() << endl; + return 1; + } + cout << "Done" << endl; + return 0; +} -- GitLab From 79929693eed51cdf8a75c144591265b935bfa32e Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 6 Oct 2014 11:20:50 -0700 Subject: [PATCH 036/338] More documentation on MonteCarloMembraneBarostat --- docs-source/usersguide/application.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs-source/usersguide/application.rst b/docs-source/usersguide/application.rst index 48ab7d5af..027614493 100644 --- a/docs-source/usersguide/application.rst +++ b/docs-source/usersguide/application.rst @@ -1196,6 +1196,22 @@ change size. system.addForce(MonteCarloAnisotropicBarostat((1, 1, 1)*bar, 300*kelvin, False, True, False)) +There is a third barostat designed specifically for simulations of membranes. +It assumes the membrane lies in the XY plane, and treats the X and Y axes of the +box differently from the Z axis. It also applies a uniform surface tension in +the plane of the membrane. The following line adds a membrane barostat that +applies a pressure of 1 bar and a surface tension of 200 bar*nm. It specifies +that the X and Y axes are treated isotropically while the Z axis is free to +change independently. +:: + + system.addForce(MonteCarloMembraneBarostat(1*bar, 200*bar*nanometer, + MonteCarloMembraneBarostat.XYIsotropic, MonteCarloMembraneBarostat.ZFree, 300*kelvin)) + +See the API documentation for details about the allowed parameter values and +their meanings. + + Energy Minimization =================== -- GitLab From 468a8a5c1ab68a9c88c4986b40539e21447a000b Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 6 Oct 2014 14:28:53 -0700 Subject: [PATCH 037/338] Began creating CPU version of CustomGBForce --- platforms/cpu/include/CpuCustomGBForce.h | 263 ++++++++++ platforms/cpu/include/CpuKernels.h | 53 ++ platforms/cpu/src/CpuCustomGBForce.cpp | 420 ++++++++++++++++ platforms/cpu/src/CpuKernelFactory.cpp | 2 + platforms/cpu/src/CpuKernels.cpp | 156 ++++++ platforms/cpu/src/CpuPlatform.cpp | 1 + platforms/cpu/tests/TestCpuCustomGBForce.cpp | 479 +++++++++++++++++++ 7 files changed, 1374 insertions(+) create mode 100644 platforms/cpu/include/CpuCustomGBForce.h create mode 100644 platforms/cpu/src/CpuCustomGBForce.cpp create mode 100644 platforms/cpu/tests/TestCpuCustomGBForce.cpp diff --git a/platforms/cpu/include/CpuCustomGBForce.h b/platforms/cpu/include/CpuCustomGBForce.h new file mode 100644 index 000000000..4bedde933 --- /dev/null +++ b/platforms/cpu/include/CpuCustomGBForce.h @@ -0,0 +1,263 @@ + +/* Portions copyright (c) 2009-2014 Stanford University and Simbios. + * Contributors: Peter Eastman + * + * 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. + */ + +#ifndef OPENMM_CPU_CUSTOM_GB_FORCE_H__ +#define OPENMM_CPU_CUSTOM_GB_FORCE_H__ + +#include "ReferenceNeighborList.h" +#include "CompiledExpressionSet.h" +#include "lepton/CompiledExpression.h" +#include "openmm/CustomGBForce.h" +#include +#include +#include + +class CpuCustomGBForce { +private: + bool cutoff; + bool periodic; + const OpenMM::NeighborList* neighborList; + RealOpenMM periodicBoxSize[3]; + RealOpenMM cutoffDistance; + OpenMM::CompiledExpressionSet expressionSet; + std::vector valueExpressions; + std::vector > valueDerivExpressions; + std::vector > valueGradientExpressions; + std::vector valueNames; + std::vector valueIndex; + std::vector valueTypes; + std::vector energyExpressions; + std::vector > energyDerivExpressions; + std::vector > energyGradientExpressions; + std::vector paramNames; + std::vector paramIndex; + std::vector energyTypes; + std::vector particleParamNames; + std::vector particleValueNames; + std::vector particleParamIndex; + std::vector particleValueIndex; + int xindex, yindex, zindex, rindex; + + /** + * Calculate a computed value of type SingleParticle + * + * @param index the index of the value to compute + * @param numAtoms number of atoms + * @param atomCoordinates atom coordinates + * @param values the vector to store computed values into + * @param globalParameters the values of global parameters + * @param atomParameters atomParameters[atomIndex][paramterIndex] + */ + + void calculateSingleParticleValue(int index, int numAtoms, std::vector& atomCoordinates, std::vector >& values, + const std::map& globalParameters, RealOpenMM** atomParameters); + + /** + * Calculate a computed value that is based on particle pairs + * + * @param index the index of the value to compute + * @param numAtoms number of atoms + * @param atomCoordinates atom coordinates + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param values the vector to store computed values into + * @param globalParameters the values of global parameters + * @param exclusions exclusions[i] is the set of excluded indices for atom i + * @param useExclusions specifies whether to use exclusions + */ + + void calculateParticlePairValue(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, + std::vector >& values, + const std::map& globalParameters, + const std::vector >& exclusions, bool useExclusions); + + /** + * Evaluate a single atom pair as part of calculating a computed value + * + * @param index the index of the value to compute + * @param atom1 the index of the first atom in the pair + * @param atom2 the index of the second atom in the pair + * @param atomCoordinates atom coordinates + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param globalParameters the values of global parameters + * @param values the vector to store computed values into + */ + + void calculateOnePairValue(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, + const std::map& globalParameters, + std::vector >& values); + + /** + * Calculate an energy term of type SingleParticle + * + * @param index the index of the value to compute + * @param numAtoms number of atoms + * @param atomCoordinates atom coordinates + * @param values the vector containing computed values + * @param globalParameters the values of global parameters + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param forces forces on atoms are added to this + * @param totalEnergy the energy contribution is added to this + * @param dEdV the derivative of energy with respect to computed values is stored in this + */ + + void calculateSingleParticleEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, const std::vector >& values, + const std::map& globalParameters, RealOpenMM** atomParameters, std::vector& forces, + RealOpenMM* totalEnergy, std::vector >& dEdV); + + /** + * Calculate an energy term that is based on particle pairs + * + * @param index the index of the term to compute + * @param numAtoms number of atoms + * @param atomCoordinates atom coordinates + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param values the vector containing computed values + * @param globalParameters the values of global parameters + * @param exclusions exclusions[i] is the set of excluded indices for atom i + * @param useExclusions specifies whether to use exclusions + * @param forces forces on atoms are added to this + * @param totalEnergy the energy contribution is added to this + * @param dEdV the derivative of energy with respect to computed values is stored in this + */ + + void calculateParticlePairEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, + const std::vector >& values, + const std::map& globalParameters, + const std::vector >& exclusions, bool useExclusions, + std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); + + /** + * Evaluate a single atom pair as part of calculating an energy term + * + * @param index the index of the term to compute + * @param atom1 the index of the first atom in the pair + * @param atom2 the index of the second atom in the pair + * @param atomCoordinates atom coordinates + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param globalParameters the values of global parameters + * @param values the vector containing computed values + * @param forces forces on atoms are added to this + * @param totalEnergy the energy contribution is added to this + * @param dEdV the derivative of energy with respect to computed values is stored in this + */ + + void calculateOnePairEnergyTerm(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, + const std::map& globalParameters, + const std::vector >& values, + std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); + + /** + * Apply the chain rule to compute forces on atoms + * + * @param numAtoms number of atoms + * @param atomCoordinates atom coordinates + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param values the vector containing computed values + * @param globalParameters the values of global parameters + * @param exclusions exclusions[i] is the set of excluded indices for atom i + * @param forces forces on atoms are added to this + * @param dEdV the derivative of energy with respect to computed values is stored in this + */ + + void calculateChainRuleForces(int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, + const std::vector >& values, + const std::map& globalParameters, + const std::vector >& exclusions, + std::vector& forces, std::vector >& dEdV); + + /** + * Evaluate a single atom pair as part of applying the chain rule + * + * @param atom1 the index of the first atom in the pair + * @param atom2 the index of the second atom in the pair + * @param atomCoordinates atom coordinates + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param globalParameters the values of global parameters + * @param values the vector containing computed values + * @param forces forces on atoms are added to this + * @param dEdV the derivative of energy with respect to computed values is stored in this + * @param isExcluded specifies whether this is an excluded pair + */ + + void calculateOnePairChainRule(int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, + const std::map& globalParameters, + const std::vector >& values, + std::vector& forces, std::vector >& dEdV, + bool isExcluded); + +public: + + /** + * Construct a new CpuCustomGBForce. + */ + + CpuCustomGBForce(const std::vector& valueExpressions, + const std::vector > valueDerivExpressions, + const std::vector > valueGradientExpressions, + const std::vector& valueNames, + const std::vector& valueTypes, + const std::vector& energyExpressions, + const std::vector > energyDerivExpressions, + const std::vector > energyGradientExpressions, + const std::vector& energyTypes, + const std::vector& parameterNames); + + ~CpuCustomGBForce(); + + /** + * Set the force to use a cutoff. + * + * @param distance the cutoff distance + * @param neighbors the neighbor list to use + */ + + void setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors); + + /** + * Set the force to use periodic boundary conditions. This requires that a cutoff has + * already been set, and the smallest side of the periodic box is at least twice the cutoff + * distance. + * + * @param boxSize the X, Y, and Z widths of the periodic box + */ + + void setPeriodic(OpenMM::RealVec& boxSize); + + /** + * Calculate custom GB ixn + * + * @param numberOfAtoms number of atoms + * @param atomCoordinates atom coordinates + * @param atomParameters atomParameters[atomIndex][paramterIndex] + * @param exclusions exclusions[i] is the set of excluded indices for atom i + * @param globalParameters the values of global parameters + * @param forces force array (forces added) + * @param totalEnergy total energy + */ + + void calculateIxn(int numberOfAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& exclusions, + std::map& globalParameters, std::vector& forces, RealOpenMM* totalEnergy); +}; + +#endif // OPENMM_CPU_CUSTOM_GB_FORCE_H__ diff --git a/platforms/cpu/include/CpuKernels.h b/platforms/cpu/include/CpuKernels.h index 49021aa0b..05b0448f9 100644 --- a/platforms/cpu/include/CpuKernels.h +++ b/platforms/cpu/include/CpuKernels.h @@ -33,6 +33,7 @@ * -------------------------------------------------------------------------- */ #include "CpuBondForce.h" +#include "CpuCustomGBForce.h" #include "CpuCustomManyParticleForce.h" #include "CpuCustomNonbondedForce.h" #include "CpuGBSAOBCForce.h" @@ -303,6 +304,58 @@ private: CpuGBSAOBCForce obc; }; +/** + * This kernel is invoked by CustomGBForce to calculate the forces acting on the system. + */ +class CpuCalcCustomGBForceKernel : public CalcCustomGBForceKernel { +public: + CpuCalcCustomGBForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) : + CalcCustomGBForceKernel(name, platform), data(data) { + } + ~CpuCalcCustomGBForceKernel(); + /** + * Initialize the kernel. + * + * @param system the System this kernel will be applied to + * @param force the CustomGBForce this kernel will be used for + */ + void initialize(const System& system, const CustomGBForce& force); + /** + * Execute the kernel to calculate the forces and/or energy. + * + * @param context the context in which to execute this kernel + * @param includeForces true if forces should be calculated + * @param includeEnergy true if the energy should be calculated + * @return the potential energy due to the force + */ + double execute(ContextImpl& context, bool includeForces, bool includeEnergy); + /** + * Copy changed parameters over to a context. + * + * @param context the context to copy parameters to + * @param force the CustomGBForce to copy the parameters from + */ + void copyParametersToContext(ContextImpl& context, const CustomGBForce& force); +private: + CpuPlatform::PlatformData& data; + int numParticles; + bool isPeriodic; + RealOpenMM **particleParamArray; + RealOpenMM nonbondedCutoff; + std::vector > exclusions; + std::vector particleParameterNames, globalParameterNames, valueNames; + std::vector valueExpressions; + std::vector > valueDerivExpressions; + std::vector > valueGradientExpressions; + std::vector valueTypes; + std::vector energyExpressions; + std::vector > energyDerivExpressions; + std::vector > energyGradientExpressions; + std::vector energyTypes; + NonbondedMethod nonbondedMethod; + NeighborList* neighborList; +}; + /** * This kernel is invoked by CustomManyParticleForce to calculate the forces acting on the system and the energy of the system. */ diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp new file mode 100644 index 000000000..0e038c017 --- /dev/null +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -0,0 +1,420 @@ + +/* Portions copyright (c) 2009-2014 Stanford University and Simbios. + * Contributors: Peter Eastman + * + * 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 +#include + +#include "SimTKOpenMMCommon.h" +#include "SimTKOpenMMLog.h" +#include "SimTKOpenMMUtilities.h" +#include "ReferenceForce.h" +#include "CpuCustomGBForce.h" + +using std::map; +using std::set; +using std::string; +using std::stringstream; +using std::vector; +using OpenMM::RealVec; + +CpuCustomGBForce::CpuCustomGBForce(const vector& valueExpressions, + const vector > valueDerivExpressions, + const vector > valueGradientExpressions, + const vector& valueNames, + const vector& valueTypes, + const vector& energyExpressions, + const vector > energyDerivExpressions, + const vector > energyGradientExpressions, + const vector& energyTypes, + const vector& parameterNames) : + cutoff(false), periodic(false), valueExpressions(valueExpressions), valueDerivExpressions(valueDerivExpressions), valueGradientExpressions(valueGradientExpressions), + valueNames(valueNames), valueTypes(valueTypes), energyExpressions(energyExpressions), energyDerivExpressions(energyDerivExpressions), energyGradientExpressions(energyGradientExpressions), + energyTypes(energyTypes), paramNames(parameterNames) { + for (int i = 0; i < (int) valueExpressions.size(); i++) + expressionSet.registerExpression(this->valueExpressions[i]); + for (int i = 0; i < (int) valueDerivExpressions.size(); i++) + for (int j = 0; j < (int) valueDerivExpressions[i].size(); j++) + expressionSet.registerExpression(this->valueDerivExpressions[i][j]); + for (int i = 0; i < (int) valueGradientExpressions.size(); i++) + for (int j = 0; j < (int) valueGradientExpressions[i].size(); j++) + expressionSet.registerExpression(this->valueGradientExpressions[i][j]); + for (int i = 0; i < (int) energyExpressions.size(); i++) + expressionSet.registerExpression(this->energyExpressions[i]); + for (int i = 0; i < (int) energyDerivExpressions.size(); i++) + for (int j = 0; j < (int) energyDerivExpressions[i].size(); j++) + expressionSet.registerExpression(this->energyDerivExpressions[i][j]); + for (int i = 0; i < (int) energyGradientExpressions.size(); i++) + for (int j = 0; j < (int) energyGradientExpressions[i].size(); j++) + expressionSet.registerExpression(this->energyGradientExpressions[i][j]); + xindex = expressionSet.getVariableIndex("x"); + yindex = expressionSet.getVariableIndex("y"); + zindex = expressionSet.getVariableIndex("z"); + rindex = expressionSet.getVariableIndex("r"); + for (int i = 0; i < (int) paramNames.size(); i++) { + paramIndex.push_back(expressionSet.getVariableIndex(paramNames[i])); + for (int j = 1; j < 3; j++) { + stringstream name; + name << paramNames[i] << j; + particleParamNames.push_back(name.str()); + particleParamIndex.push_back(expressionSet.getVariableIndex(name.str())); + } + } + for (int i = 0; i < (int) valueNames.size(); i++) { + valueIndex.push_back(expressionSet.getVariableIndex(valueNames[i])); + for (int j = 1; j < 3; j++) { + stringstream name; + name << valueNames[i] << j; + particleValueNames.push_back(name.str()); + particleValueIndex.push_back(expressionSet.getVariableIndex(name.str())); + } + } +} + +CpuCustomGBForce::~CpuCustomGBForce() { +} + +void CpuCustomGBForce::setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors) { + cutoff = true; + cutoffDistance = distance; + neighborList = &neighbors; +} + +void CpuCustomGBForce::setPeriodic(RealVec& boxSize) { + + if (cutoff) { + assert(boxSize[0] >= 2.0*cutoffDistance); + assert(boxSize[1] >= 2.0*cutoffDistance); + assert(boxSize[2] >= 2.0*cutoffDistance); + } + periodic = true; + periodicBoxSize[0] = boxSize[0]; + periodicBoxSize[1] = boxSize[1]; + periodicBoxSize[2] = boxSize[2]; + } + +void CpuCustomGBForce::calculateIxn(int numberOfAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, + const vector >& exclusions, map& globalParameters, vector& forces, + RealOpenMM* totalEnergy) { + for (map::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) + expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); + + // First calculate the computed values. + + int numValues = valueTypes.size(); + vector > values(numValues); + for (int valueIndex = 0; valueIndex < numValues; valueIndex++) { + if (valueTypes[valueIndex] == OpenMM::CustomGBForce::SingleParticle) + calculateSingleParticleValue(valueIndex, numberOfAtoms, atomCoordinates, values, globalParameters, atomParameters); + else if (valueTypes[valueIndex] == OpenMM::CustomGBForce::ParticlePair) + calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, true); + else + calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, false); + } + + // Now calculate the energy and its derivatives. + + vector > dEdV(numValues, vector(numberOfAtoms, (RealOpenMM) 0)); + for (int termIndex = 0; termIndex < (int) energyExpressions.size(); termIndex++) { + if (energyTypes[termIndex] == OpenMM::CustomGBForce::SingleParticle) + calculateSingleParticleEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, values, globalParameters, atomParameters, forces, totalEnergy, dEdV); + else if (energyTypes[termIndex] == OpenMM::CustomGBForce::ParticlePair) + calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, true, forces, totalEnergy, dEdV); + else + calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, false, forces, totalEnergy, dEdV); + } + + // Apply the chain rule to evaluate forces. + + calculateChainRuleForces(numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, forces, dEdV); +} + +void CpuCustomGBForce::calculateSingleParticleValue(int index, int numAtoms, vector& atomCoordinates, vector >& values, + const map& globalParameters, RealOpenMM** atomParameters) { + values[index].resize(numAtoms); + for (int i = 0; i < numAtoms; i++) { + expressionSet.setVariable(xindex, atomCoordinates[i][0]); + expressionSet.setVariable(yindex, atomCoordinates[i][1]); + expressionSet.setVariable(zindex, atomCoordinates[i][2]); + for (int j = 0; j < (int) paramNames.size(); j++) + expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); + for (int j = 0; j < index; j++) + expressionSet.setVariable(valueIndex[j], values[j][i]); + values[index][i] = (RealOpenMM) valueExpressions[index].evaluate(); + } +} + +void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, + vector >& values, const map& globalParameters, const vector >& exclusions, bool useExclusions) { + values[index].resize(numAtoms); + for (int i = 0; i < numAtoms; i++) + values[index][i] = (RealOpenMM) 0.0; + if (cutoff) { + // Loop over all pairs in the neighbor list. + + for (int i = 0; i < (int) neighborList->size(); i++) { + OpenMM::AtomPair pair = (*neighborList)[i]; + if (useExclusions && exclusions[pair.first].find(pair.second) != exclusions[pair.first].end()) + continue; + calculateOnePairValue(index, pair.first, pair.second, atomCoordinates, atomParameters, globalParameters, values); + calculateOnePairValue(index, pair.second, pair.first, atomCoordinates, atomParameters, globalParameters, values); + } + } + else { + // Perform an O(N^2) loop over all atom pairs. + + for (int i = 0; i < numAtoms; i++) { + for (int j = i+1; j < numAtoms; j++) { + if (useExclusions && exclusions[i].find(j) != exclusions[i].end()) + continue; + calculateOnePairValue(index, i, j, atomCoordinates, atomParameters, globalParameters, values); + calculateOnePairValue(index, j, i, atomCoordinates, atomParameters, globalParameters, values); + } + } + } +} + +void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, vector& atomCoordinates, RealOpenMM** atomParameters, + const map& globalParameters, vector >& values) { + RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; + if (periodic) + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); + else + ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); + RealOpenMM r = deltaR[ReferenceForce::RIndex]; + if (cutoff && r >= cutoffDistance) + return; + for (int i = 0; i < (int) paramNames.size(); i++) { + expressionSet.setVariable(particleParamIndex[i*2], atomParameters[atom1][i]); + expressionSet.setVariable(particleParamIndex[i*2+1], atomParameters[atom2][i]); + } + expressionSet.setVariable(rindex, r); + for (int i = 0; i < index; i++) { + expressionSet.setVariable(particleValueIndex[i*2], values[i][atom1]); + expressionSet.setVariable(particleValueIndex[i*2+1], values[i][atom2]); + } + values[index][atom1] += (RealOpenMM) valueExpressions[index].evaluate(); +} + +void CpuCustomGBForce::calculateSingleParticleEnergyTerm(int index, int numAtoms, vector& atomCoordinates, const vector >& values, + const map& globalParameters, RealOpenMM** atomParameters, vector& forces, RealOpenMM* totalEnergy, + vector >& dEdV) { + for (int i = 0; i < numAtoms; i++) { + expressionSet.setVariable(xindex, atomCoordinates[i][0]); + expressionSet.setVariable(yindex, atomCoordinates[i][1]); + expressionSet.setVariable(zindex, atomCoordinates[i][2]); + for (int j = 0; j < (int) paramNames.size(); j++) + expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); + for (int j = 0; j < (int) valueNames.size(); j++) + expressionSet.setVariable(valueIndex[j], values[j][i]); + if (totalEnergy != NULL) + *totalEnergy += (RealOpenMM) energyExpressions[index].evaluate(); + for (int j = 0; j < (int) valueNames.size(); j++) + dEdV[j][i] += (RealOpenMM) energyDerivExpressions[index][j].evaluate(); + forces[i][0] -= (RealOpenMM) energyGradientExpressions[index][0].evaluate(); + forces[i][1] -= (RealOpenMM) energyGradientExpressions[index][1].evaluate(); + forces[i][2] -= (RealOpenMM) energyGradientExpressions[index][2].evaluate(); + } +} + +void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, + const vector >& values, const map& globalParameters, const vector >& exclusions, bool useExclusions, + vector& forces, RealOpenMM* totalEnergy, vector >& dEdV) { + if (cutoff) { + // Loop over all pairs in the neighbor list. + + for (int i = 0; i < (int) neighborList->size(); i++) { + OpenMM::AtomPair pair = (*neighborList)[i]; + if (useExclusions && exclusions[pair.first].find(pair.second) != exclusions[pair.first].end()) + continue; + calculateOnePairEnergyTerm(index, pair.first, pair.second, atomCoordinates, atomParameters, globalParameters, values, forces, totalEnergy, dEdV); + } + } + else { + // Perform an O(N^2) loop over all atom pairs. + + for (int i = 0; i < numAtoms; i++) { + for (int j = i+1; j < numAtoms; j++) { + if (useExclusions && exclusions[i].find(j) != exclusions[i].end()) + continue; + calculateOnePairEnergyTerm(index, i, j, atomCoordinates, atomParameters, globalParameters, values, forces, totalEnergy, dEdV); + } + } + } +} + +void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom2, vector& atomCoordinates, RealOpenMM** atomParameters, + const map& globalParameters, const vector >& values, vector& forces, RealOpenMM* totalEnergy, + vector >& dEdV) { + // Compute the displacement. + + RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; + if (periodic) + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); + else + ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); + RealOpenMM r = deltaR[ReferenceForce::RIndex]; + if (cutoff && r >= cutoffDistance) + return; + + // Record variables for evaluating expressions. + + for (int i = 0; i < (int) paramNames.size(); i++) { + expressionSet.setVariable(particleParamIndex[i*2], atomParameters[atom1][i]); + expressionSet.setVariable(particleParamIndex[i*2+1], atomParameters[atom2][i]); + } + expressionSet.setVariable(rindex, r); + for (int i = 0; i < (int) valueNames.size(); i++) { + expressionSet.setVariable(particleValueIndex[i*2], values[i][atom1]); + expressionSet.setVariable(particleValueIndex[i*2+1], values[i][atom2]); + } + + // Evaluate the energy and its derivatives. + + if (totalEnergy != NULL) + *totalEnergy += (RealOpenMM) energyExpressions[index].evaluate(); + RealOpenMM dEdR = (RealOpenMM) energyDerivExpressions[index][0].evaluate(); + dEdR *= 1/r; + for (int i = 0; i < 3; i++) { + forces[atom1][i] -= dEdR*deltaR[i]; + forces[atom2][i] += dEdR*deltaR[i]; + } + for (int i = 0; i < (int) valueNames.size(); i++) { + dEdV[i][atom1] += (RealOpenMM) energyDerivExpressions[index][2*i+1].evaluate(); + dEdV[i][atom2] += (RealOpenMM) energyDerivExpressions[index][2*i+2].evaluate(); + } +} + +void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, + const vector >& values, const map& globalParameters, + const vector >& exclusions, vector& forces, vector >& dEdV) { + if (cutoff) { + // Loop over all pairs in the neighbor list. + + for (int i = 0; i < (int) neighborList->size(); i++) { + OpenMM::AtomPair pair = (*neighborList)[i]; + bool isExcluded = (exclusions[pair.first].find(pair.second) != exclusions[pair.first].end()); + calculateOnePairChainRule(pair.first, pair.second, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); + calculateOnePairChainRule(pair.second, pair.first, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); + } + } + else { + // Perform an O(N^2) loop over all atom pairs. + + for (int i = 0; i < numAtoms; i++) { + for (int j = i+1; j < numAtoms; j++) { + bool isExcluded = (exclusions[i].find(j) != exclusions[i].end()); + calculateOnePairChainRule(i, j, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); + calculateOnePairChainRule(j, i, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); + } + } + } + + // Compute chain rule terms for computed values that depend explicitly on particle coordinates. + + for (int i = 0; i < numAtoms; i++) { + expressionSet.setVariable(xindex, atomCoordinates[i][0]); + expressionSet.setVariable(yindex, atomCoordinates[i][1]); + expressionSet.setVariable(zindex, atomCoordinates[i][2]); + vector dVdX(valueDerivExpressions.size(), 0.0); + vector dVdY(valueDerivExpressions.size(), 0.0); + vector dVdZ(valueDerivExpressions.size(), 0.0); + for (int j = 0; j < (int) paramNames.size(); j++) + expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); + for (int j = 1; j < (int) valueNames.size(); j++) { + expressionSet.setVariable(valueIndex[j-1], values[j-1][i]); + for (int k = 1; k < j; k++) { + RealOpenMM dVdV = (RealOpenMM) valueDerivExpressions[j][k].evaluate(); + dVdX[j] += dVdV*dVdX[k]; + dVdY[j] += dVdV*dVdY[k]; + dVdZ[j] += dVdV*dVdZ[k]; + } + dVdX[j] += (RealOpenMM) valueGradientExpressions[j][0].evaluate(); + dVdY[j] += (RealOpenMM) valueGradientExpressions[j][1].evaluate(); + dVdZ[j] += (RealOpenMM) valueGradientExpressions[j][2].evaluate(); + forces[i][0] -= dEdV[j][i]*dVdX[j]; + forces[i][1] -= dEdV[j][i]*dVdY[j]; + forces[i][2] -= dEdV[j][i]*dVdZ[j]; + } + } +} + +void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, vector& atomCoordinates, RealOpenMM** atomParameters, + const map& globalParameters, const vector >& values, vector& forces, + vector >& dEdV, bool isExcluded) { + // Compute the displacement. + + RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; + if (periodic) + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); + else + ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); + RealOpenMM r = deltaR[ReferenceForce::RIndex]; + if (cutoff && r >= cutoffDistance) + return; + + // Record variables for evaluating expressions. + + for (int i = 0; i < (int) paramNames.size(); i++) { + expressionSet.setVariable(particleParamIndex[i*2], atomParameters[atom1][i]); + expressionSet.setVariable(particleParamIndex[i*2+1], atomParameters[atom2][i]); + } + expressionSet.setVariable(rindex, r); + expressionSet.setVariable(particleValueIndex[0], values[0][atom1]); + expressionSet.setVariable(particleValueIndex[1], values[0][atom2]); + + // Evaluate the derivative of each parameter with respect to position and apply forces. + + RealOpenMM rinv = 1/r; + deltaR[0] *= rinv; + deltaR[1] *= rinv; + deltaR[2] *= rinv; + vector dVdR1(valueDerivExpressions.size(), 0.0); + vector dVdR2(valueDerivExpressions.size(), 0.0); + if (!isExcluded || valueTypes[0] != OpenMM::CustomGBForce::ParticlePair) { + dVdR1[0] = (RealOpenMM) valueDerivExpressions[0][0].evaluate(); + dVdR2[0] = -dVdR1[0]; + for (int i = 0; i < 3; i++) { + forces[atom1][i] -= dEdV[0][atom1]*dVdR1[0]*deltaR[i]; + forces[atom2][i] -= dEdV[0][atom1]*dVdR2[0]*deltaR[i]; + } + } + for (int i = 0; i < (int) paramNames.size(); i++) + expressionSet.setVariable(paramIndex[i], atomParameters[atom1][i]); + expressionSet.setVariable(valueIndex[0], values[0][atom1]); + for (int i = 1; i < (int) valueNames.size(); i++) { + expressionSet.setVariable(valueIndex[i], values[i][atom1]); + expressionSet.setVariable(xindex, atomCoordinates[atom1][0]); + expressionSet.setVariable(yindex, atomCoordinates[atom1][1]); + expressionSet.setVariable(zindex, atomCoordinates[atom1][2]); + for (int j = 0; j < i; j++) { + RealOpenMM dVdV = (RealOpenMM) valueDerivExpressions[i][j].evaluate(); + dVdR1[i] += dVdV*dVdR1[j]; + dVdR2[i] += dVdV*dVdR2[j]; + } + for (int k = 0; k < 3; k++) { + forces[atom1][k] -= dEdV[i][atom1]*dVdR1[i]*deltaR[k]; + forces[atom2][k] -= dEdV[i][atom1]*dVdR2[i]*deltaR[k]; + } + } +} diff --git a/platforms/cpu/src/CpuKernelFactory.cpp b/platforms/cpu/src/CpuKernelFactory.cpp index 6e41798db..3eccd82e3 100644 --- a/platforms/cpu/src/CpuKernelFactory.cpp +++ b/platforms/cpu/src/CpuKernelFactory.cpp @@ -53,6 +53,8 @@ KernelImpl* CpuKernelFactory::createKernelImpl(std::string name, const Platform& return new CpuCalcCustomManyParticleForceKernel(name, platform, data); if (name == CalcGBSAOBCForceKernel::Name()) return new CpuCalcGBSAOBCForceKernel(name, platform, data); + if (name == CalcCustomGBForceKernel::Name()) + return new CpuCalcCustomGBForceKernel(name, platform, data); if (name == IntegrateLangevinStepKernel::Name()) return new CpuIntegrateLangevinStepKernel(name, platform, data); throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '") + name + "'").c_str()); diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 921f59f8a..af294468b 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -835,6 +835,162 @@ void CpuCalcGBSAOBCForceKernel::copyParametersToContext(ContextImpl& context, co obc.setParticleParameters(particleParams); } +CpuCalcCustomGBForceKernel::~CpuCalcCustomGBForceKernel() { + if (particleParamArray != NULL) { + for (int i = 0; i < numParticles; i++) + delete[] particleParamArray[i]; + delete[] particleParamArray; + } + if (neighborList != NULL) + delete neighborList; +} + +void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGBForce& force) { + if (force.getNumComputedValues() > 0) { + string name, expression; + CustomGBForce::ComputationType type; + force.getComputedValueParameters(0, name, expression, type); + if (type == CustomGBForce::SingleParticle) + throw OpenMMException("CpuPlatform requires that the first computed value for a CustomGBForce be of type ParticlePair or ParticlePairNoExclusions."); + for (int i = 1; i < force.getNumComputedValues(); i++) { + force.getComputedValueParameters(i, name, expression, type); + if (type != CustomGBForce::SingleParticle) + throw OpenMMException("CpuPlatform requires that a CustomGBForce only have one computed value of type ParticlePair or ParticlePairNoExclusions."); + } + } + + // Record the exclusions. + + numParticles = force.getNumParticles(); + exclusions.resize(numParticles); + for (int i = 0; i < force.getNumExclusions(); i++) { + int particle1, particle2; + force.getExclusionParticles(i, particle1, particle2); + exclusions[particle1].insert(particle2); + exclusions[particle2].insert(particle1); + } + + // Build the arrays. + + int numPerParticleParameters = force.getNumPerParticleParameters(); + particleParamArray = new double*[numParticles]; + for (int i = 0; i < numParticles; i++) + particleParamArray[i] = new double[numPerParticleParameters]; + for (int i = 0; i < numParticles; ++i) { + vector parameters; + force.getParticleParameters(i, parameters); + for (int j = 0; j < numPerParticleParameters; j++) + particleParamArray[i][j] = static_cast(parameters[j]); + } + for (int i = 0; i < numPerParticleParameters; i++) + particleParameterNames.push_back(force.getPerParticleParameterName(i)); + for (int i = 0; i < force.getNumGlobalParameters(); i++) + globalParameterNames.push_back(force.getGlobalParameterName(i)); + nonbondedMethod = CalcCustomGBForceKernel::NonbondedMethod(force.getNonbondedMethod()); + nonbondedCutoff = (RealOpenMM) force.getCutoffDistance(); + if (nonbondedMethod == NoCutoff) + neighborList = NULL; + else + neighborList = new NeighborList(); + + // Create custom functions for the tabulated functions. + + map functions; + for (int i = 0; i < force.getNumFunctions(); i++) + functions[force.getTabulatedFunctionName(i)] = createReferenceTabulatedFunction(force.getTabulatedFunction(i)); + + // Parse the expressions for computed values. + + valueDerivExpressions.resize(force.getNumComputedValues()); + valueGradientExpressions.resize(force.getNumComputedValues()); + for (int i = 0; i < force.getNumComputedValues(); i++) { + string name, expression; + CustomGBForce::ComputationType type; + force.getComputedValueParameters(i, name, expression, type); + Lepton::ParsedExpression ex = Lepton::Parser::parse(expression, functions).optimize(); + valueExpressions.push_back(ex.createCompiledExpression()); + valueTypes.push_back(type); + valueNames.push_back(name); + if (i == 0) + valueDerivExpressions[i].push_back(ex.differentiate("r").createCompiledExpression()); + else { + valueGradientExpressions[i].push_back(ex.differentiate("x").createCompiledExpression()); + valueGradientExpressions[i].push_back(ex.differentiate("y").createCompiledExpression()); + valueGradientExpressions[i].push_back(ex.differentiate("z").createCompiledExpression()); + for (int j = 0; j < i; j++) + valueDerivExpressions[i].push_back(ex.differentiate(valueNames[j]).createCompiledExpression()); + } + } + + // Parse the expressions for energy terms. + + energyDerivExpressions.resize(force.getNumEnergyTerms()); + energyGradientExpressions.resize(force.getNumEnergyTerms()); + for (int i = 0; i < force.getNumEnergyTerms(); i++) { + string expression; + CustomGBForce::ComputationType type; + force.getEnergyTermParameters(i, expression, type); + Lepton::ParsedExpression ex = Lepton::Parser::parse(expression, functions).optimize(); + energyExpressions.push_back(ex.createCompiledExpression()); + energyTypes.push_back(type); + if (type != CustomGBForce::SingleParticle) + energyDerivExpressions[i].push_back(ex.differentiate("r").createCompiledExpression()); + for (int j = 0; j < force.getNumComputedValues(); j++) { + if (type == CustomGBForce::SingleParticle) { + energyDerivExpressions[i].push_back(ex.differentiate(valueNames[j]).createCompiledExpression()); + energyGradientExpressions[i].push_back(ex.differentiate("x").createCompiledExpression()); + energyGradientExpressions[i].push_back(ex.differentiate("y").createCompiledExpression()); + energyGradientExpressions[i].push_back(ex.differentiate("z").createCompiledExpression()); + } + else { + energyDerivExpressions[i].push_back(ex.differentiate(valueNames[j]+"1").createCompiledExpression()); + energyDerivExpressions[i].push_back(ex.differentiate(valueNames[j]+"2").createCompiledExpression()); + } + } + } + + // Delete the custom functions. + + for (map::iterator iter = functions.begin(); iter != functions.end(); iter++) + delete iter->second; +} + +double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { + vector& posData = extractPositions(context); + vector& forceData = extractForces(context); + RealOpenMM energy = 0; + CpuCustomGBForce ixn(valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions, + energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames); + bool periodic = (nonbondedMethod == CutoffPeriodic); + if (periodic) + ixn.setPeriodic(extractBoxSize(context)); + if (nonbondedMethod != NoCutoff) { + computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxSize(context), periodic, nonbondedCutoff, 0.0); + ixn.setUseCutoff(nonbondedCutoff, *neighborList); + } + map globalParameters; + for (int i = 0; i < (int) globalParameterNames.size(); i++) + globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]); + ixn.calculateIxn(numParticles, posData, particleParamArray, exclusions, globalParameters, forceData, includeEnergy ? &energy : NULL); + return energy; +} + +void CpuCalcCustomGBForceKernel::copyParametersToContext(ContextImpl& context, const CustomGBForce& force) { + if (numParticles != force.getNumParticles()) + throw OpenMMException("updateParametersInContext: The number of particles has changed"); + + // Record the values. + + int numParameters = force.getNumPerParticleParameters(); + vector params; + for (int i = 0; i < numParticles; ++i) { + vector parameters; + force.getParticleParameters(i, parameters); + for (int j = 0; j < numParameters; j++) + particleParamArray[i][j] = static_cast(parameters[j]); + } +} + CpuCalcCustomManyParticleForceKernel::~CpuCalcCustomManyParticleForceKernel() { if (particleParamArray != NULL) { for (int i = 0; i < numParticles; i++) diff --git a/platforms/cpu/src/CpuPlatform.cpp b/platforms/cpu/src/CpuPlatform.cpp index 22fcc3bc5..ccd164141 100644 --- a/platforms/cpu/src/CpuPlatform.cpp +++ b/platforms/cpu/src/CpuPlatform.cpp @@ -67,6 +67,7 @@ CpuPlatform::CpuPlatform() { registerKernelFactory(CalcCustomNonbondedForceKernel::Name(), factory); registerKernelFactory(CalcCustomManyParticleForceKernel::Name(), factory); registerKernelFactory(CalcGBSAOBCForceKernel::Name(), factory); + registerKernelFactory(CalcCustomGBForceKernel::Name(), factory); registerKernelFactory(IntegrateLangevinStepKernel::Name(), factory); platformProperties.push_back(CpuThreads()); int threads = getNumProcessors(); diff --git a/platforms/cpu/tests/TestCpuCustomGBForce.cpp b/platforms/cpu/tests/TestCpuCustomGBForce.cpp new file mode 100644 index 000000000..a9da9a016 --- /dev/null +++ b/platforms/cpu/tests/TestCpuCustomGBForce.cpp @@ -0,0 +1,479 @@ + +/* -------------------------------------------------------------------------- * + * 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-2014 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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. * + * -------------------------------------------------------------------------- */ + +/** + * This tests all the different force terms in the reference implementation of CustomGBForce. + */ + +#include "openmm/internal/AssertionUtilities.h" +#include "sfmt/SFMT.h" +#include "openmm/Context.h" +#include "CpuPlatform.h" +#include "openmm/CustomGBForce.h" +#include "openmm/GBSAOBCForce.h" +#include "openmm/GBVIForce.h" +#include "openmm/OpenMMException.h" +#include "openmm/System.h" +#include "openmm/VerletIntegrator.h" +#include +#include +#include + +using namespace OpenMM; +using namespace std; + +const double TOL = 1e-5; + +void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMethod customMethod) { + const int numMolecules = 70; + const int numParticles = numMolecules*2; + const double boxSize = 10.0; + const double cutoff = 2.0; + CpuPlatform platform; + + // Create two systems: one with a GBSAOBCForce, and one using a CustomGBForce to implement the same interaction. + + System standardSystem; + System customSystem; + for (int i = 0; i < numParticles; i++) { + standardSystem.addParticle(1.0); + customSystem.addParticle(1.0); + } + standardSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize)); + customSystem.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize)); + GBSAOBCForce* obc = new GBSAOBCForce(); + CustomGBForce* custom = new CustomGBForce(); + obc->setCutoffDistance(cutoff); + custom->setCutoffDistance(cutoff); + custom->addPerParticleParameter("q"); + custom->addPerParticleParameter("radius"); + custom->addPerParticleParameter("scale"); + custom->addGlobalParameter("solventDielectric", obc->getSolventDielectric()); + custom->addGlobalParameter("soluteDielectric", obc->getSoluteDielectric()); + custom->addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(1/U^2-1/L^2)*(r-sr2*sr2/r)+0.5*log(L/U)/r+C);" + "U=r+sr2;" + "C=2*(1/or1-1/L)*step(sr2-r-or1);" + "L=max(or1, D);" + "D=abs(r-sr2);" + "sr2 = scale2*or2;" + "or1 = radius1-0.009; or2 = radius2-0.009", CustomGBForce::ParticlePairNoExclusions); + custom->addComputedValue("B", "1/(1/or-tanh(1*psi-0.8*psi^2+4.85*psi^3)/radius);" + "psi=I*or; or=radius-0.009", CustomGBForce::SingleParticle); + custom->addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B", CustomGBForce::SingleParticle); + string invCutoffString = ""; + if (obcMethod != GBSAOBCForce::NoCutoff) { + stringstream s; + s<<(1.0/cutoff); + invCutoffString = s.str(); + } + custom->addEnergyTerm("138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2*("+invCutoffString+"-1/f);" + "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce::ParticlePairNoExclusions); + vector positions(numParticles); + vector velocities(numParticles); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + + vector params(3); + for (int i = 0; i < numMolecules; i++) { + if (i < numMolecules/2) { + obc->addParticle(1.0, 0.2, 0.5); + params[0] = 1.0; + params[1] = 0.2; + params[2] = 0.5; + custom->addParticle(params); + obc->addParticle(-1.0, 0.1, 0.5); + params[0] = -1.0; + params[1] = 0.1; + custom->addParticle(params); + } + else { + obc->addParticle(1.0, 0.2, 0.8); + params[0] = 1.0; + params[1] = 0.2; + params[2] = 0.8; + custom->addParticle(params); + obc->addParticle(-1.0, 0.1, 0.8); + params[0] = -1.0; + params[1] = 0.1; + custom->addParticle(params); + } + positions[2*i] = Vec3(boxSize*genrand_real2(sfmt), boxSize*genrand_real2(sfmt), boxSize*genrand_real2(sfmt)); + positions[2*i+1] = Vec3(positions[2*i][0]+1.0, positions[2*i][1], positions[2*i][2]); + velocities[2*i] = Vec3(genrand_real2(sfmt), genrand_real2(sfmt), genrand_real2(sfmt)); + velocities[2*i+1] = Vec3(genrand_real2(sfmt), genrand_real2(sfmt), genrand_real2(sfmt)); + } + obc->setNonbondedMethod(obcMethod); + custom->setNonbondedMethod(customMethod); + standardSystem.addForce(obc); + customSystem.addForce(custom); + VerletIntegrator integrator1(0.01); + VerletIntegrator integrator2(0.01); + Context context1(standardSystem, integrator1, platform); + context1.setPositions(positions); + context1.setVelocities(velocities); + State state1 = context1.getState(State::Forces | State::Energy); + Context context2(customSystem, integrator2, platform); + context2.setPositions(positions); + context2.setVelocities(velocities); + State state2 = context2.getState(State::Forces | State::Energy); + ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), 1e-4); + for (int i = 0; i < numParticles; i++) { + ASSERT_EQUAL_VEC(state1.getForces()[i], state2.getForces()[i], 1e-4); + } + + // Try changing the particle parameters and make sure it's still correct. + + for (int i = 0; i < numMolecules/2; i++) { + obc->setParticleParameters(2*i, 1.1, 0.3, 0.6); + params[0] = 1.1; + params[1] = 0.3; + params[2] = 0.6; + custom->setParticleParameters(2*i, params); + obc->setParticleParameters(2*i+1, -1.1, 0.2, 0.4); + params[0] = -1.1; + params[1] = 0.2; + params[2] = 0.4; + custom->setParticleParameters(2*i+1, params); + } + obc->updateParametersInContext(context1); + custom->updateParametersInContext(context2); + state1 = context1.getState(State::Forces | State::Energy); + state2 = context2.getState(State::Forces | State::Energy); + ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), 1e-4); + for (int i = 0; i < numParticles; i++) { + ASSERT_EQUAL_VEC(state1.getForces()[i], state2.getForces()[i], 1e-4); + } +} + +void testMembrane() { + const int numMolecules = 70; + const int numParticles = numMolecules*2; + const double boxSize = 10.0; + CpuPlatform platform; + + // Create a system with an implicit membrane. + + System system; + for (int i = 0; i < numParticles; i++) { + system.addParticle(1.0); + } + system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0.0, 0.0), Vec3(0.0, boxSize, 0.0), Vec3(0.0, 0.0, boxSize)); + CustomGBForce* custom = new CustomGBForce(); + custom->setCutoffDistance(2.0); + custom->addPerParticleParameter("q"); + custom->addPerParticleParameter("radius"); + custom->addPerParticleParameter("scale"); + custom->addGlobalParameter("thickness", 3); + custom->addGlobalParameter("solventDielectric", 78.3); + custom->addGlobalParameter("soluteDielectric", 1); + custom->addComputedValue("Imol", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(1/U^2-1/L^2)*(r-sr2*sr2/r)+0.5*log(L/U)/r+C);" + "U=r+sr2;" + "C=2*(1/or1-1/L)*step(sr2-r-or1);" + "L=max(or1, D);" + "D=abs(r-sr2);" + "sr2 = scale2*or2;" + "or1 = radius1-0.009; or2 = radius2-0.009", CustomGBForce::ParticlePairNoExclusions); + custom->addComputedValue("Imem", "(1/radius+2*log(2)/thickness)/(1+exp(7.2*(abs(z)+radius-0.5*thickness)))", CustomGBForce::SingleParticle); + custom->addComputedValue("B", "1/(1/or-tanh(1*psi-0.8*psi^2+4.85*psi^3)/radius);" + "psi=max(Imol,Imem)*or; or=radius-0.009", CustomGBForce::SingleParticle); + custom->addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6-0.5*138.935456*(1/soluteDielectric-1/solventDielectric)*q^2/B", CustomGBForce::SingleParticle); + custom->addEnergyTerm("-138.935456*(1/soluteDielectric-1/solventDielectric)*q1*q2/f;" + "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce::ParticlePairNoExclusions); + vector positions(numParticles); + vector velocities(numParticles); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + vector params(3); + for (int i = 0; i < numMolecules; i++) { + if (i < numMolecules/2) { + params[0] = 1.0; + params[1] = 0.2; + params[2] = 0.5; + custom->addParticle(params); + params[0] = -1.0; + params[1] = 0.1; + custom->addParticle(params); + } + else { + params[0] = 1.0; + params[1] = 0.2; + params[2] = 0.8; + custom->addParticle(params); + params[0] = -1.0; + params[1] = 0.1; + custom->addParticle(params); + } + positions[2*i] = Vec3(boxSize*genrand_real2(sfmt), boxSize*genrand_real2(sfmt), boxSize*genrand_real2(sfmt)); + positions[2*i+1] = Vec3(positions[2*i][0]+1.0, positions[2*i][1], positions[2*i][2]); + velocities[2*i] = Vec3(genrand_real2(sfmt), genrand_real2(sfmt), genrand_real2(sfmt)); + velocities[2*i+1] = Vec3(genrand_real2(sfmt), genrand_real2(sfmt), genrand_real2(sfmt)); + } + system.addForce(custom); + VerletIntegrator integrator(0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + context.setVelocities(velocities); + State state = context.getState(State::Forces | State::Energy); + const vector& forces = state.getForces(); + + // Take a small step in the direction of the energy gradient and see whether the potential energy changes by the expected amount. + + double norm = 0.0; + for (int i = 0; i < (int) forces.size(); ++i) + norm += forces[i].dot(forces[i]); + norm = std::sqrt(norm); + const double stepSize = 1e-2; + double step = 0.5*stepSize/norm; + vector positions2(numParticles), positions3(numParticles); + for (int i = 0; i < (int) positions.size(); ++i) { + Vec3 p = positions[i]; + Vec3 f = forces[i]; + positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); + positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step); + } + context.setPositions(positions2); + State state2 = context.getState(State::Energy); + context.setPositions(positions3); + State state3 = context.getState(State::Energy); + ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3); +} + +void testTabulatedFunction() { + CpuPlatform platform; + System system; + system.addParticle(1.0); + system.addParticle(1.0); + VerletIntegrator integrator(0.01); + CustomGBForce* force = new CustomGBForce(); + force->addComputedValue("a", "0", CustomGBForce::ParticlePair); + force->addEnergyTerm("fn(r)+1", CustomGBForce::ParticlePair); + force->addParticle(vector()); + force->addParticle(vector()); + vector table; + for (int i = 0; i < 21; i++) + table.push_back(std::sin(0.25*i)); + force->addTabulatedFunction("fn", new Continuous1DFunction(table, 1.0, 6.0)); + system.addForce(force); + Context context(system, integrator, platform); + vector positions(2); + positions[0] = Vec3(0, 0, 0); + for (int i = 1; i < 30; i++) { + double x = (7.0/30.0)*i; + positions[1] = Vec3(x, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + const vector& forces = state.getForces(); + double force = (x < 1.0 || x > 6.0 ? 0.0 : -std::cos(x-1.0)); + double energy = (x < 1.0 || x > 6.0 ? 0.0 : std::sin(x-1.0))+1.0; + ASSERT_EQUAL_VEC(Vec3(-force, 0, 0), forces[0], 0.1); + ASSERT_EQUAL_VEC(Vec3(force, 0, 0), forces[1], 0.1); + ASSERT_EQUAL_TOL(energy, state.getPotentialEnergy(), 0.02); + } +} + +void testMultipleChainRules() { + CpuPlatform platform; + System system; + system.addParticle(1.0); + system.addParticle(1.0); + VerletIntegrator integrator(0.01); + CustomGBForce* force = new CustomGBForce(); + force->addComputedValue("a", "2*r", CustomGBForce::ParticlePair); + force->addComputedValue("b", "a+1", CustomGBForce::SingleParticle); + force->addComputedValue("c", "2*b+a", CustomGBForce::SingleParticle); + force->addEnergyTerm("0.1*a+1*b+10*c", CustomGBForce::SingleParticle); // 0.1*(2*r) + 2*r+1 + 10*(3*a+2) = 0.2*r + 2*r+1 + 40*r+20+20*r = 62.2*r+21 + force->addParticle(vector()); + force->addParticle(vector()); + system.addForce(force); + Context context(system, integrator, platform); + vector positions(2); + positions[0] = Vec3(0, 0, 0); + for (int i = 1; i < 5; i++) { + positions[1] = Vec3(i, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + const vector& forces = state.getForces(); + ASSERT_EQUAL_VEC(Vec3(124.4, 0, 0), forces[0], 1e-4); + ASSERT_EQUAL_VEC(Vec3(-124.4, 0, 0), forces[1], 1e-4); + ASSERT_EQUAL_TOL(2*(62.2*i+21), state.getPotentialEnergy(), 0.02); + } +} + +void testPositionDependence() { + CpuPlatform platform; + System system; + system.addParticle(1.0); + system.addParticle(1.0); + VerletIntegrator integrator(0.01); + CustomGBForce* force = new CustomGBForce(); + force->addComputedValue("a", "r", CustomGBForce::ParticlePair); + force->addComputedValue("b", "a+x*y", CustomGBForce::SingleParticle); + force->addEnergyTerm("b*z", CustomGBForce::SingleParticle); + force->addEnergyTerm("b1+b2", CustomGBForce::ParticlePair); // = 2*r+x1*y1+x2*y2 + force->addParticle(vector()); + force->addParticle(vector()); + system.addForce(force); + Context context(system, integrator, platform); + vector positions(2); + vector forces(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + + for (int i = 0; i < 5; i++) { + positions[0] = Vec3(genrand_real2(sfmt), genrand_real2(sfmt), genrand_real2(sfmt)); + positions[1] = Vec3(genrand_real2(sfmt), genrand_real2(sfmt), genrand_real2(sfmt)); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + const vector& forces = state.getForces(); + Vec3 delta = positions[0]-positions[1]; + double r = sqrt(delta.dot(delta)); + double energy = 2*r+positions[0][0]*positions[0][1]+positions[1][0]*positions[1][1]; + for (int j = 0; j < 2; j++) + energy += positions[j][2]*(r+positions[j][0]*positions[j][1]); + Vec3 force1(-(1+positions[0][2])*delta[0]/r-(1+positions[0][2])*positions[0][1]-(1+positions[1][2])*delta[0]/r, + -(1+positions[0][2])*delta[1]/r-(1+positions[0][2])*positions[0][0]-(1+positions[1][2])*delta[1]/r, + -(1+positions[0][2])*delta[2]/r-(r+positions[0][0]*positions[0][1])-(1+positions[1][2])*delta[2]/r); + Vec3 force2((1+positions[0][2])*delta[0]/r+(1+positions[1][2])*delta[0]/r-(1+positions[1][2])*positions[1][1], + (1+positions[0][2])*delta[1]/r+(1+positions[1][2])*delta[1]/r-(1+positions[1][2])*positions[1][0], + (1+positions[0][2])*delta[2]/r+(1+positions[1][2])*delta[2]/r-(r+positions[1][0]*positions[1][1])); + ASSERT_EQUAL_VEC(force1, forces[0], 1e-4); + ASSERT_EQUAL_VEC(force2, forces[1], 1e-4); + ASSERT_EQUAL_TOL(energy, state.getPotentialEnergy(), 0.02); + + // Take a small step in the direction of the energy gradient and see whether the potential energy changes by the expected amount. + + double norm = 0.0; + for (int i = 0; i < (int) forces.size(); ++i) + norm += forces[i].dot(forces[i]); + norm = std::sqrt(norm); + const double stepSize = 1e-3; + double step = 0.5*stepSize/norm; + vector positions2(2), positions3(2); + for (int i = 0; i < (int) positions.size(); ++i) { + Vec3 p = positions[i]; + Vec3 f = forces[i]; + positions2[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); + positions3[i] = Vec3(p[0]+f[0]*step, p[1]+f[1]*step, p[2]+f[2]*step); + } + context.setPositions(positions2); + State state2 = context.getState(State::Energy); + context.setPositions(positions3); + State state3 = context.getState(State::Energy); + ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/stepSize, 1e-3); + } +} + +void testExclusions() { + CpuPlatform platform; + for (int i = 3; i < 4; i++) { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + VerletIntegrator integrator(0.01); + CustomGBForce* force = new CustomGBForce(); + force->addComputedValue("a", "r", i < 2 ? CustomGBForce::ParticlePair : CustomGBForce::ParticlePairNoExclusions); + force->addEnergyTerm("a", CustomGBForce::SingleParticle); + force->addEnergyTerm("(1+a1+a2)*r", i%2 == 0 ? CustomGBForce::ParticlePair : CustomGBForce::ParticlePairNoExclusions); + force->addParticle(vector()); + force->addParticle(vector()); + force->addExclusion(0, 1); + system.addForce(force); + Context context(system, integrator, platform); + vector positions(2); + positions[0] = Vec3(0, 0, 0); + positions[1] = Vec3(1, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + const vector& forces = state.getForces(); + double f, energy; + switch (i) + { + case 0: // e = 0 + f = 0; + energy = 0; + break; + case 1: // e = r + f = 1; + energy = 1; + break; + case 2: // e = 2r + f = 2; + energy = 2; + break; + case 3: // e = 3r + 2r^2 + f = 7; + energy = 5; + break; + default: + ASSERT(false); + } + ASSERT_EQUAL_VEC(Vec3(f, 0, 0), forces[0], 1e-4); + ASSERT_EQUAL_VEC(Vec3(-f, 0, 0), forces[1], 1e-4); + ASSERT_EQUAL_TOL(energy, state.getPotentialEnergy(), 1e-4); + + // Take a small step in the direction of the energy gradient and see whether the potential energy changes by the expected amount. + + double norm = 0.0; + for (int i = 0; i < (int) forces.size(); ++i) + norm += forces[i].dot(forces[i]); + norm = std::sqrt(norm); + const double stepSize = 1e-3; + double step = stepSize/norm; + for (int i = 0; i < (int) positions.size(); ++i) { + Vec3 p = positions[i]; + Vec3 f = forces[i]; + positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step); + } + context.setPositions(positions); + State state2 = context.getState(State::Energy); + ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/stepSize, 1e-3*abs(state.getPotentialEnergy())); + } +} + +int main() { + try { + testOBC(GBSAOBCForce::NoCutoff, CustomGBForce::NoCutoff); + testOBC(GBSAOBCForce::CutoffNonPeriodic, CustomGBForce::CutoffNonPeriodic); + testOBC(GBSAOBCForce::CutoffPeriodic, CustomGBForce::CutoffPeriodic); + testMembrane(); + testTabulatedFunction(); + testMultipleChainRules(); + testPositionDependence(); + testExclusions(); + } + catch(const exception& e) { + cout << "exception: " << e.what() << endl; + return 1; + } + cout << "Done" << endl; + return 0; +} -- GitLab From 5c029ede957bd949fa050499461da2d1c591504c Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 6 Oct 2014 17:56:58 -0400 Subject: [PATCH 038/338] Add functions to Quantity to compute the max, min, standard deviation (as the sqrt of the variance), and average, returning a Quantity with the proper units. This should be reasonably efficient, as it takes advantage of numpy-accelerated methods if they're present. --- wrappers/python/simtk/unit/quantity.py | 79 ++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index edc372f0a..4a9f7211f 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -455,6 +455,85 @@ class Quantity(object): new_value *= math.sqrt(unit_factor) return Quantity(value=new_value, unit=new_unit) + def sum(self): + """ + Computes the sum of a sequence, with the result having the same unit as + the current sequence. + + If the value is not iterable, it raises a TypeError (same behavior as if + you tried to iterate over, for instance, an integer). + """ + try: + # This will be much faster for numpy arrays + mysum = self._value.sum() + except AttributeError: + mysum = sum(self._value) + return Quantity(mysum, self.unit) + + def mean(self): + """ + Computes the mean of a sequence, with the result having the same unit as + the current sequence. + + If the value is not iterable, it raises a TypeError + """ + try: + # Faster for numpy arrays + mean = self._value.mean() + except AttributeError: + mean = self.sum() / len(self._value) + return Quantity(mean, self.unit) + + def std(self): + """ + Computes the square root of the variance of a sequence, with the result + having the same unit as the current sequence. + + If the value is not iterable, it raises a TypeError + """ + try: + # Faster for numpy arrays + std = self._value.std() + except AttributeError: + sum1 = sum2 = 0.0 + for val in self._value: + sum1 += val + sum2 += val * val + nvals = len(self._value) + sum1 /= nvals + sum1 *= sum1 + sum2 /= nvals + std = math.sqrt(abs(sum2 - sum1)) + return Quantity(std, self.unit) + + def max(self): + """ + Computes the maximum value of the sequence, with the result having the + same unit as the current sequence. + + If the value is not iterable, it raises a TypeError + """ + try: + # Faster for numpy arrays + mymax = self._value.max() + except AttributeError: + mymax = max(self._value) + return Quantity(mymax, self.unit) + + def min(self): + """ + Computes the minimum value of the sequence, with the result having the + same unit as the current sequence. + + If the value is not iterable, it raises a TypeError + """ + try: + # Faster for numpy arrays + mymin = self._value.min() + except AttributeError: + mymin = min(self._value) + return Quantity(mymin, self.unit) + def __abs__(self): """ Return absolute value of a Quantity. -- GitLab From 8faeeb4d05aa768a1c9e2eb93557fdeb1ede6222 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 6 Oct 2014 18:29:01 -0400 Subject: [PATCH 039/338] More stable std calc. --- wrappers/python/simtk/unit/quantity.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index 4a9f7211f..fd9a18c70 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -495,15 +495,12 @@ class Quantity(object): # Faster for numpy arrays std = self._value.std() except AttributeError: - sum1 = sum2 = 0.0 + mean = self.mean() for val in self._value: - sum1 += val - sum2 += val * val - nvals = len(self._value) - sum1 /= nvals - sum1 *= sum1 - sum2 /= nvals - std = math.sqrt(abs(sum2 - sum1)) + res = mean - val + var += res * res + var /= len(self._value) + std = math.sqrt(var) return Quantity(std, self.unit) def max(self): -- GitLab From 9c38d980cb92f21dddb6011f05bf550911203f1a Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 6 Oct 2014 18:36:27 -0400 Subject: [PATCH 040/338] Stop using "== None" and "!= None". "is" and "is not" is the preferred way to do it. Not only that, I got this FutureWarning: /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/simtk/unit/quantity.py:170: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future. if value == None: --- wrappers/python/simtk/unit/doctests.py | 4 ++-- wrappers/python/simtk/unit/mymatrix.py | 2 +- wrappers/python/simtk/unit/quantity.py | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wrappers/python/simtk/unit/doctests.py b/wrappers/python/simtk/unit/doctests.py index 65b7a5961..b334119a4 100644 --- a/wrappers/python/simtk/unit/doctests.py +++ b/wrappers/python/simtk/unit/doctests.py @@ -625,9 +625,9 @@ Examples >>> 1.2*meters < 72*centimeters False - >>> meter != None + >>> meter is not None True - >>> meter == None + >>> meter is None False Examples diff --git a/wrappers/python/simtk/unit/mymatrix.py b/wrappers/python/simtk/unit/mymatrix.py index d510d0bae..b6252fb29 100644 --- a/wrappers/python/simtk/unit/mymatrix.py +++ b/wrappers/python/simtk/unit/mymatrix.py @@ -60,7 +60,7 @@ def zeros(m, n=None): [0, 0, 0] [0, 0, 0]] """ - if n == None: + if n is None: n = m result = [] for row in range(0, m): diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index fd9a18c70..b4aa525d2 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -114,7 +114,7 @@ class Quantity(object): - unit: (Unit) the physical unit, e.g. simtk.unit.meters. """ # When no unit is specified, bend over backwards to handle all one-argument possibilities - if unit == None: # one argument version, copied from UList + if unit is None: # one argument version, copied from UList if is_unit(value): # Unit argument creates an empty list with that unit attached unit = value @@ -167,7 +167,7 @@ class Quantity(object): value = value * unit._value unit = unit.unit # Use empty list for unspecified values - if value == None: + if value is None: value = [] self._value = value @@ -306,7 +306,7 @@ class Quantity(object): value_factor = 1.0 canonical_units = {} # dict of dimensionTuple: (Base/ScaledUnit, exponent) # Bias result toward guide units - if guide_unit != None: + if guide_unit is not None: for u, exponent in guide_unit.iter_base_or_scaled_units(): d = u.get_dimension_tuple() if d not in canonical_units: -- GitLab From f6d9006666848a0ea68e914fe7216c4bf7133cc3 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 6 Oct 2014 19:49:12 -0400 Subject: [PATCH 041/338] Possible speedup for unit_math.sum function. --- wrappers/python/simtk/unit/unit_math.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wrappers/python/simtk/unit/unit_math.py b/wrappers/python/simtk/unit/unit_math.py index 0ad129e62..05ad1307c 100644 --- a/wrappers/python/simtk/unit/unit_math.py +++ b/wrappers/python/simtk/unit/unit_math.py @@ -156,6 +156,10 @@ def sum(val): >>> sum((2.0*meter, 30.0*centimeter)) Quantity(value=2.3, unit=meter) """ + try: + return val.sum() + except AttributeError: + pass if len(val) == 0: return 0 result = val[0] -- GitLab From 4d827cd9ded61f0378a15e96ddc29eb6cc6012fe Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 6 Oct 2014 16:53:26 -0700 Subject: [PATCH 042/338] More optimizations to CPU CustomGBForce --- platforms/cpu/include/CpuCustomGBForce.h | 70 ++++------ platforms/cpu/include/CpuKernels.h | 9 +- platforms/cpu/src/CpuCustomGBForce.cpp | 132 ++++++++++-------- platforms/cpu/src/CpuCustomNonbondedForce.cpp | 4 +- platforms/cpu/src/CpuKernels.cpp | 33 +++-- platforms/cpu/src/CpuNonbondedForceVec4.cpp | 12 +- platforms/cpu/src/CpuNonbondedForceVec8.cpp | 12 +- 7 files changed, 137 insertions(+), 135 deletions(-) diff --git a/platforms/cpu/include/CpuCustomGBForce.h b/platforms/cpu/include/CpuCustomGBForce.h index 4bedde933..177d4af67 100644 --- a/platforms/cpu/include/CpuCustomGBForce.h +++ b/platforms/cpu/include/CpuCustomGBForce.h @@ -25,36 +25,36 @@ #ifndef OPENMM_CPU_CUSTOM_GB_FORCE_H__ #define OPENMM_CPU_CUSTOM_GB_FORCE_H__ -#include "ReferenceNeighborList.h" #include "CompiledExpressionSet.h" +#include "CpuNeighborList.h" #include "lepton/CompiledExpression.h" #include "openmm/CustomGBForce.h" #include #include #include +namespace OpenMM { + class CpuCustomGBForce { private: bool cutoff; bool periodic; - const OpenMM::NeighborList* neighborList; + const CpuNeighborList* neighborList; RealOpenMM periodicBoxSize[3]; RealOpenMM cutoffDistance; - OpenMM::CompiledExpressionSet expressionSet; + CompiledExpressionSet expressionSet; std::vector valueExpressions; std::vector > valueDerivExpressions; std::vector > valueGradientExpressions; std::vector valueNames; std::vector valueIndex; - std::vector valueTypes; + std::vector valueTypes; std::vector energyExpressions; std::vector > energyDerivExpressions; std::vector > energyGradientExpressions; std::vector paramNames; std::vector paramIndex; - std::vector energyTypes; - std::vector particleParamNames; - std::vector particleValueNames; + std::vector energyTypes; std::vector particleParamIndex; std::vector particleValueIndex; int xindex, yindex, zindex, rindex; @@ -66,12 +66,11 @@ private: * @param numAtoms number of atoms * @param atomCoordinates atom coordinates * @param values the vector to store computed values into - * @param globalParameters the values of global parameters * @param atomParameters atomParameters[atomIndex][paramterIndex] */ - void calculateSingleParticleValue(int index, int numAtoms, std::vector& atomCoordinates, std::vector >& values, - const std::map& globalParameters, RealOpenMM** atomParameters); + void calculateSingleParticleValue(int index, int numAtoms, std::vector& atomCoordinates, std::vector >& values, + RealOpenMM** atomParameters); /** * Calculate a computed value that is based on particle pairs @@ -81,14 +80,12 @@ private: * @param atomCoordinates atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector to store computed values into - * @param globalParameters the values of global parameters * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param useExclusions specifies whether to use exclusions */ - void calculateParticlePairValue(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, + void calculateParticlePairValue(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, std::vector >& values, - const std::map& globalParameters, const std::vector >& exclusions, bool useExclusions); /** @@ -99,12 +96,10 @@ private: * @param atom2 the index of the second atom in the pair * @param atomCoordinates atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param globalParameters the values of global parameters * @param values the vector to store computed values into */ - void calculateOnePairValue(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, - const std::map& globalParameters, + void calculateOnePairValue(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, std::vector >& values); /** @@ -114,15 +109,14 @@ private: * @param numAtoms number of atoms * @param atomCoordinates atom coordinates * @param values the vector containing computed values - * @param globalParameters the values of global parameters * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param forces forces on atoms are added to this * @param totalEnergy the energy contribution is added to this * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateSingleParticleEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, const std::vector >& values, - const std::map& globalParameters, RealOpenMM** atomParameters, std::vector& forces, + void calculateSingleParticleEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, const std::vector >& values, + RealOpenMM** atomParameters, std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); /** @@ -133,7 +127,6 @@ private: * @param atomCoordinates atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector containing computed values - * @param globalParameters the values of global parameters * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param useExclusions specifies whether to use exclusions * @param forces forces on atoms are added to this @@ -141,11 +134,10 @@ private: * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateParticlePairEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, + void calculateParticlePairEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& values, - const std::map& globalParameters, const std::vector >& exclusions, bool useExclusions, - std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); + std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); /** * Evaluate a single atom pair as part of calculating an energy term @@ -155,17 +147,15 @@ private: * @param atom2 the index of the second atom in the pair * @param atomCoordinates atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param globalParameters the values of global parameters * @param values the vector containing computed values * @param forces forces on atoms are added to this * @param totalEnergy the energy contribution is added to this * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateOnePairEnergyTerm(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, - const std::map& globalParameters, + void calculateOnePairEnergyTerm(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& values, - std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); + std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); /** * Apply the chain rule to compute forces on atoms @@ -174,17 +164,15 @@ private: * @param atomCoordinates atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector containing computed values - * @param globalParameters the values of global parameters * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param forces forces on atoms are added to this * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateChainRuleForces(int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, + void calculateChainRuleForces(int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& values, - const std::map& globalParameters, const std::vector >& exclusions, - std::vector& forces, std::vector >& dEdV); + std::vector& forces, std::vector >& dEdV); /** * Evaluate a single atom pair as part of applying the chain rule @@ -193,17 +181,15 @@ private: * @param atom2 the index of the second atom in the pair * @param atomCoordinates atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param globalParameters the values of global parameters * @param values the vector containing computed values * @param forces forces on atoms are added to this * @param dEdV the derivative of energy with respect to computed values is stored in this * @param isExcluded specifies whether this is an excluded pair */ - void calculateOnePairChainRule(int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, - const std::map& globalParameters, + void calculateOnePairChainRule(int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& values, - std::vector& forces, std::vector >& dEdV, + std::vector& forces, std::vector >& dEdV, bool isExcluded); public: @@ -216,11 +202,11 @@ public: const std::vector > valueDerivExpressions, const std::vector > valueGradientExpressions, const std::vector& valueNames, - const std::vector& valueTypes, + const std::vector& valueTypes, const std::vector& energyExpressions, const std::vector > energyDerivExpressions, const std::vector > energyGradientExpressions, - const std::vector& energyTypes, + const std::vector& energyTypes, const std::vector& parameterNames); ~CpuCustomGBForce(); @@ -232,7 +218,7 @@ public: * @param neighbors the neighbor list to use */ - void setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors); + void setUseCutoff(RealOpenMM distance, const CpuNeighborList& neighbors); /** * Set the force to use periodic boundary conditions. This requires that a cutoff has @@ -242,7 +228,7 @@ public: * @param boxSize the X, Y, and Z widths of the periodic box */ - void setPeriodic(OpenMM::RealVec& boxSize); + void setPeriodic(RealVec& boxSize); /** * Calculate custom GB ixn @@ -256,8 +242,10 @@ public: * @param totalEnergy total energy */ - void calculateIxn(int numberOfAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& exclusions, - std::map& globalParameters, std::vector& forces, RealOpenMM* totalEnergy); + void calculateIxn(int numberOfAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& exclusions, + std::map& globalParameters, std::vector& forces, RealOpenMM* totalEnergy); }; +} // namespace OpenMM + #endif // OPENMM_CPU_CUSTOM_GB_FORCE_H__ diff --git a/platforms/cpu/include/CpuKernels.h b/platforms/cpu/include/CpuKernels.h index 05b0448f9..ef5356961 100644 --- a/platforms/cpu/include/CpuKernels.h +++ b/platforms/cpu/include/CpuKernels.h @@ -342,18 +342,13 @@ private: bool isPeriodic; RealOpenMM **particleParamArray; RealOpenMM nonbondedCutoff; + CpuCustomGBForce* ixn; std::vector > exclusions; std::vector particleParameterNames, globalParameterNames, valueNames; - std::vector valueExpressions; - std::vector > valueDerivExpressions; - std::vector > valueGradientExpressions; std::vector valueTypes; - std::vector energyExpressions; - std::vector > energyDerivExpressions; - std::vector > energyGradientExpressions; std::vector energyTypes; NonbondedMethod nonbondedMethod; - NeighborList* neighborList; + CpuNeighborList* neighborList; }; /** diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index 0e038c017..9d2e87e7d 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -31,22 +31,18 @@ #include "ReferenceForce.h" #include "CpuCustomGBForce.h" -using std::map; -using std::set; -using std::string; -using std::stringstream; -using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; +using namespace std; CpuCustomGBForce::CpuCustomGBForce(const vector& valueExpressions, const vector > valueDerivExpressions, const vector > valueGradientExpressions, const vector& valueNames, - const vector& valueTypes, + const vector& valueTypes, const vector& energyExpressions, const vector > energyDerivExpressions, const vector > energyGradientExpressions, - const vector& energyTypes, + const vector& energyTypes, const vector& parameterNames) : cutoff(false), periodic(false), valueExpressions(valueExpressions), valueDerivExpressions(valueDerivExpressions), valueGradientExpressions(valueGradientExpressions), valueNames(valueNames), valueTypes(valueTypes), energyExpressions(energyExpressions), energyDerivExpressions(energyDerivExpressions), energyGradientExpressions(energyGradientExpressions), @@ -76,7 +72,6 @@ CpuCustomGBForce::CpuCustomGBForce(const vector& val for (int j = 1; j < 3; j++) { stringstream name; name << paramNames[i] << j; - particleParamNames.push_back(name.str()); particleParamIndex.push_back(expressionSet.getVariableIndex(name.str())); } } @@ -85,7 +80,6 @@ CpuCustomGBForce::CpuCustomGBForce(const vector& val for (int j = 1; j < 3; j++) { stringstream name; name << valueNames[i] << j; - particleValueNames.push_back(name.str()); particleValueIndex.push_back(expressionSet.getVariableIndex(name.str())); } } @@ -94,11 +88,11 @@ CpuCustomGBForce::CpuCustomGBForce(const vector& val CpuCustomGBForce::~CpuCustomGBForce() { } -void CpuCustomGBForce::setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors) { +void CpuCustomGBForce::setUseCutoff(RealOpenMM distance, const CpuNeighborList& neighbors) { cutoff = true; cutoffDistance = distance; neighborList = &neighbors; -} + } void CpuCustomGBForce::setPeriodic(RealVec& boxSize) { @@ -124,33 +118,33 @@ void CpuCustomGBForce::calculateIxn(int numberOfAtoms, vector& atomCoor int numValues = valueTypes.size(); vector > values(numValues); for (int valueIndex = 0; valueIndex < numValues; valueIndex++) { - if (valueTypes[valueIndex] == OpenMM::CustomGBForce::SingleParticle) - calculateSingleParticleValue(valueIndex, numberOfAtoms, atomCoordinates, values, globalParameters, atomParameters); - else if (valueTypes[valueIndex] == OpenMM::CustomGBForce::ParticlePair) - calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, true); + if (valueTypes[valueIndex] == CustomGBForce::SingleParticle) + calculateSingleParticleValue(valueIndex, numberOfAtoms, atomCoordinates, values, atomParameters); + else if (valueTypes[valueIndex] == CustomGBForce::ParticlePair) + calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, true); else - calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, false); + calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, false); } // Now calculate the energy and its derivatives. vector > dEdV(numValues, vector(numberOfAtoms, (RealOpenMM) 0)); for (int termIndex = 0; termIndex < (int) energyExpressions.size(); termIndex++) { - if (energyTypes[termIndex] == OpenMM::CustomGBForce::SingleParticle) - calculateSingleParticleEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, values, globalParameters, atomParameters, forces, totalEnergy, dEdV); - else if (energyTypes[termIndex] == OpenMM::CustomGBForce::ParticlePair) - calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, true, forces, totalEnergy, dEdV); + if (energyTypes[termIndex] == CustomGBForce::SingleParticle) + calculateSingleParticleEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, values, atomParameters, forces, totalEnergy, dEdV); + else if (energyTypes[termIndex] == CustomGBForce::ParticlePair) + calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, true, forces, totalEnergy, dEdV); else - calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, false, forces, totalEnergy, dEdV); + calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, false, forces, totalEnergy, dEdV); } // Apply the chain rule to evaluate forces. - calculateChainRuleForces(numberOfAtoms, atomCoordinates, atomParameters, values, globalParameters, exclusions, forces, dEdV); + calculateChainRuleForces(numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, forces, dEdV); } void CpuCustomGBForce::calculateSingleParticleValue(int index, int numAtoms, vector& atomCoordinates, vector >& values, - const map& globalParameters, RealOpenMM** atomParameters) { + RealOpenMM** atomParameters) { values[index].resize(numAtoms); for (int i = 0; i < numAtoms; i++) { expressionSet.setVariable(xindex, atomCoordinates[i][0]); @@ -165,19 +159,29 @@ void CpuCustomGBForce::calculateSingleParticleValue(int index, int numAtoms, vec } void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, - vector >& values, const map& globalParameters, const vector >& exclusions, bool useExclusions) { + vector >& values, const vector >& exclusions, bool useExclusions) { values[index].resize(numAtoms); for (int i = 0; i < numAtoms; i++) values[index][i] = (RealOpenMM) 0.0; if (cutoff) { // Loop over all pairs in the neighbor list. - for (int i = 0; i < (int) neighborList->size(); i++) { - OpenMM::AtomPair pair = (*neighborList)[i]; - if (useExclusions && exclusions[pair.first].find(pair.second) != exclusions[pair.first].end()) - continue; - calculateOnePairValue(index, pair.first, pair.second, atomCoordinates, atomParameters, globalParameters, values); - calculateOnePairValue(index, pair.second, pair.first, atomCoordinates, atomParameters, globalParameters, values); + for (int blockIndex = 0; blockIndex < neighborList->getNumBlocks(); blockIndex++) { + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; + const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); + const vector& blockExclusions = neighborList->getBlockExclusions(blockIndex); + for (int i = 0; i < (int) neighbors.size(); i++) { + int first = neighbors[i]; + for (int k = 0; k < 4; k++) { + if ((blockExclusions[i] & (1<& atomCoordinates, RealOpenMM** atomParameters, - const map& globalParameters, vector >& values) { + vector >& values) { RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (periodic) ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); @@ -217,7 +221,7 @@ void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, ve } void CpuCustomGBForce::calculateSingleParticleEnergyTerm(int index, int numAtoms, vector& atomCoordinates, const vector >& values, - const map& globalParameters, RealOpenMM** atomParameters, vector& forces, RealOpenMM* totalEnergy, + RealOpenMM** atomParameters, vector& forces, RealOpenMM* totalEnergy, vector >& dEdV) { for (int i = 0; i < numAtoms; i++) { expressionSet.setVariable(xindex, atomCoordinates[i][0]); @@ -238,16 +242,26 @@ void CpuCustomGBForce::calculateSingleParticleEnergyTerm(int index, int numAtoms } void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, - const vector >& values, const map& globalParameters, const vector >& exclusions, bool useExclusions, + const vector >& values, const vector >& exclusions, bool useExclusions, vector& forces, RealOpenMM* totalEnergy, vector >& dEdV) { if (cutoff) { // Loop over all pairs in the neighbor list. - for (int i = 0; i < (int) neighborList->size(); i++) { - OpenMM::AtomPair pair = (*neighborList)[i]; - if (useExclusions && exclusions[pair.first].find(pair.second) != exclusions[pair.first].end()) - continue; - calculateOnePairEnergyTerm(index, pair.first, pair.second, atomCoordinates, atomParameters, globalParameters, values, forces, totalEnergy, dEdV); + for (int blockIndex = 0; blockIndex < neighborList->getNumBlocks(); blockIndex++) { + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; + const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); + const vector& blockExclusions = neighborList->getBlockExclusions(blockIndex); + for (int i = 0; i < (int) neighbors.size(); i++) { + int first = neighbors[i]; + for (int k = 0; k < 4; k++) { + if ((blockExclusions[i] & (1<& atomCoordinates, RealOpenMM** atomParameters, - const map& globalParameters, const vector >& values, vector& forces, RealOpenMM* totalEnergy, + const vector >& values, vector& forces, RealOpenMM* totalEnergy, vector >& dEdV) { // Compute the displacement. @@ -306,16 +320,25 @@ void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom } void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, - const vector >& values, const map& globalParameters, - const vector >& exclusions, vector& forces, vector >& dEdV) { + const vector >& values, const vector >& exclusions, vector& forces, vector >& dEdV) { if (cutoff) { // Loop over all pairs in the neighbor list. - for (int i = 0; i < (int) neighborList->size(); i++) { - OpenMM::AtomPair pair = (*neighborList)[i]; - bool isExcluded = (exclusions[pair.first].find(pair.second) != exclusions[pair.first].end()); - calculateOnePairChainRule(pair.first, pair.second, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); - calculateOnePairChainRule(pair.second, pair.first, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); + for (int blockIndex = 0; blockIndex < neighborList->getNumBlocks(); blockIndex++) { + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; + const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); + const vector& blockExclusions = neighborList->getBlockExclusions(blockIndex); + for (int i = 0; i < (int) neighbors.size(); i++) { + int first = neighbors[i]; + for (int k = 0; k < 4; k++) { + if ((blockExclusions[i] & (1<& a for (int i = 0; i < numAtoms; i++) { for (int j = i+1; j < numAtoms; j++) { bool isExcluded = (exclusions[i].find(j) != exclusions[i].end()); - calculateOnePairChainRule(i, j, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); - calculateOnePairChainRule(j, i, atomCoordinates, atomParameters, globalParameters, values, forces, dEdV, isExcluded); + calculateOnePairChainRule(i, j, atomCoordinates, atomParameters, values, forces, dEdV, isExcluded); + calculateOnePairChainRule(j, i, atomCoordinates, atomParameters, values, forces, dEdV, isExcluded); } } } @@ -360,8 +383,7 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& a } void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, vector& atomCoordinates, RealOpenMM** atomParameters, - const map& globalParameters, const vector >& values, vector& forces, - vector >& dEdV, bool isExcluded) { + const vector >& values, vector& forces, vector >& dEdV, bool isExcluded) { // Compute the displacement. RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; @@ -391,7 +413,7 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, vector dVdR1(valueDerivExpressions.size(), 0.0); vector dVdR2(valueDerivExpressions.size(), 0.0); - if (!isExcluded || valueTypes[0] != OpenMM::CustomGBForce::ParticlePair) { + if (!isExcluded || valueTypes[0] != CustomGBForce::ParticlePair) { dVdR1[0] = (RealOpenMM) valueDerivExpressions[0][0].evaluate(); dVdR2[0] = -dVdR1[0]; for (int i = 0; i < 3; i++) { diff --git a/platforms/cpu/src/CpuCustomNonbondedForce.cpp b/platforms/cpu/src/CpuCustomNonbondedForce.cpp index 4664cab9e..f35328b40 100644 --- a/platforms/cpu/src/CpuCustomNonbondedForce.cpp +++ b/platforms/cpu/src/CpuCustomNonbondedForce.cpp @@ -182,9 +182,7 @@ void CpuCustomNonbondedForce::threadComputeForce(ThreadPool& threads, int thread int blockIndex = gmx_atomic_fetch_add(reinterpret_cast(atomicCounter), 1); if (blockIndex >= neighborList->getNumBlocks()) break; - int blockAtom[4]; - for (int i = 0; i < 4; i++) - blockAtom[i] = neighborList->getSortedAtoms()[4*blockIndex+i]; + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector& exclusions = neighborList->getBlockExclusions(blockIndex); for (int i = 0; i < (int) neighbors.size(); i++) { diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index af294468b..d5d06cc97 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -843,6 +843,8 @@ CpuCalcCustomGBForceKernel::~CpuCalcCustomGBForceKernel() { } if (neighborList != NULL) delete neighborList; + if (ixn != NULL) + delete ixn; } void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGBForce& force) { @@ -891,7 +893,7 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB if (nonbondedMethod == NoCutoff) neighborList = NULL; else - neighborList = new NeighborList(); + neighborList = new CpuNeighborList(4); // Create custom functions for the tabulated functions. @@ -901,8 +903,10 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB // Parse the expressions for computed values. - valueDerivExpressions.resize(force.getNumComputedValues()); - valueGradientExpressions.resize(force.getNumComputedValues()); + vector > valueDerivExpressions(force.getNumComputedValues()); + vector > valueGradientExpressions(force.getNumComputedValues()); + vector valueExpressions; + vector energyExpressions; for (int i = 0; i < force.getNumComputedValues(); i++) { string name, expression; CustomGBForce::ComputationType type; @@ -924,8 +928,8 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB // Parse the expressions for energy terms. - energyDerivExpressions.resize(force.getNumEnergyTerms()); - energyGradientExpressions.resize(force.getNumEnergyTerms()); + vector > energyDerivExpressions(force.getNumEnergyTerms()); + vector > energyGradientExpressions(force.getNumEnergyTerms()); for (int i = 0; i < force.getNumEnergyTerms(); i++) { string expression; CustomGBForce::ComputationType type; @@ -953,25 +957,28 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB for (map::iterator iter = functions.begin(); iter != functions.end(); iter++) delete iter->second; + ixn = new CpuCustomGBForce(valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions, + energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames); + data.isPeriodic = (force.getNonbondedMethod() == CustomGBForce::CutoffPeriodic); } double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { vector& posData = extractPositions(context); vector& forceData = extractForces(context); RealOpenMM energy = 0; - CpuCustomGBForce ixn(valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions, - energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames); - bool periodic = (nonbondedMethod == CutoffPeriodic); - if (periodic) - ixn.setPeriodic(extractBoxSize(context)); + RealVec& box = extractBoxSize(context); + float floatBoxSize[3] = {(float) box[0], (float) box[1], (float) box[2]}; + if (data.isPeriodic) + ixn->setPeriodic(extractBoxSize(context)); if (nonbondedMethod != NoCutoff) { - computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxSize(context), periodic, nonbondedCutoff, 0.0); - ixn.setUseCutoff(nonbondedCutoff, *neighborList); + vector > noExclusions(numParticles); + neighborList->computeNeighborList(numParticles, data.posq, exclusions, floatBoxSize, data.isPeriodic, nonbondedCutoff, data.threads); + ixn->setUseCutoff(nonbondedCutoff, *neighborList); } map globalParameters; for (int i = 0; i < (int) globalParameterNames.size(); i++) globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]); - ixn.calculateIxn(numParticles, posData, particleParamArray, exclusions, globalParameters, forceData, includeEnergy ? &energy : NULL); + ixn->calculateIxn(numParticles, posData, particleParamArray, exclusions, globalParameters, forceData, includeEnergy ? &energy : NULL); return energy; } diff --git a/platforms/cpu/src/CpuNonbondedForceVec4.cpp b/platforms/cpu/src/CpuNonbondedForceVec4.cpp index 32ef9db61..a8d42e849 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec4.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec4.cpp @@ -48,13 +48,11 @@ CpuNonbondedForceVec4::CpuNonbondedForceVec4() { void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. - int blockAtom[4]; + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; fvec4 blockAtomPosq[4]; fvec4 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - for (int i = 0; i < 4; i++) { - blockAtom[i] = neighborList->getSortedAtoms()[4*blockIndex+i]; + for (int i = 0; i < 4; i++) blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - } fvec4 blockAtomX = fvec4(blockAtomPosq[0][0], blockAtomPosq[1][0], blockAtomPosq[2][0], blockAtomPosq[3][0]); fvec4 blockAtomY = fvec4(blockAtomPosq[0][1], blockAtomPosq[1][1], blockAtomPosq[2][1], blockAtomPosq[3][1]); fvec4 blockAtomZ = fvec4(blockAtomPosq[0][2], blockAtomPosq[1][2], blockAtomPosq[2][2], blockAtomPosq[3][2]); @@ -159,13 +157,11 @@ void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, dou void CpuNonbondedForceVec4::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. - int blockAtom[4]; + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; fvec4 blockAtomPosq[4]; fvec4 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - for (int i = 0; i < 4; i++) { - blockAtom[i] = neighborList->getSortedAtoms()[4*blockIndex+i]; + for (int i = 0; i < 4; i++) blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - } fvec4 blockAtomX = fvec4(blockAtomPosq[0][0], blockAtomPosq[1][0], blockAtomPosq[2][0], blockAtomPosq[3][0]); fvec4 blockAtomY = fvec4(blockAtomPosq[0][1], blockAtomPosq[1][1], blockAtomPosq[2][1], blockAtomPosq[3][1]); fvec4 blockAtomZ = fvec4(blockAtomPosq[0][2], blockAtomPosq[1][2], blockAtomPosq[2][2], blockAtomPosq[3][2]); diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index f83951402..af6ac2e8a 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -74,14 +74,12 @@ CpuNonbondedForceVec8::CpuNonbondedForceVec8() { void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. - int blockAtom[8]; + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; fvec4 blockAtomPosq[8]; fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) { - blockAtom[i] = neighborList->getSortedAtoms()[8*blockIndex+i]; + for (int i = 0; i < 8; i++) blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - } transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); blockAtomCharge *= ONE_4PI_EPS0; fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); @@ -184,14 +182,12 @@ void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, dou void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. - int blockAtom[8]; + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; fvec4 blockAtomPosq[8]; fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) { - blockAtom[i] = neighborList->getSortedAtoms()[8*blockIndex+i]; + for (int i = 0; i < 8; i++) blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - } transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); blockAtomCharge *= ONE_4PI_EPS0; fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); -- GitLab From 83a0b6135185eb4f014a22d49787561fb3e0c596 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 7 Oct 2014 10:02:21 -0700 Subject: [PATCH 043/338] Eliminated some unnecessary memory allocation --- platforms/cpu/include/CpuCustomGBForce.h | 13 +++++---- platforms/cpu/src/CpuCustomGBForce.cpp | 36 ++++++++++++++++-------- platforms/cpu/src/CpuKernels.cpp | 2 +- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/platforms/cpu/include/CpuCustomGBForce.h b/platforms/cpu/include/CpuCustomGBForce.h index 177d4af67..b0f53a885 100644 --- a/platforms/cpu/include/CpuCustomGBForce.h +++ b/platforms/cpu/include/CpuCustomGBForce.h @@ -58,6 +58,9 @@ private: std::vector particleParamIndex; std::vector particleValueIndex; int xindex, yindex, zindex, rindex; + // Workspace vectors + std::vector > values, dEdV; + std::vector dVdR1, dVdR2, dVdX, dVdY, dVdZ; /** * Calculate a computed value of type SingleParticle @@ -198,14 +201,14 @@ public: * Construct a new CpuCustomGBForce. */ - CpuCustomGBForce(const std::vector& valueExpressions, - const std::vector > valueDerivExpressions, - const std::vector > valueGradientExpressions, + CpuCustomGBForce(int numAtoms, const std::vector& valueExpressions, + const std::vector >& valueDerivExpressions, + const std::vector >& valueGradientExpressions, const std::vector& valueNames, const std::vector& valueTypes, const std::vector& energyExpressions, - const std::vector > energyDerivExpressions, - const std::vector > energyGradientExpressions, + const std::vector >& energyDerivExpressions, + const std::vector >& energyGradientExpressions, const std::vector& energyTypes, const std::vector& parameterNames); diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index 9d2e87e7d..8325f965c 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -34,14 +34,14 @@ using namespace OpenMM; using namespace std; -CpuCustomGBForce::CpuCustomGBForce(const vector& valueExpressions, - const vector > valueDerivExpressions, - const vector > valueGradientExpressions, +CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector& valueExpressions, + const vector >& valueDerivExpressions, + const vector >& valueGradientExpressions, const vector& valueNames, const vector& valueTypes, const vector& energyExpressions, - const vector > energyDerivExpressions, - const vector > energyGradientExpressions, + const vector >& energyDerivExpressions, + const vector >& energyGradientExpressions, const vector& energyTypes, const vector& parameterNames) : cutoff(false), periodic(false), valueExpressions(valueExpressions), valueDerivExpressions(valueDerivExpressions), valueGradientExpressions(valueGradientExpressions), @@ -83,6 +83,17 @@ CpuCustomGBForce::CpuCustomGBForce(const vector& val particleValueIndex.push_back(expressionSet.getVariableIndex(name.str())); } } + values.resize(valueTypes.size()); + dEdV.resize(valueTypes.size()); + for (int i = 0; i < (int) values.size(); i++) { + values[i].resize(numAtoms); + dEdV[i].resize(numAtoms); + } + dVdX.resize(valueDerivExpressions.size()); + dVdY.resize(valueDerivExpressions.size()); + dVdZ.resize(valueDerivExpressions.size()); + dVdR1.resize(valueDerivExpressions.size()); + dVdR2.resize(valueDerivExpressions.size()); } CpuCustomGBForce::~CpuCustomGBForce() { @@ -116,7 +127,6 @@ void CpuCustomGBForce::calculateIxn(int numberOfAtoms, vector& atomCoor // First calculate the computed values. int numValues = valueTypes.size(); - vector > values(numValues); for (int valueIndex = 0; valueIndex < numValues; valueIndex++) { if (valueTypes[valueIndex] == CustomGBForce::SingleParticle) calculateSingleParticleValue(valueIndex, numberOfAtoms, atomCoordinates, values, atomParameters); @@ -128,7 +138,9 @@ void CpuCustomGBForce::calculateIxn(int numberOfAtoms, vector& atomCoor // Now calculate the energy and its derivatives. - vector > dEdV(numValues, vector(numberOfAtoms, (RealOpenMM) 0)); + for (int i = 0; i < (int) dEdV.size(); i++) + for (int j = 0; j < (int) dEdV[i].size(); j++) + dEdV[i][j] = 0.0; for (int termIndex = 0; termIndex < (int) energyExpressions.size(); termIndex++) { if (energyTypes[termIndex] == CustomGBForce::SingleParticle) calculateSingleParticleEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, values, atomParameters, forces, totalEnergy, dEdV); @@ -359,13 +371,13 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& a expressionSet.setVariable(xindex, atomCoordinates[i][0]); expressionSet.setVariable(yindex, atomCoordinates[i][1]); expressionSet.setVariable(zindex, atomCoordinates[i][2]); - vector dVdX(valueDerivExpressions.size(), 0.0); - vector dVdY(valueDerivExpressions.size(), 0.0); - vector dVdZ(valueDerivExpressions.size(), 0.0); for (int j = 0; j < (int) paramNames.size(); j++) expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); for (int j = 1; j < (int) valueNames.size(); j++) { expressionSet.setVariable(valueIndex[j-1], values[j-1][i]); + dVdX[j] = 0.0; + dVdY[j] = 0.0; + dVdZ[j] = 0.0; for (int k = 1; k < j; k++) { RealOpenMM dVdV = (RealOpenMM) valueDerivExpressions[j][k].evaluate(); dVdX[j] += dVdV*dVdX[k]; @@ -411,8 +423,6 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, vector dVdR1(valueDerivExpressions.size(), 0.0); - vector dVdR2(valueDerivExpressions.size(), 0.0); if (!isExcluded || valueTypes[0] != CustomGBForce::ParticlePair) { dVdR1[0] = (RealOpenMM) valueDerivExpressions[0][0].evaluate(); dVdR2[0] = -dVdR1[0]; @@ -429,6 +439,8 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, vector::iterator iter = functions.begin(); iter != functions.end(); iter++) delete iter->second; - ixn = new CpuCustomGBForce(valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions, + ixn = new CpuCustomGBForce(numParticles, valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions, energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames); data.isPeriodic = (force.getNonbondedMethod() == CustomGBForce::CutoffPeriodic); } -- GitLab From bb70341ae049bb3690c33703844026dc807a8943 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 7 Oct 2014 10:47:09 -0700 Subject: [PATCH 044/338] Further optimizations to CustomGBForce --- platforms/cpu/include/CpuCustomGBForce.h | 86 +++++---- platforms/cpu/src/CpuCustomGBForce.cpp | 217 ++++++++++++----------- platforms/cpu/src/CpuKernels.cpp | 3 +- 3 files changed, 160 insertions(+), 146 deletions(-) diff --git a/platforms/cpu/include/CpuCustomGBForce.h b/platforms/cpu/include/CpuCustomGBForce.h index b0f53a885..8e1503916 100644 --- a/platforms/cpu/include/CpuCustomGBForce.h +++ b/platforms/cpu/include/CpuCustomGBForce.h @@ -29,6 +29,7 @@ #include "CpuNeighborList.h" #include "lepton/CompiledExpression.h" #include "openmm/CustomGBForce.h" +#include "openmm/internal/vectorize.h" #include #include #include @@ -40,8 +41,8 @@ private: bool cutoff; bool periodic; const CpuNeighborList* neighborList; - RealOpenMM periodicBoxSize[3]; - RealOpenMM cutoffDistance; + float periodicBoxSize[3]; + float cutoffDistance; CompiledExpressionSet expressionSet; std::vector valueExpressions; std::vector > valueDerivExpressions; @@ -59,20 +60,20 @@ private: std::vector particleValueIndex; int xindex, yindex, zindex, rindex; // Workspace vectors - std::vector > values, dEdV; - std::vector dVdR1, dVdR2, dVdX, dVdY, dVdZ; + std::vector > values, dEdV; + std::vector dVdR1, dVdR2, dVdX, dVdY, dVdZ; /** * Calculate a computed value of type SingleParticle * * @param index the index of the value to compute * @param numAtoms number of atoms - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param values the vector to store computed values into * @param atomParameters atomParameters[atomIndex][paramterIndex] */ - void calculateSingleParticleValue(int index, int numAtoms, std::vector& atomCoordinates, std::vector >& values, + void calculateSingleParticleValue(int index, int numAtoms, float* posq, std::vector >& values, RealOpenMM** atomParameters); /** @@ -80,16 +81,16 @@ private: * * @param index the index of the value to compute * @param numAtoms number of atoms - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector to store computed values into * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param useExclusions specifies whether to use exclusions */ - void calculateParticlePairValue(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, - std::vector >& values, - const std::vector >& exclusions, bool useExclusions); + void calculateParticlePairValue(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, + std::vector >& values, + const std::vector >& exclusions, bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize); /** * Evaluate a single atom pair as part of calculating a computed value @@ -97,20 +98,20 @@ private: * @param index the index of the value to compute * @param atom1 the index of the first atom in the pair * @param atom2 the index of the second atom in the pair - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector to store computed values into */ - void calculateOnePairValue(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, - std::vector >& values); + void calculateOnePairValue(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, + std::vector >& values, const fvec4& boxSize, const fvec4& invBoxSize); /** * Calculate an energy term of type SingleParticle * * @param index the index of the value to compute * @param numAtoms number of atoms - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param values the vector containing computed values * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param forces forces on atoms are added to this @@ -118,16 +119,16 @@ private: * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateSingleParticleEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, const std::vector >& values, - RealOpenMM** atomParameters, std::vector& forces, - RealOpenMM* totalEnergy, std::vector >& dEdV); + void calculateSingleParticleEnergyTerm(int index, int numAtoms, float* posq, const std::vector >& values, + RealOpenMM** atomParameters, float* forces, + double* totalEnergy, std::vector >& dEdV); /** * Calculate an energy term that is based on particle pairs * * @param index the index of the term to compute * @param numAtoms number of atoms - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector containing computed values * @param exclusions exclusions[i] is the set of excluded indices for atom i @@ -137,10 +138,11 @@ private: * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateParticlePairEnergyTerm(int index, int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, - const std::vector >& values, + void calculateParticlePairEnergyTerm(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, + const std::vector >& values, const std::vector >& exclusions, bool useExclusions, - std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); + float* forces, double* totalEnergy, std::vector >& dEdV, + const fvec4& boxSize, const fvec4& invBoxSize); /** * Evaluate a single atom pair as part of calculating an energy term @@ -148,7 +150,7 @@ private: * @param index the index of the term to compute * @param atom1 the index of the first atom in the pair * @param atom2 the index of the second atom in the pair - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector containing computed values * @param forces forces on atoms are added to this @@ -156,15 +158,16 @@ private: * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateOnePairEnergyTerm(int index, int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, - const std::vector >& values, - std::vector& forces, RealOpenMM* totalEnergy, std::vector >& dEdV); + void calculateOnePairEnergyTerm(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, + const std::vector >& values, + float* forces, double* totalEnergy, std::vector >& dEdV, + const fvec4& boxSize, const fvec4& invBoxSize); /** * Apply the chain rule to compute forces on atoms * * @param numAtoms number of atoms - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector containing computed values * @param exclusions exclusions[i] is the set of excluded indices for atom i @@ -172,17 +175,18 @@ private: * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateChainRuleForces(int numAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, - const std::vector >& values, + void calculateChainRuleForces(int numAtoms, float* posq, RealOpenMM** atomParameters, + const std::vector >& values, const std::vector >& exclusions, - std::vector& forces, std::vector >& dEdV); + float* forces, std::vector >& dEdV, + const fvec4& boxSize, const fvec4& invBoxSize); /** * Evaluate a single atom pair as part of applying the chain rule * * @param atom1 the index of the first atom in the pair * @param atom2 the index of the second atom in the pair - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param values the vector containing computed values * @param forces forces on atoms are added to this @@ -190,10 +194,16 @@ private: * @param isExcluded specifies whether this is an excluded pair */ - void calculateOnePairChainRule(int atom1, int atom2, std::vector& atomCoordinates, RealOpenMM** atomParameters, - const std::vector >& values, - std::vector& forces, std::vector >& dEdV, - bool isExcluded); + void calculateOnePairChainRule(int atom1, int atom2, float* posq, RealOpenMM** atomParameters, + const std::vector >& values, + float* forces, std::vector >& dEdV, + bool isExcluded, const fvec4& boxSize, const fvec4& invBoxSize); + + /** + * Compute the displacement and squared distance between two points, optionally using + * periodic boundary conditions. + */ + void getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& deltaR, float& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const; public: @@ -221,7 +231,7 @@ public: * @param neighbors the neighbor list to use */ - void setUseCutoff(RealOpenMM distance, const CpuNeighborList& neighbors); + void setUseCutoff(float distance, const CpuNeighborList& neighbors); /** * Set the force to use periodic boundary conditions. This requires that a cutoff has @@ -237,7 +247,7 @@ public: * Calculate custom GB ixn * * @param numberOfAtoms number of atoms - * @param atomCoordinates atom coordinates + * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param globalParameters the values of global parameters @@ -245,8 +255,8 @@ public: * @param totalEnergy total energy */ - void calculateIxn(int numberOfAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, const std::vector >& exclusions, - std::map& globalParameters, std::vector& forces, RealOpenMM* totalEnergy); + void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, const std::vector >& exclusions, + std::map& globalParameters, float* forces, double* totalEnergy); }; } // namespace OpenMM diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index 8325f965c..ed29b7a76 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -99,7 +99,7 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector& atomCoordinates, RealOpenMM** atomParameters, - const vector >& exclusions, map& globalParameters, vector& forces, - RealOpenMM* totalEnergy) { +void CpuCustomGBForce::calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, + const vector >& exclusions, map& globalParameters, float* forces, + double* totalEnergy) { + fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); + fvec4 invBoxSize((1/periodicBoxSize[0]), (1/periodicBoxSize[1]), (1/periodicBoxSize[2]), 0); for (map::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); @@ -129,11 +131,11 @@ void CpuCustomGBForce::calculateIxn(int numberOfAtoms, vector& atomCoor int numValues = valueTypes.size(); for (int valueIndex = 0; valueIndex < numValues; valueIndex++) { if (valueTypes[valueIndex] == CustomGBForce::SingleParticle) - calculateSingleParticleValue(valueIndex, numberOfAtoms, atomCoordinates, values, atomParameters); + calculateSingleParticleValue(valueIndex, numberOfAtoms, posq, values, atomParameters); else if (valueTypes[valueIndex] == CustomGBForce::ParticlePair) - calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, true); + calculateParticlePairValue(valueIndex, numberOfAtoms, posq, atomParameters, values, exclusions, true, boxSize, invBoxSize); else - calculateParticlePairValue(valueIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, false); + calculateParticlePairValue(valueIndex, numberOfAtoms, posq, atomParameters, values, exclusions, false, boxSize, invBoxSize); } // Now calculate the energy and its derivatives. @@ -143,38 +145,38 @@ void CpuCustomGBForce::calculateIxn(int numberOfAtoms, vector& atomCoor dEdV[i][j] = 0.0; for (int termIndex = 0; termIndex < (int) energyExpressions.size(); termIndex++) { if (energyTypes[termIndex] == CustomGBForce::SingleParticle) - calculateSingleParticleEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, values, atomParameters, forces, totalEnergy, dEdV); + calculateSingleParticleEnergyTerm(termIndex, numberOfAtoms, posq, values, atomParameters, forces, totalEnergy, dEdV); else if (energyTypes[termIndex] == CustomGBForce::ParticlePair) - calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, true, forces, totalEnergy, dEdV); + calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, posq, atomParameters, values, exclusions, true, forces, totalEnergy, dEdV, boxSize, invBoxSize); else - calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, false, forces, totalEnergy, dEdV); + calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, posq, atomParameters, values, exclusions, false, forces, totalEnergy, dEdV, boxSize, invBoxSize); } // Apply the chain rule to evaluate forces. - calculateChainRuleForces(numberOfAtoms, atomCoordinates, atomParameters, values, exclusions, forces, dEdV); + calculateChainRuleForces(numberOfAtoms, posq, atomParameters, values, exclusions, forces, dEdV, boxSize, invBoxSize); } -void CpuCustomGBForce::calculateSingleParticleValue(int index, int numAtoms, vector& atomCoordinates, vector >& values, +void CpuCustomGBForce::calculateSingleParticleValue(int index, int numAtoms, float* posq, vector >& values, RealOpenMM** atomParameters) { values[index].resize(numAtoms); for (int i = 0; i < numAtoms; i++) { - expressionSet.setVariable(xindex, atomCoordinates[i][0]); - expressionSet.setVariable(yindex, atomCoordinates[i][1]); - expressionSet.setVariable(zindex, atomCoordinates[i][2]); + expressionSet.setVariable(xindex, posq[4*i]); + expressionSet.setVariable(yindex, posq[4*i+1]); + expressionSet.setVariable(zindex, posq[4*i+2]); for (int j = 0; j < (int) paramNames.size(); j++) expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); for (int j = 0; j < index; j++) expressionSet.setVariable(valueIndex[j], values[j][i]); - values[index][i] = (RealOpenMM) valueExpressions[index].evaluate(); + values[index][i] = (float) valueExpressions[index].evaluate(); } } -void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, - vector >& values, const vector >& exclusions, bool useExclusions) { +void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, + vector >& values, const vector >& exclusions, bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize) { values[index].resize(numAtoms); for (int i = 0; i < numAtoms; i++) - values[index][i] = (RealOpenMM) 0.0; + values[index][i] = 0.0f; if (cutoff) { // Loop over all pairs in the neighbor list. @@ -189,8 +191,8 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, vecto int second = blockAtom[k]; if (useExclusions && exclusions[first].find(second) != exclusions[first].end()) continue; - calculateOnePairValue(index, first, second, atomCoordinates, atomParameters, values); - calculateOnePairValue(index, second, first, atomCoordinates, atomParameters, values); + calculateOnePairValue(index, first, second, posq, atomParameters, values, boxSize, invBoxSize); + calculateOnePairValue(index, second, first, posq, atomParameters, values, boxSize, invBoxSize); } } } @@ -203,21 +205,21 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, vecto for (int j = i+1; j < numAtoms; j++) { if (useExclusions && exclusions[i].find(j) != exclusions[i].end()) continue; - calculateOnePairValue(index, i, j, atomCoordinates, atomParameters, values); - calculateOnePairValue(index, j, i, atomCoordinates, atomParameters, values); + calculateOnePairValue(index, i, j, posq, atomParameters, values, boxSize, invBoxSize); + calculateOnePairValue(index, j, i, posq, atomParameters, values, boxSize, invBoxSize); } } } } -void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, vector& atomCoordinates, RealOpenMM** atomParameters, - vector >& values) { - RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; - if (periodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); - else - ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); - RealOpenMM r = deltaR[ReferenceForce::RIndex]; +void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, + vector >& values, const fvec4& boxSize, const fvec4& invBoxSize) { + fvec4 deltaR; + fvec4 pos1(posq+4*atom1); + fvec4 pos2(posq+4*atom2); + float r2; + getDeltaR(pos2, pos1, deltaR, r2, periodic, boxSize, invBoxSize); + float r = sqrtf(r2); if (cutoff && r >= cutoffDistance) return; for (int i = 0; i < (int) paramNames.size(); i++) { @@ -229,33 +231,33 @@ void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, ve expressionSet.setVariable(particleValueIndex[i*2], values[i][atom1]); expressionSet.setVariable(particleValueIndex[i*2+1], values[i][atom2]); } - values[index][atom1] += (RealOpenMM) valueExpressions[index].evaluate(); + values[index][atom1] += (float) valueExpressions[index].evaluate(); } -void CpuCustomGBForce::calculateSingleParticleEnergyTerm(int index, int numAtoms, vector& atomCoordinates, const vector >& values, - RealOpenMM** atomParameters, vector& forces, RealOpenMM* totalEnergy, - vector >& dEdV) { +void CpuCustomGBForce::calculateSingleParticleEnergyTerm(int index, int numAtoms, float* posq, const vector >& values, + RealOpenMM** atomParameters, float* forces, double* totalEnergy, + vector >& dEdV) { for (int i = 0; i < numAtoms; i++) { - expressionSet.setVariable(xindex, atomCoordinates[i][0]); - expressionSet.setVariable(yindex, atomCoordinates[i][1]); - expressionSet.setVariable(zindex, atomCoordinates[i][2]); + expressionSet.setVariable(xindex, posq[4*i]); + expressionSet.setVariable(yindex, posq[4*i+1]); + expressionSet.setVariable(zindex, posq[4*i+2]); for (int j = 0; j < (int) paramNames.size(); j++) expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); for (int j = 0; j < (int) valueNames.size(); j++) expressionSet.setVariable(valueIndex[j], values[j][i]); if (totalEnergy != NULL) - *totalEnergy += (RealOpenMM) energyExpressions[index].evaluate(); + *totalEnergy += (float) energyExpressions[index].evaluate(); for (int j = 0; j < (int) valueNames.size(); j++) - dEdV[j][i] += (RealOpenMM) energyDerivExpressions[index][j].evaluate(); - forces[i][0] -= (RealOpenMM) energyGradientExpressions[index][0].evaluate(); - forces[i][1] -= (RealOpenMM) energyGradientExpressions[index][1].evaluate(); - forces[i][2] -= (RealOpenMM) energyGradientExpressions[index][2].evaluate(); + dEdV[j][i] += (float) energyDerivExpressions[index][j].evaluate(); + forces[4*i+0] -= (float) energyGradientExpressions[index][0].evaluate(); + forces[4*i+1] -= (float) energyGradientExpressions[index][1].evaluate(); + forces[4*i+2] -= (float) energyGradientExpressions[index][2].evaluate(); } } -void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, - const vector >& values, const vector >& exclusions, bool useExclusions, - vector& forces, RealOpenMM* totalEnergy, vector >& dEdV) { +void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, + const vector >& values, const vector >& exclusions, bool useExclusions, + float* forces, double* totalEnergy, vector >& dEdV, const fvec4& boxSize, const fvec4& invBoxSize) { if (cutoff) { // Loop over all pairs in the neighbor list. @@ -270,7 +272,7 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, int second = blockAtom[k]; if (useExclusions && exclusions[first].find(second) != exclusions[first].end()) continue; - calculateOnePairEnergyTerm(index, first, second, atomCoordinates, atomParameters, values, forces, totalEnergy, dEdV); + calculateOnePairEnergyTerm(index, first, second, posq, atomParameters, values, forces, totalEnergy, dEdV, boxSize, invBoxSize); } } } @@ -283,23 +285,23 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, for (int j = i+1; j < numAtoms; j++) { if (useExclusions && exclusions[i].find(j) != exclusions[i].end()) continue; - calculateOnePairEnergyTerm(index, i, j, atomCoordinates, atomParameters, values, forces, totalEnergy, dEdV); + calculateOnePairEnergyTerm(index, i, j, posq, atomParameters, values, forces, totalEnergy, dEdV, boxSize, invBoxSize); } } } } -void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom2, vector& atomCoordinates, RealOpenMM** atomParameters, - const vector >& values, vector& forces, RealOpenMM* totalEnergy, - vector >& dEdV) { +void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, + const vector >& values, float* forces, double* totalEnergy, + vector >& dEdV, const fvec4& boxSize, const fvec4& invBoxSize) { // Compute the displacement. - RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; - if (periodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); - else - ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); - RealOpenMM r = deltaR[ReferenceForce::RIndex]; + fvec4 deltaR; + fvec4 pos1(posq+4*atom1); + fvec4 pos2(posq+4*atom2); + float r2; + getDeltaR(pos2, pos1, deltaR, r2, periodic, boxSize, invBoxSize); + float r = sqrtf(r2); if (cutoff && r >= cutoffDistance) return; @@ -318,21 +320,21 @@ void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom // Evaluate the energy and its derivatives. if (totalEnergy != NULL) - *totalEnergy += (RealOpenMM) energyExpressions[index].evaluate(); - RealOpenMM dEdR = (RealOpenMM) energyDerivExpressions[index][0].evaluate(); + *totalEnergy += (float) energyExpressions[index].evaluate(); + float dEdR = (float) energyDerivExpressions[index][0].evaluate(); dEdR *= 1/r; - for (int i = 0; i < 3; i++) { - forces[atom1][i] -= dEdR*deltaR[i]; - forces[atom2][i] += dEdR*deltaR[i]; - } + fvec4 result = deltaR*dEdR; + (fvec4(forces+4*atom1)-result).store(forces+4*atom1); + (fvec4(forces+4*atom2)+result).store(forces+4*atom2); for (int i = 0; i < (int) valueNames.size(); i++) { - dEdV[i][atom1] += (RealOpenMM) energyDerivExpressions[index][2*i+1].evaluate(); - dEdV[i][atom2] += (RealOpenMM) energyDerivExpressions[index][2*i+2].evaluate(); + dEdV[i][atom1] += (float) energyDerivExpressions[index][2*i+1].evaluate(); + dEdV[i][atom2] += (float) energyDerivExpressions[index][2*i+2].evaluate(); } } -void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, - const vector >& values, const vector >& exclusions, vector& forces, vector >& dEdV) { +void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, float* posq, RealOpenMM** atomParameters, + const vector >& values, const vector >& exclusions, float* forces, vector >& dEdV, + const fvec4& boxSize, const fvec4& invBoxSize) { if (cutoff) { // Loop over all pairs in the neighbor list. @@ -346,8 +348,8 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& a if ((blockExclusions[i] & (1<& a for (int i = 0; i < numAtoms; i++) { for (int j = i+1; j < numAtoms; j++) { bool isExcluded = (exclusions[i].find(j) != exclusions[i].end()); - calculateOnePairChainRule(i, j, atomCoordinates, atomParameters, values, forces, dEdV, isExcluded); - calculateOnePairChainRule(j, i, atomCoordinates, atomParameters, values, forces, dEdV, isExcluded); + calculateOnePairChainRule(i, j, posq, atomParameters, values, forces, dEdV, isExcluded, boxSize, invBoxSize); + calculateOnePairChainRule(j, i, posq, atomParameters, values, forces, dEdV, isExcluded, boxSize, invBoxSize); } } } @@ -368,9 +370,9 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& a // Compute chain rule terms for computed values that depend explicitly on particle coordinates. for (int i = 0; i < numAtoms; i++) { - expressionSet.setVariable(xindex, atomCoordinates[i][0]); - expressionSet.setVariable(yindex, atomCoordinates[i][1]); - expressionSet.setVariable(zindex, atomCoordinates[i][2]); + expressionSet.setVariable(xindex, posq[4*i]); + expressionSet.setVariable(yindex, posq[4*i+1]); + expressionSet.setVariable(zindex, posq[4*i+2]); for (int j = 0; j < (int) paramNames.size(); j++) expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); for (int j = 1; j < (int) valueNames.size(); j++) { @@ -379,31 +381,31 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, vector& a dVdY[j] = 0.0; dVdZ[j] = 0.0; for (int k = 1; k < j; k++) { - RealOpenMM dVdV = (RealOpenMM) valueDerivExpressions[j][k].evaluate(); + float dVdV = (float) valueDerivExpressions[j][k].evaluate(); dVdX[j] += dVdV*dVdX[k]; dVdY[j] += dVdV*dVdY[k]; dVdZ[j] += dVdV*dVdZ[k]; } - dVdX[j] += (RealOpenMM) valueGradientExpressions[j][0].evaluate(); - dVdY[j] += (RealOpenMM) valueGradientExpressions[j][1].evaluate(); - dVdZ[j] += (RealOpenMM) valueGradientExpressions[j][2].evaluate(); - forces[i][0] -= dEdV[j][i]*dVdX[j]; - forces[i][1] -= dEdV[j][i]*dVdY[j]; - forces[i][2] -= dEdV[j][i]*dVdZ[j]; + dVdX[j] += (float) valueGradientExpressions[j][0].evaluate(); + dVdY[j] += (float) valueGradientExpressions[j][1].evaluate(); + dVdZ[j] += (float) valueGradientExpressions[j][2].evaluate(); + forces[4*i+0] -= dEdV[j][i]*dVdX[j]; + forces[4*i+1] -= dEdV[j][i]*dVdY[j]; + forces[4*i+2] -= dEdV[j][i]*dVdZ[j]; } } } -void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, vector& atomCoordinates, RealOpenMM** atomParameters, - const vector >& values, vector& forces, vector >& dEdV, bool isExcluded) { +void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, float* posq, RealOpenMM** atomParameters, + const vector >& values, float* forces, vector >& dEdV, bool isExcluded, const fvec4& boxSize, const fvec4& invBoxSize) { // Compute the displacement. - RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; - if (periodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); - else - ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); - RealOpenMM r = deltaR[ReferenceForce::RIndex]; + fvec4 deltaR; + fvec4 pos1(posq+4*atom1); + fvec4 pos2(posq+4*atom2); + float r2; + getDeltaR(pos2, pos1, deltaR, r2, periodic, boxSize, invBoxSize); + float r = sqrtf(r2); if (cutoff && r >= cutoffDistance) return; @@ -419,36 +421,39 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, vector& posData = extractPositions(context); vector& forceData = extractForces(context); RealOpenMM energy = 0; RealVec& box = extractBoxSize(context); @@ -978,7 +977,7 @@ double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeFor map globalParameters; for (int i = 0; i < (int) globalParameterNames.size(); i++) globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]); - ixn->calculateIxn(numParticles, posData, particleParamArray, exclusions, globalParameters, forceData, includeEnergy ? &energy : NULL); + ixn->calculateIxn(numParticles, &data.posq[0], particleParamArray, exclusions, globalParameters, &data.threadForce[0][0], includeEnergy ? &energy : NULL); return energy; } -- GitLab From 6a4ac837fc25df78c771ac7a281e5bbdb391f9d0 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 7 Oct 2014 15:33:23 -0700 Subject: [PATCH 045/338] Parallelized CpuCustomGBForce --- platforms/cpu/include/CpuCustomGBForce.h | 157 ++++---- platforms/cpu/src/CpuCustomGBForce.cpp | 448 +++++++++++++++-------- platforms/cpu/src/CpuKernels.cpp | 6 +- 3 files changed, 380 insertions(+), 231 deletions(-) diff --git a/platforms/cpu/include/CpuCustomGBForce.h b/platforms/cpu/include/CpuCustomGBForce.h index 8e1503916..cdc719dd1 100644 --- a/platforms/cpu/include/CpuCustomGBForce.h +++ b/platforms/cpu/include/CpuCustomGBForce.h @@ -29,6 +29,7 @@ #include "CpuNeighborList.h" #include "lepton/CompiledExpression.h" #include "openmm/CustomGBForce.h" +#include "openmm/internal/ThreadPool.h" #include "openmm/internal/vectorize.h" #include #include @@ -38,59 +39,63 @@ namespace OpenMM { class CpuCustomGBForce { private: + class ComputeForceTask; + class ThreadData; + bool cutoff; bool periodic; const CpuNeighborList* neighborList; float periodicBoxSize[3]; float cutoffDistance; - CompiledExpressionSet expressionSet; - std::vector valueExpressions; - std::vector > valueDerivExpressions; - std::vector > valueGradientExpressions; + const std::vector > exclusions; std::vector valueNames; - std::vector valueIndex; std::vector valueTypes; - std::vector energyExpressions; - std::vector > energyDerivExpressions; - std::vector > energyGradientExpressions; std::vector paramNames; - std::vector paramIndex; std::vector energyTypes; - std::vector particleParamIndex; - std::vector particleValueIndex; - int xindex, yindex, zindex, rindex; + ThreadPool& threads; + std::vector threadData; + std::vector threadEnergy; // Workspace vectors std::vector > values, dEdV; - std::vector dVdR1, dVdR2, dVdX, dVdY, dVdZ; - + // The following variables are used to make information accessible to the individual threads. + int numberOfAtoms; + float* posq; + RealOpenMM** atomParameters; + const std::map* globalParameters; + std::vector >* threadForce; + bool includeForce, includeEnergy; + void* atomicCounter; + + /** + * This routine contains the code executed by each thread. + */ + void threadComputeForce(ThreadPool& threads, int threadIndex); + /** * Calculate a computed value of type SingleParticle * * @param index the index of the value to compute + * @param data workspace for the current thread * @param numAtoms number of atoms * @param posq atom coordinates - * @param values the vector to store computed values into * @param atomParameters atomParameters[atomIndex][paramterIndex] */ - void calculateSingleParticleValue(int index, int numAtoms, float* posq, std::vector >& values, - RealOpenMM** atomParameters); + void calculateSingleParticleValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters); /** * Calculate a computed value that is based on particle pairs * * @param index the index of the value to compute + * @param data workspace for the current thread * @param numAtoms number of atoms * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param values the vector to store computed values into - * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param useExclusions specifies whether to use exclusions */ - void calculateParticlePairValue(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, - std::vector >& values, - const std::vector >& exclusions, bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize); + void calculateParticlePairValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, + bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize); /** * Evaluate a single atom pair as part of calculating a computed value @@ -98,51 +103,43 @@ private: * @param index the index of the value to compute * @param atom1 the index of the first atom in the pair * @param atom2 the index of the second atom in the pair + * @param data workspace for the current thread * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param values the vector to store computed values into */ - void calculateOnePairValue(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, - std::vector >& values, const fvec4& boxSize, const fvec4& invBoxSize); + void calculateOnePairValue(int index, int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters, + std::vector& valueArray, const fvec4& boxSize, const fvec4& invBoxSize); /** * Calculate an energy term of type SingleParticle * * @param index the index of the value to compute + * @param data workspace for the current thread * @param numAtoms number of atoms * @param posq atom coordinates - * @param values the vector containing computed values * @param atomParameters atomParameters[atomIndex][paramterIndex] * @param forces forces on atoms are added to this * @param totalEnergy the energy contribution is added to this - * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateSingleParticleEnergyTerm(int index, int numAtoms, float* posq, const std::vector >& values, - RealOpenMM** atomParameters, float* forces, - double* totalEnergy, std::vector >& dEdV); + void calculateSingleParticleEnergyTerm(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, float* forces, double& totalEnergy); /** * Calculate an energy term that is based on particle pairs * * @param index the index of the term to compute + * @param data workspace for the current thread * @param numAtoms number of atoms * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param values the vector containing computed values - * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param useExclusions specifies whether to use exclusions * @param forces forces on atoms are added to this * @param totalEnergy the energy contribution is added to this - * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateParticlePairEnergyTerm(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, - const std::vector >& values, - const std::vector >& exclusions, bool useExclusions, - float* forces, double* totalEnergy, std::vector >& dEdV, - const fvec4& boxSize, const fvec4& invBoxSize); + void calculateParticlePairEnergyTerm(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, + bool useExclusions, float* forces, double& totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); /** * Evaluate a single atom pair as part of calculating an energy term @@ -150,54 +147,43 @@ private: * @param index the index of the term to compute * @param atom1 the index of the first atom in the pair * @param atom2 the index of the second atom in the pair + * @param data workspace for the current thread * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param values the vector containing computed values * @param forces forces on atoms are added to this * @param totalEnergy the energy contribution is added to this - * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateOnePairEnergyTerm(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, - const std::vector >& values, - float* forces, double* totalEnergy, std::vector >& dEdV, - const fvec4& boxSize, const fvec4& invBoxSize); + void calculateOnePairEnergyTerm(int index, int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters, + float* forces, double& totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); /** * Apply the chain rule to compute forces on atoms * + * @param data workspace for the current thread * @param numAtoms number of atoms * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param values the vector containing computed values - * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param forces forces on atoms are added to this - * @param dEdV the derivative of energy with respect to computed values is stored in this */ - void calculateChainRuleForces(int numAtoms, float* posq, RealOpenMM** atomParameters, - const std::vector >& values, - const std::vector >& exclusions, - float* forces, std::vector >& dEdV, - const fvec4& boxSize, const fvec4& invBoxSize); + void calculateChainRuleForces(ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, + float* forces, const fvec4& boxSize, const fvec4& invBoxSize); /** * Evaluate a single atom pair as part of applying the chain rule * * @param atom1 the index of the first atom in the pair * @param atom2 the index of the second atom in the pair + * @param data workspace for the current thread * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param values the vector containing computed values * @param forces forces on atoms are added to this - * @param dEdV the derivative of energy with respect to computed values is stored in this * @param isExcluded specifies whether this is an excluded pair */ - void calculateOnePairChainRule(int atom1, int atom2, float* posq, RealOpenMM** atomParameters, - const std::vector >& values, - float* forces, std::vector >& dEdV, - bool isExcluded, const fvec4& boxSize, const fvec4& invBoxSize); + void calculateOnePairChainRule(int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters, + float* forces, bool isExcluded, const fvec4& boxSize, const fvec4& invBoxSize); /** * Compute the displacement and squared distance between two points, optionally using @@ -211,16 +197,17 @@ public: * Construct a new CpuCustomGBForce. */ - CpuCustomGBForce(int numAtoms, const std::vector& valueExpressions, - const std::vector >& valueDerivExpressions, - const std::vector >& valueGradientExpressions, - const std::vector& valueNames, - const std::vector& valueTypes, - const std::vector& energyExpressions, - const std::vector >& energyDerivExpressions, - const std::vector >& energyGradientExpressions, - const std::vector& energyTypes, - const std::vector& parameterNames); + CpuCustomGBForce(int numAtoms, const std::vector >& exclusions, + const std::vector& valueExpressions, + const std::vector >& valueDerivExpressions, + const std::vector >& valueGradientExpressions, + const std::vector& valueNames, + const std::vector& valueTypes, + const std::vector& energyExpressions, + const std::vector >& energyDerivExpressions, + const std::vector >& energyGradientExpressions, + const std::vector& energyTypes, + const std::vector& parameterNames, ThreadPool& threads); ~CpuCustomGBForce(); @@ -249,14 +236,42 @@ public: * @param numberOfAtoms number of atoms * @param posq atom coordinates * @param atomParameters atomParameters[atomIndex][paramterIndex] - * @param exclusions exclusions[i] is the set of excluded indices for atom i * @param globalParameters the values of global parameters * @param forces force array (forces added) * @param totalEnergy total energy */ - void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, const std::vector >& exclusions, - std::map& globalParameters, float* forces, double* totalEnergy); + void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, + std::map& globalParameters, std::vector >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy); +}; + +class CpuCustomGBForce::ThreadData { +public: + ThreadData(int numAtoms, int numThreads, int threadIndex, + const std::vector& valueExpressions, + const std::vector >& valueDerivExpressions, + const std::vector >& valueGradientExpressions, + const std::vector& valueNames, + const std::vector& energyExpressions, + const std::vector >& energyDerivExpressions, + const std::vector >& energyGradientExpressions, + const std::vector& parameterNames); + CompiledExpressionSet expressionSet; + std::vector valueExpressions; + std::vector > valueDerivExpressions; + std::vector > valueGradientExpressions; + std::vector valueIndex; + std::vector energyExpressions; + std::vector > energyDerivExpressions; + std::vector > energyGradientExpressions; + std::vector paramIndex; + std::vector particleParamIndex; + std::vector particleValueIndex; + int xindex, yindex, zindex, rindex; + int firstAtom, lastAtom; + // Workspace vectors + std::vector value0, dVdR1, dVdR2, dVdX, dVdY, dVdZ; + std::vector > dEdV; }; } // namespace OpenMM diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index ed29b7a76..0ae4f0aa1 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -30,23 +30,34 @@ #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "CpuCustomGBForce.h" +#include "gmx_atomic.h" using namespace OpenMM; using namespace std; -CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector& valueExpressions, - const vector >& valueDerivExpressions, - const vector >& valueGradientExpressions, - const vector& valueNames, - const vector& valueTypes, - const vector& energyExpressions, - const vector >& energyDerivExpressions, - const vector >& energyGradientExpressions, - const vector& energyTypes, - const vector& parameterNames) : - cutoff(false), periodic(false), valueExpressions(valueExpressions), valueDerivExpressions(valueDerivExpressions), valueGradientExpressions(valueGradientExpressions), - valueNames(valueNames), valueTypes(valueTypes), energyExpressions(energyExpressions), energyDerivExpressions(energyDerivExpressions), energyGradientExpressions(energyGradientExpressions), - energyTypes(energyTypes), paramNames(parameterNames) { +class CpuCustomGBForce::ComputeForceTask : public ThreadPool::Task { +public: + ComputeForceTask(CpuCustomGBForce& owner) : owner(owner) { + } + void execute(ThreadPool& threads, int threadIndex) { + owner.threadComputeForce(threads, threadIndex); + } + CpuCustomGBForce& owner; +}; + +CpuCustomGBForce::ThreadData::ThreadData(int numAtoms, int numThreads, int threadIndex, + const vector& valueExpressions, + const vector >& valueDerivExpressions, + const vector >& valueGradientExpressions, + const vector& valueNames, + const vector& energyExpressions, + const vector >& energyDerivExpressions, + const vector >& energyGradientExpressions, + const vector& parameterNames) : + valueExpressions(valueExpressions), valueDerivExpressions(valueDerivExpressions), valueGradientExpressions(valueGradientExpressions), + energyExpressions(energyExpressions), energyDerivExpressions(energyDerivExpressions), energyGradientExpressions(energyGradientExpressions) { + firstAtom = (threadIndex*(long long) numAtoms)/numThreads; + lastAtom = ((threadIndex+1)*(long long) numAtoms)/numThreads; for (int i = 0; i < (int) valueExpressions.size(); i++) expressionSet.registerExpression(this->valueExpressions[i]); for (int i = 0; i < (int) valueDerivExpressions.size(); i++) @@ -67,11 +78,11 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector >& exclusions, + const vector& valueExpressions, + const vector >& valueDerivExpressions, + const vector >& valueGradientExpressions, + const vector& valueNames, + const vector& valueTypes, + const vector& energyExpressions, + const vector >& energyDerivExpressions, + const vector >& energyGradientExpressions, + const vector& energyTypes, + const vector& parameterNames, ThreadPool& threads) : + exclusions(exclusions), cutoff(false), periodic(false), valueNames(valueNames), valueTypes(valueTypes), + energyTypes(energyTypes), paramNames(parameterNames), threads(threads) { + for (int i = 0; i < threads.getNumThreads(); i++) + threadData.push_back(new ThreadData(numAtoms, threads.getNumThreads(), i, valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, + energyExpressions, energyDerivExpressions, energyGradientExpressions, parameterNames)); + values.resize(valueNames.size()); + dEdV.resize(valueNames.size()); + for (int i = 0; i < (int) values.size(); i++) { + values[i].resize(numAtoms); + dEdV[i].resize(numAtoms); + } +} + CpuCustomGBForce::~CpuCustomGBForce() { + for (int i = 0; i < (int) threadData.size(); i++) + delete threadData[i]; } void CpuCustomGBForce::setUseCutoff(float distance, const CpuNeighborList& neighbors) { @@ -106,7 +141,6 @@ void CpuCustomGBForce::setUseCutoff(float distance, const CpuNeighborList& neigh } void CpuCustomGBForce::setPeriodic(RealVec& boxSize) { - if (cutoff) { assert(boxSize[0] >= 2.0*cutoffDistance); assert(boxSize[1] >= 2.0*cutoffDistance); @@ -119,68 +153,157 @@ void CpuCustomGBForce::setPeriodic(RealVec& boxSize) { } void CpuCustomGBForce::calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, - const vector >& exclusions, map& globalParameters, float* forces, - double* totalEnergy) { + map& globalParameters, vector >& threadForce, + bool includeForce, bool includeEnergy, double& totalEnergy) { + // Record the parameters for the threads. + + this->numberOfAtoms = numberOfAtoms; + this->posq = posq; + this->atomParameters = atomParameters; + this->globalParameters = &globalParameters; + this->threadForce = &threadForce; + this->includeForce = includeForce; + this->includeEnergy = includeEnergy; + threadEnergy.resize(threads.getNumThreads()); + gmx_atomic_t counter; + this->atomicCounter = &counter; + + // Calculate the first computed value. + + ComputeForceTask task(*this); + gmx_atomic_set(&counter, 0); + threads.execute(task); + threads.waitForThreads(); + + // Calculate the remaining computed values. + + threads.resumeThreads(); + threads.waitForThreads(); + + // Calculate the energy terms. + + for (int i = 0; i < (int) threadData[0]->energyExpressions.size(); i++) { + gmx_atomic_set(&counter, 0); + threads.execute(task); + threads.waitForThreads(); + } + + // Sum the energy derivatives. + + threads.resumeThreads(); + threads.waitForThreads(); + + // Apply the chain rule to evaluate forces. + + gmx_atomic_set(&counter, 0); + threads.resumeThreads(); + threads.waitForThreads(); + + // Combine the energies from all the threads. + + if (includeEnergy) { + int numThreads = threads.getNumThreads(); + for (int i = 0; i < numThreads; i++) + totalEnergy += threadEnergy[i]; + } +} + +void CpuCustomGBForce::threadComputeForce(ThreadPool& threads, int threadIndex) { + // Compute this thread's subset of interactions. + + int numThreads = threads.getNumThreads(); + threadEnergy[threadIndex] = 0; + double& energy = threadEnergy[threadIndex]; + float* forces = &(*threadForce)[threadIndex][0]; + ThreadData& data = *threadData[threadIndex]; fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); fvec4 invBoxSize((1/periodicBoxSize[0]), (1/periodicBoxSize[1]), (1/periodicBoxSize[2]), 0); - for (map::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) - expressionSet.setVariable(expressionSet.getVariableIndex(iter->first), iter->second); + for (map::const_iterator iter = globalParameters->begin(); iter != globalParameters->end(); ++iter) + data.expressionSet.setVariable(data.expressionSet.getVariableIndex(iter->first), iter->second); + + // Calculate the first computed value. + + for (int i = 0; i < (int) data.value0.size(); i++) + data.value0[i] = 0.0f; + if (valueTypes[0] == CustomGBForce::ParticlePair) + calculateParticlePairValue(0, data, numberOfAtoms, posq, atomParameters, true, boxSize, invBoxSize); + else + calculateParticlePairValue(0, data, numberOfAtoms, posq, atomParameters, false, boxSize, invBoxSize); + threads.syncThreads(); + + // Sum the first computed value. + + for (int atom = data.firstAtom; atom < data.lastAtom; atom++) { + float sum = 0.0f; + for (int j = 0; j < (int) threadData.size(); j++) + sum += threadData[j]->value0[atom]; + values[0][atom] = sum; + } - // First calculate the computed values. + // Calculate the remaining computed values. int numValues = valueTypes.size(); - for (int valueIndex = 0; valueIndex < numValues; valueIndex++) { - if (valueTypes[valueIndex] == CustomGBForce::SingleParticle) - calculateSingleParticleValue(valueIndex, numberOfAtoms, posq, values, atomParameters); - else if (valueTypes[valueIndex] == CustomGBForce::ParticlePair) - calculateParticlePairValue(valueIndex, numberOfAtoms, posq, atomParameters, values, exclusions, true, boxSize, invBoxSize); - else - calculateParticlePairValue(valueIndex, numberOfAtoms, posq, atomParameters, values, exclusions, false, boxSize, invBoxSize); - } + for (int i = 1; i < numValues; i++) + calculateSingleParticleValue(i, data, numberOfAtoms, posq, atomParameters); + threads.syncThreads(); // Now calculate the energy and its derivatives. - for (int i = 0; i < (int) dEdV.size(); i++) - for (int j = 0; j < (int) dEdV[i].size(); j++) - dEdV[i][j] = 0.0; - for (int termIndex = 0; termIndex < (int) energyExpressions.size(); termIndex++) { + for (int i = 0; i < (int) data.dEdV.size(); i++) + for (int j = 0; j < (int) data.dEdV[i].size(); j++) + data.dEdV[i][j] = 0.0; + for (int termIndex = 0; termIndex < (int) data.energyExpressions.size(); termIndex++) { if (energyTypes[termIndex] == CustomGBForce::SingleParticle) - calculateSingleParticleEnergyTerm(termIndex, numberOfAtoms, posq, values, atomParameters, forces, totalEnergy, dEdV); + calculateSingleParticleEnergyTerm(termIndex, data, numberOfAtoms, posq, atomParameters, forces, energy); else if (energyTypes[termIndex] == CustomGBForce::ParticlePair) - calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, posq, atomParameters, values, exclusions, true, forces, totalEnergy, dEdV, boxSize, invBoxSize); + calculateParticlePairEnergyTerm(termIndex, data, numberOfAtoms, posq, atomParameters, true, forces, energy, boxSize, invBoxSize); else - calculateParticlePairEnergyTerm(termIndex, numberOfAtoms, posq, atomParameters, values, exclusions, false, forces, totalEnergy, dEdV, boxSize, invBoxSize); + calculateParticlePairEnergyTerm(termIndex, data, numberOfAtoms, posq, atomParameters, false, forces, energy, boxSize, invBoxSize); + threads.syncThreads(); + } + + // Sum the energy derivatives. + + for (int atom = data.firstAtom; atom < data.lastAtom; atom++) { + for (int i = 0; i < (int) dEdV.size(); i++) { + float sum = 0.0f; + for (int j = 0; j < (int) threadData.size(); j++) + sum += threadData[j]->dEdV[i][atom]; + dEdV[i][atom] = sum; + } } + threads.syncThreads(); // Apply the chain rule to evaluate forces. - calculateChainRuleForces(numberOfAtoms, posq, atomParameters, values, exclusions, forces, dEdV, boxSize, invBoxSize); + calculateChainRuleForces(data, numberOfAtoms, posq, atomParameters, forces, boxSize, invBoxSize); } -void CpuCustomGBForce::calculateSingleParticleValue(int index, int numAtoms, float* posq, vector >& values, - RealOpenMM** atomParameters) { - values[index].resize(numAtoms); - for (int i = 0; i < numAtoms; i++) { - expressionSet.setVariable(xindex, posq[4*i]); - expressionSet.setVariable(yindex, posq[4*i+1]); - expressionSet.setVariable(zindex, posq[4*i+2]); +void CpuCustomGBForce::calculateSingleParticleValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters) { + for (int i = data.firstAtom; i < data.lastAtom; i++) { + data.expressionSet.setVariable(data.xindex, posq[4*i]); + data.expressionSet.setVariable(data.yindex, posq[4*i+1]); + data.expressionSet.setVariable(data.zindex, posq[4*i+2]); for (int j = 0; j < (int) paramNames.size(); j++) - expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); + data.expressionSet.setVariable(data.paramIndex[j], atomParameters[i][j]); for (int j = 0; j < index; j++) - expressionSet.setVariable(valueIndex[j], values[j][i]); - values[index][i] = (float) valueExpressions[index].evaluate(); + data.expressionSet.setVariable(data.valueIndex[j], values[j][i]); + values[index][i] = (float) data.valueExpressions[index].evaluate(); } } -void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, - vector >& values, const vector >& exclusions, bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize) { - values[index].resize(numAtoms); +void CpuCustomGBForce::calculateParticlePairValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, + bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize) { for (int i = 0; i < numAtoms; i++) values[index][i] = 0.0f; + vector& valueArray = (index == 0 ? data.value0 : values[index]); if (cutoff) { // Loop over all pairs in the neighbor list. - for (int blockIndex = 0; blockIndex < neighborList->getNumBlocks(); blockIndex++) { + while (true) { + int blockIndex = gmx_atomic_fetch_add(reinterpret_cast(atomicCounter), 1); + if (blockIndex >= neighborList->getNumBlocks()) + break; const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector& blockExclusions = neighborList->getBlockExclusions(blockIndex); @@ -191,8 +314,8 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float int second = blockAtom[k]; if (useExclusions && exclusions[first].find(second) != exclusions[first].end()) continue; - calculateOnePairValue(index, first, second, posq, atomParameters, values, boxSize, invBoxSize); - calculateOnePairValue(index, second, first, posq, atomParameters, values, boxSize, invBoxSize); + calculateOnePairValue(index, first, second, data, posq, atomParameters, valueArray, boxSize, invBoxSize); + calculateOnePairValue(index, second, first, data, posq, atomParameters, valueArray, boxSize, invBoxSize); } } } @@ -201,19 +324,22 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float else { // Perform an O(N^2) loop over all atom pairs. - for (int i = 0; i < numAtoms; i++) { + while (true) { + int i = gmx_atomic_fetch_add(reinterpret_cast(atomicCounter), 1); + if (i >= numAtoms) + break; for (int j = i+1; j < numAtoms; j++) { if (useExclusions && exclusions[i].find(j) != exclusions[i].end()) continue; - calculateOnePairValue(index, i, j, posq, atomParameters, values, boxSize, invBoxSize); - calculateOnePairValue(index, j, i, posq, atomParameters, values, boxSize, invBoxSize); + calculateOnePairValue(index, i, j, data, posq, atomParameters, valueArray, boxSize, invBoxSize); + calculateOnePairValue(index, j, i, data, posq, atomParameters, valueArray, boxSize, invBoxSize); } } } } -void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, - vector >& values, const fvec4& boxSize, const fvec4& invBoxSize) { +void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters, + vector& valueArray, const fvec4& boxSize, const fvec4& invBoxSize) { fvec4 deltaR; fvec4 pos1(posq+4*atom1); fvec4 pos2(posq+4*atom2); @@ -223,45 +349,46 @@ void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, fl if (cutoff && r >= cutoffDistance) return; for (int i = 0; i < (int) paramNames.size(); i++) { - expressionSet.setVariable(particleParamIndex[i*2], atomParameters[atom1][i]); - expressionSet.setVariable(particleParamIndex[i*2+1], atomParameters[atom2][i]); + data.expressionSet.setVariable(data.particleParamIndex[i*2], atomParameters[atom1][i]); + data.expressionSet.setVariable(data.particleParamIndex[i*2+1], atomParameters[atom2][i]); } - expressionSet.setVariable(rindex, r); + data.expressionSet.setVariable(data.rindex, r); for (int i = 0; i < index; i++) { - expressionSet.setVariable(particleValueIndex[i*2], values[i][atom1]); - expressionSet.setVariable(particleValueIndex[i*2+1], values[i][atom2]); + data.expressionSet.setVariable(data.particleValueIndex[i*2], values[i][atom1]); + data.expressionSet.setVariable(data.particleValueIndex[i*2+1], values[i][atom2]); } - values[index][atom1] += (float) valueExpressions[index].evaluate(); + valueArray[atom1] += (float) data.valueExpressions[index].evaluate(); } -void CpuCustomGBForce::calculateSingleParticleEnergyTerm(int index, int numAtoms, float* posq, const vector >& values, - RealOpenMM** atomParameters, float* forces, double* totalEnergy, - vector >& dEdV) { - for (int i = 0; i < numAtoms; i++) { - expressionSet.setVariable(xindex, posq[4*i]); - expressionSet.setVariable(yindex, posq[4*i+1]); - expressionSet.setVariable(zindex, posq[4*i+2]); +void CpuCustomGBForce::calculateSingleParticleEnergyTerm(int index, ThreadData& data, int numAtoms, float* posq, + RealOpenMM** atomParameters, float* forces, double& totalEnergy) { + for (int i = data.firstAtom; i < data.lastAtom; i++) { + data.expressionSet.setVariable(data.xindex, posq[4*i]); + data.expressionSet.setVariable(data.yindex, posq[4*i+1]); + data.expressionSet.setVariable(data.zindex, posq[4*i+2]); for (int j = 0; j < (int) paramNames.size(); j++) - expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); + data.expressionSet.setVariable(data.paramIndex[j], atomParameters[i][j]); for (int j = 0; j < (int) valueNames.size(); j++) - expressionSet.setVariable(valueIndex[j], values[j][i]); - if (totalEnergy != NULL) - *totalEnergy += (float) energyExpressions[index].evaluate(); + data.expressionSet.setVariable(data.valueIndex[j], values[j][i]); + if (includeEnergy) + totalEnergy += (float) data.energyExpressions[index].evaluate(); for (int j = 0; j < (int) valueNames.size(); j++) - dEdV[j][i] += (float) energyDerivExpressions[index][j].evaluate(); - forces[4*i+0] -= (float) energyGradientExpressions[index][0].evaluate(); - forces[4*i+1] -= (float) energyGradientExpressions[index][1].evaluate(); - forces[4*i+2] -= (float) energyGradientExpressions[index][2].evaluate(); + data.dEdV[j][i] += (float) data.energyDerivExpressions[index][j].evaluate(); + forces[4*i+0] -= (float) data.energyGradientExpressions[index][0].evaluate(); + forces[4*i+1] -= (float) data.energyGradientExpressions[index][1].evaluate(); + forces[4*i+2] -= (float) data.energyGradientExpressions[index][2].evaluate(); } } -void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, float* posq, RealOpenMM** atomParameters, - const vector >& values, const vector >& exclusions, bool useExclusions, - float* forces, double* totalEnergy, vector >& dEdV, const fvec4& boxSize, const fvec4& invBoxSize) { +void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, + bool useExclusions, float* forces, double& totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { if (cutoff) { // Loop over all pairs in the neighbor list. - for (int blockIndex = 0; blockIndex < neighborList->getNumBlocks(); blockIndex++) { + while (true) { + int blockIndex = gmx_atomic_fetch_add(reinterpret_cast(atomicCounter), 1); + if (blockIndex >= neighborList->getNumBlocks()) + break; const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector& blockExclusions = neighborList->getBlockExclusions(blockIndex); @@ -272,7 +399,7 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, int second = blockAtom[k]; if (useExclusions && exclusions[first].find(second) != exclusions[first].end()) continue; - calculateOnePairEnergyTerm(index, first, second, posq, atomParameters, values, forces, totalEnergy, dEdV, boxSize, invBoxSize); + calculateOnePairEnergyTerm(index, first, second, data, posq, atomParameters, forces, totalEnergy, boxSize, invBoxSize); } } } @@ -281,19 +408,21 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms, else { // Perform an O(N^2) loop over all atom pairs. - for (int i = 0; i < numAtoms; i++) { + while (true) { + int i = gmx_atomic_fetch_add(reinterpret_cast(atomicCounter), 1); + if (i >= numAtoms) + break; for (int j = i+1; j < numAtoms; j++) { if (useExclusions && exclusions[i].find(j) != exclusions[i].end()) continue; - calculateOnePairEnergyTerm(index, i, j, posq, atomParameters, values, forces, totalEnergy, dEdV, boxSize, invBoxSize); + calculateOnePairEnergyTerm(index, i, j, data, posq, atomParameters, forces, totalEnergy, boxSize, invBoxSize); } } } } -void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom2, float* posq, RealOpenMM** atomParameters, - const vector >& values, float* forces, double* totalEnergy, - vector >& dEdV, const fvec4& boxSize, const fvec4& invBoxSize) { +void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters, + float* forces, double& totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Compute the displacement. fvec4 deltaR; @@ -308,37 +437,39 @@ void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom // Record variables for evaluating expressions. for (int i = 0; i < (int) paramNames.size(); i++) { - expressionSet.setVariable(particleParamIndex[i*2], atomParameters[atom1][i]); - expressionSet.setVariable(particleParamIndex[i*2+1], atomParameters[atom2][i]); + data.expressionSet.setVariable(data.particleParamIndex[i*2], atomParameters[atom1][i]); + data.expressionSet.setVariable(data.particleParamIndex[i*2+1], atomParameters[atom2][i]); } - expressionSet.setVariable(rindex, r); + data.expressionSet.setVariable(data.rindex, r); for (int i = 0; i < (int) valueNames.size(); i++) { - expressionSet.setVariable(particleValueIndex[i*2], values[i][atom1]); - expressionSet.setVariable(particleValueIndex[i*2+1], values[i][atom2]); + data.expressionSet.setVariable(data.particleValueIndex[i*2], values[i][atom1]); + data.expressionSet.setVariable(data.particleValueIndex[i*2+1], values[i][atom2]); } // Evaluate the energy and its derivatives. - if (totalEnergy != NULL) - *totalEnergy += (float) energyExpressions[index].evaluate(); - float dEdR = (float) energyDerivExpressions[index][0].evaluate(); + if (includeEnergy) + totalEnergy += (float) data.energyExpressions[index].evaluate(); + float dEdR = (float) data.energyDerivExpressions[index][0].evaluate(); dEdR *= 1/r; fvec4 result = deltaR*dEdR; (fvec4(forces+4*atom1)-result).store(forces+4*atom1); (fvec4(forces+4*atom2)+result).store(forces+4*atom2); for (int i = 0; i < (int) valueNames.size(); i++) { - dEdV[i][atom1] += (float) energyDerivExpressions[index][2*i+1].evaluate(); - dEdV[i][atom2] += (float) energyDerivExpressions[index][2*i+2].evaluate(); + data.dEdV[i][atom1] += (float) data.energyDerivExpressions[index][2*i+1].evaluate(); + data.dEdV[i][atom2] += (float) data.energyDerivExpressions[index][2*i+2].evaluate(); } } -void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, float* posq, RealOpenMM** atomParameters, - const vector >& values, const vector >& exclusions, float* forces, vector >& dEdV, - const fvec4& boxSize, const fvec4& invBoxSize) { +void CpuCustomGBForce::calculateChainRuleForces(ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, + float* forces, const fvec4& boxSize, const fvec4& invBoxSize) { if (cutoff) { // Loop over all pairs in the neighbor list. - for (int blockIndex = 0; blockIndex < neighborList->getNumBlocks(); blockIndex++) { + while (true) { + int blockIndex = gmx_atomic_fetch_add(reinterpret_cast(atomicCounter), 1); + if (blockIndex >= neighborList->getNumBlocks()) + break; const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector& blockExclusions = neighborList->getBlockExclusions(blockIndex); @@ -348,8 +479,8 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, float* posq, RealO if ((blockExclusions[i] & (1<(atomicCounter), 1); + if (i >= numAtoms) + break; for (int j = i+1; j < numAtoms; j++) { bool isExcluded = (exclusions[i].find(j) != exclusions[i].end()); - calculateOnePairChainRule(i, j, posq, atomParameters, values, forces, dEdV, isExcluded, boxSize, invBoxSize); - calculateOnePairChainRule(j, i, posq, atomParameters, values, forces, dEdV, isExcluded, boxSize, invBoxSize); + calculateOnePairChainRule(i, j, data, posq, atomParameters, forces, isExcluded, boxSize, invBoxSize); + calculateOnePairChainRule(j, i, data, posq, atomParameters, forces, isExcluded, boxSize, invBoxSize); } } } // Compute chain rule terms for computed values that depend explicitly on particle coordinates. - for (int i = 0; i < numAtoms; i++) { - expressionSet.setVariable(xindex, posq[4*i]); - expressionSet.setVariable(yindex, posq[4*i+1]); - expressionSet.setVariable(zindex, posq[4*i+2]); + for (int i = data.firstAtom; i < data.lastAtom; i++) { + data.expressionSet.setVariable(data.xindex, posq[4*i]); + data.expressionSet.setVariable(data.yindex, posq[4*i+1]); + data.expressionSet.setVariable(data.zindex, posq[4*i+2]); for (int j = 0; j < (int) paramNames.size(); j++) - expressionSet.setVariable(paramIndex[j], atomParameters[i][j]); + data.expressionSet.setVariable(data.paramIndex[j], atomParameters[i][j]); for (int j = 1; j < (int) valueNames.size(); j++) { - expressionSet.setVariable(valueIndex[j-1], values[j-1][i]); - dVdX[j] = 0.0; - dVdY[j] = 0.0; - dVdZ[j] = 0.0; + data.expressionSet.setVariable(data.valueIndex[j-1], values[j-1][i]); + data.dVdX[j] = 0.0; + data.dVdY[j] = 0.0; + data.dVdZ[j] = 0.0; for (int k = 1; k < j; k++) { - float dVdV = (float) valueDerivExpressions[j][k].evaluate(); - dVdX[j] += dVdV*dVdX[k]; - dVdY[j] += dVdV*dVdY[k]; - dVdZ[j] += dVdV*dVdZ[k]; + float dVdV = (float) data.valueDerivExpressions[j][k].evaluate(); + data.dVdX[j] += dVdV*data.dVdX[k]; + data.dVdY[j] += dVdV*data.dVdY[k]; + data.dVdZ[j] += dVdV*data.dVdZ[k]; } - dVdX[j] += (float) valueGradientExpressions[j][0].evaluate(); - dVdY[j] += (float) valueGradientExpressions[j][1].evaluate(); - dVdZ[j] += (float) valueGradientExpressions[j][2].evaluate(); - forces[4*i+0] -= dEdV[j][i]*dVdX[j]; - forces[4*i+1] -= dEdV[j][i]*dVdY[j]; - forces[4*i+2] -= dEdV[j][i]*dVdZ[j]; + data.dVdX[j] += (float) data.valueGradientExpressions[j][0].evaluate(); + data.dVdY[j] += (float) data.valueGradientExpressions[j][1].evaluate(); + data.dVdZ[j] += (float) data.valueGradientExpressions[j][2].evaluate(); + forces[4*i+0] -= dEdV[j][i]*data.dVdX[j]; + forces[4*i+1] -= dEdV[j][i]*data.dVdY[j]; + forces[4*i+2] -= dEdV[j][i]*data.dVdZ[j]; } } } -void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, float* posq, RealOpenMM** atomParameters, - const vector >& values, float* forces, vector >& dEdV, bool isExcluded, const fvec4& boxSize, const fvec4& invBoxSize) { +void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters, + float* forces, bool isExcluded, const fvec4& boxSize, const fvec4& invBoxSize) { // Compute the displacement. fvec4 deltaR; @@ -412,40 +546,40 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, float* po // Record variables for evaluating expressions. for (int i = 0; i < (int) paramNames.size(); i++) { - expressionSet.setVariable(particleParamIndex[i*2], atomParameters[atom1][i]); - expressionSet.setVariable(particleParamIndex[i*2+1], atomParameters[atom2][i]); + data.expressionSet.setVariable(data.particleParamIndex[i*2], atomParameters[atom1][i]); + data.expressionSet.setVariable(data.particleParamIndex[i*2+1], atomParameters[atom2][i]); } - expressionSet.setVariable(rindex, r); - expressionSet.setVariable(particleValueIndex[0], values[0][atom1]); - expressionSet.setVariable(particleValueIndex[1], values[0][atom2]); + data.expressionSet.setVariable(data.rindex, r); + data.expressionSet.setVariable(data.particleValueIndex[0], values[0][atom1]); + data.expressionSet.setVariable(data.particleValueIndex[1], values[0][atom2]); // Evaluate the derivative of each parameter with respect to position and apply forces. float rinv = 1/r; deltaR *= rinv; if (!isExcluded || valueTypes[0] != CustomGBForce::ParticlePair) { - dVdR1[0] = (float) valueDerivExpressions[0][0].evaluate(); - dVdR2[0] = -dVdR1[0]; - (fvec4(forces+4*atom1)-deltaR*(dEdV[0][atom1]*dVdR1[0])).store(forces+4*atom1); - (fvec4(forces+4*atom2)-deltaR*(dEdV[0][atom1]*dVdR2[0])).store(forces+4*atom2); + data.dVdR1[0] = (float) data.valueDerivExpressions[0][0].evaluate(); + data.dVdR2[0] = -data.dVdR1[0]; + (fvec4(forces+4*atom1)-deltaR*(dEdV[0][atom1]*data.dVdR1[0])).store(forces+4*atom1); + (fvec4(forces+4*atom2)-deltaR*(dEdV[0][atom1]*data.dVdR2[0])).store(forces+4*atom2); } for (int i = 0; i < (int) paramNames.size(); i++) - expressionSet.setVariable(paramIndex[i], atomParameters[atom1][i]); - expressionSet.setVariable(valueIndex[0], values[0][atom1]); + data.expressionSet.setVariable(data.paramIndex[i], atomParameters[atom1][i]); + data.expressionSet.setVariable(data.valueIndex[0], values[0][atom1]); for (int i = 1; i < (int) valueNames.size(); i++) { - expressionSet.setVariable(valueIndex[i], values[i][atom1]); - expressionSet.setVariable(xindex, posq[4*atom1]); - expressionSet.setVariable(yindex, posq[4*atom1+1]); - expressionSet.setVariable(zindex, posq[4*atom1+2]); - dVdR1[i] = 0.0; - dVdR2[i] = 0.0; + data.expressionSet.setVariable(data.valueIndex[i], values[i][atom1]); + data.expressionSet.setVariable(data.xindex, posq[4*atom1]); + data.expressionSet.setVariable(data.yindex, posq[4*atom1+1]); + data.expressionSet.setVariable(data.zindex, posq[4*atom1+2]); + data.dVdR1[i] = 0.0; + data.dVdR2[i] = 0.0; for (int j = 0; j < i; j++) { - float dVdV = (float) valueDerivExpressions[i][j].evaluate(); - dVdR1[i] += dVdV*dVdR1[j]; - dVdR2[i] += dVdV*dVdR2[j]; + float dVdV = (float) data.valueDerivExpressions[i][j].evaluate(); + data.dVdR1[i] += dVdV*data.dVdR1[j]; + data.dVdR2[i] += dVdV*data.dVdR2[j]; } - (fvec4(forces+4*atom1)-deltaR*(dEdV[i][atom1]*dVdR1[i])).store(forces+4*atom1); - (fvec4(forces+4*atom2)-deltaR*(dEdV[i][atom1]*dVdR2[i])).store(forces+4*atom2); + (fvec4(forces+4*atom1)-deltaR*(dEdV[i][atom1]*data.dVdR1[i])).store(forces+4*atom1); + (fvec4(forces+4*atom2)-deltaR*(dEdV[i][atom1]*data.dVdR2[i])).store(forces+4*atom2); } } diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 7a7aa32a3..75200fef5 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -957,8 +957,8 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB for (map::iterator iter = functions.begin(); iter != functions.end(); iter++) delete iter->second; - ixn = new CpuCustomGBForce(numParticles, valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions, - energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames); + ixn = new CpuCustomGBForce(numParticles, exclusions, valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions, + energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames, data.threads); data.isPeriodic = (force.getNonbondedMethod() == CustomGBForce::CutoffPeriodic); } @@ -977,7 +977,7 @@ double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeFor map globalParameters; for (int i = 0; i < (int) globalParameterNames.size(); i++) globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]); - ixn->calculateIxn(numParticles, &data.posq[0], particleParamArray, exclusions, globalParameters, &data.threadForce[0][0], includeEnergy ? &energy : NULL); + ixn->calculateIxn(numParticles, &data.posq[0], particleParamArray, globalParameters, data.threadForce, includeForces, includeEnergy, energy); return energy; } -- GitLab From ea435536f1aec7737597a50879b4119ce16e3971 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 7 Oct 2014 15:58:21 -0700 Subject: [PATCH 046/338] Very minor optimization to CpuCustomGBForce --- platforms/cpu/include/CpuCustomGBForce.h | 12 --------- platforms/cpu/src/CpuCustomGBForce.cpp | 31 +++++++++--------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/platforms/cpu/include/CpuCustomGBForce.h b/platforms/cpu/include/CpuCustomGBForce.h index cdc719dd1..685098fa2 100644 --- a/platforms/cpu/include/CpuCustomGBForce.h +++ b/platforms/cpu/include/CpuCustomGBForce.h @@ -70,18 +70,6 @@ private: * This routine contains the code executed by each thread. */ void threadComputeForce(ThreadPool& threads, int threadIndex); - - /** - * Calculate a computed value of type SingleParticle - * - * @param index the index of the value to compute - * @param data workspace for the current thread - * @param numAtoms number of atoms - * @param posq atom coordinates - * @param atomParameters atomParameters[atomIndex][paramterIndex] - */ - - void calculateSingleParticleValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters); /** * Calculate a computed value that is based on particle pairs diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index 0ae4f0aa1..0ae114819 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -231,20 +231,24 @@ void CpuCustomGBForce::threadComputeForce(ThreadPool& threads, int threadIndex) calculateParticlePairValue(0, data, numberOfAtoms, posq, atomParameters, false, boxSize, invBoxSize); threads.syncThreads(); - // Sum the first computed value. + // Sum the first computed value and calculate the remaining ones. + int numValues = valueTypes.size(); for (int atom = data.firstAtom; atom < data.lastAtom; atom++) { float sum = 0.0f; for (int j = 0; j < (int) threadData.size(); j++) sum += threadData[j]->value0[atom]; values[0][atom] = sum; + data.expressionSet.setVariable(data.xindex, posq[4*atom]); + data.expressionSet.setVariable(data.yindex, posq[4*atom+1]); + data.expressionSet.setVariable(data.zindex, posq[4*atom+2]); + for (int j = 0; j < (int) paramNames.size(); j++) + data.expressionSet.setVariable(data.paramIndex[j], atomParameters[atom][j]); + for (int i = 1; i < numValues; i++) { + data.expressionSet.setVariable(data.valueIndex[i-1], values[i-1][atom]); + values[i][atom] = (float) data.valueExpressions[i].evaluate(); + } } - - // Calculate the remaining computed values. - - int numValues = valueTypes.size(); - for (int i = 1; i < numValues; i++) - calculateSingleParticleValue(i, data, numberOfAtoms, posq, atomParameters); threads.syncThreads(); // Now calculate the energy and its derivatives. @@ -279,19 +283,6 @@ void CpuCustomGBForce::threadComputeForce(ThreadPool& threads, int threadIndex) calculateChainRuleForces(data, numberOfAtoms, posq, atomParameters, forces, boxSize, invBoxSize); } -void CpuCustomGBForce::calculateSingleParticleValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters) { - for (int i = data.firstAtom; i < data.lastAtom; i++) { - data.expressionSet.setVariable(data.xindex, posq[4*i]); - data.expressionSet.setVariable(data.yindex, posq[4*i+1]); - data.expressionSet.setVariable(data.zindex, posq[4*i+2]); - for (int j = 0; j < (int) paramNames.size(); j++) - data.expressionSet.setVariable(data.paramIndex[j], atomParameters[i][j]); - for (int j = 0; j < index; j++) - data.expressionSet.setVariable(data.valueIndex[j], values[j][i]); - values[index][i] = (float) data.valueExpressions[index].evaluate(); - } -} - void CpuCustomGBForce::calculateParticlePairValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize) { for (int i = 0; i < numAtoms; i++) -- GitLab From 4c8750ada17eaab36320ca428120e8d9beb4318e Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 7 Oct 2014 16:56:32 -0700 Subject: [PATCH 047/338] More optimizations to CpuCustomGBForce --- platforms/cpu/include/CpuCustomGBForce.h | 2 +- platforms/cpu/src/CpuCustomGBForce.cpp | 35 +++++++++++++----------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/platforms/cpu/include/CpuCustomGBForce.h b/platforms/cpu/include/CpuCustomGBForce.h index 685098fa2..47fb3829f 100644 --- a/platforms/cpu/include/CpuCustomGBForce.h +++ b/platforms/cpu/include/CpuCustomGBForce.h @@ -46,7 +46,7 @@ private: bool periodic; const CpuNeighborList* neighborList; float periodicBoxSize[3]; - float cutoffDistance; + float cutoffDistance, cutoffDistance2; const std::vector > exclusions; std::vector valueNames; std::vector valueTypes; diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index 0ae114819..906c42cfe 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -137,6 +137,7 @@ CpuCustomGBForce::~CpuCustomGBForce() { void CpuCustomGBForce::setUseCutoff(float distance, const CpuNeighborList& neighbors) { cutoff = true; cutoffDistance = distance; + cutoffDistance2 = distance*distance; neighborList = &neighbors; } @@ -336,9 +337,9 @@ void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, Th fvec4 pos2(posq+4*atom2); float r2; getDeltaR(pos2, pos1, deltaR, r2, periodic, boxSize, invBoxSize); - float r = sqrtf(r2); - if (cutoff && r >= cutoffDistance) + if (cutoff && r2 >= cutoffDistance2) return; + float r = sqrtf(r2); for (int i = 0; i < (int) paramNames.size(); i++) { data.expressionSet.setVariable(data.particleParamIndex[i*2], atomParameters[atom1][i]); data.expressionSet.setVariable(data.particleParamIndex[i*2+1], atomParameters[atom2][i]); @@ -421,9 +422,9 @@ void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom fvec4 pos2(posq+4*atom2); float r2; getDeltaR(pos2, pos1, deltaR, r2, periodic, boxSize, invBoxSize); - float r = sqrtf(r2); - if (cutoff && r >= cutoffDistance) + if (cutoff && r2 >= cutoffDistance2) return; + float r = sqrtf(r2); // Record variables for evaluating expressions. @@ -530,16 +531,21 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, ThreadDat fvec4 pos2(posq+4*atom2); float r2; getDeltaR(pos2, pos1, deltaR, r2, periodic, boxSize, invBoxSize); - float r = sqrtf(r2); - if (cutoff && r >= cutoffDistance) + if (cutoff && r2 >= cutoffDistance2) return; + float r = sqrtf(r2); // Record variables for evaluating expressions. for (int i = 0; i < (int) paramNames.size(); i++) { data.expressionSet.setVariable(data.particleParamIndex[i*2], atomParameters[atom1][i]); data.expressionSet.setVariable(data.particleParamIndex[i*2+1], atomParameters[atom2][i]); + data.expressionSet.setVariable(data.paramIndex[i], atomParameters[atom1][i]); } + data.expressionSet.setVariable(data.valueIndex[0], values[0][atom1]); + data.expressionSet.setVariable(data.xindex, posq[4*atom1]); + data.expressionSet.setVariable(data.yindex, posq[4*atom1+1]); + data.expressionSet.setVariable(data.zindex, posq[4*atom1+2]); data.expressionSet.setVariable(data.rindex, r); data.expressionSet.setVariable(data.particleValueIndex[0], values[0][atom1]); data.expressionSet.setVariable(data.particleValueIndex[1], values[0][atom2]); @@ -548,20 +554,15 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, ThreadDat float rinv = 1/r; deltaR *= rinv; + fvec4 f1(0.0f), f2(0.0f); if (!isExcluded || valueTypes[0] != CustomGBForce::ParticlePair) { data.dVdR1[0] = (float) data.valueDerivExpressions[0][0].evaluate(); data.dVdR2[0] = -data.dVdR1[0]; - (fvec4(forces+4*atom1)-deltaR*(dEdV[0][atom1]*data.dVdR1[0])).store(forces+4*atom1); - (fvec4(forces+4*atom2)-deltaR*(dEdV[0][atom1]*data.dVdR2[0])).store(forces+4*atom2); + f1 -= deltaR*(dEdV[0][atom1]*data.dVdR1[0]); + f2 -= deltaR*(dEdV[0][atom1]*data.dVdR2[0]); } - for (int i = 0; i < (int) paramNames.size(); i++) - data.expressionSet.setVariable(data.paramIndex[i], atomParameters[atom1][i]); - data.expressionSet.setVariable(data.valueIndex[0], values[0][atom1]); for (int i = 1; i < (int) valueNames.size(); i++) { data.expressionSet.setVariable(data.valueIndex[i], values[i][atom1]); - data.expressionSet.setVariable(data.xindex, posq[4*atom1]); - data.expressionSet.setVariable(data.yindex, posq[4*atom1+1]); - data.expressionSet.setVariable(data.zindex, posq[4*atom1+2]); data.dVdR1[i] = 0.0; data.dVdR2[i] = 0.0; for (int j = 0; j < i; j++) { @@ -569,9 +570,11 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, ThreadDat data.dVdR1[i] += dVdV*data.dVdR1[j]; data.dVdR2[i] += dVdV*data.dVdR2[j]; } - (fvec4(forces+4*atom1)-deltaR*(dEdV[i][atom1]*data.dVdR1[i])).store(forces+4*atom1); - (fvec4(forces+4*atom2)-deltaR*(dEdV[i][atom1]*data.dVdR2[i])).store(forces+4*atom2); + f1 -= deltaR*(dEdV[i][atom1]*data.dVdR1[i]); + f2 -= deltaR*(dEdV[i][atom1]*data.dVdR2[i]); } + (fvec4(forces+4*atom1)+f1).store(forces+4*atom1); + (fvec4(forces+4*atom2)+f2).store(forces+4*atom2); } void CpuCustomGBForce::getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& deltaR, float& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { -- GitLab From 832e7f0456ece92c6520349d1966f90b1abcf84d Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 8 Oct 2014 15:45:19 -0700 Subject: [PATCH 048/338] CUDA platform does PME on a separate stream --- platforms/cuda/include/CudaContext.h | 13 +++++++++ platforms/cuda/include/CudaKernels.h | 4 +++ platforms/cuda/src/CudaArray.cpp | 6 ++-- platforms/cuda/src/CudaContext.cpp | 16 +++++++++-- platforms/cuda/src/CudaKernels.cpp | 41 ++++++++++++++++++++++++++-- 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/platforms/cuda/include/CudaContext.h b/platforms/cuda/include/CudaContext.h index cff8cf8d2..1052376f6 100644 --- a/platforms/cuda/include/CudaContext.h +++ b/platforms/cuda/include/CudaContext.h @@ -133,6 +133,18 @@ public: int getContextIndex() const { return contextIndex; } + /** + * Get the stream currently being used for execution. + */ + CUstream getCurrentStream(); + /** + * Set the stream to use for execution. + */ + void setCurrentStream(CUstream stream); + /** + * Reset the context to using the default stream for execution. + */ + void restoreDefaultStream(); /** * Get the array which contains the position (the xyz components) and charge (the w component) of each atom. */ @@ -521,6 +533,7 @@ private: std::map compilationDefines; CUcontext context; CUdevice device; + CUstream currentStream; CUfunction clearBufferKernel; CUfunction clearTwoBuffersKernel; CUfunction clearThreeBuffersKernel; diff --git a/platforms/cuda/include/CudaKernels.h b/platforms/cuda/include/CudaKernels.h index 7f913cd4b..201616afc 100644 --- a/platforms/cuda/include/CudaKernels.h +++ b/platforms/cuda/include/CudaKernels.h @@ -599,6 +599,8 @@ private: class PmeIO; class PmePreComputation; class PmePostComputation; + class SyncStreamPreComputation; + class SyncStreamPostComputation; CudaContext& cu; bool hasInitializedFFT; CudaArray* sigmaEpsilon; @@ -614,6 +616,8 @@ private: CudaSort* sort; Kernel cpuPme; PmeIO* pmeio; + CUstream pmeStream; + CUevent pmeSyncEvent; cufftHandle fftForward; cufftHandle fftBackward; CUfunction ewaldSumsKernel; diff --git a/platforms/cuda/src/CudaArray.cpp b/platforms/cuda/src/CudaArray.cpp index 948f80de0..d1625eef9 100644 --- a/platforms/cuda/src/CudaArray.cpp +++ b/platforms/cuda/src/CudaArray.cpp @@ -58,7 +58,7 @@ void CudaArray::upload(const void* data, bool blocking) { if (blocking) result = cuMemcpyHtoD(pointer, data, size*elementSize); else - result = cuMemcpyHtoDAsync(pointer, data, size*elementSize, 0); + result = cuMemcpyHtoDAsync(pointer, data, size*elementSize, context.getCurrentStream()); if (result != CUDA_SUCCESS) { std::stringstream str; str<<"Error uploading array "<compiler = "\""+compiler+"\""; @@ -507,6 +507,18 @@ CUfunction CudaContext::getKernel(CUmodule& module, const string& name) { return function; } +CUstream CudaContext::getCurrentStream() { + return currentStream; +} + +void CudaContext::setCurrentStream(CUstream stream) { + currentStream = stream; +} + +void CudaContext::restoreDefaultStream() { + setCurrentStream(0); +} + string CudaContext::doubleToString(double value) { stringstream s; s.precision(useDoublePrecision ? 16 : 8); @@ -575,7 +587,7 @@ void CudaContext::executeKernel(CUfunction kernel, void** arguments, int threads if (blockSize == -1) blockSize = ThreadBlockSize; int gridSize = std::min((threads+blockSize-1)/blockSize, numThreadBlocks); - CUresult result = cuLaunchKernel(kernel, gridSize, 1, 1, blockSize, 1, 1, sharedSize, 0, arguments, NULL); + CUresult result = cuLaunchKernel(kernel, gridSize, 1, 1, blockSize, 1, 1, sharedSize, currentStream, arguments, NULL); if (result != CUDA_SUCCESS) { stringstream str; str<<"Error invoking kernel: "<getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; cu.executeKernel(pmeGridIndexKernel, gridIndexArgs, cu.getNumAtoms()); @@ -1788,7 +1824,8 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF void* interpolateArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &directPmeGrid->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeInterpolateForceKernel, interpolateArgs, cu.getNumAtoms(), 128); - + cuEventRecord(pmeSyncEvent, pmeStream); + cu.restoreDefaultStream(); } double energy = (includeReciprocal ? ewaldSelfEnergy : 0.0); if (dispersionCoefficient != 0.0 && includeDirect) { -- GitLab From 94aa8c3fc35b3fa361302e504e8624c28ab8e2a2 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 8 Oct 2014 16:22:05 -0700 Subject: [PATCH 049/338] OpenCL platform does PME on a separate stream --- platforms/opencl/include/OpenCLContext.h | 16 +++++++---- platforms/opencl/include/OpenCLKernels.h | 4 +++ platforms/opencl/src/OpenCLContext.cpp | 19 +++++++++++-- platforms/opencl/src/OpenCLKernels.cpp | 35 ++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/platforms/opencl/include/OpenCLContext.h b/platforms/opencl/include/OpenCLContext.h index 9496994b1..18d33184c 100644 --- a/platforms/opencl/include/OpenCLContext.h +++ b/platforms/opencl/include/OpenCLContext.h @@ -211,11 +211,17 @@ public: return contextIndex; } /** - * Get the cl::CommandQueue associated with this object. + * Get the cl::CommandQueue currently being used for execution. */ - cl::CommandQueue& getQueue() { - return queue; - } + cl::CommandQueue& getQueue(); + /** + * Set the cl::ComandQueue to use for execution. + */ + void setQueue(cl::CommandQueue& queue); + /** + * Reset the context to using the default queue for execution. + */ + void restoreDefaultQueue(); /** * Get the array which contains the position (the xyz components) and charge (the w component) of each atom. */ @@ -629,7 +635,7 @@ private: std::map compilationDefines; cl::Context context; cl::Device device; - cl::CommandQueue queue; + cl::CommandQueue defaultQueue, currentQueue; cl::Kernel clearBufferKernel; cl::Kernel clearTwoBuffersKernel; cl::Kernel clearThreeBuffersKernel; diff --git a/platforms/opencl/include/OpenCLKernels.h b/platforms/opencl/include/OpenCLKernels.h index 0725f64b3..202c0af8f 100644 --- a/platforms/opencl/include/OpenCLKernels.h +++ b/platforms/opencl/include/OpenCLKernels.h @@ -599,6 +599,8 @@ private: class PmeIO; class PmePreComputation; class PmePostComputation; + class SyncQueuePreComputation; + class SyncQueuePostComputation; OpenCLContext& cl; bool hasInitializedKernel; OpenCLArray* sigmaEpsilon; @@ -613,6 +615,8 @@ private: OpenCLArray* pmeAtomRange; OpenCLArray* pmeAtomGridIndex; OpenCLSort* sort; + cl::CommandQueue pmeQueue; + cl::Event pmeSyncEvent; OpenCLFFT3D* fft; Kernel cpuPme; PmeIO* pmeio; diff --git a/platforms/opencl/src/OpenCLContext.cpp b/platforms/opencl/src/OpenCLContext.cpp index a111288b5..50d380c4c 100644 --- a/platforms/opencl/src/OpenCLContext.cpp +++ b/platforms/opencl/src/OpenCLContext.cpp @@ -248,7 +248,8 @@ OpenCLContext::OpenCLContext(const System& system, int platformIndex, int device contextDevices.push_back(device); cl_context_properties cprops[] = {CL_CONTEXT_PLATFORM, (cl_context_properties) platforms[bestPlatform](), 0}; context = cl::Context(contextDevices, cprops, errorCallback); - queue = cl::CommandQueue(context, device); + defaultQueue = cl::CommandQueue(context, device); + currentQueue = defaultQueue; numAtoms = system.getNumParticles(); paddedNumAtoms = TileSize*((numAtoms+TileSize-1)/TileSize); numAtomBlocks = (paddedNumAtoms+(TileSize-1))/TileSize; @@ -414,7 +415,7 @@ void OpenCLContext::initialize() { addAutoclearBuffer(*energyBuffer); int bufferBytes = max(velm->getSize()*velm->getElementSize(), energyBuffer->getSize()*energyBuffer->getElementSize()); pinnedBuffer = new cl::Buffer(context, CL_MEM_ALLOC_HOST_PTR, bufferBytes); - pinnedMemory = queue.enqueueMapBuffer(*pinnedBuffer, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, bufferBytes); + pinnedMemory = currentQueue.enqueueMapBuffer(*pinnedBuffer, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, bufferBytes); for (int i = 0; i < numAtoms; i++) { double mass = system.getParticleMass(i); if (useDoublePrecision || useMixedPrecision) @@ -514,6 +515,18 @@ cl::Program OpenCLContext::createProgram(const string source, const map events; +}; + +class OpenCLCalcNonbondedForceKernel::SyncQueuePostComputation : public OpenCLContext::ForcePostComputation { +public: + SyncQueuePostComputation(OpenCLContext& cl, cl::Event& event) : cl(cl), event(event), events(1) { + } + double computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) { + events[0] = event; + cl.getQueue().enqueueWaitForEvents(events); + return 0.0; + } +private: + OpenCLContext& cl; + cl::Event& event; + vector events; +}; + OpenCLCalcNonbondedForceKernel::~OpenCLCalcNonbondedForceKernel() { if (sigmaEpsilon != NULL) delete sigmaEpsilon; @@ -1574,6 +1603,9 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb pmeAtomGridIndex = OpenCLArray::create(cl, numParticles, "pmeAtomGridIndex"); sort = new OpenCLSort(cl, new SortTrait(), cl.getNumAtoms()); fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ); + pmeQueue = cl::CommandQueue(cl.getContext(), cl.getDevice()); + cl.addPreComputation(new SyncQueuePreComputation(cl, pmeQueue)); + cl.addPostComputation(new SyncQueuePostComputation(cl, pmeSyncEvent)); // Initialize the b-spline moduli. @@ -1753,6 +1785,7 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ cl.executeKernel(ewaldForcesKernel, cl.getNumAtoms()); } if (pmeGrid != NULL && includeReciprocal) { + cl.setQueue(pmeQueue); setPeriodicBoxSizeArg(cl, pmeUpdateBsplinesKernel, 4); setInvPeriodicBoxSizeArg(cl, pmeUpdateBsplinesKernel, 5); cl.executeKernel(pmeUpdateBsplinesKernel, cl.getNumAtoms()); @@ -1795,6 +1828,8 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ cl.executeKernel(pmeInterpolateForceKernel, 2*cl.getDevice().getInfo(), 1); else cl.executeKernel(pmeInterpolateForceKernel, cl.getNumAtoms()); + pmeQueue.enqueueMarker(&pmeSyncEvent); + cl.restoreDefaultQueue(); } double energy = (includeReciprocal ? ewaldSelfEnergy : 0.0); if (dispersionCoefficient != 0.0 && includeDirect) { -- GitLab From 19841146711070cfdde08fc533532234fc5d2857 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 9 Oct 2014 10:16:13 -0700 Subject: [PATCH 050/338] Bug fix --- platforms/cuda/src/CudaKernels.cpp | 22 +++++++++++++++------- platforms/opencl/src/OpenCLKernels.cpp | 25 +++++++++++++++++-------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 63f89c8ed..228349618 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1400,27 +1400,32 @@ private: class CudaCalcNonbondedForceKernel::SyncStreamPreComputation : public CudaContext::ForcePreComputation { public: - SyncStreamPreComputation(CUstream stream, CUevent event) : stream(stream), event(event) { + SyncStreamPreComputation(CUstream stream, CUevent event, int forceGroup) : stream(stream), event(event), forceGroup(forceGroup) { } void computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) { - cuEventRecord(event, 0); - cuStreamWaitEvent(stream, event, 0); + if ((groups&(1< events; + int forceGroup; }; class OpenCLCalcNonbondedForceKernel::SyncQueuePostComputation : public OpenCLContext::ForcePostComputation { public: - SyncQueuePostComputation(OpenCLContext& cl, cl::Event& event) : cl(cl), event(event), events(1) { + SyncQueuePostComputation(OpenCLContext& cl, cl::Event& event, int forceGroup) : cl(cl), event(event), events(1), forceGroup(forceGroup) { } double computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) { - events[0] = event; - cl.getQueue().enqueueWaitForEvents(events); + if ((groups&(1< events; + int forceGroup; }; OpenCLCalcNonbondedForceKernel::~OpenCLCalcNonbondedForceKernel() { @@ -1604,8 +1610,11 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb sort = new OpenCLSort(cl, new SortTrait(), cl.getNumAtoms()); fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ); pmeQueue = cl::CommandQueue(cl.getContext(), cl.getDevice()); - cl.addPreComputation(new SyncQueuePreComputation(cl, pmeQueue)); - cl.addPostComputation(new SyncQueuePostComputation(cl, pmeSyncEvent)); + int recipForceGroup = force.getReciprocalSpaceForceGroup(); + if (recipForceGroup < 0) + recipForceGroup = force.getForceGroup(); + cl.addPreComputation(new SyncQueuePreComputation(cl, pmeQueue, recipForceGroup)); + cl.addPostComputation(new SyncQueuePostComputation(cl, pmeSyncEvent, recipForceGroup)); // Initialize the b-spline moduli. -- GitLab From 86d09347a43b27fef765741ce4174ce8e6f861e1 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 9 Oct 2014 14:40:33 -0700 Subject: [PATCH 051/338] Deleted obsolete files --- libraries/asmjit/contrib/winremoteruntime.cpp | 79 ------------------- libraries/asmjit/contrib/winremoteruntime.h | 74 ----------------- 2 files changed, 153 deletions(-) delete mode 100644 libraries/asmjit/contrib/winremoteruntime.cpp delete mode 100644 libraries/asmjit/contrib/winremoteruntime.h diff --git a/libraries/asmjit/contrib/winremoteruntime.cpp b/libraries/asmjit/contrib/winremoteruntime.cpp deleted file mode 100644 index 3a2fe53c5..000000000 --- a/libraries/asmjit/contrib/winremoteruntime.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// [AsmJit/WinRemoteRuntime] -// Contribution for remote process handling. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Export] -#define ASMJIT_EXPORTS - -// [Dependencies - AsmJit] -#include "../base.h" - -// [Guard - Windows] -#if defined(ASMJIT_OS_WINDOWS) -#include "winremoteruntime.h" - -namespace asmjit { -namespace contrib { - -// ============================================================================ -// [asmjit::contrib::WinRemoteRuntime - Construction / Destruction] -// ============================================================================ - -WinRemoteRuntime::WinRemoteRuntime(HANDLE hProcess) : - _memMgr(hProcess) { - - // We are patching another process so enable keep-virtual-memory option. - _memMgr.setKeepVirtualMemory(true); -} - -WinRemoteRuntime::~WinRemoteRuntime() {} - -// ============================================================================ -// [asmjit::contrib::WinRemoteRuntime - Interface] -// ============================================================================ - -uint32_t WinRemoteRuntime::add(void** dest, BaseAssembler* assembler) { - // Disallow generation of no code. - size_t codeSize = assembler->getCodeSize(); - if (codeSize == 0) { - *dest = NULL; - return kErrorInvalidState; - } - - // Allocate temporary memory where the code will be stored and relocated. - void* codeData = ASMJIT_ALLOC(codeSize); - if (codeData == NULL) { - *dest = NULL; - return kErrorNoHeapMemory; - } - - // Allocate a permanent remote process memory. - void* processMemPtr = _memMgr.alloc(codeSize, kVMemAllocPermanent); - if (processMemPtr == NULL) { - ASMJIT_FREE(codeData); - *dest = NULL; - return kErrorNoVirtualMemory; - } - - // Relocate and write the code to the process memory. - assembler->relocCode(codeData, (uintptr_t)processMemPtr); - - ::WriteProcessMemory(getProcessHandle(), processMemPtr, codeData, codeSize, NULL); - ASMJIT_FREE(codeData); - - *dest = processMemPtr; - return kErrorOk; -} - -// NOP. -Error WinRemoteRuntime::release(void* p) { - return kErrorOk; -} - -} // contrib namespace -} // asmjit namespace - -// [Guard - Windows] -#endif // ASMJIT_OS_WINDOWS diff --git a/libraries/asmjit/contrib/winremoteruntime.h b/libraries/asmjit/contrib/winremoteruntime.h deleted file mode 100644 index da393444e..000000000 --- a/libraries/asmjit/contrib/winremoteruntime.h +++ /dev/null @@ -1,74 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in the package. - -// [Guard] -#ifndef _ASMJIT_CONTRIB_WINREMOTERUNTIME_H -#define _ASMJIT_CONTRIB_WINREMOTERUNTIME_H - -#include "../base.h" -#if defined(ASMJIT_OS_WINDOWS) - -namespace asmjit { -namespace contrib { - -//! \addtogroup asmjit_contrib -//! \{ - -// ============================================================================ -// [asmjit::contrib::WinRemoteRuntime] -// ============================================================================ - -//! WinRemoteRuntime can be used to inject code to a remote process. -struct WinRemoteRuntime : public Runtime { - ASMJIT_NO_COPY(WinRemoteRuntime) - - // -------------------------------------------------------------------------- - // [Construction / Destruction] - // -------------------------------------------------------------------------- - - //! Create a `WinRemoteRuntime` instance for a given `hProcess`. - ASMJIT_API WinRemoteRuntime(HANDLE hProcess); - - //! Destroy the `WinRemoteRuntime` instance. - ASMJIT_API virtual ~WinRemoteRuntime(); - - // -------------------------------------------------------------------------- - // [Accessors] - // -------------------------------------------------------------------------- - - //! Get the remote process handle. - ASMJIT_INLINE HANDLE getProcessHandle() const { - return _memMgr.getProcessHandle(); - } - - //! Get the remote memory manager. - ASMJIT_INLINE VMemMgr* getMemMgr() const { - return const_cast(&_memMgr); - } - - // -------------------------------------------------------------------------- - // [Interface] - // -------------------------------------------------------------------------- - - ASMJIT_API virtual uint32_t add(void** dest, BaseAssembler* assembler); - ASMJIT_API virtual Error release(void* p); - - // -------------------------------------------------------------------------- - // [Members] - // -------------------------------------------------------------------------- - - //! Remove memory manager. - VMemMgr _memMgr; -}; - -//! \} - -} // contrib namespace -} // asmjit namespace - -// [Guard] -#endif // ASMJIT_OS_WINDOWS -#endif // _ASMJIT_CONTRIB_WINREMOTERUNTIME_H -- GitLab From 3d1b2186ec877ada64879adcabb10cfd7a0d7226 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 9 Oct 2014 15:40:50 -0700 Subject: [PATCH 052/338] Further optimizations to NonbondedForce --- .../cuda/src/kernels/coulombLennardJones.cu | 15 +- platforms/cuda/src/kernels/nonbonded.cu | 194 ++++++++---------- platforms/opencl/include/OpenCLKernels.h | 2 +- platforms/opencl/src/OpenCLKernels.cpp | 25 ++- .../opencl/src/OpenCLNonbondedUtilities.cpp | 2 + .../opencl/src/kernels/coulombLennardJones.cl | 25 ++- platforms/opencl/src/kernels/nonbonded.cl | 12 +- 7 files changed, 136 insertions(+), 139 deletions(-) diff --git a/platforms/cuda/src/kernels/coulombLennardJones.cu b/platforms/cuda/src/kernels/coulombLennardJones.cu index 13352cc03..771b1a8a0 100644 --- a/platforms/cuda/src/kernels/coulombLennardJones.cu +++ b/platforms/cuda/src/kernels/coulombLennardJones.cu @@ -1,6 +1,7 @@ +{ #if USE_EWALD -bool needCorrection = hasExclusions && isExcluded && atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS; -if ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection) { + bool needCorrection = hasExclusions && isExcluded && atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS; + unsigned int includeInteraction = ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection); const real alphaR = EWALD_ALPHA*r; const real expAlphaRSqr = EXP(-alphaR*alphaR); const real prefactor = 138.935456f*posq1.w*posq2.w*invR; @@ -44,16 +45,14 @@ if ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection) { } #endif tempForce += prefactor*(erfcAlphaR+alphaR*expAlphaRSqr*TWO_OVER_SQRT_PI); - tempEnergy += ljEnergy + prefactor*erfcAlphaR; + tempEnergy += includeInteraction ? ljEnergy + prefactor*erfcAlphaR : 0; #else tempForce = prefactor*(erfcAlphaR+alphaR*expAlphaRSqr*TWO_OVER_SQRT_PI); - tempEnergy += prefactor*erfcAlphaR; + tempEnergy += includeInteraction ? prefactor*erfcAlphaR : 0; #endif } - dEdR += tempForce*invR*invR; -} + dEdR += includeInteraction ? tempForce*invR*invR : 0; #else -{ #ifdef USE_CUTOFF unsigned int includeInteraction = (!isExcluded && r2 < CUTOFF_SQUARED); #else @@ -91,5 +90,5 @@ if ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection) { #endif #endif dEdR += includeInteraction ? tempForce*invR*invR : 0; +#endif } -#endif \ No newline at end of file diff --git a/platforms/cuda/src/kernels/nonbonded.cu b/platforms/cuda/src/kernels/nonbonded.cu index a1b81fd21..0ae5e9958 100644 --- a/platforms/cuda/src/kernels/nonbonded.cu +++ b/platforms/cuda/src/kernels/nonbonded.cu @@ -228,57 +228,51 @@ extern "C" __global__ void computeNonbonded( delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; -#ifdef USE_CUTOFF - if (r2 < CUTOFF_SQUARED) { -#endif - real invR = RSQRT(r2); - real r = r2*invR; - LOAD_ATOM2_PARAMETERS - atom2 = y*TILE_SIZE+tj; + real invR = RSQRT(r2); + real r = r2*invR; + LOAD_ATOM2_PARAMETERS + atom2 = y*TILE_SIZE+tj; #ifdef USE_SYMMETRIC - real dEdR = 0.0f; + real dEdR = 0.0f; #else - real3 dEdR1 = make_real3(0); - real3 dEdR2 = make_real3(0); + real3 dEdR1 = make_real3(0); + real3 dEdR2 = make_real3(0); #endif #ifdef USE_EXCLUSIONS - bool isExcluded = (atom1 >= NUM_ATOMS || atom2 >= NUM_ATOMS || !(excl & 0x1)); + bool isExcluded = (atom1 >= NUM_ATOMS || atom2 >= NUM_ATOMS || !(excl & 0x1)); #endif - real tempEnergy = 0.0f; - COMPUTE_INTERACTION - energy += tempEnergy; + real tempEnergy = 0.0f; + COMPUTE_INTERACTION + energy += tempEnergy; #ifdef USE_SYMMETRIC - delta *= dEdR; - force.x -= delta.x; - force.y -= delta.y; - force.z -= delta.z; + delta *= dEdR; + force.x -= delta.x; + force.y -= delta.y; + force.z -= delta.z; #ifdef ENABLE_SHUFFLE - shflForce.x += delta.x; - shflForce.y += delta.y; - shflForce.z += delta.z; + shflForce.x += delta.x; + shflForce.y += delta.y; + shflForce.z += delta.z; #else - localData[tbx+tj].fx += delta.x; - localData[tbx+tj].fy += delta.y; - localData[tbx+tj].fz += delta.z; + localData[tbx+tj].fx += delta.x; + localData[tbx+tj].fy += delta.y; + localData[tbx+tj].fz += delta.z; #endif #else // !USE_SYMMETRIC - force.x -= dEdR1.x; - force.y -= dEdR1.y; - force.z -= dEdR1.z; + force.x -= dEdR1.x; + force.y -= dEdR1.y; + force.z -= dEdR1.z; #ifdef ENABLE_SHUFFLE - shflForce.x += dEdR2.x; - shflForce.y += dEdR2.y; - shflForce.z += dEdR2.z; + shflForce.x += dEdR2.x; + shflForce.y += dEdR2.y; + shflForce.z += dEdR2.z; #else - localData[tbx+tj].fx += dEdR2.x; - localData[tbx+tj].fy += dEdR2.y; - localData[tbx+tj].fz += dEdR2.z; + localData[tbx+tj].fx += dEdR2.x; + localData[tbx+tj].fy += dEdR2.y; + localData[tbx+tj].fz += dEdR2.z; #endif #endif // end USE_SYMMETRIC -#ifdef USE_CUTOFF - } -#endif #ifdef USE_EXCLUSIONS excl >>= 1; #endif @@ -431,53 +425,51 @@ extern "C" __global__ void computeNonbonded( #endif real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; - if (r2 < CUTOFF_SQUARED) { - real invR = RSQRT(r2); - real r = r2*invR; - LOAD_ATOM2_PARAMETERS - atom2 = atomIndices[tbx+tj]; + real invR = RSQRT(r2); + real r = r2*invR; + LOAD_ATOM2_PARAMETERS + atom2 = atomIndices[tbx+tj]; #ifdef USE_SYMMETRIC - real dEdR = 0.0f; + real dEdR = 0.0f; #else - real3 dEdR1 = make_real3(0); - real3 dEdR2 = make_real3(0); + real3 dEdR1 = make_real3(0); + real3 dEdR2 = make_real3(0); #endif #ifdef USE_EXCLUSIONS - bool isExcluded = (atom1 >= NUM_ATOMS || atom2 >= NUM_ATOMS); + bool isExcluded = (atom1 >= NUM_ATOMS || atom2 >= NUM_ATOMS); #endif - real tempEnergy = 0.0f; - COMPUTE_INTERACTION - energy += tempEnergy; + real tempEnergy = 0.0f; + COMPUTE_INTERACTION + energy += tempEnergy; #ifdef USE_SYMMETRIC - delta *= dEdR; - force.x -= delta.x; - force.y -= delta.y; - force.z -= delta.z; + delta *= dEdR; + force.x -= delta.x; + force.y -= delta.y; + force.z -= delta.z; #ifdef ENABLE_SHUFFLE - shflForce.x += delta.x; - shflForce.y += delta.y; - shflForce.z += delta.z; + shflForce.x += delta.x; + shflForce.y += delta.y; + shflForce.z += delta.z; #else - localData[tbx+tj].fx += delta.x; - localData[tbx+tj].fy += delta.y; - localData[tbx+tj].fz += delta.z; + localData[tbx+tj].fx += delta.x; + localData[tbx+tj].fy += delta.y; + localData[tbx+tj].fz += delta.z; #endif #else // !USE_SYMMETRIC - force.x -= dEdR1.x; - force.y -= dEdR1.y; - force.z -= dEdR1.z; + force.x -= dEdR1.x; + force.y -= dEdR1.y; + force.z -= dEdR1.z; #ifdef ENABLE_SHUFFLE - shflForce.x += dEdR2.x; - shflForce.y += dEdR2.y; - shflForce.z += dEdR2.z; + shflForce.x += dEdR2.x; + shflForce.y += dEdR2.y; + shflForce.z += dEdR2.z; #else - localData[tbx+tj].fx += dEdR2.x; - localData[tbx+tj].fy += dEdR2.y; - localData[tbx+tj].fz += dEdR2.z; + localData[tbx+tj].fx += dEdR2.x; + localData[tbx+tj].fy += dEdR2.y; + localData[tbx+tj].fz += dEdR2.z; #endif #endif // end USE_SYMMETRIC - } #ifdef ENABLE_SHUFFLE SHUFFLE_WARP_DATA #endif @@ -503,57 +495,51 @@ extern "C" __global__ void computeNonbonded( delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; -#ifdef USE_CUTOFF - if (r2 < CUTOFF_SQUARED) { -#endif - real invR = RSQRT(r2); - real r = r2*invR; - LOAD_ATOM2_PARAMETERS - atom2 = atomIndices[tbx+tj]; + real invR = RSQRT(r2); + real r = r2*invR; + LOAD_ATOM2_PARAMETERS + atom2 = atomIndices[tbx+tj]; #ifdef USE_SYMMETRIC - real dEdR = 0.0f; + real dEdR = 0.0f; #else - real3 dEdR1 = make_real3(0); - real3 dEdR2 = make_real3(0); + real3 dEdR1 = make_real3(0); + real3 dEdR2 = make_real3(0); #endif #ifdef USE_EXCLUSIONS - bool isExcluded = (atom1 >= NUM_ATOMS || atom2 >= NUM_ATOMS); + bool isExcluded = (atom1 >= NUM_ATOMS || atom2 >= NUM_ATOMS); #endif - real tempEnergy = 0.0f; - COMPUTE_INTERACTION - energy += tempEnergy; + real tempEnergy = 0.0f; + COMPUTE_INTERACTION + energy += tempEnergy; #ifdef USE_SYMMETRIC - delta *= dEdR; - force.x -= delta.x; - force.y -= delta.y; - force.z -= delta.z; + delta *= dEdR; + force.x -= delta.x; + force.y -= delta.y; + force.z -= delta.z; #ifdef ENABLE_SHUFFLE - shflForce.x += delta.x; - shflForce.y += delta.y; - shflForce.z += delta.z; + shflForce.x += delta.x; + shflForce.y += delta.y; + shflForce.z += delta.z; #else - localData[tbx+tj].fx += delta.x; - localData[tbx+tj].fy += delta.y; - localData[tbx+tj].fz += delta.z; + localData[tbx+tj].fx += delta.x; + localData[tbx+tj].fy += delta.y; + localData[tbx+tj].fz += delta.z; #endif #else // !USE_SYMMETRIC - force.x -= dEdR1.x; - force.y -= dEdR1.y; - force.z -= dEdR1.z; + force.x -= dEdR1.x; + force.y -= dEdR1.y; + force.z -= dEdR1.z; #ifdef ENABLE_SHUFFLE - shflForce.x += dEdR2.x; - shflForce.y += dEdR2.y; - shflForce.z += dEdR2.z; + shflForce.x += dEdR2.x; + shflForce.y += dEdR2.y; + shflForce.z += dEdR2.z; #else - localData[tbx+tj].fx += dEdR2.x; - localData[tbx+tj].fy += dEdR2.y; - localData[tbx+tj].fz += dEdR2.z; + localData[tbx+tj].fx += dEdR2.x; + localData[tbx+tj].fy += dEdR2.y; + localData[tbx+tj].fz += dEdR2.z; #endif #endif // end USE_SYMMETRIC -#ifdef USE_CUTOFF - } -#endif #ifdef ENABLE_SHUFFLE SHUFFLE_WARP_DATA #endif diff --git a/platforms/opencl/include/OpenCLKernels.h b/platforms/opencl/include/OpenCLKernels.h index 202c0af8f..3a793bcfd 100644 --- a/platforms/opencl/include/OpenCLKernels.h +++ b/platforms/opencl/include/OpenCLKernels.h @@ -633,7 +633,7 @@ private: std::map pmeDefines; std::vector > exceptionAtoms; double ewaldSelfEnergy, dispersionCoefficient, alpha; - bool hasCoulomb, hasLJ; + bool hasCoulomb, hasLJ, usePmeQueue; static const int PmeOrder = 5; }; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index b943e20d1..b55d591ea 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1609,12 +1609,16 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb pmeAtomGridIndex = OpenCLArray::create(cl, numParticles, "pmeAtomGridIndex"); sort = new OpenCLSort(cl, new SortTrait(), cl.getNumAtoms()); fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ); - pmeQueue = cl::CommandQueue(cl.getContext(), cl.getDevice()); - int recipForceGroup = force.getReciprocalSpaceForceGroup(); - if (recipForceGroup < 0) - recipForceGroup = force.getForceGroup(); - cl.addPreComputation(new SyncQueuePreComputation(cl, pmeQueue, recipForceGroup)); - cl.addPostComputation(new SyncQueuePostComputation(cl, pmeSyncEvent, recipForceGroup)); + string vendor = cl.getDevice().getInfo(); + usePmeQueue = (vendor.size() >= 6 && vendor.substr(0, 6) == "NVIDIA"); + if (usePmeQueue) { + pmeQueue = cl::CommandQueue(cl.getContext(), cl.getDevice()); + int recipForceGroup = force.getReciprocalSpaceForceGroup(); + if (recipForceGroup < 0) + recipForceGroup = force.getForceGroup(); + cl.addPreComputation(new SyncQueuePreComputation(cl, pmeQueue, recipForceGroup)); + cl.addPostComputation(new SyncQueuePostComputation(cl, pmeSyncEvent, recipForceGroup)); + } // Initialize the b-spline moduli. @@ -1794,7 +1798,8 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ cl.executeKernel(ewaldForcesKernel, cl.getNumAtoms()); } if (pmeGrid != NULL && includeReciprocal) { - cl.setQueue(pmeQueue); + if (usePmeQueue) + cl.setQueue(pmeQueue); setPeriodicBoxSizeArg(cl, pmeUpdateBsplinesKernel, 4); setInvPeriodicBoxSizeArg(cl, pmeUpdateBsplinesKernel, 5); cl.executeKernel(pmeUpdateBsplinesKernel, cl.getNumAtoms()); @@ -1837,8 +1842,10 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ cl.executeKernel(pmeInterpolateForceKernel, 2*cl.getDevice().getInfo(), 1); else cl.executeKernel(pmeInterpolateForceKernel, cl.getNumAtoms()); - pmeQueue.enqueueMarker(&pmeSyncEvent); - cl.restoreDefaultQueue(); + if (usePmeQueue) { + pmeQueue.enqueueMarker(&pmeSyncEvent); + cl.restoreDefaultQueue(); + } } double energy = (includeReciprocal ? ewaldSelfEnergy : 0.0); if (dispersionCoefficient != 0.0 && includeDirect) { diff --git a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp index 9af165f2b..3baa36ea9 100644 --- a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp +++ b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp @@ -573,6 +573,8 @@ cl::Kernel OpenCLNonbondedUtilities::createInteractionKernel(const string& sourc defines["USE_EXCLUSIONS"] = "1"; if (isSymmetric) defines["USE_SYMMETRIC"] = "1"; + if (useCutoff && context.getSIMDWidth() < 32) + defines["PRUNE_BY_CUTOFF"] = "1"; defines["FORCE_WORK_GROUP_SIZE"] = context.intToString(forceThreadBlockSize); defines["CUTOFF_SQUARED"] = context.doubleToString(cutoff*cutoff); defines["CUTOFF"] = context.doubleToString(cutoff); diff --git a/platforms/opencl/src/kernels/coulombLennardJones.cl b/platforms/opencl/src/kernels/coulombLennardJones.cl index adf739b97..63aeb4147 100644 --- a/platforms/opencl/src/kernels/coulombLennardJones.cl +++ b/platforms/opencl/src/kernels/coulombLennardJones.cl @@ -1,6 +1,12 @@ +{ +#ifdef USE_DOUBLE_PRECISION + unsigned long includeInteraction; +#else + unsigned int includeInteraction; +#endif #if USE_EWALD -bool needCorrection = hasExclusions && isExcluded && atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS; -if ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection) { + bool needCorrection = hasExclusions && isExcluded && atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS; + includeInteraction = ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection); const real alphaR = EWALD_ALPHA*r; const real expAlphaRSqr = EXP(-alphaR*alphaR); const real prefactor = 138.935456f*posq1.w*posq2.w*invR; @@ -44,21 +50,14 @@ if ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection) { } #endif tempForce += prefactor*(erfcAlphaR+alphaR*expAlphaRSqr*TWO_OVER_SQRT_PI); - tempEnergy += ljEnergy + prefactor*erfcAlphaR; + tempEnergy += select((real) 0, ljEnergy + prefactor*erfcAlphaR, includeInteraction); #else tempForce = prefactor*(erfcAlphaR+alphaR*expAlphaRSqr*TWO_OVER_SQRT_PI); - tempEnergy += prefactor*erfcAlphaR; + tempEnergy += select((real) 0, prefactor*erfcAlphaR, includeInteraction); #endif } - dEdR += tempForce*invR*invR; -} -#else -{ -#ifdef USE_DOUBLE_PRECISION - unsigned long includeInteraction; + dEdR += select((real) 0, tempForce*invR*invR, includeInteraction); #else - unsigned int includeInteraction; -#endif #ifdef USE_CUTOFF includeInteraction = (!isExcluded && r2 < CUTOFF_SQUARED); #else @@ -97,5 +96,5 @@ if ((!isExcluded && r2 < CUTOFF_SQUARED) || needCorrection) { #endif #endif dEdR += select((real) 0, tempForce*invR*invR, includeInteraction); +#endif } -#endif \ No newline at end of file diff --git a/platforms/opencl/src/kernels/nonbonded.cl b/platforms/opencl/src/kernels/nonbonded.cl index 9f4f8edf2..ed6ef0793 100644 --- a/platforms/opencl/src/kernels/nonbonded.cl +++ b/platforms/opencl/src/kernels/nonbonded.cl @@ -124,7 +124,7 @@ __kernel void computeNonbonded( delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; -#ifdef USE_CUTOFF +#ifdef PRUNE_BY_CUTOFF if (r2 < CUTOFF_SQUARED) { #endif real invR = RSQRT(r2); @@ -155,7 +155,7 @@ __kernel void computeNonbonded( localData[tbx+tj].fy += dEdR2.y; localData[tbx+tj].fz += dEdR2.z; #endif -#ifdef USE_CUTOFF +#ifdef PRUNE_BY_CUTOFF } #endif #ifdef USE_EXCLUSIONS @@ -295,7 +295,9 @@ __kernel void computeNonbonded( real4 posq2 = (real4) (localData[atom2].x, localData[atom2].y, localData[atom2].z, localData[atom2].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; +#ifdef PRUNE_BY_CUTOFF if (r2 < CUTOFF_SQUARED) { +#endif real invR = RSQRT(r2); real r = r2*invR; LOAD_ATOM2_PARAMETERS @@ -324,7 +326,9 @@ __kernel void computeNonbonded( localData[tbx+tj].fy += dEdR2.y; localData[tbx+tj].fz += dEdR2.z; #endif +#ifdef PRUNE_BY_CUTOFF } +#endif tj = (tj + 1) & (TILE_SIZE - 1); SYNC_WARPS; } @@ -343,7 +347,7 @@ __kernel void computeNonbonded( delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; -#ifdef USE_CUTOFF +#ifdef PRUNE_BY_CUTOFF if (r2 < CUTOFF_SQUARED) { #endif real invR = RSQRT(r2); @@ -374,7 +378,7 @@ __kernel void computeNonbonded( localData[tbx+tj].fy += dEdR2.y; localData[tbx+tj].fz += dEdR2.z; #endif -#ifdef USE_CUTOFF +#ifdef PRUNE_BY_CUTOFF } #endif tj = (tj + 1) & (TILE_SIZE - 1); -- GitLab From 87dd382319ae17a6373820ed401b3d897f1c5a88 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 10 Oct 2014 12:10:35 -0700 Subject: [PATCH 053/338] Optimizations to AMOEBA --- .../cuda/src/kernels/multipoleInducedField.cu | 18 +++++++----------- .../src/kernels/pmeElectrostaticPairForce.cu | 7 ++----- .../pmeElectrostaticPairForceNoQuadrupoles.cu | 7 ++----- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu index f58cd90fd..a1242f42e 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu @@ -87,17 +87,13 @@ __device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, real3 de real scale3 = 1; real scale5 = 1; real damp = atom1.damp*atom2.damp; - if (damp != 0) { - real ratio = (r/damp); - ratio = ratio*ratio*ratio; - float pgamma = atom1.thole < atom2.thole ? atom1.thole : atom2.thole; - damp = -pgamma*ratio; - if (damp > -50) { - real expdamp = EXP(damp); - scale3 = 1 - expdamp; - scale5 = 1 - expdamp*(1-damp); - } - } + real ratio = (r/damp); + ratio = ratio*ratio*ratio; + float pgamma = atom1.thole < atom2.thole ? atom1.thole : atom2.thole; + damp = damp == 0 ? 0 : -pgamma*ratio; + real expdamp = EXP(damp); + scale3 = 1 - expdamp; + scale5 = 1 - expdamp*(1-damp); real dsc3 = scale3; real dsc5 = scale5; real r3 = (r*r2); diff --git a/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForce.cu b/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForce.cu index 2c094f8a5..71358a730 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForce.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForce.cu @@ -211,7 +211,6 @@ computeOneInteractionF2NoScale( real pgamma = atom1.thole < atom2.thole ? atom1.thole : atom2.thole; real ratio = RECIP(rr1*damp); damp = -pgamma*ratio*ratio*ratio; - damp = damp < -50 ? 0 : damp; } real scale5 = (damp == 0) ? 1 : (1 - (1-damp)*EXP(damp)); @@ -358,8 +357,7 @@ computeOneInteractionF2NoScale( ftm22 += gfi1*yr; ftm23 += gfi1*zr; - if (damp != 0) { - + { real expdamp = EXP(damp); real temp3 = -1.5f*damp*expdamp*rr1*rr1; real temp5 = -damp; @@ -556,8 +554,7 @@ computeOneInteractionF2NoScale( ftm22 += gfi1*yr; ftm23 += gfi1*zr; - if (damp != 0) { - + { real expdamp = EXP(damp); real temp3 = -1.5f*damp*expdamp*rr1*rr1; real temp5 = -damp; diff --git a/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForceNoQuadrupoles.cu b/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForceNoQuadrupoles.cu index 3104e34a7..380f63a6d 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForceNoQuadrupoles.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/pmeElectrostaticPairForceNoQuadrupoles.cu @@ -129,7 +129,6 @@ computeOneInteractionF2NoScale( real pgamma = atom1.thole < atom2.thole ? atom1.thole : atom2.thole; real ratio = RECIP(rr1*damp); damp = -pgamma*ratio*ratio*ratio; - damp = damp < -50 ? 0 : damp; } real scale5 = (damp == 0) ? 1 : (1 - (1-damp)*EXP(damp)); @@ -232,8 +231,7 @@ computeOneInteractionF2NoScale( ftm22 += gfi1*yr; ftm23 += gfi1*zr; - if (damp != 0) { - + { real expdamp = EXP(damp); real temp3 = -1.5f*damp*expdamp*rr1*rr1; real temp5 = -damp; @@ -376,8 +374,7 @@ computeOneInteractionF2NoScale( ftm22 += gfi1*yr; ftm23 += gfi1*zr; - if (damp != 0) { - + { real expdamp = EXP(damp); real temp3 = -1.5f*damp*expdamp*rr1*rr1; real temp5 = -damp; -- GitLab From 34a604b8f3ef3c0b3036d0882d829bd14360fa3b Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 13 Oct 2014 11:21:04 -0700 Subject: [PATCH 054/338] GBSAOBCForce allows the surface area energy to be changed --- docs-source/usersguide/theory.rst | 6 ++-- openmmapi/include/openmm/GBSAOBCForce.h | 14 +++++++- openmmapi/src/GBSAOBCForce.cpp | 2 +- platforms/cpu/include/CpuGBSAOBCForce.h | 7 +++- platforms/cpu/src/CpuGBSAOBCForce.cpp | 5 ++- platforms/cpu/src/CpuKernels.cpp | 1 + platforms/cpu/tests/TestCpuGBSAOBCForce.cpp | 36 ++++++++++++++++--- platforms/cuda/include/CudaKernels.h | 2 +- platforms/cuda/src/CudaKernels.cpp | 2 ++ platforms/cuda/src/kernels/gbsaObc1.cu | 1 - platforms/cuda/src/kernels/nonbonded.cu | 9 +++++ platforms/cuda/tests/TestCudaGBSAOBCForce.cpp | 35 +++++++++++++++--- platforms/opencl/include/OpenCLKernels.h | 2 +- platforms/opencl/src/OpenCLKernels.cpp | 2 ++ .../opencl/src/kernels/gbsaObcReductions.cl | 1 - platforms/opencl/src/kernels/nonbonded.cl | 5 +++ .../opencl/tests/TestOpenCLGBSAOBCForce.cpp | 35 +++++++++++++++--- platforms/reference/include/ObcParameters.h | 8 +++++ platforms/reference/src/ReferenceKernels.cpp | 1 + .../reference/src/gbsa/ObcParameters.cpp | 3 ++ .../tests/TestReferenceGBSAOBCForce.cpp | 34 ++++++++++++++++-- 21 files changed, 185 insertions(+), 26 deletions(-) diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index 4b76dd3d9..6322a18ae 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -489,12 +489,12 @@ The surface area term is given by\ :cite:`Schaefer1998`\ :cite:`Ponder` .. math:: - E=4\pi \cdot 2\text{.}\text{26}\sum _{i}{\left({r}_{i}+{r}_{\mathit{solvent}}\right)}^{2}{\left(\frac{{r}_{i}}{{R}_{i}}\right)}^{6} + E=E_{SA} \cdot 4\pi \sum _{i}{\left({r}_{i}+{r}_{\mathit{solvent}}\right)}^{2}{\left(\frac{{r}_{i}}{{R}_{i}}\right)}^{6} where :math:`r_i` is the atomic radius of particle *i*\ , :math:`r_i` is -its Born radius, and :math:`r_\mathit{solvent}` is the solvent radius, which is taken -to be 0.14 nm. +its atomic radius, and :math:`r_\mathit{solvent}` is the solvent radius, which is taken +to be 0.14 nm. The default value for the energy scale :math:`E_{SA}` is 2.25936 kJ/mol/nm\ :sup:`2`\ . AndersenThermostat diff --git a/openmmapi/include/openmm/GBSAOBCForce.h b/openmmapi/include/openmm/GBSAOBCForce.h index 0033d5e60..b5473e66b 100644 --- a/openmmapi/include/openmm/GBSAOBCForce.h +++ b/openmmapi/include/openmm/GBSAOBCForce.h @@ -138,6 +138,18 @@ public: void setSoluteDielectric(double dielectric) { soluteDielectric = dielectric; } + /** + * Get the energy scale for the surface energy term, measured in kJ/mol/nm^2. + */ + double getSurfaceAreaEnergy() const { + return surfaceAreaEnergy; + } + /** + * Set the energy scale for the surface energy term, measured in kJ/mol/nm^2. + */ + void setSurfaceAreaEnergy(double energy) { + surfaceAreaEnergy = energy; + } /** * Get the method used for handling long range nonbonded interactions. */ @@ -177,7 +189,7 @@ protected: private: class ParticleInfo; NonbondedMethod nonbondedMethod; - double cutoffDistance, solventDielectric, soluteDielectric; + double cutoffDistance, solventDielectric, soluteDielectric, surfaceAreaEnergy; std::vector particles; }; diff --git a/openmmapi/src/GBSAOBCForce.cpp b/openmmapi/src/GBSAOBCForce.cpp index f00c0ab12..b4a3bf577 100644 --- a/openmmapi/src/GBSAOBCForce.cpp +++ b/openmmapi/src/GBSAOBCForce.cpp @@ -37,7 +37,7 @@ using namespace OpenMM; -GBSAOBCForce::GBSAOBCForce() : nonbondedMethod(NoCutoff), cutoffDistance(1.0), solventDielectric(78.3), soluteDielectric(1.0) { +GBSAOBCForce::GBSAOBCForce() : nonbondedMethod(NoCutoff), cutoffDistance(1.0), solventDielectric(78.3), soluteDielectric(1.0), surfaceAreaEnergy(2.25936) { } int GBSAOBCForce::addParticle(double charge, double radius, double scalingFactor) { diff --git a/platforms/cpu/include/CpuGBSAOBCForce.h b/platforms/cpu/include/CpuGBSAOBCForce.h index a781fb352..b8276324f 100644 --- a/platforms/cpu/include/CpuGBSAOBCForce.h +++ b/platforms/cpu/include/CpuGBSAOBCForce.h @@ -66,6 +66,11 @@ public: */ void setSolventDielectric(float dielectric); + /** + * Set the surface area energy. + */ + void setSurfaceAreaEnergy(float energy); + /** * Get the per-particle parameters (offset radius, scaled radius). */ @@ -96,7 +101,7 @@ private: bool cutoff; bool periodic; float periodicBoxSize[3]; - float cutoffDistance, soluteDielectric, solventDielectric; + float cutoffDistance, soluteDielectric, solventDielectric, surfaceAreaFactor; std::vector > particleParams; AlignedArray bornRadii; std::vector > threadBornForces; diff --git a/platforms/cpu/src/CpuGBSAOBCForce.cpp b/platforms/cpu/src/CpuGBSAOBCForce.cpp index 3ed8e488d..8b6831f92 100644 --- a/platforms/cpu/src/CpuGBSAOBCForce.cpp +++ b/platforms/cpu/src/CpuGBSAOBCForce.cpp @@ -77,6 +77,10 @@ void CpuGBSAOBCForce::setSolventDielectric(float dielectric) { solventDielectric = dielectric; } +void CpuGBSAOBCForce::setSurfaceAreaEnergy(float energy) { + surfaceAreaFactor = 4*M_PI*energy; +} + const std::vector >& CpuGBSAOBCForce::getParticleParameters() const { return particleParams; } @@ -211,7 +215,6 @@ void CpuGBSAOBCForce::threadComputeForce(ThreadPool& threads, int threadIndex) { // Calculate ACE surface area term. const float probeRadius = 0.14f; - const float surfaceAreaFactor = 28.3919551; double energy = 0.0; AlignedArray& bornForces = threadBornForces[threadIndex]; for (int i = 0; i < numParticles; i++) diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 75200fef5..2aa3fd963 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -802,6 +802,7 @@ void CpuCalcGBSAOBCForceKernel::initialize(const System& system, const GBSAOBCFo obc.setParticleParameters(particleParams); obc.setSolventDielectric((float) force.getSolventDielectric()); obc.setSoluteDielectric((float) force.getSoluteDielectric()); + obc.setSurfaceAreaEnergy((float) force.getSurfaceAreaEnergy()); if (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff) obc.setUseCutoff((float) force.getCutoffDistance()); data.isPeriodic = (force.getNonbondedMethod() == GBSAOBCForce::CutoffPeriodic); diff --git a/platforms/cpu/tests/TestCpuGBSAOBCForce.cpp b/platforms/cpu/tests/TestCpuGBSAOBCForce.cpp index 8714328bd..972cfe003 100644 --- a/platforms/cpu/tests/TestCpuGBSAOBCForce.cpp +++ b/platforms/cpu/tests/TestCpuGBSAOBCForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2014 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -67,7 +67,7 @@ void testSingleParticle() { double eps0 = EPSILON0; double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric())/bornRadius; double extendedRadius = 0.15+0.14; // probe radius - double nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.15/bornRadius, 6.0); // Where did this formula come from? Just copied it from CpuImplicitSolvent.cpp + double nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); // Change the parameters and see if it is still correct. @@ -77,8 +77,35 @@ void testSingleParticle() { state = context.getState(State::Energy); bornRadius = 0.25-0.009; // dielectric offset bornEnergy = (-0.4*0.4/(8*PI_M*eps0))*(1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric())/bornRadius; - extendedRadius = bornRadius+0.14; - nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.25/bornRadius, 6.0); + extendedRadius = 0.25+0.14; + nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.25/bornRadius, 6.0); + ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); +} + +void testGlobalSettings() { + CpuPlatform platform; + System system; + system.addParticle(2.0); + LangevinIntegrator integrator(0, 0.1, 0.01); + GBSAOBCForce* forceField = new GBSAOBCForce(); + forceField->addParticle(0.5, 0.15, 1); + const double soluteDielectric = 2.1; + const double solventDielectric = 35.0; + const double surfaceAreaEnergy = 0.75; + forceField->setSoluteDielectric(soluteDielectric); + forceField->setSolventDielectric(solventDielectric); + forceField->setSurfaceAreaEnergy(surfaceAreaEnergy); + system.addForce(forceField); + Context context(system, integrator, platform); + vector positions(1); + positions[0] = Vec3(0, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Energy); + double bornRadius = 0.15-0.009; // dielectric offset + double eps0 = EPSILON0; + double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/soluteDielectric-1.0/solventDielectric)/bornRadius; + double extendedRadius = 0.15+0.14; // probe radius + double nonpolarEnergy = 4*PI_M*surfaceAreaEnergy*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); } @@ -228,6 +255,7 @@ int main() { return 0; } testSingleParticle(); + testGlobalSettings(); testCutoffAndPeriodic(); for (int i = 5; i < 11; i++) { testForce(i*i*i, NonbondedForce::NoCutoff, GBSAOBCForce::NoCutoff); diff --git a/platforms/cuda/include/CudaKernels.h b/platforms/cuda/include/CudaKernels.h index 201616afc..2d166ffc9 100644 --- a/platforms/cuda/include/CudaKernels.h +++ b/platforms/cuda/include/CudaKernels.h @@ -719,7 +719,7 @@ public: */ void copyParametersToContext(ContextImpl& context, const GBSAOBCForce& force); private: - double prefactor; + double prefactor, surfaceAreaFactor; bool hasCreatedKernels; int maxTiles; CudaContext& cu; diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 228349618..462868b59 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -2480,6 +2480,7 @@ void CudaCalcGBSAOBCForceKernel::initialize(const System& system, const GBSAOBCF posq.upload(&temp[0]); params->upload(paramsVector); prefactor = -ONE_4PI_EPS0*((1.0/force.getSoluteDielectric())-(1.0/force.getSolventDielectric())); + surfaceAreaFactor = -6.0*4*M_PI*force.getSurfaceAreaEnergy(); bool useCutoff = (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff); bool usePeriodic = (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff && force.getNonbondedMethod() != GBSAOBCForce::CutoffNonPeriodic); string source = CudaKernelSources::gbsaObc2; @@ -2506,6 +2507,7 @@ double CudaCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeFor defines["CUTOFF_SQUARED"] = cu.doubleToString(nb.getCutoffDistance()*nb.getCutoffDistance()); defines["CUTOFF"] = cu.doubleToString(nb.getCutoffDistance()); defines["PREFACTOR"] = cu.doubleToString(prefactor); + defines["SURFACE_AREA_FACTOR"] = cu.doubleToString(surfaceAreaFactor); defines["NUM_ATOMS"] = cu.intToString(cu.getNumAtoms()); defines["PADDED_NUM_ATOMS"] = cu.intToString(cu.getPaddedNumAtoms()); defines["NUM_BLOCKS"] = cu.intToString(cu.getNumAtomBlocks()); diff --git a/platforms/cuda/src/kernels/gbsaObc1.cu b/platforms/cuda/src/kernels/gbsaObc1.cu index 1fcb85790..b450648e1 100644 --- a/platforms/cuda/src/kernels/gbsaObc1.cu +++ b/platforms/cuda/src/kernels/gbsaObc1.cu @@ -1,6 +1,5 @@ #define DIELECTRIC_OFFSET 0.009f #define PROBE_RADIUS 0.14f -#define SURFACE_AREA_FACTOR -170.351730667551f //-6.0f*3.14159265358979323846f*0.0216f*1000.0f*0.4184f; #define WARPS_PER_GROUP (FORCE_WORK_GROUP_SIZE/TILE_SIZE) /** diff --git a/platforms/cuda/src/kernels/nonbonded.cu b/platforms/cuda/src/kernels/nonbonded.cu index 0ae5e9958..978f1b0df 100644 --- a/platforms/cuda/src/kernels/nonbonded.cu +++ b/platforms/cuda/src/kernels/nonbonded.cu @@ -398,6 +398,15 @@ extern "C" __global__ void computeNonbonded( #endif LOAD_LOCAL_PARAMETERS_FROM_GLOBAL } + else { +#ifdef ENABLE_SHUFFLE + shflPosq = make_real4(0, 0, 0, 0); +#else + localData[threadIdx.x].x = 0; + localData[threadIdx.x].y = 0; + localData[threadIdx.x].z = 0; +#endif + } #ifdef USE_PERIODIC if (singlePeriodicCopy) { // The box is small enough that we can just translate all the atoms into a single periodic diff --git a/platforms/cuda/tests/TestCudaGBSAOBCForce.cpp b/platforms/cuda/tests/TestCudaGBSAOBCForce.cpp index 4b7eb2c05..87e01f19a 100644 --- a/platforms/cuda/tests/TestCudaGBSAOBCForce.cpp +++ b/platforms/cuda/tests/TestCudaGBSAOBCForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2014 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -72,7 +72,7 @@ void testSingleParticle() { double eps0 = EPSILON0; double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/gbsa->getSoluteDielectric()-1.0/gbsa->getSolventDielectric())/bornRadius; double extendedRadius = 0.15+0.14; // probe radius - double nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.15/bornRadius, 6.0); // Where did this formula come from? Just copied it from CpuImplicitSolvent.cpp + double nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); // Change the parameters and see if it is still correct. @@ -82,8 +82,34 @@ void testSingleParticle() { state = context.getState(State::Energy); bornRadius = 0.25-0.009; // dielectric offset bornEnergy = (-0.4*0.4/(8*PI_M*eps0))*(1.0/gbsa->getSoluteDielectric()-1.0/gbsa->getSolventDielectric())/bornRadius; - extendedRadius = bornRadius+0.14; - nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.25/bornRadius, 6.0); + extendedRadius = 0.25+0.14; + nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.25/bornRadius, 6.0); + ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); +} + +void testGlobalSettings() { + System system; + system.addParticle(2.0); + LangevinIntegrator integrator(0, 0.1, 0.01); + GBSAOBCForce* forceField = new GBSAOBCForce(); + forceField->addParticle(0.5, 0.15, 1); + const double soluteDielectric = 2.1; + const double solventDielectric = 35.0; + const double surfaceAreaEnergy = 0.75; + forceField->setSoluteDielectric(soluteDielectric); + forceField->setSolventDielectric(solventDielectric); + forceField->setSurfaceAreaEnergy(surfaceAreaEnergy); + system.addForce(forceField); + Context context(system, integrator, platform); + vector positions(1); + positions[0] = Vec3(0, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Energy); + double bornRadius = 0.15-0.009; // dielectric offset + double eps0 = EPSILON0; + double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/soluteDielectric-1.0/solventDielectric)/bornRadius; + double extendedRadius = 0.15+0.14; // probe radius + double nonpolarEnergy = 4*PI_M*surfaceAreaEnergy*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); } @@ -229,6 +255,7 @@ int main(int argc, char* argv[]) { if (argc > 1) platform.setPropertyDefaultValue("CudaPrecision", string(argv[1])); testSingleParticle(); + testGlobalSettings(); testCutoffAndPeriodic(); for (int i = 5; i < 11; i++) { testForce(i*i*i, NonbondedForce::NoCutoff, GBSAOBCForce::NoCutoff); diff --git a/platforms/opencl/include/OpenCLKernels.h b/platforms/opencl/include/OpenCLKernels.h index 3a793bcfd..d62647150 100644 --- a/platforms/opencl/include/OpenCLKernels.h +++ b/platforms/opencl/include/OpenCLKernels.h @@ -721,7 +721,7 @@ public: */ void copyParametersToContext(ContextImpl& context, const GBSAOBCForce& force); private: - double prefactor; + double prefactor, surfaceAreaFactor; bool hasCreatedKernels; int maxTiles; OpenCLContext& cl; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index b55d591ea..03df4e49c 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -2505,6 +2505,7 @@ void OpenCLCalcGBSAOBCForceKernel::initialize(const System& system, const GBSAOB cl.getPosq().upload(posqf); params->upload(paramsVector); prefactor = -ONE_4PI_EPS0*((1.0/force.getSoluteDielectric())-(1.0/force.getSolventDielectric())); + surfaceAreaFactor = -6.0*4*M_PI*force.getSurfaceAreaEnergy(); bool useCutoff = (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff); bool usePeriodic = (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff && force.getNonbondedMethod() != GBSAOBCForce::CutoffNonPeriodic); string source = OpenCLKernelSources::gbsaObc2; @@ -2530,6 +2531,7 @@ double OpenCLCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeF defines["CUTOFF_SQUARED"] = cl.doubleToString(nb.getCutoffDistance()*nb.getCutoffDistance()); defines["CUTOFF"] = cl.doubleToString(nb.getCutoffDistance()); defines["PREFACTOR"] = cl.doubleToString(prefactor); + defines["SURFACE_AREA_FACTOR"] = cl.doubleToString(surfaceAreaFactor); defines["NUM_ATOMS"] = cl.intToString(cl.getNumAtoms()); defines["PADDED_NUM_ATOMS"] = cl.intToString(cl.getPaddedNumAtoms()); defines["NUM_BLOCKS"] = cl.intToString(cl.getNumAtomBlocks()); diff --git a/platforms/opencl/src/kernels/gbsaObcReductions.cl b/platforms/opencl/src/kernels/gbsaObcReductions.cl index 179ca05fe..acfa8d9d1 100644 --- a/platforms/opencl/src/kernels/gbsaObcReductions.cl +++ b/platforms/opencl/src/kernels/gbsaObcReductions.cl @@ -1,6 +1,5 @@ #define DIELECTRIC_OFFSET 0.009f #define PROBE_RADIUS 0.14f -#define SURFACE_AREA_FACTOR -170.351730667551f //-6.0f*3.14159265358979323846f*0.0216f*1000.0f*0.4184f; /** * Reduce the Born sums to compute the Born radii. diff --git a/platforms/opencl/src/kernels/nonbonded.cl b/platforms/opencl/src/kernels/nonbonded.cl index ed6ef0793..f000282b4 100644 --- a/platforms/opencl/src/kernels/nonbonded.cl +++ b/platforms/opencl/src/kernels/nonbonded.cl @@ -277,6 +277,11 @@ __kernel void computeNonbonded( localData[localAtomIndex].fy = 0; localData[localAtomIndex].fz = 0; } + else { + localData[localAtomIndex].x = 0; + localData[localAtomIndex].y = 0; + localData[localAtomIndex].z = 0; + } SYNC_WARPS; #ifdef USE_PERIODIC if (singlePeriodicCopy) { diff --git a/platforms/opencl/tests/TestOpenCLGBSAOBCForce.cpp b/platforms/opencl/tests/TestOpenCLGBSAOBCForce.cpp index 2d71fdb26..d406c4c58 100644 --- a/platforms/opencl/tests/TestOpenCLGBSAOBCForce.cpp +++ b/platforms/opencl/tests/TestOpenCLGBSAOBCForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2014 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -72,7 +72,7 @@ void testSingleParticle() { double eps0 = EPSILON0; double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/gbsa->getSoluteDielectric()-1.0/gbsa->getSolventDielectric())/bornRadius; double extendedRadius = 0.15+0.14; // probe radius - double nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.15/bornRadius, 6.0); // Where did this formula come from? Just copied it from CpuImplicitSolvent.cpp + double nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); // Change the parameters and see if it is still correct. @@ -82,8 +82,34 @@ void testSingleParticle() { state = context.getState(State::Energy); bornRadius = 0.25-0.009; // dielectric offset bornEnergy = (-0.4*0.4/(8*PI_M*eps0))*(1.0/gbsa->getSoluteDielectric()-1.0/gbsa->getSolventDielectric())/bornRadius; - extendedRadius = bornRadius+0.14; - nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.25/bornRadius, 6.0); + extendedRadius = 0.25+0.14; + nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.25/bornRadius, 6.0); + ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); +} + +void testGlobalSettings() { + System system; + system.addParticle(2.0); + LangevinIntegrator integrator(0, 0.1, 0.01); + GBSAOBCForce* forceField = new GBSAOBCForce(); + forceField->addParticle(0.5, 0.15, 1); + const double soluteDielectric = 2.1; + const double solventDielectric = 35.0; + const double surfaceAreaEnergy = 0.75; + forceField->setSoluteDielectric(soluteDielectric); + forceField->setSolventDielectric(solventDielectric); + forceField->setSurfaceAreaEnergy(surfaceAreaEnergy); + system.addForce(forceField); + Context context(system, integrator, platform); + vector positions(1); + positions[0] = Vec3(0, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Energy); + double bornRadius = 0.15-0.009; // dielectric offset + double eps0 = EPSILON0; + double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/soluteDielectric-1.0/solventDielectric)/bornRadius; + double extendedRadius = 0.15+0.14; // probe radius + double nonpolarEnergy = 4*PI_M*surfaceAreaEnergy*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); } @@ -227,6 +253,7 @@ void testForce(int numParticles, NonbondedForce::NonbondedMethod method, GBSAOBC int main() { try { testSingleParticle(); + testGlobalSettings(); testCutoffAndPeriodic(); for (int i = 5; i < 11; i++) { testForce(i*i*i, NonbondedForce::NoCutoff, GBSAOBCForce::NoCutoff); diff --git a/platforms/reference/include/ObcParameters.h b/platforms/reference/include/ObcParameters.h index faff98959..b38c59376 100644 --- a/platforms/reference/include/ObcParameters.h +++ b/platforms/reference/include/ObcParameters.h @@ -148,6 +148,14 @@ class ObcParameters { RealOpenMM getPi4Asolv( void ) const; + /**--------------------------------------------------------------------------------------- + + Set pi4Asolv + + --------------------------------------------------------------------------------------- */ + + void setPi4Asolv( RealOpenMM pi4Asolv ); + /**--------------------------------------------------------------------------------------- Get solvent dielectric diff --git a/platforms/reference/src/ReferenceKernels.cpp b/platforms/reference/src/ReferenceKernels.cpp index b6c42cfd4..ffb5942af 100644 --- a/platforms/reference/src/ReferenceKernels.cpp +++ b/platforms/reference/src/ReferenceKernels.cpp @@ -1098,6 +1098,7 @@ void ReferenceCalcGBSAOBCForceKernel::initialize(const System& system, const GBS obcParameters->setScaledRadiusFactors(scaleFactors); obcParameters->setSolventDielectric( static_cast(force.getSolventDielectric()) ); obcParameters->setSoluteDielectric( static_cast(force.getSoluteDielectric()) ); + obcParameters->setPi4Asolv(4*M_PI*force.getSurfaceAreaEnergy()); if (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff) obcParameters->setUseCutoff(static_cast(force.getCutoffDistance())); isPeriodic = (force.getNonbondedMethod() == GBSAOBCForce::CutoffPeriodic); diff --git a/platforms/reference/src/gbsa/ObcParameters.cpp b/platforms/reference/src/gbsa/ObcParameters.cpp index 791d5d4d9..0d541a4cc 100644 --- a/platforms/reference/src/gbsa/ObcParameters.cpp +++ b/platforms/reference/src/gbsa/ObcParameters.cpp @@ -258,6 +258,9 @@ RealOpenMM ObcParameters::getPi4Asolv( void ) const { return _pi4Asolv; } +void ObcParameters::setPi4Asolv(RealOpenMM pi4Asolv) { + _pi4Asolv = pi4Asolv; +} /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp b/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp index 7733d53d9..72723e143 100644 --- a/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp +++ b/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp @@ -67,7 +67,7 @@ void testSingleParticle() { double eps0 = EPSILON0; double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric())/bornRadius; double extendedRadius = 0.15+0.14; // probe radius - double nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.15/bornRadius, 6.0); // Where did this formula come from? Just copied it from CpuImplicitSolvent.cpp + double nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); // Change the parameters and see if it is still correct. @@ -77,8 +77,35 @@ void testSingleParticle() { state = context.getState(State::Energy); bornRadius = 0.25-0.009; // dielectric offset bornEnergy = (-0.4*0.4/(8*PI_M*eps0))*(1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric())/bornRadius; - extendedRadius = bornRadius+0.14; - nonpolarEnergy = CAL2JOULE*PI_M*0.0216*(10*extendedRadius)*(10*extendedRadius)*std::pow(0.25/bornRadius, 6.0); + extendedRadius = 0.25+0.14; + nonpolarEnergy = 4*PI_M*2.25936*extendedRadius*extendedRadius*std::pow(0.25/bornRadius, 6.0); + ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); +} + +void testGlobalSettings() { + ReferencePlatform platform; + System system; + system.addParticle(2.0); + LangevinIntegrator integrator(0, 0.1, 0.01); + GBSAOBCForce* forceField = new GBSAOBCForce(); + forceField->addParticle(0.5, 0.15, 1); + const double soluteDielectric = 2.1; + const double solventDielectric = 35.0; + const double surfaceAreaEnergy = 0.75; + forceField->setSoluteDielectric(soluteDielectric); + forceField->setSolventDielectric(solventDielectric); + forceField->setSurfaceAreaEnergy(surfaceAreaEnergy); + system.addForce(forceField); + Context context(system, integrator, platform); + vector positions(1); + positions[0] = Vec3(0, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Energy); + double bornRadius = 0.15-0.009; // dielectric offset + double eps0 = EPSILON0; + double bornEnergy = (-0.5*0.5/(8*PI_M*eps0))*(1.0/soluteDielectric-1.0/solventDielectric)/bornRadius; + double extendedRadius = 0.15+0.14; // probe radius + double nonpolarEnergy = 4*PI_M*surfaceAreaEnergy*extendedRadius*extendedRadius*std::pow(0.15/bornRadius, 6.0); ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); } @@ -190,6 +217,7 @@ void testForce() { int main() { try { testSingleParticle(); + testGlobalSettings(); testCutoffAndPeriodic(); testForce(); } -- GitLab From 438b29b434b889219dd4b643d33ee7929f7d0458 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 13 Oct 2014 11:28:57 -0700 Subject: [PATCH 055/338] Setting surface area energy works with Python API --- wrappers/python/src/swig_doxygen/swigInputConfig.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wrappers/python/src/swig_doxygen/swigInputConfig.py b/wrappers/python/src/swig_doxygen/swigInputConfig.py index 07fa9f617..b7611881e 100755 --- a/wrappers/python/src/swig_doxygen/swigInputConfig.py +++ b/wrappers/python/src/swig_doxygen/swigInputConfig.py @@ -378,6 +378,7 @@ UNITS = { ("GBSAOBCForce", "getParticleParameters") : (None, ('unit.elementary_charge', 'unit.nanometer', None)), +("GBSAOBCForce", "getSurfaceAreaEnergy") : ('unit.kilojoule_per_mole/unit.nanometer/unit.nanometer', ()), ("GBVIForce", "getBornRadiusScalingMethod") : (None, ()), ("GBVIForce", "getQuinticLowerLimitFactor") : (None, ()), ("GBVIForce", "getQuinticUpperBornRadiusLimit") : ('unit.nanometer', ()), -- GitLab From ead929de84308f8c996073e566999a9f78ae670e Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 13 Oct 2014 11:33:05 -0700 Subject: [PATCH 056/338] Setting surface area energy works with serialization --- serialization/src/GBSAOBCForceProxy.cpp | 8 ++++++-- serialization/tests/TestSerializeGBSAOBCForce.cpp | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/serialization/src/GBSAOBCForceProxy.cpp b/serialization/src/GBSAOBCForceProxy.cpp index d78bd17df..cd11433e2 100644 --- a/serialization/src/GBSAOBCForceProxy.cpp +++ b/serialization/src/GBSAOBCForceProxy.cpp @@ -42,13 +42,14 @@ GBSAOBCForceProxy::GBSAOBCForceProxy() : SerializationProxy("GBSAOBCForce") { } void GBSAOBCForceProxy::serialize(const void* object, SerializationNode& node) const { - node.setIntProperty("version", 1); + node.setIntProperty("version", 2); const GBSAOBCForce& force = *reinterpret_cast(object); node.setIntProperty("forceGroup", force.getForceGroup()); node.setIntProperty("method", (int) force.getNonbondedMethod()); node.setDoubleProperty("cutoff", force.getCutoffDistance()); node.setDoubleProperty("soluteDielectric", force.getSoluteDielectric()); node.setDoubleProperty("solventDielectric", force.getSolventDielectric()); + node.setDoubleProperty("surfaceAreaEnergy", force.getSurfaceAreaEnergy()); SerializationNode& particles = node.createChildNode("Particles"); for (int i = 0; i < force.getNumParticles(); i++) { double charge, radius, scale; @@ -58,7 +59,8 @@ void GBSAOBCForceProxy::serialize(const void* object, SerializationNode& node) c } void* GBSAOBCForceProxy::deserialize(const SerializationNode& node) const { - if (node.getIntProperty("version") != 1) + int version = node.getIntProperty("version"); + if (version < 1 || version > 2) throw OpenMMException("Unsupported version number"); GBSAOBCForce* force = new GBSAOBCForce(); try { @@ -67,6 +69,8 @@ void* GBSAOBCForceProxy::deserialize(const SerializationNode& node) const { force->setCutoffDistance(node.getDoubleProperty("cutoff")); force->setSoluteDielectric(node.getDoubleProperty("soluteDielectric")); force->setSolventDielectric(node.getDoubleProperty("solventDielectric")); + if (version > 1) + force->setSurfaceAreaEnergy(node.getDoubleProperty("surfaceAreaEnergy")); const SerializationNode& particles = node.getChildNode("Particles"); for (int i = 0; i < (int) particles.getChildren().size(); i++) { const SerializationNode& particle = particles.getChildren()[i]; diff --git a/serialization/tests/TestSerializeGBSAOBCForce.cpp b/serialization/tests/TestSerializeGBSAOBCForce.cpp index fe2e4fa22..0ccbe3165 100644 --- a/serialization/tests/TestSerializeGBSAOBCForce.cpp +++ b/serialization/tests/TestSerializeGBSAOBCForce.cpp @@ -47,6 +47,7 @@ void testSerialization() { force.setCutoffDistance(2.0); force.setSoluteDielectric(5.1); force.setSolventDielectric(50.0); + force.setSurfaceAreaEnergy(1.7); force.addParticle(1, 0.1, 0.01); force.addParticle(0.5, 0.2, 0.02); force.addParticle(-0.5, 0.3, 0.03); @@ -65,6 +66,7 @@ void testSerialization() { ASSERT_EQUAL(force.getCutoffDistance(), force2.getCutoffDistance()); ASSERT_EQUAL(force.getSoluteDielectric(), force2.getSoluteDielectric()); ASSERT_EQUAL(force.getSolventDielectric(), force2.getSolventDielectric()); + ASSERT_EQUAL(force.getSurfaceAreaEnergy(), force2.getSurfaceAreaEnergy()); ASSERT_EQUAL(force.getNumParticles(), force2.getNumParticles()); for (int i = 0; i < force.getNumParticles(); i++) { double charge1, radius1, scale1; -- GitLab From dd27dd0771276ba5ccf5c8809ac7be59ebccb0c2 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 14 Oct 2014 11:57:37 -0700 Subject: [PATCH 057/338] Removed some unnecessary library references that caused problems for conda on OS X --- plugins/amoeba/platforms/cuda/CMakeLists.txt | 2 +- plugins/drude/platforms/cuda/CMakeLists.txt | 2 +- plugins/rpmd/platforms/cuda/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/CMakeLists.txt b/plugins/amoeba/platforms/cuda/CMakeLists.txt index 21c51bdb1..108d5f397 100644 --- a/plugins/amoeba/platforms/cuda/CMakeLists.txt +++ b/plugins/amoeba/platforms/cuda/CMakeLists.txt @@ -87,7 +87,7 @@ ADD_CUSTOM_COMMAND(OUTPUT ${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} SET_SOURCE_FILES_PROPERTIES(${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} PROPERTIES GENERATED TRUE) ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES}) -TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME} ${CUDA_LIBRARIES} ${PTHREADS_LIB}) +TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME} ${PTHREADS_LIB}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME}CUDA) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${SHARED_AMOEBA_TARGET}) SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY") diff --git a/plugins/drude/platforms/cuda/CMakeLists.txt b/plugins/drude/platforms/cuda/CMakeLists.txt index 98f84ff5a..b9385b177 100644 --- a/plugins/drude/platforms/cuda/CMakeLists.txt +++ b/plugins/drude/platforms/cuda/CMakeLists.txt @@ -86,7 +86,7 @@ ADD_CUSTOM_COMMAND(OUTPUT ${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} SET_SOURCE_FILES_PROPERTIES(${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} PROPERTIES GENERATED TRUE) ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES}) -TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME} ${CUDA_LIBRARIES} ${PTHREADS_LIB}) +TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME} ${PTHREADS_LIB}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME}CUDA) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${SHARED_DRUDE_TARGET}) SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY") diff --git a/plugins/rpmd/platforms/cuda/CMakeLists.txt b/plugins/rpmd/platforms/cuda/CMakeLists.txt index cb4d393a9..2b7cd8964 100644 --- a/plugins/rpmd/platforms/cuda/CMakeLists.txt +++ b/plugins/rpmd/platforms/cuda/CMakeLists.txt @@ -86,7 +86,7 @@ ADD_CUSTOM_COMMAND(OUTPUT ${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} SET_SOURCE_FILES_PROPERTIES(${CUDA_KERNELS_CPP} ${CUDA_KERNELS_H} PROPERTIES GENERATED TRUE) ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_ABS_INCLUDE_FILES}) -TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME} ${CUDA_LIBRARIES} ${PTHREADS_LIB}) +TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME} ${PTHREADS_LIB}) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME}CUDA) TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${SHARED_RPMD_TARGET}) SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_BUILDING_SHARED_LIBRARY") -- GitLab From 9184c3722ef12fd31f003c705ab19f29feed93b7 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 15 Oct 2014 12:51:29 -0700 Subject: [PATCH 058/338] Fixed bug in Quantity.sum() --- wrappers/python/simtk/unit/quantity.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index b4aa525d2..ded022297 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -467,7 +467,12 @@ class Quantity(object): # This will be much faster for numpy arrays mysum = self._value.sum() except AttributeError: - mysum = sum(self._value) + if len(self._value) == 0: + mysum = 0 + else: + mysum = self._value[0] + for i in range(1, len(self._value)): + mysum += self._value[i] return Quantity(mysum, self.unit) def mean(self): -- GitLab From 942d4d7a50b830123429cff2d6d3b6ce0d844eb2 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 15 Oct 2014 14:45:28 -0700 Subject: [PATCH 059/338] Workaround to support GTX 980 --- platforms/cuda/src/CudaContext.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 595a10609..4a71879d9 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -136,6 +136,11 @@ CudaContext::CudaContext(const System& system, int deviceIndex, bool useBlocking this->deviceIndex = deviceIndex; int major, minor; CHECK_RESULT(cuDeviceComputeCapability(&major, &minor, device)); + // This is a workaround to support GTX 980 with CUDA 6.5. It reports its compute capability + // as 5.2, but the compiler doesn't support anything beyond 5.0. We can remove this once + // CUDA 7.0 is released. + if (major == 5) + minor = 0; gpuArchitecture = intToString(major)+intToString(minor); computeCapability = major+0.1*minor; if ((useDoublePrecision || useMixedPrecision) && computeCapability < 1.3) -- GitLab From 390e0a6b194ce995599f3e41b1beb1a0d82c6d1c Mon Sep 17 00:00:00 2001 From: root Date: Tue, 21 Oct 2014 14:59:00 -0700 Subject: [PATCH 060/338] Optimizations to multi-GPU calculations --- platforms/cuda/include/CudaParallelKernels.h | 1 + platforms/cuda/src/CudaContext.cpp | 10 ++++++++ platforms/cuda/src/CudaParallelKernels.cpp | 25 +++++++++++++------- platforms/cuda/src/CudaPlatform.cpp | 23 ++++++------------ 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/platforms/cuda/include/CudaParallelKernels.h b/platforms/cuda/include/CudaParallelKernels.h index 9633f1543..f43420e97 100644 --- a/platforms/cuda/include/CudaParallelKernels.h +++ b/platforms/cuda/include/CudaParallelKernels.h @@ -85,6 +85,7 @@ private: void* pinnedPositionBuffer; long long* pinnedForceBuffer; CUfunction sumKernel; + CUevent event; }; /** diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 4a71879d9..49c709ad7 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -154,6 +154,16 @@ CudaContext::CudaContext(const System& system, int deviceIndex, bool useBlocking CHECK_RESULT(cuCtxCreate(&context, flags, device)); contextIsValid = true; CHECK_RESULT(cuCtxSetCacheConfig(CU_FUNC_CACHE_PREFER_SHARED)); + if (contextIndex > 0) { + int canAccess; + cuDeviceCanAccessPeer(&canAccess, getDevice(), platformData.contexts[0]->getDevice()); + if (canAccess) { + platformData.contexts[0]->setAsCurrent(); + CHECK_RESULT(cuCtxEnablePeerAccess(getContext(), 0)); + setAsCurrent(); + CHECK_RESULT(cuCtxEnablePeerAccess(platformData.contexts[0]->getContext(), 0)); + } + } numAtoms = system.getNumParticles(); paddedNumAtoms = TileSize*((numAtoms+TileSize-1)/TileSize); numAtomBlocks = (paddedNumAtoms+(TileSize-1))/TileSize; diff --git a/platforms/cuda/src/CudaParallelKernels.cpp b/platforms/cuda/src/CudaParallelKernels.cpp index d445b91e3..833bad8c6 100644 --- a/platforms/cuda/src/CudaParallelKernels.cpp +++ b/platforms/cuda/src/CudaParallelKernels.cpp @@ -63,21 +63,23 @@ if (result != CUDA_SUCCESS) { \ class CudaParallelCalcForcesAndEnergyKernel::BeginComputationTask : public CudaContext::WorkTask { public: BeginComputationTask(ContextImpl& context, CudaContext& cu, CudaCalcForcesAndEnergyKernel& kernel, - bool includeForce, bool includeEnergy, int groups, void* pinnedMemory) : context(context), cu(cu), kernel(kernel), - includeForce(includeForce), includeEnergy(includeEnergy), groups(groups), pinnedMemory(pinnedMemory) { + bool includeForce, bool includeEnergy, int groups, void* pinnedMemory, CUevent event) : context(context), cu(cu), kernel(kernel), + includeForce(includeForce), includeEnergy(includeEnergy), groups(groups), pinnedMemory(pinnedMemory), event(event) { } void execute() { // Copy coordinates over to this device and execute the kernel. cu.setAsCurrent(); if (cu.getContextIndex() > 0) { - if (cu.getPlatformData().peerAccessSupported && cu.getPlatformData().contexts.size() < 3) { + if (cu.getPlatformData().peerAccessSupported && false) { // Why is the peer-to-peer copy slower??? CudaContext& context0 = *cu.getPlatformData().contexts[0]; int numBytes = cu.getPosq().getSize()*cu.getPosq().getElementSize(); - CHECK_RESULT(cuMemcpyPeerAsync(cu.getPosq().getDevicePointer(), cu.getContext(), context0.getPosq().getDevicePointer(), context0.getContext(), numBytes, 0), "Error copying positions"); + CHECK_RESULT(cuMemcpyAsync(cu.getPosq().getDevicePointer(), context0.getPosq().getDevicePointer(), numBytes, 0), "Error copying positions"); } - else + else { + cuStreamWaitEvent(cu.getCurrentStream(), event, 0); cu.getPosq().upload(pinnedMemory, false); + } } kernel.beginComputation(context, includeForce, includeEnergy, groups); } @@ -88,6 +90,7 @@ private: bool includeForce, includeEnergy; int groups; void* pinnedMemory; + CUevent event; }; class CudaParallelCalcForcesAndEnergyKernel::FinishComputationTask : public CudaContext::WorkTask { @@ -108,7 +111,7 @@ public: int numBytes = numAtoms*3*sizeof(long long); int offset = (cu.getContextIndex()-1)*numBytes; CudaContext& context0 = *cu.getPlatformData().contexts[0]; - CHECK_RESULT(cuMemcpyPeer(contextForces.getDevicePointer()+offset, context0.getContext(), cu.getForce().getDevicePointer(), cu.getContext(), numBytes), "Error copying forces"); + CHECK_RESULT(cuMemcpy(contextForces.getDevicePointer()+offset, cu.getForce().getDevicePointer(), numBytes), "Error copying forces"); } else cu.getForce().download(&pinnedMemory[(cu.getContextIndex()-1)*numAtoms*3]); @@ -146,6 +149,7 @@ CudaParallelCalcForcesAndEnergyKernel::~CudaParallelCalcForcesAndEnergyKernel() cuMemFreeHost(pinnedPositionBuffer); if (pinnedForceBuffer != NULL) cuMemFreeHost(pinnedForceBuffer); + cuEventDestroy(event); } void CudaParallelCalcForcesAndEnergyKernel::initialize(const System& system) { @@ -157,6 +161,7 @@ void CudaParallelCalcForcesAndEnergyKernel::initialize(const System& system) { getKernel(i).initialize(system); for (int i = 0; i < (int) contextNonbondedFractions.size(); i++) contextNonbondedFractions[i] = 1/(double) contextNonbondedFractions.size(); + CHECK_RESULT(cuEventCreate(&event, 0), "Error creating event"); } void CudaParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { @@ -170,13 +175,15 @@ void CudaParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& contex // Copy coordinates over to each device and execute the kernel. - if (!(cu.getPlatformData().peerAccessSupported && cu.getPlatformData().contexts.size() < 3)) - cu.getPosq().download(pinnedPositionBuffer); + if (!(cu.getPlatformData().peerAccessSupported && false)) { // Why is this faster than a peer-to-peer copy??? + cu.getPosq().download(pinnedPositionBuffer, false); + cuEventRecord(event, cu.getCurrentStream()); + } for (int i = 0; i < (int) data.contexts.size(); i++) { data.contextEnergy[i] = 0.0; CudaContext& cu = *data.contexts[i]; CudaContext::WorkThread& thread = cu.getWorkThread(); - thread.addTask(new BeginComputationTask(context, cu, getKernel(i), includeForce, includeEnergy, groups, pinnedPositionBuffer)); + thread.addTask(new BeginComputationTask(context, cu, getKernel(i), includeForce, includeEnergy, groups, pinnedPositionBuffer, event)); } } diff --git a/platforms/cuda/src/CudaPlatform.cpp b/platforms/cuda/src/CudaPlatform.cpp index f38fe13d8..ab6c95ca6 100644 --- a/platforms/cuda/src/CudaPlatform.cpp +++ b/platforms/cuda/src/CudaPlatform.cpp @@ -229,22 +229,13 @@ CudaPlatform::PlatformData::PlatformData(ContextImpl* context, const System& sys // Determine whether peer-to-peer copying is supported, and enable it if so. - peerAccessSupported = false; // Disable until I figure out why it usually makes things slower -// peerAccessSupported = true; -// for (int i = 1; i < contexts.size(); i++) { -// int canAccess; -// cuDeviceCanAccessPeer(&canAccess, contexts[i]->getDevice(), contexts[0]->getDevice()); -// if (!canAccess) { -// peerAccessSupported = false; -// break; -// } -// } - if (peerAccessSupported) { - for (int i = 1; i < contexts.size(); i++) { - contexts[0]->setAsCurrent(); - CHECK_RESULT(cuCtxEnablePeerAccess(contexts[i]->getContext(), 0), "Error enabling peer access"); - contexts[i]->setAsCurrent(); - CHECK_RESULT(cuCtxEnablePeerAccess(contexts[0]->getContext(), 0), "Error enabling peer access"); + peerAccessSupported = true; + for (int i = 1; i < contexts.size(); i++) { + int canAccess; + cuDeviceCanAccessPeer(&canAccess, contexts[i]->getDevice(), contexts[0]->getDevice()); + if (!canAccess) { + peerAccessSupported = false; + break; } } } -- GitLab From 8e2fc4ea58cceb95bdf928330e39f2cf5ab7a114 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Tue, 21 Oct 2014 16:29:45 -0700 Subject: [PATCH 061/338] Workaround for driver bugs that affect GTX 980 --- platforms/cuda/include/CudaKernels.h | 2 +- platforms/cuda/src/CudaKernels.cpp | 36 ++++++++++++++++---------- platforms/opencl/src/OpenCLKernels.cpp | 6 +++++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/platforms/cuda/include/CudaKernels.h b/platforms/cuda/include/CudaKernels.h index 2d166ffc9..b02a3a763 100644 --- a/platforms/cuda/include/CudaKernels.h +++ b/platforms/cuda/include/CudaKernels.h @@ -632,7 +632,7 @@ private: std::vector > exceptionAtoms; double ewaldSelfEnergy, dispersionCoefficient, alpha; int interpolateForceThreads; - bool hasCoulomb, hasLJ; + bool hasCoulomb, hasLJ, usePmeStream; static const int PmeOrder = 5; }; diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 462868b59..8e8bc0b2f 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1457,8 +1457,10 @@ CudaCalcNonbondedForceKernel::~CudaCalcNonbondedForceKernel() { if (hasInitializedFFT) { cufftDestroy(fftForward); cufftDestroy(fftBackward); - cuStreamDestroy(pmeStream); - cuEventDestroy(pmeSyncEvent); + if (usePmeStream) { + cuStreamDestroy(pmeStream); + cuEventDestroy(pmeSyncEvent); + } } } @@ -1670,15 +1672,18 @@ void CudaCalcNonbondedForceKernel::initialize(const System& system, const Nonbon // Prepare for doing PME on its own stream. - cuStreamCreate(&pmeStream, CU_STREAM_NON_BLOCKING); - cufftSetStream(fftForward, pmeStream); - cufftSetStream(fftBackward, pmeStream); - CHECK_RESULT(cuEventCreate(&pmeSyncEvent, CU_EVENT_DISABLE_TIMING), "Error creating event for NonbondedForce"); - int recipForceGroup = force.getReciprocalSpaceForceGroup(); - if (recipForceGroup < 0) - recipForceGroup = force.getForceGroup(); - cu.addPreComputation(new SyncStreamPreComputation(pmeStream, pmeSyncEvent, recipForceGroup)); - cu.addPostComputation(new SyncStreamPostComputation(pmeSyncEvent, recipForceGroup)); + usePmeStream = (cu.getComputeCapability() < 5.0); // A driver bug causes this to be very slow on GTX 980. + if (usePmeStream) { + cuStreamCreate(&pmeStream, CU_STREAM_NON_BLOCKING); + cufftSetStream(fftForward, pmeStream); + cufftSetStream(fftBackward, pmeStream); + CHECK_RESULT(cuEventCreate(&pmeSyncEvent, CU_EVENT_DISABLE_TIMING), "Error creating event for NonbondedForce"); + int recipForceGroup = force.getReciprocalSpaceForceGroup(); + if (recipForceGroup < 0) + recipForceGroup = force.getForceGroup(); + cu.addPreComputation(new SyncStreamPreComputation(pmeStream, pmeSyncEvent, recipForceGroup)); + cu.addPostComputation(new SyncStreamPostComputation(pmeSyncEvent, recipForceGroup)); + } hasInitializedFFT = true; // Initialize the b-spline moduli. @@ -1795,7 +1800,8 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF cu.executeKernel(ewaldForcesKernel, forcesArgs, cu.getNumAtoms()); } if (directPmeGrid != NULL && includeReciprocal) { - cu.setCurrentStream(pmeStream); + if (usePmeStream) + cu.setCurrentStream(pmeStream); void* gridIndexArgs[] = {&cu.getPosq().getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; cu.executeKernel(pmeGridIndexKernel, gridIndexArgs, cu.getNumAtoms()); @@ -1832,8 +1838,10 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF void* interpolateArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &directPmeGrid->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeInterpolateForceKernel, interpolateArgs, cu.getNumAtoms(), 128); - cuEventRecord(pmeSyncEvent, pmeStream); - cu.restoreDefaultStream(); + if (usePmeStream) { + cuEventRecord(pmeSyncEvent, pmeStream); + cu.restoreDefaultStream(); + } } double energy = (includeReciprocal ? ewaldSelfEnergy : 0.0); if (dispersionCoefficient != 0.0 && includeDirect) { diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 03df4e49c..3ff761d87 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1611,6 +1611,12 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ); string vendor = cl.getDevice().getInfo(); usePmeQueue = (vendor.size() >= 6 && vendor.substr(0, 6) == "NVIDIA"); + if (cl.getDevice().getInfo().find("cl_nv_device_attribute_query") != string::npos) { + cl_uint computeCapabilityMajor; + clGetDeviceInfo(cl.getDevice()(), 0x4000, sizeof(cl_uint), &computeCapabilityMajor, NULL); // CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV + if (computeCapabilityMajor == 5) + usePmeQueue = false; // Workaround for driver bug that affects GTX 980. + } if (usePmeQueue) { pmeQueue = cl::CommandQueue(cl.getContext(), cl.getDevice()); int recipForceGroup = force.getReciprocalSpaceForceGroup(); -- GitLab From edbe9a7400a5ba6bfc4f49a5dd2662b82c17c048 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 22 Oct 2014 11:02:43 -0700 Subject: [PATCH 062/338] Handle hex values for atom and residue numbers --- .../simtk/openmm/app/internal/pdbstructure.py | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py index d46af7581..6a07c3551 100644 --- a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py +++ b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py @@ -141,6 +141,8 @@ class PdbStructure(object): self.sequences = [] self.modified_residues = [] # read file + self._atom_numbers_are_hex = False + self._residue_numbers_are_hex = False self._load(input_stream) def _load(self, input_stream): @@ -148,7 +150,7 @@ class PdbStructure(object): for pdb_line in input_stream: # Look for atoms if (pdb_line.find("ATOM ") == 0) or (pdb_line.find("HETATM") == 0): - self._add_atom(Atom(pdb_line)) + self._add_atom(Atom(pdb_line, self)) # Notice MODEL punctuation, for the next level of detail # in the structure->model->chain->residue->atom->position hierarchy elif (pdb_line.find("MODEL") == 0): @@ -653,7 +655,7 @@ class Residue(object): class Atom(object): """Atom represents one atom in a PDB structure. """ - def __init__(self, pdb_line): + def __init__(self, pdb_line, pdbstructure=None): """Create a new pdb.Atom from an ATOM or HETATM line. Example line: @@ -688,10 +690,17 @@ class Atom(object): self.is_first_atom_in_chain = False self.is_final_atom_in_chain = False self.is_first_residue_in_chain = False - self.is_final_residue_in_chain = False + self.is_final_residue_in_chain = False # Start parsing fields from pdb line self.record_name = pdb_line[0:6].strip() - self.serial_number = int(pdb_line[6:11]) + if pdbstructure is not None and pdbstructure._atom_numbers_are_hex: + self.serial_number = int(pdb_line[6:11], 16) + else: + try: + self.serial_number = int(pdb_line[6:11]) + except: + self.serial_number = int(pdb_line[6:11], 16) + pdbstructure._atom_numbers_are_hex = True self.name_with_spaces = pdb_line[12:16] alternate_location_indicator = pdb_line[16] @@ -707,7 +716,14 @@ class Atom(object): self.residue_name = self.residue_name_with_spaces.strip() self.chain_id = pdb_line[21] - self.residue_number = int(pdb_line[22:26]) + if pdbstructure is not None and pdbstructure._residue_numbers_are_hex: + self.residue_number = int(pdb_line[22:26], 16) + else: + try: + self.residue_number = int(pdb_line[22:26]) + except: + self.residue_number = int(pdb_line[22:26], 16) + pdbstructure._residue_numbers_are_hex = True self.insertion_code = pdb_line[26] # coordinates, occupancy, and temperature factor belong in Atom.Location object x = float(pdb_line[30:38]) -- GitLab From e53d4f27942e9a000c39d7f626abbbb1941c1ec7 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 22 Oct 2014 11:25:35 -0700 Subject: [PATCH 063/338] Simplified handling of hex values --- .../simtk/openmm/app/internal/pdbstructure.py | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py index 6a07c3551..f4c00158b 100644 --- a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py +++ b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py @@ -141,8 +141,6 @@ class PdbStructure(object): self.sequences = [] self.modified_residues = [] # read file - self._atom_numbers_are_hex = False - self._residue_numbers_are_hex = False self._load(input_stream) def _load(self, input_stream): @@ -150,7 +148,7 @@ class PdbStructure(object): for pdb_line in input_stream: # Look for atoms if (pdb_line.find("ATOM ") == 0) or (pdb_line.find("HETATM") == 0): - self._add_atom(Atom(pdb_line, self)) + self._add_atom(Atom(pdb_line)) # Notice MODEL punctuation, for the next level of detail # in the structure->model->chain->residue->atom->position hierarchy elif (pdb_line.find("MODEL") == 0): @@ -655,7 +653,7 @@ class Residue(object): class Atom(object): """Atom represents one atom in a PDB structure. """ - def __init__(self, pdb_line, pdbstructure=None): + def __init__(self, pdb_line): """Create a new pdb.Atom from an ATOM or HETATM line. Example line: @@ -690,17 +688,13 @@ class Atom(object): self.is_first_atom_in_chain = False self.is_final_atom_in_chain = False self.is_first_residue_in_chain = False - self.is_final_residue_in_chain = False + self.is_final_residue_in_chain = False # Start parsing fields from pdb line self.record_name = pdb_line[0:6].strip() - if pdbstructure is not None and pdbstructure._atom_numbers_are_hex: - self.serial_number = int(pdb_line[6:11], 16) - else: - try: - self.serial_number = int(pdb_line[6:11]) - except: - self.serial_number = int(pdb_line[6:11], 16) - pdbstructure._atom_numbers_are_hex = True + try: + self.serial_number = int(pdb_line[6:11]) + except: + self.serial_number = int(pdb_line[6:11], 16) # Try to parse it as hex self.name_with_spaces = pdb_line[12:16] alternate_location_indicator = pdb_line[16] @@ -716,14 +710,10 @@ class Atom(object): self.residue_name = self.residue_name_with_spaces.strip() self.chain_id = pdb_line[21] - if pdbstructure is not None and pdbstructure._residue_numbers_are_hex: - self.residue_number = int(pdb_line[22:26], 16) - else: - try: - self.residue_number = int(pdb_line[22:26]) - except: - self.residue_number = int(pdb_line[22:26], 16) - pdbstructure._residue_numbers_are_hex = True + try: + self.residue_number = int(pdb_line[22:26]) + except: + self.residue_number = int(pdb_line[22:26], 16) # Try to parse it as hex self.insertion_code = pdb_line[26] # coordinates, occupancy, and temperature factor belong in Atom.Location object x = float(pdb_line[30:38]) -- GitLab From be863b082e565412ff1b389b146106bb0291d245 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 22 Oct 2014 13:40:11 -0700 Subject: [PATCH 064/338] Better workaround for bug on GTX 980 --- platforms/opencl/src/OpenCLKernels.cpp | 6 ------ platforms/opencl/src/kernels/sort.cl | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 3ff761d87..03df4e49c 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1611,12 +1611,6 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ); string vendor = cl.getDevice().getInfo(); usePmeQueue = (vendor.size() >= 6 && vendor.substr(0, 6) == "NVIDIA"); - if (cl.getDevice().getInfo().find("cl_nv_device_attribute_query") != string::npos) { - cl_uint computeCapabilityMajor; - clGetDeviceInfo(cl.getDevice()(), 0x4000, sizeof(cl_uint), &computeCapabilityMajor, NULL); // CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV - if (computeCapabilityMajor == 5) - usePmeQueue = false; // Workaround for driver bug that affects GTX 980. - } if (usePmeQueue) { pmeQueue = cl::CommandQueue(cl.getContext(), cl.getDevice()); int recipForceGroup = force.getReciprocalSpaceForceGroup(); diff --git a/platforms/opencl/src/kernels/sort.cl b/platforms/opencl/src/kernels/sort.cl index 551be153f..ad76c3438 100644 --- a/platforms/opencl/src/kernels/sort.cl +++ b/platforms/opencl/src/kernels/sort.cl @@ -162,10 +162,10 @@ __kernel void copyDataToBuckets(__global const DATA_TYPE* restrict data, __globa * Sort the data in each bucket. */ __kernel void sortBuckets(__global DATA_TYPE* restrict data, __global const DATA_TYPE* restrict buckets, uint numBuckets, __global const uint* restrict bucketOffset, __local DATA_TYPE* restrict buffer) { - for (uint index = get_group_id(0); index < numBuckets; index += get_num_groups(0)) { - uint startIndex = (index == 0 ? 0 : bucketOffset[index-1]); - uint endIndex = bucketOffset[index]; - uint length = endIndex-startIndex; + for (int index = get_group_id(0); index < numBuckets; index += get_num_groups(0)) { + int startIndex = (index == 0 ? 0 : bucketOffset[index-1]); + int endIndex = bucketOffset[index]; + int length = endIndex-startIndex; if (length <= get_local_size(0)) { // Load the data into local memory. @@ -177,8 +177,8 @@ __kernel void sortBuckets(__global DATA_TYPE* restrict data, __global const DATA // Perform a bitonic sort in local memory. - for (uint k = 2; k <= get_local_size(0); k *= 2) { - for (uint j = k/2; j > 0; j /= 2) { + for (int k = 2; k <= get_local_size(0); k *= 2) { + for (int j = k/2; j > 0; j /= 2) { int ixj = get_local_id(0)^j; if (ixj > get_local_id(0)) { DATA_TYPE value1 = buffer[get_local_id(0)]; @@ -203,21 +203,21 @@ __kernel void sortBuckets(__global DATA_TYPE* restrict data, __global const DATA else { // Copy the bucket data over to the output array. - for (uint i = get_local_id(0); i < length; i += get_local_size(0)) + for (int i = get_local_id(0); i < length; i += get_local_size(0)) data[startIndex+i] = buckets[startIndex+i]; barrier(CLK_GLOBAL_MEM_FENCE); // Perform a bitonic sort in global memory. - for (uint k = 2; k < 2*length; k *= 2) { - for (uint j = k/2; j > 0; j /= 2) { - for (uint i = get_local_id(0); i < length; i += get_local_size(0)) { + for (int k = 2; k < 2*length; k *= 2) { + for (int j = k/2; j > 0; j /= 2) { + for (int i = get_local_id(0); i < length; i += get_local_size(0)) { int ixj = i^j; if (ixj > i && ixj < length) { DATA_TYPE value1 = data[startIndex+i]; DATA_TYPE value2 = data[startIndex+ixj]; bool ascending = ((i&k) == 0); - for (uint mask = k*2; mask < 2*length; mask *= 2) + for (int mask = k*2; mask < 2*length; mask *= 2) ascending = ((i&mask) == 0 ? !ascending : ascending); KEY_TYPE lowKey = (ascending ? getValue(value1) : getValue(value2)); KEY_TYPE highKey = (ascending ? getValue(value2) : getValue(value1)); -- GitLab From 0e36f341ac92d4a9922c6afa82edc1d05c5a9687 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 22 Oct 2014 14:04:32 -0700 Subject: [PATCH 065/338] Another attempt at correctly handling different types of numbers in PDB files --- .../simtk/openmm/app/internal/pdbstructure.py | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py index f4c00158b..0442bd333 100644 --- a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py +++ b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py @@ -144,16 +144,20 @@ class PdbStructure(object): self._load(input_stream) def _load(self, input_stream): + self._reset_atom_numbers() + self._reset_residue_numbers() # Read one line at a time for pdb_line in input_stream: # Look for atoms if (pdb_line.find("ATOM ") == 0) or (pdb_line.find("HETATM") == 0): - self._add_atom(Atom(pdb_line)) + self._add_atom(Atom(pdb_line, self)) # Notice MODEL punctuation, for the next level of detail # in the structure->model->chain->residue->atom->position hierarchy elif (pdb_line.find("MODEL") == 0): model_number = int(pdb_line[10:14]) self._add_model(Model(model_number)) + self._reset_atom_numbers() + self._reset_residue_numbers() elif (pdb_line.find("ENDMDL") == 0): self._current_model._finalize() if not self.load_all_models: @@ -164,6 +168,7 @@ class PdbStructure(object): break elif (pdb_line.find("TER") == 0 and pdb_line.split()[0] == "TER"): self._current_model._current_chain._add_ter_record() + self._reset_residue_numbers() elif (pdb_line.find("CRYST1") == 0): self._unit_cell_dimensions = Vec3(float(pdb_line[6:15]), float(pdb_line[15:24]), float(pdb_line[24:33]))*unit.angstroms elif (pdb_line.find("CONECT") == 0): @@ -182,6 +187,14 @@ class PdbStructure(object): elif (pdb_line.find("MODRES") == 0): self.modified_residues.append(ModifiedResidue(pdb_line[16], int(pdb_line[18:22]), pdb_line[12:15].strip(), pdb_line[24:27].strip())) self._finalize() + + def _reset_atom_numbers(self): + self._atom_numbers_are_hex = False + self._next_atom_number = 1 + + def _reset_residue_numbers(self): + self._residue_numbers_are_hex = False + self._next_residue_number = 1 def write(self, output_stream=sys.stdout): """Write out structure in PDB format""" @@ -653,7 +666,7 @@ class Residue(object): class Atom(object): """Atom represents one atom in a PDB structure. """ - def __init__(self, pdb_line): + def __init__(self, pdb_line, pdbstructure=None): """Create a new pdb.Atom from an ATOM or HETATM line. Example line: @@ -688,13 +701,21 @@ class Atom(object): self.is_first_atom_in_chain = False self.is_final_atom_in_chain = False self.is_first_residue_in_chain = False - self.is_final_residue_in_chain = False + self.is_final_residue_in_chain = False # Start parsing fields from pdb line self.record_name = pdb_line[0:6].strip() - try: - self.serial_number = int(pdb_line[6:11]) - except: - self.serial_number = int(pdb_line[6:11], 16) # Try to parse it as hex + if pdbstructure is not None and pdbstructure._atom_numbers_are_hex: + self.serial_number = int(pdb_line[6:11], 16) + else: + try: + self.serial_number = int(pdb_line[6:11]) + except: + try: + self.serial_number = int(pdb_line[6:11], 16) + pdbstructure._atom_numbers_are_hex = True + except: + # Just give it the next number in sequence. + self.serial_number = pdbstructure._next_atom_number self.name_with_spaces = pdb_line[12:16] alternate_location_indicator = pdb_line[16] @@ -710,10 +731,18 @@ class Atom(object): self.residue_name = self.residue_name_with_spaces.strip() self.chain_id = pdb_line[21] - try: - self.residue_number = int(pdb_line[22:26]) - except: - self.residue_number = int(pdb_line[22:26], 16) # Try to parse it as hex + if pdbstructure is not None and pdbstructure._residue_numbers_are_hex: + self.residue_number = int(pdb_line[22:26], 16) + else: + try: + self.residue_number = int(pdb_line[22:26]) + except: + try: + self.residue_number = int(pdb_line[22:26], 16) + pdbstructure._residue_numbers_are_hex = True + except: + # Just give it the next number in sequence. + self.residue_number = pdbstructure._next_residue_number self.insertion_code = pdb_line[26] # coordinates, occupancy, and temperature factor belong in Atom.Location object x = float(pdb_line[30:38]) @@ -742,6 +771,9 @@ class Atom(object): self.element = element.get_by_symbol(self.element_symbol) except KeyError: self.element = None + if pdbstructure is not None: + pdbstructure._next_atom_number = self.serial_number+1 + pdbstructure._next_residue_number = self.residue_number+1 def iter_locations(self): """ -- GitLab From 92a4bbe1e49bdd353ae6f9339ad9aed22a2688b9 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 22 Oct 2014 17:11:00 -0700 Subject: [PATCH 066/338] Optimizations to the custom GB models --- .../openmm/app/internal/amber_file_parser.py | 2 + .../openmm/app/internal/customgbforces.py | 111 ++++++++---------- wrappers/python/tests/TestAmberPrmtopFile.py | 30 +++-- .../GBn2_NoCutoff.xml | 32 +++++ .../GBn_NoCutoff_Salt.xml | 32 +++++ .../HCT_NoCutoff.xml | 32 +++++ .../OBC1_NonPeriodic.xml | 32 +++++ .../OBC2_NonPeriodic_Salt.xml | 32 +++++ 8 files changed, 231 insertions(+), 72 deletions(-) create mode 100644 wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn2_NoCutoff.xml create mode 100644 wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn_NoCutoff_Salt.xml create mode 100644 wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/HCT_NoCutoff.xml create mode 100644 wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC1_NonPeriodic.xml create mode 100644 wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 94af2985c..76c30dd7e 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -1032,6 +1032,8 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode if units.is_quantity(cutoff): cutoff = cutoff.value_in_unit(units.nanometers) gb_parms = prmtop.getGBParms(gbmodel, elements) + if gbmodel != 'OBC2' or implicitSolventKappa != 0: + gb_parms = customgb.convertParameters(gb_parms, gbmodel) if gbmodel == 'HCT': gb = customgb.GBSAHCTForce(solventDielectric, soluteDielectric, 'ACE', cutoff, implicitSolventKappa) elif gbmodel == 'OBC1': diff --git a/wrappers/python/simtk/openmm/app/internal/customgbforces.py b/wrappers/python/simtk/openmm/app/internal/customgbforces.py index 4f5342c63..5c1effeb0 100644 --- a/wrappers/python/simtk/openmm/app/internal/customgbforces.py +++ b/wrappers/python/simtk/openmm/app/internal/customgbforces.py @@ -189,36 +189,37 @@ for i in range (len(d0)): m0[i]=m0[i]*10 -def _createEnergyTerms(force, SA, cutoff, kappa): +def _createEnergyTerms(force, solventDielectric, soluteDielectric, SA, cutoff, kappa): # Add the energy terms to the CustomGBForce. These are identical for all the GB models. + params = "; solventDielectric="+str(solventDielectric)+"; soluteDielectric="+str(soluteDielectric)+"; kappa="+str(kappa)+"; cutoff="+str(cutoff) if kappa > 0: - force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-exp(-kappa*B)/solventDielectric)*q^2/B", + force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-exp(-kappa*B)/solventDielectric)*q^2/B"+params, CustomGBForce.SingleParticle) elif kappa < 0: # Do kappa check here to avoid repeating code everywhere raise ValueError('kappa/ionic strength must be >= 0') else: - force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B", + force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B"+params, CustomGBForce.SingleParticle) if SA=='ACE': - force.addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6", CustomGBForce.SingleParticle) + force.addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6; radius=or+offset", CustomGBForce.SingleParticle) elif SA is not None: raise ValueError('Unknown surface area method: '+SA) if cutoff is None: if kappa > 0: force.addEnergyTerm("-138.935485*(1/soluteDielectric-exp(-kappa*f)/solventDielectric)*q1*q2/f;" - "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce.ParticlePairNoExclusions) + "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"+params, CustomGBForce.ParticlePairNoExclusions) else: force.addEnergyTerm("-138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2/f;" - "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce.ParticlePairNoExclusions) + "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"+params, CustomGBForce.ParticlePairNoExclusions) else: if kappa > 0: force.addEnergyTerm("-138.935485*(1/soluteDielectric-kappa/solventDielectric)*q1*q2*(1/f-"+str(1/cutoff)+");" - "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce.ParticlePairNoExclusions) + "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"+params, CustomGBForce.ParticlePairNoExclusions) else: force.addEnergyTerm("-138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2*(1/f-"+str(1/cutoff)+");" - "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", CustomGBForce.ParticlePairNoExclusions) + "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"+params, CustomGBForce.ParticlePairNoExclusions) """ Amber Equivalent: igb = 1 @@ -231,22 +232,16 @@ def GBSAHCTForce(solventDielectric=78.5, soluteDielectric=1, SA=None, custom = CustomGBForce() custom.addPerParticleParameter("q") - custom.addPerParticleParameter("radius") - custom.addPerParticleParameter("scale") - if kappa > 0: custom.addGlobalParameter('kappa', kappa) - custom.addGlobalParameter("solventDielectric", solventDielectric) - custom.addGlobalParameter("soluteDielectric", soluteDielectric) + custom.addPerParticleParameter("or") # Offset radius + custom.addPerParticleParameter("sr") # Scaled offset radius custom.addGlobalParameter("offset", 0.009) custom.addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r);" "U=r+sr2;" "L=max(or1, D);" - "D=abs(r-sr2);" - "sr2 = scale2*or2;" - "or1 = radius1-offset; or2 = radius2-offset", CustomGBForce.ParticlePairNoExclusions) + "D=abs(r-sr2)", CustomGBForce.ParticlePairNoExclusions) - custom.addComputedValue("B", "1/(1/or-I);" - "or=radius-offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, SA, cutoff, kappa) + custom.addComputedValue("B", "1/(1/or-I)", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) return custom """ @@ -258,22 +253,17 @@ def GBSAOBC1Force(solventDielectric=78.5, soluteDielectric=1, SA=None, custom = CustomGBForce() custom.addPerParticleParameter("q") - custom.addPerParticleParameter("radius") - custom.addPerParticleParameter("scale") - if kappa > 0: custom.addGlobalParameter('kappa', kappa) - custom.addGlobalParameter("solventDielectric", solventDielectric) - custom.addGlobalParameter("soluteDielectric", soluteDielectric) + custom.addPerParticleParameter("or") # Offset radius + custom.addPerParticleParameter("sr") # Scaled offset radius custom.addGlobalParameter("offset", 0.009) custom.addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r);" "U=r+sr2;" "L=max(or1, D);" - "D=abs(r-sr2);" - "sr2 = scale2*or2;" - "or1 = radius1-offset; or2 = radius2-offset", CustomGBForce.ParticlePairNoExclusions) + "D=abs(r-sr2)", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(0.8*psi+2.909125*psi^3)/radius);" - "psi=I*or; or=radius-offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, SA, cutoff, kappa) + "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) return custom """ @@ -285,22 +275,17 @@ def GBSAOBC2Force(solventDielectric=78.5, soluteDielectric=1, SA=None, custom = CustomGBForce() custom.addPerParticleParameter("q") - custom.addPerParticleParameter("radius") - custom.addPerParticleParameter("scale") - if kappa > 0: custom.addGlobalParameter('kappa', kappa) - custom.addGlobalParameter("solventDielectric", solventDielectric) - custom.addGlobalParameter("soluteDielectric", soluteDielectric) + custom.addPerParticleParameter("or") # Offset radius + custom.addPerParticleParameter("sr") # Scaled offset radius custom.addGlobalParameter("offset", 0.009) custom.addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r);" "U=r+sr2;" "L=max(or1, D);" - "D=abs(r-sr2);" - "sr2 = scale2*or2;" - "or1 = radius1-offset; or2 = radius2-offset", CustomGBForce.ParticlePairNoExclusions) + "D=abs(r-sr2)", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(psi-0.8*psi^2+4.85*psi^3)/radius);" - "psi=I*or; or=radius-offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, SA, cutoff, kappa) + "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) return custom """ @@ -321,15 +306,10 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None, custom = CustomGBForce() custom.addPerParticleParameter("q") - custom.addPerParticleParameter("radius") - custom.addPerParticleParameter("scale") + custom.addPerParticleParameter("or") # Offset radius + custom.addPerParticleParameter("sr") # Scaled offset radius - if kappa > 0: custom.addGlobalParameter('kappa', kappa) - custom.addGlobalParameter("solventDielectric", solventDielectric) - custom.addGlobalParameter("soluteDielectric", soluteDielectric) custom.addGlobalParameter("offset", 0.009) - custom.addGlobalParameter("neckScale", 0.361825) - custom.addGlobalParameter("neckCut", 0.68) custom.addTabulatedFunction("getd0", Discrete1DFunction(d0)) custom.addTabulatedFunction("getm0", Discrete1DFunction(m0)) @@ -341,12 +321,12 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None, "U=r+sr2;" "L=max(or1, D);" "D=abs(r-sr2);" - "sr2 = scale2*or2;" - "or1 = radius1-offset; or2 = radius2-offset", CustomGBForce.ParticlePairNoExclusions) + "radius1=or1+offset; radius2=or2+offset;" + "neckScale=0.361825; neckCut=0.68", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(1.09511284*psi-1.907992938*psi^2+2.50798245*psi^3)/radius);" - "psi=I*or; or=radius-offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, SA, cutoff, kappa) + "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) return custom """ @@ -367,18 +347,13 @@ def GBSAGBn2Force(solventDielectric=78.5, soluteDielectric=1, SA=None, custom = CustomGBForce() custom.addPerParticleParameter("q") - custom.addPerParticleParameter("radius") - custom.addPerParticleParameter("scale") + custom.addPerParticleParameter("or") # Offset radius + custom.addPerParticleParameter("sr") # Scaled offset radius custom.addPerParticleParameter("alpha") custom.addPerParticleParameter("beta") custom.addPerParticleParameter("gamma") - if kappa > 0: custom.addGlobalParameter('kappa', kappa) - custom.addGlobalParameter("solventDielectric", solventDielectric) - custom.addGlobalParameter("soluteDielectric", soluteDielectric) custom.addGlobalParameter("offset", 0.0195141) - custom.addGlobalParameter("neckScale", 0.826836) - custom.addGlobalParameter("neckCut", 0.68) custom.addTabulatedFunction("getd0", Discrete1DFunction(d0)) custom.addTabulatedFunction("getm0", Discrete1DFunction(m0)) @@ -390,10 +365,24 @@ def GBSAGBn2Force(solventDielectric=78.5, soluteDielectric=1, SA=None, "U=r+sr2;" "L=max(or1, D);" "D=abs(r-sr2);" - "sr2 = scale2*or2;" - "or1 = radius1-offset; or2 = radius2-offset", CustomGBForce.ParticlePairNoExclusions) + "radius1=or1+offset; radius2=or2+offset;" + "neckScale=0.826836; neckCut=0.68", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(alpha*psi-beta*psi^2+gamma*psi^3)/radius);" - "psi=I*or; or=radius-offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, SA, cutoff, kappa) + "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) return custom + + +def convertParameters(params, gbmodel): + """Convert the GB parameters from the file into the values expected by the appropriate CustomGBForce.""" + newparams = [None]*len(params) + if gbmodel == 'GBn2': + offset = 0.0195141 + else: + offset = 0.009 + for i in range(len(params)): + newparams[i] = list(params[i]) + newparams[i][0] -= offset + newparams[i][1] *= newparams[i][0] + return newparams \ No newline at end of file diff --git a/wrappers/python/tests/TestAmberPrmtopFile.py b/wrappers/python/tests/TestAmberPrmtopFile.py index 9c00e969e..7b5982ea4 100644 --- a/wrappers/python/tests/TestAmberPrmtopFile.py +++ b/wrappers/python/tests/TestAmberPrmtopFile.py @@ -100,24 +100,13 @@ class TestAmberPrmtopFile(unittest.TestCase): for method in methodMap: system = prmtop2.createSystem(implicitSolvent=implicitSolvent_value, solventDielectric=50.0, soluteDielectric=0.9, nonbondedMethod=method) - found_matching_solvent_dielectric=False - found_matching_solute_dielectric=False if implicitSolvent_value in set([HCT, OBC1, GBn]): for force in system.getForces(): if isinstance(force, CustomGBForce): self.assertEqual(force.getNonbondedMethod(), methodMap[method]) - for j in range(force.getNumGlobalParameters()): - if (force.getGlobalParameterName(j) == 'solventDielectric' and - force.getGlobalParameterDefaultValue(j) == 50.0): - found_matching_solvent_dielectric = True - if (force.getGlobalParameterName(j) == 'soluteDielectric' and - force.getGlobalParameterDefaultValue(j) == 0.9): - found_matching_solute_dielectric = True if isinstance(force, NonbondedForce): self.assertEqual(force.getReactionFieldDielectric(), 1.0) self.assertEqual(force.getNonbondedMethod(), methodMap[method]) - self.assertTrue(found_matching_solvent_dielectric and - found_matching_solute_dielectric) else: for force in system.getForces(): if isinstance(force, GBSAOBCForce): @@ -240,6 +229,25 @@ class TestAmberPrmtopFile(unittest.TestCase): # Make sure the energy is relatively close to the value we get with # Amber using this force field. self.assertAlmostEqual(-7307.2735621/ene, 1, places=3) + + def test_ImplicitSolventForces(self): + """Compute forces for different implicit solvent types, and compare them to ones generated with a previous version of OpenMM to ensure they haven't changed.""" + + solventType = [HCT, OBC1, OBC2, GBn, GBn2] + nonbondedMethod = [NoCutoff, CutoffNonPeriodic, CutoffNonPeriodic, NoCutoff, NoCutoff] + salt = [0.0, 0.0, 0.5, 0.5, 0.0]*(moles/liter) + file = ['HCT_NoCutoff', 'OBC1_NonPeriodic', 'OBC2_NonPeriodic_Salt', 'GBn_NoCutoff_Salt', 'GBn2_NoCutoff'] + pdb = PDBFile('systems/alanine-dipeptide-implicit.pdb') + for i in range(5): + system = prmtop2.createSystem(implicitSolvent=solventType[i], nonbondedMethod=nonbondedMethod[i], implicitSolventSaltConc=salt[i]) + integrator = VerletIntegrator(0.001) + context = Context(system, integrator, Platform.getPlatformByName("CPU")) + context.setPositions(pdb.positions) + state1 = context.getState(getForces=True) + state2 = XmlSerializer.deserialize(open('systems/alanine-dipeptide-implicit-forces/'+file[i]+'.xml').read()) + for f1, f2, in zip(state1.getForces().value_in_unit(kilojoules_per_mole/nanometer), state2.getForces().value_in_unit(kilojoules_per_mole/nanometer)): + diff = norm(f1-f2) + self.assertTrue(diff < 0.1 or diff/norm(f1) < 1e-4) if __name__ == '__main__': unittest.main() diff --git a/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn2_NoCutoff.xml b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn2_NoCutoff.xml new file mode 100644 index 000000000..b24e5e471 --- /dev/null +++ b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn2_NoCutoff.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn_NoCutoff_Salt.xml b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn_NoCutoff_Salt.xml new file mode 100644 index 000000000..06d4dfdce --- /dev/null +++ b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/GBn_NoCutoff_Salt.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/HCT_NoCutoff.xml b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/HCT_NoCutoff.xml new file mode 100644 index 000000000..e49a98032 --- /dev/null +++ b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/HCT_NoCutoff.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC1_NonPeriodic.xml b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC1_NonPeriodic.xml new file mode 100644 index 000000000..3b68f7c5c --- /dev/null +++ b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC1_NonPeriodic.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml new file mode 100644 index 000000000..c9571da7a --- /dev/null +++ b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 71b67421c6c898c192ce9000bffb92dca9aecba0 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 23 Oct 2014 10:27:26 -0700 Subject: [PATCH 067/338] Further optimizations to custom GB models --- .../openmm/app/internal/customgbforces.py | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/customgbforces.py b/wrappers/python/simtk/openmm/app/internal/customgbforces.py index 5c1effeb0..e8f6619f3 100644 --- a/wrappers/python/simtk/openmm/app/internal/customgbforces.py +++ b/wrappers/python/simtk/openmm/app/internal/customgbforces.py @@ -189,10 +189,12 @@ for i in range (len(d0)): m0[i]=m0[i]*10 -def _createEnergyTerms(force, solventDielectric, soluteDielectric, SA, cutoff, kappa): +def _createEnergyTerms(force, solventDielectric, soluteDielectric, SA, cutoff, kappa, offset): # Add the energy terms to the CustomGBForce. These are identical for all the GB models. - params = "; solventDielectric="+str(solventDielectric)+"; soluteDielectric="+str(soluteDielectric)+"; kappa="+str(kappa)+"; cutoff="+str(cutoff) + params = "; solventDielectric=%.16g; soluteDielectric=%.16g; kappa=%.16g; offset=%.16g" % (solventDielectric, soluteDielectric, kappa, offset) + if cutoff is not None: + params += "; cutoff=%.16g" % cutoff if kappa > 0: force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-exp(-kappa*B)/solventDielectric)*q^2/B"+params, CustomGBForce.SingleParticle) @@ -203,7 +205,7 @@ def _createEnergyTerms(force, solventDielectric, soluteDielectric, SA, cutoff, k force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*q^2/B"+params, CustomGBForce.SingleParticle) if SA=='ACE': - force.addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6; radius=or+offset", CustomGBForce.SingleParticle) + force.addEnergyTerm("28.3919551*(radius+0.14)^2*(radius/B)^6; radius=or+offset"+params, CustomGBForce.SingleParticle) elif SA is not None: raise ValueError('Unknown surface area method: '+SA) if cutoff is None: @@ -234,14 +236,13 @@ def GBSAHCTForce(solventDielectric=78.5, soluteDielectric=1, SA=None, custom.addPerParticleParameter("q") custom.addPerParticleParameter("or") # Offset radius custom.addPerParticleParameter("sr") # Scaled offset radius - custom.addGlobalParameter("offset", 0.009) custom.addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r);" "U=r+sr2;" "L=max(or1, D);" "D=abs(r-sr2)", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-I)", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa, 0.009) return custom """ @@ -255,15 +256,14 @@ def GBSAOBC1Force(solventDielectric=78.5, soluteDielectric=1, SA=None, custom.addPerParticleParameter("q") custom.addPerParticleParameter("or") # Offset radius custom.addPerParticleParameter("sr") # Scaled offset radius - custom.addGlobalParameter("offset", 0.009) custom.addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r);" "U=r+sr2;" "L=max(or1, D);" "D=abs(r-sr2)", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(0.8*psi+2.909125*psi^3)/radius);" - "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) + "psi=I*or; radius=or+offset; offset=0.009", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa, 0.009) return custom """ @@ -277,15 +277,14 @@ def GBSAOBC2Force(solventDielectric=78.5, soluteDielectric=1, SA=None, custom.addPerParticleParameter("q") custom.addPerParticleParameter("or") # Offset radius custom.addPerParticleParameter("sr") # Scaled offset radius - custom.addGlobalParameter("offset", 0.009) custom.addComputedValue("I", "step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r);" "U=r+sr2;" "L=max(or1, D);" "D=abs(r-sr2)", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(psi-0.8*psi^2+4.85*psi^3)/radius);" - "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) + "psi=I*or; radius=or+offset; offset=0.009", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa, 0.009) return custom """ @@ -309,8 +308,6 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None, custom.addPerParticleParameter("or") # Offset radius custom.addPerParticleParameter("sr") # Scaled offset radius - custom.addGlobalParameter("offset", 0.009) - custom.addTabulatedFunction("getd0", Discrete1DFunction(d0)) custom.addTabulatedFunction("getm0", Discrete1DFunction(m0)) @@ -322,11 +319,11 @@ def GBSAGBnForce(solventDielectric=78.5, soluteDielectric=1, SA=None, "L=max(or1, D);" "D=abs(r-sr2);" "radius1=or1+offset; radius2=or2+offset;" - "neckScale=0.361825; neckCut=0.68", CustomGBForce.ParticlePairNoExclusions) + "neckScale=0.361825; neckCut=0.68; offset=0.009", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(1.09511284*psi-1.907992938*psi^2+2.50798245*psi^3)/radius);" - "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) + "psi=I*or; radius=or+offset; offset=0.009", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa, 0.009) return custom """ @@ -353,8 +350,6 @@ def GBSAGBn2Force(solventDielectric=78.5, soluteDielectric=1, SA=None, custom.addPerParticleParameter("beta") custom.addPerParticleParameter("gamma") - custom.addGlobalParameter("offset", 0.0195141) - custom.addTabulatedFunction("getd0", Discrete1DFunction(d0)) custom.addTabulatedFunction("getm0", Discrete1DFunction(m0)) @@ -366,11 +361,11 @@ def GBSAGBn2Force(solventDielectric=78.5, soluteDielectric=1, SA=None, "L=max(or1, D);" "D=abs(r-sr2);" "radius1=or1+offset; radius2=or2+offset;" - "neckScale=0.826836; neckCut=0.68", CustomGBForce.ParticlePairNoExclusions) + "neckScale=0.826836; neckCut=0.68; offset=0.0195141", CustomGBForce.ParticlePairNoExclusions) custom.addComputedValue("B", "1/(1/or-tanh(alpha*psi-beta*psi^2+gamma*psi^3)/radius);" - "psi=I*or; radius=or+offset", CustomGBForce.SingleParticle) - _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa) + "psi=I*or; radius=or+offset; offset=0.0195141", CustomGBForce.SingleParticle) + _createEnergyTerms(custom, solventDielectric, soluteDielectric, SA, cutoff, kappa, 0.0195141) return custom -- GitLab From 1a5029cfc7bf3757af79ef977831d44481f22930 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 23 Oct 2014 12:45:48 -0700 Subject: [PATCH 068/338] Further improvements to handling of weird PDB files created by VMD --- .../simtk/openmm/app/internal/pdbstructure.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py index 0442bd333..55062992f 100644 --- a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py +++ b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py @@ -741,8 +741,21 @@ class Atom(object): self.residue_number = int(pdb_line[22:26], 16) pdbstructure._residue_numbers_are_hex = True except: - # Just give it the next number in sequence. - self.residue_number = pdbstructure._next_residue_number + # When VMD runs out of hex values it starts filling the residue ID field with ****. + # Look at the most recent atoms to figure out whether this is a new residue or not. + if pdbstructure._current_model is None or pdbstructure._current_model._current_chain is None or pdbstructure._current_model._current_chain._current_residue is None: + # This is the first residue in the model. + self.residue_number = pdbstructure._next_residue_number + else: + currentRes = pdbstructure._current_model._current_chain._current_residue + if currentRes.name_with_spaces != self.residue_name_with_spaces: + # The residue name has changed. + self.residue_number = pdbstructure._next_residue_number + elif self.name_with_spaces in currentRes.atoms_by_name: + # There is already an atom with this name. + self.residue_number = pdbstructure._next_residue_number + else: + self.residue_number = currentRes.number self.insertion_code = pdb_line[26] # coordinates, occupancy, and temperature factor belong in Atom.Location object x = float(pdb_line[30:38]) -- GitLab From 5bed3590e6c1c9b7fb03e9a17e633c250f6d8c34 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 23 Oct 2014 14:33:29 -0700 Subject: [PATCH 069/338] Fixed CHARMM parser to work with changes to custom GB models --- .../python/simtk/openmm/app/charmmpsffile.py | 3 +- wrappers/python/tests/TestCharmmFiles.py | 32 ++++++++------ .../GBn2_NoCutoff.xml | 43 +++++++++++++++++++ .../GBn_NoCutoff_Salt.xml | 43 +++++++++++++++++++ .../HCT_NoCutoff.xml | 43 +++++++++++++++++++ .../OBC1_NonPeriodic.xml | 43 +++++++++++++++++++ .../OBC2_NonPeriodic_Salt.xml | 43 +++++++++++++++++++ 7 files changed, 237 insertions(+), 13 deletions(-) create mode 100644 wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn2_NoCutoff.xml create mode 100644 wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn_NoCutoff_Salt.xml create mode 100644 wrappers/python/tests/systems/ala-ala-ala-implicit-forces/HCT_NoCutoff.xml create mode 100644 wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC1_NonPeriodic.xml create mode 100644 wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml diff --git a/wrappers/python/simtk/openmm/app/charmmpsffile.py b/wrappers/python/simtk/openmm/app/charmmpsffile.py index eda101aa4..6da569c44 100644 --- a/wrappers/python/simtk/openmm/app/charmmpsffile.py +++ b/wrappers/python/simtk/openmm/app/charmmpsffile.py @@ -43,7 +43,7 @@ import simtk.unit as u from simtk.openmm.app import (forcefield as ff, Topology, element) from simtk.openmm.app.amberprmtopfile import HCT, OBC1, OBC2, GBn, GBn2 from simtk.openmm.app.internal.customgbforces import (GBSAHCTForce, - GBSAOBC1Force, GBSAOBC2Force, GBSAGBnForce, GBSAGBn2Force) + GBSAOBC1Force, GBSAOBC2Force, GBSAGBnForce, GBSAGBn2Force, convertParameters) # CHARMM imports from simtk.openmm.app.internal.charmm.topologyobjects import ( ResidueList, AtomList, TrackedList, Bond, Angle, Dihedral, @@ -1374,6 +1374,7 @@ class CharmmPsfFile(object): if implicitSolvent is not None: if verbose: print('Adding GB parameters...') gb_parms = self._get_gb_params(implicitSolvent) + gb_parms = convertParameters(gb_parms, str(implicitSolvent)) # If implicitSolventKappa is None, compute it from salt # concentration diff --git a/wrappers/python/tests/TestCharmmFiles.py b/wrappers/python/tests/TestCharmmFiles.py index 8d8374636..53aa3f5c6 100644 --- a/wrappers/python/tests/TestCharmmFiles.py +++ b/wrappers/python/tests/TestCharmmFiles.py @@ -69,21 +69,9 @@ class TestCharmmFiles(unittest.TestCase): system = self.psf_x.createSystem(self.params, implicitSolvent=GBn, solventDielectric=50.0, soluteDielectric = 0.9) - found_matching_solvent_dielectric=False - found_matching_solute_dielectric=False for force in system.getForces(): - if isinstance(force, CustomGBForce): - for i in range(force.getNumGlobalParameters()): - if force.getGlobalParameterName(i) == 'solventDielectric': - if force.getGlobalParameterDefaultValue(i) == 50.0: - found_matching_solvent_dielectric = True - elif force.getGlobalParameterName(i) == 'soluteDielectric': - if force.getGlobalParameterDefaultValue(i) == 0.9: - found_matching_solute_dielectric = True if isinstance(force, NonbondedForce): self.assertEqual(force.getReactionFieldDielectric(), 1.0) - self.assertTrue(found_matching_solvent_dielectric and - found_matching_solute_dielectric) def test_HydrogenMass(self): """Test that altering the mass of hydrogens works correctly.""" @@ -127,6 +115,26 @@ class TestCharmmFiles(unittest.TestCase): ene = state.getPotentialEnergy().value_in_unit(kilocalories_per_mole) self.assertAlmostEqual(ene, 15490.0033559, delta=0.05) + def test_ImplicitSolventForces(self): + """Compute forces for different implicit solvent types, and compare them to ones generated with a previous version of OpenMM to ensure they haven't changed.""" + solventType = [HCT, OBC1, OBC2, GBn, GBn2] + nonbondedMethod = [NoCutoff, CutoffNonPeriodic, CutoffNonPeriodic, NoCutoff, NoCutoff] + salt = [0.0, 0.0, 0.5, 0.5, 0.0]*(moles/liter) + file = ['HCT_NoCutoff', 'OBC1_NonPeriodic', 'OBC2_NonPeriodic_Salt', 'GBn_NoCutoff_Salt', 'GBn2_NoCutoff'] + for i in range(5): + system = self.psf_c.createSystem(self.params, implicitSolvent=solventType[i], nonbondedMethod=nonbondedMethod[i], implicitSolventSaltConc=salt[i]) + integrator = VerletIntegrator(0.001) + context = Context(system, integrator, Platform.getPlatformByName("CPU")) + context.setPositions(self.pdb.positions) + state1 = context.getState(getForces=True) + #out = open('systems/ala-ala-ala-implicit-forces/'+file[i]+'.xml', 'w') + #out.write(XmlSerializer.serialize(state1)) + #out.close() + state2 = XmlSerializer.deserialize(open('systems/ala-ala-ala-implicit-forces/'+file[i]+'.xml').read()) + for f1, f2, in zip(state1.getForces().value_in_unit(kilojoules_per_mole/nanometer), state2.getForces().value_in_unit(kilojoules_per_mole/nanometer)): + diff = norm(f1-f2) + self.assertTrue(diff < 0.1 or diff/norm(f1) < 1e-4) + if __name__ == '__main__': unittest.main() diff --git a/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn2_NoCutoff.xml b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn2_NoCutoff.xml new file mode 100644 index 000000000..fe4c6b1f9 --- /dev/null +++ b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn2_NoCutoff.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn_NoCutoff_Salt.xml b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn_NoCutoff_Salt.xml new file mode 100644 index 000000000..42bd16e82 --- /dev/null +++ b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/GBn_NoCutoff_Salt.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/HCT_NoCutoff.xml b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/HCT_NoCutoff.xml new file mode 100644 index 000000000..fb8f19b14 --- /dev/null +++ b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/HCT_NoCutoff.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC1_NonPeriodic.xml b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC1_NonPeriodic.xml new file mode 100644 index 000000000..cc6bcfe28 --- /dev/null +++ b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC1_NonPeriodic.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml new file mode 100644 index 000000000..b1f2c1487 --- /dev/null +++ b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 87ea8433d0f86319b2ce63ae3eaab5ee81f2a12e Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 23 Oct 2014 16:37:38 -0700 Subject: [PATCH 070/338] Minor optimization to discrete tabulated functions --- platforms/cuda/src/CudaExpressionUtilities.cpp | 12 ++++++------ platforms/opencl/src/OpenCLExpressionUtilities.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/platforms/cuda/src/CudaExpressionUtilities.cpp b/platforms/cuda/src/CudaExpressionUtilities.cpp index 67ca749a1..c43624257 100644 --- a/platforms/cuda/src/CudaExpressionUtilities.cpp +++ b/platforms/cuda/src/CudaExpressionUtilities.cpp @@ -239,7 +239,7 @@ void CudaExpressionUtilities::processExpression(stringstream& out, const Express if (derivOrder[0] == 0) { out << "real x = " << getTempName(node.getChildren()[0], temps) << ";\n"; out << "if (x >= 0 && x < " << paramsInt[0] << ") {\n"; - out << "int index = (int) round(x);\n"; + out << "int index = (int) floor(x+0.5f);\n"; out << nodeNames[j] << " = " << functionNames[i].second << "[index];\n"; out << "}\n"; } @@ -249,8 +249,8 @@ void CudaExpressionUtilities::processExpression(stringstream& out, const Express for (int j = 0; j < nodes.size(); j++) { const vector& derivOrder = dynamic_cast(&nodes[j]->getOperation())->getDerivOrder(); if (derivOrder[0] == 0 && derivOrder[1] == 0) { - out << "int x = (int) round(" << getTempName(node.getChildren()[0], temps) << ");\n"; - out << "int y = (int) round(" << getTempName(node.getChildren()[1], temps) << ");\n"; + out << "int x = (int) floor(" << getTempName(node.getChildren()[0], temps) << "+0.5f);\n"; + out << "int y = (int) floor(" << getTempName(node.getChildren()[1], temps) << "+0.5f);\n"; out << "int xsize = (int) " << paramsInt[0] << ";\n"; out << "int ysize = (int) " << paramsInt[1] << ";\n"; out << "int index = x+y*xsize;\n"; @@ -263,9 +263,9 @@ void CudaExpressionUtilities::processExpression(stringstream& out, const Express for (int j = 0; j < nodes.size(); j++) { const vector& derivOrder = dynamic_cast(&nodes[j]->getOperation())->getDerivOrder(); if (derivOrder[0] == 0 && derivOrder[1] == 0 && derivOrder[2] == 0) { - out << "int x = (int) round(" << getTempName(node.getChildren()[0], temps) << ");\n"; - out << "int y = (int) round(" << getTempName(node.getChildren()[1], temps) << ");\n"; - out << "int z = (int) round(" << getTempName(node.getChildren()[2], temps) << ");\n"; + out << "int x = (int) floor(" << getTempName(node.getChildren()[0], temps) << "+0.5f);\n"; + out << "int y = (int) floor(" << getTempName(node.getChildren()[1], temps) << "+0.5f);\n"; + out << "int z = (int) floor(" << getTempName(node.getChildren()[2], temps) << "+0.5f);\n"; out << "int xsize = (int) " << paramsInt[0] << ";\n"; out << "int ysize = (int) " << paramsInt[1] << ";\n"; out << "int zsize = (int) " << paramsInt[2] << ";\n"; diff --git a/platforms/opencl/src/OpenCLExpressionUtilities.cpp b/platforms/opencl/src/OpenCLExpressionUtilities.cpp index 59a936d0f..2fd83226e 100644 --- a/platforms/opencl/src/OpenCLExpressionUtilities.cpp +++ b/platforms/opencl/src/OpenCLExpressionUtilities.cpp @@ -239,7 +239,7 @@ void OpenCLExpressionUtilities::processExpression(stringstream& out, const Expre if (derivOrder[0] == 0) { out << "real x = " << getTempName(node.getChildren()[0], temps) << ";\n"; out << "if (x >= 0 && x < " << paramsInt[0] << ") {\n"; - out << "int index = (int) round(x);\n"; + out << "int index = (int) floor(x+0.5f);\n"; out << nodeNames[j] << " = " << functionNames[i].second << "[index];\n"; out << "}\n"; } @@ -249,8 +249,8 @@ void OpenCLExpressionUtilities::processExpression(stringstream& out, const Expre for (int j = 0; j < nodes.size(); j++) { const vector& derivOrder = dynamic_cast(&nodes[j]->getOperation())->getDerivOrder(); if (derivOrder[0] == 0 && derivOrder[1] == 0) { - out << "int x = (int) round(" << getTempName(node.getChildren()[0], temps) << ");\n"; - out << "int y = (int) round(" << getTempName(node.getChildren()[1], temps) << ");\n"; + out << "int x = (int) floor(" << getTempName(node.getChildren()[0], temps) << "+0.5f);\n"; + out << "int y = (int) floor(" << getTempName(node.getChildren()[1], temps) << "+0.5f);\n"; out << "int xsize = " << paramsInt[0] << ";\n"; out << "int ysize = " << paramsInt[1] << ";\n"; out << "int index = x+y*xsize;\n"; @@ -263,9 +263,9 @@ void OpenCLExpressionUtilities::processExpression(stringstream& out, const Expre for (int j = 0; j < nodes.size(); j++) { const vector& derivOrder = dynamic_cast(&nodes[j]->getOperation())->getDerivOrder(); if (derivOrder[0] == 0 && derivOrder[1] == 0 && derivOrder[2] == 0) { - out << "int x = (int) round(" << getTempName(node.getChildren()[0], temps) << ");\n"; - out << "int y = (int) round(" << getTempName(node.getChildren()[1], temps) << ");\n"; - out << "int z = (int) round(" << getTempName(node.getChildren()[2], temps) << ");\n"; + out << "int x = (int) floor(" << getTempName(node.getChildren()[0], temps) << "+0.5f);\n"; + out << "int y = (int) floor(" << getTempName(node.getChildren()[1], temps) << "+0.5f);\n"; + out << "int z = (int) floor(" << getTempName(node.getChildren()[2], temps) << "+0.5f);\n"; out << "int xsize = " << paramsInt[0] << ";\n"; out << "int ysize = " << paramsInt[1] << ";\n"; out << "int zsize = " << paramsInt[2] << ";\n"; -- GitLab From c7cacbbf9d352e4766d0703b6ce6942913a72e15 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sun, 26 Oct 2014 15:14:52 -0400 Subject: [PATCH 071/338] Added manifests to use for creating source and binary distributions. --- devtools/packaging/manifests/README.md | 9 +++++++++ devtools/packaging/manifests/binary/manifest.txt | 5 +++++ devtools/packaging/manifests/source/manifest.txt | 12 ++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 devtools/packaging/manifests/README.md create mode 100644 devtools/packaging/manifests/binary/manifest.txt create mode 100644 devtools/packaging/manifests/source/manifest.txt diff --git a/devtools/packaging/manifests/README.md b/devtools/packaging/manifests/README.md new file mode 100644 index 000000000..23beab9e7 --- /dev/null +++ b/devtools/packaging/manifests/README.md @@ -0,0 +1,9 @@ +# Manifests for automated packaging of source and binary distributions + +A detailed explanation of packaging protocols can be found on the developer wiki: +https://github.com/pandegroup/openmm/wiki/Packaging-OpenMM-installers + +## Contents +* `source/` - directories and files to be copied from the GitHub repo for a source distribution +* `binary/` - directories and files to be copied from install directory after build for a binary distribution + diff --git a/devtools/packaging/manifests/binary/manifest.txt b/devtools/packaging/manifests/binary/manifest.txt new file mode 100644 index 000000000..4ff612d6c --- /dev/null +++ b/devtools/packaging/manifests/binary/manifest.txt @@ -0,0 +1,5 @@ +docs +examples +include +lib +licenses diff --git a/devtools/packaging/manifests/source/manifest.txt b/devtools/packaging/manifests/source/manifest.txt new file mode 100644 index 000000000..ebe522954 --- /dev/null +++ b/devtools/packaging/manifests/source/manifest.txt @@ -0,0 +1,12 @@ +cmake_modules +CMakeLists.txt +docs-source +examples +libraries +olla +openmmapi +platforms +plugins +serialization +tests +wrappers -- GitLab From 5a106de08f7a1b0c64ec64ddb6acafbfa1456316 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 27 Oct 2014 10:24:42 -0700 Subject: [PATCH 072/338] Mac builds are 64 bit only by default --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ddd80eb38..4c6f7c68d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,12 +116,12 @@ ELSE( CMAKE_SIZEOF_VOID_P EQUAL 8 ) ENDIF( CMAKE_SIZEOF_VOID_P EQUAL 8 ) IF (APPLE AND (NOT PNACL)) - # Build universal binaries compatible with OS X 10.7 + # Build 64 bit binaries compatible with OS X 10.7 IF (NOT CMAKE_OSX_DEPLOYMENT_TARGET) SET (CMAKE_OSX_DEPLOYMENT_TARGET "10.7" CACHE STRING "The minimum version of OS X to support" FORCE) ENDIF (NOT CMAKE_OSX_DEPLOYMENT_TARGET) IF (NOT CMAKE_OSX_ARCHITECTURES) - SET (CMAKE_OSX_ARCHITECTURES "i386;x86_64" CACHE STRING "The processor architectures to build for" FORCE) + SET (CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "The processor architectures to build for" FORCE) ENDIF (NOT CMAKE_OSX_ARCHITECTURES) # Improve the linking behavior of Mac libraries -- GitLab From a6f749d1f525ecf0fbf30a282decbf61d0c2cd53 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 27 Oct 2014 11:39:14 -0700 Subject: [PATCH 073/338] Added 64 bit version of Windows pthreads library --- CMakeLists.txt | 8 ++++++-- libraries/pthreads/lib/pthreadVC2_x64.dll | Bin 0 -> 42496 bytes libraries/pthreads/lib/pthreadVC2_x64.lib | Bin 0 -> 29322 bytes 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 libraries/pthreads/lib/pthreadVC2_x64.dll create mode 100644 libraries/pthreads/lib/pthreadVC2_x64.lib diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c6f7c68d..8d141a93d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,8 +89,12 @@ IF(WIN32) INSTALL(FILES ${lib} DESTINATION "lib/") ENDFOREACH(lib) LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") - SET(PTHREADS_LIB pthreadVC2) - SET(PTHREADS_LIB_STATIC pthreadVC2_static_mt) + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(PTHREADS_LIB pthreadVC2_x64) + ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(PTHREADS_LIB pthreadVC2) + SET(PTHREADS_LIB_STATIC pthreadVC2_static_mt) + ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) ELSE(WIN32) IF (NOT ANDROID) SET(PTHREADS_LIB pthread) diff --git a/libraries/pthreads/lib/pthreadVC2_x64.dll b/libraries/pthreads/lib/pthreadVC2_x64.dll new file mode 100644 index 0000000000000000000000000000000000000000..8c2904638e5beba20175117db9e521f817045e2e GIT binary patch literal 42496 zcmeIbdw5jU)xf=TWe5oqE`t$42MiW3U?eDs0Zm8(ClVkEY7{gHNsvfL(qu-VD3=bY zPLHwF)@obZ^7ekQt-ZW0YFmS#5kaBU3zoK`we3lxEo!THJ>PHbeP%KfLi@hY^ZoO^ zUx#OB?X$0Iuf6u#Yp=b|Vez%wRhm*No#47k?F7oNRR8_ge~yto`izH0tDla1YRb-( z>ZhhGU(?bR?C5O2p|fFKu(6@7tvwW6)g0^$w*_0;f)z`b1=qDVHP6h+$;$Vd{^XKx zyHB70`2DfaclDL`@8`Mi>SgyI(6I9UJ`LyV^#1-|-oH&PC~-3l+n%XFa`A(d&$fuY$qiAN~OKduFgi%G)YNsx#re(3eJ`EqXg;q>x6_~sZ#S39{&?fpnw%!nV);L6?rvi*<%V_%YMP`JLcb2 z=Cc}~=C1Cva=*!7ZBR zHL>pz)5J5BD?DOFC+~yly4_HQBZ9-~$@wEqx`Ef)^utx(l!v3{p-Sic#yq^QA09Uk z?fT(C^YAhax`F$7ursbFZrO~@vKhCgz<%>H^qD6d@89-2>DtaIlG5FKL%GiBR}kyV zI8(AsUVc0;)#UkOc|AD=y8FANdpqa7F99O&q=cpkt%LqEws}ol6LbTA(9^WfioBN+ zeob%+GUC^1$qk%ou$O+^z$Wu>kAC>5dC1beG?@oM+zni99!&q2nTN0GoOwL-Wvuv` z?%PbgH*gPB+rL`|4eBjBrK)Gy(W>a8gH|-vvder`edUMspriABJm*%~E66T?f_Pq4 zbj42My>4K<9!X9HJy`Z{oTn}a_AKhK>}UGQrwd~_O)HhEun)sa(=59>f4aMz8L$sq zc13>B-e*N?;r$*yXuWF<5xW zih@Xao@v2~vZn2QPE;C_e5N%VVtKPf9~!==5>Zq9kpJB}s((AXf%rralo+9$ zi+r}Ct@#WhlpnmhY>B5nka@BFCBZ>57DvA% zeLK&wYs<6qCGx9momk!Yq1AoFzilQ3R<9mh--~=!WLK`!c(ziJBlA_#p)#~@ZmewhC^#CH2s_cHt z-@TDkS$VYT-K*&4R2-hr=btdKX6R|~90Sa9c&**|;!<9|4<+}iqR z@V`bV>+Qc<_HV6S?~S#PZM&RHt+c};EVS@w>2=bWx3t4<;B}_AT11ck=N0+W7q=Xd zoa(g0RV7C@omO`4k;r>)c+^g)d1nLzBOrXyG{iRod4+~RPH=8*Fzwo27 z6Tv=9*mrJ_VLR_E28_0kyMgN@VV~x*Cnb8od7eBe4YOp*63evgB|i6{WnYDe%b7-7 zjPuT>SgcZ9VglVDme{*~HSkW{iZ-$JX@h9{bnknRF3}>BqrDZY=QafeVO*BqZSp<{4W&&O_IU<96c4=NTmEr1I@j*-ZGraPrc;)>R z&xpL663&d)Apt|pW2m7_Ll!Xgrcvt4b`+S0`@`vmn@^Azi*lX2OQbjCT|V7vW*tB_#{^59 zaq6^U9g|A$2=Uih_Nhp}P_xx1+>ESQr1vA1XDGkOnM=d=F;Kch@Ns6u9$7N<_OoWq zopgj4qqrdGi7_(*8Kd(=u@L4A`|*Ki4JL!7V(S4!T0KOXL@pq)Hu{c5(%kTA_OkTo zIHv5TGm%X1<+@KgzDu>nHjtweoano*ivm}PfLcdDLG!|zk7F? zyRQtfghUYKn)My0$j}99*5^a%LJ1qiSUw-Cw;;wBO`8#zuPfWQ7f}h<2*iDPt%Y~z!%A9 zDr=pu28q}g4q&Jdc{;}p)RTqu-Dm-{^nI~`n32BKl6SzlhCC@f@~uyF&|V7I?q$ol zv(Zx@oJmZE)w87Ip;X=5YgF5>yDQY)F&Ly7^IvOr)5xAucryMRn-&s10daDA&Kf5J z`4{wj3k;xT$S1Vw=Rxo=^t@@33`5hi33^60)J&7K0eB=#7(0R~J^Rlz=coISHqe(;1mrs}O z{5=1U{_dXGziY2q1bD>7|!cBLRYiRRk9c>?WMlS$pX6uv$!)z}~^nmkf zr71mx*``1OLz^GIokW{0(zj4VPsgLOW?1pHtoYLSGWYZk`@%OrYZ_lPsEfFP>kU#H z=-43j`|IOKU1pHFT96u4Elyku9|sGAUT!jaFVTR=yREMtV?~PUCA9CW$gfGkLZ{{F z^>kO=Gx=)KrOd?atB&56pO+#lw~9;_&(=LsJvJc0KJTil%dSL?sqxN~!NRvVO4=Wq z^C3GmC%>MYS>L+R{W%@Z0nAiqY%BnO1S9FPv6pe?Z|3U3dlzm`4YZ+8KZ14VA2@j7ZAb~cp*7Aw&` zU&1ipG2{}-Jm9P#bC|`t9Wt32KmDIc4EcAe?YHbMmK64}C{J=?BKl>To|npa!Z$$d zH6OSx`=n(*m%M7+z)gam2!O(O%d7-Ct;W4EGcEm~6%T|3V|jrh;L@pPtyNU z+((KI7H|WtH1I!A_qBdK-ZICAY+1h}Y?Y`fmoCGCAg9iP%0jo=eyPfSksiW1=44aA zsdeQF=I<6xvQ&nFQbj5CM~YIyS&vL-#q_tsmJbyX6Nz5ibJvLtRbX3PoFPb8Om`3At85B{}-iQqxu#ea(-yC zv)sUyI(y(It7mPn%zm3SiDmcJ2?Hx15}bN2d%+FN*GL=}O)R6QBYR-ZpoN-#r90`i zI=ViWbK5n7{=%RX_G1t3>6qjOM$$l)jXC&MWq*j=&KE?S6)62g@|-IqB1-K`*Gjn; zIj%1oKpY~8b8h;S$j(}6)z0|!oe1gZ#_3qo3WRu=b!w-R{v*;Udl_XhpnXrCU{qq2B$<(_=%jpvrZ-8N-Sm1ypTv|PlNKynF2~iv z*O*!R1N)y$t$*8hm<_`b{%v29xISEC$M$byXAzWsu6zGHy;s?EA){UXch?1XNdH?# zWfu+PksNdupTfg&GUn(~f14#6KwgRziPmuYdx^#7m;L)n%znlUv4O4P8bnY(CZC{l00j*K z=88RdC2LKSxb8X_3aZ;T!|bj3vLE?+7P!%czJZzU!t|}1)6pI-4Ns+oJZIf&GR>SP z7pBYe*(03OE|50EQ=>X1=zNi53D4(7K1>Ops_VQ{pnJ`B1CKC5+ZP=*z#3YtoKk~M zs-Ob`!pT-LVn#l~uW@^(s3nC*s+bZRYtuWhCV~g1eO*YU#h8EFpCm5#E=ZG{eM|)R zDp$%%IipH!OQU7eJm5@y59{3Ffl-=*i#ae=9H#hvy7-+Gm!>(#W=G!3MJVp>N57+o zGc+GhFq{LozsjuGYT#ooS_jJ@M~^l97ptctzrLD3L8~XQMl61)J4G^%pe!d?25rRI z{0JxHjBZj)$+`FhUzjp+iaMWqX0v^u}uCVuNES?Ub z;(F1N5;h3*fPS&18SdD>e=&Vzl=YNO*xmnMk}TMm`#j7LLdfxY^~(|7zs)CcA(`H; zIOas{b}6JbE?NOc(y+2k%1No&(`g>7o`{Wve9LnJt|tB zE{9yZB$^i8=o`p#N10x@F$B9DsV=Me6rrpAyfevc5y+5P^kEl>R*>8_)rKVX_ra)f zT6-vX1T8$&|6l@n_dg^nrO+jT}KPfyzs?|FIIbjfE zkq*_*%3 zc+84c(tmHLQINPY^4{zAo3|{9yyxG{dVPHpEAYcxNBjzsx&wYvZ_V17O6`)v{-qFU zvE>{`QPNAtUhK1?YON|fEYE4c0GeoMGh`74hjO#`w};Vfu? zOtJt=eFNwEr<1taznPJVHZOJ|*_EDk?v%lC1Q=Om?{@<}uovBT2hGVvTZi3OWv?x& zvb##F>^}}~&_{kvXO_>6{52&sS^kU`L+MD^dV2qs0Bj~Sk|((xoZdeJ$>6LZT|X^F zw#F8+2le_*mXAR>3&AJT>OX;6#dYiJpd8Mqw*NH1)#JVznB=hY=ZnmhiyTZWN!kam zxPkwc=mF ztn4=mkGO#hDj??(=OKK_x%-fR+YyP##!-00#t~vyidfEms{38YnHl2} znX?H6QcCXv!P{_c_%*U@rLbZU^Ox96w4cLe<1KNjkXzEnmMBGgR0Qc+gPJPmB?f{n ztt*i2`B9*1e3B|!=cuAYs(2sZ-nMO!O{u*!Nu1? zByPRXMQ*6rRXiCOf7bNS^N}Rv;Boe%881aRFKhl2y`rXqKee))EH|(K++f0n*#L8r z+OycO4BFcTl6k|2XC=K2 z=9qP4XDlE!RvLb`xm>EH&o%5)9mdEk<{nvAHB6vo|ABNT+JTU+Jsj;g>IVL+T9N}< zwmWQY0|OL$5&E zpko+ERu0Rs9#eqf5Tprgi6JsU)zcHK?E%z8_0HK&t8Ul9o*cG?_WL|< zk*^oWP(P`Y$C)1b$xa>_2LH1R{_X~viEw9YxziTW?J)8|^mhwgmN{onwg0M>HRosO z;W_F^(9?;I6ogjIeUiMEcLXtFH92%wC(2uj6i#nn+I_un4ZKKJkM7k7hrZsK{$ zGs?XVqx^+|6uyRC2Ar$y)AcE7b{%rY4{_V4vJ6hE<@1M>JY$-M`}DK$H|R?_8;K0*J6^|U3M>sD-#d&A?z zhDDVkSz4t~lY@n5;8Q&#)*tT81mj21*Y(&d&G zQt4aT4BJZQns#qgE)lgO@xDY0v9`$;!2f|k*eL|Zqik;Gy%W1!T9I@&BN zs(vWF`%pN81M!$4juc)sDUTIZm&cD{{iw*hshcySmvi17wt`HkR)uTWE$~eh#}oLd zXCa-6T|nz?7(+hj^gHT(3M_F=9LWpS=1!iq7u55=SM{JO5PwgBKe)&`f3BQt$X(5z9;py zGFxceAYxk=jGVCBvgw-(os#&4&IQF?zHq=Thn49zxkrsi{!m0b)I(OB(Js0fvcnJURnMr*Po9WctZl^~=rh9$ojFdJYi()$+So+2%I1Dc z{u(_SA+1;4cCKiz=Oxa@8M^pJWCh09v*kgKVW2m_w)wPE_gg0TAjT~>aL4?Z7wYI3 z_K)`;g#wyU^;TH6^*y;V@>lHY-%Ezxke&1XVRqu6QSFjcYCSFI`nRDLA(o6ragu2{ zEj}${iq~@ZVp;~8cghS5)W^tviT{jJ+R>v4)g_PQ?ib=Cd9=(MiNCuvVJ;pw^RRa4 zJeZ3m*brh0)9G#Udb4&0UeWe0ec!@*IhFOoF5{12^TYAM7oKSM3D<|)wN_$SsNP#b znrTPB=}{+{U;hm;eiSFhx3tvFjFhLl;WKDIx-nNe+%V1v))!0ln#xF6GhX*`p(6Zb z@E7ETqh4TTpCu+iy|TZl=jJr6Q0Vy@6)qH>@^AYjIZ*_?NOh-@^PY?$D#pfAV0m8B zaEllD!dDxPm?%Zf<+0Yy;+omNWPpkBG3PS(No{Mhc2Y`wbnMs2zknzIJioIlWFPKU znsKoNA_Yo)aVg8Qop78H|68lt-bFKE%#7lFXJJVxR^c-u8<2CSI*VT9WXm1Y*DmEK zc8NTQ0JnDARlc1Oab|?TXsEa3mu}s4>3qL>yC1`-&}^4G*6!QooRN0C%vQ#oG3~hX z{;`u#$M`&i#|k5s_LOs3U@Y#|Zt)KBcmG9C)S@-^^KRh9ON^`$!<5!P&q6$)f1-Q( zdp_YMim)E)1~HSHUR*?O4p9$#3LECDG=(BMVj4hSpRSbzV~aT~(F4w(Scb#sp%Y7E zdg!;GlQG48ZZ<$Ek*T#BwTIb6%vfY#JGD_o=%=rrLz5D+MDQEZB9CU%_h6n!bLL(4 zS2yt7JUMG~E$YAv zIngWofJqXC_!|RsXGZx7ytVL`+2=;tnMf1;ZZAXFFo|JW&6L< z8_hUx9il5UIxioHg7Qmf!g~m`$T9b5Cx8P94rPH~XkyWHm-L2C7|lqbcdqjuqSU~M zYJ2kQM9^M2&Gh8V!_LCV_zzwSwO}={m}a_T&73D)NZal~{!T`_EuPmw>Ci=yoUZ_R zbs_E|M|-dRUblCrv}flm1TgNoOgncx^NMt8ytvt)BCi%j=FK1n5%HqT7;I+2Q)fzH zQ3tl_M5)E1z<~HkY3{J|ji~_5VIw8MaM(=}J>W#h)B3$Z4$izZvZ*2^jN9@OFjQwO#0EzsF%$rOl=<%jU52oe9ak?Go zaloU85fY{!=yCUy7(L#(I8Kk%^awq=$kTE_mfa>z1bsCWMW8Oh+F<#t2$!+Ev1CXv z=OBaaSyJnq{+5aKEtsB3x6UP87{w@wt}bFpt3^;$pXcQS9iwD{b5zqTmDY*)hJRQ~0>}Fpg$y_W2 zZFE!K#ghCYz1#I~Av5jqis+fqa^JvQb5VR91@fFe=m$59a|4To38-TiIjPhdSV}Q+ zGS5z{h&HC%g;E=L8fo=qysMT(b1a@@{p`DU-+ zcz~~eKB|eF(h7t-5o0-@fdp=#QVc7yLf?K-7{Ibl>x~>8h1in2ZQ;83ejYS7xBI9j zhU~di9CBgVAjCM~!g8(d=l4bAu{p|FQ6FSu9BuqV>@u2vp|31R6YA~5ys+VmmgPEs z7xrT5Qe#E`%RCr-^7K^|DR-cz+_r}^RDa_`#iZ2dj={E@ae@XL$ z9u`OS;I)T^kJsw@zY@#UGNvNBCXdrIU=jf@4U7yw&^3<95k|j=m*kUy?R5=48Ed$v zUcfl@@t52Puob-VS^H9z#v|qMqwG79DWBR7K~C=S0vLUk67t`hS7nU2}%P?^%%6_=UNB@OQTh*YqsKqUe0) zcd*}K_zjc6Q_eIn?7y7czJ>WOfB$~&GJfBG6_18r28|jCD^U)A{T23K#M^}{*sK)c zJadoxA%vH8=HK>nVp})rCSxkdK4<6a<}mU*Db};d=X{F|uNol+B(SAKp8u?DJi=hu489d~Mo>4QFn2gFZebE~YWDHq9TZdLe6NaKTk67@R! z(1k2pH#`zoy)u90Kg3fa;ijDR8MpZ81v$7B^^!^Qr#erxO~?Q*;7u^rS&Ht%<4E3f z@^{Oj0mng)njzyypqCQsaG%r248oZ$n0&Wx%wy^{3)dqDZ^8MnOpmmbB3k0)K~h7_ z;MwJQPA#VlNtYKT_BofynFHP|5S5wAgIyHFauU;#&#|j93|&|Q_J)QI<94jA@nL*1 zc^J9Ikbxla?zt`ddBI|~=8Ny9@w-l{iX ztj%<Ik3U@M$?%qvV;O~uuD@PKpMa1?5wt|h` z&#OiI;sy*OpL56auA5{}=~*V*Pp-2JO;C?NqqsbHi&MClMRfNr=NHdO?^K4RGovt4 zIV$#0WMaY|DEmoJ>McbE}n_hP9zbine~G1W-L#P1^RgFn^kd!_kPGJMg!4DlHiKn!>wl< zqQ@66i&`!Qe9qQaJ#;RL@MbK&VN4@}{JSE^k4uSxaqbfWqveyFZJw+G~_R zxeRd>U($p8&B7UW;trsC#3%0G$e-Wn3Hz7wrx$-4P0u0n=WsIr^EABtc_5aPFo=IC zKmCdL?@4C7`1)iHgo(y!{Qcdc0tyiaC%`!#!;dN4=bRJ60`{yto+KnS3obc<1tS~t z)TSlUsPh{BY?^VksC|*A;fMN|S1#;1`SF5x#czH5#2t=S#3WKZY|cY0p>~h zaTRtdeqa8`@zZY}Q4uYhG*~AQMd@#{*Wb|h|0X3m278sHJky}@8}9wT;E-EMC0K>HHJ3wBPtLtfq9(jMLo{flp*Vx&YG)8G z4u^V!wCb{7rYxn>?cD`Hi0E-g(z-u0=ZIOjtC1pNZB ztGyWItr2cQhhESA3;nIyo)S6Wmf45xzn0m@nB1E)dKSJhFxm~=J`;}wW$fs9J>9XD zE+ZeL-aO(FzjTg^;OcmZk{35O|2wBCd2QKp9{r2A`Y)*BJ$vmq^_BDF#1kH)3-qj? z;5_|T%JdE7>4Y+-qQ-gHBn|o={%eg&pKnf>KipCE{2j-yL$OhLGl&VrdZVf@1_d=;$4T-o3nNbZJEO9 zyE*^C9%cftUF)>?k{K+InqczW!1Ew}vhu>u+CF8!YrnwaS>y&D0QZu^p|T2_ZxcKy zU!>uCBInRMb8(&969rU#*qm|JI4 zRp$)3AREdb^1TA;a2&)p@+GllJS?)b{}6x5wsM4bH{awPHXk8LXFilijIF>8w1J9u zNv%(u_mLqkNIh$O(SkDZZ+|UxYZ*7&x^$^7eb}5fhrR(Y26wZ zW8j1o`l~)-|B*gG|Gzzk8#>=I*MfKA_YCf(N}MJqb}vK8h>cEv&mcTOcN_#0{9dW; zeb2xifij-yJ`o);kfA@}ql>-sC$y*|;d{X9%SrZ^7sM{&e3w~*AXBVJi3(x97o`q+ z3}+ftuT<^l?Q{N{HilVEM*kkNUoopPKIhkuQwJT@e6-;wkSjjO8ku-BRk=UaPCaHk zU~h9jveQa?w1EMDPLX z0GUp)18A-bk8`HbE8jU_qKxbvsMp`K$Re5VSE9@D2lK$LxsuJo&obvhUB|0_MzJ4PWqxeH%hZ z`aj|KZ_{9$6^7^cz|lljkats91O+UDfhX({^BBzLTl3xCDEz*8ii`nAsIs0KUL<=a z-^`Nh@2Q=@Dwry0O650&&5wk)GN#)Tcwh*=3HBxC$$kTwEFxw@_n}Q;-OMd7dWfx+ zS67sW+2?3{puzTQNqFw#B~NU=pu*nOlYT+j+lQkg_{71cvjoeElE>}m%KS?Xg034l z+e7v2IYUsj45}kRHP@3+VeYqvCD~A$j*JI;HE%}gO?U86+%9~_P;LHcfogV;61P$+}l~Ucv@3M*qwzgHxpV&%8MdUxkq^Qbo;S^ zXWhUqY7Q0~Y(tliO@Zu}y#Js(iEZJDmt1;&yrGDX=Bu^FUYvdA3HIU(nCcVl#Sc?~ z@20^A!`q8v?+z8R-d^@RrLxUUDmH8Vve3$Wi|=;Pf~=+*xlLo_TzTyz2^o2je7C8z z@QAra=-!3U+^z5H`1;qT)5{|7r-bv$sEH(@B_Wq?*KFmoJ!w-+&tt?V;tRFp7 z+6P)J(3oW-(vRW1jaI~ULq(BG)53;X3V!RYrR&%^t>{cQ@J&5U16OHM@(GIbLx0i> zfOE=xCjakO$y|<^LX(k8-0*mken*n7x-Td*Jiv?1IZu$L_kH~PP3rL4dlDmh44HJE zM^@{D9+QSWbfnY%f!-4E*`E8!DgR?lU= z{wXY4PMc+R{4h+LN%%8k8h?&v8vh?^dv17vWsiF>m5GTVpA~UZLTAdKak!773edbk z`d0ebsd-cnDK<1?G}TGoIATEf!R&W&A%uiy$Kwc;^LJiB5`j}%_!fTWXE1XJq-*Vk zdBv5!@D-8GT$yI{Tt8u;8d*|n|H1LYAh7EN_Cj0(GDG7uzLFPRSm8|lJu-J{JgInL zg}?HclP#&)`s9H0*IeF{b2I(Af$y9yB7@%928y|uybzJ>)4p9x$-#SFztqCl|#!@M5F-d&&&ALXh2w@Z0G z^CXAQ1e1aHJppuq!LJYC5a4;3jfs1*j4%#Nl^&g(;BWMFoF}IWXtR(8m&OK7 z5+LTh!D1O0sU0Q;QVp%@g?MX(cpXqpzqaSmYf%4s;~|zTt-hnb0@R~tMvFJxFGqNO zC2&++&vFBoLml(o$!S`cHAtPl5wxOqj?!((DR8g`Ow8d|yD?Gwz+< z>Ct28()ivZ((G|*F0vsHkwcrI4a9vagjTjo^L&wW9p-L0c7glJYIC`IQxvUg+!`H2n zr$QHKMsrf-c3n7W==XQH$%mK2>$S}4|4>K-gIwkYYQRA>aP}?FN&M-FL~)&P+(3zB z9&ju&rTA&Axm@fPLtG_jdw{o_UI~4*%1&pPhLNjaQDZtm{Rv`B5x)(+)3Bymtm5l^ zp+>26Jygw=mvQQyJs8cI7&$9i&d;?4{VVI~TfaF~g)3!f!eVfC1`E$Ik~if96kY-{5?Z`2NlMyy|Fu zaPWhTg}h05wA$`3dEVb$BwUm6dka%hpa0G?1)nD>?7v4do+PQ+veTy(Xe!kD26C;E z-JyvO%4hZ5z{40va0ImcKbm~|5(fImfy^@P+i7QX@Ekdw8uCBL)}x#sf@%MM(J)>! z>&S8gKZMfq3MoBq`A+z8K_x3=p07E&f)N{M~%6#ky_YS9tD!9)x-M`B{KCadpcXHBKk{?|f5r z2&F!KN}N*H(*Tsp@Cdb#$CAEKwxQE)OyB^YFEiup$+-rM`ZCU-475|uDzZ!Z!rLe? zM{w=QnGSF&N$$&dr`mjRy5#R+uFCqX+cMrH1)r{Ts*6KY&U-vN&%t_hIA*cEM=MrU z^7_+DPsGyTy|I+j^)R&l<^b-emFhtnh`Rz>rsXNUFWIN92e1a13<}|F|kT5-~I?mQm*Z z204}yanr(c;;rtc@Y{z^+k56d`vrNQNL&vyMteBs#)`#o9mr%<+y(SyEUbiz{LBtq zDtn0~vICuvFJ)+_oFRK~m3>_76R*QX;SA@CtSVj!ls5u-PdsTS?YBSF@7l=wO+G%$ zq}7d{oEN0Wz(7FiP2K~EtHGp}Bd;7p>gBLh>r7_C<&XjvprTNLv4#{uMfj%z1j#Cp zSgFLge$3cLqY@8RQ=iGNkmCr=@h;~+FdUd_+1vCtby*}e^l9~YkC9$>ij3b&bvxrC z$%$rst3sZ(%iEd!Dv=2Jim{91&Qp9&%NE_JnppW{FES~MinlJ0pN2O(5+RoXg zQ=axxN_EY9<;i|RPPL`lN7M;XAIYUZM9h26x^%|nRMkgZ?p;jE98ye&^K=Do|BRZOXc;%g$Znri@?s~iZwrsHu8nSD z?hdS;$!S!udgi?^qy0Da68ApK-u2+(Yk8-m*calJm)%yQHP=deqOf;svHVvD;p~S- zF@)8{m*?T__vY^X)s1Cyv1?b`hpN+dmHB^OI=<5X^V-bIda6|(Uq}p{ZeN~VU2>>1 zix*eZ9<44p*y%6BJvXvzdS%JJ&X=VJdso6GsL%xe?CPGJAAj0)tL(kbjSz@2PhEWO zt}6SWq}(nfBgt=<=Hqbv_QA-}6keW^VOB zMO;c3#WLUKBq$eDMb+qBV(a2Z%9)3)orPX^)g>=hbAqXkPJXnM%YwImL#&sWbX97m zl@YC`M|av9{r5)ww^jdb(|>#E*PZrb{rBrS<(vBNcK(*?+Y)G zeCIV}k+gqZ0`Xylc=^7Jd7vQ}n^N%%!^oj{Mk4nl)Tg7uy<3Yi_&*x_pWS8i&$Ofd z^ZUO{fy{f%=w20lkl)I?4D9gWHV@wA!5tp_sRy6*;By}Qs|PbbW7-+-!Kogc<-v_7b_F#pFe}M-t_TWsfUTj?L zCbFf&gR%6J!DFk{7STb5`^Elm9yTs@6=70@(2`uT;{j7Y_eTa^uC7$eRHeFtP^)ID z3RTTNr7jOQhnuhLYVItnDX&~V^trC8ttF%zPA*rsprx%vU9qfU*=gTj@zH^@zn1;< z*4O^>Xv>#ABRE%Fyt1`rRk&-_j8zSdYr`EYJ3?zZn;V*D+}zSuIBVtli)OF9qPexX zp{qHTb5;4QI+FR%Z&oD_)6oqr84< z#(4cneHr6VT9rC=ol-A&}L_mH?ogff%UGE!B>khBy(?JTFA*}9#2jq?@I zCNE3nHH}w!%g3p_*<)4Sq45XD_U3lz@=cVL{-s}kI(T5gm_1S*y$#j^ahV3OvJw;d}ZO9m!vQ<)=v^yltw2|Yr zK^?}jy_h*6+^^eVt`eU$ZpmeI8_+XrR%S=aq--^*DMw9O4xBwoO`4T=Y{F4*{3FxU z$dn?LS|IrGL#-(%gwVnDn3RN;QtHuW{(GlScx9f+PD)D|>r-Qwk5*%6=cuur zqkFSEM%C-KsdozD+ft8qBz`vGv);4BO9@+I?SlUaY4ArU!JALGr!}n$kp{8SgF(z!t~n&*L0=!U_@P>sglxVu1U`r zl5TivBs>Kl!c!>|v(&`UNHvl1Oa%Xl@Y=*#6M9YG^iSG&(#Fq%A2pxCtIJ2ir#_W8 z%bO>SCpeNmp7a==M=O+ioltwH;3@nyN+qY6{85!k9hR{Oy+S@+C!RJj9h|b@!=ZH< zcPNK(XRCsF$X7yv@C9?1^el9sT*i=chL1-JAJSE}a1HL)4M)r>A$gGjJdq1Mon}mZJKUp)#io`UJPZHBov`j=E(q4c$ z2+SJOD{UQ{h6Uy{rZ&(rviN~)i7PNq61ggm$+ z^H_RsYJsLhK79~cr9DkMcnEwCCZy|eFW2i=)2@KLD~G9*ln(AYFogeva4-9ynd{8t zG|J?Xe<30LlQO<^cxHs=?WAU6c5G8ycLiRme$Gu3E#YxJzFgT7v5r_h16MULvZD_80z z0)~HRXX0=1TqMtWE;E@+pDq(m*L*Qj9ZaaJ_ls5Rh2us3jAmWuu&%S!_`8h!Q5PsR zm2ii&tH+(K64NwZ$n^L=b3Xed;TN&;doq=LktUXA`ayOu=JB(UHzI2mW~+s>$0JWC zs8f~))G3F?9UF7he=w)l?7z7Ta4KQ^9kH<)K21#bWUc1W+#s@+&?M!djl^3BHS(-! zkac2OXp~B!g>}KTW8gltv#NT;lW+63Zl}8GRrdSv*SlJ7rw(JG`dY z*Mc=lZ6N5iLR(4Cv2{62x%#EtsS`}S!S<5U6Y3|Xr_9e(^XY#c?TXGOblR~}}a33w!>)2~{9rH=3qOtzYLz4e}$Zr0{Vl?zYj&dTmJ z^z$Jcv(%1K_@7|*9`uGX^gBYj>_r;qQORi<7uMX6x_T{q-0;j%2y(|%rEZrt#-yt; zd;G|t(JC=LB_|X4pR0228hH@;U!S6Nm@jJ`#^@fo=pKGG_AaA)7~W@XEoYyn@9~}R zzFv2J(pY=wDY138W3f`BmMC@Jrwl$4zlJbgo@GpXvUPquO^<1m-U|}z8o9yx>@<7d z7UuT_LTqjL=w}Y0HP-I(ER~d|`81mfqf}B|-Cwres}s|UytA}SYYlM=dLEu=!ZVDOY;m*$HwopxH zdt-A~ms*p4bwf*NL3`)2mbM#Oo0qP-vAHp%4yVy_iY?`3&XB zZaSeU%7>!l)C25&bD@JbHv)3LYiTlu@$|p>Q*)1(9$-T z5=p6B9co$Ee9>$)(Dc^!wi|9-*P#|KyQ=((;sVX|bEJ(%{*&vvj&^D`cd8|+b*8Jj z#?Fv>I;BqNN5(pJU@%_Stcqeao9f!aET0)EbxqAlExoMj8rF5)P}jU(j8@mEy1Mc@ zXwcZQx}~vhjixAkbgiU!bksI>gch{43I-8U=$qzNg>Sf_xwCFfd;40oQBtu|wbg|- zbTot2>h`*}hIP$dM5)!*zzY6)T3xsedaYI6lx9)4x9QI3rPk@xS5oV|lnc_AGo+R_ z<~Fu))co`-+YDMwmFpXuJ7lSOD5+Crm7FwtUusoXg@9x!fL2TeKMNWA`M=0Fc91}iE(y;P%Zm4PQT;1NeuA!}w zoUopw)tc*D8rSLsrIyO`vJG9K=5@=N?y@e>ZkCw(NBX+vbu2d4tHc^R=xa(^9Vx;I z=J#~${}#W`*wQGhB&@%OJ^b@Z<$aO=B6|)xB4PWf=zN6ID}a}?cM}w6uTtDmb`XN( zGXFfTH$rZJ@pV9k8mxPbCi;K>7tLT-?L(1&->pPbc>RRSw0N63Y?a@IabILbJ4uOv<= zB@|$IuBWXnNK3H~)p*YZD=14Sy_QgG$^@@bY8-PtlTbmph7cy)Mfg5pFX2VPJA`px zVh16V5w0g}Alyy(9^o;!WzOx!tI1F6MjV4L--xx4Z?{30w2O9 zgcXD^;SR!g2#*tv65b_@_$s&%W)UnxBViNa9>N2J#|gh9yiEvvO{p1#MTA;HJE5C! zAK}M@#|cLWuMu3r_^)HTBa{%XA#5Ogp0JbfJmD=u-ZzvwhcJ(@oUoR#iSTK{mk8e? z{Dja;*h@G>I6`=h@E&2rHRN(p0+2P?>6k@~M$3ON~<5Do2f0e$1z1)L1UA z$EyHua-O2{)TwGB3wM&5tWH;FsGypnrm8blzM7`aQXf&%)!FJCb*?&3&ER(8d{qGR z&r*eIwz^PVq~@q1Rje*nCHz13^VB8kQdO$T)O=OWJw_$$yHHuGN?oQFscN-YEm2EV zjk=t>j%8{&_a0ZNtGV;I2FbrdtyI^k>s6hqR}E^FYGj!*>m6%%B5DIm&$#jJ}+c(6Dn#3EL zLru-0hQ>8rAvTB;@><%~G@~bVHLhuHIw4c1b~JQ0tUF0oJ1WJA{dG0AcbwQ0{Wq>{ zK%qLZEy?LZH%!iv%{n;+QGe30kazO2ka@DP#IuGOi_SY?ERs6>SYkOzV_DVE+1bL* zKXi6t=}E(kCElDc<#k@-uydT4$5eN8t!d~?n90QK;X2Z7g7(mQjhX}F)NgEWYpPq- zi89`Z)|{L?bX>Y@QeQfytK|mKYdj9G(`lm5H6;yIC!dfq?8v34&KPFc@w^l8IO%}3 z;vPq@iRHJUuB{^>LDo?GvH7E@LW57D6~;yeI&|Nt&rJ!7gXCdYP*OcLGO>Z13uhV4 z*XVGGh)^S*+k(D2h~kZCz41oYHg7=jl*33;664~`FqqUbD0J%9g*hjlz@{cOiH;^o zYoW10n>1 zYM2!>*dUonUA2YR)peNjb9-l3BJQxsAV!@x3yn^ozn7eZrI*&(ltfi8RZqgd$hx_6 z*jk+%PEx0H!|*kROrO{Luw{pxRZ}50twU!nA$ORe$7X0~t*++Q)$u829*h`E-udFm zNs}b0!>n48hgr3fI&{@`b+ojdFnKyL34fiEGyyt=gVTwLLns_#dmkc~Wv&~M5jQl) z4xx$crF|k|tS8z4671ypW@kMyU%IVZjU?eXm&CoMc_XJz+PasW*f`>=4k^Z2y3rg= zIl^_`)PjA9U7<-9gp}xL?=WZNut+$a67E_PPtvoZo9XZ@JskDdtKpK7it%I}3Ab`G zH%YPiO-S0%(#)4kx|-L~7e)~si|uie3hFm$YneRgxs?c70^JblXlH|rMUbh+$fHvR zw>!ya%JoJkab~)uZLKb((?kjW&+q>@1!8WrPhA&0w3=6`V!sq`+(V%x$I?=X7kGYH zMIQ93{RjMig#x*QzCqeYi05P7*sFkFCLATc1Nh(=>w?V)>UN9j1bQ^Vn zS=ei8r7mzQLGDP!e)hZNDj5Z{Rngjez35cny= zGsFdcg|LTsq92C%W1KP>n+E9urxJD$7u(xfg5Z{TXD#>HUq78PcNq8}@$JMD@4n?; z{GWtdNEetDL(t0OSxiz9HyN4Se7UEnte|G3@2hlsyI zJkb|Oe21=`j{gMd0y_xz5*N7rY<$*;3;Y5>(suyc&Viq$4Deg$^1>kFP4saRU#CwH z>M0}eWkNM^f$w;6fg@)yFQkiIbvCxtgV4DYxRoG0pXkRS{v7fjjeeUl0=o$J5*PdG ztAuB^sU$xU@gezuu%0pkb7ryDh>KnHX6&KAp!`ALT^F*Zz<&pD#zkfw6#zdyhq<79 zqA#ZSWR5KYFX{@cA>2Y-;139`#Kq2gdogQ}c%rYO_%O=1f$wEp0tX1U6BjrYyKjiN zzB7P=k zEySMNV_-G${lsg4-zLbqegOCfg3M{6PnP&_y-3(k8G-*G{DQc^%~i-q;&M0e{AG;k zHtGUnelY@XC;XJY1b%^VA8~1SMsFKPDWz)4*R6KT2Hg zJ60@3HufN2fH8k0fxa5}hjf7x3FC@r%;sWys zzaw4X1zx(`rChL#wGYipfoCr_^p|^}-w`BT?n*{nY4}s_Oy+oTxi@)&AoDKwDCclz zBJ(bHDdhy=XSqlD*wxUVcI0lQxRx~O3wXeb9|TUg#w zu&ot3lYR?O{?82`?FcL<2%Rf{w-AKR0)OhoOWW8h3DYUR1Guc+$Uu3Y;U@$|y1dJv z-%lVe@C`4W%MCS!AZ7mZ`=3!DT^CE0*8)@!cFF@50Rj4F@>5g_Pl%B%CY3qS5xFZv z2N@=v*C_@IQzlkk(zo-x;~@8!#BsmYzx$s-zS3CiIXite=~r>nRmWd>zh@aYVN2B# zo~!t~fVljAnf~_=plgT>&?A0$1^uy@Q**lz90H>U442Chc_4UJG?$T7EU)Cm7d4)#XsAladVz z(+|!Ksy(6_n1O!os?=)VfqR|k7k~`;=Rq{ zb}z)F>&C`5v=(=@C#g4^8_yI?i;(WA4QyJWc>{NdhzmW^!4X}>Z6$I= z*I5c)Eznb_Ds^Ig%hSp0wsB9ILM!c*>7ZmABOmMyuMAR~Nex2Lc4*KE6`H-L)zIT+ z>Ii*)5`9eGSZQ?FA1xh!AsbDERcTm>gzDAciF)helZaKHP zL2oux+=S2EO}Gl((A*WzOw6uaPgQY)s&2li zxi#1-f9FkY=&EYFseNs8=hR@hrL0kW9Oq44-O$?AJoS>f=f~Slt{iVap~MNj&pkg0 z*SY7%2W@E3)GRJ^IIP9SGB=hID)VSP*iVf5Ra6Ku{Gi-j%$uq$@Kb~0IyP_W;@B+A zys8|JxbiEOPYvD_qkZwrf|;`}D3~>CX3^AO{4%PnvvEyJ2uDmz`_N)t(?zq%4X@%> ze^K*><Gw o>qY+m^sKg^*RnR(e|6_qd%sHL0rq1+=?-fL;6K0r;}rOR0KyKa2mk;8 literal 0 HcmV?d00001 diff --git a/libraries/pthreads/lib/pthreadVC2_x64.lib b/libraries/pthreads/lib/pthreadVC2_x64.lib new file mode 100644 index 0000000000000000000000000000000000000000..7c71accfd960244d219c0b94924b2105b352cd08 GIT binary patch literal 29322 zcmd^INsJuFu?in|(18cT@a5~^gHMJIhVWq+KItUrBoKxn{DTgLAqax-VHma!hGF=ii~Vw|%FK$) zVg2smUx`NEA=>eP=*=ZWXP;J7`7M#4vAUvj|0I%hA6L++j};|9BN8+TT|vonimDrl zB>fUs(5>GnnuVUA=8qLM-Xjv!x~!=A71BYiPZYJ+5DB_9s;Dspc~EnuqS=ec4^+RY z=?h#zGk?=`8&}YocNJB3z%J14>x%XrB@(pzb4B}54}$hwQ?&muk)XFxCP^(^LD#1h zUHdzcpzB{My4J-r=<3&sCjLMqsPsoo$hQQV&~$YvQKwb`-%>2!87RKE=?cc3flj%qCKC% zk3a`tzo5OJDmpNVXVBh@ibfw03EK6!rb%2uqo`j&Hx~;km5!Y{duD9Bbnwvm17pX| zj-MGTwYt;oq+GptV6b#|WQa4QYmHjh z6_zPVvXjh~P^emChOFC+SE)BUiDap}jMHo-4atxFzp@04Mc`;=*>OnH-~qX|=%xzD(!4n?l!KI6(t6D+&- zD$_}|bg!1wtJJaXwU$f~eMa2O)swasa*}LW(K|d@C&`vYCZ$%p)@;|h_e!(yaaDj^ za#*K)m(@YC(y@EEC{?T6F3+Z(WQV>*FF(v}p8Wit8z z2#}0F&3dhpb!-<{@fhtidq&&ix!UbJVu%sr+MTvD z{NxxRy>>OArx~oCH!f;0c4RaKksY2dqs3y;c++$$t09M%fMo(LW*e^-(J;Q#>P(m0 zNi}tOWx3Dg%4@tNk^}tOaDzFR0nd1@RRF^Z>N;;2OVJuB-E7n0HIU39sd3j+U=T#} zRi?|0sicH|s~B}ljaFK(JlDm$Q)_G+EOqgkElncEm}@5;JBt9D%|ixZuvUZ^OddWv zk_VbOmPf|s@@Tc2m88=N79`J)<&t5U)=*Vqa>@8^E{(Zays>0Snr){_^Bh+babfwM zU4LnUD+fovvu#j?zO|~YkmrOomD_~0Gp?J%>|8gw3)AImY^K(5;8|u!AA@#S-(oWQ zxgb>nr>UHVHykSkb~M&`i80U__Wg7Yg;9`6jI61{?!8tv6_6MXC!~oA3TPTmMAHnD z#<4S4C>v%--x_A~`W7>!Z^qfYvf+d@odGy2Gc!7>wleuSNa>)=ptyst$|RrrfpVjQ zo_eF6j0-2ZBtmoz!Lb~iOn_IDsg8yS7c0$1Wv<;$8dlikCA&IkMoz~|c6E|lbLF}* zq@~J1d^KyAu>~J2Yow*DQFRbmjfn9#b6I7dNcFE~>P9lqwz8}02rs=#E zS2BAI#pGrhqf^0xQtD7{s*50bs9Q!OO=UFT8Ssh9OsDoA3{J{nG)1l{-zm4lVKfb9 zxms=KZ4-G)4x?#u&TBdxMiZE7;^B4-Q=>MI(MImJgm10QW3-LKI%+17k$0R#meBEA zF)E=zc=c71R=3t{lsZZKb`5hH4Bl1Iit|Yn-w)fK?uXsM&cHh(L=SclEqRmZ>9a(? ztzbt9EAan3M|2Bzh0KAeXUA^cC(u!F5d= ztN7p#A$=v%E<)~Ro#+eD->@BV8}#lO?7{)-`fluK>?8Ud*9W*>+k>43?96=iHg?27 z)7OdqevRl$T)Vh_eU<1B6GVS3K~@m%mm=*Q&_7VdA5G(4Y#o8Vo&pwV)fMcvz>cND zCfN8Mb|HRo8Rfe`^lQ)u|)eZxO8qt;79#$gPFk*m8J{lgn5 z|7q;zl!<`&#q)C9Pk=Xhg6Jd;zRN9$>pZc!6OsnboGrYTh1B;BBk zbcL?cCAv&+(RF&8N_34b&`x@a&eAxYrXSE^+D*G?DLqL`=sX>#6Lf&~(j zGvNtP1g?HkDcVct{n zt;*;-4i`Q$mL&2b@0zuoQM8I~zi`j1YjO`|@;#=QvnaVLNW+tRr z5wEf((5Plw;#Q0;6fS^iBt8!v*1H+Yc~&;lWSD$y#O7ya7RqEc|I{+C6sfy(Mi#8N zRD!9sln0*(RGHehcFPo4&s0&C*B!Y92xd(H#YbV%)e#p@_Vjd1FV8cZ{5cNdEVaBE zS_VbVsf=2Jb@O0$;KepSyJQjG{}<~eZoclq7RO^+ODTmGBGpE7n5)kNa9H8>(}?HE z(nvlk(X0S7xf>DQznom;EIO1$s6u4^@Zb505OndZ2oPb4FyC@NvqGkK0{MYMGZ}j{ zC$a&j8hKuU=!RkYUQ|EbUv(QomyLB5&5NK${75Osy~L6UR-5qy-p`n2PPDdqA*dOr zYi`P9976DdV-=Xem%HHcW0gFe!@G-QF;>fTrn^7nK_A!L;0l*`UFG*DUFC<{PjjWz zyF%<*ae3u-Gg+ZDF4J3$5urTXd{c0fnUHHS3yLz`UZzwEvhC&UKRfM`9#P?#I11xw zN-25%#%375$}!Y=9xaLkKmN%l*Q>;lAdJ`Q%u}Xh`InIJ4oP_@nnEX_{Ln_^ls~tG z5k#Ed%CPN)J#OZrS7kDmoU^cNHBKVTwAX!no)e|}Osfm?EavnI@B(XlX*8b8OK|cl zd$KhgS+su87VyHh7`JiHHkq+fnaS89)!3Cy-WDOBv&Bpbj0YNvOuA#HNwmG8WC#6$ zT>KY@2O`-Vkf{Rmx-fcrj*vb^_M!X|iD=s0dXy>Lj#SoF93aPdp)56(mGl59^d-8+S=q;(MGWWlzy6gN$60^GbB zYS?d8N7LDz$~bw`Bourk48=H5mLZr9R6cSxWtTCtdC=jbU;jGUDWy)+0j!sSY=j7l zKU{}5R6r+86EzEpJcXiEK^r(L8E&a~escGQAeb z%u7(D`n}ePT~jP^2Hh!t7Oy%osD7v4NHMR5t?1O~inh+jrH1Rqny54OFq%05mIa5d zel802*na%UvhB?0i#hd9w-s$Nd*8BE@)0JNY#+0heCt%VX+MrP$Ut%ok)6%XItb zuS_;ou`07{v-zYA4fD9>Xpac4fqGQ#H9UH?!8+=wnf7S_)<2p)PKGJg7&r?4kw*+`bPNa^~z(IaRB)o1NxlcVNTVD+4Ewofi97x!-c6i1G-+ z9+bRWfq$QncX=?BsM4Hmq3BQD{V)30zidsYkSOaSGBq$tBuhVSQlza4PsZP2i@N-IaO0vY;0Y4sW--Xp!`yk5EQccHWDyJ?s1| zFWP1p!aM%kJm{ zf1@;N`rwdB7k&LR^PsOnZlP-VVQP3C%F%Bx9T~~SPLln&dS8rpo21Q)&6FUUn2-DC zDD9!P=tw)Vl}CRC=#OC((&J8sZZ8Yiz=i#5#JJah__|n(U&`(cKwgv~yBnpXZheMiz{B4H{KX7Dx9VUQps@WBe|v(#&&Q`dp+{JQ|0aX~=z99oLG(w{)4#>yKZ>5dfz|~&obDdfu`^qHG;d6!L`?)?E$VZZe)D>P9B$A zC9~lR*Z1~--D0}^-2i@m5!Eh2;TlN)a*Z29zJ?NfFHnMhwR+6@=K|Px$#_eOy;wgS zuzoG9f8HvAyV=qU;)q$6@!sPbfw;;>WcPD=LJs(vm@RzYM~)0CMLjGQxvchaL#|c0 zXAN8HY4+SmtiZhBqq;j^b|n|ajkWI@A2(ZWWCrhk*0VS-ts&%hS>^#AIv$<^p7H`SG`)B}&8*D^t z1KkEJ+K#dD@f8aXU6tAG>j^p1TQ|DM@o8M~I*z=HUiFZ@O-tM0!nh*=+^uNa*IeB2 zafaSX5LvN#Jx~JY$V5-*!x7)!WTD%~GHk%2zC9dRmt2qf-fZFJPkt;E>J|?bqoehg z;Ce!h)a_Oq)jGe@3tnuMebB;_hdk2VU?!|8+>2tZx-Ewsdd2tCmxgkv_Q`~vYB})! z5o-^_IaC?GhM)`AbF76&^4RWi4BP19$dQ@R_8hW%=EDXq+QuW1(Q${5J74fz-0Hw+ zC3aEXVA1hT_6}V2WPJqx%@BSc=l-$U-xiDvc>V4LaPyz5^kQvn zwfU-z8v7!~EuXTDWL%`p~sgmotGK9V! zvWrkON{XHADCJ8K_&{l)N-z;BL9`hP*Fhjo6UX?=vIO&gX4Shd#75j3X({YK9I()9 z=9LW9{<8!OY|$Ez?JZV;Dno|+7ikNOoCJ{Z(OVyoV`KfKjVz6qAJHu^>Qst~(7(T^ zf${wZ=uy)ts`@&RF|zRcWGFD(5nl<_1Rg#HRDZ>yA85l7>uzeaNB~&ay4YIajK;&% zRs97H#=xSzb11OhzZ$h!*La~ov!7VA8cTi;y1;fdG?x72v=3OZ(Y$G4WnZ;2pv65U y@Fo+dQd$}{dX%j=Vx%wJGKl(ro$8B)frx1hENp8${RJ=s*H7>4XtdA?=YIp@SMS;Y literal 0 HcmV?d00001 -- GitLab From a0769389deb5e80415d1231866d73e7ef71f722c Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 27 Oct 2014 15:45:35 -0700 Subject: [PATCH 074/338] Reduced share memory for CustomGBForce --- platforms/cuda/src/CudaKernels.cpp | 2 +- .../cuda/src/kernels/customGBEnergyN2.cu | 42 +++++++++--------- platforms/cuda/src/kernels/customGBValueN2.cu | 44 ++++++++++--------- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 8e8bc0b2f..c9696b5cb 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -3034,7 +3034,7 @@ void CudaCalcCustomGBForceKernel::initialize(const System& system, const CustomG pairEnergyDefines["USE_PERIODIC"] = "1"; if (anyExclusions) pairEnergyDefines["USE_EXCLUSIONS"] = "1"; - if (atomParamSize%2 == 0 && !cu.getUseDoublePrecision()) + if (atomParamSize%2 != 0 && !cu.getUseDoublePrecision()) pairEnergyDefines["NEED_PADDING"] = "1"; pairEnergyDefines["THREAD_BLOCK_SIZE"] = cu.intToString(cu.getNonbondedUtilities().getForceThreadBlockSize()); pairEnergyDefines["WARPS_PER_GROUP"] = cu.intToString(cu.getNonbondedUtilities().getForceThreadBlockSize()/CudaContext::TileSize); diff --git a/platforms/cuda/src/kernels/customGBEnergyN2.cu b/platforms/cuda/src/kernels/customGBEnergyN2.cu index 517e8d2fb..9c5295e42 100644 --- a/platforms/cuda/src/kernels/customGBEnergyN2.cu +++ b/platforms/cuda/src/kernels/customGBEnergyN2.cu @@ -2,7 +2,7 @@ #define STORE_DERIVATIVE_2(INDEX) atomicAdd(&derivBuffers[offset+(INDEX-1)*PADDED_NUM_ATOMS], static_cast((long long) (localData[threadIdx.x].deriv##INDEX*0x100000000))); typedef struct { - real4 posq; + real3 pos; real3 force; ATOM_PARAMETER_DATA #ifdef NEED_PADDING @@ -40,7 +40,7 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc real3 force = make_real3(0); DECLARE_ATOM1_DERIVATIVES unsigned int atom1 = x*TILE_SIZE + tgx; - real4 posq1 = posq[atom1]; + real4 pos1 = posq[atom1]; LOAD_ATOM1_PARAMETERS #ifdef USE_EXCLUSIONS unsigned int excl = exclusions[pos*TILE_SIZE+tgx]; @@ -49,12 +49,12 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc // This tile is on the diagonal. const unsigned int localAtomIndex = threadIdx.x; - localData[localAtomIndex].posq = posq1; + localData[localAtomIndex].pos = make_real3(pos1.x, pos1.y, pos1.z); LOAD_LOCAL_PARAMETERS_FROM_1 for (unsigned int j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+j; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; @@ -95,7 +95,8 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc const unsigned int localAtomIndex = threadIdx.x; unsigned int j = y*TILE_SIZE + tgx; - localData[localAtomIndex].posq = posq[j]; + real4 tempPosq = posq[j]; + localData[localAtomIndex].pos = make_real3(tempPosq.x, tempPosq.y, tempPosq.z); LOAD_LOCAL_PARAMETERS_FROM_GLOBAL localData[localAtomIndex].force = make_real3(0); CLEAR_LOCAL_DERIVATIVES @@ -105,8 +106,8 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; @@ -231,7 +232,7 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc // Load atom data for this tile. - real4 posq1 = posq[atom1]; + real4 pos1 = posq[atom1]; LOAD_ATOM1_PARAMETERS const unsigned int localAtomIndex = threadIdx.x; #ifdef USE_CUTOFF @@ -241,7 +242,8 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc #endif atomIndices[threadIdx.x] = j; if (j < PADDED_NUM_ATOMS) { - localData[localAtomIndex].posq = posq[j]; + real4 tempPosq = posq[j]; + localData[localAtomIndex].pos = make_real3(tempPosq.x, tempPosq.y, tempPosq.z); LOAD_LOCAL_PARAMETERS_FROM_GLOBAL localData[localAtomIndex].force = make_real3(0); CLEAR_LOCAL_DERIVATIVES @@ -252,17 +254,17 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.x -= floor((posq1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - posq1.y -= floor((posq1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - posq1.z -= floor((posq1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; - localData[threadIdx.x].posq.x -= floor((localData[threadIdx.x].posq.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[threadIdx.x].posq.y -= floor((localData[threadIdx.x].posq.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[threadIdx.x].posq.z -= floor((localData[threadIdx.x].posq.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + pos1.x -= floor((pos1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; + pos1.y -= floor((pos1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; + pos1.z -= floor((pos1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + localData[threadIdx.x].pos.x -= floor((localData[threadIdx.x].pos.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; + localData[threadIdx.x].pos.y -= floor((localData[threadIdx.x].pos.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; + localData[threadIdx.x].pos.z -= floor((localData[threadIdx.x].pos.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF if (r2 < CUTOFF_SQUARED) { @@ -301,8 +303,8 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; diff --git a/platforms/cuda/src/kernels/customGBValueN2.cu b/platforms/cuda/src/kernels/customGBValueN2.cu index b105e6667..fb8d65586 100644 --- a/platforms/cuda/src/kernels/customGBValueN2.cu +++ b/platforms/cuda/src/kernels/customGBValueN2.cu @@ -1,6 +1,6 @@ typedef struct { - real4 posq; - real value, temp; + real3 pos; + real value; ATOM_PARAMETER_DATA #ifdef NEED_PADDING float padding; @@ -35,7 +35,7 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const const unsigned int y = tileIndices.y; real value = 0; unsigned int atom1 = x*TILE_SIZE + tgx; - real4 posq1 = posq[atom1]; + real4 pos1 = posq[atom1]; LOAD_ATOM1_PARAMETERS #ifdef USE_EXCLUSIONS unsigned int excl = exclusions[pos*TILE_SIZE+tgx]; @@ -44,12 +44,12 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const // This tile is on the diagonal. const unsigned int localAtomIndex = threadIdx.x; - localData[localAtomIndex].posq = posq1; + localData[localAtomIndex].pos = make_real3(pos1.x, pos1.y, pos1.z); LOAD_LOCAL_PARAMETERS_FROM_1 for (unsigned int j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+j; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; @@ -87,7 +87,8 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const const unsigned int localAtomIndex = threadIdx.x; unsigned int j = y*TILE_SIZE + tgx; - localData[localAtomIndex].posq = posq[j]; + real4 tempPosq = posq[j]; + localData[localAtomIndex].pos = make_real3(tempPosq.x, tempPosq.y, tempPosq.z); LOAD_LOCAL_PARAMETERS_FROM_GLOBAL localData[localAtomIndex].value = 0; #ifdef USE_EXCLUSIONS @@ -96,8 +97,8 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; @@ -207,7 +208,7 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const // Load atom data for this tile. - real4 posq1 = posq[atom1]; + real4 pos1 = posq[atom1]; LOAD_ATOM1_PARAMETERS const unsigned int localAtomIndex = threadIdx.x; #ifdef USE_CUTOFF @@ -217,7 +218,8 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const #endif atomIndices[threadIdx.x] = j; if (j < PADDED_NUM_ATOMS) { - localData[localAtomIndex].posq = posq[j]; + real4 tempPosq = posq[j]; + localData[localAtomIndex].pos = make_real3(tempPosq.x, tempPosq.y, tempPosq.z); LOAD_LOCAL_PARAMETERS_FROM_GLOBAL localData[localAtomIndex].value = 0; } @@ -227,17 +229,17 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.x -= floor((posq1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - posq1.y -= floor((posq1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - posq1.z -= floor((posq1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; - localData[threadIdx.x].posq.x -= floor((localData[threadIdx.x].posq.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[threadIdx.x].posq.y -= floor((localData[threadIdx.x].posq.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[threadIdx.x].posq.z -= floor((localData[threadIdx.x].posq.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + pos1.x -= floor((pos1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; + pos1.y -= floor((pos1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; + pos1.z -= floor((pos1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + localData[threadIdx.x].pos.x -= floor((localData[threadIdx.x].pos.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; + localData[threadIdx.x].pos.y -= floor((localData[threadIdx.x].pos.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; + localData[threadIdx.x].pos.z -= floor((localData[threadIdx.x].pos.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; unsigned int tj = tgx; for (unsigned int j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; if (r2 < CUTOFF_SQUARED) { real invR = RSQRT(r2); @@ -263,8 +265,8 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const unsigned int tj = tgx; for (unsigned int j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; - real4 posq2 = localData[atom2].posq; - real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); + real3 pos2 = localData[atom2].pos; + real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; -- GitLab From b836c4dee157b66a9fc7ac286e84ab2034e13672 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 27 Oct 2014 17:26:55 -0700 Subject: [PATCH 075/338] Updated version number to 6.2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d141a93d..5cff1cff3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,7 +164,7 @@ ENDIF (NOT CMAKE_CXX_FLAGS_RELEASE) SET(OPENMM_LIBRARY_NAME OpenMM) SET(OPENMM_MAJOR_VERSION 6) -SET(OPENMM_MINOR_VERSION 1) +SET(OPENMM_MINOR_VERSION 2) SET(OPENMM_BUILD_VERSION 0) SET(OPENMM_COPYRIGHT_YEARS "2008-2014") -- GitLab From 63bccb58ca8839d0fd2870ec081b347fde0d6957 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 30 Oct 2014 10:29:06 -0700 Subject: [PATCH 076/338] Checked in install.sh script --- install.sh | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 000000000..b83613f0a --- /dev/null +++ b/install.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +cd $(dirname $0) + +# Ask the user for the install location and Python executable. + +defaultInstallDir=/usr/local/openmm +printf "Enter install location (default=${defaultInstallDir}): " +read installDir +if [ -z ${installDir} ] +then + installDir=${defaultInstallDir} +fi +defaultPythonBin=$(which python) +printf "Enter path to Python executable" +if [ ${defaultPythonBin} ] +then + printf " (default=${defaultPythonBin})" +fi +printf ": " +read pythonBin +if [ -z ${pythonBin} ] +then + pythonBin=${defaultPythonBin} +fi + +# Make sure it's a supported Python version. + +pythonOk=$(${pythonBin} -c "import sys; v=sys.version_info; print((v[0]==2 and v[1]>5) or v[0]>2)") +if [ ${pythonOk} != "True" ] +then + echo "Unsupported Python version. Only versions 2.6 and higher are supported." + exit +fi + +# Copy the files into place. + +cp -R docs ${installDir} +cp -R include ${installDir} +cp -R lib ${installDir} +cp -R licenses ${installDir} + +# Run the Python installer. + +cd python +export OPENMM_INCLUDE_PATH=${installDir}/include +export OPENMM_LIB_PATH=${installDir}/lib +printenv +if ${pythonBin} setup.py build && ${pythonBin} setup.py install $@ +then + # Print instructions to the user. + + echo + echo "Installation is complete." +else + echo + echo "INSTALLATION FAILED" + echo + echo "An error prevented the installation from completing. See above for details." +fi -- GitLab From da2e8c9228fd6a43bedb08618c2a785f58b8138a Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 30 Oct 2014 10:51:36 -0700 Subject: [PATCH 077/338] Minor updates to manual for 6.2. --- docs-source/usersguide/application.rst | 24 ++++++++++-------------- docs-source/usersguide/library.rst | 2 +- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/docs-source/usersguide/application.rst b/docs-source/usersguide/application.rst index 027614493..4c6ef5be6 100644 --- a/docs-source/usersguide/application.rst +++ b/docs-source/usersguide/application.rst @@ -43,15 +43,13 @@ troubleshooting guide that describes common problems and how to fix them Installing on Mac OS X ********************** -OpenMM works on Mac OS X 10.7 or later. GPU acceleration is currently only -supported on Nvidia GPUs, not on AMD or Intel GPUs. +OpenMM works on Mac OS X 10.7 or later. -.. warning:: - A serious bug was introduced in Mac OS X 10.7.5 that prevents - OpenMM’s OpenCL platform from working correctly. At the time of this writing, - the bug is present in all versions from 10.7.5 onward. The CUDA platform (see - below) is not affected by the bug, so if you have an affected version of OS X, - you should use it instead of the OpenCL platform. +.. note:: + The OpenCL implementations on all recent versions of Mac OS X contain serious + bugs that make them unsuitable for use with OpenMM. GPU acceleration is + therefore only supported with the CUDA platform. This limits it to only Nvidia + GPUs, not AMD or Intel GPUs. 1. Download the pre-compiled binary of OpenMM for Mac OS X, then double click the .zip file to expand it. @@ -63,7 +61,7 @@ and tell it to install the command line tools. With Xcode 4.2 and earlier, the command line tools are automatically installed when you install Xcode.) 3. (Optional) If you have an Nvidia GPU and want to use the CUDA platform, -download CUDA 6.0 from https://developer.nvidia.com/cuda-downloads. Be sure to +download CUDA 6.5 from https://developer.nvidia.com/cuda-downloads. Be sure to install both the drivers and toolkit. 4. (Optional) If you plan to use the CPU platform, it is recommended that you @@ -139,7 +137,7 @@ into a console window. 3. (Optional) If you want to run OpenMM on a GPU, install CUDA and/or OpenCL. - * If you have an Nvidia GPU, download CUDA 6.0 from + * If you have an Nvidia GPU, download CUDA 6.5 from https://developer.nvidia.com/cuda-downloads. Be sure to install both the drivers and toolkit. OpenCL is included with the CUDA drivers. * If you have an AMD GPU, download the latest version of the Catalyst driver @@ -222,11 +220,9 @@ and ignore it.) 4. (Optional) If you want to run OpenMM on a GPU, install CUDA and/or OpenCL. - * If you have an Nvidia GPU, download CUDA 6.0 from + * If you have an Nvidia GPU, download CUDA 6.5 from https://developer.nvidia.com/cuda-downloads. Be sure to install both the - drivers and toolkit. For 64-bit machines, you should install the 64-bit driver, - but download the 32-bit version of the toolkit since the OpenMM binary is - 32-bit. OpenCL is included with the CUDA drivers. + drivers and toolkit. OpenCL is included with the CUDA drivers. * If you have an AMD GPU, download the latest version of the Catalyst driver from http://support.amd.com. diff --git a/docs-source/usersguide/library.rst b/docs-source/usersguide/library.rst index 6c99e4d78..cee61a4a3 100644 --- a/docs-source/usersguide/library.rst +++ b/docs-source/usersguide/library.rst @@ -434,7 +434,7 @@ To download and unpack OpenMM source code: Alternatively, if you want the most recent development version of the code rather than the version corresponding to a particular release, you can get it from -https://github.com/SimTk/openmm. Be aware that the development code is constantly +https://github.com/pandegroup/openmm. Be aware that the development code is constantly changing, may contain bugs, and should never be used for production work. If you want a stable, well tested version of OpenMM, you should download the source code for the latest release as described above. -- GitLab From dc8b4038cf761c7b8a71529fcdf04383055b44b5 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 3 Nov 2014 13:42:02 -0500 Subject: [PATCH 078/338] Allow Quantity.sum (and other attributes, like mean, max, min, and std) to take arguments and pass them to the numpy function if applicable. That way, users get the full flexibility of the numpy API on those particular methods AND get the added benefit that the result has the correct units (and it all runs fast). --- wrappers/python/simtk/unit/quantity.py | 48 ++++++++++++++++++++------ 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index ded022297..1f5b764a8 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -455,18 +455,24 @@ class Quantity(object): new_value *= math.sqrt(unit_factor) return Quantity(value=new_value, unit=new_unit) - def sum(self): + def sum(self, *args, **kwargs): """ Computes the sum of a sequence, with the result having the same unit as the current sequence. If the value is not iterable, it raises a TypeError (same behavior as if you tried to iterate over, for instance, an integer). + + This function can take as arguments any arguments recognized by + `numpy.sum`. If arguments are passed to a non-numpy array, a TypeError + is raised """ try: # This will be much faster for numpy arrays - mysum = self._value.sum() + mysum = self._value.sum(*args, **kwargs) except AttributeError: + if args or kwargs: + raise TypeError('Unsupported arguments for Quantity.sum') if len(self._value) == 0: mysum = 0 else: @@ -475,31 +481,43 @@ class Quantity(object): mysum += self._value[i] return Quantity(mysum, self.unit) - def mean(self): + def mean(self, *args, **kwargs): """ Computes the mean of a sequence, with the result having the same unit as the current sequence. If the value is not iterable, it raises a TypeError + + This function can take as arguments any arguments recognized by + `numpy.mean`. If arguments are passed to a non-numpy array, a TypeError + is raised """ try: # Faster for numpy arrays - mean = self._value.mean() + mean = self._value.mean(*args, **kwargs) except AttributeError: + if args or kwargs: + raise TypeError('Unsupported arguments for Quantity.mean') mean = self.sum() / len(self._value) return Quantity(mean, self.unit) - def std(self): + def std(self, *args, **kwargs): """ Computes the square root of the variance of a sequence, with the result having the same unit as the current sequence. If the value is not iterable, it raises a TypeError + + This function can take as arguments any arguments recognized by + `numpy.std`. If arguments are passed to a non-numpy array, a TypeError + is raised """ try: # Faster for numpy arrays - std = self._value.std() + std = self._value.std(*args, **kwargs) except AttributeError: + if args or kwargs: + raise TypeError('Unsupported arguments for Quantity.std') mean = self.mean() for val in self._value: res = mean - val @@ -508,30 +526,40 @@ class Quantity(object): std = math.sqrt(var) return Quantity(std, self.unit) - def max(self): + def max(self, *args, **kwargs): """ Computes the maximum value of the sequence, with the result having the same unit as the current sequence. If the value is not iterable, it raises a TypeError + + This function can take as arguments any arguments recognized by + `numpy.max`. If arguments are passed to a non-numpy array, a TypeError + is raised """ try: # Faster for numpy arrays - mymax = self._value.max() + mymax = self._value.max(*args, **kwargs) except AttributeError: + if args or kwargs: + raise TypeError('Unsupported arguments for Quantity.max') mymax = max(self._value) return Quantity(mymax, self.unit) - def min(self): + def min(self, *args, **kwargs): """ Computes the minimum value of the sequence, with the result having the same unit as the current sequence. If the value is not iterable, it raises a TypeError + + This function can take as arguments any arguments recognized by + `numpy.min`. If arguments are passed to a non-numpy array, a TypeError + is raised """ try: # Faster for numpy arrays - mymin = self._value.min() + mymin = self._value.min(*args, **kwargs) except AttributeError: mymin = min(self._value) return Quantity(mymin, self.unit) -- GitLab From 019f502642db587ae586445c79a46e602b737db9 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 3 Nov 2014 14:42:25 -0500 Subject: [PATCH 079/338] Add missing arg check. Implement "reshape" in Quantity that passes down to the underlying numpy array. This function would be used in instances where, for instance, a certain API would send a flattened array of coordinates or velocities with units attached, and you wanted to reshape the array into (natom, 3) to be consistent with OpenMM's Context object. --- wrappers/python/simtk/unit/quantity.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index 1f5b764a8..9a43600db 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -561,9 +561,22 @@ class Quantity(object): # Faster for numpy arrays mymin = self._value.min(*args, **kwargs) except AttributeError: + if args or kwargs: + raise TypeError('Unsupported arguments for Quantity.min') mymin = min(self._value) return Quantity(mymin, self.unit) + def reshape(self, shape, order='C'): + """ + Same as numpy.ndarray.reshape, except the result is a Quantity with the + same units as the current object rather than a plain numpy.ndarray + """ + try: + return Quantity(self._value.reshape(shape, order=order)) + except AttributeError: + raise AttributeError('Only numpy array Quantity objects can be ' + 'reshaped') + def __abs__(self): """ Return absolute value of a Quantity. -- GitLab From e55865cc73dac42e6849b6736841f78ba4534480 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 3 Nov 2014 12:05:54 -0800 Subject: [PATCH 080/338] If CUDA or OpenCL is not being built, default to not building the corresponding plugins --- plugins/amoeba/CMakeLists.txt | 6 +++--- plugins/drude/CMakeLists.txt | 12 ++++++------ plugins/rpmd/CMakeLists.txt | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/plugins/amoeba/CMakeLists.txt b/plugins/amoeba/CMakeLists.txt index d495a47ee..d7acba964 100644 --- a/plugins/amoeba/CMakeLists.txt +++ b/plugins/amoeba/CMakeLists.txt @@ -125,11 +125,11 @@ ENDIF(OPENMM_BUILD_STATIC_LIB) ADD_SUBDIRECTORY(platforms/reference) -IF(CUDA_FOUND) +IF(OPENMM_BUILD_CUDA_LIB) SET(OPENMM_BUILD_AMOEBA_CUDA_LIB ON CACHE BOOL "Build OpenMMAmoebaCuda library for Nvidia GPUs") -ELSE(CUDA_FOUND) +ELSE(OPENMM_BUILD_CUDA_LIB) SET(OPENMM_BUILD_AMOEBA_CUDA_LIB OFF CACHE BOOL "Build OpenMMAmoebaCuda library for Nvidia GPUs") -ENDIF(CUDA_FOUND) +ENDIF(OPENMM_BUILD_CUDA_LIB) SET(OPENMM_BUILD_AMOEBA_PATH) SET(OPENMM_BUILD_AMOEBA_CUDA_PATH) diff --git a/plugins/drude/CMakeLists.txt b/plugins/drude/CMakeLists.txt index 2f66e5e03..d02ec3aa4 100644 --- a/plugins/drude/CMakeLists.txt +++ b/plugins/drude/CMakeLists.txt @@ -102,20 +102,20 @@ ENDIF(OPENMM_BUILD_STATIC_LIB) ADD_SUBDIRECTORY(platforms/reference) -IF(OPENCL_FOUND) +IF(OPENMM_BUILD_OPENCL_LIB) SET(OPENMM_BUILD_DRUDE_OPENCL_LIB ON CACHE BOOL "Build Drude implementation for OpenCL") -ELSE(OPENCL_FOUND) +ELSE(OPENMM_BUILD_OPENCL_LIB) SET(OPENMM_BUILD_DRUDE_OPENCL_LIB OFF CACHE BOOL "Build Drude implementation for OpenCL") -ENDIF(OPENCL_FOUND) +ENDIF(OPENMM_BUILD_OPENCL_LIB) IF(OPENMM_BUILD_DRUDE_OPENCL_LIB) ADD_SUBDIRECTORY(platforms/opencl) ENDIF(OPENMM_BUILD_DRUDE_OPENCL_LIB) -IF(CUDA_FOUND) +IF(OPENMM_BUILD_CUDA_LIB) SET(OPENMM_BUILD_DRUDE_CUDA_LIB ON CACHE BOOL "Build Drude implementation for CUDA") -ELSE(CUDA_FOUND) +ELSE(OPENMM_BUILD_CUDA_LIB) SET(OPENMM_BUILD_DRUDE_CUDA_LIB OFF CACHE BOOL "Build Drude implementation for CUDA") -ENDIF(CUDA_FOUND) +ENDIF(OPENMM_BUILD_CUDA_LIB) IF(OPENMM_BUILD_DRUDE_CUDA_LIB) ADD_SUBDIRECTORY(platforms/cuda) ENDIF(OPENMM_BUILD_DRUDE_CUDA_LIB) diff --git a/plugins/rpmd/CMakeLists.txt b/plugins/rpmd/CMakeLists.txt index 646d011f9..b71160476 100644 --- a/plugins/rpmd/CMakeLists.txt +++ b/plugins/rpmd/CMakeLists.txt @@ -109,20 +109,20 @@ ENDIF(OPENMM_BUILD_STATIC_LIB) ADD_SUBDIRECTORY(platforms/reference) -IF(OPENCL_FOUND) +IF(OPENMM_BUILD_OPENCL_LIB) SET(OPENMM_BUILD_RPMD_OPENCL_LIB ON CACHE BOOL "Build RPMD implementation for OpenCL") -ELSE(OPENCL_FOUND) +ELSE(OPENMM_BUILD_OPENCL_LIB) SET(OPENMM_BUILD_RPMD_OPENCL_LIB OFF CACHE BOOL "Build RPMD implementation for OpenCL") -ENDIF(OPENCL_FOUND) +ENDIF(OPENMM_BUILD_OPENCL_LIB) IF(OPENMM_BUILD_RPMD_OPENCL_LIB) ADD_SUBDIRECTORY(platforms/opencl) ENDIF(OPENMM_BUILD_RPMD_OPENCL_LIB) -IF(CUDA_FOUND) +IF(OPENMM_BUILD_CUDA_LIB) SET(OPENMM_BUILD_RPMD_CUDA_LIB ON CACHE BOOL "Build RPMD implementation for CUDA") -ELSE(CUDA_FOUND) +ELSE(OPENMM_BUILD_CUDA_LIB) SET(OPENMM_BUILD_RPMD_CUDA_LIB OFF CACHE BOOL "Build RPMD implementation for CUDA") -ENDIF(CUDA_FOUND) +ENDIF(OPENMM_BUILD_CUDA_LIB) IF(OPENMM_BUILD_RPMD_CUDA_LIB) ADD_SUBDIRECTORY(platforms/cuda) ENDIF(OPENMM_BUILD_RPMD_CUDA_LIB) -- GitLab From 7216f92dc12582885460f50791393ce55baca0b8 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Mon, 3 Nov 2014 18:39:02 -0500 Subject: [PATCH 081/338] Updated broken links in travis badge in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cc03c71c5..db6f5cd85 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## OpenMM: A High Performance Molecular Dynamics Library -[![Build Status](https://travis-ci.org/SimTk/openmm.png?branch=master)](https://travis-ci.org/SimTk/openmm) +[![Build Status](https://travis-ci.org/pandegroup/openmm.png?branch=master)](https://travis-ci.org/pandegroup/openmm) Introduction ------------ -- GitLab From c1cbd4413c73487403dcad061c776015e0d4d3ad Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 3 Nov 2014 20:58:20 -0800 Subject: [PATCH 082/338] range check getPlatform() --- olla/src/Platform.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/olla/src/Platform.cpp b/olla/src/Platform.cpp index 04d755b48..cdef71f0e 100644 --- a/olla/src/Platform.cpp +++ b/olla/src/Platform.cpp @@ -134,7 +134,10 @@ int Platform::getNumPlatforms() { } Platform& Platform::getPlatform(int index) { - return *getPlatforms()[index]; + if (index >= 0 && index < getNumPlatforms()) { + return *getPlatforms()[index]; + } + throw OpenMMException("Invalid platform index"); } Platform& Platform::getPlatformByName(const string& name) { -- GitLab From a5c00fa5504ca9b59c7dd7f07527be90f6a8e83a Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 4 Nov 2014 11:17:13 -0500 Subject: [PATCH 083/338] Fix another small bug for unit handling with numpy arrays. Fixes the exception: Traceback (most recent call last): File ".../python/tests/TestNumpyCompatibility.py", line 87, in testNumpyAttributes d = self.data.reshape((100, 3)) File ".../simtk/unit/quantity.py", line 575, in reshape return Quantity(self._value.reshape(shape, order=order)) File ".../simtk/unit/quantity.py", line 142, in __init__ if value == first_item: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() Also add a test for new unit numpy capabilities. --- wrappers/python/simtk/unit/quantity.py | 10 +++++++++- .../python/tests/TestNumpyCompatibility.py | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index 9a43600db..8c17e2c3e 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -139,7 +139,15 @@ class Quantity(object): first_item = iter(value).next() # Avoid infinite recursion for string, because a one-character # string is its own first element - if value == first_item: + try: + isstr = bool(value == first_item) + except ValueError: + # For numpy, value == first_item returns a numpy + # array of booleans, which cannot be evaluated for + # truthiness (a ValueError is raised). So in this + # case, we don't have a string + isstr = False + if isstr: unit = dimensionless else: unit = Quantity(first_item).unit diff --git a/wrappers/python/tests/TestNumpyCompatibility.py b/wrappers/python/tests/TestNumpyCompatibility.py index 7e87343c5..c4cfd4dbe 100644 --- a/wrappers/python/tests/TestNumpyCompatibility.py +++ b/wrappers/python/tests/TestNumpyCompatibility.py @@ -78,5 +78,24 @@ class TestNumpyCompatibility(unittest.TestCase): assert size == 10 np.testing.assert_array_almost_equal(energy, np.asarray(energy_out)) +class TestNumpyUnits(unittest.TestCase): + + def setUp(self): + self.data = unit.Quantity(np.arange(300), unit.nanometers) + + def testNumpyAttributes(self): + d = self.data.reshape((100, 3)) + self.assertTrue(unit.is_quantity(d)) + self.assertTrue(unit.is_quantity(d.sum())) + self.assertTrue(unit.is_quantity(d.sum(axis=0))) + self.assertTrue(unit.is_quantity(d.std())) + self.assertTrue(unit.is_quantity(d.std(axis=0))) + self.assertTrue(unit.is_quantity(d.max())) + self.assertTrue(unit.is_quantity(d.max(axis=1))) + self.assertTrue(unit.is_quantity(d.min())) + self.assertTrue(unit.is_quantity(d.min(axis=0))) + self.assertTrue(unit.is_quantity(d.mean())) + self.assertTrue(unit.is_quantity(d.mean(axis=1))) + if __name__ == '__main__': unittest.main() -- GitLab From 5b4abbb5d39f0bcf77fec467cbb6a27269f2428c Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 4 Nov 2014 11:41:01 -0500 Subject: [PATCH 084/338] Oops... Forgot unit on the reshape command. Add a test for the various numpy attributes (and the arguments they take) for the unit module. --- wrappers/python/simtk/unit/quantity.py | 2 +- wrappers/python/tests/TestNumpyCompatibility.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index 8c17e2c3e..69e137a00 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -580,7 +580,7 @@ class Quantity(object): same units as the current object rather than a plain numpy.ndarray """ try: - return Quantity(self._value.reshape(shape, order=order)) + return Quantity(self._value.reshape(shape, order=order), self.unit) except AttributeError: raise AttributeError('Only numpy array Quantity objects can be ' 'reshaped') diff --git a/wrappers/python/tests/TestNumpyCompatibility.py b/wrappers/python/tests/TestNumpyCompatibility.py index c4cfd4dbe..fcaf6ea5f 100644 --- a/wrappers/python/tests/TestNumpyCompatibility.py +++ b/wrappers/python/tests/TestNumpyCompatibility.py @@ -75,7 +75,7 @@ class TestNumpyCompatibility(unittest.TestCase): f.addMap(10, energy) size, energy_out = f.getMapParameters(0) - assert size == 10 + self.assertEqual(size, 10) np.testing.assert_array_almost_equal(energy, np.asarray(energy_out)) class TestNumpyUnits(unittest.TestCase): @@ -85,7 +85,7 @@ class TestNumpyUnits(unittest.TestCase): def testNumpyAttributes(self): d = self.data.reshape((100, 3)) - self.assertTrue(unit.is_quantity(d)) + self.assertTrue(unit.is_quantity(d) and d.unit is unit.nanometers) self.assertTrue(unit.is_quantity(d.sum())) self.assertTrue(unit.is_quantity(d.sum(axis=0))) self.assertTrue(unit.is_quantity(d.std())) -- GitLab From 96e6c4bc2bd053e5ec9119cb8c8a3e9103d9bb68 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 4 Nov 2014 11:17:10 -0800 Subject: [PATCH 085/338] testInstallation.py gives more information about errors --- examples/testInstallation.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/testInstallation.py b/examples/testInstallation.py index d5a489133..56eac1dd8 100644 --- a/examples/testInstallation.py +++ b/examples/testInstallation.py @@ -24,6 +24,7 @@ numPlatforms = Platform.getNumPlatforms() print("There are", numPlatforms, "Platforms available:") print() forces = [None]*numPlatforms +platformErrors = {} for i in range(numPlatforms): platform = Platform.getPlatform(i) print(i+1, platform.getName(), end=" ") @@ -36,6 +37,13 @@ for i in range(numPlatforms): print("- Successfully computed forces") except: print("- Error computing forces with", platform.getName(), "platform") + platformErrors[platform.getName()] = sys.exc_info()[1] + +# Give details of any errors. + +for platform in platformErrors: + print() + print("%s platform error: %s" % (platform, platformErrors[platform])) # See how well the platforms agree. -- GitLab From f32c804bf86ac699f739c5ec3b9b3a33dbca58f8 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 4 Nov 2014 13:10:55 -0800 Subject: [PATCH 086/338] Improvements to multi-GPU performance --- platforms/cuda/src/CudaNonbondedUtilities.cpp | 2 ++ platforms/cuda/src/CudaParallelKernels.cpp | 20 +++++++++++-------- .../opencl/src/OpenCLNonbondedUtilities.cpp | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/platforms/cuda/src/CudaNonbondedUtilities.cpp b/platforms/cuda/src/CudaNonbondedUtilities.cpp index 3391abf28..2b08d5a09 100644 --- a/platforms/cuda/src/CudaNonbondedUtilities.cpp +++ b/platforms/cuda/src/CudaNonbondedUtilities.cpp @@ -342,6 +342,8 @@ void CudaNonbondedUtilities::initialize(const System& system) { void CudaNonbondedUtilities::prepareInteractions() { if (!useCutoff) return; + if (numTiles == 0) + return; if (usePeriodic) { double4 box = context.getPeriodicBoxSize(); double minAllowedSize = 1.999999*cutoff; diff --git a/platforms/cuda/src/CudaParallelKernels.cpp b/platforms/cuda/src/CudaParallelKernels.cpp index 833bad8c6..400bcd7cf 100644 --- a/platforms/cuda/src/CudaParallelKernels.cpp +++ b/platforms/cuda/src/CudaParallelKernels.cpp @@ -71,12 +71,7 @@ public: cu.setAsCurrent(); if (cu.getContextIndex() > 0) { - if (cu.getPlatformData().peerAccessSupported && false) { // Why is the peer-to-peer copy slower??? - CudaContext& context0 = *cu.getPlatformData().contexts[0]; - int numBytes = cu.getPosq().getSize()*cu.getPosq().getElementSize(); - CHECK_RESULT(cuMemcpyAsync(cu.getPosq().getDevicePointer(), context0.getPosq().getDevicePointer(), numBytes, 0), "Error copying positions"); - } - else { + if (!cu.getPlatformData().peerAccessSupported) { cuStreamWaitEvent(cu.getCurrentStream(), event, 0); cu.getPosq().upload(pinnedMemory, false); } @@ -117,7 +112,8 @@ public: cu.getForce().download(&pinnedMemory[(cu.getContextIndex()-1)*numAtoms*3]); } else { - CHECK_RESULT(cuCtxSynchronize(), "Error synchronizing CUDA context"); + // In principle this should make the load balancing more accurate, but in practice it just seems to make things slower. + //CHECK_RESULT(cuCtxSynchronize(), "Error synchronizing CUDA context"); } } completionTime = getTime(); @@ -175,10 +171,18 @@ void CudaParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& contex // Copy coordinates over to each device and execute the kernel. - if (!(cu.getPlatformData().peerAccessSupported && false)) { // Why is this faster than a peer-to-peer copy??? + if (!cu.getPlatformData().peerAccessSupported) { cu.getPosq().download(pinnedPositionBuffer, false); cuEventRecord(event, cu.getCurrentStream()); } + else { + int numBytes = cu.getPosq().getSize()*cu.getPosq().getElementSize(); + for (int i = 1; i < (int) data.contexts.size(); i++) { + data.contexts[i]->setAsCurrent(); + CHECK_RESULT(cuMemcpyAsync(data.contexts[i]->getPosq().getDevicePointer(), cu.getPosq().getDevicePointer(), numBytes, 0), "Error copying positions"); + } + cu.setAsCurrent(); + } for (int i = 0; i < (int) data.contexts.size(); i++) { data.contextEnergy[i] = 0.0; CudaContext& cu = *data.contexts[i]; diff --git a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp index 3baa36ea9..1073ab3ee 100644 --- a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp +++ b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp @@ -386,6 +386,8 @@ static void setInvPeriodicBoxSizeArg(OpenCLContext& cl, cl::Kernel& kernel, int void OpenCLNonbondedUtilities::prepareInteractions() { if (!useCutoff) return; + if (numTiles == 0) + return; if (usePeriodic) { mm_float4 box = context.getPeriodicBoxSize(); double minAllowedSize = 1.999999*cutoff; -- GitLab From 2504cf1ac4ad1a815ce1464a2562eb1b108315e9 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 4 Nov 2014 16:54:39 -0800 Subject: [PATCH 087/338] Initial support for reading PDBx/mmCIF files --- wrappers/python/setup.py | 4 +- wrappers/python/simtk/openmm/app/__init__.py | 1 + .../openmm/app/internal/pdbx/__init__.py | 0 .../internal/pdbx/reader/PdbxContainers.py | 819 ++++++++++++++++++ .../app/internal/pdbx/reader/PdbxParser.py | 638 ++++++++++++++ .../pdbx/reader/PdbxReadWriteTests.py | 236 +++++ .../app/internal/pdbx/reader/PdbxReader.py | 461 ++++++++++ .../internal/pdbx/reader/PdbxReaderTests.py | 126 +++ .../app/internal/pdbx/reader/__init__.py | 0 .../app/internal/pdbx/writer/PdbxWriter.py | 191 ++++ .../internal/pdbx/writer/PdbxWriterTests.py | 165 ++++ .../app/internal/pdbx/writer/__init__.py | 0 wrappers/python/simtk/openmm/app/pdbxfile.py | 197 +++++ 13 files changed, 2837 insertions(+), 1 deletion(-) create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/__init__.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxContainers.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxParser.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReadWriteTests.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReader.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReaderTests.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/reader/__init__.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriter.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriterTests.py create mode 100644 wrappers/python/simtk/openmm/app/internal/pdbx/writer/__init__.py create mode 100644 wrappers/python/simtk/openmm/app/pdbxfile.py diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index e9861e223..dfcf900fa 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -145,7 +145,9 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, "simtk.openmm", "simtk.openmm.app", "simtk.openmm.app.internal", - "simtk.openmm.app.internal.charmm"] + "simtk.openmm.app.internal.charmm", + "simtk.openmm.app.internal.pdbx.reader", + "simtk.openmm.app.internal.pdbx.writer"] setupKeywords["data_files"] = [] setupKeywords["package_data"] = {"simtk" : [], "simtk.unit" : [], diff --git a/wrappers/python/simtk/openmm/app/__init__.py b/wrappers/python/simtk/openmm/app/__init__.py index ce4c12272..ece1143f9 100644 --- a/wrappers/python/simtk/openmm/app/__init__.py +++ b/wrappers/python/simtk/openmm/app/__init__.py @@ -12,6 +12,7 @@ __email__ = "peastman@stanford.edu" from topology import Topology, Chain, Residue, Atom from pdbfile import PDBFile +from pdbxfile import PDBxFile from forcefield import ForceField from simulation import Simulation from pdbreporter import PDBReporter diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/__init__.py b/wrappers/python/simtk/openmm/app/internal/pdbx/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxContainers.py b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxContainers.py new file mode 100644 index 000000000..ef5e4ba0d --- /dev/null +++ b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxContainers.py @@ -0,0 +1,819 @@ +## +# +# File: PdbxContainers.py +# Original: 02-Feb-2009 jdw +# +# Update: +# 23-Mar-2011 jdw Added method to rename attributes in category containers. +# 05-Apr-2011 jdw Change cif writer to select double quoting as preferred +# quoting style where possible. +# 16-Jan-2012 jdw Create base class for DataCategory class +# 22-Mar-2012 jdw when append attributes to existing categories update +# existing rows with placeholder null values. +# 2-Sep-2012 jdw add option to avoid embedded quoting that might +# confuse simple parsers. +# 28-Jun-2013 jdw export remove method +# 29-Jun-2013 jdw export remove row method +## +""" + +A collection of container classes supporting the PDBx/mmCIF storage model. + +A base container class is defined which supports common features of +data and definition containers. PDBx data files are organized in +sections called data blocks which are mapped to data containers. +PDBx dictionaries contain definition sections and data sections +which are mapped to definition and data containes respectively. + +Data in both PDBx data files and dictionaries are organized in +data categories. In the PDBx syntax individual items or data +identified by labels of the form '_categoryName.attributeName'. +The terms category and attribute in PDBx jargon are analogous +table and column in relational data model, or class and attribute +in an object oriented data model. + +The DataCategory class provides base storage container for instance +data and definition meta data. + +""" + +__docformat__ = "restructuredtext en" +__author__ = "John Westbrook" +__email__ = "jwest@rcsb.rutgers.edu" +__license__ = "Creative Commons Attribution 3.0 Unported" +__version__ = "V0.01" + +import re,sys,traceback + +class CifName(object): + ''' Class of utilities for CIF-style data names - + ''' + def __init__(self): + pass + + @staticmethod + def categoryPart(name): + tname="" + if name.startswith("_"): + tname=name[1:] + else: + tname=name + + i = tname.find(".") + if i == -1: + return tname + else: + return tname[:i] + + @staticmethod + def attributePart(name): + i = name.find(".") + if i == -1: + return None + else: + return name[i+1:] + + +class ContainerBase(object): + ''' Container base class for data and definition objects. + ''' + def __init__(self,name): + # The enclosing scope of the data container (e.g. data_/save_) + self.__name = name + # List of category names within this container - + self.__objNameList=[] + # dictionary of DataCategory objects keyed by category name. + self.__objCatalog={} + self.__type=None + + def getType(self): + return self.__type + + def setType(self,type): + self.__type=type + + def getName(self): + return self.__name + + def setName(self,name): + self.__name=name + + def exists(self,name): + if self.__objCatalog.has_key(name): + return True + else: + return False + + def getObj(self,name): + if self.__objCatalog.has_key(name): + return self.__objCatalog[name] + else: + return None + + def getObjNameList(self): + return self.__objNameList + + def append(self,obj): + """ Add the input object to the current object catalog. An existing object + of the same name will be overwritten. + """ + if obj.getName() is not None: + if not self.__objCatalog.has_key(obj.getName()): + # self.__objNameList is keeping track of object order here -- + self.__objNameList.append(obj.getName()) + self.__objCatalog[obj.getName()]=obj + + def replace(self,obj): + """ Replace an existing object with the input object + """ + if ((obj.getName() is not None) and (self.__objCatalog.has_key(obj.getName())) ): + self.__objCatalog[obj.getName()]=obj + + + def printIt(self,fh=sys.stdout,type="brief"): + fh.write("+ %s container: %30s contains %4d categories\n" % + (self.getType(),self.getName(),len(self.__objNameList))) + for nm in self.__objNameList: + fh.write("--------------------------------------------\n") + fh.write("Data category: %s\n" % nm) + if type == 'brief': + self.__objCatalog[nm].printIt(fh) + else: + self.__objCatalog[nm].dumpIt(fh) + + + def rename(self,curName,newName): + """ Change the name of an object in place - + """ + try: + i=self.__objNameList.index(curName) + self.__objNameList[i]=newName + self.__objCatalog[newName]=self.__objCatalog[curName] + self.__objCatalog[newName].setName(newName) + return True + except: + return False + + def remove(self,curName): + """ Revmove object by name. Return True on success or False otherwise. + """ + try: + if self.__objCatalog.has_key(curName): + del self.__objCatalog[curName] + i=self.__objNameList.index(curName) + del self.__objNameList[i] + return True + else: + return False + except: + pass + + return False + + +class DefinitionContainer(ContainerBase): + def __init__(self,name): + super(DefinitionContainer,self).__init__(name) + self.setType('definition') + + def isCategory(self): + if self.exists('category'): + return True + return False + + def isAttribute(self): + if self.exists('item'): + return True + return False + + + def printIt(self,fh=sys.stdout,type="brief"): + fh.write("Definition container: %30s contains %4d categories\n" % + (self.getName(),len(self.getObjNameList()))) + if self.isCategory(): + fh.write("Definition type: category\n") + elif self.isAttribute(): + fh.write("Definition type: item\n") + else: + fh.write("Definition type: undefined\n") + + for nm in self.getObjNameList(): + fh.write("--------------------------------------------\n") + fh.write("Definition category: %s\n" % nm) + if type == 'brief': + self.getObj(nm).printIt(fh) + else: + self.getObj(nm).dumpId(fh) + + + +class DataContainer(ContainerBase): + ''' Container class for DataCategory objects. + ''' + def __init__(self,name): + super(DataContainer,self).__init__(name) + self.setType('data') + self.__globalFlag=False + + def invokeDataBlockMethod(self,type,method,db): + self.__currentRow = 1 + exec method.getInline() + + def setGlobal(self): + self.__globalFlag=True + + def getGlobal(self): + return self.__globalFlag + + + +class DataCategoryBase(object): + """ Base object definition for a data category - + """ + def __init__(self,name,attributeNameList=None,rowList=None): + self._name = name + # + if rowList is not None: + self._rowList=rowList + else: + self._rowList=[] + + if attributeNameList is not None: + self._attributeNameList=attributeNameList + else: + self._attributeNameList=[] + # + # Derived class data - + # + self._catalog={} + self._numAttributes=0 + # + self.__setup() + + def __setup(self): + self._numAttributes = len(self._attributeNameList) + self._catalog={} + for attributeName in self._attributeNameList: + attributeNameLC = attributeName.lower() + self._catalog[attributeNameLC] = attributeName + # + def setRowList(self,rowList): + self._rowList=rowList + + def setAttributeNameList(self,attributeNameList): + self._attributeNameList=attributeNameList + self.__setup() + + def setName(self,name): + self._name=name + + def get(self): + return (self._name,self._attributeNameList,self._rowList) + + + +class DataCategory(DataCategoryBase): + """ Methods for creating, accessing, and formatting PDBx cif data categories. + """ + def __init__(self,name,attributeNameList=None,rowList=None): + super(DataCategory,self).__init__(name,attributeNameList,rowList) + # + self.__lfh = sys.stdout + + self.__currentRowIndex=0 + self.__currentAttribute=None + # + self.__avoidEmbeddedQuoting=False + # + # -------------------------------------------------------------------- + # any whitespace + self.__wsRe=re.compile(r"\s") + self.__wsAndQuotesRe=re.compile(r"[\s'\"]") + # any newline or carriage control + self.__nlRe=re.compile(r"[\n\r]") + # + # single quote + self.__sqRe=re.compile(r"[']") + # + self.__sqWsRe=re.compile(r"('\s)|(\s')") + + # double quote + self.__dqRe=re.compile(r'["]') + self.__dqWsRe=re.compile(r'("\s)|(\s")') + # + self.__intRe=re.compile(r'^[0-9]+$') + self.__floatRe=re.compile(r'^-?(([0-9]+)[.]?|([0-9]*[.][0-9]+))([(][0-9]+[)])?([eE][+-]?[0-9]+)?$') + # + self.__dataTypeList=['DT_NULL_VALUE','DT_INTEGER','DT_FLOAT','DT_UNQUOTED_STRING','DT_ITEM_NAME', + 'DT_DOUBLE_QUOTED_STRING','DT_SINGLE_QUOTED_STRING','DT_MULTI_LINE_STRING'] + self.__formatTypeList=['FT_NULL_VALUE','FT_NUMBER','FT_NUMBER','FT_UNQUOTED_STRING', + 'FT_QUOTED_STRING','FT_QUOTED_STRING','FT_QUOTED_STRING','FT_MULTI_LINE_STRING'] + # + + + def __getitem__(self, x): + """ Implements list-type functionality - + Implements op[x] for some special cases - + x=integer - returns the row in category (normal list behavior) + x=string - returns the value of attribute 'x' in first row. + """ + if isinstance(x, int): + #return self._rowList.__getitem__(x) + return self._rowList[x] + + elif isinstance(x, str): + try: + #return self._rowList[0][x] + ii=self.getAttributeIndex(x) + return self._rowList[0][ii] + except (IndexError, KeyError): + raise KeyError + raise TypeError, x + + + def getCurrentAttribute(self): + return self.__currentAttribute + + + def getRowIndex(self): + return self.__currentRowIndex + + def getRowList(self): + return self._rowList + + def getRowCount(self): + return (len(self._rowList)) + + def getRow(self,index): + try: + return self._rowList[index] + except: + return [] + + def removeRow(self,index): + try: + if ((index >= 0) and (index < len(self._rowList))): + del self._rowList[index] + if self.__currentRowIndex >= len(self._rowList): + self.__currentRowIndex = len(self._rowList) -1 + return True + else: + pass + except: + pass + + return False + + def getFullRow(self,index): + """ Return a full row based on the length of the the attribute list. + """ + try: + if (len(self._rowList[index]) < self._numAttributes): + for ii in range( self._numAttributes-len(self._rowList[index])): + self._rowList[index].append('?') + return self._rowList[index] + except: + return ['?' for ii in range(self._numAttributes)] + + def getName(self): + return self._name + + def getAttributeList(self): + return self._attributeNameList + + def getAttributeCount(self): + return len(self._attributeNameList) + + def getAttributeListWithOrder(self): + oL=[] + for ii,att in enumerate(self._attributeNameList): + oL.append((att,ii)) + return oL + + def getAttributeIndex(self,attributeName): + try: + return self._attributeNameList.index(attributeName) + except: + return -1 + + def hasAttribute(self,attributeName): + return attributeName in self._attributeNameList + + def getIndex(self,attributeName): + try: + return self._attributeNameList.index(attributeName) + except: + return -1 + + def getItemNameList(self): + itemNameList=[] + for att in self._attributeNameList: + itemNameList.append("_"+self._name+"."+att) + return itemNameList + + def append(self,row): + #self.__lfh.write("PdbxContainer(append) category %s row %r\n" % (self._name,row)) + self._rowList.append(row) + + def appendAttribute(self,attributeName): + attributeNameLC = attributeName.lower() + if attributeNameLC in self._catalog: + i = self._attributeNameList.index(self._catalog[attributeNameLC]) + self._attributeNameList[i] = attributeName + self._catalog[attributeNameLC] = attributeName + #self.__lfh.write("Appending existing attribute %s\n" % attributeName) + else: + #self.__lfh.write("Appending existing attribute %s\n" % attributeName) + self._attributeNameList.append(attributeName) + self._catalog[attributeNameLC] = attributeName + # + self._numAttributes = len(self._attributeNameList) + + + def appendAttributeExtendRows(self,attributeName): + attributeNameLC = attributeName.lower() + if attributeNameLC in self._catalog: + i = self._attributeNameList.index(self._catalog[attributeNameLC]) + self._attributeNameList[i] = attributeName + self._catalog[attributeNameLC] = attributeName + self.__lfh.write("Appending existing attribute %s\n" % attributeName) + else: + self._attributeNameList.append(attributeName) + self._catalog[attributeNameLC] = attributeName + # add a placeholder to any existing rows for the new attribute. + if (len(self._rowList) > 0): + for row in self._rowList: + row.append("?") + # + self._numAttributes = len(self._attributeNameList) + + + + def getValue(self,attributeName=None,rowIndex=None): + if attributeName is None: + attribute = self.__currentAttribute + else: + attribute = attributeName + if rowIndex is None: + rowI = self.__currentRowIndex + else: + rowI =rowIndex + + if isinstance(attribute, str) and isinstance(rowI,int): + try: + return self._rowList[rowI][self._attributeNameList.index(attribute)] + except (IndexError): + raise IndexError + raise IndexError, attribute + + def setValue(self,value,attributeName=None,rowIndex=None): + if attributeName is None: + attribute=self.__currentAttribute + else: + attribute=attributeName + + if rowIndex is None: + rowI = self.__currentRowIndex + else: + rowI = rowIndex + + if isinstance(attribute, str) and isinstance(rowI,int): + try: + # if row index is out of range - add the rows - + for ii in range(rowI+1 - len(self._rowList)): + self._rowList.append(self.__emptyRow()) + # self._rowList[rowI][attribute]=value + ll=len(self._rowList[rowI]) + ind=self._attributeNameList.index(attribute) + + # extend the list if needed - + if ( ind >= ll): + self._rowList[rowI].extend([None for ii in xrange(2*ind -ll)]) + self._rowList[rowI][ind]=value + except (IndexError): + self.__lfh.write("DataCategory(setvalue) index error category %s attribute %s index %d value %r\n" % + (self._name,attribute,rowI,value)) + traceback.print_exc(file=self.__lfh) + #raise IndexError + except (ValueError): + self.__lfh.write("DataCategory(setvalue) value error category %s attribute %s index %d value %r\n" % + (self._name,attribute,rowI,value)) + traceback.print_exc(file=self.__lfh) + #raise ValueError + + def __emptyRow(self): + return [None for ii in range(len(self._attributeNameList))] + + def replaceValue(self,oldValue,newValue,attributeName): + numReplace=0 + if attributeName not in self._attributeNameList: + return numReplace + ind=self._attributeNameList.index(attributeName) + for row in self._rowList: + if row[ind] == oldValue: + row[ind]=newValue + numReplace += 1 + return numReplace + + def replaceSubstring(self,oldValue,newValue,attributeName): + ok=False + if attributeName not in self._attributeNameList: + return ok + ind=self._attributeNameList.index(attributeName) + for row in self._rowList: + val=row[ind] + row[ind]=val.replace(oldValue,newValue) + if val != row[ind]: + ok=True + return ok + + def invokeAttributeMethod(self,attributeName,type,method,db): + self.__currentRowIndex = 0 + self.__currentAttribute=attributeName + self.appendAttribute(attributeName) + currentRowIndex=self.__currentRowIndex + # + ind=self._attributeNameList.index(attributeName) + if len(self._rowList) == 0: + row=[None for ii in xrange(len(self._attributeNameList)*2)] + row[ind]=None + self._rowList.append(row) + + for row in self._rowList: + ll = len(row) + if (ind >= ll): + row.extend([None for ii in xrange(2*ind-ll)]) + row[ind]=None + exec method.getInline() + self.__currentRowIndex+=1 + currentRowIndex=self.__currentRowIndex + + def invokeCategoryMethod(self,type,method,db): + self.__currentRowIndex = 0 + exec method.getInline() + + def getAttributeLengthMaximumList(self): + mList=[0 for i in len(self._attributeNameList)] + for row in self._rowList: + for indx,val in enumerate(row): + mList[indx] = max(mList[indx],len(val)) + return mList + + def renameAttribute(self,curAttributeName,newAttributeName): + """ Change the name of an attribute in place - + """ + try: + i=self._attributeNameList.index(curAttributeName) + self._attributeNameList[i]=newAttributeName + del self._catalog[curAttributeName.lower()] + self._catalog[newAttributeName.lower()]=newAttributeName + return True + except: + return False + + def printIt(self,fh=sys.stdout): + fh.write("--------------------------------------------\n") + fh.write(" Category: %s attribute list length: %d\n" % + (self._name,len(self._attributeNameList))) + for at in self._attributeNameList: + fh.write(" Category: %s attribute: %s\n" % (self._name,at)) + + fh.write(" Row value list length: %d\n" % len(self._rowList)) + # + for row in self._rowList[:2]: + # + if len(row) == len(self._attributeNameList): + for ii,v in enumerate(row): + fh.write(" %30s: %s ...\n" % (self._attributeNameList[ii],str(v)[:30])) + else: + fh.write("+WARNING - %s data length %d attribute name length %s mismatched\n" % + (self._name,len(row),len(self._attributeNameList))) + + def dumpIt(self,fh=sys.stdout): + fh.write("--------------------------------------------\n") + fh.write(" Category: %s attribute list length: %d\n" % + (self._name,len(self._attributeNameList))) + for at in self._attributeNameList: + fh.write(" Category: %s attribute: %s\n" % (self._name,at)) + + fh.write(" Value list length: %d\n" % len(self._rowList)) + for row in self._rowList: + for ii,v in enumerate(row): + fh.write(" %30s: %s\n" % (self._attributeNameList[ii],v)) + + + def __formatPdbx(self, inp): + """ Format input data following PDBx quoting rules - + """ + try: + if (inp is None): + return ("?",'DT_NULL_VALUE') + + # pure numerical values are returned as unquoted strings + if (isinstance(inp,int) or self.__intRe.search(str(inp))): + return ( [str(inp)],'DT_INTEGER') + + if (isinstance(inp,float) or self.__floatRe.search(str(inp))): + return ([str(inp)],'DT_FLOAT') + + # null value handling - + + if (inp == "." or inp == "?"): + return ([inp],'DT_NULL_VALUE') + + if (inp == ""): + return (["."],'DT_NULL_VALUE') + + # Contains white space or quotes ? + if not self.__wsAndQuotesRe.search(inp): + if inp.startswith("_"): + return (self.__doubleQuotedList(inp),'DT_ITEM_NAME') + else: + return ([str(inp)],'DT_UNQUOTED_STRING') + else: + if self.__nlRe.search(inp): + return (self.__semiColonQuotedList(inp),'DT_MULTI_LINE_STRING') + else: + if (self.__avoidEmbeddedQuoting): + # change priority to choose double quoting where possible. + if not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp): + return (self.__doubleQuotedList(inp),'DT_DOUBLE_QUOTED_STRING') + elif not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp): + return (self.__singleQuotedList(inp),'DT_SINGLE_QUOTED_STRING') + else: + return (self.__semiColonQuotedList(inp),'DT_MULTI_LINE_STRING') + else: + # change priority to choose double quoting where possible. + if not self.__dqRe.search(inp): + return (self.__doubleQuotedList(inp),'DT_DOUBLE_QUOTED_STRING') + elif not self.__sqRe.search(inp): + return (self.__singleQuotedList(inp),'DT_SINGLE_QUOTED_STRING') + else: + return (self.__semiColonQuotedList(inp),'DT_MULTI_LINE_STRING') + + + except: + traceback.print_exc(file=self.__lfh) + + def __dataTypePdbx(self, inp): + """ Detect the PDBx data type - + """ + if (inp is None): + return ('DT_NULL_VALUE') + + # pure numerical values are returned as unquoted strings + if isinstance(inp,int) or self.__intRe.search(str(inp)): + return ('DT_INTEGER') + + if isinstance(inp,float) or self.__floatRe.search(str(inp)): + return ('DT_FLOAT') + + # null value handling - + + if (inp == "." or inp == "?"): + return ('DT_NULL_VALUE') + + if (inp == ""): + return ('DT_NULL_VALUE') + + # Contains white space or quotes ? + if not self.__wsAndQuotesRe.search(inp): + if inp.startswith("_"): + return ('DT_ITEM_NAME') + else: + return ('DT_UNQUOTED_STRING') + else: + if self.__nlRe.search(inp): + return ('DT_MULTI_LINE_STRING') + else: + if (self.__avoidEmbeddedQuoting): + if not self.__sqRe.search(inp) and not self.__dqWsRe.search(inp): + return ('DT_DOUBLE_QUOTED_STRING') + elif not self.__dqRe.search(inp) and not self.__sqWsRe.search(inp): + return ('DT_SINGLE_QUOTED_STRING') + else: + return ('DT_MULTI_LINE_STRING') + else: + if not self.__sqRe.search(inp): + return ('DT_DOUBLE_QUOTED_STRING') + elif not self.__dqRe.search(inp): + return ('DT_SINGLE_QUOTED_STRING') + else: + return ('DT_MULTI_LINE_STRING') + + def __singleQuotedList(self,inp): + l=[] + l.append("'") + l.append(inp) + l.append("'") + return(l) + + def __doubleQuotedList(self,inp): + l=[] + l.append('"') + l.append(inp) + l.append('"') + return(l) + + def __semiColonQuotedList(self,inp): + l=[] + l.append("\n") + if inp[-1] == '\n': + l.append(";") + l.append(inp) + l.append(";") + l.append("\n") + else: + l.append(";") + l.append(inp) + l.append("\n") + l.append(";") + l.append("\n") + + return(l) + + def getValueFormatted(self,attributeName=None,rowIndex=None): + if attributeName is None: + attribute=self.__currentAttribute + else: + attribute=attributeName + + if rowIndex is None: + rowI = self.__currentRowIndex + else: + rowI = rowIndex + + if isinstance(attribute, str) and isinstance(rowI,int): + try: + list,type=self.__formatPdbx(self._rowList[rowI][self._attributeNameList.index(attribute)]) + return "".join(list) + except (IndexError): + self.__lfh.write("attributeName %s rowI %r rowdata %r\n" % (attributeName,rowI,self._rowList[rowI])) + raise IndexError + raise TypeError, attribute + + + def getValueFormattedByIndex(self,attributeIndex,rowIndex): + try: + list,type=self.__formatPdbx(self._rowList[rowIndex][attributeIndex]) + return "".join(list) + except (IndexError): + raise IndexError + + def getAttributeValueMaxLengthList(self,steps=1): + mList=[0 for i in range(len(self._attributeNameList))] + for row in self._rowList[::steps]: + for indx in range(len(self._attributeNameList)): + val=row[indx] + mList[indx] = max(mList[indx],len(str(val))) + return mList + + def getFormatTypeList(self,steps=1): + try: + curDataTypeList=['DT_NULL_VALUE' for i in range(len(self._attributeNameList))] + for row in self._rowList[::steps]: + for indx in range(len(self._attributeNameList)): + val=row[indx] + # print "index ",indx," val ",val + dType=self.__dataTypePdbx(val) + dIndx=self.__dataTypeList.index(dType) + # print "d type", dType, " d type index ",dIndx + + cType=curDataTypeList[indx] + cIndx=self.__dataTypeList.index(cType) + cIndx= max(cIndx,dIndx) + curDataTypeList[indx]=self.__dataTypeList[cIndx] + + # Map the format types to the data types + curFormatTypeList=[] + for dt in curDataTypeList: + ii=self.__dataTypeList.index(dt) + curFormatTypeList.append(self.__formatTypeList[ii]) + except: + self.__lfh.write("PdbxDataCategory(getFormatTypeList) ++Index error at index %d in row %r\n" % (indx,row)) + + return curFormatTypeList,curDataTypeList + + def getFormatTypeListX(self): + curDataTypeList=['DT_NULL_VALUE' for i in range(len(self._attributeNameList))] + for row in self._rowList: + for indx in range(len(self._attributeNameList)): + val=row[indx] + #print "index ",indx," val ",val + dType=self.__dataTypePdbx(val) + dIndx=self.__dataTypeList.index(dType) + #print "d type", dType, " d type index ",dIndx + + cType=curDataTypeList[indx] + cIndx=self.__dataTypeList.index(cType) + cIndx= max(cIndx,dIndx) + curDataTypeList[indx]=self.__dataTypeList[cIndx] + + # Map the format types to the data types + curFormatTypeList=[] + for dt in curDataTypeList: + ii=self.__dataTypeList.index(dt) + curFormatTypeList.append(self.__formatTypeList[ii]) + return curFormatTypeList,curDataTypeList + + diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxParser.py b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxParser.py new file mode 100644 index 000000000..c48c046d2 --- /dev/null +++ b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxParser.py @@ -0,0 +1,638 @@ +## +# File: PdbxParser.py +# Date: 2009-10-25 Jdw Original from py-pdbx-parser-v2 +# +# Update: +# +# 2009-11-05 - (jdw) Change table storage architecture for list of +# dictionaries to list of lists. +# 2012-01-09 - (jdw) This module now obsolted by PdbxReader/PdbxWriter +# modules. APIs are preserved. +# +# 2012-09-01 - (jdw) Revise tokenizer to better handle embedded quoting. +# +# NOTE - - Now obsolete - Use pdb.reader.PdbxReader & pdbx.writer.PdbxWriter +# +## +""" +PDBx/mmCIF dictionary and data file parser. + +Acknowledgements: + + The tokenizer used in this module is modeled after the clever parser design + used in the PyMMLIB package. + + PyMMLib Development Group + Authors: Ethan Merritt: merritt@u.washington.ed & Jay Painter: jay.painter@gmail.com + See: http://pymmlib.sourceforge.net/ + +""" + +__docformat__ = "restructuredtext en" +__author__ = "John Westbrook" +__email__ = "jwest@rcsb.rutgers.edu" +__license__ = "Creative Commons Attribution 3.0 Unported" +__version__ = "V0.01" + +import re,sys +from simtk.openmm.app.internal.pdbx.reader.PdbxContainers import * + +class PdbxError(Exception): + """ Class for catch general errors + """ + pass + +class SyntaxError(Exception): + """ Class for catching syntax errors + """ + def __init__(self, lineNumber, text): + Exception.__init__(self) + self.lineNumber = lineNumber + self.text = text + + def __str__(self): + return "%%ERROR - [at line: %d] %s" % (self.lineNumber, self.text) + + + +class PdbxReader(object): + """ PDBx reader for data files and dictionaries. + + """ + def __init__(self,ifh): + """ ifh - input file handle returned by open() + """ + # + self.__curLineNumber = 0 + self.__ifh=ifh + self.__stateDict={"data": "ST_DATA_CONTAINER", + "loop": "ST_TABLE", + "global": "ST_GLOBAL_CONTAINER", + "save": "ST_DEFINITION", + "stop": "ST_STOP"} + + def read(self, containerList): + """ + Appends to the input list of definition and data containers. + + """ + self.__curLineNumber = 0 + try: + self.__parser(self.__tokenizer(self.__ifh), containerList) + except StopIteration: + pass + else: + raise PdbxError() + + def __syntaxError(self, errText): + raise SyntaxError(self.__curLineNumber, errText) + + def __getContainerName(self,inWord): + """ Returns the name of the data_ or save_ container + """ + return str(inWord[5:]).strip() + + def __getState(self, inWord): + """Identifies reserved syntax elements and assigns an associated state. + + Returns: (reserved word, state) + where - + reserved word - is one of CIF syntax elements: + data_, loop_, global_, save_, stop_ + state - the parser state required to process this next section. + """ + i = inWord.find("_") + if i == -1: + return None,"ST_UNKNOWN" + + try: + rWord=inWord[:i].lower() + return rWord, self.__stateDict[rWord] + except: + return None,"ST_UNKNOWN" + + def __parser(self, tokenizer, containerList): + """ Parser for PDBx data files and dictionaries. + + Input - tokenizer() reentrant method recognizing data item names (_category.attribute) + quoted strings (single, double and multi-line semi-colon delimited), and unquoted + strings. + + containerList - list-type container for data and definition objects parsed from + from the input file. + + Return: + containerList - is appended with data and definition objects - + """ + # Working container - data or definition + curContainer = None + # + # Working category container + categoryIndex = {} + curCategory = None + # + curRow = None + state = None + + # Find the first reserved word and begin capturing data. + # + while True: + curCatName, curAttName, curQuotedString, curWord = tokenizer.next() + if curWord is None: + continue + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + break + + while True: + # + # Set the current state - + # + # At this point in the processing cycle we are expecting a token containing + # either a '_category.attribute' or a reserved word. + # + if curCatName is not None: + state = "ST_KEY_VALUE_PAIR" + elif curWord is not None: + reservedWord, state = self.__getState(curWord) + else: + self.__syntaxError("Miscellaneous syntax error") + return + + # + # Process _category.attribute value assignments + # + if state == "ST_KEY_VALUE_PAIR": + try: + curCategory = categoryIndex[curCatName] + except KeyError: + # A new category is encountered - create a container and add a row + curCategory = categoryIndex[curCatName] = DataCategory(curCatName) + + try: + curContainer.append(curCategory) + except AttributeError: + self.__syntaxError("Category cannot be added to data_ block") + return + + curRow = [] + curCategory.append(curRow) + else: + # Recover the existing row from the category + try: + curRow = curCategory[0] + except IndexError: + self.__syntaxError("Internal index error accessing category data") + return + + # Check for duplicate attributes and add attribute to table. + if curAttName in curCategory.getAttributeList(): + self.__syntaxError("Duplicate attribute encountered in category") + return + else: + curCategory.appendAttribute(curAttName) + + + # Get the data for this attribute from the next token + tCat, tAtt, curQuotedString, curWord = tokenizer.next() + + if tCat is not None or (curQuotedString is None and curWord is None): + self.__syntaxError("Missing data for item _%s.%s" % (curCatName,curAttName)) + + if curWord is not None: + # + # Validation check token for misplaced reserved words - + # + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + self.__syntaxError("Unexpected reserved word: %s" % (reservedWord)) + + curRow.append(curWord) + + elif curQuotedString is not None: + curRow.append(curQuotedString) + + else: + self.__syntaxError("Missing value in item-value pair") + + curCatName, curAttName, curQuotedString, curWord = tokenizer.next() + continue + + # + # Process a loop_ declaration and associated data - + # + elif state == "ST_TABLE": + + # The category name in the next curCatName,curAttName pair + # defines the name of the category container. + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + if curCatName is None or curAttName is None: + self.__syntaxError("Unexpected token in loop_ declaration") + return + + # Check for a previous category declaration. + if categoryIndex.has_key(curCatName): + self.__syntaxError("Duplicate category declaration in loop_") + return + + curCategory = DataCategory(curCatName) + + try: + curContainer.append(curCategory) + except AttributeError: + self.__syntaxError("loop_ declaration outside of data_ block or save_ frame") + return + + curCategory.appendAttribute(curAttName) + + # Read the rest of the loop_ declaration + while True: + curCatName, curAttName, curQuotedString, curWord = tokenizer.next() + + if curCatName is None: + break + + if curCatName != curCategory.getName(): + self.__syntaxError("Changed category name in loop_ declaration") + return + + curCategory.appendAttribute(curAttName) + + + # If the next token is a 'word', check it for any reserved words - + if curWord is not None: + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + if reservedWord == "stop": + return + else: + self.__syntaxError("Unexpected reserved word after loop declaration: %s" % (reservedWord)) + + # Read the table of data for this loop_ - + while True: + curRow = [] + curCategory.append(curRow) + + for tAtt in curCategory.getAttributeList(): + if curWord is not None: + curRow.append(curWord) + elif curQuotedString is not None: + curRow.append(curQuotedString) + + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + # loop_ data processing ends if - + + # A new _category.attribute is encountered + if curCatName is not None: + break + + # A reserved word is encountered + if curWord is not None: + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + break + + continue + + + elif state == "ST_DEFINITION": + # Ignore trailing unnamed saveframe delimiters e.g. 'save_' + sName=self.__getContainerName(curWord) + if (len(sName) > 0): + curContainer = DefinitionContainer(sName) + containerList.append(curContainer) + categoryIndex = {} + curCategory = None + + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + elif state == "ST_DATA_CONTAINER": + # + dName=self.__getContainerName(curWord) + if len(dName) == 0: + dName="unidentified" + curContainer = DataContainer(dName) + containerList.append(curContainer) + categoryIndex = {} + curCategory = None + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + elif state == "ST_STOP": + return + elif state == "ST_GLOBAL": + curContainer = DataContainer("blank-global") + curContainer.setGlobal() + containerList.append(curContainer) + categoryIndex = {} + curCategory = None + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + elif state == "ST_UNKNOWN": + self.__syntaxError("Unrecogized syntax element: " + str(curWord)) + return + + + def __tokenizer(self, ifh): + """ Tokenizer method for the mmCIF syntax file - + + Each return/yield from this method returns information about + the next token in the form of a tuple with the following structure. + + (category name, attribute name, quoted strings, words w/o quotes or white space) + + Differentiated the reqular expression to the better handle embedded quotes. + + """ + # + # Regex definition for mmCIF syntax - semi-colon delimited strings are handled + # outside of this regex. + mmcifRe = re.compile( + r"(?:" + + "(?:_(.+?)[.](\S+))" "|" # _category.attribute + + "(?:['](.*?)(?:[']\s|[']$))" "|" # single quoted strings + "(?:[\"](.*?)(?:[\"]\s|[\"]$))" "|" # double quoted strings + + "(?:\s*#.*$)" "|" # comments (dumped) + + "(\S+)" # unquoted words + + ")") + + fileIter = iter(ifh) + + ## Tokenizer loop begins here --- + while True: + line = fileIter.next() + self.__curLineNumber += 1 + + # Dump comments + if line.startswith("#"): + continue + + # Gobble up the entire semi-colon/multi-line delimited string and + # and stuff this into the string slot in the return tuple + # + if line.startswith(";"): + mlString = [line[1:]] + while True: + line = fileIter.next() + self.__curLineNumber += 1 + if line.startswith(";"): + break + mlString.append(line) + + # remove trailing new-line that is part of the \n; delimiter + mlString[-1] = mlString[-1].rstrip() + # + yield (None, None, "".join(mlString), None) + # + # Need to process the remainder of the current line - + line = line[1:] + #continue + + # Apply regex to the current line consolidate the single/double + # quoted within the quoted string category + for it in mmcifRe.finditer(line): + tgroups = it.groups() + if tgroups != (None, None, None, None, None): + if tgroups[2] is not None: + qs = tgroups[2] + elif tgroups[3] is not None: + qs = tgroups[3] + else: + qs = None + groups = (tgroups[0],tgroups[1],qs,tgroups[4]) + yield groups + + def __tokenizerOrg(self, ifh): + """ Tokenizer method for the mmCIF syntax file - + + Each return/yield from this method returns information about + the next token in the form of a tuple with the following structure. + + (category name, attribute name, quoted strings, words w/o quotes or white space) + + mmcifRe = re.compile( + r"(?:" + + "(?:_(.+?)[.](\S+))" "|" # _category.attribute + + "(?:['\"](.*?)(?:['\"]\s|['\"]$))" "|" # quoted strings + + "(?:\s*#.*$)" "|" # comments (dumped) + + "(\S+)" # unquoted words + + ")") + + + """ + # + # Regex definition for mmCIF syntax - semi-colon delimited strings are handled + # outside of this regex. + mmcifRe = re.compile( + r"(?:" + + "(?:_(.+?)[.](\S+))" "|" # _category.attribute + + "(?:['\"](.*?)(?:['\"]\s|['\"]$))" "|" # quoted strings + + "(?:\s*#.*$)" "|" # comments (dumped) + + "(\S+)" # unquoted words + + ")") + + fileIter = iter(ifh) + + ## Tokenizer loop begins here --- + while True: + line = fileIter.next() + self.__curLineNumber += 1 + + # Dump comments + if line.startswith("#"): + continue + + # Gobble up the entire semi-colon/multi-line delimited string and + # and stuff this into the string slot in the return tuple + # + if line.startswith(";"): + mlString = [line[1:]] + while True: + line = fileIter.next() + self.__curLineNumber += 1 + if line.startswith(";"): + break + mlString.append(line) + + # remove trailing new-line that is part of the \n; delimiter + mlString[-1] = mlString[-1].rstrip() + # + yield (None, None, "".join(mlString), None) + # + # Need to process the remainder of the current line - + line = line[1:] + #continue + + ## Apply regex to the current line + for it in mmcifRe.finditer(line): + groups = it.groups() + if groups != (None, None, None, None): + yield groups + + +class PdbxWriter(object): + """Write PDBx data files or dictionaries using the input container + or container list. + """ + def __init__(self,ofh=sys.stdout): + self.__ofh=ofh + self.__containerList=[] + self.__MAXIMUM_LINE_LENGTH = 2048 + self.__SPACING = 2 + self.__INDENT_DEFINITION = 3 + self.__indentSpace = " " * self.__INDENT_DEFINITION + self.__doDefinitionIndent=False + + def write(self, containerList): + self.__containerList=containerList + for container in self.__containerList: + self.writeContainer(container) + + def writeContainer(self,container): + indS=" " * self.__INDENT_DEFINITION + if isinstance(container, DefinitionContainer): + self.__write("save_%s\n" % container.getName()) + self.__doDefinitionIndent=True + self.__write(indS+"#\n") + elif isinstance(container, DataContainer): + if (container.getGlobal()): + self.__write("global_\n") + self.__doDefinitionIndent=False + self.__write("\n") + else: + self.__write("data_%s\n" % container.getName()) + self.__doDefinitionIndent=False + self.__write("#\n") + + for nm in container.getObjNameList(): + obj=container.getObj(nm) + objL=obj.getRowList() + + # Skip empty objects + if len(objL) == 0: + continue + + # Item - value formattting + elif len(objL) == 1: + self.__writeItemValueFormat(obj) + + # Table formatting - + elif len(objL) > 1 and len(obj.getAttributeList()) > 0: + self.__writeTableFormat(obj) + else: + raise PdbxError() + + if self.__doDefinitionIndent: + self.__write(indS+"#") + else: + self.__write("#") + + # Add a trailing saveframe reserved word + if isinstance(container, DefinitionContainer): + self.__write("save_\n") + self.__write("#\n") + + def __write(self, st): + self.__ofh.write(st) + + def __writeItemValueFormat(self, myCategory): + + # Compute the maximum item name length within this category - + attributeNameLengthMax = 0 + for attributeName in myCategory.getAttributeList(): + attributeNameLengthMax = max(attributeNameLengthMax, len(attributeName)) + itemNameLengthMax = self.__SPACING + len(myCategory.getName()) + attributeNameLengthMax + 2 + # + lineList=[] + for attributeName,iPos in myCategory.getAttributeListWithOrder(): + lineList.append("\n") + if self.__doDefinitionIndent: + # - add indent -- + lineList.append(self.__indentSpace) + + itemName = "_%s.%s" % (myCategory.getName(), attributeName) + lineList.append(itemName.ljust(itemNameLengthMax)) + + lineList.append(myCategory.getValueFormatted(attributeName,0)) + + lineList.append("\n") + self.__write("".join(lineList)) + + def __writeTableFormat(self, myCategory): + + # Write the declaration of the loop_ + # + lineList=[] + lineList.append('\n') + if self.__doDefinitionIndent: + lineList.append(self.__indentSpace) + lineList.append("loop_") + for attributeName in myCategory.getAttributeList(): + lineList.append('\n') + if self.__doDefinitionIndent: + lineList.append(self.__indentSpace) + itemName = "_%s.%s" % (myCategory.getName(), attributeName) + lineList.append(itemName) + self.__write("".join(lineList)) + + # + # Write the data in tabular format - + # + #print myCategory.getName() + #print myCategory.getAttributeList() + + formatTypeList,dataTypeList=myCategory.getFormatTypeList() + maxLengthList=myCategory.getAttributeValueMaxLengthList() + spacing = " " * self.__SPACING + # + + #print formatTypeList + #print dataTypeList + #print maxLengthList + # + for iRow in range(myCategory.getRowCount()): + lineList = [] + lineList.append('\n') + if self.__doDefinitionIndent: + lineList.append(self.__indentSpace + " ") + + for iAt in range(myCategory.getAttributeCount()): + formatType = formatTypeList[iAt] + maxLength = maxLengthList[iAt] + + if (formatType == 'FT_UNQUOTED_STRING' or formatType == 'FT_NULL_VALUE'): + val=myCategory.getValueFormattedByIndex(iAt,iRow) + lineList.append(val.ljust(maxLength)) + + elif formatType == 'FT_NUMBER': + val=myCategory.getValueFormattedByIndex(iAt,iRow) + lineList.append(val.rjust(maxLength)) + + elif formatType == 'FT_QUOTED_STRING': + val=myCategory.getValueFormattedByIndex(iAt,iRow) + lineList.append(val.ljust(maxLength)) + + elif formatType == "FT_MULTI_LINE_STRING": + val=myCategory.getValueFormattedByIndex(iAt,iRow) + lineList.append(val) + + lineList.append(spacing) + + self.__write("".join(lineList)) + self.__write("\n") diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReadWriteTests.py b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReadWriteTests.py new file mode 100644 index 000000000..de681781f --- /dev/null +++ b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReadWriteTests.py @@ -0,0 +1,236 @@ +## +# File: PdbxReadWriteTests.py +# Author: jdw +# Date: 9-Oct-2011 +# Version: 0.001 +# +# Updated: +# 24-Oct-2012 jdw update path details and reorganize. +# +## +""" Various tests caess for PDBx/mmCIF data file and dictionary reader and writer. +""" + +__docformat__ = "restructuredtext en" +__author__ = "John Westbrook" +__email__ = "jwest@rcsb.rutgers.edu" +__license__ = "Creative Commons Attribution 3.0 Unported" +__version__ = "V0.01" + +import sys, unittest, traceback +import sys, time, os, os.path, shutil + +from simtk.openmm.app.internal.pdbx.reader.PdbxReader import PdbxReader +from simtk.openmm.app.internal.pdbx.writer.PdbxWriter import PdbxWriter +from simtk.openmm.app.internal.pdbx.reader.PdbxContainers import * + + +class PdbxReadWriteTests(unittest.TestCase): + def setUp(self): + self.lfh=sys.stdout + self.verbose=False + self.pathPdbxDataFile = "../tests/1kip.cif" + self.pathOutputFile = "testOutputDataFile.cif" + + def tearDown(self): + pass + + + def testSimpleInitialization(self): + """Test case - Simple initialization of a data category and data block + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + fn="test-simple.cif" + attributeNameList=['aOne','aTwo','aThree','aFour','aFive','aSix','aSeven','aEight','aNine','aTen'] + rowList=[[1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10], + [1,2,3,4,5,6,7,8,9,10] + ] + nameCat='myCategory' + # + # + curContainer=DataContainer("myblock") + aCat=DataCategory(nameCat,attributeNameList,rowList) + aCat.printIt() + curContainer.append(aCat) + curContainer.printIt() + # + myContainerList=[] + myContainerList.append(curContainer) + ofh = open(fn, "w") + pdbxW=PdbxWriter(ofh) + pdbxW.write(myContainerList) + ofh.close() + + myContainerList=[] + ifh = open(fn, "r") + pRd=PdbxReader(ifh) + pRd.read(myContainerList) + ifh.close() + for container in myContainerList: + for objName in container.getObjNameList(): + name,aList,rList=container.getObj(objName).get() + self.lfh.write("Recovered data category %s\n" % name) + self.lfh.write("Attribute list %r\n" % repr(aList)) + self.lfh.write("Row list %r\n" % repr(rList)) + except: + traceback.print_exc(file=self.lfh) + self.fail() + + + def testWriteDataFile(self): + """Test case - write data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myDataList=[] + ofh = open("test-output.cif", "w") + curContainer=DataContainer("myblock") + aCat=DataCategory("pdbx_seqtool_mapping_ref") + aCat.appendAttribute("ordinal") + aCat.appendAttribute("entity_id") + aCat.appendAttribute("auth_mon_id") + aCat.appendAttribute("auth_mon_num") + aCat.appendAttribute("pdb_chain_id") + aCat.appendAttribute("ref_mon_id") + aCat.appendAttribute("ref_mon_num") + aCat.append([1,2,3,4,5,6,7]) + aCat.append([1,2,3,4,5,6,7]) + aCat.append([1,2,3,4,5,6,7]) + aCat.append([1,2,3,4,5,6,7]) + aCat.append([7,6,5,4,3,2,1]) + aCat.printIt() + curContainer.append(aCat) + curContainer.printIt() + # + myDataList.append(curContainer) + pdbxW=PdbxWriter(ofh) + pdbxW.write(myDataList) + ofh.close() + except: + traceback.print_exc(file=self.lfh) + self.fail() + + def testUpdateDataFile(self): + """Test case - update data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # Create a initial data file -- + # + myDataList=[] + + curContainer=DataContainer("myblock") + aCat=DataCategory("pdbx_seqtool_mapping_ref") + aCat.appendAttribute("ordinal") + aCat.appendAttribute("entity_id") + aCat.appendAttribute("auth_mon_id") + aCat.appendAttribute("auth_mon_num") + aCat.appendAttribute("pdb_chain_id") + aCat.appendAttribute("ref_mon_id") + aCat.appendAttribute("ref_mon_num") + aCat.append([9,2,3,4,5,6,7]) + aCat.append([10,2,3,4,5,6,7]) + aCat.append([11,2,3,4,5,6,7]) + aCat.append([12,2,3,4,5,6,7]) + + #self.lfh.write("Assigned data category state-----------------\n") + #aCat.dumpIt(fh=self.lfh) + + curContainer.append(aCat) + myDataList.append(curContainer) + ofh = open("test-output-1.cif", "w") + pdbxW=PdbxWriter(ofh) + pdbxW.write(myDataList) + ofh.close() + # + # + # Read and update the data - + # + myDataList=[] + ifh = open("test-output-1.cif", "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + # + myBlock=myDataList[0] + myBlock.printIt() + myCat=myBlock.getObj('pdbx_seqtool_mapping_ref') + myCat.printIt() + for iRow in xrange(0,myCat.getRowCount()): + myCat.setValue('some value', 'ref_mon_id',iRow) + myCat.setValue(100, 'ref_mon_num',iRow) + ofh = open("test-output-2.cif", "w") + pdbxW=PdbxWriter(ofh) + pdbxW.write(myDataList) + ofh.close() + # + + except: + traceback.print_exc(file=self.lfh) + self.fail() + + def testReadDataFile(self): + """Test case - read data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myDataList=[] + ifh = open(self.pathPdbxDataFile, "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + except: + traceback.print_exc(file=self.lfh) + self.fail() + + def testReadWriteDataFile(self): + """Test case - data file read write test + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + myDataList=[] + ifh = open(self.pathPdbxDataFile, "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + + ofh = open(self.pathOutputFile, "w") + pWr=PdbxWriter(ofh) + pWr.write(myDataList) + ofh.close() + except: + traceback.print_exc(file=self.lfh) + self.fail() + + +def simpleSuite(): + suiteSelect = unittest.TestSuite() + suiteSelect.addTest(PdbxReadWriteTests("testSimpleInitialization")) + suiteSelect.addTest(PdbxReadWriteTests("testUpdateDataFile")) + suiteSelect.addTest(PdbxReadWriteTests("testReadWriteDataFile")) + return suiteSelect + + +if __name__ == '__main__': + # + mySuite=simpleSuite() + unittest.TextTestRunner(verbosity=2).run(mySuite) + # + diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReader.py b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReader.py new file mode 100644 index 000000000..3947ed61b --- /dev/null +++ b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReader.py @@ -0,0 +1,461 @@ +## +# File: PdbxReader.py +# Date: 2012-01-09 Jdw Adapted from PdbxParser +# +# Updates: +# +# 2012-01-09 - (jdw) Separate reader and writer classes. +# +# 2012-09-02 - (jdw) Revise tokenizer to better handle embedded quoting. +# +## +""" +PDBx/mmCIF dictionary and data file parser. + +Acknowledgements: + + The tokenizer used in this module is modeled after the clever parser design + used in the PyMMLIB package. + + PyMMLib Development Group + Authors: Ethan Merritt: merritt@u.washington.ed & Jay Painter: jay.painter@gmail.com + See: http://pymmlib.sourceforge.net/ + +""" + +import re,sys +from simtk.openmm.app.internal.pdbx.reader.PdbxContainers import * + +class PdbxError(Exception): + """ Class for catch general errors + """ + pass + +class SyntaxError(Exception): + """ Class for catching syntax errors + """ + def __init__(self, lineNumber, text): + Exception.__init__(self) + self.lineNumber = lineNumber + self.text = text + + def __str__(self): + return "%%ERROR - [at line: %d] %s" % (self.lineNumber, self.text) + + + +class PdbxReader(object): + """ PDBx reader for data files and dictionaries. + + """ + def __init__(self,ifh): + """ ifh - input file handle returned by open() + """ + # + self.__curLineNumber = 0 + self.__ifh=ifh + self.__stateDict={"data": "ST_DATA_CONTAINER", + "loop": "ST_TABLE", + "global": "ST_GLOBAL_CONTAINER", + "save": "ST_DEFINITION", + "stop": "ST_STOP"} + + def read(self, containerList): + """ + Appends to the input list of definition and data containers. + + """ + self.__curLineNumber = 0 + try: + self.__parser(self.__tokenizer(self.__ifh), containerList) + except StopIteration: + pass + else: + raise PdbxError() + + def __syntaxError(self, errText): + raise SyntaxError(self.__curLineNumber, errText) + + def __getContainerName(self,inWord): + """ Returns the name of the data_ or save_ container + """ + return str(inWord[5:]).strip() + + def __getState(self, inWord): + """Identifies reserved syntax elements and assigns an associated state. + + Returns: (reserved word, state) + where - + reserved word - is one of CIF syntax elements: + data_, loop_, global_, save_, stop_ + state - the parser state required to process this next section. + """ + i = inWord.find("_") + if i == -1: + return None,"ST_UNKNOWN" + + try: + rWord=inWord[:i].lower() + return rWord, self.__stateDict[rWord] + except: + return None,"ST_UNKNOWN" + + def __parser(self, tokenizer, containerList): + """ Parser for PDBx data files and dictionaries. + + Input - tokenizer() reentrant method recognizing data item names (_category.attribute) + quoted strings (single, double and multi-line semi-colon delimited), and unquoted + strings. + + containerList - list-type container for data and definition objects parsed from + from the input file. + + Return: + containerList - is appended with data and definition objects - + """ + # Working container - data or definition + curContainer = None + # + # Working category container + categoryIndex = {} + curCategory = None + # + curRow = None + state = None + + # Find the first reserved word and begin capturing data. + # + while True: + curCatName, curAttName, curQuotedString, curWord = tokenizer.next() + if curWord is None: + continue + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + break + + while True: + # + # Set the current state - + # + # At this point in the processing cycle we are expecting a token containing + # either a '_category.attribute' or a reserved word. + # + if curCatName is not None: + state = "ST_KEY_VALUE_PAIR" + elif curWord is not None: + reservedWord, state = self.__getState(curWord) + else: + self.__syntaxError("Miscellaneous syntax error") + return + + # + # Process _category.attribute value assignments + # + if state == "ST_KEY_VALUE_PAIR": + try: + curCategory = categoryIndex[curCatName] + except KeyError: + # A new category is encountered - create a container and add a row + curCategory = categoryIndex[curCatName] = DataCategory(curCatName) + + try: + curContainer.append(curCategory) + except AttributeError: + self.__syntaxError("Category cannot be added to data_ block") + return + + curRow = [] + curCategory.append(curRow) + else: + # Recover the existing row from the category + try: + curRow = curCategory[0] + except IndexError: + self.__syntaxError("Internal index error accessing category data") + return + + # Check for duplicate attributes and add attribute to table. + if curAttName in curCategory.getAttributeList(): + self.__syntaxError("Duplicate attribute encountered in category") + return + else: + curCategory.appendAttribute(curAttName) + + + # Get the data for this attribute from the next token + tCat, tAtt, curQuotedString, curWord = tokenizer.next() + + if tCat is not None or (curQuotedString is None and curWord is None): + self.__syntaxError("Missing data for item _%s.%s" % (curCatName,curAttName)) + + if curWord is not None: + # + # Validation check token for misplaced reserved words - + # + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + self.__syntaxError("Unexpected reserved word: %s" % (reservedWord)) + + curRow.append(curWord) + + elif curQuotedString is not None: + curRow.append(curQuotedString) + + else: + self.__syntaxError("Missing value in item-value pair") + + curCatName, curAttName, curQuotedString, curWord = tokenizer.next() + continue + + # + # Process a loop_ declaration and associated data - + # + elif state == "ST_TABLE": + + # The category name in the next curCatName,curAttName pair + # defines the name of the category container. + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + if curCatName is None or curAttName is None: + self.__syntaxError("Unexpected token in loop_ declaration") + return + + # Check for a previous category declaration. + if categoryIndex.has_key(curCatName): + self.__syntaxError("Duplicate category declaration in loop_") + return + + curCategory = DataCategory(curCatName) + + try: + curContainer.append(curCategory) + except AttributeError: + self.__syntaxError("loop_ declaration outside of data_ block or save_ frame") + return + + curCategory.appendAttribute(curAttName) + + # Read the rest of the loop_ declaration + while True: + curCatName, curAttName, curQuotedString, curWord = tokenizer.next() + + if curCatName is None: + break + + if curCatName != curCategory.getName(): + self.__syntaxError("Changed category name in loop_ declaration") + return + + curCategory.appendAttribute(curAttName) + + + # If the next token is a 'word', check it for any reserved words - + if curWord is not None: + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + if reservedWord == "stop": + return + else: + self.__syntaxError("Unexpected reserved word after loop declaration: %s" % (reservedWord)) + + # Read the table of data for this loop_ - + while True: + curRow = [] + curCategory.append(curRow) + + for tAtt in curCategory.getAttributeList(): + if curWord is not None: + curRow.append(curWord) + elif curQuotedString is not None: + curRow.append(curQuotedString) + + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + # loop_ data processing ends if - + + # A new _category.attribute is encountered + if curCatName is not None: + break + + # A reserved word is encountered + if curWord is not None: + reservedWord, state = self.__getState(curWord) + if reservedWord is not None: + break + + continue + + + elif state == "ST_DEFINITION": + # Ignore trailing unnamed saveframe delimiters e.g. 'save_' + sName=self.__getContainerName(curWord) + if (len(sName) > 0): + curContainer = DefinitionContainer(sName) + containerList.append(curContainer) + categoryIndex = {} + curCategory = None + + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + elif state == "ST_DATA_CONTAINER": + # + dName=self.__getContainerName(curWord) + if len(dName) == 0: + dName="unidentified" + curContainer = DataContainer(dName) + containerList.append(curContainer) + categoryIndex = {} + curCategory = None + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + elif state == "ST_STOP": + return + elif state == "ST_GLOBAL": + curContainer = DataContainer("blank-global") + curContainer.setGlobal() + containerList.append(curContainer) + categoryIndex = {} + curCategory = None + curCatName,curAttName,curQuotedString,curWord = tokenizer.next() + + elif state == "ST_UNKNOWN": + self.__syntaxError("Unrecogized syntax element: " + str(curWord)) + return + + + def __tokenizer(self, ifh): + """ Tokenizer method for the mmCIF syntax file - + + Each return/yield from this method returns information about + the next token in the form of a tuple with the following structure. + + (category name, attribute name, quoted strings, words w/o quotes or white space) + + Differentiated the reqular expression to the better handle embedded quotes. + + """ + # + # Regex definition for mmCIF syntax - semi-colon delimited strings are handled + # outside of this regex. + mmcifRe = re.compile( + r"(?:" + + "(?:_(.+?)[.](\S+))" "|" # _category.attribute + + "(?:['](.*?)(?:[']\s|[']$))" "|" # single quoted strings + "(?:[\"](.*?)(?:[\"]\s|[\"]$))" "|" # double quoted strings + + "(?:\s*#.*$)" "|" # comments (dumped) + + "(\S+)" # unquoted words + + ")") + + fileIter = iter(ifh) + + ## Tokenizer loop begins here --- + while True: + line = fileIter.next() + self.__curLineNumber += 1 + + # Dump comments + if line.startswith("#"): + continue + + # Gobble up the entire semi-colon/multi-line delimited string and + # and stuff this into the string slot in the return tuple + # + if line.startswith(";"): + mlString = [line[1:]] + while True: + line = fileIter.next() + self.__curLineNumber += 1 + if line.startswith(";"): + break + mlString.append(line) + + # remove trailing new-line that is part of the \n; delimiter + mlString[-1] = mlString[-1].rstrip() + # + yield (None, None, "".join(mlString), None) + # + # Need to process the remainder of the current line - + line = line[1:] + #continue + + # Apply regex to the current line consolidate the single/double + # quoted within the quoted string category + for it in mmcifRe.finditer(line): + tgroups = it.groups() + if tgroups != (None, None, None, None, None): + if tgroups[2] is not None: + qs = tgroups[2] + elif tgroups[3] is not None: + qs = tgroups[3] + else: + qs = None + groups = (tgroups[0],tgroups[1],qs,tgroups[4]) + yield groups + + def __tokenizerOrg(self, ifh): + """ Tokenizer method for the mmCIF syntax file - + + Each return/yield from this method returns information about + the next token in the form of a tuple with the following structure. + + (category name, attribute name, quoted strings, words w/o quotes or white space) + + """ + # + # Regex definition for mmCIF syntax - semi-colon delimited strings are handled + # outside of this regex. + mmcifRe = re.compile( + r"(?:" + + "(?:_(.+?)[.](\S+))" "|" # _category.attribute + + "(?:['\"](.*?)(?:['\"]\s|['\"]$))" "|" # quoted strings + + "(?:\s*#.*$)" "|" # comments (dumped) + + "(\S+)" # unquoted words + + ")") + + fileIter = iter(ifh) + + ## Tokenizer loop begins here --- + while True: + line = fileIter.next() + self.__curLineNumber += 1 + + # Dump comments + if line.startswith("#"): + continue + + # Gobble up the entire semi-colon/multi-line delimited string and + # and stuff this into the string slot in the return tuple + # + if line.startswith(";"): + mlString = [line[1:]] + while True: + line = fileIter.next() + self.__curLineNumber += 1 + if line.startswith(";"): + break + mlString.append(line) + + # remove trailing new-line that is part of the \n; delimiter + mlString[-1] = mlString[-1].rstrip() + # + yield (None, None, "".join(mlString), None) + # + # Need to process the remainder of the current line - + line = line[1:] + #continue + + ## Apply regex to the current line + for it in mmcifRe.finditer(line): + groups = it.groups() + if groups != (None, None, None, None): + yield groups diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReaderTests.py b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReaderTests.py new file mode 100644 index 000000000..da9e6c547 --- /dev/null +++ b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/PdbxReaderTests.py @@ -0,0 +1,126 @@ +## +# File: PdbxReaderTests.py +# Author: jdw +# Date: 9-Jan-2012 +# Version: 0.001 +# +# Update: +# 27-Sep-2012 jdw add test case for reading PDBx structure factor file +# +## +""" +Test cases for reading PDBx/mmCIF data files PdbxReader class - + +""" +import sys, unittest, traceback +import sys, time, os, os.path, shutil + +from simtk.openmm.app.internal.pdbx.reader.PdbxReader import PdbxReader +from simtk.openmm.app.internal.pdbx.reader.PdbxContainers import * + +class PdbxReaderTests(unittest.TestCase): + def setUp(self): + self.lfh=sys.stderr + self.verbose=False + self.pathPdbxDataFile ="../tests/1kip.cif" + self.pathBigPdbxDataFile ="../tests/1ffk.cif" + self.pathSFDataFile ="../tests/1kip-sf.cif" + + def tearDown(self): + pass + + def testReadSmallDataFile(self): + """Test case - read data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myDataList=[] + ifh = open(self.pathPdbxDataFile, "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + except: + traceback.print_exc(file=sys.stderr) + self.fail() + + def testReadBigDataFile(self): + """Test case - read data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myDataList=[] + ifh = open(self.pathBigPdbxDataFile, "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + except: + traceback.print_exc(file=sys.stderr) + self.fail() + + def testReadSFDataFile(self): + """Test case - read PDB structure factor data file and compute statistics on f/sig(f). + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myContainerList=[] + ifh = open(self.pathSFDataFile, "r") + pRd=PdbxReader(ifh) + pRd.read(myContainerList) + c0=myContainerList[0] + # + catObj=c0.getObj("refln") + if catObj is None: + return false + + nRows=catObj.getRowCount() + # + # Get column name index. + # + itDict={} + itNameList=catObj.getItemNameList() + for idxIt,itName in enumerate(itNameList): + itDict[str(itName).lower()]=idxIt + # + idf=itDict['_refln.f_meas_au'] + idsigf=itDict['_refln.f_meas_sigma_au'] + minR=100 + maxR=-1 + sumR=0 + icount=0 + for row in catObj.getRowList(): + try: + f=float(row[idf]) + sigf=float(row[idsigf]) + ratio=sigf/f + #self.lfh.write(" %f %f %f\n" % (f,sigf,ratio)) + maxR=max(maxR,ratio) + minR=min(minR,ratio) + sumR+=ratio + icount+=1 + except: + continue + + ifh.close() + self.lfh.write("f/sig(f) min %f max %f avg %f count %d\n" % (minR, maxR, sumR/icount,icount)) + except: + traceback.print_exc(file=sys.stderr) + self.fail() + + +def simpleSuite(): + suiteSelect = unittest.TestSuite() + suiteSelect.addTest(PdbxReaderTests("testReadBigDataFile")) + suiteSelect.addTest(PdbxReaderTests("testReadSmallDataFile")) + suiteSelect.addTest(PdbxReaderTests("testReadSFDataFile")) + return suiteSelect + +if __name__ == '__main__': + mySuite=simpleSuite() + unittest.TextTestRunner(verbosity=2).run(mySuite) + # diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/reader/__init__.py b/wrappers/python/simtk/openmm/app/internal/pdbx/reader/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriter.py b/wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriter.py new file mode 100644 index 000000000..780983feb --- /dev/null +++ b/wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriter.py @@ -0,0 +1,191 @@ +## +# File: PdbxWriter.py +# Date: 2011-10-09 Jdw Adapted from PdbxParser.py +# +# Updates: +# 5-Apr-2011 jdw Using the double quote format preference +# 23-Oct-2012 jdw update path details and reorganize. +# +### +""" +Classes for writing data and dictionary containers in PDBx/mmCIF format. + +""" +__docformat__ = "restructuredtext en" +__author__ = "John Westbrook" +__email__ = "jwest@rcsb.rutgers.edu" +__license__ = "Creative Commons Attribution 3.0 Unported" +__version__ = "V0.01" + + +from simtk.openmm.app.internal.pdbx.reader.PdbxContainers import * + +class PdbxError(Exception): + """ Class for catch general errors + """ + pass + +class PdbxWriter(object): + """Write PDBx data files or dictionaries using the input container + or container list. + """ + def __init__(self,ofh=sys.stdout): + self.__ofh=ofh + self.__containerList=[] + self.__MAXIMUM_LINE_LENGTH = 2048 + self.__SPACING = 2 + self.__INDENT_DEFINITION = 3 + self.__indentSpace = " " * self.__INDENT_DEFINITION + self.__doDefinitionIndent=False + # Maximum number of rows checked for value length and format + self.__rowPartition=None + + def setRowPartition(self,numRows): + ''' Maximum number of rows checked for value length and format + ''' + self.__rowPartition=numRows + + def write(self, containerList): + self.__containerList=containerList + for container in self.__containerList: + self.writeContainer(container) + + def writeContainer(self,container): + indS=" " * self.__INDENT_DEFINITION + if isinstance(container, DefinitionContainer): + self.__write("save_%s\n" % container.getName()) + self.__doDefinitionIndent=True + self.__write(indS+"#\n") + elif isinstance(container, DataContainer): + if (container.getGlobal()): + self.__write("global_\n") + self.__doDefinitionIndent=False + self.__write("\n") + else: + self.__write("data_%s\n" % container.getName()) + self.__doDefinitionIndent=False + self.__write("#\n") + + for nm in container.getObjNameList(): + obj=container.getObj(nm) + objL=obj.getRowList() + + # Skip empty objects + if len(objL) == 0: + continue + + # Item - value formattting + elif len(objL) == 1: + self.__writeItemValueFormat(obj) + + # Table formatting - + elif len(objL) > 1 and len(obj.getAttributeList()) > 0: + self.__writeTableFormat(obj) + else: + raise PdbxError() + + if self.__doDefinitionIndent: + self.__write(indS+"#") + else: + self.__write("#") + + # Add a trailing saveframe reserved word + if isinstance(container, DefinitionContainer): + self.__write("\nsave_\n") + self.__write("#\n") + + def __write(self, st): + self.__ofh.write(st) + + def __writeItemValueFormat(self, myCategory): + + # Compute the maximum item name length within this category - + attributeNameLengthMax = 0 + for attributeName in myCategory.getAttributeList(): + attributeNameLengthMax = max(attributeNameLengthMax, len(attributeName)) + itemNameLengthMax = self.__SPACING + len(myCategory.getName()) + attributeNameLengthMax + 2 + # + lineList=[] + lineList.append("#\n") + for attributeName,iPos in myCategory.getAttributeListWithOrder(): + if self.__doDefinitionIndent: + # - add indent -- + lineList.append(self.__indentSpace) + + itemName = "_%s.%s" % (myCategory.getName(), attributeName) + lineList.append(itemName.ljust(itemNameLengthMax)) + + lineList.append(myCategory.getValueFormatted(attributeName,0)) + lineList.append("\n") + + self.__write("".join(lineList)) + + def __writeTableFormat(self, myCategory): + + # Write the declaration of the loop_ + # + lineList=[] + lineList.append('#\n') + if self.__doDefinitionIndent: + lineList.append(self.__indentSpace) + lineList.append("loop_") + for attributeName in myCategory.getAttributeList(): + lineList.append('\n') + if self.__doDefinitionIndent: + lineList.append(self.__indentSpace) + itemName = "_%s.%s" % (myCategory.getName(), attributeName) + lineList.append(itemName) + self.__write("".join(lineList)) + + # + # Write the data in tabular format - + # + #print myCategory.getName() + #print myCategory.getAttributeList() + + # For speed make the following evaluation on a portion of the table + if self.__rowPartition is not None: + numSteps=max(1,myCategory.getRowCount()/self.__rowPartition) + else: + numSteps=1 + + formatTypeList,dataTypeList=myCategory.getFormatTypeList(steps=numSteps) + maxLengthList=myCategory.getAttributeValueMaxLengthList(steps=numSteps) + spacing = " " * self.__SPACING + # + + #print formatTypeList + #print dataTypeList + #print maxLengthList + # + for iRow in range(myCategory.getRowCount()): + lineList = [] + lineList.append('\n') + if self.__doDefinitionIndent: + lineList.append(self.__indentSpace + " ") + + for iAt in range(myCategory.getAttributeCount()): + formatType = formatTypeList[iAt] + maxLength = maxLengthList[iAt] + + if (formatType == 'FT_UNQUOTED_STRING' or formatType == 'FT_NULL_VALUE'): + val=myCategory.getValueFormattedByIndex(iAt,iRow) + lineList.append(val.ljust(maxLength)) + + elif formatType == 'FT_NUMBER': + val=myCategory.getValueFormattedByIndex(iAt,iRow) + lineList.append(val.rjust(maxLength)) + + elif formatType == 'FT_QUOTED_STRING': + val=myCategory.getValueFormattedByIndex(iAt,iRow) + + lineList.append(val.ljust(maxLength+2)) + + elif formatType == "FT_MULTI_LINE_STRING": + val=myCategory.getValueFormattedByIndex(iAt,iRow) + lineList.append(val) + + lineList.append(spacing) + + self.__write("".join(lineList)) + self.__write("\n") diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriterTests.py b/wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriterTests.py new file mode 100644 index 000000000..a9395356e --- /dev/null +++ b/wrappers/python/simtk/openmm/app/internal/pdbx/writer/PdbxWriterTests.py @@ -0,0 +1,165 @@ +## +# File: PdbxWriterTests.py +# Author: jdw +# Date: 3-November-2009 +# Version: 0.001 +# +# Update: +# 5-Apr-2011 jdw Using the double quote format preference +# 24-Oct-2012 jdw Update path and examples. +## +""" +Test implementing PDBx/mmCIF write and formatting operations. + +""" +__docformat__ = "restructuredtext en" +__author__ = "John Westbrook" +__email__ = "jwest@rcsb.rutgers.edu" +__license__ = "Creative Commons Attribution 3.0 Unported" +__version__ = "V0.01" + + + +import sys, unittest, traceback +import sys, time, os, os.path, shutil + +from simtk.openmm.app.internal.pdbx.reader.PdbxReader import PdbxReader +from simtk.openmm.app.internal.pdbx.writer.PdbxWriter import PdbxWriter +from simtk.openmm.app.internal.pdbx.reader.PdbxContainers import * + +class PdbxWriterTests(unittest.TestCase): + def setUp(self): + self.lfh=sys.stderr + self.verbose=False + self.pathPdbxDataFile ="../tests/1kip.cif" + self.pathOutputFile ="testOutputDataFile.cif" + + def tearDown(self): + pass + + def testWriteDataFile(self): + """Test case - write data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myDataList=[] + ofh = open("test-output.cif", "w") + curContainer=DataContainer("myblock") + aCat=DataCategory("pdbx_seqtool_mapping_ref") + aCat.appendAttribute("ordinal") + aCat.appendAttribute("entity_id") + aCat.appendAttribute("auth_mon_id") + aCat.appendAttribute("auth_mon_num") + aCat.appendAttribute("pdb_chain_id") + aCat.appendAttribute("ref_mon_id") + aCat.appendAttribute("ref_mon_num") + aCat.append((1,2,3,4,5,6,7)) + aCat.append((1,2,3,4,5,6,7)) + aCat.append((1,2,3,4,5,6,7)) + aCat.append((1,2,3,4,5,6,7)) + curContainer.append(aCat) + myDataList.append(curContainer) + pdbxW=PdbxWriter(ofh) + pdbxW.write(myDataList) + ofh.close() + except: + traceback.print_exc(file=sys.stderr) + self.fail() + + def testUpdateDataFile(self): + """Test case - write data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # Create a initial data file -- + # + myDataList=[] + ofh = open("test-output-1.cif", "w") + curContainer=DataContainer("myblock") + aCat=DataCategory("pdbx_seqtool_mapping_ref") + aCat.appendAttribute("ordinal") + aCat.appendAttribute("entity_id") + aCat.appendAttribute("auth_mon_id") + aCat.appendAttribute("auth_mon_num") + aCat.appendAttribute("pdb_chain_id") + aCat.appendAttribute("ref_mon_id") + aCat.appendAttribute("ref_mon_num") + aCat.append((1,2,3,4,5,6,7)) + aCat.append((1,2,3,4,5,6,7)) + aCat.append((1,2,3,4,5,6,7)) + aCat.append((1,2,3,4,5,6,7)) + curContainer.append(aCat) + myDataList.append(curContainer) + pdbxW=PdbxWriter(ofh) + pdbxW.write(myDataList) + ofh.close() + # + # Read and update the data - + # + myDataList=[] + ifh = open("test-output-1.cif", "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + # + myBlock=myDataList[0] + myBlock.printIt() + myCat=myBlock.getObj('pdbx_seqtool_mapping_ref') + myCat.printIt() + for iRow in xrange(0,myCat.getRowCount()): + myCat.setValue('some value', 'ref_mon_id',iRow) + myCat.setValue(100, 'ref_mon_num',iRow) + ofh = open("test-output-2.cif", "w") + pdbxW=PdbxWriter(ofh) + pdbxW.write(myDataList) + ofh.close() + + except: + traceback.print_exc(file=sys.stderr) + self.fail() + + def testReadDataFile(self): + """Test case - read data file + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myDataList=[] + ifh = open(self.pathPdbxDataFile, "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + except: + traceback.print_exc(file=sys.stderr) + self.fail() + + def testReadWriteDataFile(self): + """Test case - data file read write test + """ + self.lfh.write("\nStarting %s %s\n" % (self.__class__.__name__, + sys._getframe().f_code.co_name)) + try: + # + myDataList=[] + ifh = open(self.pathPdbxDataFile, "r") + pRd=PdbxReader(ifh) + pRd.read(myDataList) + ifh.close() + + ofh = open(self.pathOutputFile, "w") + pWr=PdbxWriter(ofh) + pWr.write(myDataList) + ofh.close() + except: + traceback.print_exc(file=sys.stderr) + self.fail() + +def suite(): + return unittest.makeSuite(PdbxWriterTests,'test') + +if __name__ == '__main__': + unittest.main() diff --git a/wrappers/python/simtk/openmm/app/internal/pdbx/writer/__init__.py b/wrappers/python/simtk/openmm/app/internal/pdbx/writer/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/wrappers/python/simtk/openmm/app/pdbxfile.py b/wrappers/python/simtk/openmm/app/pdbxfile.py new file mode 100644 index 000000000..38380c9b7 --- /dev/null +++ b/wrappers/python/simtk/openmm/app/pdbxfile.py @@ -0,0 +1,197 @@ +""" +pdbfile.py: Used for loading PDB files. + +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) 2014 Stanford University and the Authors. +Authors: Peter Eastman +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. +""" +__author__ = "Peter Eastman" +__version__ = "1.0" + +import os +import sys +from simtk.openmm import Vec3 +from simtk.openmm.app.internal.pdbx.reader.PdbxReader import PdbxReader +from simtk.openmm.app import Topology +from simtk.unit import nanometers, angstroms, is_quantity, norm, Quantity +import element as elem +try: + import numpy +except: + pass + +class PDBxFile(object): + """PDBxFile parses a PDBx/mmCIF file and constructs a Topology and a set of atom positions from it. + + This class also provides methods for creating PDBx/mmCIF files. To write a file containing a single model, call + writeFile(). You also can create files that contain multiple models. To do this, first call writeHeader(), + then writeModel() once for each model in the file, and finally writeFooter() to complete the file.""" + + def __init__(self, file): + """Load a PDBx/mmCIF file. + + The atom positions and Topology can be retrieved by calling getPositions() and getTopology(). + + Parameters: + - file (string) the name of the file to load. Alternatively you can pass an open file object. + """ + top = Topology() + ## The Topology read from the PDBx/mmCIF file + self.topology = top + self._positions = [] + + # Load the file. + + inputFile = file + if isinstance(file, str): + inputFile = open(file) + reader = PdbxReader(inputFile) + data = [] + reader.read(data) + block = data[0] + + # Build the topology. + + atomData = block.getObj('atom_site') + atomNameCol = atomData.getAttributeIndex('label_atom_id') + atomIdCol = atomData.getAttributeIndex('id') + resNameCol = atomData.getAttributeIndex('label_comp_id') + resIdCol = atomData.getAttributeIndex('label_seq_id') + asymIdCol = atomData.getAttributeIndex('label_asym_id') + chainIdCol = atomData.getAttributeIndex('label_entity_id') + elementCol = atomData.getAttributeIndex('type_symbol') + modelCol = atomData.getAttributeIndex('pdbx_PDB_model_num') + xCol = atomData.getAttributeIndex('Cartn_x') + yCol = atomData.getAttributeIndex('Cartn_y') + zCol = atomData.getAttributeIndex('Cartn_z') + lastChainId = None + lastResId = None + lastAsymId = None + atomTable = {} + models = [] + for row in atomData.getRowList(): + atomKey = ((row[resIdCol], row[asymIdCol], row[atomNameCol])) + model = ('1' if modelCol == -1 else row[modelCol]) + if model not in models: + models.append(model) + self._positions.append([]) + modelIndex = models.index(model) + if modelIndex == 0: + # This row defines a new atom. + + if lastChainId != row[chainIdCol]: + # The start of a new chain. + chain = top.addChain() + lastChainId = row[chainIdCol] + lastResId = None + lastAsymId = None + if lastResId != row[resIdCol] or lastAsymId != row[asymIdCol]: + # The start of a new residue. + res = top.addResidue(row[resNameCol], chain) + lastResId = row[resIdCol] + lastAsymId = row[asymIdCol] + element = None + try: + element = elem.get_by_symbol(row[elementCol]) + except KeyError: + pass + atom = top.addAtom(row[atomNameCol], element, res) + atomTable[atomKey] = atom + else: + # This row defines coordinates for an existing atom in one of the later models. + + try: + atom = atomTable[atomKey] + except KeyError: + raise ValueError('Unknown atom %s in residue %s %s for model %s' % (row[atomNameCol], row[resNameCol], row[resIdCol], model)) + if atom.index != len(self._positions[modelIndex]): + raise ValueError('Atom %s for model %s does not match the order of atoms for model %s' % (row[atomIdCol], model, models[0])) + self._positions[modelIndex].append(Vec3(float(row[xCol]), float(row[yCol]), float(row[zCol]))*0.1) + for i in range(len(self._positions)): + self._positions[i] = self._positions[i]*nanometers + ## The atom positions read from the PDBx/mmCIF file. If the file contains multiple frames, these are the positions in the first frame. + self.positions = self._positions[0] + self.topology.createStandardBonds() + self.topology.createDisulfideBonds(self.positions) + self._numpyPositions = None + + # Record unit cell information, if present. + + cell = block.getObj('cell') + if cell is not None and cell.getRowCount() > 0: + row = cell.getRow(0) + cellSize = [float(row[cell.getAttributeIndex(attribute)]) for attribute in ('length_a', 'length_b', 'length_c')]*angstroms + self.topology.setUnitCellDimensions(cellSize) + + # Add bonds based on struct_conn records. + + connectData = block.getObj('struct_conn') + if connectData is not None: + res1Col = connectData.getAttributeIndex('ptnr1_label_seq_id') + res2Col = connectData.getAttributeIndex('ptnr2_label_seq_id') + atom1Col = connectData.getAttributeIndex('ptnr1_label_atom_id') + atom2Col = connectData.getAttributeIndex('ptnr2_label_atom_id') + asym1Col = connectData.getAttributeIndex('ptnr1_label_asym_id') + asym2Col = connectData.getAttributeIndex('ptnr2_label_asym_id') + typeCol = connectData.getAttributeIndex('conn_type_id') + connectBonds = [] + for row in connectData.getRowList(): + type = row[typeCol][:6] + if type in ('covale', 'disulf', 'modres'): + key1 = (row[res1Col], row[asym1Col], row[atom1Col]) + key2 = (row[res2Col], row[asym2Col], row[atom2Col]) + if key1 in atomTable and key2 in atomTable: + connectBonds.append((atomTable[key1], atomTable[key2])) + if len(connectBonds) > 0: + # Only add bonds that don't already exist. + existingBonds = set(top.bonds()) + for bond in connectBonds: + if bond not in existingBonds and (bond[1], bond[0]) not in existingBonds: + top.addBond(bond[0], bond[1]) + existingBonds.add(bond) + + def getTopology(self): + """Get the Topology of the model.""" + return self.topology + + def getNumFrames(self): + """Get the number of frames stored in the file.""" + return len(self._positions) + + def getPositions(self, asNumpy=False, frame=0): + """Get the atomic positions. + + Parameters: + - asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s + - frame (int=0) the index of the frame for which to get positions + """ + if asNumpy: + if self._numpyPositions is None: + self._numpyPositions = [None]*len(self._positions) + if self._numpyPositions[frame] is None: + self._numpyPositions[frame] = Quantity(numpy.array(self._positions[frame].value_in_unit(nanometers)), nanometers) + return self._numpyPositions[frame] + return self._positions[frame] -- GitLab From 67a3b4c08098a969c745feac7cb041a7c1b7f360 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 5 Nov 2014 10:41:24 -0800 Subject: [PATCH 088/338] Further improvements to multi-GPU performance --- platforms/cuda/include/CudaParallelKernels.h | 1 + platforms/cuda/src/CudaParallelKernels.cpp | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/platforms/cuda/include/CudaParallelKernels.h b/platforms/cuda/include/CudaParallelKernels.h index f43420e97..94fe2a7eb 100644 --- a/platforms/cuda/include/CudaParallelKernels.h +++ b/platforms/cuda/include/CudaParallelKernels.h @@ -86,6 +86,7 @@ private: long long* pinnedForceBuffer; CUfunction sumKernel; CUevent event; + CUstream peerCopyStream; }; /** diff --git a/platforms/cuda/src/CudaParallelKernels.cpp b/platforms/cuda/src/CudaParallelKernels.cpp index 400bcd7cf..de09f200f 100644 --- a/platforms/cuda/src/CudaParallelKernels.cpp +++ b/platforms/cuda/src/CudaParallelKernels.cpp @@ -71,10 +71,9 @@ public: cu.setAsCurrent(); if (cu.getContextIndex() > 0) { - if (!cu.getPlatformData().peerAccessSupported) { - cuStreamWaitEvent(cu.getCurrentStream(), event, 0); + cuStreamWaitEvent(cu.getCurrentStream(), event, 0); + if (!cu.getPlatformData().peerAccessSupported) cu.getPosq().upload(pinnedMemory, false); - } } kernel.beginComputation(context, includeForce, includeEnergy, groups); } @@ -146,6 +145,7 @@ CudaParallelCalcForcesAndEnergyKernel::~CudaParallelCalcForcesAndEnergyKernel() if (pinnedForceBuffer != NULL) cuMemFreeHost(pinnedForceBuffer); cuEventDestroy(event); + cuStreamDestroy(peerCopyStream); } void CudaParallelCalcForcesAndEnergyKernel::initialize(const System& system) { @@ -158,6 +158,7 @@ void CudaParallelCalcForcesAndEnergyKernel::initialize(const System& system) { for (int i = 0; i < (int) contextNonbondedFractions.size(); i++) contextNonbondedFractions[i] = 1/(double) contextNonbondedFractions.size(); CHECK_RESULT(cuEventCreate(&event, 0), "Error creating event"); + CHECK_RESULT(cuStreamCreate(&peerCopyStream, CU_STREAM_NON_BLOCKING), "Error creating stream"); } void CudaParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { @@ -177,11 +178,11 @@ void CudaParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& contex } else { int numBytes = cu.getPosq().getSize()*cu.getPosq().getElementSize(); - for (int i = 1; i < (int) data.contexts.size(); i++) { - data.contexts[i]->setAsCurrent(); - CHECK_RESULT(cuMemcpyAsync(data.contexts[i]->getPosq().getDevicePointer(), cu.getPosq().getDevicePointer(), numBytes, 0), "Error copying positions"); - } - cu.setAsCurrent(); + cuEventRecord(event, cu.getCurrentStream()); + cuStreamWaitEvent(peerCopyStream, event, 0); + for (int i = 1; i < (int) data.contexts.size(); i++) + CHECK_RESULT(cuMemcpyAsync(data.contexts[i]->getPosq().getDevicePointer(), cu.getPosq().getDevicePointer(), numBytes, peerCopyStream), "Error copying positions"); + cuEventRecord(event, peerCopyStream); } for (int i = 0; i < (int) data.contexts.size(); i++) { data.contextEnergy[i] = 0.0; -- GitLab From b535e6511eef8b014126b57d58125e183667a52c Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 5 Nov 2014 12:21:07 -0800 Subject: [PATCH 089/338] Cleanup to PDBx/mmCIF reader --- wrappers/python/simtk/openmm/app/pdbxfile.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/pdbxfile.py b/wrappers/python/simtk/openmm/app/pdbxfile.py index 38380c9b7..9c75d143a 100644 --- a/wrappers/python/simtk/openmm/app/pdbxfile.py +++ b/wrappers/python/simtk/openmm/app/pdbxfile.py @@ -44,11 +44,7 @@ except: pass class PDBxFile(object): - """PDBxFile parses a PDBx/mmCIF file and constructs a Topology and a set of atom positions from it. - - This class also provides methods for creating PDBx/mmCIF files. To write a file containing a single model, call - writeFile(). You also can create files that contain multiple models. To do this, first call writeHeader(), - then writeModel() once for each model in the file, and finally writeFooter() to complete the file.""" + """PDBxFile parses a PDBx/mmCIF file and constructs a Topology and a set of atom positions from it.""" def __init__(self, file): """Load a PDBx/mmCIF file. @@ -93,7 +89,8 @@ class PDBxFile(object): atomTable = {} models = [] for row in atomData.getRowList(): - atomKey = ((row[resIdCol], row[asymIdCol], row[atomNameCol])) + asymId = ('A' if asymIdCol == -1 else row[asymIdCol]) + atomKey = ((row[resIdCol], asymId, row[atomNameCol])) model = ('1' if modelCol == -1 else row[modelCol]) if model not in models: models.append(model) @@ -108,11 +105,11 @@ class PDBxFile(object): lastChainId = row[chainIdCol] lastResId = None lastAsymId = None - if lastResId != row[resIdCol] or lastAsymId != row[asymIdCol]: + if lastResId != row[resIdCol] or lastAsymId != asymId: # The start of a new residue. res = top.addResidue(row[resNameCol], chain) lastResId = row[resIdCol] - lastAsymId = row[asymIdCol] + lastAsymId = asymId element = None try: element = elem.get_by_symbol(row[elementCol]) -- GitLab From 0d82906299ca0953d45f9454bedc6231ab6617d2 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 5 Nov 2014 12:31:07 -0800 Subject: [PATCH 090/338] Added PdbxReader to Licenses.txt --- docs-source/licenses/Licenses.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs-source/licenses/Licenses.txt b/docs-source/licenses/Licenses.txt index 031c669e7..7981e0175 100644 --- a/docs-source/licenses/Licenses.txt +++ b/docs-source/licenses/Licenses.txt @@ -2,7 +2,7 @@ OpenMM was developed by 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 © 2008-2014 Stanford University and the Authors. +Portions copyright � 2008-2014 Stanford University and the Authors. There are several licenses which cover different parts of OpenMM as described below. @@ -119,3 +119,11 @@ freely, subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. + + +6. PdbxReader + +OpenMM uses the PDBx/mmCIF parser written by John Westbrook. It is distributed +under the Creative Commons Attribution 3.0 Unported license. For details, see +https://creativecommons.org/licenses/by/3.0. This library was modified to move +it inside the simtk.openmm.app.internal module. \ No newline at end of file -- GitLab From 497221582c48f635ebe3ab71c21ae0f5cd13a256 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 5 Nov 2014 16:02:52 -0800 Subject: [PATCH 091/338] Bug fix --- wrappers/python/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py index dfcf900fa..a887f28ca 100644 --- a/wrappers/python/setup.py +++ b/wrappers/python/setup.py @@ -146,6 +146,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, "simtk.openmm.app", "simtk.openmm.app.internal", "simtk.openmm.app.internal.charmm", + "simtk.openmm.app.internal.pdbx", "simtk.openmm.app.internal.pdbx.reader", "simtk.openmm.app.internal.pdbx.writer"] setupKeywords["data_files"] = [] -- GitLab From 8f12d8fc9afeadf873edb58635c76dd0029fbc14 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 6 Nov 2014 16:09:58 -0800 Subject: [PATCH 092/338] Further improvements to multi-GPU scaling --- platforms/cuda/src/CudaParallelKernels.cpp | 50 ++++++++++++---------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/platforms/cuda/src/CudaParallelKernels.cpp b/platforms/cuda/src/CudaParallelKernels.cpp index de09f200f..51429c580 100644 --- a/platforms/cuda/src/CudaParallelKernels.cpp +++ b/platforms/cuda/src/CudaParallelKernels.cpp @@ -98,6 +98,12 @@ public: // Execute the kernel, then download forces. energy += kernel.finishComputation(context, includeForce, includeEnergy, groups); + if (cu.getComputeForceCount() < 200) { + // Record timing information for load balancing. Since this takes time, only do it at the start of the simulation. + + CHECK_RESULT(cuCtxSynchronize(), "Error synchronizing CUDA context"); + completionTime = getTime(); + } if (includeForce) { if (cu.getContextIndex() > 0) { int numAtoms = cu.getPaddedNumAtoms(); @@ -110,12 +116,7 @@ public: else cu.getForce().download(&pinnedMemory[(cu.getContextIndex()-1)*numAtoms*3]); } - else { - // In principle this should make the load balancing more accurate, but in practice it just seems to make things slower. - //CHECK_RESULT(cuCtxSynchronize(), "Error synchronizing CUDA context"); - } } - completionTime = getTime(); } private: ContextImpl& context; @@ -192,6 +193,7 @@ void CudaParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& contex } } +#include double CudaParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { for (int i = 0; i < (int) data.contexts.size(); i++) { CudaContext& cu = *data.contexts[i]; @@ -216,24 +218,26 @@ double CudaParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& con // Balance work between the contexts by transferring a little nonbonded work from the context that // finished last to the one that finished first. - int firstIndex = 0, lastIndex = 0; - for (int i = 0; i < (int) completionTimes.size(); i++) { - if (completionTimes[i] < completionTimes[firstIndex]) - firstIndex = i; - if (completionTimes[i] > completionTimes[lastIndex]) - lastIndex = i; - } - double fractionToTransfer = min(0.001, contextNonbondedFractions[lastIndex]); - contextNonbondedFractions[firstIndex] += fractionToTransfer; - contextNonbondedFractions[lastIndex] -= fractionToTransfer; - double startFraction = 0.0; - for (int i = 0; i < (int) contextNonbondedFractions.size(); i++) { - double endFraction = startFraction+contextNonbondedFractions[i]; - if (i == contextNonbondedFractions.size()-1) - endFraction = 1.0; // Avoid roundoff error - data.contexts[i]->getNonbondedUtilities().setAtomBlockRange(startFraction, endFraction); - startFraction = endFraction; - } + if (cu.getComputeForceCount() < 200) { + int firstIndex = 0, lastIndex = 0; + for (int i = 0; i < (int) completionTimes.size(); i++) { + if (completionTimes[i] < completionTimes[firstIndex]) + firstIndex = i; + if (completionTimes[i] > completionTimes[lastIndex]) + lastIndex = i; + } + double fractionToTransfer = min(0.01, contextNonbondedFractions[lastIndex]); + contextNonbondedFractions[firstIndex] += fractionToTransfer; + contextNonbondedFractions[lastIndex] -= fractionToTransfer; + double startFraction = 0.0; + for (int i = 0; i < (int) contextNonbondedFractions.size(); i++) { + double endFraction = startFraction+contextNonbondedFractions[i]; + if (i == contextNonbondedFractions.size()-1) + endFraction = 1.0; // Avoid roundoff error + data.contexts[i]->getNonbondedUtilities().setAtomBlockRange(startFraction, endFraction); + startFraction = endFraction; + } + } } return energy; } -- GitLab From 160c1cdad478efbb21606ce401a3a5e224238c62 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 6 Nov 2014 16:33:46 -0800 Subject: [PATCH 093/338] Bug fixes and improvements to PDBxFile --- wrappers/python/simtk/openmm/app/pdbxfile.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/pdbxfile.py b/wrappers/python/simtk/openmm/app/pdbxfile.py index 9c75d143a..d4de47c9c 100644 --- a/wrappers/python/simtk/openmm/app/pdbxfile.py +++ b/wrappers/python/simtk/openmm/app/pdbxfile.py @@ -79,6 +79,7 @@ class PDBxFile(object): asymIdCol = atomData.getAttributeIndex('label_asym_id') chainIdCol = atomData.getAttributeIndex('label_entity_id') elementCol = atomData.getAttributeIndex('type_symbol') + altIdCol = atomData.getAttributeIndex('label_alt_id') modelCol = atomData.getAttributeIndex('pdbx_PDB_model_num') xCol = atomData.getAttributeIndex('Cartn_x') yCol = atomData.getAttributeIndex('Cartn_y') @@ -89,13 +90,16 @@ class PDBxFile(object): atomTable = {} models = [] for row in atomData.getRowList(): - asymId = ('A' if asymIdCol == -1 else row[asymIdCol]) - atomKey = ((row[resIdCol], asymId, row[atomNameCol])) + atomKey = ((row[resIdCol], row[asymIdCol], row[atomNameCol])) model = ('1' if modelCol == -1 else row[modelCol]) if model not in models: models.append(model) self._positions.append([]) modelIndex = models.index(model) + if row[altIdCol] != '.' and atomKey in atomTable and len(self._positions[modelIndex]) > atomTable[atomKey].index: + # This row is an alternate position for an existing atom, so ignore it. + + continue if modelIndex == 0: # This row defines a new atom. @@ -105,11 +109,13 @@ class PDBxFile(object): lastChainId = row[chainIdCol] lastResId = None lastAsymId = None - if lastResId != row[resIdCol] or lastAsymId != asymId: + if lastResId != row[resIdCol] or lastAsymId != row[asymIdCol]: # The start of a new residue. res = top.addResidue(row[resNameCol], chain) lastResId = row[resIdCol] - lastAsymId = asymId + if lastResId == '.': + lastResId = None + lastAsymId = row[asymIdCol] element = None try: element = elem.get_by_symbol(row[elementCol]) @@ -132,7 +138,6 @@ class PDBxFile(object): ## The atom positions read from the PDBx/mmCIF file. If the file contains multiple frames, these are the positions in the first frame. self.positions = self._positions[0] self.topology.createStandardBonds() - self.topology.createDisulfideBonds(self.positions) self._numpyPositions = None # Record unit cell information, if present. -- GitLab From ea5f9ee7237e5dcc4194b6edfdbc059cf5e998f8 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Fri, 7 Nov 2014 17:13:13 -0500 Subject: [PATCH 094/338] Removed virtual machine. --- devtools/build-vm/linux/Vagrantfile | 88 ------------------- .../linux/build_conda_package_vagrant.sh | 20 ----- devtools/build-vm/linux/setup_centos_vm.sh | 63 ------------- 3 files changed, 171 deletions(-) delete mode 100644 devtools/build-vm/linux/Vagrantfile delete mode 100644 devtools/build-vm/linux/build_conda_package_vagrant.sh delete mode 100644 devtools/build-vm/linux/setup_centos_vm.sh diff --git a/devtools/build-vm/linux/Vagrantfile b/devtools/build-vm/linux/Vagrantfile deleted file mode 100644 index 1595c6f0f..000000000 --- a/devtools/build-vm/linux/Vagrantfile +++ /dev/null @@ -1,88 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! -VAGRANTFILE_API_VERSION = "2" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - # All Vagrant configuration is done here. The most common configuration - # options are documented and commented below. For a complete reference, - # please see the online documentation at vagrantup.com. - - # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = "chef/centos-6.5" - - # Disable automatic box update checking. If you disable this, then - # boxes will only be checked for updates when the user runs - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # config.vm.network "forwarded_port", guest: 80, host: 8080 - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # If true, then any SSH connections made will enable agent forwarding. - # Default value: false - # config.ssh.forward_agent = true - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider "virtualbox" do |vb| - # # Don't boot with headless mode - # vb.gui = true - # - # # Use VBoxManage to customize the VM. For example to change memory: - # vb.customize ["modifyvm", :id, "--memory", "1024"] - # end - # - # View the documentation for the provider you're using for more - # information on available options. - - # Enable provisioning with CFEngine. CFEngine Community packages are - # automatically installed. For example, configure the host as a - # policy server and optionally a policy file to run: - # - # config.vm.provision "cfengine" do |cf| - # cf.am_policy_hub = true - # # cf.run_file = "motd.cf" - # end - # - # You can also configure and bootstrap a client to an existing - # policy server: - # - # config.vm.provision "cfengine" do |cf| - # cf.policy_server_address = "10.0.2.15" - # end - - # Enable provisioning with Puppet stand alone. Puppet manifests - # are contained in a directory path relative to this Vagrantfile. - # You will need to create the manifests directory and a manifest in - # the file default.pp in the manifests_path directory. - # - # config.vm.provision "puppet" do |puppet| - # puppet.manifests_path = "manifests" - # puppet.manifest_file = "site.pp" - # end - - config.vm.provision "shell", - inline: "su -c 'source /vagrant/setup_centos_vm.sh' vagrant" - -end diff --git a/devtools/build-vm/linux/build_conda_package_vagrant.sh b/devtools/build-vm/linux/build_conda_package_vagrant.sh deleted file mode 100644 index 7a3ecb339..000000000 --- a/devtools/build-vm/linux/build_conda_package_vagrant.sh +++ /dev/null @@ -1,20 +0,0 @@ -export PATH=$HOME/miniconda/bin:$PATH -export SWIG_LIB=$HOME/miniconda/share/swig/ -export CC="clang++" - -git clone https://github.com/simtk/openmm.git -cd openmm -git checkout tags/6.1 # To checkout specific release for packaging. -conda install --file devtools/ci/requirements-conda.txt --yes - -# For CI build: -conda build devtools/conda-recipe - -# For release build: -cd ../ -git clone https://github.com/omnia-md/conda-recipes.git -conda build conda-recipes/openmm - -# To upload the file, do something the following command but with the package version changed: - -binstar upload -u omnia /home/vagrant/miniconda/conda-bld/linux-64/openmm-6.1-py27_0.tar.bz2 diff --git a/devtools/build-vm/linux/setup_centos_vm.sh b/devtools/build-vm/linux/setup_centos_vm.sh deleted file mode 100644 index 7fd12f2b7..000000000 --- a/devtools/build-vm/linux/setup_centos_vm.sh +++ /dev/null @@ -1,63 +0,0 @@ -# Prepare a vagrant CentOS 6.5 VM for building OpenMM -# Needs latest version of vagrant to auto-download the chef package -#vagrant init chef/centos-6.5 -#vagrant up -#vagrant ssh - - -# Download and enable the EPEL RedHat EL extras repository -mkdir ~/Software -cd Software -sudo yum install wget -y -wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm -sudo rpm -i epel-release-6-8.noarch.rpm - -sudo yum update -y - -# Several of these come from the EPEL repo -sudo yum install clang cmake28 graphviz perl flex bison rpm-build texlive texlive-latex ghostscript gcc gcc-c++ git vim -y -# Note: changed from clang-3.4 to clang because the package has apparently been renamed. KAB Oct 2 2014. - -# Probably can't use RHEL6 version of doxygen because it's very old. -wget http://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.7.src.tar.gz -rpmbuild -ta doxygen-1.8.7.src.tar.gz -sudo rpm -i ~/rpmbuild/RPMS/x86_64/doxygen-1.8.7-1.x86_64.rpm -rm ~/rpmbuild -r - - -sudo yum clean headers -sudo yum clean packages - -# Install CUDA6.5 for RHEL6 -cd ~/Software -wget http://developer.download.nvidia.com/compute/cuda/repos/rhel6/x86_64/cuda-repo-rhel6-6.5-14.x86_64.rpm -sudo rpm -i cuda-repo-rhel6-6.5-14.x86_64.rpm -sudo yum clean expire-cache -sudo yum install cuda -y -# NOTE: NVIDIA may push new MAJOR release versions of CUDA without warning. -# This is even *before* doing the below update. Beware. - -sudo yum update -y # Force a second update, in case CUDA has necessary patches. - -# Install Conda -cd ~/Software -wget http://repo.continuum.io/miniconda/Miniconda-3.7.0-Linux-x86_64.sh -bash Miniconda-3.7.0-Linux-x86_64.sh -b - -# So there is a bug in some versions of anaconda where the path to swig files is HARDCODED. Below is workaround. See https://github.com/ContinuumIO/anaconda-issues/issues/48 -sudo ln -s ~/miniconda/ /opt/anaconda1anaconda2anaconda3 - -export PATH=$HOME/miniconda/bin:$PATH -conda config --add channels http://conda.binstar.org/omnia -conda install --yes fftw3f jinja2 swig sphinx conda-build cmake binstar - - -# Download AMD APP SDK from here, requires click agreement: http://developer.amd.com/amd-license-agreement-appsdk/ -# Ideally we could cache this on AWS or something... -mkdir ~/Software/AMD -cd ~/Software/AMD -# Copy the tarball to the directory containing VagrantFile, which will be shared on the guest as /vagrant/ -cp /vagrant/AMD-APP-SDK-v2.9-lnx64.tgz ./ -tar -zxvf /vagrant/AMD-APP-SDK-v2.9-lnx64.tgz -sudo ./Install-AMD-APP.sh - -- GitLab From be7120e467ae9c7bad38bc9f2e7f3db894c001a2 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Fri, 7 Nov 2014 20:10:15 -0500 Subject: [PATCH 095/338] Added Linux packaging script. --- devtools/packaging/scripts/linux/package.sh | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 devtools/packaging/scripts/linux/package.sh diff --git a/devtools/packaging/scripts/linux/package.sh b/devtools/packaging/scripts/linux/package.sh new file mode 100644 index 000000000..4dbdf8220 --- /dev/null +++ b/devtools/packaging/scripts/linux/package.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Packaging script for Linux distribution, for use in automated packaging. +# Note that this must be run from outside the checked-out openmm/ directory. + +# CONFIGURE HERE +export PACKAGE_DIR="packaging" # directory to stuff packaged source distribution +export VERSION="6.2.0" # version string +export PACKAGE_SUBDIR="OpenMM-${VERSION}-Linux" # directory where distribution will be unpacked +export DISTRO_PREFIX="OpenMM-${VERSION}-Linux" # prefix for source distribution (e.g. ${DISTRIBUTION_NAME}.zip) + +# Clean up. +rm -rf $PACKAGE_DIR + +# Make a directory to contain packaged source distribution +mkdir $PACKAGE_DIR +mkdir $PACKAGE_DIR/$PACKAGE_SUBDIR +for filename in $( cat openmm/devtools/packaging/manifests/binary/manifest.txt ); do + CMD="cp -r install/$filename $PACKAGE_DIR/$PACKAGE_SUBDIR" + echo $CMD + `$CMD` +done + +# Add the install.sh script +CMD="cp -r openmm/install.sh $PACKAGE_DIR/$PACKAGE_SUBDIR" +echo $CMD +`$CMD` + +# Make Python source distribution. +echo "Building Python source distribution..." +cd build +make PythonSdist +cd python/dist +tar zxf OpenMM-${VERSION}.tar.gz +mv OpenMM-${VERSION} python +cd ../../.. +cp -r build/python/dist/python $PACKAGE_DIR/$PACKAGE_SUBDIR + +# Create archives. +cd $PACKAGE_DIR +mkdir compressed +tar zcf compressed/${DISTRO_PREFIX}.tgz $PACKAGE_SUBDIR +zip -r compressed/${DISTRO_PREFIX}.zip $PACKAGE_SUBDIR +cd .. -- GitLab From 71220e6e374376f4abab8d736d7f7cf0b80e8275 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Fri, 7 Nov 2014 20:11:01 -0500 Subject: [PATCH 096/338] Changed Linux packaging script to executable. --- devtools/packaging/scripts/linux/package.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 devtools/packaging/scripts/linux/package.sh diff --git a/devtools/packaging/scripts/linux/package.sh b/devtools/packaging/scripts/linux/package.sh old mode 100644 new mode 100755 -- GitLab From 4b2487f3dbbd9909f765bbca6550b18ca9e08a40 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Fri, 7 Nov 2014 20:47:45 -0500 Subject: [PATCH 097/338] Added draft build script. --- devtools/packaging/scripts/linux/build.sh | 41 +++++++++++++++++++++ devtools/packaging/scripts/linux/package.sh | 3 ++ 2 files changed, 44 insertions(+) create mode 100644 devtools/packaging/scripts/linux/build.sh diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh new file mode 100644 index 000000000..67bbec0ed --- /dev/null +++ b/devtools/packaging/scripts/linux/build.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Build script for Linux distribution, for use in automated packaging. +# Note that this must be run from outside the checked-out openmm/ directory. + +INSTALL=`pwd`/install +CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" + +# setting the rpath so that libOpenMMPME.so finds the right libfftw3 +#CMAKE_FLAGS+=" -DCMAKE_INSTALL_RPATH=.." +CMAKE_FLAGS+=" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++" +CMAKE_FLAGS+=" -DCUDA_CUDART_LIBRARY=/usr/local/cuda-6.5/lib64/libcudart.so" +CMAKE_FLAGS+=" -DCUDA_NVCC_EXECUTABLE=/usr/local/cuda-6.5/bin/nvcc" +CMAKE_FLAGS+=" -DCUDA_SDK_ROOT_DIR=/usr/local/cuda-6.5/" +CMAKE_FLAGS+=" -DCUDA_TOOLKIT_INCLUDE=/usr/local/cuda-6.5/include" +CMAKE_FLAGS+=" -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-6.5/" +CMAKE_FLAGS+=" -DOPENCL_INCLUDE_DIR=/usr/local/cuda-6.5/include" +CMAKE_FLAGS+=" -DOPENCL_LIBRARY=/usr/local/cuda-6.5/lib64/libOpenCL.so" + +# Set location for FFTW3 +PREFIX="${HOME}/miniconda" +CMAKE_FLAGS+=" -DFFTW_INCLUDES=$PREFIX/include" +CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.so" +CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.so" + +# Build in subdirectory. +mkdir build +cd build +cmake ../openmm $CMAKE_FLAGS +make -j4 +make install + +# Install Python wrappers. +export OPENMM_INCLUDE_PATH=$INSTALL/include +export OPENMM_LIB_PATH=$INSTALL/lib +cd python +$PYTHON setup.py install --prefix=$INSTALL +cd .. + +# Copy all tests to bin directory so they will be distributed with install package. +#cp `find . -name "Test*" -type f -maxdepth 1` $PREFIX/bin diff --git a/devtools/packaging/scripts/linux/package.sh b/devtools/packaging/scripts/linux/package.sh index 4dbdf8220..ad33bd12e 100755 --- a/devtools/packaging/scripts/linux/package.sh +++ b/devtools/packaging/scripts/linux/package.sh @@ -9,6 +9,9 @@ export VERSION="6.2.0" # version string export PACKAGE_SUBDIR="OpenMM-${VERSION}-Linux" # directory where distribution will be unpacked export DISTRO_PREFIX="OpenMM-${VERSION}-Linux" # prefix for source distribution (e.g. ${DISTRIBUTION_NAME}.zip) +# Perform all work in a work directory. +cd work + # Clean up. rm -rf $PACKAGE_DIR -- GitLab From dda50ec8b0afcbc73c7ea5fd7dd4e1d87ce6560a Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Fri, 7 Nov 2014 20:48:53 -0500 Subject: [PATCH 098/338] Made Linux build script executable. --- devtools/packaging/scripts/linux/build.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 devtools/packaging/scripts/linux/build.sh diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh old mode 100644 new mode 100755 -- GitLab From 3fecf857bfa1599ce73ece4789f0e27466b1b68e Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Fri, 7 Nov 2014 21:07:17 -0500 Subject: [PATCH 099/338] Version number in Linux packaging script is now extracted from CMakeCache.txt (via @peastman). --- devtools/packaging/scripts/linux/package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/packaging/scripts/linux/package.sh b/devtools/packaging/scripts/linux/package.sh index ad33bd12e..407d3437f 100755 --- a/devtools/packaging/scripts/linux/package.sh +++ b/devtools/packaging/scripts/linux/package.sh @@ -5,7 +5,7 @@ # CONFIGURE HERE export PACKAGE_DIR="packaging" # directory to stuff packaged source distribution -export VERSION="6.2.0" # version string +export VERSION=$(sed -nr "s/OPENMM_VERSION:STRING=(.*)/\1/p" build/CMakeCache.txt) export PACKAGE_SUBDIR="OpenMM-${VERSION}-Linux" # directory where distribution will be unpacked export DISTRO_PREFIX="OpenMM-${VERSION}-Linux" # prefix for source distribution (e.g. ${DISTRIBUTION_NAME}.zip) -- GitLab From 81bdf03a64f1cc9a3cd46e2fc8cfade55e67ce0d Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Fri, 7 Nov 2014 21:39:10 -0500 Subject: [PATCH 100/338] Added first drafts of OS X build and packaging scripts. --- devtools/packaging/scripts/osx/build.sh | 41 +++++++++++++++++++++ devtools/packaging/scripts/osx/package.sh | 44 +++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100755 devtools/packaging/scripts/osx/build.sh create mode 100755 devtools/packaging/scripts/osx/package.sh diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh new file mode 100755 index 000000000..164d9e4aa --- /dev/null +++ b/devtools/packaging/scripts/osx/build.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Build script for Mac OS X distribution, for use in automated packaging. +# Note that this must be run from outside the checked-out openmm/ directory. + +INSTALL=`pwd`/install +CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" + +# setting the rpath so that libOpenMMPME.so finds the right libfftw3 +#CMAKE_FLAGS+=" -DCMAKE_INSTALL_RPATH=.." +CMAKE_FLAGS+=" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++" +CMAKE_FLAGS+=" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9" +CMAKE_FLAGS+=" -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" +CMAKE_FLAGS+=" -DOPENMM_BUILD_OPENCL_LIB=OFF" +CMAKE_FLAGS+=" -DOPENMM_BUILD_DRUDE_OPENCL_LIB=OFF" +CMAKE_FLAGS+=" -DOPENMM_BUILD_RPMD_OPENCL_LIB=OFF" +CMAKE_FLAGS+=" -DOPENMM_BUILD_OPENCL_TESTS=FALSE" +CMAKE_FLAGS+=" -DOPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS=FALSE" + +# Build in subdirectory. +# Set location for FFTW3 +PREFIX="${HOME}/miniconda" +CMAKE_FLAGS+=" -DFFTW_INCLUDES=$PREFIX/include" +CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.so" +CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.so" + +mkdir build +cd build +cmake ../openmm $CMAKE_FLAGS +make -j4 +make install + +# Install Python wrappers. +export OPENMM_INCLUDE_PATH=$INSTALL/include +export OPENMM_LIB_PATH=$INSTALL/lib +cd python +$PYTHON setup.py install --prefix=$INSTALL +cd .. + +# Copy all tests to bin directory so they will be distributed with install package. +#cp `find . -name "Test*" -type f -maxdepth 1` $PREFIX/bin diff --git a/devtools/packaging/scripts/osx/package.sh b/devtools/packaging/scripts/osx/package.sh new file mode 100755 index 000000000..381d275bf --- /dev/null +++ b/devtools/packaging/scripts/osx/package.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Packaging script for Mac OS X distribution, for use in automated packaging. +# Note that this must be run from outside the checked-out openmm/ directory. + +# CONFIGURE HERE +export PACKAGE_DIR="packaging" # directory to stuff packaged source distribution +export VERSION=$(sed -nr "s/OPENMM_VERSION:STRING=(.*)/\1/p" build/CMakeCache.txt) +export PACKAGE_SUBDIR="OpenMM-${VERSION}-Mac" # directory where distribution will be unpacked +export DISTRO_PREFIX="OpenMM-${VERSION}-Mac" # prefix for source distribution (e.g. ${DISTRIBUTION_NAME}.zip) + +# Clean up. +rm -rf $PACKAGE_DIR + +# Make a directory to contain packaged source distribution +mkdir $PACKAGE_DIR +mkdir $PACKAGE_DIR/$PACKAGE_SUBDIR +for filename in $( cat openmm/devtools/packaging/manifests/binary/manifest.txt ); do + CMD="cp -r install/$filename $PACKAGE_DIR/$PACKAGE_SUBDIR" + echo $CMD + `$CMD` +done + +# Add the install.sh script +CMD="cp -r openmm/install.sh $PACKAGE_DIR/$PACKAGE_SUBDIR" +echo $CMD +`$CMD` + +# Make Python source distribution. +echo "Building Python source distribution..." +cd build +make PythonSdist +cd python/dist +tar zxf OpenMM-${VERSION}.tar.gz +mv OpenMM-${VERSION} python +cd ../../.. +cp -r build/python/dist/python $PACKAGE_DIR/$PACKAGE_SUBDIR + +# Create archives. +cd $PACKAGE_DIR +mkdir compressed +tar zcf compressed/${DISTRO_PREFIX}.tgz $PACKAGE_SUBDIR +zip -r compressed/${DISTRO_PREFIX}.zip $PACKAGE_SUBDIR +cd .. -- GitLab From 4e9405a6375adb45f887cfa66bab5e8291db6fb7 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 00:45:17 -0500 Subject: [PATCH 101/338] Updated build script for packaging with Linux. --- devtools/packaging/scripts/linux/build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index 67bbec0ed..dff4247ab 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -3,6 +3,9 @@ # Build script for Linux distribution, for use in automated packaging. # Note that this must be run from outside the checked-out openmm/ directory. +echo $PATH +which cmake + INSTALL=`pwd`/install CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" @@ -24,6 +27,9 @@ CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.so" CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.so" # Build in subdirectory. +if [ -e build ]; then + rm -rf build +fi mkdir build cd build cmake ../openmm $CMAKE_FLAGS -- GitLab From 0198503fb48a1e10db6bb404a2c9171dd63adbaa Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 12:41:51 -0500 Subject: [PATCH 102/338] Minor fix to build script for automated packaging. --- devtools/packaging/scripts/linux/build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index dff4247ab..f814418a1 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -37,10 +37,10 @@ make -j4 make install # Install Python wrappers. -export OPENMM_INCLUDE_PATH=$INSTALL/include -export OPENMM_LIB_PATH=$INSTALL/lib +OPENMM_INCLUDE_PATH=$INSTALL/include +OPENMM_LIB_PATH=$INSTALL/lib cd python -$PYTHON setup.py install --prefix=$INSTALL +python setup.py install --prefix=$INSTALL cd .. # Copy all tests to bin directory so they will be distributed with install package. -- GitLab From db343579cb68562dcc67164f71850fb68eacbec0 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 12:48:26 -0500 Subject: [PATCH 103/338] Fixed python path for automated build script. --- devtools/packaging/scripts/linux/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index f814418a1..9eadb8854 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -39,8 +39,9 @@ make install # Install Python wrappers. OPENMM_INCLUDE_PATH=$INSTALL/include OPENMM_LIB_PATH=$INSTALL/lib +PYTHON=${HOME}/miniconda/bin/python cd python -python setup.py install --prefix=$INSTALL +$PYTHON setup.py install --prefix=$INSTALL cd .. # Copy all tests to bin directory so they will be distributed with install package. -- GitLab From 0abd720e69d7c93dd9bcd1eea0bf9da52488270c Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 12:53:55 -0500 Subject: [PATCH 104/338] Added miniconda/bin to path for automated build scripts. --- devtools/packaging/scripts/linux/build.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index 9eadb8854..222e09d6c 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -3,8 +3,8 @@ # Build script for Linux distribution, for use in automated packaging. # Note that this must be run from outside the checked-out openmm/ directory. -echo $PATH -which cmake +# Add conda binaries to path. +PATH=${HOME}/miniconda/bin:${PATH} INSTALL=`pwd`/install CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" @@ -33,15 +33,14 @@ fi mkdir build cd build cmake ../openmm $CMAKE_FLAGS -make -j4 +make -j16 make install # Install Python wrappers. OPENMM_INCLUDE_PATH=$INSTALL/include OPENMM_LIB_PATH=$INSTALL/lib -PYTHON=${HOME}/miniconda/bin/python cd python -$PYTHON setup.py install --prefix=$INSTALL +python setup.py install --prefix=$INSTALL cd .. # Copy all tests to bin directory so they will be distributed with install package. -- GitLab From 4d33ed568cd4d9a366c230a6d72094deff2c0157 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 16:29:32 -0500 Subject: [PATCH 105/338] Updated OSX build/package scripts for Jenkins. --- devtools/packaging/scripts/osx/build.sh | 3 +++ devtools/packaging/scripts/osx/package.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index 164d9e4aa..48c8eb6e3 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -3,6 +3,8 @@ # Build script for Mac OS X distribution, for use in automated packaging. # Note that this must be run from outside the checked-out openmm/ directory. +PATH=$HOME/miniconda/bin:$PATH + INSTALL=`pwd`/install CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" @@ -33,6 +35,7 @@ make install # Install Python wrappers. export OPENMM_INCLUDE_PATH=$INSTALL/include export OPENMM_LIB_PATH=$INSTALL/lib +export PYTHON=$HOME/miniconda/bin/python cd python $PYTHON setup.py install --prefix=$INSTALL cd .. diff --git a/devtools/packaging/scripts/osx/package.sh b/devtools/packaging/scripts/osx/package.sh index 381d275bf..82b3f56ff 100755 --- a/devtools/packaging/scripts/osx/package.sh +++ b/devtools/packaging/scripts/osx/package.sh @@ -30,7 +30,7 @@ echo $CMD echo "Building Python source distribution..." cd build make PythonSdist -cd python/dist +cd python/dist tar zxf OpenMM-${VERSION}.tar.gz mv OpenMM-${VERSION} python cd ../../.. -- GitLab From 8e778c6f2b0e80585d9fa3de90a1a22a7ea2b31c Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 16:38:14 -0500 Subject: [PATCH 106/338] More updates to OS X Jenkins build script. --- devtools/packaging/scripts/osx/build.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index 48c8eb6e3..78bd92875 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -3,7 +3,8 @@ # Build script for Mac OS X distribution, for use in automated packaging. # Note that this must be run from outside the checked-out openmm/ directory. -PATH=$HOME/miniconda/bin:$PATH +# Add conda binaries to path. +PATH=${HOME}/miniconda/bin:${PATH} INSTALL=`pwd`/install CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" @@ -26,10 +27,14 @@ CMAKE_FLAGS+=" -DFFTW_INCLUDES=$PREFIX/include" CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.so" CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.so" +# Build in subdirectory. +if [ -e build ]; then + rm -rf build +fi mkdir build cd build cmake ../openmm $CMAKE_FLAGS -make -j4 +make -j16 make install # Install Python wrappers. -- GitLab From 438463ed8a2e00c7a485f7f761a3967b0b5adba5 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 17:21:22 -0500 Subject: [PATCH 107/338] Updated Jenkins build scripts to also build docs. --- devtools/packaging/scripts/linux/build.sh | 2 +- devtools/packaging/scripts/osx/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index 222e09d6c..3982ef12f 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -33,7 +33,7 @@ fi mkdir build cd build cmake ../openmm $CMAKE_FLAGS -make -j16 +make -j4 all DoxygenApiDocs sphinxpdf make install # Install Python wrappers. diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index 78bd92875..243a39d39 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -34,7 +34,7 @@ fi mkdir build cd build cmake ../openmm $CMAKE_FLAGS -make -j16 +make -j4 all DoxygenApiDocs sphinxpdf make install # Install Python wrappers. -- GitLab From db166090f267d3aa6d3b2d9995756ef494a99796 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 17:50:20 -0500 Subject: [PATCH 108/338] Fixed some path errors with Jenkins build scripts, and added preparation scripts. --- devtools/packaging/scripts/linux/build.sh | 6 +++--- devtools/packaging/scripts/linux/prepare.sh | 23 +++++++++++++++++++++ devtools/packaging/scripts/osx/build.sh | 7 +++---- devtools/packaging/scripts/osx/prepare.sh | 23 +++++++++++++++++++++ 4 files changed, 52 insertions(+), 7 deletions(-) create mode 100755 devtools/packaging/scripts/linux/prepare.sh create mode 100755 devtools/packaging/scripts/osx/prepare.sh diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index 3982ef12f..82b97d68c 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -4,7 +4,7 @@ # Note that this must be run from outside the checked-out openmm/ directory. # Add conda binaries to path. -PATH=${HOME}/miniconda/bin:${PATH} +PATH=$WORKSPACE/miniconda/bin:$PATH INSTALL=`pwd`/install CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" @@ -21,7 +21,7 @@ CMAKE_FLAGS+=" -DOPENCL_INCLUDE_DIR=/usr/local/cuda-6.5/include" CMAKE_FLAGS+=" -DOPENCL_LIBRARY=/usr/local/cuda-6.5/lib64/libOpenCL.so" # Set location for FFTW3 -PREFIX="${HOME}/miniconda" +PREFIX="$WORKSPACE/miniconda" CMAKE_FLAGS+=" -DFFTW_INCLUDES=$PREFIX/include" CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.so" CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.so" @@ -41,7 +41,7 @@ OPENMM_INCLUDE_PATH=$INSTALL/include OPENMM_LIB_PATH=$INSTALL/lib cd python python setup.py install --prefix=$INSTALL -cd .. +cd ../.. # Copy all tests to bin directory so they will be distributed with install package. #cp `find . -name "Test*" -type f -maxdepth 1` $PREFIX/bin diff --git a/devtools/packaging/scripts/linux/prepare.sh b/devtools/packaging/scripts/linux/prepare.sh new file mode 100755 index 000000000..f68f1baea --- /dev/null +++ b/devtools/packaging/scripts/linux/prepare.sh @@ -0,0 +1,23 @@ +#!/bin/tcsh + +# Prepare for build by ensuring necessary prerequisites are locally installed. + +# Install miniconda +export VERSION="3.7.0" +export PLATFORM="Linux" +export ARCH="x86_64" +export MINICONDA="Miniconda-$VERSION-$PLATFORM-$ARCH.sh" +if [ -f $MINICONDA ]; +then + echo "File $MINICONDA exists, not downloading." + export PATH=$WORKSPACE/miniconda/bin:$PATH +else + echo "Downloading miniconda..." + wget http://repo.continuum.io/miniconda/${MINICONDA} + bash ${MINICONDA} -b -p miniconda + PIP_ARGS="-U" + export PATH=$WORKSPACE/miniconda/bin:$PATH + conda config --add channels http://conda.binstar.org/omnia + conda install --yes --quiet swig fftw3f pip + pip install sphinxcontrib-bibtex +fi diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index 243a39d39..650ad66cb 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -4,7 +4,7 @@ # Note that this must be run from outside the checked-out openmm/ directory. # Add conda binaries to path. -PATH=${HOME}/miniconda/bin:${PATH} +PATH=$WORKSPACE/miniconda/bin:$PATH INSTALL=`pwd`/install CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" @@ -22,7 +22,7 @@ CMAKE_FLAGS+=" -DOPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS=FALSE" # Build in subdirectory. # Set location for FFTW3 -PREFIX="${HOME}/miniconda" +PREFIX="$WORKSPACE/miniconda" CMAKE_FLAGS+=" -DFFTW_INCLUDES=$PREFIX/include" CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.so" CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.so" @@ -40,10 +40,9 @@ make install # Install Python wrappers. export OPENMM_INCLUDE_PATH=$INSTALL/include export OPENMM_LIB_PATH=$INSTALL/lib -export PYTHON=$HOME/miniconda/bin/python cd python $PYTHON setup.py install --prefix=$INSTALL -cd .. +cd ../.. # Copy all tests to bin directory so they will be distributed with install package. #cp `find . -name "Test*" -type f -maxdepth 1` $PREFIX/bin diff --git a/devtools/packaging/scripts/osx/prepare.sh b/devtools/packaging/scripts/osx/prepare.sh new file mode 100755 index 000000000..6b6aff93e --- /dev/null +++ b/devtools/packaging/scripts/osx/prepare.sh @@ -0,0 +1,23 @@ +#!/bin/tcsh + +# Prepare for build by ensuring necessary prerequisites are locally installed. + +# Install miniconda +export VERSION="3.7.0" +export PLATFORM="MacOSX" +export ARCH="x86_64" +export MINICONDA="Miniconda-$VERSION-$PLATFORM-$ARCH.sh" +if [ -f $MINICONDA ]; +then + echo "File $MINICONDA exists, not downloading." + export PATH=$WORKSPACE/miniconda/bin:$PATH +else + echo "Downloading miniconda..." + wget http://repo.continuum.io/miniconda/${MINICONDA} + bash ${MINICONDA} -b -p miniconda + PIP_ARGS="-U" + export PATH=$WORKSPACE/miniconda/bin:$PATH + conda config --add channels http://conda.binstar.org/omnia + conda install --yes --quiet swig fftw3f pip + pip install sphinxcontrib-bibtex +fi -- GitLab From abf0f7ef3d0a1f2b61018948d7efd37fa91ab8fc Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 17:56:18 -0500 Subject: [PATCH 109/338] Updated Jenkins preparation scripts. --- devtools/packaging/scripts/linux/prepare.sh | 17 ++++++++++------- devtools/packaging/scripts/osx/prepare.sh | 16 +++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/devtools/packaging/scripts/linux/prepare.sh b/devtools/packaging/scripts/linux/prepare.sh index f68f1baea..7091ce6e6 100755 --- a/devtools/packaging/scripts/linux/prepare.sh +++ b/devtools/packaging/scripts/linux/prepare.sh @@ -7,17 +7,20 @@ export VERSION="3.7.0" export PLATFORM="Linux" export ARCH="x86_64" export MINICONDA="Miniconda-$VERSION-$PLATFORM-$ARCH.sh" -if [ -f $MINICONDA ]; +if [ -f miniconda ]; then - echo "File $MINICONDA exists, not downloading." - export PATH=$WORKSPACE/miniconda/bin:$PATH + echo "miniconda already exists" else echo "Downloading miniconda..." wget http://repo.continuum.io/miniconda/${MINICONDA} bash ${MINICONDA} -b -p miniconda PIP_ARGS="-U" - export PATH=$WORKSPACE/miniconda/bin:$PATH - conda config --add channels http://conda.binstar.org/omnia - conda install --yes --quiet swig fftw3f pip - pip install sphinxcontrib-bibtex fi + +# Add to path. +export PATH=$WORKSPACE/miniconda/bin:$PATH + +# Ensure configuration is up to date. +conda config --add channels http://conda.binstar.org/omnia +conda install --yes --quiet swig fftw3f pip +pip install sphinxcontrib-bibtex diff --git a/devtools/packaging/scripts/osx/prepare.sh b/devtools/packaging/scripts/osx/prepare.sh index 6b6aff93e..b44a8e70e 100755 --- a/devtools/packaging/scripts/osx/prepare.sh +++ b/devtools/packaging/scripts/osx/prepare.sh @@ -7,17 +7,19 @@ export VERSION="3.7.0" export PLATFORM="MacOSX" export ARCH="x86_64" export MINICONDA="Miniconda-$VERSION-$PLATFORM-$ARCH.sh" -if [ -f $MINICONDA ]; +if [ -f miniconda ]; then - echo "File $MINICONDA exists, not downloading." - export PATH=$WORKSPACE/miniconda/bin:$PATH + echo "miniconda already exists" else echo "Downloading miniconda..." wget http://repo.continuum.io/miniconda/${MINICONDA} bash ${MINICONDA} -b -p miniconda PIP_ARGS="-U" - export PATH=$WORKSPACE/miniconda/bin:$PATH - conda config --add channels http://conda.binstar.org/omnia - conda install --yes --quiet swig fftw3f pip - pip install sphinxcontrib-bibtex fi + +export PATH=$WORKSPACE/miniconda/bin:$PATH + +# Ensure configuration is up to date. +conda config --add channels http://conda.binstar.org/omnia +conda install --yes --quiet swig fftw3f pip +pip install sphinxcontrib-bibtex -- GitLab From cd9a442e93189cc6b3fa1ecd5d8c13da322451b2 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 17:57:42 -0500 Subject: [PATCH 110/338] Minor updates to Jenkins prepare scripts. --- devtools/packaging/scripts/linux/prepare.sh | 2 +- devtools/packaging/scripts/osx/prepare.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/devtools/packaging/scripts/linux/prepare.sh b/devtools/packaging/scripts/linux/prepare.sh index 7091ce6e6..00f63290e 100755 --- a/devtools/packaging/scripts/linux/prepare.sh +++ b/devtools/packaging/scripts/linux/prepare.sh @@ -12,7 +12,7 @@ then echo "miniconda already exists" else echo "Downloading miniconda..." - wget http://repo.continuum.io/miniconda/${MINICONDA} + wget --quiet http://repo.continuum.io/miniconda/${MINICONDA} bash ${MINICONDA} -b -p miniconda PIP_ARGS="-U" fi diff --git a/devtools/packaging/scripts/osx/prepare.sh b/devtools/packaging/scripts/osx/prepare.sh index b44a8e70e..c6a5c9632 100755 --- a/devtools/packaging/scripts/osx/prepare.sh +++ b/devtools/packaging/scripts/osx/prepare.sh @@ -12,11 +12,12 @@ then echo "miniconda already exists" else echo "Downloading miniconda..." - wget http://repo.continuum.io/miniconda/${MINICONDA} + wget --quiet http://repo.continuum.io/miniconda/${MINICONDA} bash ${MINICONDA} -b -p miniconda PIP_ARGS="-U" fi +# Add to path. export PATH=$WORKSPACE/miniconda/bin:$PATH # Ensure configuration is up to date. -- GitLab From 609b6a516da95408b77b58ac3555683841ffbb98 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 18:01:14 -0500 Subject: [PATCH 111/338] Fixed fftw3f library path error in OS X Jenkins build script. --- devtools/packaging/scripts/osx/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index 650ad66cb..b6c4d3c04 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -24,8 +24,8 @@ CMAKE_FLAGS+=" -DOPENMM_BUILD_OPENCL_DOUBLE_PRECISION_TESTS=FALSE" # Set location for FFTW3 PREFIX="$WORKSPACE/miniconda" CMAKE_FLAGS+=" -DFFTW_INCLUDES=$PREFIX/include" -CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.so" -CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.so" +CMAKE_FLAGS+=" -DFFTW_LIBRARY=$PREFIX/lib/libfftw3f.dylib" +CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=$PREFIX/lib/libfftw3f_threads.dylib" # Build in subdirectory. if [ -e build ]; then -- GitLab From 865364db016df17c0c8ba19719c65cd530965d21 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 19:13:45 -0500 Subject: [PATCH 112/338] Added relative workspace path to Jenkins build prepare scripts. --- devtools/packaging/scripts/linux/prepare.sh | 3 +++ devtools/packaging/scripts/osx/prepare.sh | 3 +++ 2 files changed, 6 insertions(+) diff --git a/devtools/packaging/scripts/linux/prepare.sh b/devtools/packaging/scripts/linux/prepare.sh index 00f63290e..91d6e986e 100755 --- a/devtools/packaging/scripts/linux/prepare.sh +++ b/devtools/packaging/scripts/linux/prepare.sh @@ -2,6 +2,9 @@ # Prepare for build by ensuring necessary prerequisites are locally installed. +# Set relative workspace path. +export WORKSPACE=`pwd` + # Install miniconda export VERSION="3.7.0" export PLATFORM="Linux" diff --git a/devtools/packaging/scripts/osx/prepare.sh b/devtools/packaging/scripts/osx/prepare.sh index c6a5c9632..be26323e6 100755 --- a/devtools/packaging/scripts/osx/prepare.sh +++ b/devtools/packaging/scripts/osx/prepare.sh @@ -2,6 +2,9 @@ # Prepare for build by ensuring necessary prerequisites are locally installed. +# Set relative workspace path. +export WORKSPACE=`pwd` + # Install miniconda export VERSION="3.7.0" export PLATFORM="MacOSX" -- GitLab From 846279872efb045995b4d346398bdb269fb09015 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 19:35:26 -0500 Subject: [PATCH 113/338] Tried to fix Jenkins build script Mac autodetection of version number. --- devtools/packaging/scripts/osx/package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devtools/packaging/scripts/osx/package.sh b/devtools/packaging/scripts/osx/package.sh index 82b3f56ff..a5b0914c8 100755 --- a/devtools/packaging/scripts/osx/package.sh +++ b/devtools/packaging/scripts/osx/package.sh @@ -5,7 +5,7 @@ # CONFIGURE HERE export PACKAGE_DIR="packaging" # directory to stuff packaged source distribution -export VERSION=$(sed -nr "s/OPENMM_VERSION:STRING=(.*)/\1/p" build/CMakeCache.txt) +export VERSION=$(grep "OPENMM_VERSION:STRING" build/CMakeCache.txt | sed -E "s/OPENMM_VERSION:STRING=(.*)/\1/") export PACKAGE_SUBDIR="OpenMM-${VERSION}-Mac" # directory where distribution will be unpacked export DISTRO_PREFIX="OpenMM-${VERSION}-Mac" # prefix for source distribution (e.g. ${DISTRIBUTION_NAME}.zip) -- GitLab From 93cd76b355a37ec3bd4f52f3a0fd1dceba6ecd2a Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 19:39:01 -0500 Subject: [PATCH 114/338] Fixing more paths in Jenkins build paths. --- devtools/packaging/scripts/linux/build.sh | 3 +++ devtools/packaging/scripts/osx/build.sh | 3 +++ 2 files changed, 6 insertions(+) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index 82b97d68c..9fa0fc516 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -3,6 +3,9 @@ # Build script for Linux distribution, for use in automated packaging. # Note that this must be run from outside the checked-out openmm/ directory. +# Set relative workspace path. +export WORKSPACE=`pwd` + # Add conda binaries to path. PATH=$WORKSPACE/miniconda/bin:$PATH diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index b6c4d3c04..8fc4e15da 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -3,6 +3,9 @@ # Build script for Mac OS X distribution, for use in automated packaging. # Note that this must be run from outside the checked-out openmm/ directory. +# Set relative workspace path. +export WORKSPACE=`pwd` + # Add conda binaries to path. PATH=$WORKSPACE/miniconda/bin:$PATH -- GitLab From 4ad08011aacc885d93aa7c1555fa4c77d8bed393 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 8 Nov 2014 20:10:32 -0500 Subject: [PATCH 115/338] Hopefully fixed issue with Jenkins linux build script. --- devtools/packaging/scripts/linux/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index 9fa0fc516..4ca240548 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -40,8 +40,8 @@ make -j4 all DoxygenApiDocs sphinxpdf make install # Install Python wrappers. -OPENMM_INCLUDE_PATH=$INSTALL/include -OPENMM_LIB_PATH=$INSTALL/lib +export OPENMM_INCLUDE_PATH=$INSTALL/include +export OPENMM_LIB_PATH=$INSTALL/lib cd python python setup.py install --prefix=$INSTALL cd ../.. -- GitLab From d5666536a1d2f0ff6492054c077c8d7afe336495 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 10 Nov 2014 12:25:55 -0800 Subject: [PATCH 116/338] Fixed a bug in neighbor list construction --- platforms/cuda/src/kernels/findInteractingBlocks.cu | 4 ++-- platforms/opencl/src/kernels/findInteractingBlocks.cl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platforms/cuda/src/kernels/findInteractingBlocks.cu b/platforms/cuda/src/kernels/findInteractingBlocks.cu index 257ab8527..27204ac01 100644 --- a/platforms/cuda/src/kernels/findInteractingBlocks.cu +++ b/platforms/cuda/src/kernels/findInteractingBlocks.cu @@ -256,7 +256,7 @@ extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, rea if (indexInWarp == 0) tileStartIndex = atomicAdd(interactionCount, tilesToStore); int newTileStartIndex = tileStartIndex; - if (newTileStartIndex+tilesToStore < maxTiles) { + if (newTileStartIndex+tilesToStore <= maxTiles) { if (indexInWarp < tilesToStore) interactingTiles[newTileStartIndex+indexInWarp] = x; for (int j = 0; j < tilesToStore; j++) @@ -275,7 +275,7 @@ extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, rea if (indexInWarp == 0) tileStartIndex = atomicAdd(interactionCount, tilesToStore); int newTileStartIndex = tileStartIndex; - if (newTileStartIndex+tilesToStore < maxTiles) { + if (newTileStartIndex+tilesToStore <= maxTiles) { if (indexInWarp < tilesToStore) interactingTiles[newTileStartIndex+indexInWarp] = x; for (int j = 0; j < tilesToStore; j++) diff --git a/platforms/opencl/src/kernels/findInteractingBlocks.cl b/platforms/opencl/src/kernels/findInteractingBlocks.cl index 34b021df5..6a3c014f1 100644 --- a/platforms/opencl/src/kernels/findInteractingBlocks.cl +++ b/platforms/opencl/src/kernels/findInteractingBlocks.cl @@ -216,7 +216,7 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi *tileStartIndex = atom_add(interactionCount, tilesToStore); SYNC_WARPS; int newTileStartIndex = *tileStartIndex; - if (newTileStartIndex+tilesToStore < maxTiles) { + if (newTileStartIndex+tilesToStore <= maxTiles) { if (indexInWarp < tilesToStore) interactingTiles[newTileStartIndex+indexInWarp] = x; for (int j = 0; j < tilesToStore; j++) @@ -237,7 +237,7 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi *tileStartIndex = atom_add(interactionCount, tilesToStore); SYNC_WARPS; int newTileStartIndex = *tileStartIndex; - if (newTileStartIndex+tilesToStore < maxTiles) { + if (newTileStartIndex+tilesToStore <= maxTiles) { if (indexInWarp < tilesToStore) interactingTiles[newTileStartIndex+indexInWarp] = x; for (int j = 0; j < tilesToStore; j++) -- GitLab From ea47b895d02aed2db546cd469f808dcbbf4050c6 Mon Sep 17 00:00:00 2001 From: Matthew Harrigan Date: Fri, 6 Jun 2014 20:31:36 -0700 Subject: [PATCH 117/338] Python 3 compatitbility --- wrappers/python/simtk/openmm/app/dcdfile.py | 6 +++--- wrappers/python/simtk/openmm/app/statedatareporter.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index 28e41a730..13cbebbf0 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -70,10 +70,10 @@ class DCDFile(object): boxFlag = 0 if topology.getUnitCellDimensions() is not None: boxFlag = 1 - header = struct.pack(' Date: Mon, 10 Nov 2014 14:05:03 -0800 Subject: [PATCH 118/338] Remove buffering per @swails --- wrappers/python/simtk/openmm/app/statedatareporter.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/statedatareporter.py b/wrappers/python/simtk/openmm/app/statedatareporter.py index 6c3ffa56f..711fdfc16 100644 --- a/wrappers/python/simtk/openmm/app/statedatareporter.py +++ b/wrappers/python/simtk/openmm/app/statedatareporter.py @@ -99,8 +99,7 @@ class StateDataReporter(object): raise RuntimeError("Cannot write .bz2 file because Python could not import bz2 library") self._out = bz2.BZ2File(file, 'w', 0) else: - # 1 means Line buffering - self._out = open(file, 'w', 1) + self._out = open(file, 'w') else: self._out = file self._step = step -- GitLab From ad5821ff7d9cf806986ca51a356430e0d08f97a0 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 11 Nov 2014 15:45:50 -0800 Subject: [PATCH 119/338] CustomIntegrator throws an exception if variable names are ambiguous --- openmmapi/src/CustomIntegrator.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/openmmapi/src/CustomIntegrator.cpp b/openmmapi/src/CustomIntegrator.cpp index cba9558fb..19c78a5e2 100644 --- a/openmmapi/src/CustomIntegrator.cpp +++ b/openmmapi/src/CustomIntegrator.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2011-2012 Stanford University and the Authors. * + * Portions copyright (c) 2011-2014 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -36,11 +36,11 @@ #include "openmm/internal/ContextImpl.h" #include "openmm/internal/OSRngSeed.h" #include "openmm/kernels.h" +#include #include using namespace OpenMM; -using std::string; -using std::vector; +using namespace std; CustomIntegrator::CustomIntegrator(double stepSize) : globalsAreCurrent(true), forcesAreValid(false) { setStepSize(stepSize); @@ -52,6 +52,18 @@ CustomIntegrator::CustomIntegrator(double stepSize) : globalsAreCurrent(true), f void CustomIntegrator::initialize(ContextImpl& contextRef) { if (owner != NULL && &contextRef.getOwner() != owner) throw OpenMMException("This Integrator is already bound to a context"); + vector variableList; + set variableSet; + variableList.insert(variableList.end(), globalNames.begin(), globalNames.end()); + variableList.insert(variableList.end(), perDofNames.begin(), perDofNames.end()); + for (int i = 0; i < (int) variableList.size(); i++) { + string& name = variableList[i]; + if (variableSet.find(name) != variableSet.end()) + throw OpenMMException("The Integrator defines two variables with the same name: "+name); + variableSet.insert(name); + if (contextRef.getParameters().find(name) != contextRef.getParameters().end()) + throw OpenMMException("The Integrator defines a variable with the same name as a Context parameter: "+name); + } context = &contextRef; owner = &contextRef.getOwner(); kernel = context->getPlatform().createKernel(IntegrateCustomStepKernel::Name(), contextRef); -- GitLab From 842f295dfb5c1de62f06ce132752f831612d6e80 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 13 Nov 2014 14:54:23 -0500 Subject: [PATCH 120/338] Fix byte handling to work for both Py2 and Py3 --- wrappers/python/simtk/openmm/app/dcdfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index 13cbebbf0..024c871b1 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -73,7 +73,7 @@ class DCDFile(object): header = struct.pack(' Date: Thu, 13 Nov 2014 15:17:58 -0500 Subject: [PATCH 121/338] Add a basic DCD file test. There's no DCD file _reader_, so without MDTraj we can't validate the that this object does anything more than simply write without exceptions (i.e., we can't tell if the DCD file is actually _valid_) --- wrappers/python/tests/TestDcdFile.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 wrappers/python/tests/TestDcdFile.py diff --git a/wrappers/python/tests/TestDcdFile.py b/wrappers/python/tests/TestDcdFile.py new file mode 100644 index 000000000..afd4ca16e --- /dev/null +++ b/wrappers/python/tests/TestDcdFile.py @@ -0,0 +1,22 @@ +import unittest +import tempfile +import numpy as np +from simtk.openmm import app +import simtk.openmm as mm +from simtk import unit +from random import random +import os + +class TestDCDFile(unittest.TestCase): + def test_dcd(self): + """ Test the DCD file """ + pdbfile = app.PDBFile('systems/alanine-dipeptide-implicit.pdb') + natom = len(list(pdbfile.topology.atoms())) + dcd = app.DCDFile(open('test.dcd', 'w'), pdbfile.topology, 0.001) + for i in range(5): + dcd.writeModel([mm.Vec3(random(), random(), random()) for j in range(natom)]*unit.angstroms) + dcd._file.close() + os.remove('test.dcd') + +if __name__ == '__main__': + unittest.main() -- GitLab From a572eec6ddae20b64bdb6f2cb929dbf8fd4b728b Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 13 Nov 2014 16:45:02 -0800 Subject: [PATCH 122/338] Further documentation updates for 6.2 --- docs-source/usersguide/application.rst | 9 +++-- docs-source/usersguide/references.bib | 46 +++++++++++++++----------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/docs-source/usersguide/application.rst b/docs-source/usersguide/application.rst index 4c6ef5be6..1521a8110 100644 --- a/docs-source/usersguide/application.rst +++ b/docs-source/usersguide/application.rst @@ -366,7 +366,8 @@ molecular topology and atom positions. Your file need not be called :file:`input.pdb`. Feel free to change this line to specify any file you want, though it must contain all of the atoms needed by the force field. (More information on how to add missing atoms and residues using OpenMM tools can be found in Chapter :ref:`model-building-and-editing`.) -Make sure you include the single quotes around the file name. +Make sure you include the single quotes around the file name. OpenMM also can load +files in the newer PDBx/mmCIF format: just change :class:`PDBFile` to :class:`PDBxFile`. :: forcefield = ForceField('amber99sb.xml', 'tip3p.xml') @@ -805,8 +806,12 @@ you would type: forcefield = ForceField('amber99sb.xml', 'amber99_obc.xml') +Note that the GBSA-OBC parameters in these files are those used in TINKER.\ :cite:`Tinker` +They are designed for use with Amber force fields, but they are different from +the parameters found in the AMBER application. + If you are running a vacuum simulation, you do not need to specify a water -model. The following line specifies the AMBER10 force field and no water model. +model. The following line specifies the Amber10 force field and no water model. If you try to use it with a PDB file that contains explicit water, it will produce an error since no water parameters are defined: :: diff --git a/docs-source/usersguide/references.bib b/docs-source/usersguide/references.bib index e22b7286d..c7b07c9cd 100644 --- a/docs-source/usersguide/references.bib +++ b/docs-source/usersguide/references.bib @@ -11,7 +11,7 @@ @article{Aqvist2004 author = {Ã…qvist, Johan and Wennerström, Petra and Nervall, Martin and Bjelic, Sinisa and Brandsdal, Bjørn O.}, - title = {Molecular dynamics simulations of water and biomolecules with a Monte Carlo constant pressure algorithm}, + title = {Molecular dynamics simulations of water and biomolecules with a {Monte Carlo} constant pressure algorithm}, journal = {Chemical Physics Letters}, volume = {384}, pages = {288-294}, @@ -41,7 +41,7 @@ @article{Chow1995 author = {Chow, Kim-Hung and Ferguson, David M.}, - title = {Isothermal-isobaric molecular dynamics simulations with Monte Carlo volume sampling}, + title = {Isothermal-isobaric molecular dynamics simulations with {Monte Carlo} volume sampling}, journal = {Computer Physics Communications}, volume = {91}, pages = {283-289}, @@ -71,7 +71,7 @@ @article{Essmann1995 author = {Essmann, Ulrich and Perera, Lalith and Berkowitz, Max L. and Darden, Tom and Lee, Hsing and Pedersen, Lee G.}, - title = {A smooth particle mesh Ewald method}, + title = {A smooth particle mesh {Ewald} method}, journal = {Journal of Chemical Physics}, volume = {103}, number = {19}, @@ -103,7 +103,7 @@ @article{Horn2004 author = {Horn, Hans W. and Swope, William C. and Pitera, Jed W. and Madura, Jeffry D. and Dick, Thomas J. and Hura, Greg L. and Head-Gordon, Teresa}, - title = {Development of an improved four-site water model for biomolecular simulations: TIP4P-Ew}, + title = {Development of an improved four-site water model for biomolecular simulations: {TIP4P-Ew}}, journal = {Journal of Chemical Physics}, volume = {120}, pages = {9665-9678}, @@ -113,7 +113,7 @@ @article{Hornak2006 author = {Hornak, V. and Abel, R. and Okur, A. and Strockbine, B. and Roitberg, A. and Simmerling, C.}, - title = {Comparison of multiple Amber force fields and development of improved protein backbone parameters}, + title = {Comparison of multiple {Amber} force fields and development of improved protein backbone parameters}, journal = {Proteins}, volume = {65}, pages = {712-725}, @@ -123,7 +123,7 @@ @article{Izaguirre2010 author = {Izaguirre, Jesús A. and Sweet, Chris R. and Pande, Vijay S.}, - title = {Multiscale dynamics of macromolecules using Normal Mode Langevin}, + title = {Multiscale dynamics of macromolecules using {Normal Mode Langevin}}, journal = {Pacific Symposium on Biocomputing}, volume = {15}, pages = {240-251}, @@ -154,7 +154,7 @@ @article{Labute2008 author = {Labute, Paul}, - title = {The generalized Born/volume integral implicit solvent model: Estimation of the free energy of hydration using London dispersion instead of atomic surface area}, + title = {The generalized {Born}/volume integral implicit solvent model: Estimation of the free energy of hydration using {London} dispersion instead of atomic surface area}, journal = {Journal of Computational Chemistry}, volume = {29}, number = {10}, @@ -176,7 +176,7 @@ @article{Lamoureux2003 author = {Lamoureux, Guillaume and Roux, Benoit}, - title = {Modeling induced polarization with classical Drude oscillators: Theory and molecular dynamics simulation algorithm}, + title = {Modeling induced polarization with classical {Drude} oscillators: Theory and molecular dynamics simulation algorithm}, journal = {Journal of Chemical Physics}, volume = {119}, number = {6}, @@ -187,7 +187,7 @@ @article{Li2010 author = {Li, D.W. and Br{\"u}schweiler, R.}, - title = {NMR-based protein potentials}, + title = {{NMR}-based protein potentials}, journal = {Angewandte Chemie International Edition}, volume = {49}, pages = {6778-6780}, @@ -197,7 +197,7 @@ @article{Lindorff-Larsen2010 author = {Lindorff-Larsen, K. and Piana, S. and Palmo, K. and Maragakis, P. and Klepeis, J. and Dror, R.O. and Shaw, D.E.}, - title = {Improved side-chain torsion potentials for the Amber ff99SB protein force field}, + title = {Improved side-chain torsion potentials for the {Amber ff99SB} protein force field}, journal = {Proteins}, volume = {78}, pages = {1950-1958}, @@ -207,7 +207,7 @@ @article{Liu1989 author = {Liu, Dong C. and Nocedal, Jorge}, - title = {On the Limited Memory BFGS Method For Large Scale Optimization}, + title = {On the Limited Memory {BFGS} Method For Large Scale Optimization}, journal = {Mathematical Programming}, volume = {45}, pages = {503-528}, @@ -217,7 +217,7 @@ @article{Lopes2013, author = {Lopes, Pedro E. M. and Huang, Jing and Shim, Jihyun and Luo, Yun and Li, Hui and Roux, Benoît and MacKerell, Alexander D.}, - title = {Polarizable Force Field for Peptides and Proteins Based on the Classical Drude Oscillator}, + title = {Polarizable Force Field for Peptides and Proteins Based on the Classical {Drude} Oscillator}, journal = {Journal of Chemical Theory and Computation}, volume = {9}, number = {12}, @@ -248,7 +248,7 @@ @article{Mongan2007 author = {Mongan, John and Simmerling, Carlos and McCammon, J. Andrew and Case, David A. and Onufriev, Alexey}, - title = {Generalized Born model with a simple, robust molecular volume correction}, + title = {Generalized {Born} model with a simple, robust molecular volume correction}, journal = {Journal of Chemical Theory and Computation}, volume = {3}, number = {1}, @@ -259,7 +259,7 @@ @article{Nguyen2013 author = {Nguyen, Hai and Roe, Daniel R. and Simmerling, Carlos}, - title = {Improved Generalized Born Solvent Model Parameters for Protein Simulations}, + title = {Improved Generalized {Born} Solvent Model Parameters for Protein Simulations}, journal = {Journal of Chemical Theory and Computation}, volume = {9}, number = {4}, @@ -270,7 +270,7 @@ @article{Onufriev2004 author = {Onufriev, Alexey and Bashford, Donald and Case, David A.}, - title = {Exploring protein native states and large-scale conformational changes with a modified generalized born model}, + title = {Exploring protein native states and large-scale conformational changes with a modified generalized {Born} model}, journal = {Proteins}, volume = {55}, number = {22}, @@ -281,7 +281,7 @@ @article{Parrinello1984 author = {Parrinello, M. and Rahman, A.}, - title = {Study of an F center in molten KCl}, + title = {Study of an {F} center in molten {KCl}}, journal = {Journal of Chemical Physics}, volume = {80}, number = {2}, @@ -329,7 +329,7 @@ @article{Schnieders2007 author = {Schnieders, Michael J. and Ponder, Jay W.}, - title = {Polarizable Atomic Multipole Solutes in a Generalized Kirkwood Continuum}, + title = {Polarizable Atomic Multipole Solutes in a Generalized {Kirkwood} Continuum}, journal = {Journal of Chemical Theory and Computation}, volume = {3}, pages = {2083-2097}, @@ -349,7 +349,7 @@ @article{Shi2013 author = {Shi, Yue and Xia, Zhen and Zhang, Jiajing and Best, Robert and Wu, Chuanjie and Ponder, Jay W. and Ren, Pengyu}, - title = {Polarizable Atomic Multipole-Based AMOEBA Force Field for Proteins}, + title = {Polarizable Atomic Multipole-Based {AMOEBA} Force Field for Proteins}, journal = {Journal of Chemical Theory and Computation}, volume = {9}, number = {9}, @@ -399,6 +399,12 @@ type = {Journal Article} } +@misc{Tinker + author = {Ponder, Jay W.}, + title = {{TINKER - Software Tools for Molecular Design, 4.2}}, + year = {2004} +} + @article{Tironi1995 author = {Tironi, Ilario G. and Sperb, René and Smith, Paul E. and van Gunsteren, Wilfred F.}, title = {A generalized reaction field method for molecular dynamics simulations}, @@ -412,7 +418,7 @@ @article{Toukmaji1996 author = {Toukmaji, Abdulnour Y. and Board Jr, John A.}, - title = {Ewald summation techniques in perspective: a survey}, + title = {{Ewald} summation techniques in perspective: a survey}, journal = {Computer Physics Communications}, volume = {95}, pages = {73-92}, @@ -422,7 +428,7 @@ @article{Wang2000 author = {Wang, J. and Cieplak, P. and Kollman, P.A.}, - title = {How well does a restrained electrostatic potential (RESP) model perform in calculating conformational energies of organic and biological molecules?}, + title = {How well does a restrained electrostatic potential ({RESP}) model perform in calculating conformational energies of organic and biological molecules?}, journal = {Journal of Computational Chemistry}, volume = {21}, pages = {1049-1074}, -- GitLab From 645bf2294e98d00e839e47498a91a50b538044e1 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 14 Nov 2014 11:27:53 -0500 Subject: [PATCH 123/338] Use tempfile to make a file. --- wrappers/python/tests/TestDcdFile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/python/tests/TestDcdFile.py b/wrappers/python/tests/TestDcdFile.py index afd4ca16e..6acd834cc 100644 --- a/wrappers/python/tests/TestDcdFile.py +++ b/wrappers/python/tests/TestDcdFile.py @@ -1,6 +1,5 @@ import unittest import tempfile -import numpy as np from simtk.openmm import app import simtk.openmm as mm from simtk import unit @@ -10,13 +9,14 @@ import os class TestDCDFile(unittest.TestCase): def test_dcd(self): """ Test the DCD file """ + fname = tempfile.mktemp(suffix='.dcd') pdbfile = app.PDBFile('systems/alanine-dipeptide-implicit.pdb') natom = len(list(pdbfile.topology.atoms())) - dcd = app.DCDFile(open('test.dcd', 'w'), pdbfile.topology, 0.001) + dcd = app.DCDFile(open(fname, 'w'), pdbfile.topology, 0.001) for i in range(5): dcd.writeModel([mm.Vec3(random(), random(), random()) for j in range(natom)]*unit.angstroms) dcd._file.close() - os.remove('test.dcd') + os.remove(fname) if __name__ == '__main__': unittest.main() -- GitLab From a64e0db669881e6426a05c6f4a05fedc0a466216 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 14 Nov 2014 11:57:39 -0500 Subject: [PATCH 124/338] Open as binary (needed for Python 3) --- wrappers/python/tests/TestDcdFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/tests/TestDcdFile.py b/wrappers/python/tests/TestDcdFile.py index 6acd834cc..3f225fa50 100644 --- a/wrappers/python/tests/TestDcdFile.py +++ b/wrappers/python/tests/TestDcdFile.py @@ -12,7 +12,7 @@ class TestDCDFile(unittest.TestCase): fname = tempfile.mktemp(suffix='.dcd') pdbfile = app.PDBFile('systems/alanine-dipeptide-implicit.pdb') natom = len(list(pdbfile.topology.atoms())) - dcd = app.DCDFile(open(fname, 'w'), pdbfile.topology, 0.001) + dcd = app.DCDFile(open(fname, 'wb'), pdbfile.topology, 0.001) for i in range(5): dcd.writeModel([mm.Vec3(random(), random(), random()) for j in range(natom)]*unit.angstroms) dcd._file.close() -- GitLab From c6b6b8946e4e0cecfc110d31a058284b131406c2 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 14 Nov 2014 12:53:55 -0500 Subject: [PATCH 125/338] Make sure the DCD file handle is closed -- do it the right way in the test. Make sure files are appropriately closed by PDBFile() --- wrappers/python/simtk/openmm/app/pdbfile.py | 4 ++++ wrappers/python/tests/TestDcdFile.py | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/pdbfile.py b/wrappers/python/simtk/openmm/app/pdbfile.py index 5f4e23f7e..630f84cea 100644 --- a/wrappers/python/simtk/openmm/app/pdbfile.py +++ b/wrappers/python/simtk/openmm/app/pdbfile.py @@ -75,9 +75,13 @@ class PDBFile(object): pdb = file else: inputfile = file + own_handle = False if isinstance(file, str): inputfile = open(file) + own_handle = True pdb = PdbStructure(inputfile, load_all_models=True) + if own_handle: + inputfile.close() PDBFile._loadNameReplacementTables() # Build the topology diff --git a/wrappers/python/tests/TestDcdFile.py b/wrappers/python/tests/TestDcdFile.py index 3f225fa50..decf99431 100644 --- a/wrappers/python/tests/TestDcdFile.py +++ b/wrappers/python/tests/TestDcdFile.py @@ -12,10 +12,10 @@ class TestDCDFile(unittest.TestCase): fname = tempfile.mktemp(suffix='.dcd') pdbfile = app.PDBFile('systems/alanine-dipeptide-implicit.pdb') natom = len(list(pdbfile.topology.atoms())) - dcd = app.DCDFile(open(fname, 'wb'), pdbfile.topology, 0.001) - for i in range(5): - dcd.writeModel([mm.Vec3(random(), random(), random()) for j in range(natom)]*unit.angstroms) - dcd._file.close() + with open(fname, 'wb') as f: + dcd = app.DCDFile(f, pdbfile.topology, 0.001) + for i in range(5): + dcd.writeModel([mm.Vec3(random(), random(), random()) for j in range(natom)]*unit.angstroms) os.remove(fname) if __name__ == '__main__': -- GitLab From 4c0621eda744c2b6ede707f2f7db91f3efb96ee0 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Fri, 14 Nov 2014 11:04:50 -0800 Subject: [PATCH 126/338] Minor optimization to sorting --- platforms/cuda/src/CudaSort.cpp | 5 ++--- platforms/cuda/src/kernels/sort.cu | 8 +++++++- platforms/opencl/src/OpenCLSort.cpp | 5 +++-- platforms/opencl/src/kernels/sort.cl | 8 +++++++- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/platforms/cuda/src/CudaSort.cpp b/platforms/cuda/src/CudaSort.cpp index 088d859d6..46349b300 100644 --- a/platforms/cuda/src/CudaSort.cpp +++ b/platforms/cuda/src/CudaSort.cpp @@ -112,13 +112,12 @@ void CudaSort::sort(CudaArray& data) { else { // Compute the range of data values. - void* rangeArgs[] = {&data.getDevicePointer(), &dataLength, &dataRange->getDevicePointer()}; + unsigned int numBuckets = bucketOffset->getSize(); + void* rangeArgs[] = {&data.getDevicePointer(), &dataLength, &dataRange->getDevicePointer(), &numBuckets, &bucketOffset->getDevicePointer()}; context.executeKernel(computeRangeKernel, rangeArgs, rangeKernelSize, rangeKernelSize, rangeKernelSize*trait->getKeySize()); // Assign array elements to buckets. - unsigned int numBuckets = bucketOffset->getSize(); - context.clearBuffer(*bucketOffset); void* elementsArgs[] = {&data.getDevicePointer(), &dataLength, &numBuckets, &dataRange->getDevicePointer(), &bucketOffset->getDevicePointer(), &bucketOfElement->getDevicePointer(), &offsetInBucket->getDevicePointer()}; context.executeKernel(assignElementsKernel, elementsArgs, data.getSize()); diff --git a/platforms/cuda/src/kernels/sort.cu b/platforms/cuda/src/kernels/sort.cu index c7f33ca4a..5a69be4ee 100644 --- a/platforms/cuda/src/kernels/sort.cu +++ b/platforms/cuda/src/kernels/sort.cu @@ -50,7 +50,8 @@ __global__ void sortShortList(DATA_TYPE* __restrict__ data, unsigned int length) * Calculate the minimum and maximum value in the array to be sorted. This kernel * is executed as a single work group. */ -__global__ void computeRange(const DATA_TYPE* __restrict__ data, unsigned int length, KEY_TYPE* __restrict__ range) { +__global__ void computeRange(const DATA_TYPE* __restrict__ data, unsigned int length, KEY_TYPE* __restrict__ range, + unsigned int numBuckets, unsigned int* __restrict__ bucketOffset) { extern __shared__ KEY_TYPE rangeBuffer[]; KEY_TYPE minimum = MAX_KEY; KEY_TYPE maximum = MIN_KEY; @@ -86,6 +87,11 @@ __global__ void computeRange(const DATA_TYPE* __restrict__ data, unsigned int le range[0] = minimum; range[1] = maximum; } + + // Clear the bucket counters in preparation for the next kernel. + + for (unsigned int index = threadIdx.x; index < numBuckets; index += blockDim.x) + bucketOffset[index] = 0; } /** diff --git a/platforms/opencl/src/OpenCLSort.cpp b/platforms/opencl/src/OpenCLSort.cpp index e2247938c..a3fb2ca52 100644 --- a/platforms/opencl/src/OpenCLSort.cpp +++ b/platforms/opencl/src/OpenCLSort.cpp @@ -116,16 +116,17 @@ void OpenCLSort::sort(OpenCLArray& data) { else { // Compute the range of data values. + unsigned int numBuckets = bucketOffset->getSize(); computeRangeKernel.setArg(0, data.getDeviceBuffer()); computeRangeKernel.setArg(1, data.getSize()); computeRangeKernel.setArg(2, dataRange->getDeviceBuffer()); computeRangeKernel.setArg(3, rangeKernelSize*trait->getKeySize(), NULL); + computeRangeKernel.setArg(4, numBuckets); + computeRangeKernel.setArg(5, bucketOffset->getDeviceBuffer()); context.executeKernel(computeRangeKernel, rangeKernelSize, rangeKernelSize); // Assign array elements to buckets. - unsigned int numBuckets = bucketOffset->getSize(); - context.clearBuffer(*bucketOffset); assignElementsKernel.setArg(0, data.getDeviceBuffer()); assignElementsKernel.setArg(1, data.getSize()); assignElementsKernel.setArg(2, numBuckets); diff --git a/platforms/opencl/src/kernels/sort.cl b/platforms/opencl/src/kernels/sort.cl index ad76c3438..08c019542 100644 --- a/platforms/opencl/src/kernels/sort.cl +++ b/platforms/opencl/src/kernels/sort.cl @@ -49,7 +49,8 @@ __kernel void sortShortList(__global DATA_TYPE* __restrict__ data, uint length, * Calculate the minimum and maximum value in the array to be sorted. This kernel * is executed as a single work group. */ -__kernel void computeRange(__global const DATA_TYPE* restrict data, uint length, __global KEY_TYPE* restrict range, __local KEY_TYPE* restrict buffer) { +__kernel void computeRange(__global const DATA_TYPE* restrict data, uint length, __global KEY_TYPE* restrict range, __local KEY_TYPE* restrict buffer, + uint numBuckets, __global uint* restrict bucketOffset) { KEY_TYPE minimum = MAX_KEY; KEY_TYPE maximum = MIN_KEY; @@ -84,6 +85,11 @@ __kernel void computeRange(__global const DATA_TYPE* restrict data, uint length, range[0] = minimum; range[1] = maximum; } + + // Clear the bucket counters in preparation for the next kernel. + + for (uint index = get_local_id(0); index < numBuckets; index += get_local_size(0)) + bucketOffset[index] = 0; } /** -- GitLab From f0b8ac1478028ee77f2d356c24e0d5e7e55f6a05 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 17 Nov 2014 18:03:28 -0500 Subject: [PATCH 127/338] Remove what appears to be a debug message. --- wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i | 1 - 1 file changed, 1 deletion(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i index 3753ebc47..475200935 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i @@ -79,7 +79,6 @@ class State(_object): return serializationString def __setstate__(self, serializationString): - print 'calling set state' dState = XmlSerializer.deserialize(serializationString) # Safe provided no __slots__ or other weird things are used self.__dict__.update(dState.__dict__) -- GitLab From f16e7e3ce89c747bb29a83252c2a1b89b50f9cc8 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 18 Nov 2014 14:29:40 -0500 Subject: [PATCH 128/338] Recognize more residue labels as water in the Amber file parser. At some point, at least, TP4 was the residue label for water (I think tleap currently translates most of the water residue labels to WAT, but there are at least some -- like $AMBERHOME/test/tip4p/prmtop -- that use older labels). --- wrappers/python/simtk/openmm/app/internal/amber_file_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 76c30dd7e..7edf268df 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -720,7 +720,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode system.addParticle(mass) # Add constraints. - isWater = [prmtop.getResidueLabel(i) == 'WAT' for i in range(prmtop.getNumAtoms())] + isWater = [prmtop.getResidueLabel(i) == ('WAT', 'TP4', 'TP5', 'SPF', 'SPG') for i in range(prmtop.getNumAtoms())] if shake in ('h-bonds', 'all-bonds', 'h-angles'): for (iAtom, jAtom, k, rMin) in prmtop.getBondsWithH(): system.addConstraint(iAtom, jAtom, rMin) -- GitLab From e2c80f2e19e299e1d463b87e08a34af1b25755d9 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 18 Nov 2014 15:09:05 -0500 Subject: [PATCH 129/338] Reduce the water labels down to just the EP models, since that's where it is most important and we don't want false positives. --- wrappers/python/simtk/openmm/app/internal/amber_file_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 7edf268df..f4adee979 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -720,7 +720,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode system.addParticle(mass) # Add constraints. - isWater = [prmtop.getResidueLabel(i) == ('WAT', 'TP4', 'TP5', 'SPF', 'SPG') for i in range(prmtop.getNumAtoms())] + isWater = [prmtop.getResidueLabel(i) == ('WAT', 'TP4', 'TP5') for i in range(prmtop.getNumAtoms())] if shake in ('h-bonds', 'all-bonds', 'h-angles'): for (iAtom, jAtom, k, rMin) in prmtop.getBondsWithH(): system.addConstraint(iAtom, jAtom, rMin) -- GitLab From 67cd9e185a0211000adc5b82fcd2741fd636bc5e Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 18 Nov 2014 15:10:01 -0500 Subject: [PATCH 130/338] Add TIP4PEw name. --- wrappers/python/simtk/openmm/app/internal/amber_file_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index f4adee979..d9a8f16ce 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -720,7 +720,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode system.addParticle(mass) # Add constraints. - isWater = [prmtop.getResidueLabel(i) == ('WAT', 'TP4', 'TP5') for i in range(prmtop.getNumAtoms())] + isWater = [prmtop.getResidueLabel(i) == ('WAT', 'TP4', 'TP5', 'T4E') for i in range(prmtop.getNumAtoms())] if shake in ('h-bonds', 'all-bonds', 'h-angles'): for (iAtom, jAtom, k, rMin) in prmtop.getBondsWithH(): system.addConstraint(iAtom, jAtom, rMin) -- GitLab From b3eaa5ef6ef917cd7571c058a0bbbc3a126a525b Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 18 Nov 2014 15:13:14 -0500 Subject: [PATCH 131/338] == -> in --- wrappers/python/simtk/openmm/app/internal/amber_file_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index d9a8f16ce..ef7871766 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -720,7 +720,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode system.addParticle(mass) # Add constraints. - isWater = [prmtop.getResidueLabel(i) == ('WAT', 'TP4', 'TP5', 'T4E') for i in range(prmtop.getNumAtoms())] + isWater = [prmtop.getResidueLabel(i) in ('WAT', 'TP4', 'TP5', 'T4E') for i in range(prmtop.getNumAtoms())] if shake in ('h-bonds', 'all-bonds', 'h-angles'): for (iAtom, jAtom, k, rMin) in prmtop.getBondsWithH(): system.addConstraint(iAtom, jAtom, rMin) -- GitLab From bca1a5d84af750c1a68be779f7434a90559fe332 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 18 Nov 2014 12:54:08 -0800 Subject: [PATCH 132/338] Install benchmark.py script --- examples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f1c0d937b..6605bd88c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -93,7 +93,7 @@ FOREACH(EX_ROOT ${F_EXAMPLES}) INSTALL(FILES ${EX_ROOT}.f90 DESTINATION examples) ENDFOREACH(EX_ROOT ${F_EXAMPLES}) -INSTALL(FILES simulateAmber.py simulatePdb.py simulateGromacs.py testInstallation.py argon-chemical-potential.py input.inpcrd input.prmtop input.pdb input.gro input.top +INSTALL(FILES simulateAmber.py simulatePdb.py simulateGromacs.py testInstallation.py benchmark.py argon-chemical-potential.py input.inpcrd input.prmtop input.pdb input.gro input.top 5dfr_minimized.pdb 5dfr_solv-cube_equil.pdb DESTINATION examples) INSTALL(FILES VisualStudio/HelloArgon.vcproj -- GitLab From 285a12dbafd4c94a641e7de767803ad902b806ee Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 18 Nov 2014 13:57:49 -0800 Subject: [PATCH 133/338] Added error codes from CUDA 5.0 --- platforms/cuda/src/CudaContext.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 49c709ad7..10c157ae7 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -577,6 +577,7 @@ std::string CudaContext::getErrorString(CUresult result) { case CUDA_ERROR_ECC_UNCORRECTABLE: return "CUDA_ERROR_ECC_UNCORRECTABLE"; case CUDA_ERROR_UNSUPPORTED_LIMIT: return "CUDA_ERROR_UNSUPPORTED_LIMIT"; case CUDA_ERROR_CONTEXT_ALREADY_IN_USE: return "CUDA_ERROR_CONTEXT_ALREADY_IN_USE"; + case CUDA_ERROR_PEER_ACCESS_UNSUPPORTED: return "CUDA_ERROR_PEER_ACCESS_UNSUPPORTED"; case CUDA_ERROR_INVALID_SOURCE: return "CUDA_ERROR_INVALID_SOURCE"; case CUDA_ERROR_FILE_NOT_FOUND: return "CUDA_ERROR_FILE_NOT_FOUND"; case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND: return "CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND"; @@ -593,9 +594,15 @@ std::string CudaContext::getErrorString(CUresult result) { case CUDA_ERROR_PEER_ACCESS_NOT_ENABLED: return "CUDA_ERROR_PEER_ACCESS_NOT_ENABLED"; case CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE: return "CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE"; case CUDA_ERROR_CONTEXT_IS_DESTROYED: return "CUDA_ERROR_CONTEXT_IS_DESTROYED"; + case CUDA_ERROR_ASSERT: return "CUDA_ERROR_ASSERT"; + case CUDA_ERROR_TOO_MANY_PEERS: return "CUDA_ERROR_TOO_MANY_PEERS"; + case CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED: return "CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED"; + case CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED: return "CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED"; + case CUDA_ERROR_NOT_PERMITTED: return "CUDA_ERROR_NOT_PERMITTED"; + case CUDA_ERROR_NOT_SUPPORTED: return "CUDA_ERROR_NOT_SUPPORTED"; case CUDA_ERROR_UNKNOWN: return "CUDA_ERROR_UNKNOWN"; } - return "Invalid error code"; + return "CUDA error"; } void CudaContext::executeKernel(CUfunction kernel, void** arguments, int threads, int blockSize, unsigned int sharedSize) { -- GitLab From 8fb1f4dc89f2c9efda510767033a42c052957f8d Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 18 Nov 2014 15:10:09 -0800 Subject: [PATCH 134/338] DrudeForce did not implement getBondedParticles() --- .../include/openmm/internal/DrudeForceImpl.h | 1 + plugins/drude/openmmapi/src/DrudeForceImpl.cpp | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/plugins/drude/openmmapi/include/openmm/internal/DrudeForceImpl.h b/plugins/drude/openmmapi/include/openmm/internal/DrudeForceImpl.h index 8356efb30..d013de6bd 100644 --- a/plugins/drude/openmmapi/include/openmm/internal/DrudeForceImpl.h +++ b/plugins/drude/openmmapi/include/openmm/internal/DrudeForceImpl.h @@ -64,6 +64,7 @@ public: } std::vector getKernelNames(); void updateParametersInContext(ContextImpl& context); + std::vector > getBondedParticles() const; private: const DrudeForce& owner; Kernel kernel; diff --git a/plugins/drude/openmmapi/src/DrudeForceImpl.cpp b/plugins/drude/openmmapi/src/DrudeForceImpl.cpp index 2aa88b00c..65be6294d 100644 --- a/plugins/drude/openmmapi/src/DrudeForceImpl.cpp +++ b/plugins/drude/openmmapi/src/DrudeForceImpl.cpp @@ -146,8 +146,8 @@ double DrudeForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeFor return 0.0; } -std::vector DrudeForceImpl::getKernelNames() { - std::vector names; +vector DrudeForceImpl::getKernelNames() { + vector names; names.push_back(CalcDrudeForceKernel::Name()); return names; } @@ -155,3 +155,14 @@ std::vector DrudeForceImpl::getKernelNames() { void DrudeForceImpl::updateParametersInContext(ContextImpl& context) { kernel.getAs().copyParametersToContext(context, owner); } + +vector > DrudeForceImpl::getBondedParticles() const { + int numParticles = owner.getNumParticles(); + vector > bonds(numParticles); + for (int i = 0; i < numParticles; i++) { + int p2, p3, p4; + double charge, polarizability, aniso12, aniso34; + owner.getParticleParameters(i, bonds[i].first, bonds[i].second, p2, p3, p4, charge, polarizability, aniso12, aniso34); + } + return bonds; +} -- GitLab From 7bbf93311ea8abe505640a00fead22005f171ff3 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 18 Nov 2014 15:42:45 -0800 Subject: [PATCH 135/338] Workaround for CUDA bug --- platforms/cuda/src/CudaKernels.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index c9696b5cb..1ee828afe 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1400,15 +1400,16 @@ private: class CudaCalcNonbondedForceKernel::SyncStreamPreComputation : public CudaContext::ForcePreComputation { public: - SyncStreamPreComputation(CUstream stream, CUevent event, int forceGroup) : stream(stream), event(event), forceGroup(forceGroup) { + SyncStreamPreComputation(CudaContext& cu, CUstream stream, CUevent event, int forceGroup) : cu(cu), stream(stream), event(event), forceGroup(forceGroup) { } void computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) { if ((groups&(1< Date: Wed, 19 Nov 2014 02:38:31 -0500 Subject: [PATCH 136/338] Copy testInstallation.py to the simtk package and make it an import-safe module. Also copy the test PDB file to the data/ directory, since we rather need it... --- .../python/simtk/openmm/app/data/test.pdb | 8874 +++++++++++++++++ wrappers/python/simtk/testInstallation.py | 83 + 2 files changed, 8957 insertions(+) create mode 100644 wrappers/python/simtk/openmm/app/data/test.pdb create mode 100644 wrappers/python/simtk/testInstallation.py diff --git a/wrappers/python/simtk/openmm/app/data/test.pdb b/wrappers/python/simtk/openmm/app/data/test.pdb new file mode 100644 index 000000000..7fbcb44d1 --- /dev/null +++ b/wrappers/python/simtk/openmm/app/data/test.pdb @@ -0,0 +1,8874 @@ +REMARK GENERATED BY TRJCONV +HEADER Villin N68H in explicit water +REMARK THIS IS A SIMULATION BOX +CRYST1 49.163 45.981 38.869 90.00 90.00 90.00 P 1 1 +MODEL 0 +ATOM 1 N LEU 1 25.160 14.160 19.440 1.00 0.00 +ATOM 2 H1 LEU 1 24.350 13.730 19.870 1.00 0.00 +ATOM 3 H2 LEU 1 25.980 13.680 19.760 1.00 0.00 +ATOM 4 H3 LEU 1 25.180 15.100 19.810 1.00 0.00 +ATOM 5 CA LEU 1 25.090 13.920 17.980 1.00 0.00 +ATOM 6 HA LEU 1 24.700 12.930 17.760 1.00 0.00 +ATOM 7 CB LEU 1 24.420 14.970 17.100 1.00 0.00 +ATOM 8 HB1 LEU 1 24.590 14.630 16.080 1.00 0.00 +ATOM 9 HB2 LEU 1 24.950 15.910 17.240 1.00 0.00 +ATOM 10 CG LEU 1 22.930 15.010 17.400 1.00 0.00 +ATOM 11 HG LEU 1 22.870 15.610 18.310 1.00 0.00 +ATOM 12 CD1 LEU 1 22.410 15.830 16.210 1.00 0.00 +ATOM 13 HD11 LEU 1 22.630 15.250 15.320 1.00 0.00 +ATOM 14 HD12 LEU 1 21.320 15.930 16.260 1.00 0.00 +ATOM 15 HD13 LEU 1 22.920 16.790 16.220 1.00 0.00 +ATOM 16 CD2 LEU 1 22.100 13.730 17.590 1.00 0.00 +ATOM 17 HD21 LEU 1 22.520 12.930 16.980 1.00 0.00 +ATOM 18 HD22 LEU 1 22.090 13.470 18.650 1.00 0.00 +ATOM 19 HD23 LEU 1 21.080 13.910 17.250 1.00 0.00 +ATOM 20 C LEU 1 26.520 13.970 17.430 1.00 0.00 +ATOM 21 O LEU 1 27.360 14.710 17.880 1.00 0.00 +ATOM 22 N SER 2 26.720 13.080 16.460 1.00 0.00 +ATOM 23 H SER 2 25.900 12.580 16.160 1.00 0.00 +ATOM 24 CA SER 2 27.950 12.790 15.610 1.00 0.00 +ATOM 25 HA SER 2 28.780 12.480 16.250 1.00 0.00 +ATOM 26 CB SER 2 27.740 11.640 14.610 1.00 0.00 +ATOM 27 HB1 SER 2 28.670 11.350 14.130 1.00 0.00 +ATOM 28 HB2 SER 2 26.990 11.890 13.870 1.00 0.00 +ATOM 29 OG SER 2 27.520 10.520 15.410 1.00 0.00 +ATOM 30 HG SER 2 28.080 10.640 16.180 1.00 0.00 +ATOM 31 C SER 2 28.360 14.010 14.820 1.00 0.00 +ATOM 32 O SER 2 27.440 14.680 14.350 1.00 0.00 +ATOM 33 N ASP 3 29.650 14.360 14.620 1.00 0.00 +ATOM 34 H ASP 3 30.410 13.770 14.950 1.00 0.00 +ATOM 35 CA ASP 3 29.940 15.810 14.230 1.00 0.00 +ATOM 36 HA ASP 3 29.500 16.400 15.030 1.00 0.00 +ATOM 37 CB ASP 3 31.420 16.030 14.240 1.00 0.00 +ATOM 38 HB1 ASP 3 31.990 15.310 13.650 1.00 0.00 +ATOM 39 HB2 ASP 3 31.710 15.970 15.290 1.00 0.00 +ATOM 40 CG ASP 3 31.690 17.460 13.840 1.00 0.00 +ATOM 41 OD1 ASP 3 31.390 18.400 14.660 1.00 0.00 +ATOM 42 OD2 ASP 3 32.230 17.650 12.700 1.00 0.00 +ATOM 43 C ASP 3 29.350 16.300 12.880 1.00 0.00 +ATOM 44 O ASP 3 28.860 17.390 12.790 1.00 0.00 +ATOM 45 N GLU 4 29.370 15.470 11.800 1.00 0.00 +ATOM 46 H GLU 4 29.990 14.680 11.840 1.00 0.00 +ATOM 47 CA GLU 4 28.630 15.770 10.590 1.00 0.00 +ATOM 48 HA GLU 4 28.940 16.750 10.240 1.00 0.00 +ATOM 49 CB GLU 4 29.000 14.740 9.500 1.00 0.00 +ATOM 50 HB1 GLU 4 28.340 14.700 8.630 1.00 0.00 +ATOM 51 HB2 GLU 4 29.010 13.690 9.800 1.00 0.00 +ATOM 52 CG GLU 4 30.400 15.140 9.010 1.00 0.00 +ATOM 53 HG1 GLU 4 31.170 15.030 9.780 1.00 0.00 +ATOM 54 HG2 GLU 4 30.350 16.170 8.670 1.00 0.00 +ATOM 55 CD GLU 4 30.820 14.370 7.750 1.00 0.00 +ATOM 56 OE1 GLU 4 31.770 13.490 7.830 1.00 0.00 +ATOM 57 OE2 GLU 4 30.220 14.580 6.660 1.00 0.00 +ATOM 58 C GLU 4 27.080 15.870 10.880 1.00 0.00 +ATOM 59 O GLU 4 26.440 16.810 10.390 1.00 0.00 +ATOM 60 N ASP 5 26.570 14.980 11.720 1.00 0.00 +ATOM 61 H ASP 5 27.190 14.590 12.420 1.00 0.00 +ATOM 62 CA ASP 5 25.140 15.020 12.100 1.00 0.00 +ATOM 63 HA ASP 5 24.530 15.160 11.210 1.00 0.00 +ATOM 64 CB ASP 5 24.790 13.650 12.620 1.00 0.00 +ATOM 65 HB1 ASP 5 25.150 13.570 13.640 1.00 0.00 +ATOM 66 HB2 ASP 5 25.350 12.850 12.120 1.00 0.00 +ATOM 67 CG ASP 5 23.360 13.290 12.750 1.00 0.00 +ATOM 68 OD1 ASP 5 22.680 13.120 11.700 1.00 0.00 +ATOM 69 OD2 ASP 5 22.930 13.080 13.890 1.00 0.00 +ATOM 70 C ASP 5 24.670 16.170 13.020 1.00 0.00 +ATOM 71 O ASP 5 23.580 16.660 12.850 1.00 0.00 +ATOM 72 N PHE 6 25.600 16.840 13.760 1.00 0.00 +ATOM 73 H PHE 6 26.490 16.380 13.900 1.00 0.00 +ATOM 74 CA PHE 6 25.470 18.160 14.360 1.00 0.00 +ATOM 75 HA PHE 6 24.570 18.350 14.940 1.00 0.00 +ATOM 76 CB PHE 6 26.480 18.170 15.380 1.00 0.00 +ATOM 77 HB1 PHE 6 27.390 18.320 14.800 1.00 0.00 +ATOM 78 HB2 PHE 6 26.710 17.230 15.870 1.00 0.00 +ATOM 79 CG PHE 6 26.410 19.350 16.400 1.00 0.00 +ATOM 80 CD1 PHE 6 26.850 20.640 16.100 1.00 0.00 +ATOM 81 HD1 PHE 6 27.280 20.830 15.120 1.00 0.00 +ATOM 82 CE1 PHE 6 26.760 21.600 17.110 1.00 0.00 +ATOM 83 HE1 PHE 6 27.100 22.610 16.910 1.00 0.00 +ATOM 84 CZ PHE 6 26.260 21.270 18.370 1.00 0.00 +ATOM 85 HZ PHE 6 26.080 22.020 19.130 1.00 0.00 +ATOM 86 CE2 PHE 6 25.750 20.010 18.620 1.00 0.00 +ATOM 87 HE2 PHE 6 25.370 19.820 19.620 1.00 0.00 +ATOM 88 CD2 PHE 6 25.830 19.000 17.660 1.00 0.00 +ATOM 89 HD2 PHE 6 25.380 18.020 17.810 1.00 0.00 +ATOM 90 C PHE 6 25.620 19.370 13.340 1.00 0.00 +ATOM 91 O PHE 6 24.870 20.300 13.420 1.00 0.00 +ATOM 92 N LYS 7 26.430 19.210 12.250 1.00 0.00 +ATOM 93 H LYS 7 27.080 18.450 12.080 1.00 0.00 +ATOM 94 CA LYS 7 26.350 20.240 11.200 1.00 0.00 +ATOM 95 HA LYS 7 26.420 21.220 11.660 1.00 0.00 +ATOM 96 CB LYS 7 27.590 20.180 10.250 1.00 0.00 +ATOM 97 HB1 LYS 7 27.600 19.200 9.770 1.00 0.00 +ATOM 98 HB2 LYS 7 28.460 20.280 10.890 1.00 0.00 +ATOM 99 CG LYS 7 27.550 21.290 9.160 1.00 0.00 +ATOM 100 HG1 LYS 7 27.390 22.260 9.630 1.00 0.00 +ATOM 101 HG2 LYS 7 26.750 21.170 8.430 1.00 0.00 +ATOM 102 CD LYS 7 28.830 21.260 8.410 1.00 0.00 +ATOM 103 HD1 LYS 7 29.030 20.260 8.030 1.00 0.00 +ATOM 104 HD2 LYS 7 29.660 21.510 9.060 1.00 0.00 +ATOM 105 CE LYS 7 28.810 22.220 7.170 1.00 0.00 +ATOM 106 HE1 LYS 7 28.760 23.250 7.530 1.00 0.00 +ATOM 107 HE2 LYS 7 27.870 22.090 6.640 1.00 0.00 +ATOM 108 NZ LYS 7 30.070 22.190 6.360 1.00 0.00 +ATOM 109 HZ1 LYS 7 30.260 21.360 5.830 1.00 0.00 +ATOM 110 HZ2 LYS 7 30.070 22.930 5.670 1.00 0.00 +ATOM 111 HZ3 LYS 7 30.890 22.380 6.920 1.00 0.00 +ATOM 112 C LYS 7 25.020 20.190 10.320 1.00 0.00 +ATOM 113 O LYS 7 24.640 21.310 9.910 1.00 0.00 +ATOM 114 N ALA 8 24.390 19.060 10.210 1.00 0.00 +ATOM 115 H ALA 8 24.740 18.330 10.810 1.00 0.00 +ATOM 116 CA ALA 8 23.090 18.830 9.540 1.00 0.00 +ATOM 117 HA ALA 8 23.040 19.390 8.610 1.00 0.00 +ATOM 118 CB ALA 8 23.000 17.340 9.340 1.00 0.00 +ATOM 119 HB1 ALA 8 22.100 17.070 8.780 1.00 0.00 +ATOM 120 HB2 ALA 8 23.910 16.930 8.910 1.00 0.00 +ATOM 121 HB3 ALA 8 22.950 16.820 10.300 1.00 0.00 +ATOM 122 C ALA 8 21.910 19.340 10.440 1.00 0.00 +ATOM 123 O ALA 8 20.820 19.450 9.900 1.00 0.00 +ATOM 124 N VAL 9 22.090 19.930 11.670 1.00 0.00 +ATOM 125 H VAL 9 23.010 19.920 12.080 1.00 0.00 +ATOM 126 CA VAL 9 21.030 20.660 12.390 1.00 0.00 +ATOM 127 HA VAL 9 20.150 20.780 11.760 1.00 0.00 +ATOM 128 CB VAL 9 20.550 19.780 13.550 1.00 0.00 +ATOM 129 HB VAL 9 19.500 20.030 13.730 1.00 0.00 +ATOM 130 CG1 VAL 9 20.280 18.240 13.190 1.00 0.00 +ATOM 131 HG11 VAL 9 19.560 17.860 13.920 1.00 0.00 +ATOM 132 HG12 VAL 9 19.910 18.140 12.170 1.00 0.00 +ATOM 133 HG13 VAL 9 21.180 17.630 13.270 1.00 0.00 +ATOM 134 CG2 VAL 9 21.290 19.960 14.960 1.00 0.00 +ATOM 135 HG21 VAL 9 21.140 20.900 15.480 1.00 0.00 +ATOM 136 HG22 VAL 9 20.900 19.200 15.640 1.00 0.00 +ATOM 137 HG23 VAL 9 22.330 19.690 14.750 1.00 0.00 +ATOM 138 C VAL 9 21.380 22.070 12.940 1.00 0.00 +ATOM 139 O VAL 9 20.500 22.890 12.950 1.00 0.00 +ATOM 140 N PHE 10 22.650 22.460 13.220 1.00 0.00 +ATOM 141 H PHE 10 23.390 21.780 13.310 1.00 0.00 +ATOM 142 CA PHE 10 23.110 23.810 13.650 1.00 0.00 +ATOM 143 HA PHE 10 22.260 24.480 13.710 1.00 0.00 +ATOM 144 CB PHE 10 23.850 23.730 15.000 1.00 0.00 +ATOM 145 HB1 PHE 10 24.210 24.700 15.350 1.00 0.00 +ATOM 146 HB2 PHE 10 24.780 23.180 14.880 1.00 0.00 +ATOM 147 CG PHE 10 23.020 23.090 16.140 1.00 0.00 +ATOM 148 CD1 PHE 10 22.120 23.900 16.850 1.00 0.00 +ATOM 149 HD1 PHE 10 21.850 24.920 16.610 1.00 0.00 +ATOM 150 CE1 PHE 10 21.440 23.300 17.950 1.00 0.00 +ATOM 151 HE1 PHE 10 20.730 23.900 18.490 1.00 0.00 +ATOM 152 CZ PHE 10 21.680 22.000 18.310 1.00 0.00 +ATOM 153 HZ PHE 10 21.110 21.730 19.190 1.00 0.00 +ATOM 154 CE2 PHE 10 22.690 21.230 17.710 1.00 0.00 +ATOM 155 HE2 PHE 10 22.810 20.210 18.040 1.00 0.00 +ATOM 156 CD2 PHE 10 23.320 21.810 16.580 1.00 0.00 +ATOM 157 HD2 PHE 10 24.040 21.210 16.050 1.00 0.00 +ATOM 158 C PHE 10 24.090 24.490 12.680 1.00 0.00 +ATOM 159 O PHE 10 24.730 25.470 13.020 1.00 0.00 +ATOM 160 N GLY 11 24.320 23.980 11.440 1.00 0.00 +ATOM 161 H GLY 11 23.930 23.050 11.350 1.00 0.00 +ATOM 162 CA GLY 11 25.120 24.480 10.350 1.00 0.00 +ATOM 163 HA1 GLY 11 24.720 25.450 10.050 1.00 0.00 +ATOM 164 HA2 GLY 11 24.960 23.960 9.410 1.00 0.00 +ATOM 165 C GLY 11 26.600 24.710 10.670 1.00 0.00 +ATOM 166 O GLY 11 27.350 25.300 9.910 1.00 0.00 +ATOM 167 N MET 12 27.120 24.170 11.780 1.00 0.00 +ATOM 168 H MET 12 26.600 23.630 12.460 1.00 0.00 +ATOM 169 CA MET 12 28.510 24.310 12.260 1.00 0.00 +ATOM 170 HA MET 12 29.200 24.380 11.410 1.00 0.00 +ATOM 171 CB MET 12 28.600 25.580 13.100 1.00 0.00 +ATOM 172 HB1 MET 12 28.390 26.450 12.490 1.00 0.00 +ATOM 173 HB2 MET 12 29.620 25.650 13.480 1.00 0.00 +ATOM 174 CG MET 12 27.830 25.520 14.460 1.00 0.00 +ATOM 175 HG1 MET 12 28.110 24.600 14.970 1.00 0.00 +ATOM 176 HG2 MET 12 26.770 25.350 14.240 1.00 0.00 +ATOM 177 SD MET 12 27.930 27.010 15.450 1.00 0.00 +ATOM 178 CE MET 12 26.480 27.860 14.810 1.00 0.00 +ATOM 179 HE1 MET 12 25.670 27.190 14.550 1.00 0.00 +ATOM 180 HE2 MET 12 26.080 28.570 15.540 1.00 0.00 +ATOM 181 HE3 MET 12 26.900 28.350 13.930 1.00 0.00 +ATOM 182 C MET 12 28.920 23.030 12.900 1.00 0.00 +ATOM 183 O MET 12 28.140 22.200 13.370 1.00 0.00 +ATOM 184 N THR 13 30.230 22.850 13.100 1.00 0.00 +ATOM 185 H THR 13 30.910 23.590 12.990 1.00 0.00 +ATOM 186 CA THR 13 30.670 21.690 13.850 1.00 0.00 +ATOM 187 HA THR 13 30.220 20.780 13.450 1.00 0.00 +ATOM 188 CB THR 13 32.210 21.450 13.540 1.00 0.00 +ATOM 189 HB THR 13 32.460 20.580 14.150 1.00 0.00 +ATOM 190 CG2 THR 13 32.690 21.360 12.110 1.00 0.00 +ATOM 191 HG21 THR 13 32.090 20.540 11.710 1.00 0.00 +ATOM 192 HG22 THR 13 32.430 22.320 11.650 1.00 0.00 +ATOM 193 HG23 THR 13 33.750 21.160 11.940 1.00 0.00 +ATOM 194 OG1 THR 13 32.910 22.470 14.210 1.00 0.00 +ATOM 195 HG1 THR 13 33.770 22.530 13.790 1.00 0.00 +ATOM 196 C THR 13 30.390 21.760 15.390 1.00 0.00 +ATOM 197 O THR 13 30.110 22.770 15.950 1.00 0.00 +ATOM 198 N ARG 14 30.560 20.570 16.140 1.00 0.00 +ATOM 199 H ARG 14 30.620 19.750 15.550 1.00 0.00 +ATOM 200 CA ARG 14 30.490 20.500 17.620 1.00 0.00 +ATOM 201 HA ARG 14 29.500 20.670 18.040 1.00 0.00 +ATOM 202 CB ARG 14 30.730 19.040 18.120 1.00 0.00 +ATOM 203 HB1 ARG 14 30.860 19.150 19.200 1.00 0.00 +ATOM 204 HB2 ARG 14 31.670 18.630 17.750 1.00 0.00 +ATOM 205 CG ARG 14 29.640 17.950 17.800 1.00 0.00 +ATOM 206 HG1 ARG 14 29.290 17.880 16.770 1.00 0.00 +ATOM 207 HG2 ARG 14 28.720 18.130 18.360 1.00 0.00 +ATOM 208 CD ARG 14 30.180 16.560 18.210 1.00 0.00 +ATOM 209 HD1 ARG 14 31.130 16.420 17.700 1.00 0.00 +ATOM 210 HD2 ARG 14 29.530 15.790 17.790 1.00 0.00 +ATOM 211 NE ARG 14 30.380 16.350 19.640 1.00 0.00 +ATOM 212 HE ARG 14 31.110 16.910 20.070 1.00 0.00 +ATOM 213 CZ ARG 14 29.800 15.530 20.520 1.00 0.00 +ATOM 214 NH1 ARG 14 28.860 14.690 20.160 1.00 0.00 +ATOM 215 HH11 ARG 14 28.640 14.630 19.180 1.00 0.00 +ATOM 216 HH12 ARG 14 28.250 14.330 20.890 1.00 0.00 +ATOM 217 NH2 ARG 14 30.050 15.570 21.760 1.00 0.00 +ATOM 218 HH21 ARG 14 30.670 16.250 22.180 1.00 0.00 +ATOM 219 HH22 ARG 14 29.540 14.940 22.360 1.00 0.00 +ATOM 220 C ARG 14 31.620 21.360 18.310 1.00 0.00 +ATOM 221 O ARG 14 31.550 21.680 19.480 1.00 0.00 +ATOM 222 N SER 15 32.680 21.520 17.550 1.00 0.00 +ATOM 223 H SER 15 32.720 21.110 16.630 1.00 0.00 +ATOM 224 CA SER 15 33.830 22.370 17.950 1.00 0.00 +ATOM 225 HA SER 15 34.120 22.140 18.980 1.00 0.00 +ATOM 226 CB SER 15 35.040 21.980 17.150 1.00 0.00 +ATOM 227 HB1 SER 15 35.960 22.430 17.530 1.00 0.00 +ATOM 228 HB2 SER 15 34.880 22.250 16.100 1.00 0.00 +ATOM 229 OG SER 15 35.290 20.600 17.350 1.00 0.00 +ATOM 230 HG SER 15 34.650 20.120 16.820 1.00 0.00 +ATOM 231 C SER 15 33.520 23.880 17.840 1.00 0.00 +ATOM 232 O SER 15 33.720 24.610 18.820 1.00 0.00 +ATOM 233 N ALA 16 32.920 24.400 16.750 1.00 0.00 +ATOM 234 H ALA 16 32.800 23.860 15.910 1.00 0.00 +ATOM 235 CA ALA 16 32.590 25.790 16.590 1.00 0.00 +ATOM 236 HA ALA 16 33.510 26.310 16.870 1.00 0.00 +ATOM 237 CB ALA 16 32.410 25.920 15.160 1.00 0.00 +ATOM 238 HB1 ALA 16 31.970 26.910 15.020 1.00 0.00 +ATOM 239 HB2 ALA 16 33.340 25.740 14.620 1.00 0.00 +ATOM 240 HB3 ALA 16 31.700 25.130 14.910 1.00 0.00 +ATOM 241 C ALA 16 31.400 26.250 17.480 1.00 0.00 +ATOM 242 O ALA 16 31.390 27.340 17.970 1.00 0.00 +ATOM 243 N PHE 17 30.480 25.400 17.800 1.00 0.00 +ATOM 244 H PHE 17 30.350 24.570 17.240 1.00 0.00 +ATOM 245 CA PHE 17 29.320 25.640 18.720 1.00 0.00 +ATOM 246 HA PHE 17 28.780 26.550 18.480 1.00 0.00 +ATOM 247 CB PHE 17 28.440 24.370 18.650 1.00 0.00 +ATOM 248 HB1 PHE 17 29.000 23.610 19.200 1.00 0.00 +ATOM 249 HB2 PHE 17 28.370 24.060 17.610 1.00 0.00 +ATOM 250 CG PHE 17 27.090 24.410 19.310 1.00 0.00 +ATOM 251 CD1 PHE 17 26.950 24.020 20.660 1.00 0.00 +ATOM 252 HD1 PHE 17 27.830 23.730 21.220 1.00 0.00 +ATOM 253 CE1 PHE 17 25.730 24.190 21.320 1.00 0.00 +ATOM 254 HE1 PHE 17 25.670 23.980 22.380 1.00 0.00 +ATOM 255 CZ PHE 17 24.580 24.480 20.590 1.00 0.00 +ATOM 256 HZ PHE 17 23.590 24.520 21.020 1.00 0.00 +ATOM 257 CE2 PHE 17 24.640 24.790 19.210 1.00 0.00 +ATOM 258 HE2 PHE 17 23.750 25.060 18.670 1.00 0.00 +ATOM 259 CD2 PHE 17 25.890 24.780 18.550 1.00 0.00 +ATOM 260 HD2 PHE 17 26.040 24.990 17.500 1.00 0.00 +ATOM 261 C PHE 17 29.930 25.860 20.160 1.00 0.00 +ATOM 262 O PHE 17 29.410 26.700 20.810 1.00 0.00 +ATOM 263 N ALA 18 31.000 25.170 20.570 1.00 0.00 +ATOM 264 H ALA 18 31.470 24.630 19.870 1.00 0.00 +ATOM 265 CA ALA 18 31.700 25.540 21.790 1.00 0.00 +ATOM 266 HA ALA 18 30.860 25.430 22.470 1.00 0.00 +ATOM 267 CB ALA 18 32.760 24.430 22.070 1.00 0.00 +ATOM 268 HB1 ALA 18 32.270 23.490 22.290 1.00 0.00 +ATOM 269 HB2 ALA 18 33.310 24.220 21.150 1.00 0.00 +ATOM 270 HB3 ALA 18 33.510 24.670 22.830 1.00 0.00 +ATOM 271 C ALA 18 32.360 26.950 21.850 1.00 0.00 +ATOM 272 O ALA 18 32.910 27.300 22.880 1.00 0.00 +ATOM 273 N ASN 19 32.250 27.780 20.760 1.00 0.00 +ATOM 274 H ASN 19 32.040 27.380 19.850 1.00 0.00 +ATOM 275 CA ASN 19 32.580 29.190 20.730 1.00 0.00 +ATOM 276 HA ASN 19 33.310 29.440 21.500 1.00 0.00 +ATOM 277 CB ASN 19 33.200 29.520 19.340 1.00 0.00 +ATOM 278 HB1 ASN 19 32.380 29.820 18.680 1.00 0.00 +ATOM 279 HB2 ASN 19 33.710 28.660 18.920 1.00 0.00 +ATOM 280 CG ASN 19 34.140 30.800 19.370 1.00 0.00 +ATOM 281 OD1 ASN 19 34.630 31.200 20.390 1.00 0.00 +ATOM 282 ND2 ASN 19 34.240 31.500 18.290 1.00 0.00 +ATOM 283 HD21 ASN 19 33.890 31.130 17.420 1.00 0.00 +ATOM 284 HD22 ASN 19 35.070 32.070 18.210 1.00 0.00 +ATOM 285 C ASN 19 31.390 30.050 21.120 1.00 0.00 +ATOM 286 O ASN 19 31.590 31.260 21.430 1.00 0.00 +ATOM 287 N LEU 20 30.160 29.450 21.110 1.00 0.00 +ATOM 288 H LEU 20 30.120 28.440 21.040 1.00 0.00 +ATOM 289 CA LEU 20 29.030 30.240 21.590 1.00 0.00 +ATOM 290 HA LEU 20 29.200 31.170 21.050 1.00 0.00 +ATOM 291 CB LEU 20 27.740 29.610 21.010 1.00 0.00 +ATOM 292 HB1 LEU 20 26.860 30.250 21.130 1.00 0.00 +ATOM 293 HB2 LEU 20 27.570 28.610 21.400 1.00 0.00 +ATOM 294 CG LEU 20 27.770 29.580 19.440 1.00 0.00 +ATOM 295 HG LEU 20 28.680 29.100 19.100 1.00 0.00 +ATOM 296 CD1 LEU 20 26.630 28.720 18.880 1.00 0.00 +ATOM 297 HD11 LEU 20 25.710 29.210 19.180 1.00 0.00 +ATOM 298 HD12 LEU 20 26.660 28.680 17.790 1.00 0.00 +ATOM 299 HD13 LEU 20 26.620 27.710 19.290 1.00 0.00 +ATOM 300 CD2 LEU 20 27.520 30.990 18.930 1.00 0.00 +ATOM 301 HD21 LEU 20 28.230 31.750 19.240 1.00 0.00 +ATOM 302 HD22 LEU 20 27.530 30.880 17.850 1.00 0.00 +ATOM 303 HD23 LEU 20 26.500 31.320 19.140 1.00 0.00 +ATOM 304 C LEU 20 29.030 30.440 23.090 1.00 0.00 +ATOM 305 O LEU 20 29.610 29.530 23.740 1.00 0.00 +ATOM 306 N PRO 21 28.430 31.520 23.630 1.00 0.00 +ATOM 307 CD PRO 21 28.120 32.700 22.880 1.00 0.00 +ATOM 308 HD1 PRO 21 27.330 32.480 22.160 1.00 0.00 +ATOM 309 HD2 PRO 21 29.010 33.070 22.360 1.00 0.00 +ATOM 310 CG PRO 21 27.600 33.700 23.980 1.00 0.00 +ATOM 311 HG1 PRO 21 26.770 34.290 23.600 1.00 0.00 +ATOM 312 HG2 PRO 21 28.410 34.370 24.270 1.00 0.00 +ATOM 313 CB PRO 21 27.200 32.830 25.210 1.00 0.00 +ATOM 314 HB1 PRO 21 26.120 32.680 25.140 1.00 0.00 +ATOM 315 HB2 PRO 21 27.330 33.340 26.170 1.00 0.00 +ATOM 316 CA PRO 21 28.080 31.630 25.100 1.00 0.00 +ATOM 317 HA PRO 21 29.010 31.800 25.640 1.00 0.00 +ATOM 318 C PRO 21 27.390 30.360 25.700 1.00 0.00 +ATOM 319 O PRO 21 26.570 29.680 25.070 1.00 0.00 +ATOM 320 N LEU 22 27.510 30.170 27.000 1.00 0.00 +ATOM 321 H LEU 22 28.050 30.840 27.540 1.00 0.00 +ATOM 322 CA LEU 22 27.040 28.930 27.670 1.00 0.00 +ATOM 323 HA LEU 22 27.480 28.190 26.990 1.00 0.00 +ATOM 324 CB LEU 22 27.730 28.790 29.070 1.00 0.00 +ATOM 325 HB1 LEU 22 27.090 28.040 29.540 1.00 0.00 +ATOM 326 HB2 LEU 22 27.580 29.720 29.600 1.00 0.00 +ATOM 327 CG LEU 22 29.200 28.220 28.980 1.00 0.00 +ATOM 328 HG LEU 22 29.620 28.770 28.150 1.00 0.00 +ATOM 329 CD1 LEU 22 29.930 28.390 30.270 1.00 0.00 +ATOM 330 HD11 LEU 22 30.960 28.050 30.210 1.00 0.00 +ATOM 331 HD12 LEU 22 29.850 29.460 30.460 1.00 0.00 +ATOM 332 HD13 LEU 22 29.380 27.820 31.020 1.00 0.00 +ATOM 333 CD2 LEU 22 29.260 26.710 28.650 1.00 0.00 +ATOM 334 HD21 LEU 22 28.670 26.400 27.790 1.00 0.00 +ATOM 335 HD22 LEU 22 30.290 26.420 28.410 1.00 0.00 +ATOM 336 HD23 LEU 22 28.880 26.080 29.450 1.00 0.00 +ATOM 337 C LEU 22 25.510 28.810 27.760 1.00 0.00 +ATOM 338 O LEU 22 24.990 27.720 27.350 1.00 0.00 +ATOM 339 N TRP 23 24.810 29.910 28.070 1.00 0.00 +ATOM 340 H TRP 23 25.440 30.630 28.390 1.00 0.00 +ATOM 341 CA TRP 23 23.330 30.060 28.050 1.00 0.00 +ATOM 342 HA TRP 23 22.930 29.250 28.670 1.00 0.00 +ATOM 343 CB TRP 23 22.920 31.330 28.720 1.00 0.00 +ATOM 344 HB1 TRP 23 23.270 31.260 29.750 1.00 0.00 +ATOM 345 HB2 TRP 23 21.840 31.270 28.620 1.00 0.00 +ATOM 346 CG TRP 23 23.470 32.610 28.060 1.00 0.00 +ATOM 347 CD1 TRP 23 24.720 33.180 28.180 1.00 0.00 +ATOM 348 HD1 TRP 23 25.450 33.080 28.960 1.00 0.00 +ATOM 349 NE1 TRP 23 24.830 34.280 27.300 1.00 0.00 +ATOM 350 HE1 TRP 23 25.500 35.030 27.350 1.00 0.00 +ATOM 351 CE2 TRP 23 23.760 34.270 26.420 1.00 0.00 +ATOM 352 CZ2 TRP 23 23.440 35.030 25.320 1.00 0.00 +ATOM 353 HZ2 TRP 23 24.100 35.840 25.050 1.00 0.00 +ATOM 354 CH2 TRP 23 22.300 34.700 24.540 1.00 0.00 +ATOM 355 HH2 TRP 23 22.000 35.310 23.700 1.00 0.00 +ATOM 356 CZ3 TRP 23 21.410 33.780 25.030 1.00 0.00 +ATOM 357 HZ3 TRP 23 20.540 33.440 24.500 1.00 0.00 +ATOM 358 CE3 TRP 23 21.680 33.060 26.260 1.00 0.00 +ATOM 359 HE3 TRP 23 20.890 32.420 26.620 1.00 0.00 +ATOM 360 CD2 TRP 23 22.890 33.260 26.960 1.00 0.00 +ATOM 361 C TRP 23 22.680 29.870 26.660 1.00 0.00 +ATOM 362 O TRP 23 21.570 29.320 26.550 1.00 0.00 +ATOM 363 N LYS 24 23.490 30.310 25.670 1.00 0.00 +ATOM 364 H LYS 24 24.400 30.730 25.820 1.00 0.00 +ATOM 365 CA LYS 24 23.070 30.340 24.230 1.00 0.00 +ATOM 366 HA LYS 24 22.020 30.630 24.160 1.00 0.00 +ATOM 367 CB LYS 24 24.020 31.290 23.450 1.00 0.00 +ATOM 368 HB1 LYS 24 25.030 30.900 23.440 1.00 0.00 +ATOM 369 HB2 LYS 24 23.980 32.240 23.980 1.00 0.00 +ATOM 370 CG LYS 24 23.620 31.490 21.930 1.00 0.00 +ATOM 371 HG1 LYS 24 22.560 31.720 22.020 1.00 0.00 +ATOM 372 HG2 LYS 24 23.740 30.660 21.240 1.00 0.00 +ATOM 373 CD LYS 24 24.400 32.660 21.400 1.00 0.00 +ATOM 374 HD1 LYS 24 25.460 32.420 21.310 1.00 0.00 +ATOM 375 HD2 LYS 24 24.260 33.570 21.980 1.00 0.00 +ATOM 376 CE LYS 24 23.930 32.930 19.940 1.00 0.00 +ATOM 377 HE1 LYS 24 22.840 32.840 19.950 1.00 0.00 +ATOM 378 HE2 LYS 24 24.360 32.240 19.230 1.00 0.00 +ATOM 379 NZ LYS 24 24.320 34.280 19.630 1.00 0.00 +ATOM 380 HZ1 LYS 24 23.760 35.060 19.950 1.00 0.00 +ATOM 381 HZ2 LYS 24 25.260 34.490 19.920 1.00 0.00 +ATOM 382 HZ3 LYS 24 24.420 34.340 18.630 1.00 0.00 +ATOM 383 C LYS 24 23.100 28.910 23.620 1.00 0.00 +ATOM 384 O LYS 24 22.110 28.490 23.020 1.00 0.00 +ATOM 385 N GLN 25 24.150 28.170 23.940 1.00 0.00 +ATOM 386 H GLN 25 24.870 28.580 24.510 1.00 0.00 +ATOM 387 CA GLN 25 24.330 26.780 23.620 1.00 0.00 +ATOM 388 HA GLN 25 24.270 26.500 22.570 1.00 0.00 +ATOM 389 CB GLN 25 25.720 26.370 24.160 1.00 0.00 +ATOM 390 HB1 GLN 25 25.690 25.280 24.210 1.00 0.00 +ATOM 391 HB2 GLN 25 25.830 26.660 25.210 1.00 0.00 +ATOM 392 CG GLN 25 26.890 26.740 23.320 1.00 0.00 +ATOM 393 HG1 GLN 25 26.970 27.820 23.380 1.00 0.00 +ATOM 394 HG2 GLN 25 26.730 26.440 22.280 1.00 0.00 +ATOM 395 CD GLN 25 28.210 26.040 23.700 1.00 0.00 +ATOM 396 OE1 GLN 25 28.280 24.780 23.540 1.00 0.00 +ATOM 397 NE2 GLN 25 29.310 26.730 24.030 1.00 0.00 +ATOM 398 HE21 GLN 25 29.270 27.740 24.080 1.00 0.00 +ATOM 399 HE22 GLN 25 30.200 26.310 24.270 1.00 0.00 +ATOM 400 C GLN 25 23.210 25.850 24.120 1.00 0.00 +ATOM 401 O GLN 25 22.640 25.060 23.340 1.00 0.00 +ATOM 402 N GLN 26 22.840 26.110 25.370 1.00 0.00 +ATOM 403 H GLN 26 23.280 26.800 25.950 1.00 0.00 +ATOM 404 CA GLN 26 21.840 25.370 26.070 1.00 0.00 +ATOM 405 HA GLN 26 22.000 24.290 26.010 1.00 0.00 +ATOM 406 CB GLN 26 21.890 25.730 27.600 1.00 0.00 +ATOM 407 HB1 GLN 26 21.620 26.770 27.800 1.00 0.00 +ATOM 408 HB2 GLN 26 22.880 25.490 27.970 1.00 0.00 +ATOM 409 CG GLN 26 20.870 24.860 28.400 1.00 0.00 +ATOM 410 HG1 GLN 26 21.120 23.800 28.360 1.00 0.00 +ATOM 411 HG2 GLN 26 19.810 24.990 28.180 1.00 0.00 +ATOM 412 CD GLN 26 20.860 25.290 29.920 1.00 0.00 +ATOM 413 OE1 GLN 26 21.390 26.340 30.220 1.00 0.00 +ATOM 414 NE2 GLN 26 20.380 24.530 30.880 1.00 0.00 +ATOM 415 HE21 GLN 26 20.140 23.570 30.680 1.00 0.00 +ATOM 416 HE22 GLN 26 20.510 24.800 31.840 1.00 0.00 +ATOM 417 C GLN 26 20.380 25.660 25.480 1.00 0.00 +ATOM 418 O GLN 26 19.500 24.790 25.320 1.00 0.00 +ATOM 419 N HIE 27 20.200 26.880 25.100 1.00 0.00 +ATOM 420 H HIE 27 20.880 27.520 25.460 1.00 0.00 +ATOM 421 CA HIE 27 19.030 27.350 24.390 1.00 0.00 +ATOM 422 HA HIE 27 18.100 27.030 24.860 1.00 0.00 +ATOM 423 CB HIE 27 18.890 28.910 24.330 1.00 0.00 +ATOM 424 HB1 HIE 27 19.530 29.300 23.540 1.00 0.00 +ATOM 425 HB2 HIE 27 19.220 29.230 25.320 1.00 0.00 +ATOM 426 CG HIE 27 17.460 29.450 24.210 1.00 0.00 +ATOM 427 ND1 HIE 27 16.950 29.590 22.910 1.00 0.00 +ATOM 428 CE1 HIE 27 15.740 30.100 23.120 1.00 0.00 +ATOM 429 HE1 HIE 27 15.040 30.380 22.350 1.00 0.00 +ATOM 430 NE2 HIE 27 15.600 30.380 24.460 1.00 0.00 +ATOM 431 HE2 HIE 27 14.770 30.850 24.790 1.00 0.00 +ATOM 432 CD2 HIE 27 16.630 29.840 25.130 1.00 0.00 +ATOM 433 HD2 HIE 27 16.900 30.000 26.170 1.00 0.00 +ATOM 434 C HIE 27 18.840 26.700 23.030 1.00 0.00 +ATOM 435 O HIE 27 17.820 26.010 22.810 1.00 0.00 +ATOM 436 N LEU 28 19.910 26.650 22.270 1.00 0.00 +ATOM 437 H LEU 28 20.670 27.270 22.530 1.00 0.00 +ATOM 438 CA LEU 28 19.930 25.950 20.950 1.00 0.00 +ATOM 439 HA LEU 28 19.000 26.250 20.470 1.00 0.00 +ATOM 440 CB LEU 28 21.260 26.290 20.180 1.00 0.00 +ATOM 441 HB1 LEU 28 21.340 25.610 19.330 1.00 0.00 +ATOM 442 HB2 LEU 28 22.080 26.170 20.890 1.00 0.00 +ATOM 443 CG LEU 28 21.300 27.760 19.630 1.00 0.00 +ATOM 444 HG LEU 28 20.860 28.460 20.330 1.00 0.00 +ATOM 445 CD1 LEU 28 22.750 28.140 19.230 1.00 0.00 +ATOM 446 HD11 LEU 28 23.470 27.860 20.000 1.00 0.00 +ATOM 447 HD12 LEU 28 23.070 27.710 18.280 1.00 0.00 +ATOM 448 HD13 LEU 28 22.870 29.230 19.190 1.00 0.00 +ATOM 449 CD2 LEU 28 20.460 27.740 18.320 1.00 0.00 +ATOM 450 HD21 LEU 28 19.490 27.290 18.510 1.00 0.00 +ATOM 451 HD22 LEU 28 20.490 28.750 17.920 1.00 0.00 +ATOM 452 HD23 LEU 28 21.040 27.140 17.620 1.00 0.00 +ATOM 453 C LEU 28 19.850 24.430 21.140 1.00 0.00 +ATOM 454 O LEU 28 19.040 23.870 20.390 1.00 0.00 +ATOM 455 N LYS 29 20.460 23.850 22.130 1.00 0.00 +ATOM 456 H LYS 29 21.220 24.340 22.580 1.00 0.00 +ATOM 457 CA LYS 29 20.140 22.390 22.350 1.00 0.00 +ATOM 458 HA LYS 29 20.340 21.740 21.500 1.00 0.00 +ATOM 459 CB LYS 29 21.120 22.030 23.510 1.00 0.00 +ATOM 460 HB1 LYS 29 20.840 21.100 24.010 1.00 0.00 +ATOM 461 HB2 LYS 29 21.150 22.820 24.260 1.00 0.00 +ATOM 462 CG LYS 29 22.510 21.730 22.890 1.00 0.00 +ATOM 463 HG1 LYS 29 22.930 22.670 22.520 1.00 0.00 +ATOM 464 HG2 LYS 29 22.330 20.980 22.120 1.00 0.00 +ATOM 465 CD LYS 29 23.430 21.220 24.020 1.00 0.00 +ATOM 466 HD1 LYS 29 23.010 20.560 24.770 1.00 0.00 +ATOM 467 HD2 LYS 29 23.970 22.030 24.500 1.00 0.00 +ATOM 468 CE LYS 29 24.340 20.350 23.170 1.00 0.00 +ATOM 469 HE1 LYS 29 24.900 20.890 22.410 1.00 0.00 +ATOM 470 HE2 LYS 29 23.770 19.520 22.750 1.00 0.00 +ATOM 471 NZ LYS 29 25.330 19.670 24.080 1.00 0.00 +ATOM 472 HZ1 LYS 29 25.810 20.360 24.640 1.00 0.00 +ATOM 473 HZ2 LYS 29 24.930 19.060 24.780 1.00 0.00 +ATOM 474 HZ3 LYS 29 26.020 19.110 23.610 1.00 0.00 +ATOM 475 C LYS 29 18.700 22.080 22.820 1.00 0.00 +ATOM 476 O LYS 29 18.130 21.120 22.200 1.00 0.00 +ATOM 477 N LYS 30 18.180 22.840 23.850 1.00 0.00 +ATOM 478 H LYS 30 18.670 23.610 24.290 1.00 0.00 +ATOM 479 CA LYS 30 16.820 22.470 24.420 1.00 0.00 +ATOM 480 HA LYS 30 16.720 21.440 24.770 1.00 0.00 +ATOM 481 CB LYS 30 16.460 23.520 25.580 1.00 0.00 +ATOM 482 HB1 LYS 30 15.400 23.780 25.570 1.00 0.00 +ATOM 483 HB2 LYS 30 16.990 24.440 25.330 1.00 0.00 +ATOM 484 CG LYS 30 17.030 23.010 26.870 1.00 0.00 +ATOM 485 HG1 LYS 30 18.100 23.010 27.060 1.00 0.00 +ATOM 486 HG2 LYS 30 16.800 21.980 27.130 1.00 0.00 +ATOM 487 CD LYS 30 16.410 24.010 27.910 1.00 0.00 +ATOM 488 HD1 LYS 30 15.320 24.060 28.000 1.00 0.00 +ATOM 489 HD2 LYS 30 16.740 25.010 27.630 1.00 0.00 +ATOM 490 CE LYS 30 17.010 23.770 29.350 1.00 0.00 +ATOM 491 HE1 LYS 30 18.030 23.490 29.090 1.00 0.00 +ATOM 492 HE2 LYS 30 16.560 22.910 29.850 1.00 0.00 +ATOM 493 NZ LYS 30 16.890 24.960 30.280 1.00 0.00 +ATOM 494 HZ1 LYS 30 17.500 25.700 29.950 1.00 0.00 +ATOM 495 HZ2 LYS 30 15.960 25.310 30.450 1.00 0.00 +ATOM 496 HZ3 LYS 30 17.150 24.650 31.210 1.00 0.00 +ATOM 497 C LYS 30 15.730 22.520 23.310 1.00 0.00 +ATOM 498 O LYS 30 14.820 21.670 23.240 1.00 0.00 +ATOM 499 N GLU 31 15.820 23.560 22.440 1.00 0.00 +ATOM 500 H GLU 31 16.650 24.130 22.540 1.00 0.00 +ATOM 501 CA GLU 31 14.910 23.730 21.290 1.00 0.00 +ATOM 502 HA GLU 31 13.900 23.880 21.670 1.00 0.00 +ATOM 503 CB GLU 31 15.410 24.840 20.340 1.00 0.00 +ATOM 504 HB1 GLU 31 15.320 24.500 19.310 1.00 0.00 +ATOM 505 HB2 GLU 31 16.450 24.950 20.650 1.00 0.00 +ATOM 506 CG GLU 31 14.680 26.160 20.340 1.00 0.00 +ATOM 507 HG1 GLU 31 14.560 26.560 21.350 1.00 0.00 +ATOM 508 HG2 GLU 31 13.690 25.930 19.950 1.00 0.00 +ATOM 509 CD GLU 31 15.240 27.310 19.490 1.00 0.00 +ATOM 510 OE1 GLU 31 16.480 27.380 19.240 1.00 0.00 +ATOM 511 OE2 GLU 31 14.400 28.150 19.120 1.00 0.00 +ATOM 512 C GLU 31 14.850 22.470 20.410 1.00 0.00 +ATOM 513 O GLU 31 13.870 22.160 19.670 1.00 0.00 +ATOM 514 N LYS 32 15.930 21.650 20.380 1.00 0.00 +ATOM 515 H LYS 32 16.700 21.910 20.980 1.00 0.00 +ATOM 516 CA LYS 32 16.150 20.490 19.560 1.00 0.00 +ATOM 517 HA LYS 32 15.420 20.400 18.760 1.00 0.00 +ATOM 518 CB LYS 32 17.500 20.670 18.850 1.00 0.00 +ATOM 519 HB1 LYS 32 17.670 19.780 18.250 1.00 0.00 +ATOM 520 HB2 LYS 32 18.170 20.680 19.710 1.00 0.00 +ATOM 521 CG LYS 32 17.740 21.920 17.970 1.00 0.00 +ATOM 522 HG1 LYS 32 18.540 22.510 18.410 1.00 0.00 +ATOM 523 HG2 LYS 32 16.860 22.540 17.780 1.00 0.00 +ATOM 524 CD LYS 32 18.240 21.440 16.610 1.00 0.00 +ATOM 525 HD1 LYS 32 17.400 20.980 16.100 1.00 0.00 +ATOM 526 HD2 LYS 32 18.990 20.670 16.780 1.00 0.00 +ATOM 527 CE LYS 32 18.870 22.580 15.720 1.00 0.00 +ATOM 528 HE1 LYS 32 19.050 22.240 14.700 1.00 0.00 +ATOM 529 HE2 LYS 32 19.860 22.790 16.140 1.00 0.00 +ATOM 530 NZ LYS 32 18.130 23.860 15.560 1.00 0.00 +ATOM 531 HZ1 LYS 32 18.010 24.160 16.520 1.00 0.00 +ATOM 532 HZ2 LYS 32 18.670 24.600 15.120 1.00 0.00 +ATOM 533 HZ3 LYS 32 17.270 23.700 15.050 1.00 0.00 +ATOM 534 C LYS 32 16.190 19.130 20.380 1.00 0.00 +ATOM 535 O LYS 32 16.320 18.010 19.920 1.00 0.00 +ATOM 536 N GLY 33 15.890 19.230 21.680 1.00 0.00 +ATOM 537 H GLY 33 15.660 20.160 21.990 1.00 0.00 +ATOM 538 CA GLY 33 15.790 18.160 22.770 1.00 0.00 +ATOM 539 HA1 GLY 33 15.030 17.470 22.400 1.00 0.00 +ATOM 540 HA2 GLY 33 15.370 18.610 23.660 1.00 0.00 +ATOM 541 C GLY 33 17.110 17.460 23.130 1.00 0.00 +ATOM 542 O GLY 33 17.130 16.340 23.630 1.00 0.00 +ATOM 543 N LEU 34 18.170 18.200 22.890 1.00 0.00 +ATOM 544 H LEU 34 18.100 19.170 22.630 1.00 0.00 +ATOM 545 CA LEU 34 19.530 17.730 23.240 1.00 0.00 +ATOM 546 HA LEU 34 19.540 16.640 23.310 1.00 0.00 +ATOM 547 CB LEU 34 20.410 18.270 22.110 1.00 0.00 +ATOM 548 HB1 LEU 34 21.430 17.900 22.250 1.00 0.00 +ATOM 549 HB2 LEU 34 20.300 19.350 22.180 1.00 0.00 +ATOM 550 CG LEU 34 20.020 17.830 20.700 1.00 0.00 +ATOM 551 HG LEU 34 18.990 18.120 20.480 1.00 0.00 +ATOM 552 CD1 LEU 34 20.790 18.790 19.770 1.00 0.00 +ATOM 553 HD11 LEU 34 21.870 18.660 19.900 1.00 0.00 +ATOM 554 HD12 LEU 34 20.520 18.380 18.800 1.00 0.00 +ATOM 555 HD13 LEU 34 20.260 19.740 19.720 1.00 0.00 +ATOM 556 CD2 LEU 34 20.250 16.440 20.410 1.00 0.00 +ATOM 557 HD21 LEU 34 21.320 16.270 20.520 1.00 0.00 +ATOM 558 HD22 LEU 34 19.710 15.810 21.120 1.00 0.00 +ATOM 559 HD23 LEU 34 19.980 16.250 19.370 1.00 0.00 +ATOM 560 C LEU 34 19.970 18.260 24.580 1.00 0.00 +ATOM 561 O LEU 34 19.290 19.080 25.150 1.00 0.00 +ATOM 562 N PHE 35 21.120 17.820 25.110 1.00 0.00 +ATOM 563 H PHE 35 21.610 17.120 24.560 1.00 0.00 +ATOM 564 CA PHE 35 21.560 18.070 26.550 1.00 0.00 +ATOM 565 HA PHE 35 21.100 18.980 26.910 1.00 0.00 +ATOM 566 CB PHE 35 21.040 16.890 27.330 1.00 0.00 +ATOM 567 HB1 PHE 35 21.700 16.730 28.180 1.00 0.00 +ATOM 568 HB2 PHE 35 21.110 15.930 26.830 1.00 0.00 +ATOM 569 CG PHE 35 19.600 17.170 27.950 1.00 0.00 +ATOM 570 CD1 PHE 35 19.570 18.220 28.890 1.00 0.00 +ATOM 571 HD1 PHE 35 20.560 18.510 29.210 1.00 0.00 +ATOM 572 CE1 PHE 35 18.350 18.460 29.670 1.00 0.00 +ATOM 573 HE1 PHE 35 18.180 19.220 30.420 1.00 0.00 +ATOM 574 CZ PHE 35 17.180 17.760 29.310 1.00 0.00 +ATOM 575 HZ PHE 35 16.240 17.970 29.800 1.00 0.00 +ATOM 576 CE2 PHE 35 17.290 16.690 28.410 1.00 0.00 +ATOM 577 HE2 PHE 35 16.400 16.130 28.180 1.00 0.00 +ATOM 578 CD2 PHE 35 18.480 16.360 27.770 1.00 0.00 +ATOM 579 HD2 PHE 35 18.640 15.580 27.040 1.00 0.00 +ATOM 580 C PHE 35 23.080 18.240 26.560 1.00 0.00 +ATOM 581 OC1 PHE 35 23.760 17.900 25.550 1.00 0.00 +ATOM 582 OC2 PHE 35 23.640 18.940 27.480 1.00 0.00 +ATOM 583 Cl Cl 36 21.000 38.550 5.130 1.00 0.00 +ATOM 584 Cl Cl 37 23.430 12.390 29.810 1.00 0.00 +ATOM 585 OW HOH 38 42.690 33.950 28.530 1.00 0.00 +ATOM 586 HW1 HOH 38 41.750 34.120 28.550 1.00 0.00 +ATOM 587 HW2 HOH 38 42.890 33.660 29.420 1.00 0.00 +ATOM 588 OW HOH 39 2.030 3.230 18.140 1.00 0.00 +ATOM 589 HW1 HOH 39 2.710 2.960 18.750 1.00 0.00 +ATOM 590 HW2 HOH 39 1.240 2.790 18.450 1.00 0.00 +ATOM 591 OW HOH 40 36.100 12.320 26.220 1.00 0.00 +ATOM 592 HW1 HOH 40 36.950 12.230 25.770 1.00 0.00 +ATOM 593 HW2 HOH 40 35.490 11.850 25.660 1.00 0.00 +ATOM 594 OW HOH 41 34.950 19.480 25.010 1.00 0.00 +ATOM 595 HW1 HOH 41 34.710 20.010 24.250 1.00 0.00 +ATOM 596 HW2 HOH 41 34.860 20.070 25.760 1.00 0.00 +ATOM 597 OW HOH 42 11.800 5.760 34.580 1.00 0.00 +ATOM 598 HW1 HOH 42 11.610 4.980 35.100 1.00 0.00 +ATOM 599 HW2 HOH 42 12.750 5.890 34.670 1.00 0.00 +ATOM 600 OW HOH 43 16.850 25.480 33.290 1.00 0.00 +ATOM 601 HW1 HOH 43 17.550 25.560 33.930 1.00 0.00 +ATOM 602 HW2 HOH 43 16.440 26.340 33.260 1.00 0.00 +ATOM 603 OW HOH 44 11.560 17.740 30.520 1.00 0.00 +ATOM 604 HW1 HOH 44 12.030 17.590 31.340 1.00 0.00 +ATOM 605 HW2 HOH 44 10.670 17.970 30.790 1.00 0.00 +ATOM 606 OW HOH 45 5.930 28.700 11.270 1.00 0.00 +ATOM 607 HW1 HOH 45 6.130 28.600 12.200 1.00 0.00 +ATOM 608 HW2 HOH 45 6.670 28.280 10.820 1.00 0.00 +ATOM 609 OW HOH 46 47.120 37.740 2.820 1.00 0.00 +ATOM 610 HW1 HOH 46 47.890 38.070 3.280 1.00 0.00 +ATOM 611 HW2 HOH 46 46.530 38.490 2.760 1.00 0.00 +ATOM 612 OW HOH 47 12.340 21.730 27.040 1.00 0.00 +ATOM 613 HW1 HOH 47 12.950 21.140 27.490 1.00 0.00 +ATOM 614 HW2 HOH 47 11.760 21.150 26.560 1.00 0.00 +ATOM 615 OW HOH 48 32.630 5.790 20.420 1.00 0.00 +ATOM 616 HW1 HOH 48 32.980 6.160 19.610 1.00 0.00 +ATOM 617 HW2 HOH 48 31.840 6.300 20.590 1.00 0.00 +ATOM 618 OW HOH 49 33.860 11.120 32.520 1.00 0.00 +ATOM 619 HW1 HOH 49 34.360 11.520 31.820 1.00 0.00 +ATOM 620 HW2 HOH 49 33.000 11.540 32.480 1.00 0.00 +ATOM 621 OW HOH 50 13.290 44.980 29.430 1.00 0.00 +ATOM 622 HW1 HOH 50 12.840 45.660 29.930 1.00 0.00 +ATOM 623 HW2 HOH 50 12.710 44.220 29.500 1.00 0.00 +ATOM 624 OW HOH 51 1.890 9.610 34.920 1.00 0.00 +ATOM 625 HW1 HOH 51 2.500 8.990 35.320 1.00 0.00 +ATOM 626 HW2 HOH 51 1.040 9.390 35.300 1.00 0.00 +ATOM 627 OW HOH 52 9.840 34.570 8.670 1.00 0.00 +ATOM 628 HW1 HOH 52 10.430 35.320 8.570 1.00 0.00 +ATOM 629 HW2 HOH 52 9.220 34.840 9.350 1.00 0.00 +ATOM 630 OW HOH 53 38.090 44.700 38.640 1.00 0.00 +ATOM 631 HW1 HOH 53 37.200 44.600 38.300 1.00 0.00 +ATOM 632 HW2 HOH 53 38.440 43.810 38.670 1.00 0.00 +ATOM 633 OW HOH 54 1.440 10.360 5.840 1.00 0.00 +ATOM 634 HW1 HOH 54 2.310 10.770 5.790 1.00 0.00 +ATOM 635 HW2 HOH 54 1.610 9.430 5.710 1.00 0.00 +ATOM 636 OW HOH 55 -0.230 7.240 31.490 1.00 0.00 +ATOM 637 HW1 HOH 55 0.550 7.670 31.840 1.00 0.00 +ATOM 638 HW2 HOH 55 0.080 6.390 31.180 1.00 0.00 +ATOM 639 OW HOH 56 9.720 10.760 38.490 1.00 0.00 +ATOM 640 HW1 HOH 56 10.340 11.440 38.220 1.00 0.00 +ATOM 641 HW2 HOH 56 8.870 11.190 38.470 1.00 0.00 +ATOM 642 OW HOH 57 6.190 18.860 38.550 1.00 0.00 +ATOM 643 HW1 HOH 57 6.300 18.110 37.970 1.00 0.00 +ATOM 644 HW2 HOH 57 5.940 19.580 37.970 1.00 0.00 +ATOM 645 OW HOH 58 12.570 1.110 2.400 1.00 0.00 +ATOM 646 HW1 HOH 58 12.900 1.940 2.070 1.00 0.00 +ATOM 647 HW2 HOH 58 13.350 0.550 2.480 1.00 0.00 +ATOM 648 OW HOH 59 2.520 7.730 26.920 1.00 0.00 +ATOM 649 HW1 HOH 59 2.130 8.110 27.710 1.00 0.00 +ATOM 650 HW2 HOH 59 1.770 7.540 26.360 1.00 0.00 +ATOM 651 OW HOH 60 20.970 31.390 4.890 1.00 0.00 +ATOM 652 HW1 HOH 60 20.780 30.910 4.090 1.00 0.00 +ATOM 653 HW2 HOH 60 20.260 31.150 5.490 1.00 0.00 +ATOM 654 OW HOH 61 19.950 7.920 2.010 1.00 0.00 +ATOM 655 HW1 HOH 61 19.270 8.580 2.170 1.00 0.00 +ATOM 656 HW2 HOH 61 19.640 7.150 2.490 1.00 0.00 +ATOM 657 OW HOH 62 43.010 24.190 35.530 1.00 0.00 +ATOM 658 HW1 HOH 62 42.600 24.680 34.820 1.00 0.00 +ATOM 659 HW2 HOH 62 42.620 24.550 36.330 1.00 0.00 +ATOM 660 OW HOH 63 42.040 33.870 0.910 1.00 0.00 +ATOM 661 HW1 HOH 63 41.760 34.360 0.140 1.00 0.00 +ATOM 662 HW2 HOH 63 42.550 33.130 0.560 1.00 0.00 +ATOM 663 OW HOH 64 43.090 5.140 37.780 1.00 0.00 +ATOM 664 HW1 HOH 64 42.460 4.420 37.840 1.00 0.00 +ATOM 665 HW2 HOH 64 43.900 4.730 37.490 1.00 0.00 +ATOM 666 OW HOH 65 35.630 20.760 29.660 1.00 0.00 +ATOM 667 HW1 HOH 65 36.430 20.240 29.570 1.00 0.00 +ATOM 668 HW2 HOH 65 35.690 21.140 30.540 1.00 0.00 +ATOM 669 OW HOH 66 1.590 4.670 9.760 1.00 0.00 +ATOM 670 HW1 HOH 66 1.250 4.720 8.870 1.00 0.00 +ATOM 671 HW2 HOH 66 2.170 5.430 9.830 1.00 0.00 +ATOM 672 OW HOH 67 9.910 2.140 21.060 1.00 0.00 +ATOM 673 HW1 HOH 67 10.860 2.180 20.980 1.00 0.00 +ATOM 674 HW2 HOH 67 9.600 3.000 20.770 1.00 0.00 +ATOM 675 OW HOH 68 26.440 41.570 36.200 1.00 0.00 +ATOM 676 HW1 HOH 68 27.150 41.260 36.760 1.00 0.00 +ATOM 677 HW2 HOH 68 26.540 41.070 35.390 1.00 0.00 +ATOM 678 OW HOH 69 37.540 13.840 29.560 1.00 0.00 +ATOM 679 HW1 HOH 69 37.970 14.560 30.040 1.00 0.00 +ATOM 680 HW2 HOH 69 38.250 13.440 29.050 1.00 0.00 +ATOM 681 OW HOH 70 4.420 20.020 4.940 1.00 0.00 +ATOM 682 HW1 HOH 70 4.320 19.950 5.890 1.00 0.00 +ATOM 683 HW2 HOH 70 4.040 19.220 4.600 1.00 0.00 +ATOM 684 OW HOH 71 7.260 25.690 37.680 1.00 0.00 +ATOM 685 HW1 HOH 71 7.790 25.230 38.330 1.00 0.00 +ATOM 686 HW2 HOH 71 7.480 25.260 36.850 1.00 0.00 +ATOM 687 OW HOH 72 17.800 8.530 23.450 1.00 0.00 +ATOM 688 HW1 HOH 72 18.720 8.550 23.180 1.00 0.00 +ATOM 689 HW2 HOH 72 17.790 8.990 24.290 1.00 0.00 +ATOM 690 OW HOH 73 30.260 3.900 23.180 1.00 0.00 +ATOM 691 HW1 HOH 73 30.260 4.780 23.560 1.00 0.00 +ATOM 692 HW2 HOH 73 29.830 3.360 23.840 1.00 0.00 +ATOM 693 OW HOH 74 2.020 0.150 17.150 1.00 0.00 +ATOM 694 HW1 HOH 74 2.400 -0.560 16.630 1.00 0.00 +ATOM 695 HW2 HOH 74 2.010 0.900 16.550 1.00 0.00 +ATOM 696 OW HOH 75 16.100 23.980 11.020 1.00 0.00 +ATOM 697 HW1 HOH 75 16.810 24.130 11.640 1.00 0.00 +ATOM 698 HW2 HOH 75 16.500 23.430 10.340 1.00 0.00 +ATOM 699 OW HOH 76 2.380 19.510 38.900 1.00 0.00 +ATOM 700 HW1 HOH 76 2.990 19.160 38.250 1.00 0.00 +ATOM 701 HW2 HOH 76 1.910 20.210 38.440 1.00 0.00 +ATOM 702 OW HOH 77 18.210 6.140 11.980 1.00 0.00 +ATOM 703 HW1 HOH 77 18.790 6.800 11.590 1.00 0.00 +ATOM 704 HW2 HOH 77 17.540 6.650 12.430 1.00 0.00 +ATOM 705 OW HOH 78 20.480 44.660 34.260 1.00 0.00 +ATOM 706 HW1 HOH 78 21.400 44.420 34.340 1.00 0.00 +ATOM 707 HW2 HOH 78 20.030 43.830 34.100 1.00 0.00 +ATOM 708 OW HOH 79 43.300 28.970 1.940 1.00 0.00 +ATOM 709 HW1 HOH 79 42.890 28.600 2.720 1.00 0.00 +ATOM 710 HW2 HOH 79 43.820 29.710 2.250 1.00 0.00 +ATOM 711 OW HOH 80 43.110 6.560 11.660 1.00 0.00 +ATOM 712 HW1 HOH 80 42.230 6.850 11.890 1.00 0.00 +ATOM 713 HW2 HOH 80 43.690 7.200 12.050 1.00 0.00 +ATOM 714 OW HOH 81 12.820 1.480 13.690 1.00 0.00 +ATOM 715 HW1 HOH 81 12.540 2.210 13.140 1.00 0.00 +ATOM 716 HW2 HOH 81 12.990 1.870 14.550 1.00 0.00 +ATOM 717 OW HOH 82 47.710 33.610 36.630 1.00 0.00 +ATOM 718 HW1 HOH 82 48.230 33.970 35.920 1.00 0.00 +ATOM 719 HW2 HOH 82 48.350 33.160 37.190 1.00 0.00 +ATOM 720 OW HOH 83 45.790 3.560 18.100 1.00 0.00 +ATOM 721 HW1 HOH 83 45.660 2.770 17.560 1.00 0.00 +ATOM 722 HW2 HOH 83 45.060 3.540 18.720 1.00 0.00 +ATOM 723 OW HOH 84 45.160 25.520 22.580 1.00 0.00 +ATOM 724 HW1 HOH 84 45.190 26.030 23.390 1.00 0.00 +ATOM 725 HW2 HOH 84 45.950 24.970 22.610 1.00 0.00 +ATOM 726 OW HOH 85 11.170 12.660 37.300 1.00 0.00 +ATOM 727 HW1 HOH 85 11.930 12.830 36.750 1.00 0.00 +ATOM 728 HW2 HOH 85 11.150 13.380 37.920 1.00 0.00 +ATOM 729 OW HOH 86 47.920 40.800 2.300 1.00 0.00 +ATOM 730 HW1 HOH 86 47.830 41.530 1.700 1.00 0.00 +ATOM 731 HW2 HOH 86 48.300 40.100 1.770 1.00 0.00 +ATOM 732 OW HOH 87 48.580 27.380 7.110 1.00 0.00 +ATOM 733 HW1 HOH 87 48.340 27.240 6.190 1.00 0.00 +ATOM 734 HW2 HOH 87 49.400 27.860 7.080 1.00 0.00 +ATOM 735 OW HOH 88 16.630 38.280 20.670 1.00 0.00 +ATOM 736 HW1 HOH 88 17.410 37.730 20.750 1.00 0.00 +ATOM 737 HW2 HOH 88 16.690 38.660 19.800 1.00 0.00 +ATOM 738 OW HOH 89 32.440 20.600 21.740 1.00 0.00 +ATOM 739 HW1 HOH 89 32.780 19.740 21.530 1.00 0.00 +ATOM 740 HW2 HOH 89 31.930 20.850 20.960 1.00 0.00 +ATOM 741 OW HOH 90 12.220 17.720 1.480 1.00 0.00 +ATOM 742 HW1 HOH 90 11.760 17.140 2.080 1.00 0.00 +ATOM 743 HW2 HOH 90 13.150 17.620 1.720 1.00 0.00 +ATOM 744 OW HOH 91 8.520 38.020 20.640 1.00 0.00 +ATOM 745 HW1 HOH 91 7.890 38.610 21.060 1.00 0.00 +ATOM 746 HW2 HOH 91 8.120 37.150 20.710 1.00 0.00 +ATOM 747 OW HOH 92 2.170 7.720 13.850 1.00 0.00 +ATOM 748 HW1 HOH 92 1.320 7.560 14.270 1.00 0.00 +ATOM 749 HW2 HOH 92 2.000 8.460 13.260 1.00 0.00 +ATOM 750 OW HOH 93 15.040 14.430 16.810 1.00 0.00 +ATOM 751 HW1 HOH 93 14.200 14.050 17.070 1.00 0.00 +ATOM 752 HW2 HOH 93 14.940 14.640 15.880 1.00 0.00 +ATOM 753 OW HOH 94 13.030 11.960 23.010 1.00 0.00 +ATOM 754 HW1 HOH 94 12.650 11.770 23.870 1.00 0.00 +ATOM 755 HW2 HOH 94 12.320 12.390 22.530 1.00 0.00 +ATOM 756 OW HOH 95 22.930 11.260 7.360 1.00 0.00 +ATOM 757 HW1 HOH 95 22.090 11.070 6.950 1.00 0.00 +ATOM 758 HW2 HOH 95 22.820 12.150 7.710 1.00 0.00 +ATOM 759 OW HOH 96 12.940 4.490 17.760 1.00 0.00 +ATOM 760 HW1 HOH 96 13.220 4.560 16.850 1.00 0.00 +ATOM 761 HW2 HOH 96 13.270 5.290 18.170 1.00 0.00 +ATOM 762 OW HOH 97 44.280 43.990 19.710 1.00 0.00 +ATOM 763 HW1 HOH 97 43.710 43.330 20.100 1.00 0.00 +ATOM 764 HW2 HOH 97 44.760 43.520 19.020 1.00 0.00 +ATOM 765 OW HOH 98 35.180 45.170 28.030 1.00 0.00 +ATOM 766 HW1 HOH 98 35.490 45.690 27.280 1.00 0.00 +ATOM 767 HW2 HOH 98 34.670 45.790 28.550 1.00 0.00 +ATOM 768 OW HOH 99 47.050 7.440 35.770 1.00 0.00 +ATOM 769 HW1 HOH 99 46.850 8.330 35.460 1.00 0.00 +ATOM 770 HW2 HOH 99 47.130 7.540 36.720 1.00 0.00 +ATOM 771 OW HOH 100 7.030 23.040 12.330 1.00 0.00 +ATOM 772 HW1 HOH 100 7.180 22.290 12.900 1.00 0.00 +ATOM 773 HW2 HOH 100 6.300 23.510 12.750 1.00 0.00 +ATOM 774 OW HOH 101 23.350 10.850 10.410 1.00 0.00 +ATOM 775 HW1 HOH 101 23.900 10.970 9.640 1.00 0.00 +ATOM 776 HW2 HOH 101 23.160 11.740 10.710 1.00 0.00 +ATOM 777 OW HOH 102 43.880 13.960 29.200 1.00 0.00 +ATOM 778 HW1 HOH 102 43.510 13.090 29.030 1.00 0.00 +ATOM 779 HW2 HOH 102 44.800 13.790 29.390 1.00 0.00 +ATOM 780 OW HOH 103 17.060 41.340 27.660 1.00 0.00 +ATOM 781 HW1 HOH 103 17.600 42.080 27.930 1.00 0.00 +ATOM 782 HW2 HOH 103 17.120 40.710 28.380 1.00 0.00 +ATOM 783 OW HOH 104 40.560 12.530 30.700 1.00 0.00 +ATOM 784 HW1 HOH 104 40.240 13.430 30.790 1.00 0.00 +ATOM 785 HW2 HOH 104 40.250 12.250 29.840 1.00 0.00 +ATOM 786 OW HOH 105 13.010 25.560 32.740 1.00 0.00 +ATOM 787 HW1 HOH 105 12.390 24.840 32.620 1.00 0.00 +ATOM 788 HW2 HOH 105 12.510 26.240 33.200 1.00 0.00 +ATOM 789 OW HOH 106 41.920 37.040 0.550 1.00 0.00 +ATOM 790 HW1 HOH 106 41.270 36.910 1.240 1.00 0.00 +ATOM 791 HW2 HOH 106 41.400 37.250 -0.230 1.00 0.00 +ATOM 792 OW HOH 107 21.780 1.400 29.870 1.00 0.00 +ATOM 793 HW1 HOH 107 21.820 0.630 30.440 1.00 0.00 +ATOM 794 HW2 HOH 107 22.400 2.020 30.240 1.00 0.00 +ATOM 795 OW HOH 108 40.520 18.000 32.410 1.00 0.00 +ATOM 796 HW1 HOH 108 40.190 17.780 31.540 1.00 0.00 +ATOM 797 HW2 HOH 108 41.460 18.140 32.290 1.00 0.00 +ATOM 798 OW HOH 109 3.200 38.610 20.420 1.00 0.00 +ATOM 799 HW1 HOH 109 4.010 38.210 20.720 1.00 0.00 +ATOM 800 HW2 HOH 109 2.680 37.890 20.080 1.00 0.00 +ATOM 801 OW HOH 110 37.600 42.760 8.570 1.00 0.00 +ATOM 802 HW1 HOH 110 36.900 42.110 8.610 1.00 0.00 +ATOM 803 HW2 HOH 110 37.690 42.960 7.630 1.00 0.00 +ATOM 804 OW HOH 111 37.320 14.110 9.140 1.00 0.00 +ATOM 805 HW1 HOH 111 37.100 14.820 9.750 1.00 0.00 +ATOM 806 HW2 HOH 111 36.650 13.450 9.290 1.00 0.00 +ATOM 807 OW HOH 112 9.620 30.850 17.580 1.00 0.00 +ATOM 808 HW1 HOH 112 10.200 31.330 18.170 1.00 0.00 +ATOM 809 HW2 HOH 112 9.510 31.440 16.830 1.00 0.00 +ATOM 810 OW HOH 113 25.970 45.370 19.060 1.00 0.00 +ATOM 811 HW1 HOH 113 26.430 45.680 19.840 1.00 0.00 +ATOM 812 HW2 HOH 113 25.240 45.970 18.950 1.00 0.00 +ATOM 813 OW HOH 114 0.440 34.820 17.410 1.00 0.00 +ATOM 814 HW1 HOH 114 0.060 34.080 16.950 1.00 0.00 +ATOM 815 HW2 HOH 114 0.140 35.590 16.920 1.00 0.00 +ATOM 816 OW HOH 115 3.920 2.100 28.900 1.00 0.00 +ATOM 817 HW1 HOH 115 3.670 2.980 29.180 1.00 0.00 +ATOM 818 HW2 HOH 115 3.450 1.960 28.080 1.00 0.00 +ATOM 819 OW HOH 116 4.880 33.850 22.880 1.00 0.00 +ATOM 820 HW1 HOH 116 3.950 33.830 23.090 1.00 0.00 +ATOM 821 HW2 HOH 116 5.280 34.350 23.590 1.00 0.00 +ATOM 822 OW HOH 117 27.210 27.870 34.140 1.00 0.00 +ATOM 823 HW1 HOH 117 27.450 26.950 34.040 1.00 0.00 +ATOM 824 HW2 HOH 117 26.520 27.870 34.800 1.00 0.00 +ATOM 825 OW HOH 118 20.310 16.180 32.460 1.00 0.00 +ATOM 826 HW1 HOH 118 20.390 15.520 31.780 1.00 0.00 +ATOM 827 HW2 HOH 118 19.660 15.820 33.070 1.00 0.00 +ATOM 828 OW HOH 119 25.500 31.150 15.360 1.00 0.00 +ATOM 829 HW1 HOH 119 26.380 31.320 15.700 1.00 0.00 +ATOM 830 HW2 HOH 119 25.500 31.520 14.480 1.00 0.00 +ATOM 831 OW HOH 120 17.880 27.250 28.900 1.00 0.00 +ATOM 832 HW1 HOH 120 17.060 27.330 28.410 1.00 0.00 +ATOM 833 HW2 HOH 120 18.470 27.890 28.510 1.00 0.00 +ATOM 834 OW HOH 121 17.310 33.920 30.490 1.00 0.00 +ATOM 835 HW1 HOH 121 16.910 33.110 30.160 1.00 0.00 +ATOM 836 HW2 HOH 121 18.220 33.870 30.210 1.00 0.00 +ATOM 837 OW HOH 122 37.950 13.790 23.360 1.00 0.00 +ATOM 838 HW1 HOH 122 38.750 14.210 23.690 1.00 0.00 +ATOM 839 HW2 HOH 122 37.940 12.940 23.800 1.00 0.00 +ATOM 840 OW HOH 123 0.630 35.420 34.890 1.00 0.00 +ATOM 841 HW1 HOH 123 -0.030 35.090 34.280 1.00 0.00 +ATOM 842 HW2 HOH 123 1.430 34.940 34.650 1.00 0.00 +ATOM 843 OW HOH 124 12.550 37.820 37.920 1.00 0.00 +ATOM 844 HW1 HOH 124 12.500 36.860 37.950 1.00 0.00 +ATOM 845 HW2 HOH 124 11.680 38.100 37.620 1.00 0.00 +ATOM 846 OW HOH 125 17.070 17.700 15.120 1.00 0.00 +ATOM 847 HW1 HOH 125 17.750 17.080 15.360 1.00 0.00 +ATOM 848 HW2 HOH 125 16.470 17.710 15.860 1.00 0.00 +ATOM 849 OW HOH 126 14.240 14.040 9.620 1.00 0.00 +ATOM 850 HW1 HOH 126 13.320 14.310 9.740 1.00 0.00 +ATOM 851 HW2 HOH 126 14.430 14.270 8.710 1.00 0.00 +ATOM 852 OW HOH 127 10.410 13.620 2.920 1.00 0.00 +ATOM 853 HW1 HOH 127 10.850 13.880 2.110 1.00 0.00 +ATOM 854 HW2 HOH 127 10.870 12.820 3.200 1.00 0.00 +ATOM 855 OW HOH 128 42.710 45.740 15.850 1.00 0.00 +ATOM 856 HW1 HOH 128 43.120 44.880 15.950 1.00 0.00 +ATOM 857 HW2 HOH 128 42.640 46.080 16.740 1.00 0.00 +ATOM 858 OW HOH 129 25.770 7.480 36.690 1.00 0.00 +ATOM 859 HW1 HOH 129 25.710 7.300 35.750 1.00 0.00 +ATOM 860 HW2 HOH 129 24.980 7.090 37.070 1.00 0.00 +ATOM 861 OW HOH 130 22.350 8.280 32.660 1.00 0.00 +ATOM 862 HW1 HOH 130 21.710 7.630 32.360 1.00 0.00 +ATOM 863 HW2 HOH 130 22.050 9.100 32.280 1.00 0.00 +ATOM 864 OW HOH 131 23.800 12.320 23.690 1.00 0.00 +ATOM 865 HW1 HOH 131 24.430 11.620 23.560 1.00 0.00 +ATOM 866 HW2 HOH 131 23.460 12.180 24.570 1.00 0.00 +ATOM 867 OW HOH 132 39.100 37.290 9.980 1.00 0.00 +ATOM 868 HW1 HOH 132 38.930 38.230 9.950 1.00 0.00 +ATOM 869 HW2 HOH 132 38.290 36.900 9.640 1.00 0.00 +ATOM 870 OW HOH 133 15.090 19.570 37.300 1.00 0.00 +ATOM 871 HW1 HOH 133 14.780 19.420 36.410 1.00 0.00 +ATOM 872 HW2 HOH 133 15.280 18.690 37.640 1.00 0.00 +ATOM 873 OW HOH 134 11.200 23.890 6.930 1.00 0.00 +ATOM 874 HW1 HOH 134 11.600 24.540 7.500 1.00 0.00 +ATOM 875 HW2 HOH 134 10.280 24.160 6.870 1.00 0.00 +ATOM 876 OW HOH 135 38.140 32.110 13.290 1.00 0.00 +ATOM 877 HW1 HOH 135 38.880 32.580 12.910 1.00 0.00 +ATOM 878 HW2 HOH 135 38.430 31.870 14.170 1.00 0.00 +ATOM 879 OW HOH 136 6.540 12.020 1.010 1.00 0.00 +ATOM 880 HW1 HOH 136 6.990 12.130 0.170 1.00 0.00 +ATOM 881 HW2 HOH 136 6.100 12.860 1.150 1.00 0.00 +ATOM 882 OW HOH 137 34.090 10.550 35.100 1.00 0.00 +ATOM 883 HW1 HOH 137 33.970 10.810 34.190 1.00 0.00 +ATOM 884 HW2 HOH 137 33.730 9.660 35.140 1.00 0.00 +ATOM 885 OW HOH 138 8.670 29.930 33.250 1.00 0.00 +ATOM 886 HW1 HOH 138 8.450 29.640 34.130 1.00 0.00 +ATOM 887 HW2 HOH 138 8.570 30.890 33.280 1.00 0.00 +ATOM 888 OW HOH 139 2.580 31.520 8.910 1.00 0.00 +ATOM 889 HW1 HOH 139 2.360 31.590 9.840 1.00 0.00 +ATOM 890 HW2 HOH 139 1.790 31.800 8.450 1.00 0.00 +ATOM 891 OW HOH 140 21.620 44.970 1.800 1.00 0.00 +ATOM 892 HW1 HOH 140 22.420 44.460 1.680 1.00 0.00 +ATOM 893 HW2 HOH 140 21.340 44.760 2.700 1.00 0.00 +ATOM 894 OW HOH 141 14.990 41.770 11.790 1.00 0.00 +ATOM 895 HW1 HOH 141 15.630 42.080 11.150 1.00 0.00 +ATOM 896 HW2 HOH 141 14.160 42.160 11.520 1.00 0.00 +ATOM 897 OW HOH 142 41.710 27.290 31.510 1.00 0.00 +ATOM 898 HW1 HOH 142 42.210 27.230 30.690 1.00 0.00 +ATOM 899 HW2 HOH 142 41.330 28.170 31.500 1.00 0.00 +ATOM 900 OW HOH 143 8.570 40.410 12.150 1.00 0.00 +ATOM 901 HW1 HOH 143 7.670 40.650 12.360 1.00 0.00 +ATOM 902 HW2 HOH 143 9.090 41.190 12.350 1.00 0.00 +ATOM 903 OW HOH 144 48.180 5.140 11.280 1.00 0.00 +ATOM 904 HW1 HOH 144 49.000 4.990 10.810 1.00 0.00 +ATOM 905 HW2 HOH 144 47.500 4.810 10.690 1.00 0.00 +ATOM 906 OW HOH 145 19.750 10.040 15.880 1.00 0.00 +ATOM 907 HW1 HOH 145 20.060 9.250 15.440 1.00 0.00 +ATOM 908 HW2 HOH 145 19.390 9.730 16.710 1.00 0.00 +ATOM 909 OW HOH 146 8.940 32.460 4.290 1.00 0.00 +ATOM 910 HW1 HOH 146 9.760 32.840 4.590 1.00 0.00 +ATOM 911 HW2 HOH 146 8.560 33.110 3.700 1.00 0.00 +ATOM 912 OW HOH 147 25.960 24.940 7.360 1.00 0.00 +ATOM 913 HW1 HOH 147 26.810 25.190 7.720 1.00 0.00 +ATOM 914 HW2 HOH 147 26.130 24.760 6.440 1.00 0.00 +ATOM 915 OW HOH 148 27.890 6.360 34.070 1.00 0.00 +ATOM 916 HW1 HOH 148 28.150 5.830 34.820 1.00 0.00 +ATOM 917 HW2 HOH 148 28.710 6.500 33.590 1.00 0.00 +ATOM 918 OW HOH 149 18.880 2.270 35.600 1.00 0.00 +ATOM 919 HW1 HOH 149 19.720 2.180 36.060 1.00 0.00 +ATOM 920 HW2 HOH 149 18.980 1.720 34.820 1.00 0.00 +ATOM 921 OW HOH 150 15.380 26.510 8.840 1.00 0.00 +ATOM 922 HW1 HOH 150 15.240 25.590 8.610 1.00 0.00 +ATOM 923 HW2 HOH 150 16.310 26.580 9.020 1.00 0.00 +ATOM 924 OW HOH 151 22.190 14.440 36.990 1.00 0.00 +ATOM 925 HW1 HOH 151 22.510 13.790 36.370 1.00 0.00 +ATOM 926 HW2 HOH 151 22.190 13.980 37.830 1.00 0.00 +ATOM 927 OW HOH 152 32.790 26.240 31.690 1.00 0.00 +ATOM 928 HW1 HOH 152 32.060 26.850 31.590 1.00 0.00 +ATOM 929 HW2 HOH 152 33.200 26.490 32.510 1.00 0.00 +ATOM 930 OW HOH 153 7.320 37.290 15.060 1.00 0.00 +ATOM 931 HW1 HOH 153 6.860 36.450 15.090 1.00 0.00 +ATOM 932 HW2 HOH 153 8.020 37.190 15.700 1.00 0.00 +ATOM 933 OW HOH 154 18.050 10.530 1.980 1.00 0.00 +ATOM 934 HW1 HOH 154 17.530 10.550 2.790 1.00 0.00 +ATOM 935 HW2 HOH 154 18.870 10.980 2.200 1.00 0.00 +ATOM 936 OW HOH 155 27.450 32.600 10.950 1.00 0.00 +ATOM 937 HW1 HOH 155 27.020 33.430 10.760 1.00 0.00 +ATOM 938 HW2 HOH 155 27.420 32.120 10.130 1.00 0.00 +ATOM 939 OW HOH 156 36.170 24.070 2.370 1.00 0.00 +ATOM 940 HW1 HOH 156 36.460 23.270 2.800 1.00 0.00 +ATOM 941 HW2 HOH 156 35.730 23.780 1.580 1.00 0.00 +ATOM 942 OW HOH 157 31.950 38.730 25.450 1.00 0.00 +ATOM 943 HW1 HOH 157 32.600 38.450 24.810 1.00 0.00 +ATOM 944 HW2 HOH 157 32.120 38.180 26.220 1.00 0.00 +ATOM 945 OW HOH 158 38.540 45.940 21.640 1.00 0.00 +ATOM 946 HW1 HOH 158 38.270 45.160 21.150 1.00 0.00 +ATOM 947 HW2 HOH 158 38.700 46.600 20.970 1.00 0.00 +ATOM 948 OW HOH 159 42.110 36.000 7.230 1.00 0.00 +ATOM 949 HW1 HOH 159 41.530 36.030 6.470 1.00 0.00 +ATOM 950 HW2 HOH 159 42.140 35.080 7.480 1.00 0.00 +ATOM 951 OW HOH 160 45.410 41.520 4.440 1.00 0.00 +ATOM 952 HW1 HOH 160 45.060 40.660 4.210 1.00 0.00 +ATOM 953 HW2 HOH 160 45.860 41.370 5.280 1.00 0.00 +ATOM 954 OW HOH 161 23.520 5.810 18.870 1.00 0.00 +ATOM 955 HW1 HOH 161 24.270 5.600 18.320 1.00 0.00 +ATOM 956 HW2 HOH 161 22.820 5.250 18.540 1.00 0.00 +ATOM 957 OW HOH 162 25.540 21.910 33.720 1.00 0.00 +ATOM 958 HW1 HOH 162 26.490 21.790 33.810 1.00 0.00 +ATOM 959 HW2 HOH 162 25.160 21.260 34.300 1.00 0.00 +ATOM 960 OW HOH 163 46.590 7.450 20.810 1.00 0.00 +ATOM 961 HW1 HOH 163 46.000 7.160 21.500 1.00 0.00 +ATOM 962 HW2 HOH 163 46.820 8.340 21.050 1.00 0.00 +ATOM 963 OW HOH 164 47.440 34.100 20.200 1.00 0.00 +ATOM 964 HW1 HOH 164 47.920 34.260 21.010 1.00 0.00 +ATOM 965 HW2 HOH 164 47.890 34.650 19.550 1.00 0.00 +ATOM 966 OW HOH 165 6.210 16.340 4.800 1.00 0.00 +ATOM 967 HW1 HOH 165 6.720 15.770 4.220 1.00 0.00 +ATOM 968 HW2 HOH 165 5.380 16.470 4.340 1.00 0.00 +ATOM 969 OW HOH 166 31.650 39.620 15.570 1.00 0.00 +ATOM 970 HW1 HOH 166 30.760 39.990 15.540 1.00 0.00 +ATOM 971 HW2 HOH 166 31.630 39.030 16.320 1.00 0.00 +ATOM 972 OW HOH 167 33.640 3.990 14.660 1.00 0.00 +ATOM 973 HW1 HOH 167 33.280 3.360 15.280 1.00 0.00 +ATOM 974 HW2 HOH 167 34.400 4.370 15.120 1.00 0.00 +ATOM 975 OW HOH 168 30.550 36.090 24.860 1.00 0.00 +ATOM 976 HW1 HOH 168 30.930 36.630 24.180 1.00 0.00 +ATOM 977 HW2 HOH 168 30.890 35.210 24.690 1.00 0.00 +ATOM 978 OW HOH 169 49.200 4.990 4.710 1.00 0.00 +ATOM 979 HW1 HOH 169 48.600 4.530 4.120 1.00 0.00 +ATOM 980 HW2 HOH 169 48.970 5.910 4.620 1.00 0.00 +ATOM 981 OW HOH 170 2.910 11.180 24.230 1.00 0.00 +ATOM 982 HW1 HOH 170 2.060 10.870 24.550 1.00 0.00 +ATOM 983 HW2 HOH 170 3.500 11.080 24.970 1.00 0.00 +ATOM 984 OW HOH 171 14.640 34.790 36.450 1.00 0.00 +ATOM 985 HW1 HOH 171 15.370 35.170 36.940 1.00 0.00 +ATOM 986 HW2 HOH 171 14.610 33.870 36.720 1.00 0.00 +ATOM 987 OW HOH 172 22.300 36.010 8.620 1.00 0.00 +ATOM 988 HW1 HOH 172 21.420 36.370 8.660 1.00 0.00 +ATOM 989 HW2 HOH 172 22.410 35.520 9.430 1.00 0.00 +ATOM 990 OW HOH 173 20.790 32.090 8.330 1.00 0.00 +ATOM 991 HW1 HOH 173 20.570 32.250 9.250 1.00 0.00 +ATOM 992 HW2 HOH 173 20.210 32.670 7.840 1.00 0.00 +ATOM 993 OW HOH 174 19.570 19.030 35.500 1.00 0.00 +ATOM 994 HW1 HOH 174 19.830 19.710 36.130 1.00 0.00 +ATOM 995 HW2 HOH 174 20.050 18.250 35.770 1.00 0.00 +ATOM 996 OW HOH 175 18.320 6.520 18.390 1.00 0.00 +ATOM 997 HW1 HOH 175 18.090 6.230 19.270 1.00 0.00 +ATOM 998 HW2 HOH 175 19.280 6.610 18.410 1.00 0.00 +ATOM 999 OW HOH 176 35.690 15.340 28.020 1.00 0.00 +ATOM 1000 HW1 HOH 176 35.920 14.450 28.280 1.00 0.00 +ATOM 1001 HW2 HOH 176 36.350 15.580 27.370 1.00 0.00 +ATOM 1002 OW HOH 177 2.400 42.080 15.210 1.00 0.00 +ATOM 1003 HW1 HOH 177 2.050 42.180 16.090 1.00 0.00 +ATOM 1004 HW2 HOH 177 2.210 41.170 14.980 1.00 0.00 +ATOM 1005 OW HOH 178 24.470 37.070 15.680 1.00 0.00 +ATOM 1006 HW1 HOH 178 23.770 37.710 15.610 1.00 0.00 +ATOM 1007 HW2 HOH 178 24.220 36.370 15.080 1.00 0.00 +ATOM 1008 OW HOH 179 42.410 26.620 18.710 1.00 0.00 +ATOM 1009 HW1 HOH 179 43.030 26.030 18.290 1.00 0.00 +ATOM 1010 HW2 HOH 179 42.960 27.260 19.170 1.00 0.00 +ATOM 1011 OW HOH 180 43.760 8.790 18.310 1.00 0.00 +ATOM 1012 HW1 HOH 180 43.660 8.770 17.350 1.00 0.00 +ATOM 1013 HW2 HOH 180 43.890 7.870 18.550 1.00 0.00 +ATOM 1014 OW HOH 181 17.090 36.760 7.220 1.00 0.00 +ATOM 1015 HW1 HOH 181 16.330 36.520 6.690 1.00 0.00 +ATOM 1016 HW2 HOH 181 16.780 37.480 7.760 1.00 0.00 +ATOM 1017 OW HOH 182 11.640 31.190 7.000 1.00 0.00 +ATOM 1018 HW1 HOH 182 11.410 30.750 7.820 1.00 0.00 +ATOM 1019 HW2 HOH 182 10.800 31.410 6.600 1.00 0.00 +ATOM 1020 OW HOH 183 40.520 0.340 28.430 1.00 0.00 +ATOM 1021 HW1 HOH 183 39.610 0.610 28.470 1.00 0.00 +ATOM 1022 HW2 HOH 183 40.980 0.990 28.960 1.00 0.00 +ATOM 1023 OW HOH 184 4.520 27.710 8.660 1.00 0.00 +ATOM 1024 HW1 HOH 184 4.840 28.330 8.010 1.00 0.00 +ATOM 1025 HW2 HOH 184 4.770 28.090 9.500 1.00 0.00 +ATOM 1026 OW HOH 185 3.070 5.070 35.600 1.00 0.00 +ATOM 1027 HW1 HOH 185 3.840 4.510 35.710 1.00 0.00 +ATOM 1028 HW2 HOH 185 3.290 5.880 36.070 1.00 0.00 +ATOM 1029 OW HOH 186 13.510 31.860 10.790 1.00 0.00 +ATOM 1030 HW1 HOH 186 13.170 32.170 9.950 1.00 0.00 +ATOM 1031 HW2 HOH 186 14.250 31.290 10.560 1.00 0.00 +ATOM 1032 OW HOH 187 47.490 3.830 35.360 1.00 0.00 +ATOM 1033 HW1 HOH 187 47.220 4.530 34.760 1.00 0.00 +ATOM 1034 HW2 HOH 187 48.350 4.100 35.670 1.00 0.00 +ATOM 1035 OW HOH 188 17.410 0.130 25.170 1.00 0.00 +ATOM 1036 HW1 HOH 188 16.720 -0.460 24.860 1.00 0.00 +ATOM 1037 HW2 HOH 188 16.990 0.640 25.860 1.00 0.00 +ATOM 1038 OW HOH 189 39.170 11.870 16.470 1.00 0.00 +ATOM 1039 HW1 HOH 189 39.770 11.140 16.580 1.00 0.00 +ATOM 1040 HW2 HOH 189 38.570 11.580 15.780 1.00 0.00 +ATOM 1041 OW HOH 190 3.550 6.870 9.850 1.00 0.00 +ATOM 1042 HW1 HOH 190 2.840 7.510 9.880 1.00 0.00 +ATOM 1043 HW2 HOH 190 4.130 7.180 9.160 1.00 0.00 +ATOM 1044 OW HOH 191 38.960 34.920 14.670 1.00 0.00 +ATOM 1045 HW1 HOH 191 39.590 35.620 14.850 1.00 0.00 +ATOM 1046 HW2 HOH 191 38.900 34.890 13.710 1.00 0.00 +ATOM 1047 OW HOH 192 38.270 31.310 38.580 1.00 0.00 +ATOM 1048 HW1 HOH 192 38.930 31.570 37.930 1.00 0.00 +ATOM 1049 HW2 HOH 192 38.340 31.970 39.270 1.00 0.00 +ATOM 1050 OW HOH 193 7.300 6.140 28.960 1.00 0.00 +ATOM 1051 HW1 HOH 193 7.970 6.360 28.310 1.00 0.00 +ATOM 1052 HW2 HOH 193 7.570 5.290 29.300 1.00 0.00 +ATOM 1053 OW HOH 194 16.000 11.730 13.670 1.00 0.00 +ATOM 1054 HW1 HOH 194 16.670 11.860 13.010 1.00 0.00 +ATOM 1055 HW2 HOH 194 16.450 11.880 14.500 1.00 0.00 +ATOM 1056 OW HOH 195 7.390 24.600 20.470 1.00 0.00 +ATOM 1057 HW1 HOH 195 7.450 23.760 20.010 1.00 0.00 +ATOM 1058 HW2 HOH 195 6.620 25.020 20.110 1.00 0.00 +ATOM 1059 OW HOH 196 48.450 32.640 16.260 1.00 0.00 +ATOM 1060 HW1 HOH 196 49.130 32.430 15.620 1.00 0.00 +ATOM 1061 HW2 HOH 196 47.680 32.160 15.960 1.00 0.00 +ATOM 1062 OW HOH 197 1.040 29.010 16.090 1.00 0.00 +ATOM 1063 HW1 HOH 197 0.730 29.200 16.970 1.00 0.00 +ATOM 1064 HW2 HOH 197 1.040 28.050 16.040 1.00 0.00 +ATOM 1065 OW HOH 198 6.320 32.200 16.300 1.00 0.00 +ATOM 1066 HW1 HOH 198 5.490 31.720 16.230 1.00 0.00 +ATOM 1067 HW2 HOH 198 6.680 32.170 15.410 1.00 0.00 +ATOM 1068 OW HOH 199 7.450 40.840 21.940 1.00 0.00 +ATOM 1069 HW1 HOH 199 6.980 40.890 21.100 1.00 0.00 +ATOM 1070 HW2 HOH 199 7.750 41.740 22.100 1.00 0.00 +ATOM 1071 OW HOH 200 15.900 4.680 38.500 1.00 0.00 +ATOM 1072 HW1 HOH 200 16.460 5.250 39.010 1.00 0.00 +ATOM 1073 HW2 HOH 200 16.330 4.620 37.650 1.00 0.00 +ATOM 1074 OW HOH 201 21.530 0.530 19.660 1.00 0.00 +ATOM 1075 HW1 HOH 201 21.010 0.740 20.440 1.00 0.00 +ATOM 1076 HW2 HOH 201 21.740 -0.400 19.750 1.00 0.00 +ATOM 1077 OW HOH 202 15.690 1.990 6.640 1.00 0.00 +ATOM 1078 HW1 HOH 202 16.090 1.660 5.840 1.00 0.00 +ATOM 1079 HW2 HOH 202 16.350 1.840 7.320 1.00 0.00 +ATOM 1080 OW HOH 203 1.620 1.810 14.950 1.00 0.00 +ATOM 1081 HW1 HOH 203 1.020 2.200 14.310 1.00 0.00 +ATOM 1082 HW2 HOH 203 2.430 2.310 14.850 1.00 0.00 +ATOM 1083 OW HOH 204 7.150 9.660 34.860 1.00 0.00 +ATOM 1084 HW1 HOH 204 7.260 9.150 34.060 1.00 0.00 +ATOM 1085 HW2 HOH 204 7.600 9.150 35.530 1.00 0.00 +ATOM 1086 OW HOH 205 36.930 6.930 3.590 1.00 0.00 +ATOM 1087 HW1 HOH 205 36.170 6.700 4.140 1.00 0.00 +ATOM 1088 HW2 HOH 205 37.670 6.920 4.200 1.00 0.00 +ATOM 1089 OW HOH 206 11.010 31.770 36.290 1.00 0.00 +ATOM 1090 HW1 HOH 206 11.380 31.050 36.790 1.00 0.00 +ATOM 1091 HW2 HOH 206 10.210 32.000 36.760 1.00 0.00 +ATOM 1092 OW HOH 207 21.760 3.110 20.360 1.00 0.00 +ATOM 1093 HW1 HOH 207 21.400 3.660 19.660 1.00 0.00 +ATOM 1094 HW2 HOH 207 21.430 2.230 20.160 1.00 0.00 +ATOM 1095 OW HOH 208 32.100 5.330 6.080 1.00 0.00 +ATOM 1096 HW1 HOH 208 32.010 4.780 6.860 1.00 0.00 +ATOM 1097 HW2 HOH 208 31.330 5.900 6.110 1.00 0.00 +ATOM 1098 OW HOH 209 43.620 15.870 12.950 1.00 0.00 +ATOM 1099 HW1 HOH 209 43.880 16.010 12.040 1.00 0.00 +ATOM 1100 HW2 HOH 209 43.540 16.750 13.320 1.00 0.00 +ATOM 1101 OW HOH 210 46.630 9.840 18.410 1.00 0.00 +ATOM 1102 HW1 HOH 210 47.170 9.060 18.280 1.00 0.00 +ATOM 1103 HW2 HOH 210 45.740 9.550 18.200 1.00 0.00 +ATOM 1104 OW HOH 211 12.180 30.060 16.240 1.00 0.00 +ATOM 1105 HW1 HOH 211 11.900 30.400 15.390 1.00 0.00 +ATOM 1106 HW2 HOH 211 11.530 30.370 16.860 1.00 0.00 +ATOM 1107 OW HOH 212 2.980 43.140 10.550 1.00 0.00 +ATOM 1108 HW1 HOH 212 2.770 43.970 10.130 1.00 0.00 +ATOM 1109 HW2 HOH 212 3.760 42.830 10.100 1.00 0.00 +ATOM 1110 OW HOH 213 21.370 29.530 7.760 1.00 0.00 +ATOM 1111 HW1 HOH 213 21.170 30.470 7.790 1.00 0.00 +ATOM 1112 HW2 HOH 213 21.200 29.220 8.650 1.00 0.00 +ATOM 1113 OW HOH 214 29.070 14.170 24.070 1.00 0.00 +ATOM 1114 HW1 HOH 214 28.730 14.650 24.830 1.00 0.00 +ATOM 1115 HW2 HOH 214 29.850 13.720 24.410 1.00 0.00 +ATOM 1116 OW HOH 215 6.760 43.660 24.200 1.00 0.00 +ATOM 1117 HW1 HOH 215 7.230 44.100 24.910 1.00 0.00 +ATOM 1118 HW2 HOH 215 7.320 43.770 23.440 1.00 0.00 +ATOM 1119 OW HOH 216 42.630 3.460 25.790 1.00 0.00 +ATOM 1120 HW1 HOH 216 42.810 3.160 26.680 1.00 0.00 +ATOM 1121 HW2 HOH 216 42.610 4.420 25.860 1.00 0.00 +ATOM 1122 OW HOH 217 8.970 36.720 5.850 1.00 0.00 +ATOM 1123 HW1 HOH 217 9.880 36.960 6.050 1.00 0.00 +ATOM 1124 HW2 HOH 217 8.680 37.390 5.230 1.00 0.00 +ATOM 1125 OW HOH 218 26.790 36.820 11.220 1.00 0.00 +ATOM 1126 HW1 HOH 218 25.910 37.060 11.510 1.00 0.00 +ATOM 1127 HW2 HOH 218 27.230 36.560 12.030 1.00 0.00 +ATOM 1128 OW HOH 219 6.030 15.420 15.530 1.00 0.00 +ATOM 1129 HW1 HOH 219 5.780 14.710 14.940 1.00 0.00 +ATOM 1130 HW2 HOH 219 6.640 15.950 15.020 1.00 0.00 +ATOM 1131 OW HOH 220 15.480 30.470 19.080 1.00 0.00 +ATOM 1132 HW1 HOH 220 16.360 30.390 19.470 1.00 0.00 +ATOM 1133 HW2 HOH 220 15.190 29.570 18.960 1.00 0.00 +ATOM 1134 OW HOH 221 23.010 23.260 1.710 1.00 0.00 +ATOM 1135 HW1 HOH 221 23.490 23.950 1.240 1.00 0.00 +ATOM 1136 HW2 HOH 221 22.470 23.740 2.340 1.00 0.00 +ATOM 1137 OW HOH 222 36.520 38.470 33.220 1.00 0.00 +ATOM 1138 HW1 HOH 222 37.350 38.030 33.050 1.00 0.00 +ATOM 1139 HW2 HOH 222 36.210 38.080 34.030 1.00 0.00 +ATOM 1140 OW HOH 223 44.070 26.290 2.310 1.00 0.00 +ATOM 1141 HW1 HOH 223 43.510 27.050 2.490 1.00 0.00 +ATOM 1142 HW2 HOH 223 44.130 25.840 3.150 1.00 0.00 +ATOM 1143 OW HOH 224 29.840 32.900 -0.240 1.00 0.00 +ATOM 1144 HW1 HOH 224 29.060 32.430 0.050 1.00 0.00 +ATOM 1145 HW2 HOH 224 30.200 33.280 0.570 1.00 0.00 +ATOM 1146 OW HOH 225 18.150 31.830 5.010 1.00 0.00 +ATOM 1147 HW1 HOH 225 17.390 31.340 5.310 1.00 0.00 +ATOM 1148 HW2 HOH 225 18.350 31.460 4.150 1.00 0.00 +ATOM 1149 OW HOH 226 24.710 7.850 2.080 1.00 0.00 +ATOM 1150 HW1 HOH 226 25.540 7.460 2.350 1.00 0.00 +ATOM 1151 HW2 HOH 226 24.180 7.850 2.870 1.00 0.00 +ATOM 1152 OW HOH 227 40.130 23.480 0.680 1.00 0.00 +ATOM 1153 HW1 HOH 227 40.220 24.340 1.090 1.00 0.00 +ATOM 1154 HW2 HOH 227 40.950 23.030 0.890 1.00 0.00 +ATOM 1155 OW HOH 228 36.280 5.050 22.720 1.00 0.00 +ATOM 1156 HW1 HOH 228 37.040 4.470 22.650 1.00 0.00 +ATOM 1157 HW2 HOH 228 35.570 4.480 23.000 1.00 0.00 +ATOM 1158 OW HOH 229 47.210 39.410 17.140 1.00 0.00 +ATOM 1159 HW1 HOH 229 47.410 39.900 17.940 1.00 0.00 +ATOM 1160 HW2 HOH 229 47.370 40.030 16.430 1.00 0.00 +ATOM 1161 OW HOH 230 6.210 7.680 38.110 1.00 0.00 +ATOM 1162 HW1 HOH 230 6.560 7.450 38.970 1.00 0.00 +ATOM 1163 HW2 HOH 230 5.650 8.450 38.270 1.00 0.00 +ATOM 1164 OW HOH 231 10.270 27.550 13.810 1.00 0.00 +ATOM 1165 HW1 HOH 231 10.040 27.750 14.710 1.00 0.00 +ATOM 1166 HW2 HOH 231 10.400 26.600 13.790 1.00 0.00 +ATOM 1167 OW HOH 232 21.730 27.080 1.790 1.00 0.00 +ATOM 1168 HW1 HOH 232 21.710 27.130 2.750 1.00 0.00 +ATOM 1169 HW2 HOH 232 21.000 26.490 1.570 1.00 0.00 +ATOM 1170 OW HOH 233 18.320 38.510 26.670 1.00 0.00 +ATOM 1171 HW1 HOH 233 19.060 37.930 26.850 1.00 0.00 +ATOM 1172 HW2 HOH 233 18.020 38.800 27.530 1.00 0.00 +ATOM 1173 OW HOH 234 25.450 17.020 34.220 1.00 0.00 +ATOM 1174 HW1 HOH 234 25.320 17.060 35.170 1.00 0.00 +ATOM 1175 HW2 HOH 234 24.580 17.150 33.850 1.00 0.00 +ATOM 1176 OW HOH 235 24.110 1.630 18.960 1.00 0.00 +ATOM 1177 HW1 HOH 235 23.350 1.400 19.490 1.00 0.00 +ATOM 1178 HW2 HOH 235 24.440 2.440 19.360 1.00 0.00 +ATOM 1179 OW HOH 236 29.800 34.640 8.250 1.00 0.00 +ATOM 1180 HW1 HOH 236 29.040 35.030 8.680 1.00 0.00 +ATOM 1181 HW2 HOH 236 30.470 35.320 8.270 1.00 0.00 +ATOM 1182 OW HOH 237 47.750 32.230 6.170 1.00 0.00 +ATOM 1183 HW1 HOH 237 46.850 32.420 6.440 1.00 0.00 +ATOM 1184 HW2 HOH 237 47.660 31.640 5.420 1.00 0.00 +ATOM 1185 OW HOH 238 29.800 40.860 25.160 1.00 0.00 +ATOM 1186 HW1 HOH 238 30.290 40.040 25.080 1.00 0.00 +ATOM 1187 HW2 HOH 238 29.160 40.690 25.850 1.00 0.00 +ATOM 1188 OW HOH 239 38.980 41.530 35.120 1.00 0.00 +ATOM 1189 HW1 HOH 239 39.580 41.690 34.390 1.00 0.00 +ATOM 1190 HW2 HOH 239 38.110 41.530 34.710 1.00 0.00 +ATOM 1191 OW HOH 240 46.570 13.530 30.020 1.00 0.00 +ATOM 1192 HW1 HOH 240 47.330 13.090 30.400 1.00 0.00 +ATOM 1193 HW2 HOH 240 46.300 14.150 30.690 1.00 0.00 +ATOM 1194 OW HOH 241 1.230 17.920 35.020 1.00 0.00 +ATOM 1195 HW1 HOH 241 0.470 18.470 34.830 1.00 0.00 +ATOM 1196 HW2 HOH 241 1.050 17.110 34.550 1.00 0.00 +ATOM 1197 OW HOH 242 18.250 29.430 20.030 1.00 0.00 +ATOM 1198 HW1 HOH 242 18.020 29.410 20.960 1.00 0.00 +ATOM 1199 HW2 HOH 242 17.760 28.710 19.640 1.00 0.00 +ATOM 1200 OW HOH 243 48.760 21.510 6.890 1.00 0.00 +ATOM 1201 HW1 HOH 243 49.330 22.120 6.420 1.00 0.00 +ATOM 1202 HW2 HOH 243 48.690 20.750 6.310 1.00 0.00 +ATOM 1203 OW HOH 244 26.800 12.960 5.730 1.00 0.00 +ATOM 1204 HW1 HOH 244 27.030 12.030 5.800 1.00 0.00 +ATOM 1205 HW2 HOH 244 27.030 13.330 6.580 1.00 0.00 +ATOM 1206 OW HOH 245 42.480 42.770 37.350 1.00 0.00 +ATOM 1207 HW1 HOH 245 42.640 42.330 36.520 1.00 0.00 +ATOM 1208 HW2 HOH 245 43.250 43.310 37.490 1.00 0.00 +ATOM 1209 OW HOH 246 12.300 19.990 19.070 1.00 0.00 +ATOM 1210 HW1 HOH 246 11.570 20.050 19.690 1.00 0.00 +ATOM 1211 HW2 HOH 246 12.930 20.650 19.380 1.00 0.00 +ATOM 1212 OW HOH 247 34.450 11.310 24.230 1.00 0.00 +ATOM 1213 HW1 HOH 247 34.910 11.940 23.670 1.00 0.00 +ATOM 1214 HW2 HOH 247 34.460 10.490 23.720 1.00 0.00 +ATOM 1215 OW HOH 248 19.760 21.650 29.910 1.00 0.00 +ATOM 1216 HW1 HOH 248 20.440 21.030 30.170 1.00 0.00 +ATOM 1217 HW2 HOH 248 19.520 21.390 29.020 1.00 0.00 +ATOM 1218 OW HOH 249 48.210 8.310 24.070 1.00 0.00 +ATOM 1219 HW1 HOH 249 47.320 7.960 24.150 1.00 0.00 +ATOM 1220 HW2 HOH 249 48.240 9.050 24.680 1.00 0.00 +ATOM 1221 OW HOH 250 6.930 28.420 37.280 1.00 0.00 +ATOM 1222 HW1 HOH 250 6.690 27.510 37.480 1.00 0.00 +ATOM 1223 HW2 HOH 250 6.090 28.870 37.190 1.00 0.00 +ATOM 1224 OW HOH 251 7.030 27.350 33.720 1.00 0.00 +ATOM 1225 HW1 HOH 251 7.080 27.470 32.780 1.00 0.00 +ATOM 1226 HW2 HOH 251 6.440 28.040 34.020 1.00 0.00 +ATOM 1227 OW HOH 252 15.790 31.530 0.340 1.00 0.00 +ATOM 1228 HW1 HOH 252 15.240 31.310 -0.410 1.00 0.00 +ATOM 1229 HW2 HOH 252 15.790 32.490 0.360 1.00 0.00 +ATOM 1230 OW HOH 253 9.360 42.740 13.540 1.00 0.00 +ATOM 1231 HW1 HOH 253 9.730 42.840 14.420 1.00 0.00 +ATOM 1232 HW2 HOH 253 8.410 42.710 13.680 1.00 0.00 +ATOM 1233 OW HOH 254 12.160 33.910 34.160 1.00 0.00 +ATOM 1234 HW1 HOH 254 12.180 33.500 35.030 1.00 0.00 +ATOM 1235 HW2 HOH 254 12.910 34.500 34.160 1.00 0.00 +ATOM 1236 OW HOH 255 43.540 2.620 0.890 1.00 0.00 +ATOM 1237 HW1 HOH 255 42.770 2.890 0.390 1.00 0.00 +ATOM 1238 HW2 HOH 255 43.380 1.690 1.090 1.00 0.00 +ATOM 1239 OW HOH 256 8.740 32.770 26.690 1.00 0.00 +ATOM 1240 HW1 HOH 256 8.620 31.880 26.350 1.00 0.00 +ATOM 1241 HW2 HOH 256 8.640 33.330 25.930 1.00 0.00 +ATOM 1242 OW HOH 257 27.730 11.640 36.170 1.00 0.00 +ATOM 1243 HW1 HOH 257 26.950 11.120 36.370 1.00 0.00 +ATOM 1244 HW2 HOH 257 28.360 11.010 35.820 1.00 0.00 +ATOM 1245 OW HOH 258 11.500 16.030 33.900 1.00 0.00 +ATOM 1246 HW1 HOH 258 11.050 15.290 33.490 1.00 0.00 +ATOM 1247 HW2 HOH 258 12.190 16.270 33.290 1.00 0.00 +ATOM 1248 OW HOH 259 7.380 21.660 35.520 1.00 0.00 +ATOM 1249 HW1 HOH 259 7.280 22.270 34.780 1.00 0.00 +ATOM 1250 HW2 HOH 259 8.320 21.480 35.570 1.00 0.00 +ATOM 1251 OW HOH 260 42.880 12.150 15.160 1.00 0.00 +ATOM 1252 HW1 HOH 260 43.490 12.830 14.880 1.00 0.00 +ATOM 1253 HW2 HOH 260 42.020 12.570 15.140 1.00 0.00 +ATOM 1254 OW HOH 261 41.060 14.020 10.010 1.00 0.00 +ATOM 1255 HW1 HOH 261 40.580 14.820 10.190 1.00 0.00 +ATOM 1256 HW2 HOH 261 41.800 14.300 9.470 1.00 0.00 +ATOM 1257 OW HOH 262 37.310 10.110 35.170 1.00 0.00 +ATOM 1258 HW1 HOH 262 37.790 10.660 35.780 1.00 0.00 +ATOM 1259 HW2 HOH 262 36.750 9.570 35.720 1.00 0.00 +ATOM 1260 OW HOH 263 8.450 21.850 15.150 1.00 0.00 +ATOM 1261 HW1 HOH 263 8.960 21.290 14.570 1.00 0.00 +ATOM 1262 HW2 HOH 263 9.090 22.170 15.790 1.00 0.00 +ATOM 1263 OW HOH 264 8.050 45.320 2.530 1.00 0.00 +ATOM 1264 HW1 HOH 264 7.460 45.890 2.040 1.00 0.00 +ATOM 1265 HW2 HOH 264 8.890 45.770 2.510 1.00 0.00 +ATOM 1266 OW HOH 265 42.000 38.580 32.870 1.00 0.00 +ATOM 1267 HW1 HOH 265 41.350 39.230 33.150 1.00 0.00 +ATOM 1268 HW2 HOH 265 41.510 37.990 32.290 1.00 0.00 +ATOM 1269 OW HOH 266 22.420 6.300 11.880 1.00 0.00 +ATOM 1270 HW1 HOH 266 23.320 6.380 12.210 1.00 0.00 +ATOM 1271 HW2 HOH 266 22.480 6.610 10.980 1.00 0.00 +ATOM 1272 OW HOH 267 10.950 13.540 21.620 1.00 0.00 +ATOM 1273 HW1 HOH 267 10.870 12.890 20.930 1.00 0.00 +ATOM 1274 HW2 HOH 267 10.140 13.450 22.130 1.00 0.00 +ATOM 1275 OW HOH 268 40.390 9.070 1.780 1.00 0.00 +ATOM 1276 HW1 HOH 268 40.070 9.370 2.620 1.00 0.00 +ATOM 1277 HW2 HOH 268 41.260 9.460 1.690 1.00 0.00 +ATOM 1278 OW HOH 269 11.370 23.640 13.540 1.00 0.00 +ATOM 1279 HW1 HOH 269 11.660 23.710 12.640 1.00 0.00 +ATOM 1280 HW2 HOH 269 10.890 22.800 13.580 1.00 0.00 +ATOM 1281 OW HOH 270 34.430 10.790 37.890 1.00 0.00 +ATOM 1282 HW1 HOH 270 33.950 11.580 38.120 1.00 0.00 +ATOM 1283 HW2 HOH 270 34.600 10.870 36.950 1.00 0.00 +ATOM 1284 OW HOH 271 3.110 13.210 22.380 1.00 0.00 +ATOM 1285 HW1 HOH 271 2.420 13.680 22.830 1.00 0.00 +ATOM 1286 HW2 HOH 271 3.210 12.390 22.870 1.00 0.00 +ATOM 1287 OW HOH 272 16.060 44.220 4.450 1.00 0.00 +ATOM 1288 HW1 HOH 272 16.880 44.050 3.990 1.00 0.00 +ATOM 1289 HW2 HOH 272 16.130 43.710 5.260 1.00 0.00 +ATOM 1290 OW HOH 273 17.980 23.220 4.780 1.00 0.00 +ATOM 1291 HW1 HOH 273 17.930 22.470 4.190 1.00 0.00 +ATOM 1292 HW2 HOH 273 17.080 23.540 4.840 1.00 0.00 +ATOM 1293 OW HOH 274 39.200 9.430 37.980 1.00 0.00 +ATOM 1294 HW1 HOH 274 40.030 9.190 37.550 1.00 0.00 +ATOM 1295 HW2 HOH 274 39.400 9.370 38.910 1.00 0.00 +ATOM 1296 OW HOH 275 4.640 8.860 31.970 1.00 0.00 +ATOM 1297 HW1 HOH 275 5.320 8.190 31.970 1.00 0.00 +ATOM 1298 HW2 HOH 275 5.070 9.640 32.320 1.00 0.00 +ATOM 1299 OW HOH 276 27.270 45.640 13.880 1.00 0.00 +ATOM 1300 HW1 HOH 276 27.370 44.890 14.470 1.00 0.00 +ATOM 1301 HW2 HOH 276 26.980 45.260 13.060 1.00 0.00 +ATOM 1302 OW HOH 277 25.380 40.240 6.230 1.00 0.00 +ATOM 1303 HW1 HOH 277 25.200 40.000 5.320 1.00 0.00 +ATOM 1304 HW2 HOH 277 24.750 39.730 6.740 1.00 0.00 +ATOM 1305 OW HOH 278 19.070 4.690 23.030 1.00 0.00 +ATOM 1306 HW1 HOH 278 18.670 3.880 23.330 1.00 0.00 +ATOM 1307 HW2 HOH 278 19.570 5.010 23.780 1.00 0.00 +ATOM 1308 OW HOH 279 46.620 36.870 21.500 1.00 0.00 +ATOM 1309 HW1 HOH 279 45.890 36.340 21.820 1.00 0.00 +ATOM 1310 HW2 HOH 279 46.390 37.080 20.600 1.00 0.00 +ATOM 1311 OW HOH 280 6.850 10.140 6.310 1.00 0.00 +ATOM 1312 HW1 HOH 280 7.180 11.010 6.500 1.00 0.00 +ATOM 1313 HW2 HOH 280 6.530 10.190 5.410 1.00 0.00 +ATOM 1314 OW HOH 281 33.120 41.100 12.670 1.00 0.00 +ATOM 1315 HW1 HOH 281 33.000 40.210 13.010 1.00 0.00 +ATOM 1316 HW2 HOH 281 33.630 40.980 11.870 1.00 0.00 +ATOM 1317 OW HOH 282 37.350 39.980 16.430 1.00 0.00 +ATOM 1318 HW1 HOH 282 37.920 40.220 17.160 1.00 0.00 +ATOM 1319 HW2 HOH 282 36.820 40.760 16.270 1.00 0.00 +ATOM 1320 OW HOH 283 33.510 10.740 12.070 1.00 0.00 +ATOM 1321 HW1 HOH 283 34.000 9.920 12.180 1.00 0.00 +ATOM 1322 HW2 HOH 283 33.250 10.740 11.140 1.00 0.00 +ATOM 1323 OW HOH 284 26.750 36.180 35.290 1.00 0.00 +ATOM 1324 HW1 HOH 284 26.190 36.950 35.260 1.00 0.00 +ATOM 1325 HW2 HOH 284 26.640 35.830 36.180 1.00 0.00 +ATOM 1326 OW HOH 285 5.810 29.060 20.740 1.00 0.00 +ATOM 1327 HW1 HOH 285 5.260 28.710 20.040 1.00 0.00 +ATOM 1328 HW2 HOH 285 6.410 29.660 20.300 1.00 0.00 +ATOM 1329 OW HOH 286 8.830 14.000 17.220 1.00 0.00 +ATOM 1330 HW1 HOH 286 8.890 13.990 16.260 1.00 0.00 +ATOM 1331 HW2 HOH 286 8.690 13.090 17.460 1.00 0.00 +ATOM 1332 OW HOH 287 5.200 10.110 23.120 1.00 0.00 +ATOM 1333 HW1 HOH 287 5.720 10.800 22.720 1.00 0.00 +ATOM 1334 HW2 HOH 287 4.350 10.510 23.280 1.00 0.00 +ATOM 1335 OW HOH 288 40.280 7.080 27.560 1.00 0.00 +ATOM 1336 HW1 HOH 288 39.700 6.350 27.350 1.00 0.00 +ATOM 1337 HW2 HOH 288 40.930 6.710 28.160 1.00 0.00 +ATOM 1338 OW HOH 289 40.990 0.070 4.480 1.00 0.00 +ATOM 1339 HW1 HOH 289 40.600 0.680 3.850 1.00 0.00 +ATOM 1340 HW2 HOH 289 41.060 0.570 5.290 1.00 0.00 +ATOM 1341 OW HOH 290 34.730 21.280 27.040 1.00 0.00 +ATOM 1342 HW1 HOH 290 33.850 21.640 27.160 1.00 0.00 +ATOM 1343 HW2 HOH 290 35.090 21.230 27.930 1.00 0.00 +ATOM 1344 OW HOH 291 4.810 39.540 29.710 1.00 0.00 +ATOM 1345 HW1 HOH 291 4.590 39.910 28.860 1.00 0.00 +ATOM 1346 HW2 HOH 291 4.720 40.270 30.320 1.00 0.00 +ATOM 1347 OW HOH 292 25.400 19.070 38.080 1.00 0.00 +ATOM 1348 HW1 HOH 292 26.130 19.100 37.460 1.00 0.00 +ATOM 1349 HW2 HOH 292 24.960 19.920 37.980 1.00 0.00 +ATOM 1350 OW HOH 293 42.640 35.120 3.400 1.00 0.00 +ATOM 1351 HW1 HOH 293 42.190 34.640 2.710 1.00 0.00 +ATOM 1352 HW2 HOH 293 43.300 35.640 2.950 1.00 0.00 +ATOM 1353 OW HOH 294 17.040 34.660 11.400 1.00 0.00 +ATOM 1354 HW1 HOH 294 16.780 34.370 10.530 1.00 0.00 +ATOM 1355 HW2 HOH 294 16.250 34.570 11.930 1.00 0.00 +ATOM 1356 OW HOH 295 17.750 28.180 2.620 1.00 0.00 +ATOM 1357 HW1 HOH 295 18.160 27.410 3.020 1.00 0.00 +ATOM 1358 HW2 HOH 295 16.900 28.260 3.060 1.00 0.00 +ATOM 1359 OW HOH 296 8.150 8.700 32.570 1.00 0.00 +ATOM 1360 HW1 HOH 296 7.950 7.840 32.190 1.00 0.00 +ATOM 1361 HW2 HOH 296 9.020 8.920 32.230 1.00 0.00 +ATOM 1362 OW HOH 297 2.250 34.180 0.860 1.00 0.00 +ATOM 1363 HW1 HOH 297 3.050 34.070 1.380 1.00 0.00 +ATOM 1364 HW2 HOH 297 2.520 34.710 0.110 1.00 0.00 +ATOM 1365 OW HOH 298 7.000 3.830 31.120 1.00 0.00 +ATOM 1366 HW1 HOH 298 7.670 4.390 31.530 1.00 0.00 +ATOM 1367 HW2 HOH 298 7.490 3.270 30.520 1.00 0.00 +ATOM 1368 OW HOH 299 8.510 40.160 2.460 1.00 0.00 +ATOM 1369 HW1 HOH 299 8.190 41.060 2.420 1.00 0.00 +ATOM 1370 HW2 HOH 299 8.990 40.040 1.630 1.00 0.00 +ATOM 1371 OW HOH 300 16.270 40.350 15.110 1.00 0.00 +ATOM 1372 HW1 HOH 300 15.680 40.340 15.870 1.00 0.00 +ATOM 1373 HW2 HOH 300 15.780 39.870 14.440 1.00 0.00 +ATOM 1374 OW HOH 301 0.460 42.850 22.290 1.00 0.00 +ATOM 1375 HW1 HOH 301 0.960 43.610 22.000 1.00 0.00 +ATOM 1376 HW2 HOH 301 -0.400 43.200 22.520 1.00 0.00 +ATOM 1377 OW HOH 302 23.950 9.590 26.640 1.00 0.00 +ATOM 1378 HW1 HOH 302 23.660 9.020 25.920 1.00 0.00 +ATOM 1379 HW2 HOH 302 23.390 10.360 26.560 1.00 0.00 +ATOM 1380 OW HOH 303 14.360 16.090 19.680 1.00 0.00 +ATOM 1381 HW1 HOH 303 15.160 16.570 19.930 1.00 0.00 +ATOM 1382 HW2 HOH 303 14.660 15.190 19.540 1.00 0.00 +ATOM 1383 OW HOH 304 30.740 18.580 10.510 1.00 0.00 +ATOM 1384 HW1 HOH 304 29.910 18.220 10.830 1.00 0.00 +ATOM 1385 HW2 HOH 304 31.380 18.290 11.160 1.00 0.00 +ATOM 1386 OW HOH 305 43.820 19.920 35.830 1.00 0.00 +ATOM 1387 HW1 HOH 305 43.250 19.220 35.520 1.00 0.00 +ATOM 1388 HW2 HOH 305 43.800 20.570 35.130 1.00 0.00 +ATOM 1389 OW HOH 306 7.850 25.950 14.490 1.00 0.00 +ATOM 1390 HW1 HOH 306 7.170 25.380 14.130 1.00 0.00 +ATOM 1391 HW2 HOH 306 7.700 26.790 14.070 1.00 0.00 +ATOM 1392 OW HOH 307 13.540 0.320 20.940 1.00 0.00 +ATOM 1393 HW1 HOH 307 12.880 0.960 20.670 1.00 0.00 +ATOM 1394 HW2 HOH 307 14.310 0.520 20.420 1.00 0.00 +ATOM 1395 OW HOH 308 38.290 1.720 27.760 1.00 0.00 +ATOM 1396 HW1 HOH 308 37.460 2.190 27.780 1.00 0.00 +ATOM 1397 HW2 HOH 308 38.300 1.270 26.920 1.00 0.00 +ATOM 1398 OW HOH 309 14.780 7.680 2.660 1.00 0.00 +ATOM 1399 HW1 HOH 309 15.300 7.510 3.450 1.00 0.00 +ATOM 1400 HW2 HOH 309 14.480 6.810 2.390 1.00 0.00 +ATOM 1401 OW HOH 310 31.160 9.130 16.670 1.00 0.00 +ATOM 1402 HW1 HOH 310 31.930 9.140 17.240 1.00 0.00 +ATOM 1403 HW2 HOH 310 31.470 9.460 15.830 1.00 0.00 +ATOM 1404 OW HOH 311 44.830 6.410 32.040 1.00 0.00 +ATOM 1405 HW1 HOH 311 44.480 5.810 32.690 1.00 0.00 +ATOM 1406 HW2 HOH 311 44.160 7.080 31.940 1.00 0.00 +ATOM 1407 OW HOH 312 44.010 8.880 21.750 1.00 0.00 +ATOM 1408 HW1 HOH 312 44.110 8.460 20.900 1.00 0.00 +ATOM 1409 HW2 HOH 312 43.370 9.580 21.600 1.00 0.00 +ATOM 1410 OW HOH 313 19.870 31.440 18.680 1.00 0.00 +ATOM 1411 HW1 HOH 313 19.370 32.230 18.890 1.00 0.00 +ATOM 1412 HW2 HOH 313 19.470 30.750 19.200 1.00 0.00 +ATOM 1413 OW HOH 314 3.430 17.770 24.000 1.00 0.00 +ATOM 1414 HW1 HOH 314 3.340 17.100 24.670 1.00 0.00 +ATOM 1415 HW2 HOH 314 3.940 18.460 24.420 1.00 0.00 +ATOM 1416 OW HOH 315 11.490 27.500 34.600 1.00 0.00 +ATOM 1417 HW1 HOH 315 12.350 27.680 34.970 1.00 0.00 +ATOM 1418 HW2 HOH 315 10.880 27.950 35.170 1.00 0.00 +ATOM 1419 OW HOH 316 1.140 23.050 19.480 1.00 0.00 +ATOM 1420 HW1 HOH 316 1.570 23.740 18.980 1.00 0.00 +ATOM 1421 HW2 HOH 316 1.250 23.310 20.390 1.00 0.00 +ATOM 1422 OW HOH 317 6.910 42.720 35.160 1.00 0.00 +ATOM 1423 HW1 HOH 317 6.680 43.370 34.490 1.00 0.00 +ATOM 1424 HW2 HOH 317 6.120 42.190 35.270 1.00 0.00 +ATOM 1425 OW HOH 318 49.040 15.800 13.860 1.00 0.00 +ATOM 1426 HW1 HOH 318 48.210 16.260 13.760 1.00 0.00 +ATOM 1427 HW2 HOH 318 48.960 15.330 14.690 1.00 0.00 +ATOM 1428 OW HOH 319 17.690 9.800 26.120 1.00 0.00 +ATOM 1429 HW1 HOH 319 17.150 10.520 26.460 1.00 0.00 +ATOM 1430 HW2 HOH 319 17.700 9.160 26.830 1.00 0.00 +ATOM 1431 OW HOH 320 10.930 20.600 24.970 1.00 0.00 +ATOM 1432 HW1 HOH 320 10.480 21.230 24.410 1.00 0.00 +ATOM 1433 HW2 HOH 320 10.680 19.740 24.620 1.00 0.00 +ATOM 1434 OW HOH 321 31.410 17.430 23.480 1.00 0.00 +ATOM 1435 HW1 HOH 321 30.810 18.130 23.750 1.00 0.00 +ATOM 1436 HW2 HOH 321 32.210 17.590 23.980 1.00 0.00 +ATOM 1437 OW HOH 322 3.390 3.800 13.950 1.00 0.00 +ATOM 1438 HW1 HOH 322 3.430 4.670 13.540 1.00 0.00 +ATOM 1439 HW2 HOH 322 4.100 3.810 14.580 1.00 0.00 +ATOM 1440 OW HOH 323 30.510 14.680 35.350 1.00 0.00 +ATOM 1441 HW1 HOH 323 29.970 13.930 35.600 1.00 0.00 +ATOM 1442 HW2 HOH 323 30.730 15.110 36.180 1.00 0.00 +ATOM 1443 OW HOH 324 14.900 32.270 34.570 1.00 0.00 +ATOM 1444 HW1 HOH 324 14.780 32.670 33.710 1.00 0.00 +ATOM 1445 HW2 HOH 324 15.800 31.930 34.560 1.00 0.00 +ATOM 1446 OW HOH 325 45.860 45.140 26.790 1.00 0.00 +ATOM 1447 HW1 HOH 325 46.390 44.410 26.490 1.00 0.00 +ATOM 1448 HW2 HOH 325 45.080 44.730 27.170 1.00 0.00 +ATOM 1449 OW HOH 326 8.050 0.840 7.570 1.00 0.00 +ATOM 1450 HW1 HOH 326 7.880 -0.090 7.710 1.00 0.00 +ATOM 1451 HW2 HOH 326 8.130 1.200 8.450 1.00 0.00 +ATOM 1452 OW HOH 327 47.360 39.360 27.680 1.00 0.00 +ATOM 1453 HW1 HOH 327 46.880 38.530 27.740 1.00 0.00 +ATOM 1454 HW2 HOH 327 46.990 39.890 28.390 1.00 0.00 +ATOM 1455 OW HOH 328 23.390 38.300 7.810 1.00 0.00 +ATOM 1456 HW1 HOH 328 22.870 38.440 7.010 1.00 0.00 +ATOM 1457 HW2 HOH 328 22.980 37.540 8.220 1.00 0.00 +ATOM 1458 OW HOH 329 40.290 5.670 32.710 1.00 0.00 +ATOM 1459 HW1 HOH 329 39.940 4.960 33.250 1.00 0.00 +ATOM 1460 HW2 HOH 329 40.110 6.460 33.210 1.00 0.00 +ATOM 1461 OW HOH 330 4.370 19.790 21.290 1.00 0.00 +ATOM 1462 HW1 HOH 330 3.740 20.460 21.550 1.00 0.00 +ATOM 1463 HW2 HOH 330 5.190 20.270 21.180 1.00 0.00 +ATOM 1464 OW HOH 331 41.720 17.910 19.210 1.00 0.00 +ATOM 1465 HW1 HOH 331 41.820 17.200 18.570 1.00 0.00 +ATOM 1466 HW2 HOH 331 41.040 17.600 19.800 1.00 0.00 +ATOM 1467 OW HOH 332 6.470 45.420 9.530 1.00 0.00 +ATOM 1468 HW1 HOH 332 5.690 45.940 9.330 1.00 0.00 +ATOM 1469 HW2 HOH 332 6.770 45.760 10.380 1.00 0.00 +ATOM 1470 OW HOH 333 9.940 6.350 15.570 1.00 0.00 +ATOM 1471 HW1 HOH 333 9.150 6.670 15.990 1.00 0.00 +ATOM 1472 HW2 HOH 333 10.080 5.480 15.940 1.00 0.00 +ATOM 1473 OW HOH 334 42.910 3.000 3.430 1.00 0.00 +ATOM 1474 HW1 HOH 334 43.020 3.120 2.490 1.00 0.00 +ATOM 1475 HW2 HOH 334 43.120 2.070 3.580 1.00 0.00 +ATOM 1476 OW HOH 335 46.220 45.230 4.720 1.00 0.00 +ATOM 1477 HW1 HOH 335 46.340 44.560 4.040 1.00 0.00 +ATOM 1478 HW2 HOH 335 47.100 45.340 5.100 1.00 0.00 +ATOM 1479 OW HOH 336 37.630 15.710 25.840 1.00 0.00 +ATOM 1480 HW1 HOH 336 38.490 15.310 25.960 1.00 0.00 +ATOM 1481 HW2 HOH 336 37.790 16.650 25.950 1.00 0.00 +ATOM 1482 OW HOH 337 28.680 37.170 9.270 1.00 0.00 +ATOM 1483 HW1 HOH 337 28.590 38.050 8.920 1.00 0.00 +ATOM 1484 HW2 HOH 337 28.050 37.130 9.990 1.00 0.00 +ATOM 1485 OW HOH 338 17.170 23.950 38.380 1.00 0.00 +ATOM 1486 HW1 HOH 338 17.280 23.470 37.560 1.00 0.00 +ATOM 1487 HW2 HOH 338 17.350 24.860 38.140 1.00 0.00 +ATOM 1488 OW HOH 339 43.360 22.790 22.770 1.00 0.00 +ATOM 1489 HW1 HOH 339 43.770 23.310 22.080 1.00 0.00 +ATOM 1490 HW2 HOH 339 42.650 22.320 22.330 1.00 0.00 +ATOM 1491 OW HOH 340 17.990 9.930 7.090 1.00 0.00 +ATOM 1492 HW1 HOH 340 17.470 10.440 6.470 1.00 0.00 +ATOM 1493 HW2 HOH 340 17.800 10.330 7.940 1.00 0.00 +ATOM 1494 OW HOH 341 22.000 4.420 14.900 1.00 0.00 +ATOM 1495 HW1 HOH 341 21.390 4.390 14.160 1.00 0.00 +ATOM 1496 HW2 HOH 341 22.420 5.280 14.830 1.00 0.00 +ATOM 1497 OW HOH 342 10.070 9.720 30.540 1.00 0.00 +ATOM 1498 HW1 HOH 342 9.310 10.290 30.550 1.00 0.00 +ATOM 1499 HW2 HOH 342 10.800 10.300 30.300 1.00 0.00 +ATOM 1500 OW HOH 343 35.610 12.940 35.680 1.00 0.00 +ATOM 1501 HW1 HOH 343 35.210 12.170 35.290 1.00 0.00 +ATOM 1502 HW2 HOH 343 36.420 12.620 36.070 1.00 0.00 +ATOM 1503 OW HOH 344 20.210 23.580 36.560 1.00 0.00 +ATOM 1504 HW1 HOH 344 19.790 23.970 35.790 1.00 0.00 +ATOM 1505 HW2 HOH 344 20.680 24.310 36.970 1.00 0.00 +ATOM 1506 OW HOH 345 18.460 32.200 22.970 1.00 0.00 +ATOM 1507 HW1 HOH 345 17.690 32.750 22.830 1.00 0.00 +ATOM 1508 HW2 HOH 345 18.170 31.540 23.600 1.00 0.00 +ATOM 1509 OW HOH 346 5.500 11.370 14.920 1.00 0.00 +ATOM 1510 HW1 HOH 346 5.170 11.270 14.030 1.00 0.00 +ATOM 1511 HW2 HOH 346 4.720 11.450 15.470 1.00 0.00 +ATOM 1512 OW HOH 347 7.090 15.430 12.360 1.00 0.00 +ATOM 1513 HW1 HOH 347 6.280 14.950 12.550 1.00 0.00 +ATOM 1514 HW2 HOH 347 6.840 16.060 11.680 1.00 0.00 +ATOM 1515 OW HOH 348 0.840 38.410 27.590 1.00 0.00 +ATOM 1516 HW1 HOH 348 -0.050 38.700 27.380 1.00 0.00 +ATOM 1517 HW2 HOH 348 1.250 38.260 26.740 1.00 0.00 +ATOM 1518 OW HOH 349 34.370 21.010 1.200 1.00 0.00 +ATOM 1519 HW1 HOH 349 33.860 20.710 0.440 1.00 0.00 +ATOM 1520 HW2 HOH 349 35.220 21.260 0.840 1.00 0.00 +ATOM 1521 OW HOH 350 12.810 1.730 16.890 1.00 0.00 +ATOM 1522 HW1 HOH 350 12.060 1.160 17.040 1.00 0.00 +ATOM 1523 HW2 HOH 350 12.600 2.540 17.360 1.00 0.00 +ATOM 1524 OW HOH 351 32.810 3.660 3.670 1.00 0.00 +ATOM 1525 HW1 HOH 351 33.310 2.950 4.080 1.00 0.00 +ATOM 1526 HW2 HOH 351 32.540 4.220 4.400 1.00 0.00 +ATOM 1527 OW HOH 352 12.810 1.970 25.710 1.00 0.00 +ATOM 1528 HW1 HOH 352 12.650 1.040 25.870 1.00 0.00 +ATOM 1529 HW2 HOH 352 11.950 2.380 25.790 1.00 0.00 +ATOM 1530 OW HOH 353 46.540 17.200 13.250 1.00 0.00 +ATOM 1531 HW1 HOH 353 46.400 16.780 12.400 1.00 0.00 +ATOM 1532 HW2 HOH 353 45.670 17.530 13.500 1.00 0.00 +ATOM 1533 OW HOH 354 29.480 27.700 5.110 1.00 0.00 +ATOM 1534 HW1 HOH 354 30.290 28.030 4.740 1.00 0.00 +ATOM 1535 HW2 HOH 354 29.010 28.480 5.420 1.00 0.00 +ATOM 1536 OW HOH 355 29.540 12.960 4.600 1.00 0.00 +ATOM 1537 HW1 HOH 355 28.720 13.140 4.140 1.00 0.00 +ATOM 1538 HW2 HOH 355 29.520 13.530 5.360 1.00 0.00 +ATOM 1539 OW HOH 356 36.270 28.650 2.840 1.00 0.00 +ATOM 1540 HW1 HOH 356 35.660 27.910 2.910 1.00 0.00 +ATOM 1541 HW2 HOH 356 35.710 29.430 2.870 1.00 0.00 +ATOM 1542 OW HOH 357 17.670 2.290 23.400 1.00 0.00 +ATOM 1543 HW1 HOH 357 17.180 1.610 22.950 1.00 0.00 +ATOM 1544 HW2 HOH 357 17.380 2.240 24.310 1.00 0.00 +ATOM 1545 OW HOH 358 21.920 30.990 11.480 1.00 0.00 +ATOM 1546 HW1 HOH 358 21.070 31.390 11.290 1.00 0.00 +ATOM 1547 HW2 HOH 358 21.850 30.690 12.390 1.00 0.00 +ATOM 1548 OW HOH 359 27.110 23.810 2.080 1.00 0.00 +ATOM 1549 HW1 HOH 359 26.910 23.170 1.390 1.00 0.00 +ATOM 1550 HW2 HOH 359 27.500 24.550 1.610 1.00 0.00 +ATOM 1551 OW HOH 360 15.000 1.290 24.050 1.00 0.00 +ATOM 1552 HW1 HOH 360 14.380 1.660 24.690 1.00 0.00 +ATOM 1553 HW2 HOH 360 14.580 0.480 23.770 1.00 0.00 +ATOM 1554 OW HOH 361 38.310 25.500 32.040 1.00 0.00 +ATOM 1555 HW1 HOH 361 38.260 25.900 32.910 1.00 0.00 +ATOM 1556 HW2 HOH 361 38.040 24.590 32.180 1.00 0.00 +ATOM 1557 OW HOH 362 18.610 15.580 12.790 1.00 0.00 +ATOM 1558 HW1 HOH 362 19.450 15.630 12.340 1.00 0.00 +ATOM 1559 HW2 HOH 362 18.800 15.860 13.690 1.00 0.00 +ATOM 1560 OW HOH 363 1.760 44.140 0.870 1.00 0.00 +ATOM 1561 HW1 HOH 363 1.670 44.060 -0.080 1.00 0.00 +ATOM 1562 HW2 HOH 363 0.870 44.100 1.210 1.00 0.00 +ATOM 1563 OW HOH 364 29.850 11.840 26.370 1.00 0.00 +ATOM 1564 HW1 HOH 364 29.910 11.120 25.740 1.00 0.00 +ATOM 1565 HW2 HOH 364 30.760 12.070 26.560 1.00 0.00 +ATOM 1566 OW HOH 365 13.280 10.780 18.600 1.00 0.00 +ATOM 1567 HW1 HOH 365 14.230 10.790 18.720 1.00 0.00 +ATOM 1568 HW2 HOH 365 13.070 9.860 18.430 1.00 0.00 +ATOM 1569 OW HOH 366 31.640 40.860 9.990 1.00 0.00 +ATOM 1570 HW1 HOH 366 32.210 41.510 9.580 1.00 0.00 +ATOM 1571 HW2 HOH 366 30.880 41.360 10.290 1.00 0.00 +ATOM 1572 OW HOH 367 44.870 29.080 32.830 1.00 0.00 +ATOM 1573 HW1 HOH 367 45.500 28.420 33.130 1.00 0.00 +ATOM 1574 HW2 HOH 367 45.000 29.110 31.880 1.00 0.00 +ATOM 1575 OW HOH 368 30.760 29.930 16.520 1.00 0.00 +ATOM 1576 HW1 HOH 368 30.670 29.090 16.980 1.00 0.00 +ATOM 1577 HW2 HOH 368 30.100 29.900 15.820 1.00 0.00 +ATOM 1578 OW HOH 369 16.810 21.490 32.010 1.00 0.00 +ATOM 1579 HW1 HOH 369 16.030 21.810 32.460 1.00 0.00 +ATOM 1580 HW2 HOH 369 16.480 21.030 31.240 1.00 0.00 +ATOM 1581 OW HOH 370 4.210 30.800 11.850 1.00 0.00 +ATOM 1582 HW1 HOH 370 4.470 31.370 11.130 1.00 0.00 +ATOM 1583 HW2 HOH 370 4.790 30.040 11.770 1.00 0.00 +ATOM 1584 OW HOH 371 40.700 32.020 31.990 1.00 0.00 +ATOM 1585 HW1 HOH 371 41.140 32.570 32.630 1.00 0.00 +ATOM 1586 HW2 HOH 371 41.360 31.390 31.710 1.00 0.00 +ATOM 1587 OW HOH 372 13.670 31.820 2.530 1.00 0.00 +ATOM 1588 HW1 HOH 372 14.210 31.530 1.810 1.00 0.00 +ATOM 1589 HW2 HOH 372 12.780 31.520 2.300 1.00 0.00 +ATOM 1590 OW HOH 373 42.500 14.540 32.360 1.00 0.00 +ATOM 1591 HW1 HOH 373 41.640 14.370 32.760 1.00 0.00 +ATOM 1592 HW2 HOH 373 42.870 13.670 32.230 1.00 0.00 +ATOM 1593 OW HOH 374 30.860 38.330 4.990 1.00 0.00 +ATOM 1594 HW1 HOH 374 30.820 39.190 5.410 1.00 0.00 +ATOM 1595 HW2 HOH 374 30.150 37.830 5.390 1.00 0.00 +ATOM 1596 OW HOH 375 42.510 35.740 21.520 1.00 0.00 +ATOM 1597 HW1 HOH 375 41.630 36.130 21.490 1.00 0.00 +ATOM 1598 HW2 HOH 375 42.730 35.580 20.600 1.00 0.00 +ATOM 1599 OW HOH 376 7.890 0.030 12.000 1.00 0.00 +ATOM 1600 HW1 HOH 376 8.400 0.830 11.830 1.00 0.00 +ATOM 1601 HW2 HOH 376 8.560 -0.650 12.120 1.00 0.00 +ATOM 1602 OW HOH 377 25.060 21.870 2.840 1.00 0.00 +ATOM 1603 HW1 HOH 377 25.300 22.770 2.590 1.00 0.00 +ATOM 1604 HW2 HOH 377 24.180 21.950 3.200 1.00 0.00 +ATOM 1605 OW HOH 378 5.260 19.160 25.250 1.00 0.00 +ATOM 1606 HW1 HOH 378 5.360 19.790 24.540 1.00 0.00 +ATOM 1607 HW2 HOH 378 6.120 18.740 25.320 1.00 0.00 +ATOM 1608 OW HOH 379 8.790 25.640 30.500 1.00 0.00 +ATOM 1609 HW1 HOH 379 9.080 26.240 31.190 1.00 0.00 +ATOM 1610 HW2 HOH 379 9.320 24.850 30.640 1.00 0.00 +ATOM 1611 OW HOH 380 5.010 -0.270 4.090 1.00 0.00 +ATOM 1612 HW1 HOH 380 5.570 0.490 3.960 1.00 0.00 +ATOM 1613 HW2 HOH 380 4.310 -0.170 3.450 1.00 0.00 +ATOM 1614 OW HOH 381 29.160 9.980 34.540 1.00 0.00 +ATOM 1615 HW1 HOH 381 29.130 9.790 33.600 1.00 0.00 +ATOM 1616 HW2 HOH 381 29.670 9.270 34.920 1.00 0.00 +ATOM 1617 OW HOH 382 29.200 25.390 7.710 1.00 0.00 +ATOM 1618 HW1 HOH 382 30.000 25.850 7.940 1.00 0.00 +ATOM 1619 HW2 HOH 382 28.840 25.090 8.550 1.00 0.00 +ATOM 1620 OW HOH 383 23.420 38.340 28.250 1.00 0.00 +ATOM 1621 HW1 HOH 383 22.940 38.970 28.790 1.00 0.00 +ATOM 1622 HW2 HOH 383 22.830 37.590 28.170 1.00 0.00 +ATOM 1623 OW HOH 384 7.380 11.940 37.340 1.00 0.00 +ATOM 1624 HW1 HOH 384 7.350 11.390 36.560 1.00 0.00 +ATOM 1625 HW2 HOH 384 6.870 12.710 37.100 1.00 0.00 +ATOM 1626 OW HOH 385 20.210 13.690 14.760 1.00 0.00 +ATOM 1627 HW1 HOH 385 21.130 13.620 15.000 1.00 0.00 +ATOM 1628 HW2 HOH 385 20.130 13.210 13.940 1.00 0.00 +ATOM 1629 OW HOH 386 49.260 17.780 4.450 1.00 0.00 +ATOM 1630 HW1 HOH 386 48.580 18.450 4.420 1.00 0.00 +ATOM 1631 HW2 HOH 386 48.780 16.970 4.620 1.00 0.00 +ATOM 1632 OW HOH 387 9.660 32.120 15.010 1.00 0.00 +ATOM 1633 HW1 HOH 387 10.170 31.860 14.240 1.00 0.00 +ATOM 1634 HW2 HOH 387 9.560 33.070 14.910 1.00 0.00 +ATOM 1635 OW HOH 388 10.980 11.260 19.750 1.00 0.00 +ATOM 1636 HW1 HOH 388 10.450 11.240 18.950 1.00 0.00 +ATOM 1637 HW2 HOH 388 11.880 11.170 19.430 1.00 0.00 +ATOM 1638 OW HOH 389 17.580 6.040 8.540 1.00 0.00 +ATOM 1639 HW1 HOH 389 17.100 5.410 7.990 1.00 0.00 +ATOM 1640 HW2 HOH 389 16.970 6.770 8.660 1.00 0.00 +ATOM 1641 OW HOH 390 22.070 11.620 26.270 1.00 0.00 +ATOM 1642 HW1 HOH 390 21.770 11.360 27.140 1.00 0.00 +ATOM 1643 HW2 HOH 390 21.380 11.330 25.670 1.00 0.00 +ATOM 1644 OW HOH 391 24.580 37.900 12.340 1.00 0.00 +ATOM 1645 HW1 HOH 391 24.110 38.170 13.130 1.00 0.00 +ATOM 1646 HW2 HOH 391 24.530 38.660 11.760 1.00 0.00 +ATOM 1647 OW HOH 392 13.470 37.530 10.990 1.00 0.00 +ATOM 1648 HW1 HOH 392 13.910 36.870 10.450 1.00 0.00 +ATOM 1649 HW2 HOH 392 12.640 37.690 10.540 1.00 0.00 +ATOM 1650 OW HOH 393 37.020 31.120 30.540 1.00 0.00 +ATOM 1651 HW1 HOH 393 37.630 30.530 30.990 1.00 0.00 +ATOM 1652 HW2 HOH 393 37.540 31.520 29.850 1.00 0.00 +ATOM 1653 OW HOH 394 24.740 33.810 16.920 1.00 0.00 +ATOM 1654 HW1 HOH 394 25.000 34.330 16.150 1.00 0.00 +ATOM 1655 HW2 HOH 394 24.560 32.940 16.570 1.00 0.00 +ATOM 1656 OW HOH 395 8.880 18.840 16.040 1.00 0.00 +ATOM 1657 HW1 HOH 395 8.750 18.750 15.100 1.00 0.00 +ATOM 1658 HW2 HOH 395 9.340 18.040 16.300 1.00 0.00 +ATOM 1659 OW HOH 396 6.760 29.000 13.950 1.00 0.00 +ATOM 1660 HW1 HOH 396 7.530 29.010 14.520 1.00 0.00 +ATOM 1661 HW2 HOH 396 6.700 29.890 13.610 1.00 0.00 +ATOM 1662 OW HOH 397 19.750 26.200 15.190 1.00 0.00 +ATOM 1663 HW1 HOH 397 20.600 26.550 15.460 1.00 0.00 +ATOM 1664 HW2 HOH 397 19.710 26.350 14.250 1.00 0.00 +ATOM 1665 OW HOH 398 0.860 42.130 17.490 1.00 0.00 +ATOM 1666 HW1 HOH 398 0.640 41.510 18.190 1.00 0.00 +ATOM 1667 HW2 HOH 398 0.750 42.990 17.900 1.00 0.00 +ATOM 1668 OW HOH 399 17.480 25.080 18.070 1.00 0.00 +ATOM 1669 HW1 HOH 399 17.050 25.870 18.400 1.00 0.00 +ATOM 1670 HW2 HOH 399 18.090 24.830 18.760 1.00 0.00 +ATOM 1671 OW HOH 400 44.360 0.670 3.350 1.00 0.00 +ATOM 1672 HW1 HOH 400 44.780 0.380 4.170 1.00 0.00 +ATOM 1673 HW2 HOH 400 45.090 0.870 2.770 1.00 0.00 +ATOM 1674 OW HOH 401 7.010 17.290 10.100 1.00 0.00 +ATOM 1675 HW1 HOH 401 6.380 17.740 9.550 1.00 0.00 +ATOM 1676 HW2 HOH 401 7.630 17.970 10.370 1.00 0.00 +ATOM 1677 OW HOH 402 14.600 19.750 27.060 1.00 0.00 +ATOM 1678 HW1 HOH 402 15.420 19.640 26.580 1.00 0.00 +ATOM 1679 HW2 HOH 402 14.330 18.850 27.280 1.00 0.00 +ATOM 1680 OW HOH 403 18.690 8.570 35.620 1.00 0.00 +ATOM 1681 HW1 HOH 403 18.820 9.510 35.500 1.00 0.00 +ATOM 1682 HW2 HOH 403 18.280 8.490 36.480 1.00 0.00 +ATOM 1683 OW HOH 404 28.350 43.190 6.920 1.00 0.00 +ATOM 1684 HW1 HOH 404 27.480 43.450 6.640 1.00 0.00 +ATOM 1685 HW2 HOH 404 28.430 42.280 6.660 1.00 0.00 +ATOM 1686 OW HOH 405 23.990 43.000 1.190 1.00 0.00 +ATOM 1687 HW1 HOH 405 24.510 42.830 1.970 1.00 0.00 +ATOM 1688 HW2 HOH 405 24.570 43.480 0.610 1.00 0.00 +ATOM 1689 OW HOH 406 13.070 15.660 13.090 1.00 0.00 +ATOM 1690 HW1 HOH 406 13.950 15.300 13.210 1.00 0.00 +ATOM 1691 HW2 HOH 406 13.100 16.520 13.510 1.00 0.00 +ATOM 1692 OW HOH 407 47.530 16.160 26.010 1.00 0.00 +ATOM 1693 HW1 HOH 407 46.840 16.580 26.510 1.00 0.00 +ATOM 1694 HW2 HOH 407 47.080 15.720 25.290 1.00 0.00 +ATOM 1695 OW HOH 408 3.970 23.970 11.310 1.00 0.00 +ATOM 1696 HW1 HOH 408 3.240 24.570 11.180 1.00 0.00 +ATOM 1697 HW2 HOH 408 4.650 24.280 10.710 1.00 0.00 +ATOM 1698 OW HOH 409 16.820 18.540 25.930 1.00 0.00 +ATOM 1699 HW1 HOH 409 16.890 18.060 26.760 1.00 0.00 +ATOM 1700 HW2 HOH 409 17.720 18.830 25.750 1.00 0.00 +ATOM 1701 OW HOH 410 27.960 10.430 6.250 1.00 0.00 +ATOM 1702 HW1 HOH 410 27.740 9.530 6.470 1.00 0.00 +ATOM 1703 HW2 HOH 410 28.910 10.490 6.400 1.00 0.00 +ATOM 1704 OW HOH 411 14.510 14.220 5.140 1.00 0.00 +ATOM 1705 HW1 HOH 411 14.690 14.660 5.970 1.00 0.00 +ATOM 1706 HW2 HOH 411 13.600 14.420 4.950 1.00 0.00 +ATOM 1707 OW HOH 412 34.920 44.200 3.060 1.00 0.00 +ATOM 1708 HW1 HOH 412 34.900 43.450 3.660 1.00 0.00 +ATOM 1709 HW2 HOH 412 35.810 44.540 3.130 1.00 0.00 +ATOM 1710 OW HOH 413 14.510 27.500 14.740 1.00 0.00 +ATOM 1711 HW1 HOH 413 14.760 26.590 14.570 1.00 0.00 +ATOM 1712 HW2 HOH 413 14.200 27.500 15.650 1.00 0.00 +ATOM 1713 OW HOH 414 38.890 26.510 38.060 1.00 0.00 +ATOM 1714 HW1 HOH 414 37.950 26.550 38.230 1.00 0.00 +ATOM 1715 HW2 HOH 414 39.300 26.660 38.910 1.00 0.00 +ATOM 1716 OW HOH 415 7.700 9.800 20.610 1.00 0.00 +ATOM 1717 HW1 HOH 415 8.200 10.610 20.730 1.00 0.00 +ATOM 1718 HW2 HOH 415 8.290 9.110 20.900 1.00 0.00 +ATOM 1719 OW HOH 416 4.640 17.080 21.510 1.00 0.00 +ATOM 1720 HW1 HOH 416 4.800 17.920 21.070 1.00 0.00 +ATOM 1721 HW2 HOH 416 4.230 17.320 22.340 1.00 0.00 +ATOM 1722 OW HOH 417 31.660 20.600 24.390 1.00 0.00 +ATOM 1723 HW1 HOH 417 31.690 20.380 23.460 1.00 0.00 +ATOM 1724 HW2 HOH 417 31.210 21.450 24.420 1.00 0.00 +ATOM 1725 OW HOH 418 24.480 28.940 8.210 1.00 0.00 +ATOM 1726 HW1 HOH 418 24.200 29.850 8.320 1.00 0.00 +ATOM 1727 HW2 HOH 418 23.760 28.530 7.740 1.00 0.00 +ATOM 1728 OW HOH 419 10.390 13.820 29.610 1.00 0.00 +ATOM 1729 HW1 HOH 419 11.330 13.680 29.630 1.00 0.00 +ATOM 1730 HW2 HOH 419 10.240 14.400 28.860 1.00 0.00 +ATOM 1731 OW HOH 420 15.730 36.790 22.990 1.00 0.00 +ATOM 1732 HW1 HOH 420 15.790 37.570 23.550 1.00 0.00 +ATOM 1733 HW2 HOH 420 16.070 37.080 22.150 1.00 0.00 +ATOM 1734 OW HOH 421 19.920 1.860 27.660 1.00 0.00 +ATOM 1735 HW1 HOH 421 20.280 2.580 27.140 1.00 0.00 +ATOM 1736 HW2 HOH 421 20.510 1.790 28.420 1.00 0.00 +ATOM 1737 OW HOH 422 45.410 26.500 7.010 1.00 0.00 +ATOM 1738 HW1 HOH 422 45.190 27.360 6.650 1.00 0.00 +ATOM 1739 HW2 HOH 422 46.250 26.630 7.460 1.00 0.00 +ATOM 1740 OW HOH 423 24.730 10.290 0.450 1.00 0.00 +ATOM 1741 HW1 HOH 423 24.480 9.450 0.830 1.00 0.00 +ATOM 1742 HW2 HOH 423 25.610 10.150 0.120 1.00 0.00 +ATOM 1743 OW HOH 424 15.870 0.750 33.770 1.00 0.00 +ATOM 1744 HW1 HOH 424 16.580 0.340 34.260 1.00 0.00 +ATOM 1745 HW2 HOH 424 15.670 1.550 34.250 1.00 0.00 +ATOM 1746 OW HOH 425 18.320 25.650 9.170 1.00 0.00 +ATOM 1747 HW1 HOH 425 19.270 25.530 9.170 1.00 0.00 +ATOM 1748 HW2 HOH 425 17.970 24.810 8.880 1.00 0.00 +ATOM 1749 OW HOH 426 7.760 13.490 32.970 1.00 0.00 +ATOM 1750 HW1 HOH 426 7.620 13.860 32.100 1.00 0.00 +ATOM 1751 HW2 HOH 426 8.660 13.160 32.940 1.00 0.00 +ATOM 1752 OW HOH 427 23.060 5.640 26.170 1.00 0.00 +ATOM 1753 HW1 HOH 427 23.520 5.430 25.360 1.00 0.00 +ATOM 1754 HW2 HOH 427 23.740 5.900 26.780 1.00 0.00 +ATOM 1755 OW HOH 428 44.710 25.970 13.030 1.00 0.00 +ATOM 1756 HW1 HOH 428 44.180 26.520 12.450 1.00 0.00 +ATOM 1757 HW2 HOH 428 45.020 25.270 12.460 1.00 0.00 +ATOM 1758 OW HOH 429 31.970 32.570 3.580 1.00 0.00 +ATOM 1759 HW1 HOH 429 32.020 31.850 2.950 1.00 0.00 +ATOM 1760 HW2 HOH 429 32.760 32.480 4.110 1.00 0.00 +ATOM 1761 OW HOH 430 8.030 3.870 5.230 1.00 0.00 +ATOM 1762 HW1 HOH 430 8.670 3.240 5.570 1.00 0.00 +ATOM 1763 HW2 HOH 430 7.440 3.360 4.690 1.00 0.00 +ATOM 1764 OW HOH 431 32.870 4.980 25.570 1.00 0.00 +ATOM 1765 HW1 HOH 431 32.090 5.530 25.670 1.00 0.00 +ATOM 1766 HW2 HOH 431 33.600 5.590 25.670 1.00 0.00 +ATOM 1767 OW HOH 432 23.660 25.060 4.360 1.00 0.00 +ATOM 1768 HW1 HOH 432 22.970 24.420 4.200 1.00 0.00 +ATOM 1769 HW2 HOH 432 23.210 25.910 4.310 1.00 0.00 +ATOM 1770 OW HOH 433 31.610 29.020 10.400 1.00 0.00 +ATOM 1771 HW1 HOH 433 32.270 29.720 10.370 1.00 0.00 +ATOM 1772 HW2 HOH 433 31.710 28.570 9.560 1.00 0.00 +ATOM 1773 OW HOH 434 0.320 27.910 1.270 1.00 0.00 +ATOM 1774 HW1 HOH 434 -0.620 28.100 1.300 1.00 0.00 +ATOM 1775 HW2 HOH 434 0.360 26.960 1.180 1.00 0.00 +ATOM 1776 OW HOH 435 49.060 3.190 12.980 1.00 0.00 +ATOM 1777 HW1 HOH 435 48.980 4.010 12.480 1.00 0.00 +ATOM 1778 HW2 HOH 435 48.230 3.120 13.460 1.00 0.00 +ATOM 1779 OW HOH 436 23.300 22.230 29.840 1.00 0.00 +ATOM 1780 HW1 HOH 436 23.790 22.740 30.480 1.00 0.00 +ATOM 1781 HW2 HOH 436 23.170 21.380 30.250 1.00 0.00 +ATOM 1782 OW HOH 437 6.660 4.820 1.240 1.00 0.00 +ATOM 1783 HW1 HOH 437 6.960 5.180 2.070 1.00 0.00 +ATOM 1784 HW2 HOH 437 7.290 4.130 1.040 1.00 0.00 +ATOM 1785 OW HOH 438 22.910 8.460 3.870 1.00 0.00 +ATOM 1786 HW1 HOH 438 22.460 9.260 3.600 1.00 0.00 +ATOM 1787 HW2 HOH 438 22.250 7.960 4.340 1.00 0.00 +ATOM 1788 OW HOH 439 38.340 10.370 30.130 1.00 0.00 +ATOM 1789 HW1 HOH 439 37.750 10.260 29.380 1.00 0.00 +ATOM 1790 HW2 HOH 439 37.770 10.580 30.860 1.00 0.00 +ATOM 1791 OW HOH 440 0.770 44.480 18.930 1.00 0.00 +ATOM 1792 HW1 HOH 440 1.200 44.530 19.780 1.00 0.00 +ATOM 1793 HW2 HOH 440 1.270 45.070 18.370 1.00 0.00 +ATOM 1794 OW HOH 441 26.660 40.920 31.070 1.00 0.00 +ATOM 1795 HW1 HOH 441 27.420 40.410 30.820 1.00 0.00 +ATOM 1796 HW2 HOH 441 26.330 41.290 30.250 1.00 0.00 +ATOM 1797 OW HOH 442 7.410 19.950 4.350 1.00 0.00 +ATOM 1798 HW1 HOH 442 7.590 19.360 3.620 1.00 0.00 +ATOM 1799 HW2 HOH 442 6.560 20.350 4.140 1.00 0.00 +ATOM 1800 OW HOH 443 43.260 32.960 5.190 1.00 0.00 +ATOM 1801 HW1 HOH 443 42.500 32.950 5.770 1.00 0.00 +ATOM 1802 HW2 HOH 443 43.060 33.630 4.530 1.00 0.00 +ATOM 1803 OW HOH 444 43.090 6.010 26.400 1.00 0.00 +ATOM 1804 HW1 HOH 444 42.880 6.670 25.740 1.00 0.00 +ATOM 1805 HW2 HOH 444 42.870 6.430 27.230 1.00 0.00 +ATOM 1806 OW HOH 445 42.170 6.850 3.120 1.00 0.00 +ATOM 1807 HW1 HOH 445 42.120 7.620 3.690 1.00 0.00 +ATOM 1808 HW2 HOH 445 41.750 6.150 3.610 1.00 0.00 +ATOM 1809 OW HOH 446 0.930 23.030 14.430 1.00 0.00 +ATOM 1810 HW1 HOH 446 0.150 22.630 14.820 1.00 0.00 +ATOM 1811 HW2 HOH 446 0.760 23.970 14.450 1.00 0.00 +ATOM 1812 OW HOH 447 46.770 2.940 6.010 1.00 0.00 +ATOM 1813 HW1 HOH 447 46.380 3.730 5.650 1.00 0.00 +ATOM 1814 HW2 HOH 447 47.090 2.450 5.240 1.00 0.00 +ATOM 1815 OW HOH 448 34.790 3.620 18.520 1.00 0.00 +ATOM 1816 HW1 HOH 448 34.650 4.530 18.750 1.00 0.00 +ATOM 1817 HW2 HOH 448 33.980 3.350 18.080 1.00 0.00 +ATOM 1818 OW HOH 449 45.540 14.600 20.790 1.00 0.00 +ATOM 1819 HW1 HOH 449 46.150 14.190 20.180 1.00 0.00 +ATOM 1820 HW2 HOH 449 45.180 15.340 20.310 1.00 0.00 +ATOM 1821 OW HOH 450 9.400 11.760 23.480 1.00 0.00 +ATOM 1822 HW1 HOH 450 8.910 10.970 23.710 1.00 0.00 +ATOM 1823 HW2 HOH 450 10.110 11.800 24.120 1.00 0.00 +ATOM 1824 OW HOH 451 39.540 24.990 12.400 1.00 0.00 +ATOM 1825 HW1 HOH 451 39.710 24.500 13.200 1.00 0.00 +ATOM 1826 HW2 HOH 451 39.450 24.310 11.720 1.00 0.00 +ATOM 1827 OW HOH 452 20.120 12.220 2.000 1.00 0.00 +ATOM 1828 HW1 HOH 452 20.700 12.900 2.330 1.00 0.00 +ATOM 1829 HW2 HOH 452 19.340 12.700 1.720 1.00 0.00 +ATOM 1830 OW HOH 453 24.080 33.590 36.790 1.00 0.00 +ATOM 1831 HW1 HOH 453 23.310 33.720 36.240 1.00 0.00 +ATOM 1832 HW2 HOH 453 23.840 33.980 37.630 1.00 0.00 +ATOM 1833 OW HOH 454 18.700 5.340 2.690 1.00 0.00 +ATOM 1834 HW1 HOH 454 18.990 5.340 3.610 1.00 0.00 +ATOM 1835 HW2 HOH 454 17.850 4.900 2.700 1.00 0.00 +ATOM 1836 OW HOH 455 12.830 13.020 17.020 1.00 0.00 +ATOM 1837 HW1 HOH 455 12.760 12.450 17.790 1.00 0.00 +ATOM 1838 HW2 HOH 455 12.590 12.450 16.280 1.00 0.00 +ATOM 1839 OW HOH 456 27.530 0.850 20.900 1.00 0.00 +ATOM 1840 HW1 HOH 456 27.440 1.800 20.800 1.00 0.00 +ATOM 1841 HW2 HOH 456 28.450 0.730 21.140 1.00 0.00 +ATOM 1842 OW HOH 457 4.110 1.770 12.200 1.00 0.00 +ATOM 1843 HW1 HOH 457 3.810 2.250 12.970 1.00 0.00 +ATOM 1844 HW2 HOH 457 3.310 1.460 11.780 1.00 0.00 +ATOM 1845 OW HOH 458 37.270 38.090 26.540 1.00 0.00 +ATOM 1846 HW1 HOH 458 37.520 37.170 26.620 1.00 0.00 +ATOM 1847 HW2 HOH 458 37.410 38.450 27.410 1.00 0.00 +ATOM 1848 OW HOH 459 8.120 26.670 9.670 1.00 0.00 +ATOM 1849 HW1 HOH 459 8.240 27.220 8.900 1.00 0.00 +ATOM 1850 HW2 HOH 459 8.960 26.680 10.110 1.00 0.00 +ATOM 1851 OW HOH 460 1.860 36.880 11.550 1.00 0.00 +ATOM 1852 HW1 HOH 460 2.650 37.160 12.020 1.00 0.00 +ATOM 1853 HW2 HOH 460 2.110 36.050 11.150 1.00 0.00 +ATOM 1854 OW HOH 461 46.300 0.370 30.020 1.00 0.00 +ATOM 1855 HW1 HOH 461 46.820 1.170 29.960 1.00 0.00 +ATOM 1856 HW2 HOH 461 46.930 -0.300 30.300 1.00 0.00 +ATOM 1857 OW HOH 462 36.490 34.880 2.060 1.00 0.00 +ATOM 1858 HW1 HOH 462 35.620 34.490 2.080 1.00 0.00 +ATOM 1859 HW2 HOH 462 36.670 35.030 1.130 1.00 0.00 +ATOM 1860 OW HOH 463 25.240 17.010 0.830 1.00 0.00 +ATOM 1861 HW1 HOH 463 25.260 17.310 1.740 1.00 0.00 +ATOM 1862 HW2 HOH 463 25.330 17.820 0.310 1.00 0.00 +ATOM 1863 OW HOH 464 2.900 7.530 36.970 1.00 0.00 +ATOM 1864 HW1 HOH 464 3.420 7.850 37.710 1.00 0.00 +ATOM 1865 HW2 HOH 464 2.210 7.000 37.380 1.00 0.00 +ATOM 1866 OW HOH 465 6.240 25.300 29.010 1.00 0.00 +ATOM 1867 HW1 HOH 465 6.320 24.660 28.300 1.00 0.00 +ATOM 1868 HW2 HOH 465 7.050 25.190 29.520 1.00 0.00 +ATOM 1869 OW HOH 466 15.280 37.480 26.550 1.00 0.00 +ATOM 1870 HW1 HOH 466 15.050 37.490 25.620 1.00 0.00 +ATOM 1871 HW2 HOH 466 16.230 37.600 26.570 1.00 0.00 +ATOM 1872 OW HOH 467 29.910 33.090 12.570 1.00 0.00 +ATOM 1873 HW1 HOH 467 30.540 32.380 12.620 1.00 0.00 +ATOM 1874 HW2 HOH 467 29.390 32.900 11.780 1.00 0.00 +ATOM 1875 OW HOH 468 25.490 0.900 31.870 1.00 0.00 +ATOM 1876 HW1 HOH 468 25.440 0.480 31.010 1.00 0.00 +ATOM 1877 HW2 HOH 468 25.750 0.200 32.470 1.00 0.00 +ATOM 1878 OW HOH 469 38.770 33.430 1.590 1.00 0.00 +ATOM 1879 HW1 HOH 469 39.590 33.730 1.190 1.00 0.00 +ATOM 1880 HW2 HOH 469 38.210 34.200 1.610 1.00 0.00 +ATOM 1881 OW HOH 470 47.400 23.990 31.220 1.00 0.00 +ATOM 1882 HW1 HOH 470 48.160 24.330 31.690 1.00 0.00 +ATOM 1883 HW2 HOH 470 46.640 24.330 31.690 1.00 0.00 +ATOM 1884 OW HOH 471 17.160 2.580 26.700 1.00 0.00 +ATOM 1885 HW1 HOH 471 16.810 2.450 27.580 1.00 0.00 +ATOM 1886 HW2 HOH 471 18.070 2.280 26.760 1.00 0.00 +ATOM 1887 OW HOH 472 16.260 1.280 14.650 1.00 0.00 +ATOM 1888 HW1 HOH 472 15.870 2.130 14.420 1.00 0.00 +ATOM 1889 HW2 HOH 472 17.010 1.200 14.050 1.00 0.00 +ATOM 1890 OW HOH 473 33.960 30.260 2.420 1.00 0.00 +ATOM 1891 HW1 HOH 473 34.480 30.670 1.730 1.00 0.00 +ATOM 1892 HW2 HOH 473 33.300 29.750 1.960 1.00 0.00 +ATOM 1893 OW HOH 474 37.870 28.870 27.400 1.00 0.00 +ATOM 1894 HW1 HOH 474 36.930 28.710 27.510 1.00 0.00 +ATOM 1895 HW2 HOH 474 38.290 28.130 27.840 1.00 0.00 +ATOM 1896 OW HOH 475 4.150 4.630 30.500 1.00 0.00 +ATOM 1897 HW1 HOH 475 4.980 4.170 30.400 1.00 0.00 +ATOM 1898 HW2 HOH 475 4.190 5.020 31.370 1.00 0.00 +ATOM 1899 OW HOH 476 42.700 31.770 15.390 1.00 0.00 +ATOM 1900 HW1 HOH 476 43.250 32.550 15.330 1.00 0.00 +ATOM 1901 HW2 HOH 476 42.650 31.450 14.490 1.00 0.00 +ATOM 1902 OW HOH 477 18.630 1.700 2.270 1.00 0.00 +ATOM 1903 HW1 HOH 477 19.050 2.330 1.690 1.00 0.00 +ATOM 1904 HW2 HOH 477 19.170 1.700 3.060 1.00 0.00 +ATOM 1905 OW HOH 478 36.880 5.320 6.730 1.00 0.00 +ATOM 1906 HW1 HOH 478 36.490 5.110 7.580 1.00 0.00 +ATOM 1907 HW2 HOH 478 36.260 5.940 6.340 1.00 0.00 +ATOM 1908 OW HOH 479 7.300 24.190 16.750 1.00 0.00 +ATOM 1909 HW1 HOH 479 7.700 23.460 16.280 1.00 0.00 +ATOM 1910 HW2 HOH 479 7.670 24.970 16.340 1.00 0.00 +ATOM 1911 OW HOH 480 11.600 6.210 20.870 1.00 0.00 +ATOM 1912 HW1 HOH 480 11.830 6.940 20.300 1.00 0.00 +ATOM 1913 HW2 HOH 480 12.240 6.260 21.580 1.00 0.00 +ATOM 1914 OW HOH 481 23.580 44.580 23.210 1.00 0.00 +ATOM 1915 HW1 HOH 481 23.870 44.370 22.320 1.00 0.00 +ATOM 1916 HW2 HOH 481 24.220 44.150 23.780 1.00 0.00 +ATOM 1917 OW HOH 482 11.340 45.030 0.690 1.00 0.00 +ATOM 1918 HW1 HOH 482 11.160 44.370 1.360 1.00 0.00 +ATOM 1919 HW2 HOH 482 11.630 45.800 1.190 1.00 0.00 +ATOM 1920 OW HOH 483 19.320 29.780 28.410 1.00 0.00 +ATOM 1921 HW1 HOH 483 19.070 30.630 28.040 1.00 0.00 +ATOM 1922 HW2 HOH 483 20.060 29.500 27.870 1.00 0.00 +ATOM 1923 OW HOH 484 39.210 45.420 15.550 1.00 0.00 +ATOM 1924 HW1 HOH 484 39.160 46.190 14.990 1.00 0.00 +ATOM 1925 HW2 HOH 484 38.880 44.700 15.010 1.00 0.00 +ATOM 1926 OW HOH 485 27.830 18.780 34.970 1.00 0.00 +ATOM 1927 HW1 HOH 485 28.650 18.660 34.500 1.00 0.00 +ATOM 1928 HW2 HOH 485 27.220 18.170 34.550 1.00 0.00 +ATOM 1929 OW HOH 486 11.180 20.980 2.930 1.00 0.00 +ATOM 1930 HW1 HOH 486 11.740 21.120 2.170 1.00 0.00 +ATOM 1931 HW2 HOH 486 10.860 20.080 2.820 1.00 0.00 +ATOM 1932 OW HOH 487 2.120 22.600 25.020 1.00 0.00 +ATOM 1933 HW1 HOH 487 2.550 21.820 25.370 1.00 0.00 +ATOM 1934 HW2 HOH 487 1.640 22.290 24.260 1.00 0.00 +ATOM 1935 OW HOH 488 46.310 9.840 34.690 1.00 0.00 +ATOM 1936 HW1 HOH 488 46.580 9.500 33.840 1.00 0.00 +ATOM 1937 HW2 HOH 488 45.410 10.130 34.560 1.00 0.00 +ATOM 1938 OW HOH 489 32.730 9.410 5.790 1.00 0.00 +ATOM 1939 HW1 HOH 489 33.200 9.560 4.970 1.00 0.00 +ATOM 1940 HW2 HOH 489 32.020 10.050 5.780 1.00 0.00 +ATOM 1941 OW HOH 490 44.670 24.390 15.380 1.00 0.00 +ATOM 1942 HW1 HOH 490 44.440 24.990 14.670 1.00 0.00 +ATOM 1943 HW2 HOH 490 44.520 23.520 15.010 1.00 0.00 +ATOM 1944 OW HOH 491 3.260 1.000 31.270 1.00 0.00 +ATOM 1945 HW1 HOH 491 2.330 1.240 31.290 1.00 0.00 +ATOM 1946 HW2 HOH 491 3.580 1.390 30.450 1.00 0.00 +ATOM 1947 OW HOH 492 11.720 15.100 5.250 1.00 0.00 +ATOM 1948 HW1 HOH 492 11.600 16.040 5.380 1.00 0.00 +ATOM 1949 HW2 HOH 492 10.980 14.830 4.700 1.00 0.00 +ATOM 1950 OW HOH 493 44.520 34.170 26.360 1.00 0.00 +ATOM 1951 HW1 HOH 493 44.250 34.600 25.550 1.00 0.00 +ATOM 1952 HW2 HOH 493 43.710 34.110 26.880 1.00 0.00 +ATOM 1953 OW HOH 494 34.660 6.550 5.550 1.00 0.00 +ATOM 1954 HW1 HOH 494 34.450 5.660 5.850 1.00 0.00 +ATOM 1955 HW2 HOH 494 33.850 6.870 5.170 1.00 0.00 +ATOM 1956 OW HOH 495 32.120 21.020 38.370 1.00 0.00 +ATOM 1957 HW1 HOH 495 31.510 20.310 38.560 1.00 0.00 +ATOM 1958 HW2 HOH 495 31.760 21.790 38.800 1.00 0.00 +ATOM 1959 OW HOH 496 26.420 14.070 35.540 1.00 0.00 +ATOM 1960 HW1 HOH 496 26.120 14.410 36.380 1.00 0.00 +ATOM 1961 HW2 HOH 496 26.730 13.180 35.740 1.00 0.00 +ATOM 1962 OW HOH 497 8.470 23.190 6.740 1.00 0.00 +ATOM 1963 HW1 HOH 497 8.600 22.240 6.660 1.00 0.00 +ATOM 1964 HW2 HOH 497 7.650 23.280 7.230 1.00 0.00 +ATOM 1965 OW HOH 498 20.710 4.360 26.530 1.00 0.00 +ATOM 1966 HW1 HOH 498 20.980 3.870 25.760 1.00 0.00 +ATOM 1967 HW2 HOH 498 21.540 4.650 26.930 1.00 0.00 +ATOM 1968 OW HOH 499 7.450 3.090 22.760 1.00 0.00 +ATOM 1969 HW1 HOH 499 7.540 2.580 23.560 1.00 0.00 +ATOM 1970 HW2 HOH 499 6.690 3.650 22.920 1.00 0.00 +ATOM 1971 OW HOH 500 17.950 30.060 32.500 1.00 0.00 +ATOM 1972 HW1 HOH 500 18.560 30.770 32.730 1.00 0.00 +ATOM 1973 HW2 HOH 500 17.930 29.500 33.280 1.00 0.00 +ATOM 1974 OW HOH 501 30.490 30.360 2.000 1.00 0.00 +ATOM 1975 HW1 HOH 501 30.930 29.630 1.560 1.00 0.00 +ATOM 1976 HW2 HOH 501 29.670 30.470 1.530 1.00 0.00 +ATOM 1977 OW HOH 502 2.810 29.060 25.210 1.00 0.00 +ATOM 1978 HW1 HOH 502 2.960 28.130 25.080 1.00 0.00 +ATOM 1979 HW2 HOH 502 2.770 29.430 24.330 1.00 0.00 +ATOM 1980 OW HOH 503 33.480 20.280 6.160 1.00 0.00 +ATOM 1981 HW1 HOH 503 33.430 19.560 5.530 1.00 0.00 +ATOM 1982 HW2 HOH 503 33.400 19.860 7.010 1.00 0.00 +ATOM 1983 OW HOH 504 25.500 39.510 9.500 1.00 0.00 +ATOM 1984 HW1 HOH 504 26.280 38.960 9.450 1.00 0.00 +ATOM 1985 HW2 HOH 504 25.060 39.370 8.660 1.00 0.00 +ATOM 1986 OW HOH 505 34.470 33.060 4.720 1.00 0.00 +ATOM 1987 HW1 HOH 505 34.350 32.410 5.420 1.00 0.00 +ATOM 1988 HW2 HOH 505 35.380 32.960 4.450 1.00 0.00 +ATOM 1989 OW HOH 506 15.850 11.700 5.400 1.00 0.00 +ATOM 1990 HW1 HOH 506 16.200 12.530 5.740 1.00 0.00 +ATOM 1991 HW2 HOH 506 15.670 11.880 4.480 1.00 0.00 +ATOM 1992 OW HOH 507 5.780 7.880 20.200 1.00 0.00 +ATOM 1993 HW1 HOH 507 5.060 8.490 20.070 1.00 0.00 +ATOM 1994 HW2 HOH 507 6.560 8.430 20.270 1.00 0.00 +ATOM 1995 OW HOH 508 43.080 7.050 35.560 1.00 0.00 +ATOM 1996 HW1 HOH 508 43.910 7.540 35.590 1.00 0.00 +ATOM 1997 HW2 HOH 508 43.120 6.470 36.310 1.00 0.00 +ATOM 1998 OW HOH 509 1.140 33.540 5.510 1.00 0.00 +ATOM 1999 HW1 HOH 509 0.340 33.360 6.010 1.00 0.00 +ATOM 2000 HW2 HOH 509 0.870 33.540 4.600 1.00 0.00 +ATOM 2001 OW HOH 510 29.790 38.080 38.690 1.00 0.00 +ATOM 2002 HW1 HOH 510 28.960 38.200 38.240 1.00 0.00 +ATOM 2003 HW2 HOH 510 29.850 37.130 38.840 1.00 0.00 +ATOM 2004 OW HOH 511 13.010 5.160 5.930 1.00 0.00 +ATOM 2005 HW1 HOH 511 12.350 5.820 6.150 1.00 0.00 +ATOM 2006 HW2 HOH 511 12.950 5.080 4.970 1.00 0.00 +ATOM 2007 OW HOH 512 45.630 1.940 26.550 1.00 0.00 +ATOM 2008 HW1 HOH 512 44.730 2.240 26.650 1.00 0.00 +ATOM 2009 HW2 HOH 512 45.600 1.020 26.800 1.00 0.00 +ATOM 2010 OW HOH 513 18.930 4.980 5.310 1.00 0.00 +ATOM 2011 HW1 HOH 513 18.000 5.010 5.550 1.00 0.00 +ATOM 2012 HW2 HOH 513 19.310 4.330 5.890 1.00 0.00 +ATOM 2013 OW HOH 514 9.100 28.780 35.750 1.00 0.00 +ATOM 2014 HW1 HOH 514 8.300 28.520 36.220 1.00 0.00 +ATOM 2015 HW2 HOH 514 9.420 29.540 36.230 1.00 0.00 +ATOM 2016 OW HOH 515 46.040 35.110 38.100 1.00 0.00 +ATOM 2017 HW1 HOH 515 46.780 34.660 37.690 1.00 0.00 +ATOM 2018 HW2 HOH 515 45.870 35.860 37.520 1.00 0.00 +ATOM 2019 OW HOH 516 6.120 27.550 26.260 1.00 0.00 +ATOM 2020 HW1 HOH 516 5.780 28.380 25.920 1.00 0.00 +ATOM 2021 HW2 HOH 516 5.340 27.070 26.540 1.00 0.00 +ATOM 2022 OW HOH 517 16.680 1.780 29.280 1.00 0.00 +ATOM 2023 HW1 HOH 517 17.180 2.440 29.750 1.00 0.00 +ATOM 2024 HW2 HOH 517 16.780 0.990 29.810 1.00 0.00 +ATOM 2025 OW HOH 518 13.900 14.420 31.780 1.00 0.00 +ATOM 2026 HW1 HOH 518 14.830 14.210 31.760 1.00 0.00 +ATOM 2027 HW2 HOH 518 13.510 13.710 32.300 1.00 0.00 +ATOM 2028 OW HOH 519 8.620 31.910 30.660 1.00 0.00 +ATOM 2029 HW1 HOH 519 8.580 32.810 30.340 1.00 0.00 +ATOM 2030 HW2 HOH 519 8.610 31.370 29.870 1.00 0.00 +ATOM 2031 OW HOH 520 4.490 21.180 32.340 1.00 0.00 +ATOM 2032 HW1 HOH 520 5.180 21.810 32.510 1.00 0.00 +ATOM 2033 HW2 HOH 520 4.680 20.830 31.470 1.00 0.00 +ATOM 2034 OW HOH 521 21.550 11.980 34.360 1.00 0.00 +ATOM 2035 HW1 HOH 521 22.340 12.510 34.290 1.00 0.00 +ATOM 2036 HW2 HOH 521 21.590 11.380 33.610 1.00 0.00 +ATOM 2037 OW HOH 522 14.600 4.800 30.020 1.00 0.00 +ATOM 2038 HW1 HOH 522 14.180 3.970 29.810 1.00 0.00 +ATOM 2039 HW2 HOH 522 15.400 4.560 30.480 1.00 0.00 +ATOM 2040 OW HOH 523 27.050 36.600 27.690 1.00 0.00 +ATOM 2041 HW1 HOH 523 27.990 36.520 27.510 1.00 0.00 +ATOM 2042 HW2 HOH 523 26.750 37.290 27.100 1.00 0.00 +ATOM 2043 OW HOH 524 14.640 18.080 5.200 1.00 0.00 +ATOM 2044 HW1 HOH 524 14.580 17.320 5.780 1.00 0.00 +ATOM 2045 HW2 HOH 524 13.790 18.120 4.770 1.00 0.00 +ATOM 2046 OW HOH 525 7.510 25.050 23.150 1.00 0.00 +ATOM 2047 HW1 HOH 525 7.300 24.750 22.270 1.00 0.00 +ATOM 2048 HW2 HOH 525 6.800 25.670 23.360 1.00 0.00 +ATOM 2049 OW HOH 526 8.900 6.170 24.340 1.00 0.00 +ATOM 2050 HW1 HOH 526 8.600 6.750 23.640 1.00 0.00 +ATOM 2051 HW2 HOH 526 9.410 5.490 23.880 1.00 0.00 +ATOM 2052 OW HOH 527 42.830 21.750 34.090 1.00 0.00 +ATOM 2053 HW1 HOH 527 42.130 21.310 33.610 1.00 0.00 +ATOM 2054 HW2 HOH 527 42.380 22.340 34.690 1.00 0.00 +ATOM 2055 OW HOH 528 16.120 29.190 30.550 1.00 0.00 +ATOM 2056 HW1 HOH 528 16.950 28.910 30.160 1.00 0.00 +ATOM 2057 HW2 HOH 528 16.360 29.590 31.380 1.00 0.00 +ATOM 2058 OW HOH 529 41.530 25.710 37.040 1.00 0.00 +ATOM 2059 HW1 HOH 529 42.030 26.440 37.410 1.00 0.00 +ATOM 2060 HW2 HOH 529 40.660 25.790 37.420 1.00 0.00 +ATOM 2061 OW HOH 530 1.470 36.990 19.030 1.00 0.00 +ATOM 2062 HW1 HOH 530 1.100 36.150 18.800 1.00 0.00 +ATOM 2063 HW2 HOH 530 0.840 37.370 19.640 1.00 0.00 +ATOM 2064 OW HOH 531 29.010 41.880 19.650 1.00 0.00 +ATOM 2065 HW1 HOH 531 29.340 41.310 20.350 1.00 0.00 +ATOM 2066 HW2 HOH 531 29.800 42.230 19.230 1.00 0.00 +ATOM 2067 OW HOH 532 16.920 17.940 12.290 1.00 0.00 +ATOM 2068 HW1 HOH 532 16.840 17.940 13.240 1.00 0.00 +ATOM 2069 HW2 HOH 532 17.670 17.380 12.100 1.00 0.00 +ATOM 2070 OW HOH 533 46.870 16.050 0.390 1.00 0.00 +ATOM 2071 HW1 HOH 533 47.050 15.370 -0.250 1.00 0.00 +ATOM 2072 HW2 HOH 533 47.720 16.450 0.570 1.00 0.00 +ATOM 2073 OW HOH 534 22.950 16.300 4.670 1.00 0.00 +ATOM 2074 HW1 HOH 534 23.620 15.960 4.070 1.00 0.00 +ATOM 2075 HW2 HOH 534 22.210 15.690 4.560 1.00 0.00 +ATOM 2076 OW HOH 535 5.910 39.560 15.920 1.00 0.00 +ATOM 2077 HW1 HOH 535 5.240 39.180 16.480 1.00 0.00 +ATOM 2078 HW2 HOH 535 6.410 38.820 15.590 1.00 0.00 +ATOM 2079 OW HOH 536 15.830 6.880 16.720 1.00 0.00 +ATOM 2080 HW1 HOH 536 15.930 7.810 16.910 1.00 0.00 +ATOM 2081 HW2 HOH 536 16.630 6.480 17.050 1.00 0.00 +ATOM 2082 OW HOH 537 48.530 36.920 25.280 1.00 0.00 +ATOM 2083 HW1 HOH 537 48.980 36.130 25.570 1.00 0.00 +ATOM 2084 HW2 HOH 537 49.230 37.570 25.160 1.00 0.00 +ATOM 2085 OW HOH 538 23.850 2.260 14.370 1.00 0.00 +ATOM 2086 HW1 HOH 538 23.120 2.700 14.800 1.00 0.00 +ATOM 2087 HW2 HOH 538 23.540 1.370 14.200 1.00 0.00 +ATOM 2088 OW HOH 539 39.770 38.160 16.840 1.00 0.00 +ATOM 2089 HW1 HOH 539 40.320 37.740 16.170 1.00 0.00 +ATOM 2090 HW2 HOH 539 38.920 38.270 16.420 1.00 0.00 +ATOM 2091 OW HOH 540 11.610 35.120 2.780 1.00 0.00 +ATOM 2092 HW1 HOH 540 11.390 34.690 3.610 1.00 0.00 +ATOM 2093 HW2 HOH 540 12.250 34.540 2.370 1.00 0.00 +ATOM 2094 OW HOH 541 22.180 39.170 24.870 1.00 0.00 +ATOM 2095 HW1 HOH 541 21.560 39.870 25.070 1.00 0.00 +ATOM 2096 HW2 HOH 541 22.360 38.770 25.720 1.00 0.00 +ATOM 2097 OW HOH 542 47.830 13.840 19.020 1.00 0.00 +ATOM 2098 HW1 HOH 542 47.770 12.960 19.410 1.00 0.00 +ATOM 2099 HW2 HOH 542 48.660 14.190 19.340 1.00 0.00 +ATOM 2100 OW HOH 543 10.840 28.980 9.060 1.00 0.00 +ATOM 2101 HW1 HOH 543 10.500 28.240 8.550 1.00 0.00 +ATOM 2102 HW2 HOH 543 11.680 28.670 9.390 1.00 0.00 +ATOM 2103 OW HOH 544 30.150 6.570 24.030 1.00 0.00 +ATOM 2104 HW1 HOH 544 30.680 7.010 24.700 1.00 0.00 +ATOM 2105 HW2 HOH 544 29.300 6.450 24.440 1.00 0.00 +ATOM 2106 OW HOH 545 45.470 14.450 6.030 1.00 0.00 +ATOM 2107 HW1 HOH 545 44.770 13.850 6.300 1.00 0.00 +ATOM 2108 HW2 HOH 545 45.910 14.690 6.840 1.00 0.00 +ATOM 2109 OW HOH 546 44.400 38.280 24.200 1.00 0.00 +ATOM 2110 HW1 HOH 546 43.780 37.560 24.250 1.00 0.00 +ATOM 2111 HW2 HOH 546 43.850 39.070 24.140 1.00 0.00 +ATOM 2112 OW HOH 547 20.220 13.930 25.470 1.00 0.00 +ATOM 2113 HW1 HOH 547 20.430 13.900 26.400 1.00 0.00 +ATOM 2114 HW2 HOH 547 19.270 14.070 25.450 1.00 0.00 +ATOM 2115 OW HOH 548 2.590 19.320 10.930 1.00 0.00 +ATOM 2116 HW1 HOH 548 2.040 19.930 11.420 1.00 0.00 +ATOM 2117 HW2 HOH 548 3.430 19.790 10.840 1.00 0.00 +ATOM 2118 OW HOH 549 26.470 5.470 1.730 1.00 0.00 +ATOM 2119 HW1 HOH 549 25.600 5.070 1.700 1.00 0.00 +ATOM 2120 HW2 HOH 549 27.030 4.790 2.100 1.00 0.00 +ATOM 2121 OW HOH 550 10.460 9.110 33.840 1.00 0.00 +ATOM 2122 HW1 HOH 550 9.520 9.080 33.990 1.00 0.00 +ATOM 2123 HW2 HOH 550 10.850 9.100 34.710 1.00 0.00 +ATOM 2124 OW HOH 551 12.370 25.300 9.040 1.00 0.00 +ATOM 2125 HW1 HOH 551 12.720 24.760 9.750 1.00 0.00 +ATOM 2126 HW2 HOH 551 12.600 26.200 9.290 1.00 0.00 +ATOM 2127 OW HOH 552 4.210 42.510 23.700 1.00 0.00 +ATOM 2128 HW1 HOH 552 5.110 42.330 23.980 1.00 0.00 +ATOM 2129 HW2 HOH 552 4.300 42.850 22.810 1.00 0.00 +ATOM 2130 OW HOH 553 27.280 21.100 22.030 1.00 0.00 +ATOM 2131 HW1 HOH 553 27.030 21.560 22.830 1.00 0.00 +ATOM 2132 HW2 HOH 553 28.090 21.540 21.750 1.00 0.00 +ATOM 2133 OW HOH 554 20.570 35.400 12.850 1.00 0.00 +ATOM 2134 HW1 HOH 554 20.020 35.010 13.520 1.00 0.00 +ATOM 2135 HW2 HOH 554 20.150 36.240 12.660 1.00 0.00 +ATOM 2136 OW HOH 555 9.440 34.250 22.450 1.00 0.00 +ATOM 2137 HW1 HOH 555 9.440 34.820 23.220 1.00 0.00 +ATOM 2138 HW2 HOH 555 10.060 33.560 22.650 1.00 0.00 +ATOM 2139 OW HOH 556 48.960 19.330 33.130 1.00 0.00 +ATOM 2140 HW1 HOH 556 48.140 18.890 33.360 1.00 0.00 +ATOM 2141 HW2 HOH 556 48.760 20.260 33.170 1.00 0.00 +ATOM 2142 OW HOH 557 17.630 32.300 36.060 1.00 0.00 +ATOM 2143 HW1 HOH 557 17.740 31.350 35.960 1.00 0.00 +ATOM 2144 HW2 HOH 557 17.080 32.390 36.840 1.00 0.00 +ATOM 2145 OW HOH 558 49.110 36.640 29.490 1.00 0.00 +ATOM 2146 HW1 HOH 558 49.370 37.380 28.950 1.00 0.00 +ATOM 2147 HW2 HOH 558 48.570 36.100 28.910 1.00 0.00 +ATOM 2148 OW HOH 559 20.260 22.120 7.230 1.00 0.00 +ATOM 2149 HW1 HOH 559 20.280 21.610 6.420 1.00 0.00 +ATOM 2150 HW2 HOH 559 19.560 22.750 7.110 1.00 0.00 +ATOM 2151 OW HOH 560 48.280 14.970 4.740 1.00 0.00 +ATOM 2152 HW1 HOH 560 47.320 14.950 4.760 1.00 0.00 +ATOM 2153 HW2 HOH 560 48.520 14.370 4.040 1.00 0.00 +ATOM 2154 OW HOH 561 34.460 33.000 31.740 1.00 0.00 +ATOM 2155 HW1 HOH 561 34.240 33.040 30.810 1.00 0.00 +ATOM 2156 HW2 HOH 561 35.210 32.400 31.780 1.00 0.00 +ATOM 2157 OW HOH 562 20.430 11.010 6.270 1.00 0.00 +ATOM 2158 HW1 HOH 562 20.640 10.970 5.340 1.00 0.00 +ATOM 2159 HW2 HOH 562 19.730 10.370 6.380 1.00 0.00 +ATOM 2160 OW HOH 563 1.190 16.940 11.320 1.00 0.00 +ATOM 2161 HW1 HOH 563 1.680 17.760 11.230 1.00 0.00 +ATOM 2162 HW2 HOH 563 0.870 16.950 12.230 1.00 0.00 +ATOM 2163 OW HOH 564 32.340 44.120 25.330 1.00 0.00 +ATOM 2164 HW1 HOH 564 32.020 44.510 26.150 1.00 0.00 +ATOM 2165 HW2 HOH 564 32.140 43.190 25.420 1.00 0.00 +ATOM 2166 OW HOH 565 40.250 16.600 0.120 1.00 0.00 +ATOM 2167 HW1 HOH 565 40.940 16.490 -0.530 1.00 0.00 +ATOM 2168 HW2 HOH 565 40.380 17.480 0.470 1.00 0.00 +ATOM 2169 OW HOH 566 31.930 17.740 33.200 1.00 0.00 +ATOM 2170 HW1 HOH 566 31.210 17.130 33.050 1.00 0.00 +ATOM 2171 HW2 HOH 566 31.560 18.600 32.990 1.00 0.00 +ATOM 2172 OW HOH 567 0.940 21.450 12.150 1.00 0.00 +ATOM 2173 HW1 HOH 567 0.310 20.820 12.490 1.00 0.00 +ATOM 2174 HW2 HOH 567 0.990 22.120 12.830 1.00 0.00 +ATOM 2175 OW HOH 568 44.350 14.420 2.380 1.00 0.00 +ATOM 2176 HW1 HOH 568 44.730 15.280 2.200 1.00 0.00 +ATOM 2177 HW2 HOH 568 43.430 14.500 2.140 1.00 0.00 +ATOM 2178 OW HOH 569 32.600 3.820 8.360 1.00 0.00 +ATOM 2179 HW1 HOH 569 32.830 4.450 9.040 1.00 0.00 +ATOM 2180 HW2 HOH 569 33.290 3.150 8.410 1.00 0.00 +ATOM 2181 OW HOH 570 30.250 33.250 32.940 1.00 0.00 +ATOM 2182 HW1 HOH 570 29.490 32.870 32.500 1.00 0.00 +ATOM 2183 HW2 HOH 570 30.000 33.270 33.860 1.00 0.00 +ATOM 2184 OW HOH 571 29.700 19.020 25.370 1.00 0.00 +ATOM 2185 HW1 HOH 571 30.400 19.640 25.170 1.00 0.00 +ATOM 2186 HW2 HOH 571 29.000 19.560 25.730 1.00 0.00 +ATOM 2187 OW HOH 572 12.830 6.500 31.340 1.00 0.00 +ATOM 2188 HW1 HOH 572 11.960 6.510 30.940 1.00 0.00 +ATOM 2189 HW2 HOH 572 13.340 5.910 30.780 1.00 0.00 +ATOM 2190 OW HOH 573 9.300 24.960 1.410 1.00 0.00 +ATOM 2191 HW1 HOH 573 10.170 24.570 1.550 1.00 0.00 +ATOM 2192 HW2 HOH 573 8.740 24.210 1.180 1.00 0.00 +ATOM 2193 OW HOH 574 37.110 36.490 35.460 1.00 0.00 +ATOM 2194 HW1 HOH 574 36.240 36.880 35.500 1.00 0.00 +ATOM 2195 HW2 HOH 574 37.130 36.020 34.630 1.00 0.00 +ATOM 2196 OW HOH 575 16.050 41.810 34.470 1.00 0.00 +ATOM 2197 HW1 HOH 575 16.270 40.900 34.280 1.00 0.00 +ATOM 2198 HW2 HOH 575 15.700 41.790 35.370 1.00 0.00 +ATOM 2199 OW HOH 576 28.560 35.280 12.900 1.00 0.00 +ATOM 2200 HW1 HOH 576 29.240 35.770 12.450 1.00 0.00 +ATOM 2201 HW2 HOH 576 28.800 34.360 12.770 1.00 0.00 +ATOM 2202 OW HOH 577 43.200 8.000 24.290 1.00 0.00 +ATOM 2203 HW1 HOH 577 43.790 7.460 23.770 1.00 0.00 +ATOM 2204 HW2 HOH 577 43.790 8.530 24.840 1.00 0.00 +ATOM 2205 OW HOH 578 17.020 17.180 8.010 1.00 0.00 +ATOM 2206 HW1 HOH 578 16.390 16.470 7.850 1.00 0.00 +ATOM 2207 HW2 HOH 578 16.530 17.830 8.510 1.00 0.00 +ATOM 2208 OW HOH 579 28.970 38.510 33.560 1.00 0.00 +ATOM 2209 HW1 HOH 579 28.880 37.600 33.270 1.00 0.00 +ATOM 2210 HW2 HOH 579 29.840 38.780 33.260 1.00 0.00 +ATOM 2211 OW HOH 580 31.940 39.140 19.350 1.00 0.00 +ATOM 2212 HW1 HOH 580 32.020 38.300 18.890 1.00 0.00 +ATOM 2213 HW2 HOH 580 32.820 39.500 19.340 1.00 0.00 +ATOM 2214 OW HOH 581 47.900 41.230 30.160 1.00 0.00 +ATOM 2215 HW1 HOH 581 48.860 41.240 30.110 1.00 0.00 +ATOM 2216 HW2 HOH 581 47.690 40.460 30.670 1.00 0.00 +ATOM 2217 OW HOH 582 36.620 12.060 4.100 1.00 0.00 +ATOM 2218 HW1 HOH 582 36.320 11.160 3.950 1.00 0.00 +ATOM 2219 HW2 HOH 582 36.380 12.530 3.300 1.00 0.00 +ATOM 2220 OW HOH 583 12.750 30.930 25.240 1.00 0.00 +ATOM 2221 HW1 HOH 583 12.670 29.990 25.070 1.00 0.00 +ATOM 2222 HW2 HOH 583 12.090 31.110 25.920 1.00 0.00 +ATOM 2223 OW HOH 584 11.500 0.550 35.790 1.00 0.00 +ATOM 2224 HW1 HOH 584 10.720 0.000 35.670 1.00 0.00 +ATOM 2225 HW2 HOH 584 12.220 -0.080 35.840 1.00 0.00 +ATOM 2226 OW HOH 585 14.400 26.220 30.510 1.00 0.00 +ATOM 2227 HW1 HOH 585 14.110 27.060 30.160 1.00 0.00 +ATOM 2228 HW2 HOH 585 13.860 26.070 31.280 1.00 0.00 +ATOM 2229 OW HOH 586 24.910 7.920 33.820 1.00 0.00 +ATOM 2230 HW1 HOH 586 25.580 8.340 33.280 1.00 0.00 +ATOM 2231 HW2 HOH 586 24.080 8.100 33.370 1.00 0.00 +ATOM 2232 OW HOH 587 42.930 11.820 18.820 1.00 0.00 +ATOM 2233 HW1 HOH 587 43.340 11.060 18.400 1.00 0.00 +ATOM 2234 HW2 HOH 587 42.390 11.450 19.520 1.00 0.00 +ATOM 2235 OW HOH 588 16.260 12.280 26.840 1.00 0.00 +ATOM 2236 HW1 HOH 588 16.800 12.620 26.120 1.00 0.00 +ATOM 2237 HW2 HOH 588 15.820 13.050 27.200 1.00 0.00 +ATOM 2238 OW HOH 589 13.780 23.870 14.820 1.00 0.00 +ATOM 2239 HW1 HOH 589 13.040 24.220 14.340 1.00 0.00 +ATOM 2240 HW2 HOH 589 13.440 23.090 15.250 1.00 0.00 +ATOM 2241 OW HOH 590 11.640 7.250 9.800 1.00 0.00 +ATOM 2242 HW1 HOH 590 11.610 8.160 10.090 1.00 0.00 +ATOM 2243 HW2 HOH 590 12.470 6.910 10.140 1.00 0.00 +ATOM 2244 OW HOH 591 44.270 18.590 27.230 1.00 0.00 +ATOM 2245 HW1 HOH 591 43.760 18.580 26.420 1.00 0.00 +ATOM 2246 HW2 HOH 591 43.730 19.080 27.840 1.00 0.00 +ATOM 2247 OW HOH 592 19.760 29.060 35.910 1.00 0.00 +ATOM 2248 HW1 HOH 592 20.180 29.860 35.590 1.00 0.00 +ATOM 2249 HW2 HOH 592 20.100 28.950 36.800 1.00 0.00 +ATOM 2250 OW HOH 593 42.170 1.490 6.860 1.00 0.00 +ATOM 2251 HW1 HOH 593 42.470 2.370 6.650 1.00 0.00 +ATOM 2252 HW2 HOH 593 42.950 0.950 6.780 1.00 0.00 +ATOM 2253 OW HOH 594 30.320 5.990 36.670 1.00 0.00 +ATOM 2254 HW1 HOH 594 30.050 5.140 36.310 1.00 0.00 +ATOM 2255 HW2 HOH 594 29.630 6.210 37.300 1.00 0.00 +ATOM 2256 OW HOH 595 23.490 41.740 26.470 1.00 0.00 +ATOM 2257 HW1 HOH 595 23.000 41.020 26.080 1.00 0.00 +ATOM 2258 HW2 HOH 595 22.900 42.480 26.430 1.00 0.00 +ATOM 2259 OW HOH 596 11.900 34.770 20.280 1.00 0.00 +ATOM 2260 HW1 HOH 596 12.610 35.300 19.930 1.00 0.00 +ATOM 2261 HW2 HOH 596 11.730 35.130 21.160 1.00 0.00 +ATOM 2262 OW HOH 597 26.720 8.860 26.230 1.00 0.00 +ATOM 2263 HW1 HOH 597 26.070 9.560 26.270 1.00 0.00 +ATOM 2264 HW2 HOH 597 26.790 8.660 25.300 1.00 0.00 +ATOM 2265 OW HOH 598 33.020 14.510 27.190 1.00 0.00 +ATOM 2266 HW1 HOH 598 32.520 14.680 27.990 1.00 0.00 +ATOM 2267 HW2 HOH 598 33.870 14.910 27.350 1.00 0.00 +ATOM 2268 OW HOH 599 13.970 34.450 1.240 1.00 0.00 +ATOM 2269 HW1 HOH 599 14.820 34.880 1.160 1.00 0.00 +ATOM 2270 HW2 HOH 599 14.170 33.560 1.510 1.00 0.00 +ATOM 2271 OW HOH 600 4.300 10.320 29.090 1.00 0.00 +ATOM 2272 HW1 HOH 600 3.420 9.940 28.980 1.00 0.00 +ATOM 2273 HW2 HOH 600 4.600 9.990 29.930 1.00 0.00 +ATOM 2274 OW HOH 601 4.260 18.520 1.760 1.00 0.00 +ATOM 2275 HW1 HOH 601 4.840 18.440 1.000 1.00 0.00 +ATOM 2276 HW2 HOH 601 3.460 18.910 1.420 1.00 0.00 +ATOM 2277 OW HOH 602 41.320 14.590 6.470 1.00 0.00 +ATOM 2278 HW1 HOH 602 41.380 13.630 6.410 1.00 0.00 +ATOM 2279 HW2 HOH 602 40.380 14.770 6.490 1.00 0.00 +ATOM 2280 OW HOH 603 2.490 42.540 28.120 1.00 0.00 +ATOM 2281 HW1 HOH 603 2.120 42.070 28.870 1.00 0.00 +ATOM 2282 HW2 HOH 603 2.910 43.310 28.500 1.00 0.00 +ATOM 2283 OW HOH 604 37.480 20.230 24.520 1.00 0.00 +ATOM 2284 HW1 HOH 604 36.610 19.830 24.610 1.00 0.00 +ATOM 2285 HW2 HOH 604 37.310 21.120 24.240 1.00 0.00 +ATOM 2286 OW HOH 605 35.040 9.290 3.980 1.00 0.00 +ATOM 2287 HW1 HOH 605 35.410 8.880 4.760 1.00 0.00 +ATOM 2288 HW2 HOH 605 35.550 8.920 3.250 1.00 0.00 +ATOM 2289 OW HOH 606 6.680 36.690 30.740 1.00 0.00 +ATOM 2290 HW1 HOH 606 5.780 36.520 31.020 1.00 0.00 +ATOM 2291 HW2 HOH 606 6.590 37.350 30.050 1.00 0.00 +ATOM 2292 OW HOH 607 35.340 44.870 8.040 1.00 0.00 +ATOM 2293 HW1 HOH 607 36.200 45.250 7.880 1.00 0.00 +ATOM 2294 HW2 HOH 607 35.320 44.690 8.980 1.00 0.00 +ATOM 2295 OW HOH 608 17.060 4.740 33.650 1.00 0.00 +ATOM 2296 HW1 HOH 608 17.650 4.440 34.340 1.00 0.00 +ATOM 2297 HW2 HOH 608 17.110 5.690 33.680 1.00 0.00 +ATOM 2298 OW HOH 609 26.670 2.470 28.440 1.00 0.00 +ATOM 2299 HW1 HOH 609 26.350 2.250 29.320 1.00 0.00 +ATOM 2300 HW2 HOH 609 27.490 2.930 28.590 1.00 0.00 +ATOM 2301 OW HOH 610 28.210 44.350 9.370 1.00 0.00 +ATOM 2302 HW1 HOH 610 28.110 44.510 8.430 1.00 0.00 +ATOM 2303 HW2 HOH 610 28.280 45.220 9.760 1.00 0.00 +ATOM 2304 OW HOH 611 30.990 23.760 31.670 1.00 0.00 +ATOM 2305 HW1 HOH 611 31.250 23.430 32.530 1.00 0.00 +ATOM 2306 HW2 HOH 611 31.790 24.140 31.300 1.00 0.00 +ATOM 2307 OW HOH 612 27.720 11.940 39.020 1.00 0.00 +ATOM 2308 HW1 HOH 612 27.690 11.020 38.750 1.00 0.00 +ATOM 2309 HW2 HOH 612 27.650 12.430 38.200 1.00 0.00 +ATOM 2310 OW HOH 613 4.510 37.560 9.860 1.00 0.00 +ATOM 2311 HW1 HOH 613 4.560 37.470 10.810 1.00 0.00 +ATOM 2312 HW2 HOH 613 4.100 38.410 9.720 1.00 0.00 +ATOM 2313 OW HOH 614 30.100 1.750 15.760 1.00 0.00 +ATOM 2314 HW1 HOH 614 29.400 2.400 15.780 1.00 0.00 +ATOM 2315 HW2 HOH 614 29.830 1.130 15.080 1.00 0.00 +ATOM 2316 OW HOH 615 48.750 1.470 37.610 1.00 0.00 +ATOM 2317 HW1 HOH 615 49.030 2.340 37.320 1.00 0.00 +ATOM 2318 HW2 HOH 615 49.250 1.310 38.410 1.00 0.00 +ATOM 2319 OW HOH 616 7.780 38.720 29.050 1.00 0.00 +ATOM 2320 HW1 HOH 616 6.880 38.780 28.710 1.00 0.00 +ATOM 2321 HW2 HOH 616 8.210 38.100 28.460 1.00 0.00 +ATOM 2322 OW HOH 617 15.370 27.050 23.820 1.00 0.00 +ATOM 2323 HW1 HOH 617 16.050 26.940 23.150 1.00 0.00 +ATOM 2324 HW2 HOH 617 15.220 27.990 23.850 1.00 0.00 +ATOM 2325 OW HOH 618 30.870 13.170 0.710 1.00 0.00 +ATOM 2326 HW1 HOH 618 31.140 12.430 0.160 1.00 0.00 +ATOM 2327 HW2 HOH 618 30.840 12.800 1.590 1.00 0.00 +ATOM 2328 OW HOH 619 13.420 42.370 0.700 1.00 0.00 +ATOM 2329 HW1 HOH 619 13.530 42.460 1.650 1.00 0.00 +ATOM 2330 HW2 HOH 619 13.520 43.260 0.370 1.00 0.00 +ATOM 2331 OW HOH 620 14.370 45.230 9.900 1.00 0.00 +ATOM 2332 HW1 HOH 620 15.310 45.160 9.690 1.00 0.00 +ATOM 2333 HW2 HOH 620 14.030 44.350 9.740 1.00 0.00 +ATOM 2334 OW HOH 621 46.790 21.320 32.340 1.00 0.00 +ATOM 2335 HW1 HOH 621 47.380 22.060 32.200 1.00 0.00 +ATOM 2336 HW2 HOH 621 46.320 21.230 31.520 1.00 0.00 +ATOM 2337 OW HOH 622 41.010 4.700 4.830 1.00 0.00 +ATOM 2338 HW1 HOH 622 40.270 4.120 5.010 1.00 0.00 +ATOM 2339 HW2 HOH 622 41.590 4.180 4.270 1.00 0.00 +ATOM 2340 OW HOH 623 17.080 29.580 35.900 1.00 0.00 +ATOM 2341 HW1 HOH 623 16.840 29.270 36.770 1.00 0.00 +ATOM 2342 HW2 HOH 623 18.010 29.360 35.820 1.00 0.00 +ATOM 2343 OW HOH 624 7.120 1.630 15.590 1.00 0.00 +ATOM 2344 HW1 HOH 624 6.770 1.200 14.810 1.00 0.00 +ATOM 2345 HW2 HOH 624 6.880 1.050 16.310 1.00 0.00 +ATOM 2346 OW HOH 625 0.860 21.070 3.600 1.00 0.00 +ATOM 2347 HW1 HOH 625 1.270 20.340 3.140 1.00 0.00 +ATOM 2348 HW2 HOH 625 1.370 21.840 3.340 1.00 0.00 +ATOM 2349 OW HOH 626 1.620 28.580 37.820 1.00 0.00 +ATOM 2350 HW1 HOH 626 1.180 28.210 38.590 1.00 0.00 +ATOM 2351 HW2 HOH 626 2.510 28.760 38.120 1.00 0.00 +ATOM 2352 OW HOH 627 47.030 12.320 9.150 1.00 0.00 +ATOM 2353 HW1 HOH 627 47.100 11.930 8.280 1.00 0.00 +ATOM 2354 HW2 HOH 627 46.710 13.200 9.000 1.00 0.00 +ATOM 2355 OW HOH 628 18.270 42.100 31.220 1.00 0.00 +ATOM 2356 HW1 HOH 628 17.410 41.810 31.520 1.00 0.00 +ATOM 2357 HW2 HOH 628 18.690 42.460 32.000 1.00 0.00 +ATOM 2358 OW HOH 629 4.060 16.020 38.380 1.00 0.00 +ATOM 2359 HW1 HOH 629 3.730 16.860 38.060 1.00 0.00 +ATOM 2360 HW2 HOH 629 3.620 15.370 37.820 1.00 0.00 +ATOM 2361 OW HOH 630 5.810 44.410 6.540 1.00 0.00 +ATOM 2362 HW1 HOH 630 5.130 44.680 7.160 1.00 0.00 +ATOM 2363 HW2 HOH 630 5.610 44.900 5.740 1.00 0.00 +ATOM 2364 OW HOH 631 10.710 39.800 0.620 1.00 0.00 +ATOM 2365 HW1 HOH 631 10.430 39.030 1.110 1.00 0.00 +ATOM 2366 HW2 HOH 631 11.530 40.060 1.030 1.00 0.00 +ATOM 2367 OW HOH 632 7.970 31.090 19.590 1.00 0.00 +ATOM 2368 HW1 HOH 632 8.400 30.880 18.760 1.00 0.00 +ATOM 2369 HW2 HOH 632 8.570 30.770 20.270 1.00 0.00 +ATOM 2370 OW HOH 633 38.220 17.880 33.520 1.00 0.00 +ATOM 2371 HW1 HOH 633 39.170 17.840 33.390 1.00 0.00 +ATOM 2372 HW2 HOH 633 37.890 17.080 33.100 1.00 0.00 +ATOM 2373 OW HOH 634 17.150 0.700 37.660 1.00 0.00 +ATOM 2374 HW1 HOH 634 17.950 0.180 37.730 1.00 0.00 +ATOM 2375 HW2 HOH 634 16.930 0.670 36.720 1.00 0.00 +ATOM 2376 OW HOH 635 10.070 38.660 24.960 1.00 0.00 +ATOM 2377 HW1 HOH 635 9.200 38.780 24.580 1.00 0.00 +ATOM 2378 HW2 HOH 635 10.610 38.360 24.230 1.00 0.00 +ATOM 2379 OW HOH 636 1.140 25.260 3.590 1.00 0.00 +ATOM 2380 HW1 HOH 636 2.090 25.350 3.640 1.00 0.00 +ATOM 2381 HW2 HOH 636 0.890 24.830 4.400 1.00 0.00 +ATOM 2382 OW HOH 637 45.920 16.880 28.550 1.00 0.00 +ATOM 2383 HW1 HOH 637 45.210 17.410 28.200 1.00 0.00 +ATOM 2384 HW2 HOH 637 45.490 16.290 29.170 1.00 0.00 +ATOM 2385 OW HOH 638 26.510 41.130 24.030 1.00 0.00 +ATOM 2386 HW1 HOH 638 25.760 40.700 23.630 1.00 0.00 +ATOM 2387 HW2 HOH 638 26.870 41.680 23.330 1.00 0.00 +ATOM 2388 OW HOH 639 39.680 25.100 21.460 1.00 0.00 +ATOM 2389 HW1 HOH 639 39.410 24.190 21.310 1.00 0.00 +ATOM 2390 HW2 HOH 639 39.390 25.570 20.680 1.00 0.00 +ATOM 2391 OW HOH 640 13.910 38.930 28.270 1.00 0.00 +ATOM 2392 HW1 HOH 640 14.450 38.580 27.560 1.00 0.00 +ATOM 2393 HW2 HOH 640 13.050 39.060 27.870 1.00 0.00 +ATOM 2394 OW HOH 641 32.760 2.220 38.100 1.00 0.00 +ATOM 2395 HW1 HOH 641 32.670 3.030 37.590 1.00 0.00 +ATOM 2396 HW2 HOH 641 33.580 1.830 37.780 1.00 0.00 +ATOM 2397 OW HOH 642 0.910 23.620 22.120 1.00 0.00 +ATOM 2398 HW1 HOH 642 -0.040 23.490 22.190 1.00 0.00 +ATOM 2399 HW2 HOH 642 1.120 24.250 22.810 1.00 0.00 +ATOM 2400 OW HOH 643 20.310 0.850 17.200 1.00 0.00 +ATOM 2401 HW1 HOH 643 20.980 1.450 16.860 1.00 0.00 +ATOM 2402 HW2 HOH 643 20.780 0.290 17.820 1.00 0.00 +ATOM 2403 OW HOH 644 3.540 17.160 4.160 1.00 0.00 +ATOM 2404 HW1 HOH 644 4.060 17.350 3.380 1.00 0.00 +ATOM 2405 HW2 HOH 644 2.690 16.890 3.820 1.00 0.00 +ATOM 2406 OW HOH 645 26.560 3.960 25.850 1.00 0.00 +ATOM 2407 HW1 HOH 645 26.210 3.470 26.600 1.00 0.00 +ATOM 2408 HW2 HOH 645 26.730 4.830 26.190 1.00 0.00 +ATOM 2409 OW HOH 646 44.360 6.120 22.260 1.00 0.00 +ATOM 2410 HW1 HOH 646 43.560 5.740 21.890 1.00 0.00 +ATOM 2411 HW2 HOH 646 44.680 5.440 22.870 1.00 0.00 +ATOM 2412 OW HOH 647 47.510 20.810 10.470 1.00 0.00 +ATOM 2413 HW1 HOH 647 47.670 20.190 11.180 1.00 0.00 +ATOM 2414 HW2 HOH 647 47.810 21.650 10.820 1.00 0.00 +ATOM 2415 OW HOH 648 3.950 12.760 4.080 1.00 0.00 +ATOM 2416 HW1 HOH 648 3.540 13.310 4.740 1.00 0.00 +ATOM 2417 HW2 HOH 648 3.320 12.730 3.360 1.00 0.00 +ATOM 2418 OW HOH 649 1.210 4.610 31.280 1.00 0.00 +ATOM 2419 HW1 HOH 649 1.250 3.710 31.590 1.00 0.00 +ATOM 2420 HW2 HOH 649 2.120 4.910 31.290 1.00 0.00 +ATOM 2421 OW HOH 650 37.010 7.660 23.120 1.00 0.00 +ATOM 2422 HW1 HOH 650 36.900 6.760 22.820 1.00 0.00 +ATOM 2423 HW2 HOH 650 37.820 7.640 23.630 1.00 0.00 +ATOM 2424 OW HOH 651 15.520 0.310 19.200 1.00 0.00 +ATOM 2425 HW1 HOH 651 16.440 0.590 19.200 1.00 0.00 +ATOM 2426 HW2 HOH 651 15.360 0.030 18.300 1.00 0.00 +ATOM 2427 OW HOH 652 39.340 24.010 4.210 1.00 0.00 +ATOM 2428 HW1 HOH 652 38.620 23.930 4.840 1.00 0.00 +ATOM 2429 HW2 HOH 652 39.830 23.200 4.310 1.00 0.00 +ATOM 2430 OW HOH 653 6.060 9.680 16.950 1.00 0.00 +ATOM 2431 HW1 HOH 653 6.210 10.420 16.360 1.00 0.00 +ATOM 2432 HW2 HOH 653 5.310 9.220 16.570 1.00 0.00 +ATOM 2433 OW HOH 654 9.340 45.030 36.060 1.00 0.00 +ATOM 2434 HW1 HOH 654 8.620 44.740 35.500 1.00 0.00 +ATOM 2435 HW2 HOH 654 9.400 44.380 36.750 1.00 0.00 +ATOM 2436 OW HOH 655 18.270 13.450 33.020 1.00 0.00 +ATOM 2437 HW1 HOH 655 18.300 14.080 33.740 1.00 0.00 +ATOM 2438 HW2 HOH 655 17.470 13.660 32.540 1.00 0.00 +ATOM 2439 OW HOH 656 20.400 40.790 26.310 1.00 0.00 +ATOM 2440 HW1 HOH 656 20.170 40.650 27.230 1.00 0.00 +ATOM 2441 HW2 HOH 656 19.700 41.340 25.970 1.00 0.00 +ATOM 2442 OW HOH 657 23.930 16.910 22.850 1.00 0.00 +ATOM 2443 HW1 HOH 657 23.970 17.210 23.750 1.00 0.00 +ATOM 2444 HW2 HOH 657 23.190 16.300 22.830 1.00 0.00 +ATOM 2445 OW HOH 658 38.130 43.970 24.980 1.00 0.00 +ATOM 2446 HW1 HOH 658 38.790 44.570 25.340 1.00 0.00 +ATOM 2447 HW2 HOH 658 37.340 44.510 24.920 1.00 0.00 +ATOM 2448 OW HOH 659 46.010 41.430 10.900 1.00 0.00 +ATOM 2449 HW1 HOH 659 45.940 42.360 11.110 1.00 0.00 +ATOM 2450 HW2 HOH 659 46.830 41.340 10.420 1.00 0.00 +ATOM 2451 OW HOH 660 1.940 5.430 23.090 1.00 0.00 +ATOM 2452 HW1 HOH 660 1.990 5.680 22.170 1.00 0.00 +ATOM 2453 HW2 HOH 660 1.430 6.120 23.500 1.00 0.00 +ATOM 2454 OW HOH 661 11.020 40.190 6.550 1.00 0.00 +ATOM 2455 HW1 HOH 661 10.620 39.530 5.980 1.00 0.00 +ATOM 2456 HW2 HOH 661 10.320 40.830 6.700 1.00 0.00 +ATOM 2457 OW HOH 662 43.100 11.780 31.700 1.00 0.00 +ATOM 2458 HW1 HOH 662 42.180 11.630 31.510 1.00 0.00 +ATOM 2459 HW2 HOH 662 43.570 11.190 31.110 1.00 0.00 +ATOM 2460 OW HOH 663 26.550 9.460 32.290 1.00 0.00 +ATOM 2461 HW1 HOH 663 26.260 10.360 32.430 1.00 0.00 +ATOM 2462 HW2 HOH 663 27.440 9.550 31.930 1.00 0.00 +ATOM 2463 OW HOH 664 23.970 12.190 4.370 1.00 0.00 +ATOM 2464 HW1 HOH 664 24.630 11.510 4.230 1.00 0.00 +ATOM 2465 HW2 HOH 664 24.470 12.980 4.580 1.00 0.00 +ATOM 2466 OW HOH 665 46.420 6.810 29.880 1.00 0.00 +ATOM 2467 HW1 HOH 665 47.170 6.660 30.450 1.00 0.00 +ATOM 2468 HW2 HOH 665 45.660 6.600 30.420 1.00 0.00 +ATOM 2469 OW HOH 666 48.460 1.510 27.330 1.00 0.00 +ATOM 2470 HW1 HOH 666 48.650 0.610 27.060 1.00 0.00 +ATOM 2471 HW2 HOH 666 47.520 1.610 27.190 1.00 0.00 +ATOM 2472 OW HOH 667 6.560 18.380 32.330 1.00 0.00 +ATOM 2473 HW1 HOH 667 5.870 17.970 31.810 1.00 0.00 +ATOM 2474 HW2 HOH 667 6.080 18.840 33.030 1.00 0.00 +ATOM 2475 OW HOH 668 24.210 0.960 38.390 1.00 0.00 +ATOM 2476 HW1 HOH 668 23.440 1.260 38.870 1.00 0.00 +ATOM 2477 HW2 HOH 668 24.140 0.000 38.410 1.00 0.00 +ATOM 2478 OW HOH 669 30.520 12.310 11.820 1.00 0.00 +ATOM 2479 HW1 HOH 669 31.080 12.130 11.060 1.00 0.00 +ATOM 2480 HW2 HOH 669 29.900 11.580 11.830 1.00 0.00 +ATOM 2481 OW HOH 670 2.140 41.060 20.050 1.00 0.00 +ATOM 2482 HW1 HOH 670 1.460 41.200 20.720 1.00 0.00 +ATOM 2483 HW2 HOH 670 2.480 40.180 20.240 1.00 0.00 +ATOM 2484 OW HOH 671 13.290 7.910 15.930 1.00 0.00 +ATOM 2485 HW1 HOH 671 13.980 7.270 15.790 1.00 0.00 +ATOM 2486 HW2 HOH 671 13.670 8.750 15.670 1.00 0.00 +ATOM 2487 OW HOH 672 13.930 42.640 24.950 1.00 0.00 +ATOM 2488 HW1 HOH 672 14.130 42.510 25.880 1.00 0.00 +ATOM 2489 HW2 HOH 672 13.370 41.900 24.720 1.00 0.00 +ATOM 2490 OW HOH 673 43.290 9.750 29.350 1.00 0.00 +ATOM 2491 HW1 HOH 673 42.560 10.030 28.800 1.00 0.00 +ATOM 2492 HW2 HOH 673 43.950 9.440 28.730 1.00 0.00 +ATOM 2493 OW HOH 674 43.240 10.860 11.920 1.00 0.00 +ATOM 2494 HW1 HOH 674 43.370 11.100 11.010 1.00 0.00 +ATOM 2495 HW2 HOH 674 43.500 11.640 12.420 1.00 0.00 +ATOM 2496 OW HOH 675 25.640 45.660 35.610 1.00 0.00 +ATOM 2497 HW1 HOH 675 26.080 45.120 34.960 1.00 0.00 +ATOM 2498 HW2 HOH 675 25.400 46.460 35.150 1.00 0.00 +ATOM 2499 OW HOH 676 13.530 17.210 32.480 1.00 0.00 +ATOM 2500 HW1 HOH 676 14.060 17.260 33.270 1.00 0.00 +ATOM 2501 HW2 HOH 676 13.960 16.540 31.940 1.00 0.00 +ATOM 2502 OW HOH 677 10.720 14.850 12.670 1.00 0.00 +ATOM 2503 HW1 HOH 677 11.570 15.280 12.740 1.00 0.00 +ATOM 2504 HW2 HOH 677 10.300 14.990 13.520 1.00 0.00 +ATOM 2505 OW HOH 678 12.440 9.140 21.670 1.00 0.00 +ATOM 2506 HW1 HOH 678 12.390 9.350 20.740 1.00 0.00 +ATOM 2507 HW2 HOH 678 12.580 9.980 22.100 1.00 0.00 +ATOM 2508 OW HOH 679 0.730 24.770 31.670 1.00 0.00 +ATOM 2509 HW1 HOH 679 1.010 23.940 31.300 1.00 0.00 +ATOM 2510 HW2 HOH 679 1.150 24.800 32.530 1.00 0.00 +ATOM 2511 OW HOH 680 1.350 7.430 17.300 1.00 0.00 +ATOM 2512 HW1 HOH 680 0.960 6.640 16.910 1.00 0.00 +ATOM 2513 HW2 HOH 680 1.750 7.120 18.110 1.00 0.00 +ATOM 2514 OW HOH 681 39.350 16.200 16.420 1.00 0.00 +ATOM 2515 HW1 HOH 681 39.550 16.880 15.790 1.00 0.00 +ATOM 2516 HW2 HOH 681 40.170 15.720 16.530 1.00 0.00 +ATOM 2517 OW HOH 682 3.160 36.290 38.070 1.00 0.00 +ATOM 2518 HW1 HOH 682 3.780 36.660 37.450 1.00 0.00 +ATOM 2519 HW2 HOH 682 2.300 36.430 37.670 1.00 0.00 +ATOM 2520 OW HOH 683 45.410 36.020 15.940 1.00 0.00 +ATOM 2521 HW1 HOH 683 46.360 36.040 15.940 1.00 0.00 +ATOM 2522 HW2 HOH 683 45.150 36.830 15.490 1.00 0.00 +ATOM 2523 OW HOH 684 23.510 6.860 29.810 1.00 0.00 +ATOM 2524 HW1 HOH 684 22.820 6.980 30.460 1.00 0.00 +ATOM 2525 HW2 HOH 684 23.760 7.750 29.560 1.00 0.00 +ATOM 2526 OW HOH 685 40.540 12.510 2.480 1.00 0.00 +ATOM 2527 HW1 HOH 685 41.360 12.460 1.980 1.00 0.00 +ATOM 2528 HW2 HOH 685 40.300 13.440 2.430 1.00 0.00 +ATOM 2529 OW HOH 686 44.530 22.430 4.450 1.00 0.00 +ATOM 2530 HW1 HOH 686 44.480 23.380 4.410 1.00 0.00 +ATOM 2531 HW2 HOH 686 44.470 22.230 5.390 1.00 0.00 +ATOM 2532 OW HOH 687 47.900 14.570 37.190 1.00 0.00 +ATOM 2533 HW1 HOH 687 48.390 15.000 36.480 1.00 0.00 +ATOM 2534 HW2 HOH 687 47.580 13.760 36.800 1.00 0.00 +ATOM 2535 OW HOH 688 35.610 15.320 13.910 1.00 0.00 +ATOM 2536 HW1 HOH 688 35.110 14.920 13.200 1.00 0.00 +ATOM 2537 HW2 HOH 688 35.510 14.720 14.650 1.00 0.00 +ATOM 2538 OW HOH 689 34.450 44.650 35.580 1.00 0.00 +ATOM 2539 HW1 HOH 689 33.560 44.430 35.320 1.00 0.00 +ATOM 2540 HW2 HOH 689 34.970 44.560 34.780 1.00 0.00 +ATOM 2541 OW HOH 690 44.110 18.270 7.010 1.00 0.00 +ATOM 2542 HW1 HOH 690 44.100 17.620 6.300 1.00 0.00 +ATOM 2543 HW2 HOH 690 45.030 18.520 7.100 1.00 0.00 +ATOM 2544 OW HOH 691 34.940 18.060 13.620 1.00 0.00 +ATOM 2545 HW1 HOH 691 34.090 17.850 13.230 1.00 0.00 +ATOM 2546 HW2 HOH 691 35.310 17.210 13.860 1.00 0.00 +ATOM 2547 OW HOH 692 34.990 38.010 20.380 1.00 0.00 +ATOM 2548 HW1 HOH 692 35.430 38.790 20.030 1.00 0.00 +ATOM 2549 HW2 HOH 692 34.530 37.640 19.620 1.00 0.00 +ATOM 2550 OW HOH 693 45.430 25.090 28.680 1.00 0.00 +ATOM 2551 HW1 HOH 693 46.180 24.540 28.460 1.00 0.00 +ATOM 2552 HW2 HOH 693 44.940 24.580 29.320 1.00 0.00 +ATOM 2553 OW HOH 694 14.460 35.920 34.190 1.00 0.00 +ATOM 2554 HW1 HOH 694 14.460 35.540 35.070 1.00 0.00 +ATOM 2555 HW2 HOH 694 14.590 35.170 33.610 1.00 0.00 +ATOM 2556 OW HOH 695 30.500 19.660 5.120 1.00 0.00 +ATOM 2557 HW1 HOH 695 30.180 18.810 4.800 1.00 0.00 +ATOM 2558 HW2 HOH 695 31.140 19.930 4.460 1.00 0.00 +ATOM 2559 OW HOH 696 27.210 37.350 14.970 1.00 0.00 +ATOM 2560 HW1 HOH 696 26.540 37.950 14.640 1.00 0.00 +ATOM 2561 HW2 HOH 696 27.090 37.370 15.920 1.00 0.00 +ATOM 2562 OW HOH 697 22.280 44.050 25.460 1.00 0.00 +ATOM 2563 HW1 HOH 697 22.500 44.230 24.550 1.00 0.00 +ATOM 2564 HW2 HOH 697 21.590 44.680 25.670 1.00 0.00 +ATOM 2565 OW HOH 698 17.920 3.310 10.930 1.00 0.00 +ATOM 2566 HW1 HOH 698 18.110 2.680 10.230 1.00 0.00 +ATOM 2567 HW2 HOH 698 18.380 4.100 10.660 1.00 0.00 +ATOM 2568 OW HOH 699 7.360 40.430 31.100 1.00 0.00 +ATOM 2569 HW1 HOH 699 6.440 40.690 30.990 1.00 0.00 +ATOM 2570 HW2 HOH 699 7.570 39.960 30.290 1.00 0.00 +ATOM 2571 OW HOH 700 7.190 35.340 20.510 1.00 0.00 +ATOM 2572 HW1 HOH 700 7.000 34.690 19.830 1.00 0.00 +ATOM 2573 HW2 HOH 700 7.790 34.880 21.110 1.00 0.00 +ATOM 2574 OW HOH 701 34.910 1.620 32.810 1.00 0.00 +ATOM 2575 HW1 HOH 701 35.220 2.420 33.230 1.00 0.00 +ATOM 2576 HW2 HOH 701 34.450 1.930 32.020 1.00 0.00 +ATOM 2577 OW HOH 702 44.260 24.430 20.280 1.00 0.00 +ATOM 2578 HW1 HOH 702 44.540 25.060 20.940 1.00 0.00 +ATOM 2579 HW2 HOH 702 44.570 24.790 19.450 1.00 0.00 +ATOM 2580 OW HOH 703 36.810 33.420 15.390 1.00 0.00 +ATOM 2581 HW1 HOH 703 37.610 33.940 15.410 1.00 0.00 +ATOM 2582 HW2 HOH 703 36.280 33.810 14.700 1.00 0.00 +ATOM 2583 OW HOH 704 10.020 4.700 7.400 1.00 0.00 +ATOM 2584 HW1 HOH 704 9.090 4.580 7.590 1.00 0.00 +ATOM 2585 HW2 HOH 704 10.230 3.990 6.790 1.00 0.00 +ATOM 2586 OW HOH 705 29.650 6.020 2.360 1.00 0.00 +ATOM 2587 HW1 HOH 705 30.210 5.800 1.630 1.00 0.00 +ATOM 2588 HW2 HOH 705 29.200 5.210 2.590 1.00 0.00 +ATOM 2589 OW HOH 706 3.680 2.420 20.410 1.00 0.00 +ATOM 2590 HW1 HOH 706 4.100 2.820 21.170 1.00 0.00 +ATOM 2591 HW2 HOH 706 4.340 1.830 20.050 1.00 0.00 +ATOM 2592 OW HOH 707 34.670 2.210 5.050 1.00 0.00 +ATOM 2593 HW1 HOH 707 34.290 1.420 5.430 1.00 0.00 +ATOM 2594 HW2 HOH 707 35.450 1.900 4.570 1.00 0.00 +ATOM 2595 OW HOH 708 46.670 4.230 9.050 1.00 0.00 +ATOM 2596 HW1 HOH 708 45.890 4.710 8.780 1.00 0.00 +ATOM 2597 HW2 HOH 708 46.560 3.350 8.690 1.00 0.00 +ATOM 2598 OW HOH 709 0.500 31.800 21.690 1.00 0.00 +ATOM 2599 HW1 HOH 709 -0.320 32.120 22.060 1.00 0.00 +ATOM 2600 HW2 HOH 709 0.930 32.570 21.330 1.00 0.00 +ATOM 2601 OW HOH 710 16.350 15.420 3.500 1.00 0.00 +ATOM 2602 HW1 HOH 710 15.550 15.000 3.790 1.00 0.00 +ATOM 2603 HW2 HOH 710 17.000 15.210 4.180 1.00 0.00 +ATOM 2604 OW HOH 711 6.060 0.570 29.030 1.00 0.00 +ATOM 2605 HW1 HOH 711 5.420 1.260 28.850 1.00 0.00 +ATOM 2606 HW2 HOH 711 6.890 1.040 29.140 1.00 0.00 +ATOM 2607 OW HOH 712 37.110 7.480 0.750 1.00 0.00 +ATOM 2608 HW1 HOH 712 37.580 7.150 1.520 1.00 0.00 +ATOM 2609 HW2 HOH 712 36.770 6.690 0.330 1.00 0.00 +ATOM 2610 OW HOH 713 39.450 4.760 26.340 1.00 0.00 +ATOM 2611 HW1 HOH 713 39.620 4.220 27.110 1.00 0.00 +ATOM 2612 HW2 HOH 713 39.470 4.150 25.610 1.00 0.00 +ATOM 2613 OW HOH 714 6.990 31.990 2.050 1.00 0.00 +ATOM 2614 HW1 HOH 714 6.040 31.880 2.070 1.00 0.00 +ATOM 2615 HW2 HOH 714 7.130 32.930 2.010 1.00 0.00 +ATOM 2616 OW HOH 715 42.480 22.150 0.920 1.00 0.00 +ATOM 2617 HW1 HOH 715 42.700 21.410 0.360 1.00 0.00 +ATOM 2618 HW2 HOH 715 42.510 21.790 1.810 1.00 0.00 +ATOM 2619 OW HOH 716 31.170 19.950 28.110 1.00 0.00 +ATOM 2620 HW1 HOH 716 30.340 20.430 28.080 1.00 0.00 +ATOM 2621 HW2 HOH 716 31.800 20.580 28.470 1.00 0.00 +ATOM 2622 OW HOH 717 36.850 10.500 32.460 1.00 0.00 +ATOM 2623 HW1 HOH 717 35.990 10.910 32.540 1.00 0.00 +ATOM 2624 HW2 HOH 717 37.150 10.400 33.360 1.00 0.00 +ATOM 2625 OW HOH 718 5.740 28.270 17.910 1.00 0.00 +ATOM 2626 HW1 HOH 718 6.640 28.380 17.620 1.00 0.00 +ATOM 2627 HW2 HOH 718 5.430 27.500 17.430 1.00 0.00 +ATOM 2628 OW HOH 719 46.590 8.340 11.590 1.00 0.00 +ATOM 2629 HW1 HOH 719 47.160 8.770 12.230 1.00 0.00 +ATOM 2630 HW2 HOH 719 46.760 7.410 11.700 1.00 0.00 +ATOM 2631 OW HOH 720 18.270 36.940 11.910 1.00 0.00 +ATOM 2632 HW1 HOH 720 17.890 36.170 11.490 1.00 0.00 +ATOM 2633 HW2 HOH 720 17.690 37.100 12.660 1.00 0.00 +ATOM 2634 OW HOH 721 43.050 41.230 20.030 1.00 0.00 +ATOM 2635 HW1 HOH 721 42.110 41.370 20.160 1.00 0.00 +ATOM 2636 HW2 HOH 721 43.110 40.790 19.180 1.00 0.00 +ATOM 2637 OW HOH 722 27.010 19.750 26.750 1.00 0.00 +ATOM 2638 HW1 HOH 722 26.250 19.710 27.340 1.00 0.00 +ATOM 2639 HW2 HOH 722 27.560 20.440 27.120 1.00 0.00 +ATOM 2640 OW HOH 723 7.240 13.310 20.330 1.00 0.00 +ATOM 2641 HW1 HOH 723 7.810 14.060 20.200 1.00 0.00 +ATOM 2642 HW2 HOH 723 6.490 13.660 20.810 1.00 0.00 +ATOM 2643 OW HOH 724 38.310 19.730 29.900 1.00 0.00 +ATOM 2644 HW1 HOH 724 38.690 20.460 29.410 1.00 0.00 +ATOM 2645 HW2 HOH 724 39.060 19.200 30.170 1.00 0.00 +ATOM 2646 OW HOH 725 15.530 27.590 27.610 1.00 0.00 +ATOM 2647 HW1 HOH 725 14.830 27.840 28.210 1.00 0.00 +ATOM 2648 HW2 HOH 725 15.100 27.050 26.950 1.00 0.00 +ATOM 2649 OW HOH 726 42.970 19.310 24.420 1.00 0.00 +ATOM 2650 HW1 HOH 726 43.170 19.270 23.480 1.00 0.00 +ATOM 2651 HW2 HOH 726 43.480 20.060 24.740 1.00 0.00 +ATOM 2652 OW HOH 727 17.520 44.890 1.400 1.00 0.00 +ATOM 2653 HW1 HOH 727 18.200 45.540 1.580 1.00 0.00 +ATOM 2654 HW2 HOH 727 17.880 44.070 1.730 1.00 0.00 +ATOM 2655 OW HOH 728 2.720 27.940 20.640 1.00 0.00 +ATOM 2656 HW1 HOH 728 2.170 28.530 20.130 1.00 0.00 +ATOM 2657 HW2 HOH 728 2.760 28.340 21.510 1.00 0.00 +ATOM 2658 OW HOH 729 43.080 28.030 38.250 1.00 0.00 +ATOM 2659 HW1 HOH 729 43.890 27.580 38.020 1.00 0.00 +ATOM 2660 HW2 HOH 729 43.180 28.260 39.170 1.00 0.00 +ATOM 2661 OW HOH 730 10.140 22.980 35.310 1.00 0.00 +ATOM 2662 HW1 HOH 730 10.190 22.540 36.160 1.00 0.00 +ATOM 2663 HW2 HOH 730 9.560 23.730 35.460 1.00 0.00 +ATOM 2664 OW HOH 731 7.470 4.770 8.430 1.00 0.00 +ATOM 2665 HW1 HOH 731 7.030 4.170 9.020 1.00 0.00 +ATOM 2666 HW2 HOH 731 6.800 5.010 7.790 1.00 0.00 +ATOM 2667 OW HOH 732 31.060 6.650 26.720 1.00 0.00 +ATOM 2668 HW1 HOH 732 30.170 6.400 26.940 1.00 0.00 +ATOM 2669 HW2 HOH 732 31.350 7.200 27.440 1.00 0.00 +ATOM 2670 OW HOH 733 20.760 38.570 31.900 1.00 0.00 +ATOM 2671 HW1 HOH 733 21.220 38.180 32.640 1.00 0.00 +ATOM 2672 HW2 HOH 733 20.310 37.830 31.490 1.00 0.00 +ATOM 2673 OW HOH 734 28.020 18.560 30.950 1.00 0.00 +ATOM 2674 HW1 HOH 734 28.870 18.400 30.530 1.00 0.00 +ATOM 2675 HW2 HOH 734 27.680 17.690 31.140 1.00 0.00 +ATOM 2676 OW HOH 735 5.000 24.630 31.950 1.00 0.00 +ATOM 2677 HW1 HOH 735 4.120 24.310 32.170 1.00 0.00 +ATOM 2678 HW2 HOH 735 4.970 24.750 31.000 1.00 0.00 +ATOM 2679 OW HOH 736 21.500 25.890 33.130 1.00 0.00 +ATOM 2680 HW1 HOH 736 22.040 26.390 32.530 1.00 0.00 +ATOM 2681 HW2 HOH 736 22.120 25.310 33.570 1.00 0.00 +ATOM 2682 OW HOH 737 43.790 10.910 34.440 1.00 0.00 +ATOM 2683 HW1 HOH 737 43.300 11.050 33.630 1.00 0.00 +ATOM 2684 HW2 HOH 737 43.240 11.300 35.120 1.00 0.00 +ATOM 2685 OW HOH 738 18.190 32.650 14.280 1.00 0.00 +ATOM 2686 HW1 HOH 738 18.130 33.590 14.470 1.00 0.00 +ATOM 2687 HW2 HOH 738 18.880 32.330 14.870 1.00 0.00 +ATOM 2688 OW HOH 739 9.350 22.560 19.050 1.00 0.00 +ATOM 2689 HW1 HOH 739 9.880 22.210 18.330 1.00 0.00 +ATOM 2690 HW2 HOH 739 8.720 23.140 18.620 1.00 0.00 +ATOM 2691 OW HOH 740 4.460 2.490 7.060 1.00 0.00 +ATOM 2692 HW1 HOH 740 4.110 1.750 7.550 1.00 0.00 +ATOM 2693 HW2 HOH 740 3.700 2.930 6.700 1.00 0.00 +ATOM 2694 OW HOH 741 36.440 24.780 29.370 1.00 0.00 +ATOM 2695 HW1 HOH 741 37.020 24.050 29.570 1.00 0.00 +ATOM 2696 HW2 HOH 741 36.470 25.330 30.150 1.00 0.00 +ATOM 2697 OW HOH 742 35.160 15.750 23.500 1.00 0.00 +ATOM 2698 HW1 HOH 742 35.830 15.780 24.180 1.00 0.00 +ATOM 2699 HW2 HOH 742 34.350 15.980 23.960 1.00 0.00 +ATOM 2700 OW HOH 743 15.300 6.080 27.570 1.00 0.00 +ATOM 2701 HW1 HOH 743 15.310 5.570 28.390 1.00 0.00 +ATOM 2702 HW2 HOH 743 14.750 6.840 27.770 1.00 0.00 +ATOM 2703 OW HOH 744 41.860 26.050 23.120 1.00 0.00 +ATOM 2704 HW1 HOH 744 41.180 25.600 22.630 1.00 0.00 +ATOM 2705 HW2 HOH 744 42.650 25.980 22.580 1.00 0.00 +ATOM 2706 OW HOH 745 4.310 30.490 17.350 1.00 0.00 +ATOM 2707 HW1 HOH 745 5.040 29.920 17.610 1.00 0.00 +ATOM 2708 HW2 HOH 745 3.980 30.090 16.540 1.00 0.00 +ATOM 2709 OW HOH 746 10.740 9.050 15.570 1.00 0.00 +ATOM 2710 HW1 HOH 746 10.260 8.250 15.340 1.00 0.00 +ATOM 2711 HW2 HOH 746 11.630 8.760 15.760 1.00 0.00 +ATOM 2712 OW HOH 747 47.310 42.470 26.760 1.00 0.00 +ATOM 2713 HW1 HOH 747 48.250 42.260 26.780 1.00 0.00 +ATOM 2714 HW2 HOH 747 46.900 41.700 26.380 1.00 0.00 +ATOM 2715 OW HOH 748 33.120 12.820 20.690 1.00 0.00 +ATOM 2716 HW1 HOH 748 33.060 13.650 20.200 1.00 0.00 +ATOM 2717 HW2 HOH 748 33.870 12.940 21.270 1.00 0.00 +ATOM 2718 OW HOH 749 46.310 40.250 6.680 1.00 0.00 +ATOM 2719 HW1 HOH 749 45.580 40.000 7.250 1.00 0.00 +ATOM 2720 HW2 HOH 749 46.560 39.440 6.250 1.00 0.00 +ATOM 2721 OW HOH 750 18.600 36.600 21.600 1.00 0.00 +ATOM 2722 HW1 HOH 750 19.060 35.760 21.590 1.00 0.00 +ATOM 2723 HW2 HOH 750 18.920 37.040 22.380 1.00 0.00 +ATOM 2724 OW HOH 751 45.440 22.120 34.510 1.00 0.00 +ATOM 2725 HW1 HOH 751 44.540 22.040 34.210 1.00 0.00 +ATOM 2726 HW2 HOH 751 45.970 21.850 33.760 1.00 0.00 +ATOM 2727 OW HOH 752 13.000 31.030 19.710 1.00 0.00 +ATOM 2728 HW1 HOH 752 13.190 31.120 20.650 1.00 0.00 +ATOM 2729 HW2 HOH 752 13.850 30.890 19.300 1.00 0.00 +ATOM 2730 OW HOH 753 38.630 3.590 5.580 1.00 0.00 +ATOM 2731 HW1 HOH 753 38.230 3.480 4.710 1.00 0.00 +ATOM 2732 HW2 HOH 753 37.950 4.010 6.110 1.00 0.00 +ATOM 2733 OW HOH 754 2.260 21.250 22.230 1.00 0.00 +ATOM 2734 HW1 HOH 754 1.530 20.820 22.670 1.00 0.00 +ATOM 2735 HW2 HOH 754 1.950 22.130 22.050 1.00 0.00 +ATOM 2736 OW HOH 755 0.770 6.530 38.230 1.00 0.00 +ATOM 2737 HW1 HOH 755 0.980 7.100 38.980 1.00 0.00 +ATOM 2738 HW2 HOH 755 -0.030 6.080 38.500 1.00 0.00 +ATOM 2739 OW HOH 756 48.070 2.020 3.400 1.00 0.00 +ATOM 2740 HW1 HOH 756 47.430 2.330 2.760 1.00 0.00 +ATOM 2741 HW2 HOH 756 48.800 1.700 2.870 1.00 0.00 +ATOM 2742 OW HOH 757 8.760 30.110 24.960 1.00 0.00 +ATOM 2743 HW1 HOH 757 7.830 30.170 25.170 1.00 0.00 +ATOM 2744 HW2 HOH 757 8.930 29.180 24.860 1.00 0.00 +ATOM 2745 OW HOH 758 31.430 12.460 22.950 1.00 0.00 +ATOM 2746 HW1 HOH 758 31.950 12.520 22.150 1.00 0.00 +ATOM 2747 HW2 HOH 758 31.890 13.030 23.570 1.00 0.00 +ATOM 2748 OW HOH 759 43.610 7.350 0.580 1.00 0.00 +ATOM 2749 HW1 HOH 759 43.270 6.700 -0.040 1.00 0.00 +ATOM 2750 HW2 HOH 759 43.000 7.330 1.310 1.00 0.00 +ATOM 2751 OW HOH 760 48.270 34.060 22.830 1.00 0.00 +ATOM 2752 HW1 HOH 760 49.220 34.140 22.740 1.00 0.00 +ATOM 2753 HW2 HOH 760 48.050 34.560 23.610 1.00 0.00 +ATOM 2754 OW HOH 761 31.020 8.480 36.020 1.00 0.00 +ATOM 2755 HW1 HOH 761 31.880 8.410 35.620 1.00 0.00 +ATOM 2756 HW2 HOH 761 30.770 7.570 36.220 1.00 0.00 +ATOM 2757 OW HOH 762 36.710 16.680 10.230 1.00 0.00 +ATOM 2758 HW1 HOH 762 35.800 16.870 10.440 1.00 0.00 +ATOM 2759 HW2 HOH 762 36.780 16.840 9.290 1.00 0.00 +ATOM 2760 OW HOH 763 24.800 12.960 1.350 1.00 0.00 +ATOM 2761 HW1 HOH 763 24.550 12.040 1.440 1.00 0.00 +ATOM 2762 HW2 HOH 763 25.530 13.070 1.950 1.00 0.00 +ATOM 2763 OW HOH 764 10.050 26.740 6.670 1.00 0.00 +ATOM 2764 HW1 HOH 764 9.930 26.000 6.070 1.00 0.00 +ATOM 2765 HW2 HOH 764 9.700 27.490 6.190 1.00 0.00 +ATOM 2766 OW HOH 765 6.840 3.340 20.170 1.00 0.00 +ATOM 2767 HW1 HOH 765 6.640 3.050 21.070 1.00 0.00 +ATOM 2768 HW2 HOH 765 7.730 3.680 20.220 1.00 0.00 +ATOM 2769 OW HOH 766 2.570 17.430 28.410 1.00 0.00 +ATOM 2770 HW1 HOH 766 2.620 18.090 29.100 1.00 0.00 +ATOM 2771 HW2 HOH 766 1.750 17.600 27.960 1.00 0.00 +ATOM 2772 OW HOH 767 4.940 22.150 38.760 1.00 0.00 +ATOM 2773 HW1 HOH 767 5.220 21.290 38.470 1.00 0.00 +ATOM 2774 HW2 HOH 767 4.640 22.590 37.960 1.00 0.00 +ATOM 2775 OW HOH 768 10.750 17.120 36.480 1.00 0.00 +ATOM 2776 HW1 HOH 768 10.940 16.880 35.570 1.00 0.00 +ATOM 2777 HW2 HOH 768 10.060 16.510 36.750 1.00 0.00 +ATOM 2778 OW HOH 769 7.800 34.450 2.850 1.00 0.00 +ATOM 2779 HW1 HOH 769 8.100 35.300 2.520 1.00 0.00 +ATOM 2780 HW2 HOH 769 7.010 34.650 3.350 1.00 0.00 +ATOM 2781 OW HOH 770 12.310 24.520 0.620 1.00 0.00 +ATOM 2782 HW1 HOH 770 11.790 24.110 1.310 1.00 0.00 +ATOM 2783 HW2 HOH 770 12.980 23.870 0.400 1.00 0.00 +ATOM 2784 OW HOH 771 42.400 11.320 39.110 1.00 0.00 +ATOM 2785 HW1 HOH 771 43.000 10.670 38.730 1.00 0.00 +ATOM 2786 HW2 HOH 771 42.240 11.940 38.400 1.00 0.00 +ATOM 2787 OW HOH 772 8.320 12.080 27.580 1.00 0.00 +ATOM 2788 HW1 HOH 772 9.210 12.070 27.930 1.00 0.00 +ATOM 2789 HW2 HOH 772 7.790 11.670 28.270 1.00 0.00 +ATOM 2790 OW HOH 773 11.040 12.090 12.290 1.00 0.00 +ATOM 2791 HW1 HOH 773 10.120 11.960 12.510 1.00 0.00 +ATOM 2792 HW2 HOH 773 11.120 13.020 12.110 1.00 0.00 +ATOM 2793 OW HOH 774 29.110 3.750 35.710 1.00 0.00 +ATOM 2794 HW1 HOH 774 29.360 3.260 34.940 1.00 0.00 +ATOM 2795 HW2 HOH 774 28.170 3.580 35.820 1.00 0.00 +ATOM 2796 OW HOH 775 13.450 23.540 11.110 1.00 0.00 +ATOM 2797 HW1 HOH 775 14.360 23.820 11.150 1.00 0.00 +ATOM 2798 HW2 HOH 775 13.400 22.770 11.680 1.00 0.00 +ATOM 2799 OW HOH 776 8.700 15.740 6.160 1.00 0.00 +ATOM 2800 HW1 HOH 776 8.340 15.440 6.990 1.00 0.00 +ATOM 2801 HW2 HOH 776 8.170 15.300 5.500 1.00 0.00 +ATOM 2802 OW HOH 777 19.640 41.700 28.970 1.00 0.00 +ATOM 2803 HW1 HOH 777 20.070 42.540 28.820 1.00 0.00 +ATOM 2804 HW2 HOH 777 19.010 41.870 29.670 1.00 0.00 +ATOM 2805 OW HOH 778 26.760 14.090 21.980 1.00 0.00 +ATOM 2806 HW1 HOH 778 26.710 13.170 22.260 1.00 0.00 +ATOM 2807 HW2 HOH 778 26.590 14.590 22.780 1.00 0.00 +ATOM 2808 OW HOH 779 2.330 18.750 18.810 1.00 0.00 +ATOM 2809 HW1 HOH 779 3.220 18.820 18.480 1.00 0.00 +ATOM 2810 HW2 HOH 779 2.420 18.340 19.670 1.00 0.00 +ATOM 2811 OW HOH 780 33.900 34.070 21.340 1.00 0.00 +ATOM 2812 HW1 HOH 780 34.720 34.550 21.190 1.00 0.00 +ATOM 2813 HW2 HOH 780 34.090 33.180 21.040 1.00 0.00 +ATOM 2814 OW HOH 781 7.310 17.420 22.400 1.00 0.00 +ATOM 2815 HW1 HOH 781 6.520 16.920 22.180 1.00 0.00 +ATOM 2816 HW2 HOH 781 7.910 17.230 21.670 1.00 0.00 +ATOM 2817 OW HOH 782 4.230 5.860 33.090 1.00 0.00 +ATOM 2818 HW1 HOH 782 3.560 6.530 32.970 1.00 0.00 +ATOM 2819 HW2 HOH 782 4.110 5.540 33.980 1.00 0.00 +ATOM 2820 OW HOH 783 16.160 33.760 22.560 1.00 0.00 +ATOM 2821 HW1 HOH 783 15.810 34.650 22.630 1.00 0.00 +ATOM 2822 HW2 HOH 783 15.900 33.460 21.690 1.00 0.00 +ATOM 2823 OW HOH 784 30.920 8.000 21.310 1.00 0.00 +ATOM 2824 HW1 HOH 784 30.920 7.870 22.260 1.00 0.00 +ATOM 2825 HW2 HOH 784 31.540 8.720 21.160 1.00 0.00 +ATOM 2826 OW HOH 785 23.990 35.680 32.230 1.00 0.00 +ATOM 2827 HW1 HOH 785 24.110 36.280 31.490 1.00 0.00 +ATOM 2828 HW2 HOH 785 23.900 36.250 32.990 1.00 0.00 +ATOM 2829 OW HOH 786 37.960 30.380 5.690 1.00 0.00 +ATOM 2830 HW1 HOH 786 37.740 29.490 5.970 1.00 0.00 +ATOM 2831 HW2 HOH 786 37.490 30.950 6.290 1.00 0.00 +ATOM 2832 OW HOH 787 20.510 29.770 2.530 1.00 0.00 +ATOM 2833 HW1 HOH 787 19.790 29.140 2.550 1.00 0.00 +ATOM 2834 HW2 HOH 787 21.160 29.360 1.940 1.00 0.00 +ATOM 2835 OW HOH 788 21.760 7.370 14.900 1.00 0.00 +ATOM 2836 HW1 HOH 788 21.500 7.570 14.000 1.00 0.00 +ATOM 2837 HW2 HOH 788 20.940 7.250 15.370 1.00 0.00 +ATOM 2838 OW HOH 789 45.060 20.600 38.970 1.00 0.00 +ATOM 2839 HW1 HOH 789 44.880 21.260 38.300 1.00 0.00 +ATOM 2840 HW2 HOH 789 45.830 20.130 38.640 1.00 0.00 +ATOM 2841 OW HOH 790 46.840 37.210 9.130 1.00 0.00 +ATOM 2842 HW1 HOH 790 46.840 36.310 8.780 1.00 0.00 +ATOM 2843 HW2 HOH 790 47.600 37.230 9.710 1.00 0.00 +ATOM 2844 OW HOH 791 15.580 41.180 3.920 1.00 0.00 +ATOM 2845 HW1 HOH 791 14.880 41.780 3.660 1.00 0.00 +ATOM 2846 HW2 HOH 791 16.170 41.710 4.450 1.00 0.00 +ATOM 2847 OW HOH 792 15.290 23.960 5.340 1.00 0.00 +ATOM 2848 HW1 HOH 792 14.920 23.720 6.190 1.00 0.00 +ATOM 2849 HW2 HOH 792 14.630 24.520 4.930 1.00 0.00 +ATOM 2850 OW HOH 793 24.010 34.710 6.660 1.00 0.00 +ATOM 2851 HW1 HOH 793 23.540 34.260 5.960 1.00 0.00 +ATOM 2852 HW2 HOH 793 23.320 35.120 7.190 1.00 0.00 +ATOM 2853 OW HOH 794 44.140 28.670 19.520 1.00 0.00 +ATOM 2854 HW1 HOH 794 44.450 29.370 20.090 1.00 0.00 +ATOM 2855 HW2 HOH 794 43.830 29.120 18.730 1.00 0.00 +ATOM 2856 OW HOH 795 32.500 31.360 33.010 1.00 0.00 +ATOM 2857 HW1 HOH 795 32.910 31.540 32.160 1.00 0.00 +ATOM 2858 HW2 HOH 795 31.840 32.050 33.110 1.00 0.00 +ATOM 2859 OW HOH 796 38.470 34.840 7.600 1.00 0.00 +ATOM 2860 HW1 HOH 796 37.740 35.220 8.090 1.00 0.00 +ATOM 2861 HW2 HOH 796 38.390 35.220 6.730 1.00 0.00 +ATOM 2862 OW HOH 797 6.680 36.230 7.960 1.00 0.00 +ATOM 2863 HW1 HOH 797 5.870 35.760 7.780 1.00 0.00 +ATOM 2864 HW2 HOH 797 6.870 36.710 7.150 1.00 0.00 +ATOM 2865 OW HOH 798 2.500 40.150 38.070 1.00 0.00 +ATOM 2866 HW1 HOH 798 1.990 39.530 38.600 1.00 0.00 +ATOM 2867 HW2 HOH 798 2.460 39.800 37.180 1.00 0.00 +ATOM 2868 OW HOH 799 10.820 32.150 23.060 1.00 0.00 +ATOM 2869 HW1 HOH 799 10.410 31.790 23.850 1.00 0.00 +ATOM 2870 HW2 HOH 799 10.800 31.430 22.430 1.00 0.00 +ATOM 2871 OW HOH 800 25.100 37.220 29.950 1.00 0.00 +ATOM 2872 HW1 HOH 800 25.920 37.150 29.460 1.00 0.00 +ATOM 2873 HW2 HOH 800 24.470 37.590 29.320 1.00 0.00 +ATOM 2874 OW HOH 801 3.750 38.360 3.710 1.00 0.00 +ATOM 2875 HW1 HOH 801 4.260 38.260 4.520 1.00 0.00 +ATOM 2876 HW2 HOH 801 4.080 37.670 3.140 1.00 0.00 +ATOM 2877 OW HOH 802 14.840 37.760 1.160 1.00 0.00 +ATOM 2878 HW1 HOH 802 14.240 37.720 0.420 1.00 0.00 +ATOM 2879 HW2 HOH 802 15.660 38.080 0.780 1.00 0.00 +ATOM 2880 OW HOH 803 12.400 2.720 20.700 1.00 0.00 +ATOM 2881 HW1 HOH 803 13.000 3.170 21.290 1.00 0.00 +ATOM 2882 HW2 HOH 803 12.740 2.920 19.820 1.00 0.00 +ATOM 2883 OW HOH 804 18.940 5.690 28.120 1.00 0.00 +ATOM 2884 HW1 HOH 804 18.140 5.380 27.700 1.00 0.00 +ATOM 2885 HW2 HOH 804 19.610 5.050 27.850 1.00 0.00 +ATOM 2886 OW HOH 805 6.860 34.620 38.120 1.00 0.00 +ATOM 2887 HW1 HOH 805 7.530 34.360 37.490 1.00 0.00 +ATOM 2888 HW2 HOH 805 6.030 34.360 37.720 1.00 0.00 +ATOM 2889 OW HOH 806 42.540 40.340 2.200 1.00 0.00 +ATOM 2890 HW1 HOH 806 42.670 40.520 3.130 1.00 0.00 +ATOM 2891 HW2 HOH 806 43.290 40.730 1.770 1.00 0.00 +ATOM 2892 OW HOH 807 15.610 39.820 32.070 1.00 0.00 +ATOM 2893 HW1 HOH 807 15.260 39.970 31.190 1.00 0.00 +ATOM 2894 HW2 HOH 807 14.890 39.420 32.550 1.00 0.00 +ATOM 2895 OW HOH 808 35.370 40.470 26.020 1.00 0.00 +ATOM 2896 HW1 HOH 808 36.000 40.980 26.530 1.00 0.00 +ATOM 2897 HW2 HOH 808 35.810 39.630 25.890 1.00 0.00 +ATOM 2898 OW HOH 809 13.670 43.620 20.500 1.00 0.00 +ATOM 2899 HW1 HOH 809 14.450 43.570 19.950 1.00 0.00 +ATOM 2900 HW2 HOH 809 13.610 44.540 20.760 1.00 0.00 +ATOM 2901 OW HOH 810 27.530 31.260 8.410 1.00 0.00 +ATOM 2902 HW1 HOH 810 27.330 30.370 8.140 1.00 0.00 +ATOM 2903 HW2 HOH 810 26.780 31.780 8.120 1.00 0.00 +ATOM 2904 OW HOH 811 22.890 41.190 37.870 1.00 0.00 +ATOM 2905 HW1 HOH 811 22.860 42.010 38.350 1.00 0.00 +ATOM 2906 HW2 HOH 811 23.400 40.600 38.420 1.00 0.00 +ATOM 2907 OW HOH 812 7.700 37.710 12.310 1.00 0.00 +ATOM 2908 HW1 HOH 812 8.220 38.510 12.260 1.00 0.00 +ATOM 2909 HW2 HOH 812 7.730 37.460 13.230 1.00 0.00 +ATOM 2910 OW HOH 813 21.060 31.630 34.980 1.00 0.00 +ATOM 2911 HW1 HOH 813 20.790 31.730 34.070 1.00 0.00 +ATOM 2912 HW2 HOH 813 20.640 32.360 35.440 1.00 0.00 +ATOM 2913 OW HOH 814 37.590 10.030 12.900 1.00 0.00 +ATOM 2914 HW1 HOH 814 37.040 10.770 13.170 1.00 0.00 +ATOM 2915 HW2 HOH 814 38.480 10.310 13.120 1.00 0.00 +ATOM 2916 OW HOH 815 0.730 41.740 11.550 1.00 0.00 +ATOM 2917 HW1 HOH 815 1.340 42.410 11.240 1.00 0.00 +ATOM 2918 HW2 HOH 815 0.930 40.960 11.030 1.00 0.00 +ATOM 2919 OW HOH 816 4.880 37.310 35.800 1.00 0.00 +ATOM 2920 HW1 HOH 816 5.190 38.120 35.400 1.00 0.00 +ATOM 2921 HW2 HOH 816 4.530 36.800 35.070 1.00 0.00 +ATOM 2922 OW HOH 817 48.310 0.680 34.510 1.00 0.00 +ATOM 2923 HW1 HOH 817 47.880 1.520 34.630 1.00 0.00 +ATOM 2924 HW2 HOH 817 49.230 0.850 34.730 1.00 0.00 +ATOM 2925 OW HOH 818 3.650 45.600 7.890 1.00 0.00 +ATOM 2926 HW1 HOH 818 3.080 45.600 7.120 1.00 0.00 +ATOM 2927 HW2 HOH 818 3.050 45.660 8.640 1.00 0.00 +ATOM 2928 OW HOH 819 3.560 6.720 6.000 1.00 0.00 +ATOM 2929 HW1 HOH 819 4.150 5.970 5.920 1.00 0.00 +ATOM 2930 HW2 HOH 819 4.120 7.420 6.320 1.00 0.00 +ATOM 2931 OW HOH 820 35.420 28.440 13.080 1.00 0.00 +ATOM 2932 HW1 HOH 820 35.270 28.310 14.010 1.00 0.00 +ATOM 2933 HW2 HOH 820 34.550 28.300 12.680 1.00 0.00 +ATOM 2934 OW HOH 821 5.890 8.040 3.250 1.00 0.00 +ATOM 2935 HW1 HOH 821 6.440 7.270 3.420 1.00 0.00 +ATOM 2936 HW2 HOH 821 6.500 8.780 3.290 1.00 0.00 +ATOM 2937 OW HOH 822 10.180 35.050 14.980 1.00 0.00 +ATOM 2938 HW1 HOH 822 10.020 35.410 14.110 1.00 0.00 +ATOM 2939 HW2 HOH 822 10.100 35.790 15.570 1.00 0.00 +ATOM 2940 OW HOH 823 28.040 1.660 31.220 1.00 0.00 +ATOM 2941 HW1 HOH 823 28.290 0.760 31.010 1.00 0.00 +ATOM 2942 HW2 HOH 823 27.220 1.580 31.700 1.00 0.00 +ATOM 2943 OW HOH 824 11.770 1.900 38.170 1.00 0.00 +ATOM 2944 HW1 HOH 824 12.220 1.680 37.350 1.00 0.00 +ATOM 2945 HW2 HOH 824 11.000 1.330 38.180 1.00 0.00 +ATOM 2946 OW HOH 825 26.540 16.740 7.740 1.00 0.00 +ATOM 2947 HW1 HOH 825 26.620 16.960 8.660 1.00 0.00 +ATOM 2948 HW2 HOH 825 26.000 15.950 7.720 1.00 0.00 +ATOM 2949 OW HOH 826 26.870 3.930 32.980 1.00 0.00 +ATOM 2950 HW1 HOH 826 26.600 4.200 32.100 1.00 0.00 +ATOM 2951 HW2 HOH 826 27.440 4.640 33.280 1.00 0.00 +ATOM 2952 OW HOH 827 37.040 35.970 23.870 1.00 0.00 +ATOM 2953 HW1 HOH 827 37.680 36.680 23.950 1.00 0.00 +ATOM 2954 HW2 HOH 827 36.790 35.770 24.770 1.00 0.00 +ATOM 2955 OW HOH 828 17.470 35.630 27.680 1.00 0.00 +ATOM 2956 HW1 HOH 828 17.480 35.660 26.730 1.00 0.00 +ATOM 2957 HW2 HOH 828 16.620 35.250 27.900 1.00 0.00 +ATOM 2958 OW HOH 829 5.710 3.210 9.930 1.00 0.00 +ATOM 2959 HW1 HOH 829 4.970 3.780 10.120 1.00 0.00 +ATOM 2960 HW2 HOH 829 5.660 2.520 10.590 1.00 0.00 +ATOM 2961 OW HOH 830 20.880 44.590 28.680 1.00 0.00 +ATOM 2962 HW1 HOH 830 21.720 45.040 28.760 1.00 0.00 +ATOM 2963 HW2 HOH 830 20.620 44.720 27.770 1.00 0.00 +ATOM 2964 OW HOH 831 36.730 15.840 32.290 1.00 0.00 +ATOM 2965 HW1 HOH 831 36.410 16.650 31.910 1.00 0.00 +ATOM 2966 HW2 HOH 831 35.990 15.240 32.260 1.00 0.00 +ATOM 2967 OW HOH 832 31.180 44.270 37.920 1.00 0.00 +ATOM 2968 HW1 HOH 832 31.920 43.790 38.290 1.00 0.00 +ATOM 2969 HW2 HOH 832 31.080 45.030 38.500 1.00 0.00 +ATOM 2970 OW HOH 833 35.090 44.880 32.860 1.00 0.00 +ATOM 2971 HW1 HOH 833 34.810 45.790 32.970 1.00 0.00 +ATOM 2972 HW2 HOH 833 35.840 44.930 32.270 1.00 0.00 +ATOM 2973 OW HOH 834 1.860 0.550 34.770 1.00 0.00 +ATOM 2974 HW1 HOH 834 2.450 0.500 35.520 1.00 0.00 +ATOM 2975 HW2 HOH 834 2.440 0.510 34.010 1.00 0.00 +ATOM 2976 OW HOH 835 18.890 42.670 12.480 1.00 0.00 +ATOM 2977 HW1 HOH 835 18.350 43.350 12.890 1.00 0.00 +ATOM 2978 HW2 HOH 835 18.380 42.390 11.720 1.00 0.00 +ATOM 2979 OW HOH 836 39.220 9.260 20.280 1.00 0.00 +ATOM 2980 HW1 HOH 836 39.420 9.220 21.210 1.00 0.00 +ATOM 2981 HW2 HOH 836 38.990 10.180 20.120 1.00 0.00 +ATOM 2982 OW HOH 837 21.850 38.040 1.530 1.00 0.00 +ATOM 2983 HW1 HOH 837 21.900 37.290 0.940 1.00 0.00 +ATOM 2984 HW2 HOH 837 21.670 37.670 2.390 1.00 0.00 +ATOM 2985 OW HOH 838 26.000 30.700 4.550 1.00 0.00 +ATOM 2986 HW1 HOH 838 26.910 30.430 4.460 1.00 0.00 +ATOM 2987 HW2 HOH 838 26.040 31.620 4.830 1.00 0.00 +ATOM 2988 OW HOH 839 12.490 34.130 16.670 1.00 0.00 +ATOM 2989 HW1 HOH 839 11.810 34.180 15.990 1.00 0.00 +ATOM 2990 HW2 HOH 839 12.010 34.000 17.480 1.00 0.00 +ATOM 2991 OW HOH 840 47.530 5.620 0.460 1.00 0.00 +ATOM 2992 HW1 HOH 840 47.130 5.410 1.300 1.00 0.00 +ATOM 2993 HW2 HOH 840 47.100 6.440 0.190 1.00 0.00 +ATOM 2994 OW HOH 841 14.930 38.620 5.240 1.00 0.00 +ATOM 2995 HW1 HOH 841 14.400 38.110 4.630 1.00 0.00 +ATOM 2996 HW2 HOH 841 14.940 39.500 4.860 1.00 0.00 +ATOM 2997 OW HOH 842 0.460 39.120 14.450 1.00 0.00 +ATOM 2998 HW1 HOH 842 -0.050 39.260 13.650 1.00 0.00 +ATOM 2999 HW2 HOH 842 0.050 39.700 15.090 1.00 0.00 +ATOM 3000 OW HOH 843 4.380 42.900 13.490 1.00 0.00 +ATOM 3001 HW1 HOH 843 3.660 42.410 13.860 1.00 0.00 +ATOM 3002 HW2 HOH 843 4.060 43.210 12.640 1.00 0.00 +ATOM 3003 OW HOH 844 31.710 34.340 27.030 1.00 0.00 +ATOM 3004 HW1 HOH 844 30.900 34.570 27.480 1.00 0.00 +ATOM 3005 HW2 HOH 844 31.460 34.220 26.120 1.00 0.00 +ATOM 3006 OW HOH 845 1.750 34.290 20.930 1.00 0.00 +ATOM 3007 HW1 HOH 845 2.520 34.250 20.360 1.00 0.00 +ATOM 3008 HW2 HOH 845 1.690 35.210 21.190 1.00 0.00 +ATOM 3009 OW HOH 846 13.100 13.640 29.380 1.00 0.00 +ATOM 3010 HW1 HOH 846 13.770 14.090 28.870 1.00 0.00 +ATOM 3011 HW2 HOH 846 13.200 13.990 30.270 1.00 0.00 +ATOM 3012 OW HOH 847 9.930 9.460 24.880 1.00 0.00 +ATOM 3013 HW1 HOH 847 10.000 8.600 25.290 1.00 0.00 +ATOM 3014 HW2 HOH 847 9.170 9.860 25.280 1.00 0.00 +ATOM 3015 OW HOH 848 1.510 45.060 21.580 1.00 0.00 +ATOM 3016 HW1 HOH 848 1.270 45.940 21.290 1.00 0.00 +ATOM 3017 HW2 HOH 848 2.410 45.160 21.920 1.00 0.00 +ATOM 3018 OW HOH 849 23.070 44.980 6.030 1.00 0.00 +ATOM 3019 HW1 HOH 849 23.990 44.730 6.150 1.00 0.00 +ATOM 3020 HW2 HOH 849 23.080 45.930 6.040 1.00 0.00 +ATOM 3021 OW HOH 850 14.370 36.140 18.980 1.00 0.00 +ATOM 3022 HW1 HOH 850 14.930 36.840 19.290 1.00 0.00 +ATOM 3023 HW2 HOH 850 13.840 36.530 18.290 1.00 0.00 +ATOM 3024 OW HOH 851 33.450 22.870 6.670 1.00 0.00 +ATOM 3025 HW1 HOH 851 33.380 21.920 6.540 1.00 0.00 +ATOM 3026 HW2 HOH 851 33.630 23.220 5.800 1.00 0.00 +ATOM 3027 OW HOH 852 29.120 6.500 31.540 1.00 0.00 +ATOM 3028 HW1 HOH 852 29.140 5.560 31.350 1.00 0.00 +ATOM 3029 HW2 HOH 852 28.310 6.810 31.140 1.00 0.00 +ATOM 3030 OW HOH 853 10.610 8.910 2.040 1.00 0.00 +ATOM 3031 HW1 HOH 853 10.210 9.730 1.770 1.00 0.00 +ATOM 3032 HW2 HOH 853 10.480 8.870 2.980 1.00 0.00 +ATOM 3033 OW HOH 854 22.550 8.120 35.680 1.00 0.00 +ATOM 3034 HW1 HOH 854 21.760 8.480 36.090 1.00 0.00 +ATOM 3035 HW2 HOH 854 23.190 8.830 35.730 1.00 0.00 +ATOM 3036 OW HOH 855 15.400 3.570 20.910 1.00 0.00 +ATOM 3037 HW1 HOH 855 14.980 3.370 21.750 1.00 0.00 +ATOM 3038 HW2 HOH 855 15.780 2.740 20.630 1.00 0.00 +ATOM 3039 OW HOH 856 28.680 40.980 17.080 1.00 0.00 +ATOM 3040 HW1 HOH 856 28.320 41.840 16.860 1.00 0.00 +ATOM 3041 HW2 HOH 856 29.620 41.050 16.900 1.00 0.00 +ATOM 3042 OW HOH 857 19.880 21.440 27.120 1.00 0.00 +ATOM 3043 HW1 HOH 857 20.800 21.670 27.000 1.00 0.00 +ATOM 3044 HW2 HOH 857 19.740 20.680 26.560 1.00 0.00 +ATOM 3045 OW HOH 858 41.620 5.240 22.250 1.00 0.00 +ATOM 3046 HW1 HOH 858 40.990 5.390 21.550 1.00 0.00 +ATOM 3047 HW2 HOH 858 41.280 4.480 22.720 1.00 0.00 +ATOM 3048 OW HOH 859 3.590 16.540 14.080 1.00 0.00 +ATOM 3049 HW1 HOH 859 4.390 16.330 14.550 1.00 0.00 +ATOM 3050 HW2 HOH 859 3.140 15.700 13.970 1.00 0.00 +ATOM 3051 OW HOH 860 20.000 28.110 5.730 1.00 0.00 +ATOM 3052 HW1 HOH 860 20.570 28.160 6.500 1.00 0.00 +ATOM 3053 HW2 HOH 860 19.130 28.290 6.080 1.00 0.00 +ATOM 3054 OW HOH 861 14.980 11.360 2.730 1.00 0.00 +ATOM 3055 HW1 HOH 861 14.790 12.010 2.040 1.00 0.00 +ATOM 3056 HW2 HOH 861 15.150 10.550 2.250 1.00 0.00 +ATOM 3057 OW HOH 862 42.530 1.300 32.750 1.00 0.00 +ATOM 3058 HW1 HOH 862 42.440 1.680 33.630 1.00 0.00 +ATOM 3059 HW2 HOH 862 43.460 1.100 32.660 1.00 0.00 +ATOM 3060 OW HOH 863 2.960 13.800 36.950 1.00 0.00 +ATOM 3061 HW1 HOH 863 2.860 12.930 37.340 1.00 0.00 +ATOM 3062 HW2 HOH 863 2.250 13.870 36.310 1.00 0.00 +ATOM 3063 OW HOH 864 32.900 45.720 2.540 1.00 0.00 +ATOM 3064 HW1 HOH 864 33.580 45.140 2.880 1.00 0.00 +ATOM 3065 HW2 HOH 864 32.240 45.750 3.230 1.00 0.00 +ATOM 3066 OW HOH 865 15.010 28.960 3.710 1.00 0.00 +ATOM 3067 HW1 HOH 865 14.870 29.800 4.150 1.00 0.00 +ATOM 3068 HW2 HOH 865 14.510 28.330 4.230 1.00 0.00 +ATOM 3069 OW HOH 866 25.780 27.030 36.350 1.00 0.00 +ATOM 3070 HW1 HOH 866 26.070 26.160 36.600 1.00 0.00 +ATOM 3071 HW2 HOH 866 24.900 27.110 36.710 1.00 0.00 +ATOM 3072 OW HOH 867 18.850 15.690 15.940 1.00 0.00 +ATOM 3073 HW1 HOH 867 19.310 14.900 15.660 1.00 0.00 +ATOM 3074 HW2 HOH 867 18.480 15.470 16.790 1.00 0.00 +ATOM 3075 OW HOH 868 7.920 35.660 10.450 1.00 0.00 +ATOM 3076 HW1 HOH 868 7.390 35.950 9.700 1.00 0.00 +ATOM 3077 HW2 HOH 868 7.880 36.390 11.070 1.00 0.00 +ATOM 3078 OW HOH 869 47.240 28.670 37.900 1.00 0.00 +ATOM 3079 HW1 HOH 869 46.610 28.650 37.180 1.00 0.00 +ATOM 3080 HW2 HOH 869 47.780 27.890 37.770 1.00 0.00 +ATOM 3081 OW HOH 870 10.250 7.120 30.360 1.00 0.00 +ATOM 3082 HW1 HOH 870 9.630 6.750 29.730 1.00 0.00 +ATOM 3083 HW2 HOH 870 10.210 8.060 30.220 1.00 0.00 +ATOM 3084 OW HOH 871 31.390 37.110 8.010 1.00 0.00 +ATOM 3085 HW1 HOH 871 31.480 37.400 8.920 1.00 0.00 +ATOM 3086 HW2 HOH 871 31.070 37.880 7.540 1.00 0.00 +ATOM 3087 OW HOH 872 35.000 8.050 32.350 1.00 0.00 +ATOM 3088 HW1 HOH 872 35.450 8.620 32.970 1.00 0.00 +ATOM 3089 HW2 HOH 872 35.700 7.730 31.770 1.00 0.00 +ATOM 3090 OW HOH 873 25.750 0.840 26.400 1.00 0.00 +ATOM 3091 HW1 HOH 873 24.810 0.780 26.570 1.00 0.00 +ATOM 3092 HW2 HOH 873 26.060 1.530 26.990 1.00 0.00 +ATOM 3093 OW HOH 874 20.710 16.750 36.700 1.00 0.00 +ATOM 3094 HW1 HOH 874 21.070 15.870 36.800 1.00 0.00 +ATOM 3095 HW2 HOH 874 21.080 17.250 37.430 1.00 0.00 +ATOM 3096 OW HOH 875 48.300 35.990 15.310 1.00 0.00 +ATOM 3097 HW1 HOH 875 48.030 36.860 15.030 1.00 0.00 +ATOM 3098 HW2 HOH 875 48.970 35.730 14.680 1.00 0.00 +ATOM 3099 OW HOH 876 43.220 26.960 28.880 1.00 0.00 +ATOM 3100 HW1 HOH 876 43.000 27.510 28.120 1.00 0.00 +ATOM 3101 HW2 HOH 876 44.150 26.760 28.760 1.00 0.00 +ATOM 3102 OW HOH 877 20.870 29.230 30.730 1.00 0.00 +ATOM 3103 HW1 HOH 877 20.790 28.280 30.800 1.00 0.00 +ATOM 3104 HW2 HOH 877 20.220 29.470 30.060 1.00 0.00 +ATOM 3105 OW HOH 878 18.150 44.640 21.530 1.00 0.00 +ATOM 3106 HW1 HOH 878 17.350 44.580 22.060 1.00 0.00 +ATOM 3107 HW2 HOH 878 17.990 45.360 20.930 1.00 0.00 +ATOM 3108 OW HOH 879 24.420 42.120 9.960 1.00 0.00 +ATOM 3109 HW1 HOH 879 24.400 42.210 10.910 1.00 0.00 +ATOM 3110 HW2 HOH 879 24.980 41.350 9.810 1.00 0.00 +ATOM 3111 OW HOH 880 21.680 32.310 1.470 1.00 0.00 +ATOM 3112 HW1 HOH 880 22.480 31.920 1.820 1.00 0.00 +ATOM 3113 HW2 HOH 880 20.980 31.720 1.770 1.00 0.00 +ATOM 3114 OW HOH 881 10.980 31.470 27.560 1.00 0.00 +ATOM 3115 HW1 HOH 881 10.630 32.330 27.330 1.00 0.00 +ATOM 3116 HW2 HOH 881 10.240 31.010 27.970 1.00 0.00 +ATOM 3117 OW HOH 882 20.910 10.200 28.370 1.00 0.00 +ATOM 3118 HW1 HOH 882 21.270 9.360 28.630 1.00 0.00 +ATOM 3119 HW2 HOH 882 20.310 10.440 29.070 1.00 0.00 +ATOM 3120 OW HOH 883 27.760 32.230 31.350 1.00 0.00 +ATOM 3121 HW1 HOH 883 27.140 31.560 31.620 1.00 0.00 +ATOM 3122 HW2 HOH 883 27.270 33.050 31.410 1.00 0.00 +ATOM 3123 OW HOH 884 13.650 15.520 38.320 1.00 0.00 +ATOM 3124 HW1 HOH 884 13.830 16.030 37.530 1.00 0.00 +ATOM 3125 HW2 HOH 884 13.990 16.050 39.040 1.00 0.00 +ATOM 3126 OW HOH 885 42.550 44.440 3.040 1.00 0.00 +ATOM 3127 HW1 HOH 885 41.950 44.850 3.650 1.00 0.00 +ATOM 3128 HW2 HOH 885 43.410 44.740 3.300 1.00 0.00 +ATOM 3129 OW HOH 886 40.460 41.700 10.590 1.00 0.00 +ATOM 3130 HW1 HOH 886 40.700 41.490 9.680 1.00 0.00 +ATOM 3131 HW2 HOH 886 40.740 42.610 10.700 1.00 0.00 +ATOM 3132 OW HOH 887 9.900 37.030 18.070 1.00 0.00 +ATOM 3133 HW1 HOH 887 9.280 37.260 18.750 1.00 0.00 +ATOM 3134 HW2 HOH 887 10.410 37.830 17.920 1.00 0.00 +ATOM 3135 OW HOH 888 22.080 4.540 2.770 1.00 0.00 +ATOM 3136 HW1 HOH 888 22.200 4.120 1.920 1.00 0.00 +ATOM 3137 HW2 HOH 888 21.860 5.450 2.570 1.00 0.00 +ATOM 3138 OW HOH 889 8.120 30.040 28.610 1.00 0.00 +ATOM 3139 HW1 HOH 889 8.300 29.120 28.840 1.00 0.00 +ATOM 3140 HW2 HOH 889 7.200 30.160 28.850 1.00 0.00 +ATOM 3141 OW HOH 890 15.260 27.690 33.390 1.00 0.00 +ATOM 3142 HW1 HOH 890 14.980 27.990 34.260 1.00 0.00 +ATOM 3143 HW2 HOH 890 14.460 27.710 32.870 1.00 0.00 +ATOM 3144 OW HOH 891 24.330 21.550 38.330 1.00 0.00 +ATOM 3145 HW1 HOH 891 23.810 21.860 37.580 1.00 0.00 +ATOM 3146 HW2 HOH 891 23.890 21.930 39.090 1.00 0.00 +ATOM 3147 OW HOH 892 38.560 11.630 24.580 1.00 0.00 +ATOM 3148 HW1 HOH 892 39.360 11.700 25.110 1.00 0.00 +ATOM 3149 HW2 HOH 892 38.540 10.710 24.310 1.00 0.00 +ATOM 3150 OW HOH 893 3.680 24.920 24.360 1.00 0.00 +ATOM 3151 HW1 HOH 893 4.120 24.530 23.600 1.00 0.00 +ATOM 3152 HW2 HOH 893 3.340 24.170 24.850 1.00 0.00 +ATOM 3153 OW HOH 894 15.910 12.230 29.890 1.00 0.00 +ATOM 3154 HW1 HOH 894 15.610 11.580 29.260 1.00 0.00 +ATOM 3155 HW2 HOH 894 15.920 11.770 30.730 1.00 0.00 +ATOM 3156 OW HOH 895 28.960 0.620 36.670 1.00 0.00 +ATOM 3157 HW1 HOH 895 29.870 0.390 36.840 1.00 0.00 +ATOM 3158 HW2 HOH 895 28.530 -0.210 36.470 1.00 0.00 +ATOM 3159 OW HOH 896 37.260 27.090 19.520 1.00 0.00 +ATOM 3160 HW1 HOH 896 36.860 27.930 19.290 1.00 0.00 +ATOM 3161 HW2 HOH 896 38.200 27.220 19.390 1.00 0.00 +ATOM 3162 OW HOH 897 33.810 34.940 36.270 1.00 0.00 +ATOM 3163 HW1 HOH 897 34.090 34.940 37.190 1.00 0.00 +ATOM 3164 HW2 HOH 897 33.310 34.130 36.170 1.00 0.00 +ATOM 3165 OW HOH 898 40.180 6.290 11.750 1.00 0.00 +ATOM 3166 HW1 HOH 898 39.630 5.550 12.010 1.00 0.00 +ATOM 3167 HW2 HOH 898 39.690 6.740 11.070 1.00 0.00 +ATOM 3168 OW HOH 899 18.650 3.070 14.140 1.00 0.00 +ATOM 3169 HW1 HOH 899 19.430 3.500 13.800 1.00 0.00 +ATOM 3170 HW2 HOH 899 18.720 2.170 13.840 1.00 0.00 +ATOM 3171 OW HOH 900 45.770 37.240 26.420 1.00 0.00 +ATOM 3172 HW1 HOH 900 45.390 37.890 25.840 1.00 0.00 +ATOM 3173 HW2 HOH 900 46.650 37.090 26.080 1.00 0.00 +ATOM 3174 OW HOH 901 7.230 38.440 37.230 1.00 0.00 +ATOM 3175 HW1 HOH 901 8.070 38.080 37.530 1.00 0.00 +ATOM 3176 HW2 HOH 901 6.660 37.680 37.150 1.00 0.00 +ATOM 3177 OW HOH 902 4.820 21.170 10.940 1.00 0.00 +ATOM 3178 HW1 HOH 902 5.000 22.060 11.240 1.00 0.00 +ATOM 3179 HW2 HOH 902 5.470 21.010 10.270 1.00 0.00 +ATOM 3180 OW HOH 903 40.710 8.810 35.650 1.00 0.00 +ATOM 3181 HW1 HOH 903 40.240 8.100 36.080 1.00 0.00 +ATOM 3182 HW2 HOH 903 41.540 8.410 35.370 1.00 0.00 +ATOM 3183 OW HOH 904 41.810 43.850 33.590 1.00 0.00 +ATOM 3184 HW1 HOH 904 42.770 43.940 33.610 1.00 0.00 +ATOM 3185 HW2 HOH 904 41.490 44.680 33.930 1.00 0.00 +ATOM 3186 OW HOH 905 20.930 15.250 2.590 1.00 0.00 +ATOM 3187 HW1 HOH 905 20.810 16.190 2.460 1.00 0.00 +ATOM 3188 HW2 HOH 905 21.740 15.050 2.120 1.00 0.00 +ATOM 3189 OW HOH 906 5.590 4.770 6.200 1.00 0.00 +ATOM 3190 HW1 HOH 906 5.040 4.030 6.470 1.00 0.00 +ATOM 3191 HW2 HOH 906 6.420 4.360 5.960 1.00 0.00 +ATOM 3192 OW HOH 907 4.030 25.780 27.080 1.00 0.00 +ATOM 3193 HW1 HOH 907 3.890 25.020 26.510 1.00 0.00 +ATOM 3194 HW2 HOH 907 4.430 25.420 27.870 1.00 0.00 +ATOM 3195 OW HOH 908 15.970 31.110 13.680 1.00 0.00 +ATOM 3196 HW1 HOH 908 16.770 31.630 13.810 1.00 0.00 +ATOM 3197 HW2 HOH 908 15.470 31.230 14.490 1.00 0.00 +ATOM 3198 OW HOH 909 27.110 35.040 37.970 1.00 0.00 +ATOM 3199 HW1 HOH 909 26.490 34.600 38.550 1.00 0.00 +ATOM 3200 HW2 HOH 909 27.270 34.410 37.270 1.00 0.00 +ATOM 3201 OW HOH 910 22.170 42.330 33.020 1.00 0.00 +ATOM 3202 HW1 HOH 910 22.840 41.980 32.430 1.00 0.00 +ATOM 3203 HW2 HOH 910 22.570 42.280 33.890 1.00 0.00 +ATOM 3204 OW HOH 911 35.730 7.560 16.220 1.00 0.00 +ATOM 3205 HW1 HOH 911 36.120 8.360 16.570 1.00 0.00 +ATOM 3206 HW2 HOH 911 35.550 7.770 15.300 1.00 0.00 +ATOM 3207 OW HOH 912 11.750 36.330 8.270 1.00 0.00 +ATOM 3208 HW1 HOH 912 12.170 37.190 8.150 1.00 0.00 +ATOM 3209 HW2 HOH 912 12.380 35.830 8.790 1.00 0.00 +ATOM 3210 OW HOH 913 32.780 41.220 26.360 1.00 0.00 +ATOM 3211 HW1 HOH 913 32.270 40.560 25.880 1.00 0.00 +ATOM 3212 HW2 HOH 913 33.670 40.860 26.380 1.00 0.00 +ATOM 3213 OW HOH 914 0.180 31.340 1.800 1.00 0.00 +ATOM 3214 HW1 HOH 914 0.610 30.550 2.130 1.00 0.00 +ATOM 3215 HW2 HOH 914 0.440 32.030 2.420 1.00 0.00 +ATOM 3216 OW HOH 915 19.320 30.630 16.070 1.00 0.00 +ATOM 3217 HW1 HOH 915 18.680 29.930 16.110 1.00 0.00 +ATOM 3218 HW2 HOH 915 19.290 31.040 16.930 1.00 0.00 +ATOM 3219 OW HOH 916 14.260 27.750 36.120 1.00 0.00 +ATOM 3220 HW1 HOH 916 13.570 27.430 36.710 1.00 0.00 +ATOM 3221 HW2 HOH 916 14.970 28.000 36.710 1.00 0.00 +ATOM 3222 OW HOH 917 32.130 14.740 29.600 1.00 0.00 +ATOM 3223 HW1 HOH 917 32.620 15.460 29.990 1.00 0.00 +ATOM 3224 HW2 HOH 917 31.680 14.330 30.340 1.00 0.00 +ATOM 3225 OW HOH 918 2.350 26.100 11.020 1.00 0.00 +ATOM 3226 HW1 HOH 918 1.390 26.060 10.930 1.00 0.00 +ATOM 3227 HW2 HOH 918 2.590 26.950 10.640 1.00 0.00 +ATOM 3228 OW HOH 919 38.550 14.900 6.780 1.00 0.00 +ATOM 3229 HW1 HOH 919 37.860 15.550 6.650 1.00 0.00 +ATOM 3230 HW2 HOH 919 38.450 14.620 7.690 1.00 0.00 +ATOM 3231 OW HOH 920 10.090 1.310 3.340 1.00 0.00 +ATOM 3232 HW1 HOH 920 10.190 2.210 3.040 1.00 0.00 +ATOM 3233 HW2 HOH 920 10.970 0.940 3.310 1.00 0.00 +ATOM 3234 OW HOH 921 14.820 35.190 28.090 1.00 0.00 +ATOM 3235 HW1 HOH 921 14.830 36.130 27.940 1.00 0.00 +ATOM 3236 HW2 HOH 921 14.520 35.090 29.000 1.00 0.00 +ATOM 3237 OW HOH 922 3.780 22.430 14.140 1.00 0.00 +ATOM 3238 HW1 HOH 922 4.110 22.510 13.240 1.00 0.00 +ATOM 3239 HW2 HOH 922 2.890 22.790 14.100 1.00 0.00 +ATOM 3240 OW HOH 923 31.880 44.600 35.170 1.00 0.00 +ATOM 3241 HW1 HOH 923 31.100 44.810 34.660 1.00 0.00 +ATOM 3242 HW2 HOH 923 31.580 44.650 36.080 1.00 0.00 +ATOM 3243 OW HOH 924 28.420 39.130 13.150 1.00 0.00 +ATOM 3244 HW1 HOH 924 28.640 38.390 12.580 1.00 0.00 +ATOM 3245 HW2 HOH 924 28.170 38.730 13.980 1.00 0.00 +ATOM 3246 OW HOH 925 42.080 27.690 4.070 1.00 0.00 +ATOM 3247 HW1 HOH 925 41.540 28.350 4.510 1.00 0.00 +ATOM 3248 HW2 HOH 925 42.030 26.920 4.630 1.00 0.00 +ATOM 3249 OW HOH 926 36.470 4.870 38.550 1.00 0.00 +ATOM 3250 HW1 HOH 926 35.680 4.600 39.020 1.00 0.00 +ATOM 3251 HW2 HOH 926 36.320 4.570 37.650 1.00 0.00 +ATOM 3252 OW HOH 927 38.210 29.600 24.890 1.00 0.00 +ATOM 3253 HW1 HOH 927 38.120 29.460 25.830 1.00 0.00 +ATOM 3254 HW2 HOH 927 38.930 29.030 24.630 1.00 0.00 +ATOM 3255 OW HOH 928 3.300 42.490 7.110 1.00 0.00 +ATOM 3256 HW1 HOH 928 3.920 42.860 6.470 1.00 0.00 +ATOM 3257 HW2 HOH 928 3.320 41.550 6.950 1.00 0.00 +ATOM 3258 OW HOH 929 47.960 27.270 32.790 1.00 0.00 +ATOM 3259 HW1 HOH 929 48.180 27.310 31.860 1.00 0.00 +ATOM 3260 HW2 HOH 929 48.800 27.100 33.230 1.00 0.00 +ATOM 3261 OW HOH 930 7.490 22.500 3.320 1.00 0.00 +ATOM 3262 HW1 HOH 930 7.490 21.670 3.800 1.00 0.00 +ATOM 3263 HW2 HOH 930 7.220 23.150 3.970 1.00 0.00 +ATOM 3264 OW HOH 931 11.460 43.200 18.630 1.00 0.00 +ATOM 3265 HW1 HOH 931 11.930 43.630 19.340 1.00 0.00 +ATOM 3266 HW2 HOH 931 11.380 42.290 18.910 1.00 0.00 +ATOM 3267 OW HOH 932 20.450 4.680 12.870 1.00 0.00 +ATOM 3268 HW1 HOH 932 19.620 5.100 12.620 1.00 0.00 +ATOM 3269 HW2 HOH 932 21.130 5.240 12.500 1.00 0.00 +ATOM 3270 OW HOH 933 19.730 33.210 30.200 1.00 0.00 +ATOM 3271 HW1 HOH 933 19.750 32.800 29.330 1.00 0.00 +ATOM 3272 HW2 HOH 933 20.610 33.550 30.330 1.00 0.00 +ATOM 3273 OW HOH 934 23.270 29.290 5.570 1.00 0.00 +ATOM 3274 HW1 HOH 934 24.140 29.710 5.550 1.00 0.00 +ATOM 3275 HW2 HOH 934 22.900 29.560 6.410 1.00 0.00 +ATOM 3276 OW HOH 935 20.970 41.880 8.950 1.00 0.00 +ATOM 3277 HW1 HOH 935 21.700 41.310 9.180 1.00 0.00 +ATOM 3278 HW2 HOH 935 20.520 42.040 9.770 1.00 0.00 +ATOM 3279 OW HOH 936 28.990 45.780 5.820 1.00 0.00 +ATOM 3280 HW1 HOH 936 29.710 46.330 6.150 1.00 0.00 +ATOM 3281 HW2 HOH 936 28.520 45.520 6.610 1.00 0.00 +ATOM 3282 OW HOH 937 39.500 12.100 21.490 1.00 0.00 +ATOM 3283 HW1 HOH 937 39.720 12.700 20.770 1.00 0.00 +ATOM 3284 HW2 HOH 937 39.210 12.680 22.200 1.00 0.00 +ATOM 3285 OW HOH 938 41.680 20.340 13.390 1.00 0.00 +ATOM 3286 HW1 HOH 938 40.820 19.930 13.480 1.00 0.00 +ATOM 3287 HW2 HOH 938 41.850 20.320 12.450 1.00 0.00 +ATOM 3288 OW HOH 939 34.270 43.930 18.710 1.00 0.00 +ATOM 3289 HW1 HOH 939 33.480 44.460 18.680 1.00 0.00 +ATOM 3290 HW2 HOH 939 34.990 44.560 18.680 1.00 0.00 +ATOM 3291 OW HOH 940 46.860 3.480 14.490 1.00 0.00 +ATOM 3292 HW1 HOH 940 46.550 4.170 15.090 1.00 0.00 +ATOM 3293 HW2 HOH 940 46.180 2.810 14.530 1.00 0.00 +ATOM 3294 OW HOH 941 37.220 14.590 16.550 1.00 0.00 +ATOM 3295 HW1 HOH 941 37.580 13.810 16.140 1.00 0.00 +ATOM 3296 HW2 HOH 941 37.880 15.270 16.400 1.00 0.00 +ATOM 3297 OW HOH 942 5.580 15.640 28.250 1.00 0.00 +ATOM 3298 HW1 HOH 942 6.010 15.590 27.400 1.00 0.00 +ATOM 3299 HW2 HOH 942 4.870 14.990 28.200 1.00 0.00 +ATOM 3300 OW HOH 943 2.810 0.250 2.550 1.00 0.00 +ATOM 3301 HW1 HOH 943 2.480 0.930 1.970 1.00 0.00 +ATOM 3302 HW2 HOH 943 2.400 -0.550 2.250 1.00 0.00 +ATOM 3303 OW HOH 944 32.700 19.320 8.890 1.00 0.00 +ATOM 3304 HW1 HOH 944 32.580 18.670 8.200 1.00 0.00 +ATOM 3305 HW2 HOH 944 31.940 19.210 9.460 1.00 0.00 +ATOM 3306 OW HOH 945 14.740 23.750 33.750 1.00 0.00 +ATOM 3307 HW1 HOH 945 15.630 24.070 33.590 1.00 0.00 +ATOM 3308 HW2 HOH 945 14.170 24.460 33.440 1.00 0.00 +ATOM 3309 OW HOH 946 49.470 17.810 27.190 1.00 0.00 +ATOM 3310 HW1 HOH 946 48.940 17.240 26.630 1.00 0.00 +ATOM 3311 HW2 HOH 946 48.880 18.040 27.910 1.00 0.00 +ATOM 3312 OW HOH 947 27.630 27.290 3.060 1.00 0.00 +ATOM 3313 HW1 HOH 947 27.410 27.150 3.980 1.00 0.00 +ATOM 3314 HW2 HOH 947 28.590 27.350 3.050 1.00 0.00 +ATOM 3315 OW HOH 948 38.230 18.470 36.280 1.00 0.00 +ATOM 3316 HW1 HOH 948 38.160 18.200 35.360 1.00 0.00 +ATOM 3317 HW2 HOH 948 39.160 18.680 36.390 1.00 0.00 +ATOM 3318 OW HOH 949 46.980 11.490 28.520 1.00 0.00 +ATOM 3319 HW1 HOH 949 47.670 12.130 28.340 1.00 0.00 +ATOM 3320 HW2 HOH 949 46.310 11.990 28.990 1.00 0.00 +ATOM 3321 OW HOH 950 19.780 38.170 19.440 1.00 0.00 +ATOM 3322 HW1 HOH 950 19.760 39.010 19.890 1.00 0.00 +ATOM 3323 HW2 HOH 950 19.350 37.560 20.040 1.00 0.00 +ATOM 3324 OW HOH 951 21.820 34.510 16.810 1.00 0.00 +ATOM 3325 HW1 HOH 951 21.660 35.420 17.040 1.00 0.00 +ATOM 3326 HW2 HOH 951 22.290 34.560 15.970 1.00 0.00 +ATOM 3327 OW HOH 952 17.290 19.050 34.190 1.00 0.00 +ATOM 3328 HW1 HOH 952 18.080 18.900 34.720 1.00 0.00 +ATOM 3329 HW2 HOH 952 17.620 19.470 33.390 1.00 0.00 +ATOM 3330 OW HOH 953 17.660 28.340 14.910 1.00 0.00 +ATOM 3331 HW1 HOH 953 16.740 28.200 15.130 1.00 0.00 +ATOM 3332 HW2 HOH 953 18.120 27.590 15.280 1.00 0.00 +ATOM 3333 OW HOH 954 43.420 45.050 22.270 1.00 0.00 +ATOM 3334 HW1 HOH 954 44.120 45.670 22.490 1.00 0.00 +ATOM 3335 HW2 HOH 954 43.490 44.930 21.320 1.00 0.00 +ATOM 3336 OW HOH 955 24.340 11.750 15.560 1.00 0.00 +ATOM 3337 HW1 HOH 955 23.910 12.270 14.880 1.00 0.00 +ATOM 3338 HW2 HOH 955 23.740 11.030 15.730 1.00 0.00 +ATOM 3339 OW HOH 956 3.410 22.440 3.570 1.00 0.00 +ATOM 3340 HW1 HOH 956 4.000 22.770 2.890 1.00 0.00 +ATOM 3341 HW2 HOH 956 3.750 21.570 3.780 1.00 0.00 +ATOM 3342 OW HOH 957 23.680 25.200 34.730 1.00 0.00 +ATOM 3343 HW1 HOH 957 23.480 26.120 34.560 1.00 0.00 +ATOM 3344 HW2 HOH 957 24.420 25.000 34.160 1.00 0.00 +ATOM 3345 OW HOH 958 41.820 0.690 13.580 1.00 0.00 +ATOM 3346 HW1 HOH 958 42.240 0.130 12.920 1.00 0.00 +ATOM 3347 HW2 HOH 958 42.070 0.310 14.420 1.00 0.00 +ATOM 3348 OW HOH 959 6.620 17.110 36.540 1.00 0.00 +ATOM 3349 HW1 HOH 959 6.490 16.700 35.680 1.00 0.00 +ATOM 3350 HW2 HOH 959 7.400 17.650 36.430 1.00 0.00 +ATOM 3351 OW HOH 960 23.690 5.240 5.080 1.00 0.00 +ATOM 3352 HW1 HOH 960 23.010 5.740 5.520 1.00 0.00 +ATOM 3353 HW2 HOH 960 23.310 5.010 4.230 1.00 0.00 +ATOM 3354 OW HOH 961 24.150 31.710 8.260 1.00 0.00 +ATOM 3355 HW1 HOH 961 24.440 32.590 8.500 1.00 0.00 +ATOM 3356 HW2 HOH 961 23.250 31.830 7.960 1.00 0.00 +ATOM 3357 OW HOH 962 44.570 27.650 15.950 1.00 0.00 +ATOM 3358 HW1 HOH 962 44.820 27.580 15.030 1.00 0.00 +ATOM 3359 HW2 HOH 962 44.770 26.800 16.330 1.00 0.00 +ATOM 3360 OW HOH 963 7.800 18.110 13.630 1.00 0.00 +ATOM 3361 HW1 HOH 963 7.080 18.640 13.300 1.00 0.00 +ATOM 3362 HW2 HOH 963 8.400 18.040 12.890 1.00 0.00 +ATOM 3363 OW HOH 964 37.520 35.020 26.820 1.00 0.00 +ATOM 3364 HW1 HOH 964 36.830 34.570 27.310 1.00 0.00 +ATOM 3365 HW2 HOH 964 38.260 34.420 26.850 1.00 0.00 +ATOM 3366 OW HOH 965 24.090 18.460 29.890 1.00 0.00 +ATOM 3367 HW1 HOH 965 24.070 17.520 30.090 1.00 0.00 +ATOM 3368 HW2 HOH 965 23.980 18.510 28.940 1.00 0.00 +ATOM 3369 OW HOH 966 10.490 40.000 19.960 1.00 0.00 +ATOM 3370 HW1 HOH 966 11.070 39.800 19.230 1.00 0.00 +ATOM 3371 HW2 HOH 966 9.770 39.370 19.880 1.00 0.00 +ATOM 3372 OW HOH 967 27.750 30.830 34.410 1.00 0.00 +ATOM 3373 HW1 HOH 967 27.950 29.920 34.180 1.00 0.00 +ATOM 3374 HW2 HOH 967 27.090 31.100 33.770 1.00 0.00 +ATOM 3375 OW HOH 968 21.710 39.840 12.970 1.00 0.00 +ATOM 3376 HW1 HOH 968 22.030 39.650 12.090 1.00 0.00 +ATOM 3377 HW2 HOH 968 20.840 40.210 12.840 1.00 0.00 +ATOM 3378 OW HOH 969 1.900 36.300 31.100 1.00 0.00 +ATOM 3379 HW1 HOH 969 1.820 37.080 31.650 1.00 0.00 +ATOM 3380 HW2 HOH 969 1.180 36.360 30.490 1.00 0.00 +ATOM 3381 OW HOH 970 32.580 8.620 30.920 1.00 0.00 +ATOM 3382 HW1 HOH 970 32.990 9.340 30.440 1.00 0.00 +ATOM 3383 HW2 HOH 970 33.190 8.410 31.620 1.00 0.00 +ATOM 3384 OW HOH 971 19.190 45.560 30.650 1.00 0.00 +ATOM 3385 HW1 HOH 971 18.340 45.280 30.300 1.00 0.00 +ATOM 3386 HW2 HOH 971 19.820 45.300 29.980 1.00 0.00 +ATOM 3387 OW HOH 972 18.340 1.680 8.450 1.00 0.00 +ATOM 3388 HW1 HOH 972 18.850 1.900 7.670 1.00 0.00 +ATOM 3389 HW2 HOH 972 18.070 0.770 8.300 1.00 0.00 +ATOM 3390 OW HOH 973 30.120 36.900 11.650 1.00 0.00 +ATOM 3391 HW1 HOH 973 29.940 36.810 10.710 1.00 0.00 +ATOM 3392 HW2 HOH 973 30.760 37.610 11.710 1.00 0.00 +ATOM 3393 OW HOH 974 0.560 41.240 4.570 1.00 0.00 +ATOM 3394 HW1 HOH 974 -0.260 41.210 4.080 1.00 0.00 +ATOM 3395 HW2 HOH 974 1.190 41.650 3.980 1.00 0.00 +ATOM 3396 OW HOH 975 27.420 42.800 21.770 1.00 0.00 +ATOM 3397 HW1 HOH 975 27.980 43.490 22.130 1.00 0.00 +ATOM 3398 HW2 HOH 975 27.830 42.590 20.930 1.00 0.00 +ATOM 3399 OW HOH 976 26.600 39.130 20.040 1.00 0.00 +ATOM 3400 HW1 HOH 976 27.140 39.170 20.830 1.00 0.00 +ATOM 3401 HW2 HOH 976 25.700 39.130 20.360 1.00 0.00 +ATOM 3402 OW HOH 977 21.840 10.790 3.480 1.00 0.00 +ATOM 3403 HW1 HOH 977 22.640 11.290 3.650 1.00 0.00 +ATOM 3404 HW2 HOH 977 21.480 11.170 2.680 1.00 0.00 +ATOM 3405 OW HOH 978 24.930 16.990 20.340 1.00 0.00 +ATOM 3406 HW1 HOH 978 24.590 17.050 21.240 1.00 0.00 +ATOM 3407 HW2 HOH 978 25.670 17.600 20.330 1.00 0.00 +ATOM 3408 OW HOH 979 3.990 6.090 12.550 1.00 0.00 +ATOM 3409 HW1 HOH 979 3.940 6.460 11.670 1.00 0.00 +ATOM 3410 HW2 HOH 979 3.550 6.730 13.110 1.00 0.00 +ATOM 3411 OW HOH 980 6.460 32.660 34.670 1.00 0.00 +ATOM 3412 HW1 HOH 980 7.130 32.930 35.310 1.00 0.00 +ATOM 3413 HW2 HOH 980 5.650 33.060 34.990 1.00 0.00 +ATOM 3414 OW HOH 981 9.600 45.480 15.830 1.00 0.00 +ATOM 3415 HW1 HOH 981 9.900 45.800 16.680 1.00 0.00 +ATOM 3416 HW2 HOH 981 8.660 45.650 15.840 1.00 0.00 +ATOM 3417 OW HOH 982 9.940 17.300 3.540 1.00 0.00 +ATOM 3418 HW1 HOH 982 9.370 17.740 2.910 1.00 0.00 +ATOM 3419 HW2 HOH 982 9.360 16.690 4.000 1.00 0.00 +ATOM 3420 OW HOH 983 10.870 34.610 28.760 1.00 0.00 +ATOM 3421 HW1 HOH 983 9.940 34.740 28.960 1.00 0.00 +ATOM 3422 HW2 HOH 983 11.260 34.320 29.580 1.00 0.00 +ATOM 3423 OW HOH 984 5.830 0.620 19.560 1.00 0.00 +ATOM 3424 HW1 HOH 984 5.880 0.150 18.730 1.00 0.00 +ATOM 3425 HW2 HOH 984 6.260 1.460 19.390 1.00 0.00 +ATOM 3426 OW HOH 985 12.770 23.530 25.000 1.00 0.00 +ATOM 3427 HW1 HOH 985 11.990 23.510 24.440 1.00 0.00 +ATOM 3428 HW2 HOH 985 12.820 22.650 25.380 1.00 0.00 +ATOM 3429 OW HOH 986 33.790 13.410 0.280 1.00 0.00 +ATOM 3430 HW1 HOH 986 32.850 13.390 0.460 1.00 0.00 +ATOM 3431 HW2 HOH 986 33.930 14.240 -0.170 1.00 0.00 +ATOM 3432 OW HOH 987 29.620 22.950 36.250 1.00 0.00 +ATOM 3433 HW1 HOH 987 28.970 22.490 36.780 1.00 0.00 +ATOM 3434 HW2 HOH 987 30.330 22.310 36.140 1.00 0.00 +ATOM 3435 OW HOH 988 4.650 41.200 35.430 1.00 0.00 +ATOM 3436 HW1 HOH 988 3.780 40.870 35.640 1.00 0.00 +ATOM 3437 HW2 HOH 988 5.160 40.410 35.250 1.00 0.00 +ATOM 3438 OW HOH 989 49.330 36.660 21.850 1.00 0.00 +ATOM 3439 HW1 HOH 989 48.380 36.550 21.960 1.00 0.00 +ATOM 3440 HW2 HOH 989 49.500 37.570 22.100 1.00 0.00 +ATOM 3441 OW HOH 990 19.660 7.560 29.920 1.00 0.00 +ATOM 3442 HW1 HOH 990 20.050 7.040 30.620 1.00 0.00 +ATOM 3443 HW2 HOH 990 19.710 7.010 29.140 1.00 0.00 +ATOM 3444 OW HOH 991 10.070 29.860 21.500 1.00 0.00 +ATOM 3445 HW1 HOH 991 9.550 29.100 21.740 1.00 0.00 +ATOM 3446 HW2 HOH 991 10.510 29.610 20.680 1.00 0.00 +ATOM 3447 OW HOH 992 16.060 45.930 31.170 1.00 0.00 +ATOM 3448 HW1 HOH 992 15.720 46.300 31.980 1.00 0.00 +ATOM 3449 HW2 HOH 992 15.820 45.010 31.210 1.00 0.00 +ATOM 3450 OW HOH 993 23.300 0.100 27.740 1.00 0.00 +ATOM 3451 HW1 HOH 993 23.090 1.010 27.970 1.00 0.00 +ATOM 3452 HW2 HOH 993 23.030 0.010 26.830 1.00 0.00 +ATOM 3453 OW HOH 994 7.340 20.500 20.410 1.00 0.00 +ATOM 3454 HW1 HOH 994 7.280 19.720 19.870 1.00 0.00 +ATOM 3455 HW2 HOH 994 8.270 20.710 20.440 1.00 0.00 +ATOM 3456 OW HOH 995 33.800 41.160 18.550 1.00 0.00 +ATOM 3457 HW1 HOH 995 33.960 42.060 18.830 1.00 0.00 +ATOM 3458 HW2 HOH 995 33.850 41.200 17.600 1.00 0.00 +ATOM 3459 OW HOH 996 17.730 13.940 5.520 1.00 0.00 +ATOM 3460 HW1 HOH 996 18.670 14.130 5.510 1.00 0.00 +ATOM 3461 HW2 HOH 996 17.510 13.860 6.440 1.00 0.00 +ATOM 3462 OW HOH 997 26.020 16.880 27.220 1.00 0.00 +ATOM 3463 HW1 HOH 997 25.270 17.190 26.700 1.00 0.00 +ATOM 3464 HW2 HOH 997 26.510 17.680 27.420 1.00 0.00 +ATOM 3465 OW HOH 998 14.860 28.520 7.030 1.00 0.00 +ATOM 3466 HW1 HOH 998 14.780 28.320 7.960 1.00 0.00 +ATOM 3467 HW2 HOH 998 14.080 28.130 6.630 1.00 0.00 +ATOM 3468 OW HOH 999 27.040 40.350 0.760 1.00 0.00 +ATOM 3469 HW1 HOH 999 26.250 40.520 1.270 1.00 0.00 +ATOM 3470 HW2 HOH 999 26.780 39.680 0.120 1.00 0.00 +ATOM 3471 OW HOH 1000 49.420 21.620 37.640 1.00 0.00 +ATOM 3472 HW1 HOH 1000 49.000 22.460 37.810 1.00 0.00 +ATOM 3473 HW2 HOH 1000 48.700 21.020 37.450 1.00 0.00 +ATOM 3474 OW HOH 1001 9.600 36.940 37.270 1.00 0.00 +ATOM 3475 HW1 HOH 1001 10.040 36.100 37.310 1.00 0.00 +ATOM 3476 HW2 HOH 1001 9.480 37.110 36.330 1.00 0.00 +ATOM 3477 OW HOH 1002 15.320 33.730 32.210 1.00 0.00 +ATOM 3478 HW1 HOH 1002 14.620 33.800 31.560 1.00 0.00 +ATOM 3479 HW2 HOH 1002 16.100 34.030 31.740 1.00 0.00 +ATOM 3480 OW HOH 1003 1.660 8.950 29.310 1.00 0.00 +ATOM 3481 HW1 HOH 1003 1.730 8.850 30.260 1.00 0.00 +ATOM 3482 HW2 HOH 1003 0.720 9.060 29.150 1.00 0.00 +ATOM 3483 OW HOH 1004 13.250 28.530 29.240 1.00 0.00 +ATOM 3484 HW1 HOH 1004 13.400 29.470 29.360 1.00 0.00 +ATOM 3485 HW2 HOH 1004 12.650 28.480 28.500 1.00 0.00 +ATOM 3486 OW HOH 1005 0.540 22.730 9.430 1.00 0.00 +ATOM 3487 HW1 HOH 1005 0.420 22.050 8.760 1.00 0.00 +ATOM 3488 HW2 HOH 1005 0.640 22.240 10.250 1.00 0.00 +ATOM 3489 OW HOH 1006 18.200 32.120 27.340 1.00 0.00 +ATOM 3490 HW1 HOH 1006 17.370 31.910 27.780 1.00 0.00 +ATOM 3491 HW2 HOH 1006 17.940 32.640 26.580 1.00 0.00 +ATOM 3492 OW HOH 1007 3.080 44.230 30.440 1.00 0.00 +ATOM 3493 HW1 HOH 1007 3.150 45.170 30.590 1.00 0.00 +ATOM 3494 HW2 HOH 1007 3.900 44.000 29.990 1.00 0.00 +ATOM 3495 OW HOH 1008 18.330 0.590 19.650 1.00 0.00 +ATOM 3496 HW1 HOH 1008 18.850 0.160 18.970 1.00 0.00 +ATOM 3497 HW2 HOH 1008 18.690 1.470 19.700 1.00 0.00 +ATOM 3498 OW HOH 1009 33.100 40.490 5.890 1.00 0.00 +ATOM 3499 HW1 HOH 1009 33.450 41.200 5.360 1.00 0.00 +ATOM 3500 HW2 HOH 1009 33.560 39.710 5.600 1.00 0.00 +ATOM 3501 OW HOH 1010 2.710 20.180 16.100 1.00 0.00 +ATOM 3502 HW1 HOH 1010 3.590 19.900 16.350 1.00 0.00 +ATOM 3503 HW2 HOH 1010 2.770 21.130 16.050 1.00 0.00 +ATOM 3504 OW HOH 1011 24.420 34.550 0.470 1.00 0.00 +ATOM 3505 HW1 HOH 1011 23.590 35.020 0.550 1.00 0.00 +ATOM 3506 HW2 HOH 1011 24.620 34.270 1.360 1.00 0.00 +ATOM 3507 OW HOH 1012 9.100 31.240 11.680 1.00 0.00 +ATOM 3508 HW1 HOH 1012 9.190 31.310 10.730 1.00 0.00 +ATOM 3509 HW2 HOH 1012 9.990 31.040 11.990 1.00 0.00 +ATOM 3510 OW HOH 1013 21.120 37.150 34.710 1.00 0.00 +ATOM 3511 HW1 HOH 1013 21.640 37.030 35.510 1.00 0.00 +ATOM 3512 HW2 HOH 1013 20.440 37.770 34.960 1.00 0.00 +ATOM 3513 OW HOH 1014 8.460 28.980 15.840 1.00 0.00 +ATOM 3514 HW1 HOH 1014 8.720 28.250 16.390 1.00 0.00 +ATOM 3515 HW2 HOH 1014 8.900 29.740 16.220 1.00 0.00 +ATOM 3516 OW HOH 1015 29.700 3.870 18.750 1.00 0.00 +ATOM 3517 HW1 HOH 1015 29.050 3.240 18.440 1.00 0.00 +ATOM 3518 HW2 HOH 1015 29.690 4.560 18.080 1.00 0.00 +ATOM 3519 OW HOH 1016 39.730 24.530 34.910 1.00 0.00 +ATOM 3520 HW1 HOH 1016 40.410 24.960 35.420 1.00 0.00 +ATOM 3521 HW2 HOH 1016 39.170 25.250 34.620 1.00 0.00 +ATOM 3522 OW HOH 1017 29.080 36.290 18.200 1.00 0.00 +ATOM 3523 HW1 HOH 1017 29.950 36.620 18.000 1.00 0.00 +ATOM 3524 HW2 HOH 1017 28.490 37.010 17.970 1.00 0.00 +ATOM 3525 OW HOH 1018 41.580 38.150 9.170 1.00 0.00 +ATOM 3526 HW1 HOH 1018 40.770 37.860 9.580 1.00 0.00 +ATOM 3527 HW2 HOH 1018 41.840 37.420 8.610 1.00 0.00 +ATOM 3528 OW HOH 1019 11.180 32.660 18.900 1.00 0.00 +ATOM 3529 HW1 HOH 1019 11.980 32.180 19.120 1.00 0.00 +ATOM 3530 HW2 HOH 1019 11.210 33.430 19.470 1.00 0.00 +ATOM 3531 OW HOH 1020 17.470 40.630 22.140 1.00 0.00 +ATOM 3532 HW1 HOH 1020 17.350 40.690 23.090 1.00 0.00 +ATOM 3533 HW2 HOH 1020 16.850 39.950 21.870 1.00 0.00 +ATOM 3534 OW HOH 1021 6.510 39.410 34.840 1.00 0.00 +ATOM 3535 HW1 HOH 1021 7.040 39.500 34.050 1.00 0.00 +ATOM 3536 HW2 HOH 1021 7.120 39.090 35.500 1.00 0.00 +ATOM 3537 OW HOH 1022 5.200 40.590 18.800 1.00 0.00 +ATOM 3538 HW1 HOH 1022 5.060 40.920 17.910 1.00 0.00 +ATOM 3539 HW2 HOH 1022 4.670 39.800 18.850 1.00 0.00 +ATOM 3540 OW HOH 1023 20.140 12.840 20.290 1.00 0.00 +ATOM 3541 HW1 HOH 1023 19.530 13.290 19.710 1.00 0.00 +ATOM 3542 HW2 HOH 1023 19.810 13.010 21.170 1.00 0.00 +ATOM 3543 OW HOH 1024 35.830 5.980 26.000 1.00 0.00 +ATOM 3544 HW1 HOH 1024 36.000 6.770 26.510 1.00 0.00 +ATOM 3545 HW2 HOH 1024 36.230 6.150 25.150 1.00 0.00 +ATOM 3546 OW HOH 1025 41.380 24.790 29.330 1.00 0.00 +ATOM 3547 HW1 HOH 1025 41.340 24.610 30.270 1.00 0.00 +ATOM 3548 HW2 HOH 1025 42.000 25.500 29.240 1.00 0.00 +ATOM 3549 OW HOH 1026 25.150 1.880 34.230 1.00 0.00 +ATOM 3550 HW1 HOH 1026 25.050 1.760 33.280 1.00 0.00 +ATOM 3551 HW2 HOH 1026 25.630 2.700 34.320 1.00 0.00 +ATOM 3552 OW HOH 1027 30.890 33.140 19.820 1.00 0.00 +ATOM 3553 HW1 HOH 1027 31.000 34.060 20.080 1.00 0.00 +ATOM 3554 HW2 HOH 1027 31.290 32.650 20.540 1.00 0.00 +ATOM 3555 OW HOH 1028 46.920 14.720 11.730 1.00 0.00 +ATOM 3556 HW1 HOH 1028 47.720 14.820 11.220 1.00 0.00 +ATOM 3557 HW2 HOH 1028 47.220 14.580 12.630 1.00 0.00 +ATOM 3558 OW HOH 1029 30.420 40.080 21.470 1.00 0.00 +ATOM 3559 HW1 HOH 1029 30.870 39.840 20.660 1.00 0.00 +ATOM 3560 HW2 HOH 1029 31.020 40.670 21.920 1.00 0.00 +ATOM 3561 OW HOH 1030 48.350 2.170 29.930 1.00 0.00 +ATOM 3562 HW1 HOH 1030 47.800 2.950 29.840 1.00 0.00 +ATOM 3563 HW2 HOH 1030 48.600 1.950 29.030 1.00 0.00 +ATOM 3564 OW HOH 1031 27.610 13.380 2.430 1.00 0.00 +ATOM 3565 HW1 HOH 1031 27.750 12.440 2.560 1.00 0.00 +ATOM 3566 HW2 HOH 1031 27.590 13.480 1.480 1.00 0.00 +ATOM 3567 OW HOH 1032 17.390 35.540 17.560 1.00 0.00 +ATOM 3568 HW1 HOH 1032 16.440 35.540 17.440 1.00 0.00 +ATOM 3569 HW2 HOH 1032 17.740 35.360 16.690 1.00 0.00 +ATOM 3570 OW HOH 1033 20.020 41.610 6.240 1.00 0.00 +ATOM 3571 HW1 HOH 1033 20.650 41.670 6.960 1.00 0.00 +ATOM 3572 HW2 HOH 1033 20.180 40.750 5.850 1.00 0.00 +ATOM 3573 OW HOH 1034 15.290 7.650 8.080 1.00 0.00 +ATOM 3574 HW1 HOH 1034 14.740 8.380 7.790 1.00 0.00 +ATOM 3575 HW2 HOH 1034 14.850 7.310 8.860 1.00 0.00 +ATOM 3576 OW HOH 1035 18.340 42.900 3.980 1.00 0.00 +ATOM 3577 HW1 HOH 1035 18.790 42.640 4.780 1.00 0.00 +ATOM 3578 HW2 HOH 1035 18.960 42.700 3.280 1.00 0.00 +ATOM 3579 OW HOH 1036 48.350 19.280 12.450 1.00 0.00 +ATOM 3580 HW1 HOH 1036 47.780 18.510 12.480 1.00 0.00 +ATOM 3581 HW2 HOH 1036 48.960 19.140 13.180 1.00 0.00 +ATOM 3582 OW HOH 1037 14.710 34.690 13.440 1.00 0.00 +ATOM 3583 HW1 HOH 1037 14.870 34.480 14.360 1.00 0.00 +ATOM 3584 HW2 HOH 1037 14.040 34.050 13.160 1.00 0.00 +ATOM 3585 OW HOH 1038 9.000 13.400 8.480 1.00 0.00 +ATOM 3586 HW1 HOH 1038 9.020 12.930 9.310 1.00 0.00 +ATOM 3587 HW2 HOH 1038 9.180 14.310 8.720 1.00 0.00 +ATOM 3588 OW HOH 1039 23.920 42.050 35.410 1.00 0.00 +ATOM 3589 HW1 HOH 1039 24.790 42.270 35.750 1.00 0.00 +ATOM 3590 HW2 HOH 1039 23.580 41.410 36.030 1.00 0.00 +ATOM 3591 OW HOH 1040 4.720 18.910 17.760 1.00 0.00 +ATOM 3592 HW1 HOH 1040 4.900 19.320 16.920 1.00 0.00 +ATOM 3593 HW2 HOH 1040 5.580 18.690 18.110 1.00 0.00 +ATOM 3594 OW HOH 1041 41.860 20.370 10.540 1.00 0.00 +ATOM 3595 HW1 HOH 1041 41.420 19.530 10.410 1.00 0.00 +ATOM 3596 HW2 HOH 1041 41.490 20.940 9.860 1.00 0.00 +ATOM 3597 OW HOH 1042 36.820 31.460 9.920 1.00 0.00 +ATOM 3598 HW1 HOH 1042 36.380 31.440 10.770 1.00 0.00 +ATOM 3599 HW2 HOH 1042 37.660 31.870 10.100 1.00 0.00 +ATOM 3600 OW HOH 1043 32.280 38.320 10.460 1.00 0.00 +ATOM 3601 HW1 HOH 1043 31.930 39.190 10.290 1.00 0.00 +ATOM 3602 HW2 HOH 1043 32.540 38.330 11.380 1.00 0.00 +ATOM 3603 OW HOH 1044 28.030 41.850 13.100 1.00 0.00 +ATOM 3604 HW1 HOH 1044 28.170 40.910 13.010 1.00 0.00 +ATOM 3605 HW2 HOH 1044 27.330 41.930 13.750 1.00 0.00 +ATOM 3606 OW HOH 1045 48.090 26.370 37.370 1.00 0.00 +ATOM 3607 HW1 HOH 1045 48.140 25.910 36.530 1.00 0.00 +ATOM 3608 HW2 HOH 1045 48.340 25.710 38.020 1.00 0.00 +ATOM 3609 OW HOH 1046 41.100 3.090 37.730 1.00 0.00 +ATOM 3610 HW1 HOH 1046 40.490 3.150 38.470 1.00 0.00 +ATOM 3611 HW2 HOH 1046 40.650 2.540 37.090 1.00 0.00 +ATOM 3612 OW HOH 1047 34.920 42.140 31.790 1.00 0.00 +ATOM 3613 HW1 HOH 1047 35.050 42.320 30.860 1.00 0.00 +ATOM 3614 HW2 HOH 1047 34.120 42.600 32.010 1.00 0.00 +ATOM 3615 OW HOH 1048 40.400 42.260 15.940 1.00 0.00 +ATOM 3616 HW1 HOH 1048 40.410 43.210 15.790 1.00 0.00 +ATOM 3617 HW2 HOH 1048 40.640 41.880 15.090 1.00 0.00 +ATOM 3618 OW HOH 1049 20.030 44.820 23.530 1.00 0.00 +ATOM 3619 HW1 HOH 1049 20.620 45.560 23.390 1.00 0.00 +ATOM 3620 HW2 HOH 1049 19.330 44.950 22.900 1.00 0.00 +ATOM 3621 OW HOH 1050 46.850 43.140 22.900 1.00 0.00 +ATOM 3622 HW1 HOH 1050 46.520 43.010 23.790 1.00 0.00 +ATOM 3623 HW2 HOH 1050 46.230 42.670 22.350 1.00 0.00 +ATOM 3624 OW HOH 1051 16.860 14.620 31.030 1.00 0.00 +ATOM 3625 HW1 HOH 1051 16.540 13.860 30.530 1.00 0.00 +ATOM 3626 HW2 HOH 1051 17.410 15.100 30.410 1.00 0.00 +ATOM 3627 OW HOH 1052 19.080 42.920 25.310 1.00 0.00 +ATOM 3628 HW1 HOH 1052 19.380 43.270 24.480 1.00 0.00 +ATOM 3629 HW2 HOH 1052 19.160 43.650 25.930 1.00 0.00 +ATOM 3630 OW HOH 1053 40.860 11.810 25.740 1.00 0.00 +ATOM 3631 HW1 HOH 1053 41.720 12.060 25.420 1.00 0.00 +ATOM 3632 HW2 HOH 1053 41.030 11.300 26.530 1.00 0.00 +ATOM 3633 OW HOH 1054 10.580 23.050 23.320 1.00 0.00 +ATOM 3634 HW1 HOH 1054 9.740 23.160 23.760 1.00 0.00 +ATOM 3635 HW2 HOH 1054 10.530 23.620 22.560 1.00 0.00 +ATOM 3636 OW HOH 1055 45.810 21.280 29.840 1.00 0.00 +ATOM 3637 HW1 HOH 1055 45.230 20.990 29.150 1.00 0.00 +ATOM 3638 HW2 HOH 1055 46.430 21.870 29.410 1.00 0.00 +ATOM 3639 OW HOH 1056 46.380 15.140 8.440 1.00 0.00 +ATOM 3640 HW1 HOH 1056 47.200 15.620 8.330 1.00 0.00 +ATOM 3641 HW2 HOH 1056 46.100 15.350 9.330 1.00 0.00 +ATOM 3642 OW HOH 1057 35.690 8.100 13.360 1.00 0.00 +ATOM 3643 HW1 HOH 1057 36.420 8.730 13.390 1.00 0.00 +ATOM 3644 HW2 HOH 1057 35.440 8.070 12.430 1.00 0.00 +ATOM 3645 OW HOH 1058 6.420 24.530 10.010 1.00 0.00 +ATOM 3646 HW1 HOH 1058 7.090 25.210 9.880 1.00 0.00 +ATOM 3647 HW2 HOH 1058 6.580 24.210 10.900 1.00 0.00 +ATOM 3648 OW HOH 1059 4.260 25.780 3.900 1.00 0.00 +ATOM 3649 HW1 HOH 1059 4.830 25.150 4.350 1.00 0.00 +ATOM 3650 HW2 HOH 1059 4.220 25.470 3.000 1.00 0.00 +ATOM 3651 OW HOH 1060 6.310 41.170 13.540 1.00 0.00 +ATOM 3652 HW1 HOH 1060 5.540 41.730 13.450 1.00 0.00 +ATOM 3653 HW2 HOH 1060 6.130 40.650 14.330 1.00 0.00 +ATOM 3654 OW HOH 1061 38.320 15.520 13.410 1.00 0.00 +ATOM 3655 HW1 HOH 1061 37.420 15.780 13.630 1.00 0.00 +ATOM 3656 HW2 HOH 1061 38.300 14.560 13.390 1.00 0.00 +ATOM 3657 OW HOH 1062 39.900 29.230 10.670 1.00 0.00 +ATOM 3658 HW1 HOH 1062 40.190 28.350 10.430 1.00 0.00 +ATOM 3659 HW2 HOH 1062 38.960 29.140 10.830 1.00 0.00 +ATOM 3660 OW HOH 1063 40.290 11.350 8.860 1.00 0.00 +ATOM 3661 HW1 HOH 1063 40.490 12.240 9.160 1.00 0.00 +ATOM 3662 HW2 HOH 1063 39.530 11.090 9.380 1.00 0.00 +ATOM 3663 OW HOH 1064 15.340 9.000 0.120 1.00 0.00 +ATOM 3664 HW1 HOH 1064 15.480 8.390 0.850 1.00 0.00 +ATOM 3665 HW2 HOH 1064 14.390 9.060 0.040 1.00 0.00 +ATOM 3666 OW HOH 1065 48.390 41.070 8.540 1.00 0.00 +ATOM 3667 HW1 HOH 1065 47.710 40.900 7.890 1.00 0.00 +ATOM 3668 HW2 HOH 1065 49.210 40.850 8.100 1.00 0.00 +ATOM 3669 OW HOH 1066 14.070 36.550 3.470 1.00 0.00 +ATOM 3670 HW1 HOH 1066 14.590 36.890 2.740 1.00 0.00 +ATOM 3671 HW2 HOH 1066 13.230 36.310 3.060 1.00 0.00 +ATOM 3672 OW HOH 1067 9.040 18.700 31.300 1.00 0.00 +ATOM 3673 HW1 HOH 1067 8.220 18.400 31.700 1.00 0.00 +ATOM 3674 HW2 HOH 1067 8.790 18.950 30.410 1.00 0.00 +ATOM 3675 OW HOH 1068 35.750 39.590 30.820 1.00 0.00 +ATOM 3676 HW1 HOH 1068 35.940 39.050 31.600 1.00 0.00 +ATOM 3677 HW2 HOH 1068 35.510 40.440 31.180 1.00 0.00 +ATOM 3678 OW HOH 1069 20.720 23.320 3.530 1.00 0.00 +ATOM 3679 HW1 HOH 1069 20.220 23.920 4.090 1.00 0.00 +ATOM 3680 HW2 HOH 1069 20.870 22.550 4.080 1.00 0.00 +ATOM 3681 OW HOH 1070 18.870 40.300 14.960 1.00 0.00 +ATOM 3682 HW1 HOH 1070 17.920 40.330 15.120 1.00 0.00 +ATOM 3683 HW2 HOH 1070 19.040 41.060 14.390 1.00 0.00 +ATOM 3684 OW HOH 1071 46.850 34.730 10.770 1.00 0.00 +ATOM 3685 HW1 HOH 1071 47.650 35.250 10.680 1.00 0.00 +ATOM 3686 HW2 HOH 1071 47.100 33.990 11.320 1.00 0.00 +ATOM 3687 OW HOH 1072 3.040 16.740 8.410 1.00 0.00 +ATOM 3688 HW1 HOH 1072 2.570 17.480 8.020 1.00 0.00 +ATOM 3689 HW2 HOH 1072 2.500 16.460 9.140 1.00 0.00 +ATOM 3690 OW HOH 1073 11.020 40.650 15.170 1.00 0.00 +ATOM 3691 HW1 HOH 1073 11.680 41.300 15.400 1.00 0.00 +ATOM 3692 HW2 HOH 1073 11.300 40.300 14.320 1.00 0.00 +ATOM 3693 OW HOH 1074 13.770 5.220 1.180 1.00 0.00 +ATOM 3694 HW1 HOH 1074 12.980 5.020 0.690 1.00 0.00 +ATOM 3695 HW2 HOH 1074 14.490 5.000 0.580 1.00 0.00 +ATOM 3696 OW HOH 1075 13.380 22.180 16.950 1.00 0.00 +ATOM 3697 HW1 HOH 1075 13.540 22.110 17.890 1.00 0.00 +ATOM 3698 HW2 HOH 1075 13.640 21.330 16.600 1.00 0.00 +ATOM 3699 OW HOH 1076 14.600 40.240 17.420 1.00 0.00 +ATOM 3700 HW1 HOH 1076 14.680 41.160 17.650 1.00 0.00 +ATOM 3701 HW2 HOH 1076 15.400 39.830 17.730 1.00 0.00 +ATOM 3702 OW HOH 1077 42.790 46.190 18.460 1.00 0.00 +ATOM 3703 HW1 HOH 1077 42.050 45.740 18.880 1.00 0.00 +ATOM 3704 HW2 HOH 1077 43.560 45.700 18.750 1.00 0.00 +ATOM 3705 OW HOH 1078 39.970 17.610 29.540 1.00 0.00 +ATOM 3706 HW1 HOH 1078 39.750 17.770 28.620 1.00 0.00 +ATOM 3707 HW2 HOH 1078 40.700 16.990 29.500 1.00 0.00 +ATOM 3708 OW HOH 1079 0.820 29.880 19.120 1.00 0.00 +ATOM 3709 HW1 HOH 1079 0.140 30.510 18.920 1.00 0.00 +ATOM 3710 HW2 HOH 1079 1.570 30.420 19.390 1.00 0.00 +ATOM 3711 OW HOH 1080 5.560 35.080 15.460 1.00 0.00 +ATOM 3712 HW1 HOH 1080 5.740 34.190 15.760 1.00 0.00 +ATOM 3713 HW2 HOH 1080 4.660 35.250 15.750 1.00 0.00 +ATOM 3714 OW HOH 1081 15.670 44.200 23.810 1.00 0.00 +ATOM 3715 HW1 HOH 1081 16.400 43.590 23.710 1.00 0.00 +ATOM 3716 HW2 HOH 1081 14.950 43.670 24.160 1.00 0.00 +ATOM 3717 OW HOH 1082 25.380 43.520 24.990 1.00 0.00 +ATOM 3718 HW1 HOH 1082 24.900 43.150 25.720 1.00 0.00 +ATOM 3719 HW2 HOH 1082 25.740 42.760 24.530 1.00 0.00 +ATOM 3720 OW HOH 1083 14.010 45.240 38.900 1.00 0.00 +ATOM 3721 HW1 HOH 1083 13.110 45.120 38.590 1.00 0.00 +ATOM 3722 HW2 HOH 1083 14.240 46.140 38.640 1.00 0.00 +ATOM 3723 OW HOH 1084 26.850 1.420 38.250 1.00 0.00 +ATOM 3724 HW1 HOH 1084 26.010 1.330 37.800 1.00 0.00 +ATOM 3725 HW2 HOH 1084 27.500 1.420 37.550 1.00 0.00 +ATOM 3726 OW HOH 1085 10.850 4.360 10.120 1.00 0.00 +ATOM 3727 HW1 HOH 1085 10.500 4.360 9.230 1.00 0.00 +ATOM 3728 HW2 HOH 1085 11.240 5.230 10.230 1.00 0.00 +ATOM 3729 OW HOH 1086 3.570 8.860 15.890 1.00 0.00 +ATOM 3730 HW1 HOH 1086 3.160 8.870 15.030 1.00 0.00 +ATOM 3731 HW2 HOH 1086 2.940 8.410 16.450 1.00 0.00 +ATOM 3732 OW HOH 1087 34.360 4.450 1.490 1.00 0.00 +ATOM 3733 HW1 HOH 1087 33.590 4.900 1.130 1.00 0.00 +ATOM 3734 HW2 HOH 1087 34.130 4.290 2.410 1.00 0.00 +ATOM 3735 OW HOH 1088 9.240 33.690 0.730 1.00 0.00 +ATOM 3736 HW1 HOH 1088 8.860 33.840 1.600 1.00 0.00 +ATOM 3737 HW2 HOH 1088 8.520 33.900 0.130 1.00 0.00 +ATOM 3738 OW HOH 1089 49.110 4.840 7.640 1.00 0.00 +ATOM 3739 HW1 HOH 1089 48.770 4.900 6.750 1.00 0.00 +ATOM 3740 HW2 HOH 1089 48.350 4.580 8.160 1.00 0.00 +ATOM 3741 OW HOH 1090 46.330 30.800 8.670 1.00 0.00 +ATOM 3742 HW1 HOH 1090 45.740 30.330 9.260 1.00 0.00 +ATOM 3743 HW2 HOH 1090 45.780 31.450 8.240 1.00 0.00 +ATOM 3744 OW HOH 1091 28.450 32.290 28.790 1.00 0.00 +ATOM 3745 HW1 HOH 1091 28.130 32.300 29.690 1.00 0.00 +ATOM 3746 HW2 HOH 1091 29.010 33.060 28.730 1.00 0.00 +ATOM 3747 OW HOH 1092 16.730 1.070 3.970 1.00 0.00 +ATOM 3748 HW1 HOH 1092 17.080 1.290 3.110 1.00 0.00 +ATOM 3749 HW2 HOH 1092 16.400 0.180 3.880 1.00 0.00 +ATOM 3750 OW HOH 1093 44.590 44.660 37.680 1.00 0.00 +ATOM 3751 HW1 HOH 1093 44.900 45.240 36.980 1.00 0.00 +ATOM 3752 HW2 HOH 1093 44.260 45.250 38.360 1.00 0.00 +ATOM 3753 OW HOH 1094 12.610 8.450 38.670 1.00 0.00 +ATOM 3754 HW1 HOH 1094 12.260 8.230 37.810 1.00 0.00 +ATOM 3755 HW2 HOH 1094 11.860 8.420 39.260 1.00 0.00 +ATOM 3756 OW HOH 1095 29.730 34.700 28.980 1.00 0.00 +ATOM 3757 HW1 HOH 1095 29.250 35.480 29.250 1.00 0.00 +ATOM 3758 HW2 HOH 1095 30.370 34.550 29.670 1.00 0.00 +ATOM 3759 OW HOH 1096 21.510 2.320 36.510 1.00 0.00 +ATOM 3760 HW1 HOH 1096 22.100 2.750 37.130 1.00 0.00 +ATOM 3761 HW2 HOH 1096 21.940 2.410 35.660 1.00 0.00 +ATOM 3762 OW HOH 1097 10.220 0.460 28.310 1.00 0.00 +ATOM 3763 HW1 HOH 1097 10.770 0.510 29.090 1.00 0.00 +ATOM 3764 HW2 HOH 1097 10.840 0.360 27.580 1.00 0.00 +ATOM 3765 OW HOH 1098 39.560 37.160 34.480 1.00 0.00 +ATOM 3766 HW1 HOH 1098 40.250 37.220 35.140 1.00 0.00 +ATOM 3767 HW2 HOH 1098 38.750 37.260 34.980 1.00 0.00 +ATOM 3768 OW HOH 1099 29.550 12.390 33.190 1.00 0.00 +ATOM 3769 HW1 HOH 1099 29.350 11.950 34.020 1.00 0.00 +ATOM 3770 HW2 HOH 1099 28.700 12.710 32.880 1.00 0.00 +ATOM 3771 OW HOH 1100 11.310 3.730 31.940 1.00 0.00 +ATOM 3772 HW1 HOH 1100 11.830 4.500 31.700 1.00 0.00 +ATOM 3773 HW2 HOH 1100 11.890 3.190 32.470 1.00 0.00 +ATOM 3774 OW HOH 1101 35.540 19.930 20.060 1.00 0.00 +ATOM 3775 HW1 HOH 1101 35.500 18.980 20.140 1.00 0.00 +ATOM 3776 HW2 HOH 1101 35.320 20.100 19.140 1.00 0.00 +ATOM 3777 OW HOH 1102 15.970 7.370 30.840 1.00 0.00 +ATOM 3778 HW1 HOH 1102 15.160 6.880 30.960 1.00 0.00 +ATOM 3779 HW2 HOH 1102 16.630 6.710 30.610 1.00 0.00 +ATOM 3780 OW HOH 1103 13.650 29.040 12.680 1.00 0.00 +ATOM 3781 HW1 HOH 1103 14.310 29.730 12.640 1.00 0.00 +ATOM 3782 HW2 HOH 1103 13.920 28.490 13.410 1.00 0.00 +ATOM 3783 OW HOH 1104 7.840 14.250 23.460 1.00 0.00 +ATOM 3784 HW1 HOH 1104 8.230 13.430 23.160 1.00 0.00 +ATOM 3785 HW2 HOH 1104 7.060 14.360 22.920 1.00 0.00 +ATOM 3786 OW HOH 1105 11.610 32.250 31.050 1.00 0.00 +ATOM 3787 HW1 HOH 1105 12.020 31.760 31.760 1.00 0.00 +ATOM 3788 HW2 HOH 1105 11.130 31.600 30.550 1.00 0.00 +ATOM 3789 OW HOH 1106 17.580 45.420 10.820 1.00 0.00 +ATOM 3790 HW1 HOH 1106 17.400 45.860 11.650 1.00 0.00 +ATOM 3791 HW2 HOH 1106 18.390 45.830 10.500 1.00 0.00 +ATOM 3792 OW HOH 1107 5.300 23.480 7.650 1.00 0.00 +ATOM 3793 HW1 HOH 1107 5.590 23.710 8.530 1.00 0.00 +ATOM 3794 HW2 HOH 1107 4.380 23.750 7.620 1.00 0.00 +ATOM 3795 OW HOH 1108 47.440 0.750 21.230 1.00 0.00 +ATOM 3796 HW1 HOH 1108 47.440 0.350 22.100 1.00 0.00 +ATOM 3797 HW2 HOH 1108 48.350 1.010 21.090 1.00 0.00 +ATOM 3798 OW HOH 1109 11.570 35.070 38.480 1.00 0.00 +ATOM 3799 HW1 HOH 1109 12.370 34.750 38.890 1.00 0.00 +ATOM 3800 HW2 HOH 1109 10.960 34.340 38.540 1.00 0.00 +ATOM 3801 OW HOH 1110 40.600 26.610 10.580 1.00 0.00 +ATOM 3802 HW1 HOH 1110 40.320 26.280 11.440 1.00 0.00 +ATOM 3803 HW2 HOH 1110 40.750 25.820 10.060 1.00 0.00 +ATOM 3804 OW HOH 1111 7.490 18.500 18.320 1.00 0.00 +ATOM 3805 HW1 HOH 1111 7.620 17.570 18.520 1.00 0.00 +ATOM 3806 HW2 HOH 1111 7.950 18.620 17.490 1.00 0.00 +ATOM 3807 OW HOH 1112 25.810 14.260 8.570 1.00 0.00 +ATOM 3808 HW1 HOH 1112 24.930 14.010 8.850 1.00 0.00 +ATOM 3809 HW2 HOH 1112 26.340 13.470 8.720 1.00 0.00 +ATOM 3810 OW HOH 1113 29.710 45.030 33.540 1.00 0.00 +ATOM 3811 HW1 HOH 1113 29.350 44.190 33.260 1.00 0.00 +ATOM 3812 HW2 HOH 1113 28.960 45.490 33.930 1.00 0.00 +ATOM 3813 OW HOH 1114 30.030 27.280 37.630 1.00 0.00 +ATOM 3814 HW1 HOH 1114 30.600 28.010 37.370 1.00 0.00 +ATOM 3815 HW2 HOH 1114 29.170 27.510 37.270 1.00 0.00 +ATOM 3816 OW HOH 1115 45.130 5.190 5.390 1.00 0.00 +ATOM 3817 HW1 HOH 1115 45.140 5.990 5.910 1.00 0.00 +ATOM 3818 HW2 HOH 1115 44.260 4.830 5.530 1.00 0.00 +ATOM 3819 OW HOH 1116 10.260 43.680 32.490 1.00 0.00 +ATOM 3820 HW1 HOH 1116 11.060 44.180 32.650 1.00 0.00 +ATOM 3821 HW2 HOH 1116 10.170 43.120 33.250 1.00 0.00 +ATOM 3822 OW HOH 1117 5.160 36.990 21.180 1.00 0.00 +ATOM 3823 HW1 HOH 1117 5.710 36.390 20.680 1.00 0.00 +ATOM 3824 HW2 HOH 1117 5.140 36.610 22.060 1.00 0.00 +ATOM 3825 OW HOH 1118 46.000 43.110 29.520 1.00 0.00 +ATOM 3826 HW1 HOH 1118 46.800 42.600 29.670 1.00 0.00 +ATOM 3827 HW2 HOH 1118 46.140 43.540 28.680 1.00 0.00 +ATOM 3828 OW HOH 1119 36.690 8.320 26.810 1.00 0.00 +ATOM 3829 HW1 HOH 1119 36.120 8.790 26.200 1.00 0.00 +ATOM 3830 HW2 HOH 1119 37.570 8.620 26.600 1.00 0.00 +ATOM 3831 OW HOH 1120 10.820 35.600 31.850 1.00 0.00 +ATOM 3832 HW1 HOH 1120 10.600 36.510 32.080 1.00 0.00 +ATOM 3833 HW2 HOH 1120 11.140 35.220 32.660 1.00 0.00 +ATOM 3834 OW HOH 1121 37.380 17.520 38.900 1.00 0.00 +ATOM 3835 HW1 HOH 1121 37.150 17.840 38.030 1.00 0.00 +ATOM 3836 HW2 HOH 1121 38.270 17.180 38.800 1.00 0.00 +ATOM 3837 OW HOH 1122 36.050 17.550 29.920 1.00 0.00 +ATOM 3838 HW1 HOH 1122 36.010 17.020 29.130 1.00 0.00 +ATOM 3839 HW2 HOH 1122 36.810 18.130 29.780 1.00 0.00 +ATOM 3840 OW HOH 1123 48.350 8.960 28.820 1.00 0.00 +ATOM 3841 HW1 HOH 1123 47.850 8.150 28.960 1.00 0.00 +ATOM 3842 HW2 HOH 1123 47.680 9.620 28.630 1.00 0.00 +ATOM 3843 OW HOH 1124 0.700 22.260 34.750 1.00 0.00 +ATOM 3844 HW1 HOH 1124 0.120 22.870 35.210 1.00 0.00 +ATOM 3845 HW2 HOH 1124 1.160 21.790 35.440 1.00 0.00 +ATOM 3846 OW HOH 1125 48.780 32.920 33.570 1.00 0.00 +ATOM 3847 HW1 HOH 1125 48.760 32.980 32.620 1.00 0.00 +ATOM 3848 HW2 HOH 1125 49.520 32.340 33.750 1.00 0.00 +ATOM 3849 OW HOH 1126 36.190 31.660 7.090 1.00 0.00 +ATOM 3850 HW1 HOH 1126 36.440 31.770 8.010 1.00 0.00 +ATOM 3851 HW2 HOH 1126 35.260 31.420 7.120 1.00 0.00 +ATOM 3852 OW HOH 1127 34.830 1.090 36.970 1.00 0.00 +ATOM 3853 HW1 HOH 1127 35.750 1.110 37.210 1.00 0.00 +ATOM 3854 HW2 HOH 1127 34.710 0.260 36.510 1.00 0.00 +ATOM 3855 OW HOH 1128 12.840 27.470 17.160 1.00 0.00 +ATOM 3856 HW1 HOH 1128 12.550 28.310 16.800 1.00 0.00 +ATOM 3857 HW2 HOH 1128 13.480 27.700 17.830 1.00 0.00 +ATOM 3858 OW HOH 1129 15.770 25.360 14.080 1.00 0.00 +ATOM 3859 HW1 HOH 1129 15.140 24.740 14.450 1.00 0.00 +ATOM 3860 HW2 HOH 1129 15.890 25.070 13.170 1.00 0.00 +ATOM 3861 OW HOH 1130 46.760 24.350 11.050 1.00 0.00 +ATOM 3862 HW1 HOH 1130 47.100 24.800 10.280 1.00 0.00 +ATOM 3863 HW2 HOH 1130 47.160 24.800 11.790 1.00 0.00 +ATOM 3864 OW HOH 1131 19.060 38.560 35.910 1.00 0.00 +ATOM 3865 HW1 HOH 1131 18.140 38.360 35.700 1.00 0.00 +ATOM 3866 HW2 HOH 1131 19.150 39.490 35.710 1.00 0.00 +ATOM 3867 OW HOH 1132 41.220 37.180 36.650 1.00 0.00 +ATOM 3868 HW1 HOH 1132 41.330 36.290 36.980 1.00 0.00 +ATOM 3869 HW2 HOH 1132 42.080 37.430 36.330 1.00 0.00 +ATOM 3870 OW HOH 1133 48.320 21.190 16.370 1.00 0.00 +ATOM 3871 HW1 HOH 1133 47.720 20.480 16.600 1.00 0.00 +ATOM 3872 HW2 HOH 1133 49.140 20.960 16.820 1.00 0.00 +ATOM 3873 OW HOH 1134 4.440 25.860 20.070 1.00 0.00 +ATOM 3874 HW1 HOH 1134 4.730 25.910 19.150 1.00 0.00 +ATOM 3875 HW2 HOH 1134 4.000 26.700 20.220 1.00 0.00 +ATOM 3876 OW HOH 1135 44.900 41.740 1.640 1.00 0.00 +ATOM 3877 HW1 HOH 1135 45.510 42.200 1.060 1.00 0.00 +ATOM 3878 HW2 HOH 1135 45.360 41.670 2.470 1.00 0.00 +ATOM 3879 OW HOH 1136 6.130 45.160 17.230 1.00 0.00 +ATOM 3880 HW1 HOH 1136 5.210 45.140 16.960 1.00 0.00 +ATOM 3881 HW2 HOH 1136 6.480 44.310 16.970 1.00 0.00 +ATOM 3882 OW HOH 1137 9.910 35.500 25.230 1.00 0.00 +ATOM 3883 HW1 HOH 1137 9.450 36.110 25.810 1.00 0.00 +ATOM 3884 HW2 HOH 1137 10.810 35.520 25.530 1.00 0.00 +ATOM 3885 OW HOH 1138 36.870 32.390 3.920 1.00 0.00 +ATOM 3886 HW1 HOH 1138 37.040 31.650 4.510 1.00 0.00 +ATOM 3887 HW2 HOH 1138 37.400 32.200 3.150 1.00 0.00 +ATOM 3888 OW HOH 1139 6.820 30.030 4.180 1.00 0.00 +ATOM 3889 HW1 HOH 1139 6.260 29.390 3.730 1.00 0.00 +ATOM 3890 HW2 HOH 1139 7.110 30.620 3.480 1.00 0.00 +ATOM 3891 OW HOH 1140 39.800 19.170 23.520 1.00 0.00 +ATOM 3892 HW1 HOH 1140 40.360 19.320 24.280 1.00 0.00 +ATOM 3893 HW2 HOH 1140 38.980 19.610 23.740 1.00 0.00 +ATOM 3894 OW HOH 1141 16.990 13.370 7.930 1.00 0.00 +ATOM 3895 HW1 HOH 1141 16.260 12.990 8.420 1.00 0.00 +ATOM 3896 HW2 HOH 1141 17.670 13.520 8.590 1.00 0.00 +ATOM 3897 OW HOH 1142 38.080 5.650 13.290 1.00 0.00 +ATOM 3898 HW1 HOH 1142 37.740 5.170 14.050 1.00 0.00 +ATOM 3899 HW2 HOH 1142 37.510 6.430 13.230 1.00 0.00 +ATOM 3900 OW HOH 1143 46.740 18.740 6.860 1.00 0.00 +ATOM 3901 HW1 HOH 1143 47.590 18.480 7.240 1.00 0.00 +ATOM 3902 HW2 HOH 1143 46.960 19.150 6.030 1.00 0.00 +ATOM 3903 OW HOH 1144 16.220 44.330 28.660 1.00 0.00 +ATOM 3904 HW1 HOH 1144 15.900 44.980 29.290 1.00 0.00 +ATOM 3905 HW2 HOH 1144 16.040 44.720 27.800 1.00 0.00 +ATOM 3906 OW HOH 1145 11.210 19.260 38.260 1.00 0.00 +ATOM 3907 HW1 HOH 1145 10.990 18.450 37.800 1.00 0.00 +ATOM 3908 HW2 HOH 1145 11.570 18.960 39.100 1.00 0.00 +ATOM 3909 OW HOH 1146 4.940 10.450 9.810 1.00 0.00 +ATOM 3910 HW1 HOH 1146 5.000 9.700 9.220 1.00 0.00 +ATOM 3911 HW2 HOH 1146 5.850 10.620 10.060 1.00 0.00 +ATOM 3912 OW HOH 1147 33.400 17.220 25.080 1.00 0.00 +ATOM 3913 HW1 HOH 1147 33.940 17.990 25.280 1.00 0.00 +ATOM 3914 HW2 HOH 1147 32.950 17.040 25.910 1.00 0.00 +ATOM 3915 OW HOH 1148 31.540 27.480 34.300 1.00 0.00 +ATOM 3916 HW1 HOH 1148 30.750 27.940 34.560 1.00 0.00 +ATOM 3917 HW2 HOH 1148 32.210 28.160 34.260 1.00 0.00 +ATOM 3918 OW HOH 1149 5.380 14.370 21.980 1.00 0.00 +ATOM 3919 HW1 HOH 1149 4.680 13.730 22.080 1.00 0.00 +ATOM 3920 HW2 HOH 1149 4.930 15.210 21.910 1.00 0.00 +ATOM 3921 OW HOH 1150 21.730 35.950 29.180 1.00 0.00 +ATOM 3922 HW1 HOH 1150 21.010 36.300 29.720 1.00 0.00 +ATOM 3923 HW2 HOH 1150 22.150 35.290 29.730 1.00 0.00 +ATOM 3924 OW HOH 1151 41.990 32.660 25.570 1.00 0.00 +ATOM 3925 HW1 HOH 1151 41.830 31.970 24.920 1.00 0.00 +ATOM 3926 HW2 HOH 1151 42.380 33.380 25.070 1.00 0.00 +ATOM 3927 OW HOH 1152 47.410 26.990 18.920 1.00 0.00 +ATOM 3928 HW1 HOH 1152 48.320 27.010 19.200 1.00 0.00 +ATOM 3929 HW2 HOH 1152 47.020 27.750 19.350 1.00 0.00 +ATOM 3930 OW HOH 1153 16.490 43.620 13.600 1.00 0.00 +ATOM 3931 HW1 HOH 1153 15.950 43.250 12.900 1.00 0.00 +ATOM 3932 HW2 HOH 1153 15.920 44.280 14.010 1.00 0.00 +ATOM 3933 OW HOH 1154 26.230 20.070 29.750 1.00 0.00 +ATOM 3934 HW1 HOH 1154 25.330 19.840 29.980 1.00 0.00 +ATOM 3935 HW2 HOH 1154 26.770 19.480 30.280 1.00 0.00 +ATOM 3936 OW HOH 1155 7.460 5.880 3.570 1.00 0.00 +ATOM 3937 HW1 HOH 1155 7.430 5.200 4.240 1.00 0.00 +ATOM 3938 HW2 HOH 1155 7.830 6.640 4.010 1.00 0.00 +ATOM 3939 OW HOH 1156 10.940 42.160 21.400 1.00 0.00 +ATOM 3940 HW1 HOH 1156 10.660 41.400 20.900 1.00 0.00 +ATOM 3941 HW2 HOH 1156 11.580 41.820 22.020 1.00 0.00 +ATOM 3942 OW HOH 1157 15.070 33.640 20.260 1.00 0.00 +ATOM 3943 HW1 HOH 1157 15.080 32.990 19.560 1.00 0.00 +ATOM 3944 HW2 HOH 1157 14.790 34.450 19.830 1.00 0.00 +ATOM 3945 OW HOH 1158 16.540 7.010 36.620 1.00 0.00 +ATOM 3946 HW1 HOH 1158 17.260 6.370 36.640 1.00 0.00 +ATOM 3947 HW2 HOH 1158 16.270 7.080 37.540 1.00 0.00 +ATOM 3948 OW HOH 1159 29.920 2.410 33.170 1.00 0.00 +ATOM 3949 HW1 HOH 1159 29.190 2.080 32.650 1.00 0.00 +ATOM 3950 HW2 HOH 1159 30.540 1.690 33.210 1.00 0.00 +ATOM 3951 OW HOH 1160 14.360 27.690 1.180 1.00 0.00 +ATOM 3952 HW1 HOH 1160 14.630 28.190 1.950 1.00 0.00 +ATOM 3953 HW2 HOH 1160 14.080 26.840 1.530 1.00 0.00 +ATOM 3954 OW HOH 1161 19.270 35.150 33.220 1.00 0.00 +ATOM 3955 HW1 HOH 1161 18.440 34.820 33.560 1.00 0.00 +ATOM 3956 HW2 HOH 1161 19.690 35.570 33.970 1.00 0.00 +ATOM 3957 OW HOH 1162 48.390 34.580 8.180 1.00 0.00 +ATOM 3958 HW1 HOH 1162 49.230 34.240 8.500 1.00 0.00 +ATOM 3959 HW2 HOH 1162 47.930 33.810 7.840 1.00 0.00 +ATOM 3960 OW HOH 1163 4.100 23.730 36.540 1.00 0.00 +ATOM 3961 HW1 HOH 1163 3.450 24.420 36.680 1.00 0.00 +ATOM 3962 HW2 HOH 1163 4.740 24.120 35.950 1.00 0.00 +ATOM 3963 OW HOH 1164 43.180 40.420 11.480 1.00 0.00 +ATOM 3964 HW1 HOH 1164 43.800 40.450 10.750 1.00 0.00 +ATOM 3965 HW2 HOH 1164 42.330 40.310 11.070 1.00 0.00 +ATOM 3966 OW HOH 1165 34.240 35.320 24.560 1.00 0.00 +ATOM 3967 HW1 HOH 1165 34.920 35.090 23.920 1.00 0.00 +ATOM 3968 HW2 HOH 1165 34.500 36.170 24.900 1.00 0.00 +ATOM 3969 OW HOH 1166 1.700 19.970 26.160 1.00 0.00 +ATOM 3970 HW1 HOH 1166 1.370 19.080 26.290 1.00 0.00 +ATOM 3971 HW2 HOH 1166 1.130 20.330 25.480 1.00 0.00 +ATOM 3972 OW HOH 1167 45.300 17.940 37.140 1.00 0.00 +ATOM 3973 HW1 HOH 1167 44.850 18.760 36.920 1.00 0.00 +ATOM 3974 HW2 HOH 1167 44.730 17.530 37.790 1.00 0.00 +ATOM 3975 OW HOH 1168 44.290 21.540 25.100 1.00 0.00 +ATOM 3976 HW1 HOH 1168 44.140 22.010 24.280 1.00 0.00 +ATOM 3977 HW2 HOH 1168 43.690 21.950 25.730 1.00 0.00 +ATOM 3978 OW HOH 1169 37.750 43.350 20.550 1.00 0.00 +ATOM 3979 HW1 HOH 1169 36.890 43.090 20.890 1.00 0.00 +ATOM 3980 HW2 HOH 1169 38.310 43.350 21.330 1.00 0.00 +ATOM 3981 OW HOH 1170 43.830 24.790 9.710 1.00 0.00 +ATOM 3982 HW1 HOH 1170 44.650 24.750 9.210 1.00 0.00 +ATOM 3983 HW2 HOH 1170 43.150 24.900 9.040 1.00 0.00 +ATOM 3984 OW HOH 1171 3.370 18.130 36.790 1.00 0.00 +ATOM 3985 HW1 HOH 1171 4.070 18.530 36.270 1.00 0.00 +ATOM 3986 HW2 HOH 1171 2.620 18.120 36.210 1.00 0.00 +ATOM 3987 OW HOH 1172 32.240 40.650 37.550 1.00 0.00 +ATOM 3988 HW1 HOH 1172 31.640 41.400 37.560 1.00 0.00 +ATOM 3989 HW2 HOH 1172 32.300 40.400 36.630 1.00 0.00 +ATOM 3990 OW HOH 1173 46.440 1.570 8.120 1.00 0.00 +ATOM 3991 HW1 HOH 1173 46.570 1.990 7.270 1.00 0.00 +ATOM 3992 HW2 HOH 1173 45.760 0.920 7.970 1.00 0.00 +ATOM 3993 OW HOH 1174 18.250 13.670 36.450 1.00 0.00 +ATOM 3994 HW1 HOH 1174 18.550 14.160 35.680 1.00 0.00 +ATOM 3995 HW2 HOH 1174 17.950 14.350 37.060 1.00 0.00 +ATOM 3996 OW HOH 1175 8.730 26.950 26.840 1.00 0.00 +ATOM 3997 HW1 HOH 1175 7.770 27.030 26.890 1.00 0.00 +ATOM 3998 HW2 HOH 1175 8.930 27.090 25.920 1.00 0.00 +ATOM 3999 OW HOH 1176 35.250 27.880 36.100 1.00 0.00 +ATOM 4000 HW1 HOH 1176 35.340 26.990 36.430 1.00 0.00 +ATOM 4001 HW2 HOH 1176 34.480 27.860 35.530 1.00 0.00 +ATOM 4002 OW HOH 1177 3.140 15.590 26.340 1.00 0.00 +ATOM 4003 HW1 HOH 1177 3.430 14.820 26.840 1.00 0.00 +ATOM 4004 HW2 HOH 1177 3.050 16.270 27.000 1.00 0.00 +ATOM 4005 OW HOH 1178 10.640 20.770 17.120 1.00 0.00 +ATOM 4006 HW1 HOH 1178 9.970 20.140 16.870 1.00 0.00 +ATOM 4007 HW2 HOH 1178 11.310 20.250 17.560 1.00 0.00 +ATOM 4008 OW HOH 1179 16.460 37.310 30.600 1.00 0.00 +ATOM 4009 HW1 HOH 1179 16.070 37.750 31.350 1.00 0.00 +ATOM 4010 HW2 HOH 1179 15.960 36.510 30.490 1.00 0.00 +ATOM 4011 OW HOH 1180 20.110 3.680 0.840 1.00 0.00 +ATOM 4012 HW1 HOH 1180 20.150 3.860 -0.090 1.00 0.00 +ATOM 4013 HW2 HOH 1180 19.800 4.500 1.230 1.00 0.00 +ATOM 4014 OW HOH 1181 11.950 18.020 5.320 1.00 0.00 +ATOM 4015 HW1 HOH 1181 11.680 18.640 6.000 1.00 0.00 +ATOM 4016 HW2 HOH 1181 11.200 17.990 4.720 1.00 0.00 +ATOM 4017 OW HOH 1182 12.650 39.660 2.520 1.00 0.00 +ATOM 4018 HW1 HOH 1182 13.200 38.890 2.380 1.00 0.00 +ATOM 4019 HW2 HOH 1182 13.140 40.190 3.150 1.00 0.00 +ATOM 4020 OW HOH 1183 40.640 41.220 8.040 1.00 0.00 +ATOM 4021 HW1 HOH 1183 40.220 40.860 7.260 1.00 0.00 +ATOM 4022 HW2 HOH 1183 41.570 41.030 7.920 1.00 0.00 +ATOM 4023 OW HOH 1184 28.800 30.600 4.150 1.00 0.00 +ATOM 4024 HW1 HOH 1184 29.350 30.390 3.390 1.00 0.00 +ATOM 4025 HW2 HOH 1184 29.360 31.110 4.720 1.00 0.00 +ATOM 4026 OW HOH 1185 41.660 32.860 11.760 1.00 0.00 +ATOM 4027 HW1 HOH 1185 41.800 33.810 11.810 1.00 0.00 +ATOM 4028 HW2 HOH 1185 42.450 32.490 12.170 1.00 0.00 +ATOM 4029 OW HOH 1186 38.840 34.350 30.940 1.00 0.00 +ATOM 4030 HW1 HOH 1186 38.870 34.370 31.900 1.00 0.00 +ATOM 4031 HW2 HOH 1186 38.990 33.430 30.720 1.00 0.00 +ATOM 4032 OW HOH 1187 44.860 32.760 0.150 1.00 0.00 +ATOM 4033 HW1 HOH 1187 45.240 33.530 -0.260 1.00 0.00 +ATOM 4034 HW2 HOH 1187 45.570 32.120 0.190 1.00 0.00 +ATOM 4035 OW HOH 1188 14.130 32.930 26.890 1.00 0.00 +ATOM 4036 HW1 HOH 1188 14.510 33.740 27.230 1.00 0.00 +ATOM 4037 HW2 HOH 1188 14.030 32.370 27.670 1.00 0.00 +ATOM 4038 OW HOH 1189 19.480 36.610 30.620 1.00 0.00 +ATOM 4039 HW1 HOH 1189 19.550 35.780 31.100 1.00 0.00 +ATOM 4040 HW2 HOH 1189 18.550 36.690 30.400 1.00 0.00 +ATOM 4041 OW HOH 1190 16.840 7.340 13.970 1.00 0.00 +ATOM 4042 HW1 HOH 1190 16.260 7.380 14.730 1.00 0.00 +ATOM 4043 HW2 HOH 1190 17.710 7.190 14.340 1.00 0.00 +ATOM 4044 OW HOH 1191 16.130 31.440 28.880 1.00 0.00 +ATOM 4045 HW1 HOH 1191 16.430 30.620 29.300 1.00 0.00 +ATOM 4046 HW2 HOH 1191 15.180 31.400 28.930 1.00 0.00 +ATOM 4047 OW HOH 1192 36.390 35.730 31.050 1.00 0.00 +ATOM 4048 HW1 HOH 1192 37.250 35.530 30.690 1.00 0.00 +ATOM 4049 HW2 HOH 1192 36.220 35.020 31.670 1.00 0.00 +ATOM 4050 OW HOH 1193 14.540 19.120 34.600 1.00 0.00 +ATOM 4051 HW1 HOH 1193 14.110 19.820 34.110 1.00 0.00 +ATOM 4052 HW2 HOH 1193 15.440 19.130 34.280 1.00 0.00 +ATOM 4053 OW HOH 1194 4.350 16.150 18.420 1.00 0.00 +ATOM 4054 HW1 HOH 1194 4.280 17.020 18.050 1.00 0.00 +ATOM 4055 HW2 HOH 1194 4.100 16.260 19.340 1.00 0.00 +ATOM 4056 OW HOH 1195 41.790 27.670 26.090 1.00 0.00 +ATOM 4057 HW1 HOH 1195 41.290 27.860 25.290 1.00 0.00 +ATOM 4058 HW2 HOH 1195 41.360 26.900 26.460 1.00 0.00 +ATOM 4059 OW HOH 1196 9.460 34.020 12.110 1.00 0.00 +ATOM 4060 HW1 HOH 1196 9.000 34.610 11.510 1.00 0.00 +ATOM 4061 HW2 HOH 1196 9.130 33.150 11.890 1.00 0.00 +ATOM 4062 OW HOH 1197 6.020 0.880 1.180 1.00 0.00 +ATOM 4063 HW1 HOH 1197 6.800 1.390 0.950 1.00 0.00 +ATOM 4064 HW2 HOH 1197 5.800 0.420 0.360 1.00 0.00 +ATOM 4065 OW HOH 1198 24.910 33.220 34.010 1.00 0.00 +ATOM 4066 HW1 HOH 1198 25.610 33.760 34.370 1.00 0.00 +ATOM 4067 HW2 HOH 1198 24.100 33.620 34.310 1.00 0.00 +ATOM 4068 OW HOH 1199 20.440 43.380 38.760 1.00 0.00 +ATOM 4069 HW1 HOH 1199 20.840 44.000 39.370 1.00 0.00 +ATOM 4070 HW2 HOH 1199 19.760 43.890 38.320 1.00 0.00 +ATOM 4071 OW HOH 1200 36.660 32.710 35.680 1.00 0.00 +ATOM 4072 HW1 HOH 1200 36.940 32.030 35.070 1.00 0.00 +ATOM 4073 HW2 HOH 1200 35.740 32.500 35.860 1.00 0.00 +ATOM 4074 OW HOH 1201 13.490 42.470 9.350 1.00 0.00 +ATOM 4075 HW1 HOH 1201 13.510 41.540 9.150 1.00 0.00 +ATOM 4076 HW2 HOH 1201 12.560 42.680 9.450 1.00 0.00 +ATOM 4077 OW HOH 1202 19.390 12.780 23.050 1.00 0.00 +ATOM 4078 HW1 HOH 1202 18.540 12.530 23.390 1.00 0.00 +ATOM 4079 HW2 HOH 1202 19.870 13.130 23.800 1.00 0.00 +ATOM 4080 OW HOH 1203 46.360 19.700 17.530 1.00 0.00 +ATOM 4081 HW1 HOH 1203 46.750 18.850 17.340 1.00 0.00 +ATOM 4082 HW2 HOH 1203 45.430 19.590 17.350 1.00 0.00 +ATOM 4083 OW HOH 1204 37.100 37.660 13.510 1.00 0.00 +ATOM 4084 HW1 HOH 1204 37.190 36.780 13.870 1.00 0.00 +ATOM 4085 HW2 HOH 1204 36.280 37.640 13.020 1.00 0.00 +ATOM 4086 OW HOH 1205 43.690 21.990 14.240 1.00 0.00 +ATOM 4087 HW1 HOH 1205 42.960 21.380 14.170 1.00 0.00 +ATOM 4088 HW2 HOH 1205 43.930 22.180 13.330 1.00 0.00 +ATOM 4089 OW HOH 1206 21.210 9.760 37.660 1.00 0.00 +ATOM 4090 HW1 HOH 1206 20.360 10.140 37.440 1.00 0.00 +ATOM 4091 HW2 HOH 1206 21.850 10.360 37.270 1.00 0.00 +ATOM 4092 OW HOH 1207 15.960 4.720 25.270 1.00 0.00 +ATOM 4093 HW1 HOH 1207 16.250 3.940 25.750 1.00 0.00 +ATOM 4094 HW2 HOH 1207 15.540 5.270 25.930 1.00 0.00 +ATOM 4095 OW HOH 1208 21.570 43.490 19.440 1.00 0.00 +ATOM 4096 HW1 HOH 1208 20.620 43.500 19.550 1.00 0.00 +ATOM 4097 HW2 HOH 1208 21.850 42.650 19.810 1.00 0.00 +ATOM 4098 OW HOH 1209 10.890 43.930 3.270 1.00 0.00 +ATOM 4099 HW1 HOH 1209 10.180 44.270 3.810 1.00 0.00 +ATOM 4100 HW2 HOH 1209 11.300 43.260 3.820 1.00 0.00 +ATOM 4101 OW HOH 1210 30.370 28.720 13.010 1.00 0.00 +ATOM 4102 HW1 HOH 1210 29.800 29.240 13.570 1.00 0.00 +ATOM 4103 HW2 HOH 1210 30.270 29.120 12.140 1.00 0.00 +ATOM 4104 OW HOH 1211 18.840 17.380 2.120 1.00 0.00 +ATOM 4105 HW1 HOH 1211 18.500 16.780 2.790 1.00 0.00 +ATOM 4106 HW2 HOH 1211 19.600 17.790 2.540 1.00 0.00 +ATOM 4107 OW HOH 1212 22.210 1.870 8.140 1.00 0.00 +ATOM 4108 HW1 HOH 1212 22.550 2.290 8.930 1.00 0.00 +ATOM 4109 HW2 HOH 1212 22.190 0.940 8.360 1.00 0.00 +ATOM 4110 OW HOH 1213 23.560 35.650 3.370 1.00 0.00 +ATOM 4111 HW1 HOH 1213 23.070 34.830 3.450 1.00 0.00 +ATOM 4112 HW2 HOH 1213 24.480 35.380 3.300 1.00 0.00 +ATOM 4113 OW HOH 1214 4.170 32.410 13.990 1.00 0.00 +ATOM 4114 HW1 HOH 1214 4.240 31.860 13.210 1.00 0.00 +ATOM 4115 HW2 HOH 1214 4.940 32.980 13.950 1.00 0.00 +ATOM 4116 OW HOH 1215 35.080 28.040 27.030 1.00 0.00 +ATOM 4117 HW1 HOH 1215 35.100 28.900 27.440 1.00 0.00 +ATOM 4118 HW2 HOH 1215 34.510 28.140 26.280 1.00 0.00 +ATOM 4119 OW HOH 1216 6.800 22.720 32.840 1.00 0.00 +ATOM 4120 HW1 HOH 1216 7.570 22.430 32.340 1.00 0.00 +ATOM 4121 HW2 HOH 1216 6.500 23.490 32.370 1.00 0.00 +ATOM 4122 OW HOH 1217 18.690 37.940 2.520 1.00 0.00 +ATOM 4123 HW1 HOH 1217 19.180 38.250 3.290 1.00 0.00 +ATOM 4124 HW2 HOH 1217 17.990 38.590 2.410 1.00 0.00 +ATOM 4125 OW HOH 1218 2.280 3.560 5.470 1.00 0.00 +ATOM 4126 HW1 HOH 1218 2.860 3.760 4.730 1.00 0.00 +ATOM 4127 HW2 HOH 1218 1.570 4.210 5.400 1.00 0.00 +ATOM 4128 OW HOH 1219 45.880 35.780 4.470 1.00 0.00 +ATOM 4129 HW1 HOH 1219 46.140 36.370 3.760 1.00 0.00 +ATOM 4130 HW2 HOH 1219 45.340 36.320 5.040 1.00 0.00 +ATOM 4131 OW HOH 1220 13.990 25.870 25.660 1.00 0.00 +ATOM 4132 HW1 HOH 1220 14.590 26.230 25.010 1.00 0.00 +ATOM 4133 HW2 HOH 1220 13.760 25.010 25.320 1.00 0.00 +ATOM 4134 OW HOH 1221 1.360 39.520 10.050 1.00 0.00 +ATOM 4135 HW1 HOH 1221 1.530 38.610 10.290 1.00 0.00 +ATOM 4136 HW2 HOH 1221 0.680 39.470 9.380 1.00 0.00 +ATOM 4137 OW HOH 1222 2.890 14.750 1.700 1.00 0.00 +ATOM 4138 HW1 HOH 1222 1.950 14.630 1.590 1.00 0.00 +ATOM 4139 HW2 HOH 1222 3.170 15.190 0.890 1.00 0.00 +ATOM 4140 OW HOH 1223 26.900 7.730 29.740 1.00 0.00 +ATOM 4141 HW1 HOH 1223 26.410 8.170 30.430 1.00 0.00 +ATOM 4142 HW2 HOH 1223 27.410 8.430 29.320 1.00 0.00 +ATOM 4143 OW HOH 1224 10.530 44.720 10.950 1.00 0.00 +ATOM 4144 HW1 HOH 1224 10.650 44.830 11.890 1.00 0.00 +ATOM 4145 HW2 HOH 1224 10.690 45.590 10.590 1.00 0.00 +ATOM 4146 OW HOH 1225 15.730 11.770 36.780 1.00 0.00 +ATOM 4147 HW1 HOH 1225 15.310 10.940 36.590 1.00 0.00 +ATOM 4148 HW2 HOH 1225 16.650 11.640 36.540 1.00 0.00 +ATOM 4149 OW HOH 1226 39.220 24.420 23.900 1.00 0.00 +ATOM 4150 HW1 HOH 1226 39.330 24.980 23.130 1.00 0.00 +ATOM 4151 HW2 HOH 1226 38.470 23.870 23.680 1.00 0.00 +ATOM 4152 OW HOH 1227 2.690 33.940 32.060 1.00 0.00 +ATOM 4153 HW1 HOH 1227 2.470 34.820 31.760 1.00 0.00 +ATOM 4154 HW2 HOH 1227 2.250 33.350 31.440 1.00 0.00 +ATOM 4155 OW HOH 1228 24.110 29.470 11.070 1.00 0.00 +ATOM 4156 HW1 HOH 1228 24.440 29.230 10.200 1.00 0.00 +ATOM 4157 HW2 HOH 1228 23.440 30.120 10.910 1.00 0.00 +ATOM 4158 OW HOH 1229 23.340 29.570 31.830 1.00 0.00 +ATOM 4159 HW1 HOH 1229 23.430 28.890 31.160 1.00 0.00 +ATOM 4160 HW2 HOH 1229 22.420 29.810 31.800 1.00 0.00 +ATOM 4161 OW HOH 1230 33.110 34.870 12.820 1.00 0.00 +ATOM 4162 HW1 HOH 1230 33.700 35.440 13.330 1.00 0.00 +ATOM 4163 HW2 HOH 1230 32.270 34.930 13.290 1.00 0.00 +ATOM 4164 OW HOH 1231 2.960 34.220 11.230 1.00 0.00 +ATOM 4165 HW1 HOH 1231 2.830 33.280 11.330 1.00 0.00 +ATOM 4166 HW2 HOH 1231 3.910 34.340 11.260 1.00 0.00 +ATOM 4167 OW HOH 1232 31.780 24.520 35.220 1.00 0.00 +ATOM 4168 HW1 HOH 1232 31.040 23.920 35.100 1.00 0.00 +ATOM 4169 HW2 HOH 1232 31.570 25.270 34.660 1.00 0.00 +ATOM 4170 OW HOH 1233 21.710 7.540 0.220 1.00 0.00 +ATOM 4171 HW1 HOH 1233 21.580 8.280 -0.370 1.00 0.00 +ATOM 4172 HW2 HOH 1233 21.240 7.790 1.020 1.00 0.00 +ATOM 4173 OW HOH 1234 19.150 34.170 2.350 1.00 0.00 +ATOM 4174 HW1 HOH 1234 19.590 34.620 3.070 1.00 0.00 +ATOM 4175 HW2 HOH 1234 18.770 33.390 2.760 1.00 0.00 +ATOM 4176 OW HOH 1235 26.580 34.530 14.830 1.00 0.00 +ATOM 4177 HW1 HOH 1235 26.900 34.340 13.950 1.00 0.00 +ATOM 4178 HW2 HOH 1235 26.950 35.390 15.030 1.00 0.00 +ATOM 4179 OW HOH 1236 11.940 14.120 25.720 1.00 0.00 +ATOM 4180 HW1 HOH 1236 12.350 14.420 24.900 1.00 0.00 +ATOM 4181 HW2 HOH 1236 11.640 13.240 25.520 1.00 0.00 +ATOM 4182 OW HOH 1237 36.210 25.340 14.950 1.00 0.00 +ATOM 4183 HW1 HOH 1237 36.040 26.200 15.340 1.00 0.00 +ATOM 4184 HW2 HOH 1237 36.860 24.940 15.530 1.00 0.00 +ATOM 4185 OW HOH 1238 36.070 28.010 15.670 1.00 0.00 +ATOM 4186 HW1 HOH 1238 36.060 27.820 16.600 1.00 0.00 +ATOM 4187 HW2 HOH 1238 36.090 28.970 15.620 1.00 0.00 +ATOM 4188 OW HOH 1239 33.330 28.610 25.070 1.00 0.00 +ATOM 4189 HW1 HOH 1239 33.390 29.550 24.910 1.00 0.00 +ATOM 4190 HW2 HOH 1239 32.840 28.280 24.310 1.00 0.00 +ATOM 4191 OW HOH 1240 43.700 33.070 31.190 1.00 0.00 +ATOM 4192 HW1 HOH 1240 43.950 33.840 31.710 1.00 0.00 +ATOM 4193 HW2 HOH 1240 43.740 32.350 31.820 1.00 0.00 +ATOM 4194 OW HOH 1241 15.780 14.480 12.550 1.00 0.00 +ATOM 4195 HW1 HOH 1241 16.310 15.050 11.990 1.00 0.00 +ATOM 4196 HW2 HOH 1241 16.420 13.940 13.010 1.00 0.00 +ATOM 4197 OW HOH 1242 7.630 7.210 16.880 1.00 0.00 +ATOM 4198 HW1 HOH 1242 7.980 7.260 17.760 1.00 0.00 +ATOM 4199 HW2 HOH 1242 6.760 7.610 16.940 1.00 0.00 +ATOM 4200 OW HOH 1243 37.310 40.970 0.250 1.00 0.00 +ATOM 4201 HW1 HOH 1243 37.880 41.390 -0.390 1.00 0.00 +ATOM 4202 HW2 HOH 1243 37.900 40.620 0.910 1.00 0.00 +ATOM 4203 OW HOH 1244 7.720 22.640 24.510 1.00 0.00 +ATOM 4204 HW1 HOH 1244 8.160 22.840 25.340 1.00 0.00 +ATOM 4205 HW2 HOH 1244 7.770 23.440 24.000 1.00 0.00 +ATOM 4206 OW HOH 1245 16.660 28.500 38.370 1.00 0.00 +ATOM 4207 HW1 HOH 1245 15.810 28.350 38.770 1.00 0.00 +ATOM 4208 HW2 HOH 1245 17.090 27.650 38.370 1.00 0.00 +ATOM 4209 OW HOH 1246 12.700 2.090 33.850 1.00 0.00 +ATOM 4210 HW1 HOH 1246 12.370 1.650 34.630 1.00 0.00 +ATOM 4211 HW2 HOH 1246 13.560 2.410 34.100 1.00 0.00 +ATOM 4212 OW HOH 1247 7.060 42.090 28.010 1.00 0.00 +ATOM 4213 HW1 HOH 1247 7.720 42.570 28.510 1.00 0.00 +ATOM 4214 HW2 HOH 1247 7.550 41.700 27.280 1.00 0.00 +ATOM 4215 OW HOH 1248 1.660 26.860 28.420 1.00 0.00 +ATOM 4216 HW1 HOH 1248 2.500 26.480 28.170 1.00 0.00 +ATOM 4217 HW2 HOH 1248 1.120 26.770 27.630 1.00 0.00 +ATOM 4218 OW HOH 1249 25.000 11.820 32.560 1.00 0.00 +ATOM 4219 HW1 HOH 1249 24.480 12.070 31.800 1.00 0.00 +ATOM 4220 HW2 HOH 1249 25.800 12.330 32.480 1.00 0.00 +ATOM 4221 OW HOH 1250 22.010 18.270 38.580 1.00 0.00 +ATOM 4222 HW1 HOH 1250 21.870 19.100 38.120 1.00 0.00 +ATOM 4223 HW2 HOH 1250 22.700 18.460 39.220 1.00 0.00 +ATOM 4224 OW HOH 1251 17.010 42.840 10.100 1.00 0.00 +ATOM 4225 HW1 HOH 1251 17.440 42.500 9.320 1.00 0.00 +ATOM 4226 HW2 HOH 1251 17.260 43.770 10.120 1.00 0.00 +ATOM 4227 OW HOH 1252 8.140 2.510 0.620 1.00 0.00 +ATOM 4228 HW1 HOH 1252 8.500 2.340 -0.250 1.00 0.00 +ATOM 4229 HW2 HOH 1252 8.910 2.540 1.190 1.00 0.00 +ATOM 4230 OW HOH 1253 40.080 25.840 27.090 1.00 0.00 +ATOM 4231 HW1 HOH 1253 40.210 25.690 28.020 1.00 0.00 +ATOM 4232 HW2 HOH 1253 39.130 25.870 26.980 1.00 0.00 +ATOM 4233 OW HOH 1254 21.930 1.630 0.910 1.00 0.00 +ATOM 4234 HW1 HOH 1254 21.110 2.050 1.200 1.00 0.00 +ATOM 4235 HW2 HOH 1254 21.810 0.700 1.100 1.00 0.00 +ATOM 4236 OW HOH 1255 12.490 27.110 38.210 1.00 0.00 +ATOM 4237 HW1 HOH 1255 12.440 26.220 38.560 1.00 0.00 +ATOM 4238 HW2 HOH 1255 12.990 27.590 38.860 1.00 0.00 +ATOM 4239 OW HOH 1256 30.280 35.430 37.390 1.00 0.00 +ATOM 4240 HW1 HOH 1256 31.070 35.960 37.270 1.00 0.00 +ATOM 4241 HW2 HOH 1256 30.570 34.680 37.910 1.00 0.00 +ATOM 4242 OW HOH 1257 43.000 18.770 31.260 1.00 0.00 +ATOM 4243 HW1 HOH 1257 43.210 19.340 30.520 1.00 0.00 +ATOM 4244 HW2 HOH 1257 43.720 18.890 31.870 1.00 0.00 +ATOM 4245 OW HOH 1258 7.680 27.540 1.380 1.00 0.00 +ATOM 4246 HW1 HOH 1258 8.310 26.820 1.400 1.00 0.00 +ATOM 4247 HW2 HOH 1258 7.400 27.590 0.460 1.00 0.00 +ATOM 4248 OW HOH 1259 23.390 32.600 12.920 1.00 0.00 +ATOM 4249 HW1 HOH 1259 22.700 32.370 12.290 1.00 0.00 +ATOM 4250 HW2 HOH 1259 24.140 32.070 12.660 1.00 0.00 +ATOM 4251 OW HOH 1260 17.160 9.160 29.270 1.00 0.00 +ATOM 4252 HW1 HOH 1260 17.940 8.610 29.270 1.00 0.00 +ATOM 4253 HW2 HOH 1260 16.510 8.650 29.750 1.00 0.00 +ATOM 4254 OW HOH 1261 29.330 0.420 18.090 1.00 0.00 +ATOM 4255 HW1 HOH 1261 28.710 1.090 18.370 1.00 0.00 +ATOM 4256 HW2 HOH 1261 29.650 0.710 17.240 1.00 0.00 +ATOM 4257 OW HOH 1262 13.520 3.300 8.420 1.00 0.00 +ATOM 4258 HW1 HOH 1262 12.990 3.780 7.780 1.00 0.00 +ATOM 4259 HW2 HOH 1262 14.080 2.730 7.900 1.00 0.00 +ATOM 4260 OW HOH 1263 46.730 11.090 6.700 1.00 0.00 +ATOM 4261 HW1 HOH 1263 45.790 11.230 6.580 1.00 0.00 +ATOM 4262 HW2 HOH 1263 47.040 10.760 5.850 1.00 0.00 +ATOM 4263 OW HOH 1264 37.510 24.350 17.340 1.00 0.00 +ATOM 4264 HW1 HOH 1264 37.940 25.200 17.350 1.00 0.00 +ATOM 4265 HW2 HOH 1264 38.090 23.790 17.870 1.00 0.00 +ATOM 4266 OW HOH 1265 5.780 17.870 7.300 1.00 0.00 +ATOM 4267 HW1 HOH 1265 6.020 17.590 6.420 1.00 0.00 +ATOM 4268 HW2 HOH 1265 5.140 17.230 7.590 1.00 0.00 +ATOM 4269 OW HOH 1266 46.220 45.900 0.910 1.00 0.00 +ATOM 4270 HW1 HOH 1266 45.770 45.090 0.660 1.00 0.00 +ATOM 4271 HW2 HOH 1266 46.030 46.510 0.200 1.00 0.00 +ATOM 4272 OW HOH 1267 30.570 11.220 6.560 1.00 0.00 +ATOM 4273 HW1 HOH 1267 30.750 11.850 7.260 1.00 0.00 +ATOM 4274 HW2 HOH 1267 30.450 11.750 5.780 1.00 0.00 +ATOM 4275 OW HOH 1268 34.310 24.600 26.610 1.00 0.00 +ATOM 4276 HW1 HOH 1268 34.310 23.750 27.060 1.00 0.00 +ATOM 4277 HW2 HOH 1268 33.740 25.150 27.150 1.00 0.00 +ATOM 4278 OW HOH 1269 5.620 11.500 33.490 1.00 0.00 +ATOM 4279 HW1 HOH 1269 6.370 12.080 33.350 1.00 0.00 +ATOM 4280 HW2 HOH 1269 5.860 10.980 34.260 1.00 0.00 +ATOM 4281 OW HOH 1270 33.470 7.910 35.090 1.00 0.00 +ATOM 4282 HW1 HOH 1270 34.080 7.590 35.740 1.00 0.00 +ATOM 4283 HW2 HOH 1270 33.760 7.510 34.270 1.00 0.00 +ATOM 4284 OW HOH 1271 37.630 32.330 25.340 1.00 0.00 +ATOM 4285 HW1 HOH 1271 37.760 31.440 25.010 1.00 0.00 +ATOM 4286 HW2 HOH 1271 36.710 32.520 25.150 1.00 0.00 +ATOM 4287 OW HOH 1272 8.540 12.550 11.120 1.00 0.00 +ATOM 4288 HW1 HOH 1272 8.050 12.000 10.510 1.00 0.00 +ATOM 4289 HW2 HOH 1272 8.390 12.160 11.980 1.00 0.00 +ATOM 4290 OW HOH 1273 22.010 17.830 33.620 1.00 0.00 +ATOM 4291 HW1 HOH 1273 22.150 17.470 34.500 1.00 0.00 +ATOM 4292 HW2 HOH 1273 21.560 17.130 33.150 1.00 0.00 +ATOM 4293 OW HOH 1274 4.380 37.840 32.430 1.00 0.00 +ATOM 4294 HW1 HOH 1274 3.890 38.400 31.820 1.00 0.00 +ATOM 4295 HW2 HOH 1274 5.020 38.420 32.830 1.00 0.00 +ATOM 4296 OW HOH 1275 9.060 25.060 4.850 1.00 0.00 +ATOM 4297 HW1 HOH 1275 8.620 24.420 5.410 1.00 0.00 +ATOM 4298 HW2 HOH 1275 8.450 25.220 4.130 1.00 0.00 +ATOM 4299 OW HOH 1276 21.090 36.640 26.240 1.00 0.00 +ATOM 4300 HW1 HOH 1276 21.220 35.820 25.760 1.00 0.00 +ATOM 4301 HW2 HOH 1276 21.260 36.420 27.150 1.00 0.00 +ATOM 4302 OW HOH 1277 13.120 35.890 22.640 1.00 0.00 +ATOM 4303 HW1 HOH 1277 14.040 36.120 22.750 1.00 0.00 +ATOM 4304 HW2 HOH 1277 13.010 35.090 23.160 1.00 0.00 +ATOM 4305 OW HOH 1278 4.640 37.130 12.530 1.00 0.00 +ATOM 4306 HW1 HOH 1278 5.500 37.370 12.870 1.00 0.00 +ATOM 4307 HW2 HOH 1278 4.030 37.310 13.250 1.00 0.00 +ATOM 4308 OW HOH 1279 4.200 32.530 2.800 1.00 0.00 +ATOM 4309 HW1 HOH 1279 4.320 33.400 3.180 1.00 0.00 +ATOM 4310 HW2 HOH 1279 3.760 32.030 3.490 1.00 0.00 +ATOM 4311 OW HOH 1280 42.410 4.240 30.920 1.00 0.00 +ATOM 4312 HW1 HOH 1280 41.530 4.080 31.260 1.00 0.00 +ATOM 4313 HW2 HOH 1280 42.970 4.230 31.690 1.00 0.00 +ATOM 4314 OW HOH 1281 46.040 23.670 1.560 1.00 0.00 +ATOM 4315 HW1 HOH 1281 46.190 24.180 2.360 1.00 0.00 +ATOM 4316 HW2 HOH 1281 45.290 24.090 1.150 1.00 0.00 +ATOM 4317 OW HOH 1282 39.870 22.460 17.810 1.00 0.00 +ATOM 4318 HW1 HOH 1282 40.360 22.910 17.130 1.00 0.00 +ATOM 4319 HW2 HOH 1282 40.280 22.740 18.630 1.00 0.00 +ATOM 4320 OW HOH 1283 9.740 27.280 32.410 1.00 0.00 +ATOM 4321 HW1 HOH 1283 10.600 27.230 32.830 1.00 0.00 +ATOM 4322 HW2 HOH 1283 9.230 27.870 32.960 1.00 0.00 +ATOM 4323 OW HOH 1284 20.280 26.210 12.370 1.00 0.00 +ATOM 4324 HW1 HOH 1284 21.140 26.510 12.680 1.00 0.00 +ATOM 4325 HW2 HOH 1284 20.280 26.430 11.440 1.00 0.00 +ATOM 4326 OW HOH 1285 0.950 1.650 20.730 1.00 0.00 +ATOM 4327 HW1 HOH 1285 1.870 1.810 20.520 1.00 0.00 +ATOM 4328 HW2 HOH 1285 0.630 2.490 21.050 1.00 0.00 +ATOM 4329 OW HOH 1286 8.500 33.950 35.890 1.00 0.00 +ATOM 4330 HW1 HOH 1286 9.250 33.470 35.530 1.00 0.00 +ATOM 4331 HW2 HOH 1286 8.320 34.630 35.240 1.00 0.00 +ATOM 4332 OW HOH 1287 10.750 29.180 30.580 1.00 0.00 +ATOM 4333 HW1 HOH 1287 10.780 28.760 29.720 1.00 0.00 +ATOM 4334 HW2 HOH 1287 9.930 28.850 30.970 1.00 0.00 +ATOM 4335 OW HOH 1288 38.360 3.400 22.740 1.00 0.00 +ATOM 4336 HW1 HOH 1288 39.150 3.420 23.270 1.00 0.00 +ATOM 4337 HW2 HOH 1288 37.990 2.520 22.880 1.00 0.00 +ATOM 4338 OW HOH 1289 5.250 20.380 36.570 1.00 0.00 +ATOM 4339 HW1 HOH 1289 6.010 20.840 36.240 1.00 0.00 +ATOM 4340 HW2 HOH 1289 4.630 20.370 35.840 1.00 0.00 +ATOM 4341 OW HOH 1290 25.770 14.720 38.100 1.00 0.00 +ATOM 4342 HW1 HOH 1290 25.430 14.020 38.660 1.00 0.00 +ATOM 4343 HW2 HOH 1290 25.870 15.470 38.680 1.00 0.00 +ATOM 4344 OW HOH 1291 33.000 27.770 12.450 1.00 0.00 +ATOM 4345 HW1 HOH 1291 32.240 27.850 13.040 1.00 0.00 +ATOM 4346 HW2 HOH 1291 32.790 28.330 11.710 1.00 0.00 +ATOM 4347 OW HOH 1292 15.670 3.890 13.410 1.00 0.00 +ATOM 4348 HW1 HOH 1292 16.590 4.030 13.200 1.00 0.00 +ATOM 4349 HW2 HOH 1292 15.220 3.980 12.570 1.00 0.00 +ATOM 4350 OW HOH 1293 14.970 39.210 12.590 1.00 0.00 +ATOM 4351 HW1 HOH 1293 15.120 40.100 12.260 1.00 0.00 +ATOM 4352 HW2 HOH 1293 14.530 38.760 11.860 1.00 0.00 +ATOM 4353 OW HOH 1294 14.090 6.570 10.380 1.00 0.00 +ATOM 4354 HW1 HOH 1294 14.430 7.210 11.010 1.00 0.00 +ATOM 4355 HW2 HOH 1294 14.570 5.760 10.580 1.00 0.00 +ATOM 4356 OW HOH 1295 46.260 43.090 36.120 1.00 0.00 +ATOM 4357 HW1 HOH 1295 45.500 43.230 36.670 1.00 0.00 +ATOM 4358 HW2 HOH 1295 46.870 43.780 36.360 1.00 0.00 +ATOM 4359 OW HOH 1296 41.040 5.410 17.020 1.00 0.00 +ATOM 4360 HW1 HOH 1296 41.490 4.580 17.180 1.00 0.00 +ATOM 4361 HW2 HOH 1296 41.180 5.920 17.820 1.00 0.00 +ATOM 4362 OW HOH 1297 28.420 43.800 36.100 1.00 0.00 +ATOM 4363 HW1 HOH 1297 27.570 43.490 35.800 1.00 0.00 +ATOM 4364 HW2 HOH 1297 28.480 43.510 37.000 1.00 0.00 +ATOM 4365 OW HOH 1298 28.510 39.830 8.930 1.00 0.00 +ATOM 4366 HW1 HOH 1298 28.610 40.670 9.380 1.00 0.00 +ATOM 4367 HW2 HOH 1298 28.970 39.950 8.100 1.00 0.00 +ATOM 4368 OW HOH 1299 45.000 10.230 24.330 1.00 0.00 +ATOM 4369 HW1 HOH 1299 44.800 9.640 23.590 1.00 0.00 +ATOM 4370 HW2 HOH 1299 44.160 10.630 24.540 1.00 0.00 +ATOM 4371 OW HOH 1300 6.990 31.860 13.420 1.00 0.00 +ATOM 4372 HW1 HOH 1300 7.780 31.440 13.070 1.00 0.00 +ATOM 4373 HW2 HOH 1300 6.900 32.660 12.900 1.00 0.00 +ATOM 4374 OW HOH 1301 8.520 19.800 28.820 1.00 0.00 +ATOM 4375 HW1 HOH 1301 8.840 20.010 27.940 1.00 0.00 +ATOM 4376 HW2 HOH 1301 7.750 19.250 28.680 1.00 0.00 +ATOM 4377 OW HOH 1302 13.840 2.310 29.620 1.00 0.00 +ATOM 4378 HW1 HOH 1302 13.420 1.950 30.400 1.00 0.00 +ATOM 4379 HW2 HOH 1302 14.670 1.830 29.550 1.00 0.00 +ATOM 4380 OW HOH 1303 27.270 17.550 23.660 1.00 0.00 +ATOM 4381 HW1 HOH 1303 27.830 17.850 24.370 1.00 0.00 +ATOM 4382 HW2 HOH 1303 26.850 16.750 24.000 1.00 0.00 +ATOM 4383 OW HOH 1304 13.250 8.560 33.210 1.00 0.00 +ATOM 4384 HW1 HOH 1304 12.560 8.250 33.800 1.00 0.00 +ATOM 4385 HW2 HOH 1304 13.110 8.090 32.390 1.00 0.00 +ATOM 4386 OW HOH 1305 17.630 11.710 16.130 1.00 0.00 +ATOM 4387 HW1 HOH 1305 17.820 12.300 16.860 1.00 0.00 +ATOM 4388 HW2 HOH 1305 18.440 11.210 16.010 1.00 0.00 +ATOM 4389 OW HOH 1306 1.920 11.790 2.310 1.00 0.00 +ATOM 4390 HW1 HOH 1306 1.580 12.140 1.480 1.00 0.00 +ATOM 4391 HW2 HOH 1306 2.730 11.340 2.060 1.00 0.00 +ATOM 4392 OW HOH 1307 39.380 39.130 13.880 1.00 0.00 +ATOM 4393 HW1 HOH 1307 39.240 39.510 14.740 1.00 0.00 +ATOM 4394 HW2 HOH 1307 38.680 38.490 13.770 1.00 0.00 +ATOM 4395 OW HOH 1308 37.900 43.660 14.000 1.00 0.00 +ATOM 4396 HW1 HOH 1308 37.230 44.180 13.550 1.00 0.00 +ATOM 4397 HW2 HOH 1308 37.730 42.760 13.730 1.00 0.00 +ATOM 4398 OW HOH 1309 20.240 13.850 30.910 1.00 0.00 +ATOM 4399 HW1 HOH 1309 19.710 13.400 31.570 1.00 0.00 +ATOM 4400 HW2 HOH 1309 21.130 13.510 31.050 1.00 0.00 +ATOM 4401 OW HOH 1310 8.650 15.730 37.390 1.00 0.00 +ATOM 4402 HW1 HOH 1310 7.740 16.000 37.270 1.00 0.00 +ATOM 4403 HW2 HOH 1310 8.630 14.770 37.360 1.00 0.00 +ATOM 4404 OW HOH 1311 10.370 3.810 23.340 1.00 0.00 +ATOM 4405 HW1 HOH 1311 11.190 3.380 23.080 1.00 0.00 +ATOM 4406 HW2 HOH 1311 9.690 3.290 22.910 1.00 0.00 +ATOM 4407 OW HOH 1312 44.320 41.320 30.920 1.00 0.00 +ATOM 4408 HW1 HOH 1312 44.670 41.560 31.780 1.00 0.00 +ATOM 4409 HW2 HOH 1312 44.950 41.690 30.300 1.00 0.00 +ATOM 4410 OW HOH 1313 23.790 13.570 34.490 1.00 0.00 +ATOM 4411 HW1 HOH 1313 24.210 12.790 34.140 1.00 0.00 +ATOM 4412 HW2 HOH 1313 24.480 13.990 35.010 1.00 0.00 +ATOM 4413 OW HOH 1314 40.840 22.260 36.830 1.00 0.00 +ATOM 4414 HW1 HOH 1314 39.990 22.350 37.250 1.00 0.00 +ATOM 4415 HW2 HOH 1314 40.750 22.740 36.000 1.00 0.00 +ATOM 4416 OW HOH 1315 14.400 14.510 27.180 1.00 0.00 +ATOM 4417 HW1 HOH 1315 13.620 14.210 26.710 1.00 0.00 +ATOM 4418 HW2 HOH 1315 14.300 15.460 27.200 1.00 0.00 +ATOM 4419 OW HOH 1316 0.670 25.930 14.580 1.00 0.00 +ATOM 4420 HW1 HOH 1316 0.120 25.860 15.360 1.00 0.00 +ATOM 4421 HW2 HOH 1316 0.080 26.220 13.890 1.00 0.00 +ATOM 4422 OW HOH 1317 32.760 17.150 20.920 1.00 0.00 +ATOM 4423 HW1 HOH 1317 33.650 16.780 20.910 1.00 0.00 +ATOM 4424 HW2 HOH 1317 32.620 17.400 21.840 1.00 0.00 +ATOM 4425 OW HOH 1318 13.740 21.270 32.980 1.00 0.00 +ATOM 4426 HW1 HOH 1318 13.050 20.840 32.460 1.00 0.00 +ATOM 4427 HW2 HOH 1318 13.460 22.180 33.040 1.00 0.00 +ATOM 4428 OW HOH 1319 2.490 44.340 24.600 1.00 0.00 +ATOM 4429 HW1 HOH 1319 3.310 43.860 24.470 1.00 0.00 +ATOM 4430 HW2 HOH 1319 1.810 43.670 24.570 1.00 0.00 +ATOM 4431 OW HOH 1320 22.850 27.440 12.840 1.00 0.00 +ATOM 4432 HW1 HOH 1320 22.990 28.190 12.250 1.00 0.00 +ATOM 4433 HW2 HOH 1320 23.700 27.020 12.910 1.00 0.00 +ATOM 4434 OW HOH 1321 38.520 39.710 9.430 1.00 0.00 +ATOM 4435 HW1 HOH 1321 39.140 40.430 9.320 1.00 0.00 +ATOM 4436 HW2 HOH 1321 37.680 40.050 9.130 1.00 0.00 +ATOM 4437 OW HOH 1322 30.250 12.790 30.650 1.00 0.00 +ATOM 4438 HW1 HOH 1322 29.490 12.520 30.120 1.00 0.00 +ATOM 4439 HW2 HOH 1322 29.990 12.600 31.550 1.00 0.00 +ATOM 4440 OW HOH 1323 31.830 43.640 4.380 1.00 0.00 +ATOM 4441 HW1 HOH 1323 32.030 42.800 3.970 1.00 0.00 +ATOM 4442 HW2 HOH 1323 31.120 44.000 3.850 1.00 0.00 +ATOM 4443 OW HOH 1324 27.470 3.160 6.920 1.00 0.00 +ATOM 4444 HW1 HOH 1324 27.920 2.950 6.100 1.00 0.00 +ATOM 4445 HW2 HOH 1324 27.880 3.970 7.210 1.00 0.00 +ATOM 4446 OW HOH 1325 23.260 21.350 4.730 1.00 0.00 +ATOM 4447 HW1 HOH 1325 23.550 21.870 5.470 1.00 0.00 +ATOM 4448 HW2 HOH 1325 23.200 20.450 5.070 1.00 0.00 +ATOM 4449 OW HOH 1326 45.710 4.330 37.290 1.00 0.00 +ATOM 4450 HW1 HOH 1326 46.200 4.320 36.470 1.00 0.00 +ATOM 4451 HW2 HOH 1326 46.290 4.780 37.910 1.00 0.00 +ATOM 4452 OW HOH 1327 17.820 39.260 29.510 1.00 0.00 +ATOM 4453 HW1 HOH 1327 17.340 38.500 29.840 1.00 0.00 +ATOM 4454 HW2 HOH 1327 18.340 39.570 30.260 1.00 0.00 +ATOM 4455 OW HOH 1328 13.380 38.340 30.950 1.00 0.00 +ATOM 4456 HW1 HOH 1328 13.580 38.820 30.150 1.00 0.00 +ATOM 4457 HW2 HOH 1328 13.050 39.000 31.560 1.00 0.00 +ATOM 4458 OW HOH 1329 10.440 23.140 30.330 1.00 0.00 +ATOM 4459 HW1 HOH 1329 11.020 22.400 30.480 1.00 0.00 +ATOM 4460 HW2 HOH 1329 10.840 23.620 29.610 1.00 0.00 +ATOM 4461 OW HOH 1330 2.580 42.590 3.230 1.00 0.00 +ATOM 4462 HW1 HOH 1330 2.540 43.060 2.400 1.00 0.00 +ATOM 4463 HW2 HOH 1330 3.410 42.110 3.200 1.00 0.00 +ATOM 4464 OW HOH 1331 24.030 25.490 0.570 1.00 0.00 +ATOM 4465 HW1 HOH 1331 24.050 26.440 0.710 1.00 0.00 +ATOM 4466 HW2 HOH 1331 24.710 25.330 -0.090 1.00 0.00 +ATOM 4467 OW HOH 1332 5.990 30.430 25.230 1.00 0.00 +ATOM 4468 HW1 HOH 1332 5.190 30.310 24.730 1.00 0.00 +ATOM 4469 HW2 HOH 1332 6.440 31.160 24.790 1.00 0.00 +ATOM 4470 OW HOH 1333 9.510 15.460 10.040 1.00 0.00 +ATOM 4471 HW1 HOH 1333 9.590 14.990 10.870 1.00 0.00 +ATOM 4472 HW2 HOH 1333 8.860 16.140 10.210 1.00 0.00 +ATOM 4473 OW HOH 1334 44.650 22.920 11.560 1.00 0.00 +ATOM 4474 HW1 HOH 1334 44.130 23.370 10.890 1.00 0.00 +ATOM 4475 HW2 HOH 1334 45.500 23.370 11.540 1.00 0.00 +ATOM 4476 OW HOH 1335 27.750 36.400 22.460 1.00 0.00 +ATOM 4477 HW1 HOH 1335 28.270 36.180 23.240 1.00 0.00 +ATOM 4478 HW2 HOH 1335 27.960 37.320 22.280 1.00 0.00 +ATOM 4479 OW HOH 1336 48.080 25.650 16.500 1.00 0.00 +ATOM 4480 HW1 HOH 1336 47.620 24.840 16.700 1.00 0.00 +ATOM 4481 HW2 HOH 1336 48.160 26.100 17.350 1.00 0.00 +ATOM 4482 OW HOH 1337 1.570 31.790 14.660 1.00 0.00 +ATOM 4483 HW1 HOH 1337 2.450 32.140 14.480 1.00 0.00 +ATOM 4484 HW2 HOH 1337 1.730 31.050 15.250 1.00 0.00 +ATOM 4485 OW HOH 1338 40.750 9.920 28.390 1.00 0.00 +ATOM 4486 HW1 HOH 1338 40.460 9.090 28.020 1.00 0.00 +ATOM 4487 HW2 HOH 1338 40.190 10.050 29.160 1.00 0.00 +ATOM 4488 OW HOH 1339 36.580 40.660 19.430 1.00 0.00 +ATOM 4489 HW1 HOH 1339 35.870 40.820 18.810 1.00 0.00 +ATOM 4490 HW2 HOH 1339 37.210 41.360 19.250 1.00 0.00 +ATOM 4491 OW HOH 1340 12.380 41.170 32.590 1.00 0.00 +ATOM 4492 HW1 HOH 1340 12.320 41.180 31.640 1.00 0.00 +ATOM 4493 HW2 HOH 1340 11.480 41.310 32.900 1.00 0.00 +ATOM 4494 OW HOH 1341 43.720 34.740 19.330 1.00 0.00 +ATOM 4495 HW1 HOH 1341 43.400 33.890 19.050 1.00 0.00 +ATOM 4496 HW2 HOH 1341 43.680 35.290 18.550 1.00 0.00 +ATOM 4497 OW HOH 1342 16.850 44.520 35.280 1.00 0.00 +ATOM 4498 HW1 HOH 1342 17.350 43.870 34.780 1.00 0.00 +ATOM 4499 HW2 HOH 1342 17.270 44.530 36.140 1.00 0.00 +ATOM 4500 OW HOH 1343 37.050 29.400 18.330 1.00 0.00 +ATOM 4501 HW1 HOH 1343 36.500 30.130 18.040 1.00 0.00 +ATOM 4502 HW2 HOH 1343 37.930 29.760 18.360 1.00 0.00 +ATOM 4503 OW HOH 1344 48.030 3.420 21.960 1.00 0.00 +ATOM 4504 HW1 HOH 1344 47.490 2.680 21.690 1.00 0.00 +ATOM 4505 HW2 HOH 1344 48.320 3.200 22.840 1.00 0.00 +ATOM 4506 OW HOH 1345 24.990 40.170 2.410 1.00 0.00 +ATOM 4507 HW1 HOH 1345 24.230 40.660 2.700 1.00 0.00 +ATOM 4508 HW2 HOH 1345 25.040 39.420 3.000 1.00 0.00 +ATOM 4509 OW HOH 1346 41.970 8.870 5.000 1.00 0.00 +ATOM 4510 HW1 HOH 1346 42.050 8.770 5.950 1.00 0.00 +ATOM 4511 HW2 HOH 1346 41.090 9.240 4.870 1.00 0.00 +ATOM 4512 OW HOH 1347 11.860 29.590 4.440 1.00 0.00 +ATOM 4513 HW1 HOH 1347 12.270 28.890 4.930 1.00 0.00 +ATOM 4514 HW2 HOH 1347 11.870 30.340 5.030 1.00 0.00 +ATOM 4515 OW HOH 1348 6.540 33.310 18.760 1.00 0.00 +ATOM 4516 HW1 HOH 1348 6.590 32.810 17.950 1.00 0.00 +ATOM 4517 HW2 HOH 1348 6.680 32.660 19.450 1.00 0.00 +ATOM 4518 OW HOH 1349 12.380 1.260 10.330 1.00 0.00 +ATOM 4519 HW1 HOH 1349 13.060 0.610 10.130 1.00 0.00 +ATOM 4520 HW2 HOH 1349 12.710 2.070 9.960 1.00 0.00 +ATOM 4521 OW HOH 1350 14.460 23.120 38.480 1.00 0.00 +ATOM 4522 HW1 HOH 1350 14.100 23.180 37.590 1.00 0.00 +ATOM 4523 HW2 HOH 1350 15.400 23.230 38.360 1.00 0.00 +ATOM 4524 OW HOH 1351 19.330 26.540 34.900 1.00 0.00 +ATOM 4525 HW1 HOH 1351 19.960 26.150 34.290 1.00 0.00 +ATOM 4526 HW2 HOH 1351 19.510 27.480 34.870 1.00 0.00 +ATOM 4527 OW HOH 1352 13.110 40.740 36.970 1.00 0.00 +ATOM 4528 HW1 HOH 1352 12.790 41.120 37.790 1.00 0.00 +ATOM 4529 HW2 HOH 1352 13.380 39.850 37.210 1.00 0.00 +ATOM 4530 OW HOH 1353 44.360 12.400 9.620 1.00 0.00 +ATOM 4531 HW1 HOH 1353 44.190 12.770 10.480 1.00 0.00 +ATOM 4532 HW2 HOH 1353 45.260 12.100 9.660 1.00 0.00 +ATOM 4533 OW HOH 1354 25.760 10.210 3.420 1.00 0.00 +ATOM 4534 HW1 HOH 1354 25.340 9.640 2.770 1.00 0.00 +ATOM 4535 HW2 HOH 1354 26.460 9.680 3.790 1.00 0.00 +ATOM 4536 OW HOH 1355 40.300 41.290 29.910 1.00 0.00 +ATOM 4537 HW1 HOH 1355 39.580 40.730 29.630 1.00 0.00 +ATOM 4538 HW2 HOH 1355 41.060 40.690 29.970 1.00 0.00 +ATOM 4539 OW HOH 1356 16.250 36.840 13.850 1.00 0.00 +ATOM 4540 HW1 HOH 1356 15.770 37.650 13.720 1.00 0.00 +ATOM 4541 HW2 HOH 1356 15.620 36.150 13.640 1.00 0.00 +ATOM 4542 OW HOH 1357 5.490 8.450 7.970 1.00 0.00 +ATOM 4543 HW1 HOH 1357 5.940 8.940 7.270 1.00 0.00 +ATOM 4544 HW2 HOH 1357 6.200 8.010 8.440 1.00 0.00 +ATOM 4545 OW HOH 1358 6.200 5.180 24.690 1.00 0.00 +ATOM 4546 HW1 HOH 1358 6.090 5.940 24.120 1.00 0.00 +ATOM 4547 HW2 HOH 1358 7.020 5.340 25.160 1.00 0.00 +ATOM 4548 OW HOH 1359 8.630 3.030 34.470 1.00 0.00 +ATOM 4549 HW1 HOH 1359 8.860 2.330 33.860 1.00 0.00 +ATOM 4550 HW2 HOH 1359 8.570 3.810 33.920 1.00 0.00 +ATOM 4551 OW HOH 1360 10.100 4.340 17.320 1.00 0.00 +ATOM 4552 HW1 HOH 1360 11.040 4.400 17.460 1.00 0.00 +ATOM 4553 HW2 HOH 1360 10.000 3.760 16.560 1.00 0.00 +ATOM 4554 OW HOH 1361 1.850 41.160 23.890 1.00 0.00 +ATOM 4555 HW1 HOH 1361 2.720 41.530 23.730 1.00 0.00 +ATOM 4556 HW2 HOH 1361 1.290 41.590 23.240 1.00 0.00 +ATOM 4557 OW HOH 1362 24.020 38.200 4.150 1.00 0.00 +ATOM 4558 HW1 HOH 1362 23.250 38.610 4.550 1.00 0.00 +ATOM 4559 HW2 HOH 1362 23.720 37.320 3.920 1.00 0.00 +ATOM 4560 OW HOH 1363 31.900 25.130 25.330 1.00 0.00 +ATOM 4561 HW1 HOH 1363 32.070 25.930 25.830 1.00 0.00 +ATOM 4562 HW2 HOH 1363 32.610 24.540 25.570 1.00 0.00 +ATOM 4563 OW HOH 1364 21.400 22.150 33.090 1.00 0.00 +ATOM 4564 HW1 HOH 1364 21.490 21.340 32.600 1.00 0.00 +ATOM 4565 HW2 HOH 1364 20.500 22.150 33.410 1.00 0.00 +ATOM 4566 OW HOH 1365 19.640 32.290 32.690 1.00 0.00 +ATOM 4567 HW1 HOH 1365 19.550 33.220 32.900 1.00 0.00 +ATOM 4568 HW2 HOH 1365 19.620 32.250 31.740 1.00 0.00 +ATOM 4569 OW HOH 1366 29.120 9.820 31.200 1.00 0.00 +ATOM 4570 HW1 HOH 1366 29.580 9.000 31.340 1.00 0.00 +ATOM 4571 HW2 HOH 1366 29.520 10.200 30.410 1.00 0.00 +ATOM 4572 OW HOH 1367 24.010 45.870 12.110 1.00 0.00 +ATOM 4573 HW1 HOH 1367 24.850 45.420 12.120 1.00 0.00 +ATOM 4574 HW2 HOH 1367 23.410 45.260 11.680 1.00 0.00 +ATOM 4575 OW HOH 1368 47.060 7.370 17.370 1.00 0.00 +ATOM 4576 HW1 HOH 1368 47.710 6.960 16.800 1.00 0.00 +ATOM 4577 HW2 HOH 1368 46.270 6.850 17.250 1.00 0.00 +ATOM 4578 OW HOH 1369 44.290 2.410 14.300 1.00 0.00 +ATOM 4579 HW1 HOH 1369 43.730 1.640 14.360 1.00 0.00 +ATOM 4580 HW2 HOH 1369 43.840 2.990 13.690 1.00 0.00 +ATOM 4581 OW HOH 1370 41.950 30.670 27.930 1.00 0.00 +ATOM 4582 HW1 HOH 1370 42.140 31.300 27.240 1.00 0.00 +ATOM 4583 HW2 HOH 1370 41.040 30.400 27.770 1.00 0.00 +ATOM 4584 OW HOH 1371 2.540 1.090 23.980 1.00 0.00 +ATOM 4585 HW1 HOH 1371 2.980 1.080 23.130 1.00 0.00 +ATOM 4586 HW2 HOH 1371 2.570 0.180 24.270 1.00 0.00 +ATOM 4587 OW HOH 1372 17.680 5.320 20.750 1.00 0.00 +ATOM 4588 HW1 HOH 1372 18.300 4.910 21.360 1.00 0.00 +ATOM 4589 HW2 HOH 1372 16.820 5.120 21.120 1.00 0.00 +ATOM 4590 OW HOH 1373 44.800 25.050 32.670 1.00 0.00 +ATOM 4591 HW1 HOH 1373 44.330 24.710 31.910 1.00 0.00 +ATOM 4592 HW2 HOH 1373 44.110 25.310 33.280 1.00 0.00 +ATOM 4593 OW HOH 1374 42.890 40.520 24.250 1.00 0.00 +ATOM 4594 HW1 HOH 1374 42.210 40.080 24.770 1.00 0.00 +ATOM 4595 HW2 HOH 1374 42.500 41.360 24.020 1.00 0.00 +ATOM 4596 OW HOH 1375 30.570 23.190 0.690 1.00 0.00 +ATOM 4597 HW1 HOH 1375 29.740 22.870 0.340 1.00 0.00 +ATOM 4598 HW2 HOH 1375 30.800 23.940 0.130 1.00 0.00 +ATOM 4599 OW HOH 1376 34.450 25.480 6.900 1.00 0.00 +ATOM 4600 HW1 HOH 1376 33.990 24.670 7.080 1.00 0.00 +ATOM 4601 HW2 HOH 1376 34.870 25.330 6.050 1.00 0.00 +ATOM 4602 OW HOH 1377 23.830 16.640 36.620 1.00 0.00 +ATOM 4603 HW1 HOH 1377 23.530 17.110 37.390 1.00 0.00 +ATOM 4604 HW2 HOH 1377 23.330 15.830 36.620 1.00 0.00 +ATOM 4605 OW HOH 1378 47.570 28.710 25.000 1.00 0.00 +ATOM 4606 HW1 HOH 1378 46.710 28.960 24.660 1.00 0.00 +ATOM 4607 HW2 HOH 1378 48.190 29.070 24.360 1.00 0.00 +ATOM 4608 OW HOH 1379 41.990 24.400 25.200 1.00 0.00 +ATOM 4609 HW1 HOH 1379 41.140 24.490 25.640 1.00 0.00 +ATOM 4610 HW2 HOH 1379 41.950 25.020 24.470 1.00 0.00 +ATOM 4611 OW HOH 1380 45.990 32.160 29.550 1.00 0.00 +ATOM 4612 HW1 HOH 1380 45.250 32.560 29.990 1.00 0.00 +ATOM 4613 HW2 HOH 1380 45.890 31.220 29.700 1.00 0.00 +ATOM 4614 OW HOH 1381 3.140 12.360 18.880 1.00 0.00 +ATOM 4615 HW1 HOH 1381 2.750 11.500 18.760 1.00 0.00 +ATOM 4616 HW2 HOH 1381 4.040 12.180 19.150 1.00 0.00 +ATOM 4617 OW HOH 1382 21.600 34.890 0.560 1.00 0.00 +ATOM 4618 HW1 HOH 1382 20.790 35.280 0.890 1.00 0.00 +ATOM 4619 HW2 HOH 1382 21.510 33.960 0.720 1.00 0.00 +ATOM 4620 OW HOH 1383 6.360 44.710 33.340 1.00 0.00 +ATOM 4621 HW1 HOH 1383 7.070 44.460 32.750 1.00 0.00 +ATOM 4622 HW2 HOH 1383 6.320 45.660 33.270 1.00 0.00 +ATOM 4623 OW HOH 1384 32.760 11.860 26.900 1.00 0.00 +ATOM 4624 HW1 HOH 1384 33.040 11.920 25.980 1.00 0.00 +ATOM 4625 HW2 HOH 1384 33.070 12.670 27.290 1.00 0.00 +ATOM 4626 OW HOH 1385 47.630 13.110 2.540 1.00 0.00 +ATOM 4627 HW1 HOH 1385 46.680 13.100 2.590 1.00 0.00 +ATOM 4628 HW2 HOH 1385 47.910 12.370 3.070 1.00 0.00 +ATOM 4629 OW HOH 1386 47.970 29.060 14.230 1.00 0.00 +ATOM 4630 HW1 HOH 1386 48.910 29.100 14.090 1.00 0.00 +ATOM 4631 HW2 HOH 1386 47.840 29.430 15.100 1.00 0.00 +ATOM 4632 OW HOH 1387 1.600 31.150 33.510 1.00 0.00 +ATOM 4633 HW1 HOH 1387 1.570 30.220 33.730 1.00 0.00 +ATOM 4634 HW2 HOH 1387 2.540 31.330 33.390 1.00 0.00 +ATOM 4635 OW HOH 1388 10.690 20.980 13.820 1.00 0.00 +ATOM 4636 HW1 HOH 1388 10.850 20.530 12.990 1.00 0.00 +ATOM 4637 HW2 HOH 1388 11.030 20.380 14.490 1.00 0.00 +ATOM 4638 OW HOH 1389 27.860 38.500 36.350 1.00 0.00 +ATOM 4639 HW1 HOH 1389 26.910 38.570 36.310 1.00 0.00 +ATOM 4640 HW2 HOH 1389 28.050 37.650 35.950 1.00 0.00 +ATOM 4641 OW HOH 1390 15.610 39.230 7.870 1.00 0.00 +ATOM 4642 HW1 HOH 1390 14.850 39.410 8.430 1.00 0.00 +ATOM 4643 HW2 HOH 1390 15.240 39.080 7.000 1.00 0.00 +ATOM 4644 OW HOH 1391 10.270 3.890 2.580 1.00 0.00 +ATOM 4645 HW1 HOH 1391 10.390 3.960 1.640 1.00 0.00 +ATOM 4646 HW2 HOH 1391 10.600 4.720 2.930 1.00 0.00 +ATOM 4647 OW HOH 1392 20.080 1.660 21.910 1.00 0.00 +ATOM 4648 HW1 HOH 1392 20.320 2.580 21.770 1.00 0.00 +ATOM 4649 HW2 HOH 1392 19.200 1.700 22.300 1.00 0.00 +ATOM 4650 OW HOH 1393 13.470 17.070 36.190 1.00 0.00 +ATOM 4651 HW1 HOH 1393 12.510 17.020 36.270 1.00 0.00 +ATOM 4652 HW2 HOH 1393 13.630 17.940 35.810 1.00 0.00 +ATOM 4653 OW HOH 1394 44.000 5.450 16.140 1.00 0.00 +ATOM 4654 HW1 HOH 1394 43.470 4.750 15.760 1.00 0.00 +ATOM 4655 HW2 HOH 1394 43.930 5.310 17.090 1.00 0.00 +ATOM 4656 OW HOH 1395 1.370 14.450 23.950 1.00 0.00 +ATOM 4657 HW1 HOH 1395 1.990 14.910 24.510 1.00 0.00 +ATOM 4658 HW2 HOH 1395 0.700 14.120 24.550 1.00 0.00 +ATOM 4659 OW HOH 1396 37.640 27.190 6.250 1.00 0.00 +ATOM 4660 HW1 HOH 1396 37.950 26.360 6.620 1.00 0.00 +ATOM 4661 HW2 HOH 1396 37.130 26.930 5.480 1.00 0.00 +ATOM 4662 OW HOH 1397 24.000 11.600 19.990 1.00 0.00 +ATOM 4663 HW1 HOH 1397 24.270 11.640 20.910 1.00 0.00 +ATOM 4664 HW2 HOH 1397 23.790 10.680 19.840 1.00 0.00 +ATOM 4665 OW HOH 1398 26.930 36.540 2.970 1.00 0.00 +ATOM 4666 HW1 HOH 1398 26.850 36.840 3.870 1.00 0.00 +ATOM 4667 HW2 HOH 1398 26.170 35.960 2.850 1.00 0.00 +ATOM 4668 OW HOH 1399 9.290 7.830 18.690 1.00 0.00 +ATOM 4669 HW1 HOH 1399 9.800 8.060 17.910 1.00 0.00 +ATOM 4670 HW2 HOH 1399 9.800 8.180 19.420 1.00 0.00 +ATOM 4671 OW HOH 1400 28.320 40.960 3.310 1.00 0.00 +ATOM 4672 HW1 HOH 1400 27.900 40.680 2.500 1.00 0.00 +ATOM 4673 HW2 HOH 1400 29.110 41.420 3.030 1.00 0.00 +ATOM 4674 OW HOH 1401 43.480 34.400 23.740 1.00 0.00 +ATOM 4675 HW1 HOH 1401 42.840 34.790 23.140 1.00 0.00 +ATOM 4676 HW2 HOH 1401 44.180 34.090 23.170 1.00 0.00 +ATOM 4677 OW HOH 1402 8.700 43.430 22.270 1.00 0.00 +ATOM 4678 HW1 HOH 1402 8.500 44.110 21.630 1.00 0.00 +ATOM 4679 HW2 HOH 1402 9.590 43.140 22.050 1.00 0.00 +ATOM 4680 OW HOH 1403 17.870 4.530 36.530 1.00 0.00 +ATOM 4681 HW1 HOH 1403 18.730 4.830 36.810 1.00 0.00 +ATOM 4682 HW2 HOH 1403 18.010 3.650 36.200 1.00 0.00 +ATOM 4683 OW HOH 1404 30.210 22.660 3.480 1.00 0.00 +ATOM 4684 HW1 HOH 1404 29.710 23.360 3.900 1.00 0.00 +ATOM 4685 HW2 HOH 1404 30.230 22.900 2.560 1.00 0.00 +ATOM 4686 OW HOH 1405 2.700 11.280 8.440 1.00 0.00 +ATOM 4687 HW1 HOH 1405 3.410 10.950 8.980 1.00 0.00 +ATOM 4688 HW2 HOH 1405 3.060 11.320 7.560 1.00 0.00 +ATOM 4689 OW HOH 1406 47.880 26.360 12.830 1.00 0.00 +ATOM 4690 HW1 HOH 1406 47.330 26.750 13.510 1.00 0.00 +ATOM 4691 HW2 HOH 1406 47.890 27.010 12.120 1.00 0.00 +ATOM 4692 OW HOH 1407 2.620 29.530 28.320 1.00 0.00 +ATOM 4693 HW1 HOH 1407 2.370 28.670 28.670 1.00 0.00 +ATOM 4694 HW2 HOH 1407 2.620 29.410 27.370 1.00 0.00 +ATOM 4695 OW HOH 1408 19.240 11.130 30.100 1.00 0.00 +ATOM 4696 HW1 HOH 1408 18.590 11.760 29.800 1.00 0.00 +ATOM 4697 HW2 HOH 1408 18.750 10.310 30.200 1.00 0.00 +ATOM 4698 OW HOH 1409 25.430 5.080 16.980 1.00 0.00 +ATOM 4699 HW1 HOH 1409 26.370 5.230 17.130 1.00 0.00 +ATOM 4700 HW2 HOH 1409 25.380 4.170 16.690 1.00 0.00 +ATOM 4701 OW HOH 1410 16.280 37.670 35.560 1.00 0.00 +ATOM 4702 HW1 HOH 1410 15.830 37.150 34.900 1.00 0.00 +ATOM 4703 HW2 HOH 1410 15.610 38.260 35.900 1.00 0.00 +ATOM 4704 OW HOH 1411 24.030 38.350 33.810 1.00 0.00 +ATOM 4705 HW1 HOH 1411 23.300 38.350 33.200 1.00 0.00 +ATOM 4706 HW2 HOH 1411 24.520 39.150 33.600 1.00 0.00 +ATOM 4707 OW HOH 1412 27.480 44.060 0.410 1.00 0.00 +ATOM 4708 HW1 HOH 1412 28.200 43.430 0.390 1.00 0.00 +ATOM 4709 HW2 HOH 1412 27.830 44.810 0.900 1.00 0.00 +ATOM 4710 OW HOH 1413 31.050 39.630 7.470 1.00 0.00 +ATOM 4711 HW1 HOH 1413 31.270 40.020 8.310 1.00 0.00 +ATOM 4712 HW2 HOH 1413 31.610 40.090 6.840 1.00 0.00 +ATOM 4713 OW HOH 1414 25.460 5.010 30.480 1.00 0.00 +ATOM 4714 HW1 HOH 1414 24.620 5.450 30.540 1.00 0.00 +ATOM 4715 HW2 HOH 1414 25.970 5.540 29.870 1.00 0.00 +ATOM 4716 OW HOH 1415 26.410 43.160 3.180 1.00 0.00 +ATOM 4717 HW1 HOH 1415 26.690 43.450 2.310 1.00 0.00 +ATOM 4718 HW2 HOH 1415 26.890 42.340 3.320 1.00 0.00 +ATOM 4719 OW HOH 1416 40.370 9.250 32.170 1.00 0.00 +ATOM 4720 HW1 HOH 1416 39.630 8.760 32.530 1.00 0.00 +ATOM 4721 HW2 HOH 1416 40.000 9.720 31.430 1.00 0.00 +ATOM 4722 OW HOH 1417 46.970 38.880 23.780 1.00 0.00 +ATOM 4723 HW1 HOH 1417 47.380 38.150 24.230 1.00 0.00 +ATOM 4724 HW2 HOH 1417 46.090 38.560 23.560 1.00 0.00 +ATOM 4725 OW HOH 1418 39.060 29.670 31.660 1.00 0.00 +ATOM 4726 HW1 HOH 1418 39.160 29.400 32.570 1.00 0.00 +ATOM 4727 HW2 HOH 1418 39.760 30.310 31.520 1.00 0.00 +ATOM 4728 OW HOH 1419 46.870 24.710 25.380 1.00 0.00 +ATOM 4729 HW1 HOH 1419 46.330 25.490 25.530 1.00 0.00 +ATOM 4730 HW2 HOH 1419 46.720 24.160 26.160 1.00 0.00 +ATOM 4731 OW HOH 1420 32.240 45.250 30.360 1.00 0.00 +ATOM 4732 HW1 HOH 1420 32.940 45.840 30.090 1.00 0.00 +ATOM 4733 HW2 HOH 1420 31.720 45.110 29.570 1.00 0.00 +ATOM 4734 OW HOH 1421 40.320 9.460 15.990 1.00 0.00 +ATOM 4735 HW1 HOH 1421 39.560 9.010 16.370 1.00 0.00 +ATOM 4736 HW2 HOH 1421 40.980 8.770 15.890 1.00 0.00 +ATOM 4737 OW HOH 1422 45.010 25.700 17.940 1.00 0.00 +ATOM 4738 HW1 HOH 1422 45.860 26.100 18.120 1.00 0.00 +ATOM 4739 HW2 HOH 1422 45.200 25.010 17.300 1.00 0.00 +ATOM 4740 OW HOH 1423 9.160 40.430 37.210 1.00 0.00 +ATOM 4741 HW1 HOH 1423 9.870 40.270 37.820 1.00 0.00 +ATOM 4742 HW2 HOH 1423 8.610 39.650 37.270 1.00 0.00 +ATOM 4743 OW HOH 1424 7.530 42.640 2.370 1.00 0.00 +ATOM 4744 HW1 HOH 1424 7.690 42.980 3.250 1.00 0.00 +ATOM 4745 HW2 HOH 1424 7.850 43.320 1.780 1.00 0.00 +ATOM 4746 OW HOH 1425 41.220 31.440 9.430 1.00 0.00 +ATOM 4747 HW1 HOH 1425 40.680 30.720 9.770 1.00 0.00 +ATOM 4748 HW2 HOH 1425 41.710 31.750 10.180 1.00 0.00 +ATOM 4749 OW HOH 1426 5.290 42.450 9.400 1.00 0.00 +ATOM 4750 HW1 HOH 1426 6.200 42.400 9.690 1.00 0.00 +ATOM 4751 HW2 HOH 1426 5.280 43.110 8.710 1.00 0.00 +ATOM 4752 OW HOH 1427 25.370 6.590 27.540 1.00 0.00 +ATOM 4753 HW1 HOH 1427 25.230 7.020 28.390 1.00 0.00 +ATOM 4754 HW2 HOH 1427 25.750 7.280 26.990 1.00 0.00 +ATOM 4755 OW HOH 1428 7.030 39.130 8.860 1.00 0.00 +ATOM 4756 HW1 HOH 1428 7.360 38.710 8.070 1.00 0.00 +ATOM 4757 HW2 HOH 1428 6.420 38.500 9.230 1.00 0.00 +ATOM 4758 OW HOH 1429 45.440 5.550 2.690 1.00 0.00 +ATOM 4759 HW1 HOH 1429 45.220 5.560 3.620 1.00 0.00 +ATOM 4760 HW2 HOH 1429 44.870 6.210 2.300 1.00 0.00 +ATOM 4761 OW HOH 1430 0.230 18.360 16.840 1.00 0.00 +ATOM 4762 HW1 HOH 1430 0.490 18.740 16.000 1.00 0.00 +ATOM 4763 HW2 HOH 1430 0.980 18.510 17.410 1.00 0.00 +ATOM 4764 OW HOH 1431 14.700 35.550 5.820 1.00 0.00 +ATOM 4765 HW1 HOH 1431 14.440 36.010 5.030 1.00 0.00 +ATOM 4766 HW2 HOH 1431 14.490 34.630 5.660 1.00 0.00 +ATOM 4767 OW HOH 1432 11.180 33.420 5.330 1.00 0.00 +ATOM 4768 HW1 HOH 1432 11.230 34.080 6.020 1.00 0.00 +ATOM 4769 HW2 HOH 1432 12.080 33.090 5.250 1.00 0.00 +ATOM 4770 OW HOH 1433 0.770 43.130 6.610 1.00 0.00 +ATOM 4771 HW1 HOH 1433 0.610 42.420 5.980 1.00 0.00 +ATOM 4772 HW2 HOH 1433 1.630 42.950 6.970 1.00 0.00 +ATOM 4773 OW HOH 1434 34.350 28.130 6.200 1.00 0.00 +ATOM 4774 HW1 HOH 1434 34.420 27.200 6.390 1.00 0.00 +ATOM 4775 HW2 HOH 1434 35.180 28.510 6.500 1.00 0.00 +ATOM 4776 OW HOH 1435 4.620 4.210 22.430 1.00 0.00 +ATOM 4777 HW1 HOH 1435 4.860 4.170 23.350 1.00 0.00 +ATOM 4778 HW2 HOH 1435 3.810 4.720 22.410 1.00 0.00 +ATOM 4779 OW HOH 1436 44.400 9.960 4.790 1.00 0.00 +ATOM 4780 HW1 HOH 1436 43.470 9.760 4.690 1.00 0.00 +ATOM 4781 HW2 HOH 1436 44.450 10.920 4.720 1.00 0.00 +ATOM 4782 OW HOH 1437 36.050 0.160 25.620 1.00 0.00 +ATOM 4783 HW1 HOH 1437 36.260 0.590 24.800 1.00 0.00 +ATOM 4784 HW2 HOH 1437 35.380 -0.480 25.390 1.00 0.00 +ATOM 4785 OW HOH 1438 44.400 14.010 17.920 1.00 0.00 +ATOM 4786 HW1 HOH 1438 45.070 13.330 18.000 1.00 0.00 +ATOM 4787 HW2 HOH 1438 43.600 13.600 18.260 1.00 0.00 +ATOM 4788 OW HOH 1439 31.190 10.640 38.010 1.00 0.00 +ATOM 4789 HW1 HOH 1439 31.630 10.230 37.270 1.00 0.00 +ATOM 4790 HW2 HOH 1439 30.500 10.020 38.260 1.00 0.00 +ATOM 4791 OW HOH 1440 44.470 45.770 6.950 1.00 0.00 +ATOM 4792 HW1 HOH 1440 44.990 45.470 6.210 1.00 0.00 +ATOM 4793 HW2 HOH 1440 44.000 44.990 7.240 1.00 0.00 +ATOM 4794 OW HOH 1441 3.770 35.310 8.330 1.00 0.00 +ATOM 4795 HW1 HOH 1441 3.820 35.960 9.030 1.00 0.00 +ATOM 4796 HW2 HOH 1441 3.170 35.680 7.690 1.00 0.00 +ATOM 4797 OW HOH 1442 24.710 5.280 34.300 1.00 0.00 +ATOM 4798 HW1 HOH 1442 24.620 6.230 34.240 1.00 0.00 +ATOM 4799 HW2 HOH 1442 25.370 5.070 33.630 1.00 0.00 +ATOM 4800 OW HOH 1443 38.750 27.490 13.790 1.00 0.00 +ATOM 4801 HW1 HOH 1443 37.830 27.420 14.030 1.00 0.00 +ATOM 4802 HW2 HOH 1443 38.980 26.630 13.440 1.00 0.00 +ATOM 4803 OW HOH 1444 14.700 20.750 29.810 1.00 0.00 +ATOM 4804 HW1 HOH 1444 14.590 21.710 29.810 1.00 0.00 +ATOM 4805 HW2 HOH 1444 14.630 20.500 28.890 1.00 0.00 +ATOM 4806 OW HOH 1445 33.570 43.260 0.450 1.00 0.00 +ATOM 4807 HW1 HOH 1445 33.680 43.670 1.310 1.00 0.00 +ATOM 4808 HW2 HOH 1445 33.680 42.320 0.620 1.00 0.00 +ATOM 4809 OW HOH 1446 42.900 43.370 7.600 1.00 0.00 +ATOM 4810 HW1 HOH 1446 42.330 43.900 8.160 1.00 0.00 +ATOM 4811 HW2 HOH 1446 43.300 42.740 8.190 1.00 0.00 +ATOM 4812 OW HOH 1447 22.250 41.070 3.630 1.00 0.00 +ATOM 4813 HW1 HOH 1447 21.800 40.530 4.270 1.00 0.00 +ATOM 4814 HW2 HOH 1447 21.560 41.390 3.040 1.00 0.00 +ATOM 4815 OW HOH 1448 3.520 20.450 7.820 1.00 0.00 +ATOM 4816 HW1 HOH 1448 3.670 21.190 8.410 1.00 0.00 +ATOM 4817 HW2 HOH 1448 4.260 19.860 7.990 1.00 0.00 +ATOM 4818 OW HOH 1449 5.610 29.590 34.600 1.00 0.00 +ATOM 4819 HW1 HOH 1449 5.440 29.690 35.540 1.00 0.00 +ATOM 4820 HW2 HOH 1449 5.620 30.490 34.260 1.00 0.00 +ATOM 4821 OW HOH 1450 49.470 11.420 15.780 1.00 0.00 +ATOM 4822 HW1 HOH 1450 48.950 10.750 15.340 1.00 0.00 +ATOM 4823 HW2 HOH 1450 48.880 12.170 15.860 1.00 0.00 +ATOM 4824 OW HOH 1451 9.370 36.960 34.730 1.00 0.00 +ATOM 4825 HW1 HOH 1451 9.080 37.490 33.980 1.00 0.00 +ATOM 4826 HW2 HOH 1451 10.330 36.950 34.660 1.00 0.00 +ATOM 4827 OW HOH 1452 41.760 15.500 29.600 1.00 0.00 +ATOM 4828 HW1 HOH 1452 42.660 15.190 29.540 1.00 0.00 +ATOM 4829 HW2 HOH 1452 41.480 15.270 30.490 1.00 0.00 +ATOM 4830 OW HOH 1453 31.940 27.800 7.870 1.00 0.00 +ATOM 4831 HW1 HOH 1453 31.360 28.470 7.500 1.00 0.00 +ATOM 4832 HW2 HOH 1453 32.750 27.880 7.370 1.00 0.00 +ATOM 4833 OW HOH 1454 6.440 7.460 23.010 1.00 0.00 +ATOM 4834 HW1 HOH 1454 6.220 7.270 22.090 1.00 0.00 +ATOM 4835 HW2 HOH 1454 6.130 8.350 23.150 1.00 0.00 +ATOM 4836 OW HOH 1455 8.420 14.260 14.540 1.00 0.00 +ATOM 4837 HW1 HOH 1455 8.080 14.810 13.830 1.00 0.00 +ATOM 4838 HW2 HOH 1455 8.510 13.390 14.150 1.00 0.00 +ATOM 4839 OW HOH 1456 14.450 20.200 7.200 1.00 0.00 +ATOM 4840 HW1 HOH 1456 14.630 19.750 6.370 1.00 0.00 +ATOM 4841 HW2 HOH 1456 13.620 19.830 7.500 1.00 0.00 +ATOM 4842 OW HOH 1457 48.300 44.610 37.090 1.00 0.00 +ATOM 4843 HW1 HOH 1457 48.390 45.540 37.310 1.00 0.00 +ATOM 4844 HW2 HOH 1457 49.060 44.420 36.540 1.00 0.00 +ATOM 4845 OW HOH 1458 36.170 25.180 4.880 1.00 0.00 +ATOM 4846 HW1 HOH 1458 35.680 25.840 4.380 1.00 0.00 +ATOM 4847 HW2 HOH 1458 36.150 24.400 4.320 1.00 0.00 +ATOM 4848 OW HOH 1459 44.140 42.450 27.030 1.00 0.00 +ATOM 4849 HW1 HOH 1459 44.120 42.260 26.090 1.00 0.00 +ATOM 4850 HW2 HOH 1459 44.840 41.910 27.370 1.00 0.00 +ATOM 4851 OW HOH 1460 15.020 17.140 1.630 1.00 0.00 +ATOM 4852 HW1 HOH 1460 15.430 16.570 2.280 1.00 0.00 +ATOM 4853 HW2 HOH 1460 15.240 18.030 1.910 1.00 0.00 +ATOM 4854 OW HOH 1461 33.980 1.390 8.680 1.00 0.00 +ATOM 4855 HW1 HOH 1461 33.310 0.710 8.810 1.00 0.00 +ATOM 4856 HW2 HOH 1461 34.750 1.050 9.130 1.00 0.00 +ATOM 4857 OW HOH 1462 25.910 44.040 5.900 1.00 0.00 +ATOM 4858 HW1 HOH 1462 25.830 43.710 5.010 1.00 0.00 +ATOM 4859 HW2 HOH 1462 25.720 44.970 5.830 1.00 0.00 +ATOM 4860 OW HOH 1463 11.100 23.650 2.970 1.00 0.00 +ATOM 4861 HW1 HOH 1463 10.810 22.790 3.250 1.00 0.00 +ATOM 4862 HW2 HOH 1463 10.470 24.260 3.360 1.00 0.00 +ATOM 4863 OW HOH 1464 29.760 1.930 24.760 1.00 0.00 +ATOM 4864 HW1 HOH 1464 30.530 1.380 24.890 1.00 0.00 +ATOM 4865 HW2 HOH 1464 29.050 1.310 24.570 1.00 0.00 +ATOM 4866 OW HOH 1465 1.850 9.410 12.030 1.00 0.00 +ATOM 4867 HW1 HOH 1465 1.750 9.380 11.080 1.00 0.00 +ATOM 4868 HW2 HOH 1465 0.950 9.370 12.370 1.00 0.00 +ATOM 4869 OW HOH 1466 35.610 25.310 36.760 1.00 0.00 +ATOM 4870 HW1 HOH 1466 35.830 24.600 36.150 1.00 0.00 +ATOM 4871 HW2 HOH 1466 35.150 24.870 37.480 1.00 0.00 +ATOM 4872 OW HOH 1467 8.900 16.220 20.330 1.00 0.00 +ATOM 4873 HW1 HOH 1467 9.680 15.740 20.030 1.00 0.00 +ATOM 4874 HW2 HOH 1467 8.250 16.060 19.640 1.00 0.00 +ATOM 4875 OW HOH 1468 31.870 3.000 11.820 1.00 0.00 +ATOM 4876 HW1 HOH 1468 31.150 2.600 11.340 1.00 0.00 +ATOM 4877 HW2 HOH 1468 31.850 2.580 12.680 1.00 0.00 +ATOM 4878 OW HOH 1469 48.760 16.910 8.650 1.00 0.00 +ATOM 4879 HW1 HOH 1469 49.250 17.000 9.460 1.00 0.00 +ATOM 4880 HW2 HOH 1469 49.350 17.230 7.970 1.00 0.00 +ATOM 4881 OW HOH 1470 4.890 38.330 6.600 1.00 0.00 +ATOM 4882 HW1 HOH 1470 4.360 38.350 7.390 1.00 0.00 +ATOM 4883 HW2 HOH 1470 5.490 39.070 6.700 1.00 0.00 +ATOM 4884 OW HOH 1471 21.070 44.390 4.430 1.00 0.00 +ATOM 4885 HW1 HOH 1471 20.320 43.950 4.840 1.00 0.00 +ATOM 4886 HW2 HOH 1471 21.680 44.530 5.150 1.00 0.00 +ATOM 4887 OW HOH 1472 26.780 22.310 38.790 1.00 0.00 +ATOM 4888 HW1 HOH 1472 25.870 22.040 38.690 1.00 0.00 +ATOM 4889 HW2 HOH 1472 27.290 21.500 38.720 1.00 0.00 +ATOM 4890 OW HOH 1473 12.270 40.330 12.510 1.00 0.00 +ATOM 4891 HW1 HOH 1473 13.140 40.020 12.770 1.00 0.00 +ATOM 4892 HW2 HOH 1473 12.300 41.280 12.670 1.00 0.00 +ATOM 4893 OW HOH 1474 47.360 12.190 36.180 1.00 0.00 +ATOM 4894 HW1 HOH 1474 47.050 11.360 35.820 1.00 0.00 +ATOM 4895 HW2 HOH 1474 47.590 11.990 37.090 1.00 0.00 +ATOM 4896 OW HOH 1475 7.660 10.420 25.370 1.00 0.00 +ATOM 4897 HW1 HOH 1475 6.880 9.910 25.160 1.00 0.00 +ATOM 4898 HW2 HOH 1475 7.360 11.020 26.060 1.00 0.00 +ATOM 4899 OW HOH 1476 30.590 6.580 15.820 1.00 0.00 +ATOM 4900 HW1 HOH 1476 30.380 7.480 16.060 1.00 0.00 +ATOM 4901 HW2 HOH 1476 31.110 6.660 15.020 1.00 0.00 +ATOM 4902 OW HOH 1477 25.210 23.000 26.660 1.00 0.00 +ATOM 4903 HW1 HOH 1477 25.610 23.610 27.290 1.00 0.00 +ATOM 4904 HW2 HOH 1477 24.300 22.930 26.940 1.00 0.00 +ATOM 4905 OW HOH 1478 47.810 39.160 32.320 1.00 0.00 +ATOM 4906 HW1 HOH 1478 47.330 38.350 32.170 1.00 0.00 +ATOM 4907 HW2 HOH 1478 47.460 39.500 33.140 1.00 0.00 +ATOM 4908 OW HOH 1479 12.440 42.820 16.150 1.00 0.00 +ATOM 4909 HW1 HOH 1479 13.270 43.200 15.870 1.00 0.00 +ATOM 4910 HW2 HOH 1479 12.340 43.130 17.050 1.00 0.00 +ATOM 4911 OW HOH 1480 13.880 44.920 35.780 1.00 0.00 +ATOM 4912 HW1 HOH 1480 13.680 43.990 35.700 1.00 0.00 +ATOM 4913 HW2 HOH 1480 14.800 44.990 35.520 1.00 0.00 +ATOM 4914 OW HOH 1481 37.230 2.420 17.780 1.00 0.00 +ATOM 4915 HW1 HOH 1481 36.400 2.750 18.140 1.00 0.00 +ATOM 4916 HW2 HOH 1481 37.760 3.200 17.640 1.00 0.00 +ATOM 4917 OW HOH 1482 23.460 30.820 35.820 1.00 0.00 +ATOM 4918 HW1 HOH 1482 23.790 31.710 35.650 1.00 0.00 +ATOM 4919 HW2 HOH 1482 22.520 30.880 35.670 1.00 0.00 +ATOM 4920 OW HOH 1483 11.050 45.380 13.470 1.00 0.00 +ATOM 4921 HW1 HOH 1483 11.760 46.010 13.530 1.00 0.00 +ATOM 4922 HW2 HOH 1483 10.670 45.360 14.350 1.00 0.00 +ATOM 4923 OW HOH 1484 46.600 25.900 34.710 1.00 0.00 +ATOM 4924 HW1 HOH 1484 45.950 25.540 34.110 1.00 0.00 +ATOM 4925 HW2 HOH 1484 47.020 26.600 34.220 1.00 0.00 +ATOM 4926 OW HOH 1485 35.840 33.320 28.020 1.00 0.00 +ATOM 4927 HW1 HOH 1485 35.360 33.590 28.800 1.00 0.00 +ATOM 4928 HW2 HOH 1485 35.190 33.340 27.310 1.00 0.00 +ATOM 4929 OW HOH 1486 28.150 10.150 23.140 1.00 0.00 +ATOM 4930 HW1 HOH 1486 29.050 10.090 23.450 1.00 0.00 +ATOM 4931 HW2 HOH 1486 27.670 10.530 23.880 1.00 0.00 +ATOM 4932 OW HOH 1487 24.090 31.440 2.450 1.00 0.00 +ATOM 4933 HW1 HOH 1487 24.480 31.110 1.640 1.00 0.00 +ATOM 4934 HW2 HOH 1487 24.160 30.720 3.070 1.00 0.00 +ATOM 4935 OW HOH 1488 9.110 21.760 11.420 1.00 0.00 +ATOM 4936 HW1 HOH 1488 8.330 22.130 11.830 1.00 0.00 +ATOM 4937 HW2 HOH 1488 9.470 22.480 10.900 1.00 0.00 +ATOM 4938 OW HOH 1489 23.100 44.560 9.780 1.00 0.00 +ATOM 4939 HW1 HOH 1489 23.160 44.810 8.860 1.00 0.00 +ATOM 4940 HW2 HOH 1489 23.470 43.670 9.810 1.00 0.00 +ATOM 4941 OW HOH 1490 35.540 22.770 10.480 1.00 0.00 +ATOM 4942 HW1 HOH 1490 35.310 23.570 10.000 1.00 0.00 +ATOM 4943 HW2 HOH 1490 35.500 23.020 11.400 1.00 0.00 +ATOM 4944 OW HOH 1491 39.540 0.270 25.630 1.00 0.00 +ATOM 4945 HW1 HOH 1491 40.210 0.520 26.270 1.00 0.00 +ATOM 4946 HW2 HOH 1491 40.000 0.260 24.790 1.00 0.00 +ATOM 4947 OW HOH 1492 39.870 17.900 14.390 1.00 0.00 +ATOM 4948 HW1 HOH 1492 39.540 18.790 14.300 1.00 0.00 +ATOM 4949 HW2 HOH 1492 39.290 17.370 13.840 1.00 0.00 +ATOM 4950 OW HOH 1493 12.950 41.480 29.990 1.00 0.00 +ATOM 4951 HW1 HOH 1493 12.270 40.930 29.630 1.00 0.00 +ATOM 4952 HW2 HOH 1493 13.540 41.660 29.260 1.00 0.00 +ATOM 4953 OW HOH 1494 19.200 6.540 15.560 1.00 0.00 +ATOM 4954 HW1 HOH 1494 19.300 5.670 15.960 1.00 0.00 +ATOM 4955 HW2 HOH 1494 18.710 7.050 16.210 1.00 0.00 +ATOM 4956 OW HOH 1495 6.760 15.770 34.070 1.00 0.00 +ATOM 4957 HW1 HOH 1495 6.720 16.620 33.630 1.00 0.00 +ATOM 4958 HW2 HOH 1495 7.360 15.260 33.520 1.00 0.00 +ATOM 4959 OW HOH 1496 42.980 15.370 37.360 1.00 0.00 +ATOM 4960 HW1 HOH 1496 43.630 15.620 38.010 1.00 0.00 +ATOM 4961 HW2 HOH 1496 43.380 15.590 36.520 1.00 0.00 +ATOM 4962 OW HOH 1497 43.880 24.580 -0.020 1.00 0.00 +ATOM 4963 HW1 HOH 1497 43.090 24.060 0.130 1.00 0.00 +ATOM 4964 HW2 HOH 1497 43.740 25.380 0.480 1.00 0.00 +ATOM 4965 OW HOH 1498 26.490 5.360 4.940 1.00 0.00 +ATOM 4966 HW1 HOH 1498 25.540 5.430 5.090 1.00 0.00 +ATOM 4967 HW2 HOH 1498 26.600 4.510 4.500 1.00 0.00 +ATOM 4968 OW HOH 1499 41.690 21.590 31.020 1.00 0.00 +ATOM 4969 HW1 HOH 1499 41.500 22.440 31.400 1.00 0.00 +ATOM 4970 HW2 HOH 1499 41.300 20.960 31.620 1.00 0.00 +ATOM 4971 OW HOH 1500 40.220 14.740 24.870 1.00 0.00 +ATOM 4972 HW1 HOH 1500 40.780 15.370 24.430 1.00 0.00 +ATOM 4973 HW2 HOH 1500 40.600 14.650 25.750 1.00 0.00 +ATOM 4974 OW HOH 1501 24.860 43.610 20.990 1.00 0.00 +ATOM 4975 HW1 HOH 1501 25.200 44.140 20.280 1.00 0.00 +ATOM 4976 HW2 HOH 1501 25.610 43.100 21.290 1.00 0.00 +ATOM 4977 OW HOH 1502 22.070 10.500 14.110 1.00 0.00 +ATOM 4978 HW1 HOH 1502 21.260 10.450 14.610 1.00 0.00 +ATOM 4979 HW2 HOH 1502 22.180 11.430 13.910 1.00 0.00 +ATOM 4980 OW HOH 1503 23.980 28.040 34.170 1.00 0.00 +ATOM 4981 HW1 HOH 1503 23.250 28.650 34.010 1.00 0.00 +ATOM 4982 HW2 HOH 1503 24.610 28.240 33.480 1.00 0.00 +ATOM 4983 OW HOH 1504 1.030 43.900 35.260 1.00 0.00 +ATOM 4984 HW1 HOH 1504 1.950 43.660 35.380 1.00 0.00 +ATOM 4985 HW2 HOH 1504 1.060 44.780 34.890 1.00 0.00 +ATOM 4986 OW HOH 1505 28.880 0.390 28.010 1.00 0.00 +ATOM 4987 HW1 HOH 1505 29.050 -0.040 28.850 1.00 0.00 +ATOM 4988 HW2 HOH 1505 27.930 0.450 27.960 1.00 0.00 +ATOM 4989 OW HOH 1506 28.870 22.030 26.660 1.00 0.00 +ATOM 4990 HW1 HOH 1506 29.410 22.430 25.990 1.00 0.00 +ATOM 4991 HW2 HOH 1506 29.170 22.420 27.480 1.00 0.00 +ATOM 4992 OW HOH 1507 40.430 10.780 13.450 1.00 0.00 +ATOM 4993 HW1 HOH 1507 41.130 10.320 12.990 1.00 0.00 +ATOM 4994 HW2 HOH 1507 40.460 10.440 14.350 1.00 0.00 +ATOM 4995 OW HOH 1508 14.890 3.290 34.670 1.00 0.00 +ATOM 4996 HW1 HOH 1508 14.330 4.050 34.850 1.00 0.00 +ATOM 4997 HW2 HOH 1508 15.630 3.650 34.190 1.00 0.00 +ATOM 4998 OW HOH 1509 17.800 13.700 1.620 1.00 0.00 +ATOM 4999 HW1 HOH 1509 17.270 13.540 0.840 1.00 0.00 +ATOM 5000 HW2 HOH 1509 17.160 13.980 2.280 1.00 0.00 +ATOM 5001 OW HOH 1510 28.080 3.650 2.260 1.00 0.00 +ATOM 5002 HW1 HOH 1510 28.560 3.390 1.470 1.00 0.00 +ATOM 5003 HW2 HOH 1510 28.280 2.960 2.890 1.00 0.00 +ATOM 5004 OW HOH 1511 3.700 28.300 4.550 1.00 0.00 +ATOM 5005 HW1 HOH 1511 4.150 28.660 5.320 1.00 0.00 +ATOM 5006 HW2 HOH 1511 3.980 27.390 4.510 1.00 0.00 +ATOM 5007 OW HOH 1512 0.310 14.420 10.930 1.00 0.00 +ATOM 5008 HW1 HOH 1512 0.620 14.220 10.040 1.00 0.00 +ATOM 5009 HW2 HOH 1512 0.950 15.040 11.270 1.00 0.00 +ATOM 5010 OW HOH 1513 1.440 25.880 18.870 1.00 0.00 +ATOM 5011 HW1 HOH 1513 2.100 26.540 19.070 1.00 0.00 +ATOM 5012 HW2 HOH 1513 1.110 25.610 19.730 1.00 0.00 +ATOM 5013 OW HOH 1514 44.640 30.860 21.100 1.00 0.00 +ATOM 5014 HW1 HOH 1514 44.580 31.800 21.270 1.00 0.00 +ATOM 5015 HW2 HOH 1514 44.620 30.460 21.970 1.00 0.00 +ATOM 5016 OW HOH 1515 18.340 26.370 37.500 1.00 0.00 +ATOM 5017 HW1 HOH 1515 18.600 26.640 36.620 1.00 0.00 +ATOM 5018 HW2 HOH 1515 19.150 26.050 37.900 1.00 0.00 +ATOM 5019 OW HOH 1516 34.660 16.960 17.390 1.00 0.00 +ATOM 5020 HW1 HOH 1516 35.540 17.230 17.650 1.00 0.00 +ATOM 5021 HW2 HOH 1516 34.340 17.680 16.850 1.00 0.00 +ATOM 5022 OW HOH 1517 -0.010 44.750 30.520 1.00 0.00 +ATOM 5023 HW1 HOH 1517 -0.210 44.530 31.430 1.00 0.00 +ATOM 5024 HW2 HOH 1517 0.800 44.280 30.330 1.00 0.00 +ATOM 5025 OW HOH 1518 21.450 45.790 14.330 1.00 0.00 +ATOM 5026 HW1 HOH 1518 21.890 45.750 15.180 1.00 0.00 +ATOM 5027 HW2 HOH 1518 21.560 44.920 13.960 1.00 0.00 +ATOM 5028 OW HOH 1519 39.540 28.820 34.660 1.00 0.00 +ATOM 5029 HW1 HOH 1519 40.490 28.730 34.650 1.00 0.00 +ATOM 5030 HW2 HOH 1519 39.320 28.930 35.590 1.00 0.00 +ATOM 5031 OW HOH 1520 39.730 43.300 22.560 1.00 0.00 +ATOM 5032 HW1 HOH 1520 40.590 43.190 22.960 1.00 0.00 +ATOM 5033 HW2 HOH 1520 39.160 43.560 23.280 1.00 0.00 +ATOM 5034 OW HOH 1521 31.960 15.460 4.580 1.00 0.00 +ATOM 5035 HW1 HOH 1521 32.620 14.790 4.700 1.00 0.00 +ATOM 5036 HW2 HOH 1521 31.300 15.280 5.250 1.00 0.00 +ATOM 5037 OW HOH 1522 5.060 13.880 13.310 1.00 0.00 +ATOM 5038 HW1 HOH 1522 5.090 12.930 13.460 1.00 0.00 +ATOM 5039 HW2 HOH 1522 4.130 14.070 13.170 1.00 0.00 +ATOM 5040 OW HOH 1523 40.030 35.570 28.730 1.00 0.00 +ATOM 5041 HW1 HOH 1523 39.700 35.270 27.880 1.00 0.00 +ATOM 5042 HW2 HOH 1523 39.450 35.150 29.370 1.00 0.00 +ATOM 5043 OW HOH 1524 30.870 42.610 16.670 1.00 0.00 +ATOM 5044 HW1 HOH 1524 31.660 42.100 16.550 1.00 0.00 +ATOM 5045 HW2 HOH 1524 30.660 42.930 15.790 1.00 0.00 +ATOM 5046 OW HOH 1525 40.780 13.520 17.780 1.00 0.00 +ATOM 5047 HW1 HOH 1525 41.480 12.870 17.830 1.00 0.00 +ATOM 5048 HW2 HOH 1525 40.020 13.040 17.470 1.00 0.00 +ATOM 5049 OW HOH 1526 12.190 33.600 12.320 1.00 0.00 +ATOM 5050 HW1 HOH 1526 11.300 33.740 12.000 1.00 0.00 +ATOM 5051 HW2 HOH 1526 12.560 32.940 11.730 1.00 0.00 +ATOM 5052 OW HOH 1527 35.200 29.100 31.970 1.00 0.00 +ATOM 5053 HW1 HOH 1527 35.760 29.720 31.500 1.00 0.00 +ATOM 5054 HW2 HOH 1527 34.310 29.370 31.760 1.00 0.00 +ATOM 5055 OW HOH 1528 41.450 8.880 7.870 1.00 0.00 +ATOM 5056 HW1 HOH 1528 40.660 8.510 8.260 1.00 0.00 +ATOM 5057 HW2 HOH 1528 41.360 9.830 8.020 1.00 0.00 +ATOM 5058 OW HOH 1529 45.380 1.220 32.430 1.00 0.00 +ATOM 5059 HW1 HOH 1529 45.540 0.970 31.520 1.00 0.00 +ATOM 5060 HW2 HOH 1529 45.920 2.010 32.560 1.00 0.00 +ATOM 5061 OW HOH 1530 33.140 29.630 34.880 1.00 0.00 +ATOM 5062 HW1 HOH 1530 33.060 30.180 34.100 1.00 0.00 +ATOM 5063 HW2 HOH 1530 33.680 30.140 35.480 1.00 0.00 +ATOM 5064 OW HOH 1531 46.080 33.110 3.260 1.00 0.00 +ATOM 5065 HW1 HOH 1531 45.620 33.800 3.750 1.00 0.00 +ATOM 5066 HW2 HOH 1531 46.490 33.570 2.530 1.00 0.00 +ATOM 5067 OW HOH 1532 9.780 10.810 4.470 1.00 0.00 +ATOM 5068 HW1 HOH 1532 9.870 11.430 5.210 1.00 0.00 +ATOM 5069 HW2 HOH 1532 10.590 10.910 3.970 1.00 0.00 +ATOM 5070 OW HOH 1533 28.280 16.630 5.590 1.00 0.00 +ATOM 5071 HW1 HOH 1533 29.030 16.140 5.920 1.00 0.00 +ATOM 5072 HW2 HOH 1533 27.600 16.520 6.260 1.00 0.00 +ATOM 5073 OW HOH 1534 10.230 16.540 16.930 1.00 0.00 +ATOM 5074 HW1 HOH 1534 9.700 15.740 17.000 1.00 0.00 +ATOM 5075 HW2 HOH 1534 10.820 16.490 17.680 1.00 0.00 +ATOM 5076 OW HOH 1535 28.360 23.210 32.490 1.00 0.00 +ATOM 5077 HW1 HOH 1535 29.170 23.490 32.070 1.00 0.00 +ATOM 5078 HW2 HOH 1535 27.790 22.940 31.760 1.00 0.00 +ATOM 5079 OW HOH 1536 31.320 38.560 32.180 1.00 0.00 +ATOM 5080 HW1 HOH 1536 31.650 39.430 31.940 1.00 0.00 +ATOM 5081 HW2 HOH 1536 32.070 37.980 32.100 1.00 0.00 +ATOM 5082 OW HOH 1537 19.560 42.290 33.980 1.00 0.00 +ATOM 5083 HW1 HOH 1537 20.380 41.970 33.610 1.00 0.00 +ATOM 5084 HW2 HOH 1537 19.460 41.790 34.800 1.00 0.00 +ATOM 5085 OW HOH 1538 28.140 39.210 22.620 1.00 0.00 +ATOM 5086 HW1 HOH 1538 28.980 39.440 22.220 1.00 0.00 +ATOM 5087 HW2 HOH 1538 27.970 39.900 23.250 1.00 0.00 +ATOM 5088 OW HOH 1539 4.240 45.190 21.940 1.00 0.00 +ATOM 5089 HW1 HOH 1539 4.680 44.410 21.610 1.00 0.00 +ATOM 5090 HW2 HOH 1539 4.840 45.910 21.770 1.00 0.00 +ATOM 5091 OW HOH 1540 20.770 18.670 6.780 1.00 0.00 +ATOM 5092 HW1 HOH 1540 19.930 18.230 6.590 1.00 0.00 +ATOM 5093 HW2 HOH 1540 20.760 18.780 7.730 1.00 0.00 +ATOM 5094 OW HOH 1541 47.200 9.890 15.650 1.00 0.00 +ATOM 5095 HW1 HOH 1541 47.510 9.300 16.340 1.00 0.00 +ATOM 5096 HW2 HOH 1541 46.370 10.230 15.990 1.00 0.00 +ATOM 5097 OW HOH 1542 23.450 14.980 32.050 1.00 0.00 +ATOM 5098 HW1 HOH 1542 23.610 14.720 32.960 1.00 0.00 +ATOM 5099 HW2 HOH 1542 23.450 14.160 31.560 1.00 0.00 +ATOM 5100 OW HOH 1543 42.970 2.320 35.220 1.00 0.00 +ATOM 5101 HW1 HOH 1543 43.520 1.540 35.330 1.00 0.00 +ATOM 5102 HW2 HOH 1543 42.110 2.050 35.560 1.00 0.00 +ATOM 5103 OW HOH 1544 32.450 6.290 0.390 1.00 0.00 +ATOM 5104 HW1 HOH 1544 32.020 5.800 -0.310 1.00 0.00 +ATOM 5105 HW2 HOH 1544 31.940 7.100 0.460 1.00 0.00 +ATOM 5106 OW HOH 1545 32.600 22.640 28.050 1.00 0.00 +ATOM 5107 HW1 HOH 1545 32.730 23.240 28.790 1.00 0.00 +ATOM 5108 HW2 HOH 1545 31.650 22.600 27.940 1.00 0.00 +ATOM 5109 OW HOH 1546 25.580 0.830 6.660 1.00 0.00 +ATOM 5110 HW1 HOH 1546 25.090 1.330 6.010 1.00 0.00 +ATOM 5111 HW2 HOH 1546 26.010 1.490 7.210 1.00 0.00 +ATOM 5112 OW HOH 1547 33.180 31.000 7.170 1.00 0.00 +ATOM 5113 HW1 HOH 1547 32.220 31.010 7.180 1.00 0.00 +ATOM 5114 HW2 HOH 1547 33.430 31.670 7.810 1.00 0.00 +ATOM 5115 OW HOH 1548 12.420 17.330 22.300 1.00 0.00 +ATOM 5116 HW1 HOH 1548 12.740 18.230 22.270 1.00 0.00 +ATOM 5117 HW2 HOH 1548 12.290 17.090 21.380 1.00 0.00 +ATOM 5118 OW HOH 1549 11.440 26.980 22.080 1.00 0.00 +ATOM 5119 HW1 HOH 1549 11.560 27.420 21.240 1.00 0.00 +ATOM 5120 HW2 HOH 1549 11.120 26.110 21.860 1.00 0.00 +ATOM 5121 OW HOH 1550 38.770 0.910 11.720 1.00 0.00 +ATOM 5122 HW1 HOH 1550 39.400 0.850 11.010 1.00 0.00 +ATOM 5123 HW2 HOH 1550 39.170 1.520 12.350 1.00 0.00 +ATOM 5124 OW HOH 1551 37.350 8.800 6.090 1.00 0.00 +ATOM 5125 HW1 HOH 1551 38.120 8.410 5.680 1.00 0.00 +ATOM 5126 HW2 HOH 1551 37.490 8.690 7.030 1.00 0.00 +ATOM 5127 OW HOH 1552 28.100 1.090 10.060 1.00 0.00 +ATOM 5128 HW1 HOH 1552 27.890 1.570 10.860 1.00 0.00 +ATOM 5129 HW2 HOH 1552 28.830 1.580 9.670 1.00 0.00 +ATOM 5130 OW HOH 1553 1.780 -0.220 9.800 1.00 0.00 +ATOM 5131 HW1 HOH 1553 0.840 -0.340 9.940 1.00 0.00 +ATOM 5132 HW2 HOH 1553 1.980 0.640 10.170 1.00 0.00 +ATOM 5133 OW HOH 1554 12.050 29.690 38.040 1.00 0.00 +ATOM 5134 HW1 HOH 1554 11.830 28.770 38.150 1.00 0.00 +ATOM 5135 HW2 HOH 1554 11.820 30.090 38.890 1.00 0.00 +ATOM 5136 OW HOH 1555 15.650 3.170 17.360 1.00 0.00 +ATOM 5137 HW1 HOH 1555 15.000 2.480 17.220 1.00 0.00 +ATOM 5138 HW2 HOH 1555 15.150 3.980 17.400 1.00 0.00 +ATOM 5139 OW HOH 1556 4.130 39.920 8.700 1.00 0.00 +ATOM 5140 HW1 HOH 1556 4.720 40.660 8.840 1.00 0.00 +ATOM 5141 HW2 HOH 1556 3.290 40.220 9.030 1.00 0.00 +ATOM 5142 OW HOH 1557 5.930 45.170 37.700 1.00 0.00 +ATOM 5143 HW1 HOH 1557 5.430 44.510 37.220 1.00 0.00 +ATOM 5144 HW2 HOH 1557 6.780 44.760 37.860 1.00 0.00 +ATOM 5145 OW HOH 1558 19.420 8.430 11.290 1.00 0.00 +ATOM 5146 HW1 HOH 1558 18.980 9.280 11.190 1.00 0.00 +ATOM 5147 HW2 HOH 1558 20.280 8.550 10.890 1.00 0.00 +ATOM 5148 OW HOH 1559 13.880 10.770 26.640 1.00 0.00 +ATOM 5149 HW1 HOH 1559 13.960 10.010 27.220 1.00 0.00 +ATOM 5150 HW2 HOH 1559 14.680 11.280 26.810 1.00 0.00 +ATOM 5151 OW HOH 1560 37.230 24.160 7.640 1.00 0.00 +ATOM 5152 HW1 HOH 1560 36.850 24.600 6.880 1.00 0.00 +ATOM 5153 HW2 HOH 1560 36.900 23.260 7.590 1.00 0.00 +ATOM 5154 OW HOH 1561 46.450 22.170 8.070 1.00 0.00 +ATOM 5155 HW1 HOH 1561 47.300 21.910 7.720 1.00 0.00 +ATOM 5156 HW2 HOH 1561 46.470 21.850 8.980 1.00 0.00 +ATOM 5157 OW HOH 1562 0.190 23.500 26.650 1.00 0.00 +ATOM 5158 HW1 HOH 1562 -0.100 24.210 26.080 1.00 0.00 +ATOM 5159 HW2 HOH 1562 1.010 23.200 26.270 1.00 0.00 +ATOM 5160 OW HOH 1563 9.040 6.810 27.100 1.00 0.00 +ATOM 5161 HW1 HOH 1563 9.970 6.990 27.280 1.00 0.00 +ATOM 5162 HW2 HOH 1563 9.030 6.370 26.260 1.00 0.00 +ATOM 5163 OW HOH 1564 1.070 11.300 32.950 1.00 0.00 +ATOM 5164 HW1 HOH 1564 1.370 10.710 33.640 1.00 0.00 +ATOM 5165 HW2 HOH 1564 1.850 11.480 32.430 1.00 0.00 +ATOM 5166 OW HOH 1565 16.940 39.000 17.910 1.00 0.00 +ATOM 5167 HW1 HOH 1565 17.750 39.510 17.960 1.00 0.00 +ATOM 5168 HW2 HOH 1565 17.160 38.250 17.370 1.00 0.00 +ATOM 5169 OW HOH 1566 33.250 42.520 8.470 1.00 0.00 +ATOM 5170 HW1 HOH 1566 32.440 42.530 7.960 1.00 0.00 +ATOM 5171 HW2 HOH 1566 33.780 43.230 8.100 1.00 0.00 +ATOM 5172 OW HOH 1567 46.210 12.030 20.160 1.00 0.00 +ATOM 5173 HW1 HOH 1567 46.230 11.300 19.540 1.00 0.00 +ATOM 5174 HW2 HOH 1567 46.250 11.620 21.020 1.00 0.00 +ATOM 5175 OW HOH 1568 6.440 6.740 31.850 1.00 0.00 +ATOM 5176 HW1 HOH 1568 6.470 6.290 31.010 1.00 0.00 +ATOM 5177 HW2 HOH 1568 5.740 6.310 32.330 1.00 0.00 +ATOM 5178 OW HOH 1569 13.480 6.900 23.070 1.00 0.00 +ATOM 5179 HW1 HOH 1569 13.260 7.720 22.640 1.00 0.00 +ATOM 5180 HW2 HOH 1569 14.430 6.960 23.220 1.00 0.00 +ATOM 5181 OW HOH 1570 18.700 30.460 38.570 1.00 0.00 +ATOM 5182 HW1 HOH 1570 17.870 30.050 38.330 1.00 0.00 +ATOM 5183 HW2 HOH 1570 18.570 30.760 39.470 1.00 0.00 +ATOM 5184 OW HOH 1571 0.160 32.560 38.350 1.00 0.00 +ATOM 5185 HW1 HOH 1571 0.870 33.150 38.620 1.00 0.00 +ATOM 5186 HW2 HOH 1571 0.110 31.900 39.030 1.00 0.00 +ATOM 5187 OW HOH 1572 45.120 1.270 22.400 1.00 0.00 +ATOM 5188 HW1 HOH 1572 45.780 1.180 21.710 1.00 0.00 +ATOM 5189 HW2 HOH 1572 45.380 2.070 22.870 1.00 0.00 +ATOM 5190 OW HOH 1573 17.430 4.720 30.990 1.00 0.00 +ATOM 5191 HW1 HOH 1573 18.370 4.680 30.840 1.00 0.00 +ATOM 5192 HW2 HOH 1573 17.340 4.810 31.930 1.00 0.00 +ATOM 5193 OW HOH 1574 35.050 41.440 23.460 1.00 0.00 +ATOM 5194 HW1 HOH 1574 35.140 41.300 24.400 1.00 0.00 +ATOM 5195 HW2 HOH 1574 35.720 40.890 23.060 1.00 0.00 +ATOM 5196 OW HOH 1575 33.810 19.120 15.850 1.00 0.00 +ATOM 5197 HW1 HOH 1575 32.950 19.180 15.440 1.00 0.00 +ATOM 5198 HW2 HOH 1575 34.370 18.740 15.180 1.00 0.00 +ATOM 5199 OW HOH 1576 34.320 42.940 29.240 1.00 0.00 +ATOM 5200 HW1 HOH 1576 33.400 42.800 29.030 1.00 0.00 +ATOM 5201 HW2 HOH 1576 34.590 43.650 28.640 1.00 0.00 +ATOM 5202 OW HOH 1577 11.160 14.780 39.050 1.00 0.00 +ATOM 5203 HW1 HOH 1577 12.040 15.080 38.830 1.00 0.00 +ATOM 5204 HW2 HOH 1577 10.570 15.330 38.530 1.00 0.00 +ATOM 5205 OW HOH 1578 4.570 24.520 1.390 1.00 0.00 +ATOM 5206 HW1 HOH 1578 4.870 25.340 1.000 1.00 0.00 +ATOM 5207 HW2 HOH 1578 4.470 23.920 0.650 1.00 0.00 +ATOM 5208 OW HOH 1579 19.520 45.450 36.850 1.00 0.00 +ATOM 5209 HW1 HOH 1579 19.790 45.170 35.980 1.00 0.00 +ATOM 5210 HW2 HOH 1579 20.140 46.140 37.090 1.00 0.00 +ATOM 5211 OW HOH 1580 44.270 6.310 19.490 1.00 0.00 +ATOM 5212 HW1 HOH 1580 44.070 5.480 19.900 1.00 0.00 +ATOM 5213 HW2 HOH 1580 45.140 6.550 19.830 1.00 0.00 +ATOM 5214 OW HOH 1581 44.290 16.700 0.520 1.00 0.00 +ATOM 5215 HW1 HOH 1581 45.240 16.620 0.450 1.00 0.00 +ATOM 5216 HW2 HOH 1581 44.140 17.180 1.330 1.00 0.00 +ATOM 5217 OW HOH 1582 29.920 44.680 14.830 1.00 0.00 +ATOM 5218 HW1 HOH 1582 30.810 44.920 15.110 1.00 0.00 +ATOM 5219 HW2 HOH 1582 30.060 44.100 14.080 1.00 0.00 +ATOM 5220 OW HOH 1583 16.200 6.390 22.970 1.00 0.00 +ATOM 5221 HW1 HOH 1583 16.250 5.710 23.640 1.00 0.00 +ATOM 5222 HW2 HOH 1583 16.990 6.920 23.100 1.00 0.00 +ATOM 5223 OW HOH 1584 32.370 29.030 4.660 1.00 0.00 +ATOM 5224 HW1 HOH 1584 32.950 29.550 4.100 1.00 0.00 +ATOM 5225 HW2 HOH 1584 32.910 28.820 5.420 1.00 0.00 +ATOM 5226 OW HOH 1585 36.100 4.890 15.730 1.00 0.00 +ATOM 5227 HW1 HOH 1585 36.960 4.910 16.140 1.00 0.00 +ATOM 5228 HW2 HOH 1585 35.830 5.810 15.700 1.00 0.00 +ATOM 5229 OW HOH 1586 32.000 14.630 24.580 1.00 0.00 +ATOM 5230 HW1 HOH 1586 32.350 14.600 25.470 1.00 0.00 +ATOM 5231 HW2 HOH 1586 31.790 15.560 24.440 1.00 0.00 +ATOM 5232 OW HOH 1587 32.550 37.720 37.830 1.00 0.00 +ATOM 5233 HW1 HOH 1587 32.480 37.720 36.880 1.00 0.00 +ATOM 5234 HW2 HOH 1587 31.990 38.440 38.120 1.00 0.00 +ATOM 5235 OW HOH 1588 14.400 10.330 15.410 1.00 0.00 +ATOM 5236 HW1 HOH 1588 13.550 10.700 15.200 1.00 0.00 +ATOM 5237 HW2 HOH 1588 14.990 10.690 14.740 1.00 0.00 +ATOM 5238 OW HOH 1589 4.750 41.780 31.190 1.00 0.00 +ATOM 5239 HW1 HOH 1589 5.340 42.330 30.660 1.00 0.00 +ATOM 5240 HW2 HOH 1589 4.190 42.410 31.650 1.00 0.00 +ATOM 5241 OW HOH 1590 23.360 45.080 33.840 1.00 0.00 +ATOM 5242 HW1 HOH 1590 23.850 44.690 34.570 1.00 0.00 +ATOM 5243 HW2 HOH 1590 23.130 45.950 34.150 1.00 0.00 +ATOM 5244 OW HOH 1591 21.620 37.830 22.600 1.00 0.00 +ATOM 5245 HW1 HOH 1591 22.020 38.300 23.330 1.00 0.00 +ATOM 5246 HW2 HOH 1591 20.860 38.350 22.360 1.00 0.00 +ATOM 5247 OW HOH 1592 28.770 10.220 11.840 1.00 0.00 +ATOM 5248 HW1 HOH 1592 28.080 9.630 12.160 1.00 0.00 +ATOM 5249 HW2 HOH 1592 29.210 9.710 11.160 1.00 0.00 +ATOM 5250 OW HOH 1593 34.040 14.350 9.450 1.00 0.00 +ATOM 5251 HW1 HOH 1593 34.220 15.280 9.340 1.00 0.00 +ATOM 5252 HW2 HOH 1593 33.380 14.150 8.790 1.00 0.00 +ATOM 5253 OW HOH 1594 15.190 3.870 10.690 1.00 0.00 +ATOM 5254 HW1 HOH 1594 14.820 3.420 9.930 1.00 0.00 +ATOM 5255 HW2 HOH 1594 16.120 3.950 10.500 1.00 0.00 +ATOM 5256 OW HOH 1595 14.050 21.040 12.080 1.00 0.00 +ATOM 5257 HW1 HOH 1595 13.870 20.170 11.730 1.00 0.00 +ATOM 5258 HW2 HOH 1595 14.990 21.180 11.920 1.00 0.00 +ATOM 5259 OW HOH 1596 15.180 15.120 34.780 1.00 0.00 +ATOM 5260 HW1 HOH 1596 14.750 15.790 35.320 1.00 0.00 +ATOM 5261 HW2 HOH 1596 15.880 14.780 35.340 1.00 0.00 +ATOM 5262 OW HOH 1597 13.150 17.430 27.830 1.00 0.00 +ATOM 5263 HW1 HOH 1597 12.470 17.490 27.160 1.00 0.00 +ATOM 5264 HW2 HOH 1597 12.670 17.440 28.660 1.00 0.00 +ATOM 5265 OW HOH 1598 18.770 3.100 19.320 1.00 0.00 +ATOM 5266 HW1 HOH 1598 18.520 3.890 19.790 1.00 0.00 +ATOM 5267 HW2 HOH 1598 18.570 3.290 18.400 1.00 0.00 +ATOM 5268 OW HOH 1599 42.490 6.670 29.510 1.00 0.00 +ATOM 5269 HW1 HOH 1599 42.660 5.850 29.970 1.00 0.00 +ATOM 5270 HW2 HOH 1599 42.050 7.220 30.160 1.00 0.00 +ATOM 5271 OW HOH 1600 8.190 1.010 32.480 1.00 0.00 +ATOM 5272 HW1 HOH 1600 7.300 1.350 32.370 1.00 0.00 +ATOM 5273 HW2 HOH 1600 8.240 0.250 31.910 1.00 0.00 +ATOM 5274 OW HOH 1601 20.390 40.240 21.700 1.00 0.00 +ATOM 5275 HW1 HOH 1601 19.560 39.900 22.060 1.00 0.00 +ATOM 5276 HW2 HOH 1601 20.560 41.040 22.190 1.00 0.00 +ATOM 5277 OW HOH 1602 28.270 32.790 15.750 1.00 0.00 +ATOM 5278 HW1 HOH 1602 27.660 33.500 15.570 1.00 0.00 +ATOM 5279 HW2 HOH 1602 28.850 33.140 16.420 1.00 0.00 +ATOM 5280 OW HOH 1603 3.630 33.820 18.440 1.00 0.00 +ATOM 5281 HW1 HOH 1603 3.380 34.410 17.730 1.00 0.00 +ATOM 5282 HW2 HOH 1603 4.590 33.870 18.470 1.00 0.00 +ATOM 5283 OW HOH 1604 34.720 38.380 4.550 1.00 0.00 +ATOM 5284 HW1 HOH 1604 34.620 38.320 3.600 1.00 0.00 +ATOM 5285 HW2 HOH 1604 35.050 37.530 4.810 1.00 0.00 +ATOM 5286 OW HOH 1605 40.940 34.540 37.440 1.00 0.00 +ATOM 5287 HW1 HOH 1605 40.890 33.590 37.390 1.00 0.00 +ATOM 5288 HW2 HOH 1605 40.040 34.830 37.300 1.00 0.00 +ATOM 5289 OW HOH 1606 33.490 41.810 15.720 1.00 0.00 +ATOM 5290 HW1 HOH 1606 34.170 42.050 15.090 1.00 0.00 +ATOM 5291 HW2 HOH 1606 33.160 40.970 15.410 1.00 0.00 +ATOM 5292 OW HOH 1607 9.240 11.020 17.320 1.00 0.00 +ATOM 5293 HW1 HOH 1607 9.730 11.060 16.500 1.00 0.00 +ATOM 5294 HW2 HOH 1607 8.600 10.320 17.190 1.00 0.00 +ATOM 5295 OW HOH 1608 3.180 38.920 17.120 1.00 0.00 +ATOM 5296 HW1 HOH 1608 3.010 38.000 17.310 1.00 0.00 +ATOM 5297 HW2 HOH 1608 2.570 39.400 17.680 1.00 0.00 +ATOM 5298 OW HOH 1609 20.820 13.540 28.390 1.00 0.00 +ATOM 5299 HW1 HOH 1609 21.500 12.880 28.460 1.00 0.00 +ATOM 5300 HW2 HOH 1609 20.470 13.630 29.280 1.00 0.00 +ATOM 5301 OW HOH 1610 29.440 25.030 4.900 1.00 0.00 +ATOM 5302 HW1 HOH 1610 29.550 25.970 4.810 1.00 0.00 +ATOM 5303 HW2 HOH 1610 28.990 24.920 5.740 1.00 0.00 +ATOM 5304 OW HOH 1611 10.450 21.750 37.610 1.00 0.00 +ATOM 5305 HW1 HOH 1611 10.750 20.850 37.740 1.00 0.00 +ATOM 5306 HW2 HOH 1611 9.950 21.950 38.400 1.00 0.00 +ATOM 5307 OW HOH 1612 34.290 27.450 38.690 1.00 0.00 +ATOM 5308 HW1 HOH 1612 34.980 27.030 39.210 1.00 0.00 +ATOM 5309 HW2 HOH 1612 34.710 27.650 37.850 1.00 0.00 +ATOM 5310 OW HOH 1613 48.280 29.660 5.020 1.00 0.00 +ATOM 5311 HW1 HOH 1613 47.450 29.200 5.100 1.00 0.00 +ATOM 5312 HW2 HOH 1613 48.700 29.260 4.260 1.00 0.00 +ATOM 5313 OW HOH 1614 40.450 32.920 17.140 1.00 0.00 +ATOM 5314 HW1 HOH 1614 40.150 33.450 17.880 1.00 0.00 +ATOM 5315 HW2 HOH 1614 41.300 33.290 16.910 1.00 0.00 +ATOM 5316 OW HOH 1615 28.680 9.730 28.040 1.00 0.00 +ATOM 5317 HW1 HOH 1615 28.640 10.680 28.170 1.00 0.00 +ATOM 5318 HW2 HOH 1615 27.980 9.550 27.400 1.00 0.00 +ATOM 5319 OW HOH 1616 12.690 45.090 33.010 1.00 0.00 +ATOM 5320 HW1 HOH 1616 13.280 44.330 33.010 1.00 0.00 +ATOM 5321 HW2 HOH 1616 13.200 45.800 33.400 1.00 0.00 +ATOM 5322 OW HOH 1617 34.710 40.890 1.860 1.00 0.00 +ATOM 5323 HW1 HOH 1617 35.270 40.540 2.550 1.00 0.00 +ATOM 5324 HW2 HOH 1617 35.310 41.110 1.150 1.00 0.00 +ATOM 5325 OW HOH 1618 23.680 23.350 32.320 1.00 0.00 +ATOM 5326 HW1 HOH 1618 22.790 23.090 32.560 1.00 0.00 +ATOM 5327 HW2 HOH 1618 24.230 22.930 32.980 1.00 0.00 +ATOM 5328 OW HOH 1619 14.580 45.620 16.520 1.00 0.00 +ATOM 5329 HW1 HOH 1619 15.190 45.940 15.850 1.00 0.00 +ATOM 5330 HW2 HOH 1619 13.850 46.230 16.490 1.00 0.00 +ATOM 5331 OW HOH 1620 20.290 14.800 5.260 1.00 0.00 +ATOM 5332 HW1 HOH 1620 20.490 14.770 4.320 1.00 0.00 +ATOM 5333 HW2 HOH 1620 19.900 15.660 5.390 1.00 0.00 +ATOM 5334 OW HOH 1621 2.340 0.640 5.600 1.00 0.00 +ATOM 5335 HW1 HOH 1621 3.020 0.490 4.940 1.00 0.00 +ATOM 5336 HW2 HOH 1621 2.340 1.590 5.740 1.00 0.00 +ATOM 5337 OW HOH 1622 34.720 16.760 1.230 1.00 0.00 +ATOM 5338 HW1 HOH 1622 35.450 17.300 0.910 1.00 0.00 +ATOM 5339 HW2 HOH 1622 34.590 16.100 0.550 1.00 0.00 +ATOM 5340 OW HOH 1623 38.660 22.870 10.840 1.00 0.00 +ATOM 5341 HW1 HOH 1623 39.250 22.710 10.110 1.00 0.00 +ATOM 5342 HW2 HOH 1623 37.810 22.520 10.550 1.00 0.00 +ATOM 5343 OW HOH 1624 14.200 10.140 7.300 1.00 0.00 +ATOM 5344 HW1 HOH 1624 14.430 10.540 6.460 1.00 0.00 +ATOM 5345 HW2 HOH 1624 13.270 10.320 7.400 1.00 0.00 +ATOM 5346 OW HOH 1625 11.720 18.870 12.020 1.00 0.00 +ATOM 5347 HW1 HOH 1625 12.420 18.440 11.530 1.00 0.00 +ATOM 5348 HW2 HOH 1625 11.680 18.390 12.850 1.00 0.00 +ATOM 5349 OW HOH 1626 23.130 9.190 20.530 1.00 0.00 +ATOM 5350 HW1 HOH 1626 23.980 8.890 20.220 1.00 0.00 +ATOM 5351 HW2 HOH 1626 23.010 8.750 21.370 1.00 0.00 +ATOM 5352 OW HOH 1627 12.290 11.290 3.550 1.00 0.00 +ATOM 5353 HW1 HOH 1627 12.410 10.590 4.190 1.00 0.00 +ATOM 5354 HW2 HOH 1627 13.170 11.650 3.420 1.00 0.00 +ATOM 5355 OW HOH 1628 40.130 42.820 2.350 1.00 0.00 +ATOM 5356 HW1 HOH 1628 41.040 43.090 2.240 1.00 0.00 +ATOM 5357 HW2 HOH 1628 40.100 41.930 2.010 1.00 0.00 +ATOM 5358 OW HOH 1629 43.590 1.150 10.980 1.00 0.00 +ATOM 5359 HW1 HOH 1629 44.550 1.090 11.060 1.00 0.00 +ATOM 5360 HW2 HOH 1629 43.390 2.050 11.200 1.00 0.00 +ATOM 5361 OW HOH 1630 38.420 22.640 29.170 1.00 0.00 +ATOM 5362 HW1 HOH 1630 39.050 23.300 28.910 1.00 0.00 +ATOM 5363 HW2 HOH 1630 37.970 22.400 28.360 1.00 0.00 +ATOM 5364 OW HOH 1631 0.860 1.930 31.900 1.00 0.00 +ATOM 5365 HW1 HOH 1631 0.170 1.980 31.240 1.00 0.00 +ATOM 5366 HW2 HOH 1631 0.440 1.600 32.680 1.00 0.00 +ATOM 5367 OW HOH 1632 33.410 23.420 4.030 1.00 0.00 +ATOM 5368 HW1 HOH 1632 34.240 22.940 4.090 1.00 0.00 +ATOM 5369 HW2 HOH 1632 32.850 22.860 3.490 1.00 0.00 +ATOM 5370 OW HOH 1633 36.600 -0.060 13.140 1.00 0.00 +ATOM 5371 HW1 HOH 1633 36.640 0.810 13.530 1.00 0.00 +ATOM 5372 HW2 HOH 1633 37.390 -0.110 12.590 1.00 0.00 +ATOM 5373 OW HOH 1634 46.970 43.600 15.030 1.00 0.00 +ATOM 5374 HW1 HOH 1634 47.630 43.720 14.340 1.00 0.00 +ATOM 5375 HW2 HOH 1634 46.980 44.430 15.510 1.00 0.00 +ATOM 5376 OW HOH 1635 34.150 36.740 14.640 1.00 0.00 +ATOM 5377 HW1 HOH 1635 34.520 37.420 15.200 1.00 0.00 +ATOM 5378 HW2 HOH 1635 33.880 36.050 15.250 1.00 0.00 +ATOM 5379 OW HOH 1636 48.440 9.710 13.170 1.00 0.00 +ATOM 5380 HW1 HOH 1636 47.990 9.970 13.970 1.00 0.00 +ATOM 5381 HW2 HOH 1636 48.540 10.530 12.680 1.00 0.00 +ATOM 5382 OW HOH 1637 43.430 4.700 33.630 1.00 0.00 +ATOM 5383 HW1 HOH 1637 43.110 5.490 34.080 1.00 0.00 +ATOM 5384 HW2 HOH 1637 43.150 3.980 34.200 1.00 0.00 +ATOM 5385 OW HOH 1638 27.660 28.770 37.520 1.00 0.00 +ATOM 5386 HW1 HOH 1638 27.770 29.370 36.780 1.00 0.00 +ATOM 5387 HW2 HOH 1638 27.010 28.130 37.220 1.00 0.00 +ATOM 5388 OW HOH 1639 9.230 27.110 24.220 1.00 0.00 +ATOM 5389 HW1 HOH 1639 8.320 26.980 23.980 1.00 0.00 +ATOM 5390 HW2 HOH 1639 9.730 26.730 23.500 1.00 0.00 +ATOM 5391 OW HOH 1640 47.100 15.770 32.390 1.00 0.00 +ATOM 5392 HW1 HOH 1640 46.860 16.650 32.080 1.00 0.00 +ATOM 5393 HW2 HOH 1640 46.350 15.480 32.900 1.00 0.00 +ATOM 5394 OW HOH 1641 8.300 41.430 25.710 1.00 0.00 +ATOM 5395 HW1 HOH 1641 8.010 42.180 25.190 1.00 0.00 +ATOM 5396 HW2 HOH 1641 8.690 40.830 25.070 1.00 0.00 +ATOM 5397 OW HOH 1642 28.900 30.130 14.750 1.00 0.00 +ATOM 5398 HW1 HOH 1642 28.770 31.050 15.000 1.00 0.00 +ATOM 5399 HW2 HOH 1642 28.080 29.700 15.000 1.00 0.00 +ATOM 5400 OW HOH 1643 10.230 15.530 27.430 1.00 0.00 +ATOM 5401 HW1 HOH 1643 9.440 15.770 26.950 1.00 0.00 +ATOM 5402 HW2 HOH 1643 10.780 15.080 26.790 1.00 0.00 +ATOM 5403 OW HOH 1644 0.750 17.830 23.260 1.00 0.00 +ATOM 5404 HW1 HOH 1644 1.690 17.960 23.280 1.00 0.00 +ATOM 5405 HW2 HOH 1644 0.610 17.210 22.540 1.00 0.00 +ATOM 5406 OW HOH 1645 28.810 36.820 6.130 1.00 0.00 +ATOM 5407 HW1 HOH 1645 29.150 36.840 7.030 1.00 0.00 +ATOM 5408 HW2 HOH 1645 27.870 36.910 6.220 1.00 0.00 +ATOM 5409 OW HOH 1646 0.500 25.060 0.960 1.00 0.00 +ATOM 5410 HW1 HOH 1646 -0.110 24.380 0.700 1.00 0.00 +ATOM 5411 HW2 HOH 1646 0.720 24.860 1.870 1.00 0.00 +ATOM 5412 OW HOH 1647 5.390 23.350 27.150 1.00 0.00 +ATOM 5413 HW1 HOH 1647 4.980 22.490 27.260 1.00 0.00 +ATOM 5414 HW2 HOH 1647 5.980 23.240 26.390 1.00 0.00 +ATOM 5415 OW HOH 1648 31.280 44.590 11.420 1.00 0.00 +ATOM 5416 HW1 HOH 1648 31.070 43.810 11.940 1.00 0.00 +ATOM 5417 HW2 HOH 1648 31.850 45.110 11.980 1.00 0.00 +ATOM 5418 OW HOH 1649 39.040 33.270 9.960 1.00 0.00 +ATOM 5419 HW1 HOH 1649 39.000 33.610 9.060 1.00 0.00 +ATOM 5420 HW2 HOH 1649 39.930 32.930 10.050 1.00 0.00 +ATOM 5421 OW HOH 1650 15.700 9.570 17.700 1.00 0.00 +ATOM 5422 HW1 HOH 1650 15.200 9.880 16.940 1.00 0.00 +ATOM 5423 HW2 HOH 1650 16.550 10.000 17.610 1.00 0.00 +ATOM 5424 OW HOH 1651 5.550 40.750 2.400 1.00 0.00 +ATOM 5425 HW1 HOH 1651 5.460 39.830 2.670 1.00 0.00 +ATOM 5426 HW2 HOH 1651 6.470 40.840 2.170 1.00 0.00 +ATOM 5427 OW HOH 1652 16.310 3.840 2.680 1.00 0.00 +ATOM 5428 HW1 HOH 1652 16.310 3.080 3.260 1.00 0.00 +ATOM 5429 HW2 HOH 1652 15.920 3.530 1.870 1.00 0.00 +ATOM 5430 OW HOH 1653 26.900 22.070 24.630 1.00 0.00 +ATOM 5431 HW1 HOH 1653 26.090 22.290 25.090 1.00 0.00 +ATOM 5432 HW2 HOH 1653 27.580 22.160 25.290 1.00 0.00 +ATOM 5433 OW HOH 1654 46.660 19.660 20.130 1.00 0.00 +ATOM 5434 HW1 HOH 1654 46.300 19.510 19.260 1.00 0.00 +ATOM 5435 HW2 HOH 1654 47.540 20.000 19.970 1.00 0.00 +ATOM 5436 OW HOH 1655 41.690 25.550 5.590 1.00 0.00 +ATOM 5437 HW1 HOH 1655 41.220 25.890 6.360 1.00 0.00 +ATOM 5438 HW2 HOH 1655 41.020 25.070 5.100 1.00 0.00 +ATOM 5439 OW HOH 1656 32.410 20.880 3.100 1.00 0.00 +ATOM 5440 HW1 HOH 1656 33.010 20.790 2.360 1.00 0.00 +ATOM 5441 HW2 HOH 1656 31.610 21.220 2.720 1.00 0.00 +ATOM 5442 OW HOH 1657 35.600 31.280 12.290 1.00 0.00 +ATOM 5443 HW1 HOH 1657 35.500 30.360 12.520 1.00 0.00 +ATOM 5444 HW2 HOH 1657 36.410 31.550 12.710 1.00 0.00 +ATOM 5445 OW HOH 1658 10.140 2.860 15.050 1.00 0.00 +ATOM 5446 HW1 HOH 1658 9.380 2.290 15.070 1.00 0.00 +ATOM 5447 HW2 HOH 1658 10.420 2.870 14.140 1.00 0.00 +ATOM 5448 OW HOH 1659 11.510 15.730 19.180 1.00 0.00 +ATOM 5449 HW1 HOH 1659 12.450 15.880 19.220 1.00 0.00 +ATOM 5450 HW2 HOH 1659 11.430 14.830 18.850 1.00 0.00 +ATOM 5451 OW HOH 1660 21.030 13.440 7.400 1.00 0.00 +ATOM 5452 HW1 HOH 1660 20.810 14.070 6.720 1.00 0.00 +ATOM 5453 HW2 HOH 1660 20.870 12.580 7.000 1.00 0.00 +ATOM 5454 OW HOH 1661 30.760 18.790 0.670 1.00 0.00 +ATOM 5455 HW1 HOH 1661 31.290 18.170 1.170 1.00 0.00 +ATOM 5456 HW2 HOH 1661 30.100 19.090 1.300 1.00 0.00 +ATOM 5457 OW HOH 1662 36.350 17.790 7.780 1.00 0.00 +ATOM 5458 HW1 HOH 1662 36.120 18.710 7.950 1.00 0.00 +ATOM 5459 HW2 HOH 1662 36.840 17.810 6.960 1.00 0.00 +ATOM 5460 OW HOH 1663 20.360 5.330 37.220 1.00 0.00 +ATOM 5461 HW1 HOH 1663 20.870 5.470 36.420 1.00 0.00 +ATOM 5462 HW2 HOH 1663 20.810 5.850 37.890 1.00 0.00 +ATOM 5463 OW HOH 1664 1.500 31.940 11.920 1.00 0.00 +ATOM 5464 HW1 HOH 1664 1.880 31.500 12.680 1.00 0.00 +ATOM 5465 HW2 HOH 1664 0.570 31.740 11.970 1.00 0.00 +ATOM 5466 OW HOH 1665 21.620 30.250 38.290 1.00 0.00 +ATOM 5467 HW1 HOH 1665 21.890 31.110 38.620 1.00 0.00 +ATOM 5468 HW2 HOH 1665 20.670 30.270 38.320 1.00 0.00 +ATOM 5469 OW HOH 1666 12.800 9.220 12.770 1.00 0.00 +ATOM 5470 HW1 HOH 1666 13.680 9.420 12.460 1.00 0.00 +ATOM 5471 HW2 HOH 1666 12.230 9.710 12.180 1.00 0.00 +ATOM 5472 OW HOH 1667 35.350 30.480 28.160 1.00 0.00 +ATOM 5473 HW1 HOH 1667 35.700 30.600 29.050 1.00 0.00 +ATOM 5474 HW2 HOH 1667 35.540 31.310 27.710 1.00 0.00 +ATOM 5475 OW HOH 1668 39.620 10.800 4.220 1.00 0.00 +ATOM 5476 HW1 HOH 1668 39.990 11.350 3.530 1.00 0.00 +ATOM 5477 HW2 HOH 1668 38.670 10.930 4.150 1.00 0.00 +ATOM 5478 OW HOH 1669 31.410 37.700 22.570 1.00 0.00 +ATOM 5479 HW1 HOH 1669 32.240 37.690 23.050 1.00 0.00 +ATOM 5480 HW2 HOH 1669 31.250 38.620 22.380 1.00 0.00 +ATOM 5481 OW HOH 1670 36.410 14.260 19.060 1.00 0.00 +ATOM 5482 HW1 HOH 1670 35.530 14.610 19.170 1.00 0.00 +ATOM 5483 HW2 HOH 1670 36.670 14.540 18.180 1.00 0.00 +ATOM 5484 OW HOH 1671 36.260 38.030 7.160 1.00 0.00 +ATOM 5485 HW1 HOH 1671 35.440 37.800 6.720 1.00 0.00 +ATOM 5486 HW2 HOH 1671 36.260 37.520 7.970 1.00 0.00 +ATOM 5487 OW HOH 1672 23.330 11.460 37.170 1.00 0.00 +ATOM 5488 HW1 HOH 1672 24.080 11.290 36.600 1.00 0.00 +ATOM 5489 HW2 HOH 1672 23.600 11.110 38.020 1.00 0.00 +ATOM 5490 OW HOH 1673 11.300 30.470 1.700 1.00 0.00 +ATOM 5491 HW1 HOH 1673 10.420 30.170 1.470 1.00 0.00 +ATOM 5492 HW2 HOH 1673 11.400 30.230 2.620 1.00 0.00 +ATOM 5493 OW HOH 1674 36.240 20.430 36.330 1.00 0.00 +ATOM 5494 HW1 HOH 1674 35.510 19.870 36.080 1.00 0.00 +ATOM 5495 HW2 HOH 1674 36.950 19.820 36.540 1.00 0.00 +ATOM 5496 OW HOH 1675 7.040 4.360 14.430 1.00 0.00 +ATOM 5497 HW1 HOH 1675 6.990 3.530 14.900 1.00 0.00 +ATOM 5498 HW2 HOH 1675 6.640 5.000 15.020 1.00 0.00 +ATOM 5499 OW HOH 1676 32.040 0.530 23.960 1.00 0.00 +ATOM 5500 HW1 HOH 1676 32.670 1.200 24.210 1.00 0.00 +ATOM 5501 HW2 HOH 1676 32.410 -0.280 24.310 1.00 0.00 +ATOM 5502 OW HOH 1677 0.920 37.820 3.770 1.00 0.00 +ATOM 5503 HW1 HOH 1677 0.760 37.140 4.430 1.00 0.00 +ATOM 5504 HW2 HOH 1677 1.820 38.100 3.930 1.00 0.00 +ATOM 5505 OW HOH 1678 33.760 45.680 6.050 1.00 0.00 +ATOM 5506 HW1 HOH 1678 34.040 45.000 5.440 1.00 0.00 +ATOM 5507 HW2 HOH 1678 34.290 45.550 6.830 1.00 0.00 +ATOM 5508 OW HOH 1679 25.670 2.070 23.710 1.00 0.00 +ATOM 5509 HW1 HOH 1679 26.330 2.100 24.410 1.00 0.00 +ATOM 5510 HW2 HOH 1679 26.180 1.930 22.920 1.00 0.00 +ATOM 5511 OW HOH 1680 5.650 32.520 30.280 1.00 0.00 +ATOM 5512 HW1 HOH 1680 6.490 32.130 30.540 1.00 0.00 +ATOM 5513 HW2 HOH 1680 5.320 31.930 29.590 1.00 0.00 +ATOM 5514 OW HOH 1681 11.410 9.990 10.270 1.00 0.00 +ATOM 5515 HW1 HOH 1681 11.500 9.930 9.320 1.00 0.00 +ATOM 5516 HW2 HOH 1681 11.740 10.860 10.490 1.00 0.00 +ATOM 5517 OW HOH 1682 43.430 16.320 5.160 1.00 0.00 +ATOM 5518 HW1 HOH 1682 42.580 16.000 4.860 1.00 0.00 +ATOM 5519 HW2 HOH 1682 44.030 15.600 4.980 1.00 0.00 +ATOM 5520 OW HOH 1683 47.970 26.590 3.900 1.00 0.00 +ATOM 5521 HW1 HOH 1683 47.510 26.670 3.070 1.00 0.00 +ATOM 5522 HW2 HOH 1683 48.550 25.840 3.780 1.00 0.00 +ATOM 5523 OW HOH 1684 44.760 20.210 11.910 1.00 0.00 +ATOM 5524 HW1 HOH 1684 45.030 19.790 11.090 1.00 0.00 +ATOM 5525 HW2 HOH 1684 44.800 21.150 11.720 1.00 0.00 +ATOM 5526 OW HOH 1685 13.210 21.030 0.960 1.00 0.00 +ATOM 5527 HW1 HOH 1685 13.590 21.660 0.340 1.00 0.00 +ATOM 5528 HW2 HOH 1685 12.950 20.290 0.420 1.00 0.00 +ATOM 5529 OW HOH 1686 14.640 43.000 32.470 1.00 0.00 +ATOM 5530 HW1 HOH 1686 14.130 42.220 32.240 1.00 0.00 +ATOM 5531 HW2 HOH 1686 14.990 42.800 33.340 1.00 0.00 +ATOM 5532 OW HOH 1687 40.010 24.230 15.070 1.00 0.00 +ATOM 5533 HW1 HOH 1687 39.640 24.930 15.610 1.00 0.00 +ATOM 5534 HW2 HOH 1687 40.850 24.030 15.490 1.00 0.00 +ATOM 5535 OW HOH 1688 31.530 23.550 8.670 1.00 0.00 +ATOM 5536 HW1 HOH 1688 31.670 24.110 9.430 1.00 0.00 +ATOM 5537 HW2 HOH 1688 32.410 23.410 8.310 1.00 0.00 +ATOM 5538 OW HOH 1689 18.230 4.000 16.770 1.00 0.00 +ATOM 5539 HW1 HOH 1689 18.110 3.570 15.920 1.00 0.00 +ATOM 5540 HW2 HOH 1689 17.360 3.990 17.170 1.00 0.00 +ATOM 5541 OW HOH 1690 32.780 17.710 27.710 1.00 0.00 +ATOM 5542 HW1 HOH 1690 32.260 18.510 27.780 1.00 0.00 +ATOM 5543 HW2 HOH 1690 33.070 17.530 28.610 1.00 0.00 +ATOM 5544 OW HOH 1691 4.220 5.620 27.330 1.00 0.00 +ATOM 5545 HW1 HOH 1691 3.890 6.510 27.290 1.00 0.00 +ATOM 5546 HW2 HOH 1691 4.840 5.620 28.060 1.00 0.00 +ATOM 5547 OW HOH 1692 25.910 11.350 22.330 1.00 0.00 +ATOM 5548 HW1 HOH 1692 26.610 10.720 22.500 1.00 0.00 +ATOM 5549 HW2 HOH 1692 25.960 11.520 21.390 1.00 0.00 +ATOM 5550 OW HOH 1693 38.250 5.290 30.660 1.00 0.00 +ATOM 5551 HW1 HOH 1693 39.050 5.360 31.180 1.00 0.00 +ATOM 5552 HW2 HOH 1693 38.550 4.930 29.820 1.00 0.00 +ATOM 5553 OW HOH 1694 37.500 1.270 35.740 1.00 0.00 +ATOM 5554 HW1 HOH 1694 37.620 0.330 35.650 1.00 0.00 +ATOM 5555 HW2 HOH 1694 37.880 1.470 36.590 1.00 0.00 +ATOM 5556 OW HOH 1695 46.980 35.250 1.800 1.00 0.00 +ATOM 5557 HW1 HOH 1695 46.650 35.550 0.960 1.00 0.00 +ATOM 5558 HW2 HOH 1695 47.030 36.040 2.340 1.00 0.00 +ATOM 5559 OW HOH 1696 5.350 19.260 13.040 1.00 0.00 +ATOM 5560 HW1 HOH 1696 5.240 19.630 12.170 1.00 0.00 +ATOM 5561 HW2 HOH 1696 4.550 18.740 13.170 1.00 0.00 +ATOM 5562 OW HOH 1697 0.470 5.100 16.620 1.00 0.00 +ATOM 5563 HW1 HOH 1697 1.190 4.570 16.270 1.00 0.00 +ATOM 5564 HW2 HOH 1697 0.240 4.670 17.450 1.00 0.00 +ATOM 5565 OW HOH 1698 9.040 28.580 5.150 1.00 0.00 +ATOM 5566 HW1 HOH 1698 9.570 29.040 4.510 1.00 0.00 +ATOM 5567 HW2 HOH 1698 8.140 28.800 4.910 1.00 0.00 +ATOM 5568 OW HOH 1699 47.950 40.700 19.440 1.00 0.00 +ATOM 5569 HW1 HOH 1699 48.490 40.420 20.180 1.00 0.00 +ATOM 5570 HW2 HOH 1699 47.170 41.100 19.840 1.00 0.00 +ATOM 5571 OW HOH 1700 21.970 3.560 24.280 1.00 0.00 +ATOM 5572 HW1 HOH 1700 21.980 2.800 23.700 1.00 0.00 +ATOM 5573 HW2 HOH 1700 22.570 4.180 23.870 1.00 0.00 +ATOM 5574 OW HOH 1701 28.890 42.850 32.150 1.00 0.00 +ATOM 5575 HW1 HOH 1701 29.680 42.330 31.990 1.00 0.00 +ATOM 5576 HW2 HOH 1701 28.190 42.200 32.170 1.00 0.00 +ATOM 5577 OW HOH 1702 16.890 10.780 9.600 1.00 0.00 +ATOM 5578 HW1 HOH 1702 15.940 10.700 9.470 1.00 0.00 +ATOM 5579 HW2 HOH 1702 16.980 11.260 10.430 1.00 0.00 +ATOM 5580 OW HOH 1703 27.380 21.120 4.490 1.00 0.00 +ATOM 5581 HW1 HOH 1703 27.260 20.280 4.940 1.00 0.00 +ATOM 5582 HW2 HOH 1703 26.650 21.170 3.870 1.00 0.00 +ATOM 5583 OW HOH 1704 8.490 20.490 6.820 1.00 0.00 +ATOM 5584 HW1 HOH 1704 9.350 20.200 6.520 1.00 0.00 +ATOM 5585 HW2 HOH 1704 7.900 20.290 6.090 1.00 0.00 +ATOM 5586 OW HOH 1705 36.560 32.400 21.790 1.00 0.00 +ATOM 5587 HW1 HOH 1705 36.070 32.080 21.040 1.00 0.00 +ATOM 5588 HW2 HOH 1705 36.460 31.710 22.450 1.00 0.00 +ATOM 5589 OW HOH 1706 4.530 40.720 27.120 1.00 0.00 +ATOM 5590 HW1 HOH 1706 5.260 41.290 26.890 1.00 0.00 +ATOM 5591 HW2 HOH 1706 3.820 41.330 27.360 1.00 0.00 +ATOM 5592 OW HOH 1707 23.230 14.960 1.160 1.00 0.00 +ATOM 5593 HW1 HOH 1707 23.870 14.270 1.370 1.00 0.00 +ATOM 5594 HW2 HOH 1707 23.770 15.720 0.940 1.00 0.00 +ATOM 5595 OW HOH 1708 9.480 42.110 34.880 1.00 0.00 +ATOM 5596 HW1 HOH 1708 8.560 42.280 35.050 1.00 0.00 +ATOM 5597 HW2 HOH 1708 9.730 41.430 35.510 1.00 0.00 +ATOM 5598 OW HOH 1709 22.910 2.540 11.280 1.00 0.00 +ATOM 5599 HW1 HOH 1709 22.680 2.810 12.170 1.00 0.00 +ATOM 5600 HW2 HOH 1709 23.570 1.860 11.400 1.00 0.00 +ATOM 5601 OW HOH 1710 19.020 13.810 9.860 1.00 0.00 +ATOM 5602 HW1 HOH 1710 19.200 14.630 10.310 1.00 0.00 +ATOM 5603 HW2 HOH 1710 19.870 13.510 9.540 1.00 0.00 +ATOM 5604 OW HOH 1711 16.190 19.710 8.940 1.00 0.00 +ATOM 5605 HW1 HOH 1711 17.030 20.090 8.690 1.00 0.00 +ATOM 5606 HW2 HOH 1711 15.580 20.010 8.270 1.00 0.00 +ATOM 5607 OW HOH 1712 7.230 7.150 9.680 1.00 0.00 +ATOM 5608 HW1 HOH 1712 7.130 6.690 10.520 1.00 0.00 +ATOM 5609 HW2 HOH 1712 7.420 6.450 9.050 1.00 0.00 +ATOM 5610 OW HOH 1713 44.290 38.880 17.220 1.00 0.00 +ATOM 5611 HW1 HOH 1713 43.850 39.660 16.880 1.00 0.00 +ATOM 5612 HW2 HOH 1713 45.220 39.110 17.210 1.00 0.00 +ATOM 5613 OW HOH 1714 30.320 12.550 18.590 1.00 0.00 +ATOM 5614 HW1 HOH 1714 30.390 11.590 18.580 1.00 0.00 +ATOM 5615 HW2 HOH 1714 29.860 12.750 19.410 1.00 0.00 +ATOM 5616 OW HOH 1715 48.360 41.180 15.570 1.00 0.00 +ATOM 5617 HW1 HOH 1715 47.800 41.860 15.210 1.00 0.00 +ATOM 5618 HW2 HOH 1715 48.900 41.630 16.220 1.00 0.00 +ATOM 5619 OW HOH 1716 1.400 13.730 20.310 1.00 0.00 +ATOM 5620 HW1 HOH 1716 2.220 13.710 20.810 1.00 0.00 +ATOM 5621 HW2 HOH 1716 1.610 13.270 19.500 1.00 0.00 +ATOM 5622 OW HOH 1717 43.580 42.670 14.600 1.00 0.00 +ATOM 5623 HW1 HOH 1717 43.380 43.110 13.780 1.00 0.00 +ATOM 5624 HW2 HOH 1717 44.480 42.370 14.510 1.00 0.00 +ATOM 5625 OW HOH 1718 43.930 23.290 30.420 1.00 0.00 +ATOM 5626 HW1 HOH 1718 44.410 22.630 29.930 1.00 0.00 +ATOM 5627 HW2 HOH 1718 43.550 22.820 31.160 1.00 0.00 +ATOM 5628 OW HOH 1719 13.430 4.120 15.160 1.00 0.00 +ATOM 5629 HW1 HOH 1719 12.810 4.210 14.440 1.00 0.00 +ATOM 5630 HW2 HOH 1719 14.270 4.380 14.790 1.00 0.00 +ATOM 5631 OW HOH 1720 39.690 31.220 15.280 1.00 0.00 +ATOM 5632 HW1 HOH 1720 40.490 30.870 14.890 1.00 0.00 +ATOM 5633 HW2 HOH 1720 40.000 31.880 15.900 1.00 0.00 +ATOM 5634 OW HOH 1721 32.330 5.750 30.690 1.00 0.00 +ATOM 5635 HW1 HOH 1721 33.240 5.470 30.550 1.00 0.00 +ATOM 5636 HW2 HOH 1721 32.370 6.700 30.690 1.00 0.00 +ATOM 5637 OW HOH 1722 37.490 7.140 19.170 1.00 0.00 +ATOM 5638 HW1 HOH 1722 37.960 7.910 19.500 1.00 0.00 +ATOM 5639 HW2 HOH 1722 36.990 6.820 19.920 1.00 0.00 +ATOM 5640 OW HOH 1723 4.380 10.810 2.170 1.00 0.00 +ATOM 5641 HW1 HOH 1723 4.570 10.560 3.080 1.00 0.00 +ATOM 5642 HW2 HOH 1723 5.230 11.010 1.790 1.00 0.00 +ATOM 5643 OW HOH 1724 6.820 34.560 28.140 1.00 0.00 +ATOM 5644 HW1 HOH 1724 7.230 34.760 28.980 1.00 0.00 +ATOM 5645 HW2 HOH 1724 7.060 33.650 27.970 1.00 0.00 +ATOM 5646 OW HOH 1725 18.830 17.060 5.780 1.00 0.00 +ATOM 5647 HW1 HOH 1725 18.330 16.760 6.530 1.00 0.00 +ATOM 5648 HW2 HOH 1725 18.320 17.790 5.420 1.00 0.00 +ATOM 5649 OW HOH 1726 41.240 21.610 8.180 1.00 0.00 +ATOM 5650 HW1 HOH 1726 42.130 21.430 7.890 1.00 0.00 +ATOM 5651 HW2 HOH 1726 40.680 21.280 7.480 1.00 0.00 +ATOM 5652 OW HOH 1727 30.380 9.560 9.650 1.00 0.00 +ATOM 5653 HW1 HOH 1727 30.300 8.990 8.880 1.00 0.00 +ATOM 5654 HW2 HOH 1727 31.150 10.100 9.470 1.00 0.00 +ATOM 5655 OW HOH 1728 28.920 10.220 18.050 1.00 0.00 +ATOM 5656 HW1 HOH 1728 28.860 9.610 18.790 1.00 0.00 +ATOM 5657 HW2 HOH 1728 29.600 9.850 17.490 1.00 0.00 +ATOM 5658 OW HOH 1729 38.880 7.760 33.870 1.00 0.00 +ATOM 5659 HW1 HOH 1729 38.270 7.200 34.360 1.00 0.00 +ATOM 5660 HW2 HOH 1729 38.790 8.620 34.290 1.00 0.00 +ATOM 5661 OW HOH 1730 4.430 16.980 30.690 1.00 0.00 +ATOM 5662 HW1 HOH 1730 3.580 17.410 30.720 1.00 0.00 +ATOM 5663 HW2 HOH 1730 4.370 16.380 29.950 1.00 0.00 +ATOM 5664 OW HOH 1731 42.430 16.540 8.320 1.00 0.00 +ATOM 5665 HW1 HOH 1731 42.160 15.930 7.630 1.00 0.00 +ATOM 5666 HW2 HOH 1731 43.060 17.120 7.910 1.00 0.00 +ATOM 5667 OW HOH 1732 12.530 28.020 24.530 1.00 0.00 +ATOM 5668 HW1 HOH 1732 12.140 27.700 23.720 1.00 0.00 +ATOM 5669 HW2 HOH 1732 12.920 27.240 24.920 1.00 0.00 +ATOM 5670 OW HOH 1733 37.230 39.600 22.330 1.00 0.00 +ATOM 5671 HW1 HOH 1733 37.260 39.740 21.390 1.00 0.00 +ATOM 5672 HW2 HOH 1733 37.910 38.950 22.500 1.00 0.00 +ATOM 5673 OW HOH 1734 35.220 13.240 22.480 1.00 0.00 +ATOM 5674 HW1 HOH 1734 36.160 13.100 22.610 1.00 0.00 +ATOM 5675 HW2 HOH 1734 35.060 14.130 22.790 1.00 0.00 +ATOM 5676 OW HOH 1735 40.690 45.100 38.090 1.00 0.00 +ATOM 5677 HW1 HOH 1735 41.000 44.200 38.090 1.00 0.00 +ATOM 5678 HW2 HOH 1735 39.780 45.050 38.400 1.00 0.00 +ATOM 5679 OW HOH 1736 25.970 36.750 5.770 1.00 0.00 +ATOM 5680 HW1 HOH 1736 25.450 36.110 6.250 1.00 0.00 +ATOM 5681 HW2 HOH 1736 25.330 37.340 5.370 1.00 0.00 +ATOM 5682 OW HOH 1737 45.240 31.620 26.350 1.00 0.00 +ATOM 5683 HW1 HOH 1737 44.940 32.520 26.500 1.00 0.00 +ATOM 5684 HW2 HOH 1737 46.130 31.600 26.690 1.00 0.00 +ATOM 5685 OW HOH 1738 44.450 16.310 31.060 1.00 0.00 +ATOM 5686 HW1 HOH 1738 44.040 15.440 31.090 1.00 0.00 +ATOM 5687 HW2 HOH 1738 43.770 16.890 30.730 1.00 0.00 +ATOM 5688 OW HOH 1739 21.070 7.650 18.410 1.00 0.00 +ATOM 5689 HW1 HOH 1739 20.860 8.570 18.550 1.00 0.00 +ATOM 5690 HW2 HOH 1739 21.980 7.560 18.720 1.00 0.00 +ATOM 5691 OW HOH 1740 42.050 3.090 18.070 1.00 0.00 +ATOM 5692 HW1 HOH 1740 41.920 2.840 18.980 1.00 0.00 +ATOM 5693 HW2 HOH 1740 42.280 2.280 17.630 1.00 0.00 +ATOM 5694 OW HOH 1741 31.610 1.540 6.150 1.00 0.00 +ATOM 5695 HW1 HOH 1741 31.860 2.210 6.770 1.00 0.00 +ATOM 5696 HW2 HOH 1741 32.350 0.930 6.140 1.00 0.00 +ATOM 5697 OW HOH 1742 33.340 31.020 23.700 1.00 0.00 +ATOM 5698 HW1 HOH 1742 34.120 30.480 23.600 1.00 0.00 +ATOM 5699 HW2 HOH 1742 33.080 31.240 22.810 1.00 0.00 +ATOM 5700 OW HOH 1743 19.230 0.690 12.930 1.00 0.00 +ATOM 5701 HW1 HOH 1743 19.850 0.790 12.210 1.00 0.00 +ATOM 5702 HW2 HOH 1743 19.650 0.070 13.520 1.00 0.00 +ATOM 5703 OW HOH 1744 26.560 16.260 31.620 1.00 0.00 +ATOM 5704 HW1 HOH 1744 25.950 15.940 30.960 1.00 0.00 +ATOM 5705 HW2 HOH 1744 26.010 16.420 32.390 1.00 0.00 +ATOM 5706 OW HOH 1745 11.150 10.230 7.560 1.00 0.00 +ATOM 5707 HW1 HOH 1745 10.830 11.060 7.190 1.00 0.00 +ATOM 5708 HW2 HOH 1745 11.170 9.630 6.810 1.00 0.00 +ATOM 5709 OW HOH 1746 21.220 4.340 18.010 1.00 0.00 +ATOM 5710 HW1 HOH 1746 21.560 4.160 17.140 1.00 0.00 +ATOM 5711 HW2 HOH 1746 20.290 4.120 17.960 1.00 0.00 +ATOM 5712 OW HOH 1747 34.120 44.700 12.290 1.00 0.00 +ATOM 5713 HW1 HOH 1747 34.410 44.180 11.540 1.00 0.00 +ATOM 5714 HW2 HOH 1747 34.930 44.940 12.740 1.00 0.00 +ATOM 5715 OW HOH 1748 45.350 20.370 2.860 1.00 0.00 +ATOM 5716 HW1 HOH 1748 45.160 20.670 1.970 1.00 0.00 +ATOM 5717 HW2 HOH 1748 45.090 21.100 3.420 1.00 0.00 +ATOM 5718 OW HOH 1749 46.900 21.300 22.370 1.00 0.00 +ATOM 5719 HW1 HOH 1749 46.840 20.930 21.490 1.00 0.00 +ATOM 5720 HW2 HOH 1749 46.150 20.940 22.840 1.00 0.00 +ATOM 5721 OW HOH 1750 41.000 44.030 19.070 1.00 0.00 +ATOM 5722 HW1 HOH 1750 40.180 44.380 18.730 1.00 0.00 +ATOM 5723 HW2 HOH 1750 40.810 43.110 19.270 1.00 0.00 +ATOM 5724 OW HOH 1751 8.500 11.310 13.670 1.00 0.00 +ATOM 5725 HW1 HOH 1751 8.420 10.380 13.450 1.00 0.00 +ATOM 5726 HW2 HOH 1751 7.750 11.490 14.230 1.00 0.00 +ATOM 5727 OW HOH 1752 34.370 24.340 34.160 1.00 0.00 +ATOM 5728 HW1 HOH 1752 33.480 24.380 34.510 1.00 0.00 +ATOM 5729 HW2 HOH 1752 34.540 25.230 33.850 1.00 0.00 +ATOM 5730 OW HOH 1753 46.450 18.010 9.670 1.00 0.00 +ATOM 5731 HW1 HOH 1753 47.210 17.600 9.250 1.00 0.00 +ATOM 5732 HW2 HOH 1753 46.520 18.940 9.430 1.00 0.00 +ATOM 5733 OW HOH 1754 11.180 30.280 13.400 1.00 0.00 +ATOM 5734 HW1 HOH 1754 10.760 29.510 13.780 1.00 0.00 +ATOM 5735 HW2 HOH 1754 11.800 29.920 12.760 1.00 0.00 +ATOM 5736 OW HOH 1755 1.170 13.560 8.650 1.00 0.00 +ATOM 5737 HW1 HOH 1755 1.480 12.650 8.630 1.00 0.00 +ATOM 5738 HW2 HOH 1755 0.470 13.580 8.000 1.00 0.00 +ATOM 5739 OW HOH 1756 17.700 43.010 16.210 1.00 0.00 +ATOM 5740 HW1 HOH 1756 17.260 42.960 15.350 1.00 0.00 +ATOM 5741 HW2 HOH 1756 18.040 43.900 16.250 1.00 0.00 +ATOM 5742 OW HOH 1757 21.770 40.030 29.670 1.00 0.00 +ATOM 5743 HW1 HOH 1757 21.480 39.620 30.490 1.00 0.00 +ATOM 5744 HW2 HOH 1757 21.040 40.590 29.420 1.00 0.00 +ATOM 5745 OW HOH 1758 48.310 7.500 5.090 1.00 0.00 +ATOM 5746 HW1 HOH 1758 47.360 7.510 5.210 1.00 0.00 +ATOM 5747 HW2 HOH 1758 48.660 7.560 5.970 1.00 0.00 +ATOM 5748 OW HOH 1759 23.000 22.760 36.270 1.00 0.00 +ATOM 5749 HW1 HOH 1759 23.210 23.620 35.910 1.00 0.00 +ATOM 5750 HW2 HOH 1759 22.170 22.520 35.850 1.00 0.00 +ATOM 5751 OW HOH 1760 7.590 18.190 2.070 1.00 0.00 +ATOM 5752 HW1 HOH 1760 7.120 18.730 1.450 1.00 0.00 +ATOM 5753 HW2 HOH 1760 7.610 17.320 1.670 1.00 0.00 +ATOM 5754 OW HOH 1761 28.600 17.880 3.240 1.00 0.00 +ATOM 5755 HW1 HOH 1761 28.970 17.170 2.710 1.00 0.00 +ATOM 5756 HW2 HOH 1761 28.330 17.460 4.050 1.00 0.00 +ATOM 5757 OW HOH 1762 1.190 5.090 28.310 1.00 0.00 +ATOM 5758 HW1 HOH 1762 1.380 4.890 29.230 1.00 0.00 +ATOM 5759 HW2 HOH 1762 2.040 5.290 27.920 1.00 0.00 +ATOM 5760 OW HOH 1763 5.270 2.510 26.050 1.00 0.00 +ATOM 5761 HW1 HOH 1763 4.340 2.420 26.270 1.00 0.00 +ATOM 5762 HW2 HOH 1763 5.400 3.440 25.930 1.00 0.00 +ATOM 5763 OW HOH 1764 38.500 20.130 19.000 1.00 0.00 +ATOM 5764 HW1 HOH 1764 39.050 20.720 18.490 1.00 0.00 +ATOM 5765 HW2 HOH 1764 37.790 19.890 18.400 1.00 0.00 +ATOM 5766 OW HOH 1765 36.120 38.600 38.310 1.00 0.00 +ATOM 5767 HW1 HOH 1765 36.790 38.530 37.620 1.00 0.00 +ATOM 5768 HW2 HOH 1765 36.220 39.490 38.650 1.00 0.00 +ATOM 5769 OW HOH 1766 44.580 33.620 9.800 1.00 0.00 +ATOM 5770 HW1 HOH 1766 44.790 32.710 10.010 1.00 0.00 +ATOM 5771 HW2 HOH 1766 45.260 34.140 10.230 1.00 0.00 +ATOM 5772 OW HOH 1767 14.780 39.530 24.330 1.00 0.00 +ATOM 5773 HW1 HOH 1767 15.450 40.210 24.400 1.00 0.00 +ATOM 5774 HW2 HOH 1767 14.160 39.880 23.680 1.00 0.00 +ATOM 5775 OW HOH 1768 30.490 7.850 4.310 1.00 0.00 +ATOM 5776 HW1 HOH 1768 30.080 7.120 3.850 1.00 0.00 +ATOM 5777 HW2 HOH 1768 31.420 7.800 4.060 1.00 0.00 +ATOM 5778 OW HOH 1769 10.550 39.700 30.190 1.00 0.00 +ATOM 5779 HW1 HOH 1769 9.770 39.430 30.670 1.00 0.00 +ATOM 5780 HW2 HOH 1769 10.530 39.180 29.380 1.00 0.00 +ATOM 5781 OW HOH 1770 1.240 26.530 34.070 1.00 0.00 +ATOM 5782 HW1 HOH 1770 1.070 27.320 34.580 1.00 0.00 +ATOM 5783 HW2 HOH 1770 2.100 26.230 34.370 1.00 0.00 +ATOM 5784 OW HOH 1771 23.010 45.810 16.820 1.00 0.00 +ATOM 5785 HW1 HOH 1771 23.620 46.390 17.260 1.00 0.00 +ATOM 5786 HW2 HOH 1771 23.140 44.960 17.240 1.00 0.00 +ATOM 5787 OW HOH 1772 34.810 37.910 35.570 1.00 0.00 +ATOM 5788 HW1 HOH 1772 34.060 37.630 35.050 1.00 0.00 +ATOM 5789 HW2 HOH 1772 34.470 37.990 36.460 1.00 0.00 +ATOM 5790 OW HOH 1773 17.000 39.070 38.550 1.00 0.00 +ATOM 5791 HW1 HOH 1773 16.590 39.800 38.090 1.00 0.00 +ATOM 5792 HW2 HOH 1773 17.790 39.450 38.940 1.00 0.00 +ATOM 5793 OW HOH 1774 1.200 18.430 7.280 1.00 0.00 +ATOM 5794 HW1 HOH 1774 1.140 18.450 6.330 1.00 0.00 +ATOM 5795 HW2 HOH 1774 1.640 19.260 7.510 1.00 0.00 +ATOM 5796 OW HOH 1775 4.200 38.590 25.410 1.00 0.00 +ATOM 5797 HW1 HOH 1775 4.170 39.540 25.340 1.00 0.00 +ATOM 5798 HW2 HOH 1775 4.390 38.420 26.330 1.00 0.00 +ATOM 5799 OW HOH 1776 27.390 8.160 3.670 1.00 0.00 +ATOM 5800 HW1 HOH 1776 28.190 8.520 4.050 1.00 0.00 +ATOM 5801 HW2 HOH 1776 27.680 7.420 3.140 1.00 0.00 +ATOM 5802 OW HOH 1777 45.620 7.870 6.020 1.00 0.00 +ATOM 5803 HW1 HOH 1777 45.050 8.600 5.790 1.00 0.00 +ATOM 5804 HW2 HOH 1777 46.200 8.230 6.700 1.00 0.00 +ATOM 5805 OW HOH 1778 48.230 44.980 2.510 1.00 0.00 +ATOM 5806 HW1 HOH 1778 48.710 45.360 3.240 1.00 0.00 +ATOM 5807 HW2 HOH 1778 47.610 45.670 2.240 1.00 0.00 +ATOM 5808 OW HOH 1779 36.220 35.770 17.720 1.00 0.00 +ATOM 5809 HW1 HOH 1779 36.140 34.870 17.410 1.00 0.00 +ATOM 5810 HW2 HOH 1779 36.920 35.740 18.370 1.00 0.00 +ATOM 5811 OW HOH 1780 43.610 41.230 35.140 1.00 0.00 +ATOM 5812 HW1 HOH 1780 43.950 41.700 34.370 1.00 0.00 +ATOM 5813 HW2 HOH 1780 44.360 41.150 35.720 1.00 0.00 +ATOM 5814 OW HOH 1781 41.520 15.210 2.200 1.00 0.00 +ATOM 5815 HW1 HOH 1781 41.140 15.950 1.720 1.00 0.00 +ATOM 5816 HW2 HOH 1781 40.990 15.140 2.990 1.00 0.00 +ATOM 5817 OW HOH 1782 20.540 9.120 22.520 1.00 0.00 +ATOM 5818 HW1 HOH 1782 20.950 9.600 21.800 1.00 0.00 +ATOM 5819 HW2 HOH 1782 20.530 9.740 23.240 1.00 0.00 +ATOM 5820 OW HOH 1783 23.690 14.530 26.200 1.00 0.00 +ATOM 5821 HW1 HOH 1783 23.410 15.430 26.310 1.00 0.00 +ATOM 5822 HW2 HOH 1783 22.880 14.020 26.230 1.00 0.00 +ATOM 5823 OW HOH 1784 46.430 3.910 29.010 1.00 0.00 +ATOM 5824 HW1 HOH 1784 45.530 3.700 28.730 1.00 0.00 +ATOM 5825 HW2 HOH 1784 46.630 4.740 28.580 1.00 0.00 +ATOM 5826 OW HOH 1785 32.560 45.210 14.920 1.00 0.00 +ATOM 5827 HW1 HOH 1785 32.840 45.630 14.110 1.00 0.00 +ATOM 5828 HW2 HOH 1785 33.380 45.040 15.400 1.00 0.00 +ATOM 5829 OW HOH 1786 38.270 5.400 17.280 1.00 0.00 +ATOM 5830 HW1 HOH 1786 37.980 6.050 17.930 1.00 0.00 +ATOM 5831 HW2 HOH 1786 39.210 5.300 17.440 1.00 0.00 +ATOM 5832 OW HOH 1787 44.210 8.660 13.320 1.00 0.00 +ATOM 5833 HW1 HOH 1787 43.960 9.450 12.820 1.00 0.00 +ATOM 5834 HW2 HOH 1787 45.160 8.710 13.370 1.00 0.00 +ATOM 5835 OW HOH 1788 16.150 43.010 6.950 1.00 0.00 +ATOM 5836 HW1 HOH 1788 16.710 42.300 7.270 1.00 0.00 +ATOM 5837 HW2 HOH 1788 15.340 42.920 7.470 1.00 0.00 +ATOM 5838 OW HOH 1789 6.650 40.420 6.350 1.00 0.00 +ATOM 5839 HW1 HOH 1789 7.430 40.940 6.520 1.00 0.00 +ATOM 5840 HW2 HOH 1789 5.920 41.030 6.470 1.00 0.00 +ATOM 5841 OW HOH 1790 6.690 13.170 6.870 1.00 0.00 +ATOM 5842 HW1 HOH 1790 6.090 13.710 7.380 1.00 0.00 +ATOM 5843 HW2 HOH 1790 7.530 13.250 7.310 1.00 0.00 +ATOM 5844 OW HOH 1791 30.960 32.140 8.340 1.00 0.00 +ATOM 5845 HW1 HOH 1791 31.490 32.390 9.100 1.00 0.00 +ATOM 5846 HW2 HOH 1791 30.370 32.880 8.190 1.00 0.00 +ATOM 5847 OW HOH 1792 5.660 4.930 37.230 1.00 0.00 +ATOM 5848 HW1 HOH 1792 6.370 4.630 37.790 1.00 0.00 +ATOM 5849 HW2 HOH 1792 5.800 5.870 37.150 1.00 0.00 +ATOM 5850 OW HOH 1793 0.320 15.680 16.740 1.00 0.00 +ATOM 5851 HW1 HOH 1793 1.150 15.310 17.050 1.00 0.00 +ATOM 5852 HW2 HOH 1793 0.410 16.620 16.860 1.00 0.00 +ATOM 5853 OW HOH 1794 11.440 23.360 33.020 1.00 0.00 +ATOM 5854 HW1 HOH 1794 11.000 23.120 33.840 1.00 0.00 +ATOM 5855 HW2 HOH 1794 10.770 23.230 32.350 1.00 0.00 +ATOM 5856 OW HOH 1795 35.040 6.910 37.060 1.00 0.00 +ATOM 5857 HW1 HOH 1795 34.870 6.060 36.640 1.00 0.00 +ATOM 5858 HW2 HOH 1795 35.760 6.730 37.670 1.00 0.00 +ATOM 5859 OW HOH 1796 19.740 34.090 21.700 1.00 0.00 +ATOM 5860 HW1 HOH 1796 19.440 33.400 22.300 1.00 0.00 +ATOM 5861 HW2 HOH 1796 19.490 33.780 20.830 1.00 0.00 +ATOM 5862 OW HOH 1797 21.530 43.210 13.470 1.00 0.00 +ATOM 5863 HW1 HOH 1797 21.610 42.430 14.020 1.00 0.00 +ATOM 5864 HW2 HOH 1797 20.620 43.190 13.170 1.00 0.00 +ATOM 5865 OW HOH 1798 46.550 1.080 10.840 1.00 0.00 +ATOM 5866 HW1 HOH 1798 46.570 1.440 9.950 1.00 0.00 +ATOM 5867 HW2 HOH 1798 47.410 0.680 10.960 1.00 0.00 +ATOM 5868 OW HOH 1799 13.630 39.680 34.570 1.00 0.00 +ATOM 5869 HW1 HOH 1799 13.390 40.160 35.360 1.00 0.00 +ATOM 5870 HW2 HOH 1799 13.400 40.260 33.850 1.00 0.00 +ATOM 5871 OW HOH 1800 34.910 35.790 4.510 1.00 0.00 +ATOM 5872 HW1 HOH 1800 33.980 35.780 4.300 1.00 0.00 +ATOM 5873 HW2 HOH 1800 35.110 34.900 4.790 1.00 0.00 +ATOM 5874 OW HOH 1801 48.000 39.800 12.250 1.00 0.00 +ATOM 5875 HW1 HOH 1801 47.150 39.960 11.830 1.00 0.00 +ATOM 5876 HW2 HOH 1801 48.440 40.650 12.220 1.00 0.00 +ATOM 5877 OW HOH 1802 15.300 10.570 31.920 1.00 0.00 +ATOM 5878 HW1 HOH 1802 15.030 9.660 31.770 1.00 0.00 +ATOM 5879 HW2 HOH 1802 16.140 10.500 32.370 1.00 0.00 +ATOM 5880 OW HOH 1803 46.480 34.810 28.550 1.00 0.00 +ATOM 5881 HW1 HOH 1803 46.300 33.950 28.930 1.00 0.00 +ATOM 5882 HW2 HOH 1803 45.850 34.890 27.830 1.00 0.00 +ATOM 5883 OW HOH 1804 35.650 9.770 29.210 1.00 0.00 +ATOM 5884 HW1 HOH 1804 35.050 9.210 28.720 1.00 0.00 +ATOM 5885 HW2 HOH 1804 36.170 9.160 29.730 1.00 0.00 +ATOM 5886 OW HOH 1805 43.260 29.830 17.200 1.00 0.00 +ATOM 5887 HW1 HOH 1805 43.270 30.520 16.540 1.00 0.00 +ATOM 5888 HW2 HOH 1805 43.750 29.110 16.800 1.00 0.00 +ATOM 5889 OW HOH 1806 22.790 34.840 11.260 1.00 0.00 +ATOM 5890 HW1 HOH 1806 21.930 35.030 11.640 1.00 0.00 +ATOM 5891 HW2 HOH 1806 23.250 34.340 11.940 1.00 0.00 +ATOM 5892 OW HOH 1807 42.660 26.300 33.700 1.00 0.00 +ATOM 5893 HW1 HOH 1807 42.270 26.830 33.000 1.00 0.00 +ATOM 5894 HW2 HOH 1807 42.860 26.920 34.390 1.00 0.00 +ATOM 5895 OW HOH 1808 14.320 23.020 7.880 1.00 0.00 +ATOM 5896 HW1 HOH 1808 13.520 23.370 8.270 1.00 0.00 +ATOM 5897 HW2 HOH 1808 14.070 22.160 7.560 1.00 0.00 +ATOM 5898 OW HOH 1809 20.130 10.170 24.930 1.00 0.00 +ATOM 5899 HW1 HOH 1809 20.560 9.420 25.340 1.00 0.00 +ATOM 5900 HW2 HOH 1809 19.450 10.430 25.550 1.00 0.00 +ATOM 5901 OW HOH 1810 27.130 18.280 21.160 1.00 0.00 +ATOM 5902 HW1 HOH 1810 27.240 17.800 21.980 1.00 0.00 +ATOM 5903 HW2 HOH 1810 27.330 19.190 21.380 1.00 0.00 +ATOM 5904 OW HOH 1811 44.290 16.580 10.530 1.00 0.00 +ATOM 5905 HW1 HOH 1811 43.610 17.030 10.020 1.00 0.00 +ATOM 5906 HW2 HOH 1811 45.110 16.860 10.120 1.00 0.00 +ATOM 5907 OW HOH 1812 7.740 29.460 8.990 1.00 0.00 +ATOM 5908 HW1 HOH 1812 8.580 29.720 9.370 1.00 0.00 +ATOM 5909 HW2 HOH 1812 7.650 30.000 8.200 1.00 0.00 +ATOM 5910 OW HOH 1813 10.670 38.440 27.800 1.00 0.00 +ATOM 5911 HW1 HOH 1813 11.250 37.710 27.590 1.00 0.00 +ATOM 5912 HW2 HOH 1813 10.250 38.660 26.960 1.00 0.00 +ATOM 5913 OW HOH 1814 48.180 43.830 33.330 1.00 0.00 +ATOM 5914 HW1 HOH 1814 48.660 43.390 34.020 1.00 0.00 +ATOM 5915 HW2 HOH 1814 48.040 44.720 33.660 1.00 0.00 +ATOM 5916 OW HOH 1815 47.420 20.150 37.050 1.00 0.00 +ATOM 5917 HW1 HOH 1815 47.390 19.190 37.010 1.00 0.00 +ATOM 5918 HW2 HOH 1815 47.030 20.430 36.230 1.00 0.00 +ATOM 5919 OW HOH 1816 6.440 29.710 31.450 1.00 0.00 +ATOM 5920 HW1 HOH 1816 6.420 29.080 30.730 1.00 0.00 +ATOM 5921 HW2 HOH 1816 7.360 29.770 31.690 1.00 0.00 +ATOM 5922 OW HOH 1817 2.690 11.100 37.160 1.00 0.00 +ATOM 5923 HW1 HOH 1817 2.650 11.090 36.200 1.00 0.00 +ATOM 5924 HW2 HOH 1817 1.860 10.700 37.430 1.00 0.00 +ATOM 5925 OW HOH 1818 40.710 8.230 23.240 1.00 0.00 +ATOM 5926 HW1 HOH 1818 41.180 7.420 23.050 1.00 0.00 +ATOM 5927 HW2 HOH 1818 41.370 8.920 23.150 1.00 0.00 +ATOM 5928 OW HOH 1819 17.660 14.610 18.000 1.00 0.00 +ATOM 5929 HW1 HOH 1819 17.340 14.750 18.890 1.00 0.00 +ATOM 5930 HW2 HOH 1819 16.860 14.600 17.460 1.00 0.00 +ATOM 5931 OW HOH 1820 26.320 3.560 20.420 1.00 0.00 +ATOM 5932 HW1 HOH 1820 27.010 4.090 20.810 1.00 0.00 +ATOM 5933 HW2 HOH 1820 25.520 3.850 20.850 1.00 0.00 +ATOM 5934 OW HOH 1821 38.820 45.220 18.220 1.00 0.00 +ATOM 5935 HW1 HOH 1821 38.870 45.170 17.270 1.00 0.00 +ATOM 5936 HW2 HOH 1821 37.910 45.000 18.420 1.00 0.00 +ATOM 5937 OW HOH 1822 41.320 36.420 15.090 1.00 0.00 +ATOM 5938 HW1 HOH 1822 41.560 37.010 14.370 1.00 0.00 +ATOM 5939 HW2 HOH 1822 41.710 35.580 14.850 1.00 0.00 +ATOM 5940 OW HOH 1823 44.000 17.760 21.790 1.00 0.00 +ATOM 5941 HW1 HOH 1823 44.890 17.880 22.110 1.00 0.00 +ATOM 5942 HW2 HOH 1823 44.110 17.430 20.900 1.00 0.00 +ATOM 5943 OW HOH 1824 34.390 13.350 11.980 1.00 0.00 +ATOM 5944 HW1 HOH 1824 34.330 13.540 11.050 1.00 0.00 +ATOM 5945 HW2 HOH 1824 33.920 12.530 12.100 1.00 0.00 +ATOM 5946 OW HOH 1825 7.580 36.730 1.280 1.00 0.00 +ATOM 5947 HW1 HOH 1825 7.400 35.940 0.780 1.00 0.00 +ATOM 5948 HW2 HOH 1825 8.520 36.890 1.140 1.00 0.00 +ATOM 5949 OW HOH 1826 49.270 38.090 34.960 1.00 0.00 +ATOM 5950 HW1 HOH 1826 48.410 38.020 34.550 1.00 0.00 +ATOM 5951 HW2 HOH 1826 49.560 37.180 35.050 1.00 0.00 +ATOM 5952 OW HOH 1827 44.920 41.400 22.000 1.00 0.00 +ATOM 5953 HW1 HOH 1827 44.510 41.200 21.160 1.00 0.00 +ATOM 5954 HW2 HOH 1827 44.270 41.140 22.650 1.00 0.00 +ATOM 5955 OW HOH 1828 47.350 9.790 22.010 1.00 0.00 +ATOM 5956 HW1 HOH 1828 48.110 10.280 21.720 1.00 0.00 +ATOM 5957 HW2 HOH 1828 47.670 9.260 22.740 1.00 0.00 +ATOM 5958 OW HOH 1829 24.090 22.490 7.040 1.00 0.00 +ATOM 5959 HW1 HOH 1829 23.910 22.660 7.970 1.00 0.00 +ATOM 5960 HW2 HOH 1829 24.890 22.990 6.860 1.00 0.00 +ATOM 5961 OW HOH 1830 19.790 37.680 15.060 1.00 0.00 +ATOM 5962 HW1 HOH 1830 20.600 37.830 15.530 1.00 0.00 +ATOM 5963 HW2 HOH 1830 19.370 38.540 15.020 1.00 0.00 +ATOM 5964 OW HOH 1831 10.240 0.700 23.960 1.00 0.00 +ATOM 5965 HW1 HOH 1831 10.520 0.490 23.070 1.00 0.00 +ATOM 5966 HW2 HOH 1831 9.390 0.270 24.050 1.00 0.00 +ATOM 5967 OW HOH 1832 3.670 4.700 2.960 1.00 0.00 +ATOM 5968 HW1 HOH 1832 3.480 5.630 2.860 1.00 0.00 +ATOM 5969 HW2 HOH 1832 3.500 4.330 2.090 1.00 0.00 +ATOM 5970 OW HOH 1833 38.410 29.000 37.030 1.00 0.00 +ATOM 5971 HW1 HOH 1833 38.090 29.780 37.480 1.00 0.00 +ATOM 5972 HW2 HOH 1833 38.170 28.270 37.610 1.00 0.00 +ATOM 5973 OW HOH 1834 8.000 8.770 12.740 1.00 0.00 +ATOM 5974 HW1 HOH 1834 7.390 8.100 13.040 1.00 0.00 +ATOM 5975 HW2 HOH 1834 8.450 8.360 12.000 1.00 0.00 +ATOM 5976 OW HOH 1835 46.850 0.260 16.170 1.00 0.00 +ATOM 5977 HW1 HOH 1835 46.820 0.040 17.100 1.00 0.00 +ATOM 5978 HW2 HOH 1835 47.500 0.960 16.120 1.00 0.00 +ATOM 5979 OW HOH 1836 6.270 27.580 22.820 1.00 0.00 +ATOM 5980 HW1 HOH 1836 5.480 27.840 23.290 1.00 0.00 +ATOM 5981 HW2 HOH 1836 6.290 28.160 22.050 1.00 0.00 +ATOM 5982 OW HOH 1837 8.180 41.840 9.780 1.00 0.00 +ATOM 5983 HW1 HOH 1837 8.060 41.350 10.590 1.00 0.00 +ATOM 5984 HW2 HOH 1837 7.970 41.210 9.090 1.00 0.00 +ATOM 5985 OW HOH 1838 5.560 25.350 34.980 1.00 0.00 +ATOM 5986 HW1 HOH 1838 6.070 26.130 34.770 1.00 0.00 +ATOM 5987 HW2 HOH 1838 5.710 24.760 34.240 1.00 0.00 +ATOM 5988 OW HOH 1839 30.740 1.220 21.840 1.00 0.00 +ATOM 5989 HW1 HOH 1839 31.260 1.170 22.640 1.00 0.00 +ATOM 5990 HW2 HOH 1839 30.170 1.990 21.970 1.00 0.00 +ATOM 5991 OW HOH 1840 4.300 11.050 6.270 1.00 0.00 +ATOM 5992 HW1 HOH 1840 4.200 11.850 5.750 1.00 0.00 +ATOM 5993 HW2 HOH 1840 5.130 11.160 6.720 1.00 0.00 +ATOM 5994 OW HOH 1841 2.790 33.020 27.620 1.00 0.00 +ATOM 5995 HW1 HOH 1841 2.870 33.640 28.340 1.00 0.00 +ATOM 5996 HW2 HOH 1841 2.100 32.410 27.900 1.00 0.00 +ATOM 5997 OW HOH 1842 17.690 34.020 8.540 1.00 0.00 +ATOM 5998 HW1 HOH 1842 17.250 34.860 8.600 1.00 0.00 +ATOM 5999 HW2 HOH 1842 18.270 34.100 7.780 1.00 0.00 +ATOM 6000 OW HOH 1843 36.050 0.060 19.370 1.00 0.00 +ATOM 6001 HW1 HOH 1843 35.840 0.570 20.150 1.00 0.00 +ATOM 6002 HW2 HOH 1843 36.300 0.720 18.720 1.00 0.00 +ATOM 6003 OW HOH 1844 14.570 11.650 11.330 1.00 0.00 +ATOM 6004 HW1 HOH 1844 14.540 12.600 11.210 1.00 0.00 +ATOM 6005 HW2 HOH 1844 14.920 11.540 12.210 1.00 0.00 +ATOM 6006 OW HOH 1845 13.910 16.230 7.060 1.00 0.00 +ATOM 6007 HW1 HOH 1845 13.740 16.960 7.660 1.00 0.00 +ATOM 6008 HW2 HOH 1845 13.040 15.910 6.820 1.00 0.00 +ATOM 6009 OW HOH 1846 13.070 8.660 28.390 1.00 0.00 +ATOM 6010 HW1 HOH 1846 12.730 9.140 29.150 1.00 0.00 +ATOM 6011 HW2 HOH 1846 12.290 8.270 27.990 1.00 0.00 +ATOM 6012 OW HOH 1847 11.540 30.760 33.530 1.00 0.00 +ATOM 6013 HW1 HOH 1847 10.680 30.420 33.300 1.00 0.00 +ATOM 6014 HW2 HOH 1847 11.420 31.170 34.390 1.00 0.00 +ATOM 6015 OW HOH 1848 3.460 12.090 31.920 1.00 0.00 +ATOM 6016 HW1 HOH 1848 4.290 11.970 32.370 1.00 0.00 +ATOM 6017 HW2 HOH 1848 3.290 13.030 31.940 1.00 0.00 +ATOM 6018 OW HOH 1849 12.000 37.460 34.510 1.00 0.00 +ATOM 6019 HW1 HOH 1849 12.730 36.840 34.550 1.00 0.00 +ATOM 6020 HW2 HOH 1849 12.420 38.310 34.360 1.00 0.00 +ATOM 6021 OW HOH 1850 22.880 13.980 21.300 1.00 0.00 +ATOM 6022 HW1 HOH 1850 22.350 13.230 21.020 1.00 0.00 +ATOM 6023 HW2 HOH 1850 23.350 13.670 22.070 1.00 0.00 +ATOM 6024 OW HOH 1851 46.030 2.980 1.780 1.00 0.00 +ATOM 6025 HW1 HOH 1851 45.840 3.900 1.990 1.00 0.00 +ATOM 6026 HW2 HOH 1851 45.180 2.620 1.520 1.00 0.00 +ATOM 6027 OW HOH 1852 39.520 43.970 29.820 1.00 0.00 +ATOM 6028 HW1 HOH 1852 40.020 44.530 29.230 1.00 0.00 +ATOM 6029 HW2 HOH 1852 40.040 43.170 29.900 1.00 0.00 +ATOM 6030 OW HOH 1853 38.750 35.390 11.670 1.00 0.00 +ATOM 6031 HW1 HOH 1853 39.170 34.650 11.240 1.00 0.00 +ATOM 6032 HW2 HOH 1853 39.120 36.160 11.240 1.00 0.00 +ATOM 6033 OW HOH 1854 31.510 44.030 21.850 1.00 0.00 +ATOM 6034 HW1 HOH 1854 31.610 44.960 22.030 1.00 0.00 +ATOM 6035 HW2 HOH 1854 31.340 43.980 20.910 1.00 0.00 +ATOM 6036 OW HOH 1855 2.200 36.240 6.070 1.00 0.00 +ATOM 6037 HW1 HOH 1855 2.900 35.880 5.530 1.00 0.00 +ATOM 6038 HW2 HOH 1855 1.440 35.670 5.900 1.00 0.00 +ATOM 6039 OW HOH 1856 16.250 8.280 5.050 1.00 0.00 +ATOM 6040 HW1 HOH 1856 16.120 9.230 5.130 1.00 0.00 +ATOM 6041 HW2 HOH 1856 16.640 8.020 5.880 1.00 0.00 +ATOM 6042 OW HOH 1857 38.700 20.210 13.400 1.00 0.00 +ATOM 6043 HW1 HOH 1857 38.470 21.090 13.700 1.00 0.00 +ATOM 6044 HW2 HOH 1857 38.190 20.090 12.600 1.00 0.00 +ATOM 6045 OW HOH 1858 41.360 37.800 27.830 1.00 0.00 +ATOM 6046 HW1 HOH 1858 41.160 36.890 28.030 1.00 0.00 +ATOM 6047 HW2 HOH 1858 41.040 38.300 28.580 1.00 0.00 +ATOM 6048 OW HOH 1859 13.900 32.930 5.030 1.00 0.00 +ATOM 6049 HW1 HOH 1859 14.530 32.380 5.510 1.00 0.00 +ATOM 6050 HW2 HOH 1859 13.900 32.560 4.140 1.00 0.00 +ATOM 6051 OW HOH 1860 48.060 11.690 31.310 1.00 0.00 +ATOM 6052 HW1 HOH 1860 47.670 10.820 31.290 1.00 0.00 +ATOM 6053 HW2 HOH 1860 48.800 11.610 31.930 1.00 0.00 +ATOM 6054 OW HOH 1861 38.360 8.230 8.840 1.00 0.00 +ATOM 6055 HW1 HOH 1861 38.160 9.050 9.300 1.00 0.00 +ATOM 6056 HW2 HOH 1861 38.080 7.540 9.440 1.00 0.00 +ATOM 6057 OW HOH 1862 18.130 -0.130 16.040 1.00 0.00 +ATOM 6058 HW1 HOH 1862 17.610 0.550 15.600 1.00 0.00 +ATOM 6059 HW2 HOH 1862 18.850 0.350 16.450 1.00 0.00 +ATOM 6060 OW HOH 1863 21.160 15.380 11.820 1.00 0.00 +ATOM 6061 HW1 HOH 1863 21.560 14.510 11.770 1.00 0.00 +ATOM 6062 HW2 HOH 1863 21.850 15.930 12.200 1.00 0.00 +ATOM 6063 OW HOH 1864 29.900 22.710 29.270 1.00 0.00 +ATOM 6064 HW1 HOH 1864 30.150 23.430 29.850 1.00 0.00 +ATOM 6065 HW2 HOH 1864 29.170 22.280 29.730 1.00 0.00 +ATOM 6066 OW HOH 1865 46.150 31.670 15.040 1.00 0.00 +ATOM 6067 HW1 HOH 1865 45.910 32.270 15.750 1.00 0.00 +ATOM 6068 HW2 HOH 1865 46.370 30.850 15.480 1.00 0.00 +ATOM 6069 OW HOH 1866 12.280 15.820 10.020 1.00 0.00 +ATOM 6070 HW1 HOH 1866 12.430 15.780 10.960 1.00 0.00 +ATOM 6071 HW2 HOH 1866 11.370 15.560 9.910 1.00 0.00 +ATOM 6072 OW HOH 1867 1.550 10.330 18.270 1.00 0.00 +ATOM 6073 HW1 HOH 1867 0.810 10.700 17.780 1.00 0.00 +ATOM 6074 HW2 HOH 1867 1.340 9.400 18.370 1.00 0.00 +ATOM 6075 OW HOH 1868 9.860 18.570 23.630 1.00 0.00 +ATOM 6076 HW1 HOH 1868 8.950 18.420 23.360 1.00 0.00 +ATOM 6077 HW2 HOH 1868 10.380 18.310 22.870 1.00 0.00 +ATOM 6078 OW HOH 1869 4.000 44.890 15.360 1.00 0.00 +ATOM 6079 HW1 HOH 1869 3.980 43.980 15.050 1.00 0.00 +ATOM 6080 HW2 HOH 1869 4.710 45.290 14.860 1.00 0.00 +ATOM 6081 OW HOH 1870 5.700 22.580 18.960 1.00 0.00 +ATOM 6082 HW1 HOH 1870 6.380 22.730 18.310 1.00 0.00 +ATOM 6083 HW2 HOH 1870 5.560 21.630 18.960 1.00 0.00 +ATOM 6084 OW HOH 1871 5.470 24.640 13.880 1.00 0.00 +ATOM 6085 HW1 HOH 1871 4.810 25.310 13.710 1.00 0.00 +ATOM 6086 HW2 HOH 1871 5.010 23.950 14.350 1.00 0.00 +ATOM 6087 OW HOH 1872 0.310 17.240 1.430 1.00 0.00 +ATOM 6088 HW1 HOH 1872 0.460 17.390 2.360 1.00 0.00 +ATOM 6089 HW2 HOH 1872 0.530 18.060 1.010 1.00 0.00 +ATOM 6090 OW HOH 1873 37.320 1.470 38.550 1.00 0.00 +ATOM 6091 HW1 HOH 1873 37.780 0.630 38.560 1.00 0.00 +ATOM 6092 HW2 HOH 1873 36.590 1.350 39.160 1.00 0.00 +ATOM 6093 OW HOH 1874 39.760 6.210 1.670 1.00 0.00 +ATOM 6094 HW1 HOH 1874 40.460 6.500 2.250 1.00 0.00 +ATOM 6095 HW2 HOH 1874 39.510 6.990 1.180 1.00 0.00 +ATOM 6096 OW HOH 1875 30.290 22.840 24.250 1.00 0.00 +ATOM 6097 HW1 HOH 1875 29.550 23.420 24.070 1.00 0.00 +ATOM 6098 HW2 HOH 1875 31.040 23.430 24.330 1.00 0.00 +ATOM 6099 OW HOH 1876 28.370 4.730 15.520 1.00 0.00 +ATOM 6100 HW1 HOH 1876 29.080 5.320 15.760 1.00 0.00 +ATOM 6101 HW2 HOH 1876 28.460 4.610 14.580 1.00 0.00 +ATOM 6102 OW HOH 1877 32.090 13.910 32.880 1.00 0.00 +ATOM 6103 HW1 HOH 1877 31.240 13.520 32.700 1.00 0.00 +ATOM 6104 HW2 HOH 1877 31.950 14.460 33.650 1.00 0.00 +ATOM 6105 OW HOH 1878 33.290 30.490 30.280 1.00 0.00 +ATOM 6106 HW1 HOH 1878 33.730 30.210 29.480 1.00 0.00 +ATOM 6107 HW2 HOH 1878 32.810 31.280 30.030 1.00 0.00 +ATOM 6108 OW HOH 1879 43.210 2.620 28.290 1.00 0.00 +ATOM 6109 HW1 HOH 1879 43.370 1.700 28.470 1.00 0.00 +ATOM 6110 HW2 HOH 1879 42.980 2.990 29.140 1.00 0.00 +ATOM 6111 OW HOH 1880 23.980 43.480 17.950 1.00 0.00 +ATOM 6112 HW1 HOH 1880 24.540 42.720 18.140 1.00 0.00 +ATOM 6113 HW2 HOH 1880 23.250 43.400 18.570 1.00 0.00 +ATOM 6114 OW HOH 1881 36.690 26.150 24.140 1.00 0.00 +ATOM 6115 HW1 HOH 1881 37.310 25.520 24.520 1.00 0.00 +ATOM 6116 HW2 HOH 1881 35.880 26.010 24.630 1.00 0.00 +ATOM 6117 OW HOH 1882 9.960 4.590 36.400 1.00 0.00 +ATOM 6118 HW1 HOH 1882 9.740 3.760 35.980 1.00 0.00 +ATOM 6119 HW2 HOH 1882 9.600 5.250 35.820 1.00 0.00 +ATOM 6120 OW HOH 1883 41.170 4.950 14.070 1.00 0.00 +ATOM 6121 HW1 HOH 1883 41.100 5.240 14.980 1.00 0.00 +ATOM 6122 HW2 HOH 1883 40.760 5.650 13.570 1.00 0.00 +ATOM 6123 OW HOH 1884 11.160 21.220 5.970 1.00 0.00 +ATOM 6124 HW1 HOH 1884 11.250 22.140 6.220 1.00 0.00 +ATOM 6125 HW2 HOH 1884 11.140 21.220 5.020 1.00 0.00 +ATOM 6126 OW HOH 1885 38.000 43.530 5.810 1.00 0.00 +ATOM 6127 HW1 HOH 1885 38.910 43.570 6.090 1.00 0.00 +ATOM 6128 HW2 HOH 1885 38.020 43.770 4.880 1.00 0.00 +ATOM 6129 OW HOH 1886 43.770 44.470 12.070 1.00 0.00 +ATOM 6130 HW1 HOH 1886 43.750 45.250 11.520 1.00 0.00 +ATOM 6131 HW2 HOH 1886 44.670 44.160 12.020 1.00 0.00 +ATOM 6132 OW HOH 1887 36.790 20.180 32.230 1.00 0.00 +ATOM 6133 HW1 HOH 1887 37.150 19.630 32.930 1.00 0.00 +ATOM 6134 HW2 HOH 1887 37.380 20.030 31.480 1.00 0.00 +ATOM 6135 OW HOH 1888 37.620 44.420 35.560 1.00 0.00 +ATOM 6136 HW1 HOH 1888 37.230 43.840 34.910 1.00 0.00 +ATOM 6137 HW2 HOH 1888 37.670 43.890 36.350 1.00 0.00 +ATOM 6138 OW HOH 1889 32.150 12.050 3.770 1.00 0.00 +ATOM 6139 HW1 HOH 1889 32.700 12.420 4.460 1.00 0.00 +ATOM 6140 HW2 HOH 1889 31.320 12.530 3.830 1.00 0.00 +ATOM 6141 OW HOH 1890 39.540 16.030 10.670 1.00 0.00 +ATOM 6142 HW1 HOH 1890 39.690 15.610 11.520 1.00 0.00 +ATOM 6143 HW2 HOH 1890 38.590 15.980 10.540 1.00 0.00 +ATOM 6144 OW HOH 1891 40.360 18.120 9.460 1.00 0.00 +ATOM 6145 HW1 HOH 1891 39.890 17.470 9.970 1.00 0.00 +ATOM 6146 HW2 HOH 1891 41.210 17.720 9.280 1.00 0.00 +ATOM 6147 OW HOH 1892 3.030 11.660 15.750 1.00 0.00 +ATOM 6148 HW1 HOH 1892 2.080 11.660 15.680 1.00 0.00 +ATOM 6149 HW2 HOH 1892 3.220 11.090 16.500 1.00 0.00 +ATOM 6150 OW HOH 1893 27.160 9.310 38.500 1.00 0.00 +ATOM 6151 HW1 HOH 1893 27.200 8.480 38.030 1.00 0.00 +ATOM 6152 HW2 HOH 1893 27.940 9.310 39.050 1.00 0.00 +ATOM 6153 OW HOH 1894 37.200 4.090 3.460 1.00 0.00 +ATOM 6154 HW1 HOH 1894 37.100 5.030 3.340 1.00 0.00 +ATOM 6155 HW2 HOH 1894 36.400 3.720 3.090 1.00 0.00 +ATOM 6156 OW HOH 1895 13.630 43.140 3.650 1.00 0.00 +ATOM 6157 HW1 HOH 1895 14.160 43.940 3.580 1.00 0.00 +ATOM 6158 HW2 HOH 1895 13.150 43.250 4.470 1.00 0.00 +ATOM 6159 OW HOH 1896 48.500 5.580 20.430 1.00 0.00 +ATOM 6160 HW1 HOH 1896 47.960 6.330 20.680 1.00 0.00 +ATOM 6161 HW2 HOH 1896 48.470 5.000 21.190 1.00 0.00 +ATOM 6162 OW HOH 1897 46.480 3.730 32.200 1.00 0.00 +ATOM 6163 HW1 HOH 1897 47.090 4.410 32.500 1.00 0.00 +ATOM 6164 HW2 HOH 1897 46.340 3.940 31.270 1.00 0.00 +ATOM 6165 OW HOH 1898 39.460 15.010 3.940 1.00 0.00 +ATOM 6166 HW1 HOH 1898 38.580 14.970 3.590 1.00 0.00 +ATOM 6167 HW2 HOH 1898 39.340 15.290 4.850 1.00 0.00 +ATOM 6168 OW HOH 1899 38.490 27.250 29.980 1.00 0.00 +ATOM 6169 HW1 HOH 1899 38.560 28.060 30.500 1.00 0.00 +ATOM 6170 HW2 HOH 1899 38.720 26.560 30.590 1.00 0.00 +ATOM 6171 OW HOH 1900 41.960 16.410 23.600 1.00 0.00 +ATOM 6172 HW1 HOH 1900 41.310 16.590 22.910 1.00 0.00 +ATOM 6173 HW2 HOH 1900 42.750 16.860 23.300 1.00 0.00 +ATOM 6174 OW HOH 1901 47.460 5.870 33.670 1.00 0.00 +ATOM 6175 HW1 HOH 1901 47.180 6.480 34.360 1.00 0.00 +ATOM 6176 HW2 HOH 1901 47.850 6.440 33.000 1.00 0.00 +ATOM 6177 OW HOH 1902 38.140 15.280 20.910 1.00 0.00 +ATOM 6178 HW1 HOH 1902 37.610 14.880 20.220 1.00 0.00 +ATOM 6179 HW2 HOH 1902 38.090 14.670 21.640 1.00 0.00 +ATOM 6180 OW HOH 1903 33.500 8.870 26.960 1.00 0.00 +ATOM 6181 HW1 HOH 1903 33.430 9.780 26.690 1.00 0.00 +ATOM 6182 HW2 HOH 1903 32.880 8.780 27.690 1.00 0.00 +ATOM 6183 OW HOH 1904 43.710 15.480 34.580 1.00 0.00 +ATOM 6184 HW1 HOH 1904 43.310 15.460 33.710 1.00 0.00 +ATOM 6185 HW2 HOH 1904 44.560 15.040 34.470 1.00 0.00 +ATOM 6186 OW HOH 1905 13.500 33.130 8.030 1.00 0.00 +ATOM 6187 HW1 HOH 1905 12.860 32.450 7.820 1.00 0.00 +ATOM 6188 HW2 HOH 1905 14.300 32.660 8.240 1.00 0.00 +ATOM 6189 OW HOH 1906 11.680 6.500 27.330 1.00 0.00 +ATOM 6190 HW1 HOH 1906 11.610 6.450 26.380 1.00 0.00 +ATOM 6191 HW2 HOH 1906 12.190 5.720 27.570 1.00 0.00 +ATOM 6192 OW HOH 1907 4.260 10.230 26.470 1.00 0.00 +ATOM 6193 HW1 HOH 1907 4.320 10.400 27.410 1.00 0.00 +ATOM 6194 HW2 HOH 1907 4.030 9.310 26.410 1.00 0.00 +ATOM 6195 OW HOH 1908 45.220 12.520 4.120 1.00 0.00 +ATOM 6196 HW1 HOH 1908 45.300 13.010 4.940 1.00 0.00 +ATOM 6197 HW2 HOH 1908 44.900 13.170 3.490 1.00 0.00 +ATOM 6198 OW HOH 1909 25.060 7.890 23.850 1.00 0.00 +ATOM 6199 HW1 HOH 1909 25.700 7.260 23.500 1.00 0.00 +ATOM 6200 HW2 HOH 1909 24.250 7.690 23.390 1.00 0.00 +ATOM 6201 OW HOH 1910 39.530 3.680 29.040 1.00 0.00 +ATOM 6202 HW1 HOH 1910 38.950 3.070 28.580 1.00 0.00 +ATOM 6203 HW2 HOH 1910 40.000 3.130 29.660 1.00 0.00 +ATOM 6204 OW HOH 1911 47.260 45.330 18.660 1.00 0.00 +ATOM 6205 HW1 HOH 1911 48.140 45.070 18.950 1.00 0.00 +ATOM 6206 HW2 HOH 1911 46.910 45.820 19.400 1.00 0.00 +ATOM 6207 OW HOH 1912 20.490 37.630 10.450 1.00 0.00 +ATOM 6208 HW1 HOH 1912 19.800 37.720 11.110 1.00 0.00 +ATOM 6209 HW2 HOH 1912 20.030 37.410 9.640 1.00 0.00 +ATOM 6210 OW HOH 1913 43.860 15.060 25.230 1.00 0.00 +ATOM 6211 HW1 HOH 1913 43.270 15.070 24.480 1.00 0.00 +ATOM 6212 HW2 HOH 1913 44.690 15.390 24.890 1.00 0.00 +ATOM 6213 OW HOH 1914 1.330 18.460 31.190 1.00 0.00 +ATOM 6214 HW1 HOH 1914 0.560 18.290 30.640 1.00 0.00 +ATOM 6215 HW2 HOH 1914 0.990 19.010 31.900 1.00 0.00 +ATOM 6216 OW HOH 1915 42.340 30.000 31.180 1.00 0.00 +ATOM 6217 HW1 HOH 1915 42.500 30.410 30.340 1.00 0.00 +ATOM 6218 HW2 HOH 1915 43.180 29.610 31.420 1.00 0.00 +ATOM 6219 OW HOH 1916 38.900 6.710 36.900 1.00 0.00 +ATOM 6220 HW1 HOH 1916 38.470 6.070 37.460 1.00 0.00 +ATOM 6221 HW2 HOH 1916 38.680 7.560 37.290 1.00 0.00 +ATOM 6222 OW HOH 1917 41.500 2.660 20.820 1.00 0.00 +ATOM 6223 HW1 HOH 1917 40.750 2.620 20.230 1.00 0.00 +ATOM 6224 HW2 HOH 1917 41.110 2.570 21.690 1.00 0.00 +ATOM 6225 OW HOH 1918 2.810 35.260 16.310 1.00 0.00 +ATOM 6226 HW1 HOH 1918 2.070 34.840 16.760 1.00 0.00 +ATOM 6227 HW2 HOH 1918 2.560 35.250 15.380 1.00 0.00 +ATOM 6228 OW HOH 1919 32.200 36.840 28.160 1.00 0.00 +ATOM 6229 HW1 HOH 1919 32.410 36.070 27.640 1.00 0.00 +ATOM 6230 HW2 HOH 1919 32.980 37.000 28.690 1.00 0.00 +ATOM 6231 OW HOH 1920 32.600 43.400 32.460 1.00 0.00 +ATOM 6232 HW1 HOH 1920 32.560 44.070 31.770 1.00 0.00 +ATOM 6233 HW2 HOH 1920 32.360 43.870 33.260 1.00 0.00 +ATOM 6234 OW HOH 1921 25.100 27.830 1.970 1.00 0.00 +ATOM 6235 HW1 HOH 1921 24.530 27.540 2.680 1.00 0.00 +ATOM 6236 HW2 HOH 1921 25.990 27.600 2.260 1.00 0.00 +ATOM 6237 OW HOH 1922 44.110 3.510 20.430 1.00 0.00 +ATOM 6238 HW1 HOH 1922 44.620 3.460 21.240 1.00 0.00 +ATOM 6239 HW2 HOH 1922 43.200 3.460 20.710 1.00 0.00 +ATOM 6240 OW HOH 1923 21.270 40.090 17.220 1.00 0.00 +ATOM 6241 HW1 HOH 1923 21.660 40.500 18.000 1.00 0.00 +ATOM 6242 HW2 HOH 1923 20.330 40.260 17.310 1.00 0.00 +ATOM 6243 OW HOH 1924 5.510 1.320 33.130 1.00 0.00 +ATOM 6244 HW1 HOH 1924 4.950 0.970 32.430 1.00 0.00 +ATOM 6245 HW2 HOH 1924 5.090 2.140 33.380 1.00 0.00 +ATOM 6246 OW HOH 1925 12.340 40.250 25.560 1.00 0.00 +ATOM 6247 HW1 HOH 1925 13.120 39.740 25.340 1.00 0.00 +ATOM 6248 HW2 HOH 1925 11.620 39.780 25.150 1.00 0.00 +ATOM 6249 OW HOH 1926 26.250 19.000 5.970 1.00 0.00 +ATOM 6250 HW1 HOH 1926 25.300 18.960 6.090 1.00 0.00 +ATOM 6251 HW2 HOH 1926 26.580 18.200 6.390 1.00 0.00 +ATOM 6252 OW HOH 1927 20.500 1.110 10.500 1.00 0.00 +ATOM 6253 HW1 HOH 1927 19.970 1.580 9.850 1.00 0.00 +ATOM 6254 HW2 HOH 1927 21.200 1.720 10.720 1.00 0.00 +ATOM 6255 OW HOH 1928 37.320 14.670 37.240 1.00 0.00 +ATOM 6256 HW1 HOH 1928 36.550 14.140 37.450 1.00 0.00 +ATOM 6257 HW2 HOH 1928 37.130 15.050 36.390 1.00 0.00 +ATOM 6258 OW HOH 1929 39.710 2.600 13.950 1.00 0.00 +ATOM 6259 HW1 HOH 1929 40.030 3.400 14.370 1.00 0.00 +ATOM 6260 HW2 HOH 1929 40.510 2.110 13.760 1.00 0.00 +ATOM 6261 OW HOH 1930 34.740 32.580 25.510 1.00 0.00 +ATOM 6262 HW1 HOH 1930 34.270 33.410 25.410 1.00 0.00 +ATOM 6263 HW2 HOH 1930 34.300 31.980 24.910 1.00 0.00 +ATOM 6264 OW HOH 1931 22.740 36.180 36.980 1.00 0.00 +ATOM 6265 HW1 HOH 1931 23.520 36.610 37.340 1.00 0.00 +ATOM 6266 HW2 HOH 1931 22.300 35.800 37.740 1.00 0.00 +ATOM 6267 OW HOH 1932 15.790 8.480 11.820 1.00 0.00 +ATOM 6268 HW1 HOH 1932 16.460 9.060 11.460 1.00 0.00 +ATOM 6269 HW2 HOH 1932 16.210 8.070 12.580 1.00 0.00 +ATOM 6270 OW HOH 1933 37.570 42.280 27.380 1.00 0.00 +ATOM 6271 HW1 HOH 1933 37.370 43.000 27.990 1.00 0.00 +ATOM 6272 HW2 HOH 1933 37.670 42.710 26.530 1.00 0.00 +ATOM 6273 OW HOH 1934 38.890 1.580 2.890 1.00 0.00 +ATOM 6274 HW1 HOH 1934 38.060 1.640 3.350 1.00 0.00 +ATOM 6275 HW2 HOH 1934 38.860 2.290 2.250 1.00 0.00 +ATOM 6276 OW HOH 1935 43.480 19.410 17.490 1.00 0.00 +ATOM 6277 HW1 HOH 1935 42.810 20.090 17.370 1.00 0.00 +ATOM 6278 HW2 HOH 1935 42.980 18.610 17.640 1.00 0.00 +ATOM 6279 OW HOH 1936 46.770 31.030 0.240 1.00 0.00 +ATOM 6280 HW1 HOH 1936 47.400 31.090 0.960 1.00 0.00 +ATOM 6281 HW2 HOH 1936 46.930 30.170 -0.140 1.00 0.00 +ATOM 6282 OW HOH 1937 25.140 41.970 28.680 1.00 0.00 +ATOM 6283 HW1 HOH 1937 25.630 42.800 28.720 1.00 0.00 +ATOM 6284 HW2 HOH 1937 24.580 42.070 27.910 1.00 0.00 +ATOM 6285 OW HOH 1938 17.830 18.760 0.100 1.00 0.00 +ATOM 6286 HW1 HOH 1938 18.510 19.360 -0.220 1.00 0.00 +ATOM 6287 HW2 HOH 1938 18.200 18.370 0.890 1.00 0.00 +ATOM 6288 OW HOH 1939 24.020 4.410 21.090 1.00 0.00 +ATOM 6289 HW1 HOH 1939 23.920 5.030 20.370 1.00 0.00 +ATOM 6290 HW2 HOH 1939 23.210 3.910 21.080 1.00 0.00 +ATOM 6291 OW HOH 1940 13.620 12.890 35.550 1.00 0.00 +ATOM 6292 HW1 HOH 1940 14.040 13.570 35.020 1.00 0.00 +ATOM 6293 HW2 HOH 1940 14.350 12.430 35.960 1.00 0.00 +ATOM 6294 OW HOH 1941 47.800 13.460 16.000 1.00 0.00 +ATOM 6295 HW1 HOH 1941 48.080 14.050 16.700 1.00 0.00 +ATOM 6296 HW2 HOH 1941 46.970 13.830 15.690 1.00 0.00 +ATOM 6297 OW HOH 1942 32.130 10.030 1.750 1.00 0.00 +ATOM 6298 HW1 HOH 1942 32.480 10.330 0.920 1.00 0.00 +ATOM 6299 HW2 HOH 1942 32.500 10.620 2.400 1.00 0.00 +ATOM 6300 OW HOH 1943 32.600 3.810 35.490 1.00 0.00 +ATOM 6301 HW1 HOH 1943 32.510 2.920 35.160 1.00 0.00 +ATOM 6302 HW2 HOH 1943 31.940 4.310 35.000 1.00 0.00 +ATOM 6303 OW HOH 1944 24.020 38.220 -0.110 1.00 0.00 +ATOM 6304 HW1 HOH 1944 24.820 38.110 0.400 1.00 0.00 +ATOM 6305 HW2 HOH 1944 23.360 38.510 0.520 1.00 0.00 +ATOM 6306 OW HOH 1945 33.500 34.310 16.110 1.00 0.00 +ATOM 6307 HW1 HOH 1945 33.440 33.760 16.890 1.00 0.00 +ATOM 6308 HW2 HOH 1945 32.730 34.070 15.590 1.00 0.00 +ATOM 6309 OW HOH 1946 28.150 40.540 6.000 1.00 0.00 +ATOM 6310 HW1 HOH 1946 28.210 40.810 5.090 1.00 0.00 +ATOM 6311 HW2 HOH 1946 27.210 40.470 6.170 1.00 0.00 +ATOM 6312 OW HOH 1947 25.200 15.490 29.470 1.00 0.00 +ATOM 6313 HW1 HOH 1947 24.660 14.710 29.310 1.00 0.00 +ATOM 6314 HW2 HOH 1947 25.490 15.760 28.590 1.00 0.00 +ATOM 6315 OW HOH 1948 4.530 32.850 7.620 1.00 0.00 +ATOM 6316 HW1 HOH 1948 3.750 32.400 7.940 1.00 0.00 +ATOM 6317 HW2 HOH 1948 4.450 33.750 7.940 1.00 0.00 +ATOM 6318 OW HOH 1949 34.600 37.460 26.530 1.00 0.00 +ATOM 6319 HW1 HOH 1949 34.410 37.280 27.450 1.00 0.00 +ATOM 6320 HW2 HOH 1949 35.550 37.530 26.490 1.00 0.00 +ATOM 6321 OW HOH 1950 16.050 32.030 8.460 1.00 0.00 +ATOM 6322 HW1 HOH 1950 16.640 32.780 8.420 1.00 0.00 +ATOM 6323 HW2 HOH 1950 16.290 31.570 9.270 1.00 0.00 +ATOM 6324 OW HOH 1951 43.000 8.520 31.870 1.00 0.00 +ATOM 6325 HW1 HOH 1951 43.240 8.950 31.040 1.00 0.00 +ATOM 6326 HW2 HOH 1951 42.060 8.660 31.950 1.00 0.00 +ATOM 6327 OW HOH 1952 4.160 28.590 15.220 1.00 0.00 +ATOM 6328 HW1 HOH 1952 3.940 27.750 14.830 1.00 0.00 +ATOM 6329 HW2 HOH 1952 5.020 28.800 14.870 1.00 0.00 +ATOM 6330 OW HOH 1953 35.000 21.010 22.530 1.00 0.00 +ATOM 6331 HW1 HOH 1953 34.100 21.230 22.320 1.00 0.00 +ATOM 6332 HW2 HOH 1953 35.420 20.870 21.690 1.00 0.00 +ATOM 6333 OW HOH 1954 33.240 31.560 10.610 1.00 0.00 +ATOM 6334 HW1 HOH 1954 33.690 32.010 9.890 1.00 0.00 +ATOM 6335 HW2 HOH 1954 33.940 31.080 11.060 1.00 0.00 +ATOM 6336 OW HOH 1955 31.150 8.550 28.500 1.00 0.00 +ATOM 6337 HW1 HOH 1955 30.290 8.900 28.250 1.00 0.00 +ATOM 6338 HW2 HOH 1955 31.260 8.810 29.410 1.00 0.00 +ATOM 6339 OW HOH 1956 22.990 26.240 7.260 1.00 0.00 +ATOM 6340 HW1 HOH 1956 23.010 26.280 6.310 1.00 0.00 +ATOM 6341 HW2 HOH 1956 23.830 25.860 7.510 1.00 0.00 +ATOM 6342 OW HOH 1957 36.590 1.390 22.960 1.00 0.00 +ATOM 6343 HW1 HOH 1957 35.690 1.190 22.710 1.00 0.00 +ATOM 6344 HW2 HOH 1957 37.100 0.640 22.650 1.00 0.00 +ATOM 6345 OW HOH 1958 34.260 26.730 3.550 1.00 0.00 +ATOM 6346 HW1 HOH 1958 33.580 26.340 3.010 1.00 0.00 +ATOM 6347 HW2 HOH 1958 33.790 27.270 4.180 1.00 0.00 +ATOM 6348 OW HOH 1959 30.820 10.090 24.240 1.00 0.00 +ATOM 6349 HW1 HOH 1959 31.570 9.500 24.240 1.00 0.00 +ATOM 6350 HW2 HOH 1959 31.140 10.890 23.810 1.00 0.00 +ATOM 6351 OW HOH 1960 10.610 12.570 6.370 1.00 0.00 +ATOM 6352 HW1 HOH 1960 11.050 13.320 5.970 1.00 0.00 +ATOM 6353 HW2 HOH 1960 10.030 12.960 7.020 1.00 0.00 +ATOM 6354 OW HOH 1961 14.940 12.900 0.390 1.00 0.00 +ATOM 6355 HW1 HOH 1961 15.320 12.530 -0.410 1.00 0.00 +ATOM 6356 HW2 HOH 1961 14.410 13.640 0.100 1.00 0.00 +ATOM 6357 OW HOH 1962 35.960 3.330 26.970 1.00 0.00 +ATOM 6358 HW1 HOH 1962 35.720 4.260 26.870 1.00 0.00 +ATOM 6359 HW2 HOH 1962 36.250 3.070 26.100 1.00 0.00 +ATOM 6360 OW HOH 1963 32.350 41.490 22.570 1.00 0.00 +ATOM 6361 HW1 HOH 1963 32.140 42.390 22.300 1.00 0.00 +ATOM 6362 HW2 HOH 1963 33.290 41.510 22.740 1.00 0.00 +ATOM 6363 OW HOH 1964 28.870 41.040 37.680 1.00 0.00 +ATOM 6364 HW1 HOH 1964 28.510 41.000 38.560 1.00 0.00 +ATOM 6365 HW2 HOH 1964 29.000 40.130 37.430 1.00 0.00 +ATOM 6366 OW HOH 1965 8.550 34.740 30.240 1.00 0.00 +ATOM 6367 HW1 HOH 1965 7.850 35.300 30.580 1.00 0.00 +ATOM 6368 HW2 HOH 1965 9.330 35.000 30.750 1.00 0.00 +ATOM 6369 OW HOH 1966 2.310 31.690 30.440 1.00 0.00 +ATOM 6370 HW1 HOH 1966 2.770 31.000 29.970 1.00 0.00 +ATOM 6371 HW2 HOH 1966 2.270 31.380 31.340 1.00 0.00 +ATOM 6372 OW HOH 1967 32.320 11.470 9.530 1.00 0.00 +ATOM 6373 HW1 HOH 1967 31.970 12.190 9.000 1.00 0.00 +ATOM 6374 HW2 HOH 1967 33.120 11.210 9.070 1.00 0.00 +ATOM 6375 OW HOH 1968 26.430 41.790 18.780 1.00 0.00 +ATOM 6376 HW1 HOH 1968 26.330 40.880 19.070 1.00 0.00 +ATOM 6377 HW2 HOH 1968 27.370 41.930 18.740 1.00 0.00 +ATOM 6378 OW HOH 1969 20.570 6.580 34.430 1.00 0.00 +ATOM 6379 HW1 HOH 1969 21.460 6.880 34.600 1.00 0.00 +ATOM 6380 HW2 HOH 1969 20.020 7.180 34.930 1.00 0.00 +ATOM 6381 OW HOH 1970 25.970 39.520 27.950 1.00 0.00 +ATOM 6382 HW1 HOH 1970 25.630 40.380 28.200 1.00 0.00 +ATOM 6383 HW2 HOH 1970 25.200 38.950 27.920 1.00 0.00 +ATOM 6384 OW HOH 1971 32.250 11.120 29.470 1.00 0.00 +ATOM 6385 HW1 HOH 1971 31.820 11.930 29.750 1.00 0.00 +ATOM 6386 HW2 HOH 1971 32.250 11.170 28.510 1.00 0.00 +ATOM 6387 OW HOH 1972 35.070 1.180 1.300 1.00 0.00 +ATOM 6388 HW1 HOH 1972 34.710 0.370 1.650 1.00 0.00 +ATOM 6389 HW2 HOH 1972 34.300 1.710 1.080 1.00 0.00 +ATOM 6390 OW HOH 1973 12.680 18.270 8.420 1.00 0.00 +ATOM 6391 HW1 HOH 1973 12.230 19.000 8.850 1.00 0.00 +ATOM 6392 HW2 HOH 1973 12.530 17.520 8.990 1.00 0.00 +ATOM 6393 OW HOH 1974 23.100 0.940 24.490 1.00 0.00 +ATOM 6394 HW1 HOH 1974 23.070 0.020 24.240 1.00 0.00 +ATOM 6395 HW2 HOH 1974 23.900 1.280 24.070 1.00 0.00 +ATOM 6396 OW HOH 1975 40.880 1.090 9.890 1.00 0.00 +ATOM 6397 HW1 HOH 1975 41.660 0.760 10.340 1.00 0.00 +ATOM 6398 HW2 HOH 1975 41.220 1.600 9.160 1.00 0.00 +ATOM 6399 OW HOH 1976 38.540 34.270 19.490 1.00 0.00 +ATOM 6400 HW1 HOH 1976 37.940 34.480 20.200 1.00 0.00 +ATOM 6401 HW2 HOH 1976 39.340 33.980 19.920 1.00 0.00 +ATOM 6402 OW HOH 1977 7.020 15.880 18.510 1.00 0.00 +ATOM 6403 HW1 HOH 1977 6.110 15.880 18.210 1.00 0.00 +ATOM 6404 HW2 HOH 1977 7.460 15.220 17.980 1.00 0.00 +ATOM 6405 OW HOH 1978 13.350 22.870 36.060 1.00 0.00 +ATOM 6406 HW1 HOH 1978 13.700 22.890 35.170 1.00 0.00 +ATOM 6407 HW2 HOH 1978 12.400 22.910 35.940 1.00 0.00 +ATOM 6408 OW HOH 1979 15.280 24.750 2.210 1.00 0.00 +ATOM 6409 HW1 HOH 1979 15.250 24.460 1.290 1.00 0.00 +ATOM 6410 HW2 HOH 1979 15.900 24.150 2.630 1.00 0.00 +ATOM 6411 OW HOH 1980 6.300 33.800 11.660 1.00 0.00 +ATOM 6412 HW1 HOH 1980 6.210 33.080 11.040 1.00 0.00 +ATOM 6413 HW2 HOH 1980 6.680 34.510 11.140 1.00 0.00 +ATOM 6414 OW HOH 1981 26.720 44.080 27.730 1.00 0.00 +ATOM 6415 HW1 HOH 1981 27.560 43.750 27.420 1.00 0.00 +ATOM 6416 HW2 HOH 1981 26.310 44.460 26.940 1.00 0.00 +ATOM 6417 OW HOH 1982 46.330 37.350 30.250 1.00 0.00 +ATOM 6418 HW1 HOH 1982 46.460 36.410 30.300 1.00 0.00 +ATOM 6419 HW2 HOH 1982 45.520 37.450 29.740 1.00 0.00 +ATOM 6420 OW HOH 1983 48.370 3.330 18.720 1.00 0.00 +ATOM 6421 HW1 HOH 1983 47.470 3.430 18.400 1.00 0.00 +ATOM 6422 HW2 HOH 1983 48.510 4.070 19.300 1.00 0.00 +ATOM 6423 OW HOH 1984 7.380 14.860 26.200 1.00 0.00 +ATOM 6424 HW1 HOH 1984 7.660 14.110 26.730 1.00 0.00 +ATOM 6425 HW2 HOH 1984 7.270 14.510 25.320 1.00 0.00 +ATOM 6426 OW HOH 1985 24.180 42.550 12.770 1.00 0.00 +ATOM 6427 HW1 HOH 1985 23.380 42.960 13.110 1.00 0.00 +ATOM 6428 HW2 HOH 1985 24.630 42.220 13.550 1.00 0.00 +ATOM 6429 OW HOH 1986 46.550 37.240 18.530 1.00 0.00 +ATOM 6430 HW1 HOH 1986 45.720 37.110 18.070 1.00 0.00 +ATOM 6431 HW2 HOH 1986 46.980 37.940 18.040 1.00 0.00 +ATOM 6432 OW HOH 1987 9.230 41.710 17.230 1.00 0.00 +ATOM 6433 HW1 HOH 1987 9.610 40.970 16.750 1.00 0.00 +ATOM 6434 HW2 HOH 1987 9.930 42.360 17.260 1.00 0.00 +ATOM 6435 OW HOH 1988 32.280 1.420 34.350 1.00 0.00 +ATOM 6436 HW1 HOH 1988 32.160 0.540 34.700 1.00 0.00 +ATOM 6437 HW2 HOH 1988 33.150 1.400 33.940 1.00 0.00 +ATOM 6438 OW HOH 1989 4.180 34.190 5.120 1.00 0.00 +ATOM 6439 HW1 HOH 1989 5.000 34.660 5.080 1.00 0.00 +ATOM 6440 HW2 HOH 1989 4.210 33.720 5.960 1.00 0.00 +ATOM 6441 OW HOH 1990 7.980 15.010 2.920 1.00 0.00 +ATOM 6442 HW1 HOH 1990 7.290 14.450 2.560 1.00 0.00 +ATOM 6443 HW2 HOH 1990 8.740 14.430 3.010 1.00 0.00 +ATOM 6444 OW HOH 1991 38.390 19.830 8.510 1.00 0.00 +ATOM 6445 HW1 HOH 1991 39.110 19.230 8.720 1.00 0.00 +ATOM 6446 HW2 HOH 1991 38.080 20.140 9.350 1.00 0.00 +ATOM 6447 OW HOH 1992 40.180 40.330 4.500 1.00 0.00 +ATOM 6448 HW1 HOH 1992 40.890 40.900 4.810 1.00 0.00 +ATOM 6449 HW2 HOH 1992 39.930 39.810 5.260 1.00 0.00 +ATOM 6450 OW HOH 1993 20.390 2.870 6.480 1.00 0.00 +ATOM 6451 HW1 HOH 1993 20.970 2.450 7.110 1.00 0.00 +ATOM 6452 HW2 HOH 1993 20.450 2.320 5.700 1.00 0.00 +ATOM 6453 OW HOH 1994 28.830 35.770 33.360 1.00 0.00 +ATOM 6454 HW1 HOH 1994 28.140 35.740 34.020 1.00 0.00 +ATOM 6455 HW2 HOH 1994 29.350 34.980 33.520 1.00 0.00 +ATOM 6456 OW HOH 1995 35.310 9.590 21.750 1.00 0.00 +ATOM 6457 HW1 HOH 1995 35.670 8.940 22.360 1.00 0.00 +ATOM 6458 HW2 HOH 1995 34.530 9.170 21.390 1.00 0.00 +ATOM 6459 OW HOH 1996 39.080 28.330 1.880 1.00 0.00 +ATOM 6460 HW1 HOH 1996 39.670 29.070 2.000 1.00 0.00 +ATOM 6461 HW2 HOH 1996 38.340 28.510 2.450 1.00 0.00 +ATOM 6462 OW HOH 1997 22.200 31.850 17.620 1.00 0.00 +ATOM 6463 HW1 HOH 1997 21.330 31.710 18.000 1.00 0.00 +ATOM 6464 HW2 HOH 1997 22.120 32.670 17.130 1.00 0.00 +ATOM 6465 OW HOH 1998 43.010 45.950 0.740 1.00 0.00 +ATOM 6466 HW1 HOH 1998 42.310 45.760 0.110 1.00 0.00 +ATOM 6467 HW2 HOH 1998 42.670 45.630 1.580 1.00 0.00 +ATOM 6468 OW HOH 1999 32.030 25.220 11.140 1.00 0.00 +ATOM 6469 HW1 HOH 1999 32.920 25.250 10.780 1.00 0.00 +ATOM 6470 HW2 HOH 1999 31.990 25.950 11.750 1.00 0.00 +ATOM 6471 OW HOH 2000 2.120 8.040 32.350 1.00 0.00 +ATOM 6472 HW1 HOH 2000 2.970 8.220 31.940 1.00 0.00 +ATOM 6473 HW2 HOH 2000 2.140 8.500 33.180 1.00 0.00 +ATOM 6474 OW HOH 2001 26.120 15.060 24.500 1.00 0.00 +ATOM 6475 HW1 HOH 2001 25.300 15.050 24.990 1.00 0.00 +ATOM 6476 HW2 HOH 2001 26.640 14.350 24.880 1.00 0.00 +ATOM 6477 OW HOH 2002 35.710 43.640 37.960 1.00 0.00 +ATOM 6478 HW1 HOH 2002 35.280 44.050 37.200 1.00 0.00 +ATOM 6479 HW2 HOH 2002 35.020 43.600 38.630 1.00 0.00 +ATOM 6480 OW HOH 2003 29.650 2.980 27.440 1.00 0.00 +ATOM 6481 HW1 HOH 2003 29.850 3.160 26.530 1.00 0.00 +ATOM 6482 HW2 HOH 2003 29.680 2.030 27.510 1.00 0.00 +ATOM 6483 OW HOH 2004 32.910 26.400 27.940 1.00 0.00 +ATOM 6484 HW1 HOH 2004 33.580 27.050 27.710 1.00 0.00 +ATOM 6485 HW2 HOH 2004 32.850 26.460 28.890 1.00 0.00 +ATOM 6486 OW HOH 2005 20.170 21.000 37.650 1.00 0.00 +ATOM 6487 HW1 HOH 2005 20.550 21.800 37.300 1.00 0.00 +ATOM 6488 HW2 HOH 2005 20.150 21.140 38.590 1.00 0.00 +ATOM 6489 OW HOH 2006 23.390 2.800 26.830 1.00 0.00 +ATOM 6490 HW1 HOH 2006 23.070 2.510 25.980 1.00 0.00 +ATOM 6491 HW2 HOH 2006 23.380 3.750 26.780 1.00 0.00 +ATOM 6492 OW HOH 2007 44.540 37.110 1.410 1.00 0.00 +ATOM 6493 HW1 HOH 2007 43.600 37.210 1.250 1.00 0.00 +ATOM 6494 HW2 HOH 2007 44.790 36.330 0.910 1.00 0.00 +ATOM 6495 OW HOH 2008 48.470 20.550 28.410 1.00 0.00 +ATOM 6496 HW1 HOH 2008 47.770 20.710 27.790 1.00 0.00 +ATOM 6497 HW2 HOH 2008 49.270 20.560 27.890 1.00 0.00 +ATOM 6498 OW HOH 2009 2.320 1.600 38.910 1.00 0.00 +ATOM 6499 HW1 HOH 2009 2.620 2.420 39.310 1.00 0.00 +ATOM 6500 HW2 HOH 2009 2.980 1.390 38.260 1.00 0.00 +ATOM 6501 OW HOH 2010 49.370 20.320 23.740 1.00 0.00 +ATOM 6502 HW1 HOH 2010 49.360 19.410 23.440 1.00 0.00 +ATOM 6503 HW2 HOH 2010 48.460 20.490 23.990 1.00 0.00 +ATOM 6504 OW HOH 2011 35.390 15.650 35.030 1.00 0.00 +ATOM 6505 HW1 HOH 2011 34.990 14.830 35.340 1.00 0.00 +ATOM 6506 HW2 HOH 2011 36.000 15.380 34.350 1.00 0.00 +ATOM 6507 OW HOH 2012 48.480 25.220 9.270 1.00 0.00 +ATOM 6508 HW1 HOH 2012 48.570 25.570 8.390 1.00 0.00 +ATOM 6509 HW2 HOH 2012 48.870 24.340 9.220 1.00 0.00 +ATOM 6510 OW HOH 2013 41.720 14.590 14.490 1.00 0.00 +ATOM 6511 HW1 HOH 2013 42.140 15.200 13.880 1.00 0.00 +ATOM 6512 HW2 HOH 2013 40.970 14.250 14.000 1.00 0.00 +ATOM 6513 OW HOH 2014 16.800 14.970 20.690 1.00 0.00 +ATOM 6514 HW1 HOH 2014 16.470 14.300 21.290 1.00 0.00 +ATOM 6515 HW2 HOH 2014 17.160 15.650 21.270 1.00 0.00 +ATOM 6516 OW HOH 2015 5.720 11.120 19.160 1.00 0.00 +ATOM 6517 HW1 HOH 2015 5.850 10.650 18.340 1.00 0.00 +ATOM 6518 HW2 HOH 2015 6.550 11.580 19.300 1.00 0.00 +ATOM 6519 OW HOH 2016 28.670 4.950 21.200 1.00 0.00 +ATOM 6520 HW1 HOH 2016 29.370 4.650 21.770 1.00 0.00 +ATOM 6521 HW2 HOH 2016 29.010 4.830 20.320 1.00 0.00 +ATOM 6522 OW HOH 2017 36.720 43.320 17.060 1.00 0.00 +ATOM 6523 HW1 HOH 2017 36.880 43.430 16.120 1.00 0.00 +ATOM 6524 HW2 HOH 2017 35.770 43.170 17.130 1.00 0.00 +ATOM 6525 OW HOH 2018 31.280 11.850 14.620 1.00 0.00 +ATOM 6526 HW1 HOH 2018 31.550 10.950 14.450 1.00 0.00 +ATOM 6527 HW2 HOH 2018 30.840 12.130 13.810 1.00 0.00 +ATOM 6528 OW HOH 2019 27.410 2.460 18.310 1.00 0.00 +ATOM 6529 HW1 HOH 2019 26.700 2.350 17.680 1.00 0.00 +ATOM 6530 HW2 HOH 2019 27.020 2.940 19.040 1.00 0.00 +ATOM 6531 OW HOH 2020 11.550 45.300 26.240 1.00 0.00 +ATOM 6532 HW1 HOH 2020 11.230 45.520 25.370 1.00 0.00 +ATOM 6533 HW2 HOH 2020 11.620 44.340 26.240 1.00 0.00 +ATOM 6534 OW HOH 2021 11.510 11.420 25.390 1.00 0.00 +ATOM 6535 HW1 HOH 2021 10.980 10.650 25.170 1.00 0.00 +ATOM 6536 HW2 HOH 2021 12.310 11.050 25.770 1.00 0.00 +ATOM 6537 OW HOH 2022 24.500 8.960 6.350 1.00 0.00 +ATOM 6538 HW1 HOH 2022 24.210 9.860 6.510 1.00 0.00 +ATOM 6539 HW2 HOH 2022 24.300 8.810 5.430 1.00 0.00 +ATOM 6540 OW HOH 2023 2.950 37.840 14.580 1.00 0.00 +ATOM 6541 HW1 HOH 2023 3.260 38.230 15.400 1.00 0.00 +ATOM 6542 HW2 HOH 2023 2.000 37.990 14.600 1.00 0.00 +ATOM 6543 OW HOH 2024 42.440 7.680 15.200 1.00 0.00 +ATOM 6544 HW1 HOH 2024 43.080 7.890 14.520 1.00 0.00 +ATOM 6545 HW2 HOH 2024 42.760 6.870 15.590 1.00 0.00 +ATOM 6546 OW HOH 2025 28.410 12.540 28.730 1.00 0.00 +ATOM 6547 HW1 HOH 2025 28.860 12.370 27.900 1.00 0.00 +ATOM 6548 HW2 HOH 2025 27.490 12.600 28.500 1.00 0.00 +ATOM 6549 OW HOH 2026 40.820 0.910 36.150 1.00 0.00 +ATOM 6550 HW1 HOH 2026 40.350 0.590 35.380 1.00 0.00 +ATOM 6551 HW2 HOH 2026 40.730 0.220 36.800 1.00 0.00 +ATOM 6552 OW HOH 2027 30.740 7.040 11.030 1.00 0.00 +ATOM 6553 HW1 HOH 2027 29.800 6.860 11.080 1.00 0.00 +ATOM 6554 HW2 HOH 2027 30.790 7.960 10.760 1.00 0.00 +ATOM 6555 OW HOH 2028 9.710 2.010 10.670 1.00 0.00 +ATOM 6556 HW1 HOH 2028 10.590 1.680 10.830 1.00 0.00 +ATOM 6557 HW2 HOH 2028 9.810 2.960 10.610 1.00 0.00 +ATOM 6558 OW HOH 2029 36.960 11.240 20.090 1.00 0.00 +ATOM 6559 HW1 HOH 2029 36.470 10.890 20.830 1.00 0.00 +ATOM 6560 HW2 HOH 2029 36.700 12.160 20.040 1.00 0.00 +ATOM 6561 OW HOH 2030 29.380 15.790 28.760 1.00 0.00 +ATOM 6562 HW1 HOH 2030 30.220 15.380 28.990 1.00 0.00 +ATOM 6563 HW2 HOH 2030 29.410 16.650 29.200 1.00 0.00 +ATOM 6564 OW HOH 2031 26.820 11.900 9.550 1.00 0.00 +ATOM 6565 HW1 HOH 2031 26.760 11.170 8.940 1.00 0.00 +ATOM 6566 HW2 HOH 2031 27.040 11.490 10.390 1.00 0.00 +ATOM 6567 OW HOH 2032 6.090 14.060 35.910 1.00 0.00 +ATOM 6568 HW1 HOH 2032 5.310 14.420 36.340 1.00 0.00 +ATOM 6569 HW2 HOH 2032 6.220 14.610 35.140 1.00 0.00 +ATOM 6570 OW HOH 2033 4.180 1.150 36.680 1.00 0.00 +ATOM 6571 HW1 HOH 2033 4.540 1.970 36.350 1.00 0.00 +ATOM 6572 HW2 HOH 2033 4.950 0.600 36.850 1.00 0.00 +ATOM 6573 OW HOH 2034 42.340 12.790 36.110 1.00 0.00 +ATOM 6574 HW1 HOH 2034 41.560 13.240 36.420 1.00 0.00 +ATOM 6575 HW2 HOH 2034 42.940 13.490 35.860 1.00 0.00 +ATOM 6576 OW HOH 2035 19.410 33.680 6.600 1.00 0.00 +ATOM 6577 HW1 HOH 2035 19.760 34.340 6.010 1.00 0.00 +ATOM 6578 HW2 HOH 2035 19.120 32.970 6.020 1.00 0.00 +ATOM 6579 OW HOH 2036 11.740 4.000 12.640 1.00 0.00 +ATOM 6580 HW1 HOH 2036 11.530 4.940 12.620 1.00 0.00 +ATOM 6581 HW2 HOH 2036 11.470 3.670 11.780 1.00 0.00 +ATOM 6582 OW HOH 2037 36.470 36.530 9.490 1.00 0.00 +ATOM 6583 HW1 HOH 2037 35.540 36.440 9.650 1.00 0.00 +ATOM 6584 HW2 HOH 2037 36.870 36.590 10.360 1.00 0.00 +ATOM 6585 OW HOH 2038 41.190 11.820 6.360 1.00 0.00 +ATOM 6586 HW1 HOH 2038 40.640 11.430 5.680 1.00 0.00 +ATOM 6587 HW2 HOH 2038 40.770 11.590 7.180 1.00 0.00 +ATOM 6588 OW HOH 2039 38.930 21.130 1.960 1.00 0.00 +ATOM 6589 HW1 HOH 2039 38.130 21.040 1.430 1.00 0.00 +ATOM 6590 HW2 HOH 2039 39.320 21.950 1.660 1.00 0.00 +ATOM 6591 OW HOH 2040 40.430 24.060 8.750 1.00 0.00 +ATOM 6592 HW1 HOH 2040 39.590 24.060 8.300 1.00 0.00 +ATOM 6593 HW2 HOH 2040 40.800 23.200 8.560 1.00 0.00 +ATOM 6594 OW HOH 2041 3.260 7.450 3.450 1.00 0.00 +ATOM 6595 HW1 HOH 2041 4.200 7.600 3.310 1.00 0.00 +ATOM 6596 HW2 HOH 2041 3.190 7.270 4.390 1.00 0.00 +ATOM 6597 OW HOH 2042 10.220 24.790 21.360 1.00 0.00 +ATOM 6598 HW1 HOH 2042 10.540 24.410 20.540 1.00 0.00 +ATOM 6599 HW2 HOH 2042 9.290 24.950 21.200 1.00 0.00 +ATOM 6600 OW HOH 2043 14.890 11.060 20.640 1.00 0.00 +ATOM 6601 HW1 HOH 2043 14.630 11.230 21.540 1.00 0.00 +ATOM 6602 HW2 HOH 2043 15.600 10.420 20.710 1.00 0.00 +ATOM 6603 OW HOH 2044 35.140 3.160 12.080 1.00 0.00 +ATOM 6604 HW1 HOH 2044 35.880 3.030 12.680 1.00 0.00 +ATOM 6605 HW2 HOH 2044 34.390 3.340 12.650 1.00 0.00 +ATOM 6606 OW HOH 2045 11.740 9.640 36.160 1.00 0.00 +ATOM 6607 HW1 HOH 2045 11.470 10.020 37.000 1.00 0.00 +ATOM 6608 HW2 HOH 2045 12.670 9.860 36.080 1.00 0.00 +ATOM 6609 OW HOH 2046 36.510 15.490 3.400 1.00 0.00 +ATOM 6610 HW1 HOH 2046 36.570 14.600 3.060 1.00 0.00 +ATOM 6611 HW2 HOH 2046 35.830 15.910 2.870 1.00 0.00 +ATOM 6612 OW HOH 2047 38.940 39.120 6.740 1.00 0.00 +ATOM 6613 HW1 HOH 2047 38.580 38.350 6.310 1.00 0.00 +ATOM 6614 HW2 HOH 2047 38.790 38.970 7.680 1.00 0.00 +ATOM 6615 OW HOH 2048 39.550 39.980 1.700 1.00 0.00 +ATOM 6616 HW1 HOH 2048 40.200 40.020 1.010 1.00 0.00 +ATOM 6617 HW2 HOH 2048 40.050 39.980 2.510 1.00 0.00 +ATOM 6618 OW HOH 2049 31.190 44.130 19.010 1.00 0.00 +ATOM 6619 HW1 HOH 2049 31.140 43.560 18.240 1.00 0.00 +ATOM 6620 HW2 HOH 2049 30.620 44.870 18.800 1.00 0.00 +ATOM 6621 OW HOH 2050 40.620 28.380 23.640 1.00 0.00 +ATOM 6622 HW1 HOH 2050 40.020 28.710 22.970 1.00 0.00 +ATOM 6623 HW2 HOH 2050 41.140 27.710 23.190 1.00 0.00 +ATOM 6624 OW HOH 2051 25.480 3.790 8.760 1.00 0.00 +ATOM 6625 HW1 HOH 2051 25.090 3.000 9.120 1.00 0.00 +ATOM 6626 HW2 HOH 2051 26.050 3.480 8.050 1.00 0.00 +ATOM 6627 OW HOH 2052 7.320 10.200 3.390 1.00 0.00 +ATOM 6628 HW1 HOH 2052 8.220 10.160 3.730 1.00 0.00 +ATOM 6629 HW2 HOH 2052 7.160 11.140 3.260 1.00 0.00 +ATOM 6630 OW HOH 2053 23.770 2.940 30.810 1.00 0.00 +ATOM 6631 HW1 HOH 2053 24.080 2.310 31.460 1.00 0.00 +ATOM 6632 HW2 HOH 2053 24.550 3.440 30.560 1.00 0.00 +ATOM 6633 OW HOH 2054 18.680 9.280 18.140 1.00 0.00 +ATOM 6634 HW1 HOH 2054 19.280 9.800 18.670 1.00 0.00 +ATOM 6635 HW2 HOH 2054 18.500 8.500 18.680 1.00 0.00 +ATOM 6636 OW HOH 2055 36.690 12.340 6.670 1.00 0.00 +ATOM 6637 HW1 HOH 2055 36.720 12.340 5.720 1.00 0.00 +ATOM 6638 HW2 HOH 2055 37.460 12.830 6.940 1.00 0.00 +ATOM 6639 OW HOH 2056 46.200 7.970 -0.070 1.00 0.00 +ATOM 6640 HW1 HOH 2056 46.470 8.700 0.480 1.00 0.00 +ATOM 6641 HW2 HOH 2056 45.340 7.720 0.260 1.00 0.00 +ATOM 6642 OW HOH 2057 39.380 42.430 37.640 1.00 0.00 +ATOM 6643 HW1 HOH 2057 39.400 42.240 36.700 1.00 0.00 +ATOM 6644 HW2 HOH 2057 40.110 41.930 38.000 1.00 0.00 +ATOM 6645 OW HOH 2058 1.520 13.620 34.450 1.00 0.00 +ATOM 6646 HW1 HOH 2058 1.780 14.270 33.800 1.00 0.00 +ATOM 6647 HW2 HOH 2058 1.200 12.880 33.930 1.00 0.00 +ATOM 6648 OW HOH 2059 0.790 28.970 35.080 1.00 0.00 +ATOM 6649 HW1 HOH 2059 1.160 29.150 35.950 1.00 0.00 +ATOM 6650 HW2 HOH 2059 -0.020 29.470 35.050 1.00 0.00 +ATOM 6651 OW HOH 2060 37.590 17.670 18.110 1.00 0.00 +ATOM 6652 HW1 HOH 2060 38.210 17.370 17.440 1.00 0.00 +ATOM 6653 HW2 HOH 2060 38.110 18.220 18.690 1.00 0.00 +ATOM 6654 OW HOH 2061 30.810 42.440 13.570 1.00 0.00 +ATOM 6655 HW1 HOH 2061 31.510 42.020 13.070 1.00 0.00 +ATOM 6656 HW2 HOH 2061 30.010 42.010 13.270 1.00 0.00 +ATOM 6657 OW HOH 2062 7.210 27.660 29.770 1.00 0.00 +ATOM 6658 HW1 HOH 2062 6.470 27.200 29.390 1.00 0.00 +ATOM 6659 HW2 HOH 2062 7.860 26.980 29.930 1.00 0.00 +ATOM 6660 OW HOH 2063 25.280 9.990 35.830 1.00 0.00 +ATOM 6661 HW1 HOH 2063 25.700 9.250 36.270 1.00 0.00 +ATOM 6662 HW2 HOH 2063 25.080 9.670 34.950 1.00 0.00 +ATOM 6663 OW HOH 2064 3.630 30.730 0.840 1.00 0.00 +ATOM 6664 HW1 HOH 2064 4.200 30.340 1.500 1.00 0.00 +ATOM 6665 HW2 HOH 2064 2.870 31.040 1.320 1.00 0.00 +ATOM 6666 OW HOH 2065 32.500 40.840 34.700 1.00 0.00 +ATOM 6667 HW1 HOH 2065 32.400 41.780 34.640 1.00 0.00 +ATOM 6668 HW2 HOH 2065 33.080 40.610 33.970 1.00 0.00 +ATOM 6669 OW HOH 2066 8.160 38.200 32.670 1.00 0.00 +ATOM 6670 HW1 HOH 2066 8.080 39.000 32.150 1.00 0.00 +ATOM 6671 HW2 HOH 2066 7.580 37.570 32.240 1.00 0.00 +ATOM 6672 OW HOH 2067 12.300 11.050 29.860 1.00 0.00 +ATOM 6673 HW1 HOH 2067 12.490 11.270 30.770 1.00 0.00 +ATOM 6674 HW2 HOH 2067 12.550 11.830 29.370 1.00 0.00 +ATOM 6675 OW HOH 2068 28.290 15.550 26.440 1.00 0.00 +ATOM 6676 HW1 HOH 2068 28.750 15.560 27.280 1.00 0.00 +ATOM 6677 HW2 HOH 2068 27.440 15.960 26.630 1.00 0.00 +ATOM 6678 OW HOH 2069 10.330 20.670 20.870 1.00 0.00 +ATOM 6679 HW1 HOH 2069 9.900 21.470 20.580 1.00 0.00 +ATOM 6680 HW2 HOH 2069 11.000 20.960 21.500 1.00 0.00 +ATOM 6681 OW HOH 2070 28.210 24.980 34.620 1.00 0.00 +ATOM 6682 HW1 HOH 2070 28.170 24.400 33.860 1.00 0.00 +ATOM 6683 HW2 HOH 2070 28.660 24.460 35.290 1.00 0.00 +ATOM 6684 OW HOH 2071 38.000 22.930 20.010 1.00 0.00 +ATOM 6685 HW1 HOH 2071 37.180 23.110 20.460 1.00 0.00 +ATOM 6686 HW2 HOH 2071 38.150 22.000 20.130 1.00 0.00 +ATOM 6687 OW HOH 2072 33.600 35.430 0.170 1.00 0.00 +ATOM 6688 HW1 HOH 2072 33.370 36.250 -0.280 1.00 0.00 +ATOM 6689 HW2 HOH 2072 32.830 35.220 0.690 1.00 0.00 +ATOM 6690 OW HOH 2073 47.400 43.740 8.760 1.00 0.00 +ATOM 6691 HW1 HOH 2073 47.740 42.890 8.470 1.00 0.00 +ATOM 6692 HW2 HOH 2073 47.910 44.380 8.250 1.00 0.00 +ATOM 6693 OW HOH 2074 14.220 31.070 37.140 1.00 0.00 +ATOM 6694 HW1 HOH 2074 14.380 31.380 36.240 1.00 0.00 +ATOM 6695 HW2 HOH 2074 13.530 30.420 37.040 1.00 0.00 +ATOM 6696 OW HOH 2075 41.900 16.030 17.260 1.00 0.00 +ATOM 6697 HW1 HOH 2075 42.740 15.860 16.850 1.00 0.00 +ATOM 6698 HW2 HOH 2075 41.590 15.170 17.540 1.00 0.00 +ATOM 6699 OW HOH 2076 12.890 39.950 8.560 1.00 0.00 +ATOM 6700 HW1 HOH 2076 12.160 39.940 9.180 1.00 0.00 +ATOM 6701 HW2 HOH 2076 12.470 39.910 7.700 1.00 0.00 +ATOM 6702 OW HOH 2077 15.470 17.290 17.390 1.00 0.00 +ATOM 6703 HW1 HOH 2077 15.260 16.360 17.310 1.00 0.00 +ATOM 6704 HW2 HOH 2077 16.110 17.340 18.090 1.00 0.00 +ATOM 6705 OW HOH 2078 28.150 19.910 37.390 1.00 0.00 +ATOM 6706 HW1 HOH 2078 28.750 19.380 37.920 1.00 0.00 +ATOM 6707 HW2 HOH 2078 28.330 19.640 36.490 1.00 0.00 +ATOM 6708 OW HOH 2079 26.790 37.440 0.500 1.00 0.00 +ATOM 6709 HW1 HOH 2079 26.800 36.650 -0.040 1.00 0.00 +ATOM 6710 HW2 HOH 2079 26.960 37.130 1.390 1.00 0.00 +ATOM 6711 OW HOH 2080 39.900 21.260 4.970 1.00 0.00 +ATOM 6712 HW1 HOH 2080 39.460 20.810 4.250 1.00 0.00 +ATOM 6713 HW2 HOH 2080 40.290 20.550 5.490 1.00 0.00 +ATOM 6714 OW HOH 2081 17.860 10.840 32.920 1.00 0.00 +ATOM 6715 HW1 HOH 2081 18.300 10.270 33.550 1.00 0.00 +ATOM 6716 HW2 HOH 2081 18.280 11.700 33.040 1.00 0.00 +ATOM 6717 OW HOH 2082 17.470 6.560 0.600 1.00 0.00 +ATOM 6718 HW1 HOH 2082 17.870 7.400 0.400 1.00 0.00 +ATOM 6719 HW2 HOH 2082 17.860 6.300 1.440 1.00 0.00 +ATOM 6720 OW HOH 2083 48.000 5.410 26.990 1.00 0.00 +ATOM 6721 HW1 HOH 2083 48.240 4.530 26.720 1.00 0.00 +ATOM 6722 HW2 HOH 2083 48.640 5.630 27.670 1.00 0.00 +ATOM 6723 OW HOH 2084 1.520 29.300 3.310 1.00 0.00 +ATOM 6724 HW1 HOH 2084 2.280 28.980 3.790 1.00 0.00 +ATOM 6725 HW2 HOH 2084 1.420 28.700 2.570 1.00 0.00 +ATOM 6726 OW HOH 2085 3.260 31.280 19.810 1.00 0.00 +ATOM 6727 HW1 HOH 2085 3.450 30.900 18.960 1.00 0.00 +ATOM 6728 HW2 HOH 2085 3.540 32.200 19.740 1.00 0.00 +ATOM 6729 OW HOH 2086 18.780 21.910 34.100 1.00 0.00 +ATOM 6730 HW1 HOH 2086 18.270 21.950 33.290 1.00 0.00 +ATOM 6731 HW2 HOH 2086 18.520 21.090 34.520 1.00 0.00 +ATOM 6732 OW HOH 2087 41.310 40.830 -0.050 1.00 0.00 +ATOM 6733 HW1 HOH 2087 41.820 40.390 0.630 1.00 0.00 +ATOM 6734 HW2 HOH 2087 41.960 41.320 -0.560 1.00 0.00 +ATOM 6735 OW HOH 2088 29.660 8.770 1.330 1.00 0.00 +ATOM 6736 HW1 HOH 2088 29.670 8.090 2.000 1.00 0.00 +ATOM 6737 HW2 HOH 2088 30.430 9.300 1.510 1.00 0.00 +ATOM 6738 OW HOH 2089 42.620 22.400 18.990 1.00 0.00 +ATOM 6739 HW1 HOH 2089 42.440 21.660 19.570 1.00 0.00 +ATOM 6740 HW2 HOH 2089 43.100 23.020 19.540 1.00 0.00 +ATOM 6741 OW HOH 2090 25.290 1.270 9.790 1.00 0.00 +ATOM 6742 HW1 HOH 2090 24.950 0.600 10.390 1.00 0.00 +ATOM 6743 HW2 HOH 2090 26.240 1.240 9.900 1.00 0.00 +ATOM 6744 OW HOH 2091 40.650 44.450 8.660 1.00 0.00 +ATOM 6745 HW1 HOH 2091 40.280 45.210 9.110 1.00 0.00 +ATOM 6746 HW2 HOH 2091 39.900 44.000 8.280 1.00 0.00 +ATOM 6747 OW HOH 2092 32.800 8.390 24.370 1.00 0.00 +ATOM 6748 HW1 HOH 2092 33.320 7.850 23.780 1.00 0.00 +ATOM 6749 HW2 HOH 2092 33.200 8.270 25.230 1.00 0.00 +ATOM 6750 OW HOH 2093 48.720 10.820 3.700 1.00 0.00 +ATOM 6751 HW1 HOH 2093 49.050 10.730 4.590 1.00 0.00 +ATOM 6752 HW2 HOH 2093 49.500 10.830 3.150 1.00 0.00 +ATOM 6753 OW HOH 2094 2.460 2.010 26.640 1.00 0.00 +ATOM 6754 HW1 HOH 2094 2.440 1.900 25.690 1.00 0.00 +ATOM 6755 HW2 HOH 2094 1.550 1.940 26.910 1.00 0.00 +ATOM 6756 OW HOH 2095 43.970 18.330 13.740 1.00 0.00 +ATOM 6757 HW1 HOH 2095 44.000 19.160 13.270 1.00 0.00 +ATOM 6758 HW2 HOH 2095 43.900 18.580 14.660 1.00 0.00 +ATOM 6759 OW HOH 2096 -0.160 44.960 26.190 1.00 0.00 +ATOM 6760 HW1 HOH 2096 -0.250 44.290 26.870 1.00 0.00 +ATOM 6761 HW2 HOH 2096 0.720 44.830 25.830 1.00 0.00 +ATOM 6762 OW HOH 2097 1.780 28.940 7.510 1.00 0.00 +ATOM 6763 HW1 HOH 2097 2.570 29.340 7.140 1.00 0.00 +ATOM 6764 HW2 HOH 2097 1.160 29.670 7.580 1.00 0.00 +ATOM 6765 OW HOH 2098 43.930 21.460 7.650 1.00 0.00 +ATOM 6766 HW1 HOH 2098 44.180 20.540 7.590 1.00 0.00 +ATOM 6767 HW2 HOH 2098 44.760 21.930 7.720 1.00 0.00 +ATOM 6768 OW HOH 2099 15.530 13.230 23.930 1.00 0.00 +ATOM 6769 HW1 HOH 2099 15.280 14.130 24.140 1.00 0.00 +ATOM 6770 HW2 HOH 2099 14.720 12.820 23.630 1.00 0.00 +ATOM 6771 OW HOH 2100 6.870 42.910 15.820 1.00 0.00 +ATOM 6772 HW1 HOH 2100 7.490 42.490 16.410 1.00 0.00 +ATOM 6773 HW2 HOH 2100 6.530 42.200 15.280 1.00 0.00 +ATOM 6774 OW HOH 2101 7.880 36.680 26.810 1.00 0.00 +ATOM 6775 HW1 HOH 2101 7.700 35.840 27.240 1.00 0.00 +ATOM 6776 HW2 HOH 2101 7.240 36.730 26.100 1.00 0.00 +ATOM 6777 OW HOH 2102 26.550 2.690 15.880 1.00 0.00 +ATOM 6778 HW1 HOH 2102 25.950 2.290 15.250 1.00 0.00 +ATOM 6779 HW2 HOH 2102 27.020 3.360 15.380 1.00 0.00 +ATOM 6780 OW HOH 2103 9.130 7.070 35.140 1.00 0.00 +ATOM 6781 HW1 HOH 2103 10.010 7.370 34.920 1.00 0.00 +ATOM 6782 HW2 HOH 2103 8.960 7.440 36.010 1.00 0.00 +ATOM 6783 OW HOH 2104 22.720 7.440 22.590 1.00 0.00 +ATOM 6784 HW1 HOH 2104 21.920 7.900 22.840 1.00 0.00 +ATOM 6785 HW2 HOH 2104 22.420 6.670 22.100 1.00 0.00 +ATOM 6786 OW HOH 2105 42.200 37.040 25.350 1.00 0.00 +ATOM 6787 HW1 HOH 2105 41.380 36.960 24.860 1.00 0.00 +ATOM 6788 HW2 HOH 2105 41.920 37.170 26.260 1.00 0.00 +ATOM 6789 OW HOH 2106 15.200 1.930 0.480 1.00 0.00 +ATOM 6790 HW1 HOH 2106 15.840 1.260 0.230 1.00 0.00 +ATOM 6791 HW2 HOH 2106 15.550 2.750 0.120 1.00 0.00 +ATOM 6792 OW HOH 2107 48.940 39.440 22.010 1.00 0.00 +ATOM 6793 HW1 HOH 2107 49.100 40.070 22.720 1.00 0.00 +ATOM 6794 HW2 HOH 2107 48.190 38.930 22.300 1.00 0.00 +ATOM 6795 OW HOH 2108 28.430 6.690 38.440 1.00 0.00 +ATOM 6796 HW1 HOH 2108 27.910 6.160 39.040 1.00 0.00 +ATOM 6797 HW2 HOH 2108 28.990 7.220 39.010 1.00 0.00 +ATOM 6798 OW HOH 2109 38.290 39.040 36.510 1.00 0.00 +ATOM 6799 HW1 HOH 2109 39.210 39.270 36.640 1.00 0.00 +ATOM 6800 HW2 HOH 2109 37.990 39.660 35.850 1.00 0.00 +ATOM 6801 OW HOH 2110 40.590 36.100 32.060 1.00 0.00 +ATOM 6802 HW1 HOH 2110 40.200 36.100 32.930 1.00 0.00 +ATOM 6803 HW2 HOH 2110 39.980 35.600 31.510 1.00 0.00 +ATOM 6804 OW HOH 2111 29.000 3.920 30.090 1.00 0.00 +ATOM 6805 HW1 HOH 2111 29.410 3.560 29.300 1.00 0.00 +ATOM 6806 HW2 HOH 2111 28.840 3.170 30.650 1.00 0.00 +ATOM 6807 OW HOH 2112 44.370 25.060 4.960 1.00 0.00 +ATOM 6808 HW1 HOH 2112 44.950 25.370 5.660 1.00 0.00 +ATOM 6809 HW2 HOH 2112 43.490 25.170 5.320 1.00 0.00 +ATOM 6810 OW HOH 2113 8.690 31.630 37.560 1.00 0.00 +ATOM 6811 HW1 HOH 2113 8.840 32.010 38.430 1.00 0.00 +ATOM 6812 HW2 HOH 2113 7.790 31.290 37.610 1.00 0.00 +ATOM 6813 OW HOH 2114 1.600 8.710 9.300 1.00 0.00 +ATOM 6814 HW1 HOH 2114 1.210 8.190 8.600 1.00 0.00 +ATOM 6815 HW2 HOH 2114 1.820 9.550 8.880 1.00 0.00 +ATOM 6816 OW HOH 2115 29.820 22.200 21.670 1.00 0.00 +ATOM 6817 HW1 HOH 2115 30.540 22.410 21.080 1.00 0.00 +ATOM 6818 HW2 HOH 2115 30.170 22.350 22.550 1.00 0.00 +ATOM 6819 OW HOH 2116 39.520 30.380 18.340 1.00 0.00 +ATOM 6820 HW1 HOH 2116 39.650 31.000 19.050 1.00 0.00 +ATOM 6821 HW2 HOH 2116 39.490 30.920 17.550 1.00 0.00 +ATOM 6822 OW HOH 2117 27.190 22.440 30.180 1.00 0.00 +ATOM 6823 HW1 HOH 2117 26.830 23.010 29.500 1.00 0.00 +ATOM 6824 HW2 HOH 2117 26.870 21.560 29.950 1.00 0.00 +ATOM 6825 OW HOH 2118 45.240 32.820 7.110 1.00 0.00 +ATOM 6826 HW1 HOH 2118 45.000 33.400 7.830 1.00 0.00 +ATOM 6827 HW2 HOH 2118 44.560 32.970 6.450 1.00 0.00 +ATOM 6828 OW HOH 2119 43.300 13.660 22.120 1.00 0.00 +ATOM 6829 HW1 HOH 2119 42.730 14.290 21.670 1.00 0.00 +ATOM 6830 HW2 HOH 2119 44.160 13.810 21.740 1.00 0.00 +ATOM 6831 OW HOH 2120 2.830 23.950 8.370 1.00 0.00 +ATOM 6832 HW1 HOH 2120 2.150 23.760 9.020 1.00 0.00 +ATOM 6833 HW2 HOH 2120 2.670 24.860 8.120 1.00 0.00 +ATOM 6834 OW HOH 2121 2.170 14.220 13.730 1.00 0.00 +ATOM 6835 HW1 HOH 2121 1.350 14.700 13.700 1.00 0.00 +ATOM 6836 HW2 HOH 2121 2.210 13.860 14.620 1.00 0.00 +ATOM 6837 OW HOH 2122 43.190 12.440 24.600 1.00 0.00 +ATOM 6838 HW1 HOH 2122 43.130 12.720 23.690 1.00 0.00 +ATOM 6839 HW2 HOH 2122 43.480 13.220 25.070 1.00 0.00 +ATOM 6840 OW HOH 2123 34.190 7.060 22.410 1.00 0.00 +ATOM 6841 HW1 HOH 2123 33.670 6.630 21.720 1.00 0.00 +ATOM 6842 HW2 HOH 2123 34.970 6.520 22.490 1.00 0.00 +ATOM 6843 OW HOH 2124 31.090 44.730 27.860 1.00 0.00 +ATOM 6844 HW1 HOH 2124 30.660 45.580 27.760 1.00 0.00 +ATOM 6845 HW2 HOH 2124 30.400 44.090 27.710 1.00 0.00 +ATOM 6846 OW HOH 2125 6.250 24.510 5.190 1.00 0.00 +ATOM 6847 HW1 HOH 2125 5.770 24.060 5.890 1.00 0.00 +ATOM 6848 HW2 HOH 2125 6.360 25.400 5.510 1.00 0.00 +ATOM 6849 OW HOH 2126 40.750 29.680 5.220 1.00 0.00 +ATOM 6850 HW1 HOH 2126 40.880 29.980 4.320 1.00 0.00 +ATOM 6851 HW2 HOH 2126 39.830 29.880 5.410 1.00 0.00 +ATOM 6852 OW HOH 2127 46.600 39.610 38.040 1.00 0.00 +ATOM 6853 HW1 HOH 2127 46.220 40.040 38.810 1.00 0.00 +ATOM 6854 HW2 HOH 2127 46.150 38.770 37.980 1.00 0.00 +ATOM 6855 OW HOH 2128 8.880 25.520 35.510 1.00 0.00 +ATOM 6856 HW1 HOH 2128 8.560 26.140 34.860 1.00 0.00 +ATOM 6857 HW2 HOH 2128 9.780 25.790 35.680 1.00 0.00 +ATOM 6858 OW HOH 2129 24.000 38.160 20.780 1.00 0.00 +ATOM 6859 HW1 HOH 2129 23.340 37.730 21.310 1.00 0.00 +ATOM 6860 HW2 HOH 2129 24.290 37.490 20.160 1.00 0.00 +ATOM 6861 OW HOH 2130 46.120 32.680 34.650 1.00 0.00 +ATOM 6862 HW1 HOH 2130 46.630 33.130 33.980 1.00 0.00 +ATOM 6863 HW2 HOH 2130 46.560 32.880 35.470 1.00 0.00 +ATOM 6864 OW HOH 2131 16.560 20.610 11.620 1.00 0.00 +ATOM 6865 HW1 HOH 2131 16.660 20.370 10.700 1.00 0.00 +ATOM 6866 HW2 HOH 2131 16.650 19.790 12.090 1.00 0.00 +ATOM 6867 OW HOH 2132 20.940 10.410 19.290 1.00 0.00 +ATOM 6868 HW1 HOH 2132 20.770 11.330 19.490 1.00 0.00 +ATOM 6869 HW2 HOH 2132 21.810 10.250 19.670 1.00 0.00 +ATOM 6870 OW HOH 2133 38.190 18.760 26.640 1.00 0.00 +ATOM 6871 HW1 HOH 2133 37.850 19.240 25.890 1.00 0.00 +ATOM 6872 HW2 HOH 2133 39.140 18.880 26.600 1.00 0.00 +ATOM 6873 OW HOH 2134 36.280 35.600 21.240 1.00 0.00 +ATOM 6874 HW1 HOH 2134 36.660 35.860 22.080 1.00 0.00 +ATOM 6875 HW2 HOH 2134 36.160 36.430 20.770 1.00 0.00 +ATOM 6876 OW HOH 2135 35.180 42.830 13.850 1.00 0.00 +ATOM 6877 HW1 HOH 2135 35.290 42.190 13.140 1.00 0.00 +ATOM 6878 HW2 HOH 2135 34.500 43.420 13.530 1.00 0.00 +ATOM 6879 OW HOH 2136 21.880 42.550 22.520 1.00 0.00 +ATOM 6880 HW1 HOH 2136 22.530 42.740 21.840 1.00 0.00 +ATOM 6881 HW2 HOH 2136 21.600 43.410 22.830 1.00 0.00 +ATOM 6882 OW HOH 2137 18.590 41.000 17.830 1.00 0.00 +ATOM 6883 HW1 HOH 2137 18.270 41.570 17.130 1.00 0.00 +ATOM 6884 HW2 HOH 2137 18.600 41.560 18.610 1.00 0.00 +ATOM 6885 OW HOH 2138 19.050 36.120 0.640 1.00 0.00 +ATOM 6886 HW1 HOH 2138 19.080 35.440 1.320 1.00 0.00 +ATOM 6887 HW2 HOH 2138 18.880 36.930 1.120 1.00 0.00 +ATOM 6888 OW HOH 2139 11.510 20.700 31.000 1.00 0.00 +ATOM 6889 HW1 HOH 2139 10.870 20.070 31.320 1.00 0.00 +ATOM 6890 HW2 HOH 2139 12.220 20.160 30.650 1.00 0.00 +ATOM 6891 OW HOH 2140 28.410 0.530 1.210 1.00 0.00 +ATOM 6892 HW1 HOH 2140 27.850 0.920 0.550 1.00 0.00 +ATOM 6893 HW2 HOH 2140 29.300 0.660 0.890 1.00 0.00 +ATOM 6894 OW HOH 2141 36.920 2.440 13.950 1.00 0.00 +ATOM 6895 HW1 HOH 2141 36.730 3.000 14.700 1.00 0.00 +ATOM 6896 HW2 HOH 2141 37.870 2.320 13.980 1.00 0.00 +ATOM 6897 OW HOH 2142 40.360 41.460 20.270 1.00 0.00 +ATOM 6898 HW1 HOH 2142 39.650 41.310 19.650 1.00 0.00 +ATOM 6899 HW2 HOH 2142 40.070 42.190 20.820 1.00 0.00 +ATOM 6900 OW HOH 2143 13.740 35.440 30.540 1.00 0.00 +ATOM 6901 HW1 HOH 2143 12.890 35.010 30.460 1.00 0.00 +ATOM 6902 HW2 HOH 2143 13.540 36.340 30.760 1.00 0.00 +ATOM 6903 OW HOH 2144 22.780 40.830 19.670 1.00 0.00 +ATOM 6904 HW1 HOH 2144 23.380 40.110 19.460 1.00 0.00 +ATOM 6905 HW2 HOH 2144 22.120 40.430 20.240 1.00 0.00 +ATOM 6906 OW HOH 2145 37.030 0.590 4.660 1.00 0.00 +ATOM 6907 HW1 HOH 2145 37.540 -0.060 4.170 1.00 0.00 +ATOM 6908 HW2 HOH 2145 37.550 0.760 5.450 1.00 0.00 +ATOM 6909 OW HOH 2146 15.360 43.220 17.590 1.00 0.00 +ATOM 6910 HW1 HOH 2146 16.210 43.030 17.190 1.00 0.00 +ATOM 6911 HW2 HOH 2146 15.070 44.020 17.150 1.00 0.00 +ATOM 6912 OW HOH 2147 17.940 12.240 11.910 1.00 0.00 +ATOM 6913 HW1 HOH 2147 18.190 12.850 11.220 1.00 0.00 +ATOM 6914 HW2 HOH 2147 18.740 11.760 12.110 1.00 0.00 +ATOM 6915 OW HOH 2148 46.400 36.740 33.870 1.00 0.00 +ATOM 6916 HW1 HOH 2148 46.880 36.290 33.170 1.00 0.00 +ATOM 6917 HW2 HOH 2148 45.610 37.070 33.440 1.00 0.00 +ATOM 6918 OW HOH 2149 48.670 11.890 11.760 1.00 0.00 +ATOM 6919 HW1 HOH 2149 48.010 11.890 11.060 1.00 0.00 +ATOM 6920 HW2 HOH 2149 49.310 12.550 11.480 1.00 0.00 +ATOM 6921 OW HOH 2150 29.480 42.350 10.720 1.00 0.00 +ATOM 6922 HW1 HOH 2150 28.940 42.980 10.230 1.00 0.00 +ATOM 6923 HW2 HOH 2150 29.120 42.370 11.610 1.00 0.00 +ATOM 6924 OW HOH 2151 3.010 30.050 22.510 1.00 0.00 +ATOM 6925 HW1 HOH 2151 3.610 30.140 21.780 1.00 0.00 +ATOM 6926 HW2 HOH 2151 2.270 30.620 22.290 1.00 0.00 +ATOM 6927 OW HOH 2152 25.020 30.350 38.940 1.00 0.00 +ATOM 6928 HW1 HOH 2152 24.860 29.490 39.320 1.00 0.00 +ATOM 6929 HW2 HOH 2152 24.550 30.330 38.100 1.00 0.00 +ATOM 6930 OW HOH 2153 9.290 43.220 28.960 1.00 0.00 +ATOM 6931 HW1 HOH 2153 9.810 43.270 28.160 1.00 0.00 +ATOM 6932 HW2 HOH 2153 9.810 42.670 29.550 1.00 0.00 +ATOM 6933 OW HOH 2154 23.470 18.580 6.040 1.00 0.00 +ATOM 6934 HW1 HOH 2154 22.550 18.820 6.180 1.00 0.00 +ATOM 6935 HW2 HOH 2154 23.420 17.710 5.630 1.00 0.00 +ATOM 6936 OW HOH 2155 29.760 37.490 27.180 1.00 0.00 +ATOM 6937 HW1 HOH 2155 30.560 37.320 27.680 1.00 0.00 +ATOM 6938 HW2 HOH 2155 29.970 37.200 26.290 1.00 0.00 +ATOM 6939 OW HOH 2156 20.020 45.570 26.330 1.00 0.00 +ATOM 6940 HW1 HOH 2156 19.100 45.490 26.050 1.00 0.00 +ATOM 6941 HW2 HOH 2156 20.070 46.410 26.780 1.00 0.00 +ATOM 6942 OW HOH 2157 35.350 38.100 16.680 1.00 0.00 +ATOM 6943 HW1 HOH 2157 36.020 38.770 16.590 1.00 0.00 +ATOM 6944 HW2 HOH 2157 35.800 37.330 17.020 1.00 0.00 +ATOM 6945 OW HOH 2158 23.060 34.960 14.360 1.00 0.00 +ATOM 6946 HW1 HOH 2158 23.420 34.200 13.910 1.00 0.00 +ATOM 6947 HW2 HOH 2158 22.360 35.270 13.780 1.00 0.00 +ATOM 6948 OW HOH 2159 11.620 0.760 30.950 1.00 0.00 +ATOM 6949 HW1 HOH 2159 11.340 1.580 31.340 1.00 0.00 +ATOM 6950 HW2 HOH 2159 11.960 0.250 31.680 1.00 0.00 +ATOM 6951 OW HOH 2160 19.440 32.390 11.200 1.00 0.00 +ATOM 6952 HW1 HOH 2160 19.260 32.250 12.130 1.00 0.00 +ATOM 6953 HW2 HOH 2160 18.990 33.210 10.990 1.00 0.00 +ATOM 6954 OW HOH 2161 46.770 8.710 32.210 1.00 0.00 +ATOM 6955 HW1 HOH 2161 47.460 8.100 31.960 1.00 0.00 +ATOM 6956 HW2 HOH 2161 45.970 8.190 32.150 1.00 0.00 +ATOM 6957 OW HOH 2162 36.440 34.280 38.050 1.00 0.00 +ATOM 6958 HW1 HOH 2162 36.840 35.140 37.940 1.00 0.00 +ATOM 6959 HW2 HOH 2162 36.500 33.870 37.180 1.00 0.00 +ATOM 6960 OW HOH 2163 31.740 41.060 31.230 1.00 0.00 +ATOM 6961 HW1 HOH 2163 32.120 41.860 31.600 1.00 0.00 +ATOM 6962 HW2 HOH 2163 31.520 41.300 30.330 1.00 0.00 +ATOM 6963 OW HOH 2164 26.050 15.090 3.810 1.00 0.00 +ATOM 6964 HW1 HOH 2164 26.800 14.760 3.320 1.00 0.00 +ATOM 6965 HW2 HOH 2164 26.070 14.610 4.640 1.00 0.00 +ATOM 6966 OW HOH 2165 18.270 33.480 19.380 1.00 0.00 +ATOM 6967 HW1 HOH 2165 17.370 33.160 19.440 1.00 0.00 +ATOM 6968 HW2 HOH 2165 18.200 34.300 18.880 1.00 0.00 +ATOM 6969 OW HOH 2166 40.030 11.370 34.410 1.00 0.00 +ATOM 6970 HW1 HOH 2166 40.470 10.620 34.800 1.00 0.00 +ATOM 6971 HW2 HOH 2166 39.630 11.020 33.610 1.00 0.00 +ATOM 6972 OW HOH 2167 33.500 36.600 32.250 1.00 0.00 +ATOM 6973 HW1 HOH 2167 33.990 36.710 31.430 1.00 0.00 +ATOM 6974 HW2 HOH 2167 34.060 36.060 32.790 1.00 0.00 +ATOM 6975 OW HOH 2168 35.450 5.030 9.850 1.00 0.00 +ATOM 6976 HW1 HOH 2168 34.590 5.360 10.080 1.00 0.00 +ATOM 6977 HW2 HOH 2168 35.520 4.190 10.310 1.00 0.00 +ATOM 6978 OW HOH 2169 19.260 0.830 33.180 1.00 0.00 +ATOM 6979 HW1 HOH 2169 19.010 0.400 32.360 1.00 0.00 +ATOM 6980 HW2 HOH 2169 19.800 0.190 33.630 1.00 0.00 +ATOM 6981 OW HOH 2170 17.170 23.160 8.470 1.00 0.00 +ATOM 6982 HW1 HOH 2170 16.290 23.120 8.090 1.00 0.00 +ATOM 6983 HW2 HOH 2170 17.470 22.250 8.460 1.00 0.00 +ATOM 6984 OW HOH 2171 44.700 16.600 19.140 1.00 0.00 +ATOM 6985 HW1 HOH 2171 44.370 15.900 18.580 1.00 0.00 +ATOM 6986 HW2 HOH 2171 45.030 17.260 18.530 1.00 0.00 +ATOM 6987 OW HOH 2172 10.050 1.960 6.100 1.00 0.00 +ATOM 6988 HW1 HOH 2172 10.070 1.630 5.200 1.00 0.00 +ATOM 6989 HW2 HOH 2172 9.350 1.460 6.520 1.00 0.00 +ATOM 6990 OW HOH 2173 31.020 43.490 7.100 1.00 0.00 +ATOM 6991 HW1 HOH 2173 30.070 43.410 7.120 1.00 0.00 +ATOM 6992 HW2 HOH 2173 31.230 43.760 6.210 1.00 0.00 +ATOM 6993 OW HOH 2174 32.820 5.290 10.520 1.00 0.00 +ATOM 6994 HW1 HOH 2174 32.130 5.930 10.720 1.00 0.00 +ATOM 6995 HW2 HOH 2174 32.560 4.510 11.000 1.00 0.00 +ATOM 6996 OW HOH 2175 37.060 32.340 18.030 1.00 0.00 +ATOM 6997 HW1 HOH 2175 37.500 33.070 18.460 1.00 0.00 +ATOM 6998 HW2 HOH 2175 37.200 32.490 17.090 1.00 0.00 +ATOM 6999 OW HOH 2176 37.160 30.530 34.170 1.00 0.00 +ATOM 7000 HW1 HOH 2176 36.390 30.020 33.930 1.00 0.00 +ATOM 7001 HW2 HOH 2176 37.830 29.870 34.380 1.00 0.00 +ATOM 7002 OW HOH 2177 22.470 45.220 31.230 1.00 0.00 +ATOM 7003 HW1 HOH 2177 23.050 45.250 31.990 1.00 0.00 +ATOM 7004 HW2 HOH 2177 21.920 44.450 31.380 1.00 0.00 +ATOM 7005 OW HOH 2178 17.150 41.010 24.900 1.00 0.00 +ATOM 7006 HW1 HOH 2178 17.030 40.700 25.800 1.00 0.00 +ATOM 7007 HW2 HOH 2178 17.670 41.800 24.990 1.00 0.00 +ATOM 7008 OW HOH 2179 44.170 29.250 27.320 1.00 0.00 +ATOM 7009 HW1 HOH 2179 44.320 30.200 27.310 1.00 0.00 +ATOM 7010 HW2 HOH 2179 43.280 29.150 26.980 1.00 0.00 +ATOM 7011 OW HOH 2180 34.120 15.760 37.550 1.00 0.00 +ATOM 7012 HW1 HOH 2180 33.270 16.170 37.420 1.00 0.00 +ATOM 7013 HW2 HOH 2180 34.620 16.000 36.770 1.00 0.00 +ATOM 7014 OW HOH 2181 32.340 2.560 16.650 1.00 0.00 +ATOM 7015 HW1 HOH 2181 31.460 2.480 16.280 1.00 0.00 +ATOM 7016 HW2 HOH 2181 32.320 2.040 17.450 1.00 0.00 +ATOM 7017 OW HOH 2182 34.260 23.780 38.660 1.00 0.00 +ATOM 7018 HW1 HOH 2182 33.390 24.110 38.420 1.00 0.00 +ATOM 7019 HW2 HOH 2182 34.260 22.870 38.340 1.00 0.00 +ATOM 7020 OW HOH 2183 28.980 2.500 4.530 1.00 0.00 +ATOM 7021 HW1 HOH 2183 28.840 1.630 4.910 1.00 0.00 +ATOM 7022 HW2 HOH 2183 29.920 2.660 4.630 1.00 0.00 +ATOM 7023 OW HOH 2184 44.240 32.520 13.080 1.00 0.00 +ATOM 7024 HW1 HOH 2184 44.130 31.830 12.420 1.00 0.00 +ATOM 7025 HW2 HOH 2184 45.080 32.320 13.490 1.00 0.00 +ATOM 7026 OW HOH 2185 21.970 27.220 4.400 1.00 0.00 +ATOM 7027 HW1 HOH 2185 22.420 28.020 4.680 1.00 0.00 +ATOM 7028 HW2 HOH 2185 21.060 27.350 4.660 1.00 0.00 +ATOM 7029 OW HOH 2186 19.770 8.000 7.740 1.00 0.00 +ATOM 7030 HW1 HOH 2186 19.250 7.230 8.000 1.00 0.00 +ATOM 7031 HW2 HOH 2186 19.120 8.680 7.570 1.00 0.00 +ATOM 7032 OW HOH 2187 17.740 14.150 24.900 1.00 0.00 +ATOM 7033 HW1 HOH 2187 17.590 15.080 24.760 1.00 0.00 +ATOM 7034 HW2 HOH 2187 17.030 13.710 24.440 1.00 0.00 +ATOM 7035 OW HOH 2188 12.320 42.870 12.960 1.00 0.00 +ATOM 7036 HW1 HOH 2188 11.370 42.840 12.920 1.00 0.00 +ATOM 7037 HW2 HOH 2188 12.520 43.780 13.170 1.00 0.00 +ATOM 7038 OW HOH 2189 33.940 37.960 23.410 1.00 0.00 +ATOM 7039 HW1 HOH 2189 34.770 38.200 23.830 1.00 0.00 +ATOM 7040 HW2 HOH 2189 34.080 38.150 22.480 1.00 0.00 +ATOM 7041 OW HOH 2190 13.430 19.450 16.560 1.00 0.00 +ATOM 7042 HW1 HOH 2190 14.020 18.710 16.720 1.00 0.00 +ATOM 7043 HW2 HOH 2190 13.050 19.640 17.420 1.00 0.00 +ATOM 7044 OW HOH 2191 32.950 31.120 15.790 1.00 0.00 +ATOM 7045 HW1 HOH 2191 32.180 30.580 15.990 1.00 0.00 +ATOM 7046 HW2 HOH 2191 32.770 31.470 14.920 1.00 0.00 +ATOM 7047 OW HOH 2192 8.990 18.740 11.380 1.00 0.00 +ATOM 7048 HW1 HOH 2192 8.940 19.700 11.290 1.00 0.00 +ATOM 7049 HW2 HOH 2192 9.910 18.530 11.240 1.00 0.00 +ATOM 7050 OW HOH 2193 43.260 6.340 8.870 1.00 0.00 +ATOM 7051 HW1 HOH 2193 43.070 7.220 8.550 1.00 0.00 +ATOM 7052 HW2 HOH 2193 43.280 6.430 9.820 1.00 0.00 +ATOM 7053 OW HOH 2194 44.180 17.970 2.960 1.00 0.00 +ATOM 7054 HW1 HOH 2194 44.550 18.850 3.050 1.00 0.00 +ATOM 7055 HW2 HOH 2194 44.090 17.660 3.860 1.00 0.00 +ATOM 7056 OW HOH 2195 7.360 38.830 24.310 1.00 0.00 +ATOM 7057 HW1 HOH 2195 6.800 38.100 24.580 1.00 0.00 +ATOM 7058 HW2 HOH 2195 6.950 39.160 23.510 1.00 0.00 +ATOM 7059 OW HOH 2196 4.920 19.950 29.760 1.00 0.00 +ATOM 7060 HW1 HOH 2196 4.700 20.530 29.040 1.00 0.00 +ATOM 7061 HW2 HOH 2196 5.340 19.200 29.350 1.00 0.00 +ATOM 7062 OW HOH 2197 5.510 14.410 1.380 1.00 0.00 +ATOM 7063 HW1 HOH 2197 4.710 14.550 1.890 1.00 0.00 +ATOM 7064 HW2 HOH 2197 5.360 14.890 0.570 1.00 0.00 +ATOM 7065 OW HOH 2198 42.970 36.610 17.660 1.00 0.00 +ATOM 7066 HW1 HOH 2198 42.390 36.560 16.900 1.00 0.00 +ATOM 7067 HW2 HOH 2198 43.540 37.360 17.490 1.00 0.00 +ATOM 7068 OW HOH 2199 11.350 38.250 22.520 1.00 0.00 +ATOM 7069 HW1 HOH 2199 10.810 38.320 21.740 1.00 0.00 +ATOM 7070 HW2 HOH 2199 11.980 37.560 22.320 1.00 0.00 +ATOM 7071 OW HOH 2200 3.080 26.130 13.860 1.00 0.00 +ATOM 7072 HW1 HOH 2200 2.230 26.160 14.300 1.00 0.00 +ATOM 7073 HW2 HOH 2200 2.910 26.410 12.960 1.00 0.00 +ATOM 7074 OW HOH 2201 46.430 44.040 11.260 1.00 0.00 +ATOM 7075 HW1 HOH 2201 46.720 44.140 10.360 1.00 0.00 +ATOM 7076 HW2 HOH 2201 46.830 44.770 11.730 1.00 0.00 +ATOM 7077 OW HOH 2202 1.700 35.340 26.280 1.00 0.00 +ATOM 7078 HW1 HOH 2202 1.910 35.690 27.150 1.00 0.00 +ATOM 7079 HW2 HOH 2202 1.550 34.410 26.430 1.00 0.00 +ATOM 7080 OW HOH 2203 10.060 38.000 14.880 1.00 0.00 +ATOM 7081 HW1 HOH 2203 10.250 38.900 15.160 1.00 0.00 +ATOM 7082 HW2 HOH 2203 10.570 37.880 14.090 1.00 0.00 +ATOM 7083 OW HOH 2204 4.590 14.350 8.360 1.00 0.00 +ATOM 7084 HW1 HOH 2204 3.840 13.850 8.700 1.00 0.00 +ATOM 7085 HW2 HOH 2204 4.380 15.260 8.550 1.00 0.00 +ATOM 7086 OW HOH 2205 36.460 29.300 8.210 1.00 0.00 +ATOM 7087 HW1 HOH 2205 36.730 30.120 8.620 1.00 0.00 +ATOM 7088 HW2 HOH 2205 36.590 28.630 8.880 1.00 0.00 +ATOM 7089 OW HOH 2206 4.930 26.680 38.510 1.00 0.00 +ATOM 7090 HW1 HOH 2206 4.200 26.180 38.130 1.00 0.00 +ATOM 7091 HW2 HOH 2206 5.710 26.260 38.160 1.00 0.00 +ATOM 7092 OW HOH 2207 39.400 37.790 23.750 1.00 0.00 +ATOM 7093 HW1 HOH 2207 39.570 38.390 23.030 1.00 0.00 +ATOM 7094 HW2 HOH 2207 39.530 38.310 24.540 1.00 0.00 +ATOM 7095 OW HOH 2208 5.690 0.410 13.710 1.00 0.00 +ATOM 7096 HW1 HOH 2208 5.050 0.820 13.130 1.00 0.00 +ATOM 7097 HW2 HOH 2208 6.430 0.190 13.140 1.00 0.00 +ATOM 7098 OW HOH 2209 6.390 18.180 28.390 1.00 0.00 +ATOM 7099 HW1 HOH 2209 6.120 17.280 28.570 1.00 0.00 +ATOM 7100 HW2 HOH 2209 6.780 18.140 27.520 1.00 0.00 +ATOM 7101 OW HOH 2210 34.150 8.520 7.770 1.00 0.00 +ATOM 7102 HW1 HOH 2210 34.440 7.660 7.460 1.00 0.00 +ATOM 7103 HW2 HOH 2210 33.550 8.830 7.090 1.00 0.00 +ATOM 7104 OW HOH 2211 39.730 33.720 26.470 1.00 0.00 +ATOM 7105 HW1 HOH 2211 39.210 33.380 25.730 1.00 0.00 +ATOM 7106 HW2 HOH 2211 40.640 33.550 26.210 1.00 0.00 +ATOM 7107 OW HOH 2212 36.160 1.070 10.350 1.00 0.00 +ATOM 7108 HW1 HOH 2212 35.500 1.340 10.990 1.00 0.00 +ATOM 7109 HW2 HOH 2212 37.000 1.260 10.760 1.00 0.00 +ATOM 7110 OW HOH 2213 34.770 17.510 5.240 1.00 0.00 +ATOM 7111 HW1 HOH 2213 35.230 16.700 5.010 1.00 0.00 +ATOM 7112 HW2 HOH 2213 34.840 18.060 4.460 1.00 0.00 +ATOM 7113 OW HOH 2214 44.460 10.110 15.950 1.00 0.00 +ATOM 7114 HW1 HOH 2214 43.950 10.900 15.810 1.00 0.00 +ATOM 7115 HW2 HOH 2214 44.130 9.490 15.300 1.00 0.00 +ATOM 7116 OW HOH 2215 40.410 1.890 30.960 1.00 0.00 +ATOM 7117 HW1 HOH 2215 39.960 1.250 31.520 1.00 0.00 +ATOM 7118 HW2 HOH 2215 41.290 1.960 31.340 1.00 0.00 +ATOM 7119 OW HOH 2216 21.000 6.720 5.610 1.00 0.00 +ATOM 7120 HW1 HOH 2216 20.600 7.130 6.380 1.00 0.00 +ATOM 7121 HW2 HOH 2216 20.330 6.120 5.290 1.00 0.00 +ATOM 7122 OW HOH 2217 2.660 26.370 7.190 1.00 0.00 +ATOM 7123 HW1 HOH 2217 2.150 27.020 6.720 1.00 0.00 +ATOM 7124 HW2 HOH 2217 3.430 26.840 7.500 1.00 0.00 +ATOM 7125 OW HOH 2218 5.130 34.020 25.840 1.00 0.00 +ATOM 7126 HW1 HOH 2218 5.670 34.250 26.600 1.00 0.00 +ATOM 7127 HW2 HOH 2218 4.440 33.460 26.200 1.00 0.00 +ATOM 7128 OW HOH 2219 21.740 15.340 23.550 1.00 0.00 +ATOM 7129 HW1 HOH 2219 21.270 14.740 24.130 1.00 0.00 +ATOM 7130 HW2 HOH 2219 21.790 14.870 22.710 1.00 0.00 +ATOM 7131 OW HOH 2220 32.870 34.950 6.950 1.00 0.00 +ATOM 7132 HW1 HOH 2220 32.290 34.770 6.210 1.00 0.00 +ATOM 7133 HW2 HOH 2220 32.560 35.780 7.310 1.00 0.00 +ATOM 7134 OW HOH 2221 7.830 43.780 5.070 1.00 0.00 +ATOM 7135 HW1 HOH 2221 8.000 44.560 4.550 1.00 0.00 +ATOM 7136 HW2 HOH 2221 7.100 44.030 5.640 1.00 0.00 +ATOM 7137 OW HOH 2222 9.440 32.880 33.290 1.00 0.00 +ATOM 7138 HW1 HOH 2222 9.040 32.600 32.470 1.00 0.00 +ATOM 7139 HW2 HOH 2222 10.350 33.070 33.070 1.00 0.00 +ATOM 7140 OW HOH 2223 18.550 35.330 14.960 1.00 0.00 +ATOM 7141 HW1 HOH 2223 17.810 35.710 14.480 1.00 0.00 +ATOM 7142 HW2 HOH 2223 19.080 36.080 15.220 1.00 0.00 +ATOM 7143 OW HOH 2224 46.570 9.500 2.370 1.00 0.00 +ATOM 7144 HW1 HOH 2224 47.330 9.510 2.960 1.00 0.00 +ATOM 7145 HW2 HOH 2224 45.840 9.800 2.920 1.00 0.00 +ATOM 7146 OW HOH 2225 28.550 4.780 12.940 1.00 0.00 +ATOM 7147 HW1 HOH 2225 28.270 4.160 12.270 1.00 0.00 +ATOM 7148 HW2 HOH 2225 28.030 5.570 12.780 1.00 0.00 +ATOM 7149 OW HOH 2226 22.150 35.650 21.110 1.00 0.00 +ATOM 7150 HW1 HOH 2226 21.890 36.440 21.580 1.00 0.00 +ATOM 7151 HW2 HOH 2226 21.420 35.050 21.230 1.00 0.00 +ATOM 7152 OW HOH 2227 40.570 35.990 5.000 1.00 0.00 +ATOM 7153 HW1 HOH 2227 39.750 35.530 4.860 1.00 0.00 +ATOM 7154 HW2 HOH 2227 41.240 35.420 4.630 1.00 0.00 +ATOM 7155 OW HOH 2228 35.760 23.500 13.120 1.00 0.00 +ATOM 7156 HW1 HOH 2228 35.650 24.270 13.670 1.00 0.00 +ATOM 7157 HW2 HOH 2228 36.400 22.960 13.590 1.00 0.00 +ATOM 7158 OW HOH 2229 24.130 6.260 38.550 1.00 0.00 +ATOM 7159 HW1 HOH 2229 24.780 6.640 39.140 1.00 0.00 +ATOM 7160 HW2 HOH 2229 23.290 6.590 38.870 1.00 0.00 +ATOM 7161 OW HOH 2230 2.270 28.880 11.110 1.00 0.00 +ATOM 7162 HW1 HOH 2230 2.720 29.690 11.320 1.00 0.00 +ATOM 7163 HW2 HOH 2230 2.190 28.890 10.150 1.00 0.00 +ATOM 7164 OW HOH 2231 16.010 43.700 38.170 1.00 0.00 +ATOM 7165 HW1 HOH 2231 16.660 44.040 38.790 1.00 0.00 +ATOM 7166 HW2 HOH 2231 15.250 44.260 38.280 1.00 0.00 +ATOM 7167 OW HOH 2232 11.510 20.620 9.100 1.00 0.00 +ATOM 7168 HW1 HOH 2232 11.790 21.080 9.890 1.00 0.00 +ATOM 7169 HW2 HOH 2232 11.120 21.300 8.540 1.00 0.00 +ATOM 7170 OW HOH 2233 0.010 26.950 30.400 1.00 0.00 +ATOM 7171 HW1 HOH 2233 0.690 27.030 29.730 1.00 0.00 +ATOM 7172 HW2 HOH 2233 0.220 26.120 30.840 1.00 0.00 +ATOM 7173 OW HOH 2234 1.050 7.950 1.940 1.00 0.00 +ATOM 7174 HW1 HOH 2234 1.720 8.160 2.590 1.00 0.00 +ATOM 7175 HW2 HOH 2234 0.290 7.660 2.460 1.00 0.00 +ATOM 7176 OW HOH 2235 48.630 45.910 12.170 1.00 0.00 +ATOM 7177 HW1 HOH 2235 48.670 46.720 12.670 1.00 0.00 +ATOM 7178 HW2 HOH 2235 49.180 45.290 12.650 1.00 0.00 +ATOM 7179 OW HOH 2236 5.750 20.580 15.870 1.00 0.00 +ATOM 7180 HW1 HOH 2236 5.400 20.560 14.980 1.00 0.00 +ATOM 7181 HW2 HOH 2236 6.670 20.820 15.760 1.00 0.00 +ATOM 7182 OW HOH 2237 1.570 18.760 13.940 1.00 0.00 +ATOM 7183 HW1 HOH 2237 2.200 18.040 13.880 1.00 0.00 +ATOM 7184 HW2 HOH 2237 1.950 19.370 14.570 1.00 0.00 +ATOM 7185 OW HOH 2238 21.010 5.960 31.720 1.00 0.00 +ATOM 7186 HW1 HOH 2238 20.770 5.080 31.460 1.00 0.00 +ATOM 7187 HW2 HOH 2238 20.770 6.010 32.650 1.00 0.00 +ATOM 7188 OW HOH 2239 45.800 42.860 17.520 1.00 0.00 +ATOM 7189 HW1 HOH 2239 46.130 42.930 16.630 1.00 0.00 +ATOM 7190 HW2 HOH 2239 46.100 43.670 17.950 1.00 0.00 +ATOM 7191 OW HOH 2240 46.130 15.380 23.440 1.00 0.00 +ATOM 7192 HW1 HOH 2240 46.580 16.110 23.010 1.00 0.00 +ATOM 7193 HW2 HOH 2240 45.840 14.820 22.720 1.00 0.00 +ATOM 7194 OW HOH 2241 23.280 14.130 9.350 1.00 0.00 +ATOM 7195 HW1 HOH 2241 22.920 14.140 10.240 1.00 0.00 +ATOM 7196 HW2 HOH 2241 22.720 13.510 8.880 1.00 0.00 +ATOM 7197 OW HOH 2242 37.720 35.150 4.980 1.00 0.00 +ATOM 7198 HW1 HOH 2242 37.800 34.320 4.510 1.00 0.00 +ATOM 7199 HW2 HOH 2242 36.860 35.480 4.740 1.00 0.00 +ATOM 7200 OW HOH 2243 7.560 14.210 30.320 1.00 0.00 +ATOM 7201 HW1 HOH 2243 6.970 14.630 29.690 1.00 0.00 +ATOM 7202 HW2 HOH 2243 8.430 14.330 29.940 1.00 0.00 +ATOM 7203 OW HOH 2244 21.290 28.110 9.970 1.00 0.00 +ATOM 7204 HW1 HOH 2244 21.700 27.940 10.820 1.00 0.00 +ATOM 7205 HW2 HOH 2244 21.520 27.350 9.440 1.00 0.00 +ATOM 7206 OW HOH 2245 44.690 3.940 23.870 1.00 0.00 +ATOM 7207 HW1 HOH 2245 45.570 3.930 24.230 1.00 0.00 +ATOM 7208 HW2 HOH 2245 44.130 3.640 24.580 1.00 0.00 +ATOM 7209 OW HOH 2246 16.540 34.120 0.740 1.00 0.00 +ATOM 7210 HW1 HOH 2246 16.750 34.450 -0.130 1.00 0.00 +ATOM 7211 HW2 HOH 2246 17.360 34.210 1.230 1.00 0.00 +ATOM 7212 OW HOH 2247 36.300 9.860 1.340 1.00 0.00 +ATOM 7213 HW1 HOH 2247 35.840 10.190 0.570 1.00 0.00 +ATOM 7214 HW2 HOH 2247 36.480 8.940 1.140 1.00 0.00 +ATOM 7215 OW HOH 2248 12.350 36.360 26.980 1.00 0.00 +ATOM 7216 HW1 HOH 2248 13.100 35.860 26.660 1.00 0.00 +ATOM 7217 HW2 HOH 2248 11.790 35.710 27.400 1.00 0.00 +ATOM 7218 OW HOH 2249 9.220 4.640 20.050 1.00 0.00 +ATOM 7219 HW1 HOH 2249 9.870 5.320 20.230 1.00 0.00 +ATOM 7220 HW2 HOH 2249 9.100 4.670 19.100 1.00 0.00 +ATOM 7221 OW HOH 2250 30.100 33.750 17.370 1.00 0.00 +ATOM 7222 HW1 HOH 2250 30.470 33.350 18.160 1.00 0.00 +ATOM 7223 HW2 HOH 2250 29.880 34.640 17.630 1.00 0.00 +ATOM 7224 OW HOH 2251 17.000 35.930 37.590 1.00 0.00 +ATOM 7225 HW1 HOH 2251 16.720 36.640 37.020 1.00 0.00 +ATOM 7226 HW2 HOH 2251 17.580 36.340 38.230 1.00 0.00 +ATOM 7227 OW HOH 2252 2.010 26.740 23.660 1.00 0.00 +ATOM 7228 HW1 HOH 2252 1.830 26.640 22.720 1.00 0.00 +ATOM 7229 HW2 HOH 2252 2.610 26.030 23.870 1.00 0.00 +ATOM 7230 OW HOH 2253 33.010 7.320 3.240 1.00 0.00 +ATOM 7231 HW1 HOH 2253 33.120 6.910 2.380 1.00 0.00 +ATOM 7232 HW2 HOH 2253 33.610 8.060 3.230 1.00 0.00 +ATOM 7233 OW HOH 2254 1.460 38.580 24.890 1.00 0.00 +ATOM 7234 HW1 HOH 2254 1.420 39.450 24.470 1.00 0.00 +ATOM 7235 HW2 HOH 2254 2.360 38.290 24.750 1.00 0.00 +ATOM 7236 OW HOH 2255 29.010 43.250 26.360 1.00 0.00 +ATOM 7237 HW1 HOH 2255 29.180 42.310 26.410 1.00 0.00 +ATOM 7238 HW2 HOH 2255 29.120 43.450 25.430 1.00 0.00 +ATOM 7239 OW HOH 2256 10.940 39.440 10.390 1.00 0.00 +ATOM 7240 HW1 HOH 2256 10.020 39.290 10.610 1.00 0.00 +ATOM 7241 HW2 HOH 2256 11.370 39.610 11.230 1.00 0.00 +ATOM 7242 OW HOH 2257 2.890 14.750 5.900 1.00 0.00 +ATOM 7243 HW1 HOH 2257 2.200 15.420 5.960 1.00 0.00 +ATOM 7244 HW2 HOH 2257 3.390 14.840 6.710 1.00 0.00 +ATOM 7245 OW HOH 2258 24.040 5.850 9.350 1.00 0.00 +ATOM 7246 HW1 HOH 2258 23.170 5.500 9.150 1.00 0.00 +ATOM 7247 HW2 HOH 2258 24.630 5.120 9.180 1.00 0.00 +ATOM 7248 OW HOH 2259 47.450 24.020 22.700 1.00 0.00 +ATOM 7249 HW1 HOH 2259 47.650 24.090 23.640 1.00 0.00 +ATOM 7250 HW2 HOH 2259 47.150 23.120 22.580 1.00 0.00 +ATOM 7251 OW HOH 2260 46.870 29.660 19.750 1.00 0.00 +ATOM 7252 HW1 HOH 2260 47.240 30.370 19.220 1.00 0.00 +ATOM 7253 HW2 HOH 2260 46.140 30.070 20.210 1.00 0.00 +ATOM 7254 OW HOH 2261 39.930 37.100 2.330 1.00 0.00 +ATOM 7255 HW1 HOH 2261 39.040 37.380 2.540 1.00 0.00 +ATOM 7256 HW2 HOH 2261 40.470 37.500 3.020 1.00 0.00 +ATOM 7257 OW HOH 2262 31.960 35.690 20.640 1.00 0.00 +ATOM 7258 HW1 HOH 2262 32.360 35.000 21.170 1.00 0.00 +ATOM 7259 HW2 HOH 2262 31.610 36.310 21.280 1.00 0.00 +ATOM 7260 OW HOH 2263 35.840 17.180 21.180 1.00 0.00 +ATOM 7261 HW1 HOH 2263 35.700 16.730 22.010 1.00 0.00 +ATOM 7262 HW2 HOH 2263 36.710 16.910 20.890 1.00 0.00 +ATOM 7263 OW HOH 2264 22.180 4.500 28.800 1.00 0.00 +ATOM 7264 HW1 HOH 2264 22.810 3.970 29.300 1.00 0.00 +ATOM 7265 HW2 HOH 2264 22.370 5.410 29.060 1.00 0.00 +ATOM 7266 OW HOH 2265 47.290 29.470 34.500 1.00 0.00 +ATOM 7267 HW1 HOH 2265 47.480 28.800 33.840 1.00 0.00 +ATOM 7268 HW2 HOH 2265 46.860 30.180 34.020 1.00 0.00 +ATOM 7269 OW HOH 2266 18.720 15.880 34.690 1.00 0.00 +ATOM 7270 HW1 HOH 2266 18.030 16.530 34.590 1.00 0.00 +ATOM 7271 HW2 HOH 2266 19.370 16.310 35.240 1.00 0.00 +ATOM 7272 OW HOH 2267 36.750 23.400 22.790 1.00 0.00 +ATOM 7273 HW1 HOH 2267 36.050 22.750 22.910 1.00 0.00 +ATOM 7274 HW2 HOH 2267 36.390 24.030 22.160 1.00 0.00 +ATOM 7275 OW HOH 2268 21.980 37.210 17.830 1.00 0.00 +ATOM 7276 HW1 HOH 2268 21.120 36.960 18.160 1.00 0.00 +ATOM 7277 HW2 HOH 2268 21.900 38.130 17.590 1.00 0.00 +ATOM 7278 OW HOH 2269 5.780 31.620 9.790 1.00 0.00 +ATOM 7279 HW1 HOH 2269 6.340 30.870 9.590 1.00 0.00 +ATOM 7280 HW2 HOH 2269 5.320 31.810 8.970 1.00 0.00 +ATOM 7281 OW HOH 2270 12.870 27.110 5.880 1.00 0.00 +ATOM 7282 HW1 HOH 2270 13.170 26.420 5.290 1.00 0.00 +ATOM 7283 HW2 HOH 2270 11.980 26.850 6.110 1.00 0.00 +ATOM 7284 OW HOH 2271 1.160 7.350 7.140 1.00 0.00 +ATOM 7285 HW1 HOH 2271 0.900 6.430 7.170 1.00 0.00 +ATOM 7286 HW2 HOH 2271 2.110 7.330 6.990 1.00 0.00 +ATOM 7287 OW HOH 2272 3.830 34.680 29.470 1.00 0.00 +ATOM 7288 HW1 HOH 2272 3.380 35.030 30.240 1.00 0.00 +ATOM 7289 HW2 HOH 2272 4.450 34.050 29.830 1.00 0.00 +ATOM 7290 OW HOH 2273 27.680 7.120 6.870 1.00 0.00 +ATOM 7291 HW1 HOH 2273 26.900 7.190 7.430 1.00 0.00 +ATOM 7292 HW2 HOH 2273 27.420 6.530 6.170 1.00 0.00 +ATOM 7293 OW HOH 2274 1.750 2.120 11.280 1.00 0.00 +ATOM 7294 HW1 HOH 2274 2.130 2.990 11.280 1.00 0.00 +ATOM 7295 HW2 HOH 2274 0.900 2.220 11.710 1.00 0.00 +ATOM 7296 OW HOH 2275 45.070 26.460 37.190 1.00 0.00 +ATOM 7297 HW1 HOH 2275 45.800 26.340 36.580 1.00 0.00 +ATOM 7298 HW2 HOH 2275 44.950 25.600 37.590 1.00 0.00 +ATOM 7299 OW HOH 2276 48.090 18.290 29.930 1.00 0.00 +ATOM 7300 HW1 HOH 2276 47.490 17.620 29.600 1.00 0.00 +ATOM 7301 HW2 HOH 2276 47.740 19.110 29.570 1.00 0.00 +ATOM 7302 OW HOH 2277 38.350 44.660 3.190 1.00 0.00 +ATOM 7303 HW1 HOH 2277 38.930 43.930 3.010 1.00 0.00 +ATOM 7304 HW2 HOH 2277 38.270 45.130 2.360 1.00 0.00 +ATOM 7305 OW HOH 2278 11.260 27.610 27.300 1.00 0.00 +ATOM 7306 HW1 HOH 2278 11.520 27.730 26.380 1.00 0.00 +ATOM 7307 HW2 HOH 2278 10.350 27.330 27.250 1.00 0.00 +ATOM 7308 OW HOH 2279 29.370 45.180 30.700 1.00 0.00 +ATOM 7309 HW1 HOH 2279 28.920 44.360 30.920 1.00 0.00 +ATOM 7310 HW2 HOH 2279 30.020 45.290 31.400 1.00 0.00 +ATOM 7311 OW HOH 2280 16.370 22.380 13.960 1.00 0.00 +ATOM 7312 HW1 HOH 2280 16.670 21.960 13.150 1.00 0.00 +ATOM 7313 HW2 HOH 2280 15.440 22.190 14.000 1.00 0.00 +ATOM 7314 OW HOH 2281 6.350 20.660 23.110 1.00 0.00 +ATOM 7315 HW1 HOH 2281 6.780 21.350 23.610 1.00 0.00 +ATOM 7316 HW2 HOH 2281 6.850 20.600 22.300 1.00 0.00 +ATOM 7317 OW HOH 2282 16.520 7.360 33.520 1.00 0.00 +ATOM 7318 HW1 HOH 2282 16.420 7.700 32.630 1.00 0.00 +ATOM 7319 HW2 HOH 2282 16.930 8.070 34.010 1.00 0.00 +ATOM 7320 OW HOH 2283 7.020 32.420 23.910 1.00 0.00 +ATOM 7321 HW1 HOH 2283 6.260 32.880 23.550 1.00 0.00 +ATOM 7322 HW2 HOH 2283 7.770 32.850 23.500 1.00 0.00 +ATOM 7323 OW HOH 2284 26.440 24.830 37.510 1.00 0.00 +ATOM 7324 HW1 HOH 2284 26.450 23.970 37.930 1.00 0.00 +ATOM 7325 HW2 HOH 2284 27.100 25.340 37.990 1.00 0.00 +ATOM 7326 OW HOH 2285 0.820 34.700 13.650 1.00 0.00 +ATOM 7327 HW1 HOH 2285 0.740 33.830 13.260 1.00 0.00 +ATOM 7328 HW2 HOH 2285 1.440 35.160 13.080 1.00 0.00 +ATOM 7329 OW HOH 2286 8.280 0.160 21.220 1.00 0.00 +ATOM 7330 HW1 HOH 2286 8.930 0.870 21.160 1.00 0.00 +ATOM 7331 HW2 HOH 2286 7.440 0.610 21.180 1.00 0.00 +ATOM 7332 OW HOH 2287 30.060 32.570 5.610 1.00 0.00 +ATOM 7333 HW1 HOH 2287 30.720 32.650 4.920 1.00 0.00 +ATOM 7334 HW2 HOH 2287 30.560 32.440 6.410 1.00 0.00 +ATOM 7335 OW HOH 2288 29.510 16.470 37.880 1.00 0.00 +ATOM 7336 HW1 HOH 2288 28.690 16.380 38.360 1.00 0.00 +ATOM 7337 HW2 HOH 2288 29.970 17.180 38.340 1.00 0.00 +ATOM 7338 OW HOH 2289 44.900 22.750 37.180 1.00 0.00 +ATOM 7339 HW1 HOH 2289 44.700 23.140 36.330 1.00 0.00 +ATOM 7340 HW2 HOH 2289 44.560 23.380 37.810 1.00 0.00 +ATOM 7341 OW HOH 2290 19.930 35.730 4.530 1.00 0.00 +ATOM 7342 HW1 HOH 2290 19.100 36.140 4.770 1.00 0.00 +ATOM 7343 HW2 HOH 2290 20.500 36.450 4.270 1.00 0.00 +ATOM 7344 OW HOH 2291 21.670 25.860 37.290 1.00 0.00 +ATOM 7345 HW1 HOH 2291 21.800 26.740 37.630 1.00 0.00 +ATOM 7346 HW2 HOH 2291 22.310 25.320 37.750 1.00 0.00 +ATOM 7347 OW HOH 2292 27.430 11.910 25.210 1.00 0.00 +ATOM 7348 HW1 HOH 2292 28.240 12.110 25.680 1.00 0.00 +ATOM 7349 HW2 HOH 2292 26.760 11.890 25.900 1.00 0.00 +ATOM 7350 OW HOH 2293 22.580 39.610 10.510 1.00 0.00 +ATOM 7351 HW1 HOH 2293 21.820 39.050 10.370 1.00 0.00 +ATOM 7352 HW2 HOH 2293 23.210 39.350 9.840 1.00 0.00 +ATOM 7353 OW HOH 2294 42.180 21.070 3.360 1.00 0.00 +ATOM 7354 HW1 HOH 2294 42.750 21.670 3.840 1.00 0.00 +ATOM 7355 HW2 HOH 2294 41.340 21.130 3.820 1.00 0.00 +ATOM 7356 OW HOH 2295 8.040 11.430 30.230 1.00 0.00 +ATOM 7357 HW1 HOH 2295 8.150 12.380 30.250 1.00 0.00 +ATOM 7358 HW2 HOH 2295 7.580 11.230 31.040 1.00 0.00 +ATOM 7359 OW HOH 2296 8.670 7.730 5.020 1.00 0.00 +ATOM 7360 HW1 HOH 2296 8.890 7.400 5.890 1.00 0.00 +ATOM 7361 HW2 HOH 2296 8.480 8.660 5.160 1.00 0.00 +ATOM 7362 OW HOH 2297 8.910 42.100 6.770 1.00 0.00 +ATOM 7363 HW1 HOH 2297 8.660 42.760 6.120 1.00 0.00 +ATOM 7364 HW2 HOH 2297 9.400 42.590 7.440 1.00 0.00 +ATOM 7365 OW HOH 2298 8.850 5.390 32.880 1.00 0.00 +ATOM 7366 HW1 HOH 2298 8.590 6.070 33.500 1.00 0.00 +ATOM 7367 HW2 HOH 2298 9.700 5.670 32.560 1.00 0.00 +ATOM 7368 OW HOH 2299 13.160 25.430 3.940 1.00 0.00 +ATOM 7369 HW1 HOH 2299 13.780 25.040 3.320 1.00 0.00 +ATOM 7370 HW2 HOH 2299 12.390 24.860 3.910 1.00 0.00 +ATOM 7371 OW HOH 2300 20.600 11.430 11.800 1.00 0.00 +ATOM 7372 HW1 HOH 2300 21.070 10.600 11.710 1.00 0.00 +ATOM 7373 HW2 HOH 2300 21.230 12.100 11.540 1.00 0.00 +ATOM 7374 OW HOH 2301 29.600 33.660 35.410 1.00 0.00 +ATOM 7375 HW1 HOH 2301 28.860 33.050 35.470 1.00 0.00 +ATOM 7376 HW2 HOH 2301 29.460 34.280 36.130 1.00 0.00 +ATOM 7377 OW HOH 2302 19.130 38.000 24.050 1.00 0.00 +ATOM 7378 HW1 HOH 2302 18.670 38.380 24.810 1.00 0.00 +ATOM 7379 HW2 HOH 2302 19.790 37.420 24.440 1.00 0.00 +ATOM 7380 OW HOH 2303 40.860 32.990 20.140 1.00 0.00 +ATOM 7381 HW1 HOH 2303 41.640 32.580 19.760 1.00 0.00 +ATOM 7382 HW2 HOH 2303 40.700 32.480 20.930 1.00 0.00 +ATOM 7383 OW HOH 2304 29.850 0.990 12.310 1.00 0.00 +ATOM 7384 HW1 HOH 2304 29.600 0.130 12.670 1.00 0.00 +ATOM 7385 HW2 HOH 2304 29.120 1.560 12.530 1.00 0.00 +ATOM 7386 OW HOH 2305 14.340 35.530 9.020 1.00 0.00 +ATOM 7387 HW1 HOH 2305 14.750 35.990 8.290 1.00 0.00 +ATOM 7388 HW2 HOH 2305 13.970 34.740 8.630 1.00 0.00 +ATOM 7389 OW HOH 2306 24.350 4.790 24.040 1.00 0.00 +ATOM 7390 HW1 HOH 2306 25.010 4.160 24.340 1.00 0.00 +ATOM 7391 HW2 HOH 2306 24.620 5.010 23.140 1.00 0.00 +ATOM 7392 OW HOH 2307 16.300 30.680 10.930 1.00 0.00 +ATOM 7393 HW1 HOH 2307 16.230 30.900 11.860 1.00 0.00 +ATOM 7394 HW2 HOH 2307 17.190 30.320 10.830 1.00 0.00 +ATOM 7395 OW HOH 2308 38.330 21.880 34.810 1.00 0.00 +ATOM 7396 HW1 HOH 2308 38.290 22.840 34.820 1.00 0.00 +ATOM 7397 HW2 HOH 2308 37.550 21.610 35.290 1.00 0.00 +ATOM 7398 OW HOH 2309 47.650 23.580 35.600 1.00 0.00 +ATOM 7399 HW1 HOH 2309 46.990 23.070 35.130 1.00 0.00 +ATOM 7400 HW2 HOH 2309 47.460 24.490 35.370 1.00 0.00 +ATOM 7401 OW HOH 2310 21.390 25.510 9.240 1.00 0.00 +ATOM 7402 HW1 HOH 2310 21.650 24.600 9.380 1.00 0.00 +ATOM 7403 HW2 HOH 2310 21.970 25.810 8.540 1.00 0.00 +ATOM 7404 OW HOH 2311 37.000 22.600 26.720 1.00 0.00 +ATOM 7405 HW1 HOH 2311 36.110 22.320 26.930 1.00 0.00 +ATOM 7406 HW2 HOH 2311 36.910 23.500 26.410 1.00 0.00 +ATOM 7407 OW HOH 2312 11.980 39.270 17.800 1.00 0.00 +ATOM 7408 HW1 HOH 2312 12.740 39.850 17.690 1.00 0.00 +ATOM 7409 HW2 HOH 2312 12.160 38.520 17.250 1.00 0.00 +ATOM 7410 OW HOH 2313 33.380 13.580 5.870 1.00 0.00 +ATOM 7411 HW1 HOH 2313 32.830 13.710 6.650 1.00 0.00 +ATOM 7412 HW2 HOH 2313 34.130 13.080 6.190 1.00 0.00 +ATOM 7413 OW HOH 2314 36.660 21.520 38.740 1.00 0.00 +ATOM 7414 HW1 HOH 2314 36.980 22.350 38.390 1.00 0.00 +ATOM 7415 HW2 HOH 2314 36.470 20.990 37.970 1.00 0.00 +ATOM 7416 OW HOH 2315 47.990 31.700 18.820 1.00 0.00 +ATOM 7417 HW1 HOH 2315 48.040 32.460 19.400 1.00 0.00 +ATOM 7418 HW2 HOH 2315 48.100 32.060 17.940 1.00 0.00 +ATOM 7419 OW HOH 2316 2.290 6.030 20.260 1.00 0.00 +ATOM 7420 HW1 HOH 2316 2.850 5.470 19.730 1.00 0.00 +ATOM 7421 HW2 HOH 2316 1.420 5.630 20.200 1.00 0.00 +ATOM 7422 OW HOH 2317 47.530 20.070 4.510 1.00 0.00 +ATOM 7423 HW1 HOH 2317 48.280 20.480 4.080 1.00 0.00 +ATOM 7424 HW2 HOH 2317 46.830 20.090 3.860 1.00 0.00 +ATOM 7425 OW HOH 2318 32.250 17.670 6.620 1.00 0.00 +ATOM 7426 HW1 HOH 2318 33.000 17.290 6.160 1.00 0.00 +ATOM 7427 HW2 HOH 2318 31.500 17.460 6.070 1.00 0.00 +ATOM 7428 OW HOH 2319 46.960 40.290 34.880 1.00 0.00 +ATOM 7429 HW1 HOH 2319 46.700 41.170 35.160 1.00 0.00 +ATOM 7430 HW2 HOH 2319 46.950 39.780 35.690 1.00 0.00 +ATOM 7431 OW HOH 2320 2.410 32.170 36.510 1.00 0.00 +ATOM 7432 HW1 HOH 2320 2.040 32.000 35.640 1.00 0.00 +ATOM 7433 HW2 HOH 2320 1.750 31.830 37.120 1.00 0.00 +ATOM 7434 OW HOH 2321 13.550 41.260 22.040 1.00 0.00 +ATOM 7435 HW1 HOH 2321 13.720 42.150 21.730 1.00 0.00 +ATOM 7436 HW2 HOH 2321 13.260 40.780 21.260 1.00 0.00 +ATOM 7437 OW HOH 2322 12.100 3.910 28.080 1.00 0.00 +ATOM 7438 HW1 HOH 2322 12.900 3.520 28.430 1.00 0.00 +ATOM 7439 HW2 HOH 2322 11.540 3.170 27.870 1.00 0.00 +ATOM 7440 OW HOH 2323 3.940 35.520 33.970 1.00 0.00 +ATOM 7441 HW1 HOH 2323 3.990 36.250 33.350 1.00 0.00 +ATOM 7442 HW2 HOH 2323 3.610 34.790 33.460 1.00 0.00 +ATOM 7443 OW HOH 2324 16.440 21.940 36.720 1.00 0.00 +ATOM 7444 HW1 HOH 2324 16.240 21.120 37.170 1.00 0.00 +ATOM 7445 HW2 HOH 2324 16.080 21.830 35.840 1.00 0.00 +ATOM 7446 OW HOH 2325 25.900 10.210 17.560 1.00 0.00 +ATOM 7447 HW1 HOH 2325 26.170 9.710 16.790 1.00 0.00 +ATOM 7448 HW2 HOH 2325 25.050 10.590 17.310 1.00 0.00 +ATOM 7449 OW HOH 2326 41.080 41.620 13.280 1.00 0.00 +ATOM 7450 HW1 HOH 2326 40.870 41.380 12.380 1.00 0.00 +ATOM 7451 HW2 HOH 2326 42.040 41.720 13.280 1.00 0.00 +ATOM 7452 OW HOH 2327 8.110 44.730 31.110 1.00 0.00 +ATOM 7453 HW1 HOH 2327 8.290 44.320 30.260 1.00 0.00 +ATOM 7454 HW2 HOH 2327 8.710 44.310 31.720 1.00 0.00 +ATOM 7455 OW HOH 2328 35.580 42.440 4.980 1.00 0.00 +ATOM 7456 HW1 HOH 2328 36.270 43.030 5.260 1.00 0.00 +ATOM 7457 HW2 HOH 2328 36.010 41.590 4.860 1.00 0.00 +ATOM 7458 OW HOH 2329 40.350 27.130 7.820 1.00 0.00 +ATOM 7459 HW1 HOH 2329 40.210 27.240 8.760 1.00 0.00 +ATOM 7460 HW2 HOH 2329 39.880 27.870 7.420 1.00 0.00 +ATOM 7461 OW HOH 2330 41.410 24.120 32.260 1.00 0.00 +ATOM 7462 HW1 HOH 2330 42.000 24.770 32.650 1.00 0.00 +ATOM 7463 HW2 HOH 2330 40.570 24.270 32.690 1.00 0.00 +ATOM 7464 OW HOH 2331 4.880 3.770 16.440 1.00 0.00 +ATOM 7465 HW1 HOH 2331 4.420 3.120 16.970 1.00 0.00 +ATOM 7466 HW2 HOH 2331 5.150 4.440 17.060 1.00 0.00 +ATOM 7467 OW HOH 2332 45.110 33.600 21.400 1.00 0.00 +ATOM 7468 HW1 HOH 2332 44.640 33.990 20.660 1.00 0.00 +ATOM 7469 HW2 HOH 2332 46.040 33.720 21.180 1.00 0.00 +ATOM 7470 OW HOH 2333 42.020 23.280 16.600 1.00 0.00 +ATOM 7471 HW1 HOH 2333 42.300 23.060 17.490 1.00 0.00 +ATOM 7472 HW2 HOH 2333 42.840 23.320 16.100 1.00 0.00 +ATOM 7473 OW HOH 2334 42.170 20.070 37.980 1.00 0.00 +ATOM 7474 HW1 HOH 2334 42.860 20.150 37.320 1.00 0.00 +ATOM 7475 HW2 HOH 2334 41.650 20.870 37.870 1.00 0.00 +ATOM 7476 OW HOH 2335 42.580 41.030 16.650 1.00 0.00 +ATOM 7477 HW1 HOH 2335 41.690 41.380 16.700 1.00 0.00 +ATOM 7478 HW2 HOH 2335 43.070 41.680 16.150 1.00 0.00 +ATOM 7479 OW HOH 2336 15.700 41.150 37.450 1.00 0.00 +ATOM 7480 HW1 HOH 2336 14.750 41.100 37.580 1.00 0.00 +ATOM 7481 HW2 HOH 2336 15.950 41.970 37.860 1.00 0.00 +ATOM 7482 OW HOH 2337 34.740 37.360 29.300 1.00 0.00 +ATOM 7483 HW1 HOH 2337 35.570 37.000 29.590 1.00 0.00 +ATOM 7484 HW2 HOH 2337 34.740 38.260 29.630 1.00 0.00 +ATOM 7485 OW HOH 2338 48.400 37.180 11.420 1.00 0.00 +ATOM 7486 HW1 HOH 2338 48.190 38.100 11.550 1.00 0.00 +ATOM 7487 HW2 HOH 2338 49.310 37.100 11.690 1.00 0.00 +ATOM 7488 OW HOH 2339 19.620 25.320 1.770 1.00 0.00 +ATOM 7489 HW1 HOH 2339 18.970 25.160 2.450 1.00 0.00 +ATOM 7490 HW2 HOH 2339 19.750 24.470 1.350 1.00 0.00 +ATOM 7491 OW HOH 2340 46.190 6.860 25.730 1.00 0.00 +ATOM 7492 HW1 HOH 2340 45.460 6.290 25.940 1.00 0.00 +ATOM 7493 HW2 HOH 2340 46.930 6.500 26.210 1.00 0.00 +ATOM 7494 OW HOH 2341 37.210 25.560 10.330 1.00 0.00 +ATOM 7495 HW1 HOH 2341 37.400 25.080 9.520 1.00 0.00 +ATOM 7496 HW2 HOH 2341 37.690 25.080 11.010 1.00 0.00 +ATOM 7497 OW HOH 2342 33.990 36.190 10.090 1.00 0.00 +ATOM 7498 HW1 HOH 2342 33.560 37.010 10.330 1.00 0.00 +ATOM 7499 HW2 HOH 2342 33.540 35.520 10.610 1.00 0.00 +ATOM 7500 OW HOH 2343 45.120 42.400 33.330 1.00 0.00 +ATOM 7501 HW1 HOH 2343 45.320 43.340 33.400 1.00 0.00 +ATOM 7502 HW2 HOH 2343 45.970 41.970 33.300 1.00 0.00 +ATOM 7503 OW HOH 2344 40.460 31.950 37.090 1.00 0.00 +ATOM 7504 HW1 HOH 2344 40.820 31.890 36.200 1.00 0.00 +ATOM 7505 HW2 HOH 2344 41.000 31.350 37.600 1.00 0.00 +ATOM 7506 OW HOH 2345 40.940 37.980 19.430 1.00 0.00 +ATOM 7507 HW1 HOH 2345 40.310 38.080 18.720 1.00 0.00 +ATOM 7508 HW2 HOH 2345 41.760 37.740 19.000 1.00 0.00 +ATOM 7509 OW HOH 2346 0.160 13.590 27.370 1.00 0.00 +ATOM 7510 HW1 HOH 2346 0.400 13.060 26.610 1.00 0.00 +ATOM 7511 HW2 HOH 2346 -0.380 14.290 27.020 1.00 0.00 +ATOM 7512 OW HOH 2347 39.210 3.600 0.840 1.00 0.00 +ATOM 7513 HW1 HOH 2347 38.340 3.550 0.470 1.00 0.00 +ATOM 7514 HW2 HOH 2347 39.350 4.540 1.000 1.00 0.00 +ATOM 7515 OW HOH 2348 7.480 23.080 0.790 1.00 0.00 +ATOM 7516 HW1 HOH 2348 6.580 23.110 0.450 1.00 0.00 +ATOM 7517 HW2 HOH 2348 7.380 22.700 1.670 1.00 0.00 +ATOM 7518 OW HOH 2349 10.770 42.580 26.440 1.00 0.00 +ATOM 7519 HW1 HOH 2349 11.400 41.990 26.030 1.00 0.00 +ATOM 7520 HW2 HOH 2349 9.940 42.100 26.420 1.00 0.00 +ATOM 7521 OW HOH 2350 17.540 28.380 7.230 1.00 0.00 +ATOM 7522 HW1 HOH 2350 16.580 28.380 7.160 1.00 0.00 +ATOM 7523 HW2 HOH 2350 17.710 28.690 8.120 1.00 0.00 +ATOM 7524 OW HOH 2351 1.720 40.190 35.280 1.00 0.00 +ATOM 7525 HW1 HOH 2351 1.180 39.400 35.330 1.00 0.00 +ATOM 7526 HW2 HOH 2351 1.280 40.820 35.850 1.00 0.00 +ATOM 7527 OW HOH 2352 10.530 27.010 11.040 1.00 0.00 +ATOM 7528 HW1 HOH 2352 10.310 27.430 11.870 1.00 0.00 +ATOM 7529 HW2 HOH 2352 11.450 27.220 10.900 1.00 0.00 +ATOM 7530 OW HOH 2353 5.670 3.620 34.910 1.00 0.00 +ATOM 7531 HW1 HOH 2353 6.450 3.420 34.390 1.00 0.00 +ATOM 7532 HW2 HOH 2353 6.000 4.080 35.680 1.00 0.00 +ATOM 7533 OW HOH 2354 26.960 33.040 36.110 1.00 0.00 +ATOM 7534 HW1 HOH 2354 27.200 32.360 35.490 1.00 0.00 +ATOM 7535 HW2 HOH 2354 26.140 32.730 36.500 1.00 0.00 +ATOM 7536 OW HOH 2355 47.600 43.050 0.590 1.00 0.00 +ATOM 7537 HW1 HOH 2355 47.800 43.340 -0.300 1.00 0.00 +ATOM 7538 HW2 HOH 2355 47.750 43.820 1.140 1.00 0.00 +ATOM 7539 OW HOH 2356 0.400 26.810 25.890 1.00 0.00 +ATOM 7540 HW1 HOH 2356 -0.320 27.350 25.560 1.00 0.00 +ATOM 7541 HW2 HOH 2356 1.070 26.870 25.210 1.00 0.00 +ATOM 7542 OW HOH 2357 23.440 28.240 37.280 1.00 0.00 +ATOM 7543 HW1 HOH 2357 22.820 28.910 37.540 1.00 0.00 +ATOM 7544 HW2 HOH 2357 23.770 28.530 36.430 1.00 0.00 +ATOM 7545 OW HOH 2358 10.450 12.260 32.910 1.00 0.00 +ATOM 7546 HW1 HOH 2358 11.400 12.210 32.940 1.00 0.00 +ATOM 7547 HW2 HOH 2358 10.160 11.400 33.240 1.00 0.00 +ATOM 7548 OW HOH 2359 12.780 36.840 16.430 1.00 0.00 +ATOM 7549 HW1 HOH 2359 12.310 36.930 15.590 1.00 0.00 +ATOM 7550 HW2 HOH 2359 12.690 35.910 16.640 1.00 0.00 +ATOM 7551 OW HOH 2360 0.660 3.980 36.850 1.00 0.00 +ATOM 7552 HW1 HOH 2360 1.420 3.880 36.280 1.00 0.00 +ATOM 7553 HW2 HOH 2360 0.900 4.690 37.450 1.00 0.00 +ATOM 7554 OW HOH 2361 36.630 7.170 29.820 1.00 0.00 +ATOM 7555 HW1 HOH 2361 36.330 6.910 28.950 1.00 0.00 +ATOM 7556 HW2 HOH 2361 37.330 6.540 30.030 1.00 0.00 +ATOM 7557 OW HOH 2362 31.430 21.190 35.160 1.00 0.00 +ATOM 7558 HW1 HOH 2362 31.320 20.290 34.860 1.00 0.00 +ATOM 7559 HW2 HOH 2362 32.290 21.200 35.570 1.00 0.00 +ATOM 7560 OW HOH 2363 32.570 6.290 13.640 1.00 0.00 +ATOM 7561 HW1 HOH 2363 33.190 5.580 13.770 1.00 0.00 +ATOM 7562 HW2 HOH 2363 32.000 5.980 12.940 1.00 0.00 +ATOM 7563 OW HOH 2364 47.870 35.780 31.880 1.00 0.00 +ATOM 7564 HW1 HOH 2364 48.350 35.000 31.590 1.00 0.00 +ATOM 7565 HW2 HOH 2364 47.850 36.350 31.110 1.00 0.00 +ATOM 7566 OW HOH 2365 16.070 4.810 6.560 1.00 0.00 +ATOM 7567 HW1 HOH 2365 15.770 3.900 6.590 1.00 0.00 +ATOM 7568 HW2 HOH 2365 15.330 5.290 6.200 1.00 0.00 +ATOM 7569 OW HOH 2366 44.620 38.880 3.590 1.00 0.00 +ATOM 7570 HW1 HOH 2366 44.170 38.460 4.320 1.00 0.00 +ATOM 7571 HW2 HOH 2366 44.350 38.370 2.820 1.00 0.00 +ATOM 7572 OW HOH 2367 3.850 19.690 34.370 1.00 0.00 +ATOM 7573 HW1 HOH 2367 3.920 20.190 33.560 1.00 0.00 +ATOM 7574 HW2 HOH 2367 3.000 19.250 34.310 1.00 0.00 +ATOM 7575 OW HOH 2368 32.500 9.990 20.360 1.00 0.00 +ATOM 7576 HW1 HOH 2368 32.500 9.990 19.410 1.00 0.00 +ATOM 7577 HW2 HOH 2368 32.710 10.890 20.610 1.00 0.00 +ATOM 7578 OW HOH 2369 26.240 44.410 11.650 1.00 0.00 +ATOM 7579 HW1 HOH 2369 25.740 43.620 11.840 1.00 0.00 +ATOM 7580 HW2 HOH 2369 26.740 44.200 10.860 1.00 0.00 +ATOM 7581 OW HOH 2370 44.390 30.850 3.680 1.00 0.00 +ATOM 7582 HW1 HOH 2370 44.870 31.590 3.310 1.00 0.00 +ATOM 7583 HW2 HOH 2370 43.720 31.240 4.240 1.00 0.00 +ATOM 7584 OW HOH 2371 28.890 20.150 1.990 1.00 0.00 +ATOM 7585 HW1 HOH 2371 28.760 20.880 2.590 1.00 0.00 +ATOM 7586 HW2 HOH 2371 28.620 19.380 2.490 1.00 0.00 +ATOM 7587 OW HOH 2372 40.440 41.690 32.540 1.00 0.00 +ATOM 7588 HW1 HOH 2372 40.940 42.400 32.950 1.00 0.00 +ATOM 7589 HW2 HOH 2372 40.330 41.960 31.630 1.00 0.00 +ATOM 7590 OW HOH 2373 33.410 2.220 25.590 1.00 0.00 +ATOM 7591 HW1 HOH 2373 33.290 3.100 25.230 1.00 0.00 +ATOM 7592 HW2 HOH 2373 33.690 2.370 26.500 1.00 0.00 +ATOM 7593 OW HOH 2374 22.110 22.850 9.120 1.00 0.00 +ATOM 7594 HW1 HOH 2374 22.420 21.950 9.240 1.00 0.00 +ATOM 7595 HW2 HOH 2374 21.760 22.860 8.230 1.00 0.00 +ATOM 7596 OW HOH 2375 46.730 16.970 16.860 1.00 0.00 +ATOM 7597 HW1 HOH 2375 47.440 16.910 17.500 1.00 0.00 +ATOM 7598 HW2 HOH 2375 46.830 16.180 16.320 1.00 0.00 +ATOM 7599 OW HOH 2376 26.880 11.650 19.690 1.00 0.00 +ATOM 7600 HW1 HOH 2376 27.750 11.730 20.080 1.00 0.00 +ATOM 7601 HW2 HOH 2376 27.010 11.100 18.920 1.00 0.00 +ATOM 7602 OW HOH 2377 8.290 2.290 29.040 1.00 0.00 +ATOM 7603 HW1 HOH 2377 9.020 1.780 28.680 1.00 0.00 +ATOM 7604 HW2 HOH 2377 8.660 3.160 29.180 1.00 0.00 +ATOM 7605 OW HOH 2378 31.300 34.420 1.620 1.00 0.00 +ATOM 7606 HW1 HOH 2378 31.570 33.720 2.220 1.00 0.00 +ATOM 7607 HW2 HOH 2378 30.670 34.940 2.130 1.00 0.00 +ATOM 7608 OW HOH 2379 26.860 34.710 30.810 1.00 0.00 +ATOM 7609 HW1 HOH 2379 26.100 35.260 30.630 1.00 0.00 +ATOM 7610 HW2 HOH 2379 27.610 35.300 30.730 1.00 0.00 +ATOM 7611 OW HOH 2380 41.780 38.200 13.130 1.00 0.00 +ATOM 7612 HW1 HOH 2380 42.220 38.990 12.810 1.00 0.00 +ATOM 7613 HW2 HOH 2380 40.860 38.450 13.210 1.00 0.00 +ATOM 7614 OW HOH 2381 20.170 41.830 2.010 1.00 0.00 +ATOM 7615 HW1 HOH 2381 20.210 42.410 1.240 1.00 0.00 +ATOM 7616 HW2 HOH 2381 20.060 40.950 1.640 1.00 0.00 +ATOM 7617 OW HOH 2382 28.860 5.610 27.770 1.00 0.00 +ATOM 7618 HW1 HOH 2382 29.030 4.670 27.800 1.00 0.00 +ATOM 7619 HW2 HOH 2382 28.600 5.830 28.660 1.00 0.00 +ATOM 7620 OW HOH 2383 31.160 0.430 0.650 1.00 0.00 +ATOM 7621 HW1 HOH 2383 31.840 1.000 0.290 1.00 0.00 +ATOM 7622 HW2 HOH 2383 31.510 0.130 1.490 1.00 0.00 +ATOM 7623 OW HOH 2384 30.050 36.670 2.830 1.00 0.00 +ATOM 7624 HW1 HOH 2384 29.320 36.740 3.440 1.00 0.00 +ATOM 7625 HW2 HOH 2384 30.380 37.570 2.760 1.00 0.00 +ATOM 7626 OW HOH 2385 11.440 24.740 28.390 1.00 0.00 +ATOM 7627 HW1 HOH 2385 12.220 24.410 27.950 1.00 0.00 +ATOM 7628 HW2 HOH 2385 11.560 25.690 28.390 1.00 0.00 +ATOM 7629 OW HOH 2386 1.480 13.160 29.850 1.00 0.00 +ATOM 7630 HW1 HOH 2386 0.860 12.720 30.440 1.00 0.00 +ATOM 7631 HW2 HOH 2386 1.060 13.120 28.990 1.00 0.00 +ATOM 7632 OW HOH 2387 47.790 23.600 38.590 1.00 0.00 +ATOM 7633 HW1 HOH 2387 47.350 23.450 37.760 1.00 0.00 +ATOM 7634 HW2 HOH 2387 47.180 23.290 39.260 1.00 0.00 +ATOM 7635 OW HOH 2388 27.080 34.970 20.000 1.00 0.00 +ATOM 7636 HW1 HOH 2388 27.790 35.310 19.470 1.00 0.00 +ATOM 7637 HW2 HOH 2388 27.270 35.280 20.890 1.00 0.00 +ATOM 7638 OW HOH 2389 37.860 40.010 28.660 1.00 0.00 +ATOM 7639 HW1 HOH 2389 37.580 40.220 29.550 1.00 0.00 +ATOM 7640 HW2 HOH 2389 37.650 40.800 28.150 1.00 0.00 +ATOM 7641 OW HOH 2390 45.320 14.630 14.940 1.00 0.00 +ATOM 7642 HW1 HOH 2390 44.840 14.970 15.700 1.00 0.00 +ATOM 7643 HW2 HOH 2390 45.130 15.260 14.240 1.00 0.00 +ATOM 7644 OW HOH 2391 40.650 43.810 5.850 1.00 0.00 +ATOM 7645 HW1 HOH 2391 41.110 44.000 6.670 1.00 0.00 +ATOM 7646 HW2 HOH 2391 40.670 44.630 5.360 1.00 0.00 +ATOM 7647 OW HOH 2392 46.990 27.770 29.220 1.00 0.00 +ATOM 7648 HW1 HOH 2392 46.450 26.980 29.150 1.00 0.00 +ATOM 7649 HW2 HOH 2392 47.830 27.460 29.560 1.00 0.00 +ATOM 7650 OW HOH 2393 33.200 10.660 17.780 1.00 0.00 +ATOM 7651 HW1 HOH 2393 33.380 11.600 17.750 1.00 0.00 +ATOM 7652 HW2 HOH 2393 34.050 10.250 17.610 1.00 0.00 +ATOM 7653 OW HOH 2394 37.780 17.260 5.280 1.00 0.00 +ATOM 7654 HW1 HOH 2394 37.970 17.990 4.700 1.00 0.00 +ATOM 7655 HW2 HOH 2394 37.500 16.550 4.700 1.00 0.00 +ATOM 7656 OW HOH 2395 38.650 41.890 18.110 1.00 0.00 +ATOM 7657 HW1 HOH 2395 38.060 42.610 18.350 1.00 0.00 +ATOM 7658 HW2 HOH 2395 39.180 42.240 17.390 1.00 0.00 +ATOM 7659 OW HOH 2396 4.800 42.830 20.900 1.00 0.00 +ATOM 7660 HW1 HOH 2396 4.170 42.360 20.350 1.00 0.00 +ATOM 7661 HW2 HOH 2396 5.650 42.600 20.530 1.00 0.00 +ATOM 7662 OW HOH 2397 48.630 27.920 10.220 1.00 0.00 +ATOM 7663 HW1 HOH 2397 49.280 28.260 9.600 1.00 0.00 +ATOM 7664 HW2 HOH 2397 48.460 27.020 9.930 1.00 0.00 +ATOM 7665 OW HOH 2398 46.990 17.680 22.330 1.00 0.00 +ATOM 7666 HW1 HOH 2398 47.640 17.060 22.000 1.00 0.00 +ATOM 7667 HW2 HOH 2398 47.160 18.490 21.840 1.00 0.00 +ATOM 7668 OW HOH 2399 15.160 33.930 16.390 1.00 0.00 +ATOM 7669 HW1 HOH 2399 14.210 34.010 16.510 1.00 0.00 +ATOM 7670 HW2 HOH 2399 15.320 32.980 16.430 1.00 0.00 +ATOM 7671 OW HOH 2400 10.530 42.840 8.930 1.00 0.00 +ATOM 7672 HW1 HOH 2400 9.840 42.250 9.250 1.00 0.00 +ATOM 7673 HW2 HOH 2400 10.470 43.600 9.510 1.00 0.00 +ATOM 7674 OW HOH 2401 17.240 19.270 4.690 1.00 0.00 +ATOM 7675 HW1 HOH 2401 16.540 19.020 5.310 1.00 0.00 +ATOM 7676 HW2 HOH 2401 16.830 19.180 3.830 1.00 0.00 +ATOM 7677 OW HOH 2402 45.630 8.550 28.000 1.00 0.00 +ATOM 7678 HW1 HOH 2402 45.810 7.830 28.610 1.00 0.00 +ATOM 7679 HW2 HOH 2402 46.120 8.310 27.210 1.00 0.00 +ATOM 7680 OW HOH 2403 36.580 42.600 33.790 1.00 0.00 +ATOM 7681 HW1 HOH 2403 35.970 42.010 34.250 1.00 0.00 +ATOM 7682 HW2 HOH 2403 36.150 42.770 32.950 1.00 0.00 +ATOM 7683 OW HOH 2404 29.860 19.630 33.430 1.00 0.00 +ATOM 7684 HW1 HOH 2404 29.240 20.360 33.450 1.00 0.00 +ATOM 7685 HW2 HOH 2404 29.540 19.060 32.730 1.00 0.00 +ATOM 7686 OW HOH 2405 6.570 35.710 5.110 1.00 0.00 +ATOM 7687 HW1 HOH 2405 7.470 35.660 5.410 1.00 0.00 +ATOM 7688 HW2 HOH 2405 6.440 36.630 4.880 1.00 0.00 +ATOM 7689 OW HOH 2406 48.840 12.260 22.120 1.00 0.00 +ATOM 7690 HW1 HOH 2406 48.070 12.830 22.170 1.00 0.00 +ATOM 7691 HW2 HOH 2406 49.370 12.630 21.420 1.00 0.00 +ATOM 7692 OW HOH 2407 29.390 15.730 1.910 1.00 0.00 +ATOM 7693 HW1 HOH 2407 29.110 15.000 2.460 1.00 0.00 +ATOM 7694 HW2 HOH 2407 30.340 15.610 1.830 1.00 0.00 +ATOM 7695 OW HOH 2408 41.400 30.830 23.980 1.00 0.00 +ATOM 7696 HW1 HOH 2408 40.730 31.290 23.480 1.00 0.00 +ATOM 7697 HW2 HOH 2408 41.070 29.940 24.080 1.00 0.00 +ATOM 7698 OW HOH 2409 7.460 17.580 25.540 1.00 0.00 +ATOM 7699 HW1 HOH 2409 7.280 16.640 25.520 1.00 0.00 +ATOM 7700 HW2 HOH 2409 8.340 17.670 25.170 1.00 0.00 +ATOM 7701 OW HOH 2410 10.490 38.940 4.260 1.00 0.00 +ATOM 7702 HW1 HOH 2410 9.950 38.390 3.690 1.00 0.00 +ATOM 7703 HW2 HOH 2410 11.030 39.450 3.650 1.00 0.00 +ATOM 7704 OW HOH 2411 27.880 34.140 4.820 1.00 0.00 +ATOM 7705 HW1 HOH 2411 28.440 33.690 5.450 1.00 0.00 +ATOM 7706 HW2 HOH 2411 27.700 35.000 5.230 1.00 0.00 +ATOM 7707 OW HOH 2412 38.070 11.990 36.870 1.00 0.00 +ATOM 7708 HW1 HOH 2412 38.750 12.660 36.980 1.00 0.00 +ATOM 7709 HW2 HOH 2412 38.390 11.240 37.370 1.00 0.00 +ATOM 7710 OW HOH 2413 41.970 20.740 21.540 1.00 0.00 +ATOM 7711 HW1 HOH 2413 41.110 20.470 21.850 1.00 0.00 +ATOM 7712 HW2 HOH 2413 42.420 19.910 21.340 1.00 0.00 +ATOM 7713 OW HOH 2414 19.330 11.130 35.680 1.00 0.00 +ATOM 7714 HW1 HOH 2414 20.170 11.400 35.320 1.00 0.00 +ATOM 7715 HW2 HOH 2414 18.960 11.930 36.050 1.00 0.00 +ATOM 7716 OW HOH 2415 2.280 31.110 5.380 1.00 0.00 +ATOM 7717 HW1 HOH 2415 1.610 30.610 4.920 1.00 0.00 +ATOM 7718 HW2 HOH 2415 1.950 32.010 5.370 1.00 0.00 +ATOM 7719 OW HOH 2416 46.540 29.380 16.860 1.00 0.00 +ATOM 7720 HW1 HOH 2416 45.690 29.080 16.550 1.00 0.00 +ATOM 7721 HW2 HOH 2416 46.650 28.940 17.710 1.00 0.00 +ATOM 7722 OW HOH 2417 25.990 25.010 28.570 1.00 0.00 +ATOM 7723 HW1 HOH 2417 25.860 25.810 28.070 1.00 0.00 +ATOM 7724 HW2 HOH 2417 25.340 25.050 29.270 1.00 0.00 +ATOM 7725 OW HOH 2418 44.310 36.190 10.520 1.00 0.00 +ATOM 7726 HW1 HOH 2418 45.260 36.150 10.420 1.00 0.00 +ATOM 7727 HW2 HOH 2418 43.990 35.380 10.130 1.00 0.00 +ATOM 7728 OW HOH 2419 9.830 8.280 21.590 1.00 0.00 +ATOM 7729 HW1 HOH 2419 10.530 8.820 21.960 1.00 0.00 +ATOM 7730 HW2 HOH 2419 10.150 7.380 21.660 1.00 0.00 +ATOM 7731 OW HOH 2420 34.460 18.460 35.640 1.00 0.00 +ATOM 7732 HW1 HOH 2420 34.770 17.830 34.990 1.00 0.00 +ATOM 7733 HW2 HOH 2420 33.580 18.160 35.870 1.00 0.00 +ATOM 7734 OW HOH 2421 39.170 8.410 25.530 1.00 0.00 +ATOM 7735 HW1 HOH 2421 39.670 7.840 26.120 1.00 0.00 +ATOM 7736 HW2 HOH 2421 39.570 8.270 24.670 1.00 0.00 +ATOM 7737 OW HOH 2422 36.340 12.390 13.720 1.00 0.00 +ATOM 7738 HW1 HOH 2422 35.930 12.730 12.920 1.00 0.00 +ATOM 7739 HW2 HOH 2422 35.700 12.560 14.410 1.00 0.00 +ATOM 7740 OW HOH 2423 11.780 6.170 3.090 1.00 0.00 +ATOM 7741 HW1 HOH 2423 11.080 6.780 2.860 1.00 0.00 +ATOM 7742 HW2 HOH 2423 12.170 5.920 2.260 1.00 0.00 +ATOM 7743 OW HOH 2424 13.250 27.830 9.840 1.00 0.00 +ATOM 7744 HW1 HOH 2424 14.000 27.300 9.590 1.00 0.00 +ATOM 7745 HW2 HOH 2424 13.460 28.140 10.720 1.00 0.00 +ATOM 7746 OW HOH 2425 35.920 10.070 17.580 1.00 0.00 +ATOM 7747 HW1 HOH 2425 36.540 10.800 17.600 1.00 0.00 +ATOM 7748 HW2 HOH 2425 36.170 9.520 18.320 1.00 0.00 +ATOM 7749 OW HOH 2426 41.130 30.260 13.300 1.00 0.00 +ATOM 7750 HW1 HOH 2426 40.910 30.730 12.500 1.00 0.00 +ATOM 7751 HW2 HOH 2426 40.350 29.730 13.490 1.00 0.00 +ATOM 7752 OW HOH 2427 14.290 45.290 12.790 1.00 0.00 +ATOM 7753 HW1 HOH 2427 14.150 45.460 11.860 1.00 0.00 +ATOM 7754 HW2 HOH 2427 14.000 46.090 13.230 1.00 0.00 +ATOM 7755 OW HOH 2428 38.040 40.870 12.280 1.00 0.00 +ATOM 7756 HW1 HOH 2428 38.500 40.200 12.770 1.00 0.00 +ATOM 7757 HW2 HOH 2428 38.660 41.140 11.600 1.00 0.00 +ATOM 7758 OW HOH 2429 29.910 3.940 38.580 1.00 0.00 +ATOM 7759 HW1 HOH 2429 29.540 3.980 37.690 1.00 0.00 +ATOM 7760 HW2 HOH 2429 30.180 3.030 38.690 1.00 0.00 +ATOM 7761 OW HOH 2430 19.690 33.910 35.660 1.00 0.00 +ATOM 7762 HW1 HOH 2430 19.490 34.550 36.340 1.00 0.00 +ATOM 7763 HW2 HOH 2430 18.940 33.310 35.660 1.00 0.00 +ATOM 7764 OW HOH 2431 48.960 26.970 21.140 1.00 0.00 +ATOM 7765 HW1 HOH 2431 48.180 26.480 21.390 1.00 0.00 +ATOM 7766 HW2 HOH 2431 48.900 27.790 21.620 1.00 0.00 +ATOM 7767 OW HOH 2432 32.390 41.540 2.900 1.00 0.00 +ATOM 7768 HW1 HOH 2432 33.220 41.320 2.490 1.00 0.00 +ATOM 7769 HW2 HOH 2432 31.820 40.790 2.730 1.00 0.00 +ATOM 7770 OW HOH 2433 47.140 3.580 24.870 1.00 0.00 +ATOM 7771 HW1 HOH 2433 48.080 3.450 24.790 1.00 0.00 +ATOM 7772 HW2 HOH 2433 46.880 2.990 25.580 1.00 0.00 +ATOM 7773 OW HOH 2434 9.360 27.910 18.180 1.00 0.00 +ATOM 7774 HW1 HOH 2434 9.840 27.140 18.480 1.00 0.00 +ATOM 7775 HW2 HOH 2434 9.940 28.650 18.360 1.00 0.00 +ATOM 7776 OW HOH 2435 48.600 15.690 34.620 1.00 0.00 +ATOM 7777 HW1 HOH 2435 49.120 14.880 34.590 1.00 0.00 +ATOM 7778 HW2 HOH 2435 48.230 15.760 33.750 1.00 0.00 +ATOM 7779 OW HOH 2436 4.130 20.840 27.190 1.00 0.00 +ATOM 7780 HW1 HOH 2436 3.260 20.510 26.970 1.00 0.00 +ATOM 7781 HW2 HOH 2436 4.740 20.210 26.800 1.00 0.00 +ATOM 7782 OW HOH 2437 37.790 44.660 31.850 1.00 0.00 +ATOM 7783 HW1 HOH 2437 37.930 43.900 32.410 1.00 0.00 +ATOM 7784 HW2 HOH 2437 38.340 44.500 31.080 1.00 0.00 +ATOM 7785 OW HOH 2438 30.430 2.380 9.350 1.00 0.00 +ATOM 7786 HW1 HOH 2438 30.760 1.480 9.290 1.00 0.00 +ATOM 7787 HW2 HOH 2438 31.190 2.920 9.120 1.00 0.00 +ATOM 7788 OW HOH 2439 14.730 31.210 16.460 1.00 0.00 +ATOM 7789 HW1 HOH 2439 13.890 30.770 16.370 1.00 0.00 +ATOM 7790 HW2 HOH 2439 15.020 31.010 17.350 1.00 0.00 +ATOM 7791 OW HOH 2440 29.690 44.910 3.230 1.00 0.00 +ATOM 7792 HW1 HOH 2440 29.430 44.920 4.150 1.00 0.00 +ATOM 7793 HW2 HOH 2440 29.180 45.610 2.830 1.00 0.00 +ATOM 7794 OW HOH 2441 34.390 14.590 31.820 1.00 0.00 +ATOM 7795 HW1 HOH 2441 33.640 14.380 32.370 1.00 0.00 +ATOM 7796 HW2 HOH 2441 34.600 13.780 31.370 1.00 0.00 +ATOM 7797 OW HOH 2442 44.990 29.150 5.660 1.00 0.00 +ATOM 7798 HW1 HOH 2442 44.510 29.640 6.320 1.00 0.00 +ATOM 7799 HW2 HOH 2442 44.930 29.690 4.870 1.00 0.00 +ATOM 7800 OW HOH 2443 27.780 46.100 24.190 1.00 0.00 +ATOM 7801 HW1 HOH 2443 27.250 45.840 24.940 1.00 0.00 +ATOM 7802 HW2 HOH 2443 28.390 45.370 24.070 1.00 0.00 +ATOM 7803 OW HOH 2444 15.970 19.690 2.170 1.00 0.00 +ATOM 7804 HW1 HOH 2444 16.440 19.940 1.370 1.00 0.00 +ATOM 7805 HW2 HOH 2444 15.390 20.430 2.350 1.00 0.00 +ATOM 7806 OW HOH 2445 44.310 30.540 11.350 1.00 0.00 +ATOM 7807 HW1 HOH 2445 45.190 30.240 11.590 1.00 0.00 +ATOM 7808 HW2 HOH 2445 43.760 29.760 11.410 1.00 0.00 +ATOM 7809 OW HOH 2446 47.170 10.570 25.620 1.00 0.00 +ATOM 7810 HW1 HOH 2446 46.360 10.590 25.120 1.00 0.00 +ATOM 7811 HW2 HOH 2446 46.900 10.620 26.540 1.00 0.00 +ATOM 7812 OW HOH 2447 23.540 29.470 16.330 1.00 0.00 +ATOM 7813 HW1 HOH 2447 23.360 30.080 17.050 1.00 0.00 +ATOM 7814 HW2 HOH 2447 24.230 29.900 15.830 1.00 0.00 +ATOM 7815 OW HOH 2448 2.940 14.490 17.040 1.00 0.00 +ATOM 7816 HW1 HOH 2448 3.160 13.870 17.740 1.00 0.00 +ATOM 7817 HW2 HOH 2448 3.670 15.110 17.040 1.00 0.00 +ATOM 7818 OW HOH 2449 40.890 30.290 2.610 1.00 0.00 +ATOM 7819 HW1 HOH 2449 40.690 31.190 2.350 1.00 0.00 +ATOM 7820 HW2 HOH 2449 41.540 30.000 1.970 1.00 0.00 +ATOM 7821 OW HOH 2450 10.690 23.400 16.430 1.00 0.00 +ATOM 7822 HW1 HOH 2450 10.920 23.770 15.580 1.00 0.00 +ATOM 7823 HW2 HOH 2450 11.300 22.670 16.550 1.00 0.00 +ATOM 7824 OW HOH 2451 6.710 26.670 6.700 1.00 0.00 +ATOM 7825 HW1 HOH 2451 7.640 26.540 6.540 1.00 0.00 +ATOM 7826 HW2 HOH 2451 6.560 26.330 7.580 1.00 0.00 +ATOM 7827 OW HOH 2452 25.570 31.020 32.810 1.00 0.00 +ATOM 7828 HW1 HOH 2452 24.790 30.640 32.410 1.00 0.00 +ATOM 7829 HW2 HOH 2452 25.240 31.720 33.370 1.00 0.00 +ATOM 7830 OW HOH 2453 14.790 6.310 20.400 1.00 0.00 +ATOM 7831 HW1 HOH 2453 14.770 5.350 20.450 1.00 0.00 +ATOM 7832 HW2 HOH 2453 15.190 6.590 21.220 1.00 0.00 +ATOM 7833 OW HOH 2454 18.620 20.590 8.790 1.00 0.00 +ATOM 7834 HW1 HOH 2454 19.320 20.160 9.280 1.00 0.00 +ATOM 7835 HW2 HOH 2454 19.080 21.160 8.170 1.00 0.00 +ATOM 7836 OW HOH 2455 26.610 8.990 12.930 1.00 0.00 +ATOM 7837 HW1 HOH 2455 26.810 9.360 13.790 1.00 0.00 +ATOM 7838 HW2 HOH 2455 25.670 8.850 12.940 1.00 0.00 +ATOM 7839 OW HOH 2456 40.880 19.690 26.150 1.00 0.00 +ATOM 7840 HW1 HOH 2456 41.700 19.530 25.670 1.00 0.00 +ATOM 7841 HW2 HOH 2456 40.670 20.600 25.980 1.00 0.00 +ATOM 7842 OW HOH 2457 8.630 8.820 37.170 1.00 0.00 +ATOM 7843 HW1 HOH 2457 9.020 9.340 37.870 1.00 0.00 +ATOM 7844 HW2 HOH 2457 7.750 8.600 37.500 1.00 0.00 +ATOM 7845 OW HOH 2458 11.090 25.550 18.350 1.00 0.00 +ATOM 7846 HW1 HOH 2458 11.800 26.100 18.020 1.00 0.00 +ATOM 7847 HW2 HOH 2458 10.850 25.000 17.600 1.00 0.00 +ATOM 7848 OW HOH 2459 5.240 28.520 2.200 1.00 0.00 +ATOM 7849 HW1 HOH 2459 5.770 27.880 1.730 1.00 0.00 +ATOM 7850 HW2 HOH 2459 4.670 27.990 2.760 1.00 0.00 +ATOM 7851 OW HOH 2460 31.680 45.570 8.950 1.00 0.00 +ATOM 7852 HW1 HOH 2460 31.570 45.200 9.830 1.00 0.00 +ATOM 7853 HW2 HOH 2460 31.440 44.860 8.360 1.00 0.00 +ATOM 7854 OW HOH 2461 4.230 3.810 0.500 1.00 0.00 +ATOM 7855 HW1 HOH 2461 4.350 4.290 -0.320 1.00 0.00 +ATOM 7856 HW2 HOH 2461 5.050 3.940 0.980 1.00 0.00 +ATOM 7857 OW HOH 2462 36.450 43.940 10.610 1.00 0.00 +ATOM 7858 HW1 HOH 2462 37.050 43.510 10.000 1.00 0.00 +ATOM 7859 HW2 HOH 2462 36.900 44.740 10.860 1.00 0.00 +ATOM 7860 OW HOH 2463 0.400 31.490 28.260 1.00 0.00 +ATOM 7861 HW1 HOH 2463 0.980 30.780 28.540 1.00 0.00 +ATOM 7862 HW2 HOH 2463 -0.420 31.060 28.010 1.00 0.00 +ATOM 7863 OW HOH 2464 6.580 19.990 8.770 1.00 0.00 +ATOM 7864 HW1 HOH 2464 6.380 19.190 8.280 1.00 0.00 +ATOM 7865 HW2 HOH 2464 7.250 20.420 8.240 1.00 0.00 +ATOM 7866 OW HOH 2465 29.250 11.710 21.000 1.00 0.00 +ATOM 7867 HW1 HOH 2465 29.720 12.280 21.610 1.00 0.00 +ATOM 7868 HW2 HOH 2465 28.860 11.040 21.550 1.00 0.00 +ATOM 7869 OW HOH 2466 39.220 31.920 22.370 1.00 0.00 +ATOM 7870 HW1 HOH 2466 38.990 31.030 22.120 1.00 0.00 +ATOM 7871 HW2 HOH 2466 38.390 32.400 22.370 1.00 0.00 +ATOM 7872 OW HOH 2467 44.050 41.210 9.040 1.00 0.00 +ATOM 7873 HW1 HOH 2467 44.850 41.500 9.470 1.00 0.00 +ATOM 7874 HW2 HOH 2467 44.250 40.320 8.740 1.00 0.00 +ATOM 7875 OW HOH 2468 39.580 22.250 25.620 1.00 0.00 +ATOM 7876 HW1 HOH 2468 39.760 23.000 25.060 1.00 0.00 +ATOM 7877 HW2 HOH 2468 38.680 22.380 25.910 1.00 0.00 +ATOM 7878 OW HOH 2469 26.470 44.270 33.330 1.00 0.00 +ATOM 7879 HW1 HOH 2469 25.840 44.110 32.640 1.00 0.00 +ATOM 7880 HW2 HOH 2469 27.260 43.820 33.050 1.00 0.00 +ATOM 7881 OW HOH 2470 37.540 0.560 8.010 1.00 0.00 +ATOM 7882 HW1 HOH 2470 37.900 1.410 7.790 1.00 0.00 +ATOM 7883 HW2 HOH 2470 37.230 0.650 8.910 1.00 0.00 +ATOM 7884 OW HOH 2471 36.870 28.350 10.810 1.00 0.00 +ATOM 7885 HW1 HOH 2471 36.620 28.610 11.690 1.00 0.00 +ATOM 7886 HW2 HOH 2471 37.010 27.400 10.860 1.00 0.00 +ATOM 7887 OW HOH 2472 25.760 33.960 3.040 1.00 0.00 +ATOM 7888 HW1 HOH 2472 25.340 33.120 2.870 1.00 0.00 +ATOM 7889 HW2 HOH 2472 26.480 33.750 3.640 1.00 0.00 +ATOM 7890 OW HOH 2473 23.500 19.640 2.300 1.00 0.00 +ATOM 7891 HW1 HOH 2473 24.250 19.170 2.670 1.00 0.00 +ATOM 7892 HW2 HOH 2473 23.820 20.530 2.150 1.00 0.00 +ATOM 7893 OW HOH 2474 19.730 39.680 0.460 1.00 0.00 +ATOM 7894 HW1 HOH 2474 19.760 39.460 -0.470 1.00 0.00 +ATOM 7895 HW2 HOH 2474 20.290 39.020 0.880 1.00 0.00 +ATOM 7896 OW HOH 2475 32.870 4.140 28.170 1.00 0.00 +ATOM 7897 HW1 HOH 2475 32.840 4.620 27.340 1.00 0.00 +ATOM 7898 HW2 HOH 2475 32.340 4.660 28.770 1.00 0.00 +ATOM 7899 OW HOH 2476 16.560 8.740 20.790 1.00 0.00 +ATOM 7900 HW1 HOH 2476 17.050 8.710 21.610 1.00 0.00 +ATOM 7901 HW2 HOH 2476 16.580 7.840 20.470 1.00 0.00 +ATOM 7902 OW HOH 2477 12.210 8.750 5.000 1.00 0.00 +ATOM 7903 HW1 HOH 2477 12.800 8.310 4.380 1.00 0.00 +ATOM 7904 HW2 HOH 2477 12.170 8.160 5.750 1.00 0.00 +ATOM 7905 OW HOH 2478 26.710 5.920 22.950 1.00 0.00 +ATOM 7906 HW1 HOH 2478 27.260 6.400 23.580 1.00 0.00 +ATOM 7907 HW2 HOH 2478 27.330 5.590 22.300 1.00 0.00 +ATOM 7908 OW HOH 2479 48.300 36.070 5.750 1.00 0.00 +ATOM 7909 HW1 HOH 2479 48.280 35.720 6.640 1.00 0.00 +ATOM 7910 HW2 HOH 2479 47.560 35.640 5.320 1.00 0.00 +ATOM 7911 OW HOH 2480 24.420 40.060 22.980 1.00 0.00 +ATOM 7912 HW1 HOH 2480 23.730 39.810 23.590 1.00 0.00 +ATOM 7913 HW2 HOH 2480 24.000 40.050 22.120 1.00 0.00 +ATOM 7914 OW HOH 2481 5.030 5.090 19.200 1.00 0.00 +ATOM 7915 HW1 HOH 2481 5.390 5.910 19.530 1.00 0.00 +ATOM 7916 HW2 HOH 2481 5.630 4.420 19.510 1.00 0.00 +ATOM 7917 OW HOH 2482 32.940 17.280 30.620 1.00 0.00 +ATOM 7918 HW1 HOH 2482 33.890 17.290 30.490 1.00 0.00 +ATOM 7919 HW2 HOH 2482 32.830 17.230 31.570 1.00 0.00 +ATOM 7920 OW HOH 2483 42.080 35.620 12.260 1.00 0.00 +ATOM 7921 HW1 HOH 2483 42.100 36.380 12.830 1.00 0.00 +ATOM 7922 HW2 HOH 2483 42.850 35.720 11.700 1.00 0.00 +ATOM 7923 OW HOH 2484 25.700 31.230 12.640 1.00 0.00 +ATOM 7924 HW1 HOH 2484 26.180 31.640 11.920 1.00 0.00 +ATOM 7925 HW2 HOH 2484 25.370 30.420 12.270 1.00 0.00 +ATOM 7926 OW HOH 2485 36.230 34.640 12.600 1.00 0.00 +ATOM 7927 HW1 HOH 2485 35.980 34.090 11.850 1.00 0.00 +ATOM 7928 HW2 HOH 2485 37.170 34.760 12.510 1.00 0.00 +ATOM 7929 OW HOH 2486 37.570 22.530 15.370 1.00 0.00 +ATOM 7930 HW1 HOH 2486 38.380 22.970 15.110 1.00 0.00 +ATOM 7931 HW2 HOH 2486 37.470 22.730 16.300 1.00 0.00 +ATOM 7932 OW HOH 2487 10.970 45.840 18.080 1.00 0.00 +ATOM 7933 HW1 HOH 2487 10.600 46.210 18.880 1.00 0.00 +ATOM 7934 HW2 HOH 2487 11.020 44.900 18.250 1.00 0.00 +ATOM 7935 OW HOH 2488 43.010 43.430 29.390 1.00 0.00 +ATOM 7936 HW1 HOH 2488 43.620 43.090 28.740 1.00 0.00 +ATOM 7937 HW2 HOH 2488 43.310 43.070 30.230 1.00 0.00 +ATOM 7938 OW HOH 2489 36.870 40.550 3.470 1.00 0.00 +ATOM 7939 HW1 HOH 2489 37.120 39.710 3.840 1.00 0.00 +ATOM 7940 HW2 HOH 2489 37.630 40.830 2.960 1.00 0.00 +ATOM 7941 OW HOH 2490 14.710 9.580 35.640 1.00 0.00 +ATOM 7942 HW1 HOH 2490 14.330 9.250 34.820 1.00 0.00 +ATOM 7943 HW2 HOH 2490 15.020 8.800 36.090 1.00 0.00 +ATOM 7944 OW HOH 2491 41.450 14.850 20.610 1.00 0.00 +ATOM 7945 HW1 HOH 2491 41.070 14.670 19.750 1.00 0.00 +ATOM 7946 HW2 HOH 2491 41.200 15.750 20.800 1.00 0.00 +ATOM 7947 OW HOH 2492 13.100 15.200 23.600 1.00 0.00 +ATOM 7948 HW1 HOH 2492 13.110 16.160 23.560 1.00 0.00 +ATOM 7949 HW2 HOH 2492 12.390 14.950 23.020 1.00 0.00 +ATOM 7950 OW HOH 2493 31.390 39.000 1.780 1.00 0.00 +ATOM 7951 HW1 HOH 2493 30.920 38.720 0.990 1.00 0.00 +ATOM 7952 HW2 HOH 2493 32.310 38.970 1.530 1.00 0.00 +ATOM 7953 OW HOH 2494 32.600 31.950 13.280 1.00 0.00 +ATOM 7954 HW1 HOH 2494 32.770 32.880 13.130 1.00 0.00 +ATOM 7955 HW2 HOH 2494 32.550 31.570 12.400 1.00 0.00 +ATOM 7956 OW HOH 2495 39.960 14.240 34.350 1.00 0.00 +ATOM 7957 HW1 HOH 2495 40.080 13.290 34.460 1.00 0.00 +ATOM 7958 HW2 HOH 2495 40.030 14.600 35.230 1.00 0.00 +ATOM 7959 OW HOH 2496 45.370 33.430 16.990 1.00 0.00 +ATOM 7960 HW1 HOH 2496 45.480 33.660 17.910 1.00 0.00 +ATOM 7961 HW2 HOH 2496 45.410 34.260 16.520 1.00 0.00 +ATOM 7962 OW HOH 2497 43.890 37.580 5.990 1.00 0.00 +ATOM 7963 HW1 HOH 2497 44.160 38.140 6.730 1.00 0.00 +ATOM 7964 HW2 HOH 2497 43.180 37.050 6.340 1.00 0.00 +ATOM 7965 OW HOH 2498 44.490 39.390 14.090 1.00 0.00 +ATOM 7966 HW1 HOH 2498 44.310 39.900 13.300 1.00 0.00 +ATOM 7967 HW2 HOH 2498 43.750 39.580 14.670 1.00 0.00 +ATOM 7968 OW HOH 2499 8.230 43.270 37.790 1.00 0.00 +ATOM 7969 HW1 HOH 2499 7.550 43.050 37.150 1.00 0.00 +ATOM 7970 HW2 HOH 2499 8.710 42.450 37.920 1.00 0.00 +ATOM 7971 OW HOH 2500 30.190 42.180 1.570 1.00 0.00 +ATOM 7972 HW1 HOH 2500 30.590 43.040 1.520 1.00 0.00 +ATOM 7973 HW2 HOH 2500 30.500 41.730 0.780 1.00 0.00 +ATOM 7974 OW HOH 2501 40.010 13.390 12.440 1.00 0.00 +ATOM 7975 HW1 HOH 2501 40.270 12.500 12.660 1.00 0.00 +ATOM 7976 HW2 HOH 2501 40.570 13.630 11.700 1.00 0.00 +ATOM 7977 OW HOH 2502 11.100 7.230 7.030 1.00 0.00 +ATOM 7978 HW1 HOH 2502 11.240 7.470 7.950 1.00 0.00 +ATOM 7979 HW2 HOH 2502 10.500 6.480 7.080 1.00 0.00 +ATOM 7980 OW HOH 2503 46.590 26.890 1.350 1.00 0.00 +ATOM 7981 HW1 HOH 2503 45.750 26.450 1.500 1.00 0.00 +ATOM 7982 HW2 HOH 2503 46.450 27.430 0.570 1.00 0.00 +ATOM 7983 OW HOH 2504 28.650 40.070 27.630 1.00 0.00 +ATOM 7984 HW1 HOH 2504 27.720 39.980 27.870 1.00 0.00 +ATOM 7985 HW2 HOH 2504 28.940 39.170 27.470 1.00 0.00 +ATOM 7986 OW HOH 2505 5.300 43.940 28.840 1.00 0.00 +ATOM 7987 HW1 HOH 2505 5.960 43.490 28.310 1.00 0.00 +ATOM 7988 HW2 HOH 2505 5.530 44.870 28.790 1.00 0.00 +ATOM 7989 OW HOH 2506 5.920 36.420 24.760 1.00 0.00 +ATOM 7990 HW1 HOH 2506 5.230 37.070 24.910 1.00 0.00 +ATOM 7991 HW2 HOH 2506 5.490 35.580 24.920 1.00 0.00 +ATOM 7992 OW HOH 2507 42.590 4.340 7.250 1.00 0.00 +ATOM 7993 HW1 HOH 2507 42.780 4.990 7.920 1.00 0.00 +ATOM 7994 HW2 HOH 2507 42.040 4.810 6.610 1.00 0.00 +ATOM 7995 OW HOH 2508 45.300 37.150 36.390 1.00 0.00 +ATOM 7996 HW1 HOH 2508 44.380 37.320 36.200 1.00 0.00 +ATOM 7997 HW2 HOH 2508 45.740 37.250 35.550 1.00 0.00 +ATOM 7998 OW HOH 2509 42.760 30.190 7.370 1.00 0.00 +ATOM 7999 HW1 HOH 2509 42.310 30.460 8.170 1.00 0.00 +ATOM 8000 HW2 HOH 2509 42.050 29.940 6.770 1.00 0.00 +ATOM 8001 OW HOH 2510 0.390 37.940 1.160 1.00 0.00 +ATOM 8002 HW1 HOH 2510 0.790 37.980 2.030 1.00 0.00 +ATOM 8003 HW2 HOH 2510 -0.510 37.680 1.320 1.00 0.00 +ATOM 8004 OW HOH 2511 37.620 10.350 10.080 1.00 0.00 +ATOM 8005 HW1 HOH 2511 37.570 10.450 11.030 1.00 0.00 +ATOM 8006 HW2 HOH 2511 36.750 10.590 9.770 1.00 0.00 +ATOM 8007 OW HOH 2512 44.980 29.290 29.990 1.00 0.00 +ATOM 8008 HW1 HOH 2512 44.480 29.520 29.210 1.00 0.00 +ATOM 8009 HW2 HOH 2512 45.770 28.870 29.650 1.00 0.00 +ATOM 8010 OW HOH 2513 24.230 9.390 29.510 1.00 0.00 +ATOM 8011 HW1 HOH 2513 24.030 9.640 28.610 1.00 0.00 +ATOM 8012 HW2 HOH 2513 23.940 10.150 30.030 1.00 0.00 +ATOM 8013 OW HOH 2514 14.010 23.300 29.980 1.00 0.00 +ATOM 8014 HW1 HOH 2514 13.930 24.140 29.540 1.00 0.00 +ATOM 8015 HW2 HOH 2514 13.380 23.350 30.710 1.00 0.00 +ATOM 8016 OW HOH 2515 21.900 1.880 33.400 1.00 0.00 +ATOM 8017 HW1 HOH 2515 22.180 2.620 32.850 1.00 0.00 +ATOM 8018 HW2 HOH 2515 21.030 1.650 33.060 1.00 0.00 +ATOM 8019 OW HOH 2516 35.540 40.540 11.330 1.00 0.00 +ATOM 8020 HW1 HOH 2516 35.510 40.620 10.380 1.00 0.00 +ATOM 8021 HW2 HOH 2516 36.460 40.690 11.550 1.00 0.00 +ATOM 8022 OW HOH 2517 43.110 22.830 27.320 1.00 0.00 +ATOM 8023 HW1 HOH 2517 42.820 23.230 28.140 1.00 0.00 +ATOM 8024 HW2 HOH 2517 42.660 23.330 26.640 1.00 0.00 +ATOM 8025 OW HOH 2518 1.140 39.330 6.900 1.00 0.00 +ATOM 8026 HW1 HOH 2518 1.240 38.430 6.600 1.00 0.00 +ATOM 8027 HW2 HOH 2518 0.870 39.820 6.120 1.00 0.00 +ATOM 8028 OW HOH 2519 20.610 44.680 8.330 1.00 0.00 +ATOM 8029 HW1 HOH 2519 20.940 44.790 9.230 1.00 0.00 +ATOM 8030 HW2 HOH 2519 21.110 43.940 7.980 1.00 0.00 +ATOM 8031 OW HOH 2520 27.800 28.210 8.320 1.00 0.00 +ATOM 8032 HW1 HOH 2520 26.890 28.080 8.590 1.00 0.00 +ATOM 8033 HW2 HOH 2520 28.240 27.380 8.540 1.00 0.00 +ATOM 8034 OW HOH 2521 22.310 33.950 30.920 1.00 0.00 +ATOM 8035 HW1 HOH 2521 22.710 33.090 30.870 1.00 0.00 +ATOM 8036 HW2 HOH 2521 22.760 34.390 31.640 1.00 0.00 +ATOM 8037 OW HOH 2522 46.690 17.860 34.730 1.00 0.00 +ATOM 8038 HW1 HOH 2522 47.210 17.070 34.890 1.00 0.00 +ATOM 8039 HW2 HOH 2522 46.230 18.020 35.550 1.00 0.00 +ATOM 8040 OW HOH 2523 34.910 44.250 23.790 1.00 0.00 +ATOM 8041 HW1 HOH 2523 35.000 43.420 23.330 1.00 0.00 +ATOM 8042 HW2 HOH 2523 34.150 44.120 24.370 1.00 0.00 +ATOM 8043 OW HOH 2524 11.920 17.830 14.840 1.00 0.00 +ATOM 8044 HW1 HOH 2524 11.440 17.260 15.440 1.00 0.00 +ATOM 8045 HW2 HOH 2524 12.460 18.380 15.410 1.00 0.00 +ATOM 8046 OW HOH 2525 40.920 0.300 23.240 1.00 0.00 +ATOM 8047 HW1 HOH 2525 40.290 0.040 22.570 1.00 0.00 +ATOM 8048 HW2 HOH 2525 41.770 -0.010 22.910 1.00 0.00 +ATOM 8049 OW HOH 2526 25.080 44.210 37.980 1.00 0.00 +ATOM 8050 HW1 HOH 2526 26.000 44.200 38.250 1.00 0.00 +ATOM 8051 HW2 HOH 2526 25.100 44.510 37.070 1.00 0.00 +ATOM 8052 OW HOH 2527 36.070 13.230 1.780 1.00 0.00 +ATOM 8053 HW1 HOH 2527 35.190 13.240 1.410 1.00 0.00 +ATOM 8054 HW2 HOH 2527 36.550 12.600 1.230 1.00 0.00 +ATOM 8055 OW HOH 2528 26.420 3.950 36.390 1.00 0.00 +ATOM 8056 HW1 HOH 2528 25.870 4.450 35.780 1.00 0.00 +ATOM 8057 HW2 HOH 2528 26.130 4.220 37.260 1.00 0.00 +ATOM 8058 OW HOH 2529 35.770 30.760 15.720 1.00 0.00 +ATOM 8059 HW1 HOH 2529 34.820 30.830 15.630 1.00 0.00 +ATOM 8060 HW2 HOH 2529 36.100 31.610 15.410 1.00 0.00 +ATOM 8061 OW HOH 2530 43.150 38.460 35.220 1.00 0.00 +ATOM 8062 HW1 HOH 2530 43.450 39.350 35.400 1.00 0.00 +ATOM 8063 HW2 HOH 2530 42.830 38.500 34.320 1.00 0.00 +ATOM 8064 OW HOH 2531 31.800 32.490 36.580 1.00 0.00 +ATOM 8065 HW1 HOH 2531 31.130 32.770 35.950 1.00 0.00 +ATOM 8066 HW2 HOH 2531 31.350 32.510 37.430 1.00 0.00 +ATOM 8067 OW HOH 2532 44.900 -0.010 34.730 1.00 0.00 +ATOM 8068 HW1 HOH 2532 44.930 0.320 33.830 1.00 0.00 +ATOM 8069 HW2 HOH 2532 45.570 0.490 35.190 1.00 0.00 +ATOM 8070 OW HOH 2533 27.490 1.960 12.630 1.00 0.00 +ATOM 8071 HW1 HOH 2533 26.700 2.500 12.550 1.00 0.00 +ATOM 8072 HW2 HOH 2533 27.250 1.300 13.290 1.00 0.00 +ATOM 8073 OW HOH 2534 16.580 33.380 25.320 1.00 0.00 +ATOM 8074 HW1 HOH 2534 16.620 33.610 24.390 1.00 0.00 +ATOM 8075 HW2 HOH 2534 15.640 33.320 25.510 1.00 0.00 +ATOM 8076 OW HOH 2535 1.590 39.210 32.580 1.00 0.00 +ATOM 8077 HW1 HOH 2535 1.950 39.700 33.320 1.00 0.00 +ATOM 8078 HW2 HOH 2535 0.650 39.390 32.600 1.00 0.00 +ATOM 8079 OW HOH 2536 41.110 7.080 19.100 1.00 0.00 +ATOM 8080 HW1 HOH 2536 42.000 7.090 19.440 1.00 0.00 +ATOM 8081 HW2 HOH 2536 40.730 7.910 19.390 1.00 0.00 +ATOM 8082 OW HOH 2537 19.750 3.480 31.280 1.00 0.00 +ATOM 8083 HW1 HOH 2537 20.470 3.310 30.680 1.00 0.00 +ATOM 8084 HW2 HOH 2537 19.530 2.620 31.650 1.00 0.00 +ATOM 8085 OW HOH 2538 0.650 13.580 0.540 1.00 0.00 +ATOM 8086 HW1 HOH 2538 0.230 14.240 -0.020 1.00 0.00 +ATOM 8087 HW2 HOH 2538 -0.020 13.360 1.190 1.00 0.00 +ATOM 8088 OW HOH 2539 33.630 1.390 29.210 1.00 0.00 +ATOM 8089 HW1 HOH 2539 32.990 1.880 29.730 1.00 0.00 +ATOM 8090 HW2 HOH 2539 33.920 2.000 28.540 1.00 0.00 +ATOM 8091 OW HOH 2540 19.980 20.630 4.810 1.00 0.00 +ATOM 8092 HW1 HOH 2540 19.180 20.150 4.600 1.00 0.00 +ATOM 8093 HW2 HOH 2540 20.480 20.030 5.360 1.00 0.00 +ATOM 8094 OW HOH 2541 4.670 30.280 37.220 1.00 0.00 +ATOM 8095 HW1 HOH 2541 3.970 30.830 36.870 1.00 0.00 +ATOM 8096 HW2 HOH 2541 4.580 30.360 38.170 1.00 0.00 +ATOM 8097 OW HOH 2542 7.420 42.220 19.560 1.00 0.00 +ATOM 8098 HW1 HOH 2542 8.310 42.160 19.230 1.00 0.00 +ATOM 8099 HW2 HOH 2542 6.930 41.560 19.070 1.00 0.00 +ATOM 8100 OW HOH 2543 4.280 23.450 22.120 1.00 0.00 +ATOM 8101 HW1 HOH 2543 4.610 23.870 21.330 1.00 0.00 +ATOM 8102 HW2 HOH 2543 3.930 22.610 21.820 1.00 0.00 +ATOM 8103 OW HOH 2544 47.670 45.680 23.710 1.00 0.00 +ATOM 8104 HW1 HOH 2544 47.370 44.810 23.470 1.00 0.00 +ATOM 8105 HW2 HOH 2544 48.100 45.570 24.560 1.00 0.00 +ATOM 8106 OW HOH 2545 35.090 20.370 9.400 1.00 0.00 +ATOM 8107 HW1 HOH 2545 34.200 20.390 9.070 1.00 0.00 +ATOM 8108 HW2 HOH 2545 35.200 21.200 9.850 1.00 0.00 +ATOM 8109 OW HOH 2546 29.000 39.480 30.430 1.00 0.00 +ATOM 8110 HW1 HOH 2546 29.790 39.110 30.830 1.00 0.00 +ATOM 8111 HW2 HOH 2546 29.310 39.870 29.610 1.00 0.00 +ATOM 8112 OW HOH 2547 1.140 21.260 30.770 1.00 0.00 +ATOM 8113 HW1 HOH 2547 1.910 20.690 30.770 1.00 0.00 +ATOM 8114 HW2 HOH 2547 0.640 20.970 30.000 1.00 0.00 +ATOM 8115 OW HOH 2548 34.370 33.110 8.630 1.00 0.00 +ATOM 8116 HW1 HOH 2548 35.190 33.480 8.950 1.00 0.00 +ATOM 8117 HW2 HOH 2548 34.030 33.770 8.020 1.00 0.00 +ATOM 8118 OW HOH 2549 31.960 13.570 16.810 1.00 0.00 +ATOM 8119 HW1 HOH 2549 31.630 13.020 16.100 1.00 0.00 +ATOM 8120 HW2 HOH 2549 31.350 13.420 17.530 1.00 0.00 +ATOM 8121 OW HOH 2550 10.150 2.480 26.050 1.00 0.00 +ATOM 8122 HW1 HOH 2550 9.270 2.860 26.020 1.00 0.00 +ATOM 8123 HW2 HOH 2550 10.190 1.920 25.280 1.00 0.00 +ATOM 8124 OW HOH 2551 32.280 28.720 0.810 1.00 0.00 +ATOM 8125 HW1 HOH 2551 32.990 28.100 0.640 1.00 0.00 +ATOM 8126 HW2 HOH 2551 31.860 28.830 -0.040 1.00 0.00 +ATOM 8127 OW HOH 2552 4.920 25.680 16.760 1.00 0.00 +ATOM 8128 HW1 HOH 2552 4.270 25.090 16.380 1.00 0.00 +ATOM 8129 HW2 HOH 2552 5.640 25.110 17.030 1.00 0.00 +ATOM 8130 OW HOH 2553 39.830 3.250 7.970 1.00 0.00 +ATOM 8131 HW1 HOH 2553 39.460 3.320 7.090 1.00 0.00 +ATOM 8132 HW2 HOH 2553 40.760 3.420 7.860 1.00 0.00 +ATOM 8133 OW HOH 2554 39.900 27.760 18.910 1.00 0.00 +ATOM 8134 HW1 HOH 2554 40.810 27.470 18.880 1.00 0.00 +ATOM 8135 HW2 HOH 2554 39.920 28.610 18.470 1.00 0.00 +ATOM 8136 OW HOH 2555 40.040 17.050 21.610 1.00 0.00 +ATOM 8137 HW1 HOH 2555 39.170 16.840 21.270 1.00 0.00 +ATOM 8138 HW2 HOH 2555 39.900 17.830 22.150 1.00 0.00 +ATOM 8139 OW HOH 2556 38.390 34.250 33.730 1.00 0.00 +ATOM 8140 HW1 HOH 2556 39.140 34.350 34.320 1.00 0.00 +ATOM 8141 HW2 HOH 2556 37.760 33.740 34.230 1.00 0.00 +ATOM 8142 OW HOH 2557 4.870 29.640 6.640 1.00 0.00 +ATOM 8143 HW1 HOH 2557 4.510 30.520 6.610 1.00 0.00 +ATOM 8144 HW2 HOH 2557 5.670 29.690 6.110 1.00 0.00 +ATOM 8145 OW HOH 2558 4.790 36.490 1.800 1.00 0.00 +ATOM 8146 HW1 HOH 2558 5.700 36.690 1.570 1.00 0.00 +ATOM 8147 HW2 HOH 2558 4.390 36.210 0.980 1.00 0.00 +ATOM 8148 OW HOH 2559 0.040 15.540 21.870 1.00 0.00 +ATOM 8149 HW1 HOH 2559 0.330 14.970 21.160 1.00 0.00 +ATOM 8150 HW2 HOH 2559 0.560 15.270 22.630 1.00 0.00 +ATOM 8151 OW HOH 2560 22.370 38.940 15.250 1.00 0.00 +ATOM 8152 HW1 HOH 2560 21.840 39.490 15.840 1.00 0.00 +ATOM 8153 HW2 HOH 2560 22.250 39.340 14.390 1.00 0.00 +ATOM 8154 OW HOH 2561 37.950 18.350 2.600 1.00 0.00 +ATOM 8155 HW1 HOH 2561 37.730 17.790 1.850 1.00 0.00 +ATOM 8156 HW2 HOH 2561 38.520 19.020 2.230 1.00 0.00 +ATOM 8157 OW HOH 2562 11.320 6.670 13.160 1.00 0.00 +ATOM 8158 HW1 HOH 2562 11.810 7.490 13.150 1.00 0.00 +ATOM 8159 HW2 HOH 2562 10.910 6.640 14.020 1.00 0.00 +ATOM 8160 OW HOH 2563 36.020 21.630 4.290 1.00 0.00 +ATOM 8161 HW1 HOH 2563 35.770 20.710 4.270 1.00 0.00 +ATOM 8162 HW2 HOH 2563 36.290 21.780 5.200 1.00 0.00 +ATOM 8163 OW HOH 2564 35.130 0.180 16.260 1.00 0.00 +ATOM 8164 HW1 HOH 2564 34.680 0.760 16.870 1.00 0.00 +ATOM 8165 HW2 HOH 2564 35.960 0.610 16.070 1.00 0.00 +ATOM 8166 OW HOH 2565 40.390 20.810 33.420 1.00 0.00 +ATOM 8167 HW1 HOH 2565 39.660 21.280 33.830 1.00 0.00 +ATOM 8168 HW2 HOH 2565 40.040 19.930 33.280 1.00 0.00 +ATOM 8169 OW HOH 2566 32.080 36.790 18.340 1.00 0.00 +ATOM 8170 HW1 HOH 2566 32.010 36.440 19.230 1.00 0.00 +ATOM 8171 HW2 HOH 2566 32.660 36.170 17.900 1.00 0.00 +ATOM 8172 OW HOH 2567 28.650 36.680 30.670 1.00 0.00 +ATOM 8173 HW1 HOH 2567 28.500 36.680 31.620 1.00 0.00 +ATOM 8174 HW2 HOH 2567 28.670 37.610 30.430 1.00 0.00 +ATOM 8175 OW HOH 2568 0.800 41.940 26.220 1.00 0.00 +ATOM 8176 HW1 HOH 2568 1.550 42.120 26.790 1.00 0.00 +ATOM 8177 HW2 HOH 2568 1.150 41.380 25.530 1.00 0.00 +ATOM 8178 OW HOH 2569 31.080 34.220 14.710 1.00 0.00 +ATOM 8179 HW1 HOH 2569 30.780 33.830 15.530 1.00 0.00 +ATOM 8180 HW2 HOH 2569 30.630 33.710 14.030 1.00 0.00 +ATOM 8181 OW HOH 2570 45.310 19.180 32.770 1.00 0.00 +ATOM 8182 HW1 HOH 2570 45.690 20.020 33.020 1.00 0.00 +ATOM 8183 HW2 HOH 2570 45.650 18.560 33.410 1.00 0.00 +ATOM 8184 OW HOH 2571 38.990 26.570 16.370 1.00 0.00 +ATOM 8185 HW1 HOH 2571 39.310 27.050 17.130 1.00 0.00 +ATOM 8186 HW2 HOH 2571 39.040 27.200 15.650 1.00 0.00 +ATOM 8187 OW HOH 2572 25.870 12.140 27.560 1.00 0.00 +ATOM 8188 HW1 HOH 2572 25.540 12.150 28.460 1.00 0.00 +ATOM 8189 HW2 HOH 2572 25.190 12.590 27.050 1.00 0.00 +ATOM 8190 OW HOH 2573 33.420 15.020 18.780 1.00 0.00 +ATOM 8191 HW1 HOH 2573 33.810 15.800 18.370 1.00 0.00 +ATOM 8192 HW2 HOH 2573 32.820 14.680 18.110 1.00 0.00 +ATOM 8193 OW HOH 2574 27.780 30.990 0.480 1.00 0.00 +ATOM 8194 HW1 HOH 2574 26.980 31.120 0.990 1.00 0.00 +ATOM 8195 HW2 HOH 2574 27.660 30.140 0.050 1.00 0.00 +ATOM 8196 OW HOH 2575 18.700 29.440 12.690 1.00 0.00 +ATOM 8197 HW1 HOH 2575 17.990 29.160 13.270 1.00 0.00 +ATOM 8198 HW2 HOH 2575 19.410 29.670 13.280 1.00 0.00 +ATOM 8199 OW HOH 2576 22.320 34.180 34.930 1.00 0.00 +ATOM 8200 HW1 HOH 2576 22.200 35.000 34.440 1.00 0.00 +ATOM 8201 HW2 HOH 2576 21.440 33.910 35.170 1.00 0.00 +ATOM 8202 OW HOH 2577 42.540 41.850 4.870 1.00 0.00 +ATOM 8203 HW1 HOH 2577 42.190 42.670 5.220 1.00 0.00 +ATOM 8204 HW2 HOH 2577 43.480 41.910 5.020 1.00 0.00 +ATOM 8205 OW HOH 2578 43.080 28.240 11.770 1.00 0.00 +ATOM 8206 HW1 HOH 2578 42.490 28.490 12.480 1.00 0.00 +ATOM 8207 HW2 HOH 2578 42.510 28.200 10.990 1.00 0.00 +ATOM 8208 OW HOH 2579 35.290 19.090 3.060 1.00 0.00 +ATOM 8209 HW1 HOH 2579 36.060 18.730 2.620 1.00 0.00 +ATOM 8210 HW2 HOH 2579 35.020 19.830 2.510 1.00 0.00 +ATOM 8211 OW HOH 2580 44.080 37.180 28.820 1.00 0.00 +ATOM 8212 HW1 HOH 2580 43.430 37.770 28.420 1.00 0.00 +ATOM 8213 HW2 HOH 2580 44.350 36.610 28.110 1.00 0.00 +ATOM 8214 OW HOH 2581 25.570 45.960 29.480 1.00 0.00 +ATOM 8215 HW1 HOH 2581 26.070 45.350 28.940 1.00 0.00 +ATOM 8216 HW2 HOH 2581 24.790 46.150 28.960 1.00 0.00 +ATOM 8217 OW HOH 2582 39.190 0.460 33.470 1.00 0.00 +ATOM 8218 HW1 HOH 2582 38.800 -0.140 32.830 1.00 0.00 +ATOM 8219 HW2 HOH 2582 38.430 0.900 33.870 1.00 0.00 +ATOM 8220 OW HOH 2583 4.770 34.090 36.460 1.00 0.00 +ATOM 8221 HW1 HOH 2583 3.930 33.840 36.850 1.00 0.00 +ATOM 8222 HW2 HOH 2583 4.540 34.730 35.790 1.00 0.00 +ATOM 8223 OW HOH 2584 23.010 9.610 17.300 1.00 0.00 +ATOM 8224 HW1 HOH 2584 22.560 9.130 16.600 1.00 0.00 +ATOM 8225 HW2 HOH 2584 23.430 8.920 17.830 1.00 0.00 +ATOM 8226 OW HOH 2585 34.870 34.780 33.760 1.00 0.00 +ATOM 8227 HW1 HOH 2585 34.300 34.720 34.520 1.00 0.00 +ATOM 8228 HW2 HOH 2585 34.600 34.060 33.200 1.00 0.00 +ATOM 8229 OW HOH 2586 18.350 25.830 4.380 1.00 0.00 +ATOM 8230 HW1 HOH 2586 18.350 26.380 5.170 1.00 0.00 +ATOM 8231 HW2 HOH 2586 18.340 24.930 4.710 1.00 0.00 +ATOM 8232 OW HOH 2587 43.020 31.710 19.140 1.00 0.00 +ATOM 8233 HW1 HOH 2587 42.860 31.150 18.370 1.00 0.00 +ATOM 8234 HW2 HOH 2587 43.680 31.240 19.640 1.00 0.00 +ATOM 8235 OW HOH 2588 42.720 3.680 11.830 1.00 0.00 +ATOM 8236 HW1 HOH 2588 41.940 3.780 12.370 1.00 0.00 +ATOM 8237 HW2 HOH 2588 42.920 4.570 11.540 1.00 0.00 +ATOM 8238 OW HOH 2589 34.570 13.260 15.540 1.00 0.00 +ATOM 8239 HW1 HOH 2589 33.700 12.870 15.380 1.00 0.00 +ATOM 8240 HW2 HOH 2589 34.520 13.610 16.430 1.00 0.00 +ATOM 8241 OW HOH 2590 37.630 27.060 34.600 1.00 0.00 +ATOM 8242 HW1 HOH 2590 38.440 27.580 34.640 1.00 0.00 +ATOM 8243 HW2 HOH 2590 37.210 27.210 35.450 1.00 0.00 +ATOM 8244 OW HOH 2591 12.760 20.220 22.480 1.00 0.00 +ATOM 8245 HW1 HOH 2591 13.530 20.760 22.680 1.00 0.00 +ATOM 8246 HW2 HOH 2591 12.360 20.050 23.340 1.00 0.00 +ATOM 8247 OW HOH 2592 44.540 13.160 12.270 1.00 0.00 +ATOM 8248 HW1 HOH 2592 45.350 13.670 12.290 1.00 0.00 +ATOM 8249 HW2 HOH 2592 43.850 13.810 12.380 1.00 0.00 +ATOM 8250 OW HOH 2593 30.360 27.320 2.340 1.00 0.00 +ATOM 8251 HW1 HOH 2593 30.850 26.560 2.650 1.00 0.00 +ATOM 8252 HW2 HOH 2593 31.020 27.990 2.180 1.00 0.00 +ATOM 8253 OW HOH 2594 24.850 43.750 31.140 1.00 0.00 +ATOM 8254 HW1 HOH 2594 24.070 44.190 30.810 1.00 0.00 +ATOM 8255 HW2 HOH 2594 24.630 42.820 31.160 1.00 0.00 +ATOM 8256 OW HOH 2595 20.310 41.310 36.550 1.00 0.00 +ATOM 8257 HW1 HOH 2595 21.070 40.790 36.810 1.00 0.00 +ATOM 8258 HW2 HOH 2595 20.410 42.130 37.040 1.00 0.00 +ATOM 8259 OW HOH 2596 42.090 11.010 21.470 1.00 0.00 +ATOM 8260 HW1 HOH 2596 42.830 11.440 21.900 1.00 0.00 +ATOM 8261 HW2 HOH 2596 41.330 11.530 21.730 1.00 0.00 +ATOM 8262 OW HOH 2597 32.300 9.450 14.080 1.00 0.00 +ATOM 8263 HW1 HOH 2597 32.070 8.650 13.610 1.00 0.00 +ATOM 8264 HW2 HOH 2597 32.720 10.010 13.430 1.00 0.00 +ATOM 8265 OW HOH 2598 24.950 36.750 18.440 1.00 0.00 +ATOM 8266 HW1 HOH 2598 24.480 36.680 17.610 1.00 0.00 +ATOM 8267 HW2 HOH 2598 25.870 36.780 18.190 1.00 0.00 +ATOM 8268 OW HOH 2599 9.970 24.010 10.390 1.00 0.00 +ATOM 8269 HW1 HOH 2599 10.590 24.520 9.870 1.00 0.00 +ATOM 8270 HW2 HOH 2599 9.280 24.630 10.630 1.00 0.00 +ATOM 8271 OW HOH 2600 3.500 43.260 36.440 1.00 0.00 +ATOM 8272 HW1 HOH 2600 4.040 42.720 35.860 1.00 0.00 +ATOM 8273 HW2 HOH 2600 3.660 42.910 37.310 1.00 0.00 +ATOM 8274 OW HOH 2601 4.130 31.280 32.420 1.00 0.00 +ATOM 8275 HW1 HOH 2601 4.930 30.770 32.320 1.00 0.00 +ATOM 8276 HW2 HOH 2601 4.310 32.100 31.960 1.00 0.00 +ATOM 8277 OW HOH 2602 24.670 6.040 14.250 1.00 0.00 +ATOM 8278 HW1 HOH 2602 24.100 6.800 14.160 1.00 0.00 +ATOM 8279 HW2 HOH 2602 24.920 6.030 15.180 1.00 0.00 +ATOM 8280 OW HOH 2603 29.680 43.410 23.800 1.00 0.00 +ATOM 8281 HW1 HOH 2603 29.730 42.470 23.960 1.00 0.00 +ATOM 8282 HW2 HOH 2603 30.440 43.590 23.240 1.00 0.00 +ATOM 8283 OW HOH 2604 47.870 32.220 12.450 1.00 0.00 +ATOM 8284 HW1 HOH 2604 47.400 32.210 13.280 1.00 0.00 +ATOM 8285 HW2 HOH 2604 47.540 31.450 11.980 1.00 0.00 +ATOM 8286 OW HOH 2605 7.110 38.400 4.360 1.00 0.00 +ATOM 8287 HW1 HOH 2605 7.110 39.140 4.980 1.00 0.00 +ATOM 8288 HW2 HOH 2605 7.570 38.740 3.590 1.00 0.00 +ATOM 8289 OW HOH 2606 32.550 25.540 1.930 1.00 0.00 +ATOM 8290 HW1 HOH 2606 32.630 24.580 1.980 1.00 0.00 +ATOM 8291 HW2 HOH 2606 32.370 25.710 1.000 1.00 0.00 +ATOM 8292 OW HOH 2607 29.420 16.500 33.450 1.00 0.00 +ATOM 8293 HW1 HOH 2607 29.410 15.870 34.160 1.00 0.00 +ATOM 8294 HW2 HOH 2607 28.610 16.330 32.960 1.00 0.00 +ATOM 8295 OW HOH 2608 27.670 7.050 11.220 1.00 0.00 +ATOM 8296 HW1 HOH 2608 27.090 7.610 11.740 1.00 0.00 +ATOM 8297 HW2 HOH 2608 27.370 7.180 10.320 1.00 0.00 +ATOM 8298 OW HOH 2609 33.170 6.850 17.880 1.00 0.00 +ATOM 8299 HW1 HOH 2609 33.790 7.110 17.200 1.00 0.00 +ATOM 8300 HW2 HOH 2609 32.430 6.470 17.400 1.00 0.00 +ATOM 8301 OW HOH 2610 41.800 14.570 26.900 1.00 0.00 +ATOM 8302 HW1 HOH 2610 41.860 15.010 27.750 1.00 0.00 +ATOM 8303 HW2 HOH 2610 42.570 14.860 26.420 1.00 0.00 +ATOM 8304 OW HOH 2611 38.720 31.620 28.270 1.00 0.00 +ATOM 8305 HW1 HOH 2611 38.320 31.060 27.610 1.00 0.00 +ATOM 8306 HW2 HOH 2611 38.960 32.420 27.800 1.00 0.00 +ATOM 8307 OW HOH 2612 27.410 38.430 17.500 1.00 0.00 +ATOM 8308 HW1 HOH 2612 27.910 39.190 17.200 1.00 0.00 +ATOM 8309 HW2 HOH 2612 27.120 38.660 18.380 1.00 0.00 +ATOM 8310 OW HOH 2613 34.680 5.010 30.680 1.00 0.00 +ATOM 8311 HW1 HOH 2613 35.020 4.330 30.110 1.00 0.00 +ATOM 8312 HW2 HOH 2613 35.300 5.730 30.590 1.00 0.00 +ATOM 8313 OW HOH 2614 4.510 36.640 27.820 1.00 0.00 +ATOM 8314 HW1 HOH 2614 4.460 35.710 28.070 1.00 0.00 +ATOM 8315 HW2 HOH 2614 4.650 37.110 28.640 1.00 0.00 +ATOM 8316 OW HOH 2615 30.040 29.770 7.470 1.00 0.00 +ATOM 8317 HW1 HOH 2615 29.260 29.260 7.680 1.00 0.00 +ATOM 8318 HW2 HOH 2615 29.850 30.650 7.800 1.00 0.00 +ATOM 8319 OW HOH 2616 26.260 24.720 4.580 1.00 0.00 +ATOM 8320 HW1 HOH 2616 26.510 24.200 3.820 1.00 0.00 +ATOM 8321 HW2 HOH 2616 25.340 24.930 4.440 1.00 0.00 +ATOM 8322 OW HOH 2617 5.660 2.740 3.450 1.00 0.00 +ATOM 8323 HW1 HOH 2617 5.220 2.070 2.930 1.00 0.00 +ATOM 8324 HW2 HOH 2617 5.240 3.560 3.180 1.00 0.00 +ATOM 8325 OW HOH 2618 47.510 23.460 28.500 1.00 0.00 +ATOM 8326 HW1 HOH 2618 47.780 23.400 29.410 1.00 0.00 +ATOM 8327 HW2 HOH 2618 48.320 23.400 28.000 1.00 0.00 +ATOM 8328 OW HOH 2619 35.520 31.720 0.090 1.00 0.00 +ATOM 8329 HW1 HOH 2619 35.630 32.640 -0.110 1.00 0.00 +ATOM 8330 HW2 HOH 2619 36.410 31.380 0.200 1.00 0.00 +ATOM 8331 OW HOH 2620 8.740 24.120 26.430 1.00 0.00 +ATOM 8332 HW1 HOH 2620 9.490 23.990 27.000 1.00 0.00 +ATOM 8333 HW2 HOH 2620 8.630 25.070 26.380 1.00 0.00 +ATOM 8334 OW HOH 2621 41.160 41.980 27.200 1.00 0.00 +ATOM 8335 HW1 HOH 2621 40.550 42.560 27.650 1.00 0.00 +ATOM 8336 HW2 HOH 2621 42.010 42.180 27.590 1.00 0.00 +ATOM 8337 OW HOH 2622 12.060 36.680 13.360 1.00 0.00 +ATOM 8338 HW1 HOH 2622 12.690 37.000 12.710 1.00 0.00 +ATOM 8339 HW2 HOH 2622 11.980 35.740 13.160 1.00 0.00 +ATOM 8340 OW HOH 2623 39.000 6.660 5.440 1.00 0.00 +ATOM 8341 HW1 HOH 2623 39.550 5.910 5.210 1.00 0.00 +ATOM 8342 HW2 HOH 2623 38.470 6.350 6.180 1.00 0.00 +ATOM 8343 OW HOH 2624 34.250 31.450 36.550 1.00 0.00 +ATOM 8344 HW1 HOH 2624 33.370 31.820 36.620 1.00 0.00 +ATOM 8345 HW2 HOH 2624 34.630 31.560 37.420 1.00 0.00 +ATOM 8346 OW HOH 2625 8.110 22.050 30.480 1.00 0.00 +ATOM 8347 HW1 HOH 2625 8.190 21.360 29.820 1.00 0.00 +ATOM 8348 HW2 HOH 2625 8.880 22.610 30.340 1.00 0.00 +ATOM 8349 OW HOH 2626 46.480 8.810 8.600 1.00 0.00 +ATOM 8350 HW1 HOH 2626 46.230 8.740 9.520 1.00 0.00 +ATOM 8351 HW2 HOH 2626 46.780 9.710 8.500 1.00 0.00 +ATOM 8352 OW HOH 2627 21.280 30.140 14.010 1.00 0.00 +ATOM 8353 HW1 HOH 2627 22.040 29.800 14.480 1.00 0.00 +ATOM 8354 HW2 HOH 2627 20.760 30.590 14.680 1.00 0.00 +ATOM 8355 OW HOH 2628 18.710 42.440 20.080 1.00 0.00 +ATOM 8356 HW1 HOH 2628 18.460 41.710 20.650 1.00 0.00 +ATOM 8357 HW2 HOH 2628 18.440 43.220 20.560 1.00 0.00 +ATOM 8358 OW HOH 2629 40.000 4.140 34.910 1.00 0.00 +ATOM 8359 HW1 HOH 2629 40.290 4.500 35.750 1.00 0.00 +ATOM 8360 HW2 HOH 2629 39.120 3.810 35.080 1.00 0.00 +ATOM 8361 OW HOH 2630 14.760 0.100 26.940 1.00 0.00 +ATOM 8362 HW1 HOH 2630 13.950 -0.400 27.060 1.00 0.00 +ATOM 8363 HW2 HOH 2630 14.480 1.010 26.920 1.00 0.00 +ATOM 8364 OW HOH 2631 38.320 23.530 37.610 1.00 0.00 +ATOM 8365 HW1 HOH 2631 38.590 24.240 37.040 1.00 0.00 +ATOM 8366 HW2 HOH 2631 38.820 23.660 38.420 1.00 0.00 +ATOM 8367 OW HOH 2632 37.110 6.790 10.730 1.00 0.00 +ATOM 8368 HW1 HOH 2632 36.570 6.190 10.220 1.00 0.00 +ATOM 8369 HW2 HOH 2632 36.980 6.520 11.640 1.00 0.00 +ATOM 8370 OW HOH 2633 36.510 26.330 0.900 1.00 0.00 +ATOM 8371 HW1 HOH 2633 36.880 26.810 1.640 1.00 0.00 +ATOM 8372 HW2 HOH 2633 36.330 25.460 1.250 1.00 0.00 +ATOM 8373 OW HOH 2634 49.110 12.120 24.950 1.00 0.00 +ATOM 8374 HW1 HOH 2634 48.990 12.130 24.000 1.00 0.00 +ATOM 8375 HW2 HOH 2634 48.410 11.560 25.270 1.00 0.00 +ATOM 8376 OW HOH 2635 11.030 4.390 39.040 1.00 0.00 +ATOM 8377 HW1 HOH 2635 10.510 4.660 38.290 1.00 0.00 +ATOM 8378 HW2 HOH 2635 11.360 3.520 38.810 1.00 0.00 +ATOM 8379 OW HOH 2636 21.370 18.310 3.290 1.00 0.00 +ATOM 8380 HW1 HOH 2636 21.860 17.750 3.890 1.00 0.00 +ATOM 8381 HW2 HOH 2636 22.010 18.950 2.980 1.00 0.00 +ATOM 8382 OW HOH 2637 39.680 13.180 28.010 1.00 0.00 +ATOM 8383 HW1 HOH 2637 40.370 13.830 27.850 1.00 0.00 +ATOM 8384 HW2 HOH 2637 39.560 12.750 27.160 1.00 0.00 +ATOM 8385 OW HOH 2638 25.690 8.700 19.770 1.00 0.00 +ATOM 8386 HW1 HOH 2638 25.900 9.150 18.950 1.00 0.00 +ATOM 8387 HW2 HOH 2638 26.530 8.620 20.220 1.00 0.00 +ATOM 8388 OW HOH 2639 26.670 40.120 33.770 1.00 0.00 +ATOM 8389 HW1 HOH 2639 27.430 39.540 33.800 1.00 0.00 +ATOM 8390 HW2 HOH 2639 26.590 40.360 32.840 1.00 0.00 +ATOM 8391 OW HOH 2640 43.640 31.450 33.770 1.00 0.00 +ATOM 8392 HW1 HOH 2640 43.770 30.510 33.670 1.00 0.00 +ATOM 8393 HW2 HOH 2640 44.380 31.740 34.300 1.00 0.00 +ATOM 8394 OW HOH 2641 37.210 25.710 27.000 1.00 0.00 +ATOM 8395 HW1 HOH 2641 36.850 25.550 27.870 1.00 0.00 +ATOM 8396 HW2 HOH 2641 36.740 26.480 26.690 1.00 0.00 +ATOM 8397 OW HOH 2642 5.410 30.760 28.020 1.00 0.00 +ATOM 8398 HW1 HOH 2642 5.640 30.490 27.130 1.00 0.00 +ATOM 8399 HW2 HOH 2642 4.560 30.360 28.180 1.00 0.00 +ATOM 8400 OW HOH 2643 17.900 41.050 8.080 1.00 0.00 +ATOM 8401 HW1 HOH 2643 18.750 41.020 7.630 1.00 0.00 +ATOM 8402 HW2 HOH 2643 17.720 40.140 8.310 1.00 0.00 +ATOM 8403 OW HOH 2644 8.340 10.260 9.640 1.00 0.00 +ATOM 8404 HW1 HOH 2644 8.200 9.320 9.740 1.00 0.00 +ATOM 8405 HW2 HOH 2644 9.290 10.370 9.700 1.00 0.00 +ATOM 8406 OW HOH 2645 21.770 8.740 10.080 1.00 0.00 +ATOM 8407 HW1 HOH 2645 22.340 9.510 10.030 1.00 0.00 +ATOM 8408 HW2 HOH 2645 21.420 8.640 9.200 1.00 0.00 +ATOM 8409 OW HOH 2646 43.600 46.160 29.180 1.00 0.00 +ATOM 8410 HW1 HOH 2646 44.520 45.920 29.200 1.00 0.00 +ATOM 8411 HW2 HOH 2646 43.130 45.360 29.430 1.00 0.00 +ATOM 8412 OW HOH 2647 0.280 33.890 2.800 1.00 0.00 +ATOM 8413 HW1 HOH 2647 -0.540 34.300 2.530 1.00 0.00 +ATOM 8414 HW2 HOH 2647 0.910 34.150 2.120 1.00 0.00 +ATOM 8415 OW HOH 2648 13.100 28.390 32.200 1.00 0.00 +ATOM 8416 HW1 HOH 2648 12.930 28.420 31.260 1.00 0.00 +ATOM 8417 HW2 HOH 2648 12.360 28.850 32.600 1.00 0.00 +ATOM 8418 OW HOH 2649 36.030 30.120 23.440 1.00 0.00 +ATOM 8419 HW1 HOH 2649 36.620 29.770 24.110 1.00 0.00 +ATOM 8420 HW2 HOH 2649 35.810 29.360 22.900 1.00 0.00 +ATOM 8421 OW HOH 2650 49.020 31.070 8.490 1.00 0.00 +ATOM 8422 HW1 HOH 2650 48.360 30.670 9.060 1.00 0.00 +ATOM 8423 HW2 HOH 2650 48.530 31.450 7.770 1.00 0.00 +ATOM 8424 OW HOH 2651 33.440 24.190 29.880 1.00 0.00 +ATOM 8425 HW1 HOH 2651 33.240 24.990 30.360 1.00 0.00 +ATOM 8426 HW2 HOH 2651 34.400 24.130 29.900 1.00 0.00 +ATOM 8427 OW HOH 2652 47.390 34.270 25.430 1.00 0.00 +ATOM 8428 HW1 HOH 2652 46.520 33.880 25.340 1.00 0.00 +ATOM 8429 HW2 HOH 2652 47.360 34.720 26.280 1.00 0.00 +ATOM 8430 OW HOH 2653 7.560 1.630 24.890 1.00 0.00 +ATOM 8431 HW1 HOH 2653 6.680 1.890 25.160 1.00 0.00 +ATOM 8432 HW2 HOH 2653 7.810 0.950 25.530 1.00 0.00 +ATOM 8433 OW HOH 2654 47.420 29.960 27.510 1.00 0.00 +ATOM 8434 HW1 HOH 2654 47.430 29.350 28.240 1.00 0.00 +ATOM 8435 HW2 HOH 2654 47.420 29.400 26.730 1.00 0.00 +ATOM 8436 OW HOH 2655 17.670 15.700 38.250 1.00 0.00 +ATOM 8437 HW1 HOH 2655 18.010 15.490 39.130 1.00 0.00 +ATOM 8438 HW2 HOH 2655 17.570 16.650 38.250 1.00 0.00 +ATOM 8439 OW HOH 2656 30.320 7.570 7.280 1.00 0.00 +ATOM 8440 HW1 HOH 2656 29.380 7.390 7.230 1.00 0.00 +ATOM 8441 HW2 HOH 2656 30.540 7.990 6.450 1.00 0.00 +ATOM 8442 OW HOH 2657 13.540 3.620 22.970 1.00 0.00 +ATOM 8443 HW1 HOH 2657 13.900 3.130 23.710 1.00 0.00 +ATOM 8444 HW2 HOH 2657 13.620 4.540 23.240 1.00 0.00 +ATOM 8445 OW HOH 2658 23.720 41.000 31.150 1.00 0.00 +ATOM 8446 HW1 HOH 2658 24.570 40.570 31.010 1.00 0.00 +ATOM 8447 HW2 HOH 2658 23.200 40.730 30.400 1.00 0.00 +ATOM 8448 OW HOH 2659 45.860 41.210 24.900 1.00 0.00 +ATOM 8449 HW1 HOH 2659 44.910 41.130 24.820 1.00 0.00 +ATOM 8450 HW2 HOH 2659 46.200 40.440 24.430 1.00 0.00 +ATOM 8451 OW HOH 2660 1.260 23.240 5.660 1.00 0.00 +ATOM 8452 HW1 HOH 2660 1.800 23.440 6.420 1.00 0.00 +ATOM 8453 HW2 HOH 2660 1.860 22.850 5.030 1.00 0.00 +ATOM 8454 OW HOH 2661 48.410 32.990 30.680 1.00 0.00 +ATOM 8455 HW1 HOH 2661 49.000 32.890 29.930 1.00 0.00 +ATOM 8456 HW2 HOH 2661 47.570 32.650 30.360 1.00 0.00 +ATOM 8457 OW HOH 2662 2.350 35.390 23.530 1.00 0.00 +ATOM 8458 HW1 HOH 2662 2.350 35.290 24.480 1.00 0.00 +ATOM 8459 HW2 HOH 2662 1.540 35.870 23.330 1.00 0.00 +ATOM 8460 OW HOH 2663 12.900 7.970 18.710 1.00 0.00 +ATOM 8461 HW1 HOH 2663 13.770 7.660 18.950 1.00 0.00 +ATOM 8462 HW2 HOH 2663 12.830 7.780 17.770 1.00 0.00 +ATOM 8463 OW HOH 2664 8.910 32.110 9.210 1.00 0.00 +ATOM 8464 HW1 HOH 2664 9.390 32.930 9.080 1.00 0.00 +ATOM 8465 HW2 HOH 2664 8.270 32.090 8.500 1.00 0.00 +ATOM 8466 OW HOH 2665 44.950 29.690 35.870 1.00 0.00 +ATOM 8467 HW1 HOH 2665 45.330 30.440 36.310 1.00 0.00 +ATOM 8468 HW2 HOH 2665 45.600 29.430 35.220 1.00 0.00 +ATOM 8469 OW HOH 2666 12.050 11.310 14.910 1.00 0.00 +ATOM 8470 HW1 HOH 2666 11.480 10.540 15.020 1.00 0.00 +ATOM 8471 HW2 HOH 2666 11.800 11.660 14.050 1.00 0.00 +ATOM 8472 OW HOH 2667 1.880 15.020 32.060 1.00 0.00 +ATOM 8473 HW1 HOH 2667 1.680 14.670 31.190 1.00 0.00 +ATOM 8474 HW2 HOH 2667 2.180 15.920 31.890 1.00 0.00 +ATOM 8475 OW HOH 2668 43.920 12.370 7.020 1.00 0.00 +ATOM 8476 HW1 HOH 2668 42.980 12.240 6.890 1.00 0.00 +ATOM 8477 HW2 HOH 2668 44.020 12.430 7.980 1.00 0.00 +ATOM 8478 OW HOH 2669 36.850 23.360 32.570 1.00 0.00 +ATOM 8479 HW1 HOH 2669 36.700 22.420 32.440 1.00 0.00 +ATOM 8480 HW2 HOH 2669 35.980 23.720 32.720 1.00 0.00 +ATOM 8481 OW HOH 2670 42.280 43.180 23.800 1.00 0.00 +ATOM 8482 HW1 HOH 2670 42.770 43.720 23.180 1.00 0.00 +ATOM 8483 HW2 HOH 2670 42.120 43.750 24.550 1.00 0.00 +ATOM 8484 OW HOH 2671 28.230 25.950 0.690 1.00 0.00 +ATOM 8485 HW1 HOH 2671 27.910 26.370 1.490 1.00 0.00 +ATOM 8486 HW2 HOH 2671 29.000 26.470 0.440 1.00 0.00 +ATOM 8487 OW HOH 2672 40.550 39.710 25.530 1.00 0.00 +ATOM 8488 HW1 HOH 2672 40.580 40.540 26.000 1.00 0.00 +ATOM 8489 HW2 HOH 2672 40.570 39.040 26.210 1.00 0.00 +ATOM 8490 OW HOH 2673 41.670 33.150 34.510 1.00 0.00 +ATOM 8491 HW1 HOH 2673 42.220 33.920 34.670 1.00 0.00 +ATOM 8492 HW2 HOH 2673 42.290 32.480 34.210 1.00 0.00 +ATOM 8493 OW HOH 2674 45.460 13.460 34.570 1.00 0.00 +ATOM 8494 HW1 HOH 2674 46.280 13.170 34.980 1.00 0.00 +ATOM 8495 HW2 HOH 2674 45.020 12.640 34.340 1.00 0.00 +ATOM 8496 OW HOH 2675 18.650 28.940 9.900 1.00 0.00 +ATOM 8497 HW1 HOH 2675 19.500 28.510 9.810 1.00 0.00 +ATOM 8498 HW2 HOH 2675 18.480 28.960 10.840 1.00 0.00 +ATOM 8499 OW HOH 2676 31.600 34.680 31.030 1.00 0.00 +ATOM 8500 HW1 HOH 2676 31.260 34.210 31.790 1.00 0.00 +ATOM 8501 HW2 HOH 2676 31.480 35.610 31.230 1.00 0.00 +ATOM 8502 OW HOH 2677 36.480 21.390 7.040 1.00 0.00 +ATOM 8503 HW1 HOH 2677 37.310 21.040 7.360 1.00 0.00 +ATOM 8504 HW2 HOH 2677 35.810 20.920 7.530 1.00 0.00 +ATOM 8505 OW HOH 2678 11.910 5.390 24.730 1.00 0.00 +ATOM 8506 HW1 HOH 2678 11.120 4.970 24.400 1.00 0.00 +ATOM 8507 HW2 HOH 2678 12.350 5.740 23.950 1.00 0.00 +ATOM 8508 OW HOH 2679 34.440 25.390 9.920 1.00 0.00 +ATOM 8509 HW1 HOH 2679 34.250 26.100 9.320 1.00 0.00 +ATOM 8510 HW2 HOH 2679 35.250 25.650 10.360 1.00 0.00 +ATOM 8511 OW HOH 2680 44.210 30.080 23.830 1.00 0.00 +ATOM 8512 HW1 HOH 2680 43.270 29.970 23.900 1.00 0.00 +ATOM 8513 HW2 HOH 2680 44.450 30.630 24.570 1.00 0.00 +ATOM 8514 OW HOH 2681 40.890 3.010 23.680 1.00 0.00 +ATOM 8515 HW1 HOH 2681 40.800 2.060 23.560 1.00 0.00 +ATOM 8516 HW2 HOH 2681 41.570 3.100 24.340 1.00 0.00 +ATOM 8517 OW HOH 2682 6.700 12.810 4.200 1.00 0.00 +ATOM 8518 HW1 HOH 2682 6.770 12.970 5.150 1.00 0.00 +ATOM 8519 HW2 HOH 2682 5.760 12.850 4.020 1.00 0.00 +ATOM 8520 OW HOH 2683 18.270 24.400 12.390 1.00 0.00 +ATOM 8521 HW1 HOH 2683 18.740 25.220 12.230 1.00 0.00 +ATOM 8522 HW2 HOH 2683 18.950 23.770 12.620 1.00 0.00 +ATOM 8523 OW HOH 2684 41.240 33.340 7.190 1.00 0.00 +ATOM 8524 HW1 HOH 2684 41.440 32.770 7.920 1.00 0.00 +ATOM 8525 HW2 HOH 2684 40.380 33.700 7.380 1.00 0.00 +ATOM 8526 OW HOH 2685 0.240 43.520 13.620 1.00 0.00 +ATOM 8527 HW1 HOH 2685 0.610 43.160 12.810 1.00 0.00 +ATOM 8528 HW2 HOH 2685 0.940 43.450 14.260 1.00 0.00 +ATOM 8529 OW HOH 2686 40.940 18.760 1.760 1.00 0.00 +ATOM 8530 HW1 HOH 2686 41.370 19.100 2.550 1.00 0.00 +ATOM 8531 HW2 HOH 2686 41.390 19.180 1.030 1.00 0.00 +ATOM 8532 OW HOH 2687 25.280 17.620 3.400 1.00 0.00 +ATOM 8533 HW1 HOH 2687 25.540 16.740 3.680 1.00 0.00 +ATOM 8534 HW2 HOH 2687 25.870 18.200 3.870 1.00 0.00 +ATOM 8535 OW HOH 2688 12.760 33.860 24.500 1.00 0.00 +ATOM 8536 HW1 HOH 2688 12.240 33.250 23.980 1.00 0.00 +ATOM 8537 HW2 HOH 2688 13.170 33.320 25.170 1.00 0.00 +ATOM 8538 OW HOH 2689 3.630 13.730 28.290 1.00 0.00 +ATOM 8539 HW1 HOH 2689 2.950 13.810 28.960 1.00 0.00 +ATOM 8540 HW2 HOH 2689 3.830 12.790 28.270 1.00 0.00 +ATOM 8541 OW HOH 2690 43.080 20.440 29.010 1.00 0.00 +ATOM 8542 HW1 HOH 2690 42.490 20.750 29.700 1.00 0.00 +ATOM 8543 HW2 HOH 2690 43.110 21.160 28.380 1.00 0.00 +ATOM 8544 OW HOH 2691 8.660 30.050 1.180 1.00 0.00 +ATOM 8545 HW1 HOH 2691 8.180 29.220 1.220 1.00 0.00 +ATOM 8546 HW2 HOH 2691 8.070 30.690 1.580 1.00 0.00 +ATOM 8547 OW HOH 2692 13.130 11.870 33.090 1.00 0.00 +ATOM 8548 HW1 HOH 2692 13.860 11.320 32.800 1.00 0.00 +ATOM 8549 HW2 HOH 2692 13.320 12.040 34.010 1.00 0.00 +ATOM 8550 OW HOH 2693 15.670 30.860 5.920 1.00 0.00 +ATOM 8551 HW1 HOH 2693 15.720 31.460 6.660 1.00 0.00 +ATOM 8552 HW2 HOH 2693 15.530 30.000 6.320 1.00 0.00 +ATOM 8553 OW HOH 2694 11.700 28.500 19.720 1.00 0.00 +ATOM 8554 HW1 HOH 2694 11.960 27.670 19.320 1.00 0.00 +ATOM 8555 HW2 HOH 2694 12.390 29.120 19.470 1.00 0.00 +ATOM 8556 OW HOH 2695 32.950 33.090 29.320 1.00 0.00 +ATOM 8557 HW1 HOH 2695 32.680 33.330 28.440 1.00 0.00 +ATOM 8558 HW2 HOH 2695 32.520 33.730 29.890 1.00 0.00 +ATOM 8559 OW HOH 2696 35.750 24.740 20.470 1.00 0.00 +ATOM 8560 HW1 HOH 2696 36.470 25.240 20.100 1.00 0.00 +ATOM 8561 HW2 HOH 2696 35.060 24.790 19.810 1.00 0.00 +ATOM 8562 OW HOH 2697 26.740 44.050 16.410 1.00 0.00 +ATOM 8563 HW1 HOH 2697 26.240 44.010 17.220 1.00 0.00 +ATOM 8564 HW2 HOH 2697 27.450 44.660 16.590 1.00 0.00 +ATOM 8565 OW HOH 2698 7.480 45.240 26.720 1.00 0.00 +ATOM 8566 HW1 HOH 2698 8.360 45.300 27.080 1.00 0.00 +ATOM 8567 HW2 HOH 2698 6.920 45.610 27.410 1.00 0.00 +ATOM 8568 OW HOH 2699 48.400 29.560 22.290 1.00 0.00 +ATOM 8569 HW1 HOH 2699 48.980 30.230 21.920 1.00 0.00 +ATOM 8570 HW2 HOH 2699 47.820 29.320 21.570 1.00 0.00 +ATOM 8571 OW HOH 2700 22.080 19.930 31.380 1.00 0.00 +ATOM 8572 HW1 HOH 2700 21.960 19.420 32.180 1.00 0.00 +ATOM 8573 HW2 HOH 2700 22.600 19.370 30.810 1.00 0.00 +ATOM 8574 OW HOH 2701 25.610 7.960 8.700 1.00 0.00 +ATOM 8575 HW1 HOH 2701 25.000 7.380 9.160 1.00 0.00 +ATOM 8576 HW2 HOH 2701 25.110 8.270 7.940 1.00 0.00 +ATOM 8577 OW HOH 2702 35.500 12.390 30.330 1.00 0.00 +ATOM 8578 HW1 HOH 2702 35.330 11.690 29.700 1.00 0.00 +ATOM 8579 HW2 HOH 2702 36.280 12.830 30.000 1.00 0.00 +ATOM 8580 OW HOH 2703 0.540 3.250 24.060 1.00 0.00 +ATOM 8581 HW1 HOH 2703 1.230 3.880 23.870 1.00 0.00 +ATOM 8582 HW2 HOH 2703 1.000 2.400 24.100 1.00 0.00 +ATOM 8583 OW HOH 2704 37.120 37.530 2.810 1.00 0.00 +ATOM 8584 HW1 HOH 2704 37.090 36.640 3.150 1.00 0.00 +ATOM 8585 HW2 HOH 2704 36.260 37.670 2.420 1.00 0.00 +ATOM 8586 OW HOH 2705 7.510 31.530 6.810 1.00 0.00 +ATOM 8587 HW1 HOH 2705 7.840 31.740 5.930 1.00 0.00 +ATOM 8588 HW2 HOH 2705 6.580 31.750 6.770 1.00 0.00 +ATOM 8589 OW HOH 2706 21.100 7.710 25.810 1.00 0.00 +ATOM 8590 HW1 HOH 2706 20.350 7.170 26.060 1.00 0.00 +ATOM 8591 HW2 HOH 2706 21.850 7.120 25.860 1.00 0.00 +ATOM 8592 OW HOH 2707 17.790 45.060 7.760 1.00 0.00 +ATOM 8593 HW1 HOH 2707 17.350 44.460 7.160 1.00 0.00 +ATOM 8594 HW2 HOH 2707 18.710 44.800 7.720 1.00 0.00 +ATOM 8595 OW HOH 2708 42.420 39.600 30.160 1.00 0.00 +ATOM 8596 HW1 HOH 2708 43.120 40.230 30.340 1.00 0.00 +ATOM 8597 HW2 HOH 2708 42.720 38.790 30.580 1.00 0.00 +ATOM 8598 OW HOH 2709 2.340 25.770 37.620 1.00 0.00 +ATOM 8599 HW1 HOH 2709 1.650 25.770 38.280 1.00 0.00 +ATOM 8600 HW2 HOH 2709 2.230 26.600 37.160 1.00 0.00 +ATOM 8601 OW HOH 2710 23.140 4.530 36.620 1.00 0.00 +ATOM 8602 HW1 HOH 2710 23.400 5.110 37.330 1.00 0.00 +ATOM 8603 HW2 HOH 2710 23.840 4.600 35.980 1.00 0.00 +ATOM 8604 OW HOH 2711 46.640 20.740 25.750 1.00 0.00 +ATOM 8605 HW1 HOH 2711 46.010 20.070 26.050 1.00 0.00 +ATOM 8606 HW2 HOH 2711 46.100 21.370 25.270 1.00 0.00 +ATOM 8607 OW HOH 2712 34.960 26.800 33.160 1.00 0.00 +ATOM 8608 HW1 HOH 2712 35.040 27.640 32.700 1.00 0.00 +ATOM 8609 HW2 HOH 2712 35.860 26.540 33.350 1.00 0.00 +ATOM 8610 OW HOH 2713 25.240 38.430 36.070 1.00 0.00 +ATOM 8611 HW1 HOH 2713 24.540 38.440 35.420 1.00 0.00 +ATOM 8612 HW2 HOH 2713 24.830 38.760 36.870 1.00 0.00 +ATOM 8613 OW HOH 2714 1.420 40.440 29.790 1.00 0.00 +ATOM 8614 HW1 HOH 2714 1.300 39.890 30.570 1.00 0.00 +ATOM 8615 HW2 HOH 2714 1.260 39.840 29.060 1.00 0.00 +ATOM 8616 OW HOH 2715 31.110 41.030 28.400 1.00 0.00 +ATOM 8617 HW1 HOH 2715 31.630 41.220 27.620 1.00 0.00 +ATOM 8618 HW2 HOH 2715 30.290 40.670 28.060 1.00 0.00 +ATOM 8619 OW HOH 2716 41.730 44.570 26.340 1.00 0.00 +ATOM 8620 HW1 HOH 2716 41.910 44.930 27.210 1.00 0.00 +ATOM 8621 HW2 HOH 2716 41.780 43.620 26.460 1.00 0.00 +ATOM 8622 OW HOH 2717 17.680 30.810 2.410 1.00 0.00 +ATOM 8623 HW1 HOH 2717 17.820 29.870 2.410 1.00 0.00 +ATOM 8624 HW2 HOH 2717 17.080 30.970 1.680 1.00 0.00 +ATOM 8625 OW HOH 2718 22.620 21.460 27.330 1.00 0.00 +ATOM 8626 HW1 HOH 2718 22.910 20.550 27.370 1.00 0.00 +ATOM 8627 HW2 HOH 2718 22.830 21.810 28.200 1.00 0.00 +ATOM 8628 OW HOH 2719 31.780 33.750 24.240 1.00 0.00 +ATOM 8629 HW1 HOH 2719 31.790 32.820 24.010 1.00 0.00 +ATOM 8630 HW2 HOH 2719 32.660 34.060 24.020 1.00 0.00 +ATOM 8631 OW HOH 2720 39.970 25.720 2.090 1.00 0.00 +ATOM 8632 HW1 HOH 2720 39.570 25.170 2.770 1.00 0.00 +ATOM 8633 HW2 HOH 2720 39.940 26.610 2.450 1.00 0.00 +ATOM 8634 OW HOH 2721 32.110 16.780 2.010 1.00 0.00 +ATOM 8635 HW1 HOH 2721 32.170 16.160 2.740 1.00 0.00 +ATOM 8636 HW2 HOH 2721 33.020 17.050 1.860 1.00 0.00 +ATOM 8637 OW HOH 2722 31.910 3.090 31.080 1.00 0.00 +ATOM 8638 HW1 HOH 2722 31.980 4.010 30.830 1.00 0.00 +ATOM 8639 HW2 HOH 2722 31.360 3.100 31.870 1.00 0.00 +ATOM 8640 OW HOH 2723 46.000 1.410 37.460 1.00 0.00 +ATOM 8641 HW1 HOH 2723 46.890 1.700 37.660 1.00 0.00 +ATOM 8642 HW2 HOH 2723 45.500 2.220 37.400 1.00 0.00 +ATOM 8643 OW HOH 2724 39.820 39.170 21.510 1.00 0.00 +ATOM 8644 HW1 HOH 2724 40.080 40.050 21.240 1.00 0.00 +ATOM 8645 HW2 HOH 2724 40.220 38.590 20.860 1.00 0.00 +ATOM 8646 OW HOH 2725 45.010 26.850 25.530 1.00 0.00 +ATOM 8647 HW1 HOH 2725 44.980 27.780 25.740 1.00 0.00 +ATOM 8648 HW2 HOH 2725 44.170 26.500 25.810 1.00 0.00 +ATOM 8649 OW HOH 2726 43.360 34.500 14.840 1.00 0.00 +ATOM 8650 HW1 HOH 2726 43.780 34.310 14.000 1.00 0.00 +ATOM 8651 HW2 HOH 2726 43.990 35.060 15.300 1.00 0.00 +ATOM 8652 OW HOH 2727 0.330 9.880 38.370 1.00 0.00 +ATOM 8653 HW1 HOH 2727 -0.380 10.410 38.710 1.00 0.00 +ATOM 8654 HW2 HOH 2727 0.420 9.160 39.000 1.00 0.00 +ATOM 8655 OW HOH 2728 -0.090 45.330 5.240 1.00 0.00 +ATOM 8656 HW1 HOH 2728 0.190 44.550 5.720 1.00 0.00 +ATOM 8657 HW2 HOH 2728 0.600 45.980 5.410 1.00 0.00 +ATOM 8658 OW HOH 2729 32.300 36.190 4.150 1.00 0.00 +ATOM 8659 HW1 HOH 2729 31.780 35.970 3.380 1.00 0.00 +ATOM 8660 HW2 HOH 2729 31.930 37.010 4.470 1.00 0.00 +ATOM 8661 OW HOH 2730 40.100 14.320 37.000 1.00 0.00 +ATOM 8662 HW1 HOH 2730 40.730 14.840 37.500 1.00 0.00 +ATOM 8663 HW2 HOH 2730 39.260 14.760 37.150 1.00 0.00 +ATOM 8664 OW HOH 2731 39.330 14.620 31.890 1.00 0.00 +ATOM 8665 HW1 HOH 2731 38.450 14.990 31.940 1.00 0.00 +ATOM 8666 HW2 HOH 2731 39.600 14.520 32.800 1.00 0.00 +ATOM 8667 OW HOH 2732 23.880 2.140 4.620 1.00 0.00 +ATOM 8668 HW1 HOH 2732 24.370 2.570 3.920 1.00 0.00 +ATOM 8669 HW2 HOH 2732 23.210 2.780 4.860 1.00 0.00 +ATOM 8670 OW HOH 2733 30.360 18.160 29.880 1.00 0.00 +ATOM 8671 HW1 HOH 2733 31.190 18.180 30.350 1.00 0.00 +ATOM 8672 HW2 HOH 2733 30.490 18.750 29.140 1.00 0.00 +ATOM 8673 OW HOH 2734 27.270 13.540 32.750 1.00 0.00 +ATOM 8674 HW1 HOH 2734 27.190 14.290 32.160 1.00 0.00 +ATOM 8675 HW2 HOH 2734 27.090 13.890 33.620 1.00 0.00 +ATOM 8676 OW HOH 2735 35.540 10.810 8.380 1.00 0.00 +ATOM 8677 HW1 HOH 2735 35.920 11.350 7.690 1.00 0.00 +ATOM 8678 HW2 HOH 2735 35.450 9.940 7.990 1.00 0.00 +ATOM 8679 OW HOH 2736 41.090 18.930 5.490 1.00 0.00 +ATOM 8680 HW1 HOH 2736 41.840 18.340 5.630 1.00 0.00 +ATOM 8681 HW2 HOH 2736 40.350 18.470 5.880 1.00 0.00 +ATOM 8682 OW HOH 2737 47.200 11.230 0.000 1.00 0.00 +ATOM 8683 HW1 HOH 2737 47.470 11.980 0.530 1.00 0.00 +ATOM 8684 HW2 HOH 2737 46.590 10.760 0.560 1.00 0.00 +ATOM 8685 OW HOH 2738 32.050 2.890 19.690 1.00 0.00 +ATOM 8686 HW1 HOH 2738 31.180 3.220 19.450 1.00 0.00 +ATOM 8687 HW2 HOH 2738 31.870 2.080 20.180 1.00 0.00 +ATOM 8688 OW HOH 2739 34.690 37.660 1.630 1.00 0.00 +ATOM 8689 HW1 HOH 2739 34.780 37.970 0.730 1.00 0.00 +ATOM 8690 HW2 HOH 2739 34.260 36.810 1.550 1.00 0.00 +ATOM 8691 OW HOH 2740 22.950 33.100 4.730 1.00 0.00 +ATOM 8692 HW1 HOH 2740 23.120 32.190 4.450 1.00 0.00 +ATOM 8693 HW2 HOH 2740 22.150 33.040 5.250 1.00 0.00 +ATOM 8694 OW HOH 2741 4.650 9.600 38.390 1.00 0.00 +ATOM 8695 HW1 HOH 2741 4.410 9.860 39.270 1.00 0.00 +ATOM 8696 HW2 HOH 2741 4.000 10.010 37.820 1.00 0.00 +ATOM 8697 OW HOH 2742 35.580 40.630 8.570 1.00 0.00 +ATOM 8698 HW1 HOH 2742 34.870 41.150 8.190 1.00 0.00 +ATOM 8699 HW2 HOH 2742 35.680 39.890 7.970 1.00 0.00 +ATOM 8700 OW HOH 2743 38.250 36.400 38.260 1.00 0.00 +ATOM 8701 HW1 HOH 2743 38.140 36.970 37.490 1.00 0.00 +ATOM 8702 HW2 HOH 2743 38.080 36.970 39.010 1.00 0.00 +ATOM 8703 OW HOH 2744 42.490 28.550 35.500 1.00 0.00 +ATOM 8704 HW1 HOH 2744 43.400 28.850 35.490 1.00 0.00 +ATOM 8705 HW2 HOH 2744 42.330 28.320 36.420 1.00 0.00 +ATOM 8706 OW HOH 2745 0.770 37.430 37.530 1.00 0.00 +ATOM 8707 HW1 HOH 2745 0.570 37.260 38.460 1.00 0.00 +ATOM 8708 HW2 HOH 2745 -0.060 37.290 37.080 1.00 0.00 +ATOM 8709 OW HOH 2746 0.100 20.420 19.380 1.00 0.00 +ATOM 8710 HW1 HOH 2746 0.950 20.000 19.220 1.00 0.00 +ATOM 8711 HW2 HOH 2746 0.260 21.350 19.210 1.00 0.00 +ATOM 8712 OW HOH 2747 46.830 37.980 14.190 1.00 0.00 +ATOM 8713 HW1 HOH 2747 46.020 38.410 13.930 1.00 0.00 +ATOM 8714 HW2 HOH 2747 47.520 38.520 13.800 1.00 0.00 +ATOM 8715 OW HOH 2748 23.900 8.960 12.680 1.00 0.00 +ATOM 8716 HW1 HOH 2748 23.660 9.230 11.790 1.00 0.00 +ATOM 8717 HW2 HOH 2748 23.390 9.540 13.250 1.00 0.00 +ATOM 8718 OW HOH 2749 32.310 38.220 13.150 1.00 0.00 +ATOM 8719 HW1 HOH 2749 31.630 38.440 13.790 1.00 0.00 +ATOM 8720 HW2 HOH 2749 32.900 37.630 13.610 1.00 0.00 +ATOM 8721 OW HOH 2750 14.560 18.430 11.090 1.00 0.00 +ATOM 8722 HW1 HOH 2750 14.680 19.040 10.360 1.00 0.00 +ATOM 8723 HW2 HOH 2750 15.450 18.190 11.360 1.00 0.00 +ATOM 8724 OW HOH 2751 31.500 25.020 37.890 1.00 0.00 +ATOM 8725 HW1 HOH 2751 30.880 25.740 37.800 1.00 0.00 +ATOM 8726 HW2 HOH 2751 31.700 24.760 36.990 1.00 0.00 +ATOM 8727 OW HOH 2752 36.480 19.730 11.650 1.00 0.00 +ATOM 8728 HW1 HOH 2752 35.890 19.270 12.250 1.00 0.00 +ATOM 8729 HW2 HOH 2752 35.940 19.920 10.880 1.00 0.00 +ATOM 8730 OW HOH 2753 17.140 22.630 2.100 1.00 0.00 +ATOM 8731 HW1 HOH 2753 17.050 23.140 1.300 1.00 0.00 +ATOM 8732 HW2 HOH 2753 17.950 22.130 1.980 1.00 0.00 +ATOM 8733 OW HOH 2754 25.200 2.990 1.630 1.00 0.00 +ATOM 8734 HW1 HOH 2754 26.140 2.900 1.760 1.00 0.00 +ATOM 8735 HW2 HOH 2754 25.010 2.460 0.850 1.00 0.00 +ATOM 8736 OW HOH 2755 19.570 37.060 7.950 1.00 0.00 +ATOM 8737 HW1 HOH 2755 18.620 37.090 7.990 1.00 0.00 +ATOM 8738 HW2 HOH 2755 19.780 37.230 7.040 1.00 0.00 +ATOM 8739 OW HOH 2756 4.270 41.890 38.670 1.00 0.00 +ATOM 8740 HW1 HOH 2756 3.540 41.290 38.540 1.00 0.00 +ATOM 8741 HW2 HOH 2756 4.770 41.510 39.390 1.00 0.00 +ATOM 8742 OW HOH 2757 25.710 42.000 14.940 1.00 0.00 +ATOM 8743 HW1 HOH 2757 26.110 42.740 15.410 1.00 0.00 +ATOM 8744 HW2 HOH 2757 25.610 41.320 15.600 1.00 0.00 +ATOM 8745 OW HOH 2758 28.280 8.580 20.780 1.00 0.00 +ATOM 8746 HW1 HOH 2758 28.140 8.870 21.680 1.00 0.00 +ATOM 8747 HW2 HOH 2758 29.140 8.160 20.790 1.00 0.00 +ATOM 8748 OW HOH 2759 30.200 36.960 15.430 1.00 0.00 +ATOM 8749 HW1 HOH 2759 30.510 36.060 15.300 1.00 0.00 +ATOM 8750 HW2 HOH 2759 29.250 36.900 15.300 1.00 0.00 +ATOM 8751 OW HOH 2760 2.660 23.220 33.270 1.00 0.00 +ATOM 8752 HW1 HOH 2760 3.170 22.510 32.890 1.00 0.00 +ATOM 8753 HW2 HOH 2760 1.970 22.780 33.760 1.00 0.00 +ATOM 8754 OW HOH 2761 28.140 6.680 25.620 1.00 0.00 +ATOM 8755 HW1 HOH 2761 27.630 7.440 25.900 1.00 0.00 +ATOM 8756 HW2 HOH 2761 28.380 6.240 26.440 1.00 0.00 +ATOM 8757 OW HOH 2762 25.120 34.070 9.150 1.00 0.00 +ATOM 8758 HW1 HOH 2762 25.200 34.310 8.230 1.00 0.00 +ATOM 8759 HW2 HOH 2762 25.060 34.910 9.610 1.00 0.00 +ATOM 8760 OW HOH 2763 34.400 2.030 20.910 1.00 0.00 +ATOM 8761 HW1 HOH 2763 34.190 2.380 20.040 1.00 0.00 +ATOM 8762 HW2 HOH 2763 33.760 2.450 21.490 1.00 0.00 +ATOM 8763 OW HOH 2764 22.290 27.040 15.520 1.00 0.00 +ATOM 8764 HW1 HOH 2764 22.340 27.180 14.570 1.00 0.00 +ATOM 8765 HW2 HOH 2764 22.830 27.740 15.890 1.00 0.00 +ATOM 8766 OW HOH 2765 25.400 3.480 12.320 1.00 0.00 +ATOM 8767 HW1 HOH 2765 24.930 4.310 12.280 1.00 0.00 +ATOM 8768 HW2 HOH 2765 24.870 2.930 12.890 1.00 0.00 +ATOM 8769 OW HOH 2766 9.580 4.360 29.770 1.00 0.00 +ATOM 8770 HW1 HOH 2766 10.070 4.040 30.520 1.00 0.00 +ATOM 8771 HW2 HOH 2766 10.250 4.540 29.100 1.00 0.00 +ATOM 8772 OW HOH 2767 34.800 4.640 33.800 1.00 0.00 +ATOM 8773 HW1 HOH 2767 34.040 4.320 34.280 1.00 0.00 +ATOM 8774 HW2 HOH 2767 34.450 5.340 33.240 1.00 0.00 +ATOM 8775 OW HOH 2768 6.970 6.000 12.340 1.00 0.00 +ATOM 8776 HW1 HOH 2768 6.020 6.020 12.190 1.00 0.00 +ATOM 8777 HW2 HOH 2768 7.090 5.310 13.000 1.00 0.00 +ATOM 8778 OW HOH 2769 32.080 37.650 35.080 1.00 0.00 +ATOM 8779 HW1 HOH 2769 31.720 38.060 34.290 1.00 0.00 +ATOM 8780 HW2 HOH 2769 31.910 36.720 34.960 1.00 0.00 +ATOM 8781 OW HOH 2770 20.900 1.990 3.690 1.00 0.00 +ATOM 8782 HW1 HOH 2770 21.640 1.420 3.480 1.00 0.00 +ATOM 8783 HW2 HOH 2770 21.240 2.870 3.570 1.00 0.00 +ATOM 8784 OW HOH 2771 43.450 35.550 32.690 1.00 0.00 +ATOM 8785 HW1 HOH 2771 42.770 36.020 32.200 1.00 0.00 +ATOM 8786 HW2 HOH 2771 43.090 35.480 33.580 1.00 0.00 +ATOM 8787 OW HOH 2772 13.350 31.630 29.080 1.00 0.00 +ATOM 8788 HW1 HOH 2772 12.630 31.390 28.490 1.00 0.00 +ATOM 8789 HW2 HOH 2772 12.920 31.870 29.900 1.00 0.00 +ATOM 8790 OW HOH 2773 36.700 27.900 22.200 1.00 0.00 +ATOM 8791 HW1 HOH 2773 36.340 27.330 21.510 1.00 0.00 +ATOM 8792 HW2 HOH 2773 36.780 27.330 22.960 1.00 0.00 +ATOM 8793 OW HOH 2774 33.820 17.090 10.150 1.00 0.00 +ATOM 8794 HW1 HOH 2774 33.400 17.920 9.940 1.00 0.00 +ATOM 8795 HW2 HOH 2774 33.630 16.940 11.070 1.00 0.00 +ATOM 8796 OW HOH 2775 4.180 11.180 12.620 1.00 0.00 +ATOM 8797 HW1 HOH 2775 3.300 10.860 12.420 1.00 0.00 +ATOM 8798 HW2 HOH 2775 4.700 10.930 11.850 1.00 0.00 +ATOM 8799 OW HOH 2776 21.260 10.700 31.990 1.00 0.00 +ATOM 8800 HW1 HOH 2776 20.490 10.920 31.470 1.00 0.00 +ATOM 8801 HW2 HOH 2776 22.000 10.990 31.460 1.00 0.00 +ATOM 8802 OW HOH 2777 42.500 30.740 38.630 1.00 0.00 +ATOM 8803 HW1 HOH 2777 42.830 29.850 38.490 1.00 0.00 +ATOM 8804 HW2 HOH 2777 43.250 31.230 38.970 1.00 0.00 +ATOM 8805 OW HOH 2778 14.550 42.290 27.790 1.00 0.00 +ATOM 8806 HW1 HOH 2778 15.380 41.870 27.570 1.00 0.00 +ATOM 8807 HW2 HOH 2778 14.800 43.120 28.190 1.00 0.00 +ATOM 8808 OW HOH 2779 34.600 8.390 10.490 1.00 0.00 +ATOM 8809 HW1 HOH 2779 34.160 8.530 9.650 1.00 0.00 +ATOM 8810 HW2 HOH 2779 35.500 8.160 10.250 1.00 0.00 +ATOM 8811 OW HOH 2780 14.320 6.060 35.200 1.00 0.00 +ATOM 8812 HW1 HOH 2780 14.920 6.250 34.480 1.00 0.00 +ATOM 8813 HW2 HOH 2780 14.820 6.270 35.990 1.00 0.00 +ATOM 8814 OW HOH 2781 31.920 17.350 36.130 1.00 0.00 +ATOM 8815 HW1 HOH 2781 32.000 17.330 35.180 1.00 0.00 +ATOM 8816 HW2 HOH 2781 30.980 17.440 36.300 1.00 0.00 +ATOM 8817 OW HOH 2782 20.630 21.070 1.700 1.00 0.00 +ATOM 8818 HW1 HOH 2782 20.880 20.350 2.270 1.00 0.00 +ATOM 8819 HW2 HOH 2782 20.950 21.850 2.160 1.00 0.00 +ATOM 8820 OW HOH 2783 10.380 37.070 1.350 1.00 0.00 +ATOM 8821 HW1 HOH 2783 10.600 36.670 0.510 1.00 0.00 +ATOM 8822 HW2 HOH 2783 10.980 36.650 1.980 1.00 0.00 +ATOM 8823 OW HOH 2784 36.930 3.890 35.750 1.00 0.00 +ATOM 8824 HW1 HOH 2784 36.460 4.110 34.940 1.00 0.00 +ATOM 8825 HW2 HOH 2784 37.150 2.960 35.650 1.00 0.00 +ATOM 8826 OW HOH 2785 38.810 29.290 21.660 1.00 0.00 +ATOM 8827 HW1 HOH 2785 38.920 29.070 20.740 1.00 0.00 +ATOM 8828 HW2 HOH 2785 37.970 28.900 21.900 1.00 0.00 +ATOM 8829 OW HOH 2786 11.720 43.030 5.780 1.00 0.00 +ATOM 8830 HW1 HOH 2786 11.620 43.330 6.680 1.00 0.00 +ATOM 8831 HW2 HOH 2786 11.660 42.080 5.830 1.00 0.00 +ATOM 8832 OW HOH 2787 43.750 34.550 35.390 1.00 0.00 +ATOM 8833 HW1 HOH 2787 43.380 34.860 36.220 1.00 0.00 +ATOM 8834 HW2 HOH 2787 44.640 34.290 35.610 1.00 0.00 +ATOM 8835 OW HOH 2788 39.310 1.890 19.530 1.00 0.00 +ATOM 8836 HW1 HOH 2788 39.440 1.020 19.140 1.00 0.00 +ATOM 8837 HW2 HOH 2788 38.440 2.150 19.210 1.00 0.00 +ATOM 8838 OW HOH 2789 35.710 40.940 35.780 1.00 0.00 +ATOM 8839 HW1 HOH 2789 35.490 40.010 35.800 1.00 0.00 +ATOM 8840 HW2 HOH 2789 35.860 41.170 36.690 1.00 0.00 +ATOM 8841 OW HOH 2790 31.320 29.440 36.720 1.00 0.00 +ATOM 8842 HW1 HOH 2790 31.930 29.340 35.990 1.00 0.00 +ATOM 8843 HW2 HOH 2790 30.970 30.330 36.620 1.00 0.00 +ATOM 8844 OW HOH 2791 46.790 23.430 17.130 1.00 0.00 +ATOM 8845 HW1 HOH 2791 47.220 22.690 16.700 1.00 0.00 +ATOM 8846 HW2 HOH 2791 45.870 23.330 16.880 1.00 0.00 +ATOM 8847 OW HOH 2792 27.150 38.410 25.250 1.00 0.00 +ATOM 8848 HW1 HOH 2792 26.590 39.130 25.540 1.00 0.00 +ATOM 8849 HW2 HOH 2792 26.790 38.160 24.400 1.00 0.00 +ATOM 8850 OW HOH 2793 46.750 29.380 11.820 1.00 0.00 +ATOM 8851 HW1 HOH 2793 47.360 28.830 11.330 1.00 0.00 +ATOM 8852 HW2 HOH 2793 47.010 29.270 12.740 1.00 0.00 +ATOM 8853 OW HOH 2794 8.860 1.660 37.070 1.00 0.00 +ATOM 8854 HW1 HOH 2794 8.630 2.070 36.240 1.00 0.00 +ATOM 8855 HW2 HOH 2794 9.240 0.810 36.830 1.00 0.00 +ATOM 8856 OW HOH 2795 32.750 3.600 22.440 1.00 0.00 +ATOM 8857 HW1 HOH 2795 32.720 4.000 21.570 1.00 0.00 +ATOM 8858 HW2 HOH 2795 31.850 3.640 22.750 1.00 0.00 +ATOM 8859 OW HOH 2796 24.060 25.030 30.370 1.00 0.00 +ATOM 8860 HW1 HOH 2796 23.890 24.400 31.080 1.00 0.00 +ATOM 8861 HW2 HOH 2796 23.370 25.690 30.470 1.00 0.00 +ATOM 8862 OW HOH 2797 18.010 8.960 38.190 1.00 0.00 +ATOM 8863 HW1 HOH 2797 18.840 9.360 38.460 1.00 0.00 +ATOM 8864 HW2 HOH 2797 17.340 9.540 38.550 1.00 0.00 +ATOM 8865 OW HOH 2798 44.640 38.770 8.430 1.00 0.00 +ATOM 8866 HW1 HOH 2798 45.460 38.350 8.690 1.00 0.00 +ATOM 8867 HW2 HOH 2798 43.960 38.220 8.830 1.00 0.00 +TER +ENDMDL diff --git a/wrappers/python/simtk/testInstallation.py b/wrappers/python/simtk/testInstallation.py new file mode 100644 index 000000000..28ecf4247 --- /dev/null +++ b/wrappers/python/simtk/testInstallation.py @@ -0,0 +1,83 @@ +from __future__ import print_function +import os +import sys +# First make sure OpenMM is installed. + +class TestingError(Exception): + """ + An error is encountered when + """ + +def run_tests(): + try: + from simtk.openmm.app import * + from simtk.openmm import * + from simtk.unit import * + except ImportError as err: + raise TestingError('Failed to import OpenMM packages; Make sure OpenMM\n' + 'is installed and the library path is set correctly.\n' + 'Error message: %s' % err.message) + + # Create a System for the tests. + data_dir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'openmm', 'app', 'data') + pdb = PDBFile(os.path.join(data_dir, 'test.pdb')) + forcefield = ForceField('amber99sb.xml', 'tip3p.xml') + system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) + + # List all installed platforms and compute forces with each one. + + numPlatforms = Platform.getNumPlatforms() + print("There are", numPlatforms, "Platforms available:") + print() + forces = [None]*numPlatforms + platformErrors = {} + for i in range(numPlatforms): + platform = Platform.getPlatform(i) + print(i+1, platform.getName(), end=" ") + integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) + try: + simulation = Simulation(pdb.topology, system, integrator, platform) + simulation.context.setPositions(pdb.positions) + forces[i] = simulation.context.getState(getForces=True).getForces() + del simulation + print("- Successfully computed forces") + except: + print("- Error computing forces with", platform.getName(), "platform") + platformErrors[platform.getName()] = sys.exc_info()[1] + + # Give details of any errors. + + for platform in platformErrors: + print() + print("%s platform error: %s" % (platform, platformErrors[platform])) + + # See how well the platforms agree. + + if numPlatforms > 1: + print() + print("Median difference in forces between platforms:") + print() + for i in range(numPlatforms): + for j in range(i): + if forces[i] is not None and forces[j] is not None: + errors = [] + for f1, f2 in zip(forces[i], forces[j]): + d = f1-f2 + error = sqrt((d[0]*d[0]+d[1]*d[1]+d[2]*d[2])/(f1[0]*f1[0]+f1[1]*f1[1]+f1[2]*f1[2])) + errors.append(error) + print("{} vs. {}: {:g}".format(Platform.getPlatform(j).getName(), + Platform.getPlatform(i).getName(), + sorted(errors)[len(errors)//2])) + +if __name__ == '__main__': + + try: + run_tests() + except TestingError as err: + print('An error was encountered during testing:') + print(err) + sys.exit(1) + except BaseException as err: + print('An unexpected error was encountered during testing:') + print(err) + sys.exit(1) -- GitLab From 0a86b311d30055630486f4a24ab8e378efbbd2e1 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 19 Nov 2014 02:40:24 -0500 Subject: [PATCH 137/338] Delete all of the code from testInstallation.py and instead replace it with an import of the new testInstallation module and a command to run the tests. This way, we only have one place where we need to maintain this code, yet the current workflow of "run testInstallation.py" still works. --- examples/testInstallation.py | 62 ++---------------------------------- 1 file changed, 2 insertions(+), 60 deletions(-) diff --git a/examples/testInstallation.py b/examples/testInstallation.py index 56eac1dd8..f81fe3868 100644 --- a/examples/testInstallation.py +++ b/examples/testInstallation.py @@ -1,64 +1,6 @@ from __future__ import print_function # First make sure OpenMM is installed. +from simtk import testInstallation -import sys -try: - from simtk.openmm.app import * - from simtk.openmm import * - from simtk.unit import * -except ImportError as err: - print("Failed to import OpenMM packages:", err.message) - print("Make sure OpenMM is installed and the library path is set correctly.") - sys.exit() - -# Create a System for the tests. - -pdb = PDBFile('input.pdb') -forcefield = ForceField('amber99sb.xml', 'tip3p.xml') -system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) - -# List all installed platforms and compute forces with each one. - -numPlatforms = Platform.getNumPlatforms() -print("There are", numPlatforms, "Platforms available:") -print() -forces = [None]*numPlatforms -platformErrors = {} -for i in range(numPlatforms): - platform = Platform.getPlatform(i) - print(i+1, platform.getName(), end=" ") - integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) - try: - simulation = Simulation(pdb.topology, system, integrator, platform) - simulation.context.setPositions(pdb.positions) - forces[i] = simulation.context.getState(getForces=True).getForces() - del simulation - print("- Successfully computed forces") - except: - print("- Error computing forces with", platform.getName(), "platform") - platformErrors[platform.getName()] = sys.exc_info()[1] - -# Give details of any errors. - -for platform in platformErrors: - print() - print("%s platform error: %s" % (platform, platformErrors[platform])) - -# See how well the platforms agree. - -if numPlatforms > 1: - print() - print("Median difference in forces between platforms:") - print() - for i in range(numPlatforms): - for j in range(i): - if forces[i] is not None and forces[j] is not None: - errors = [] - for f1, f2 in zip(forces[i], forces[j]): - d = f1-f2 - error = sqrt((d[0]*d[0]+d[1]*d[1]+d[2]*d[2])/(f1[0]*f1[0]+f1[1]*f1[1]+f1[2]*f1[2])) - errors.append(error) - print("{} vs. {}: {:g}".format(Platform.getPlatform(j).getName(), - Platform.getPlatform(i).getName(), - sorted(errors)[len(errors)//2])) +testInstallation.run_tests() -- GitLab From 64ebc7919b81794369bd203359dc9314755d22ba Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 19 Nov 2014 02:50:26 -0500 Subject: [PATCH 138/338] Apparently "from XXX import *" is only allowed at the module level (I get a SyntaxWarning otherwise). So move those imports back to the module level and save any error messages for when the tests are actually run (if ever). python -m simtk.testInstallation runs the tests, whereas python -c "import simtk.testInstallation" does not. --- wrappers/python/simtk/testInstallation.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/wrappers/python/simtk/testInstallation.py b/wrappers/python/simtk/testInstallation.py index 28ecf4247..9df093fbd 100644 --- a/wrappers/python/simtk/testInstallation.py +++ b/wrappers/python/simtk/testInstallation.py @@ -7,17 +7,24 @@ class TestingError(Exception): """ An error is encountered when """ + pass + +try: + from simtk.openmm.app import * + from simtk.openmm import * + from simtk.unit import * +except ImportError as err: + simtk_import_failed = True + simtk_import_error = err.message +else: + simtk_import_failed = False def run_tests(): - try: - from simtk.openmm.app import * - from simtk.openmm import * - from simtk.unit import * - except ImportError as err: + + if simtk_import_failed: raise TestingError('Failed to import OpenMM packages; Make sure OpenMM\n' 'is installed and the library path is set correctly.\n' - 'Error message: %s' % err.message) - + 'Error message: %s' % simtk_import_error) # Create a System for the tests. data_dir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'openmm', 'app', 'data') pdb = PDBFile(os.path.join(data_dir, 'test.pdb')) -- GitLab From 612ca4144842ffb20cd4774741daec74ce8b7599 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 19 Nov 2014 02:56:18 -0500 Subject: [PATCH 139/338] Tweak error message formatting. --- wrappers/python/simtk/testInstallation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/python/simtk/testInstallation.py b/wrappers/python/simtk/testInstallation.py index 9df093fbd..038bf29f2 100644 --- a/wrappers/python/simtk/testInstallation.py +++ b/wrappers/python/simtk/testInstallation.py @@ -22,9 +22,9 @@ else: def run_tests(): if simtk_import_failed: - raise TestingError('Failed to import OpenMM packages; Make sure OpenMM\n' - 'is installed and the library path is set correctly.\n' - 'Error message: %s' % simtk_import_error) + raise TestingError('Failed to import OpenMM packages; Make sure OpenMM' + 'is installed and the library path is set correctly.' + '\n\tError message: %s' % simtk_import_error) # Create a System for the tests. data_dir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'openmm', 'app', 'data') pdb = PDBFile(os.path.join(data_dir, 'test.pdb')) -- GitLab From ab81ee068799836e364cad74f2a39da307f67c42 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 19 Nov 2014 02:58:01 -0500 Subject: [PATCH 140/338] Further formatting tweaks. --- wrappers/python/simtk/testInstallation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/testInstallation.py b/wrappers/python/simtk/testInstallation.py index 038bf29f2..bf0ce8d54 100644 --- a/wrappers/python/simtk/testInstallation.py +++ b/wrappers/python/simtk/testInstallation.py @@ -22,9 +22,9 @@ else: def run_tests(): if simtk_import_failed: - raise TestingError('Failed to import OpenMM packages; Make sure OpenMM' + raise TestingError('Failed to import OpenMM packages; Make sure OpenMM ' 'is installed and the library path is set correctly.' - '\n\tError message: %s' % simtk_import_error) + '\n\nError message: %s' % simtk_import_error) # Create a System for the tests. data_dir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'openmm', 'app', 'data') pdb = PDBFile(os.path.join(data_dir, 'test.pdb')) -- GitLab From 9f8e7335540fc6518c2e51665b584a5aa487e7ae Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 19 Nov 2014 11:29:36 -0500 Subject: [PATCH 141/338] Add docstring to test function. Convert all raised exceptions raised in run_tests to TestingError so users only ever have one exception to catch. --- wrappers/python/simtk/testInstallation.py | 40 ++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/wrappers/python/simtk/testInstallation.py b/wrappers/python/simtk/testInstallation.py index bf0ce8d54..66ec2efad 100644 --- a/wrappers/python/simtk/testInstallation.py +++ b/wrappers/python/simtk/testInstallation.py @@ -1,4 +1,5 @@ from __future__ import print_function +from functools import wraps import os import sys # First make sure OpenMM is installed. @@ -19,11 +20,39 @@ except ImportError as err: else: simtk_import_failed = False +def error_converter(error_type): + """ Converts all exceptions to the given Exception type """ + def wrapper(func): + @wraps(func) + def new_func(*args, **kwargs): + try: + func(*args, **kwargs) + except error_type: + # Pass the existing error through + raise + except BaseException as err: + raise TestingError('Problem with OpenMM installation ' + 'encountered. OpenMM will not work until the problem ' + 'has been fixed.\n\nError message: %s' % err.message) + return new_func + return wrapper + +@error_converter(TestingError) def run_tests(): + """ + Runs a set of tests to determine which platforms are available and tests the + relative accuracy between them. This can be used to determine if the Python + API is installed and working properly, as well as the fidelity of the + underlying OpenMM libraries with respect to computing energies and forces on + the different platforms supported by your installation. + This test prints the available platforms and the relative force errors + between them for a test system. If a problem is detected, TestingError is + raised. + """ if simtk_import_failed: - raise TestingError('Failed to import OpenMM packages; Make sure OpenMM ' - 'is installed and the library path is set correctly.' + raise TestingError('Failed to import OpenMM packages; OpenMM will not work.\n' + 'Make sure OpenMM is installed and the library path is set correctly.' '\n\nError message: %s' % simtk_import_error) # Create a System for the tests. data_dir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), 'openmm', 'app', 'data') @@ -81,10 +110,5 @@ if __name__ == '__main__': try: run_tests() except TestingError as err: - print('An error was encountered during testing:') - print(err) - sys.exit(1) - except BaseException as err: - print('An unexpected error was encountered during testing:') - print(err) + print(err.message) sys.exit(1) -- GitLab From 3b85cf430777ee7f714c57c43b6c8d31397ca2a4 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 19 Nov 2014 11:33:31 -0500 Subject: [PATCH 142/338] Add "python -m simtk.testInstallation" to .travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2f967a533..feb3a76d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,8 @@ script: - make -j2 - make -j2 install - sudo make PythonInstall + - # Run the testInstallation script + - python -m simtk.testInstallation - # run all of the tests - ctest -j2 -V - # get a list of all of the failed tests into this stupid ctest format -- GitLab From b7730b84914d0ac6c1a51d445bb8160d7148fab6 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 19 Nov 2014 10:58:58 -0800 Subject: [PATCH 143/338] Updated instructions on running the test installation script --- docs-source/usersguide/application.rst | 28 ++++++++++---------------- examples/CMakeLists.txt | 2 +- examples/testInstallation.py | 6 ------ install.sh | 5 ++++- 4 files changed, 16 insertions(+), 25 deletions(-) delete mode 100644 examples/testInstallation.py diff --git a/docs-source/usersguide/application.rst b/docs-source/usersguide/application.rst index 1521a8110..a52d55513 100644 --- a/docs-source/usersguide/application.rst +++ b/docs-source/usersguide/application.rst @@ -105,14 +105,12 @@ example, export OPENMM_CUDA_COMPILER=/opt/CUDA/cuda-6.0/bin/nvcc -7. Verify your installation by running the :file:`testInstallation.py` script found in -the :file:`examples` folder of your OpenMM installation. To run it, cd to the -examples folder and type +7. Verify your installation by typing the following command: :: - python testInstallation.py + python -m simtk.testInstallation -This script confirms that OpenMM is installed, checks whether GPU acceleration +This command confirms that OpenMM is installed, checks whether GPU acceleration is available (via the OpenCL and/or CUDA platforms), and verifies that all platforms produce consistent results. @@ -186,15 +184,13 @@ example, export OPENMM_CUDA_COMPILER=/opt/CUDA/cuda-6.0/bin/nvcc -7. Verify your installation by running the :file:`testInstallation.py` script found in -the :file:`examples` folder of your OpenMM installation. To run it, :command:`cd` to the -:file:`examples` folder and type +7. Verify your installation by typing the following command: :: - python testInstallation.py + python -m simtk.testInstallation -This script confirms that OpenMM is installed, checks whether GPU acceleration -is available (via that OpenCL and/or CUDA platforms), and verifies that all +This command confirms that OpenMM is installed, checks whether GPU acceleration +is available (via the OpenCL and/or CUDA platforms), and verifies that all platforms produce consistent results. .. _installing-on-windows: @@ -272,15 +268,13 @@ your PATH. not set, it will assume plugins are in the default location (:file:`C:\\Program Files\\OpenMM\\lib\\plugins` or :file:`C:\\Program Files (x86)\\OpenMM\\lib\\plugins`). -7. Verify your installation by running the :file:`testInstallation.py` script found in -the :file:`examples` folder of your OpenMM installation. To run it, open a command -window, :command:`cd` to the :file:`examples` folder, and type +7. Verify your installation by typing the following command: :: - python testInstallation.py + python -m simtk.testInstallation -This script confirms that OpenMM is installed, checks whether GPU acceleration -is available (via that OpenCL and/or CUDA platforms), and verifies that all +This command confirms that OpenMM is installed, checks whether GPU acceleration +is available (via the OpenCL and/or CUDA platforms), and verifies that all platforms produce consistent results. .. _running-simulations: diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6605bd88c..0bdef126a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -93,7 +93,7 @@ FOREACH(EX_ROOT ${F_EXAMPLES}) INSTALL(FILES ${EX_ROOT}.f90 DESTINATION examples) ENDFOREACH(EX_ROOT ${F_EXAMPLES}) -INSTALL(FILES simulateAmber.py simulatePdb.py simulateGromacs.py testInstallation.py benchmark.py argon-chemical-potential.py input.inpcrd input.prmtop input.pdb input.gro input.top 5dfr_minimized.pdb 5dfr_solv-cube_equil.pdb +INSTALL(FILES simulateAmber.py simulatePdb.py simulateGromacs.py benchmark.py argon-chemical-potential.py input.inpcrd input.prmtop input.pdb input.gro input.top 5dfr_minimized.pdb 5dfr_solv-cube_equil.pdb DESTINATION examples) INSTALL(FILES VisualStudio/HelloArgon.vcproj diff --git a/examples/testInstallation.py b/examples/testInstallation.py deleted file mode 100644 index f81fe3868..000000000 --- a/examples/testInstallation.py +++ /dev/null @@ -1,6 +0,0 @@ -from __future__ import print_function -# First make sure OpenMM is installed. - -from simtk import testInstallation - -testInstallation.run_tests() diff --git a/install.sh b/install.sh index b83613f0a..bbdb18754 100755 --- a/install.sh +++ b/install.sh @@ -51,7 +51,10 @@ then # Print instructions to the user. echo - echo "Installation is complete." + echo "Installation is complete. You should now test your installation to make sure" + echo "it is working correctly by typing the following command:" + echo + echo "python -m simtk.testInstallation" else echo echo "INSTALLATION FAILED" -- GitLab From 59484a6fb482160c54d6d89d7324dc66c1d6fc79 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 25 Nov 2014 16:34:11 -0800 Subject: [PATCH 144/338] Prevent running tests on unsupported CPUs --- platforms/cpu/tests/TestCpuCustomGBForce.cpp | 4 ++++ platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/platforms/cpu/tests/TestCpuCustomGBForce.cpp b/platforms/cpu/tests/TestCpuCustomGBForce.cpp index a9da9a016..6bdaf72d7 100644 --- a/platforms/cpu/tests/TestCpuCustomGBForce.cpp +++ b/platforms/cpu/tests/TestCpuCustomGBForce.cpp @@ -461,6 +461,10 @@ void testExclusions() { int main() { try { + if (!CpuPlatform::isProcessorSupported()) { + cout << "CPU is not supported. Exiting." << endl; + return 0; + } testOBC(GBSAOBCForce::NoCutoff, CustomGBForce::NoCutoff); testOBC(GBSAOBCForce::CutoffNonPeriodic, CustomGBForce::CutoffNonPeriodic); testOBC(GBSAOBCForce::CutoffPeriodic, CustomGBForce::CutoffPeriodic); diff --git a/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp b/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp index c52f1981e..7a1a930b3 100644 --- a/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp +++ b/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp @@ -673,6 +673,10 @@ void testCentralParticleModeLargeSystem() { int main() { try { + if (!CpuPlatform::isProcessorSupported()) { + cout << "CPU is not supported. Exiting." << endl; + return 0; + } testNoCutoff(); testCutoff(); testPeriodic(); -- GitLab From 4b5f48ee16054db5044372fd793f66c41edb7fd5 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 26 Nov 2014 11:30:23 -0800 Subject: [PATCH 145/338] Workaround for compiler bug in Visual Studio --- platforms/cpu/src/CpuNonbondedForceVec8.cpp | 664 ++++++++++---------- 1 file changed, 335 insertions(+), 329 deletions(-) diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index af6ac2e8a..32cc3d08e 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -1,329 +1,335 @@ - -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. - * Contributors: Pande Group - * - * 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 "SimTKOpenMMCommon.h" -#include "SimTKOpenMMUtilities.h" -#include "CpuNonbondedForceVec8.h" -#include "openmm/OpenMMException.h" -#include "openmm/internal/hardware.h" - -using namespace std; -using namespace OpenMM; - -#ifndef __AVX__ -bool isVec8Supported() { - return false; -} - -CpuNonbondedForce* createCpuNonbondedForceVec8() { - throw OpenMMException("Internal error: OpenMM was compiled without AVX support"); -} -#else -/** - * Check whether 8 component vectors are supported with the current CPU. - */ -bool isVec8Supported() { - // Make sure the CPU supports AVX. - - int cpuInfo[4]; - cpuid(cpuInfo, 0); - if (cpuInfo[0] >= 1) { - cpuid(cpuInfo, 1); - return ((cpuInfo[2] & ((int) 1 << 28)) != 0); - } - return false; -} - -/** - * Factory method to create a CpuNonbondedForceVec8. - */ -CpuNonbondedForce* createCpuNonbondedForceVec8() { - return new CpuNonbondedForceVec8(); -} - -/**--------------------------------------------------------------------------------------- - - CpuNonbondedForceVec8 constructor - - --------------------------------------------------------------------------------------- */ - -CpuNonbondedForceVec8::CpuNonbondedForceVec8() { -} - -void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - // Load the positions and parameters of the atoms in the block. - - const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; - fvec4 blockAtomPosq[8]; - fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) - blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); - blockAtomCharge *= ONE_4PI_EPS0; - fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); - fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); - const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); - - // Loop over neighbors for this block. - - const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); - const vector& exclusions = neighborList->getBlockExclusions(blockIndex); - for (int i = 0; i < (int) neighbors.size(); i++) { - // Load the next neighbor. - - int atom = neighbors[i]; - - // Compute the distances to the block atoms. - - fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); - ivec8 include; - char excl = exclusions[i]; - if (excl == 0) - include = -1; - else - include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); - include = include & (r2 < cutoffDistance*cutoffDistance); - if (!any(include)) - continue; // No interactions to compute. - - // Compute the interactions. - - fvec8 r = sqrt(r2); - fvec8 inverseR = fvec8(1.0f)/r; - fvec8 energy, dEdR; - float atomEpsilon = atomParameters[atom].second; - if (atomEpsilon != 0.0f) { - fvec8 sig = blockAtomSigma+atomParameters[atom].first; - fvec8 sig2 = inverseR*sig; - sig2 *= sig2; - fvec8 sig6 = sig2*sig2*sig2; - fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; - dEdR = epsSig6*(12.0f*sig6 - 6.0f); - energy = epsSig6*(sig6-1.0f); - if (useSwitch) { - fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); - fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); - fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; - dEdR = switchValue*dEdR - energy*switchDeriv*r; - energy *= switchValue; - } - } - else { - energy = 0.0f; - dEdR = 0.0f; - } - fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; - if (cutoff) - dEdR += chargeProd*(inverseR-2.0f*krf*r2); - else - dEdR += chargeProd*inverseR; - dEdR *= inverseR*inverseR; - - // Accumulate energies. - - fvec8 one(1.0f); - if (totalEnergy) { - if (cutoff) - energy += chargeProd*(inverseR+krf*r2-crf); - else - energy += chargeProd*inverseR; - energy = blend(0.0f, energy, include); - *totalEnergy += dot8(energy, one); - } - - // Accumulate forces. - - dEdR = blend(0.0f, dEdR, include); - fvec8 fx = dx*dEdR; - fvec8 fy = dy*dEdR; - fvec8 fz = dz*dEdR; - blockAtomForceX += fx; - blockAtomForceY += fy; - blockAtomForceZ += fz; - float* atomForce = forces+4*atom; - atomForce[0] -= dot8(fx, one); - atomForce[1] -= dot8(fy, one); - atomForce[2] -= dot8(fz, one); - } - - // Record the forces on the block atoms. - - fvec4 f[8]; - transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); - for (int j = 0; j < 8; j++) - (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); - } - -void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - // Load the positions and parameters of the atoms in the block. - - const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; - fvec4 blockAtomPosq[8]; - fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) - blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); - blockAtomCharge *= ONE_4PI_EPS0; - fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); - fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); - const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); - - // Loop over neighbors for this block. - - const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); - const vector& exclusions = neighborList->getBlockExclusions(blockIndex); - for (int i = 0; i < (int) neighbors.size(); i++) { - // Load the next neighbor. - - int atom = neighbors[i]; - - // Compute the distances to the block atoms. - - fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); - ivec8 include; - char excl = exclusions[i]; - if (excl == 0) - include = -1; - else - include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); - include = include & (r2 < cutoffDistance*cutoffDistance); - if (!any(include)) - continue; // No interactions to compute. - - // Compute the interactions. - - fvec8 r = sqrt(r2); - fvec8 inverseR = fvec8(1.0f)/r; - fvec8 energy, dEdR; - float atomEpsilon = atomParameters[atom].second; - if (atomEpsilon != 0.0f) { - fvec8 sig = blockAtomSigma+atomParameters[atom].first; - fvec8 sig2 = inverseR*sig; - sig2 *= sig2; - fvec8 sig6 = sig2*sig2*sig2; - fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; - dEdR = epsSig6*(12.0f*sig6 - 6.0f); - energy = epsSig6*(sig6-1.0f); - if (useSwitch) { - fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); - fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); - fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; - dEdR = switchValue*dEdR - energy*switchDeriv*r; - energy *= switchValue; - } - } - else { - energy = 0.0f; - dEdR = 0.0f; - } - fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; - dEdR += chargeProd*inverseR*ewaldScaleFunction(r); - dEdR *= inverseR*inverseR; - - // Accumulate energies. - - fvec8 one(1.0f); - if (totalEnergy) { - energy += chargeProd*inverseR*erfcApprox(alphaEwald*r); - energy = blend(0.0f, energy, include); - *totalEnergy += dot8(energy, one); - } - - // Accumulate forces. - - dEdR = blend(0.0f, dEdR, include); - fvec8 fx = dx*dEdR; - fvec8 fy = dy*dEdR; - fvec8 fz = dz*dEdR; - blockAtomForceX += fx; - blockAtomForceY += fy; - blockAtomForceZ += fz; - float* atomForce = forces+4*atom; - atomForce[0] -= dot8(fx, one); - atomForce[1] -= dot8(fy, one); - atomForce[2] -= dot8(fz, one); - } - - // Record the forces on the block atoms. - - fvec4 f[8]; - transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); - for (int j = 0; j < 8; j++) - (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); -} - -void CpuNonbondedForceVec8::getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { - dx = x-posI[0]; - dy = y-posI[1]; - dz = z-posI[2]; - if (periodic) { - dx -= round(dx*invBoxSize[0])*boxSize[0]; - dy -= round(dy*invBoxSize[1])*boxSize[1]; - dz -= round(dz*invBoxSize[2])*boxSize[2]; - } - r2 = dx*dx + dy*dy + dz*dz; -} - -fvec8 CpuNonbondedForceVec8::erfcApprox(const fvec8& x) { - // This approximation for erfc is from Abramowitz and Stegun (1964) p. 299. They cite the following as - // the original source: C. Hastings, Jr., Approximations for Digital Computers (1955). It has a maximum - // error of 3e-7. - - fvec8 t = 1.0f+(0.0705230784f+(0.0422820123f+(0.0092705272f+(0.0001520143f+(0.0002765672f+0.0000430638f*x)*x)*x)*x)*x)*x; - t *= t; - t *= t; - t *= t; - return 1.0f/(t*t); -} - -fvec8 CpuNonbondedForceVec8::ewaldScaleFunction(const fvec8& x) { - // Compute the tabulated Ewald scale factor: erfc(alpha*r) + 2*alpha*r*exp(-alpha*alpha*r*r)/sqrt(PI) - - fvec8 x1 = x*ewaldDXInv; - ivec8 index = min(floor(x1), NUM_TABLE_POINTS); - fvec8 coeff2 = x1-index; - fvec8 coeff1 = 1.0f-coeff2; - ivec4 indexLower = index.lowerVec(); - ivec4 indexUpper = index.upperVec(); - fvec4 t1(&ewaldScaleTable[indexLower[0]]); - fvec4 t2(&ewaldScaleTable[indexLower[1]]); - fvec4 t3(&ewaldScaleTable[indexLower[2]]); - fvec4 t4(&ewaldScaleTable[indexLower[3]]); - fvec4 t5(&ewaldScaleTable[indexUpper[0]]); - fvec4 t6(&ewaldScaleTable[indexUpper[1]]); - fvec4 t7(&ewaldScaleTable[indexUpper[2]]); - fvec4 t8(&ewaldScaleTable[indexUpper[3]]); - fvec8 s1, s2, s3, s4; - transpose(t1, t2, t3, t4, t5, t6, t7, t8, s1, s2, s3, s4); - return coeff1*s1 + coeff2*s2; -} -#endif + +/* Portions copyright (c) 2006-2013 Stanford University and Simbios. + * Contributors: Pande Group + * + * 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 "SimTKOpenMMCommon.h" +#include "SimTKOpenMMUtilities.h" +#include "CpuNonbondedForceVec8.h" +#include "openmm/OpenMMException.h" +#include "openmm/internal/hardware.h" + +using namespace std; +using namespace OpenMM; + +#ifdef _MSC_VER + // Workaround for a compiler bug in Visual Studio 10. Hopefully we can remove this + // once we move to a later version. + #undef __AVX__ +#endif + +#ifndef __AVX__ +bool isVec8Supported() { + return false; +} + +CpuNonbondedForce* createCpuNonbondedForceVec8() { + throw OpenMMException("Internal error: OpenMM was compiled without AVX support"); +} +#else +/** + * Check whether 8 component vectors are supported with the current CPU. + */ +bool isVec8Supported() { + // Make sure the CPU supports AVX. + + int cpuInfo[4]; + cpuid(cpuInfo, 0); + if (cpuInfo[0] >= 1) { + cpuid(cpuInfo, 1); + return ((cpuInfo[2] & ((int) 1 << 28)) != 0); + } + return false; +} + +/** + * Factory method to create a CpuNonbondedForceVec8. + */ +CpuNonbondedForce* createCpuNonbondedForceVec8() { + return new CpuNonbondedForceVec8(); +} + +/**--------------------------------------------------------------------------------------- + + CpuNonbondedForceVec8 constructor + + --------------------------------------------------------------------------------------- */ + +CpuNonbondedForceVec8::CpuNonbondedForceVec8() { +} + +void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + // Load the positions and parameters of the atoms in the block. + + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; + fvec4 blockAtomPosq[8]; + fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); + fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; + for (int i = 0; i < 8; i++) + blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); + blockAtomCharge *= ONE_4PI_EPS0; + fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); + fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); + bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || + any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); + + // Loop over neighbors for this block. + + const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); + const vector& exclusions = neighborList->getBlockExclusions(blockIndex); + for (int i = 0; i < (int) neighbors.size(); i++) { + // Load the next neighbor. + + int atom = neighbors[i]; + + // Compute the distances to the block atoms. + + fvec8 dx, dy, dz, r2; + getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + ivec8 include; + char excl = exclusions[i]; + if (excl == 0) + include = -1; + else + include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); + include = include & (r2 < cutoffDistance*cutoffDistance); + if (!any(include)) + continue; // No interactions to compute. + + // Compute the interactions. + + fvec8 r = sqrt(r2); + fvec8 inverseR = fvec8(1.0f)/r; + fvec8 energy, dEdR; + float atomEpsilon = atomParameters[atom].second; + if (atomEpsilon != 0.0f) { + fvec8 sig = blockAtomSigma+atomParameters[atom].first; + fvec8 sig2 = inverseR*sig; + sig2 *= sig2; + fvec8 sig6 = sig2*sig2*sig2; + fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; + dEdR = epsSig6*(12.0f*sig6 - 6.0f); + energy = epsSig6*(sig6-1.0f); + if (useSwitch) { + fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); + fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); + fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; + dEdR = switchValue*dEdR - energy*switchDeriv*r; + energy *= switchValue; + } + } + else { + energy = 0.0f; + dEdR = 0.0f; + } + fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; + if (cutoff) + dEdR += chargeProd*(inverseR-2.0f*krf*r2); + else + dEdR += chargeProd*inverseR; + dEdR *= inverseR*inverseR; + + // Accumulate energies. + + fvec8 one(1.0f); + if (totalEnergy) { + if (cutoff) + energy += chargeProd*(inverseR+krf*r2-crf); + else + energy += chargeProd*inverseR; + energy = blend(0.0f, energy, include); + *totalEnergy += dot8(energy, one); + } + + // Accumulate forces. + + dEdR = blend(0.0f, dEdR, include); + fvec8 fx = dx*dEdR; + fvec8 fy = dy*dEdR; + fvec8 fz = dz*dEdR; + blockAtomForceX += fx; + blockAtomForceY += fy; + blockAtomForceZ += fz; + float* atomForce = forces+4*atom; + atomForce[0] -= dot8(fx, one); + atomForce[1] -= dot8(fy, one); + atomForce[2] -= dot8(fz, one); + } + + // Record the forces on the block atoms. + + fvec4 f[8]; + transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); + for (int j = 0; j < 8; j++) + (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); + } + +void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + // Load the positions and parameters of the atoms in the block. + + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; + fvec4 blockAtomPosq[8]; + fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); + fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; + for (int i = 0; i < 8; i++) + blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); + blockAtomCharge *= ONE_4PI_EPS0; + fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); + fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); + bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || + any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); + + // Loop over neighbors for this block. + + const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); + const vector& exclusions = neighborList->getBlockExclusions(blockIndex); + for (int i = 0; i < (int) neighbors.size(); i++) { + // Load the next neighbor. + + int atom = neighbors[i]; + + // Compute the distances to the block atoms. + + fvec8 dx, dy, dz, r2; + getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + ivec8 include; + char excl = exclusions[i]; + if (excl == 0) + include = -1; + else + include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); + include = include & (r2 < cutoffDistance*cutoffDistance); + if (!any(include)) + continue; // No interactions to compute. + + // Compute the interactions. + + fvec8 r = sqrt(r2); + fvec8 inverseR = fvec8(1.0f)/r; + fvec8 energy, dEdR; + float atomEpsilon = atomParameters[atom].second; + if (atomEpsilon != 0.0f) { + fvec8 sig = blockAtomSigma+atomParameters[atom].first; + fvec8 sig2 = inverseR*sig; + sig2 *= sig2; + fvec8 sig6 = sig2*sig2*sig2; + fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; + dEdR = epsSig6*(12.0f*sig6 - 6.0f); + energy = epsSig6*(sig6-1.0f); + if (useSwitch) { + fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); + fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); + fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; + dEdR = switchValue*dEdR - energy*switchDeriv*r; + energy *= switchValue; + } + } + else { + energy = 0.0f; + dEdR = 0.0f; + } + fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; + dEdR += chargeProd*inverseR*ewaldScaleFunction(r); + dEdR *= inverseR*inverseR; + + // Accumulate energies. + + fvec8 one(1.0f); + if (totalEnergy) { + energy += chargeProd*inverseR*erfcApprox(alphaEwald*r); + energy = blend(0.0f, energy, include); + *totalEnergy += dot8(energy, one); + } + + // Accumulate forces. + + dEdR = blend(0.0f, dEdR, include); + fvec8 fx = dx*dEdR; + fvec8 fy = dy*dEdR; + fvec8 fz = dz*dEdR; + blockAtomForceX += fx; + blockAtomForceY += fy; + blockAtomForceZ += fz; + float* atomForce = forces+4*atom; + atomForce[0] -= dot8(fx, one); + atomForce[1] -= dot8(fy, one); + atomForce[2] -= dot8(fz, one); + } + + // Record the forces on the block atoms. + + fvec4 f[8]; + transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); + for (int j = 0; j < 8; j++) + (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); +} + +void CpuNonbondedForceVec8::getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { + dx = x-posI[0]; + dy = y-posI[1]; + dz = z-posI[2]; + if (periodic) { + dx -= round(dx*invBoxSize[0])*boxSize[0]; + dy -= round(dy*invBoxSize[1])*boxSize[1]; + dz -= round(dz*invBoxSize[2])*boxSize[2]; + } + r2 = dx*dx + dy*dy + dz*dz; +} + +fvec8 CpuNonbondedForceVec8::erfcApprox(const fvec8& x) { + // This approximation for erfc is from Abramowitz and Stegun (1964) p. 299. They cite the following as + // the original source: C. Hastings, Jr., Approximations for Digital Computers (1955). It has a maximum + // error of 3e-7. + + fvec8 t = 1.0f+(0.0705230784f+(0.0422820123f+(0.0092705272f+(0.0001520143f+(0.0002765672f+0.0000430638f*x)*x)*x)*x)*x)*x; + t *= t; + t *= t; + t *= t; + return 1.0f/(t*t); +} + +fvec8 CpuNonbondedForceVec8::ewaldScaleFunction(const fvec8& x) { + // Compute the tabulated Ewald scale factor: erfc(alpha*r) + 2*alpha*r*exp(-alpha*alpha*r*r)/sqrt(PI) + + fvec8 x1 = x*ewaldDXInv; + ivec8 index = min(floor(x1), NUM_TABLE_POINTS); + fvec8 coeff2 = x1-index; + fvec8 coeff1 = 1.0f-coeff2; + ivec4 indexLower = index.lowerVec(); + ivec4 indexUpper = index.upperVec(); + fvec4 t1(&ewaldScaleTable[indexLower[0]]); + fvec4 t2(&ewaldScaleTable[indexLower[1]]); + fvec4 t3(&ewaldScaleTable[indexLower[2]]); + fvec4 t4(&ewaldScaleTable[indexLower[3]]); + fvec4 t5(&ewaldScaleTable[indexUpper[0]]); + fvec4 t6(&ewaldScaleTable[indexUpper[1]]); + fvec4 t7(&ewaldScaleTable[indexUpper[2]]); + fvec4 t8(&ewaldScaleTable[indexUpper[3]]); + fvec8 s1, s2, s3, s4; + transpose(t1, t2, t3, t4, t5, t6, t7, t8, s1, s2, s3, s4); + return coeff1*s1 + coeff2*s2; +} +#endif -- GitLab From a55b34ee9c93f9c210e75d30879013be06e672ab Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 26 Nov 2014 11:46:37 -0800 Subject: [PATCH 146/338] Fixed line endings --- platforms/cpu/src/CpuNonbondedForceVec8.cpp | 670 ++++++++++---------- 1 file changed, 335 insertions(+), 335 deletions(-) diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index 32cc3d08e..175bb6951 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -1,335 +1,335 @@ - -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. - * Contributors: Pande Group - * - * 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 "SimTKOpenMMCommon.h" -#include "SimTKOpenMMUtilities.h" -#include "CpuNonbondedForceVec8.h" -#include "openmm/OpenMMException.h" -#include "openmm/internal/hardware.h" - -using namespace std; -using namespace OpenMM; - -#ifdef _MSC_VER - // Workaround for a compiler bug in Visual Studio 10. Hopefully we can remove this - // once we move to a later version. - #undef __AVX__ -#endif - -#ifndef __AVX__ -bool isVec8Supported() { - return false; -} - -CpuNonbondedForce* createCpuNonbondedForceVec8() { - throw OpenMMException("Internal error: OpenMM was compiled without AVX support"); -} -#else -/** - * Check whether 8 component vectors are supported with the current CPU. - */ -bool isVec8Supported() { - // Make sure the CPU supports AVX. - - int cpuInfo[4]; - cpuid(cpuInfo, 0); - if (cpuInfo[0] >= 1) { - cpuid(cpuInfo, 1); - return ((cpuInfo[2] & ((int) 1 << 28)) != 0); - } - return false; -} - -/** - * Factory method to create a CpuNonbondedForceVec8. - */ -CpuNonbondedForce* createCpuNonbondedForceVec8() { - return new CpuNonbondedForceVec8(); -} - -/**--------------------------------------------------------------------------------------- - - CpuNonbondedForceVec8 constructor - - --------------------------------------------------------------------------------------- */ - -CpuNonbondedForceVec8::CpuNonbondedForceVec8() { -} - -void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - // Load the positions and parameters of the atoms in the block. - - const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; - fvec4 blockAtomPosq[8]; - fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) - blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); - blockAtomCharge *= ONE_4PI_EPS0; - fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); - fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); - const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); - - // Loop over neighbors for this block. - - const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); - const vector& exclusions = neighborList->getBlockExclusions(blockIndex); - for (int i = 0; i < (int) neighbors.size(); i++) { - // Load the next neighbor. - - int atom = neighbors[i]; - - // Compute the distances to the block atoms. - - fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); - ivec8 include; - char excl = exclusions[i]; - if (excl == 0) - include = -1; - else - include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); - include = include & (r2 < cutoffDistance*cutoffDistance); - if (!any(include)) - continue; // No interactions to compute. - - // Compute the interactions. - - fvec8 r = sqrt(r2); - fvec8 inverseR = fvec8(1.0f)/r; - fvec8 energy, dEdR; - float atomEpsilon = atomParameters[atom].second; - if (atomEpsilon != 0.0f) { - fvec8 sig = blockAtomSigma+atomParameters[atom].first; - fvec8 sig2 = inverseR*sig; - sig2 *= sig2; - fvec8 sig6 = sig2*sig2*sig2; - fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; - dEdR = epsSig6*(12.0f*sig6 - 6.0f); - energy = epsSig6*(sig6-1.0f); - if (useSwitch) { - fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); - fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); - fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; - dEdR = switchValue*dEdR - energy*switchDeriv*r; - energy *= switchValue; - } - } - else { - energy = 0.0f; - dEdR = 0.0f; - } - fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; - if (cutoff) - dEdR += chargeProd*(inverseR-2.0f*krf*r2); - else - dEdR += chargeProd*inverseR; - dEdR *= inverseR*inverseR; - - // Accumulate energies. - - fvec8 one(1.0f); - if (totalEnergy) { - if (cutoff) - energy += chargeProd*(inverseR+krf*r2-crf); - else - energy += chargeProd*inverseR; - energy = blend(0.0f, energy, include); - *totalEnergy += dot8(energy, one); - } - - // Accumulate forces. - - dEdR = blend(0.0f, dEdR, include); - fvec8 fx = dx*dEdR; - fvec8 fy = dy*dEdR; - fvec8 fz = dz*dEdR; - blockAtomForceX += fx; - blockAtomForceY += fy; - blockAtomForceZ += fz; - float* atomForce = forces+4*atom; - atomForce[0] -= dot8(fx, one); - atomForce[1] -= dot8(fy, one); - atomForce[2] -= dot8(fz, one); - } - - // Record the forces on the block atoms. - - fvec4 f[8]; - transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); - for (int j = 0; j < 8; j++) - (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); - } - -void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - // Load the positions and parameters of the atoms in the block. - - const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; - fvec4 blockAtomPosq[8]; - fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) - blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); - transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); - blockAtomCharge *= ONE_4PI_EPS0; - fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); - fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); - const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); - - // Loop over neighbors for this block. - - const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); - const vector& exclusions = neighborList->getBlockExclusions(blockIndex); - for (int i = 0; i < (int) neighbors.size(); i++) { - // Load the next neighbor. - - int atom = neighbors[i]; - - // Compute the distances to the block atoms. - - fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); - ivec8 include; - char excl = exclusions[i]; - if (excl == 0) - include = -1; - else - include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); - include = include & (r2 < cutoffDistance*cutoffDistance); - if (!any(include)) - continue; // No interactions to compute. - - // Compute the interactions. - - fvec8 r = sqrt(r2); - fvec8 inverseR = fvec8(1.0f)/r; - fvec8 energy, dEdR; - float atomEpsilon = atomParameters[atom].second; - if (atomEpsilon != 0.0f) { - fvec8 sig = blockAtomSigma+atomParameters[atom].first; - fvec8 sig2 = inverseR*sig; - sig2 *= sig2; - fvec8 sig6 = sig2*sig2*sig2; - fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; - dEdR = epsSig6*(12.0f*sig6 - 6.0f); - energy = epsSig6*(sig6-1.0f); - if (useSwitch) { - fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); - fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); - fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; - dEdR = switchValue*dEdR - energy*switchDeriv*r; - energy *= switchValue; - } - } - else { - energy = 0.0f; - dEdR = 0.0f; - } - fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; - dEdR += chargeProd*inverseR*ewaldScaleFunction(r); - dEdR *= inverseR*inverseR; - - // Accumulate energies. - - fvec8 one(1.0f); - if (totalEnergy) { - energy += chargeProd*inverseR*erfcApprox(alphaEwald*r); - energy = blend(0.0f, energy, include); - *totalEnergy += dot8(energy, one); - } - - // Accumulate forces. - - dEdR = blend(0.0f, dEdR, include); - fvec8 fx = dx*dEdR; - fvec8 fy = dy*dEdR; - fvec8 fz = dz*dEdR; - blockAtomForceX += fx; - blockAtomForceY += fy; - blockAtomForceZ += fz; - float* atomForce = forces+4*atom; - atomForce[0] -= dot8(fx, one); - atomForce[1] -= dot8(fy, one); - atomForce[2] -= dot8(fz, one); - } - - // Record the forces on the block atoms. - - fvec4 f[8]; - transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); - for (int j = 0; j < 8; j++) - (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); -} - -void CpuNonbondedForceVec8::getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { - dx = x-posI[0]; - dy = y-posI[1]; - dz = z-posI[2]; - if (periodic) { - dx -= round(dx*invBoxSize[0])*boxSize[0]; - dy -= round(dy*invBoxSize[1])*boxSize[1]; - dz -= round(dz*invBoxSize[2])*boxSize[2]; - } - r2 = dx*dx + dy*dy + dz*dz; -} - -fvec8 CpuNonbondedForceVec8::erfcApprox(const fvec8& x) { - // This approximation for erfc is from Abramowitz and Stegun (1964) p. 299. They cite the following as - // the original source: C. Hastings, Jr., Approximations for Digital Computers (1955). It has a maximum - // error of 3e-7. - - fvec8 t = 1.0f+(0.0705230784f+(0.0422820123f+(0.0092705272f+(0.0001520143f+(0.0002765672f+0.0000430638f*x)*x)*x)*x)*x)*x; - t *= t; - t *= t; - t *= t; - return 1.0f/(t*t); -} - -fvec8 CpuNonbondedForceVec8::ewaldScaleFunction(const fvec8& x) { - // Compute the tabulated Ewald scale factor: erfc(alpha*r) + 2*alpha*r*exp(-alpha*alpha*r*r)/sqrt(PI) - - fvec8 x1 = x*ewaldDXInv; - ivec8 index = min(floor(x1), NUM_TABLE_POINTS); - fvec8 coeff2 = x1-index; - fvec8 coeff1 = 1.0f-coeff2; - ivec4 indexLower = index.lowerVec(); - ivec4 indexUpper = index.upperVec(); - fvec4 t1(&ewaldScaleTable[indexLower[0]]); - fvec4 t2(&ewaldScaleTable[indexLower[1]]); - fvec4 t3(&ewaldScaleTable[indexLower[2]]); - fvec4 t4(&ewaldScaleTable[indexLower[3]]); - fvec4 t5(&ewaldScaleTable[indexUpper[0]]); - fvec4 t6(&ewaldScaleTable[indexUpper[1]]); - fvec4 t7(&ewaldScaleTable[indexUpper[2]]); - fvec4 t8(&ewaldScaleTable[indexUpper[3]]); - fvec8 s1, s2, s3, s4; - transpose(t1, t2, t3, t4, t5, t6, t7, t8, s1, s2, s3, s4); - return coeff1*s1 + coeff2*s2; -} -#endif + +/* Portions copyright (c) 2006-2013 Stanford University and Simbios. + * Contributors: Pande Group + * + * 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 "SimTKOpenMMCommon.h" +#include "SimTKOpenMMUtilities.h" +#include "CpuNonbondedForceVec8.h" +#include "openmm/OpenMMException.h" +#include "openmm/internal/hardware.h" + +using namespace std; +using namespace OpenMM; + +#ifdef _MSC_VER + // Workaround for a compiler bug in Visual Studio 10. Hopefully we can remove this + // once we move to a later version. + #undef __AVX__ +#endif + +#ifndef __AVX__ +bool isVec8Supported() { + return false; +} + +CpuNonbondedForce* createCpuNonbondedForceVec8() { + throw OpenMMException("Internal error: OpenMM was compiled without AVX support"); +} +#else +/** + * Check whether 8 component vectors are supported with the current CPU. + */ +bool isVec8Supported() { + // Make sure the CPU supports AVX. + + int cpuInfo[4]; + cpuid(cpuInfo, 0); + if (cpuInfo[0] >= 1) { + cpuid(cpuInfo, 1); + return ((cpuInfo[2] & ((int) 1 << 28)) != 0); + } + return false; +} + +/** + * Factory method to create a CpuNonbondedForceVec8. + */ +CpuNonbondedForce* createCpuNonbondedForceVec8() { + return new CpuNonbondedForceVec8(); +} + +/**--------------------------------------------------------------------------------------- + + CpuNonbondedForceVec8 constructor + + --------------------------------------------------------------------------------------- */ + +CpuNonbondedForceVec8::CpuNonbondedForceVec8() { +} + +void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + // Load the positions and parameters of the atoms in the block. + + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; + fvec4 blockAtomPosq[8]; + fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); + fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; + for (int i = 0; i < 8; i++) + blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); + blockAtomCharge *= ONE_4PI_EPS0; + fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); + fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); + bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || + any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); + + // Loop over neighbors for this block. + + const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); + const vector& exclusions = neighborList->getBlockExclusions(blockIndex); + for (int i = 0; i < (int) neighbors.size(); i++) { + // Load the next neighbor. + + int atom = neighbors[i]; + + // Compute the distances to the block atoms. + + fvec8 dx, dy, dz, r2; + getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + ivec8 include; + char excl = exclusions[i]; + if (excl == 0) + include = -1; + else + include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); + include = include & (r2 < cutoffDistance*cutoffDistance); + if (!any(include)) + continue; // No interactions to compute. + + // Compute the interactions. + + fvec8 r = sqrt(r2); + fvec8 inverseR = fvec8(1.0f)/r; + fvec8 energy, dEdR; + float atomEpsilon = atomParameters[atom].second; + if (atomEpsilon != 0.0f) { + fvec8 sig = blockAtomSigma+atomParameters[atom].first; + fvec8 sig2 = inverseR*sig; + sig2 *= sig2; + fvec8 sig6 = sig2*sig2*sig2; + fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; + dEdR = epsSig6*(12.0f*sig6 - 6.0f); + energy = epsSig6*(sig6-1.0f); + if (useSwitch) { + fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); + fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); + fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; + dEdR = switchValue*dEdR - energy*switchDeriv*r; + energy *= switchValue; + } + } + else { + energy = 0.0f; + dEdR = 0.0f; + } + fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; + if (cutoff) + dEdR += chargeProd*(inverseR-2.0f*krf*r2); + else + dEdR += chargeProd*inverseR; + dEdR *= inverseR*inverseR; + + // Accumulate energies. + + fvec8 one(1.0f); + if (totalEnergy) { + if (cutoff) + energy += chargeProd*(inverseR+krf*r2-crf); + else + energy += chargeProd*inverseR; + energy = blend(0.0f, energy, include); + *totalEnergy += dot8(energy, one); + } + + // Accumulate forces. + + dEdR = blend(0.0f, dEdR, include); + fvec8 fx = dx*dEdR; + fvec8 fy = dy*dEdR; + fvec8 fz = dz*dEdR; + blockAtomForceX += fx; + blockAtomForceY += fy; + blockAtomForceZ += fz; + float* atomForce = forces+4*atom; + atomForce[0] -= dot8(fx, one); + atomForce[1] -= dot8(fy, one); + atomForce[2] -= dot8(fz, one); + } + + // Record the forces on the block atoms. + + fvec4 f[8]; + transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); + for (int j = 0; j < 8; j++) + (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); + } + +void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + // Load the positions and parameters of the atoms in the block. + + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; + fvec4 blockAtomPosq[8]; + fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); + fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; + for (int i = 0; i < 8; i++) + blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); + blockAtomCharge *= ONE_4PI_EPS0; + fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); + fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); + bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || + any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); + + // Loop over neighbors for this block. + + const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); + const vector& exclusions = neighborList->getBlockExclusions(blockIndex); + for (int i = 0; i < (int) neighbors.size(); i++) { + // Load the next neighbor. + + int atom = neighbors[i]; + + // Compute the distances to the block atoms. + + fvec8 dx, dy, dz, r2; + getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + ivec8 include; + char excl = exclusions[i]; + if (excl == 0) + include = -1; + else + include = ivec8(excl&1 ? 0 : -1, excl&2 ? 0 : -1, excl&4 ? 0 : -1, excl&8 ? 0 : -1, excl&16 ? 0 : -1, excl&32 ? 0 : -1, excl&64 ? 0 : -1, excl&128 ? 0 : -1); + include = include & (r2 < cutoffDistance*cutoffDistance); + if (!any(include)) + continue; // No interactions to compute. + + // Compute the interactions. + + fvec8 r = sqrt(r2); + fvec8 inverseR = fvec8(1.0f)/r; + fvec8 energy, dEdR; + float atomEpsilon = atomParameters[atom].second; + if (atomEpsilon != 0.0f) { + fvec8 sig = blockAtomSigma+atomParameters[atom].first; + fvec8 sig2 = inverseR*sig; + sig2 *= sig2; + fvec8 sig6 = sig2*sig2*sig2; + fvec8 epsSig6 = blockAtomEpsilon*atomEpsilon*sig6; + dEdR = epsSig6*(12.0f*sig6 - 6.0f); + energy = epsSig6*(sig6-1.0f); + if (useSwitch) { + fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); + fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); + fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; + dEdR = switchValue*dEdR - energy*switchDeriv*r; + energy *= switchValue; + } + } + else { + energy = 0.0f; + dEdR = 0.0f; + } + fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; + dEdR += chargeProd*inverseR*ewaldScaleFunction(r); + dEdR *= inverseR*inverseR; + + // Accumulate energies. + + fvec8 one(1.0f); + if (totalEnergy) { + energy += chargeProd*inverseR*erfcApprox(alphaEwald*r); + energy = blend(0.0f, energy, include); + *totalEnergy += dot8(energy, one); + } + + // Accumulate forces. + + dEdR = blend(0.0f, dEdR, include); + fvec8 fx = dx*dEdR; + fvec8 fy = dy*dEdR; + fvec8 fz = dz*dEdR; + blockAtomForceX += fx; + blockAtomForceY += fy; + blockAtomForceZ += fz; + float* atomForce = forces+4*atom; + atomForce[0] -= dot8(fx, one); + atomForce[1] -= dot8(fy, one); + atomForce[2] -= dot8(fz, one); + } + + // Record the forces on the block atoms. + + fvec4 f[8]; + transpose(blockAtomForceX, blockAtomForceY, blockAtomForceZ, 0.0f, f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); + for (int j = 0; j < 8; j++) + (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); +} + +void CpuNonbondedForceVec8::getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { + dx = x-posI[0]; + dy = y-posI[1]; + dz = z-posI[2]; + if (periodic) { + dx -= round(dx*invBoxSize[0])*boxSize[0]; + dy -= round(dy*invBoxSize[1])*boxSize[1]; + dz -= round(dz*invBoxSize[2])*boxSize[2]; + } + r2 = dx*dx + dy*dy + dz*dz; +} + +fvec8 CpuNonbondedForceVec8::erfcApprox(const fvec8& x) { + // This approximation for erfc is from Abramowitz and Stegun (1964) p. 299. They cite the following as + // the original source: C. Hastings, Jr., Approximations for Digital Computers (1955). It has a maximum + // error of 3e-7. + + fvec8 t = 1.0f+(0.0705230784f+(0.0422820123f+(0.0092705272f+(0.0001520143f+(0.0002765672f+0.0000430638f*x)*x)*x)*x)*x)*x; + t *= t; + t *= t; + t *= t; + return 1.0f/(t*t); +} + +fvec8 CpuNonbondedForceVec8::ewaldScaleFunction(const fvec8& x) { + // Compute the tabulated Ewald scale factor: erfc(alpha*r) + 2*alpha*r*exp(-alpha*alpha*r*r)/sqrt(PI) + + fvec8 x1 = x*ewaldDXInv; + ivec8 index = min(floor(x1), NUM_TABLE_POINTS); + fvec8 coeff2 = x1-index; + fvec8 coeff1 = 1.0f-coeff2; + ivec4 indexLower = index.lowerVec(); + ivec4 indexUpper = index.upperVec(); + fvec4 t1(&ewaldScaleTable[indexLower[0]]); + fvec4 t2(&ewaldScaleTable[indexLower[1]]); + fvec4 t3(&ewaldScaleTable[indexLower[2]]); + fvec4 t4(&ewaldScaleTable[indexLower[3]]); + fvec4 t5(&ewaldScaleTable[indexUpper[0]]); + fvec4 t6(&ewaldScaleTable[indexUpper[1]]); + fvec4 t7(&ewaldScaleTable[indexUpper[2]]); + fvec4 t8(&ewaldScaleTable[indexUpper[3]]); + fvec8 s1, s2, s3, s4; + transpose(t1, t2, t3, t4, t5, t6, t7, t8, s1, s2, s3, s4); + return coeff1*s1 + coeff2*s2; +} +#endif -- GitLab From fa28374438f92c915085de356ad6a941024fca3e Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 1 Dec 2014 16:11:21 -0800 Subject: [PATCH 147/338] Updated API and documentation to permit triclinic boxes --- docs-source/usersguide/theory.rst | 55 +++++++++++++++++++ openmmapi/include/openmm/Context.h | 5 +- openmmapi/include/openmm/System.h | 8 +-- .../include/openmm/internal/ContextImpl.h | 8 +-- openmmapi/src/ContextImpl.cpp | 9 +-- openmmapi/src/System.cpp | 9 +-- 6 files changed, 74 insertions(+), 20 deletions(-) diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index 6322a18ae..17dabd748 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -1261,6 +1261,61 @@ Other Features ############## +Periodic Boundary Conditions +**************************** + +Many Force objects support periodic boundary conditions. They act as if space +were tiled with infinitely repeating copies of the system, then compute the +forces acting on a single copy based on the infinite periodic copies. In most +(but not all) cases, they apply a cutoff so that each particle only interacts +with a single copy of each other particle. + +OpenMM supports triclinic periodic boxes. This means the periodicity is defined +by three vectors, :math:`\mathbf{a}`\ , :math:`\mathbf{b}`\ , and +:math:`\mathbf{c}`\ . Given a particle position, the infinite periodic copies +of that particle are generated by adding vectors of the form +:math:`i \mathbf{a}+j \mathbf{b}+k \mathbf{c}`\ , where :math:`i`\ , +:math:`j`\ , and :math:`k` are arbitrary integers. + +The periodic box vectors must be chosen to satisfy certain requirements. +Roughly speaking, :math:`\mathbf{a}`\ , :math:`\mathbf{b}`\ , and +:math:`\mathbf{c}` need to "mostly" correspond to the x, y, and z axes. They +must have the form + +.. math:: + \mathbf{a} = (a_x, 0, 0) + + \mathbf{b} = (b_x, b_y, 0) + + \mathbf{c} = (c_x, c_y, c_z) + +It is always possible to put the box vectors into this form by rotating the +system until :math:`\mathbf{a}` is parallel to x and :math:`\mathbf{b}` lies in +the xy plane. + +Furthermore, they must obey the following constraints: + +.. math:: + a_x > 0, b_y > 0, c_z > 0 + + a_x \ge 2 |b_x| + + a_x \ge 2 |c_x| + + b_y \ge 2 |c_y| + +This effectively requires the box vectors to be specified in a particular +reduced form. By forming combinations of box vectors (a process known as +"lattice reduction"), it is always possible to put them in this form without +changing the periodic system they represent. + +These requirements have an important consequence: the periodic unit cell can +always be treated as an axis-aligned rectangular box of size +:math:`(a_x, b_y, c_z)`\ . The remaining non-zero elements of the box vectors +cause the repeating copies of the system to be staggered relative to each other, +but they do not affect the shape or size of each copy. The volume of the unit +cell is simply given by :math:`a_x b_y c_z`\ . + LocalEnergyMinimizer ******************** diff --git a/openmmapi/include/openmm/Context.h b/openmmapi/include/openmm/Context.h index caa00b785..48404714d 100644 --- a/openmmapi/include/openmm/Context.h +++ b/openmmapi/include/openmm/Context.h @@ -182,8 +182,9 @@ public: * Set the vectors defining the axes of the periodic box (measured in nm). They will affect * any Force that uses periodic boundary conditions. * - * Currently, only rectangular boxes are supported. This means that a, b, and c must be aligned with the - * x, y, and z axes respectively. Future releases may support arbitrary triclinic boxes. + * Triclinic boxes are supported, but the vectors must satisfy certain requirements. In particular, + * a must point in the x direction, b must point "mostly" in the y direction, and c must point "mostly" + * in the z direction. See the documentation for details. * * @param a the vector defining the first edge of the periodic box * @param b the vector defining the second edge of the periodic box diff --git a/openmmapi/include/openmm/System.h b/openmmapi/include/openmm/System.h index 5704d2c41..bad9f8072 100644 --- a/openmmapi/include/openmm/System.h +++ b/openmmapi/include/openmm/System.h @@ -203,9 +203,6 @@ public: * created Context will have its box vectors set to these. They will affect * any Force added to the System that uses periodic boundary conditions. * - * Currently, only rectangular boxes are supported. This means that a, b, and c must be aligned with the - * x, y, and z axes respectively. Future releases may support arbitrary triclinic boxes. - * * @param a on exit, this contains the vector defining the first edge of the periodic box * @param b on exit, this contains the vector defining the second edge of the periodic box * @param c on exit, this contains the vector defining the third edge of the periodic box @@ -216,8 +213,9 @@ public: * created Context will have its box vectors set to these. They will affect * any Force added to the System that uses periodic boundary conditions. * - * Currently, only rectangular boxes are supported. This means that a, b, and c must be aligned with the - * x, y, and z axes respectively. Future releases may support arbitrary triclinic boxes. + * Triclinic boxes are supported, but the vectors must satisfy certain requirements. In particular, + * a must point in the x direction, b must point "mostly" in the y direction, and c must point "mostly" + * in the z direction. See the documentation for details. * * @param a the vector defining the first edge of the periodic box * @param b the vector defining the second edge of the periodic box diff --git a/openmmapi/include/openmm/internal/ContextImpl.h b/openmmapi/include/openmm/internal/ContextImpl.h index 6d6d4cdf2..a49f16752 100644 --- a/openmmapi/include/openmm/internal/ContextImpl.h +++ b/openmmapi/include/openmm/internal/ContextImpl.h @@ -142,9 +142,6 @@ public: * Get the vectors defining the axes of the periodic box (measured in nm). They will affect * any Force that uses periodic boundary conditions. * - * Currently, only rectangular boxes are supported. This means that a, b, and c must be aligned with the - * x, y, and z axes respectively. Future releases may support arbitrary triclinic boxes. - * * @param a the vector defining the first edge of the periodic box * @param b the vector defining the second edge of the periodic box * @param c the vector defining the third edge of the periodic box @@ -154,8 +151,9 @@ public: * Set the vectors defining the axes of the periodic box (measured in nm). They will affect * any Force that uses periodic boundary conditions. * - * Currently, only rectangular boxes are supported. This means that a, b, and c must be aligned with the - * x, y, and z axes respectively. Future releases may support arbitrary triclinic boxes. + * Triclinic boxes are supported, but the vectors must satisfy certain requirements. In particular, + * a must point in the x direction, b must point "mostly" in the y direction, and c must point "mostly" + * in the z direction. See the documentation for details. * * @param a the vector defining the first edge of the periodic box * @param b the vector defining the second edge of the periodic box diff --git a/openmmapi/src/ContextImpl.cpp b/openmmapi/src/ContextImpl.cpp index 153a74413..dfc98328e 100644 --- a/openmmapi/src/ContextImpl.cpp +++ b/openmmapi/src/ContextImpl.cpp @@ -40,6 +40,7 @@ #include "openmm/VirtualSite.h" #include "openmm/Context.h" #include +#include #include #include #include @@ -235,10 +236,10 @@ void ContextImpl::getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) { void ContextImpl::setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) { if (a[1] != 0.0 || a[2] != 0.0) throw OpenMMException("First periodic box vector must be parallel to x."); - if (b[0] != 0.0 || b[2] != 0.0) - throw OpenMMException("Second periodic box vector must be parallel to y."); - if (c[0] != 0.0 || c[1] != 0.0) - throw OpenMMException("Third periodic box vector must be parallel to z."); + if (b[2] != 0.0) + throw OpenMMException("Second periodic box vector must be in the x-y plane."); + if (a[0] <= 0.0 || b[1] <= 0.0 || c[2] <= 0.0 || a[0] < 2*fabs(b[0]) || a[0] < 2*fabs(c[0]) || b[1] < 2*fabs(c[1])) + throw OpenMMException("Periodic box vectors must be in reduced form."); updateStateDataKernel.getAs().setPeriodicBoxVectors(*this, a, b, c); } diff --git a/openmmapi/src/System.cpp b/openmmapi/src/System.cpp index 766a74222..c8f366b3a 100644 --- a/openmmapi/src/System.cpp +++ b/openmmapi/src/System.cpp @@ -34,6 +34,7 @@ #include "openmm/System.h" #include "openmm/VirtualSite.h" #include "openmm/internal/AssertionUtilities.h" +#include using namespace OpenMM; @@ -111,10 +112,10 @@ void System::getDefaultPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) const { void System::setDefaultPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) { if (a[1] != 0.0 || a[2] != 0.0) throw OpenMMException("First periodic box vector must be parallel to x."); - if (b[0] != 0.0 || b[2] != 0.0) - throw OpenMMException("Second periodic box vector must be parallel to y."); - if (c[0] != 0.0 || c[1] != 0.0) - throw OpenMMException("Third periodic box vector must be parallel to z."); + if (b[2] != 0.0) + throw OpenMMException("Second periodic box vector must be in the x-y plane."); + if (a[0] <= 0.0 || b[1] <= 0.0 || c[2] <= 0.0 || a[0] < 2*fabs(b[0]) || a[0] < 2*fabs(c[0]) || b[1] < 2*fabs(c[1])) + throw OpenMMException("Periodic box vectors must be in reduced form."); periodicBoxVectors[0] = a; periodicBoxVectors[1] = b; periodicBoxVectors[2] = c; -- GitLab From e2977b9131eb403723856fc7b1de1441a938300a Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 2 Dec 2014 14:33:50 -0800 Subject: [PATCH 148/338] Began implementing triclinic boxes in reference platform --- platforms/reference/include/ReferenceForce.h | 21 +++-- .../reference/include/ReferenceLJCoulombIxn.h | 6 +- .../reference/include/ReferenceNeighborList.h | 6 +- .../reference/include/ReferencePlatform.h | 1 + platforms/reference/src/ReferenceKernels.cpp | 29 ++++--- platforms/reference/src/ReferencePlatform.cpp | 2 + .../src/SimTKReference/ReferenceForce.cpp | 86 +++---------------- .../SimTKReference/ReferenceLJCoulombIxn.cpp | 25 +++--- .../SimTKReference/ReferenceNeighborList.cpp | 82 +++++++----------- .../tests/TestReferenceNeighborList.cpp | 18 ++-- .../tests/TestReferenceNonbondedForce.cpp | 65 ++++++++++++++ .../reference/src/AmoebaReferenceKernels.cpp | 7 +- 12 files changed, 179 insertions(+), 169 deletions(-) diff --git a/platforms/reference/include/ReferenceForce.h b/platforms/reference/include/ReferenceForce.h index 16c9b0a7a..200ab66fb 100644 --- a/platforms/reference/include/ReferenceForce.h +++ b/platforms/reference/include/ReferenceForce.h @@ -24,6 +24,7 @@ #ifndef __ReferenceForce_H__ #define __ReferenceForce_H__ +#include "RealVec.h" #include "lepton/CompiledExpression.h" #include "openmm/internal/windowsExport.h" @@ -97,18 +98,20 @@ class OPENMM_EXPORT ReferenceForce { static void getDeltaRPeriodic( const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, const RealOpenMM* boxSize, RealOpenMM* deltaR ); - /**--------------------------------------------------------------------------------------- - - Get deltaR between atomI and atomJ (static method): deltaR: j - i - + /**--------------------------------------------------------------------------------------- + + Get deltaR and distance and distance**2 between atomI and atomJ, assuming periodic + boundary conditions (static method); deltaR: j - i + @param atomCoordinatesI atom i coordinates @param atomCoordinatesI atom j coordinates - @param deltaR deltaX, deltaY, deltaZ upon return - + @param boxVectors the vectors defining the periodic box + @param deltaR deltaX, deltaY, deltaZ, R2, R upon return + --------------------------------------------------------------------------------------- */ - - static void getDeltaROnly( const RealOpenMM* atomCoordinatesI, const RealOpenMM* atomCoordinatesJ, - RealOpenMM* deltaR ); + + static void getDeltaRPeriodic( const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, + const OpenMM::RealVec* boxVectors, RealOpenMM* deltaR ); /** * Get a pointer to the memory for setting a variable in a CompiledExpression. If the expression diff --git a/platforms/reference/include/ReferenceLJCoulombIxn.h b/platforms/reference/include/ReferenceLJCoulombIxn.h index 8887f1dfe..dce5bd55b 100644 --- a/platforms/reference/include/ReferenceLJCoulombIxn.h +++ b/platforms/reference/include/ReferenceLJCoulombIxn.h @@ -40,7 +40,7 @@ class ReferenceLJCoulombIxn { bool ewald; bool pme; const OpenMM::NeighborList* neighborList; - RealOpenMM periodicBoxSize[3]; + OpenMM::RealVec periodicBoxVectors[3]; RealOpenMM cutoffDistance, switchingDistance; RealOpenMM krf, crf; RealOpenMM alphaEwald; @@ -118,11 +118,11 @@ class ReferenceLJCoulombIxn { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic( OpenMM::RealVec& boxSize ); + void setPeriodic(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceNeighborList.h b/platforms/reference/include/ReferenceNeighborList.h index 7c3a76930..0e36f96b0 100644 --- a/platforms/reference/include/ReferenceNeighborList.h +++ b/platforms/reference/include/ReferenceNeighborList.h @@ -22,7 +22,7 @@ void OPENMM_EXPORT computeNeighborListNaive( int nAtoms, const AtomLocationList& atomLocations, const std::vector >& exclusions, - const RealVec& periodicBoxSize, + const RealVec* periodicBoxVectors, bool usePeriodic, double maxDistance, double minDistance = 0.0, @@ -35,9 +35,9 @@ void OPENMM_EXPORT computeNeighborListNaive( void OPENMM_EXPORT computeNeighborListVoxelHash( NeighborList& neighborList, int nAtoms, - const AtomLocationList& atomLocations, + const AtomLocationList& atomLocations, const std::vector >& exclusions, - const RealVec& periodicBoxSize, + const RealVec* periodicBoxVectors, bool usePeriodic, double maxDistance, double minDistance = 0.0, diff --git a/platforms/reference/include/ReferencePlatform.h b/platforms/reference/include/ReferencePlatform.h index 99d056f93..ff50ae79a 100644 --- a/platforms/reference/include/ReferencePlatform.h +++ b/platforms/reference/include/ReferencePlatform.h @@ -66,6 +66,7 @@ public: void* velocities; void* forces; void* periodicBoxSize; + void* periodicBoxVectors; void* constraints; }; } // namespace OpenMM diff --git a/platforms/reference/src/ReferenceKernels.cpp b/platforms/reference/src/ReferenceKernels.cpp index ffb5942af..86570ae00 100644 --- a/platforms/reference/src/ReferenceKernels.cpp +++ b/platforms/reference/src/ReferenceKernels.cpp @@ -134,6 +134,11 @@ static RealVec& extractBoxSize(ContextImpl& context) { return *(RealVec*) data->periodicBoxSize; } +static RealVec* extractBoxVectors(ContextImpl& context) { + ReferencePlatform::PlatformData* data = reinterpret_cast(context.getPlatformData()); + return (RealVec*) data->periodicBoxVectors; +} + static ReferenceConstraints& extractConstraints(ContextImpl& context) { ReferencePlatform::PlatformData* data = reinterpret_cast(context.getPlatformData()); return *(ReferenceConstraints*) data->constraints; @@ -256,10 +261,10 @@ void ReferenceUpdateStateDataKernel::getForces(ContextImpl& context, std::vector } void ReferenceUpdateStateDataKernel::getPeriodicBoxVectors(ContextImpl& context, Vec3& a, Vec3& b, Vec3& c) const { - RealVec& box = extractBoxSize(context); - a = Vec3(box[0], 0, 0); - b = Vec3(0, box[1], 0); - c = Vec3(0, 0, box[2]); + RealVec* vectors = extractBoxVectors(context); + a = vectors[0]; + b = vectors[1]; + c = vectors[2]; } void ReferenceUpdateStateDataKernel::setPeriodicBoxVectors(ContextImpl& context, const Vec3& a, const Vec3& b, const Vec3& c) const { @@ -267,6 +272,10 @@ void ReferenceUpdateStateDataKernel::setPeriodicBoxVectors(ContextImpl& context, box[0] = (RealOpenMM) a[0]; box[1] = (RealOpenMM) b[1]; box[2] = (RealOpenMM) c[2]; + RealVec* vectors = extractBoxVectors(context); + vectors[0] = a; + vectors[1] = b; + vectors[2] = c; } void ReferenceUpdateStateDataKernel::createCheckpoint(ContextImpl& context, ostream& stream) { @@ -854,15 +863,15 @@ double ReferenceCalcNonbondedForceKernel::execute(ContextImpl& context, bool inc bool ewald = (nonbondedMethod == Ewald); bool pme = (nonbondedMethod == PME); if (nonbondedMethod != NoCutoff) { - computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxSize(context), periodic || ewald || pme, nonbondedCutoff, 0.0); + computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxVectors(context), periodic || ewald || pme, nonbondedCutoff, 0.0); clj.setUseCutoff(nonbondedCutoff, *neighborList, rfDielectric); } if (periodic || ewald || pme) { - RealVec& box = extractBoxSize(context); + RealVec* vectors = extractBoxVectors(context); double minAllowedSize = 1.999999*nonbondedCutoff; - if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize) + if (vectors[0][0] < minAllowedSize || vectors[1][1] < minAllowedSize || vectors[2][2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - clj.setPeriodic(box); + clj.setPeriodic(vectors); } if (ewald) clj.setUseEwald(ewaldAlpha, kmax[0], kmax[1], kmax[2]); @@ -1018,7 +1027,7 @@ double ReferenceCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bo ReferenceCustomNonbondedIxn ixn(energyExpression, forceExpression, parameterNames); bool periodic = (nonbondedMethod == CutoffPeriodic); if (nonbondedMethod != NoCutoff) { - computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxSize(context), periodic, nonbondedCutoff, 0.0); + computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxVectors(context), periodic, nonbondedCutoff, 0.0); ixn.setUseCutoff(nonbondedCutoff, *neighborList); } if (periodic) { @@ -1322,7 +1331,7 @@ double ReferenceCalcCustomGBForceKernel::execute(ContextImpl& context, bool incl if (periodic) ixn.setPeriodic(extractBoxSize(context)); if (nonbondedMethod != NoCutoff) { - computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxSize(context), periodic, nonbondedCutoff, 0.0); + computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxVectors(context), periodic, nonbondedCutoff, 0.0); ixn.setUseCutoff(nonbondedCutoff, *neighborList); } map globalParameters; diff --git a/platforms/reference/src/ReferencePlatform.cpp b/platforms/reference/src/ReferencePlatform.cpp index 2374da40f..190efec35 100644 --- a/platforms/reference/src/ReferencePlatform.cpp +++ b/platforms/reference/src/ReferencePlatform.cpp @@ -97,6 +97,7 @@ ReferencePlatform::PlatformData::PlatformData(const System& system) : time(0.0), velocities = new vector(numParticles); forces = new vector(numParticles); periodicBoxSize = new RealVec(); + periodicBoxVectors = new RealVec[3]; constraints = new ReferenceConstraints(system); } @@ -105,5 +106,6 @@ ReferencePlatform::PlatformData::~PlatformData() { delete (vector*) velocities; delete (vector*) forces; delete (RealVec*) periodicBoxSize; + delete[] (RealVec*) periodicBoxVectors; delete (ReferenceConstraints*) constraints; } diff --git a/platforms/reference/src/SimTKReference/ReferenceForce.cpp b/platforms/reference/src/SimTKReference/ReferenceForce.cpp index 43265634e..7718e66cb 100644 --- a/platforms/reference/src/SimTKReference/ReferenceForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceForce.cpp @@ -41,13 +41,6 @@ using OpenMM::RealVec; --------------------------------------------------------------------------------------- */ ReferenceForce::ReferenceForce( ){ - - // --------------------------------------------------------------------------------------- - - // static const char* methodName = "\nReferenceForce::ReferenceForce"; - - // --------------------------------------------------------------------------------------- - } /**--------------------------------------------------------------------------------------- @@ -57,13 +50,6 @@ ReferenceForce::ReferenceForce( ){ --------------------------------------------------------------------------------------- */ ReferenceForce::~ReferenceForce( ){ - - // --------------------------------------------------------------------------------------- - - // static const char* methodName = "\nReferenceForce::~ReferenceForce"; - - // --------------------------------------------------------------------------------------- - } /**--------------------------------------------------------------------------------------- @@ -79,27 +65,8 @@ RealOpenMM ReferenceForce::periodicDifference(RealOpenMM val1, RealOpenMM val2, } - -/**--------------------------------------------------------------------------------------- - - Get deltaR and distance and distance**2 between atomI and atomJ (static method) - deltaR: j - i - - @param atomCoordinatesI atom i coordinates - @param atomCoordinatesI atom j coordinates - @param deltaR deltaX, deltaY, deltaZ, R2, R upon return - - --------------------------------------------------------------------------------------- */ - void ReferenceForce::getDeltaR( const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, RealOpenMM* deltaR ){ - - // --------------------------------------------------------------------------------------- - - // static const std::string methodName = "\nReferenceForce::getDeltaR"; - - // --------------------------------------------------------------------------------------- - deltaR[XIndex] = atomCoordinatesJ[0] - atomCoordinatesI[0]; deltaR[YIndex] = atomCoordinatesJ[1] - atomCoordinatesI[1]; deltaR[ZIndex] = atomCoordinatesJ[2] - atomCoordinatesI[2]; @@ -108,27 +75,8 @@ void ReferenceForce::getDeltaR( const RealVec& atomCoordinatesI, const RealVec& deltaR[RIndex] = (RealOpenMM) SQRT( deltaR[R2Index] ); } -/**--------------------------------------------------------------------------------------- - - Get deltaR and distance and distance**2 between atomI and atomJ, assuming periodic - boundary conditions (static method); deltaR: j - i - - @param atomCoordinatesI atom i coordinates - @param atomCoordinatesI atom j coordinates - @param boxSize X, Y, and Z sizes of the periodic box - @param deltaR deltaX, deltaY, deltaZ, R2, R upon return - - --------------------------------------------------------------------------------------- */ - void ReferenceForce::getDeltaRPeriodic( const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, const RealOpenMM* boxSize, RealOpenMM* deltaR ){ - - // --------------------------------------------------------------------------------------- - - // static const std::string methodName = "\nReferenceForce::getDeltaR"; - - // --------------------------------------------------------------------------------------- - deltaR[XIndex] = periodicDifference(atomCoordinatesJ[0], atomCoordinatesI[0], boxSize[0]); deltaR[YIndex] = periodicDifference(atomCoordinatesJ[1], atomCoordinatesI[1], boxSize[1]); deltaR[ZIndex] = periodicDifference(atomCoordinatesJ[2], atomCoordinatesI[2], boxSize[2]); @@ -137,29 +85,17 @@ void ReferenceForce::getDeltaRPeriodic( const RealVec& atomCoordinatesI, const R deltaR[RIndex] = (RealOpenMM) SQRT( deltaR[R2Index] ); } -/**--------------------------------------------------------------------------------------- - - Get deltaR between atomI and atomJ (static method); deltaR: j - i - - @param atomCoordinatesI atom i coordinates - @param atomCoordinatesI atom j coordinates - @param deltaR deltaX, deltaY, deltaZ upon return - - --------------------------------------------------------------------------------------- */ - -void ReferenceForce::getDeltaROnly( const RealOpenMM* atomCoordinatesI, - const RealOpenMM* atomCoordinatesJ, - RealOpenMM* deltaR ){ - - // --------------------------------------------------------------------------------------- - - // static const std::string methodName = "\nReferenceForce::getDeltaR"; - - // --------------------------------------------------------------------------------------- - - deltaR[XIndex] = atomCoordinatesJ[0] - atomCoordinatesI[0]; - deltaR[YIndex] = atomCoordinatesJ[1] - atomCoordinatesI[1]; - deltaR[ZIndex] = atomCoordinatesJ[2] - atomCoordinatesI[2]; +void ReferenceForce::getDeltaRPeriodic( const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, + const RealVec* boxVectors, RealOpenMM* deltaR ){ + RealVec diff = atomCoordinatesJ-atomCoordinatesI; + diff -= boxVectors[2]*floor(diff[2]/boxVectors[2][2]+0.5); + diff -= boxVectors[1]*floor(diff[1]/boxVectors[1][1]+0.5); + diff -= boxVectors[0]*floor(diff[0]/boxVectors[0][0]+0.5); + deltaR[XIndex] = diff[0]; + deltaR[YIndex] = diff[1]; + deltaR[ZIndex] = diff[2]; + deltaR[R2Index] = diff.dot(diff); + deltaR[RIndex] = SQRT(deltaR[R2Index]); } double* ReferenceForce::getVariablePointer(Lepton::CompiledExpression& expression, const std::string& name) { diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp index ef2987c4f..988d8442b 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp @@ -112,20 +112,20 @@ void ReferenceLJCoulombIxn::setUseSwitchingFunction( RealOpenMM distance ) { also been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void ReferenceLJCoulombIxn::setPeriodic( RealVec& boxSize ) { + void ReferenceLJCoulombIxn::setPeriodic(OpenMM::RealVec* vectors) { assert(cutoff); - assert(boxSize[0] >= 2.0*cutoffDistance); - assert(boxSize[1] >= 2.0*cutoffDistance); - assert(boxSize[2] >= 2.0*cutoffDistance); + assert(vectors[0][0] >= 2.0*cutoffDistance); + assert(vectors[1][1] >= 2.0*cutoffDistance); + assert(vectors[2][2] >= 2.0*cutoffDistance); periodic = true; - periodicBoxSize[0] = boxSize[0]; - periodicBoxSize[1] = boxSize[1]; - periodicBoxSize[2] = boxSize[2]; + periodicBoxVectors[0] = vectors[0]; + periodicBoxVectors[1] = vectors[1]; + periodicBoxVectors[2] = vectors[2]; } /**--------------------------------------------------------------------------------------- @@ -197,7 +197,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector RealOpenMM factorEwald = -1 / (4*alphaEwald*alphaEwald); RealOpenMM SQRT_PI = sqrt(PI_M); RealOpenMM TWO_PI = 2.0 * PI_M; - RealOpenMM recipCoeff = (RealOpenMM)(ONE_4PI_EPS0*4*PI_M/(periodicBoxSize[0] * periodicBoxSize[1] * periodicBoxSize[2]) /epsilon); + RealOpenMM recipCoeff = (RealOpenMM)(ONE_4PI_EPS0*4*PI_M/(periodicBoxVectors[0][0] * periodicBoxVectors[1][1] * periodicBoxVectors[2][2]) /epsilon); RealOpenMM totalSelfEwaldEnergy = 0.0; RealOpenMM realSpaceEwaldEnergy = 0.0; @@ -237,6 +237,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector vector charges(numberOfAtoms); for (int i = 0; i < numberOfAtoms; i++) charges[i] = atomParameters[i][QIndex]; + RealOpenMM periodicBoxSize[] = {periodicBoxVectors[0][0], periodicBoxVectors[1][1], periodicBoxVectors[2][2]}; pme_exec(pmedata,atomCoordinates,forces,charges,periodicBoxSize,&recipEnergy,virial); if( totalEnergy ) @@ -255,7 +256,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector // setup reciprocal box - RealOpenMM recipBoxSize[3] = { TWO_PI / periodicBoxSize[0], TWO_PI / periodicBoxSize[1], TWO_PI / periodicBoxSize[2]}; + RealOpenMM recipBoxSize[3] = { TWO_PI / periodicBoxVectors[0][0], TWO_PI / periodicBoxVectors[1][1], TWO_PI / periodicBoxVectors[2][2]}; // setup K-vectors @@ -370,7 +371,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector int jj = pair.second; RealOpenMM deltaR[2][ReferenceForce::LastDeltaRIndex]; - ReferenceForce::getDeltaRPeriodic( atomCoordinates[jj], atomCoordinates[ii], periodicBoxSize, deltaR[0] ); + ReferenceForce::getDeltaRPeriodic( atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR[0] ); RealOpenMM r = deltaR[0][ReferenceForce::RIndex]; RealOpenMM inverseR = one/(deltaR[0][ReferenceForce::RIndex]); RealOpenMM switchValue = 1, switchDeriv = 0; @@ -556,7 +557,7 @@ void ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, vector& at // get deltaR, R2, and R between 2 atoms if (periodic) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[jj], atomCoordinates[ii], periodicBoxSize, deltaR[0] ); + ReferenceForce::getDeltaRPeriodic( atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR[0] ); else ReferenceForce::getDeltaR( atomCoordinates[jj], atomCoordinates[ii], deltaR[0] ); diff --git a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp index 154541f24..5076ba385 100644 --- a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp @@ -12,26 +12,15 @@ namespace OpenMM { typedef std::vector AtomList; -static double periodicDifference(double val1, double val2, double period) { - double diff = val1-val2; - double base = floor(diff/period+0.5)*period; - return diff-base; -} - // squared distance between two points -static double compPairDistanceSquared(const RealVec& pos1, const RealVec& pos2, const RealVec& periodicBoxSize, bool usePeriodic) { - double dx, dy, dz; - if (!usePeriodic) { - dx = pos2[0] - pos1[0]; - dy = pos2[1] - pos1[1]; - dz = pos2[2] - pos1[2]; - } - else { - dx = periodicDifference(pos2[0], pos1[0], periodicBoxSize[0]); - dy = periodicDifference(pos2[1], pos1[1], periodicBoxSize[1]); - dz = periodicDifference(pos2[2], pos1[2], periodicBoxSize[2]); +static double compPairDistanceSquared(const RealVec& pos1, const RealVec& pos2, const RealVec* periodicBoxVectors, bool usePeriodic) { + RealVec diff = pos2-pos1; + if (usePeriodic) { + diff -= periodicBoxVectors[2]*floor(diff[2]/periodicBoxVectors[2][2]+0.5); + diff -= periodicBoxVectors[1]*floor(diff[1]/periodicBoxVectors[1][1]+0.5); + diff -= periodicBoxVectors[0]*floor(diff[0]/periodicBoxVectors[0][0]+0.5); } - return dx*dx + dy*dy + dz*dz; + return diff.dot(diff); } // Ridiculous O(n^2) version of neighbor list @@ -41,7 +30,7 @@ void OPENMM_EXPORT computeNeighborListNaive( int nAtoms, const AtomLocationList& atomLocations, const vector >& exclusions, - const RealVec& periodicBoxSize, + const RealVec* periodicBoxVectors, bool usePeriodic, double maxDistance, double minDistance, @@ -55,7 +44,7 @@ void OPENMM_EXPORT computeNeighborListNaive( { for (AtomIndex atomJ = atomI + 1; atomJ < (AtomIndex) nAtoms; ++atomJ) { - double pairDistanceSquared = compPairDistanceSquared(atomLocations[atomI], atomLocations[atomJ], periodicBoxSize, usePeriodic); + double pairDistanceSquared = compPairDistanceSquared(atomLocations[atomI], atomLocations[atomJ], periodicBoxVectors, usePeriodic); if ( (pairDistanceSquared <= maxDistanceSquared) && (pairDistanceSquared >= minDistanceSquared)) if (exclusions[atomI].find(atomJ) == exclusions[atomI].end()) { @@ -95,15 +84,15 @@ typedef std::vector< VoxelItem > Voxel; class VoxelHash { public: - VoxelHash(double vsx, double vsy, double vsz, const RealVec& periodicBoxSize, bool usePeriodic) : - voxelSizeX(vsx), voxelSizeY(vsy), voxelSizeZ(vsz), periodicBoxSize(periodicBoxSize), usePeriodic(usePeriodic) { + VoxelHash(double vsx, double vsy, double vsz, const RealVec* periodicBoxVectors, bool usePeriodic) : + voxelSizeX(vsx), voxelSizeY(vsy), voxelSizeZ(vsz), periodicBoxVectors(periodicBoxVectors), usePeriodic(usePeriodic) { if (usePeriodic) { - nx = (int) floor(periodicBoxSize[0]/voxelSizeX+0.5); - ny = (int) floor(periodicBoxSize[1]/voxelSizeY+0.5); - nz = (int) floor(periodicBoxSize[2]/voxelSizeZ+0.5); - voxelSizeX = periodicBoxSize[0]/nx; - voxelSizeY = periodicBoxSize[1]/ny; - voxelSizeZ = periodicBoxSize[2]/nz; + nx = (int) floor(periodicBoxVectors[0][0]/voxelSizeX+0.5); + ny = (int) floor(periodicBoxVectors[1][1]/voxelSizeY+0.5); + nz = (int) floor(periodicBoxVectors[2][2]/voxelSizeZ+0.5); + voxelSizeX = periodicBoxVectors[0][0]/nx; + voxelSizeY = periodicBoxVectors[1][1]/ny; + voxelSizeZ = periodicBoxVectors[2][2]/nz; } } @@ -118,20 +107,15 @@ public: VoxelIndex getVoxelIndex(const RealVec& location) const { - double xperiodic, yperiodic, zperiodic; - if (!usePeriodic) { - xperiodic = location[0]; - yperiodic = location[1]; - zperiodic = location[2]; - } - else { - xperiodic = location[0]-periodicBoxSize[0]*floor(location[0]/periodicBoxSize[0]); - yperiodic = location[1]-periodicBoxSize[1]*floor(location[1]/periodicBoxSize[1]); - zperiodic = location[2]-periodicBoxSize[2]*floor(location[2]/periodicBoxSize[2]); + RealVec r = location; + if (usePeriodic) { + r -= periodicBoxVectors[2]*floor(r[2]/periodicBoxVectors[2][2]); + r -= periodicBoxVectors[1]*floor(r[1]/periodicBoxVectors[1][1]); + r -= periodicBoxVectors[0]*floor(r[0]/periodicBoxVectors[0][0]); } - int x = int(floor(xperiodic / voxelSizeX)); - int y = int(floor(yperiodic / voxelSizeY)); - int z = int(floor(zperiodic / voxelSizeZ)); + int x = int(floor(r[0]/voxelSizeX)); + int y = int(floor(r[1]/voxelSizeY)); + int z = int(floor(r[2]/voxelSizeZ)); return VoxelIndex(x, y, z); } @@ -194,7 +178,7 @@ public: // Ignore self hits if (atomI == atomJ) continue; - double dSquared = compPairDistanceSquared(locationI, locationJ, periodicBoxSize, usePeriodic); + double dSquared = compPairDistanceSquared(locationI, locationJ, periodicBoxVectors, usePeriodic); if (dSquared > maxDistanceSquared) continue; if (dSquared < minDistanceSquared) continue; @@ -213,7 +197,7 @@ public: private: double voxelSizeX, voxelSizeY, voxelSizeZ; int nx, ny, nz; - const RealVec& periodicBoxSize; + const RealVec* periodicBoxVectors; const bool usePeriodic; std::map voxelMap; }; @@ -223,9 +207,9 @@ private: void OPENMM_EXPORT computeNeighborListVoxelHash( NeighborList& neighborList, int nAtoms, - const AtomLocationList& atomLocations, + const AtomLocationList& atomLocations, const vector >& exclusions, - const RealVec& periodicBoxSize, + const RealVec* periodicBoxVectors, bool usePeriodic, double maxDistance, double minDistance, @@ -238,11 +222,11 @@ void OPENMM_EXPORT computeNeighborListVoxelHash( if (!usePeriodic) edgeSizeX = edgeSizeY = edgeSizeZ = maxDistance; // TODO - adjust this as needed else { - edgeSizeX = 0.5*periodicBoxSize[0]/floor(periodicBoxSize[0]/maxDistance); - edgeSizeY = 0.5*periodicBoxSize[1]/floor(periodicBoxSize[1]/maxDistance); - edgeSizeZ = 0.5*periodicBoxSize[2]/floor(periodicBoxSize[2]/maxDistance); + edgeSizeX = 0.5*periodicBoxVectors[0][0]/floor(periodicBoxVectors[0][0]/maxDistance); + edgeSizeY = 0.5*periodicBoxVectors[1][1]/floor(periodicBoxVectors[1][1]/maxDistance); + edgeSizeZ = 0.5*periodicBoxVectors[2][2]/floor(periodicBoxVectors[2][2]/maxDistance); } - VoxelHash voxelHash(edgeSizeX, edgeSizeY, edgeSizeZ, periodicBoxSize, usePeriodic); + VoxelHash voxelHash(edgeSizeX, edgeSizeY, edgeSizeZ, periodicBoxVectors, usePeriodic); for (AtomIndex atomJ = 0; atomJ < (AtomIndex) nAtoms; ++atomJ) // use "j", because j > i for pairs { // 1) Find other atoms that are close to this one diff --git a/platforms/reference/tests/TestReferenceNeighborList.cpp b/platforms/reference/tests/TestReferenceNeighborList.cpp index 62c2746f7..f82cd45b0 100644 --- a/platforms/reference/tests/TestReferenceNeighborList.cpp +++ b/platforms/reference/tests/TestReferenceNeighborList.cpp @@ -48,17 +48,17 @@ void testNeighborList() NeighborList neighborList; - RealVec boxSize; - computeNeighborListNaive(neighborList, 2, particleList, exclusions, boxSize, false, 13.7, 0.01); + RealVec boxVectors[3]; + computeNeighborListNaive(neighborList, 2, particleList, exclusions, boxVectors, false, 13.7, 0.01); assert(neighborList.size() == 1); - computeNeighborListNaive(neighborList, 2, particleList, exclusions, boxSize, false, 13.5, 0.01); + computeNeighborListNaive(neighborList, 2, particleList, exclusions, boxVectors, false, 13.5, 0.01); assert(neighborList.size() == 0); - computeNeighborListVoxelHash(neighborList, 2, particleList, exclusions, boxSize, false, 13.7, 0.01); + computeNeighborListVoxelHash(neighborList, 2, particleList, exclusions, boxVectors, false, 13.7, 0.01); assert(neighborList.size() == 1); - computeNeighborListVoxelHash(neighborList, 2, particleList, exclusions, boxSize, false, 13.5, 0.01); + computeNeighborListVoxelHash(neighborList, 2, particleList, exclusions, boxVectors, false, 13.5, 0.01); assert(neighborList.size() == 0); } @@ -93,6 +93,10 @@ void testPeriodic() { const int numParticles = 100; const double cutoff = 3.0; const RealVec periodicBoxSize(20.0, 15.0, 22.0); + RealVec periodicBoxVectors[3]; + periodicBoxVectors[0] = RealVec(20, 0, 0); + periodicBoxVectors[1] = RealVec(0, 15, 0); + periodicBoxVectors[2] = RealVec(0, 0, 22); vector particleList(numParticles); OpenMM_SFMT::SFMT sfmt; init_gen_rand(0, sfmt); @@ -104,9 +108,9 @@ void testPeriodic() { } vector > exclusions(numParticles); NeighborList neighborList; - computeNeighborListNaive(neighborList, numParticles, particleList, exclusions, periodicBoxSize, true, cutoff); + computeNeighborListNaive(neighborList, numParticles, particleList, exclusions, periodicBoxVectors, true, cutoff); verifyNeighborList(neighborList, numParticles, particleList, periodicBoxSize, cutoff); - computeNeighborListVoxelHash(neighborList, numParticles, particleList, exclusions, periodicBoxSize, true, cutoff); + computeNeighborListVoxelHash(neighborList, numParticles, particleList, exclusions, periodicBoxVectors, true, cutoff); verifyNeighborList(neighborList, numParticles, particleList, periodicBoxSize, cutoff); } diff --git a/platforms/reference/tests/TestReferenceNonbondedForce.cpp b/platforms/reference/tests/TestReferenceNonbondedForce.cpp index 9e1e00d2f..50018cd68 100644 --- a/platforms/reference/tests/TestReferenceNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceNonbondedForce.cpp @@ -41,6 +41,7 @@ #include "openmm/VerletIntegrator.h" #include "SimTKOpenMMRealType.h" #include "openmm/HarmonicBondForce.h" +#include "sfmt/SFMT.h" #include #include @@ -351,6 +352,69 @@ void testPeriodic() { ASSERT_EQUAL_TOL(2*ONE_4PI_EPS0*(1.0)*(1.0+krf*1.0-crf), state.getPotentialEnergy(), TOL); } +void testTriclinic() { + ReferencePlatform platform; + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + NonbondedForce* nonbonded = new NonbondedForce(); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + const double eps = 78.3; + const double krf = (1.0/(cutoff*cutoff*cutoff))*(eps-1.0)/(2.0*eps+1.0); + const double crf = (1.0/cutoff)*(3.0*eps)/(2.0*eps+1.0); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta*ONE_4PI_EPS0*(-1.0/(distance*distance*distance)+2.0*krf); + ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(1.0/distance+krf*distance*distance-crf), state.getPotentialEnergy(), TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} + void testDispersionCorrection() { // Create a box full of identical particles. @@ -483,6 +547,7 @@ int main() { testCutoff(); testCutoff14(); testPeriodic(); + testTriclinic(); testDispersionCorrection(); testSwitchingFunction(NonbondedForce::CutoffNonPeriodic); testSwitchingFunction(NonbondedForce::PME); diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp index 5ce7d620a..dc6114c89 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp @@ -74,6 +74,11 @@ static RealVec& extractBoxSize(ContextImpl& context) { return *(RealVec*) data->periodicBoxSize; } +static RealVec* extractBoxVectors(ContextImpl& context) { + ReferencePlatform::PlatformData* data = reinterpret_cast(context.getPlatformData()); + return (RealVec*) data->periodicBoxVectors; +} + // *************************************************************************** ReferenceCalcAmoebaBondForceKernel::ReferenceCalcAmoebaBondForceKernel(std::string name, const Platform& platform, const System& system) : @@ -968,7 +973,7 @@ double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool inc RealOpenMM energy; if( useCutoff ){ vdwForce.setCutoff( cutoff ); - computeNeighborListVoxelHash( *neighborList, numParticles, posData, allExclusions, extractBoxSize(context), usePBC, cutoff, 0.0); + computeNeighborListVoxelHash( *neighborList, numParticles, posData, allExclusions, extractBoxVectors(context), usePBC, cutoff, 0.0); if( usePBC ){ vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::CutoffPeriodic); RealVec& box = extractBoxSize(context); -- GitLab From 4fcf2b166241b8cb6defb65b12cf68c813c7ab13 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Tue, 2 Dec 2014 15:55:42 -0800 Subject: [PATCH 149/338] Modified packaging scripts so that we no longer install Python into lib. --- devtools/packaging/scripts/linux/build.sh | 10 ---------- devtools/packaging/scripts/osx/build.sh | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index 4ca240548..f84b07bc2 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -38,13 +38,3 @@ cd build cmake ../openmm $CMAKE_FLAGS make -j4 all DoxygenApiDocs sphinxpdf make install - -# Install Python wrappers. -export OPENMM_INCLUDE_PATH=$INSTALL/include -export OPENMM_LIB_PATH=$INSTALL/lib -cd python -python setup.py install --prefix=$INSTALL -cd ../.. - -# Copy all tests to bin directory so they will be distributed with install package. -#cp `find . -name "Test*" -type f -maxdepth 1` $PREFIX/bin diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index 8fc4e15da..e969bb70b 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -39,13 +39,3 @@ cd build cmake ../openmm $CMAKE_FLAGS make -j4 all DoxygenApiDocs sphinxpdf make install - -# Install Python wrappers. -export OPENMM_INCLUDE_PATH=$INSTALL/include -export OPENMM_LIB_PATH=$INSTALL/lib -cd python -$PYTHON setup.py install --prefix=$INSTALL -cd ../.. - -# Copy all tests to bin directory so they will be distributed with install package. -#cp `find . -name "Test*" -type f -maxdepth 1` $PREFIX/bin -- GitLab From 74d6686921ed4e55e7fb6ed7af620fc65795dd1f Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Tue, 2 Dec 2014 17:21:59 -0800 Subject: [PATCH 150/338] Debugging issues with packaging script. --- devtools/packaging/scripts/linux/package.sh | 19 ++++++++++++++++++- devtools/packaging/scripts/osx/package.sh | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/devtools/packaging/scripts/linux/package.sh b/devtools/packaging/scripts/linux/package.sh index 407d3437f..8f052f290 100755 --- a/devtools/packaging/scripts/linux/package.sh +++ b/devtools/packaging/scripts/linux/package.sh @@ -9,16 +9,32 @@ export VERSION=$(sed -nr "s/OPENMM_VERSION:STRING=(.*)/\1/p" build/CMakeCache.tx export PACKAGE_SUBDIR="OpenMM-${VERSION}-Linux" # directory where distribution will be unpacked export DISTRO_PREFIX="OpenMM-${VERSION}-Linux" # prefix for source distribution (e.g. ${DISTRIBUTION_NAME}.zip) +# DEBUG +echo "DEBUG 1" +pwd +ls -ltr . +# END DEBUG + # Perform all work in a work directory. cd work +# DEBUG +echo "DEBUG 1" +pwd +ls -ltr . +# END DEBUG + # Clean up. rm -rf $PACKAGE_DIR # Make a directory to contain packaged source distribution +echo "DEBUG 3" mkdir $PACKAGE_DIR mkdir $PACKAGE_DIR/$PACKAGE_SUBDIR for filename in $( cat openmm/devtools/packaging/manifests/binary/manifest.txt ); do + # DEBUG: List contents of each directory. + ls -ltr install/$filename + # END DEBUG CMD="cp -r install/$filename $PACKAGE_DIR/$PACKAGE_SUBDIR" echo $CMD `$CMD` @@ -31,12 +47,13 @@ echo $CMD # Make Python source distribution. echo "Building Python source distribution..." +pushd . cd build make PythonSdist cd python/dist tar zxf OpenMM-${VERSION}.tar.gz mv OpenMM-${VERSION} python -cd ../../.. +popd cp -r build/python/dist/python $PACKAGE_DIR/$PACKAGE_SUBDIR # Create archives. diff --git a/devtools/packaging/scripts/osx/package.sh b/devtools/packaging/scripts/osx/package.sh index a5b0914c8..ce3ec74d0 100755 --- a/devtools/packaging/scripts/osx/package.sh +++ b/devtools/packaging/scripts/osx/package.sh @@ -28,12 +28,13 @@ echo $CMD # Make Python source distribution. echo "Building Python source distribution..." +pushd . cd build make PythonSdist cd python/dist tar zxf OpenMM-${VERSION}.tar.gz mv OpenMM-${VERSION} python -cd ../../.. +popd cp -r build/python/dist/python $PACKAGE_DIR/$PACKAGE_SUBDIR # Create archives. -- GitLab From 9e2b5a120b9b85832ad8e6f394a796fdef11b19e Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 2 Dec 2014 17:32:25 -0800 Subject: [PATCH 151/338] Continuing to implement triclinic boxes in reference platform --- .../src/MonteCarloAnisotropicBarostatImpl.cpp | 4 +- .../src/MonteCarloMembraneBarostatImpl.cpp | 4 +- platforms/reference/include/GBVIParameters.h | 8 +- platforms/reference/include/ObcParameters.h | 10 +-- .../reference/include/ReferenceCustomGBIxn.h | 6 +- .../include/ReferenceCustomHbondIxn.h | 6 +- .../include/ReferenceCustomManyParticleIxn.h | 6 +- .../include/ReferenceCustomNonbondedIxn.h | 6 +- .../include/ReferenceMonteCarloBarostat.h | 4 +- platforms/reference/src/ReferenceKernels.cpp | 48 ++++++------ .../SimTKReference/ReferenceCustomGBIxn.cpp | 22 +++--- .../ReferenceCustomHbondIxn.cpp | 18 ++--- .../ReferenceCustomManyParticleIxn.cpp | 16 ++-- .../ReferenceCustomNonbondedIxn.cpp | 18 ++--- .../ReferenceMonteCarloBarostat.cpp | 38 ++++----- .../reference/src/gbsa/GBVIParameters.cpp | 26 +++---- .../reference/src/gbsa/ObcParameters.cpp | 24 +++--- .../TestReferenceCustomNonbondedForce.cpp | 61 +++++++++++++++ ...ReferenceMonteCarloAnisotropicBarostat.cpp | 78 +++++++++++++++++++ 19 files changed, 267 insertions(+), 136 deletions(-) diff --git a/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp b/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp index d13f2d6f0..1c64e65c2 100644 --- a/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp @@ -108,7 +108,9 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) Vec3 lengthScale(1.0, 1.0, 1.0); lengthScale[axis] = newVolume/volume; kernel.getAs().scaleCoordinates(context, lengthScale[0], lengthScale[1], lengthScale[2]); - context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale[0], box[1]*lengthScale[1], box[2]*lengthScale[2]); + context.getOwner().setPeriodicBoxVectors(Vec3(box[0][0]*lengthScale[0], box[0][1]*lengthScale[1], box[0][2]*lengthScale[2]), + Vec3(box[1][0]*lengthScale[0], box[1][1]*lengthScale[1], box[1][2]*lengthScale[2]), + Vec3(box[2][0]*lengthScale[0], box[2][1]*lengthScale[1], box[2][2]*lengthScale[2])); // Compute the energy of the modified system. diff --git a/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp index bd6eff28d..a09a5285d 100644 --- a/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp @@ -109,7 +109,9 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) { } double deltaArea = box[0][0]*lengthScale[0]*box[1][1]*lengthScale[1] - box[0][0]*box[1][1]; kernel.getAs().scaleCoordinates(context, lengthScale[0], lengthScale[1], lengthScale[2]); - context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale[0], box[1]*lengthScale[1], box[2]*lengthScale[2]); + context.getOwner().setPeriodicBoxVectors(Vec3(box[0][0]*lengthScale[0], box[0][1]*lengthScale[1], box[0][2]*lengthScale[2]), + Vec3(box[1][0]*lengthScale[0], box[1][1]*lengthScale[1], box[1][2]*lengthScale[2]), + Vec3(box[2][0]*lengthScale[0], box[2][1]*lengthScale[1], box[2][2]*lengthScale[2])); // Compute the energy of the modified system. diff --git a/platforms/reference/include/GBVIParameters.h b/platforms/reference/include/GBVIParameters.h index 294eaad15..425039e47 100644 --- a/platforms/reference/include/GBVIParameters.h +++ b/platforms/reference/include/GBVIParameters.h @@ -65,7 +65,7 @@ class GBVIParameters { bool _cutoff; bool _periodic; - RealOpenMM _periodicBoxSize[3]; + OpenMM::RealVec _periodicBoxVectors[3]; RealOpenMM _cutoffDistance; int _bornRadiusScalingMethod; @@ -244,11 +244,11 @@ class GBVIParameters { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic( OpenMM::RealVec& boxSize ); + void setPeriodic(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- @@ -264,7 +264,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMM* getPeriodicBox(); + const OpenMM::RealVec* getPeriodicBox(); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ObcParameters.h b/platforms/reference/include/ObcParameters.h index b38c59376..c55eef696 100644 --- a/platforms/reference/include/ObcParameters.h +++ b/platforms/reference/include/ObcParameters.h @@ -64,7 +64,7 @@ class ObcParameters { bool _cutoff; bool _periodic; - RealOpenMM _periodicBoxSize[3]; + OpenMM::RealVec _periodicBoxVectors[3]; RealOpenMM _cutoffDistance; /**--------------------------------------------------------------------------------------- @@ -329,11 +329,11 @@ class ObcParameters { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic( const OpenMM::RealVec& boxSize ); + void setPeriodic(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- @@ -345,11 +345,11 @@ class ObcParameters { /**--------------------------------------------------------------------------------------- - Get the periodic box dimension + Get the periodic box vectors --------------------------------------------------------------------------------------- */ - const RealOpenMM* getPeriodicBox(); + const OpenMM::RealVec* getPeriodicBox(); }; diff --git a/platforms/reference/include/ReferenceCustomGBIxn.h b/platforms/reference/include/ReferenceCustomGBIxn.h index 5c3cc26c4..b92211f05 100644 --- a/platforms/reference/include/ReferenceCustomGBIxn.h +++ b/platforms/reference/include/ReferenceCustomGBIxn.h @@ -41,7 +41,7 @@ class ReferenceCustomGBIxn { bool cutoff; bool periodic; const OpenMM::NeighborList* neighborList; - RealOpenMM periodicBoxSize[3]; + OpenMM::RealVec periodicBoxVectors[3]; RealOpenMM cutoffDistance; std::vector valueExpressions; std::vector > valueDerivExpressions; @@ -263,11 +263,11 @@ class ReferenceCustomGBIxn { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic( OpenMM::RealVec& boxSize ); + void setPeriodic(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceCustomHbondIxn.h b/platforms/reference/include/ReferenceCustomHbondIxn.h index f4ea94ee9..d6052d514 100644 --- a/platforms/reference/include/ReferenceCustomHbondIxn.h +++ b/platforms/reference/include/ReferenceCustomHbondIxn.h @@ -43,7 +43,7 @@ class ReferenceCustomHbondIxn : public ReferenceBondIxn { class DihedralTermInfo; bool cutoff; bool periodic; - RealOpenMM periodicBoxSize[3]; + OpenMM::RealVec periodicBoxVectors[3]; RealOpenMM cutoffDistance; std::vector > donorAtoms, acceptorAtoms; Lepton::ExpressionProgram energyExpression; @@ -111,11 +111,11 @@ class ReferenceCustomHbondIxn : public ReferenceBondIxn { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic(OpenMM::RealVec& boxSize); + void setPeriodic(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceCustomManyParticleIxn.h b/platforms/reference/include/ReferenceCustomManyParticleIxn.h index b1ad771a1..616caf4d3 100644 --- a/platforms/reference/include/ReferenceCustomManyParticleIxn.h +++ b/platforms/reference/include/ReferenceCustomManyParticleIxn.h @@ -46,7 +46,7 @@ class ReferenceCustomManyParticleIxn { int numParticlesPerSet, numPerParticleParameters, numTypes; bool useCutoff, usePeriodic, centralParticleMode; RealOpenMM cutoffDistance; - RealOpenMM periodicBoxSize[3]; + OpenMM::RealVec periodicBoxVectors[3]; Lepton::ExpressionProgram energyExpression; std::vector > particleParamNames; std::vector > exclusions; @@ -118,11 +118,11 @@ class ReferenceCustomManyParticleIxn { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic(OpenMM::RealVec& boxSize); + void setPeriodic(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceCustomNonbondedIxn.h b/platforms/reference/include/ReferenceCustomNonbondedIxn.h index 24254fe93..4ac419ca8 100644 --- a/platforms/reference/include/ReferenceCustomNonbondedIxn.h +++ b/platforms/reference/include/ReferenceCustomNonbondedIxn.h @@ -43,7 +43,7 @@ class ReferenceCustomNonbondedIxn { bool useSwitch; bool periodic; const OpenMM::NeighborList* neighborList; - RealOpenMM periodicBoxSize[3]; + OpenMM::RealVec periodicBoxVectors[3]; RealOpenMM cutoffDistance, switchingDistance; Lepton::CompiledExpression energyExpression; Lepton::CompiledExpression forceExpression; @@ -129,11 +129,11 @@ class ReferenceCustomNonbondedIxn { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic( OpenMM::RealVec& boxSize ); + void setPeriodic(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceMonteCarloBarostat.h b/platforms/reference/include/ReferenceMonteCarloBarostat.h index efb5a087c..cfc6f67aa 100644 --- a/platforms/reference/include/ReferenceMonteCarloBarostat.h +++ b/platforms/reference/include/ReferenceMonteCarloBarostat.h @@ -61,14 +61,14 @@ class ReferenceMonteCarloBarostat { Apply the barostat at the start of a time step, scaling x, y, and z coordinates independently. @param atomPositions atom positions - @param boxSize the periodic box dimensions + @param boxVectors the periodic box vectors @param scaleX the factor by which to scale atomic x coordinates @param scaleY the factor by which to scale atomic y coordinates @param scaleZ the factor by which to scale atomic z coordinates --------------------------------------------------------------------------------------- */ - void applyBarostat(std::vector& atomPositions, const OpenMM::RealVec& boxSize, RealOpenMM scaleX, RealOpenMM scaleY, RealOpenMM scaleZ); + void applyBarostat(std::vector& atomPositions, const OpenMM::RealVec* boxVectors, RealOpenMM scaleX, RealOpenMM scaleY, RealOpenMM scaleZ); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/ReferenceKernels.cpp b/platforms/reference/src/ReferenceKernels.cpp index 86570ae00..f455125f3 100644 --- a/platforms/reference/src/ReferenceKernels.cpp +++ b/platforms/reference/src/ReferenceKernels.cpp @@ -279,30 +279,30 @@ void ReferenceUpdateStateDataKernel::setPeriodicBoxVectors(ContextImpl& context, } void ReferenceUpdateStateDataKernel::createCheckpoint(ContextImpl& context, ostream& stream) { - int version = 1; + int version = 2; stream.write((char*) &version, sizeof(int)); stream.write((char*) &data.time, sizeof(data.time)); vector& posData = extractPositions(context); stream.write((char*) &posData[0], sizeof(RealVec)*posData.size()); vector& velData = extractVelocities(context); stream.write((char*) &velData[0], sizeof(RealVec)*velData.size()); - RealVec& box = extractBoxSize(context); - stream.write((char*) &box, sizeof(RealVec)); + RealVec* vectors = extractBoxVectors(context); + stream.write((char*) vectors, 3*sizeof(RealVec)); SimTKOpenMMUtilities::createCheckpoint(stream); } void ReferenceUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& stream) { int version; stream.read((char*) &version, sizeof(int)); - if (version != 1) + if (version != 2) throw OpenMMException("Checkpoint was created with a different version of OpenMM"); stream.read((char*) &data.time, sizeof(data.time)); vector& posData = extractPositions(context); stream.read((char*) &posData[0], sizeof(RealVec)*posData.size()); vector& velData = extractVelocities(context); stream.read((char*) &velData[0], sizeof(RealVec)*velData.size()); - RealVec& box = extractBoxSize(context); - stream.read((char*) &box, sizeof(RealVec)); + RealVec* vectors = extractBoxVectors(context); + stream.read((char*) vectors, 3*sizeof(RealVec)); SimTKOpenMMUtilities::loadCheckpoint(stream); } @@ -867,11 +867,11 @@ double ReferenceCalcNonbondedForceKernel::execute(ContextImpl& context, bool inc clj.setUseCutoff(nonbondedCutoff, *neighborList, rfDielectric); } if (periodic || ewald || pme) { - RealVec* vectors = extractBoxVectors(context); + RealVec* boxVectors = extractBoxVectors(context); double minAllowedSize = 1.999999*nonbondedCutoff; - if (vectors[0][0] < minAllowedSize || vectors[1][1] < minAllowedSize || vectors[2][2] < minAllowedSize) + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - clj.setPeriodic(vectors); + clj.setPeriodic(boxVectors); } if (ewald) clj.setUseEwald(ewaldAlpha, kmax[0], kmax[1], kmax[2]); @@ -885,8 +885,8 @@ double ReferenceCalcNonbondedForceKernel::execute(ContextImpl& context, bool inc ReferenceLJCoulomb14 nonbonded14; refBondForce.calculateForce(num14, bonded14IndexArray, posData, bonded14ParamArray, forceData, includeEnergy ? &energy : NULL, nonbonded14); if (periodic || ewald || pme) { - RealVec& boxSize = extractBoxSize(context); - energy += dispersionCoefficient/(boxSize[0]*boxSize[1]*boxSize[2]); + RealVec* boxVectors = extractBoxVectors(context); + energy += dispersionCoefficient/(boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]); } } return energy; @@ -1022,7 +1022,7 @@ void ReferenceCalcCustomNonbondedForceKernel::initialize(const System& system, c double ReferenceCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { vector& posData = extractPositions(context); vector& forceData = extractForces(context); - RealVec& box = extractBoxSize(context); + RealVec* boxVectors = extractBoxVectors(context); RealOpenMM energy = 0; ReferenceCustomNonbondedIxn ixn(energyExpression, forceExpression, parameterNames); bool periodic = (nonbondedMethod == CutoffPeriodic); @@ -1032,9 +1032,9 @@ double ReferenceCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bo } if (periodic) { double minAllowedSize = 2*nonbondedCutoff; - if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize) + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - ixn.setPeriodic(box); + ixn.setPeriodic(boxVectors); } if (interactionGroups.size() > 0) ixn.setInteractionGroups(interactionGroups); @@ -1055,7 +1055,7 @@ double ReferenceCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bo longRangeCoefficient = CustomNonbondedForceImpl::calcLongRangeCorrection(*forceCopy, context.getOwner()); hasInitializedLongRangeCorrection = true; } - energy += longRangeCoefficient/(box[0]*box[1]*box[2]); + energy += longRangeCoefficient/(boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]); return energy; } @@ -1119,7 +1119,7 @@ double ReferenceCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool inclu vector& posData = extractPositions(context); vector& forceData = extractForces(context); if (isPeriodic) - obc->getObcParameters()->setPeriodic(extractBoxSize(context)); + obc->getObcParameters()->setPeriodic(extractBoxVectors(context)); return obc->computeBornEnergyForces(posData, charges, forceData); } @@ -1193,7 +1193,7 @@ double ReferenceCalcGBVIForceKernel::execute(ContextImpl& context, bool includeF vector& posData = extractPositions(context); if (isPeriodic) - gbvi->getGBVIParameters()->setPeriodic(extractBoxSize(context)); + gbvi->getGBVIParameters()->setPeriodic(extractBoxVectors(context)); RealOpenMM energy; if (includeForces) { @@ -1329,7 +1329,7 @@ double ReferenceCalcCustomGBForceKernel::execute(ContextImpl& context, bool incl energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames); bool periodic = (nonbondedMethod == CutoffPeriodic); if (periodic) - ixn.setPeriodic(extractBoxSize(context)); + ixn.setPeriodic(extractBoxVectors(context)); if (nonbondedMethod != NoCutoff) { computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, extractBoxVectors(context), periodic, nonbondedCutoff, 0.0); ixn.setUseCutoff(nonbondedCutoff, *neighborList); @@ -1508,7 +1508,7 @@ double ReferenceCalcCustomHbondForceKernel::execute(ContextImpl& context, bool i vector& posData = extractPositions(context); vector& forceData = extractForces(context); if (isPeriodic) - ixn->setPeriodic(extractBoxSize(context)); + ixn->setPeriodic(extractBoxVectors(context)); RealOpenMM energy = 0; map globalParameters; for (int i = 0; i < (int) globalParameterNames.size(); i++) @@ -1661,11 +1661,11 @@ double ReferenceCalcCustomManyParticleForceKernel::execute(ContextImpl& context, for (int i = 0; i < (int) globalParameterNames.size(); i++) globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]); if (nonbondedMethod == CutoffPeriodic) { - RealVec& box = extractBoxSize(context); + RealVec* boxVectors = extractBoxVectors(context); double minAllowedSize = 2*cutoffDistance; - if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize) + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - ixn->setPeriodic(box); + ixn->setPeriodic(boxVectors); } ixn->calculateIxn(posData, particleParamArray, globalParameters, forceData, includeEnergy ? &energy : NULL); return energy; @@ -2014,8 +2014,8 @@ void ReferenceApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& conte if (barostat == NULL) barostat = new ReferenceMonteCarloBarostat(context.getSystem().getNumParticles(), context.getMolecules()); vector& posData = extractPositions(context); - RealVec& boxSize = extractBoxSize(context); - barostat->applyBarostat(posData, boxSize, scaleX, scaleY, scaleZ); + RealVec* boxVectors = extractBoxVectors(context); + barostat->applyBarostat(posData, boxVectors, scaleX, scaleY, scaleZ); } void ReferenceApplyMonteCarloBarostatKernel::restoreCoordinates(ContextImpl& context) { diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp index 436416568..aeb9bc308 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp @@ -118,21 +118,21 @@ ReferenceCustomGBIxn::~ReferenceCustomGBIxn( ){ also been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void ReferenceCustomGBIxn::setPeriodic( RealVec& boxSize ) { + void ReferenceCustomGBIxn::setPeriodic(RealVec* vectors) { if (cutoff) { - assert(boxSize[0] >= 2.0*cutoffDistance); - assert(boxSize[1] >= 2.0*cutoffDistance); - assert(boxSize[2] >= 2.0*cutoffDistance); + assert(vectors[0][0] >= 2.0*cutoffDistance); + assert(vectors[1][1] >= 2.0*cutoffDistance); + assert(vectors[2][2] >= 2.0*cutoffDistance); } periodic = true; - periodicBoxSize[0] = boxSize[0]; - periodicBoxSize[1] = boxSize[1]; - periodicBoxSize[2] = boxSize[2]; + periodicBoxVectors[0] = vectors[0]; + periodicBoxVectors[1] = vectors[1]; + periodicBoxVectors[2] = vectors[2]; } void ReferenceCustomGBIxn::calculateIxn(int numberOfAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, @@ -218,7 +218,7 @@ void ReferenceCustomGBIxn::calculateOnePairValue(int index, int atom1, int atom2 const map& globalParameters, vector >& values) const { RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (periodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR); else ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); RealOpenMM r = deltaR[ReferenceForce::RIndex]; @@ -292,7 +292,7 @@ void ReferenceCustomGBIxn::calculateOnePairEnergyTerm(int index, int atom1, int RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (periodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR); else ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); RealOpenMM r = deltaR[ReferenceForce::RIndex]; @@ -390,7 +390,7 @@ void ReferenceCustomGBIxn::calculateOnePairChainRule(int atom1, int atom2, vecto RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (periodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxSize, deltaR); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom2], atomCoordinates[atom1], periodicBoxVectors, deltaR); else ReferenceForce::getDeltaR(atomCoordinates[atom2], atomCoordinates[atom1], deltaR); RealOpenMM r = deltaR[ReferenceForce::RIndex]; diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp index a521e490c..2f9aeb482 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp @@ -87,19 +87,19 @@ void ReferenceCustomHbondIxn::setUseCutoff(RealOpenMM distance) { also been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ -void ReferenceCustomHbondIxn::setPeriodic(RealVec& boxSize) { +void ReferenceCustomHbondIxn::setPeriodic(RealVec* vectors) { assert(cutoff); - assert(boxSize[0] >= 2.0*cutoffDistance); - assert(boxSize[1] >= 2.0*cutoffDistance); - assert(boxSize[2] >= 2.0*cutoffDistance); + assert(vectors[0][0] >= 2.0*cutoffDistance); + assert(vectors[1][1] >= 2.0*cutoffDistance); + assert(vectors[2][2] >= 2.0*cutoffDistance); periodic = true; - periodicBoxSize[0] = boxSize[0]; - periodicBoxSize[1] = boxSize[1]; - periodicBoxSize[2] = boxSize[2]; + periodicBoxVectors[0] = vectors[0]; + periodicBoxVectors[1] = vectors[1]; + periodicBoxVectors[2] = vectors[2]; } @@ -288,7 +288,7 @@ void ReferenceCustomHbondIxn::calculateOneIxn(int donor, int acceptor, vector& atomCoordinates) const { if (periodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxSize, delta); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxVectors, delta); else ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta); } diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp index 312a50e28..868684c21 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp @@ -120,15 +120,15 @@ void ReferenceCustomManyParticleIxn::setUseCutoff(RealOpenMM distance) { cutoffDistance = distance; } -void ReferenceCustomManyParticleIxn::setPeriodic(RealVec& boxSize) { +void ReferenceCustomManyParticleIxn::setPeriodic(RealVec* vectors) { assert(useCutoff); - assert(boxSize[0] >= 2.0*cutoffDistance); - assert(boxSize[1] >= 2.0*cutoffDistance); - assert(boxSize[2] >= 2.0*cutoffDistance); + assert(vectors[0][0] >= 2.0*cutoffDistance); + assert(vectors[1][1] >= 2.0*cutoffDistance); + assert(vectors[2][2] >= 2.0*cutoffDistance); usePeriodic = true; - periodicBoxSize[0] = boxSize[0]; - periodicBoxSize[1] = boxSize[1]; - periodicBoxSize[2] = boxSize[2]; + periodicBoxVectors[0] = vectors[0]; + periodicBoxVectors[1] = vectors[1]; + periodicBoxVectors[2] = vectors[2]; } void ReferenceCustomManyParticleIxn::loopOverInteractions(vector& particles, int loopIndex, vector& atomCoordinates, @@ -304,7 +304,7 @@ void ReferenceCustomManyParticleIxn::calculateOneIxn(const vector& particle void ReferenceCustomManyParticleIxn::computeDelta(int atom1, int atom2, RealOpenMM* delta, vector& atomCoordinates) const { if (usePeriodic) - ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxSize, delta); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atom1], atomCoordinates[atom2], periodicBoxVectors, delta); else ReferenceForce::getDeltaR(atomCoordinates[atom1], atomCoordinates[atom2], delta); } diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp index 2ff0a6e0a..17b16163a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp @@ -131,20 +131,20 @@ void ReferenceCustomNonbondedIxn::setUseSwitchingFunction( RealOpenMM distance ) also been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void ReferenceCustomNonbondedIxn::setPeriodic( RealVec& boxSize ) { + void ReferenceCustomNonbondedIxn::setPeriodic(OpenMM::RealVec* vectors) { assert(cutoff); - assert(boxSize[0] >= 2.0*cutoffDistance); - assert(boxSize[1] >= 2.0*cutoffDistance); - assert(boxSize[2] >= 2.0*cutoffDistance); + assert(vectors[0][0] >= 2.0*cutoffDistance); + assert(vectors[1][1] >= 2.0*cutoffDistance); + assert(vectors[2][2] >= 2.0*cutoffDistance); periodic = true; - periodicBoxSize[0] = boxSize[0]; - periodicBoxSize[1] = boxSize[1]; - periodicBoxSize[2] = boxSize[2]; + periodicBoxVectors[0] = vectors[0]; + periodicBoxVectors[1] = vectors[1]; + periodicBoxVectors[2] = vectors[2]; } @@ -268,7 +268,7 @@ void ReferenceCustomNonbondedIxn::calculateOneIxn( int ii, int jj, vector& atomPositions, const RealVec& boxSize, RealOpenMM scaleX, RealOpenMM scaleY, RealOpenMM scaleZ) { +void ReferenceMonteCarloBarostat::applyBarostat(vector& atomPositions, const RealVec* boxVectors, RealOpenMM scaleX, RealOpenMM scaleY, RealOpenMM scaleZ) { int numAtoms = savedAtomPositions[0].size(); for (int i = 0; i < numAtoms; i++) for (int j = 0; j < 3; j++) @@ -75,39 +75,29 @@ void ReferenceMonteCarloBarostat::applyBarostat(vector& atomPositions, for (int i = 0; i < (int) molecules.size(); i++) { // Find the molecule center. - RealOpenMM pos[3] = {0, 0, 0}; + RealVec pos(0, 0, 0); for (int j = 0; j < (int) molecules[i].size(); j++) { RealVec& atomPos = atomPositions[molecules[i][j]]; - pos[0] += atomPos[0]; - pos[1] += atomPos[1]; - pos[2] += atomPos[2]; + pos += atomPos; } - pos[0] /= molecules[i].size(); - pos[1] /= molecules[i].size(); - pos[2] /= molecules[i].size(); + pos /= molecules[i].size(); // Move it into the first periodic box. - int xcell = (int) floor(pos[0]/boxSize[0]); - int ycell = (int) floor(pos[1]/boxSize[1]); - int zcell = (int) floor(pos[2]/boxSize[2]); - RealOpenMM dx = xcell*boxSize[0]; - RealOpenMM dy = ycell*boxSize[1]; - RealOpenMM dz = zcell*boxSize[2]; - pos[0] -= dx; - pos[1] -= dy; - pos[2] -= dz; + RealVec newPos = pos; + newPos -= boxVectors[2]*floor(newPos[2]/boxVectors[2][2]); + newPos -= boxVectors[1]*floor(newPos[1]/boxVectors[1][1]); + newPos -= boxVectors[0]*floor(newPos[0]/boxVectors[0][0]); // Now scale the position of the molecule center. - dx = pos[0]*(scaleX-1)-dx; - dy = pos[1]*(scaleY-1)-dy; - dz = pos[2]*(scaleZ-1)-dz; + newPos[0] *= scaleX; + newPos[1] *= scaleY; + newPos[2] *= scaleZ; + RealVec offset = newPos-pos; for (int j = 0; j < (int) molecules[i].size(); j++) { RealVec& atomPos = atomPositions[molecules[i][j]]; - atomPos[0] += dx; - atomPos[1] += dy; - atomPos[2] += dz; + atomPos += offset; } } } diff --git a/platforms/reference/src/gbsa/GBVIParameters.cpp b/platforms/reference/src/gbsa/GBVIParameters.cpp index fbf593bb0..170f1f5c9 100644 --- a/platforms/reference/src/gbsa/GBVIParameters.cpp +++ b/platforms/reference/src/gbsa/GBVIParameters.cpp @@ -286,22 +286,20 @@ RealOpenMM GBVIParameters::getCutoffDistance() { also been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ -void GBVIParameters::setPeriodic( RealVec& boxSize ) { +void GBVIParameters::setPeriodic(RealVec* vectors) { - assert(_cutoff); - - assert(boxSize[0] >= 2.0*_cutoffDistance); - assert(boxSize[1] >= 2.0*_cutoffDistance); - assert(boxSize[2] >= 2.0*_cutoffDistance); - - _periodic = true; - _periodicBoxSize[0] = boxSize[0]; - _periodicBoxSize[1] = boxSize[1]; - _periodicBoxSize[2] = boxSize[2]; + assert(_cutoff); + assert(vectors[0][0] >= 2.0*_cutoffDistance); + assert(vectors[1][1] >= 2.0*_cutoffDistance); + assert(vectors[2][2] >= 2.0*_cutoffDistance); + _periodic = true; + _periodicBoxVectors[0] = vectors[0]; + _periodicBoxVectors[1] = vectors[1]; + _periodicBoxVectors[2] = vectors[2]; } /**--------------------------------------------------------------------------------------- @@ -320,8 +318,8 @@ bool GBVIParameters::getPeriodic() { --------------------------------------------------------------------------------------- */ -const RealOpenMM* GBVIParameters::getPeriodicBox() { - return _periodicBoxSize; +const OpenMM::RealVec* GBVIParameters::getPeriodicBox() { + return _periodicBoxVectors; } /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/gbsa/ObcParameters.cpp b/platforms/reference/src/gbsa/ObcParameters.cpp index 0d541a4cc..1641ee4e2 100644 --- a/platforms/reference/src/gbsa/ObcParameters.cpp +++ b/platforms/reference/src/gbsa/ObcParameters.cpp @@ -374,22 +374,22 @@ RealOpenMM ObcParameters::getCutoffDistance() const { also been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ -void ObcParameters::setPeriodic( const OpenMM::RealVec& boxSize ) { +void ObcParameters::setPeriodic(OpenMM::RealVec* vectors) { - assert(_cutoff); + assert(_cutoff); - assert(boxSize[0] >= 2.0*_cutoffDistance); - assert(boxSize[1] >= 2.0*_cutoffDistance); - assert(boxSize[2] >= 2.0*_cutoffDistance); + assert(boxSize[0][0] >= 2.0*_cutoffDistance); + assert(boxSize[1][1] >= 2.0*_cutoffDistance); + assert(boxSize[2][2] >= 2.0*_cutoffDistance); - _periodic = true; - _periodicBoxSize[0] = boxSize[0]; - _periodicBoxSize[1] = boxSize[1]; - _periodicBoxSize[2] = boxSize[2]; + _periodic = true; + _periodicBoxVectors[0] = vectors[0]; + _periodicBoxVectors[1] = vectors[1]; + _periodicBoxVectors[2] = vectors[2]; } /**--------------------------------------------------------------------------------------- @@ -408,6 +408,6 @@ bool ObcParameters::getPeriodic() { --------------------------------------------------------------------------------------- */ -const RealOpenMM* ObcParameters::getPeriodicBox() { - return _periodicBoxSize; +const OpenMM::RealVec* ObcParameters::getPeriodicBox() { + return _periodicBoxVectors; } diff --git a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp index 23d254141..17eaa08e4 100644 --- a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp @@ -227,6 +227,66 @@ void testPeriodic() { ASSERT_EQUAL_TOL(1.9+1+0.9, state.getPotentialEnergy(), TOL); } +void testTriclinic() { + ReferencePlatform platform; + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + CustomNonbondedForce* nonbonded = new CustomNonbondedForce("r"); + nonbonded->addParticle(vector()); + nonbonded->addParticle(vector()); + nonbonded->setNonbondedMethod(CustomNonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta/sqrt(delta.dot(delta)); + ASSERT_EQUAL_TOL(distance, state.getPotentialEnergy(), TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} + void testContinuous1DFunction() { ReferencePlatform platform; System system; @@ -863,6 +923,7 @@ int main() { testExclusions(); testCutoff(); testPeriodic(); + testTriclinic(); testContinuous1DFunction(); testContinuous2DFunction(); testContinuous3DFunction(); diff --git a/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp index 0a327c5f3..c81074607 100644 --- a/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp +++ b/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp @@ -237,6 +237,83 @@ void testRandomSeed() { } } +void testTriclinic() { + const int numParticles = 64; + const int frequency = 10; + const int steps = 1000; + const double pressure = 1.5; + const double pressureInMD = pressure*(AVOGADRO*1e-25); // pressure in kJ/mol/nm^3 + const double temperature = 300.0; + const double initialVolume = numParticles*BOLTZ*temperature/pressureInMD; + const double initialLength = std::pow(initialVolume, 1.0/3.0); + + // Create a gas of noninteracting particles. + + ReferencePlatform platform; + System system; + Vec3 initialBox[3]; + initialBox[0] = Vec3(initialLength, 0, 0); + initialBox[1] = Vec3(0.2*initialLength, initialLength, 0); + initialBox[2] = Vec3(0.1*initialLength, 0.3*initialLength, initialLength); + system.setDefaultPeriodicBoxVectors(initialBox[0], initialBox[1], initialBox[2]); + vector positions(numParticles); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int i = 0; i < numParticles; ++i) { + system.addParticle(1.0); + positions[i] = Vec3(initialLength*genrand_real2(sfmt), initialLength*genrand_real2(sfmt), initialLength*genrand_real2(sfmt)); + } + MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temperature, true, true, true, frequency); + system.addForce(barostat); + + // Run a simulation + + LangevinIntegrator integrator(temperature, 0.1, 0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + + // Let it equilibrate. + + integrator.step(10000); + + // Now run it for a while and see if the volume is correct. + + double volume = 0.0; + for (int j = 0; j < steps; ++j) { + Vec3 box[3]; + context.getState(0).getPeriodicBoxVectors(box[0], box[1], box[2]); + volume += box[0][0]*box[1][1]*box[2][2]; + integrator.step(frequency); + } + volume /= steps; + double expected = (numParticles+1)*BOLTZ*temperature/pressureInMD; + ASSERT_USUALLY_EQUAL_TOL(expected, volume, 3/std::sqrt((double) steps)); + + // Make sure the box vectors have been scaled consistently. + + State state = context.getState(State::Positions); + Vec3 box[3]; + state.getPeriodicBoxVectors(box[0], box[1], box[2]); + double xscale = box[2][0]/(0.1*initialLength); + double yscale = box[2][1]/(0.3*initialLength); + double zscale = box[2][2]/(1.0*initialLength); + for (int i = 0; i < 3; i++) { + ASSERT_EQUAL_VEC(Vec3(xscale*initialBox[i][0], yscale*initialBox[i][1], zscale*initialBox[i][2]), box[i], 1e-5); + } + + // The barostat should have put all particles inside the first periodic box. One integration step + // has happened since then, so they may have moved slightly outside it. + + for (int i = 0; i < numParticles; i++) { + Vec3 pos = state.getPositions()[i]; + ASSERT(pos[2]/box[2][2] > -1 && pos[2]/box[2][2] < 2); + pos -= box[2]*floor(pos[2]/box[2][2]); + ASSERT(pos[1]/box[1][1] > -1 && pos[1]/box[1][1] < 2); + pos -= box[1]*floor(pos[1]/box[1][1]); + ASSERT(pos[0]/box[0][0] > -1 && pos[0]/box[0][0] < 2); + } +} + /** * Run a constant pressure simulation on an anisotropic Einstein crystal * using isotropic and anisotropic barostats. There are a total of 15 simulations: @@ -389,6 +466,7 @@ int main() { testIdealGasAxis(1); testIdealGasAxis(2); testRandomSeed(); + testTriclinic(); //testEinsteinCrystal(); } catch(const exception& e) { -- GitLab From 741d186d8937eaa5d9bc37d72335bf2ced4aa9ab Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Tue, 2 Dec 2014 18:09:15 -0800 Subject: [PATCH 152/338] Build scripts now first remove old install directory. --- devtools/packaging/scripts/linux/build.sh | 6 ++++++ devtools/packaging/scripts/osx/build.sh | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/devtools/packaging/scripts/linux/build.sh b/devtools/packaging/scripts/linux/build.sh index f84b07bc2..2fccf9970 100755 --- a/devtools/packaging/scripts/linux/build.sh +++ b/devtools/packaging/scripts/linux/build.sh @@ -10,6 +10,10 @@ export WORKSPACE=`pwd` PATH=$WORKSPACE/miniconda/bin:$PATH INSTALL=`pwd`/install +if [ -e $INSTALL ]; then + rm -rf $INSTALL +fi + CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" # setting the rpath so that libOpenMMPME.so finds the right libfftw3 @@ -37,4 +41,6 @@ mkdir build cd build cmake ../openmm $CMAKE_FLAGS make -j4 all DoxygenApiDocs sphinxpdf + +# Install. make install diff --git a/devtools/packaging/scripts/osx/build.sh b/devtools/packaging/scripts/osx/build.sh index e969bb70b..ce992e505 100755 --- a/devtools/packaging/scripts/osx/build.sh +++ b/devtools/packaging/scripts/osx/build.sh @@ -9,7 +9,12 @@ export WORKSPACE=`pwd` # Add conda binaries to path. PATH=$WORKSPACE/miniconda/bin:$PATH +# Set install directory. INSTALL=`pwd`/install +if [ -e $INSTALL ]; then + rm -rf $INSTALL +fi + CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=$INSTALL" # setting the rpath so that libOpenMMPME.so finds the right libfftw3 @@ -38,4 +43,6 @@ mkdir build cd build cmake ../openmm $CMAKE_FLAGS make -j4 all DoxygenApiDocs sphinxpdf + +# Install. make install -- GitLab From 662eb730d42ce64807b618fb5b0b7a4c810c3c52 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Tue, 2 Dec 2014 18:11:59 -0800 Subject: [PATCH 153/338] Minor cleanup in prepare.sh script. --- devtools/packaging/scripts/linux/prepare.sh | 1 + devtools/packaging/scripts/osx/prepare.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/devtools/packaging/scripts/linux/prepare.sh b/devtools/packaging/scripts/linux/prepare.sh index 91d6e986e..9d6c1c31e 100755 --- a/devtools/packaging/scripts/linux/prepare.sh +++ b/devtools/packaging/scripts/linux/prepare.sh @@ -15,6 +15,7 @@ then echo "miniconda already exists" else echo "Downloading miniconda..." + rm -rf Miniconda-* wget --quiet http://repo.continuum.io/miniconda/${MINICONDA} bash ${MINICONDA} -b -p miniconda PIP_ARGS="-U" diff --git a/devtools/packaging/scripts/osx/prepare.sh b/devtools/packaging/scripts/osx/prepare.sh index be26323e6..94b9d2d45 100755 --- a/devtools/packaging/scripts/osx/prepare.sh +++ b/devtools/packaging/scripts/osx/prepare.sh @@ -15,6 +15,7 @@ then echo "miniconda already exists" else echo "Downloading miniconda..." + rm -rf Miniconda-* wget --quiet http://repo.continuum.io/miniconda/${MINICONDA} bash ${MINICONDA} -b -p miniconda PIP_ARGS="-U" -- GitLab From 5030c946899a9e2c3241944a2b1a938f92075623 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Tue, 2 Dec 2014 18:33:04 -0800 Subject: [PATCH 154/338] Removed debugging statements from packaging scripts. --- devtools/packaging/scripts/linux/package.sh | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/devtools/packaging/scripts/linux/package.sh b/devtools/packaging/scripts/linux/package.sh index 8f052f290..56803707f 100755 --- a/devtools/packaging/scripts/linux/package.sh +++ b/devtools/packaging/scripts/linux/package.sh @@ -9,32 +9,16 @@ export VERSION=$(sed -nr "s/OPENMM_VERSION:STRING=(.*)/\1/p" build/CMakeCache.tx export PACKAGE_SUBDIR="OpenMM-${VERSION}-Linux" # directory where distribution will be unpacked export DISTRO_PREFIX="OpenMM-${VERSION}-Linux" # prefix for source distribution (e.g. ${DISTRIBUTION_NAME}.zip) -# DEBUG -echo "DEBUG 1" -pwd -ls -ltr . -# END DEBUG - # Perform all work in a work directory. cd work -# DEBUG -echo "DEBUG 1" -pwd -ls -ltr . -# END DEBUG - # Clean up. rm -rf $PACKAGE_DIR # Make a directory to contain packaged source distribution -echo "DEBUG 3" mkdir $PACKAGE_DIR mkdir $PACKAGE_DIR/$PACKAGE_SUBDIR for filename in $( cat openmm/devtools/packaging/manifests/binary/manifest.txt ); do - # DEBUG: List contents of each directory. - ls -ltr install/$filename - # END DEBUG CMD="cp -r install/$filename $PACKAGE_DIR/$PACKAGE_SUBDIR" echo $CMD `$CMD` -- GitLab From a7ab275380d95de17c2c0175f046ac5216dfb17f Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 3 Dec 2014 11:10:25 -0800 Subject: [PATCH 155/338] Fixed uninitialized memory in variable step size integrators --- openmmapi/src/VariableLangevinIntegrator.cpp | 1 + openmmapi/src/VariableVerletIntegrator.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/openmmapi/src/VariableLangevinIntegrator.cpp b/openmmapi/src/VariableLangevinIntegrator.cpp index 5873c0a38..72ef8d456 100644 --- a/openmmapi/src/VariableLangevinIntegrator.cpp +++ b/openmmapi/src/VariableLangevinIntegrator.cpp @@ -49,6 +49,7 @@ VariableLangevinIntegrator::VariableLangevinIntegrator(double temperature, doubl setErrorTolerance(errorTol); setConstraintTolerance(1e-5); setRandomNumberSeed(osrngseed()); + setStepSize(0.0); } void VariableLangevinIntegrator::initialize(ContextImpl& contextRef) { diff --git a/openmmapi/src/VariableVerletIntegrator.cpp b/openmmapi/src/VariableVerletIntegrator.cpp index cd2b3d585..7e8aca0f3 100644 --- a/openmmapi/src/VariableVerletIntegrator.cpp +++ b/openmmapi/src/VariableVerletIntegrator.cpp @@ -43,6 +43,7 @@ using std::vector; VariableVerletIntegrator::VariableVerletIntegrator(double errorTol) : errorTol(errorTol) { setConstraintTolerance(1e-5); + setStepSize(0.0); } void VariableVerletIntegrator::initialize(ContextImpl& contextRef) { -- GitLab From 2c68f67af58c5b32ca76827cbaf1d5223cd3456a Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 4 Dec 2014 11:59:12 -0800 Subject: [PATCH 156/338] Disable PME stream on old versions of cufft --- platforms/cuda/src/CudaKernels.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 1ee828afe..950acb35f 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1674,7 +1674,9 @@ void CudaCalcNonbondedForceKernel::initialize(const System& system, const Nonbon // Prepare for doing PME on its own stream. - usePmeStream = (cu.getComputeCapability() < 5.0 && numParticles < 130000); // Workarounds for various CUDA bugs + int cufftVersion; + cufftGetVersion(&cufftVersion); + usePmeStream = (cu.getComputeCapability() < 5.0 && numParticles < 130000 && cufftVersion >= 6000); // Workarounds for various CUDA bugs if (usePmeStream) { cuStreamCreate(&pmeStream, CU_STREAM_NON_BLOCKING); cufftSetStream(fftForward, pmeStream); -- GitLab From b9a19a0c01b7bdc930f28d7d1a8c29ab6f293f15 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 6 Dec 2014 18:21:10 -0500 Subject: [PATCH 157/338] Fix small bug in unit related to mutable sequences. --- wrappers/python/simtk/unit/quantity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index 69e137a00..3db332405 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -356,7 +356,7 @@ class Quantity(object): if unit.is_dimensionless(): assert unit is dimensionless # should have been set earlier in this method if is_quantity(result): - result = result._value + result = copy.deepcopy(result._value) return result def __mul__(self, other): -- GitLab From f7a7f4ea12df4f477fa77af11c113ee7da5726ae Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sun, 7 Dec 2014 20:17:19 -0500 Subject: [PATCH 158/338] Fix the mean() and std() methods on container Quantities when those containers are NOT numpy arrays. --- wrappers/python/simtk/unit/quantity.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/unit/quantity.py b/wrappers/python/simtk/unit/quantity.py index 3db332405..0fe44b293 100644 --- a/wrappers/python/simtk/unit/quantity.py +++ b/wrappers/python/simtk/unit/quantity.py @@ -506,7 +506,7 @@ class Quantity(object): except AttributeError: if args or kwargs: raise TypeError('Unsupported arguments for Quantity.mean') - mean = self.sum() / len(self._value) + mean = (self.sum() / len(self._value))._value return Quantity(mean, self.unit) def std(self, *args, **kwargs): @@ -526,7 +526,8 @@ class Quantity(object): except AttributeError: if args or kwargs: raise TypeError('Unsupported arguments for Quantity.std') - mean = self.mean() + mean = self.mean()._value + var = 0 for val in self._value: res = mean - val var += res * res -- GitLab From f976bb34f8084807697b89b6b4b687fafb20fd94 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sun, 7 Dec 2014 20:20:09 -0500 Subject: [PATCH 159/338] Add a set of unittests for the simtk.unit package. Implements most of what I found in doctests.py (and quite a bit more, too) --- wrappers/python/tests/TestUnits.py | 691 +++++++++++++++++++++++++++++ 1 file changed, 691 insertions(+) create mode 100644 wrappers/python/tests/TestUnits.py diff --git a/wrappers/python/tests/TestUnits.py b/wrappers/python/tests/TestUnits.py new file mode 100644 index 000000000..5be69e609 --- /dev/null +++ b/wrappers/python/tests/TestUnits.py @@ -0,0 +1,691 @@ +""" +Tests the functionality in the chemistry.unit package. +""" +from __future__ import division + +from simtk import unit as u +import copy +import math +import unittest +try: + import numpy as np +except ImportError: + np = None +try: + from itertools import izip as zip +except ImportError: + pass # Python 3... zip _is_ izip + +class QuantityTestCase(unittest.TestCase): + + def assertAlmostEqualQuantities(self, item1, item2, places=6): + try: + val1 = item1.value_in_unit(item1.unit) + val2 = item2.value_in_unit(item1.unit) + except TypeError: + raise self.failureException('Incompatible units %s and %s' % + (item1.unit, item2.unit)) + try: + if len(val1) != len(val2): + raise self.failureException('collections are different lengths') + for x, y in zip(val1, val2): + self.assertAlmostEqual(x, y, places=places) + except TypeError: + self.assertAlmostEqual(val1, val2, places=places) + +class TestUnits(QuantityTestCase): + + def testBaseUnit(self): + """ Tests the creation of a base unit furlong """ + furlong = u.BaseUnit(u.length_dimension, "furlong", "fur") + furlong.define_conversion_factor_to(u.meter_base_unit, 201.168) + self.assertEqual(furlong.conversion_factor_to(u.angstrom_base_unit), + 201.168e10) + + def testIsUnit(self): + """ Tests the unit.is_unit introspective function """ + self.assertTrue(u.is_unit(u.meters)) + self.assertFalse(u.is_unit(None)) + self.assertFalse(u.is_unit(10)) + # Distinguish between "units" and "quantities" + self.assertFalse(u.is_unit(1*u.meters)) + + def testCalorieConversion(self): + """ Tests unit conversion with calories to joules """ + c = 1.0 * u.calories + j = 1.0 * u.joules + j2c = j.in_units_of(u.calories) + self.assertNotEqual(c, 1.0) # Units do not equal scalars! + self.assertIs(c.unit, u.calories) + self.assertEqual(c._value, 1) + self.assertEqual(u.calorie.conversion_factor_to(u.joule), 4.184) + self.assertEqual(u.joule.conversion_factor_to(u.calorie), 1/4.184) + self.assertIs(j2c.unit, u.calories) + self.assertEqual(j2c._value, 1/4.184) + self.assertEqual(c / u.calories, 1.0) # Dimensionless now + self.assertEqual(j / u.calories, j2c._value) + c2 = c**2 + cc = c * c + self.assertEqual(cc, c2) + self.assertTrue(c2.unit, u.calories**2) + self.assertEqual(c2.in_units_of(u.joules**2), (4.184*u.joules)**2) + + def testScaledUnit(self): + """ Tests ScaledUnit class with kilokelvins """ + kK = u.ScaledUnit(1000.0, u.kelvin, "kilokelvin", "kK") + self.assertIs(kK.master, u.kelvin) + self.assertEqual(kK.factor, 1000) + self.assertEqual(str(kK), 'kilokelvin') + self.assertEqual(kK.name, 'kilokelvin') + self.assertEqual(kK.symbol, 'kK') + + def testComparisonOperators(self): + """ Tests unit comparison operators """ + self.assertGreater(u.meters, u.centimeters) + self.assertLess(u.angstroms, u.centimeters) + + def testUnitDivision(self): + """ Tests the division of units and is_dimensionless """ + mps = u.meter / u.second + mpm = u.meter / u.meter + mpc = u.meter / u.centimeter + self.assertTrue(u.is_unit(mps)) + self.assertTrue(u.is_unit(mpm)) + self.assertTrue(u.is_unit(mpc)) + self.assertFalse(mps.is_dimensionless()) + self.assertTrue(mpm.is_dimensionless()) + self.assertTrue(mpc.is_dimensionless()) + + def testCompositeUnits(self): + """ Tests the creation of a composite unit """ + mps = u.Unit({u.meter_base_unit : 1.0, u.second_base_unit : -1.0}) + self.assertTrue(u.is_unit(mps)) + self.assertEqual(str(mps), 'meter/second') + + def testUnitSystem(self): + """ Tests the creation of a UnitSystem and its behavior """ + us = u.UnitSystem([u.ScaledUnit(1.0, u.coulomb/u.second, 'ampere', 'A'), + u.second_base_unit]) + self.assertEqual(us.express_unit(u.second), u.second) + self.assertEqual(us.express_unit(u.hour), u.second) + self.assertNotEqual(u.hour, u.second) + self.assertEqual(us.express_unit(u.coulomb/u.second), u.ampere) + self.assertEqual(us.express_unit(u.meter/u.second), u.meter/u.second) + self.assertEqual(us.express_unit(u.kilometer/u.hour), + u.kilometer/u.second) + x = 100 * u.millimeters + self.assertEqual(x.value_in_unit_system(u.si_unit_system), 0.1) + self.assertEqual(x.value_in_unit_system(u.cgs_unit_system), 10.0) + self.assertAlmostEqual(x.value_in_unit_system(u.md_unit_system), 1e8) + y = 20 * u.millimeters / u.millisecond**2 + self.assertAlmostEqual(y.value_in_unit_system(u.si_unit_system), 2e4) + self.assertAlmostEqual(y.value_in_unit_system(u.cgs_unit_system), 2e6) + self.assertAlmostEqual(y.value_in_unit_system(u.md_unit_system), 2e-11, + places=18) + kcal = 1 * u.md_kilocalorie / u.mole + self.assertEqual(kcal.value_in_unit_system(u.md_unit_system), 4.184) + + def testUnitSqrt(self): + """ Tests taking the square root of units """ + self.assertEqual((u.meter * u.meter).sqrt(), u.meter) + self.assertEqual((u.meter**4).sqrt(), u.meter**2) + + def testQuantitySqrt(self): + """ Tests taking the square root of quantities """ + self.assertEqual((9.0*u.meters**2).sqrt(), 3.0*u.meters) + self.assertEqual((9.0*u.meters**2/u.second**2).sqrt(), + 3.0*u.meters/u.second) + + def testUnitBadSqrt(self): + """ Tests that illegal sqrt calls on incompatible units fails """ + mps2 = u.meters/u.second**2 + self.assertRaises(ArithmeticError, lambda: u.meter.sqrt()) + self.assertRaises(ArithmeticError, lambda: (u.meters**3).sqrt()) + self.assertRaises(ArithmeticError, lambda: mps2.sqrt()) + + def testQuantityBadSqrt(self): + " Tests that taking sqrt of Quantities with incompatible units fails " + self.assertRaises(ArithmeticError, lambda: (9.0*u.meters).sqrt()) + self.assertRaises(ArithmeticError, lambda: (9.0*u.meters**3).sqrt()) + + def testBaseScaleMix(self): + """ Test mixing of BaseUnit and ScaledUnit instances """ + kgj = u.kilogram * u.joule + self.assertTrue(u.is_unit(kgj)) + self.assertEqual(str(kgj.sqrt()), 'kilogram*meter/second') + + def testGetUnitAttributes(self): + """ Tests the unit attribute `getters' """ + self.assertEqual(u.newton.get_name(), 'newton') + self.assertEqual(u.newtons.get_name(), 'newton') + self.assertEqual(u.newton.get_symbol(), 'N') + self.assertEqual(u.ampere.get_symbol(), 'A') + self.assertEqual(u.meter.get_name(), 'meter') + self.assertEqual(u.meter.get_symbol(), 'm') + + def testPresetUnitSystems(self): + """ Tests some of the pre-set UnitSystem's """ + self.assertEqual(u.angstrom.in_unit_system(u.si_unit_system), u.meter) + self.assertEqual(u.angstrom.in_unit_system(u.cgs_unit_system), + u.centimeter) + self.assertEqual(u.angstrom.in_unit_system(u.md_unit_system), + u.nanometer) + mps = u.meter / u.second**2 + self.assertEqual(str(mps), 'meter/(second**2)') + self.assertEqual(mps.in_unit_system(u.si_unit_system), mps) + self.assertEqual(mps.in_unit_system(u.cgs_unit_system), + u.centimeter/u.second**2) + self.assertEqual(mps.in_unit_system(u.md_unit_system), + u.nanometer/u.picosecond**2) + + def testIsCompatible(self): + """ Tests the is_compatible attribute of units """ + self.assertTrue(u.meter.is_compatible(u.centimeter)) + self.assertTrue(u.centimeter.is_compatible(u.meter)) + self.assertTrue(u.meter.is_compatible(u.meter)) + self.assertTrue(u.joule.is_compatible(u.calorie)) + self.assertFalse(u.meter.is_compatible(u.kelvin)) + self.assertFalse(u.meter.is_compatible(u.meter/u.second)) + self.assertFalse(u.meter.is_compatible(u.joule)) + + def testConversionFactorTo(self): + """ Tests the "conversion_factor_to" attribute of Units """ + self.assertEqual(u.meter.conversion_factor_to(u.centimeter), 100) + self.assertEqual(u.kilocalorie.conversion_factor_to(u.joule), 4184) + self.assertEqual(u.calorie.conversion_factor_to(u.kilojoule), 4.184e-3) + self.assertEqual((u.kilocalorie/u.mole/u.angstrom).conversion_factor_to( + u.kilojoule/u.mole/u.nanometer), 41.84) + + def testUnitString(self): + """ Test the Unit->str casting functionality """ + # Always alphabetical order + self.assertEqual(str(u.meter * u.second * u.second * u.kilogram), + 'kilogram*meter*second**2') + self.assertEqual(str(u.meter / u.second / u.second / u.kilogram), + 'meter/(kilogram*second**2)') + self.assertEqual(str(u.meter**3), 'meter**3') + + def testToBaseUnit(self): + """ Tests the "get_conversion_factor_to_base_units" method """ + self.assertEqual(u.meter.get_conversion_factor_to_base_units(), 1) + self.assertEqual(u.calorie.get_conversion_factor_to_base_units(), 4.184) + kcpma = u.md_kilocalorie/u.mole/u.angstrom + self.assertEqual(kcpma.get_conversion_factor_to_base_units(), 4.184) + + def testScalarQuantityMultiplyDivide(self): + """ Tests creating a scalar Quantity object by * or / by a Unit """ + self.assertTrue(u.is_quantity(5 * u.centimeters)) + self.assertTrue(u.is_quantity(1 / u.centimeters)) + self.assertTrue(u.is_quantity(10 * u.centimeters)) + self.assertTrue(u.is_quantity(9.81 * u.meters / u.second**2)) + + def testScalarQuantityConstructor(self): + """ Tests creating a Quantity using the Quantity constructor """ + self.assertTrue(u.is_quantity(u.Quantity(5, u.centimeters))) + self.assertTrue(u.is_quantity(u.Quantity(5, u.centimeters**-1))) + x = u.Quantity(value=5.0, unit=100.0*u.meters) + self.assertTrue(u.is_quantity(x)) + self.assertEqual(x, 500*u.meters) + + def testValueInUnit(self): + """ Tests the value_in_unit functionality for Quantity """ + i = 5 * u.centimeters + self.assertEqual(i.value_in_unit(u.millimeters), 50) + self.assertEqual(i / u.millimeters, 50) + + def testCollectionQuantities(self): + """ Tests the use of collections as Quantity values """ + s = [1, 2, 3] * u.centimeters + self.assertEqual(str(s), '[1, 2, 3] cm') + self.assertTrue(u.is_quantity(s)) + s2 = s / u.millimeters + self.assertEqual(s2, [10.0, 20.0, 30.0]) + self.assertEqual(s2, s.value_in_unit(u.millimeters)) + # Test 2-D list + s = [[1, 2, 3], [4, 5, 6]] + s *= u.centimeters + self.assertTrue(u.is_quantity(s)) + s2 = s / u.millimeters + self.assertEqual(s2, [[10.0, 20.0, 30.0], [40.0, 50.0, 60.0]]) + self.assertEqual(s.value_in_unit(u.millimeters), s2) + # Test tuples + s = (1, 2, 3) * u.centimeters + self.assertTrue(u.is_quantity(s)) + self.assertEqual(str(s), '(1, 2, 3) cm') + s2 = s / u.millimeters + self.assertEqual(s2, (10, 20, 30)) + self.assertIsInstance(s2, tuple) + self.assertEqual(s.value_in_unit(u.millimeters), s2) + self.assertIsInstance(s.value_in_unit(u.millimeters), tuple) + x = [1, 2, 3] * u.centimeters + x *= u.meters + self.assertEqual(x, [100, 200, 300] * u.centimeters**2) + + def testReduceUnit(self): + """ Tests the reduce_unit functionality """ + x = u.nanometer**2 / u.angstrom**2 + self.assertEqual(str(x), 'nanometer**2/(angstrom**2)') + self.assertTrue(x.is_dimensionless()) + q = u.Quantity(2.0, x) + self.assertEqual(str(q), '2.0 nm**2/(A**2)') + self.assertEqual(q.reduce_unit(), 200) + + def testCollectionQuantityOperations(self): + """ Tests that Quantity collections behave correctly """ + # Tests that __getitem__ returns a unit + s = [1, 2, 3, 4] * u.angstroms + self.assertTrue(u.is_quantity(s[0])) + for i, val in enumerate(s): + self.assertTrue(u.is_quantity(val)) + self.assertEqual(val, (i+1) * u.angstroms) + # Tests that __setitem__ fails when an incompatible type is added + def fail(s): s[0] = 5 + self.assertRaises(AttributeError, lambda: fail(s)) + def fail(s): s[0] = 5 * u.joules + self.assertRaises(TypeError, lambda: fail(s)) + def fail(s): s[0] /= 10 * u.meters + self.assertRaises(AttributeError, lambda: fail(s)) + # Tests that __setitem__ converts to the unit of the container + s[0] = 1 * u.nanometers + self.assertEqual(s[0]._value, 10) + # Tests standard unit conversions + x = [1, 2, 3] * u.centimeters + self.assertEqual(x / u.millimeters, [10, 20, 30]) + # Test the construction of a container in which each element is a + # Quantity, passed to the Quantity constructor + x = u.Quantity([1*u.angstrom, 2*u.nanometer, 3*u.angstrom]) + self.assertEqual(x._value, [1, 20, 3]) + self.assertEqual(x.unit, u.angstrom) + x = u.Quantity((1, 2, 3)) + self.assertTrue(u.is_quantity(x)) + self.assertTrue(x.unit.is_dimensionless()) + x = u.Quantity(([1*u.angstrom, 2*u.nanometer, 3*u.angstrom], + [1*u.angstrom, 4*u.nanometer, 3*u.angstrom])) + self.assertEqual(x._value, ([1, 20, 3], [1, 40, 3])) + self.assertEqual(x.unit, u.angstrom) + self.assertTrue(u.is_quantity(u.Quantity([]))) + + def testMutableQuantityOperations(self): + " Tests that mutable Quantity objects do not get unexpectedly changed " + # This used to be a bug -- t and s._value were the same object, so + # changing t would also change s silently + s = [1, 2, 3, 4] * u.angstroms + t = s / u.angstroms + self.assertEqual(t, [1, 2, 3, 4]) + self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) + t[0] = 2 + self.assertEqual(t, [2, 2, 3, 4]) + self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) + t = s.value_in_unit(u.angstroms) + self.assertEqual(t, [1, 2, 3, 4]) + self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) + t[0] = 2 + self.assertEqual(t, [2, 2, 3, 4]) + self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) + s = [1, 2, 3, 4] * u.nanometers + self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.nanometers)) + t = s.in_units_of(u.nanometers) + self.assertEqual(s, t) + t[0] = 1 * u.meters + self.assertAlmostEqualQuantities(t, + u.Quantity([1e9, 2, 3, 4], u.nanometers)) + self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.nanometers)) + + def testQuantityMaths(self): + """ Tests dimensional analysis & maths on and b/w Quantity objects """ + x = 1.3 * u.meters + y = 75.2 * u.centimeters + self.assertEqual((x + y) / u.meters, 2.052) + self.assertEqual((x - y) / u.meters, 0.548) + self.assertEqual(x / y, 1.3 / 0.752) + self.assertEqual(x * y, 1.3*0.752*u.meters**2) + d1 = 2.0*u.meters + d2 = 2.0*u.nanometers + self.assertEqual(d1 + d2, (2+2e-9)*u.meters) + self.assertAlmostEqual((d2+d1-(2e9+2)*u.nanometers)._value, 0, places=6) + self.assertEqual(d1 + d1, 4.0*u.meters) + self.assertEqual(d1 - d1, 0.0*u.meters) + self.assertEqual(d1 / d1, 1.0) + self.assertEqual(d1 * u.meters, 2.0*u.meters**2) + self.assertEqual(u.kilograms*(d1/u.seconds)*(d1/u.seconds), + 4*u.kilograms*u.meters**2/u.seconds**2) + self.assertEqual(u.kilograms*(d1/u.seconds)**2, + 4*u.kilograms*u.meters**2/u.seconds**2) + self.assertEqual(d1**3, 8.0*u.meters**3) + x = d1**(3/2) + self.assertAlmostEqual(x._value, math.sqrt(2)**3) + self.assertEqual(x.unit, u.meters**(3/2)) + self.assertAlmostEqual((d1**0.5)._value, math.sqrt(2)) + self.assertEqual((d1**0.5).unit, u.meters**0.5) + comp = (3.0 + 4.0j) * u.meters + self.assertTrue(u.is_quantity(comp)) + self.assertEqual(comp.unit, u.meters) + self.assertEqual(str(comp), '(3+4j) m') + self.assertEqual(comp + comp, (6.0 + 8.0j)*u.meters) + self.assertEqual(comp - comp, 0*u.meters) + self.assertEqual(comp * comp, (3.0 + 4.0j)**2 * u.meters**2) + self.assertAlmostEqual(comp / comp, 1) + self.assertAlmostEqual(1.5*u.nanometers / u.meters, 1.5e-9, places=15) + self.assertEqual((2.3*u.meters)**2, 2.3**2*u.meters**2) + x = 4.3 * u.meters + self.assertEqual(x / u.centimeters, 430) + self.assertEqual(str(x / u.seconds), '4.3 m/s') + self.assertEqual(str(8.4 / (4.2*u.centimeters)), '2.0 /cm') + x = 1.2 * u.meters + self.assertEqual(x * 5, u.Quantity(6.0, u.meters)) + + def testQuantityComplicatedMaths(self): + """ Tests a complicated set of mathematical operations on a Quantity """ + s1 = 2.0 + x1 = 2 + x2 = 4.0 / 3.0 + u1 = u.kilogram * u.meter / u.second**2 + u2 = u1 * u.meter + q1 = 1.0 * u1 + q2 = 2.0 * u2 + self.assertEqual(s1, 2.0) + self.assertEqual(x1, 2) + self.assertAlmostEqual(x2, 1.33333333333333) + self.assertEqual(str(u1), 'kilogram*meter/(second**2)') + self.assertEqual(str(u2), 'kilogram*meter**2/(second**2)') + self.assertEqual(str(q1), '1.0 kg m/(s**2)') + self.assertEqual(str(q2), '2.0 kg m**2/(s**2)') + self.assertEqual(str(u1*s1), '2.0 kg m/(s**2)') + self.assertEqual(str(s1*u1), '2.0 kg m/(s**2)') + self.assertEqual(str(u1/s1), '0.5 kg m/(s**2)') + self.assertEqual(str(s1/u1), '2.0 s**2/(kg m)') + self.assertEqual(str(u1*u1), 'kilogram**2*meter**2/(second**4)') + self.assertEqual(u1/u1, u.dimensionless) + self.assertEqual(str(u1/u1), 'dimensionless') + self.assertEqual(str(u1*u2), 'kilogram**2*meter**3/(second**4)') + self.assertEqual(u1/u2, u.meters**-1) + self.assertEqual(str(u1/u2), '/meter') + self.assertEqual(u1**x1, u.kilogram**2*u.meter**2/(u.second**4)) + self.assertEqual(u1**(1/x1), u.kilogram**0.5*u.meter**0.5/u.second) + self.assertEqual(u1**x2, + u.kilogram**(1+1/3)*u.meter**(1+1/3)/u.second**(2+2/3)) + q = 1.0 * u.md_kilocalorie/u.mole/u.angstrom + self.assertEqual(str(q.in_units_of(u.md_kilojoule/u.mole/u.nanometer)), + '41.84 kJ/(nm mol)') + + def testQuantityComparisons(self): + """ Tests binary comparison operators between Quantity """ + l1 = 1.0 * u.meters + l2 = 2.0 * u.meters + l3 = 1.0 * u.meters + self.assertEqual(l1, l3) + self.assertNotEqual(l1, l2) + self.assertLessEqual(l1, l2) + self.assertLess(l1, l2) + self.assertGreater(l2, l1) + self.assertGreaterEqual(l2, l1) + self.assertLessEqual(l1, l3) + self.assertGreaterEqual(l1, l3) + self.assertGreater(1.2*u.meters, 72*u.centimeters) + self.assertLess(1*u.meters, 200*u.centimeters) + + def testChemistryProblems(self): + """ Tests some gen-chem applications with Quantity's """ + def work(f, dx): + return f * dx + + F = 1.0 * u.kilogram * u.meter / u.second**2 + dx = 1.0 * u.meter + self.assertEqual(work(F, dx), 1.0 * u.joule) + self.assertEqual(F, 1.0 * u.newton) + + def ideal_gas_law(P, V, T): + R = u.MOLAR_GAS_CONSTANT_R + return (P * V / (R * T)).in_units_of(u.mole) + + T = (273.0 + 37.0) * u.kelvin + P = (1.01325e5) * u.pascals + r = 0.5e-6 * u.meters + V = 4/3 * math.pi * r**3 + n = ideal_gas_law(P, V, T) + val = 4/3*math.pi*0.5e-6**3*1 + self.assertAlmostEqualQuantities(P*V, val * u.atmospheres*u.meters**3) + self.assertAlmostEqualQuantities(n, 2.05834818672e-17 * u.mole) + self.assertAlmostEqualQuantities(V, 5.2359833333333e-19 * u.meters**3) + self.assertEqual(str(T), '310.0 K') + self.assertEqual(str(u.MOLAR_GAS_CONSTANT_R), '8.31447247122 J/(K mol)') + self.assertTrue(u.is_quantity(V)) + # Checks trouble with complicated unit conversion factors + p1 = 1.0 * u.atmospheres + p2 = p1.in_units_of(u.joules/u.nanometers**3) + V = 2.4 * u.nanometers**3 + beta = 4.e-4 * u.mole/u.joule + x1 = beta * p1 * V + y1 = x1 * u.AVOGADRO_CONSTANT_NA + self.assertAlmostEqual(y1, 0.0585785776197) + x2 = beta * p2 * V + y2 = x2 * u.AVOGADRO_CONSTANT_NA + self.assertAlmostEqual(y1, y2) + + def testAngleQuantities(self): + """ Tests angle measurements """ + self.assertEqual(1.0*u.radians / u.degrees, 180 / math.pi) + self.assertTrue(u.is_quantity(1.0*u.radians)) + self.assertTrue(u.is_quantity(1.0*u.degrees)) + self.assertEqual((1.0*u.radians).in_units_of(u.degrees), + (180 / math.pi)*u.degrees) + self.assertEqual(90*u.degrees/u.radians, math.pi/2) + q = 90 * u.degrees + 0.3 * u.radians + self.assertEqual(q._value, 90 + 180*0.3/math.pi) + self.assertEqual(q.unit, u.degrees) + + def testIsQuantity(self): + """ Tests if is_quantity can detect Quantities vs. scalars and units """ + self.assertTrue(u.is_quantity(1/u.second)) + self.assertFalse(u.is_quantity(u.second**-1)) + self.assertTrue(u.is_quantity(10*u.meters)) + self.assertFalse(u.is_quantity(10)) + + def testBadQuantityMaths(self): + """ Tests that Maths of incompatible units properly fails """ + self.assertRaises(TypeError, lambda:1*u.meters + 1*u.liters) + self.assertRaises(AttributeError, lambda: 1*u.liters + 5) + + def testBadQuantityComparisons(self): + """ Checks that comparisons of incompatible units fails """ + self.assertRaises(TypeError, lambda: 1*u.meters > 1*u.liters) + self.assertRaises(TypeError, lambda: 1*u.nanometers > 1*u.degrees) + + def testDimensionless(self): + """ Tests the properties of unit.dimensionless """ + x = 5 * u.dimensionless + y = u.Quantity(5, u.dimensionless) + self.assertTrue(u.is_quantity(x)) + self.assertTrue(u.is_quantity(y)) + self.assertNotEqual(x, 5) + self.assertNotEqual(y, 5) + self.assertEqual(x, y) + self.assertEqual(x.value_in_unit_system(u.si_unit_system), 5) + self.assertEqual(x.value_in_unit_system(u.cgs_unit_system), 5) + self.assertEqual(x.value_in_unit_system(u.md_unit_system), 5) + x = u.Quantity(1.0, u.dimensionless) + y = u.Quantity(1.0, u.dimensionless) + self.assertIsNot(x, y) + self.assertEqual(x, y) + + def testTruthiness(self): + """ Tests the truthiness of units """ + true = 2.3 * u.meters + false = 0.0 * u.meters + self.assertTrue(true) + self.assertFalse(false) + self.assertTrue(bool(true)) + self.assertFalse(bool(false)) + + def testUnaryOperators(self): + """ Tests unary operators on units """ + self.assertEqual(-(2.3*u.meters), u.Quantity(-2.3, u.meters)) + self.assertEqual(-(2.3*u.meters), -u.Quantity(2.3, u.meters)) + self.assertEqual(+(2.3*u.meters), u.Quantity(2.3, u.meters)) + self.assertEqual(2.3*u.meters, +u.Quantity(2.3, u.meters)) + + def testUnitMathModule(self): + """ Tests the unit_math functions on Quantity objects """ + self.assertEqual(u.sqrt(1.0*u.kilogram*u.joule), + 1.0*u.kilogram*u.meter/u.second) + self.assertEqual(u.sqrt(1.0*u.kilogram*u.calorie), + math.sqrt(4.184)*u.kilogram*u.meter/u.second) + self.assertEqual(u.sqrt(9), 3) # Test on a scalar + self.assertEqual(u.sin(90*u.degrees), 1) + self.assertEqual(u.sin(math.pi/2*u.radians), 1) + self.assertEqual(u.sin(math.pi/2), 1) + self.assertEqual(u.cos(180*u.degrees), -1) + self.assertEqual(u.cos(math.pi*u.radians), -1) + self.assertEqual(u.cos(math.pi), -1) + self.assertAlmostEqual(u.tan(45*u.degrees), 1) + self.assertAlmostEqual(u.tan(math.pi/4*u.radians), 1) + self.assertAlmostEqual(u.tan(math.pi/4), 1) + acos = u.acos(1.0) + asin = u.asin(1.0) + atan = u.atan(1.0) + self.assertTrue(u.is_quantity(acos)) + self.assertTrue(u.is_quantity(asin)) + self.assertTrue(u.is_quantity(atan)) + self.assertEqual(acos.unit, u.radians) + self.assertEqual(asin.unit, u.radians) + self.assertEqual(atan.unit, u.radians) + self.assertEqual(acos.value_in_unit(u.degrees), 0) + self.assertEqual(acos / u.radians, 0) + self.assertEqual(asin.value_in_unit(u.degrees), 90) + self.assertEqual(asin / u.radians, math.pi/2) + self.assertAlmostEqual(atan.value_in_unit(u.degrees), 45) + self.assertAlmostEqual(atan / u.radians, math.pi/4) + # Check some sequence maths + seq = [1, 2, 3, 4] * u.meters + self.assertEqual(u.sum(seq), 10*u.meters) + self.assertEqual(u.dot(seq, seq), (1+4+9+16)*u.meters**2) + self.assertEqual(u.norm(seq), math.sqrt(30)*u.meters) + + def testUnitMathModuleBadInput(self): + """ Tests that bad units to unit_math fails appropriately """ + self.assertRaises(ArithmeticError, lambda: u.sqrt(9*u.meters)) + self.assertRaises(TypeError, lambda: u.sin(1*u.meters)) + + def testBadQuantityConversions(self): + """ Tests that conversions to incompatible units fails """ + self.assertRaises(TypeError, + lambda: (1.0*u.meters).in_units_of(u.seconds)) + self.assertRaises(TypeError, + lambda: (1.0*u.meters).value_in_unit(u.seconds)) + + def testCreateNewBaseUnit(self): + """ Tests creating a new base unit """ + ms = u.milli * u.second_base_unit + self.assertIsInstance(ms, u.BaseUnit) + self.assertEqual(repr(ms), + 'BaseUnit(base_dim=BaseDimension("time"), name="millisecond", ' + 'symbol="ms")') + self.assertEqual(ms.conversion_factor_to(u.second_base_unit), 0.001) + + def testCreateNewScaledUnit(self): + """ Tests creating a new ScaledUnit """ + mC = u.milli * u.ScaledUnit(4.184, u.joule, "calorie", "cal") + self.assertIsInstance(mC, u.ScaledUnit) + self.assertEqual(repr(mC), + "ScaledUnit(factor=0.004184, master=joule, name='millicalorie'," + " symbol='mcal')") + self.assertFalse(u.is_unit(mC)) + + def testCreateNewUnit(self): + """ Tests creating a new Unit """ + ms = u.milli * u.second + self.assertTrue(u.is_unit(ms)) + self.assertEqual(repr(ms), + 'Unit({BaseUnit(base_dim=BaseDimension("time"), ' + 'name="millisecond", symbol="ms"): 1.0})') + + def testIllegalQuantityOps(self): + """ Test that illegal operations on Quantity objects fails """ + self.assertRaises(TypeError, lambda: u.milli * (1.0 * u.second)) + + def testQuantityFormat(self): + """ Tests the format method on Quantity instances """ + x = 5.439999999 * u.picosecond + self.assertEqual(x.format("%.3f"), '5.440 ps') + + def testQuantityCollectionMethods(self): + """ Tests some sequence methods on Quantity objects (no numpy) """ + seq = [1, 2, 3, 4] * u.meters + self.assertEqual(seq.sum(), 10*u.meters) + self.assertEqual(seq.mean(), 2.5*u.meters) + self.assertEqual(seq.max(), 4*u.meters) + self.assertEqual(seq.min(), 1*u.meters) + self.assertAlmostEqual(seq.std(), 1.1180339887498949*u.meters) + + def testString(self): + """ Tests unit handling with strings, which should be dimensionless """ + s = u.Quantity("string") + self.assertEqual(s.value_in_unit_system(u.md_unit_system), "string") + + def testMisc(self): + """ Miscellaneous tests for the unit package """ + self.assertTrue(u.meter is not None) + self.assertFalse(u.meter is None) + self.assertEqual(repr(1.2*u.meters), 'Quantity(value=1.2, unit=meter)') + class Foo(object): + def bar(self): + return 'bar' + x = Foo() + self.assertEqual(x.bar(), 'bar') + y = x * u.nanometers + self.assertEqual(y.bar(), 'bar') + self.assertEqual(str(u.meters*u.centimeters), 'centimeter*meter') + self.assertEqual(str(u.meters*u.meters), 'meter**2') + self.assertEqual(str(u.meter*u.meter), 'meter**2') + +class TestNumpyUnits(QuantityTestCase): + + def testNumpyQuantity(self): + """ Tests that numpy arrays can form Quantity values """ + q = u.Quantity(np.array([1, 2, 3]), u.centimeters) + self.assertTrue(u.is_quantity(q)) + self.assertIsInstance(q._value, np.ndarray) + self.assertTrue(np.all(q / u.millimeters == np.array([1, 2, 3])*10)) + + def testNumpyDeepCopy(self): + """ Check that deepcopy on numpy array does not strip units """ + x = u.Quantity(np.zeros((2, 3)), u.nanometer) + y = copy.deepcopy(x) + self.assertTrue(np.all(x == y)) + self.assertTrue(u.is_quantity(x)) + self.assertTrue(u.is_quantity(y)) + + def testNumpyDivision(self): + """ Tests that division of numpy Quantities works correctly """ + x = u.Quantity(np.asarray([1., 2.]), u.nanometers) + y = u.Quantity(np.asarray([3., 4.]), u.picoseconds) + xy = x / y + self.assertTrue(u.is_quantity(xy)) + self.assertEqual(xy.unit, u.nanometers/u.picoseconds) + self.assertEqual(xy[0].value_in_unit(u.nanometers/u.picoseconds), 1/3) + self.assertEqual(xy[1].value_in_unit(u.nanometers/u.picoseconds), 0.5) + + def testNumpyIsString(self): + """ Tests the internal _is_string method with numpy Quantities """ + from chemistry.unit.quantity import _is_string + a = np.array([[1, 2, 3], [4, 5, 6]]) + self.assertIsInstance("", str) + self.assertTrue(_is_string("")) + self.assertTrue(_is_string("t")) + self.assertTrue(_is_string("test")) + self.assertFalse(_is_string(3)) + self.assertFalse(_is_string(a)) + + def testNumpyFunctions(self): + """ Tests various numpy attributes that they result in Quantities """ + a = u.Quantity(np.arange(10), u.seconds) + self.assertEqual(a.max(), 9*u.seconds) + self.assertEqual(a.min(), 0*u.seconds) + self.assertEqual(a.mean(), 4.5*u.seconds) + self.assertAlmostEqualQuantities(a.std(), 2.8722813232690143*u.seconds) + b = a.reshape((5, 2)) + self.assertTrue(u.is_quantity(b)) + +if np is None: + # Support lack of numpy + del TestNumpyUnits -- GitLab From f8a101d70b008b46e72a478e95acbab5b4ad0509 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sun, 7 Dec 2014 22:07:48 -0500 Subject: [PATCH 160/338] chemistry.unit -> simtk.unit --- wrappers/python/tests/TestUnits.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/tests/TestUnits.py b/wrappers/python/tests/TestUnits.py index 5be69e609..9c7964196 100644 --- a/wrappers/python/tests/TestUnits.py +++ b/wrappers/python/tests/TestUnits.py @@ -1,5 +1,5 @@ """ -Tests the functionality in the chemistry.unit package. +Tests the functionality in the simtk.unit package. """ from __future__ import division @@ -667,7 +667,7 @@ class TestNumpyUnits(QuantityTestCase): def testNumpyIsString(self): """ Tests the internal _is_string method with numpy Quantities """ - from chemistry.unit.quantity import _is_string + from simtk.unit.quantity import _is_string a = np.array([[1, 2, 3], [4, 5, 6]]) self.assertIsInstance("", str) self.assertTrue(_is_string("")) -- GitLab From 9c6011f8ccac2c5e40fcf6ee4486c2f0b70d67fd Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 9 Dec 2014 10:35:33 -0800 Subject: [PATCH 161/338] Implemented PME for triclinic boxes in reference platform --- platforms/cpu/src/CpuNonbondedForce.cpp | 5 +- platforms/reference/include/ReferencePME.h | 6 +- .../SimTKReference/ReferenceLJCoulombIxn.cpp | 4 +- .../src/SimTKReference/ReferencePME.cpp | 142 +++++++++--------- .../reference/tests/TestReferenceEwald.cpp | 53 +++++++ 5 files changed, 128 insertions(+), 82 deletions(-) diff --git a/platforms/cpu/src/CpuNonbondedForce.cpp b/platforms/cpu/src/CpuNonbondedForce.cpp index 0248ffe01..c13e3aaf2 100644 --- a/platforms/cpu/src/CpuNonbondedForce.cpp +++ b/platforms/cpu/src/CpuNonbondedForce.cpp @@ -190,14 +190,13 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c if (pme) { pme_t pmedata; - RealOpenMM virial[3][3]; pme_init(&pmedata, alphaEwald, numberOfAtoms, meshDim, 5, 1); vector charges(numberOfAtoms); for (int i = 0; i < numberOfAtoms; i++) charges[i] = posq[4*i+3]; - RealOpenMM boxSize[3] = {periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2]}; + RealVec boxVectors[3] = {Vec3(periodicBoxSize[0], 0, 0), Vec3(0, periodicBoxSize[1], 0), Vec3(0, 0, periodicBoxSize[2])}; RealOpenMM recipEnergy = 0.0; - pme_exec(pmedata, atomCoordinates, forces, charges, boxSize, &recipEnergy, virial); + pme_exec(pmedata, atomCoordinates, forces, charges, boxVectors, &recipEnergy); if (totalEnergy) *totalEnergy += recipEnergy; pme_destroy(pmedata); diff --git a/platforms/reference/include/ReferencePME.h b/platforms/reference/include/ReferencePME.h index 8db48d483..b8056008d 100644 --- a/platforms/reference/include/ReferencePME.h +++ b/platforms/reference/include/ReferencePME.h @@ -72,16 +72,14 @@ pme_init(pme_t * ppme, * charge Array of charges (units of e) * box Simulation cell dimensions (nm) * energy Total energy (will be written in units of kJ/mol) - * pme_virial Long-range part of the virial, output. */ int OPENMM_EXPORT pme_exec(pme_t pme, const std::vector& atomCoordinates, std::vector& forces, const std::vector& charges, - const RealOpenMM periodicBoxSize[3], - RealOpenMM * energy, - RealOpenMM pme_virial[3][3]); + const OpenMM::RealVec periodicBoxVectors[3], + RealOpenMM * energy); diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp index 988d8442b..8de3cd3f9 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp @@ -230,15 +230,13 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector if (pme && includeReciprocal) { pme_t pmedata; /* abstract handle for PME data */ - RealOpenMM virial[3][3]; pme_init(&pmedata,alphaEwald,numberOfAtoms,meshDim,5,1); vector charges(numberOfAtoms); for (int i = 0; i < numberOfAtoms; i++) charges[i] = atomParameters[i][QIndex]; - RealOpenMM periodicBoxSize[] = {periodicBoxVectors[0][0], periodicBoxVectors[1][1], periodicBoxVectors[2][2]}; - pme_exec(pmedata,atomCoordinates,forces,charges,periodicBoxSize,&recipEnergy,virial); + pme_exec(pmedata,atomCoordinates,forces,charges,periodicBoxVectors,&recipEnergy); if( totalEnergy ) *totalEnergy += recipEnergy; diff --git a/platforms/reference/src/SimTKReference/ReferencePME.cpp b/platforms/reference/src/SimTKReference/ReferencePME.cpp index 5a5fed614..4d774fa2d 100644 --- a/platforms/reference/src/SimTKReference/ReferencePME.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePME.cpp @@ -192,11 +192,21 @@ pme_calculate_bsplines_moduli(pme_t pme) } +static void invert_box_vectors(const RealVec boxVectors[3], RealVec recipBoxVectors[3]) +{ + RealOpenMM determinant = boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]; + assert(determinant > 0); + RealOpenMM scale = 1.0/determinant; + recipBoxVectors[0] = RealVec(boxVectors[1][1]*boxVectors[2][2], 0, 0)*scale; + recipBoxVectors[1] = RealVec(-boxVectors[1][0]*boxVectors[2][2], boxVectors[0][0]*boxVectors[2][2], 0)*scale; + recipBoxVectors[2] = RealVec(boxVectors[1][0]*boxVectors[2][1]-boxVectors[1][1]*boxVectors[2][0], -boxVectors[0][0]*boxVectors[2][1], boxVectors[0][0]*boxVectors[1][1])*scale; +} static void pme_update_grid_index_and_fraction(pme_t pme, const vector& atomCoordinates, - const RealOpenMM periodicBoxSize[3]) + const RealVec periodicBoxVectors[3], + const RealVec recipBoxVectors[3]) { int i; int d; @@ -205,47 +215,48 @@ pme_update_grid_index_and_fraction(pme_t pme, for(i=0;inatoms;i++) { + /* Index calculation (Look mom, no conditionals!): + * + * Both for Cuda and modern CPUs it is nice to avoid conditionals, but we still need to apply periodic boundary conditions. + * Instead of having loops to add/subtract the box dimension, we do it this way: + * + * 1. First add the box size, to make sure this atom coordinate isnt -0.1 or something. + * After this we assume all fractional box positions are *positive*. + * The reason for this is that we always want to round coordinates _down_ to get + * their grid index, and when taking the integer part of -3.4 we would get -3, not -4 as we want. + * Since we anyway need the grid indices to fall in the central box, it is more convenient + * to first manipulate the coordinates to be positive. + * 2. Convert to integer grid index + * Since we have added a whole box unit in step 1, this index might actually be larger than + * the grid dimension. Examples, assuming 10*10*10nm box and grid dimension 100*100*100 (spacing 0.1 nm): + * + * coordinate is { 0.543 , 6.235 , -0.73 } + * + * x[i][d]/box[d] becomes { 0.0543 , 0.6235 , -0.073 } + * (x[i][d]/box[d] + 1.0) becomes { 1.0543 , 1.6235 , 0.927 } + * (x[i][d]/box[d] + 1.0)*ngrid[d] becomes { 105.43 , 162.35 , 92.7 } + * + * integer part is now { 105 , 162 , 92 } + * + * The fraction is calculates as t-ti, which becomes { 0.43 , 0.35 , 0.7 } + * + * 3. Take the first integer index part (which can be larger than the grid) modulo the grid dimension + * + * Now we get { 5 , 62 , 92 } + * + * Voila, both index and fraction, entirely without conditionals. The one limitation here is that + * we only add one box length, so if the particle had a coordinate <=-10.0, we would be screwed. + * In principle we can of course add 100.0, but that just moves the problem, it doesnt solve it. + * In practice, MD programs will apply PBC to reset particles inside the central box to avoid + * numerical problems, so this shouldnt cause any problems. + * (And, by adding 100.0 box lengths, we would lose a bit of numerical accuracy here!) + */ + RealVec coord = atomCoordinates[i]; + for(d=0;d<3;d++) + coord[d] -= floor(coord[d]*recipBoxVectors[d][d])*periodicBoxVectors[d][d]; for(d=0;d<3;d++) { - /* Index calculation (Look mom, no conditionals!): - * - * Both for Cuda and modern CPUs it is nice to avoid conditionals, but we still need to apply periodic boundary conditions. - * Instead of having loops to add/subtract the box dimension, we do it this way: - * - * 1. First add the box size, to make sure this atom coordinate isnt -0.1 or something. - * After this we assume all fractional box positions are *positive*. - * The reason for this is that we always want to round coordinates _down_ to get - * their grid index, and when taking the integer part of -3.4 we would get -3, not -4 as we want. - * Since we anyway need the grid indices to fall in the central box, it is more convenient - * to first manipulate the coordinates to be positive. - * 2. Convert to integer grid index - * Since we have added a whole box unit in step 1, this index might actually be larger than - * the grid dimension. Examples, assuming 10*10*10nm box and grid dimension 100*100*100 (spacing 0.1 nm): - * - * coordinate is { 0.543 , 6.235 , -0.73 } - * - * x[i][d]/box[d] becomes { 0.0543 , 0.6235 , -0.073 } - * (x[i][d]/box[d] + 1.0) becomes { 1.0543 , 1.6235 , 0.927 } - * (x[i][d]/box[d] + 1.0)*ngrid[d] becomes { 105.43 , 162.35 , 92.7 } - * - * integer part is now { 105 , 162 , 92 } - * - * The fraction is calculates as t-ti, which becomes { 0.43 , 0.35 , 0.7 } - * - * 3. Take the first integer index part (which can be larger than the grid) modulo the grid dimension - * - * Now we get { 5 , 62 , 92 } - * - * Voila, both index and fraction, entirely without conditionals. The one limitation here is that - * we only add one box length, so if the particle had a coordinate <=-10.0, we would be screwed. - * In principle we can of course add 100.0, but that just moves the problem, it doesnt solve it. - * In practice, MD programs will apply PBC to reset particles inside the central box to avoid - * numerical problems, so this shouldnt cause any problems. - * (And, by adding 100.0 box lengths, we would lose a bit of numerical accuracy here!) - */ - RealOpenMM coord = atomCoordinates[i][d]; - coord -= floor(coord/periodicBoxSize[d])*periodicBoxSize[d]; - t = (coord / periodicBoxSize[d])*pme->ngrid[d]; + t = (coord[0]*recipBoxVectors[0][d]+coord[1]*recipBoxVectors[1][d]+coord[2]*recipBoxVectors[2][d])*pme->ngrid[d]; ti = (int) t; pme->particlefraction[i][d] = t - ti; @@ -397,9 +408,9 @@ pme_grid_spread_charge(pme_t pme, const vector& charges) static void pme_reciprocal_convolution(pme_t pme, - const RealOpenMM periodicBoxSize[3], - RealOpenMM * energy, - RealOpenMM pme_virial[3][3]) + const RealVec periodicBoxVectors[3], + const RealVec recipBoxVectors[3], + RealOpenMM * energy) { int kx,ky,kz; int nx,ny,nz; @@ -424,7 +435,7 @@ pme_reciprocal_convolution(pme_t pme, one_4pi_eps = (RealOpenMM) (ONE_4PI_EPS0/pme->epsilon_r); factor = (RealOpenMM) (M_PI*M_PI/(pme->ewaldcoeff*pme->ewaldcoeff)); - boxfactor = (RealOpenMM) (M_PI*periodicBoxSize[0]*periodicBoxSize[1]*periodicBoxSize[2]); + boxfactor = (RealOpenMM) (M_PI*periodicBoxVectors[0][0]*periodicBoxVectors[1][1]*periodicBoxVectors[2][2]); esum = 0; virxx = 0; @@ -442,14 +453,14 @@ pme_reciprocal_convolution(pme_t pme, { /* Calculate frequency. Grid indices in the upper half correspond to negative frequencies! */ mx = (RealOpenMM) ((kxbsplines_moduli[0][kx]; for(ky=0;kybsplines_moduli[1][ky]; for(kz=0;kzgrid + kx*ny*nz + ky*nz + kz; @@ -494,24 +505,9 @@ pme_reciprocal_convolution(pme_t pme, /* Long-range PME contribution to the energy for this frequency */ ets2 = eterm*struct2; esum += ets2; - - /* PME long-range contribution to atomic virial. Since it is symmetric, we only calculate half the matrix inside this loop. */ - vfactor = (factor*m2+1)*2/m2; - virxx += ets2*(vfactor*mhx*mhx-1); - virxy += ets2*vfactor*mhx*mhy; - virxz += ets2*vfactor*mhx*mhz; - viryy += ets2*(vfactor*mhy*mhy-1); - viryz += ets2*vfactor*mhy*mhz; - virzz += ets2*(vfactor*mhz*mhz-1); } } } - pme_virial[0][0] = (RealOpenMM) (0.25*virxx); - pme_virial[1][1] = (RealOpenMM) (0.25*viryy); - pme_virial[2][2] = (RealOpenMM) (0.25*virzz); - pme_virial[0][1] = pme_virial[1][0] = (RealOpenMM) (0.25*virxy); - pme_virial[0][2] = pme_virial[2][0] = (RealOpenMM) (0.25*virxz); - pme_virial[1][2] = pme_virial[2][1] = (RealOpenMM) (0.25*viryz); /* The factor 0.5 is nothing special, but it is better to have it here than inside the loop :-) */ *energy = (RealOpenMM) (0.5*esum); @@ -520,7 +516,7 @@ pme_reciprocal_convolution(pme_t pme, static void pme_grid_interpolate_force(pme_t pme, - const RealOpenMM periodicBoxSize[3], + const RealVec recipBoxVectors[3], const vector& charges, vector& forces) { @@ -610,9 +606,9 @@ pme_grid_interpolate_force(pme_t pme, } } /* Update memory force, note that we multiply by charge and some box stuff */ - forces[i][0] -= q*fx*nx/periodicBoxSize[0]; - forces[i][1] -= q*fy*ny/periodicBoxSize[1]; - forces[i][2] -= q*fz*nz/periodicBoxSize[2]; + forces[i][0] -= q*(fx*nx*recipBoxVectors[0][0]); + forces[i][1] -= q*(fx*nx*recipBoxVectors[1][0]+fy*ny*recipBoxVectors[1][1]); + forces[i][2] -= q*(fx*nx*recipBoxVectors[2][0]+fy*ny*recipBoxVectors[2][1]+fz*nz*recipBoxVectors[2][2]); } } @@ -669,12 +665,14 @@ int pme_exec(pme_t pme, const vector& atomCoordinates, vector& forces, const vector& charges, - const RealOpenMM periodicBoxSize[3], - RealOpenMM* energy, - RealOpenMM pme_virial[3][3]) + const RealVec periodicBoxVectors[3], + RealOpenMM* energy) { /* Routine is called with coordinates in x, a box, and charges in q */ + RealVec recipBoxVectors[3]; + invert_box_vectors(periodicBoxVectors, recipBoxVectors); + /* Before we can do the actual interpolation, we need to recalculate and update * the indices for each particle in the charge grid (initialized in pme_init()), * and what its fractional offset in this grid cell is. @@ -683,7 +681,7 @@ int pme_exec(pme_t pme, /* Update charge grid indices and fractional offsets for each atom. * The indices/fractions are stored internally in the pme datatype */ - pme_update_grid_index_and_fraction(pme,atomCoordinates,periodicBoxSize); + pme_update_grid_index_and_fraction(pme,atomCoordinates,periodicBoxVectors,recipBoxVectors); /* Calculate bsplines (and their differentials) from current fractional coordinates, store in pme structure */ pme_update_bsplines(pme); @@ -695,13 +693,13 @@ int pme_exec(pme_t pme, fftpack_exec_3d(pme->fftplan,FFTPACK_FORWARD,pme->grid,pme->grid); /* solve in k-space */ - pme_reciprocal_convolution(pme,periodicBoxSize,energy,pme_virial); + pme_reciprocal_convolution(pme,periodicBoxVectors,recipBoxVectors,energy); /* do 3d-invfft */ fftpack_exec_3d(pme->fftplan,FFTPACK_BACKWARD,pme->grid,pme->grid); /* Get the particle forces from the grid and bsplines in the pme structure */ - pme_grid_interpolate_force(pme,periodicBoxSize,charges,forces); + pme_grid_interpolate_force(pme,recipBoxVectors,charges,forces); return 0; } diff --git a/platforms/reference/tests/TestReferenceEwald.cpp b/platforms/reference/tests/TestReferenceEwald.cpp index 9ee9512a1..8fe41e63f 100644 --- a/platforms/reference/tests/TestReferenceEwald.cpp +++ b/platforms/reference/tests/TestReferenceEwald.cpp @@ -302,6 +302,58 @@ void testWaterSystem() { } +void testTriclinic() { + // Create a triclinic box containing eight particles. + + ReferencePlatform platform; + System system; + system.setDefaultPeriodicBoxVectors(Vec3(2.5, 0, 0), Vec3(0.5, 3.0, 0), Vec3(0.7, 0.9, 3.5)); + for (int i = 0; i < 8; i++) + system.addParticle(1.0); + NonbondedForce* force = new NonbondedForce(); + system.addForce(force); + force->setNonbondedMethod(NonbondedForce::PME); + force->setCutoffDistance(1.0); + force->setPMEParameters(3.45891, 32, 40, 48); + for (int i = 0; i < 4; i++) + force->addParticle(-1, 0.440104, 0.4184); // Cl parameters + for (int i = 0; i < 4; i++) + force->addParticle(1, 0.332840, 0.0115897); // Na parameters + vector positions(8); + positions[0] = Vec3(1.744, 2.788, 3.162); + positions[1] = Vec3(1.048, 0.762, 2.340); + positions[2] = Vec3(2.489, 1.570, 2.817); + positions[3] = Vec3(1.027, 1.893, 3.271); + positions[4] = Vec3(0.937, 0.825, 0.009); + positions[5] = Vec3(2.290, 1.887, 3.352); + positions[6] = Vec3(1.266, 1.111, 2.894); + positions[7] = Vec3(0.933, 1.862, 3.490); + + // Compute the forces and energy. + + VerletIntegrator integ(0.001); + Context context(system, integ, platform); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + + // Compare them to values computed by Gromacs. + + double expectedEnergy = -963.370; + vector expectedForce(8); + expectedForce[0] = Vec3(4.25253e+01, -1.23503e+02, 1.22139e+02); + expectedForce[1] = Vec3(9.74752e+01, 1.68213e+02, 1.93169e+02); + expectedForce[2] = Vec3(-1.50348e+02, 1.29165e+02, 3.70435e+02); + expectedForce[3] = Vec3(9.18644e+02, -3.52571e+00, -1.34772e+03); + expectedForce[4] = Vec3(-1.61193e+02, 9.01528e+01, -7.12904e+01); + expectedForce[5] = Vec3(2.82630e+02, 2.78029e+01, -3.72864e+02); + expectedForce[6] = Vec3(-1.47454e+02, -2.14448e+02, -3.55789e+02); + expectedForce[7] = Vec3(-8.82195e+02, -7.39132e+01, 1.46202e+03); + for (int i = 0; i < 8; i++) { + ASSERT_EQUAL_VEC(expectedForce[i], state.getForces()[i], 1e-4); + } + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), 1e-4); +} + void testErrorTolerance(NonbondedForce::NonbondedMethod method) { // Create a cloud of random point charges. @@ -409,6 +461,7 @@ int main() { testEwaldPME(); // testEwald2Ions(); // testWaterSystem(); + testTriclinic(); testErrorTolerance(NonbondedForce::Ewald); testErrorTolerance(NonbondedForce::PME); testPMEParameters(); -- GitLab From 4b6f53e5e835f4713ae5e0d447a137303636ddc3 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 10 Dec 2014 11:39:54 -0800 Subject: [PATCH 162/338] Began implementing triclinic boxes for CPU platform --- platforms/cpu/include/CpuNonbondedForce.h | 9 ++- platforms/cpu/src/CpuKernels.cpp | 43 ++++++++++--- platforms/cpu/src/CpuNonbondedForce.cpp | 52 ++++++++++------ platforms/cpu/src/CpuNonbondedForceVec4.cpp | 19 +++++- platforms/cpu/src/CpuNonbondedForceVec8.cpp | 19 +++++- platforms/cpu/tests/TestCpuNonbondedForce.cpp | 62 +++++++++++++++++++ 6 files changed, 167 insertions(+), 37 deletions(-) diff --git a/platforms/cpu/include/CpuNonbondedForce.h b/platforms/cpu/include/CpuNonbondedForce.h index 535360610..c05608383 100644 --- a/platforms/cpu/include/CpuNonbondedForce.h +++ b/platforms/cpu/include/CpuNonbondedForce.h @@ -83,11 +83,11 @@ class CpuNonbondedForce { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param periodicBoxVectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic(float* periodicBoxSize); + void setPeriodic(RealVec* periodicBoxVectors); /**--------------------------------------------------------------------------------------- @@ -161,11 +161,14 @@ protected: bool cutoff; bool useSwitch; bool periodic; + bool triclinic; bool ewald; bool pme; bool tableIsValid; const CpuNeighborList* neighborList; - float periodicBoxSize[3]; + float recipBoxSize[3]; + RealVec periodicBoxVectors[3]; + AlignedArray periodicBoxVec4; float cutoffDistance, switchingDistance; float krf, crf; float alphaEwald; diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 2aa3fd963..0b32dd19f 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -73,6 +73,11 @@ static RealVec& extractBoxSize(ContextImpl& context) { return *(RealVec*) data->periodicBoxSize; } +static RealVec* extractBoxVectors(ContextImpl& context) { + ReferencePlatform::PlatformData* data = reinterpret_cast(context.getPlatformData()); + return (RealVec*) data->periodicBoxVectors; +} + static ReferenceConstraints& extractConstraints(ContextImpl& context) { ReferencePlatform::PlatformData* data = reinterpret_cast(context.getPlatformData()); return *(ReferenceConstraints*) data->constraints; @@ -147,19 +152,36 @@ public: AlignedArray& posq = data.posq; vector& posData = extractPositions(context); - RealVec boxSize = extractBoxSize(context); - double invBoxSize[3] = {1/boxSize[0], 1/boxSize[1], 1/boxSize[2]}; + RealVec* boxVectors = extractBoxVectors(context); + double boxSize[3] = {boxVectors[0][0], boxVectors[1][1], boxVectors[2][2]}; + double invBoxSize[3] = {1/boxVectors[0][0], 1/boxVectors[1][1], 1/boxVectors[2][2]}; + bool triclinic = (boxVectors[0][1] != 0 || boxVectors[0][2] != 0 || boxVectors[1][0] != 0 || boxVectors[1][2] != 0 || boxVectors[2][0] != 0 || boxVectors[2][1] != 0); int numParticles = context.getSystem().getNumParticles(); int numThreads = threads.getNumThreads(); int start = threadIndex*numParticles/numThreads; int end = (threadIndex+1)*numParticles/numThreads; - if (data.isPeriodic) - for (int i = start; i < end; i++) - for (int j = 0; j < 3; j++) { - RealOpenMM x = posData[i][j]; - double base = floor(x*invBoxSize[j])*boxSize[j]; - posq[4*i+j] = (float) (x-base); + if (data.isPeriodic) { + if (triclinic) { + for (int i = start; i < end; i++) { + RealVec pos = posData[i]; + pos -= boxVectors[2]*floor(pos[2]*invBoxSize[2]); + pos -= boxVectors[1]*floor(pos[1]*invBoxSize[1]); + pos -= boxVectors[0]*floor(pos[0]*invBoxSize[0]); + posq[4*i] = (float) pos[0]; + posq[4*i+1] = (float) pos[1]; + posq[4*i+2] = (float) pos[2]; + } + } + else { + for (int i = start; i < end; i++) { + for (int j = 0; j < 3; j++) { + RealOpenMM x = posData[i][j]; + double base = floor(x*invBoxSize[j])*boxSize[j]; + posq[4*i+j] = (float) (x-base); + } } + } + } else for (int i = start; i < end; i++) { posq[4*i] = (float) posData[i][0]; @@ -543,10 +565,11 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo nonbonded->setUseCutoff(nonbondedCutoff, *neighborList, rfDielectric); } if (data.isPeriodic) { + RealVec* boxVectors = extractBoxVectors(context); double minAllowedSize = 1.999999*nonbondedCutoff; - if (boxSize[0] < minAllowedSize || boxSize[1] < minAllowedSize || boxSize[2] < minAllowedSize) + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - nonbonded->setPeriodic(floatBoxSize); + nonbonded->setPeriodic(boxVectors); } if (ewald) nonbonded->setUseEwald(ewaldAlpha, kmax[0], kmax[1], kmax[2]); diff --git a/platforms/cpu/src/CpuNonbondedForce.cpp b/platforms/cpu/src/CpuNonbondedForce.cpp index c13e3aaf2..e72cfb8f6 100644 --- a/platforms/cpu/src/CpuNonbondedForce.cpp +++ b/platforms/cpu/src/CpuNonbondedForce.cpp @@ -103,20 +103,30 @@ void CpuNonbondedForce::setUseSwitchingFunction(float distance) { also been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param periodicBoxVectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void CpuNonbondedForce::setPeriodic(float* periodicBoxSize) { + void CpuNonbondedForce::setPeriodic(RealVec* periodicBoxVectors) { assert(cutoff); - assert(periodicBoxSize[0] >= 2*cutoffDistance); - assert(periodicBoxSize[1] >= 2*cutoffDistance); - assert(periodicBoxSize[2] >= 2*cutoffDistance); + assert(periodicBoxVectors[0][0] >= 2.0*cutoffDistance); + assert(periodicBoxVectors[1][1] >= 2.0*cutoffDistance); + assert(periodicBoxVectors[2][2] >= 2.0*cutoffDistance); periodic = true; - this->periodicBoxSize[0] = periodicBoxSize[0]; - this->periodicBoxSize[1] = periodicBoxSize[1]; - this->periodicBoxSize[2] = periodicBoxSize[2]; + this->periodicBoxVectors[0] = periodicBoxVectors[0]; + this->periodicBoxVectors[1] = periodicBoxVectors[1]; + this->periodicBoxVectors[2] = periodicBoxVectors[2]; + recipBoxSize[0] = (float) (1.0/periodicBoxVectors[0][0]); + recipBoxSize[1] = (float) (1.0/periodicBoxVectors[1][1]); + recipBoxSize[2] = (float) (1.0/periodicBoxVectors[2][2]); + periodicBoxVec4.resize(3); + periodicBoxVec4[0] = fvec4(periodicBoxVectors[0][0], periodicBoxVectors[0][1], periodicBoxVectors[0][2], 0); + periodicBoxVec4[1] = fvec4(periodicBoxVectors[1][0], periodicBoxVectors[1][1], periodicBoxVectors[1][2], 0); + periodicBoxVec4[2] = fvec4(periodicBoxVectors[2][0], periodicBoxVectors[2][1], periodicBoxVectors[2][2], 0); + triclinic = (periodicBoxVectors[0][1] != 0.0 || periodicBoxVectors[0][2] != 0.0 || + periodicBoxVectors[1][0] != 0.0 || periodicBoxVectors[1][2] != 0.0 || + periodicBoxVectors[2][0] != 0.0 || periodicBoxVectors[2][1] != 0.0); } /**--------------------------------------------------------------------------------------- @@ -186,7 +196,7 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c int kmax = (ewald ? max(numRx, max(numRy,numRz)) : 0); float factorEwald = -1 / (4*alphaEwald*alphaEwald); float TWO_PI = 2.0 * PI_M; - float recipCoeff = (float)(ONE_4PI_EPS0*4*PI_M/(periodicBoxSize[0] * periodicBoxSize[1] * periodicBoxSize[2]) /epsilon); + float recipCoeff = (float)(ONE_4PI_EPS0*4*PI_M/(periodicBoxVectors[0][0] * periodicBoxVectors[1][1] * periodicBoxVectors[2][2]) /epsilon); if (pme) { pme_t pmedata; @@ -194,9 +204,8 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c vector charges(numberOfAtoms); for (int i = 0; i < numberOfAtoms; i++) charges[i] = posq[4*i+3]; - RealVec boxVectors[3] = {Vec3(periodicBoxSize[0], 0, 0), Vec3(0, periodicBoxSize[1], 0), Vec3(0, 0, periodicBoxSize[2])}; RealOpenMM recipEnergy = 0.0; - pme_exec(pmedata, atomCoordinates, forces, charges, boxVectors, &recipEnergy); + pme_exec(pmedata, atomCoordinates, forces, charges, periodicBoxVectors, &recipEnergy); if (totalEnergy) *totalEnergy += recipEnergy; pme_destroy(pmedata); @@ -208,7 +217,7 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c // setup reciprocal box - float recipBoxSize[3] = { TWO_PI / periodicBoxSize[0], TWO_PI / periodicBoxSize[1], TWO_PI / periodicBoxSize[2]}; + float recipBoxSize[3] = { TWO_PI / periodicBoxVectors[0][0], TWO_PI / periodicBoxVectors[1][1], TWO_PI / periodicBoxVectors[2][2]}; // setup K-vectors @@ -329,8 +338,8 @@ void CpuNonbondedForce::threadComputeDirect(ThreadPool& threads, int threadIndex threadEnergy[threadIndex] = 0; double* energyPtr = (includeEnergy ? &threadEnergy[threadIndex] : NULL); float* forces = &(*threadForce)[threadIndex][0]; - fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); - fvec4 invBoxSize((1/periodicBoxSize[0]), (1/periodicBoxSize[1]), (1/periodicBoxSize[2]), 0); + fvec4 boxSize(periodicBoxVectors[0][0], periodicBoxVectors[1][1], periodicBoxVectors[2][2], 0); + fvec4 invBoxSize(recipBoxSize[0], recipBoxSize[1], recipBoxSize[2], 0); if (ewald || pme) { // Compute the interactions from the neighbor list. @@ -343,8 +352,8 @@ void CpuNonbondedForce::threadComputeDirect(ThreadPool& threads, int threadIndex // Now subtract off the exclusions, since they were implicitly included in the reciprocal space sum. - fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); - fvec4 invBoxSize((1/periodicBoxSize[0]), (1/periodicBoxSize[1]), (1/periodicBoxSize[2]), 0); + fvec4 boxSize(periodicBoxVectors[0][0], periodicBoxVectors[1][1], periodicBoxVectors[2][2], 0); + fvec4 invBoxSize(recipBoxSize[0], recipBoxSize[1], recipBoxSize[2], 0); for (int i = threadIndex; i < numberOfAtoms; i += numThreads) { fvec4 posI((float) atomCoordinates[i][0], (float) atomCoordinates[i][1], (float) atomCoordinates[i][2], 0.0f); for (set::const_iterator iter = exclusions[i].begin(); iter != exclusions[i].end(); ++iter) { @@ -453,8 +462,15 @@ void CpuNonbondedForce::calculateOneIxn(int ii, int jj, float* forces, double* t void CpuNonbondedForce::getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& deltaR, float& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { deltaR = posJ-posI; if (periodic) { - fvec4 base = round(deltaR*invBoxSize)*boxSize; - deltaR = deltaR-base; + if (triclinic) { + deltaR -= periodicBoxVec4[2]*floor(deltaR[2]*recipBoxSize[2]+0.5f); + deltaR -= periodicBoxVec4[1]*floor(deltaR[1]*recipBoxSize[1]+0.5f); + deltaR -= periodicBoxVec4[0]*floor(deltaR[0]*recipBoxSize[0]+0.5f); + } + else { + fvec4 base = round(deltaR*invBoxSize)*boxSize; + deltaR = deltaR-base; + } } r2 = dot3(deltaR, deltaR); } diff --git a/platforms/cpu/src/CpuNonbondedForceVec4.cpp b/platforms/cpu/src/CpuNonbondedForceVec4.cpp index a8d42e849..dfe8854aa 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec4.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec4.cpp @@ -262,9 +262,22 @@ void CpuNonbondedForceVec4::getDeltaR(const float* posI, const fvec4& x, const f dy = y-posI[1]; dz = z-posI[2]; if (periodic) { - dx -= round(dx*invBoxSize[0])*boxSize[0]; - dy -= round(dy*invBoxSize[1])*boxSize[1]; - dz -= round(dz*invBoxSize[2])*boxSize[2]; + if (triclinic) { + fvec4 scale3 = floor(dz*recipBoxSize[2]+0.5f); + dx -= scale3*periodicBoxVectors[2][0]; + dy -= scale3*periodicBoxVectors[2][1]; + dz -= scale3*periodicBoxVectors[2][2]; + fvec4 scale2 = floor(dy*recipBoxSize[1]+0.5f); + dx -= scale2*periodicBoxVectors[1][0]; + dy -= scale2*periodicBoxVectors[1][1]; + fvec4 scale1 = floor(dx*recipBoxSize[0]+0.5f); + dx -= scale1*periodicBoxVectors[0][0]; + } + else { + dx -= round(dx*invBoxSize[0])*boxSize[0]; + dy -= round(dy*invBoxSize[1])*boxSize[1]; + dz -= round(dz*invBoxSize[2])*boxSize[2]; + } } r2 = dx*dx + dy*dy + dz*dz; } diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index 175bb6951..fda08f3f4 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -292,9 +292,22 @@ void CpuNonbondedForceVec8::getDeltaR(const float* posI, const fvec8& x, const f dy = y-posI[1]; dz = z-posI[2]; if (periodic) { - dx -= round(dx*invBoxSize[0])*boxSize[0]; - dy -= round(dy*invBoxSize[1])*boxSize[1]; - dz -= round(dz*invBoxSize[2])*boxSize[2]; + if (triclinic) { + fvec8 scale3 = floor(dz*recipBoxSize[2]+0.5f); + dx -= scale3*periodicBoxVectors[2][0]; + dy -= scale3*periodicBoxVectors[2][1]; + dz -= scale3*periodicBoxVectors[2][2]; + fvec8 scale2 = floor(dy*recipBoxSize[1]+0.5f); + dx -= scale2*periodicBoxVectors[1][0]; + dy -= scale2*periodicBoxVectors[1][1]; + fvec8 scale1 = floor(dx*recipBoxSize[0]+0.5f); + dx -= scale1*periodicBoxVectors[0][0]; + } + else { + dx -= round(dx*invBoxSize[0])*boxSize[0]; + dy -= round(dy*invBoxSize[1])*boxSize[1]; + dz -= round(dz*invBoxSize[2])*boxSize[2]; + } } r2 = dx*dx + dy*dy + dz*dz; } diff --git a/platforms/cpu/tests/TestCpuNonbondedForce.cpp b/platforms/cpu/tests/TestCpuNonbondedForce.cpp index 2dd2ebc13..21a150f00 100644 --- a/platforms/cpu/tests/TestCpuNonbondedForce.cpp +++ b/platforms/cpu/tests/TestCpuNonbondedForce.cpp @@ -353,6 +353,67 @@ void testPeriodic() { ASSERT_EQUAL_TOL(2*ONE_4PI_EPS0*(1.0)*(1.0+krf*1.0-crf), state.getPotentialEnergy(), TOL); } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + NonbondedForce* nonbonded = new NonbondedForce(); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + const double eps = 78.3; + const double krf = (1.0/(cutoff*cutoff*cutoff))*(eps-1.0)/(2.0*eps+1.0); + const double crf = (1.0/cutoff)*(3.0*eps)/(2.0*eps+1.0); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta*ONE_4PI_EPS0*(-1.0/(distance*distance*distance)+2.0*krf); + ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(1.0/distance+krf*distance*distance-crf), state.getPotentialEnergy(), 1e-4); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} void testLargeSystem() { const int numMolecules = 600; @@ -635,6 +696,7 @@ int main(int argc, char* argv[]) { testCutoff(); testCutoff14(); testPeriodic(); + testTriclinic(); testLargeSystem(); testDispersionCorrection(); testChangingParameters(); -- GitLab From 34ddae9645d9990e19786f13416878daebb17b46 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 11 Dec 2014 14:02:50 -0800 Subject: [PATCH 163/338] ReferenceNeighborList correctly handles triclinic boxes --- .../SimTKReference/ReferenceNeighborList.cpp | 38 ++++++++---- .../tests/TestReferenceNeighborList.cpp | 59 ++++++++++++------- 2 files changed, 65 insertions(+), 32 deletions(-) diff --git a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp index 5076ba385..fbd8dbc9c 100644 --- a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp @@ -116,7 +116,7 @@ public: int x = int(floor(r[0]/voxelSizeX)); int y = int(floor(r[1]/voxelSizeY)); int z = int(floor(r[2]/voxelSizeZ)); - + return VoxelIndex(x, y, z); } @@ -147,19 +147,33 @@ public: int dIndexY = int(maxDistance / voxelSizeY) + 1; int dIndexZ = int(maxDistance / voxelSizeZ) + 1; VoxelIndex centerVoxelIndex = getVoxelIndex(locationI); - int lastx = centerVoxelIndex.x+dIndexX; - int lasty = centerVoxelIndex.y+dIndexY; - int lastz = centerVoxelIndex.z+dIndexZ; - if (usePeriodic) { - lastx = min(lastx, centerVoxelIndex.x-dIndexX+nx-1); - lasty = min(lasty, centerVoxelIndex.y-dIndexY+ny-1); - lastz = min(lastz, centerVoxelIndex.z-dIndexZ+nz-1); - } - for (int x = centerVoxelIndex.x - dIndexX; x <= lastx; ++x) + int minz = centerVoxelIndex.z-dIndexZ; + int maxz = centerVoxelIndex.z+dIndexZ; + if (usePeriodic) + maxz = min(maxz, minz+nz-1); + for (int z = minz; z <= maxz; ++z) { - for (int y = centerVoxelIndex.y - dIndexY; y <= lasty; ++y) + int boxz = (int) floor((float) z/nz); + int miny = centerVoxelIndex.y-dIndexY; + int maxy = centerVoxelIndex.y+dIndexY; + if (usePeriodic) { + int yoffset = (int) ceil(boxz*periodicBoxVectors[2][1]/voxelSizeY); + miny -= yoffset; + maxy -= yoffset-1; + maxy = min(maxy, miny+ny-1); + } + for (int y = miny; y <= maxy; ++y) { - for (int z = centerVoxelIndex.z - dIndexZ; z <= lastz; ++z) + int boxy = (int) floor((float) y/ny); + int minx = centerVoxelIndex.x-dIndexX; + int maxx = centerVoxelIndex.x+dIndexX; + if (usePeriodic) { + int xoffset = (int) ceil((boxy*periodicBoxVectors[1][0]+boxz*periodicBoxVectors[2][0])/voxelSizeX); + minx -= xoffset; + maxx -= xoffset-1; + maxx = min(maxx, minx+nx-1); + } + for (int x = minx; x <= maxx; ++x) { VoxelIndex voxelIndex(x, y, z); if (usePeriodic) { diff --git a/platforms/reference/tests/TestReferenceNeighborList.cpp b/platforms/reference/tests/TestReferenceNeighborList.cpp index f82cd45b0..7df30cc55 100644 --- a/platforms/reference/tests/TestReferenceNeighborList.cpp +++ b/platforms/reference/tests/TestReferenceNeighborList.cpp @@ -62,29 +62,24 @@ void testNeighborList() assert(neighborList.size() == 0); } -double periodicDifference(double val1, double val2, double period) { - double diff = val1-val2; - double base = floor(diff/period+0.5)*period; - return diff-base; +double distance2(RealVec& pos1, RealVec& pos2, const RealVec* periodicBoxVectors) { + RealVec diff = pos1-pos2; + diff -= periodicBoxVectors[2]*floor(diff[2]/periodicBoxVectors[2][2]+0.5); + diff -= periodicBoxVectors[1]*floor(diff[1]/periodicBoxVectors[1][1]+0.5); + diff -= periodicBoxVectors[0]*floor(diff[0]/periodicBoxVectors[0][0]+0.5); + return diff.dot(diff); } -double distance2(RealVec& pos1, RealVec& pos2, const RealVec& periodicBoxSize) { - double dx = periodicDifference(pos1[0], pos2[0], periodicBoxSize[0]); - double dy = periodicDifference(pos1[1], pos2[1], periodicBoxSize[1]); - double dz = periodicDifference(pos1[2], pos2[2], periodicBoxSize[2]); - return dx*dx+dy*dy+dz*dz; -} - -void verifyNeighborList(NeighborList& list, int numParticles, vector& positions, const RealVec& periodicBoxSize, double cutoff) { +void verifyNeighborList(NeighborList& list, int numParticles, vector& positions, const RealVec* periodicBoxVectors, double cutoff) { for (int i = 0; i < (int) list.size(); i++) { int particle1 = list[i].first; int particle2 = list[i].second; - ASSERT(distance2(positions[particle1], positions[particle2], periodicBoxSize) <= cutoff*cutoff); + ASSERT(distance2(positions[particle1], positions[particle2], periodicBoxVectors) <= cutoff*cutoff); } int count = 0; for (int i = 0; i < numParticles; i++) for (int j = i+1; j < numParticles; j++) - if (distance2(positions[i], positions[j], periodicBoxSize) <= cutoff*cutoff) + if (distance2(positions[i], positions[j], periodicBoxVectors) <= cutoff*cutoff) count++; ASSERT_EQUAL(count, list.size()); } @@ -92,7 +87,6 @@ void verifyNeighborList(NeighborList& list, int numParticles, vector& p void testPeriodic() { const int numParticles = 100; const double cutoff = 3.0; - const RealVec periodicBoxSize(20.0, 15.0, 22.0); RealVec periodicBoxVectors[3]; periodicBoxVectors[0] = RealVec(20, 0, 0); periodicBoxVectors[1] = RealVec(0, 15, 0); @@ -102,16 +96,40 @@ void testPeriodic() { init_gen_rand(0, sfmt); for (int i = 0; i > exclusions(numParticles); + NeighborList neighborList; + computeNeighborListNaive(neighborList, numParticles, particleList, exclusions, periodicBoxVectors, true, cutoff); + verifyNeighborList(neighborList, numParticles, particleList, periodicBoxVectors, cutoff); + computeNeighborListVoxelHash(neighborList, numParticles, particleList, exclusions, periodicBoxVectors, true, cutoff); + verifyNeighborList(neighborList, numParticles, particleList, periodicBoxVectors, cutoff); +} + +void testTriclinic() { + const int numParticles = 1000; + const double cutoff = 3.0; + RealVec periodicBoxVectors[3]; + periodicBoxVectors[0] = RealVec(20, 0, 0); + periodicBoxVectors[1] = RealVec(5, 15, 0); + periodicBoxVectors[2] = RealVec(-3, -7, 22); + vector particleList(numParticles); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + + for (int i = 0; i > exclusions(numParticles); NeighborList neighborList; computeNeighborListNaive(neighborList, numParticles, particleList, exclusions, periodicBoxVectors, true, cutoff); - verifyNeighborList(neighborList, numParticles, particleList, periodicBoxSize, cutoff); + verifyNeighborList(neighborList, numParticles, particleList, periodicBoxVectors, cutoff); computeNeighborListVoxelHash(neighborList, numParticles, particleList, exclusions, periodicBoxVectors, true, cutoff); - verifyNeighborList(neighborList, numParticles, particleList, periodicBoxSize, cutoff); + verifyNeighborList(neighborList, numParticles, particleList, periodicBoxVectors, cutoff); } int main() @@ -119,6 +137,7 @@ int main() try { testNeighborList(); testPeriodic(); + testTriclinic(); } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From 4193a41602a38dc4e0b642a9b33fc7483cf16d73 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 16 Dec 2014 13:59:17 -0800 Subject: [PATCH 164/338] CpuNeighborList correctly handles triclinic boxes --- platforms/cpu/include/CpuNeighborList.h | 7 +- platforms/cpu/src/CpuNeighborList.cpp | 229 +++++++++++------- platforms/cpu/src/CpuNonbondedForce.cpp | 6 +- platforms/cpu/tests/TestCpuNeighborList.cpp | 36 ++- .../SimTKReference/ReferenceNeighborList.cpp | 12 +- 5 files changed, 179 insertions(+), 111 deletions(-) diff --git a/platforms/cpu/include/CpuNeighborList.h b/platforms/cpu/include/CpuNeighborList.h index 6e16785c5..a602cc6d2 100644 --- a/platforms/cpu/include/CpuNeighborList.h +++ b/platforms/cpu/include/CpuNeighborList.h @@ -33,6 +33,7 @@ * -------------------------------------------------------------------------- */ #include "AlignedArray.h" +#include "RealVec.h" #include "windowsExportCpu.h" #include "openmm/internal/ThreadPool.h" #include @@ -40,12 +41,14 @@ #include namespace OpenMM { - + class OPENMM_EXPORT_CPU CpuNeighborList { public: class ThreadTask; class Voxels; CpuNeighborList(int blockSize); + void computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const std::vector >& exclusions, + const RealVec* periodicBoxVectors, bool usePeriodic, float maxDistance, ThreadPool& threads); void computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const std::vector >& exclusions, const float* periodicBoxSize, bool usePeriodic, float maxDistance, ThreadPool& threads); int getNumBlocks() const; @@ -68,7 +71,7 @@ private: Voxels* voxels; const std::vector >* exclusions; const float* atomLocations; - const float* periodicBoxSize; + RealVec periodicBoxVectors[3]; int numAtoms; bool usePeriodic; float maxDistance; diff --git a/platforms/cpu/src/CpuNeighborList.cpp b/platforms/cpu/src/CpuNeighborList.cpp index 6c819ea52..d3919ddd6 100644 --- a/platforms/cpu/src/CpuNeighborList.cpp +++ b/platforms/cpu/src/CpuNeighborList.cpp @@ -45,12 +45,12 @@ namespace OpenMM { class VoxelIndex { public: - VoxelIndex() : x(0), y(0) { + VoxelIndex() : y(0), z(0) { } - VoxelIndex(int x, int y) : x(x), y(y) { + VoxelIndex(int y, int z) : y(y), z(z) { } - int x; int y; + int z; }; /** @@ -59,26 +59,35 @@ public: */ class CpuNeighborList::Voxels { public: - Voxels(int blockSize, float vsx, float vsy, float minx, float maxx, float miny, float maxy, const float* periodicBoxSize, bool usePeriodic) : - blockSize(blockSize), voxelSizeX(vsx), voxelSizeY(vsy), minx(minx), maxx(maxx), miny(miny), maxy(maxy), periodicBoxSize(periodicBoxSize), usePeriodic(usePeriodic) { + Voxels(int blockSize, float vsy, float vsz, float miny, float maxy, float minz, float maxz, const RealVec* periodicBoxVectors, bool usePeriodic) : + blockSize(blockSize), voxelSizeY(vsy), voxelSizeZ(vsz), miny(miny), maxy(maxy), minz(minz), maxz(maxz), periodicBoxVectors(periodicBoxVectors), usePeriodic(usePeriodic) { + periodicBoxSize[0] = (float) periodicBoxVectors[0][0]; + periodicBoxSize[1] = (float) periodicBoxVectors[1][1]; + periodicBoxSize[2] = (float) periodicBoxVectors[2][2]; + recipBoxSize[0] = (float) (1/periodicBoxVectors[0][0]); + recipBoxSize[1] = (float) (1/periodicBoxVectors[1][1]); + recipBoxSize[2] = (float) (1/periodicBoxVectors[2][2]); + triclinic = (periodicBoxVectors[0][1] != 0.0 || periodicBoxVectors[0][2] != 0.0 || + periodicBoxVectors[1][0] != 0.0 || periodicBoxVectors[1][2] != 0.0 || + periodicBoxVectors[2][0] != 0.0 || periodicBoxVectors[2][1] != 0.0); if (usePeriodic) { - nx = (int) floorf(periodicBoxSize[0]/voxelSizeX+0.5f); - ny = (int) floorf(periodicBoxSize[1]/voxelSizeY+0.5f); - voxelSizeX = periodicBoxSize[0]/nx; - voxelSizeY = periodicBoxSize[1]/ny; + ny = (int) floorf(periodicBoxVectors[1][1]/voxelSizeY+0.5f); + nz = (int) floorf(periodicBoxVectors[2][2]/voxelSizeZ+0.5f); + voxelSizeY = periodicBoxVectors[1][1]/ny; + voxelSizeZ = periodicBoxVectors[2][2]/nz; } else { - nx = max(1, (int) floorf((maxx-minx)/voxelSizeX+0.5f)); ny = max(1, (int) floorf((maxy-miny)/voxelSizeY+0.5f)); - if (maxx > minx) - voxelSizeX = (maxx-minx)/nx; + nz = max(1, (int) floorf((maxz-minz)/voxelSizeZ+0.5f)); if (maxy > miny) voxelSizeY = (maxy-miny)/ny; + if (maxz > minz) + voxelSizeZ = (maxz-minz)/nz; } - bins.resize(nx); - for (int i = 0; i < nx; i++) { - bins[i].resize(ny); - for (int j = 0; j < ny; j++) + bins.resize(ny); + for (int i = 0; i < ny; i++) { + bins[i].resize(nz); + for (int j = 0; j < nz; j++) bins[i][j].resize(0); } } @@ -88,28 +97,28 @@ public: */ void insert(const int& atom, const float* location) { VoxelIndex voxelIndex = getVoxelIndex(location); - bins[voxelIndex.x][voxelIndex.y].push_back(make_pair(location[2], atom)); + bins[voxelIndex.y][voxelIndex.z].push_back(make_pair(location[0], atom)); } /** - * Sort the particles in each voxel by z coordinate. + * Sort the particles in each voxel by x coordinate. */ void sortItems() { - for (int i = 0; i < nx; i++) - for (int j = 0; j < ny; j++) + for (int i = 0; i < ny; i++) + for (int j = 0; j < nz; j++) sort(bins[i][j].begin(), bins[i][j].end()); } /** - * Find the index of the first particle in voxel (x,y) whose z coordinate in >= the specified value. + * Find the index of the first particle in voxel (y,z) whose x coordinate in >= the specified value. */ - int findLowerBound(int x, int y, double z) const { - const vector >& bin = bins[x][y]; + int findLowerBound(int y, int z, double x) const { + const vector >& bin = bins[y][z]; int lower = 0; int upper = bin.size(); while (lower < upper) { int middle = (lower+upper)/2; - if (bin[middle].first < z) + if (bin[middle].first < x) lower = middle+1; else upper = middle; @@ -118,15 +127,15 @@ public: } /** - * Find the index of the first particle in voxel (x,y) whose z coordinate in greater than the specified value. + * Find the index of the first particle in voxel (y,z) whose x coordinate in greater than the specified value. */ - int findUpperBound(int x, int y, double z) const { - const vector >& bin = bins[x][y]; + int findUpperBound(int y, int z, double x) const { + const vector >& bin = bins[y][z]; int lower = 0; int upper = bin.size(); while (lower < upper) { int middle = (lower+upper)/2; - if (bin[middle].first > z) + if (bin[middle].first > x) upper = middle; else lower = middle+1; @@ -138,121 +147,144 @@ public: * Get the voxel index containing a particular location. */ VoxelIndex getVoxelIndex(const float* location) const { - float xperiodic, yperiodic; + float yperiodic, zperiodic; if (!usePeriodic) { - xperiodic = location[0]-minx; yperiodic = location[1]-miny; + zperiodic = location[2]-minz; } else { - xperiodic = location[0]-periodicBoxSize[0]*floorf(location[0]/periodicBoxSize[0]); - yperiodic = location[1]-periodicBoxSize[1]*floorf(location[1]/periodicBoxSize[1]); + float scale2 = floorf(location[2]*recipBoxSize[2]); + yperiodic = location[1]-periodicBoxVectors[2][1]*scale2; + zperiodic = location[2]-periodicBoxVectors[2][2]*scale2; + float scale1 = floorf(yperiodic*recipBoxSize[1]); + yperiodic -= periodicBoxVectors[1][0]*scale1; } - int x = min(nx-1, int(floorf(xperiodic / voxelSizeX))); int y = min(ny-1, int(floorf(yperiodic / voxelSizeY))); + int z = min(nz-1, int(floorf(zperiodic / voxelSizeZ))); - return VoxelIndex(x, y); + return VoxelIndex(y, z); } void getNeighbors(vector& neighbors, int blockIndex, const fvec4& blockCenter, const fvec4& blockWidth, const vector& sortedAtoms, vector& exclusions, float maxDistance, const vector& blockAtoms, const float* atomLocations, const vector& atomVoxelIndex) const { neighbors.resize(0); exclusions.resize(0); fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); - fvec4 invBoxSize(1/periodicBoxSize[0], 1/periodicBoxSize[1], 1/periodicBoxSize[2], 0); - + fvec4 invBoxSize(recipBoxSize[0], recipBoxSize[1], recipBoxSize[2], 0); + fvec4 periodicBoxVec4[3]; + periodicBoxVec4[0] = fvec4(periodicBoxVectors[0][0], periodicBoxVectors[0][1], periodicBoxVectors[0][2], 0); + periodicBoxVec4[1] = fvec4(periodicBoxVectors[1][0], periodicBoxVectors[1][1], periodicBoxVectors[1][2], 0); + periodicBoxVec4[2] = fvec4(periodicBoxVectors[2][0], periodicBoxVectors[2][1], periodicBoxVectors[2][2], 0); + float maxDistanceSquared = maxDistance * maxDistance; float refineCutoff = maxDistance-max(max(blockWidth[0], blockWidth[1]), blockWidth[2]); float refineCutoffSquared = refineCutoff*refineCutoff; - int dIndexX = int((maxDistance+blockWidth[0])/voxelSizeX)+1; // How may voxels away do we have to look? - int dIndexY = int((maxDistance+blockWidth[1])/voxelSizeY)+1; + int dIndexY = int((maxDistance+blockWidth[1])/voxelSizeY)+1; // How may voxels away do we have to look? + int dIndexZ = int((maxDistance+blockWidth[2])/voxelSizeZ)+1; if (usePeriodic) { - dIndexX = min(nx/2, dIndexX); dIndexY = min(ny/2, dIndexY); + dIndexZ = min(nz/2, dIndexZ); } float centerPos[4]; blockCenter.store(centerPos); VoxelIndex centerVoxelIndex = getVoxelIndex(centerPos); - int startx = centerVoxelIndex.x-dIndexX; - int starty = centerVoxelIndex.y-dIndexY; - int endx = centerVoxelIndex.x+dIndexX; - int endy = centerVoxelIndex.y+dIndexY; - int numRanges; - if (usePeriodic) { - endx = min(endx, centerVoxelIndex.x-dIndexX+nx-1); - endy = min(endy, centerVoxelIndex.y-dIndexY+ny-1); - } + + // Loop over voxels along the z axis. + + int startz = centerVoxelIndex.z-dIndexZ; + int endz = centerVoxelIndex.z+dIndexZ; + if (usePeriodic) + endz = min(endz, startz+nz-1); else { - startx = max(startx, 0); - starty = max(starty, 0); - endx = min(endx, nx-1); - endy = min(endy, ny-1); + startz = max(startz, 0); + endz = min(endz, nz-1); } int lastSortedIndex = blockSize*(blockIndex+1); VoxelIndex voxelIndex(0, 0); - for (int x = startx; x <= endx; ++x) { - voxelIndex.x = x; + for (int z = startz; z <= endz; ++z) { + voxelIndex.z = z; if (usePeriodic) - voxelIndex.x = (x < 0 ? x+nx : (x >= nx ? x-nx : x)); + voxelIndex.z = (z < 0 ? z+nz : (z >= nz ? z-nz : z)); + + // Loop over voxels along the y axis. + + int boxz = (int) floor((float) z/nz); + int starty = centerVoxelIndex.y-dIndexY; + int endy = centerVoxelIndex.y+dIndexY; + float yoffset = (float) (usePeriodic ? boxz*periodicBoxVectors[2][1] : 0); + if (usePeriodic) { + starty -= (int) ceil(yoffset/voxelSizeY); + endy -= (int) floor(yoffset/voxelSizeY); + endy = min(endy, starty+ny-1); + } + else { + starty = max(starty, 0); + endy = min(endy, ny-1); + } for (int y = starty; y <= endy; ++y) { voxelIndex.y = y; if (usePeriodic) voxelIndex.y = (y < 0 ? y+ny : (y >= ny ? y-ny : y)); + int boxy = (int) floor((float) y/ny); + float xoffset = (float) (usePeriodic ? boxy*periodicBoxVectors[1][0]+boxz*periodicBoxVectors[2][0] : 0); // Identify the range of atoms within this bin we need to search. When using periodic boundary // conditions, there may be two separate ranges. - float minz = centerPos[2]; - float maxz = centerPos[2]; - fvec4 offset(voxelSizeX*x+(usePeriodic ? 0.0f : minx), voxelSizeY*y+(usePeriodic ? 0.0f : miny), 0, 0); + float minx = centerPos[0]; + float maxx = centerPos[0]; + fvec4 offset(-xoffset, -yoffset+voxelSizeY*y+(usePeriodic ? 0.0f : miny), voxelSizeZ*z+(usePeriodic ? 0.0f : minz), 0); for (int k = 0; k < (int) blockAtoms.size(); k++) { const float* atomPos = &atomLocations[4*blockAtoms[k]]; fvec4 posVec(atomPos); fvec4 delta1 = offset-posVec; - fvec4 delta2 = delta1+fvec4(voxelSizeX, voxelSizeY, 0, 0); + fvec4 delta2 = delta1+fvec4(0, voxelSizeY, voxelSizeZ, 0); if (usePeriodic) { delta1 -= round(delta1*invBoxSize)*boxSize; delta2 -= round(delta2*invBoxSize)*boxSize; } fvec4 delta = min(abs(delta1), abs(delta2)); - float dx = (x == atomVoxelIndex[k].x ? 0.0f : delta[0]); float dy = (y == atomVoxelIndex[k].y ? 0.0f : delta[1]); - float dist2 = maxDistanceSquared-dx*dx-dy*dy; + float dz = (z == atomVoxelIndex[k].z ? 0.0f : delta[2]); + float dist2 = maxDistanceSquared-dy*dy-dz*dz; if (dist2 > 0) { float dist = sqrtf(dist2); - minz = min(minz, atomPos[2]-dist); - maxz = max(maxz, atomPos[2]+dist); + minx = min(minx, atomPos[0]-dist-xoffset); + maxx = max(maxx, atomPos[0]+dist-xoffset); } } - if (minz == maxz) + if (minx == maxx) continue; - bool needPeriodic = (centerPos[0]-blockWidth[0] < maxDistance || centerPos[0]+blockWidth[0] > periodicBoxSize[0]-maxDistance || - centerPos[1]-blockWidth[1] < maxDistance || centerPos[1]+blockWidth[1] > periodicBoxSize[1]-maxDistance || - minz < 0.0f || maxz > periodicBoxSize[2]); + bool needPeriodic = (centerPos[1]-blockWidth[1] < maxDistance || centerPos[1]+blockWidth[1] > periodicBoxSize[1]-maxDistance || + centerPos[2]-blockWidth[2] < maxDistance || centerPos[2]+blockWidth[2] > periodicBoxSize[2]-maxDistance || + minx < 0.0f || maxx > periodicBoxVectors[0][0]); + int numRanges; int rangeStart[2]; int rangeEnd[2]; - rangeStart[0] = findLowerBound(voxelIndex.x, voxelIndex.y, minz); + rangeStart[0] = findLowerBound(voxelIndex.y, voxelIndex.z, minx); if (needPeriodic) { numRanges = 2; - rangeEnd[0] = findUpperBound(voxelIndex.x, voxelIndex.y, maxz); + rangeEnd[0] = findUpperBound(voxelIndex.y, voxelIndex.z, maxx); if (rangeStart[0] > 0) { rangeStart[1] = 0; - rangeEnd[1] = min(findUpperBound(voxelIndex.x, voxelIndex.y, maxz-periodicBoxSize[2]), rangeStart[0]); + rangeEnd[1] = min(findUpperBound(voxelIndex.y, voxelIndex.z, maxx-periodicBoxSize[0]), rangeStart[0]); } else { - rangeStart[1] = max(findLowerBound(voxelIndex.x, voxelIndex.y, minz+periodicBoxSize[2]), rangeEnd[0]); - rangeEnd[1] = bins[voxelIndex.x][voxelIndex.y].size(); + rangeStart[1] = max(findLowerBound(voxelIndex.y, voxelIndex.z, minx+periodicBoxSize[0]), rangeEnd[0]); + rangeEnd[1] = bins[voxelIndex.y][voxelIndex.z].size(); } } else { numRanges = 1; - rangeEnd[0] = findUpperBound(voxelIndex.x, voxelIndex.y, maxz); + rangeEnd[0] = findUpperBound(voxelIndex.y, voxelIndex.z, maxx); } + bool periodicRectangular = (needPeriodic && !triclinic); // Loop over atoms and check to see if they are neighbors of this block. for (int range = 0; range < numRanges; range++) { for (int item = rangeStart[range]; item < rangeEnd[range]; item++) { - const int sortedIndex = bins[voxelIndex.x][voxelIndex.y][item].second; + const int sortedIndex = bins[voxelIndex.y][voxelIndex.z][item].second; // Avoid duplicate entries. if (sortedIndex >= lastSortedIndex) @@ -260,10 +292,15 @@ public: fvec4 atomPos(atomLocations+4*sortedAtoms[sortedIndex]); fvec4 delta = atomPos-centerPos; - if (needPeriodic) { + if (periodicRectangular) { fvec4 base = round(delta*invBoxSize)*boxSize; delta = delta-base; } + else if (needPeriodic) { + delta -= periodicBoxVec4[2]*floorf(delta[2]*recipBoxSize[2]+0.5f); + delta -= periodicBoxVec4[1]*floorf(delta[1]*recipBoxSize[1]+0.5f); + delta -= periodicBoxVec4[0]*floorf(delta[0]*recipBoxSize[0]+0.5f); + } delta = max(0.0f, abs(delta)-blockWidth); float dSquared = dot3(delta, delta); if (dSquared > maxDistanceSquared) @@ -277,10 +314,15 @@ public: for (int k = 0; k < (int) blockAtoms.size(); k++) { fvec4 pos1(&atomLocations[4*blockAtoms[k]]); delta = atomPos-pos1; - if (needPeriodic) { + if (periodicRectangular) { fvec4 base = round(delta*invBoxSize)*boxSize; delta = delta-base; } + else if (needPeriodic) { + delta -= periodicBoxVec4[2]*floorf(delta[2]*recipBoxSize[2]+0.5f); + delta -= periodicBoxVec4[1]*floorf(delta[1]*recipBoxSize[1]+0.5f); + delta -= periodicBoxVec4[0]*floorf(delta[0]*recipBoxSize[0]+0.5f); + } float r2 = dot3(delta, delta); if (r2 < maxDistanceSquared) { any = true; @@ -308,10 +350,12 @@ public: private: int blockSize; - float voxelSizeX, voxelSizeY; - float minx, maxx, miny, maxy; - int nx, ny; - const float* periodicBoxSize; + float voxelSizeY, voxelSizeZ; + float miny, maxy, minz, maxz; + int ny, nz; + float periodicBoxSize[3], recipBoxSize[3]; + bool triclinic; + const RealVec* periodicBoxVectors; const bool usePeriodic; vector > > > bins; }; @@ -331,6 +375,15 @@ CpuNeighborList::CpuNeighborList(int blockSize) : blockSize(blockSize) { void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const vector >& exclusions, const float* periodicBoxSize, bool usePeriodic, float maxDistance, ThreadPool& threads) { + RealVec vectors[3]; + vectors[0] = RealVec(periodicBoxSize[0], 0, 0); + vectors[1] = RealVec(0, periodicBoxSize[1], 0); + vectors[2] = RealVec(0, 0, periodicBoxSize[2]); + computeNeighborList(numAtoms, atomLocations, exclusions, vectors, usePeriodic, maxDistance, threads); +} + +void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const vector >& exclusions, + const RealVec* periodicBoxVectors, bool usePeriodic, float maxDistance, ThreadPool& threads) { int numBlocks = (numAtoms+blockSize-1)/blockSize; blockNeighbors.resize(numBlocks); blockExclusions.resize(numBlocks); @@ -340,7 +393,9 @@ void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArrayexclusions = &exclusions; this->atomLocations = &atomLocations[0]; - this->periodicBoxSize = periodicBoxSize; + this->periodicBoxVectors[0] = periodicBoxVectors[0]; + this->periodicBoxVectors[1] = periodicBoxVectors[1]; + this->periodicBoxVectors[2] = periodicBoxVectors[2]; this->numAtoms = numAtoms; this->usePeriodic = usePeriodic; this->maxDistance = maxDistance; @@ -371,14 +426,14 @@ void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArrayvoxels = &voxels; - + // Signal the threads to start running and wait for them to finish. threads.resumeThreads(); diff --git a/platforms/cpu/src/CpuNonbondedForce.cpp b/platforms/cpu/src/CpuNonbondedForce.cpp index e72cfb8f6..483c26072 100644 --- a/platforms/cpu/src/CpuNonbondedForce.cpp +++ b/platforms/cpu/src/CpuNonbondedForce.cpp @@ -463,9 +463,9 @@ void CpuNonbondedForce::getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& d deltaR = posJ-posI; if (periodic) { if (triclinic) { - deltaR -= periodicBoxVec4[2]*floor(deltaR[2]*recipBoxSize[2]+0.5f); - deltaR -= periodicBoxVec4[1]*floor(deltaR[1]*recipBoxSize[1]+0.5f); - deltaR -= periodicBoxVec4[0]*floor(deltaR[0]*recipBoxSize[0]+0.5f); + deltaR -= periodicBoxVec4[2]*floorf(deltaR[2]*recipBoxSize[2]+0.5f); + deltaR -= periodicBoxVec4[1]*floorf(deltaR[1]*recipBoxSize[1]+0.5f); + deltaR -= periodicBoxVec4[0]*floorf(deltaR[0]*recipBoxSize[0]+0.5f); } else { fvec4 base = round(deltaR*invBoxSize)*boxSize; diff --git a/platforms/cpu/tests/TestCpuNeighborList.cpp b/platforms/cpu/tests/TestCpuNeighborList.cpp index 2922d7a86..9d2a1ac0c 100644 --- a/platforms/cpu/tests/TestCpuNeighborList.cpp +++ b/platforms/cpu/tests/TestCpuNeighborList.cpp @@ -48,10 +48,21 @@ using namespace OpenMM; using namespace std; -void testNeighborList(bool periodic) { +void testNeighborList(bool periodic, bool triclinic) { const int numParticles = 500; const float cutoff = 2.0f; - const float boxSize[3] = {20.0f, 15.0f, 22.0f}; + RealVec boxVectors[3]; + if (triclinic) { + boxVectors[0] = RealVec(20, 0, 0); + boxVectors[1] = RealVec(5, 15, 0); + boxVectors[2] = RealVec(-3, -7, 22); + } + else { + boxVectors[0] = RealVec(20, 0, 0); + boxVectors[1] = RealVec(0, 15, 0); + boxVectors[2] = RealVec(0, 0, 22); + } + const float boxSize[3] = {boxVectors[0][0], boxVectors[1][1], boxVectors[2][2]}; const int blockSize = 8; OpenMM_SFMT::SFMT sfmt; init_gen_rand(0, sfmt); @@ -69,7 +80,7 @@ void testNeighborList(bool periodic) { } ThreadPool threads; CpuNeighborList neighborList(blockSize); - neighborList.computeNeighborList(numParticles, positions, exclusions, boxSize, periodic, cutoff, threads); + neighborList.computeNeighborList(numParticles, positions, exclusions, boxVectors, periodic, cutoff, threads); // Convert the neighbor list to a set for faster lookup. @@ -90,19 +101,17 @@ void testNeighborList(bool periodic) { } // Check each particle pair and figure out whether they should be in the neighbor list. - + for (int i = 0; i < numParticles; i++) for (int j = 0; j <= i; j++) { bool shouldInclude = (exclusions[i].find(j) == exclusions[i].end()); - float dx = positions[4*i]-positions[4*j]; - float dy = positions[4*i+1]-positions[4*j+1]; - float dz = positions[4*i+2]-positions[4*j+2]; + Vec3 diff(positions[4*i]-positions[4*j], positions[4*i+1]-positions[4*j+1], positions[4*i+2]-positions[4*j+2]); if (periodic) { - dx -= floor(dx/boxSize[0]+0.5f)*boxSize[0]; - dy -= floor(dy/boxSize[1]+0.5f)*boxSize[1]; - dz -= floor(dz/boxSize[2]+0.5f)*boxSize[2]; + diff -= boxVectors[2]*floor(diff[2]/boxSize[2]+0.5); + diff -= boxVectors[1]*floor(diff[1]/boxSize[1]+0.5); + diff -= boxVectors[0]*floor(diff[0]/boxSize[0]+0.5); } - if (dx*dx + dy*dy + dz*dz > cutoff*cutoff) + if (diff.dot(diff) > cutoff*cutoff) shouldInclude = false; bool isIncluded = (neighbors.find(make_pair(i, j)) != neighbors.end() || neighbors.find(make_pair(j, i)) != neighbors.end()); if (shouldInclude) @@ -116,8 +125,9 @@ int main() { cout << "CPU is not supported. Exiting." << endl; return 0; } - testNeighborList(false); - testNeighborList(true); + testNeighborList(false, false); + testNeighborList(true, false); + testNeighborList(true, true); } catch(const exception& e) { cout << "exception: " << e.what() << endl; diff --git a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp index fbd8dbc9c..428588334 100644 --- a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp @@ -157,9 +157,9 @@ public: int miny = centerVoxelIndex.y-dIndexY; int maxy = centerVoxelIndex.y+dIndexY; if (usePeriodic) { - int yoffset = (int) ceil(boxz*periodicBoxVectors[2][1]/voxelSizeY); - miny -= yoffset; - maxy -= yoffset-1; + double yoffset = boxz*periodicBoxVectors[2][1]/voxelSizeY; + miny -= (int) ceil(yoffset); + maxy -= (int) floor(yoffset); maxy = min(maxy, miny+ny-1); } for (int y = miny; y <= maxy; ++y) @@ -168,9 +168,9 @@ public: int minx = centerVoxelIndex.x-dIndexX; int maxx = centerVoxelIndex.x+dIndexX; if (usePeriodic) { - int xoffset = (int) ceil((boxy*periodicBoxVectors[1][0]+boxz*periodicBoxVectors[2][0])/voxelSizeX); - minx -= xoffset; - maxx -= xoffset-1; + double xoffset = (boxy*periodicBoxVectors[1][0]+boxz*periodicBoxVectors[2][0])/voxelSizeX; + minx -= (int) ceil(xoffset); + maxx -= (int) floor(xoffset); maxx = min(maxx, minx+nx-1); } for (int x = minx; x <= maxx; ++x) -- GitLab From 78e5f13abe0dbb98b2b8d88c45e7f01ef3f8a96a Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 16 Dec 2014 16:50:07 -0800 Subject: [PATCH 165/338] Continuing to implement triclinic boxes in CPU platform --- .../cpu/include/CpuCustomManyParticleForce.h | 10 ++- .../cpu/include/CpuCustomNonbondedForce.h | 9 ++- platforms/cpu/include/CpuNeighborList.h | 2 - .../cpu/src/CpuCustomManyParticleForce.cpp | 44 ++++++---- platforms/cpu/src/CpuCustomNonbondedForce.cpp | 39 ++++++--- platforms/cpu/src/CpuKernels.cpp | 34 ++++---- platforms/cpu/src/CpuNeighborList.cpp | 11 +-- platforms/cpu/src/CpuNonbondedForce.cpp | 2 - .../tests/TestCpuCustomManyParticleForce.cpp | 80 ++++++++++++++----- .../cpu/tests/TestCpuCustomNonbondedForce.cpp | 60 ++++++++++++++ .../TestReferenceCustomManyParticleForce.cpp | 74 +++++++++++++---- 11 files changed, 266 insertions(+), 99 deletions(-) diff --git a/platforms/cpu/include/CpuCustomManyParticleForce.h b/platforms/cpu/include/CpuCustomManyParticleForce.h index 60d43bd86..cc67a463d 100644 --- a/platforms/cpu/include/CpuCustomManyParticleForce.h +++ b/platforms/cpu/include/CpuCustomManyParticleForce.h @@ -51,9 +51,11 @@ private: class ComputeForceTask; class ThreadData; int numParticles, numParticlesPerSet, numPerParticleParameters, numTypes; - bool useCutoff, usePeriodic, centralParticleMode; + bool useCutoff, usePeriodic, triclinic, centralParticleMode; RealOpenMM cutoffDistance; - RealOpenMM periodicBoxSize[3]; + float recipBoxSize[3]; + RealVec periodicBoxVectors[3]; + AlignedArray periodicBoxVec4; CpuNeighborList* neighborList; ThreadPool& threads; std::vector > exclusions; @@ -138,9 +140,9 @@ public: * already been set, and the smallest side of the periodic box is at least twice the cutoff * distance. * - * @param boxSize the X, Y, and Z widths of the periodic box + * @param periodicBoxVectors the vectors defining the periodic box */ - void setPeriodic(OpenMM::RealVec& boxSize); + void setPeriodic(RealVec* periodicBoxVectors); /** * Calculate the interaction. diff --git a/platforms/cpu/include/CpuCustomNonbondedForce.h b/platforms/cpu/include/CpuCustomNonbondedForce.h index 4cb8c21f4..ea305668b 100644 --- a/platforms/cpu/include/CpuCustomNonbondedForce.h +++ b/platforms/cpu/include/CpuCustomNonbondedForce.h @@ -95,11 +95,11 @@ class CpuCustomNonbondedForce { already been set, and the smallest side of the periodic box is at least twice the cutoff distance. - @param boxSize the X, Y, and Z widths of the periodic box + @param periodicBoxVectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodic(OpenMM::RealVec& boxSize); + void setPeriodic(RealVec* periodicBoxVectors); /**--------------------------------------------------------------------------------------- @@ -127,8 +127,11 @@ private: bool cutoff; bool useSwitch; bool periodic; + bool triclinic; const CpuNeighborList* neighborList; - RealOpenMM periodicBoxSize[3]; + float recipBoxSize[3]; + RealVec periodicBoxVectors[3]; + AlignedArray periodicBoxVec4; RealOpenMM cutoffDistance, switchingDistance; ThreadPool& threads; const std::vector > exclusions; diff --git a/platforms/cpu/include/CpuNeighborList.h b/platforms/cpu/include/CpuNeighborList.h index a602cc6d2..0ffcf3806 100644 --- a/platforms/cpu/include/CpuNeighborList.h +++ b/platforms/cpu/include/CpuNeighborList.h @@ -49,8 +49,6 @@ public: CpuNeighborList(int blockSize); void computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const std::vector >& exclusions, const RealVec* periodicBoxVectors, bool usePeriodic, float maxDistance, ThreadPool& threads); - void computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const std::vector >& exclusions, - const float* periodicBoxSize, bool usePeriodic, float maxDistance, ThreadPool& threads); int getNumBlocks() const; const std::vector& getSortedAtoms() const; const std::vector& getBlockNeighbors(int blockIndex) const; diff --git a/platforms/cpu/src/CpuCustomManyParticleForce.cpp b/platforms/cpu/src/CpuCustomManyParticleForce.cpp index ab60c8be9..e4f4d53fc 100644 --- a/platforms/cpu/src/CpuCustomManyParticleForce.cpp +++ b/platforms/cpu/src/CpuCustomManyParticleForce.cpp @@ -122,8 +122,7 @@ void CpuCustomManyParticleForce::calculateIxn(AlignedArray& posq, RealOpe particleNeighbors.resize(numParticles); for (int i = 0; i < numParticles; i++) particleNeighbors[i].clear(); - float boxSizeFloat[] = {(float) periodicBoxSize[0], (float) periodicBoxSize[1], (float) periodicBoxSize[2]}; - neighborList->computeNeighborList(numParticles, posq, exclusions, boxSizeFloat, usePeriodic, cutoffDistance, threads); + neighborList->computeNeighborList(numParticles, posq, exclusions, periodicBoxVectors, usePeriodic, cutoffDistance, threads); for (int blockIndex = 0; blockIndex < neighborList->getNumBlocks(); blockIndex++) { const vector& neighbors = neighborList->getBlockNeighbors(blockIndex); const vector& exclusions = neighborList->getBlockExclusions(blockIndex); @@ -159,8 +158,8 @@ void CpuCustomManyParticleForce::calculateIxn(AlignedArray& posq, RealOpe void CpuCustomManyParticleForce::threadComputeForce(ThreadPool& threads, int threadIndex) { vector particleIndices(numParticlesPerSet); - fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); - fvec4 invBoxSize((1/periodicBoxSize[0]), (1/periodicBoxSize[1]), (1/periodicBoxSize[2]), 0); + fvec4 boxSize(periodicBoxVectors[0][0], periodicBoxVectors[1][1], periodicBoxVectors[2][2], 0); + fvec4 invBoxSize(recipBoxSize[0], recipBoxSize[1], recipBoxSize[2], 0); float* forces = &(*threadForce)[threadIndex][0]; ThreadData& data = *threadData[threadIndex]; data.energy = 0; @@ -201,15 +200,25 @@ void CpuCustomManyParticleForce::setUseCutoff(RealOpenMM distance) { neighborList = new CpuNeighborList(4); } -void CpuCustomManyParticleForce::setPeriodic(RealVec& boxSize) { - assert(useCutoff); - assert(boxSize[0] >= 2.0*cutoffDistance); - assert(boxSize[1] >= 2.0*cutoffDistance); - assert(boxSize[2] >= 2.0*cutoffDistance); +void CpuCustomManyParticleForce::setPeriodic(RealVec* periodicBoxVectors) { + assert(cutoff); + assert(periodicBoxVectors[0][0] >= 2.0*cutoffDistance); + assert(periodicBoxVectors[1][1] >= 2.0*cutoffDistance); + assert(periodicBoxVectors[2][2] >= 2.0*cutoffDistance); usePeriodic = true; - periodicBoxSize[0] = boxSize[0]; - periodicBoxSize[1] = boxSize[1]; - periodicBoxSize[2] = boxSize[2]; + this->periodicBoxVectors[0] = periodicBoxVectors[0]; + this->periodicBoxVectors[1] = periodicBoxVectors[1]; + this->periodicBoxVectors[2] = periodicBoxVectors[2]; + recipBoxSize[0] = (float) (1.0/periodicBoxVectors[0][0]); + recipBoxSize[1] = (float) (1.0/periodicBoxVectors[1][1]); + recipBoxSize[2] = (float) (1.0/periodicBoxVectors[2][2]); + periodicBoxVec4.resize(3); + periodicBoxVec4[0] = fvec4(periodicBoxVectors[0][0], periodicBoxVectors[0][1], periodicBoxVectors[0][2], 0); + periodicBoxVec4[1] = fvec4(periodicBoxVectors[1][0], periodicBoxVectors[1][1], periodicBoxVectors[1][2], 0); + periodicBoxVec4[2] = fvec4(periodicBoxVectors[2][0], periodicBoxVectors[2][1], periodicBoxVectors[2][2], 0); + triclinic = (periodicBoxVectors[0][1] != 0.0 || periodicBoxVectors[0][2] != 0.0 || + periodicBoxVectors[1][0] != 0.0 || periodicBoxVectors[1][2] != 0.0 || + periodicBoxVectors[2][0] != 0.0 || periodicBoxVectors[2][1] != 0.0); } void CpuCustomManyParticleForce::loopOverInteractions(vector& availableParticles, vector& particleSet, int loopIndex, int startIndex, @@ -394,8 +403,15 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector& particleSet, RealO void CpuCustomManyParticleForce::computeDelta(const fvec4& posI, const fvec4& posJ, fvec4& deltaR, float& r2, const fvec4& boxSize, const fvec4& invBoxSize) const { deltaR = posJ-posI; if (usePeriodic) { - fvec4 base = round(deltaR*invBoxSize)*boxSize; - deltaR = deltaR-base; + if (triclinic) { + deltaR -= periodicBoxVec4[2]*floorf(deltaR[2]*recipBoxSize[2]+0.5f); + deltaR -= periodicBoxVec4[1]*floorf(deltaR[1]*recipBoxSize[1]+0.5f); + deltaR -= periodicBoxVec4[0]*floorf(deltaR[0]*recipBoxSize[0]+0.5f); + } + else { + fvec4 base = round(deltaR*invBoxSize)*boxSize; + deltaR = deltaR-base; + } } r2 = dot3(deltaR, deltaR); } diff --git a/platforms/cpu/src/CpuCustomNonbondedForce.cpp b/platforms/cpu/src/CpuCustomNonbondedForce.cpp index f35328b40..660a8d02f 100644 --- a/platforms/cpu/src/CpuCustomNonbondedForce.cpp +++ b/platforms/cpu/src/CpuCustomNonbondedForce.cpp @@ -98,15 +98,25 @@ void CpuCustomNonbondedForce::setUseSwitchingFunction(RealOpenMM distance) { switchingDistance = distance; } -void CpuCustomNonbondedForce::setPeriodic(RealVec& boxSize) { +void CpuCustomNonbondedForce::setPeriodic(RealVec* periodicBoxVectors) { assert(cutoff); - assert(boxSize[0] >= 2.0*cutoffDistance); - assert(boxSize[1] >= 2.0*cutoffDistance); - assert(boxSize[2] >= 2.0*cutoffDistance); + assert(periodicBoxVectors[0][0] >= 2.0*cutoffDistance); + assert(periodicBoxVectors[1][1] >= 2.0*cutoffDistance); + assert(periodicBoxVectors[2][2] >= 2.0*cutoffDistance); periodic = true; - periodicBoxSize[0] = boxSize[0]; - periodicBoxSize[1] = boxSize[1]; - periodicBoxSize[2] = boxSize[2]; + this->periodicBoxVectors[0] = periodicBoxVectors[0]; + this->periodicBoxVectors[1] = periodicBoxVectors[1]; + this->periodicBoxVectors[2] = periodicBoxVectors[2]; + recipBoxSize[0] = (float) (1.0/periodicBoxVectors[0][0]); + recipBoxSize[1] = (float) (1.0/periodicBoxVectors[1][1]); + recipBoxSize[2] = (float) (1.0/periodicBoxVectors[2][2]); + periodicBoxVec4.resize(3); + periodicBoxVec4[0] = fvec4(periodicBoxVectors[0][0], periodicBoxVectors[0][1], periodicBoxVectors[0][2], 0); + periodicBoxVec4[1] = fvec4(periodicBoxVectors[1][0], periodicBoxVectors[1][1], periodicBoxVectors[1][2], 0); + periodicBoxVec4[2] = fvec4(periodicBoxVectors[2][0], periodicBoxVectors[2][1], periodicBoxVectors[2][2], 0); + triclinic = (periodicBoxVectors[0][1] != 0.0 || periodicBoxVectors[0][2] != 0.0 || + periodicBoxVectors[1][0] != 0.0 || periodicBoxVectors[1][2] != 0.0 || + periodicBoxVectors[2][0] != 0.0 || periodicBoxVectors[2][1] != 0.0); } @@ -155,8 +165,8 @@ void CpuCustomNonbondedForce::threadComputeForce(ThreadPool& threads, int thread ReferenceForce::setVariable(ReferenceForce::getVariablePointer(data.energyExpression, iter->first), iter->second); ReferenceForce::setVariable(ReferenceForce::getVariablePointer(data.forceExpression, iter->first), iter->second); } - fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); - fvec4 invBoxSize((1/periodicBoxSize[0]), (1/periodicBoxSize[1]), (1/periodicBoxSize[2]), 0); + fvec4 boxSize(periodicBoxVectors[0][0], periodicBoxVectors[1][1], periodicBoxVectors[2][2], 0); + fvec4 invBoxSize(recipBoxSize[0], recipBoxSize[1], recipBoxSize[2], 0); if (groupInteractions.size() > 0) { // The user has specified interaction groups, so compute only the requested interactions. @@ -266,8 +276,15 @@ void CpuCustomNonbondedForce::calculateOneIxn(int ii, int jj, ThreadData& data, void CpuCustomNonbondedForce::getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& deltaR, float& r2, const fvec4& boxSize, const fvec4& invBoxSize) const { deltaR = posJ-posI; if (periodic) { - fvec4 base = round(deltaR*invBoxSize)*boxSize; - deltaR = deltaR-base; + if (triclinic) { + deltaR -= periodicBoxVec4[2]*floorf(deltaR[2]*recipBoxSize[2]+0.5f); + deltaR -= periodicBoxVec4[1]*floorf(deltaR[1]*recipBoxSize[1]+0.5f); + deltaR -= periodicBoxVec4[0]*floorf(deltaR[0]*recipBoxSize[0]+0.5f); + } + else { + fvec4 base = round(deltaR*invBoxSize)*boxSize; + deltaR = deltaR-base; + } } r2 = dot3(deltaR, deltaR); } diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 0b32dd19f..601d94519 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -216,7 +216,7 @@ void CpuCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool i referenceKernel.getAs().beginComputation(context, includeForce, includeEnergy, groups); // Convert positions to single precision and clear the forces. - + InitForceTask task(context.getSystem().getNumParticles(), context, data); data.threads.execute(task); data.threads.waitForThreads(); @@ -512,8 +512,7 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo AlignedArray& posq = data.posq; vector& posData = extractPositions(context); vector& forceData = extractForces(context); - RealVec boxSize = extractBoxSize(context); - float floatBoxSize[3] = {(float) boxSize[0], (float) boxSize[1], (float) boxSize[2]}; + RealVec* boxVectors = extractBoxVectors(context); double energy = (includeReciprocal ? ewaldSelfEnergy : 0.0); bool ewald = (nonbondedMethod == Ewald); bool pme = (nonbondedMethod == PME); @@ -559,7 +558,7 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo } } if (needRecompute) { - neighborList->computeNeighborList(numParticles, posq, exclusions, floatBoxSize, data.isPeriodic, nonbondedCutoff+padding, data.threads); + neighborList->computeNeighborList(numParticles, posq, exclusions, boxVectors, data.isPeriodic, nonbondedCutoff+padding, data.threads); lastPositions = posData; } nonbonded->setUseCutoff(nonbondedCutoff, *neighborList, rfDielectric); @@ -583,7 +582,7 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo if (includeReciprocal) { if (useOptimizedPme) { PmeIO io(&posq[0], &data.threadForce[0][0], numParticles); - Vec3 periodicBoxSize(boxSize[0], boxSize[1], boxSize[2]); + Vec3 periodicBoxSize(boxVectors[0][0], boxVectors[1][1], boxVectors[2][2]); optimizedPme.getAs().beginComputation(io, periodicBoxSize, includeEnergy); nonbondedEnergy += optimizedPme.getAs().finishComputation(io); } @@ -596,7 +595,7 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo ReferenceLJCoulomb14 nonbonded14; refBondForce.calculateForce(num14, bonded14IndexArray, posData, bonded14ParamArray, forceData, includeEnergy ? &energy : NULL, nonbonded14); if (data.isPeriodic) - energy += dispersionCoefficient/(boxSize[0]*boxSize[1]*boxSize[2]); + energy += dispersionCoefficient/(boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]); } return energy; } @@ -750,19 +749,18 @@ void CpuCalcCustomNonbondedForceKernel::initialize(const System& system, const C double CpuCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { vector& posData = extractPositions(context); vector& forceData = extractForces(context); - RealVec& box = extractBoxSize(context); - float floatBoxSize[3] = {(float) box[0], (float) box[1], (float) box[2]}; + RealVec* boxVectors = extractBoxVectors(context); double energy = 0; bool periodic = (nonbondedMethod == CutoffPeriodic); if (nonbondedMethod != NoCutoff) { - neighborList->computeNeighborList(numParticles, data.posq, exclusions, floatBoxSize, data.isPeriodic, nonbondedCutoff, data.threads); + neighborList->computeNeighborList(numParticles, data.posq, exclusions, boxVectors, data.isPeriodic, nonbondedCutoff, data.threads); nonbonded->setUseCutoff(nonbondedCutoff, *neighborList); } if (periodic) { double minAllowedSize = 2*nonbondedCutoff; - if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize) + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - nonbonded->setPeriodic(box); + nonbonded->setPeriodic(boxVectors); } bool globalParamsChanged = false; for (int i = 0; i < (int) globalParameterNames.size(); i++) { @@ -781,7 +779,7 @@ double CpuCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool inc longRangeCoefficient = CustomNonbondedForceImpl::calcLongRangeCorrection(*forceCopy, context.getOwner()); hasInitializedLongRangeCorrection = true; } - energy += longRangeCoefficient/(box[0]*box[1]*box[2]); + energy += longRangeCoefficient/(boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]); return energy; } @@ -989,13 +987,12 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { vector& forceData = extractForces(context); RealOpenMM energy = 0; - RealVec& box = extractBoxSize(context); - float floatBoxSize[3] = {(float) box[0], (float) box[1], (float) box[2]}; + RealVec* boxVectors = extractBoxVectors(context); if (data.isPeriodic) ixn->setPeriodic(extractBoxSize(context)); if (nonbondedMethod != NoCutoff) { vector > noExclusions(numParticles); - neighborList->computeNeighborList(numParticles, data.posq, exclusions, floatBoxSize, data.isPeriodic, nonbondedCutoff, data.threads); + neighborList->computeNeighborList(numParticles, data.posq, exclusions, boxVectors, data.isPeriodic, nonbondedCutoff, data.threads); ixn->setUseCutoff(nonbondedCutoff, *neighborList); } map globalParameters; @@ -1052,6 +1049,7 @@ void CpuCalcCustomManyParticleForceKernel::initialize(const System& system, cons ixn = new CpuCustomManyParticleForce(force, data.threads); nonbondedMethod = CalcCustomManyParticleForceKernel::NonbondedMethod(force.getNonbondedMethod()); cutoffDistance = force.getCutoffDistance(); + data.isPeriodic = (nonbondedMethod == CutoffPeriodic); } double CpuCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { @@ -1059,11 +1057,11 @@ double CpuCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool for (int i = 0; i < (int) globalParameterNames.size(); i++) globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]); if (nonbondedMethod == CutoffPeriodic) { - RealVec& box = extractBoxSize(context); + RealVec* boxVectors = extractBoxVectors(context); double minAllowedSize = 2*cutoffDistance; - if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize) + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - ixn->setPeriodic(box); + ixn->setPeriodic(boxVectors); } double energy = 0; ixn->calculateIxn(data.posq, particleParamArray, globalParameters, data.threadForce, includeForces, includeEnergy, energy); diff --git a/platforms/cpu/src/CpuNeighborList.cpp b/platforms/cpu/src/CpuNeighborList.cpp index d3919ddd6..a41d402d7 100644 --- a/platforms/cpu/src/CpuNeighborList.cpp +++ b/platforms/cpu/src/CpuNeighborList.cpp @@ -373,15 +373,6 @@ public: CpuNeighborList::CpuNeighborList(int blockSize) : blockSize(blockSize) { } -void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const vector >& exclusions, - const float* periodicBoxSize, bool usePeriodic, float maxDistance, ThreadPool& threads) { - RealVec vectors[3]; - vectors[0] = RealVec(periodicBoxSize[0], 0, 0); - vectors[1] = RealVec(0, periodicBoxSize[1], 0); - vectors[2] = RealVec(0, 0, periodicBoxSize[2]); - computeNeighborList(numAtoms, atomLocations, exclusions, vectors, usePeriodic, maxDistance, threads); -} - void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArray& atomLocations, const vector >& exclusions, const RealVec* periodicBoxVectors, bool usePeriodic, float maxDistance, ThreadPool& threads) { int numBlocks = (numAtoms+blockSize-1)/blockSize; @@ -425,7 +416,7 @@ void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArray::const_iterator iter = exclusions[i].begin(); iter != exclusions[i].end(); ++iter) { diff --git a/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp b/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp index 7a1a930b3..03a6f803c 100644 --- a/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp +++ b/platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp @@ -53,15 +53,36 @@ using namespace std; const double TOL = 1e-5; -void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize) { +Vec3 computeDelta(const Vec3& pos1, const Vec3& pos2, bool periodic, const Vec3* periodicBoxVectors) { + Vec3 diff = pos1-pos2; + if (periodic) { + diff -= periodicBoxVectors[2]*floor(diff[2]/periodicBoxVectors[2][2]+0.5); + diff -= periodicBoxVectors[1]*floor(diff[1]/periodicBoxVectors[1][1]+0.5); + diff -= periodicBoxVectors[0]*floor(diff[0]/periodicBoxVectors[0][0]+0.5); + } + return diff; +} + +void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize, bool triclinic) { // Create a System and Context. - + int numParticles = force->getNumParticles(); CustomManyParticleForce::NonbondedMethod nonbondedMethod = force->getNonbondedMethod(); System system; for (int i = 0; i < numParticles; i++) system.addParticle(1.0); - system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); + Vec3 boxVectors[3]; + if (triclinic) { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0.2*boxSize, boxSize, 0); + boxVectors[2] = Vec3(-0.3*boxSize, -0.1*boxSize, boxSize); + } + else { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0, boxSize, 0); + boxVectors[2] = Vec3(0, 0, boxSize); + } + system.setDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); system.addForce(force); VerletIntegrator integrator(0.001); CpuPlatform platform; @@ -69,24 +90,18 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p context.setPositions(positions); State state1 = context.getState(State::Forces | State::Energy); double c = context.getParameter("C"); - + // See if the energy matches the expected value. - + double expectedEnergy = 0; + bool periodic = (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic); for (int i = 0; i < (int) expectedSets.size(); i++) { int p1 = expectedSets[i][0]; int p2 = expectedSets[i][1]; int p3 = expectedSets[i][2]; - Vec3 d12 = positions[p2]-positions[p1]; - Vec3 d13 = positions[p3]-positions[p1]; - Vec3 d23 = positions[p3]-positions[p2]; - if (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic) { - for (int j = 0; j < 3; j++) { - d12[j] -= floor(d12[j]/boxSize+0.5f)*boxSize; - d13[j] -= floor(d13[j]/boxSize+0.5f)*boxSize; - d23[j] -= floor(d23[j]/boxSize+0.5f)*boxSize; - } - } + Vec3 d12 = computeDelta(positions[p2], positions[p1], periodic, boxVectors); + Vec3 d13 = computeDelta(positions[p3], positions[p1], periodic, boxVectors); + Vec3 d23 = computeDelta(positions[p3], positions[p2], periodic, boxVectors); double r12 = sqrt(d12.dot(d12)); double r13 = sqrt(d13.dot(d13)); double r23 = sqrt(d23.dot(d23)); @@ -210,7 +225,7 @@ void testNoCutoff() { positions.push_back(Vec3(0.4, 0, -0.8)); int sets[4][3] = {{0,1,2}, {1,2,3}, {2,3,0}, {3,0,1}}; vector expectedSets(&sets[0], &sets[4]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testCutoff() { @@ -235,7 +250,7 @@ void testCutoff() { positions.push_back(Vec3(0.2, 0.5, -0.1)); int sets[7][3] = {{0,1,2}, {0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,2,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[7]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testPeriodic() { @@ -261,7 +276,33 @@ void testPeriodic() { double boxSize = 2.1; int sets[5][3] = {{0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, boxSize); + validateAxilrodTeller(force, positions, expectedSets, boxSize, false); +} + +void testTriclinic() { + CustomManyParticleForce* force = new CustomManyParticleForce(3, + "C*(1+3*cos(theta1)*cos(theta2)*cos(theta3))/(r12*r13*r23)^3;" + "theta1=angle(p1,p2,p3); theta2=angle(p2,p3,p1); theta3=angle(p3,p1,p2);" + "r12=distance(p1,p2); r13=distance(p1,p3); r23=distance(p2,p3)"); + force->addGlobalParameter("C", 1.5); + force->setNonbondedMethod(CustomManyParticleForce::CutoffPeriodic); + force->setCutoffDistance(1.05); + vector params; + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + vector positions; + positions.push_back(Vec3(0, 0, 0)); + positions.push_back(Vec3(1, 0, 0)); + positions.push_back(Vec3(0, 1.1, 0.3)); + positions.push_back(Vec3(0.4, 0, -0.8)); + positions.push_back(Vec3(0.2, 0.5, -0.1)); + double boxSize = 2.1; + int sets[4][3] = {{0,1,3}, {0,1,4}, {0,3,4}, {1,3,4}}; + vector expectedSets(&sets[0], &sets[4]); + validateAxilrodTeller(force, positions, expectedSets, boxSize, true); } void testExclusions() { @@ -286,7 +327,7 @@ void testExclusions() { force->addExclusion(0, 3); int sets[5][3] = {{0,1,4}, {1,2,3}, {1,2,4}, {1,3,4}, {2,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testAllTerms() { @@ -680,6 +721,7 @@ int main() { testNoCutoff(); testCutoff(); testPeriodic(); + testTriclinic(); testExclusions(); testAllTerms(); testParameters(); diff --git a/platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp b/platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp index fdc440adf..57c0835f9 100644 --- a/platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp +++ b/platforms/cpu/tests/TestCpuCustomNonbondedForce.cpp @@ -224,6 +224,65 @@ void testPeriodic() { ASSERT_EQUAL_TOL(1.9+1+0.9, state.getPotentialEnergy(), TOL); } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + CustomNonbondedForce* nonbonded = new CustomNonbondedForce("r"); + nonbonded->addParticle(vector()); + nonbonded->addParticle(vector()); + nonbonded->setNonbondedMethod(CustomNonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta/sqrt(delta.dot(delta)); + ASSERT_EQUAL_TOL(distance, state.getPotentialEnergy(), TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} + void testContinuous1DFunction() { System system; system.addParticle(1.0); @@ -852,6 +911,7 @@ int main() { testExclusions(); testCutoff(); testPeriodic(); + testTriclinic(); testContinuous1DFunction(); testContinuous2DFunction(); testContinuous3DFunction(); diff --git a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp index 22c312197..13dfbe3b5 100644 --- a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp @@ -53,7 +53,17 @@ using namespace std; const double TOL = 1e-5; -void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize) { +Vec3 computeDelta(const Vec3& pos1, const Vec3& pos2, bool periodic, const Vec3* periodicBoxVectors) { + Vec3 diff = pos1-pos2; + if (periodic) { + diff -= periodicBoxVectors[2]*floor(diff[2]/periodicBoxVectors[2][2]+0.5); + diff -= periodicBoxVectors[1]*floor(diff[1]/periodicBoxVectors[1][1]+0.5); + diff -= periodicBoxVectors[0]*floor(diff[0]/periodicBoxVectors[0][0]+0.5); + } + return diff; +} + +void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize, bool triclinic) { // Create a System and Context. int numParticles = force->getNumParticles(); @@ -61,7 +71,18 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p System system; for (int i = 0; i < numParticles; i++) system.addParticle(1.0); - system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); + Vec3 boxVectors[3]; + if (triclinic) { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0.2*boxSize, boxSize, 0); + boxVectors[2] = Vec3(-0.3*boxSize, -0.1*boxSize, boxSize); + } + else { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0, boxSize, 0); + boxVectors[2] = Vec3(0, 0, boxSize); + } + system.setDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); system.addForce(force); VerletIntegrator integrator(0.001); ReferencePlatform platform; @@ -73,20 +94,14 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p // See if the energy matches the expected value. double expectedEnergy = 0; + bool periodic = (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic); for (int i = 0; i < (int) expectedSets.size(); i++) { int p1 = expectedSets[i][0]; int p2 = expectedSets[i][1]; int p3 = expectedSets[i][2]; - Vec3 d12 = positions[p2]-positions[p1]; - Vec3 d13 = positions[p3]-positions[p1]; - Vec3 d23 = positions[p3]-positions[p2]; - if (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic) { - for (int j = 0; j < 3; j++) { - d12[j] -= floor(d12[j]/boxSize+0.5f)*boxSize; - d13[j] -= floor(d13[j]/boxSize+0.5f)*boxSize; - d23[j] -= floor(d23[j]/boxSize+0.5f)*boxSize; - } - } + Vec3 d12 = computeDelta(positions[p2], positions[p1], periodic, boxVectors); + Vec3 d13 = computeDelta(positions[p3], positions[p1], periodic, boxVectors); + Vec3 d23 = computeDelta(positions[p3], positions[p2], periodic, boxVectors); double r12 = sqrt(d12.dot(d12)); double r13 = sqrt(d13.dot(d13)); double r23 = sqrt(d23.dot(d23)); @@ -210,7 +225,7 @@ void testNoCutoff() { positions.push_back(Vec3(0.4, 0, -0.8)); int sets[4][3] = {{0,1,2}, {1,2,3}, {2,3,0}, {3,0,1}}; vector expectedSets(&sets[0], &sets[4]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testCutoff() { @@ -235,7 +250,7 @@ void testCutoff() { positions.push_back(Vec3(0.2, 0.5, -0.1)); int sets[7][3] = {{0,1,2}, {0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,2,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[7]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testPeriodic() { @@ -261,7 +276,33 @@ void testPeriodic() { double boxSize = 2.1; int sets[5][3] = {{0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, boxSize); + validateAxilrodTeller(force, positions, expectedSets, boxSize, false); +} + +void testTriclinic() { + CustomManyParticleForce* force = new CustomManyParticleForce(3, + "C*(1+3*cos(theta1)*cos(theta2)*cos(theta3))/(r12*r13*r23)^3;" + "theta1=angle(p1,p2,p3); theta2=angle(p2,p3,p1); theta3=angle(p3,p1,p2);" + "r12=distance(p1,p2); r13=distance(p1,p3); r23=distance(p2,p3)"); + force->addGlobalParameter("C", 1.5); + force->setNonbondedMethod(CustomManyParticleForce::CutoffPeriodic); + force->setCutoffDistance(1.05); + vector params; + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + vector positions; + positions.push_back(Vec3(0, 0, 0)); + positions.push_back(Vec3(1, 0, 0)); + positions.push_back(Vec3(0, 1.1, 0.3)); + positions.push_back(Vec3(0.4, 0, -0.8)); + positions.push_back(Vec3(0.2, 0.5, -0.1)); + double boxSize = 2.1; + int sets[4][3] = {{0,1,3}, {0,1,4}, {0,3,4}, {1,3,4}}; + vector expectedSets(&sets[0], &sets[4]); + validateAxilrodTeller(force, positions, expectedSets, boxSize, true); } void testExclusions() { @@ -286,7 +327,7 @@ void testExclusions() { force->addExclusion(0, 3); int sets[5][3] = {{0,1,4}, {1,2,3}, {1,2,4}, {1,3,4}, {2,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testAllTerms() { @@ -592,6 +633,7 @@ int main() { testNoCutoff(); testCutoff(); testPeriodic(); + testTriclinic(); testExclusions(); testAllTerms(); testParameters(); -- GitLab From e68027ab84d4c1f65b8d75c4e0e1e37a7aaf3e16 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 18 Dec 2014 13:52:52 -0800 Subject: [PATCH 166/338] Optimization to CPU PME --- plugins/cpupme/src/CpuPmeKernels.cpp | 16 +++++++++++----- plugins/cpupme/src/CpuPmeKernels.h | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/plugins/cpupme/src/CpuPmeKernels.cpp b/plugins/cpupme/src/CpuPmeKernels.cpp index 707dc6767..2016fb5de 100644 --- a/plugins/cpupme/src/CpuPmeKernels.cpp +++ b/plugins/cpupme/src/CpuPmeKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2013 Stanford University and the Authors. * + * Portions copyright (c) 2013-2014 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -350,9 +350,9 @@ void CpuCalcPmeReciprocalForceKernel::initialize(int xsize, int ysize, int zsize fftwf_init_threads(); hasInitializedThreads = true; } - gridx = findFFTDimension(xsize); - gridy = findFFTDimension(ysize); - gridz = findFFTDimension(zsize); + gridx = findFFTDimension(xsize, false); + gridy = findFFTDimension(ysize, false); + gridz = findFFTDimension(zsize, true); this->numParticles = numParticles; this->alpha = alpha; force.resize(4*numParticles); @@ -572,12 +572,18 @@ bool CpuCalcPmeReciprocalForceKernel::isProcessorSupported() { return isVec4Supported(); } -int CpuCalcPmeReciprocalForceKernel::findFFTDimension(int minimum) { +int CpuCalcPmeReciprocalForceKernel::findFFTDimension(int minimum, bool isZ) { if (minimum < 1) return 1; while (true) { // Attempt to factor the current value. + if (isZ && minimum%2 == 1) { + // Force the last dimension to be even, since this produces better performance in FFTW. + + minimum++; + continue; + } int unfactored = minimum; for (int factor = 2; factor < 8; factor++) { while (unfactored > 1 && unfactored%factor == 0) diff --git a/plugins/cpupme/src/CpuPmeKernels.h b/plugins/cpupme/src/CpuPmeKernels.h index 5a946ff6b..21529f1b2 100644 --- a/plugins/cpupme/src/CpuPmeKernels.h +++ b/plugins/cpupme/src/CpuPmeKernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2013 Stanford University and the Authors. * + * Portions copyright (c) 2013-2014 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -98,7 +98,7 @@ private: /** * Select a size for one grid dimension that FFTW can handle efficiently. */ - int findFFTDimension(int minimum); + int findFFTDimension(int minimum, bool isZ); static bool hasInitializedThreads; static int numThreads; int gridx, gridy, gridz, numParticles; -- GitLab From f6aae604f4ca808e98fe7aa4e3772dfee6742fc8 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 18 Dec 2014 16:38:46 -0800 Subject: [PATCH 167/338] CPU PME works with triclinic boxes --- olla/include/openmm/kernels.h | 10 +- platforms/cpu/src/CpuKernels.cpp | 4 +- platforms/cpu/tests/TestCpuEwald.cpp | 52 ++++++++++ platforms/cuda/src/CudaKernels.cpp | 4 +- platforms/opencl/src/OpenCLKernels.cpp | 4 +- .../src/SimTKReference/ReferencePME.cpp | 3 +- plugins/cpupme/src/CpuPmeKernels.cpp | 99 +++++++++++-------- plugins/cpupme/src/CpuPmeKernels.h | 12 +-- plugins/cpupme/tests/TestCpuPme.cpp | 20 +++- 9 files changed, 147 insertions(+), 61 deletions(-) diff --git a/olla/include/openmm/kernels.h b/olla/include/openmm/kernels.h index 0bd8c4e99..62b2f0dda 100644 --- a/olla/include/openmm/kernels.h +++ b/olla/include/openmm/kernels.h @@ -1223,12 +1223,12 @@ public: virtual void initialize(int gridx, int gridy, int gridz, int numParticles, double alpha) = 0; /** * Begin computing the force and energy. - * - * @param io an object that coordinates data transfer - * @param periodicBoxSize the size of the periodic box (measured in nm) - * @param includeEnergy true if potential energy should be computed + * + * @param io an object that coordinates data transfer + * @param periodicBoxVectors the vectors defining the periodic box (measured in nm) + * @param includeEnergy true if potential energy should be computed */ - virtual void beginComputation(IO& io, Vec3 periodicBoxSize, bool includeEnergy) = 0; + virtual void beginComputation(IO& io, const Vec3* periodicBoxVectors, bool includeEnergy) = 0; /** * Finish computing the force and energy. * diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 601d94519..e24238977 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -582,8 +582,8 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo if (includeReciprocal) { if (useOptimizedPme) { PmeIO io(&posq[0], &data.threadForce[0][0], numParticles); - Vec3 periodicBoxSize(boxVectors[0][0], boxVectors[1][1], boxVectors[2][2]); - optimizedPme.getAs().beginComputation(io, periodicBoxSize, includeEnergy); + Vec3 periodicBoxVectors[3] = {boxVectors[0], boxVectors[1], boxVectors[2]}; + optimizedPme.getAs().beginComputation(io, periodicBoxVectors, includeEnergy); nonbondedEnergy += optimizedPme.getAs().finishComputation(io); } else diff --git a/platforms/cpu/tests/TestCpuEwald.cpp b/platforms/cpu/tests/TestCpuEwald.cpp index 6d8b14d8b..6c3f084b1 100644 --- a/platforms/cpu/tests/TestCpuEwald.cpp +++ b/platforms/cpu/tests/TestCpuEwald.cpp @@ -201,6 +201,57 @@ void testEwald2Ions() { ASSERT_EQUAL_TOL(-217.276, state.getPotentialEnergy(), 0.01/*10*TOL*/); } +void testTriclinic() { + // Create a triclinic box containing eight particles. + + System system; + system.setDefaultPeriodicBoxVectors(Vec3(2.5, 0, 0), Vec3(0.5, 3.0, 0), Vec3(0.7, 0.9, 3.5)); + for (int i = 0; i < 8; i++) + system.addParticle(1.0); + NonbondedForce* force = new NonbondedForce(); + system.addForce(force); + force->setNonbondedMethod(NonbondedForce::PME); + force->setCutoffDistance(1.0); + force->setPMEParameters(3.45891, 32, 40, 48); + for (int i = 0; i < 4; i++) + force->addParticle(-1, 0.440104, 0.4184); // Cl parameters + for (int i = 0; i < 4; i++) + force->addParticle(1, 0.332840, 0.0115897); // Na parameters + vector positions(8); + positions[0] = Vec3(1.744, 2.788, 3.162); + positions[1] = Vec3(1.048, 0.762, 2.340); + positions[2] = Vec3(2.489, 1.570, 2.817); + positions[3] = Vec3(1.027, 1.893, 3.271); + positions[4] = Vec3(0.937, 0.825, 0.009); + positions[5] = Vec3(2.290, 1.887, 3.352); + positions[6] = Vec3(1.266, 1.111, 2.894); + positions[7] = Vec3(0.933, 1.862, 3.490); + + // Compute the forces and energy. + + VerletIntegrator integ(0.001); + Context context(system, integ, platform); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + + // Compare them to values computed by Gromacs. + + double expectedEnergy = -963.370; + vector expectedForce(8); + expectedForce[0] = Vec3(4.25253e+01, -1.23503e+02, 1.22139e+02); + expectedForce[1] = Vec3(9.74752e+01, 1.68213e+02, 1.93169e+02); + expectedForce[2] = Vec3(-1.50348e+02, 1.29165e+02, 3.70435e+02); + expectedForce[3] = Vec3(9.18644e+02, -3.52571e+00, -1.34772e+03); + expectedForce[4] = Vec3(-1.61193e+02, 9.01528e+01, -7.12904e+01); + expectedForce[5] = Vec3(2.82630e+02, 2.78029e+01, -3.72864e+02); + expectedForce[6] = Vec3(-1.47454e+02, -2.14448e+02, -3.55789e+02); + expectedForce[7] = Vec3(-8.82195e+02, -7.39132e+01, 1.46202e+03); + for (int i = 0; i < 8; i++) { + ASSERT_EQUAL_VEC(expectedForce[i], state.getForces()[i], 1e-4); + } + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), 1e-4); +} + void testErrorTolerance(NonbondedForce::NonbondedMethod method) { // Create a cloud of random point charges. @@ -261,6 +312,7 @@ int main(int argc, char* argv[]) { testEwaldPME(false); testEwaldPME(true); // testEwald2Ions(); + testTriclinic(); testErrorTolerance(NonbondedForce::Ewald); testErrorTolerance(NonbondedForce::PME); } diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 1ee828afe..4d9214ed2 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1377,8 +1377,8 @@ public: PmePreComputation(CudaContext& cu, Kernel& pme, CalcPmeReciprocalForceKernel::IO& io) : cu(cu), pme(pme), io(io) { } void computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) { - Vec3 boxSize(cu.getPeriodicBoxSize().x, cu.getPeriodicBoxSize().y, cu.getPeriodicBoxSize().z); - pme.getAs().beginComputation(io, boxSize, includeEnergy); + Vec3 boxVectors[3] = {Vec3(cu.getPeriodicBoxSize().x, 0, 0), Vec3(0, cu.getPeriodicBoxSize().y, 0), Vec3(0, 0, cu.getPeriodicBoxSize().z)}; + pme.getAs().beginComputation(io, boxVectors, includeEnergy); } private: CudaContext& cu; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 03df4e49c..861611467 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1363,8 +1363,8 @@ public: PmePreComputation(OpenCLContext& cl, Kernel& pme, CalcPmeReciprocalForceKernel::IO& io) : cl(cl), pme(pme), io(io) { } void computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) { - Vec3 boxSize(cl.getPeriodicBoxSize().x, cl.getPeriodicBoxSize().y, cl.getPeriodicBoxSize().z); - pme.getAs().beginComputation(io, boxSize, includeEnergy); + Vec3 boxVectors[3] = {Vec3(cl.getPeriodicBoxSize().x, 0, 0), Vec3(0, cl.getPeriodicBoxSize().y, 0), Vec3(0, 0, cl.getPeriodicBoxSize().z)}; + pme.getAs().beginComputation(io, boxVectors, includeEnergy); } private: OpenCLContext& cl; diff --git a/platforms/reference/src/SimTKReference/ReferencePME.cpp b/platforms/reference/src/SimTKReference/ReferencePME.cpp index 4d774fa2d..b5d89327f 100644 --- a/platforms/reference/src/SimTKReference/ReferencePME.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePME.cpp @@ -256,7 +256,8 @@ pme_update_grid_index_and_fraction(pme_t pme, coord[d] -= floor(coord[d]*recipBoxVectors[d][d])*periodicBoxVectors[d][d]; for(d=0;d<3;d++) { - t = (coord[0]*recipBoxVectors[0][d]+coord[1]*recipBoxVectors[1][d]+coord[2]*recipBoxVectors[2][d])*pme->ngrid[d]; + t = coord[0]*recipBoxVectors[0][d]+coord[1]*recipBoxVectors[1][d]+coord[2]*recipBoxVectors[2][d]; + t = (t-floor(t))*pme->ngrid[d]; ti = (int) t; pme->particlefraction[i][d] = t - ti; diff --git a/plugins/cpupme/src/CpuPmeKernels.cpp b/plugins/cpupme/src/CpuPmeKernels.cpp index 707dc6767..c4be50a4d 100644 --- a/plugins/cpupme/src/CpuPmeKernels.cpp +++ b/plugins/cpupme/src/CpuPmeKernels.cpp @@ -47,10 +47,13 @@ static const int PME_ORDER = 5; bool CpuCalcPmeReciprocalForceKernel::hasInitializedThreads = false; int CpuCalcPmeReciprocalForceKernel::numThreads = 0; -static void spreadCharge(int start, int end, float* posq, float* grid, int gridx, int gridy, int gridz, int numParticles, Vec3 periodicBoxSize) { +static void spreadCharge(int start, int end, float* posq, float* grid, int gridx, int gridy, int gridz, int numParticles, Vec3* periodicBoxVectors, Vec3* recipBoxVectors) { float temp[4]; - fvec4 boxSize((float) periodicBoxSize[0], (float) periodicBoxSize[1], (float) periodicBoxSize[2], 0); - fvec4 invBoxSize((float) (1/periodicBoxSize[0]), (float) (1/periodicBoxSize[1]), (float) (1/periodicBoxSize[2]), 0); + fvec4 boxSize((float) periodicBoxVectors[0][0], (float) periodicBoxVectors[1][1], (float) periodicBoxVectors[2][2], 0); + fvec4 invBoxSize((float) recipBoxVectors[0][0], (float) recipBoxVectors[1][1], (float) recipBoxVectors[2][2], 0); + fvec4 recipBoxVec0((float) recipBoxVectors[0][0], (float) recipBoxVectors[0][1], (float) recipBoxVectors[0][2], 0); + fvec4 recipBoxVec1((float) recipBoxVectors[1][0], (float) recipBoxVectors[1][1], (float) recipBoxVectors[1][2], 0); + fvec4 recipBoxVec2((float) recipBoxVectors[2][0], (float) recipBoxVectors[2][1], (float) recipBoxVectors[2][2], 0); fvec4 gridSize(gridx, gridy, gridz, 0); ivec4 gridSizeInt(gridx, gridy, gridz, 0); fvec4 one(1); @@ -61,9 +64,10 @@ static void spreadCharge(int start, int end, float* posq, float* grid, int gridx // Find the position relative to the nearest grid point. fvec4 pos(&posq[4*i]); - fvec4 posFloor = floor(pos*invBoxSize); - fvec4 posInBox = pos-boxSize*posFloor; - fvec4 t = posInBox*invBoxSize*gridSize; + float posInBox[4]; + (pos-boxSize*floor(pos*invBoxSize)).store(posInBox); + fvec4 t = posInBox[0]*recipBoxVec0 + posInBox[1]*recipBoxVec1 + posInBox[2]*recipBoxVec2; + t = (t-floor(t))*gridSize; ivec4 ti = t; fvec4 dr = t-ti; ivec4 gridIndex = ti-(gridSizeInt&ti==gridSizeInt); @@ -142,29 +146,26 @@ static void spreadCharge(int start, int end, float* posq, float* grid, int gridx } } -static void computeReciprocalEterm(int start, int end, int gridx, int gridy, int gridz, vector& recipEterm, double alpha, vector* bsplineModuli, Vec3 periodicBoxSize) { +static void computeReciprocalEterm(int start, int end, int gridx, int gridy, int gridz, vector& recipEterm, double alpha, vector* bsplineModuli, Vec3* periodicBoxVectors, Vec3* recipBoxVectors) { const unsigned int zsize = gridz/2+1; const unsigned int yzsize = gridy*zsize; - const float scaleFactor = (float) (M_PI*periodicBoxSize[0]*periodicBoxSize[1]*periodicBoxSize[2]); + const float scaleFactor = (float) (M_PI*periodicBoxVectors[0][0]*periodicBoxVectors[1][1]*periodicBoxVectors[2][2]); const float recipExpFactor = (float) (M_PI*M_PI/(alpha*alpha)); - const float invPeriodicBoxSizeX = (float) (1.0/periodicBoxSize[0]); - const float invPeriodicBoxSizeY = (float) (1.0/periodicBoxSize[1]); - const float invPeriodicBoxSizeZ = (float) (1.0/periodicBoxSize[2]); int firstz = (start == 0 ? 1 : 0); for (int kx = start; kx < end; kx++) { int mx = (kx < (gridx+1)/2) ? kx : kx-gridx; - float mhx = mx*invPeriodicBoxSizeX; + float mhx = mx*(float)recipBoxVectors[0][0]; float bx = scaleFactor*bsplineModuli[0][kx]; for (int ky = 0; ky < gridy; ky++) { int my = (ky < (gridy+1)/2) ? ky : ky-gridy; - float mhy = my*invPeriodicBoxSizeY; + float mhy = mx*(float)recipBoxVectors[1][0] + my*(float)recipBoxVectors[1][1]; float mhx2y2 = mhx*mhx + mhy*mhy; float bxby = bx*bsplineModuli[1][ky]; for (int kz = firstz; kz < zsize; kz++) { int index = kx*yzsize + ky*zsize + kz; int mz = (kz < (gridz+1)/2) ? kz : kz-gridz; - float mhz = mz*invPeriodicBoxSizeZ; + float mhz = mx*(float)recipBoxVectors[2][0] + my*(float)recipBoxVectors[2][1] + mz*(float)recipBoxVectors[2][2]; float bz = bsplineModuli[2][kz]; float m2 = mhx2y2 + mhz*mhz; float denom = m2*bxby*bz; @@ -175,29 +176,26 @@ static void computeReciprocalEterm(int start, int end, int gridx, int gridy, int } } -static float reciprocalEnergy(int start, int end, fftwf_complex* grid, int gridx, int gridy, int gridz, double alpha, vector* bsplineModuli, Vec3 periodicBoxSize) { +static float reciprocalEnergy(int start, int end, fftwf_complex* grid, int gridx, int gridy, int gridz, double alpha, vector* bsplineModuli, Vec3* periodicBoxVectors, Vec3* recipBoxVectors) { const unsigned int zsizeHalf = gridz/2+1; const unsigned int yzsizeHalf = gridy*zsizeHalf; - const float scaleFactor = (float) (M_PI*periodicBoxSize[0]*periodicBoxSize[1]*periodicBoxSize[2]); + const float scaleFactor = (float) (M_PI*periodicBoxVectors[0][0]*periodicBoxVectors[1][1]*periodicBoxVectors[2][2]); const float recipExpFactor = (float) (M_PI*M_PI/(alpha*alpha)); - const float invPeriodicBoxSizeX = (float) (1.0/periodicBoxSize[0]); - const float invPeriodicBoxSizeY = (float) (1.0/periodicBoxSize[1]); - const float invPeriodicBoxSizeZ = (float) (1.0/periodicBoxSize[2]); float energy = 0.0f; int firstz = (start == 0 ? 1 : 0); for (int kx = start; kx < end; kx++) { int mx = (kx < (gridx+1)/2) ? kx : kx-gridx; - float mhx = mx*invPeriodicBoxSizeX; + float mhx = mx*(float)recipBoxVectors[0][0]; float bx = scaleFactor*bsplineModuli[0][kx]; for (int ky = 0; ky < gridy; ky++) { int my = (ky < (gridy+1)/2) ? ky : ky-gridy; - float mhy = my*invPeriodicBoxSizeY; + float mhy = mx*(float)recipBoxVectors[1][0] + my*(float)recipBoxVectors[1][1]; float mhx2y2 = mhx*mhx + mhy*mhy; float bxby = bx*bsplineModuli[1][ky]; for (int kz = firstz; kz < gridz; kz++) { int mz = (kz < (gridz+1)/2) ? kz : kz-gridz; - float mhz = mz*invPeriodicBoxSizeZ; + float mhz = mx*(float)recipBoxVectors[2][0] + my*(float)recipBoxVectors[2][1] + mz*(float)recipBoxVectors[2][2]; float bz = bsplineModuli[2][kz]; float m2 = mhx2y2 + mhz*mhz; float denom = m2*bxby*bz; @@ -242,9 +240,12 @@ static void reciprocalConvolution(int start, int end, fftwf_complex* grid, int g } } -static void interpolateForces(int start, int end, float* posq, float* force, float* grid, int gridx, int gridy, int gridz, int numParticles, Vec3 periodicBoxSize) { - fvec4 boxSize((float) periodicBoxSize[0], (float) periodicBoxSize[1], (float) periodicBoxSize[2], 0); - fvec4 invBoxSize((float) (1/periodicBoxSize[0]), (float) (1/periodicBoxSize[1]), (float) (1/periodicBoxSize[2]), 0); +static void interpolateForces(int start, int end, float* posq, float* force, float* grid, int gridx, int gridy, int gridz, int numParticles, Vec3* periodicBoxVectors, Vec3* recipBoxVectors) { + fvec4 boxSize((float) periodicBoxVectors[0][0], (float) periodicBoxVectors[1][1], (float) periodicBoxVectors[2][2], 0); + fvec4 invBoxSize((float) recipBoxVectors[0][0], (float) recipBoxVectors[1][1], (float) recipBoxVectors[2][2], 0); + fvec4 recipBoxVec0((float) recipBoxVectors[0][0], (float) recipBoxVectors[0][1], (float) recipBoxVectors[0][2], 0); + fvec4 recipBoxVec1((float) recipBoxVectors[1][0], (float) recipBoxVectors[1][1], (float) recipBoxVectors[1][2], 0); + fvec4 recipBoxVec2((float) recipBoxVectors[2][0], (float) recipBoxVectors[2][1], (float) recipBoxVectors[2][2], 0); fvec4 gridSize(gridx, gridy, gridz, 0); ivec4 gridSizeInt(gridx, gridy, gridz, 0); fvec4 one(1); @@ -254,9 +255,10 @@ static void interpolateForces(int start, int end, float* posq, float* force, flo // Find the position relative to the nearest grid point. fvec4 pos(&posq[4*i]); - fvec4 posFloor = floor(pos*invBoxSize); - fvec4 posInBox = pos-boxSize*posFloor; - fvec4 t = posInBox*invBoxSize*gridSize; + float posInBox[4]; + (pos-boxSize*floor(pos*invBoxSize)).store(posInBox); + fvec4 t = posInBox[0]*recipBoxVec0 + posInBox[1]*recipBoxVec1 + posInBox[2]*recipBoxVec2; + t = (t-floor(t))*gridSize; ivec4 ti = t; fvec4 dr = t-ti; ivec4 gridIndex = ti-(gridSizeInt&ti==gridSizeInt); @@ -321,8 +323,12 @@ static void interpolateForces(int start, int end, float* posq, float* force, flo } } } - f = invBoxSize*gridSize*f*(-epsilonFactor*posq[4*i+3]); - f.store(&force[4*i]); + f *= -epsilonFactor*posq[4*i+3]; + float fc[4]; + f.store(fc); + force[4*i+0] = fc[0]*gridx*(float)recipBoxVectors[0][0]; + force[4*i+1] = fc[0]*gridx*(float)recipBoxVectors[1][0]+fc[1]*gridy*(float)recipBoxVectors[1][1]; + force[4*i+2] = fc[0]*gridx*(float)recipBoxVectors[2][0]+fc[1]*gridy*(float)recipBoxVectors[2][1]+fc[2]*gridz*(float)recipBoxVectors[2][2]; } } @@ -476,7 +482,7 @@ void CpuCalcPmeReciprocalForceKernel::runThread(int index) { advanceThreads(); // Signal threads to perform charge spreading. advanceThreads(); // Signal threads to sum the charge grids. fftwf_execute_dft_r2c(forwardFFT, realGrid, complexGrid); - if (lastBoxSize != periodicBoxSize) + if (lastBoxVectors[0] != periodicBoxVectors[0] || lastBoxVectors[1] != periodicBoxVectors[1] || lastBoxVectors[2] != periodicBoxVectors[2]) advanceThreads(); // Signal threads to compute the reciprocal scale factors. if (includeEnergy) advanceThreads(); // Signal threads to compute energy. @@ -484,7 +490,9 @@ void CpuCalcPmeReciprocalForceKernel::runThread(int index) { fftwf_execute_dft_c2r(backwardFFT, complexGrid, realGrid); advanceThreads(); // Signal threads to interpolate forces. isFinished = true; - lastBoxSize = periodicBoxSize; + lastBoxVectors[0] = periodicBoxVectors[0]; + lastBoxVectors[1] = periodicBoxVectors[1]; + lastBoxVectors[2] = periodicBoxVectors[2]; pthread_cond_signal(&mainThreadEndCondition); } pthread_mutex_unlock(&lock); @@ -503,7 +511,7 @@ void CpuCalcPmeReciprocalForceKernel::runThread(int index) { threadWait(); if (isDeleted) break; - spreadCharge(particleStart, particleEnd, posq, threadData[index]->tempGrid, gridx, gridy, gridz, numParticles, periodicBoxSize); + spreadCharge(particleStart, particleEnd, posq, threadData[index]->tempGrid, gridx, gridy, gridz, numParticles, periodicBoxVectors, recipBoxVectors); threadWait(); int numGrids = threadData.size(); for (int i = gridStart; i < gridEnd; i += 4) { @@ -513,12 +521,12 @@ void CpuCalcPmeReciprocalForceKernel::runThread(int index) { sum.store(&realGrid[i]); } threadWait(); - if (lastBoxSize != periodicBoxSize) { - computeReciprocalEterm(gridxStart, gridxEnd, gridx, gridy, gridz, recipEterm, alpha, bsplineModuli, periodicBoxSize); + if (lastBoxVectors[0] != periodicBoxVectors[0] || lastBoxVectors[1] != periodicBoxVectors[1] || lastBoxVectors[2] != periodicBoxVectors[2]) { + computeReciprocalEterm(gridxStart, gridxEnd, gridx, gridy, gridz, recipEterm, alpha, bsplineModuli, periodicBoxVectors, recipBoxVectors); threadWait(); } if (includeEnergy) { - double threadEnergy = reciprocalEnergy(gridxStart, gridxEnd, complexGrid, gridx, gridy, gridz, alpha, bsplineModuli, periodicBoxSize); + double threadEnergy = reciprocalEnergy(gridxStart, gridxEnd, complexGrid, gridx, gridy, gridz, alpha, bsplineModuli, periodicBoxVectors, recipBoxVectors); pthread_mutex_lock(&lock); energy += threadEnergy; pthread_mutex_unlock(&lock); @@ -526,7 +534,7 @@ void CpuCalcPmeReciprocalForceKernel::runThread(int index) { } reciprocalConvolution(gridxStart, gridxEnd, complexGrid, gridx, gridy, gridz, recipEterm); threadWait(); - interpolateForces(particleStart, particleEnd, posq, &force[0], realGrid, gridx, gridy, gridz, numParticles, periodicBoxSize); + interpolateForces(particleStart, particleEnd, posq, &force[0], realGrid, gridx, gridy, gridz, numParticles, periodicBoxVectors, recipBoxVectors); } } } @@ -547,11 +555,24 @@ void CpuCalcPmeReciprocalForceKernel::advanceThreads() { } } -void CpuCalcPmeReciprocalForceKernel::beginComputation(IO& io, Vec3 periodicBoxSize, bool includeEnergy) { +void CpuCalcPmeReciprocalForceKernel::beginComputation(IO& io, const Vec3* periodicBoxVectors, bool includeEnergy) { this->io = &io; - this->periodicBoxSize = periodicBoxSize; + this->periodicBoxVectors[0] = periodicBoxVectors[0]; + this->periodicBoxVectors[1] = periodicBoxVectors[1]; + this->periodicBoxVectors[2] = periodicBoxVectors[2]; this->includeEnergy = includeEnergy; energy = 0.0; + + // Invert the box vectors. + + double determinant = periodicBoxVectors[0][0]*periodicBoxVectors[1][1]*periodicBoxVectors[2][2]; + double scale = 1.0/determinant; + recipBoxVectors[0] = Vec3(periodicBoxVectors[1][1]*periodicBoxVectors[2][2], 0, 0)*scale; + recipBoxVectors[1] = Vec3(-periodicBoxVectors[1][0]*periodicBoxVectors[2][2], periodicBoxVectors[0][0]*periodicBoxVectors[2][2], 0)*scale; + recipBoxVectors[2] = Vec3(periodicBoxVectors[1][0]*periodicBoxVectors[2][1]-periodicBoxVectors[1][1]*periodicBoxVectors[2][0], -periodicBoxVectors[0][0]*periodicBoxVectors[2][1], periodicBoxVectors[0][0]*periodicBoxVectors[1][1])*scale; + + // Do the calculation. + pthread_mutex_lock(&lock); isFinished = false; pthread_cond_signal(&mainThreadStartCondition); diff --git a/plugins/cpupme/src/CpuPmeKernels.h b/plugins/cpupme/src/CpuPmeKernels.h index 5a946ff6b..cb0afe453 100644 --- a/plugins/cpupme/src/CpuPmeKernels.h +++ b/plugins/cpupme/src/CpuPmeKernels.h @@ -66,11 +66,11 @@ public: /** * Begin computing the force and energy. * - * @param io an object that coordinates data transfer - * @param periodicBoxSize the size of the periodic box (measured in nm) - * @param includeEnergy true if potential energy should be computed + * @param io an object that coordinates data transfer + * @param periodicBoxVectors the vectors defining the periodic box (measured in nm) + * @param includeEnergy true if potential energy should be computed */ - void beginComputation(IO& io, Vec3 periodicBoxSize, bool includeEnergy); + void beginComputation(IO& io, const Vec3* periodicBoxVectors, bool includeEnergy); /** * Finish computing the force and energy. * @@ -107,7 +107,7 @@ private: std::vector force; std::vector bsplineModuli[3]; std::vector recipEterm; - Vec3 lastBoxSize; + Vec3 lastBoxVectors[3]; float* realGrid; fftwf_complex* complexGrid; fftwf_plan forwardFFT, backwardFFT; @@ -122,7 +122,7 @@ private: IO* io; float energy; float* posq; - Vec3 periodicBoxSize; + Vec3 periodicBoxVectors[3], recipBoxVectors[3]; bool includeEnergy; }; diff --git a/plugins/cpupme/tests/TestCpuPme.cpp b/plugins/cpupme/tests/TestCpuPme.cpp index 75acc1db3..7d07e5814 100644 --- a/plugins/cpupme/tests/TestCpuPme.cpp +++ b/plugins/cpupme/tests/TestCpuPme.cpp @@ -61,14 +61,25 @@ public: } }; -void testPME() { +void testPME(bool triclinic) { // Create a cloud of random point charges. const int numParticles = 51; const double boxWidth = 5.0; const double cutoff = 1.0; + Vec3 boxVectors[3]; + if (triclinic) { + boxVectors[0] = Vec3(boxWidth, 0, 0); + boxVectors[1] = Vec3(0.2*boxWidth, boxWidth, 0); + boxVectors[2] = Vec3(-0.3*boxWidth, -0.1*boxWidth, boxWidth); + } + else { + boxVectors[0] = Vec3(boxWidth, 0, 0); + boxVectors[1] = Vec3(0, boxWidth, 0); + boxVectors[2] = Vec3(0, 0, boxWidth); + } System system; - system.setDefaultPeriodicBoxVectors(Vec3(boxWidth, 0, 0), Vec3(0, boxWidth, 0), Vec3(0, 0, boxWidth)); + system.setDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); NonbondedForce* force = new NonbondedForce(); system.addForce(force); vector positions(numParticles); @@ -112,7 +123,7 @@ void testPME() { } double ewaldSelfEnergy = -ONE_4PI_EPS0*alpha*sumSquaredCharges/sqrt(M_PI); pme.initialize(gridx, gridy, gridz, numParticles, alpha); - pme.beginComputation(io, Vec3(boxWidth, boxWidth, boxWidth), true); + pme.beginComputation(io, boxVectors, true); double energy = pme.finishComputation(io); // See if they match. @@ -128,7 +139,8 @@ int main(int argc, char* argv[]) { cout << "CPU is not supported. Exiting." << endl; return 0; } - testPME(); + testPME(false); + testPME(true); } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From b3bab4999237ad43cdaa2b8b120e84335acb8183 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 19 Dec 2014 10:34:35 -0800 Subject: [PATCH 168/338] Use templates to improve performance when not using triclinic boxes --- platforms/cpu/include/CpuNonbondedForceVec4.h | 15 ++++++++++- platforms/cpu/include/CpuNonbondedForceVec8.h | 15 ++++++++++- platforms/cpu/src/CpuNonbondedForceVec4.cpp | 25 ++++++++++++++++--- platforms/cpu/src/CpuNonbondedForceVec8.cpp | 25 ++++++++++++++++--- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/platforms/cpu/include/CpuNonbondedForceVec4.h b/platforms/cpu/include/CpuNonbondedForceVec4.h index e4d7d8b66..14c66f0a9 100644 --- a/platforms/cpu/include/CpuNonbondedForceVec4.h +++ b/platforms/cpu/include/CpuNonbondedForceVec4.h @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. +/* Portions copyright (c) 2006-2014 Stanford University and Simbios. * Contributors: Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -52,6 +52,12 @@ protected: --------------------------------------------------------------------------------------- */ void calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + + /** + * Templatized implementation of calculateBlockIxn. + */ + template + void calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); /**--------------------------------------------------------------------------------------- @@ -65,10 +71,17 @@ protected: void calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + /** + * Templatized implementation of calculateBlockEwaldIxn. + */ + template + void calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + /** * Compute the displacement and squared distance between a collection of points, optionally using * periodic boundary conditions. */ + template void getDeltaR(const float* posI, const fvec4& x, const fvec4& y, const fvec4& z, fvec4& dx, fvec4& dy, fvec4& dz, fvec4& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const; /** diff --git a/platforms/cpu/include/CpuNonbondedForceVec8.h b/platforms/cpu/include/CpuNonbondedForceVec8.h index 98a273f08..cd1b1b923 100644 --- a/platforms/cpu/include/CpuNonbondedForceVec8.h +++ b/platforms/cpu/include/CpuNonbondedForceVec8.h @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. +/* Portions copyright (c) 2006-2014 Stanford University and Simbios. * Contributors: Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -51,6 +51,12 @@ protected: --------------------------------------------------------------------------------------- */ void calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + + /** + * Templatized implementation of calculateBlockIxn. + */ + template + void calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); /**--------------------------------------------------------------------------------------- @@ -64,10 +70,17 @@ protected: void calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + /** + * Templatized implementation of calculateBlockEwaldIxn. + */ + template + void calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + /** * Compute the displacement and squared distance between a collection of points, optionally using * periodic boundary conditions. */ + template void getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const; /** diff --git a/platforms/cpu/src/CpuNonbondedForceVec4.cpp b/platforms/cpu/src/CpuNonbondedForceVec4.cpp index dfe8854aa..789060e6e 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec4.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec4.cpp @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. +/* Portions copyright (c) 2006-2014 Stanford University and Simbios. * Contributors: Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -46,6 +46,14 @@ CpuNonbondedForceVec4::CpuNonbondedForceVec4() { } void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + if (triclinic) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + else + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); +} + +template +void CpuNonbondedForceVec4::calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; @@ -75,7 +83,7 @@ void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, dou // Compute the distances to the block atoms. fvec4 dx, dy, dz, r2; - getDeltaR(posq+4*atom, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + getDeltaR(posq+4*atom, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec4 include; char excl = exclusions[i]; if (excl == 0) @@ -155,6 +163,14 @@ void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, dou } void CpuNonbondedForceVec4::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + if (triclinic) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + else + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); +} + +template +void CpuNonbondedForceVec4::calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; @@ -184,7 +200,7 @@ void CpuNonbondedForceVec4::calculateBlockEwaldIxn(int blockIndex, float* forces // Compute the distances to the block atoms. fvec4 dx, dy, dz, r2; - getDeltaR(posq+4*atom, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + getDeltaR(posq+4*atom, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec4 include; char excl = exclusions[i]; if (excl == 0) @@ -257,12 +273,13 @@ void CpuNonbondedForceVec4::calculateBlockEwaldIxn(int blockIndex, float* forces (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); } +template void CpuNonbondedForceVec4::getDeltaR(const float* posI, const fvec4& x, const fvec4& y, const fvec4& z, fvec4& dx, fvec4& dy, fvec4& dz, fvec4& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { dx = x-posI[0]; dy = y-posI[1]; dz = z-posI[2]; if (periodic) { - if (triclinic) { + if (TRICLINIC) { fvec4 scale3 = floor(dz*recipBoxSize[2]+0.5f); dx -= scale3*periodicBoxVectors[2][0]; dy -= scale3*periodicBoxVectors[2][1]; diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index fda08f3f4..15c90d44b 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. +/* Portions copyright (c) 2006-2014 Stanford University and Simbios. * Contributors: Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -78,6 +78,14 @@ CpuNonbondedForceVec8::CpuNonbondedForceVec8() { } void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + if (triclinic) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + else + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); +} + +template +void CpuNonbondedForceVec8::calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; @@ -106,7 +114,7 @@ void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, dou // Compute the distances to the block atoms. fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec8 include; char excl = exclusions[i]; if (excl == 0) @@ -186,6 +194,14 @@ void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, dou } void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { + if (triclinic) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + else + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); +} + +template +void CpuNonbondedForceVec8::calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; @@ -214,7 +230,7 @@ void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces // Compute the distances to the block atoms. fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec8 include; char excl = exclusions[i]; if (excl == 0) @@ -287,12 +303,13 @@ void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); } +template void CpuNonbondedForceVec8::getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { dx = x-posI[0]; dy = y-posI[1]; dz = z-posI[2]; if (periodic) { - if (triclinic) { + if (TRICLINIC) { fvec8 scale3 = floor(dz*recipBoxSize[2]+0.5f); dx -= scale3*periodicBoxVectors[2][0]; dy -= scale3*periodicBoxVectors[2][1]; -- GitLab From c7cacc13006d21c21eff0260b7c73ad49552bcbb Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 26 Dec 2014 11:28:36 -0500 Subject: [PATCH 169/338] Fix typo. --- wrappers/python/simtk/openmm/app/gromacstopfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/gromacstopfile.py b/wrappers/python/simtk/openmm/app/gromacstopfile.py index 9960a99e6..7bad309f8 100644 --- a/wrappers/python/simtk/openmm/app/gromacstopfile.py +++ b/wrappers/python/simtk/openmm/app/gromacstopfile.py @@ -280,7 +280,7 @@ class GromacsTopFile(object): raise ValueError('Found [ cmap ] section before [ moleculetype ]') fields = line.split() if len(fields) < 6: - raise ValueError('Too few fields in [ pairs ] line: '+line); + raise ValueError('Too few fields in [ cmap ] line: '+line); self._currentMoleculeType.cmaps.append(fields) def _processAtomType(self, line): -- GitLab From 67ad655774799773b70f49dd85c5269cc3cbb2bc Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 26 Dec 2014 17:21:42 -0500 Subject: [PATCH 170/338] Squash the following warning: /usr/local/openmm/include/openmm/CustomHbondForce.h:477:25: warning: field 'p3' will be initialized after field 'parameters' [-Wreorder] p1(p1), p2(p2), p3(p3), parameters(parameters) { ^ I believe that the initializer is supposed to assign variables in the same order they're declared in the class definition (not the same order they're defined in the constructor argument list. --- openmmapi/include/openmm/CustomHbondForce.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmmapi/include/openmm/CustomHbondForce.h b/openmmapi/include/openmm/CustomHbondForce.h index 0ee6c4283..547c8fa4e 100644 --- a/openmmapi/include/openmm/CustomHbondForce.h +++ b/openmmapi/include/openmm/CustomHbondForce.h @@ -474,7 +474,7 @@ public: GroupInfo() : p1(-1), p2(-1), p3(-1) { } GroupInfo(int p1, int p2, int p3, const std::vector& parameters) : - p1(p1), p2(p2), p3(p3), parameters(parameters) { + parameters(parameters), p1(p1), p2(p2), p3(p3) { } }; -- GitLab From ddbd992bc54185ead8807f1491e8005b309c15ca Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 29 Dec 2014 21:57:37 -0500 Subject: [PATCH 171/338] Add a usesPeriodicBoundaryConditions() method to all of the Force classes and the System. The System inspects all of its forces and calls usePeriodicBoundaryConditions -- it reports 'true' if at least one of its Forces returns 'true' for usesPeriodicBoundaryConditions. The default Force implementation is to raise an exception (NotImplementedError). The System implementation will return true if at least one of its Forces returns 'true' for usesPeriodicBoundaryConditions, _regardless_ of whether or not one or more of the forces does not implement the method. If at least one of the forces does not implement usesPeriodicBoundaryConditions and all forces return false, an OpenMMException is thrown. --- .../include/openmm/.HarmonicAngleForce.h.swp | Bin 0 -> 16384 bytes openmmapi/include/openmm/CMAPTorsionForce.h | 7 ++++++ openmmapi/include/openmm/CustomAngleForce.h | 7 ++++++ openmmapi/include/openmm/CustomBondForce.h | 7 ++++++ .../include/openmm/CustomCompoundBondForce.h | 7 ++++++ .../include/openmm/CustomExternalForce.h | 7 ++++++ openmmapi/include/openmm/CustomGBForce.h | 9 ++++++++ openmmapi/include/openmm/CustomHbondForce.h | 9 ++++++++ .../include/openmm/CustomManyParticleForce.h | 9 ++++++++ .../include/openmm/CustomNonbondedForce.h | 9 ++++++++ openmmapi/include/openmm/CustomTorsionForce.h | 7 ++++++ openmmapi/include/openmm/Force.h | 8 +++++++ openmmapi/include/openmm/GBSAOBCForce.h | 9 ++++++++ openmmapi/include/openmm/GBVIForce.h | 9 ++++++++ openmmapi/include/openmm/HarmonicAngleForce.h | 7 ++++++ openmmapi/include/openmm/HarmonicBondForce.h | 7 ++++++ openmmapi/include/openmm/NonbondedForce.h | 11 +++++++++ openmmapi/include/openmm/OpenMMException.h | 11 +++++++++ .../include/openmm/PeriodicTorsionForce.h | 7 ++++++ openmmapi/include/openmm/RBTorsionForce.h | 7 ++++++ openmmapi/include/openmm/System.h | 9 ++++++++ openmmapi/src/Force.cpp | 4 ++++ openmmapi/src/System.cpp | 21 ++++++++++++++++++ 23 files changed, 188 insertions(+) create mode 100644 openmmapi/include/openmm/.HarmonicAngleForce.h.swp diff --git a/openmmapi/include/openmm/.HarmonicAngleForce.h.swp b/openmmapi/include/openmm/.HarmonicAngleForce.h.swp new file mode 100644 index 0000000000000000000000000000000000000000..b592e978637b09f4038fd4d2427ffef5994cd3e0 GIT binary patch literal 16384 zcmeHOU2Ggz6&_m3e+mM%q7SI2jv5?m?RD%%DQ+oQugCEe?~iuZ2@$AecIK}4;@P>& z%&Z-^YLSo-5U|>J|p)AWdh(@8vZ*2I8*FipPtAC0- zfXl$QfUg6mfqCFg;58IK{to;VcpmsM5CZoAzX31I&A0P{$SoX0;$x1^4*kR*kk7w- z(3i5lAo10ajAS>FBYUSr1L3EmM1&+`O8ijzaq8&j$08solR+ewiABgb6qiW#^hws2 zNl5tv)Kkeo#@qUq?)Vy#mX1nFMWEsv5OwOPsGdyH?0+kj>sARvuw;qKL^7aEX`!$t z5Y&?*3K#Ul<+(Zi`IKo&M2W~oiEW!Mr1A+dd-5TDSH>A_i>y8x=--~CvnL4#La!%H z$TeB?iZSkR_7}1XoXAz(m%C8pV-7cl&BY`29~rqhSbDo9xd5 zJfvQ1ThE?^s&kXk>-#Bng}{J>p$JP>LQDe{%HBRnbT>7q>>^eob@z2w?7XSS^pH*Z zLpMa7zD#LPMiKYe71AwQzI);aBW&ib-%*aqfu-OgPOW4IERYa*Hl8n z5Bg@zA-K|mz1*Sh-Hd`93?nhX_@`_*{7fXi_JOfh+ld+tQ!_^s0e7(z*pj{LCsL$i zF9XB-Ff8k9*V5kRuqQb&$VrDj^lIQ|R<#tLJapVf}Ec?NXyfjn0PKqBXa&>DAA* z$*U7CP`k0-xln1j;QbvOSPJHhpbK8xEm5WAwIPkxTa8+Y8e1J|taD!wUTxItZnfhz z>U6>DY#iu}AK}hP%Ui3|D(BqxM8{39vg&Pmor@*9u;FU8A+UmfMjrZr^iB(>CF=0B zggkv{c`UiI)!AsY+9mU#x4MPLbPv@=^J2?8w}GkL*j#gQan&X6aMPuAh^f>sQgyT9 z!5kb~-n!SRyY05QP0dQH<5jmdD=lhnwVDl(TdA*6y;1k->n)Js*4%n$fhnjr$UTn} zYHw6FH^=h4T65EL*GhP#y1BK+{6RlF-GL%Cuj8)4D9sNBrd6qTJSJzIYHq8#fzvTL zR=??CB(F`)R^z<41}QTY40C%1EMfq7aICzGER7BQyjO=BSlU`_AFS8*Y9?>aA1#kp zvp@}b`eCZ4qi&k{W+CUvgLT}_T0w2q%l7<4T+UQA=4DX^IK`3_2}|mu7545_x@XAZ*B!aj~;ePnf4KBV1Er2rK-dXm?bga zaid6KJ=x~HGL)K-6-&S2FAmF0oS5R#L?U@lC1bcUW+M#1e!;Y&&%M6F-VVm}q2=+J zW=%hUH5>~#h(uJRcMOh>l5Jen+gjQ$QHcF1k=;>-i%=e$qlmec^*^>uU|Y8PbgqLEt|>vpE+4F{@k4S0tEI&BCzpoC-6buE_=LLApQstfUwoD#*gI}0k=KD^Lq{Z^%l)V3Dc&XQ4pXcx|ffGxKZPBTJ6 z5F%y^K`?t=-P@p+@HM&v)x@rAeVap2c2ff)1aqP2$ry~8xPGJ3s$uJ{R_fu2g<-p$o-!IE&y*J_kRtz z1Pp;QKpA)mHGpS;hOGzu0(F1@_#*I6)B#=rhQM2>1AG?8$>Xvz^(UleVCu^Jouy?<`kda*?Mv%9@-m z9Xwq|Jf{%Eaj=Xk+4u}XR~%l4Cz|UA=(Dr~EG{e>!}yVLPq>kPUz+;9jPLWO%<~f+ zbFB|{zhfSo)))qirB1#sKja*&%p9%ZtgMWCV}>wFNLSAe6S<3+k-z6#XI?``s zfG}9c=m|=4h-4%OGy}5(BiBHfnpevfOr5|EbDD)KD<gGkhBm|h+vXEnSx6# z#C}XAE~bhG@hx2>MDeH(Xbrfp&Tw#EcWck@oimB8{5-C z?51KAjixq zyCTeq%|DTp=&T5m2ZYQQL8nO`t?6Sm5jYN^q^=-dt)|EAY++Cn>j*1@FJO~1X7IEWl{w6FovC7=^yIS@No}rcd8-M0(WcY)r!o)K#XReyz5L_hEYP&W$>Ii&oG70&H(^8vp& impls = context.getImpl().getForceImpls(); for (int i = 0; i < (int) impls.size(); i++) diff --git a/openmmapi/src/System.cpp b/openmmapi/src/System.cpp index 766a74222..a23485d76 100644 --- a/openmmapi/src/System.cpp +++ b/openmmapi/src/System.cpp @@ -119,3 +119,24 @@ void System::setDefaultPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Ve periodicBoxVectors[1] = b; periodicBoxVectors[2] = c; } + +bool System::usesPeriodicBoundaryConditions() { + + bool uses_pbc = false; + bool all_forces_implement = true; + for (std::vector::const_iterator it = forces.begin(); + it != forces.end(); it++) { + try { + if ((*it)->usesPeriodicBoundaryConditions()) + uses_pbc = true; + } catch (NotImplementedError &e) { + all_forces_implement = false; + } + } + + if (!all_forces_implement && !uses_pbc) { + throw OpenMMException("not all forces implement usesPeriodicBoundaryConditions"); + } + + return uses_pbc; +} -- GitLab From c7e17f713013ff722d4d3576262d33ddb571bac5 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 29 Dec 2014 23:11:54 -0500 Subject: [PATCH 172/338] Add usesPeriodicBoundaryConditions to the plugin Forces. --- .../amoeba/openmmapi/include/openmm/AmoebaAngleForce.h | 8 +++++++- plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h | 8 +++++++- .../include/openmm/AmoebaGeneralizedKirkwoodForce.h | 8 +++++++- .../openmmapi/include/openmm/AmoebaInPlaneAngleForce.h | 8 +++++++- .../openmmapi/include/openmm/AmoebaMultipoleForce.h | 8 +++++++- .../openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h | 8 +++++++- .../openmmapi/include/openmm/AmoebaPiTorsionForce.h | 8 +++++++- .../openmmapi/include/openmm/AmoebaStretchBendForce.h | 8 +++++++- .../openmmapi/include/openmm/AmoebaTorsionTorsionForce.h | 8 +++++++- plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h | 8 +++++++- .../openmmapi/include/openmm/AmoebaWcaDispersionForce.h | 8 +++++++- plugins/drude/openmmapi/include/openmm/DrudeForce.h | 7 +++++++ 12 files changed, 84 insertions(+), 11 deletions(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h index 3e6405db8..e8f7f0467 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h @@ -166,7 +166,13 @@ public: * in an angle cannot be changed, nor can new angles be added. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; double _globalCubicK, _globalQuarticK, _globalPenticK, _globalSexticK; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h index ef94c0375..316c9ced4 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h @@ -138,7 +138,13 @@ public: * in a bond cannot be changed, nor can new bonds be added. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: double _globalQuarticK, _globalCubicK; ForceImpl* createImpl() const; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h index a8f457dcc..a2a6c2582 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h @@ -163,7 +163,13 @@ public: * (the probe radius, the surface area factor, etc.) are unaffected and can only be changed by reinitializing the Context. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h index d81381c19..87c85449f 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h @@ -171,7 +171,13 @@ public: * in an angle cannot be changed, nor can new angles be added. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; double _globalCubicK, _globalQuarticK, _globalPenticK, _globalSexticK; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h index ef7cf29b1..90ada1c61 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h @@ -349,7 +349,13 @@ public: * only to change the parameters of existing ones. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return nonbondedMethod == AmoebaMultipoleForce::PME;} protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h index 433e56b1f..244c76559 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h @@ -163,7 +163,13 @@ public: * in a term cannot be changed, nor can new terms be added. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; double _globalCubicK, _globalQuarticK, _globalPenticK, _globalSexticK; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h index ea5012f23..1c1b0d20e 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h @@ -113,7 +113,13 @@ public: * in a torsion cannot be changed, nor can new torsions be added. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index 784494552..f3554ea89 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -116,7 +116,13 @@ public: * in a term cannot be changed, nor can new terms be added. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h index 86a6d0c54..ec6474e38 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h @@ -137,7 +137,13 @@ public: * grid[x][y][5] = dEd(xy) value */ void setTorsionTorsionGrid(int index, const std::vector > >& grid); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h index ca549b68c..30729f5d3 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h @@ -212,7 +212,13 @@ public: * (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed by reinitializing the Context. */ void updateParametersInContext(Context& context); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return nonbondedMethod == AmoebaVdwForce::CutoffPeriodic}; protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h index fc615e1d2..497b6ebf2 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h @@ -121,7 +121,13 @@ public: void setShctd(double inputValue); void setDispoff(double inputValue); void setSlevy(double inputValue); - + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: diff --git a/plugins/drude/openmmapi/include/openmm/DrudeForce.h b/plugins/drude/openmmapi/include/openmm/DrudeForce.h index 278f53e48..a7215a218 100644 --- a/plugins/drude/openmmapi/include/openmm/DrudeForce.h +++ b/plugins/drude/openmmapi/include/openmm/DrudeForce.h @@ -162,6 +162,13 @@ public: * be used to add new particles or screenedPairs, only to change the parameters of existing ones. */ void updateParametersInContext(Context& context); + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if nonbondedMethod uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: -- GitLab From 930fb6d6d8050817510ed877e98a4b0796e05db0 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 29 Dec 2014 23:12:38 -0500 Subject: [PATCH 173/338] Do not track the vim swp file. --- .../include/openmm/.HarmonicAngleForce.h.swp | Bin 16384 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 openmmapi/include/openmm/.HarmonicAngleForce.h.swp diff --git a/openmmapi/include/openmm/.HarmonicAngleForce.h.swp b/openmmapi/include/openmm/.HarmonicAngleForce.h.swp deleted file mode 100644 index b592e978637b09f4038fd4d2427ffef5994cd3e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeHOU2Ggz6&_m3e+mM%q7SI2jv5?m?RD%%DQ+oQugCEe?~iuZ2@$AecIK}4;@P>& z%&Z-^YLSo-5U|>J|p)AWdh(@8vZ*2I8*FipPtAC0- zfXl$QfUg6mfqCFg;58IK{to;VcpmsM5CZoAzX31I&A0P{$SoX0;$x1^4*kR*kk7w- z(3i5lAo10ajAS>FBYUSr1L3EmM1&+`O8ijzaq8&j$08solR+ewiABgb6qiW#^hws2 zNl5tv)Kkeo#@qUq?)Vy#mX1nFMWEsv5OwOPsGdyH?0+kj>sARvuw;qKL^7aEX`!$t z5Y&?*3K#Ul<+(Zi`IKo&M2W~oiEW!Mr1A+dd-5TDSH>A_i>y8x=--~CvnL4#La!%H z$TeB?iZSkR_7}1XoXAz(m%C8pV-7cl&BY`29~rqhSbDo9xd5 zJfvQ1ThE?^s&kXk>-#Bng}{J>p$JP>LQDe{%HBRnbT>7q>>^eob@z2w?7XSS^pH*Z zLpMa7zD#LPMiKYe71AwQzI);aBW&ib-%*aqfu-OgPOW4IERYa*Hl8n z5Bg@zA-K|mz1*Sh-Hd`93?nhX_@`_*{7fXi_JOfh+ld+tQ!_^s0e7(z*pj{LCsL$i zF9XB-Ff8k9*V5kRuqQb&$VrDj^lIQ|R<#tLJapVf}Ec?NXyfjn0PKqBXa&>DAA* z$*U7CP`k0-xln1j;QbvOSPJHhpbK8xEm5WAwIPkxTa8+Y8e1J|taD!wUTxItZnfhz z>U6>DY#iu}AK}hP%Ui3|D(BqxM8{39vg&Pmor@*9u;FU8A+UmfMjrZr^iB(>CF=0B zggkv{c`UiI)!AsY+9mU#x4MPLbPv@=^J2?8w}GkL*j#gQan&X6aMPuAh^f>sQgyT9 z!5kb~-n!SRyY05QP0dQH<5jmdD=lhnwVDl(TdA*6y;1k->n)Js*4%n$fhnjr$UTn} zYHw6FH^=h4T65EL*GhP#y1BK+{6RlF-GL%Cuj8)4D9sNBrd6qTJSJzIYHq8#fzvTL zR=??CB(F`)R^z<41}QTY40C%1EMfq7aICzGER7BQyjO=BSlU`_AFS8*Y9?>aA1#kp zvp@}b`eCZ4qi&k{W+CUvgLT}_T0w2q%l7<4T+UQA=4DX^IK`3_2}|mu7545_x@XAZ*B!aj~;ePnf4KBV1Er2rK-dXm?bga zaid6KJ=x~HGL)K-6-&S2FAmF0oS5R#L?U@lC1bcUW+M#1e!;Y&&%M6F-VVm}q2=+J zW=%hUH5>~#h(uJRcMOh>l5Jen+gjQ$QHcF1k=;>-i%=e$qlmec^*^>uU|Y8PbgqLEt|>vpE+4F{@k4S0tEI&BCzpoC-6buE_=LLApQstfUwoD#*gI}0k=KD^Lq{Z^%l)V3Dc&XQ4pXcx|ffGxKZPBTJ6 z5F%y^K`?t=-P@p+@HM&v)x@rAeVap2c2ff)1aqP2$ry~8xPGJ3s$uJ{R_fu2g<-p$o-!IE&y*J_kRtz z1Pp;QKpA)mHGpS;hOGzu0(F1@_#*I6)B#=rhQM2>1AG?8$>Xvz^(UleVCu^Jouy?<`kda*?Mv%9@-m z9Xwq|Jf{%Eaj=Xk+4u}XR~%l4Cz|UA=(Dr~EG{e>!}yVLPq>kPUz+;9jPLWO%<~f+ zbFB|{zhfSo)))qirB1#sKja*&%p9%ZtgMWCV}>wFNLSAe6S<3+k-z6#XI?``s zfG}9c=m|=4h-4%OGy}5(BiBHfnpevfOr5|EbDD)KD<gGkhBm|h+vXEnSx6# z#C}XAE~bhG@hx2>MDeH(Xbrfp&Tw#EcWck@oimB8{5-C z?51KAjixq zyCTeq%|DTp=&T5m2ZYQQL8nO`t?6Sm5jYN^q^=-dt)|EAY++Cn>j*1@FJO~1X7IEWl{w6FovC7=^yIS@No}rcd8-M0(WcY)r!o)K#XReyz5L_hEYP&W$>Ii&oG70&H(^8vp Date: Tue, 30 Dec 2014 00:08:29 -0500 Subject: [PATCH 174/338] Add tests for the new usesPeriodicBoundaryConditions API function to the Reference platform. --- .../tests/TestReferenceCMAPTorsionForce.cpp | 4 ++++ .../tests/TestReferenceCustomAngleForce.cpp | 2 ++ .../tests/TestReferenceCustomBondForce.cpp | 2 ++ .../TestReferenceCustomCompoundBondForce.cpp | 2 ++ .../TestReferenceCustomExternalForce.cpp | 2 ++ .../tests/TestReferenceCustomGBForce.cpp | 11 +++++++++++ .../tests/TestReferenceCustomHbondForce.cpp | 2 ++ .../TestReferenceCustomManyParticleForce.cpp | 7 +++++++ .../TestReferenceCustomNonbondedForce.cpp | 6 ++++++ .../tests/TestReferenceCustomTorsionForce.cpp | 2 ++ .../tests/TestReferenceGBSAOBCForce.cpp | 16 ++++++++++++++++ .../tests/TestReferenceGBVIForce.cpp | 2 ++ .../tests/TestReferenceHarmonicAngleForce.cpp | 2 ++ .../tests/TestReferenceHarmonicBondForce.cpp | 2 ++ .../tests/TestReferenceNonbondedForce.cpp | 19 +++++++++++++++++++ .../TestReferencePeriodicTorsionForce.cpp | 2 ++ .../tests/TestReferenceRBTorsionForce.cpp | 2 ++ 17 files changed, 85 insertions(+) diff --git a/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp b/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp index 86cbee2af..f88e51d94 100644 --- a/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp +++ b/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp @@ -64,6 +64,8 @@ void testCMAPTorsions() { periodic->addTorsion(0, 1, 2, 3, 2, M_PI/4, 1.5); periodic->addTorsion(1, 2, 3, 4, 3, M_PI/3, 2.0); system1.addForce(periodic); + ASSERT(!periodic->usesPeriodicBoundaryConditions()); + ASSERT(!system1.usesPeriodicBoundaryConditions()); System system2; for (int i = 0; i < 5; i++) system2.addParticle(1.0); @@ -81,6 +83,8 @@ void testCMAPTorsions() { cmap->addMap(mapSize, mapEnergy); cmap->addTorsion(0, 0, 1, 2, 3, 1, 2, 3, 4); system2.addForce(cmap); + ASSERT(!cmap->usesPeriodicBoundaryConditions()); + ASSERT(!system2.usesPeriodicBoundaryConditions()); // Set the atoms in various positions, and verify that both systems give equal forces and energy. diff --git a/platforms/reference/tests/TestReferenceCustomAngleForce.cpp b/platforms/reference/tests/TestReferenceCustomAngleForce.cpp index b4e319cf2..179332463 100644 --- a/platforms/reference/tests/TestReferenceCustomAngleForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomAngleForce.cpp @@ -71,6 +71,8 @@ void testAngles() { parameters[1] = 0.5; custom->addAngle(1, 2, 3, parameters); customSystem.addForce(custom); + ASSERT(!custom->usesPeriodicBoundaryConditions()); + ASSERT(!customSystem.usesPeriodicBoundaryConditions()); // Create an identical system using a HarmonicAngleForce. diff --git a/platforms/reference/tests/TestReferenceCustomBondForce.cpp b/platforms/reference/tests/TestReferenceCustomBondForce.cpp index 8cd760435..eaf5e6a20 100644 --- a/platforms/reference/tests/TestReferenceCustomBondForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomBondForce.cpp @@ -67,6 +67,8 @@ void testBonds() { parameters[1] = 0.7; forceField->addBond(1, 2, parameters); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(3); positions[0] = Vec3(0, 2, 0); diff --git a/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp b/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp index d70cd07f3..8c5364f17 100644 --- a/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp @@ -85,6 +85,8 @@ void testBond() { parameters[5] = 1.3; custom->addBond(particles, parameters); customSystem.addForce(custom); + ASSERT(!custom->usesPeriodicBoundaryConditions()); + ASSERT(!customSystem.usesPeriodicBoundaryConditions()); // Create an identical system using standard forces. diff --git a/platforms/reference/tests/TestReferenceCustomExternalForce.cpp b/platforms/reference/tests/TestReferenceCustomExternalForce.cpp index 99b0cf7bf..5c46385af 100644 --- a/platforms/reference/tests/TestReferenceCustomExternalForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomExternalForce.cpp @@ -67,6 +67,8 @@ void testForce() { parameters[1] = 3.0; forceField->addParticle(2, parameters); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(3); positions[0] = Vec3(0, 2, 0); diff --git a/platforms/reference/tests/TestReferenceCustomGBForce.cpp b/platforms/reference/tests/TestReferenceCustomGBForce.cpp index f8e48b1c4..eceafde73 100644 --- a/platforms/reference/tests/TestReferenceCustomGBForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomGBForce.cpp @@ -135,6 +135,17 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe custom->setNonbondedMethod(customMethod); standardSystem.addForce(obc); customSystem.addForce(custom); + if (customMethod == CustomGBForce::CutoffPeriodic) { + ASSERT(custom->usesPeriodicBoundaryConditions()); + ASSERT(obc->usesPeriodicBoundaryConditions()); + ASSERT(standardSystem.usesPeriodicBoundaryConditions()); + ASSERT(customSystem.usesPeriodicBoundaryConditions()); + } else { + ASSERT(!custom->usesPeriodicBoundaryConditions()); + ASSERT(!obc->usesPeriodicBoundaryConditions()); + ASSERT(!standardSystem.usesPeriodicBoundaryConditions()); + ASSERT(!customSystem.usesPeriodicBoundaryConditions()); + } VerletIntegrator integrator1(0.01); VerletIntegrator integrator2(0.01); Context context1(standardSystem, integrator1, platform); diff --git a/platforms/reference/tests/TestReferenceCustomHbondForce.cpp b/platforms/reference/tests/TestReferenceCustomHbondForce.cpp index 67dfee9b1..37215258e 100644 --- a/platforms/reference/tests/TestReferenceCustomHbondForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomHbondForce.cpp @@ -83,6 +83,8 @@ void testHbond() { custom->addAcceptor(2, 3, 4, parameters); custom->setCutoffDistance(10.0); customSystem.addForce(custom); + ASSERT(!custom->usesPeriodicBoundaryConditions()); + ASSERT(!customSystem.usesPeriodicBoundaryConditions()); // Create an identical system using HarmonicBondForce, HarmonicAngleForce, and PeriodicTorsionForce. diff --git a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp index 22c312197..5e9229e6a 100644 --- a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp @@ -63,6 +63,13 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p system.addParticle(1.0); system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); system.addForce(force); + if (force->getNonbondedMethod() == CustomManyParticleForce::CutoffPeriodic) { + ASSERT(force->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); + } else { + ASSERT(!force->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); + } VerletIntegrator integrator(0.001); ReferencePlatform platform; Context context(system, integrator, platform); diff --git a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp index 23d254141..bf854f1ef 100644 --- a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp @@ -184,6 +184,8 @@ void testCutoff() { forceField->setNonbondedMethod(CustomNonbondedForce::CutoffNonPeriodic); forceField->setCutoffDistance(2.5); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(3); positions[0] = Vec3(0, 0, 0); @@ -213,6 +215,8 @@ void testPeriodic() { forceField->setCutoffDistance(2.0); system.setDefaultPeriodicBoxVectors(Vec3(4, 0, 0), Vec3(0, 4, 0), Vec3(0, 0, 4)); system.addForce(forceField); + ASSERT(forceField->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(3); positions[0] = Vec3(0, 0, 0); @@ -531,6 +535,8 @@ void testCoulombLennardJones() { customNonbonded->setNonbondedMethod(CustomNonbondedForce::NoCutoff); standardSystem.addForce(standardNonbonded); customSystem.addForce(customNonbonded); + ASSERT(!customNonbonded->usesPeriodicBoundaryConditions()); + ASSERT(!customSystem.usesPeriodicBoundaryConditions()); VerletIntegrator integrator1(0.01); VerletIntegrator integrator2(0.01); Context context1(standardSystem, integrator1, platform); diff --git a/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp b/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp index 8b6cf2868..3ddd6773d 100644 --- a/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp @@ -75,6 +75,8 @@ void testTorsions() { parameters[1] = 2; custom->addTorsion(1, 2, 3, 4, parameters); customSystem.addForce(custom); + ASSERT(!custom->usesPeriodicBoundaryConditions()); + ASSERT(!customSystem.usesPeriodicBoundaryConditions()); // Create an identical system using a PeriodicTorsionForce. diff --git a/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp b/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp index 72723e143..d9ff935a1 100644 --- a/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp +++ b/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp @@ -58,6 +58,8 @@ void testSingleParticle() { GBSAOBCForce* forceField = new GBSAOBCForce(); forceField->addParticle(0.5, 0.15, 1); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(1); positions[0] = Vec3(0, 0, 0); @@ -96,6 +98,8 @@ void testGlobalSettings() { forceField->setSolventDielectric(solventDielectric); forceField->setSurfaceAreaEnergy(surfaceAreaEnergy); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(1); positions[0] = Vec3(0, 0, 0); @@ -136,22 +140,34 @@ void testCutoffAndPeriodic() { nonbonded->setNonbondedMethod(NonbondedForce::CutoffNonPeriodic); gbsa->setNonbondedMethod(GBSAOBCForce::CutoffNonPeriodic); + ASSERT(!nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(!gbsa->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); context.setPositions(positions); State state1 = context.getState(State::Forces); nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); gbsa->setNonbondedMethod(GBSAOBCForce::CutoffPeriodic); + ASSERT(nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(gbsa->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); context.reinitialize(); context.setPositions(positions); State state2 = context.getState(State::Forces); positions[1][0]+= boxSize; nonbonded->setNonbondedMethod(NonbondedForce::CutoffNonPeriodic); gbsa->setNonbondedMethod(GBSAOBCForce::CutoffNonPeriodic); + ASSERT(!nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(!gbsa->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); context.reinitialize(); context.setPositions(positions); State state3 = context.getState(State::Forces); nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); gbsa->setNonbondedMethod(GBSAOBCForce::CutoffPeriodic); + ASSERT(nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(gbsa->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); context.reinitialize(); context.setPositions(positions); State state4 = context.getState(State::Forces); diff --git a/platforms/reference/tests/TestReferenceGBVIForce.cpp b/platforms/reference/tests/TestReferenceGBVIForce.cpp index 15979a436..131e82861 100644 --- a/platforms/reference/tests/TestReferenceGBVIForce.cpp +++ b/platforms/reference/tests/TestReferenceGBVIForce.cpp @@ -66,6 +66,8 @@ void testSingleParticle() { double gamma = 1.0; forceField->addParticle(charge, radius, gamma); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(1); diff --git a/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp b/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp index 8a84ac153..0d0f7c42c 100644 --- a/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp +++ b/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp @@ -60,6 +60,8 @@ void testAngles() { forceField->addAngle(0, 1, 2, PI_M/3, 1.1); forceField->addAngle(1, 2, 3, PI_M/2, 1.2); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(4); positions[0] = Vec3(0, 1, 0); diff --git a/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp b/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp index 5f9f615fd..f4bab1069 100644 --- a/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp +++ b/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp @@ -59,6 +59,8 @@ void testBonds() { forceField->addBond(0, 1, 1.5, 0.8); forceField->addBond(1, 2, 1.2, 0.7); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(3); positions[0] = Vec3(0, 2, 0); diff --git a/platforms/reference/tests/TestReferenceNonbondedForce.cpp b/platforms/reference/tests/TestReferenceNonbondedForce.cpp index 9e1e00d2f..f22706ff5 100644 --- a/platforms/reference/tests/TestReferenceNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceNonbondedForce.cpp @@ -59,6 +59,8 @@ void testCoulomb() { forceField->addParticle(0.5, 1, 0); forceField->addParticle(-1.5, 1, 0); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(2); positions[0] = Vec3(0, 0, 0); @@ -82,6 +84,8 @@ void testLJ() { forceField->addParticle(0, 1.2, 1); forceField->addParticle(0, 1.4, 2); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(2); positions[0] = Vec3(0, 0, 0); @@ -201,6 +205,8 @@ void testCutoff() { const double eps = 50.0; forceField->setReactionFieldDielectric(eps); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(3); positions[0] = Vec3(0, 0, 0); @@ -252,6 +258,8 @@ void testCutoff14() { second14 = i; } system.addForce(nonbonded); + ASSERT(!nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(5); positions[0] = Vec3(0, 0, 0); @@ -333,6 +341,8 @@ void testPeriodic() { nonbonded->setCutoffDistance(cutoff); system.setDefaultPeriodicBoxVectors(Vec3(4, 0, 0), Vec3(0, 4, 0), Vec3(0, 0, 4)); system.addForce(nonbonded); + ASSERT(nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(3); positions[0] = Vec3(0, 0, 0); @@ -376,6 +386,8 @@ void testDispersionCorrection() { nonbonded->setCutoffDistance(cutoff); system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); system.addForce(nonbonded); + ASSERT(nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); // See if the correction has the correct value. @@ -435,6 +447,13 @@ void testSwitchingFunction(NonbondedForce::NonbondedMethod method) { nonbonded->setSwitchingDistance(1.5); nonbonded->setUseDispersionCorrection(false); system.addForce(nonbonded); + if (method == NonbondedForce::PME) { + ASSERT(nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); + } else { + ASSERT(!nonbonded->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); + } Context context(system, integrator, platform); vector positions(2); positions[0] = Vec3(0, 0, 0); diff --git a/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp b/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp index 816b8dfb2..14bd5f752 100644 --- a/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp +++ b/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp @@ -59,6 +59,8 @@ void testPeriodicTorsions() { PeriodicTorsionForce* forceField = new PeriodicTorsionForce(); forceField->addTorsion(0, 1, 2, 3, 2, PI_M/3, 1.1); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(4); positions[0] = Vec3(0, 1, 0); diff --git a/platforms/reference/tests/TestReferenceRBTorsionForce.cpp b/platforms/reference/tests/TestReferenceRBTorsionForce.cpp index 24311775c..51cbfe899 100644 --- a/platforms/reference/tests/TestReferenceRBTorsionForce.cpp +++ b/platforms/reference/tests/TestReferenceRBTorsionForce.cpp @@ -59,6 +59,8 @@ void testRBTorsions() { RBTorsionForce* forceField = new RBTorsionForce(); forceField->addTorsion(0, 1, 2, 3, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6); system.addForce(forceField); + ASSERT(!forceField->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(4); positions[0] = Vec3(0, 1, 0); -- GitLab From f4af4bb8d988c0dbed8807abb61ef29721cefa07 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 30 Dec 2014 00:12:34 -0500 Subject: [PATCH 175/338] Add test to the Amoeba plugin for the new usesPeriodicBoundaryConditions function call. --- .../reference/tests/TestReferenceAmoebaAngleForce.cpp | 2 ++ .../reference/tests/TestReferenceAmoebaBondForce.cpp | 2 ++ .../tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp | 2 ++ .../tests/TestReferenceAmoebaInPlaneAngleForce.cpp | 2 ++ .../reference/tests/TestReferenceAmoebaMultipoleForce.cpp | 4 ++++ .../tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp | 2 ++ .../reference/tests/TestReferenceAmoebaPiTorsionForce.cpp | 2 ++ .../reference/tests/TestReferenceAmoebaStretchBendForce.cpp | 2 ++ .../tests/TestReferenceAmoebaTorsionTorsionForce.cpp | 2 ++ .../reference/tests/TestReferenceAmoebaVdwForce.cpp | 6 ++++++ .../reference/tests/TestReferenceWcaDispersionForce.cpp | 2 ++ 11 files changed, 28 insertions(+) diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp index 9016b9c6b..9f3d78afb 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp @@ -286,6 +286,8 @@ void testOneAngle( FILE* log ) { amoebaAngleForce->setAmoebaGlobalAngleSextic(sexticK); system.addForce(amoebaAngleForce); + ASSERT(!amoebaAngleForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, Platform::getPlatformByName( "Reference")); std::vector positions(numberOfParticles); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp index 9f12cb0b3..baf391719 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp @@ -193,6 +193,8 @@ void testTwoBond( FILE* log ) { amoebaBondForce->addBond(1, 2, bondLength, quadraticK); system.addForce(amoebaBondForce); + ASSERT(!amoebaBondForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, Platform::getPlatformByName( "Reference")); std::vector positions(3); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp index e42b9f081..e615a4343 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp @@ -7176,6 +7176,8 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE System system; AmoebaGeneralizedKirkwoodForce* amoebaGeneralizedKirkwoodForce = new AmoebaGeneralizedKirkwoodForce(); setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Mutual, 1); + ASSERT(!amoebaGeneralizedKirkwoodForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); getForcesEnergyMultipoleAmmonia(context, forces, energy, log ); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp index 0c3cd145a..5bb873101 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp @@ -361,6 +361,8 @@ void testOneAngle( FILE* log ) { amoebaInPlaneAngleForce->setAmoebaGlobalInPlaneAngleSextic(sexticK); system.addForce(amoebaInPlaneAngleForce); + ASSERT(!amoebaInPlaneAngleForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, Platform::getPlatformByName( "Reference")); std::vector positions(numberOfParticles); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp index ea5d00cd5..6316d50e0 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp @@ -460,6 +460,8 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; setupMultipoleAmmonia(system, amoebaMultipoleForce, AmoebaMultipoleForce::NoCutoff, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension); + ASSERT(!amoebaMultipoleForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); getForcesEnergyMultipoleAmmonia(context, forces, energy); @@ -639,6 +641,8 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01 ); system.addForce(amoebaMultipoleForce); + ASSERT(amoebaMultipoleForce->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); std::string platformName; platformName = "Reference"; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp index a1aed8ba7..399725703 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp @@ -321,6 +321,8 @@ void testOneOutOfPlaneBend( FILE* log ) { amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend ); system.addForce(amoebaOutOfPlaneBendForce); + ASSERT(!amoebaOutOfPlaneBendForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, Platform::getPlatformByName( "Reference")); std::vector positions(numberOfParticles); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp index 66d5da3ee..8b204c4d0 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp @@ -285,6 +285,8 @@ void testOnePiTorsion( FILE* log ) { amoebaPiTorsionForce->addPiTorsion(0, 1, 2, 3, 4, 5, kTorsion ); system.addForce(amoebaPiTorsionForce); + ASSERT(!amoebaPiTorsionForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, Platform::getPlatformByName( "Reference")); std::vector positions(numberOfParticles); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp index 6f2ce53e7..3357d21cd 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp @@ -275,6 +275,8 @@ void testOneStretchBend( FILE* log ) { amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend ); system.addForce(amoebaStretchBendForce); + ASSERT(!amoebaStretchBendForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, Platform::getPlatformByName( "Reference")); std::vector positions(numberOfParticles); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp index 7bff871b0..10283c058 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp @@ -2646,6 +2646,8 @@ void testTorsionTorsion(int systemId, bool includeDerivs) { amoebaTorsionTorsionForce->setTorsionTorsionGrid(0, getTorsionGrid(gridIndex, includeDerivs)); system.addForce(amoebaTorsionTorsionForce); + ASSERT(!amoebaTorsionTorsionForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); Context context(system, integrator, Platform::getPlatformByName("Reference")); context.setPositions(positions); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp index f45d30d34..6b60307b4 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp @@ -328,6 +328,12 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c system.addForce(amoebaVdwForce); + if( boxDimension > 0.0 ){ + ASSERT(amoebaVdwForce->usesPeriodicBoundaryConditions()); + } else { + ASSERT(!amoebaVdwForce->usesPeriodicBoundaryConditions()); + } + std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp index 9af4094ca..224b5ee95 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp @@ -116,6 +116,8 @@ void testWcaDispersionAmmonia( FILE* log ) { positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); system.addForce(amoebaWcaDispersionForce); + ASSERT(!amoebaWcaDispersionForce->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); std::string platformName; platformName = "Reference"; -- GitLab From 876329d4b68c8927ed59761602b654cddd650916 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 30 Dec 2014 00:17:15 -0500 Subject: [PATCH 176/338] Add a test to the Drude force for usesPeriodicBoundaryConditions --- .../drude/platforms/reference/tests/TestReferenceDrudeForce.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp b/plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp index f27f7bfc2..e183d500c 100644 --- a/plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp +++ b/plugins/drude/platforms/reference/tests/TestReferenceDrudeForce.cpp @@ -85,6 +85,8 @@ void testSingleParticle() { DrudeForce* drude = new DrudeForce(); drude->addParticle(1, 0, -1, -1, -1, charge, alpha, 1, 1); system.addForce(drude); + ASSERT(!drude->usesPeriodicBoundaryConditions()); + ASSERT(!system.usesPeriodicBoundaryConditions()); vector positions(2); positions[0] = Vec3(-1, 0, 0); positions[1] = Vec3(2, 0, 0); -- GitLab From eb2e1ee3e9cd3a1de6affd48eddc9e8c6c86f88d Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 30 Dec 2014 00:30:23 -0500 Subject: [PATCH 177/338] Remove NotImplementedError -- do everything through OpenMMException --- openmmapi/include/openmm/Force.h | 2 +- openmmapi/include/openmm/OpenMMException.h | 11 ----------- openmmapi/include/openmm/System.h | 2 +- openmmapi/src/Force.cpp | 2 +- openmmapi/src/System.cpp | 2 +- 5 files changed, 4 insertions(+), 15 deletions(-) diff --git a/openmmapi/include/openmm/Force.h b/openmmapi/include/openmm/Force.h index ee94fdd13..537f47915 100644 --- a/openmmapi/include/openmm/Force.h +++ b/openmmapi/include/openmm/Force.h @@ -81,7 +81,7 @@ public: /** * Returns whether or not this force makes use of periodic boundary * conditions. This method should be overridden for all Force subclasses, or - * a OpenMM::NotImplementedError will be thrown + * a OpenMM::OpenMMException will be thrown * * @return true if Force uses periodic boundaries or false if it does not */ diff --git a/openmmapi/include/openmm/OpenMMException.h b/openmmapi/include/openmm/OpenMMException.h index 0085d3010..7533324ee 100644 --- a/openmmapi/include/openmm/OpenMMException.h +++ b/openmmapi/include/openmm/OpenMMException.h @@ -54,17 +54,6 @@ private: std::string message; }; -class NotImplementedError : public std::exception { -public: - explicit NotImplementedError(const std::string& message) : message(message) { - } - ~NotImplementedError() throw() { - } - const char* what() const throw() { - return message.c_str(); - } -}; - } // namespace OpenMM #endif /*OPENMM_OPENMMEXCEPTION_H_*/ diff --git a/openmmapi/include/openmm/System.h b/openmmapi/include/openmm/System.h index 7bce2fe24..a1e01bc9c 100644 --- a/openmmapi/include/openmm/System.h +++ b/openmmapi/include/openmm/System.h @@ -228,7 +228,7 @@ public: * Returns whether or not any forces in this System use periodic boundaries. * * If a force in this System does not implement usesPeriodicBoundaryConditions - * a NotImplementedError is thrown + * a OpenMM::OpenMMException is thrown * * @return true of at least one force uses PBC and false otherwise */ diff --git a/openmmapi/src/Force.cpp b/openmmapi/src/Force.cpp index 00cf41d76..cae2ca21b 100644 --- a/openmmapi/src/Force.cpp +++ b/openmmapi/src/Force.cpp @@ -50,7 +50,7 @@ void Force::setForceGroup(int group) { } bool Force::usesPeriodicBoundaryConditions() const { - throw NotImplementedError("usesPeriodicBoundaryConditions is not implemented"); + throw OpenMMException("usesPeriodicBoundaryConditions is not implemented"); } ForceImpl& Force::getImplInContext(Context& context) { diff --git a/openmmapi/src/System.cpp b/openmmapi/src/System.cpp index a23485d76..29c38167c 100644 --- a/openmmapi/src/System.cpp +++ b/openmmapi/src/System.cpp @@ -129,7 +129,7 @@ bool System::usesPeriodicBoundaryConditions() { try { if ((*it)->usesPeriodicBoundaryConditions()) uses_pbc = true; - } catch (NotImplementedError &e) { + } catch (OpenMMException &e) { all_forces_implement = false; } } -- GitLab From 92d5b9a7b62fd65f60f719c2dfdb764842ac82f4 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 30 Dec 2014 00:32:35 -0500 Subject: [PATCH 178/338] Small typo. --- plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h index 30729f5d3..33d1b6b87 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h @@ -218,7 +218,7 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return nonbondedMethod == AmoebaVdwForce::CutoffPeriodic}; + bool usesPeriodicBoundaryConditions() const {return nonbondedMethod == AmoebaVdwForce::CutoffPeriodic;} protected: ForceImpl* createImpl() const; private: -- GitLab From 1b44cb9e5e257ab406cfe917debf9ba6723bd927 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 30 Dec 2014 01:15:12 -0500 Subject: [PATCH 179/338] Fix up some of the documentation and add the usesPeriodicBoundaryConditions to the barostats and andersen thermostat. --- openmmapi/include/openmm/AndersenThermostat.h | 7 +++++++ openmmapi/include/openmm/CMMotionRemover.h | 7 +++++++ openmmapi/include/openmm/CustomGBForce.h | 2 +- openmmapi/include/openmm/CustomHbondForce.h | 2 +- openmmapi/include/openmm/CustomManyParticleForce.h | 2 +- openmmapi/include/openmm/CustomNonbondedForce.h | 2 +- openmmapi/include/openmm/CustomTorsionForce.h | 2 +- openmmapi/include/openmm/GBSAOBCForce.h | 2 +- openmmapi/include/openmm/GBVIForce.h | 2 +- openmmapi/include/openmm/HarmonicAngleForce.h | 2 +- openmmapi/include/openmm/HarmonicBondForce.h | 2 +- openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h | 7 +++++++ openmmapi/include/openmm/MonteCarloBarostat.h | 7 +++++++ openmmapi/include/openmm/MonteCarloMembraneBarostat.h | 7 +++++++ openmmapi/include/openmm/NonbondedForce.h | 2 +- openmmapi/include/openmm/PeriodicTorsionForce.h | 2 +- openmmapi/include/openmm/RBTorsionForce.h | 2 +- 17 files changed, 47 insertions(+), 12 deletions(-) diff --git a/openmmapi/include/openmm/AndersenThermostat.h b/openmmapi/include/openmm/AndersenThermostat.h index bb1c5b063..cba3053ed 100644 --- a/openmmapi/include/openmm/AndersenThermostat.h +++ b/openmmapi/include/openmm/AndersenThermostat.h @@ -117,6 +117,13 @@ public: void setRandomNumberSeed(int seed) { randomNumberSeed = seed; } + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if force uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CMMotionRemover.h b/openmmapi/include/openmm/CMMotionRemover.h index ad003b569..6e1107fc4 100644 --- a/openmmapi/include/openmm/CMMotionRemover.h +++ b/openmmapi/include/openmm/CMMotionRemover.h @@ -61,6 +61,13 @@ public: void setFrequency(int freq) { frequency = freq; } + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if force uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return false;} protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CustomGBForce.h b/openmmapi/include/openmm/CustomGBForce.h index 4d0613333..df7d76c9d 100644 --- a/openmmapi/include/openmm/CustomGBForce.h +++ b/openmmapi/include/openmm/CustomGBForce.h @@ -527,7 +527,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const { return nonbondedMethod == CustomGBForce::CutoffPeriodic; diff --git a/openmmapi/include/openmm/CustomHbondForce.h b/openmmapi/include/openmm/CustomHbondForce.h index c3dc1667a..51475e588 100644 --- a/openmmapi/include/openmm/CustomHbondForce.h +++ b/openmmapi/include/openmm/CustomHbondForce.h @@ -447,7 +447,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const { return nonbondedMethod == CustomHbondForce::CutoffPeriodic; diff --git a/openmmapi/include/openmm/CustomManyParticleForce.h b/openmmapi/include/openmm/CustomManyParticleForce.h index 08edfdffa..c1257c801 100644 --- a/openmmapi/include/openmm/CustomManyParticleForce.h +++ b/openmmapi/include/openmm/CustomManyParticleForce.h @@ -465,7 +465,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const { return nonbondedMethod == CustomManyParticleForce::CutoffPeriodic; diff --git a/openmmapi/include/openmm/CustomNonbondedForce.h b/openmmapi/include/openmm/CustomNonbondedForce.h index e9609d518..74fae4ec8 100644 --- a/openmmapi/include/openmm/CustomNonbondedForce.h +++ b/openmmapi/include/openmm/CustomNonbondedForce.h @@ -468,7 +468,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const { return nonbondedMethod == CustomNonbondedForce::CutoffPeriodic; diff --git a/openmmapi/include/openmm/CustomTorsionForce.h b/openmmapi/include/openmm/CustomTorsionForce.h index 3d1371a75..223f1ca43 100644 --- a/openmmapi/include/openmm/CustomTorsionForce.h +++ b/openmmapi/include/openmm/CustomTorsionForce.h @@ -209,7 +209,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const {return false;} protected: diff --git a/openmmapi/include/openmm/GBSAOBCForce.h b/openmmapi/include/openmm/GBSAOBCForce.h index 996df681f..60f54fa4a 100644 --- a/openmmapi/include/openmm/GBSAOBCForce.h +++ b/openmmapi/include/openmm/GBSAOBCForce.h @@ -188,7 +188,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const { return nonbondedMethod == GBSAOBCForce::CutoffPeriodic; diff --git a/openmmapi/include/openmm/GBVIForce.h b/openmmapi/include/openmm/GBVIForce.h index b1ce1c328..41a96cd26 100644 --- a/openmmapi/include/openmm/GBVIForce.h +++ b/openmmapi/include/openmm/GBVIForce.h @@ -233,7 +233,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const { return nonbondedMethod == GBVIForce::CutoffPeriodic; diff --git a/openmmapi/include/openmm/HarmonicAngleForce.h b/openmmapi/include/openmm/HarmonicAngleForce.h index 391adc913..e3f88d586 100644 --- a/openmmapi/include/openmm/HarmonicAngleForce.h +++ b/openmmapi/include/openmm/HarmonicAngleForce.h @@ -106,7 +106,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const {return false;} protected: diff --git a/openmmapi/include/openmm/HarmonicBondForce.h b/openmmapi/include/openmm/HarmonicBondForce.h index 68f91a68d..6b6391ab1 100644 --- a/openmmapi/include/openmm/HarmonicBondForce.h +++ b/openmmapi/include/openmm/HarmonicBondForce.h @@ -103,7 +103,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const {return false;} protected: diff --git a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h index 9bbc06424..22a1cdfb3 100644 --- a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h +++ b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h @@ -171,6 +171,13 @@ public: void setRandomNumberSeed(int seed) { randomNumberSeed = seed; } + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if force uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return true;} protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index 93a0efccd..5ee22912f 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -127,6 +127,13 @@ public: void setRandomNumberSeed(int seed) { randomNumberSeed = seed; } + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if force uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return true;} protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h index a65d0793c..efb78524b 100644 --- a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -224,6 +224,13 @@ public: void setRandomNumberSeed(int seed) { randomNumberSeed = seed; } + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if force uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const {return true;} protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/NonbondedForce.h b/openmmapi/include/openmm/NonbondedForce.h index 1b05b1582..371acb515 100644 --- a/openmmapi/include/openmm/NonbondedForce.h +++ b/openmmapi/include/openmm/NonbondedForce.h @@ -356,7 +356,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const { return nonbondedMethod == NonbondedForce::CutoffPeriodic || diff --git a/openmmapi/include/openmm/PeriodicTorsionForce.h b/openmmapi/include/openmm/PeriodicTorsionForce.h index a11b02631..c4926f815 100644 --- a/openmmapi/include/openmm/PeriodicTorsionForce.h +++ b/openmmapi/include/openmm/PeriodicTorsionForce.h @@ -112,7 +112,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const {return false;} protected: diff --git a/openmmapi/include/openmm/RBTorsionForce.h b/openmmapi/include/openmm/RBTorsionForce.h index b330eccb2..a35e5c4e0 100644 --- a/openmmapi/include/openmm/RBTorsionForce.h +++ b/openmmapi/include/openmm/RBTorsionForce.h @@ -121,7 +121,7 @@ public: * Returns whether or not this force makes use of periodic boundary * conditions. * - * @returns true if nonbondedMethod uses PBC and false otherwise + * @returns true if force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions() const {return false;} protected: -- GitLab From ba37b26b6a167b5669673d208761c23f06e5c280 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 30 Dec 2014 01:20:36 -0500 Subject: [PATCH 180/338] Update the tests of the classes I just updated. --- .../reference/tests/TestReferenceAndersenThermostat.cpp | 1 + .../tests/TestReferenceMonteCarloAnisotropicBarostat.cpp | 6 ++++++ .../reference/tests/TestReferenceMonteCarloBarostat.cpp | 4 ++++ .../tests/TestReferenceMonteCarloMembraneBarostat.cpp | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/platforms/reference/tests/TestReferenceAndersenThermostat.cpp b/platforms/reference/tests/TestReferenceAndersenThermostat.cpp index f8d7f0cf2..5bd84a99c 100644 --- a/platforms/reference/tests/TestReferenceAndersenThermostat.cpp +++ b/platforms/reference/tests/TestReferenceAndersenThermostat.cpp @@ -64,6 +64,7 @@ void testTemperature() { system.addForce(forceField); AndersenThermostat* thermstat = new AndersenThermostat(temp, collisionFreq); system.addForce(thermstat); + ASSERT(!thermostat->usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(numParticles); for (int i = 0; i < numParticles; ++i) diff --git a/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp index 0a327c5f3..67718a759 100644 --- a/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp +++ b/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp @@ -75,6 +75,8 @@ void testIdealGas() { } MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], true, true, true, frequency); system.addForce(barostat); + ASSERT(barostat->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); // Test it for three different temperatures. @@ -134,6 +136,8 @@ void testIdealGasAxis(int axis) { } MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp[0], scaleX, scaleY, scaleZ, frequency); system.addForce(barostat); + ASSERT(barostat->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); // Test it for three different temperatures. @@ -191,6 +195,8 @@ void testRandomSeed() { system.addForce(forceField); MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temp, true, true, true, 1); system.addForce(barostat); + ASSERT(barostat->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); vector positions(numParticles); vector velocities(numParticles); for (int i = 0; i < numParticles; ++i) { diff --git a/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp index 47c17e238..f436114f4 100644 --- a/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp +++ b/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp @@ -112,6 +112,8 @@ void testIdealGas() { } MonteCarloBarostat* barostat = new MonteCarloBarostat(pressure, temp[0], frequency); system.addForce(barostat); + ASSERT(barostat->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); // Test it for three different temperatures. @@ -159,6 +161,8 @@ void testRandomSeed() { system.addForce(forceField); MonteCarloBarostat* barostat = new MonteCarloBarostat(pressure, temp, 1); system.addForce(barostat); + ASSERT(barostat->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); vector positions(numParticles); vector velocities(numParticles); for (int i = 0; i < numParticles; ++i) { diff --git a/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp index fa8ea8ddf..cf5c09b3e 100644 --- a/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp +++ b/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp @@ -75,6 +75,8 @@ void testIdealGas(MonteCarloMembraneBarostat::XYMode xymode, MonteCarloMembraneB } MonteCarloMembraneBarostat* barostat = new MonteCarloMembraneBarostat(pressure, tension, temp[0], xymode, zmode, frequency); system.addForce(barostat); + ASSERT(barostat->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); // Test it for three different temperatures. @@ -132,6 +134,8 @@ void testRandomSeed() { system.addForce(forceField); MonteCarloMembraneBarostat* barostat = new MonteCarloMembraneBarostat(pressure, tension, temp, MonteCarloMembraneBarostat::XYAnisotropic, MonteCarloMembraneBarostat::ZFree, 1); system.addForce(barostat); + ASSERT(barostat->usesPeriodicBoundaryConditions()); + ASSERT(system.usesPeriodicBoundaryConditions()); vector positions(numParticles); vector velocities(numParticles); for (int i = 0; i < numParticles; ++i) { -- GitLab From ab82c962247140b3d7583bdfcd69840d7e9e287e Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Tue, 30 Dec 2014 09:58:04 -0500 Subject: [PATCH 181/338] thermstat -> thermostat --- .../reference/tests/TestReferenceAndersenThermostat.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platforms/reference/tests/TestReferenceAndersenThermostat.cpp b/platforms/reference/tests/TestReferenceAndersenThermostat.cpp index 5bd84a99c..0ca2a70ba 100644 --- a/platforms/reference/tests/TestReferenceAndersenThermostat.cpp +++ b/platforms/reference/tests/TestReferenceAndersenThermostat.cpp @@ -62,8 +62,8 @@ void testTemperature() { forceField->addParticle((i%2 == 0 ? 1.0 : -1.0), 1.0, 5.0); } system.addForce(forceField); - AndersenThermostat* thermstat = new AndersenThermostat(temp, collisionFreq); - system.addForce(thermstat); + AndersenThermostat* thermostat = new AndersenThermostat(temp, collisionFreq); + system.addForce(thermostat); ASSERT(!thermostat->usesPeriodicBoundaryConditions()); Context context(system, integrator, platform); vector positions(numParticles); @@ -111,8 +111,8 @@ void testConstraints() { system.addConstraint(5, 6, 1); system.addConstraint(6, 7, 1); system.addConstraint(7, 4, 1); - AndersenThermostat* thermstat = new AndersenThermostat(temp, collisionFreq); - system.addForce(thermstat); + AndersenThermostat* thermostat = new AndersenThermostat(temp, collisionFreq); + system.addForce(thermostat); Context context(system, integrator, platform); vector positions(numParticles); positions[0] = Vec3(0, 0, 0); -- GitLab From b8f6d2699631a4b47b03a8884e8cfad27b96ce59 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 2 Jan 2015 19:20:00 -0500 Subject: [PATCH 182/338] Changes to bring in line with SimTK style guide. --- openmmapi/include/openmm/AndersenThermostat.h | 4 +++- openmmapi/include/openmm/CMAPTorsionForce.h | 4 +++- openmmapi/include/openmm/CMMotionRemover.h | 4 +++- openmmapi/include/openmm/CustomAngleForce.h | 4 +++- openmmapi/include/openmm/CustomBondForce.h | 4 +++- .../include/openmm/CustomCompoundBondForce.h | 4 +++- .../include/openmm/CustomExternalForce.h | 4 +++- openmmapi/include/openmm/CustomTorsionForce.h | 4 +++- openmmapi/include/openmm/HarmonicAngleForce.h | 4 +++- openmmapi/include/openmm/HarmonicBondForce.h | 4 +++- .../openmm/MonteCarloAnisotropicBarostat.h | 4 +++- openmmapi/include/openmm/MonteCarloBarostat.h | 4 +++- .../openmm/MonteCarloMembraneBarostat.h | 4 +++- .../include/openmm/PeriodicTorsionForce.h | 4 +++- openmmapi/include/openmm/RBTorsionForce.h | 4 +++- openmmapi/include/openmm/System.h | 2 +- openmmapi/src/System.cpp | 3 ++- .../tests/TestReferenceCustomGBForce.cpp | 21 ++++++++++++------- .../TestReferenceCustomManyParticleForce.cpp | 3 ++- .../tests/TestReferenceGBVIForce.cpp | 6 ++++-- .../tests/TestReferenceNonbondedForce.cpp | 3 ++- .../include/openmm/AmoebaAngleForce.h | 4 +++- .../include/openmm/AmoebaBondForce.h | 4 +++- .../openmm/AmoebaGeneralizedKirkwoodForce.h | 4 +++- .../include/openmm/AmoebaInPlaneAngleForce.h | 4 +++- .../include/openmm/AmoebaMultipoleForce.h | 4 +++- .../openmm/AmoebaOutOfPlaneBendForce.h | 4 +++- .../include/openmm/AmoebaPiTorsionForce.h | 4 +++- .../include/openmm/AmoebaStretchBendForce.h | 4 +++- .../openmm/AmoebaTorsionTorsionForce.h | 4 +++- .../openmmapi/include/openmm/AmoebaVdwForce.h | 4 +++- .../include/openmm/AmoebaWcaDispersionForce.h | 4 +++- .../openmmapi/include/openmm/DrudeForce.h | 4 +++- 33 files changed, 106 insertions(+), 40 deletions(-) diff --git a/openmmapi/include/openmm/AndersenThermostat.h b/openmmapi/include/openmm/AndersenThermostat.h index cba3053ed..1cf198e74 100644 --- a/openmmapi/include/openmm/AndersenThermostat.h +++ b/openmmapi/include/openmm/AndersenThermostat.h @@ -123,7 +123,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CMAPTorsionForce.h b/openmmapi/include/openmm/CMAPTorsionForce.h index 5fdb8765c..1288f4773 100644 --- a/openmmapi/include/openmm/CMAPTorsionForce.h +++ b/openmmapi/include/openmm/CMAPTorsionForce.h @@ -154,7 +154,9 @@ public: * * @returns false */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CMMotionRemover.h b/openmmapi/include/openmm/CMMotionRemover.h index 6e1107fc4..ba814dac8 100644 --- a/openmmapi/include/openmm/CMMotionRemover.h +++ b/openmmapi/include/openmm/CMMotionRemover.h @@ -67,7 +67,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CustomAngleForce.h b/openmmapi/include/openmm/CustomAngleForce.h index 11f2af55c..e806c47dc 100644 --- a/openmmapi/include/openmm/CustomAngleForce.h +++ b/openmmapi/include/openmm/CustomAngleForce.h @@ -208,7 +208,9 @@ public: * * @returns false */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CustomBondForce.h b/openmmapi/include/openmm/CustomBondForce.h index 811b1f562..84b38cd6b 100644 --- a/openmmapi/include/openmm/CustomBondForce.h +++ b/openmmapi/include/openmm/CustomBondForce.h @@ -205,7 +205,9 @@ public: * * @returns false */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CustomCompoundBondForce.h b/openmmapi/include/openmm/CustomCompoundBondForce.h index db8725035..00d6aa25d 100644 --- a/openmmapi/include/openmm/CustomCompoundBondForce.h +++ b/openmmapi/include/openmm/CustomCompoundBondForce.h @@ -303,7 +303,9 @@ public: * * @returns false */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CustomExternalForce.h b/openmmapi/include/openmm/CustomExternalForce.h index a4dfff55c..d6886bfc6 100644 --- a/openmmapi/include/openmm/CustomExternalForce.h +++ b/openmmapi/include/openmm/CustomExternalForce.h @@ -205,7 +205,9 @@ public: * * @returns false */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/CustomTorsionForce.h b/openmmapi/include/openmm/CustomTorsionForce.h index 223f1ca43..a5a52557f 100644 --- a/openmmapi/include/openmm/CustomTorsionForce.h +++ b/openmmapi/include/openmm/CustomTorsionForce.h @@ -211,7 +211,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/HarmonicAngleForce.h b/openmmapi/include/openmm/HarmonicAngleForce.h index e3f88d586..4eb302d45 100644 --- a/openmmapi/include/openmm/HarmonicAngleForce.h +++ b/openmmapi/include/openmm/HarmonicAngleForce.h @@ -108,7 +108,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/HarmonicBondForce.h b/openmmapi/include/openmm/HarmonicBondForce.h index 6b6391ab1..2c2ca4310 100644 --- a/openmmapi/include/openmm/HarmonicBondForce.h +++ b/openmmapi/include/openmm/HarmonicBondForce.h @@ -105,7 +105,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h index 22a1cdfb3..68c60fe09 100644 --- a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h +++ b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h @@ -177,7 +177,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return true;} + bool usesPeriodicBoundaryConditions() const { + return true; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index 5ee22912f..c78b569fe 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -133,7 +133,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return true;} + bool usesPeriodicBoundaryConditions() const { + return true; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h index efb78524b..05220f43a 100644 --- a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -230,7 +230,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return true;} + bool usesPeriodicBoundaryConditions() const { + return true; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/PeriodicTorsionForce.h b/openmmapi/include/openmm/PeriodicTorsionForce.h index c4926f815..5e06ad940 100644 --- a/openmmapi/include/openmm/PeriodicTorsionForce.h +++ b/openmmapi/include/openmm/PeriodicTorsionForce.h @@ -114,7 +114,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/RBTorsionForce.h b/openmmapi/include/openmm/RBTorsionForce.h index a35e5c4e0..981901541 100644 --- a/openmmapi/include/openmm/RBTorsionForce.h +++ b/openmmapi/include/openmm/RBTorsionForce.h @@ -123,7 +123,9 @@ public: * * @returns true if force uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/openmmapi/include/openmm/System.h b/openmmapi/include/openmm/System.h index a1e01bc9c..eb9fd71ed 100644 --- a/openmmapi/include/openmm/System.h +++ b/openmmapi/include/openmm/System.h @@ -230,7 +230,7 @@ public: * If a force in this System does not implement usesPeriodicBoundaryConditions * a OpenMM::OpenMMException is thrown * - * @return true of at least one force uses PBC and false otherwise + * @return true if at least one force uses PBC and false otherwise */ bool usesPeriodicBoundaryConditions(); private: diff --git a/openmmapi/src/System.cpp b/openmmapi/src/System.cpp index 29c38167c..704b599f4 100644 --- a/openmmapi/src/System.cpp +++ b/openmmapi/src/System.cpp @@ -129,7 +129,8 @@ bool System::usesPeriodicBoundaryConditions() { try { if ((*it)->usesPeriodicBoundaryConditions()) uses_pbc = true; - } catch (OpenMMException &e) { + } + catch (OpenMMException &e) { all_forces_implement = false; } } diff --git a/platforms/reference/tests/TestReferenceCustomGBForce.cpp b/platforms/reference/tests/TestReferenceCustomGBForce.cpp index eceafde73..44f04d9bc 100644 --- a/platforms/reference/tests/TestReferenceCustomGBForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomGBForce.cpp @@ -140,7 +140,8 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe ASSERT(obc->usesPeriodicBoundaryConditions()); ASSERT(standardSystem.usesPeriodicBoundaryConditions()); ASSERT(customSystem.usesPeriodicBoundaryConditions()); - } else { + } + else { ASSERT(!custom->usesPeriodicBoundaryConditions()); ASSERT(!obc->usesPeriodicBoundaryConditions()); ASSERT(!standardSystem.usesPeriodicBoundaryConditions()); @@ -539,7 +540,8 @@ static void buildEthane( GBVIForce* gbviForce, std::vector& positions ) { C_gamma = -0.2863; H_radius = 0.125; H_gamma = 0.2437; - } else { + } + else { C_radius = 0.215; C_gamma = -1.1087; H_radius = 0.150; @@ -617,7 +619,8 @@ static void buildDimer( GBVIForce* gbviForce, std::vector& positions ) { C_gamma = -0.2863; H_radius = 0.125; H_gamma = 0.2437; - } else { + } + else { C_radius = 0.215; C_gamma = -1.1087; H_radius = 0.150; @@ -744,7 +747,8 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR } scaledRadiusJ = radiusJ; // errors++; - } else { + } + else { double rJ2 = radiusJ*radiusJ; @@ -774,7 +778,8 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR scaledRadiusJ = (radiusJ*radiusJ*radiusJ) - 0.125*scaledRadiusJ; if( scaledRadiusJ > 0.0 ){ scaledRadiusJ = 0.95*pow( scaledRadiusJ, (1.0/3.0) ); - } else { + } + else { scaledRadiusJ = 0.0; } } @@ -849,9 +854,11 @@ void testGBVI(GBVIForce::NonbondedMethod gbviMethod, CustomGBForce::NonbondedMet if( molecule == "Monomer" ){ buildMonomer( gbvi, positions ); - } else if( molecule == "Dimer" ){ + } + else if( molecule == "Dimer" ){ buildDimer( gbvi, positions ); - } else { + } + else { buildEthane( gbvi, positions ); } diff --git a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp index 5e9229e6a..82413b7c9 100644 --- a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp @@ -66,7 +66,8 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p if (force->getNonbondedMethod() == CustomManyParticleForce::CutoffPeriodic) { ASSERT(force->usesPeriodicBoundaryConditions()); ASSERT(system.usesPeriodicBoundaryConditions()); - } else { + } + else { ASSERT(!force->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); } diff --git a/platforms/reference/tests/TestReferenceGBVIForce.cpp b/platforms/reference/tests/TestReferenceGBVIForce.cpp index 131e82861..485ad2ac0 100644 --- a/platforms/reference/tests/TestReferenceGBVIForce.cpp +++ b/platforms/reference/tests/TestReferenceGBVIForce.cpp @@ -128,7 +128,8 @@ void testEnergyEthane( int applyBornRadiiScaling ) { C_gamma = -0.2863; H_radius = 0.125; H_gamma = 0.2437; - } else { + } + else { C_radius = 0.215; C_gamma = -1.1087; H_radius = 0.150; @@ -144,7 +145,8 @@ void testEnergyEthane( int applyBornRadiiScaling ) { GBVIForce* forceField = new GBVIForce(); if( applyBornRadiiScaling ){ forceField->setBornRadiusScalingMethod( GBVIForce::QuinticSpline ); - } else { + } + else { forceField->setBornRadiusScalingMethod( GBVIForce::NoScaling ); } for( int i = 0; i < numParticles; i++ ){ diff --git a/platforms/reference/tests/TestReferenceNonbondedForce.cpp b/platforms/reference/tests/TestReferenceNonbondedForce.cpp index f22706ff5..aea6e6cd2 100644 --- a/platforms/reference/tests/TestReferenceNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceNonbondedForce.cpp @@ -450,7 +450,8 @@ void testSwitchingFunction(NonbondedForce::NonbondedMethod method) { if (method == NonbondedForce::PME) { ASSERT(nonbonded->usesPeriodicBoundaryConditions()); ASSERT(system.usesPeriodicBoundaryConditions()); - } else { + } + else { ASSERT(!nonbonded->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); } diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h index e8f7f0467..924b96532 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h @@ -172,7 +172,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; double _globalCubicK, _globalQuarticK, _globalPenticK, _globalSexticK; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h index 316c9ced4..81802104a 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h @@ -144,7 +144,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: double _globalQuarticK, _globalCubicK; ForceImpl* createImpl() const; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h index a2a6c2582..69b535977 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h @@ -169,7 +169,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h index 87c85449f..fb825c9d9 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h @@ -177,7 +177,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; double _globalCubicK, _globalQuarticK, _globalPenticK, _globalSexticK; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h index 90ada1c61..321ea05c1 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h @@ -355,7 +355,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return nonbondedMethod == AmoebaMultipoleForce::PME;} + bool usesPeriodicBoundaryConditions() const { + return nonbondedMethod == AmoebaMultipoleForce::PME; + } protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h index 244c76559..23d416627 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h @@ -169,7 +169,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; double _globalCubicK, _globalQuarticK, _globalPenticK, _globalSexticK; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h index 1c1b0d20e..c04ef68b4 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h @@ -119,7 +119,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index f3554ea89..ad26d045d 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -122,7 +122,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h index ec6474e38..be4c86025 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaTorsionTorsionForce.h @@ -143,7 +143,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h index 33d1b6b87..0dbc0500f 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h @@ -218,7 +218,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return nonbondedMethod == AmoebaVdwForce::CutoffPeriodic;} + bool usesPeriodicBoundaryConditions() const { + return nonbondedMethod == AmoebaVdwForce::CutoffPeriodic; + } protected: ForceImpl* createImpl() const; private: diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h index 497b6ebf2..acc1fd74e 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h @@ -127,7 +127,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: diff --git a/plugins/drude/openmmapi/include/openmm/DrudeForce.h b/plugins/drude/openmmapi/include/openmm/DrudeForce.h index a7215a218..5a7bac510 100644 --- a/plugins/drude/openmmapi/include/openmm/DrudeForce.h +++ b/plugins/drude/openmmapi/include/openmm/DrudeForce.h @@ -168,7 +168,9 @@ public: * * @returns true if nonbondedMethod uses PBC and false otherwise */ - bool usesPeriodicBoundaryConditions() const {return false;} + bool usesPeriodicBoundaryConditions() const { + return false; + } protected: ForceImpl* createImpl() const; private: -- GitLab From 1f15a914a40f863b99e180689869c178180b97b3 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 2 Jan 2015 19:24:00 -0500 Subject: [PATCH 183/338] More } else { --> } else { However, these were not my additions originally, but rather part of the Amoeba test cases that have been around for awhile. I figured while I was at it, I might as well update these styles as well. --- .../tests/TestReferenceAmoebaAngleForce.cpp | 8 +++-- ...eferenceAmoebaGeneralizedKirkwoodForce.cpp | 3 +- .../TestReferenceAmoebaInPlaneAngleForce.cpp | 11 ++++--- .../TestReferenceAmoebaMultipoleForce.cpp | 30 ++++++++++++------- ...TestReferenceAmoebaOutOfPlaneBendForce.cpp | 26 ++++++++++------ .../TestReferenceAmoebaStretchBendForce.cpp | 6 ++-- ...TestReferenceAmoebaTorsionTorsionForce.cpp | 6 ++-- .../tests/TestReferenceAmoebaVdwForce.cpp | 26 ++++++++++------ .../tests/TestReferenceWcaDispersionForce.cpp | 3 +- 9 files changed, 77 insertions(+), 42 deletions(-) diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp index 9f3d78afb..56e2ddc24 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp @@ -82,9 +82,11 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou double angle; if( cosine >= 1.0 ){ angle = 0.0f; - } else if( cosine <= -1.0 ){ + } + else if( cosine <= -1.0 ){ angle = RADIAN*PI_M; - } else { + } + else { angle = RADIAN*acos(cosine); } #ifdef AMOEBA_DEBUG @@ -157,7 +159,7 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions double rp = sqrt( pVector[0]*pVector[0] + pVector[1]*pVector[1] + pVector[2]*pVector[2] ); if( rp < 1.0e-06 ){ rp = 1.0e-06; - } + } double dot = deltaR[0][0]*deltaR[1][0] + deltaR[0][1]*deltaR[1][1] + deltaR[0][2]*deltaR[1][2]; double cosine = dot/sqrt(r2_0*r2_1); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp index e615a4343..e754b6e35 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp @@ -8488,7 +8488,8 @@ int main( int numberOfArguments, char* argv[] ) { testGeneralizedKirkwoodVillinDirectPolarization( log ); testGeneralizedKirkwoodVillinMutualPolarization( log ); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; return 1; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp index 5bb873101..bbcf4b513 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp @@ -84,9 +84,11 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP double angle; if( cosine >= 1.0 ){ angle = 0.0f; - } else if( cosine <= -1.0 ){ + } + else if( cosine <= -1.0 ){ angle = RADIAN*PI_M; - } else { + } + else { angle = RADIAN*acos(cosine); } #ifdef AMOEBA_DEBUG @@ -175,7 +177,7 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po deltaR[P][ii] = positions[particle2][ii] + deltaR[T][ii]*delta; deltaR[AP][ii] = positions[particle1][ii] - deltaR[P][ii]; deltaR[CP][ii] = positions[particle3][ii] - deltaR[P][ii]; - } + } double rAp2 = dotVector3( deltaR[AP], deltaR[AP] ); double rCp2 = dotVector3( deltaR[CP], deltaR[CP] ); @@ -245,7 +247,8 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); } - } else { + } + else { for( int ii = 0; ii < 3; ii++ ){ forceTerm[dA][ii] += delta*deltaR[CDxdB][ii]; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp index 6316d50e0..14f22a557 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp @@ -623,7 +623,7 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond covalentMap.push_back( jj+1 ); amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); - } + } std::vector positions(numberOfParticles); @@ -841,7 +841,8 @@ static void testQuadrupoleValidation( FILE* log ){ std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; throw OpenMMException(buffer.str()); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { } oxygenMolecularQuadrupole[4] -= 0.1; @@ -857,7 +858,8 @@ static void testQuadrupoleValidation( FILE* log ){ std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; throw OpenMMException(buffer.str()); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { } oxygenMolecularQuadrupole[1] -= 0.1; @@ -871,7 +873,8 @@ static void testQuadrupoleValidation( FILE* log ){ std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; throw OpenMMException(buffer.str()); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { } oxygenMolecularQuadrupole[2] -= 0.1; @@ -885,7 +888,8 @@ static void testQuadrupoleValidation( FILE* log ){ std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; throw OpenMMException(buffer.str()); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { } oxygenMolecularQuadrupole[5] -= 0.1; @@ -1043,7 +1047,7 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: covalentMap.push_back( jj+1 ); amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); - } + } std::vector positions(numberOfParticles); @@ -1259,7 +1263,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No covalentMap.push_back( jj+1 ); amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); - } + } system.addForce(amoebaMultipoleForce); static std::vector positions; // Static to work around bug in Visual Studio that makes compilation very very slow. @@ -1923,9 +1927,11 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No if( testName == "testSystemMultipoleMoments" ){ amoebaMultipoleForce->getSystemMultipoleMoments( context, outputMultipoleMoments ); - } else if( testName == "testMultipoleGridPotential" ){ + } + else if( testName == "testMultipoleGridPotential" ){ amoebaMultipoleForce->getElectrostaticPotential( inputGrid, context, outputGridPotential ); - } else { + } + else { State state = context.getState(State::Forces | State::Energy); forces = state.getForces(); @@ -2690,7 +2696,8 @@ static void testSystemMultipoleMoments( FILE* log ) { double difference; if( fabs( tinkerMoments[ii] ) > 0.0 ){ difference = fabs( outputMultipoleMoments[ii] - tinkerMoments[ii] )/fabs( tinkerMoments[ii] ); - } else { + } + else { difference = fabs( outputMultipoleMoments[ii] - tinkerMoments[ii] ); } if( log ){ @@ -2854,7 +2861,8 @@ int main( int numberOfArguments, char* argv[] ) { testPMEMutualPolarizationLargeWater( log ); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; return 1; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp index 399725703..8bd47a61c 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp @@ -114,7 +114,7 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& deltaR[DB][ii] = positions[particle4][ii] - positions[particle2][ii]; deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii]; deltaR[CD][ii] = positions[particle3][ii] - positions[particle4][ii]; - } + } double rDB2 = dotVector3( deltaR[DB], deltaR[DB] ); double rAD2 = dotVector3( deltaR[AD], deltaR[AD] ); @@ -134,9 +134,11 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& double angle; if( cosine >= 1.0 ){ angle = 0.0; - } else if( cosine <= -1.0 ){ + } + else if( cosine <= -1.0 ){ angle = PI_M; - } else { + } + else { angle = RADIAN*acos(cosine); } #ifdef AMOEBA_DEBUG @@ -405,37 +407,43 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { particleIndices.push_back( 443 ); particleIndices.push_back( 444 ); kOutOfPlaneBend = 0.328682196E-01; - } else if( setId == 2 ){ + } + else if( setId == 2 ){ particleIndices.push_back( 441 ); particleIndices.push_back( 442 ); particleIndices.push_back( 444 ); particleIndices.push_back( 443 ); kOutOfPlaneBend = 0.164493407E-01; - } else if( setId == 3 ){ + } + else if( setId == 3 ){ particleIndices.push_back( 443 ); particleIndices.push_back( 442 ); particleIndices.push_back( 444 ); particleIndices.push_back( 441 ); kOutOfPlaneBend = 0.636650407E-02; - } else if( setId == 4 ){ + } + else if( setId == 4 ){ particleIndices.push_back( 442 ); particleIndices.push_back( 444 ); particleIndices.push_back( 447 ); particleIndices.push_back( 448 ); kOutOfPlaneBend = 0.392956472E-02; - } else if( setId == 5 ){ + } + else if( setId == 5 ){ particleIndices.push_back( 442 ); particleIndices.push_back( 444 ); particleIndices.push_back( 448 ); particleIndices.push_back( 447 ); kOutOfPlaneBend = 0.392956472E-02; - } else if( setId == 6 ){ + } + else if( setId == 6 ){ particleIndices.push_back( 447 ); particleIndices.push_back( 444 ); particleIndices.push_back( 448 ); particleIndices.push_back( 442 ); kOutOfPlaneBend = 0.214755281E-01; - } else { + } + else { #ifdef AMOEBA_DEBUG if( log ){ (void) fprintf( log, "Set id %d not recognized.\n", setId ); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp index 3357d21cd..e321e3d2f 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp @@ -129,9 +129,11 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos double angle; if( cosine >= 1.0 ){ angle = 0.0; - } else if( cosine <= -1.0 ){ + } + else if( cosine <= -1.0 ){ angle = PI_M; - } else { + } + else { angle = RADIAN*acos(cosine); } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp index 10283c058..d37698f4d 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp @@ -2620,7 +2620,8 @@ void testTorsionTorsion(int systemId, bool includeDerivs) { expectedEnergy = -2.699654759E+00; - } else if( systemId == 1 ){ + } + else if( systemId == 1 ){ // villin: 158 176 177 178 183 -1 0 chiralCheckAtomIndex = -1; @@ -2676,7 +2677,8 @@ int main( int numberOfArguments, char* argv[] ) { registerAmoebaReferenceKernelFactories(); testTorsionTorsion(1, true); testTorsionTorsion(1, false); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; return 1; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp index 6b60307b4..cdb825412 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp @@ -75,7 +75,8 @@ void testVdw( FILE* log ) { sigma = 1.70250E+00; epsilon = 1.10000E-01; reduction = 0.0; - } else { + } + else { mass = 1.0; indexIV = ii < 3 ? 0 : 3; sigma = 1.32750E+00; @@ -89,7 +90,8 @@ void testVdw( FILE* log ) { exclusions.push_back ( 0 ); exclusions.push_back ( 1 ); exclusions.push_back ( 2 ); - } else { + } + else { exclusions.push_back ( 3 ); exclusions.push_back ( 4 ); exclusions.push_back ( 5 ); @@ -155,7 +157,7 @@ void testVdw( FILE* log ) { forces[ii][0] *= conversion; forces[ii][1] *= conversion; forces[ii][2] *= conversion; - } + } expectedEnergy *= CalToJoule; #ifdef AMOEBA_DEBUG @@ -223,7 +225,8 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c system.setDefaultPeriodicBoxVectors( a, b, c ); amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); amoebaVdwForce->setUseDispersionCorrection( 1 ); - } else { + } + else { amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff); amoebaVdwForce->setUseDispersionCorrection( 0 ); } @@ -330,7 +333,8 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c if( boxDimension > 0.0 ){ ASSERT(amoebaVdwForce->usesPeriodicBoundaryConditions()); - } else { + } + else { ASSERT(!amoebaVdwForce->usesPeriodicBoundaryConditions()); } @@ -573,7 +577,8 @@ void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, con system.setDefaultPeriodicBoxVectors( a, b, c ); amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); amoebaVdwForce->setUseDispersionCorrection( includeVdwDispersionCorrection ); - } else { + } + else { amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff); amoebaVdwForce->setUseDispersionCorrection( 0 ); } @@ -1281,7 +1286,8 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { std::string testName; if( includeVdwDispersionCorrection ){ testName = "testVdwWaterWithDispersionCorrection"; - } else { + } + else { testName = "testVdwWater"; } @@ -1299,7 +1305,8 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { double expectedEnergy; if( includeVdwDispersionCorrection ){ expectedEnergy = 4.0108819792e+03; - } else { + } + else { expectedEnergy = 4.0349101e+03; } @@ -2036,7 +2043,8 @@ int main( int numberOfArguments, char* argv[] ) { includeVdwDispersionCorrection = 1; testVdwWater( includeVdwDispersionCorrection, log ); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; return 1; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp index 224b5ee95..5fd12e486 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp @@ -185,7 +185,8 @@ int main( int numberOfArguments, char* argv[] ) { testWcaDispersionAmmonia( log ); - } catch(const std::exception& e) { + } + catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; return 1; -- GitLab From 42c3cc03450f455562a62534dea4574769e131a8 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 2 Jan 2015 22:10:39 -0500 Subject: [PATCH 184/338] Add a check and raise an exception if someone tries to use a CHAMBER-style topology file with the Amber file parsers. These do *not* currently work for creating a system. --- .../simtk/openmm/app/amberprmtopfile.py | 4 ++ .../openmm/app/internal/amber_file_parser.py | 62 ++++++++++--------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/amberprmtopfile.py b/wrappers/python/simtk/openmm/app/amberprmtopfile.py index 825aeccf3..0fa2c3506 100644 --- a/wrappers/python/simtk/openmm/app/amberprmtopfile.py +++ b/wrappers/python/simtk/openmm/app/amberprmtopfile.py @@ -173,6 +173,10 @@ class AmberPrmtopFile(object): - ewaldErrorTolerance (float=0.0005) The error tolerance to use if nonbondedMethod is Ewald or PME. Returns: the newly created System """ + if self._prmtop.chamber: + raise ValueError("CHAMBER-style topology file detected. CHAMBER " + "topologies are not supported -- use the native " + "CHARMM files directly.") methodMap = {ff.NoCutoff:'NoCutoff', ff.CutoffNonPeriodic:'CutoffNonPeriodic', ff.CutoffPeriodic:'CutoffPeriodic', diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index ef7871766..78f55cdea 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -119,36 +119,38 @@ class PrmtopLoader(object): self._raw_data={} self._has_nbfix_terms = False - fIn=open(inFilename) - for line in fIn: - if line.startswith('%VERSION'): - tag, self._prmtopVersion = line.rstrip().split(None, 1) - elif line.startswith('%FLAG'): - tag, flag = line.rstrip().split(None, 1) - self._flags.append(flag) - self._raw_data[flag] = [] - elif line.startswith('%FORMAT'): - format = line.rstrip() - index0=format.index('(') - index1=format.index(')') - format = format[index0+1:index1] - m = FORMAT_RE_PATTERN.search(format) - self._raw_format[self._flags[-1]] = (format, m.group(1), m.group(2), m.group(3), m.group(4)) - elif self._flags \ - and 'TITLE'==self._flags[-1] \ - and not self._raw_data['TITLE']: - self._raw_data['TITLE'] = line.rstrip() - else: - flag=self._flags[-1] - (format, numItems, itemType, - itemLength, itemPrecision) = self._getFormat(flag) - iLength=int(itemLength) - line = line.rstrip() - for index in range(0, len(line), iLength): - item = line[index:index+iLength] - if item: - self._raw_data[flag].append(item.strip()) - fIn.close() + with open(inFilename, 'r') as fIn: + for line in fIn: + if line.startswith('%VERSION'): + tag, self._prmtopVersion = line.rstrip().split(None, 1) + elif line.startswith('%FLAG'): + tag, flag = line.rstrip().split(None, 1) + self._flags.append(flag) + self._raw_data[flag] = [] + elif line.startswith('%FORMAT'): + format = line.rstrip() + index0=format.index('(') + index1=format.index(')') + format = format[index0+1:index1] + m = FORMAT_RE_PATTERN.search(format) + self._raw_format[self._flags[-1]] = (format, m.group(1), m.group(2), m.group(3), m.group(4)) + elif self._flags \ + and 'TITLE'==self._flags[-1] \ + and not self._raw_data['TITLE']: + self._raw_data['TITLE'] = line.rstrip() + else: + flag=self._flags[-1] + (format, numItems, itemType, + itemLength, itemPrecision) = self._getFormat(flag) + iLength=int(itemLength) + line = line.rstrip() + for index in range(0, len(line), iLength): + item = line[index:index+iLength] + if item: + self._raw_data[flag].append(item.strip()) + # See if this is a CHAMBER-style topology file, which is not supported + # for creating Systems + self.chamber = 'CTITLE' in self._flags def _getFormat(self, flag=None): if not flag: -- GitLab From 2284ac618aea355b58df3e5bf4df788bca4caf8d Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 3 Jan 2015 15:52:37 -0500 Subject: [PATCH 185/338] Make it so that getRandomNumberSeed by default returns a osrngseed() result, rather than some pre-set seed generated at construction time. Any call to "setRandomNumberSeed" prevents this behavior (unless the generator is seeded with 0). --- openmmapi/include/openmm/AndersenThermostat.h | 3 +++ openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h | 3 +++ openmmapi/include/openmm/MonteCarloBarostat.h | 3 +++ openmmapi/include/openmm/MonteCarloMembraneBarostat.h | 3 +++ openmmapi/src/AndersenThermostat.cpp | 2 +- openmmapi/src/MonteCarloAnisotropicBarostat.cpp | 3 +-- openmmapi/src/MonteCarloBarostat.cpp | 3 +-- openmmapi/src/MonteCarloMembraneBarostat.cpp | 3 +-- 8 files changed, 16 insertions(+), 7 deletions(-) diff --git a/openmmapi/include/openmm/AndersenThermostat.h b/openmmapi/include/openmm/AndersenThermostat.h index 1cf198e74..40cd3cecd 100644 --- a/openmmapi/include/openmm/AndersenThermostat.h +++ b/openmmapi/include/openmm/AndersenThermostat.h @@ -35,6 +35,7 @@ #include "Force.h" #include #include "internal/windowsExport.h" +#include "openmm/internal/OSRngSeed.h" namespace OpenMM { @@ -104,6 +105,8 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { + if (randomNumberSeed == 0) + return osrngseed(); return randomNumberSeed; } /** diff --git a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h index 68c60fe09..85a277b7d 100644 --- a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h +++ b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h @@ -36,6 +36,7 @@ #include "Vec3.h" #include #include "internal/windowsExport.h" +#include "openmm/internal/OSRngSeed.h" namespace OpenMM { @@ -159,6 +160,8 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { + if (randomNumberSeed == 0) + return osrngseed(); return randomNumberSeed; } /** diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index c78b569fe..3188eb389 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -35,6 +35,7 @@ #include "Force.h" #include #include "internal/windowsExport.h" +#include "openmm/internal/OSRngSeed.h" namespace OpenMM { @@ -115,6 +116,8 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { + if (randomNumberSeed == 0) + return osrngseed(); return randomNumberSeed; } /** diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h index 05220f43a..8055315ed 100644 --- a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -35,6 +35,7 @@ #include "Force.h" #include #include "internal/windowsExport.h" +#include "openmm/internal/OSRngSeed.h" namespace OpenMM { @@ -212,6 +213,8 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { + if (randomNumberSeed == 0) + return osrngseed(); return randomNumberSeed; } /** diff --git a/openmmapi/src/AndersenThermostat.cpp b/openmmapi/src/AndersenThermostat.cpp index 4410224c6..f215ac215 100644 --- a/openmmapi/src/AndersenThermostat.cpp +++ b/openmmapi/src/AndersenThermostat.cpp @@ -37,7 +37,7 @@ using namespace OpenMM; AndersenThermostat::AndersenThermostat(double defaultTemperature, double defaultCollisionFrequency) : defaultTemp(defaultTemperature), defaultFreq(defaultCollisionFrequency) { - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } ForceImpl* AndersenThermostat::createImpl() const { diff --git a/openmmapi/src/MonteCarloAnisotropicBarostat.cpp b/openmmapi/src/MonteCarloAnisotropicBarostat.cpp index 5459a7884..365105e7c 100644 --- a/openmmapi/src/MonteCarloAnisotropicBarostat.cpp +++ b/openmmapi/src/MonteCarloAnisotropicBarostat.cpp @@ -31,13 +31,12 @@ #include "openmm/MonteCarloAnisotropicBarostat.h" #include "openmm/internal/MonteCarloAnisotropicBarostatImpl.h" -#include "openmm/internal/OSRngSeed.h" using namespace OpenMM; MonteCarloAnisotropicBarostat::MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double temperature, bool scaleX, bool scaleY, bool scaleZ, int frequency) : defaultPressure(defaultPressure), temperature(temperature), scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ), frequency(frequency) { - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } ForceImpl* MonteCarloAnisotropicBarostat::createImpl() const { diff --git a/openmmapi/src/MonteCarloBarostat.cpp b/openmmapi/src/MonteCarloBarostat.cpp index d45e4883f..64a9b20e1 100644 --- a/openmmapi/src/MonteCarloBarostat.cpp +++ b/openmmapi/src/MonteCarloBarostat.cpp @@ -31,13 +31,12 @@ #include "openmm/MonteCarloBarostat.h" #include "openmm/internal/MonteCarloBarostatImpl.h" -#include "openmm/internal/OSRngSeed.h" using namespace OpenMM; MonteCarloBarostat::MonteCarloBarostat(double defaultPressure, double temperature, int frequency) : defaultPressure(defaultPressure), temperature(temperature), frequency(frequency) { - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } ForceImpl* MonteCarloBarostat::createImpl() const { diff --git a/openmmapi/src/MonteCarloMembraneBarostat.cpp b/openmmapi/src/MonteCarloMembraneBarostat.cpp index 24f153564..9c7410967 100644 --- a/openmmapi/src/MonteCarloMembraneBarostat.cpp +++ b/openmmapi/src/MonteCarloMembraneBarostat.cpp @@ -31,14 +31,13 @@ #include "openmm/MonteCarloMembraneBarostat.h" #include "openmm/internal/MonteCarloMembraneBarostatImpl.h" -#include "openmm/internal/OSRngSeed.h" using namespace OpenMM; MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double temperature, XYMode xymode, ZMode zmode, int frequency) : defaultPressure(defaultPressure), defaultSurfaceTension(defaultSurfaceTension), temperature(temperature), xymode(xymode), zmode(zmode), frequency(frequency) { - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } ForceImpl* MonteCarloMembraneBarostat::createImpl() const { -- GitLab From e04a73686827fc6d19fb6f181ae9fb1399990460 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 5 Jan 2015 15:39:31 -0500 Subject: [PATCH 186/338] Attempt to move the implementation of separate osrngseed() calls for each Context into the platform rather than hacked into getRandomNumberSeed... Someone please check this. --- openmmapi/include/openmm/AndersenThermostat.h | 2 -- openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h | 3 --- openmmapi/include/openmm/MonteCarloBarostat.h | 1 - openmmapi/src/BrownianIntegrator.cpp | 3 +-- openmmapi/src/CustomIntegrator.cpp | 3 +-- openmmapi/src/LangevinIntegrator.cpp | 3 +-- openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp | 6 +++++- openmmapi/src/MonteCarloBarostatImpl.cpp | 6 +++++- openmmapi/src/MonteCarloMembraneBarostatImpl.cpp | 6 +++++- openmmapi/src/VariableLangevinIntegrator.cpp | 3 +-- platforms/cuda/src/CudaIntegrationUtilities.cpp | 2 ++ platforms/opencl/src/OpenCLIntegrationUtilities.cpp | 3 +++ .../reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp | 7 ++++++- 13 files changed, 30 insertions(+), 18 deletions(-) diff --git a/openmmapi/include/openmm/AndersenThermostat.h b/openmmapi/include/openmm/AndersenThermostat.h index 40cd3cecd..4750c9bf5 100644 --- a/openmmapi/include/openmm/AndersenThermostat.h +++ b/openmmapi/include/openmm/AndersenThermostat.h @@ -105,8 +105,6 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { - if (randomNumberSeed == 0) - return osrngseed(); return randomNumberSeed; } /** diff --git a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h index 85a277b7d..68c60fe09 100644 --- a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h +++ b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h @@ -36,7 +36,6 @@ #include "Vec3.h" #include #include "internal/windowsExport.h" -#include "openmm/internal/OSRngSeed.h" namespace OpenMM { @@ -160,8 +159,6 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { - if (randomNumberSeed == 0) - return osrngseed(); return randomNumberSeed; } /** diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index 3188eb389..856acd61c 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -35,7 +35,6 @@ #include "Force.h" #include #include "internal/windowsExport.h" -#include "openmm/internal/OSRngSeed.h" namespace OpenMM { diff --git a/openmmapi/src/BrownianIntegrator.cpp b/openmmapi/src/BrownianIntegrator.cpp index 7323dbfb5..a07ff4a73 100644 --- a/openmmapi/src/BrownianIntegrator.cpp +++ b/openmmapi/src/BrownianIntegrator.cpp @@ -33,7 +33,6 @@ #include "openmm/Context.h" #include "openmm/OpenMMException.h" #include "openmm/internal/ContextImpl.h" -#include "openmm/internal/OSRngSeed.h" #include "openmm/kernels.h" #include @@ -46,7 +45,7 @@ BrownianIntegrator::BrownianIntegrator(double temperature, double frictionCoeff, setFriction(frictionCoeff); setStepSize(stepSize); setConstraintTolerance(1e-5); - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } void BrownianIntegrator::initialize(ContextImpl& contextRef) { diff --git a/openmmapi/src/CustomIntegrator.cpp b/openmmapi/src/CustomIntegrator.cpp index 19c78a5e2..4928f5d58 100644 --- a/openmmapi/src/CustomIntegrator.cpp +++ b/openmmapi/src/CustomIntegrator.cpp @@ -34,7 +34,6 @@ #include "openmm/OpenMMException.h" #include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/ContextImpl.h" -#include "openmm/internal/OSRngSeed.h" #include "openmm/kernels.h" #include #include @@ -45,7 +44,7 @@ using namespace std; CustomIntegrator::CustomIntegrator(double stepSize) : globalsAreCurrent(true), forcesAreValid(false) { setStepSize(stepSize); setConstraintTolerance(1e-5); - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); kineticEnergy = "m*v*v/2"; } diff --git a/openmmapi/src/LangevinIntegrator.cpp b/openmmapi/src/LangevinIntegrator.cpp index 740156732..22343c878 100644 --- a/openmmapi/src/LangevinIntegrator.cpp +++ b/openmmapi/src/LangevinIntegrator.cpp @@ -33,7 +33,6 @@ #include "openmm/Context.h" #include "openmm/OpenMMException.h" #include "openmm/internal/ContextImpl.h" -#include "openmm/internal/OSRngSeed.h" #include "openmm/kernels.h" #include @@ -46,7 +45,7 @@ LangevinIntegrator::LangevinIntegrator(double temperature, double frictionCoeff, setFriction(frictionCoeff); setStepSize(stepSize); setConstraintTolerance(1e-5); - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } void LangevinIntegrator::initialize(ContextImpl& contextRef) { diff --git a/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp b/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp index d13f2d6f0..cb8b24827 100644 --- a/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp @@ -31,6 +31,7 @@ #include "openmm/internal/MonteCarloAnisotropicBarostatImpl.h" #include "openmm/internal/ContextImpl.h" +#include "openmm/internal/OSRngSeed.h" #include "openmm/Context.h" #include "openmm/kernels.h" #include @@ -60,7 +61,10 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) { numAttempted[i] = 0; numAccepted[i] = 0; } - init_gen_rand(owner.getRandomNumberSeed(), random); + int randSeed = owner.getRandomNumberSeed(); + // A random seed of 0 means pull a new one from the clock + if (randSeed == 0) randSeed = osrngseed(); + init_gen_rand(randSeed, random); } void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context) { diff --git a/openmmapi/src/MonteCarloBarostatImpl.cpp b/openmmapi/src/MonteCarloBarostatImpl.cpp index 99cc5e6f5..82f38b9cf 100644 --- a/openmmapi/src/MonteCarloBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloBarostatImpl.cpp @@ -31,6 +31,7 @@ #include "openmm/internal/MonteCarloBarostatImpl.h" #include "openmm/internal/ContextImpl.h" +#include "openmm/internal/OSRngSeed.h" #include "openmm/Context.h" #include "openmm/kernels.h" #include @@ -58,7 +59,10 @@ void MonteCarloBarostatImpl::initialize(ContextImpl& context) { volumeScale = 0.01*volume; numAttempted = 0; numAccepted = 0; - init_gen_rand(owner.getRandomNumberSeed(), random); + int randSeed = owner.getRandomNumberSeed(); + // A random seed of 0 means pull a new one from the clock + if (randSeed == 0) randSeed = osrngseed(); + init_gen_rand(randSeed, random); } void MonteCarloBarostatImpl::updateContextState(ContextImpl& context) { diff --git a/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp index bd6eff28d..4028a82fd 100644 --- a/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp @@ -31,6 +31,7 @@ #include "openmm/internal/MonteCarloMembraneBarostatImpl.h" #include "openmm/internal/ContextImpl.h" +#include "openmm/internal/OSRngSeed.h" #include "openmm/Context.h" #include "openmm/kernels.h" #include @@ -60,7 +61,10 @@ void MonteCarloMembraneBarostatImpl::initialize(ContextImpl& context) { numAttempted[i] = 0; numAccepted[i] = 0; } - init_gen_rand(owner.getRandomNumberSeed(), random); + int randSeed = owner.getRandomNumberSeed(); + // A random seed of 0 means pull a new one from the clock + if (randSeed == 0) randSeed = osrngseed(); + init_gen_rand(randSeed, random); } void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context) { diff --git a/openmmapi/src/VariableLangevinIntegrator.cpp b/openmmapi/src/VariableLangevinIntegrator.cpp index 72ef8d456..b73b13839 100644 --- a/openmmapi/src/VariableLangevinIntegrator.cpp +++ b/openmmapi/src/VariableLangevinIntegrator.cpp @@ -33,7 +33,6 @@ #include "openmm/Context.h" #include "openmm/OpenMMException.h" #include "openmm/internal/ContextImpl.h" -#include "openmm/internal/OSRngSeed.h" #include "openmm/kernels.h" #include #include @@ -48,7 +47,7 @@ VariableLangevinIntegrator::VariableLangevinIntegrator(double temperature, doubl setFriction(frictionCoeff); setErrorTolerance(errorTol); setConstraintTolerance(1e-5); - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); setStepSize(0.0); } diff --git a/platforms/cuda/src/CudaIntegrationUtilities.cpp b/platforms/cuda/src/CudaIntegrationUtilities.cpp index a65f7abbf..e3c94a93a 100644 --- a/platforms/cuda/src/CudaIntegrationUtilities.cpp +++ b/platforms/cuda/src/CudaIntegrationUtilities.cpp @@ -27,6 +27,7 @@ #include "CudaIntegrationUtilities.h" #include "CudaArray.h" #include "CudaKernelSources.h" +#include "openmm/internal/OSRngSeed.h" #include "openmm/HarmonicAngleForce.h" #include "openmm/VirtualSite.h" #include "quern.h" @@ -858,6 +859,7 @@ void CudaIntegrationUtilities::initRandomNumberGenerator(unsigned int randomNumb vector seed(randomSeed->getSize()); unsigned int r = randomNumberSeed; + if (r == 0) r = (unsigned int) osrngseed(); for (int i = 0; i < randomSeed->getSize(); i++) { seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; diff --git a/platforms/opencl/src/OpenCLIntegrationUtilities.cpp b/platforms/opencl/src/OpenCLIntegrationUtilities.cpp index 5a2efbee7..f619da473 100644 --- a/platforms/opencl/src/OpenCLIntegrationUtilities.cpp +++ b/platforms/opencl/src/OpenCLIntegrationUtilities.cpp @@ -27,6 +27,7 @@ #include "OpenCLIntegrationUtilities.h" #include "OpenCLArray.h" #include "OpenCLKernelSources.h" +#include "openmm/internal/OSRngSeed.h" #include "openmm/HarmonicAngleForce.h" #include "openmm/VirtualSite.h" #include "quern.h" @@ -1003,6 +1004,8 @@ void OpenCLIntegrationUtilities::initRandomNumberGenerator(unsigned int randomNu vector seed(randomSeed->getSize()); unsigned int r = randomNumberSeed; + // A seed of 0 means pull one from the clock + if (r == 0) r = (unsigned int) osrngseed(); for (int i = 0; i < randomSeed->getSize(); i++) { seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp index bef4b0ff9..1fef5c137 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp @@ -24,6 +24,7 @@ // class of shared, static utility methods +#include "openmm/internal/OSRngSeed.h" #include "SimTKOpenMMUtilities.h" #include "SimTKOpenMMLog.h" #include "sfmt/SFMT.h" @@ -361,7 +362,11 @@ void SimTKOpenMMUtilities::setRandomNumberSeed( uint32_t seed ) { // --------------------------------------------------------------------------------------- - _randomNumberSeed = seed; + // If the seed is 0, generate one from the clock + if (seed == 0) + _randomNumberSeed = (uint32_t) osrngseed(); + else + _randomNumberSeed = seed; _randomInitialized = false; } -- GitLab From 92cc46170d2997c9871a87a14ff6b783b12b2309 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 5 Jan 2015 16:06:21 -0500 Subject: [PATCH 187/338] Oops, missed one. --- openmmapi/include/openmm/MonteCarloBarostat.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index 856acd61c..c78b569fe 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -115,8 +115,6 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { - if (randomNumberSeed == 0) - return osrngseed(); return randomNumberSeed; } /** -- GitLab From 10cb26a69853bff7b620e7a27c14b5db0f2ac20e Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 5 Jan 2015 16:08:51 -0500 Subject: [PATCH 188/338] Last one. --- openmmapi/include/openmm/MonteCarloMembraneBarostat.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h index 8055315ed..05220f43a 100644 --- a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -35,7 +35,6 @@ #include "Force.h" #include #include "internal/windowsExport.h" -#include "openmm/internal/OSRngSeed.h" namespace OpenMM { @@ -213,8 +212,6 @@ public: * Get the random number seed. See setRandomNumberSeed() for details. */ int getRandomNumberSeed() const { - if (randomNumberSeed == 0) - return osrngseed(); return randomNumberSeed; } /** -- GitLab From 61458a5f5d01553be7b6812bcde3e190207d6446 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Mon, 5 Jan 2015 15:03:02 -0800 Subject: [PATCH 189/338] Beginning of CUDA support for triclinic boxes --- platforms/cuda/include/CudaContext.h | 68 +++++++++++++++---- platforms/cuda/src/CudaContext.cpp | 62 ++++++++++++++++- platforms/cuda/src/CudaKernels.cpp | 24 +++---- platforms/cuda/src/CudaNonbondedUtilities.cpp | 17 +++-- .../cuda/src/kernels/findInteractingBlocks.cu | 39 ++++------- platforms/cuda/src/kernels/nonbonded.cu | 29 +++----- .../tests/TestCudaCustomNonbondedForce.cpp | 62 ++++++++++++++++- .../cuda/tests/TestCudaNonbondedForce.cpp | 64 ++++++++++++++++- 8 files changed, 286 insertions(+), 79 deletions(-) diff --git a/platforms/cuda/include/CudaContext.h b/platforms/cuda/include/CudaContext.h index 1052376f6..21aae8724 100644 --- a/platforms/cuda/include/CudaContext.h +++ b/platforms/cuda/include/CudaContext.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2013 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -361,6 +361,12 @@ public: bool getUseMixedPrecision() { return useMixedPrecision; } + /** + * Get whether the periodic box is triclinic. + */ + bool getBoxIsTriclinic() { + return boxIsTriclinic; + } /** * Convert a number to a string in a format suitable for including in a kernel. * This takes into account whether the context uses single or double precision. @@ -374,21 +380,34 @@ public: * Convert a CUDA result code to the corresponding string description. */ static std::string getErrorString(CUresult result); - /** - * Get the size of the periodic box. + * Get the vectors defining the periodic box. */ - double4 getPeriodicBoxSize() const { - return periodicBoxSize; + void getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) const { + a = Vec3(periodicBoxVecX.x, periodicBoxVecX.y, periodicBoxVecX.z); + b = Vec3(periodicBoxVecY.x, periodicBoxVecY.y, periodicBoxVecY.z); + c = Vec3(periodicBoxVecZ.x, periodicBoxVecZ.y, periodicBoxVecZ.z); } /** - * Set the size of the periodic box. + * Set the vectors defining the periodic box. */ - void setPeriodicBoxSize(double xsize, double ysize, double zsize) { - periodicBoxSize = make_double4(xsize, ysize, zsize, 0.0); - invPeriodicBoxSize = make_double4(1.0/xsize, 1.0/ysize, 1.0/zsize, 0.0); - periodicBoxSizeFloat = make_float4((float) xsize, (float) ysize, (float) zsize, 0.0f); - invPeriodicBoxSizeFloat = make_float4(1.0f/(float) xsize, 1.0f/(float) ysize, 1.0f/(float) zsize, 0.0f); + void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) { + periodicBoxVecX = make_double4(a[0], a[1], a[2], 0.0); + periodicBoxVecY = make_double4(b[0], b[1], b[2], 0.0); + periodicBoxVecZ = make_double4(c[0], c[1], c[2], 0.0); + periodicBoxVecXFloat = make_float4((float) a[0], (float) a[1], (float) a[2], 0.0f); + periodicBoxVecYFloat = make_float4((float) b[0], (float) b[1], (float) b[2], 0.0f); + periodicBoxVecZFloat = make_float4((float) c[0], (float) c[1], (float) c[2], 0.0f); + periodicBoxSize = make_double4(a[0], b[1], c[2], 0.0); + invPeriodicBoxSize = make_double4(1.0/a[0], 1.0/b[1], 1.0/c[2], 0.0); + periodicBoxSizeFloat = make_float4((float) a[0], (float) b[1], (float) c[2], 0.0f); + invPeriodicBoxSizeFloat = make_float4(1.0f/(float) a[0], 1.0f/(float) b[1], 1.0f/(float) c[2], 0.0f); + } + /** + * Get the size of the periodic box. + */ + double4 getPeriodicBoxSize() const { + return periodicBoxSize; } /** * Get the inverse of the size of the periodic box. @@ -410,6 +429,27 @@ public: void* getInvPeriodicBoxSizePointer() { return (useDoublePrecision ? reinterpret_cast(&invPeriodicBoxSize) : reinterpret_cast(&invPeriodicBoxSizeFloat)); } + /** + * Get a pointer to the first periodic box vector, represented as either a float4 or double4 depending on + * this context's precision. This value is suitable for passing to kernels as an argument. + */ + void* getPeriodicBoxVecXPointer() { + return (useDoublePrecision ? reinterpret_cast(&periodicBoxVecX) : reinterpret_cast(&periodicBoxVecXFloat)); + } + /** + * Get a pointer to the second periodic box vector, represented as either a float4 or double4 depending on + * this context's precision. This value is suitable for passing to kernels as an argument. + */ + void* getPeriodicBoxVecYPointer() { + return (useDoublePrecision ? reinterpret_cast(&periodicBoxVecY) : reinterpret_cast(&periodicBoxVecYFloat)); + } + /** + * Get a pointer to the third periodic box vector, represented as either a float4 or double4 depending on + * this context's precision. This value is suitable for passing to kernels as an argument. + */ + void* getPeriodicBoxVecZPointer() { + return (useDoublePrecision ? reinterpret_cast(&periodicBoxVecZ) : reinterpret_cast(&periodicBoxVecZFloat)); + } /** * Get the CudaIntegrationUtilities for this context. */ @@ -525,10 +565,10 @@ private: int paddedNumAtoms; int numAtomBlocks; int numThreadBlocks; - bool useBlockingSync, useDoublePrecision, useMixedPrecision, contextIsValid, atomsWereReordered; + bool useBlockingSync, useDoublePrecision, useMixedPrecision, contextIsValid, atomsWereReordered, boxIsTriclinic; std::string compiler, tempDir, cacheDir, gpuArchitecture; - float4 periodicBoxSizeFloat, invPeriodicBoxSizeFloat; - double4 periodicBoxSize, invPeriodicBoxSize; + float4 periodicBoxVecXFloat, periodicBoxVecYFloat, periodicBoxVecZFloat, periodicBoxSizeFloat, invPeriodicBoxSizeFloat; + double4 periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ, periodicBoxSize, invPeriodicBoxSize; std::string defaultOptimizationOptions; std::map compilationDefines; CUcontext context; diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 10c157ae7..1083846fa 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2013 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -233,6 +233,66 @@ CudaContext::CudaContext(const System& system, int deviceIndex, bool useBlocking compilationDefines["ERF"] = useDoublePrecision ? "erf" : "erff"; compilationDefines["ERFC"] = useDoublePrecision ? "erfc" : "erfcf"; + // Set defines for applying periodic boundary conditions. + + Vec3 boxVectors[3]; + system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); + boxIsTriclinic = (boxVectors[0][1] != 0.0 || boxVectors[0][2] != 0.0 || + boxVectors[1][0] != 0.0 || boxVectors[1][2] != 0.0 || + boxVectors[2][0] != 0.0 || boxVectors[2][1] != 0.0); + if (boxIsTriclinic) { + compilationDefines["APPLY_PERIODIC_TO_DELTA(delta)"] = + "{" + "real scale3 = floor(delta.z*invPeriodicBoxSize.z+0.5f); \\\n" + "delta.x -= scale3*periodicBoxVecZ.x; \\\n" + "delta.y -= scale3*periodicBoxVecZ.y; \\\n" + "delta.z -= scale3*periodicBoxVecZ.z; \\\n" + "real scale2 = floor(delta.y*invPeriodicBoxSize.y+0.5f); \\\n" + "delta.x -= scale2*periodicBoxVecY.x; \\\n" + "delta.y -= scale2*periodicBoxVecY.y; \\\n" + "real scale1 = floor(delta.x*invPeriodicBoxSize.x+0.5f); \\\n" + "delta.x -= scale1*periodicBoxVecX.x;}"; + compilationDefines["APPLY_PERIODIC_TO_POS(pos)"] = + "{" + "real scale3 = floor(pos.z*invPeriodicBoxSize.z); \\\n" + "pos.x -= scale3*periodicBoxVecZ.x; \\\n" + "pos.y -= scale3*periodicBoxVecZ.y; \\\n" + "pos.z -= scale3*periodicBoxVecZ.z; \\\n" + "real scale2 = floor(pos.y*invPeriodicBoxSize.y); \\\n" + "pos.x -= scale2*periodicBoxVecY.x; \\\n" + "pos.y -= scale2*periodicBoxVecY.y; \\\n" + "real scale1 = floor(pos.x*invPeriodicBoxSize.x); \\\n" + "pos.x -= scale1*periodicBoxVecX.x;}"; + compilationDefines["APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center)"] = + "{" + "real scale3 = floor((pos.z-center.z)*invPeriodicBoxSize.z+0.5f); \\\n" + "pos.x -= scale3*periodicBoxVecZ.x; \\\n" + "pos.y -= scale3*periodicBoxVecZ.y; \\\n" + "pos.z -= scale3*periodicBoxVecZ.z; \\\n" + "real scale2 = floor((pos.y-center.y)*invPeriodicBoxSize.y+0.5f); \\\n" + "pos.x -= scale2*periodicBoxVecY.x; \\\n" + "pos.y -= scale2*periodicBoxVecY.y; \\\n" + "real scale1 = floor((pos.x-center.x)*invPeriodicBoxSize.x+0.5f); \\\n" + "pos.x -= scale1*periodicBoxVecX.x;}"; + } + else { + compilationDefines["APPLY_PERIODIC_TO_DELTA(delta)"] = + "{" + "delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; \\\n" + "delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; \\\n" + "delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;}"; + compilationDefines["APPLY_PERIODIC_TO_POS(pos)"] = + "{" + "pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; \\\n" + "pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; \\\n" + "pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z;}"; + compilationDefines["APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center)"] = + "{" + "pos.x -= floor((pos.x-center.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; \\\n" + "pos.y -= floor((pos.y-center.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; \\\n" + "pos.z -= floor((pos.z-center.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;}"; + } + // Create the work thread used for parallelization when running on multiple devices. thread = new WorkThread(); diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 4d9214ed2..fd43dd1be 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2014 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -304,21 +304,18 @@ void CudaUpdateStateDataKernel::getForces(ContextImpl& context, vector& fo } void CudaUpdateStateDataKernel::getPeriodicBoxVectors(ContextImpl& context, Vec3& a, Vec3& b, Vec3& c) const { - double4 box = cu.getPeriodicBoxSize(); - a = Vec3(box.x, 0, 0); - b = Vec3(0, box.y, 0); - c = Vec3(0, 0, box.z); + cu.getPeriodicBoxVectors(a, b, c); } void CudaUpdateStateDataKernel::setPeriodicBoxVectors(ContextImpl& context, const Vec3& a, const Vec3& b, const Vec3& c) const { vector& contexts = cu.getPlatformData().contexts; for (int i = 0; i < (int) contexts.size(); i++) - contexts[i]->setPeriodicBoxSize(a[0], b[1], c[2]); + contexts[i]->setPeriodicBoxVectors(a, b, c); } void CudaUpdateStateDataKernel::createCheckpoint(ContextImpl& context, ostream& stream) { cu.setAsCurrent(); - int version = 1; + int version = 2; stream.write((char*) &version, sizeof(int)); int precision = (cu.getUseDoublePrecision() ? 2 : cu.getUseMixedPrecision() ? 1 : 0); stream.write((char*) &precision, sizeof(int)); @@ -339,8 +336,9 @@ void CudaUpdateStateDataKernel::createCheckpoint(ContextImpl& context, ostream& stream.write(buffer, cu.getVelm().getSize()*cu.getVelm().getElementSize()); stream.write((char*) &cu.getAtomIndex()[0], sizeof(int)*cu.getAtomIndex().size()); stream.write((char*) &cu.getPosCellOffsets()[0], sizeof(int4)*cu.getPosCellOffsets().size()); - double4 box = cu.getPeriodicBoxSize(); - stream.write((char*) &box, sizeof(double4)); + Vec3 boxVectors[3]; + cu.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); + stream.write((char*) boxVectors, 3*sizeof(Vec3)); cu.getIntegrationUtilities().createCheckpoint(stream); SimTKOpenMMUtilities::createCheckpoint(stream); } @@ -349,7 +347,7 @@ void CudaUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& st cu.setAsCurrent(); int version; stream.read((char*) &version, sizeof(int)); - if (version != 1) + if (version != 2) throw OpenMMException("Checkpoint was created with a different version of OpenMM"); int precision; stream.read((char*) &precision, sizeof(int)); @@ -379,10 +377,10 @@ void CudaUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& st stream.read((char*) &cu.getAtomIndex()[0], sizeof(int)*cu.getAtomIndex().size()); cu.getAtomIndexArray().upload(cu.getAtomIndex()); stream.read((char*) &cu.getPosCellOffsets()[0], sizeof(int4)*cu.getPosCellOffsets().size()); - double4 box; - stream.read((char*) &box, sizeof(double4)); + Vec3 boxVectors[3]; + stream.read((char*) &boxVectors, 3*sizeof(Vec3)); for (int i = 0; i < (int) contexts.size(); i++) - contexts[i]->setPeriodicBoxSize(box.x, box.y, box.z); + contexts[i]->setPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); cu.getIntegrationUtilities().loadCheckpoint(stream); SimTKOpenMMUtilities::loadCheckpoint(stream); for (int i = 0; i < cu.getReorderListeners().size(); i++) diff --git a/platforms/cuda/src/CudaNonbondedUtilities.cpp b/platforms/cuda/src/CudaNonbondedUtilities.cpp index 2b08d5a09..9a5e3f805 100644 --- a/platforms/cuda/src/CudaNonbondedUtilities.cpp +++ b/platforms/cuda/src/CudaNonbondedUtilities.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2013 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -304,6 +304,9 @@ void CudaNonbondedUtilities::initialize(const System& system) { findBlockBoundsArgs.push_back(&numAtoms); findBlockBoundsArgs.push_back(context.getPeriodicBoxSizePointer()); findBlockBoundsArgs.push_back(context.getInvPeriodicBoxSizePointer()); + findBlockBoundsArgs.push_back(context.getPeriodicBoxVecXPointer()); + findBlockBoundsArgs.push_back(context.getPeriodicBoxVecYPointer()); + findBlockBoundsArgs.push_back(context.getPeriodicBoxVecZPointer()); findBlockBoundsArgs.push_back(&context.getPosq().getDevicePointer()); findBlockBoundsArgs.push_back(&blockCenter->getDevicePointer()); findBlockBoundsArgs.push_back(&blockBoundingBox->getDevicePointer()); @@ -322,6 +325,9 @@ void CudaNonbondedUtilities::initialize(const System& system) { findInteractingBlocksKernel = context.getKernel(interactingBlocksProgram, "findBlocksWithInteractions"); findInteractingBlocksArgs.push_back(context.getPeriodicBoxSizePointer()); findInteractingBlocksArgs.push_back(context.getInvPeriodicBoxSizePointer()); + findInteractingBlocksArgs.push_back(context.getPeriodicBoxVecXPointer()); + findInteractingBlocksArgs.push_back(context.getPeriodicBoxVecYPointer()); + findInteractingBlocksArgs.push_back(context.getPeriodicBoxVecZPointer()); findInteractingBlocksArgs.push_back(&interactionCount->getDevicePointer()); findInteractingBlocksArgs.push_back(&interactingTiles->getDevicePointer()); findInteractingBlocksArgs.push_back(&interactingAtoms->getDevicePointer()); @@ -390,10 +396,10 @@ void CudaNonbondedUtilities::updateNeighborListSize() { interactingAtoms = CudaArray::create(context, CudaContext::TileSize*maxTiles, "interactingAtoms"); if (forceArgs.size() > 0) forceArgs[7] = &interactingTiles->getDevicePointer(); - findInteractingBlocksArgs[3] = &interactingTiles->getDevicePointer(); + findInteractingBlocksArgs[6] = &interactingTiles->getDevicePointer(); if (forceArgs.size() > 0) - forceArgs[14] = &interactingAtoms->getDevicePointer(); - findInteractingBlocksArgs[4] = &interactingAtoms->getDevicePointer(); + forceArgs[17] = &interactingAtoms->getDevicePointer(); + findInteractingBlocksArgs[7] = &interactingAtoms->getDevicePointer(); if (context.getUseDoublePrecision()) { vector oldPositionsVec(numAtoms, make_double4(1e30, 1e30, 1e30, 0)); oldPositions->upload(oldPositionsVec); @@ -627,6 +633,9 @@ CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source, forceArgs.push_back(&interactionCount->getDevicePointer()); forceArgs.push_back(context.getPeriodicBoxSizePointer()); forceArgs.push_back(context.getInvPeriodicBoxSizePointer()); + forceArgs.push_back(context.getPeriodicBoxVecXPointer()); + forceArgs.push_back(context.getPeriodicBoxVecYPointer()); + forceArgs.push_back(context.getPeriodicBoxVecZPointer()); forceArgs.push_back(&maxTiles); forceArgs.push_back(&blockCenter->getDevicePointer()); forceArgs.push_back(&blockBoundingBox->getDevicePointer()); diff --git a/platforms/cuda/src/kernels/findInteractingBlocks.cu b/platforms/cuda/src/kernels/findInteractingBlocks.cu index 27204ac01..34822f0c8 100644 --- a/platforms/cuda/src/kernels/findInteractingBlocks.cu +++ b/platforms/cuda/src/kernels/findInteractingBlocks.cu @@ -4,16 +4,15 @@ /** * Find a bounding box for the atoms in each block. */ -extern "C" __global__ void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, const real4* __restrict__ posq, - real4* __restrict__ blockCenter, real4* __restrict__ blockBoundingBox, int* __restrict__ rebuildNeighborList, real2* __restrict__ sortedBlocks) { +extern "C" __global__ void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + const real4* __restrict__ posq, real4* __restrict__ blockCenter, real4* __restrict__ blockBoundingBox, int* __restrict__ rebuildNeighborList, + real2* __restrict__ sortedBlocks) { int index = blockIdx.x*blockDim.x+threadIdx.x; int base = index*TILE_SIZE; while (base < numAtoms) { real4 pos = posq[base]; #ifdef USE_PERIODIC - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS(pos) #endif real4 minPos = pos; real4 maxPos = pos; @@ -22,9 +21,7 @@ extern "C" __global__ void findBlockBounds(int numAtoms, real4 periodicBoxSize, pos = posq[i]; #ifdef USE_PERIODIC real4 center = 0.5f*(maxPos+minPos); - pos.x -= floor((pos.x-center.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - pos.y -= floor((pos.y-center.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - pos.z -= floor((pos.z-center.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center) #endif minPos = make_real4(min(minPos.x,pos.x), min(minPos.y,pos.y), min(minPos.z,pos.z), 0); maxPos = make_real4(max(maxPos.x,pos.x), max(maxPos.y,pos.y), max(maxPos.z,pos.z), 0); @@ -116,11 +113,11 @@ extern "C" __global__ void sortBoxData(const real2* __restrict__ sortedBlock, co * [in] rebuildNeighbourList - whether or not to execute this kernel * */ -extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodicBoxSize, unsigned int* __restrict__ interactionCount, - int* __restrict__ interactingTiles, unsigned int* __restrict__ interactingAtoms, const real4* __restrict__ posq, unsigned int maxTiles, unsigned int startBlockIndex, - unsigned int numBlocks, real2* __restrict__ sortedBlocks, const real4* __restrict__ sortedBlockCenter, const real4* __restrict__ sortedBlockBoundingBox, - const unsigned int* __restrict__ exclusionIndices, const unsigned int* __restrict__ exclusionRowIndices, real4* __restrict__ oldPositions, - const int* __restrict__ rebuildNeighborList) { +extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + unsigned int* __restrict__ interactionCount, int* __restrict__ interactingTiles, unsigned int* __restrict__ interactingAtoms, const real4* __restrict__ posq, + unsigned int maxTiles, unsigned int startBlockIndex, unsigned int numBlocks, real2* __restrict__ sortedBlocks, const real4* __restrict__ sortedBlockCenter, + const real4* __restrict__ sortedBlockBoundingBox, const unsigned int* __restrict__ exclusionIndices, const unsigned int* __restrict__ exclusionRowIndices, + real4* __restrict__ oldPositions, const int* __restrict__ rebuildNeighborList) { if (rebuildNeighborList[0] == 0) return; // The neighbor list doesn't need to be rebuilt. @@ -157,9 +154,7 @@ extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, rea // The box is small enough that we can just translate all the atoms into a single periodic // box, then skip having to apply periodic boundary conditions later. - pos1.x -= floor((pos1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - pos1.y -= floor((pos1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - pos1.z -= floor((pos1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos1, blockCenterX) } #endif posBuffer[threadIdx.x] = pos1; @@ -185,9 +180,7 @@ extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, rea real4 blockSizeY = (block2 < NUM_BLOCKS ? sortedBlockBoundingBox[block2] : make_real4(0)); real4 blockDelta = blockCenterX-blockCenterY; #ifdef USE_PERIODIC - blockDelta.x -= floor(blockDelta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - blockDelta.y -= floor(blockDelta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - blockDelta.z -= floor(blockDelta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(blockDelta) #endif blockDelta.x = max(0.0f, fabs(blockDelta.x)-blockSizeX.x-blockSizeY.x); blockDelta.y = max(0.0f, fabs(blockDelta.y)-blockSizeX.y-blockSizeY.y); @@ -215,9 +208,7 @@ extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, rea real3 pos2 = trimTo3(posq[atom2]); #ifdef USE_PERIODIC if (singlePeriodicCopy) { - pos2.x -= floor((pos2.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - pos2.y -= floor((pos2.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - pos2.z -= floor((pos2.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos2, blockCenterX) } #endif bool interacts = false; @@ -226,9 +217,7 @@ extern "C" __global__ void findBlocksWithInteractions(real4 periodicBoxSize, rea if (!singlePeriodicCopy) { for (int j = 0; j < TILE_SIZE; j++) { real3 delta = pos2-posBuffer[warpStart+j]; - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) interacts |= (delta.x*delta.x+delta.y*delta.y+delta.z*delta.z < PADDED_CUTOFF_SQUARED); } } diff --git a/platforms/cuda/src/kernels/nonbonded.cu b/platforms/cuda/src/kernels/nonbonded.cu index 978f1b0df..986a9f6c8 100644 --- a/platforms/cuda/src/kernels/nonbonded.cu +++ b/platforms/cuda/src/kernels/nonbonded.cu @@ -103,8 +103,9 @@ extern "C" __global__ void computeNonbonded( unsigned long long* __restrict__ forceBuffers, real* __restrict__ energyBuffer, const real4* __restrict__ posq, const tileflags* __restrict__ exclusions, const ushort2* __restrict__ exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices #ifdef USE_CUTOFF - , const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, const real4* __restrict__ blockCenter, const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms + , const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount,real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms #endif PARAMETER_ARGUMENTS) { const unsigned int totalWarps = (blockDim.x*gridDim.x)/TILE_SIZE; @@ -155,9 +156,7 @@ extern "C" __global__ void computeNonbonded( #endif real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; real invR = RSQRT(r2); @@ -223,9 +222,7 @@ extern "C" __global__ void computeNonbonded( #endif real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; real invR = RSQRT(r2); @@ -412,17 +409,11 @@ extern "C" __global__ void computeNonbonded( // The box is small enough that we can just translate all the atoms into a single periodic // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.x -= floor((posq1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - posq1.y -= floor((posq1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - posq1.z -= floor((posq1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) #ifdef ENABLE_SHUFFLE - shflPosq.x -= floor((shflPosq.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - shflPosq.y -= floor((shflPosq.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - shflPosq.z -= floor((shflPosq.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(shflPosq, blockCenterX) #else - localData[threadIdx.x].x -= floor((localData[threadIdx.x].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[threadIdx.x].y -= floor((localData[threadIdx.x].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[threadIdx.x].z -= floor((localData[threadIdx.x].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[threadIdx.x], blockCenterX) #endif unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { @@ -499,9 +490,7 @@ extern "C" __global__ void computeNonbonded( #endif real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; real invR = RSQRT(r2); diff --git a/platforms/cuda/tests/TestCudaCustomNonbondedForce.cpp b/platforms/cuda/tests/TestCudaCustomNonbondedForce.cpp index af74e308e..b17e4efcc 100644 --- a/platforms/cuda/tests/TestCudaCustomNonbondedForce.cpp +++ b/platforms/cuda/tests/TestCudaCustomNonbondedForce.cpp @@ -7,7 +7,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2014 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -261,6 +261,65 @@ void testPeriodic() { ASSERT_EQUAL_TOL(1.9+1+0.9, state.getPotentialEnergy(), TOL); } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + CustomNonbondedForce* nonbonded = new CustomNonbondedForce("r"); + nonbonded->addParticle(vector()); + nonbonded->addParticle(vector()); + nonbonded->setNonbondedMethod(CustomNonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta/sqrt(delta.dot(delta)); + ASSERT_EQUAL_TOL(distance, state.getPotentialEnergy(), TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} + void testContinuous1DFunction() { System system; system.addParticle(1.0); @@ -925,6 +984,7 @@ int main(int argc, char* argv[]) { testExclusions(); testCutoff(); testPeriodic(); + testTriclinic(); testContinuous1DFunction(); testContinuous2DFunction(); testContinuous3DFunction(); diff --git a/platforms/cuda/tests/TestCudaNonbondedForce.cpp b/platforms/cuda/tests/TestCudaNonbondedForce.cpp index dc127f94d..2164e672c 100644 --- a/platforms/cuda/tests/TestCudaNonbondedForce.cpp +++ b/platforms/cuda/tests/TestCudaNonbondedForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -355,6 +355,67 @@ void testPeriodic() { ASSERT_EQUAL_TOL(2*ONE_4PI_EPS0*(1.0)*(1.0+krf*1.0-crf), state.getPotentialEnergy(), TOL); } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + NonbondedForce* nonbonded = new NonbondedForce(); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + const double eps = 78.3; + const double krf = (1.0/(cutoff*cutoff*cutoff))*(eps-1.0)/(2.0*eps+1.0); + const double crf = (1.0/cutoff)*(3.0*eps)/(2.0*eps+1.0); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta*ONE_4PI_EPS0*(-1.0/(distance*distance*distance)+2.0*krf); + ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(1.0/distance+krf*distance*distance-crf), state.getPotentialEnergy(), TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} void testLargeSystem() { const int numMolecules = 600; @@ -872,6 +933,7 @@ int main(int argc, char* argv[]) { testCutoff(); testCutoff14(); testPeriodic(); + testTriclinic(); testLargeSystem(); //testBlockInteractions(false); //testBlockInteractions(true); -- GitLab From 6eb302fbdd5ee58a37bcd06b66749e856754e149 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Mon, 5 Jan 2015 17:17:35 -0800 Subject: [PATCH 190/338] Continuing to implement CUDA support for triclinic boxes --- platforms/cuda/src/CudaKernels.cpp | 55 ++++++++++--- .../cuda/src/kernels/customGBEnergyN2.cu | 25 ++---- platforms/cuda/src/kernels/customGBValueN2.cu | 25 ++---- .../cuda/src/kernels/customHbondForce.cu | 16 ++-- .../cuda/src/kernels/customManyParticle.cu | 30 +++----- .../cuda/src/kernels/customNonbondedGroups.cu | 6 +- platforms/cuda/src/kernels/gbsaObc1.cu | 50 ++++-------- .../cuda/src/kernels/monteCarloBarostat.cu | 13 ++-- .../tests/TestCudaCustomManyParticleForce.cpp | 74 ++++++++++++++---- .../TestCudaMonteCarloAnisotropicBarostat.cpp | 77 +++++++++++++++++++ 10 files changed, 236 insertions(+), 135 deletions(-) diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index fd43dd1be..448a814d8 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -2380,6 +2380,9 @@ double CudaCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool in interactionGroupArgs.push_back(&interactionGroupData->getDevicePointer()); interactionGroupArgs.push_back(cu.getPeriodicBoxSizePointer()); interactionGroupArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + interactionGroupArgs.push_back(cu.getPeriodicBoxVecXPointer()); + interactionGroupArgs.push_back(cu.getPeriodicBoxVecYPointer()); + interactionGroupArgs.push_back(cu.getPeriodicBoxVecZPointer()); for (int i = 0; i < (int) params->getBuffers().size(); i++) interactionGroupArgs.push_back(¶ms->getBuffers()[i].getMemory()); if (globals != NULL) @@ -2539,6 +2542,9 @@ double CudaCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeFor computeSumArgs.push_back(&nb.getInteractionCount().getDevicePointer()); computeSumArgs.push_back(cu.getPeriodicBoxSizePointer()); computeSumArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + computeSumArgs.push_back(cu.getPeriodicBoxVecXPointer()); + computeSumArgs.push_back(cu.getPeriodicBoxVecYPointer()); + computeSumArgs.push_back(cu.getPeriodicBoxVecZPointer()); computeSumArgs.push_back(&maxTiles); computeSumArgs.push_back(&nb.getBlockCenters().getDevicePointer()); computeSumArgs.push_back(&nb.getBlockBoundingBoxes().getDevicePointer()); @@ -2558,6 +2564,9 @@ double CudaCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeFor force1Args.push_back(&nb.getInteractionCount().getDevicePointer()); force1Args.push_back(cu.getPeriodicBoxSizePointer()); force1Args.push_back(cu.getInvPeriodicBoxSizePointer()); + force1Args.push_back(cu.getPeriodicBoxVecXPointer()); + force1Args.push_back(cu.getPeriodicBoxVecYPointer()); + force1Args.push_back(cu.getPeriodicBoxVecZPointer()); force1Args.push_back(&maxTiles); force1Args.push_back(&nb.getBlockCenters().getDevicePointer()); force1Args.push_back(&nb.getBlockBoundingBoxes().getDevicePointer()); @@ -2574,8 +2583,8 @@ double CudaCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeFor maxTiles = nb.getInteractingTiles().getSize(); computeSumArgs[3] = &nb.getInteractingTiles().getDevicePointer(); force1Args[5] = &nb.getInteractingTiles().getDevicePointer(); - computeSumArgs[10] = &nb.getInteractingAtoms().getDevicePointer(); - force1Args[12] = &nb.getInteractingAtoms().getDevicePointer(); + computeSumArgs[13] = &nb.getInteractingAtoms().getDevicePointer(); + force1Args[15] = &nb.getInteractingAtoms().getDevicePointer(); } } cu.executeKernel(computeBornSumKernel, &computeSumArgs[0], nb.getNumForceThreadBlocks()*nb.getForceThreadBlockSize(), nb.getForceThreadBlockSize()); @@ -3344,6 +3353,9 @@ double CudaCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeFo pairValueArgs.push_back(&nb.getInteractionCount().getDevicePointer()); pairValueArgs.push_back(cu.getPeriodicBoxSizePointer()); pairValueArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + pairValueArgs.push_back(cu.getPeriodicBoxVecXPointer()); + pairValueArgs.push_back(cu.getPeriodicBoxVecYPointer()); + pairValueArgs.push_back(cu.getPeriodicBoxVecZPointer()); pairValueArgs.push_back(&maxTiles); pairValueArgs.push_back(&nb.getBlockCenters().getDevicePointer()); pairValueArgs.push_back(&nb.getBlockBoundingBoxes().getDevicePointer()); @@ -3379,6 +3391,9 @@ double CudaCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeFo pairEnergyArgs.push_back(&nb.getInteractionCount().getDevicePointer()); pairEnergyArgs.push_back(cu.getPeriodicBoxSizePointer()); pairEnergyArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + pairEnergyArgs.push_back(cu.getPeriodicBoxVecXPointer()); + pairEnergyArgs.push_back(cu.getPeriodicBoxVecYPointer()); + pairEnergyArgs.push_back(cu.getPeriodicBoxVecZPointer()); pairEnergyArgs.push_back(&maxTiles); pairEnergyArgs.push_back(&nb.getBlockCenters().getDevicePointer()); pairEnergyArgs.push_back(&nb.getBlockBoundingBoxes().getDevicePointer()); @@ -3444,8 +3459,8 @@ double CudaCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeFo maxTiles = nb.getInteractingTiles().getSize(); pairValueArgs[4] = &nb.getInteractingTiles().getDevicePointer(); pairEnergyArgs[5] = &nb.getInteractingTiles().getDevicePointer(); - pairValueArgs[11] = &nb.getInteractingAtoms().getDevicePointer(); - pairEnergyArgs[12] = &nb.getInteractingAtoms().getDevicePointer(); + pairValueArgs[14] = &nb.getInteractingAtoms().getDevicePointer(); + pairEnergyArgs[15] = &nb.getInteractingAtoms().getDevicePointer(); } } cu.executeKernel(pairValueKernel, &pairValueArgs[0], nb.getNumForceThreadBlocks()*nb.getForceThreadBlockSize(), nb.getForceThreadBlockSize()); @@ -4061,6 +4076,9 @@ double CudaCalcCustomHbondForceKernel::execute(ContextImpl& context, bool includ donorArgs.push_back(&acceptors->getDevicePointer()); donorArgs.push_back(cu.getPeriodicBoxSizePointer()); donorArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + donorArgs.push_back(cu.getPeriodicBoxVecXPointer()); + donorArgs.push_back(cu.getPeriodicBoxVecYPointer()); + donorArgs.push_back(cu.getPeriodicBoxVecZPointer()); if (globals != NULL) donorArgs.push_back(&globals->getDevicePointer()); for (int i = 0; i < (int) donorParams->getBuffers().size(); i++) { @@ -4082,6 +4100,9 @@ double CudaCalcCustomHbondForceKernel::execute(ContextImpl& context, bool includ acceptorArgs.push_back(&acceptors->getDevicePointer()); acceptorArgs.push_back(cu.getPeriodicBoxSizePointer()); acceptorArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + acceptorArgs.push_back(cu.getPeriodicBoxVecXPointer()); + acceptorArgs.push_back(cu.getPeriodicBoxVecYPointer()); + acceptorArgs.push_back(cu.getPeriodicBoxVecZPointer()); if (globals != NULL) acceptorArgs.push_back(&globals->getDevicePointer()); for (int i = 0; i < (int) donorParams->getBuffers().size(); i++) { @@ -4684,7 +4705,7 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con const vector& atoms = iter->second; string deltaName = atomNames[atoms[0]]+atomNames[atoms[1]]; if (computedDeltas.count(deltaName) == 0) { - compute<<"real4 delta"<getDevicePointer()); forceArgs.push_back(&neighborStartIndex->getDevicePointer()); @@ -5000,6 +5024,9 @@ double CudaCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool blockBoundsArgs.push_back(cu.getPeriodicBoxSizePointer()); blockBoundsArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + blockBoundsArgs.push_back(cu.getPeriodicBoxVecXPointer()); + blockBoundsArgs.push_back(cu.getPeriodicBoxVecYPointer()); + blockBoundsArgs.push_back(cu.getPeriodicBoxVecZPointer()); blockBoundsArgs.push_back(&cu.getPosq().getDevicePointer()); blockBoundsArgs.push_back(&blockCenter->getDevicePointer()); blockBoundsArgs.push_back(&blockBoundingBox->getDevicePointer()); @@ -5009,6 +5036,9 @@ double CudaCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool neighborsArgs.push_back(cu.getPeriodicBoxSizePointer()); neighborsArgs.push_back(cu.getInvPeriodicBoxSizePointer()); + neighborsArgs.push_back(cu.getPeriodicBoxVecXPointer()); + neighborsArgs.push_back(cu.getPeriodicBoxVecYPointer()); + neighborsArgs.push_back(cu.getPeriodicBoxVecZPointer()); neighborsArgs.push_back(&cu.getPosq().getDevicePointer()); neighborsArgs.push_back(&blockCenter->getDevicePointer()); neighborsArgs.push_back(&blockBoundingBox->getDevicePointer()); @@ -6412,7 +6442,8 @@ void CudaApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context, d float scalefX = (float) scaleX; float scalefY = (float) scaleY; float scalefZ = (float) scaleZ; - void* args[] = {&scalefX, &scalefY, &scalefZ, &numMolecules, cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), + void* args[] = {&scalefX, &scalefY, &scalefZ, &numMolecules, cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), + cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), &cu.getPosq().getDevicePointer(), &moleculeAtoms->getDevicePointer(), &moleculeStartIndex->getDevicePointer()}; cu.executeKernel(kernel, args, cu.getNumAtoms()); for (int i = 0; i < (int) cu.getPosCellOffsets().size(); i++) diff --git a/platforms/cuda/src/kernels/customGBEnergyN2.cu b/platforms/cuda/src/kernels/customGBEnergyN2.cu index 9c5295e42..d3831ada2 100644 --- a/platforms/cuda/src/kernels/customGBEnergyN2.cu +++ b/platforms/cuda/src/kernels/customGBEnergyN2.cu @@ -16,8 +16,9 @@ typedef struct { extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forceBuffers, real* __restrict__ energyBuffer, const real4* __restrict__ posq, const unsigned int* __restrict__ exclusions, const ushort2* __restrict__ exclusionTiles, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, const real4* __restrict__ blockCenter, const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms #else unsigned int numTiles #endif @@ -56,9 +57,7 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc real3 pos2 = localData[atom2].pos; real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -109,9 +108,7 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc real3 pos2 = localData[atom2].pos; real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -254,12 +251,8 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - pos1.x -= floor((pos1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - pos1.y -= floor((pos1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - pos1.z -= floor((pos1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; - localData[threadIdx.x].pos.x -= floor((localData[threadIdx.x].pos.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[threadIdx.x].pos.y -= floor((localData[threadIdx.x].pos.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[threadIdx.x].pos.z -= floor((localData[threadIdx.x].pos.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[threadIdx.x].pos, blockCenterX) unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; @@ -306,9 +299,7 @@ extern "C" __global__ void computeN2Energy(unsigned long long* __restrict__ forc real3 pos2 = localData[atom2].pos; real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/cuda/src/kernels/customGBValueN2.cu b/platforms/cuda/src/kernels/customGBValueN2.cu index fb8d65586..f3552bba0 100644 --- a/platforms/cuda/src/kernels/customGBValueN2.cu +++ b/platforms/cuda/src/kernels/customGBValueN2.cu @@ -13,8 +13,9 @@ typedef struct { extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const unsigned int* __restrict__ exclusions, const ushort2* __restrict__ exclusionTiles, unsigned long long* __restrict__ global_value, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, const real4* __restrict__ blockCenter, const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms #else unsigned int numTiles #endif @@ -51,9 +52,7 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const real3 pos2 = localData[atom2].pos; real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -100,9 +99,7 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const real3 pos2 = localData[atom2].pos; real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -229,12 +226,8 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - pos1.x -= floor((pos1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - pos1.y -= floor((pos1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - pos1.z -= floor((pos1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; - localData[threadIdx.x].pos.x -= floor((localData[threadIdx.x].pos.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[threadIdx.x].pos.y -= floor((localData[threadIdx.x].pos.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[threadIdx.x].pos.z -= floor((localData[threadIdx.x].pos.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[threadIdx.x].pos, blockCenterX) unsigned int tj = tgx; for (unsigned int j = 0; j < TILE_SIZE; j++) { int atom2 = tbx+tj; @@ -268,9 +261,7 @@ extern "C" __global__ void computeN2Value(const real4* __restrict__ posq, const real3 pos2 = localData[atom2].pos; real3 delta = make_real3(pos2.x-pos1.x, pos2.y-pos1.y, pos2.z-pos1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/cuda/src/kernels/customHbondForce.cu b/platforms/cuda/src/kernels/customHbondForce.cu index c54a689c1..4d9d4e54e 100644 --- a/platforms/cuda/src/kernels/customHbondForce.cu +++ b/platforms/cuda/src/kernels/customHbondForce.cu @@ -25,12 +25,10 @@ inline __device__ real4 delta(real4 vec1, real4 vec2) { * Compute the difference between two vectors, taking periodic boundary conditions into account * and setting the fourth component to the squared magnitude. */ -inline __device__ real4 deltaPeriodic(real4 vec1, real4 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize) { +inline __device__ real4 deltaPeriodic(real4 vec1, real4 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ) { real4 result = make_real4(vec1.x-vec2.x, vec1.y-vec2.y, vec1.z-vec2.z, 0.0f); #ifdef USE_PERIODIC - result.x -= floor(result.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - result.y -= floor(result.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - result.z -= floor(result.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(result) #endif result.w = result.x*result.x + result.y*result.y + result.z*result.z; return result; @@ -69,7 +67,8 @@ inline __device__ real4 computeCross(real4 vec1, real4 vec2) { * Compute forces on donors. */ extern "C" __global__ void computeDonorForces(unsigned long long* __restrict__ force, real* __restrict__ energyBuffer, const real4* __restrict__ posq, - const int4* __restrict__ exclusions, const int4* __restrict__ donorAtoms, const int4* __restrict__ acceptorAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize + const int4* __restrict__ exclusions, const int4* __restrict__ donorAtoms, const int4* __restrict__ acceptorAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ PARAMETER_ARGUMENTS) { extern __shared__ real4 posBuffer[]; real energy = 0; @@ -116,7 +115,7 @@ extern "C" __global__ void computeDonorForces(unsigned long long* __restrict__ f real4 a1 = posBuffer[3*index]; real4 a2 = posBuffer[3*index+1]; real4 a3 = posBuffer[3*index+2]; - real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize); + real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); #ifdef USE_CUTOFF if (deltaD1A1.w < CUTOFF_SQUARED) { #endif @@ -157,7 +156,8 @@ extern "C" __global__ void computeDonorForces(unsigned long long* __restrict__ f * Compute forces on acceptors. */ extern "C" __global__ void computeAcceptorForces(unsigned long long* __restrict__ force, real* __restrict__ energyBuffer, const real4* __restrict__ posq, - const int4* __restrict__ exclusions, const int4* __restrict__ donorAtoms, const int4* __restrict__ acceptorAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize + const int4* __restrict__ exclusions, const int4* __restrict__ donorAtoms, const int4* __restrict__ acceptorAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ PARAMETER_ARGUMENTS) { extern __shared__ real4 posBuffer[]; real3 f1 = make_real3(0); @@ -203,7 +203,7 @@ extern "C" __global__ void computeAcceptorForces(unsigned long long* __restrict_ real4 d1 = posBuffer[3*index]; real4 d2 = posBuffer[3*index+1]; real4 d3 = posBuffer[3*index+2]; - real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize); + real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); #ifdef USE_CUTOFF if (deltaD1A1.w < CUTOFF_SQUARED) { #endif diff --git a/platforms/cuda/src/kernels/customManyParticle.cu b/platforms/cuda/src/kernels/customManyParticle.cu index 811cd241f..30de85657 100644 --- a/platforms/cuda/src/kernels/customManyParticle.cu +++ b/platforms/cuda/src/kernels/customManyParticle.cu @@ -18,12 +18,10 @@ inline __device__ real3 trim(real4 v) { * Compute the difference between two vectors, taking periodic boundary conditions into account * and setting the fourth component to the squared magnitude. */ -inline __device__ real4 delta(real3 vec1, real3 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize) { +inline __device__ real4 delta(real3 vec1, real3 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ) { real4 result = make_real4(vec1.x-vec2.x, vec1.y-vec2.y, vec1.z-vec2.z, 0.0f); #ifdef USE_PERIODIC - result.x -= floor(result.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - result.y -= floor(result.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - result.z -= floor(result.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(result) #endif result.w = result.x*result.x + result.y*result.y + result.z*result.z; return result; @@ -81,7 +79,7 @@ __constant__ float globals[NUM_GLOBALS]; */ extern "C" __global__ void computeInteraction( unsigned long long* __restrict__ forceBuffers, real* __restrict__ energyBuffer, const real4* __restrict__ posq, - real4 periodicBoxSize, real4 invPeriodicBoxSize + real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ #ifdef USE_CUTOFF , const int* __restrict__ neighbors, const int* __restrict__ neighborStartIndex #endif @@ -144,16 +142,14 @@ extern "C" __global__ void computeInteraction( /** * Find a bounding box for the atoms in each block. */ -extern "C" __global__ void findBlockBounds(real4 periodicBoxSize, real4 invPeriodicBoxSize, const real4* __restrict__ posq, - real4* __restrict__ blockCenter, real4* __restrict__ blockBoundingBox, int* __restrict__ numNeighborPairs) { +extern "C" __global__ void findBlockBounds(real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + const real4* __restrict__ posq, real4* __restrict__ blockCenter, real4* __restrict__ blockBoundingBox, int* __restrict__ numNeighborPairs) { int index = blockIdx.x*blockDim.x+threadIdx.x; int base = index*TILE_SIZE; while (base < NUM_ATOMS) { real4 pos = posq[base]; #ifdef USE_PERIODIC - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS(pos) #endif real4 minPos = pos; real4 maxPos = pos; @@ -162,9 +158,7 @@ extern "C" __global__ void findBlockBounds(real4 periodicBoxSize, real4 invPerio pos = posq[i]; #ifdef USE_PERIODIC real4 center = 0.5f*(maxPos+minPos); - pos.x -= floor((pos.x-center.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - pos.y -= floor((pos.y-center.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - pos.z -= floor((pos.z-center.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center) #endif minPos = make_real4(min(minPos.x,pos.x), min(minPos.y,pos.y), min(minPos.z,pos.z), 0); maxPos = make_real4(max(maxPos.x,pos.x), max(maxPos.y,pos.y), max(maxPos.z,pos.z), 0); @@ -182,8 +176,8 @@ extern "C" __global__ void findBlockBounds(real4 periodicBoxSize, real4 invPerio /** * Find a list of neighbors for each atom. */ -extern "C" __global__ void findNeighbors(real4 periodicBoxSize, real4 invPeriodicBoxSize, const real4* __restrict__ posq, - const real4* __restrict__ blockCenter, const real4* __restrict__ blockBoundingBox, int2* __restrict__ neighborPairs, +extern "C" __global__ void findNeighbors(real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + const real4* __restrict__ posq, const real4* __restrict__ blockCenter, const real4* __restrict__ blockBoundingBox, int2* __restrict__ neighborPairs, int* __restrict__ numNeighborPairs, int* __restrict__ numNeighborsForAtom, int maxNeighborPairs #ifdef USE_EXCLUSIONS , int* __restrict__ exclusions, int* __restrict__ exclusionStartIndex @@ -216,9 +210,7 @@ extern "C" __global__ void findNeighbors(real4 periodicBoxSize, real4 invPeriodi real4 blockSize2 = blockBoundingBox[block2]; real4 blockDelta = blockCenter1-blockCenter2; #ifdef USE_PERIODIC - blockDelta.x -= floor(blockDelta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - blockDelta.y -= floor(blockDelta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - blockDelta.z -= floor(blockDelta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(blockDelta) #endif blockDelta.x = max(0.0f, fabs(blockDelta.x)-blockSize1.x-blockSize2.x); blockDelta.y = max(0.0f, fabs(blockDelta.y)-blockSize1.y-blockSize2.y); @@ -247,7 +239,7 @@ extern "C" __global__ void findNeighbors(real4 periodicBoxSize, real4 invPeriodi // Decide whether to include this atom pair in the neighbor list. - real4 atomDelta = delta(pos1, pos2, periodicBoxSize, invPeriodicBoxSize); + real4 atomDelta = delta(pos1, pos2, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); #ifdef USE_CENTRAL_PARTICLE bool includeAtom = (atom2 != atom1 && atom2 < NUM_ATOMS && atomDelta.w < CUTOFF_SQUARED); #else diff --git a/platforms/cuda/src/kernels/customNonbondedGroups.cu b/platforms/cuda/src/kernels/customNonbondedGroups.cu index b284896ee..8bf2ff0ff 100644 --- a/platforms/cuda/src/kernels/customNonbondedGroups.cu +++ b/platforms/cuda/src/kernels/customNonbondedGroups.cu @@ -10,7 +10,7 @@ typedef struct { extern "C" __global__ void computeInteractionGroups( unsigned long long* __restrict__ forceBuffers, real* __restrict__ energyBuffer, const real4* __restrict__ posq, const int4* __restrict__ groupData, - real4 periodicBoxSize, real4 invPeriodicBoxSize + real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ PARAMETER_ARGUMENTS) { const unsigned int totalWarps = (blockDim.x*gridDim.x)/TILE_SIZE; const unsigned int warp = (blockIdx.x*blockDim.x+threadIdx.x)/TILE_SIZE; // global warpIndex @@ -47,9 +47,7 @@ extern "C" __global__ void computeInteractionGroups( posq2 = make_real4(localData[localIndex].x, localData[localIndex].y, localData[localIndex].z, localData[localIndex].q); real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/cuda/src/kernels/gbsaObc1.cu b/platforms/cuda/src/kernels/gbsaObc1.cu index b450648e1..acdf162fb 100644 --- a/platforms/cuda/src/kernels/gbsaObc1.cu +++ b/platforms/cuda/src/kernels/gbsaObc1.cu @@ -68,8 +68,9 @@ typedef struct { */ extern "C" __global__ void computeBornSum(unsigned long long* __restrict__ global_bornSum, const real4* __restrict__ posq, const float2* __restrict__ global_params, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, const real4* __restrict__ blockCenter, const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms, + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms, #else unsigned int numTiles, #endif @@ -104,9 +105,7 @@ extern "C" __global__ void computeBornSum(unsigned long long* __restrict__ globa for (unsigned int j = 0; j < TILE_SIZE; j++) { real3 delta = make_real3(localData[tbx+j].x-posq1.x, localData[tbx+j].y-posq1.y, localData[tbx+j].z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -151,9 +150,7 @@ extern "C" __global__ void computeBornSum(unsigned long long* __restrict__ globa for (j = 0; j < TILE_SIZE; j++) { real3 delta = make_real3(localData[tbx+tj].x-posq1.x, localData[tbx+tj].y-posq1.y, localData[tbx+tj].z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -291,12 +288,8 @@ extern "C" __global__ void computeBornSum(unsigned long long* __restrict__ globa // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.x -= floor((posq1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - posq1.y -= floor((posq1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - posq1.z -= floor((posq1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; - localData[threadIdx.x].x -= floor((localData[threadIdx.x].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[threadIdx.x].y -= floor((localData[threadIdx.x].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[threadIdx.x].z -= floor((localData[threadIdx.x].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[threadIdx.x], blockCenterX) unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { real3 delta = make_real3(localData[tbx+tj].x-posq1.x, localData[tbx+tj].y-posq1.y, localData[tbx+tj].z-posq1.z); @@ -342,9 +335,7 @@ extern "C" __global__ void computeBornSum(unsigned long long* __restrict__ globa for (j = 0; j < TILE_SIZE; j++) { real3 delta = make_real3(localData[tbx+tj].x-posq1.x, localData[tbx+tj].y-posq1.y, localData[tbx+tj].z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; int atom2 = atomIndices[tbx+tj]; @@ -413,8 +404,9 @@ typedef struct { extern "C" __global__ void computeGBSAForce1(unsigned long long* __restrict__ forceBuffers, unsigned long long* __restrict__ global_bornForce, real* __restrict__ energyBuffer, const real4* __restrict__ posq, const real* __restrict__ global_bornRadii, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, const real4* __restrict__ blockCenter, const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms, + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const real4* __restrict__ blockSize, const unsigned int* __restrict__ interactingAtoms, #else unsigned int numTiles, #endif @@ -451,9 +443,7 @@ extern "C" __global__ void computeGBSAForce1(unsigned long long* __restrict__ fo real4 posq2 = make_real4(localData[tbx+j].x, localData[tbx+j].y, localData[tbx+j].z, localData[tbx+j].q); real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -508,9 +498,7 @@ extern "C" __global__ void computeGBSAForce1(unsigned long long* __restrict__ fo real4 posq2 = make_real4(localData[tbx+tj].x, localData[tbx+tj].y, localData[tbx+tj].z, localData[tbx+tj].q); real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -656,12 +644,8 @@ extern "C" __global__ void computeGBSAForce1(unsigned long long* __restrict__ fo // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.x -= floor((posq1.x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - posq1.y -= floor((posq1.y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - posq1.z -= floor((posq1.z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; - localData[threadIdx.x].x -= floor((localData[threadIdx.x].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[threadIdx.x].y -= floor((localData[threadIdx.x].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[threadIdx.x].z -= floor((localData[threadIdx.x].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[threadIdx.x], blockCenterX) unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { int atom2 = atomIndices[tbx+tj]; @@ -713,9 +697,7 @@ extern "C" __global__ void computeGBSAForce1(unsigned long long* __restrict__ fo real4 posq2 = make_real4(localData[tbx+tj].x, localData[tbx+tj].y, localData[tbx+tj].z, localData[tbx+tj].q); real3 delta = make_real3(posq2.x-posq1.x, posq2.y-posq1.y, posq2.z-posq1.z); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/cuda/src/kernels/monteCarloBarostat.cu b/platforms/cuda/src/kernels/monteCarloBarostat.cu index d47727b78..90cd49a62 100644 --- a/platforms/cuda/src/kernels/monteCarloBarostat.cu +++ b/platforms/cuda/src/kernels/monteCarloBarostat.cu @@ -2,7 +2,8 @@ * Scale the particle positions with each axis independent */ -extern "C" __global__ void scalePositions(float scaleX, float scaleY, float scaleZ, int numMolecules, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4* __restrict__ posq, +extern "C" __global__ void scalePositions(float scaleX, float scaleY, float scaleZ, int numMolecules, real4 periodicBoxSize, + real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, real4* __restrict__ posq, const int* __restrict__ moleculeAtoms, const int* __restrict__ moleculeStartIndex) { for (int index = blockIdx.x*blockDim.x+threadIdx.x; index < numMolecules; index += blockDim.x*gridDim.x) { int first = moleculeStartIndex[index]; @@ -25,13 +26,9 @@ extern "C" __global__ void scalePositions(float scaleX, float scaleY, float scal // Move it into the first periodic box. - int xcell = (int) floor(center.x*invPeriodicBoxSize.x); - int ycell = (int) floor(center.y*invPeriodicBoxSize.y); - int zcell = (int) floor(center.z*invPeriodicBoxSize.z); - real3 delta = make_real3(xcell*periodicBoxSize.x, ycell*periodicBoxSize.y, zcell*periodicBoxSize.z); - center.x -= delta.x; - center.y -= delta.y; - center.z -= delta.z; + real3 oldCenter = center; + APPLY_PERIODIC_TO_POS(center) + real3 delta = make_real3(oldCenter.x-center.x, oldCenter.y-center.y, oldCenter.z-center.z); // Now scale the position of the molecule center. diff --git a/platforms/cuda/tests/TestCudaCustomManyParticleForce.cpp b/platforms/cuda/tests/TestCudaCustomManyParticleForce.cpp index 7a0e94ccb..95c7a17ee 100644 --- a/platforms/cuda/tests/TestCudaCustomManyParticleForce.cpp +++ b/platforms/cuda/tests/TestCudaCustomManyParticleForce.cpp @@ -55,7 +55,17 @@ const double TOL = 1e-5; CudaPlatform platform; -void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize) { +Vec3 computeDelta(const Vec3& pos1, const Vec3& pos2, bool periodic, const Vec3* periodicBoxVectors) { + Vec3 diff = pos1-pos2; + if (periodic) { + diff -= periodicBoxVectors[2]*floor(diff[2]/periodicBoxVectors[2][2]+0.5); + diff -= periodicBoxVectors[1]*floor(diff[1]/periodicBoxVectors[1][1]+0.5); + diff -= periodicBoxVectors[0]*floor(diff[0]/periodicBoxVectors[0][0]+0.5); + } + return diff; +} + +void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize, bool triclinic) { // Create a System and Context. int numParticles = force->getNumParticles(); @@ -63,7 +73,18 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p System system; for (int i = 0; i < numParticles; i++) system.addParticle(1.0); - system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); + Vec3 boxVectors[3]; + if (triclinic) { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0.2*boxSize, boxSize, 0); + boxVectors[2] = Vec3(-0.3*boxSize, -0.1*boxSize, boxSize); + } + else { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0, boxSize, 0); + boxVectors[2] = Vec3(0, 0, boxSize); + } + system.setDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); system.addForce(force); VerletIntegrator integrator(0.001); Context context(system, integrator, platform); @@ -74,20 +95,14 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p // See if the energy matches the expected value. double expectedEnergy = 0; + bool periodic = (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic); for (int i = 0; i < (int) expectedSets.size(); i++) { int p1 = expectedSets[i][0]; int p2 = expectedSets[i][1]; int p3 = expectedSets[i][2]; - Vec3 d12 = positions[p2]-positions[p1]; - Vec3 d13 = positions[p3]-positions[p1]; - Vec3 d23 = positions[p3]-positions[p2]; - if (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic) { - for (int j = 0; j < 3; j++) { - d12[j] -= floor(d12[j]/boxSize+0.5f)*boxSize; - d13[j] -= floor(d13[j]/boxSize+0.5f)*boxSize; - d23[j] -= floor(d23[j]/boxSize+0.5f)*boxSize; - } - } + Vec3 d12 = computeDelta(positions[p2], positions[p1], periodic, boxVectors); + Vec3 d13 = computeDelta(positions[p3], positions[p1], periodic, boxVectors); + Vec3 d23 = computeDelta(positions[p3], positions[p2], periodic, boxVectors); double r12 = sqrt(d12.dot(d12)); double r13 = sqrt(d13.dot(d13)); double r23 = sqrt(d23.dot(d23)); @@ -210,7 +225,7 @@ void testNoCutoff() { positions.push_back(Vec3(0.4, 0, -0.8)); int sets[4][3] = {{0,1,2}, {1,2,3}, {2,3,0}, {3,0,1}}; vector expectedSets(&sets[0], &sets[4]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testCutoff() { @@ -235,7 +250,7 @@ void testCutoff() { positions.push_back(Vec3(0.2, 0.5, -0.1)); int sets[7][3] = {{0,1,2}, {0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,2,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[7]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testPeriodic() { @@ -261,7 +276,33 @@ void testPeriodic() { double boxSize = 2.1; int sets[5][3] = {{0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, boxSize); + validateAxilrodTeller(force, positions, expectedSets, boxSize, false); +} + +void testTriclinic() { + CustomManyParticleForce* force = new CustomManyParticleForce(3, + "C*(1+3*cos(theta1)*cos(theta2)*cos(theta3))/(r12*r13*r23)^3;" + "theta1=angle(p1,p2,p3); theta2=angle(p2,p3,p1); theta3=angle(p3,p1,p2);" + "r12=distance(p1,p2); r13=distance(p1,p3); r23=distance(p2,p3)"); + force->addGlobalParameter("C", 1.5); + force->setNonbondedMethod(CustomManyParticleForce::CutoffPeriodic); + force->setCutoffDistance(1.05); + vector params; + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + vector positions; + positions.push_back(Vec3(0, 0, 0)); + positions.push_back(Vec3(1, 0, 0)); + positions.push_back(Vec3(0, 1.1, 0.3)); + positions.push_back(Vec3(0.4, 0, -0.8)); + positions.push_back(Vec3(0.2, 0.5, -0.1)); + double boxSize = 2.1; + int sets[4][3] = {{0,1,3}, {0,1,4}, {0,3,4}, {1,3,4}}; + vector expectedSets(&sets[0], &sets[4]); + validateAxilrodTeller(force, positions, expectedSets, boxSize, true); } void testExclusions() { @@ -286,7 +327,7 @@ void testExclusions() { force->addExclusion(0, 3); int sets[5][3] = {{0,1,4}, {1,2,3}, {1,2,4}, {1,3,4}, {2,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testAllTerms() { @@ -672,6 +713,7 @@ int main(int argc, char* argv[]) { testNoCutoff(); testCutoff(); testPeriodic(); + testTriclinic(); testExclusions(); testAllTerms(); testParameters(); diff --git a/platforms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp b/platforms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp index 6d8373d4b..8c2501481 100644 --- a/platforms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp +++ b/platforms/cuda/tests/TestCudaMonteCarloAnisotropicBarostat.cpp @@ -236,6 +236,82 @@ void testRandomSeed() { } } +void testTriclinic() { + const int numParticles = 64; + const int frequency = 10; + const int steps = 1000; + const double pressure = 1.5; + const double pressureInMD = pressure*(AVOGADRO*1e-25); // pressure in kJ/mol/nm^3 + const double temperature = 300.0; + const double initialVolume = numParticles*BOLTZ*temperature/pressureInMD; + const double initialLength = std::pow(initialVolume, 1.0/3.0); + + // Create a gas of noninteracting particles. + + System system; + Vec3 initialBox[3]; + initialBox[0] = Vec3(initialLength, 0, 0); + initialBox[1] = Vec3(0.2*initialLength, initialLength, 0); + initialBox[2] = Vec3(0.1*initialLength, 0.3*initialLength, initialLength); + system.setDefaultPeriodicBoxVectors(initialBox[0], initialBox[1], initialBox[2]); + vector positions(numParticles); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int i = 0; i < numParticles; ++i) { + system.addParticle(1.0); + positions[i] = Vec3(initialLength*genrand_real2(sfmt), initialLength*genrand_real2(sfmt), initialLength*genrand_real2(sfmt)); + } + MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temperature, true, true, true, frequency); + system.addForce(barostat); + + // Run a simulation + + LangevinIntegrator integrator(temperature, 0.1, 0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + + // Let it equilibrate. + + integrator.step(10000); + + // Now run it for a while and see if the volume is correct. + + double volume = 0.0; + for (int j = 0; j < steps; ++j) { + Vec3 box[3]; + context.getState(0).getPeriodicBoxVectors(box[0], box[1], box[2]); + volume += box[0][0]*box[1][1]*box[2][2]; + integrator.step(frequency); + } + volume /= steps; + double expected = (numParticles+1)*BOLTZ*temperature/pressureInMD; + ASSERT_USUALLY_EQUAL_TOL(expected, volume, 3/std::sqrt((double) steps)); + + // Make sure the box vectors have been scaled consistently. + + State state = context.getState(State::Positions); + Vec3 box[3]; + state.getPeriodicBoxVectors(box[0], box[1], box[2]); + double xscale = box[2][0]/(0.1*initialLength); + double yscale = box[2][1]/(0.3*initialLength); + double zscale = box[2][2]/(1.0*initialLength); + for (int i = 0; i < 3; i++) { + ASSERT_EQUAL_VEC(Vec3(xscale*initialBox[i][0], yscale*initialBox[i][1], zscale*initialBox[i][2]), box[i], 1e-5); + } + + // The barostat should have put all particles inside the first periodic box. One integration step + // has happened since then, so they may have moved slightly outside it. + + for (int i = 0; i < numParticles; i++) { + Vec3 pos = state.getPositions()[i]; + ASSERT(pos[2]/box[2][2] > -1 && pos[2]/box[2][2] < 2); + pos -= box[2]*floor(pos[2]/box[2][2]); + ASSERT(pos[1]/box[1][1] > -1 && pos[1]/box[1][1] < 2); + pos -= box[1]*floor(pos[1]/box[1][1]); + ASSERT(pos[0]/box[0][0] > -1 && pos[0]/box[0][0] < 2); + } +} + /** * Run a constant pressure simulation on an anisotropic Einstein crystal * using isotropic and anisotropic barostats. There are a total of 15 simulations: @@ -389,6 +465,7 @@ int main(int argc, char* argv[]) { testIdealGasAxis(1); testIdealGasAxis(2); testRandomSeed(); + testTriclinic(); //testEinsteinCrystal(); } catch(const exception& e) { -- GitLab From e7eb7852cf3c0837f999569ea88aa2bb326ee894 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Tue, 6 Jan 2015 13:57:32 -0800 Subject: [PATCH 191/338] CUDA support for PME with triclinic boxes --- platforms/cuda/src/CudaKernels.cpp | 44 +++++++++++-- platforms/cuda/src/kernels/pme.cu | 86 ++++++++++++++------------ platforms/cuda/tests/TestCudaEwald.cpp | 52 ++++++++++++++++ 3 files changed, 139 insertions(+), 43 deletions(-) diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 448a814d8..1805bc9c7 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1802,13 +1802,43 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF if (directPmeGrid != NULL && includeReciprocal) { if (usePmeStream) cu.setCurrentStream(pmeStream); - void* gridIndexArgs[] = {&cu.getPosq().getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + + // Invert the periodic box vectors. + + Vec3 boxVectors[3]; + cu.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); + double determinant = boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]; + double scale = 1.0/determinant; + double3 recipBoxVectors[3]; + recipBoxVectors[0] = make_double3(boxVectors[1][1]*boxVectors[2][2]*scale, 0, 0); + recipBoxVectors[1] = make_double3(-boxVectors[1][0]*boxVectors[2][2]*scale, boxVectors[0][0]*boxVectors[2][2]*scale, 0); + recipBoxVectors[2] = make_double3((boxVectors[1][0]*boxVectors[2][1]-boxVectors[1][1]*boxVectors[2][0])*scale, -boxVectors[0][0]*boxVectors[2][1]*scale, boxVectors[0][0]*boxVectors[1][1]*scale); + float3 recipBoxVectorsFloat[3]; + void* recipBoxVectorPointer[3]; + if (cu.getUseDoublePrecision()) { + recipBoxVectorPointer[0] = &recipBoxVectors[0]; + recipBoxVectorPointer[1] = &recipBoxVectors[1]; + recipBoxVectorPointer[2] = &recipBoxVectors[2]; + } + else { + recipBoxVectorsFloat[0] = make_float3((float) recipBoxVectors[0].x, 0, 0); + recipBoxVectorsFloat[1] = make_float3((float) recipBoxVectors[1].x, (float) recipBoxVectors[1].y, 0); + recipBoxVectorsFloat[2] = make_float3((float) recipBoxVectors[2].x, (float) recipBoxVectors[2].y, (float) recipBoxVectors[2].z); + recipBoxVectorPointer[0] = &recipBoxVectorsFloat[0]; + recipBoxVectorPointer[1] = &recipBoxVectorsFloat[1]; + recipBoxVectorPointer[2] = &recipBoxVectorsFloat[2]; + } + + // Execute the reciprocal space kernels. + + void* gridIndexArgs[] = {&cu.getPosq().getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), + recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeGridIndexKernel, gridIndexArgs, cu.getNumAtoms()); sort->sort(*pmeAtomGridIndex); void* spreadArgs[] = {&cu.getPosq().getDevicePointer(), &directPmeGrid->getDevicePointer(), cu.getPeriodicBoxSizePointer(), - cu.getInvPeriodicBoxSizePointer(), &pmeAtomGridIndex->getDevicePointer()}; + recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeSpreadChargeKernel, spreadArgs, cu.getNumAtoms(), 128); if (cu.getUseDoublePrecision() || cu.getComputeCapability() < 2.0) { @@ -1822,11 +1852,15 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF cufftExecR2C(fftForward, (float*) directPmeGrid->getDevicePointer(), (float2*) reciprocalPmeGrid->getDevicePointer()); if (includeEnergy) { - void* computeEnergyArgs[] = {&reciprocalPmeGrid->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), &pmeBsplineModuliX->getDevicePointer(), &pmeBsplineModuliY->getDevicePointer(), &pmeBsplineModuliZ->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + void* computeEnergyArgs[] = {&reciprocalPmeGrid->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), + &pmeBsplineModuliX->getDevicePointer(), &pmeBsplineModuliY->getDevicePointer(), &pmeBsplineModuliZ->getDevicePointer(), + cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeEvalEnergyKernel, computeEnergyArgs, cu.getNumAtoms()); } - void* convolutionArgs[] = {&reciprocalPmeGrid->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), &pmeBsplineModuliX->getDevicePointer(), &pmeBsplineModuliY->getDevicePointer(), &pmeBsplineModuliZ->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + void* convolutionArgs[] = {&reciprocalPmeGrid->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), + &pmeBsplineModuliX->getDevicePointer(), &pmeBsplineModuliY->getDevicePointer(), &pmeBsplineModuliZ->getDevicePointer(), + cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeConvolutionKernel, convolutionArgs, cu.getNumAtoms()); if (cu.getUseDoublePrecision()) @@ -1836,7 +1870,7 @@ double CudaCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeF void* interpolateArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &directPmeGrid->getDevicePointer(), - cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), &pmeAtomGridIndex->getDevicePointer()}; + cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeInterpolateForceKernel, interpolateArgs, cu.getNumAtoms(), 128); if (usePmeStream) { cuEventRecord(pmeSyncEvent, pmeStream); diff --git a/platforms/cuda/src/kernels/pme.cu b/platforms/cuda/src/kernels/pme.cu index 797ca6b4d..4dd21a6c5 100644 --- a/platforms/cuda/src/kernels/pme.cu +++ b/platforms/cuda/src/kernels/pme.cu @@ -1,24 +1,27 @@ extern "C" __global__ void findAtomGridIndex(const real4* __restrict__ posq, int2* __restrict__ pmeAtomGridIndex, - real4 periodicBoxSize, real4 invPeriodicBoxSize) { + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { // Compute the index of the grid point each atom is associated with. for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { real4 pos = posq[i]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; - real3 t = make_real3((pos.x*invPeriodicBoxSize.x)*GRID_SIZE_X, - (pos.y*invPeriodicBoxSize.y)*GRID_SIZE_Y, - (pos.z*invPeriodicBoxSize.z)*GRID_SIZE_Z); + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + real3 t = make_real3(pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, + pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, + pos.z*recipBoxVecZ.z); + t.x = (t.x-floor(t.x))*GRID_SIZE_X; + t.y = (t.y-floor(t.y))*GRID_SIZE_Y; + t.z = (t.z-floor(t.z))*GRID_SIZE_Z; int3 gridIndex = make_int3(((int) t.x) % GRID_SIZE_X, - ((int) t.y) % GRID_SIZE_Y, - ((int) t.z) % GRID_SIZE_Z); + ((int) t.y) % GRID_SIZE_Y, + ((int) t.z) % GRID_SIZE_Z); pmeAtomGridIndex[i] = make_int2(i, gridIndex.x*GRID_SIZE_Y*GRID_SIZE_Z+gridIndex.y*GRID_SIZE_Z+gridIndex.z); } } extern "C" __global__ void gridSpreadCharge(const real4* __restrict__ posq, real* __restrict__ originalPmeGrid, - real4 periodicBoxSize, real4 invPeriodicBoxSize, const int2* __restrict__ pmeAtomGridIndex) { + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ, const int2* __restrict__ pmeAtomGridIndex) { real3 data[PME_ORDER]; const real scale = RECIP(PME_ORDER-1); @@ -30,12 +33,15 @@ extern "C" __global__ void gridSpreadCharge(const real4* __restrict__ posq, real real charge = posq[atom].w; real3 force = make_real3(0); real4 pos = posq[atom]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; - real3 t = make_real3((pos.x*invPeriodicBoxSize.x)*GRID_SIZE_X, - (pos.y*invPeriodicBoxSize.y)*GRID_SIZE_Y, - (pos.z*invPeriodicBoxSize.z)*GRID_SIZE_Z); + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + real3 t = make_real3(pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, + pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, + pos.z*recipBoxVecZ.z); + t.x = (t.x-floor(t.x))*GRID_SIZE_X; + t.y = (t.y-floor(t.y))*GRID_SIZE_Y; + t.z = (t.z-floor(t.z))*GRID_SIZE_Z; int3 gridIndex = make_int3(((int) t.x) % GRID_SIZE_X, ((int) t.y) % GRID_SIZE_Y, ((int) t.z) % GRID_SIZE_Z); @@ -115,9 +121,8 @@ extern "C" __global__ void finishSpreadCharge(long long* __restrict__ originalPm // convolutes on the halfcomplex_pmeGrid, which is of size NX*NY*(NZ/2+1) as F(Q) is conjugate symmetric extern "C" __global__ void reciprocalConvolution(real2* __restrict__ halfcomplex_pmeGrid, real* __restrict__ energyBuffer, - const real* __restrict__ pmeBsplineModuliX, - const real* __restrict__ pmeBsplineModuliY, const real* __restrict__ pmeBsplineModuliZ, - real4 periodicBoxSize, real4 invPeriodicBoxSize) { + const real* __restrict__ pmeBsplineModuliX, const real* __restrict__ pmeBsplineModuliY, const real* __restrict__ pmeBsplineModuliZ, + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { // R2C stores into a half complex matrix where the last dimension is cut by half const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*(GRID_SIZE_Z/2+1); const real recipScaleFactor = RECIP(M_PI*periodicBoxSize.x*periodicBoxSize.y*periodicBoxSize.z); @@ -131,9 +136,9 @@ reciprocalConvolution(real2* __restrict__ halfcomplex_pmeGrid, real* __restrict_ int mx = (kx < (GRID_SIZE_X+1)/2) ? kx : (kx-GRID_SIZE_X); int my = (ky < (GRID_SIZE_Y+1)/2) ? ky : (ky-GRID_SIZE_Y); int mz = (kz < (GRID_SIZE_Z+1)/2) ? kz : (kz-GRID_SIZE_Z); - real mhx = mx*invPeriodicBoxSize.x; - real mhy = my*invPeriodicBoxSize.y; - real mhz = mz*invPeriodicBoxSize.z; + real mhx = mx*recipBoxVecX.x; + real mhy = mx*recipBoxVecY.x+my*recipBoxVecY.y; + real mhz = mx*recipBoxVecZ.x+my*recipBoxVecZ.y+mz*recipBoxVecZ.z; real bx = pmeBsplineModuliX[kx]; real by = pmeBsplineModuliY[ky]; real bz = pmeBsplineModuliZ[kz]; @@ -151,9 +156,8 @@ reciprocalConvolution(real2* __restrict__ halfcomplex_pmeGrid, real* __restrict_ extern "C" __global__ void gridEvaluateEnergy(real2* __restrict__ halfcomplex_pmeGrid, real* __restrict__ energyBuffer, - const real* __restrict__ pmeBsplineModuliX, - const real* __restrict__ pmeBsplineModuliY, const real* __restrict__ pmeBsplineModuliZ, - real4 periodicBoxSize, real4 invPeriodicBoxSize) { + const real* __restrict__ pmeBsplineModuliX, const real* __restrict__ pmeBsplineModuliY, const real* __restrict__ pmeBsplineModuliZ, + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { // R2C stores into a half complex matrix where the last dimension is cut by half const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; const real recipScaleFactor = RECIP(M_PI*periodicBoxSize.x*periodicBoxSize.y*periodicBoxSize.z); @@ -168,9 +172,9 @@ gridEvaluateEnergy(real2* __restrict__ halfcomplex_pmeGrid, real* __restrict__ e int mx = (kx < (GRID_SIZE_X+1)/2) ? kx : (kx-GRID_SIZE_X); int my = (ky < (GRID_SIZE_Y+1)/2) ? ky : (ky-GRID_SIZE_Y); int mz = (kz < (GRID_SIZE_Z+1)/2) ? kz : (kz-GRID_SIZE_Z); - real mhx = mx*invPeriodicBoxSize.x; - real mhy = my*invPeriodicBoxSize.y; - real mhz = mz*invPeriodicBoxSize.z; + real mhx = mx*recipBoxVecX.x; + real mhy = mx*recipBoxVecY.x+my*recipBoxVecY.y; + real mhz = mx*recipBoxVecZ.x+my*recipBoxVecZ.y+mz*recipBoxVecZ.z; real m2 = mhx*mhx+mhy*mhy+mhz*mhz; real bx = pmeBsplineModuliX[kx]; real by = pmeBsplineModuliY[ky]; @@ -194,7 +198,7 @@ gridEvaluateEnergy(real2* __restrict__ halfcomplex_pmeGrid, real* __restrict__ e extern "C" __global__ void gridInterpolateForce(const real4* __restrict__ posq, unsigned long long* __restrict__ forceBuffers, const real* __restrict__ originalPmeGrid, - real4 periodicBoxSize, real4 invPeriodicBoxSize, const int2* __restrict__ pmeAtomGridIndex) { + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ, const int2* __restrict__ pmeAtomGridIndex) { real3 data[PME_ORDER]; real3 ddata[PME_ORDER]; const real scale = RECIP(PME_ORDER-1); @@ -206,12 +210,15 @@ void gridInterpolateForce(const real4* __restrict__ posq, unsigned long long* __ int atom = pmeAtomGridIndex[i].x; real3 force = make_real3(0); real4 pos = posq[atom]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; - real3 t = make_real3((pos.x*invPeriodicBoxSize.x)*GRID_SIZE_X, - (pos.y*invPeriodicBoxSize.y)*GRID_SIZE_Y, - (pos.z*invPeriodicBoxSize.z)*GRID_SIZE_Z); + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + real3 t = make_real3(pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, + pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, + pos.z*recipBoxVecZ.z); + t.x = (t.x-floor(t.x))*GRID_SIZE_X; + t.y = (t.y-floor(t.y))*GRID_SIZE_Y; + t.z = (t.z-floor(t.z))*GRID_SIZE_Z; int3 gridIndex = make_int3(((int) t.x) % GRID_SIZE_X, ((int) t.y) % GRID_SIZE_Y, ((int) t.z) % GRID_SIZE_Z); @@ -266,9 +273,12 @@ void gridInterpolateForce(const real4* __restrict__ posq, unsigned long long* __ } } real q = pos.w*EPSILON_FACTOR; - forceBuffers[atom] += static_cast((long long) (-q*force.x*GRID_SIZE_X*invPeriodicBoxSize.x*0x100000000)); - forceBuffers[atom+PADDED_NUM_ATOMS] += static_cast((long long) (-q*force.y*GRID_SIZE_Y*invPeriodicBoxSize.y*0x100000000)); - forceBuffers[atom+2*PADDED_NUM_ATOMS] += static_cast((long long) (-q*force.z*GRID_SIZE_Z*invPeriodicBoxSize.z*0x100000000)); + real forceX = -q*(force.x*GRID_SIZE_X*recipBoxVecX.x); + real forceY = -q*(force.x*GRID_SIZE_X*recipBoxVecY.x+force.y*GRID_SIZE_Y*recipBoxVecY.y); + real forceZ = -q*(force.x*GRID_SIZE_X*recipBoxVecZ.x+force.y*GRID_SIZE_Y*recipBoxVecZ.y+force.z*GRID_SIZE_Z*recipBoxVecZ.z); + forceBuffers[atom] += static_cast((long long) (forceX*0x100000000)); + forceBuffers[atom+PADDED_NUM_ATOMS] += static_cast((long long) (forceY*0x100000000)); + forceBuffers[atom+2*PADDED_NUM_ATOMS] += static_cast((long long) (forceZ*0x100000000)); } } diff --git a/platforms/cuda/tests/TestCudaEwald.cpp b/platforms/cuda/tests/TestCudaEwald.cpp index dd7395742..51773b649 100644 --- a/platforms/cuda/tests/TestCudaEwald.cpp +++ b/platforms/cuda/tests/TestCudaEwald.cpp @@ -201,6 +201,57 @@ void testEwald2Ions() { ASSERT_EQUAL_TOL(-217.276, state.getPotentialEnergy(), 0.01/*10*TOL*/); } +void testTriclinic() { + // Create a triclinic box containing eight particles. + + System system; + system.setDefaultPeriodicBoxVectors(Vec3(2.5, 0, 0), Vec3(0.5, 3.0, 0), Vec3(0.7, 0.9, 3.5)); + for (int i = 0; i < 8; i++) + system.addParticle(1.0); + NonbondedForce* force = new NonbondedForce(); + system.addForce(force); + force->setNonbondedMethod(NonbondedForce::PME); + force->setCutoffDistance(1.0); + force->setPMEParameters(3.45891, 32, 40, 48); + for (int i = 0; i < 4; i++) + force->addParticle(-1, 0.440104, 0.4184); // Cl parameters + for (int i = 0; i < 4; i++) + force->addParticle(1, 0.332840, 0.0115897); // Na parameters + vector positions(8); + positions[0] = Vec3(1.744, 2.788, 3.162); + positions[1] = Vec3(1.048, 0.762, 2.340); + positions[2] = Vec3(2.489, 1.570, 2.817); + positions[3] = Vec3(1.027, 1.893, 3.271); + positions[4] = Vec3(0.937, 0.825, 0.009); + positions[5] = Vec3(2.290, 1.887, 3.352); + positions[6] = Vec3(1.266, 1.111, 2.894); + positions[7] = Vec3(0.933, 1.862, 3.490); + + // Compute the forces and energy. + + VerletIntegrator integ(0.001); + Context context(system, integ, platform); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + + // Compare them to values computed by Gromacs. + + double expectedEnergy = -963.370; + vector expectedForce(8); + expectedForce[0] = Vec3(4.25253e+01, -1.23503e+02, 1.22139e+02); + expectedForce[1] = Vec3(9.74752e+01, 1.68213e+02, 1.93169e+02); + expectedForce[2] = Vec3(-1.50348e+02, 1.29165e+02, 3.70435e+02); + expectedForce[3] = Vec3(9.18644e+02, -3.52571e+00, -1.34772e+03); + expectedForce[4] = Vec3(-1.61193e+02, 9.01528e+01, -7.12904e+01); + expectedForce[5] = Vec3(2.82630e+02, 2.78029e+01, -3.72864e+02); + expectedForce[6] = Vec3(-1.47454e+02, -2.14448e+02, -3.55789e+02); + expectedForce[7] = Vec3(-8.82195e+02, -7.39132e+01, 1.46202e+03); + for (int i = 0; i < 8; i++) { + ASSERT_EQUAL_VEC(expectedForce[i], state.getForces()[i], 1e-4); + } + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), 1e-4); +} + void testErrorTolerance(NonbondedForce::NonbondedMethod method) { // Create a cloud of random point charges. @@ -307,6 +358,7 @@ int main(int argc, char* argv[]) { testEwaldPME(false); testEwaldPME(true); // testEwald2Ions(); + testTriclinic(); testErrorTolerance(NonbondedForce::Ewald); testErrorTolerance(NonbondedForce::PME); testPMEParameters(); -- GitLab From 17c06daae12c26cfc2b5850948ec3eccd1cd074b Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 7 Jan 2015 11:05:08 -0800 Subject: [PATCH 192/338] Fixed some methods that should have been marked const --- platforms/cuda/include/CudaContext.h | 10 +++++----- platforms/cuda/src/CudaContext.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platforms/cuda/include/CudaContext.h b/platforms/cuda/include/CudaContext.h index 21aae8724..18e4a8620 100644 --- a/platforms/cuda/include/CudaContext.h +++ b/platforms/cuda/include/CudaContext.h @@ -352,30 +352,30 @@ public: /** * Get whether double precision is being used. */ - bool getUseDoublePrecision() { + bool getUseDoublePrecision() const { return useDoublePrecision; } /** * Get whether mixed precision is being used. */ - bool getUseMixedPrecision() { + bool getUseMixedPrecision() const { return useMixedPrecision; } /** * Get whether the periodic box is triclinic. */ - bool getBoxIsTriclinic() { + bool getBoxIsTriclinic() const { return boxIsTriclinic; } /** * Convert a number to a string in a format suitable for including in a kernel. * This takes into account whether the context uses single or double precision. */ - std::string doubleToString(double value); + std::string doubleToString(double value) const; /** * Convert a number to a string in a format suitable for including in a kernel. */ - std::string intToString(int value); + std::string intToString(int value) const; /** * Convert a CUDA result code to the corresponding string description. */ diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 1083846fa..569e9ee1b 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -594,7 +594,7 @@ void CudaContext::restoreDefaultStream() { setCurrentStream(0); } -string CudaContext::doubleToString(double value) { +string CudaContext::doubleToString(double value) const { stringstream s; s.precision(useDoublePrecision ? 16 : 8); s << scientific << value; @@ -603,7 +603,7 @@ string CudaContext::doubleToString(double value) { return s.str(); } -string CudaContext::intToString(int value) { +string CudaContext::intToString(int value) const { stringstream s; s << value; return s.str(); -- GitLab From 195bcecf2839458e14a7c8fe72e50f5380782dbc Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 7 Jan 2015 13:07:52 -0800 Subject: [PATCH 193/338] Began implementing OpenCL support for triclinic boxes --- platforms/opencl/include/OpenCLContext.h | 94 ++++++++++++++---- platforms/opencl/src/OpenCLContext.cpp | 54 ++++++++++- platforms/opencl/src/OpenCLKernels.cpp | 44 +++++---- .../opencl/src/OpenCLNonbondedUtilities.cpp | 95 +++++++++---------- .../src/kernels/findInteractingBlocks.cl | 23 ++--- .../opencl/src/kernels/monteCarloBarostat.cl | 17 ++-- platforms/opencl/src/kernels/nonbonded.cl | 15 ++- .../tests/TestOpenCLCustomNonbondedForce.cpp | 62 +++++++++++- ...estOpenCLMonteCarloAnisotropicBarostat.cpp | 79 ++++++++++++++- .../opencl/tests/TestOpenCLNonbondedForce.cpp | 64 ++++++++++++- 10 files changed, 430 insertions(+), 117 deletions(-) diff --git a/platforms/opencl/include/OpenCLContext.h b/platforms/opencl/include/OpenCLContext.h index 18d33184c..a1c01e777 100644 --- a/platforms/opencl/include/OpenCLContext.h +++ b/platforms/opencl/include/OpenCLContext.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2013 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -448,36 +448,65 @@ public: /** * Get whether the device being used supports 64 bit atomic operations on global memory. */ - bool getSupports64BitGlobalAtomics() { + bool getSupports64BitGlobalAtomics() const { return supports64BitGlobalAtomics; } /** * Get whether the device being used supports double precision math. */ - bool getSupportsDoublePrecision() { + bool getSupportsDoublePrecision() const { return supportsDoublePrecision; } /** * Get whether double precision is being used. */ - bool getUseDoublePrecision() { + bool getUseDoublePrecision() const { return useDoublePrecision; } /** * Get whether mixed precision is being used. */ - bool getUseMixedPrecision() { + bool getUseMixedPrecision() const { return useMixedPrecision; } + /** + * Get whether the periodic box is triclinic. + */ + bool getBoxIsTriclinic() const { + return boxIsTriclinic; + } /** * Convert a number to a string in a format suitable for including in a kernel. * This takes into account whether the context uses single or double precision. */ - std::string doubleToString(double value); + std::string doubleToString(double value) const; /** * Convert a number to a string in a format suitable for including in a kernel. */ - std::string intToString(int value); + std::string intToString(int value) const; + /** + * Get the vectors defining the periodic box. + */ + void getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) const { + a = Vec3(periodicBoxVecXDouble.x, periodicBoxVecXDouble.y, periodicBoxVecXDouble.z); + b = Vec3(periodicBoxVecYDouble.x, periodicBoxVecYDouble.y, periodicBoxVecYDouble.z); + c = Vec3(periodicBoxVecZDouble.x, periodicBoxVecZDouble.y, periodicBoxVecZDouble.z); + } + /** + * Set the vectors defining the periodic box. + */ + void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c) { + periodicBoxVecX = mm_float4((float) a[0], (float) a[1], (float) a[2], 0.0f); + periodicBoxVecY = mm_float4((float) b[0], (float) b[1], (float) b[2], 0.0f); + periodicBoxVecZ = mm_float4((float) c[0], (float) c[1], (float) c[2], 0.0f); + periodicBoxVecXDouble = mm_double4(a[0], a[1], a[2], 0.0); + periodicBoxVecYDouble = mm_double4(b[0], b[1], b[2], 0.0); + periodicBoxVecZDouble = mm_double4(c[0], c[1], c[2], 0.0); + periodicBoxSize = mm_float4((float) a[0], (float) b[1], (float) c[2], 0.0f); + invPeriodicBoxSize = mm_float4(1.0f/(float) a[0], 1.0f/(float) b[1], 1.0f/(float) c[2], 0.0f); + periodicBoxSizeDouble = mm_double4(a[0], b[1], c[2], 0.0); + invPeriodicBoxSizeDouble = mm_double4(1.0/a[0], 1.0/b[1], 1.0/c[2], 0.0); + } /** * Get the size of the periodic box. */ @@ -490,15 +519,6 @@ public: mm_double4 getPeriodicBoxSizeDouble() const { return periodicBoxSizeDouble; } - /** - * Set the size of the periodic box. - */ - void setPeriodicBoxSize(double xsize, double ysize, double zsize) { - periodicBoxSize = mm_float4((float) xsize, (float) ysize, (float) zsize, 0); - invPeriodicBoxSize = mm_float4((float) (1.0/xsize), (float) (1.0/ysize), (float) (1.0/zsize), 0); - periodicBoxSizeDouble = mm_double4(xsize, ysize, zsize, 0); - invPeriodicBoxSizeDouble = mm_double4(1.0/xsize, 1.0/ysize, 1.0/zsize, 0); - } /** * Get the inverse of the size of the periodic box. */ @@ -511,6 +531,42 @@ public: mm_double4 getInvPeriodicBoxSizeDouble() const { return invPeriodicBoxSizeDouble; } + /** + * Get the first periodic box vector. + */ + mm_float4 getPeriodicBoxVecX() { + return periodicBoxVecX; + } + /** + * Get the first periodic box vector. + */ + mm_double4 getPeriodicBoxVecXDouble() { + return periodicBoxVecXDouble; + } + /** + * Get the second periodic box vector. + */ + mm_float4 getPeriodicBoxVecY() { + return periodicBoxVecY; + } + /** + * Get the second periodic box vector. + */ + mm_double4 getPeriodicBoxVecYDouble() { + return periodicBoxVecYDouble; + } + /** + * Get the third periodic box vector. + */ + mm_float4 getPeriodicBoxVecZ() { + return periodicBoxVecZ; + } + /** + * Get the third periodic box vector. + */ + mm_double4 getPeriodicBoxVecZDouble() { + return periodicBoxVecZDouble; + } /** * Get the OpenCLIntegrationUtilities for this context. */ @@ -628,9 +684,9 @@ private: int numThreadBlocks; int numForceBuffers; int simdWidth; - bool supports64BitGlobalAtomics, supportsDoublePrecision, useDoublePrecision, useMixedPrecision, atomsWereReordered; - mm_float4 periodicBoxSize, invPeriodicBoxSize; - mm_double4 periodicBoxSizeDouble, invPeriodicBoxSizeDouble; + bool supports64BitGlobalAtomics, supportsDoublePrecision, useDoublePrecision, useMixedPrecision, atomsWereReordered, boxIsTriclinic; + mm_float4 periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ; + mm_double4 periodicBoxSizeDouble, invPeriodicBoxSizeDouble, periodicBoxVecXDouble, periodicBoxVecYDouble, periodicBoxVecZDouble; std::string defaultOptimizationOptions; std::map compilationDefines; cl::Context context; diff --git a/platforms/opencl/src/OpenCLContext.cpp b/platforms/opencl/src/OpenCLContext.cpp index 50d380c4c..34616289b 100644 --- a/platforms/opencl/src/OpenCLContext.cpp +++ b/platforms/opencl/src/OpenCLContext.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2013 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -336,6 +336,54 @@ OpenCLContext::OpenCLContext(const System& system, int platformIndex, int device compilationDefines["LOG"] = "log"; } + // Set defines for applying periodic boundary conditions. + + Vec3 boxVectors[3]; + system.getDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); + boxIsTriclinic = (boxVectors[0][1] != 0.0 || boxVectors[0][2] != 0.0 || + boxVectors[1][0] != 0.0 || boxVectors[1][2] != 0.0 || + boxVectors[2][0] != 0.0 || boxVectors[2][1] != 0.0); + if (boxIsTriclinic) { + compilationDefines["APPLY_PERIODIC_TO_DELTA(delta)"] = + "{" + "real scale3 = floor(delta.z*invPeriodicBoxSize.z+0.5f); \\\n" + "delta.xyz -= scale3*periodicBoxVecZ.xyz; \\\n" + "real scale2 = floor(delta.y*invPeriodicBoxSize.y+0.5f); \\\n" + "delta.xy -= scale2*periodicBoxVecY.xy; \\\n" + "real scale1 = floor(delta.x*invPeriodicBoxSize.x+0.5f); \\\n" + "delta.x -= scale1*periodicBoxVecX.x;}"; + compilationDefines["APPLY_PERIODIC_TO_POS(pos)"] = + "{" + "real scale3 = floor(pos.z*invPeriodicBoxSize.z); \\\n" + "pos.xyz -= scale3*periodicBoxVecZ.xyz; \\\n" + "real scale2 = floor(pos.y*invPeriodicBoxSize.y); \\\n" + "pos.xy -= scale2*periodicBoxVecY.xy; \\\n" + "real scale1 = floor(pos.x*invPeriodicBoxSize.x); \\\n" + "pos.x -= scale1*periodicBoxVecX.x;}"; + compilationDefines["APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center)"] = + "{" + "real scale3 = floor((pos.z-center.z)*invPeriodicBoxSize.z+0.5f); \\\n" + "pos.x -= scale3*periodicBoxVecZ.x; \\\n" + "pos.y -= scale3*periodicBoxVecZ.y; \\\n" + "pos.z -= scale3*periodicBoxVecZ.z; \\\n" + "real scale2 = floor((pos.y-center.y)*invPeriodicBoxSize.y+0.5f); \\\n" + "pos.x -= scale2*periodicBoxVecY.x; \\\n" + "pos.y -= scale2*periodicBoxVecY.y; \\\n" + "real scale1 = floor((pos.x-center.x)*invPeriodicBoxSize.x+0.5f); \\\n" + "pos.x -= scale1*periodicBoxVecX.x;}"; + } + else { + compilationDefines["APPLY_PERIODIC_TO_DELTA(delta)"] = + "delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz;"; + compilationDefines["APPLY_PERIODIC_TO_POS(pos)"] = + "pos.xyz -= floor(pos.xyz*invPeriodicBoxSize.xyz)*periodicBoxSize.xyz;"; + compilationDefines["APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center)"] = + "{" + "pos.x -= floor((pos.x-center.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; \\\n" + "pos.y -= floor((pos.y-center.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; \\\n" + "pos.z -= floor((pos.z-center.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z;}"; + } + // Create the work thread used for parallelization when running on multiple devices. thread = new WorkThread(); @@ -527,7 +575,7 @@ void OpenCLContext::restoreDefaultQueue() { currentQueue = defaultQueue; } -string OpenCLContext::doubleToString(double value) { +string OpenCLContext::doubleToString(double value) const { stringstream s; s.precision(useDoublePrecision ? 16 : 8); s << scientific << value; @@ -536,7 +584,7 @@ string OpenCLContext::doubleToString(double value) { return s.str(); } -string OpenCLContext::intToString(int value) { +string OpenCLContext::intToString(int value) const { stringstream s; s << value; return s.str(); diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 861611467..40177c220 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2014 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -77,6 +77,19 @@ static void setInvPeriodicBoxSizeArg(OpenCLContext& cl, cl::Kernel& kernel, int kernel.setArg(index, cl.getInvPeriodicBoxSize()); } +static void setPeriodicBoxVecArgs(OpenCLContext& cl, cl::Kernel& kernel, int index) { + if (cl.getUseDoublePrecision()) { + kernel.setArg(index++, cl.getPeriodicBoxVecXDouble()); + kernel.setArg(index++, cl.getPeriodicBoxVecYDouble()); + kernel.setArg(index, cl.getPeriodicBoxVecZDouble()); + } + else { + kernel.setArg(index++, cl.getPeriodicBoxVecX()); + kernel.setArg(index++, cl.getPeriodicBoxVecY()); + kernel.setArg(index, cl.getPeriodicBoxVecZ()); + } +} + static bool isZeroExpression(const Lepton::ParsedExpression& expression) { const Lepton::Operation& op = expression.getRootNode().getOperation(); if (op.getId() != Lepton::Operation::CONSTANT) @@ -323,20 +336,17 @@ void OpenCLUpdateStateDataKernel::getForces(ContextImpl& context, vector& } void OpenCLUpdateStateDataKernel::getPeriodicBoxVectors(ContextImpl& context, Vec3& a, Vec3& b, Vec3& c) const { - mm_double4 box = cl.getPeriodicBoxSizeDouble(); - a = Vec3(box.x, 0, 0); - b = Vec3(0, box.y, 0); - c = Vec3(0, 0, box.z); + cl.getPeriodicBoxVectors(a, b, c); } void OpenCLUpdateStateDataKernel::setPeriodicBoxVectors(ContextImpl& context, const Vec3& a, const Vec3& b, const Vec3& c) const { vector& contexts = cl.getPlatformData().contexts; for (int i = 0; i < (int) contexts.size(); i++) - contexts[i]->setPeriodicBoxSize(a[0], b[1], c[2]); + contexts[i]->setPeriodicBoxVectors(a, b, c); } void OpenCLUpdateStateDataKernel::createCheckpoint(ContextImpl& context, ostream& stream) { - int version = 1; + int version = 2; stream.write((char*) &version, sizeof(int)); int precision = (cl.getUseDoublePrecision() ? 2 : cl.getUseMixedPrecision() ? 1 : 0); stream.write((char*) &precision, sizeof(int)); @@ -357,8 +367,9 @@ void OpenCLUpdateStateDataKernel::createCheckpoint(ContextImpl& context, ostream stream.write(buffer, cl.getVelm().getSize()*cl.getVelm().getElementSize()); stream.write((char*) &cl.getAtomIndex()[0], sizeof(cl_int)*cl.getAtomIndex().size()); stream.write((char*) &cl.getPosCellOffsets()[0], sizeof(mm_int4)*cl.getPosCellOffsets().size()); - mm_float4 box = cl.getPeriodicBoxSize(); - stream.write((char*) &box, sizeof(mm_float4)); + Vec3 boxVectors[3]; + cl.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); + stream.write((char*) boxVectors, 3*sizeof(Vec3)); cl.getIntegrationUtilities().createCheckpoint(stream); SimTKOpenMMUtilities::createCheckpoint(stream); } @@ -366,7 +377,7 @@ void OpenCLUpdateStateDataKernel::createCheckpoint(ContextImpl& context, ostream void OpenCLUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& stream) { int version; stream.read((char*) &version, sizeof(int)); - if (version != 1) + if (version != 2) throw OpenMMException("Checkpoint was created with a different version of OpenMM"); int precision; stream.read((char*) &precision, sizeof(int)); @@ -396,10 +407,10 @@ void OpenCLUpdateStateDataKernel::loadCheckpoint(ContextImpl& context, istream& stream.read((char*) &cl.getAtomIndex()[0], sizeof(cl_int)*cl.getAtomIndex().size()); cl.getAtomIndexArray().upload(cl.getAtomIndex()); stream.read((char*) &cl.getPosCellOffsets()[0], sizeof(mm_int4)*cl.getPosCellOffsets().size()); - mm_float4 box; - stream.read((char*) &box, sizeof(mm_float4)); + Vec3 boxVectors[3]; + stream.read((char*) &boxVectors, 3*sizeof(Vec3)); for (int i = 0; i < (int) contexts.size(); i++) - contexts[i]->setPeriodicBoxSize(box.x, box.y, box.z); + contexts[i]->setPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); cl.getIntegrationUtilities().loadCheckpoint(stream); SimTKOpenMMUtilities::loadCheckpoint(stream); for (int i = 0; i < (int) cl.getReorderListeners().size(); i++) @@ -6636,9 +6647,9 @@ void OpenCLApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context, // Initialize the kernel arguments. kernel.setArg(3, numMolecules); - kernel.setArg(6, cl.getPosq().getDeviceBuffer()); - kernel.setArg(7, moleculeAtoms->getDeviceBuffer()); - kernel.setArg(8, moleculeStartIndex->getDeviceBuffer()); + kernel.setArg(9, cl.getPosq().getDeviceBuffer()); + kernel.setArg(10, moleculeAtoms->getDeviceBuffer()); + kernel.setArg(11, moleculeStartIndex->getDeviceBuffer()); } int bytesToCopy = cl.getPosq().getSize()*(cl.getUseDoublePrecision() ? sizeof(mm_double4) : sizeof(mm_float4)); cl.getQueue().enqueueCopyBuffer(cl.getPosq().getDeviceBuffer(), savedPositions->getDeviceBuffer(), 0, 0, bytesToCopy); @@ -6647,6 +6658,7 @@ void OpenCLApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context, kernel.setArg(2, (cl_float) scaleZ); setPeriodicBoxSizeArg(cl, kernel, 4); setInvPeriodicBoxSizeArg(cl, kernel, 5); + setPeriodicBoxVecArgs(cl, kernel, 6); cl.executeKernel(kernel, cl.getNumAtoms()); for (int i = 0; i < (int) cl.getPosCellOffsets().size(); i++) cl.getPosCellOffsets()[i] = mm_int4(0, 0, 0, 0); diff --git a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp index 1073ab3ee..643298cc2 100644 --- a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp +++ b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2013 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -325,11 +325,11 @@ void OpenCLNonbondedUtilities::initialize(const System& system) { cl::Program interactingBlocksProgram = context.createProgram(file, defines); findBlockBoundsKernel = cl::Kernel(interactingBlocksProgram, "findBlockBounds"); findBlockBoundsKernel.setArg(0, context.getNumAtoms()); - findBlockBoundsKernel.setArg(3, context.getPosq().getDeviceBuffer()); - findBlockBoundsKernel.setArg(4, blockCenter->getDeviceBuffer()); - findBlockBoundsKernel.setArg(5, blockBoundingBox->getDeviceBuffer()); - findBlockBoundsKernel.setArg(6, rebuildNeighborList->getDeviceBuffer()); - findBlockBoundsKernel.setArg(7, sortedBlocks->getDeviceBuffer()); + findBlockBoundsKernel.setArg(6, context.getPosq().getDeviceBuffer()); + findBlockBoundsKernel.setArg(7, blockCenter->getDeviceBuffer()); + findBlockBoundsKernel.setArg(8, blockBoundingBox->getDeviceBuffer()); + findBlockBoundsKernel.setArg(9, rebuildNeighborList->getDeviceBuffer()); + findBlockBoundsKernel.setArg(10, sortedBlocks->getDeviceBuffer()); sortBoxDataKernel = cl::Kernel(interactingBlocksProgram, "sortBoxData"); sortBoxDataKernel.setArg(0, sortedBlocks->getDeviceBuffer()); sortBoxDataKernel.setArg(1, blockCenter->getDeviceBuffer()); @@ -341,20 +341,20 @@ void OpenCLNonbondedUtilities::initialize(const System& system) { sortBoxDataKernel.setArg(7, interactionCount->getDeviceBuffer()); sortBoxDataKernel.setArg(8, rebuildNeighborList->getDeviceBuffer()); findInteractingBlocksKernel = cl::Kernel(interactingBlocksProgram, "findBlocksWithInteractions"); - findInteractingBlocksKernel.setArg(2, interactionCount->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(3, interactingTiles->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(4, interactingAtoms->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(5, context.getPosq().getDeviceBuffer()); - findInteractingBlocksKernel.setArg(6, interactingTiles->getSize()); - findInteractingBlocksKernel.setArg(7, startBlockIndex); - findInteractingBlocksKernel.setArg(8, numBlocks); - findInteractingBlocksKernel.setArg(9, sortedBlocks->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(10, sortedBlockCenter->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(11, sortedBlockBoundingBox->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(12, exclusionIndices->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(13, exclusionRowIndices->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(14, oldPositions->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(15, rebuildNeighborList->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(5, interactionCount->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(6, interactingTiles->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(7, interactingAtoms->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(8, context.getPosq().getDeviceBuffer()); + findInteractingBlocksKernel.setArg(9, interactingTiles->getSize()); + findInteractingBlocksKernel.setArg(10, startBlockIndex); + findInteractingBlocksKernel.setArg(11, numBlocks); + findInteractingBlocksKernel.setArg(12, sortedBlocks->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(13, sortedBlockCenter->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(14, sortedBlockBoundingBox->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(15, exclusionIndices->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(16, exclusionRowIndices->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(17, oldPositions->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(18, rebuildNeighborList->getDeviceBuffer()); if (findInteractingBlocksKernel.getWorkGroupInfo(context.getDevice()) < groupSize) { // The device can't handle this block size, so reduce it. @@ -369,18 +369,21 @@ void OpenCLNonbondedUtilities::initialize(const System& system) { } } -static void setPeriodicBoxSizeArg(OpenCLContext& cl, cl::Kernel& kernel, int index) { - if (cl.getUseDoublePrecision()) - kernel.setArg(index, cl.getPeriodicBoxSizeDouble()); - else - kernel.setArg(index, cl.getPeriodicBoxSize()); -} - -static void setInvPeriodicBoxSizeArg(OpenCLContext& cl, cl::Kernel& kernel, int index) { - if (cl.getUseDoublePrecision()) - kernel.setArg(index, cl.getInvPeriodicBoxSizeDouble()); - else - kernel.setArg(index, cl.getInvPeriodicBoxSize()); +static void setPeriodicBoxArgs(OpenCLContext& cl, cl::Kernel& kernel, int index) { + if (cl.getUseDoublePrecision()) { + kernel.setArg(index++, cl.getPeriodicBoxSizeDouble()); + kernel.setArg(index++, cl.getInvPeriodicBoxSizeDouble()); + kernel.setArg(index++, cl.getPeriodicBoxVecXDouble()); + kernel.setArg(index++, cl.getPeriodicBoxVecYDouble()); + kernel.setArg(index, cl.getPeriodicBoxVecZDouble()); + } + else { + kernel.setArg(index++, cl.getPeriodicBoxSize()); + kernel.setArg(index++, cl.getInvPeriodicBoxSize()); + kernel.setArg(index++, cl.getPeriodicBoxVecX()); + kernel.setArg(index++, cl.getPeriodicBoxVecY()); + kernel.setArg(index, cl.getPeriodicBoxVecZ()); + } } void OpenCLNonbondedUtilities::prepareInteractions() { @@ -397,22 +400,18 @@ void OpenCLNonbondedUtilities::prepareInteractions() { // Compute the neighbor list. - setPeriodicBoxSizeArg(context, findBlockBoundsKernel, 1); - setInvPeriodicBoxSizeArg(context, findBlockBoundsKernel, 2); + setPeriodicBoxArgs(context, findBlockBoundsKernel, 1); context.executeKernel(findBlockBoundsKernel, context.getNumAtoms()); blockSorter->sort(*sortedBlocks); context.executeKernel(sortBoxDataKernel, context.getNumAtoms()); - setPeriodicBoxSizeArg(context, findInteractingBlocksKernel, 0); - setInvPeriodicBoxSizeArg(context, findInteractingBlocksKernel, 1); + setPeriodicBoxArgs(context, findInteractingBlocksKernel, 0); context.executeKernel(findInteractingBlocksKernel, context.getNumAtoms(), interactingBlocksThreadBlockSize); } void OpenCLNonbondedUtilities::computeInteractions() { if (kernelSource.size() > 0) { - if (useCutoff) { - setPeriodicBoxSizeArg(context, forceKernel, 9); - setInvPeriodicBoxSizeArg(context, forceKernel, 10); - } + if (useCutoff) + setPeriodicBoxArgs(context, forceKernel, 9); context.executeKernel(forceKernel, numForceThreadBlocks*forceThreadBlockSize, forceThreadBlockSize); if (context.getComputeForceCount() == 1) updateNeighborListSize(); // This is the first time step, so check whether our initial guess was large enough. @@ -441,11 +440,11 @@ void OpenCLNonbondedUtilities::updateNeighborListSize() { interactingTiles = OpenCLArray::create(context, maxTiles, "interactingTiles"); interactingAtoms = OpenCLArray::create(context, OpenCLContext::TileSize*maxTiles, "interactingAtoms"); forceKernel.setArg(7, interactingTiles->getDeviceBuffer()); - forceKernel.setArg(11, maxTiles); - forceKernel.setArg(14, interactingAtoms->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(3, interactingTiles->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(4, interactingAtoms->getDeviceBuffer()); - findInteractingBlocksKernel.setArg(6, maxTiles); + forceKernel.setArg(14, maxTiles); + forceKernel.setArg(17, interactingAtoms->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(6, interactingTiles->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(7, interactingAtoms->getDeviceBuffer()); + findInteractingBlocksKernel.setArg(9, maxTiles); int numAtoms = context.getNumAtoms(); if (context.getUseDoublePrecision()) { vector oldPositionsVec(numAtoms, mm_double4(1e30, 1e30, 1e30, 0)); @@ -473,8 +472,8 @@ void OpenCLNonbondedUtilities::setAtomBlockRange(double startFraction, double en forceKernel.setArg(5, startTileIndex); forceKernel.setArg(6, numTiles); - findInteractingBlocksKernel.setArg(7, startBlockIndex); - findInteractingBlocksKernel.setArg(8, numBlocks); + findInteractingBlocksKernel.setArg(10, startBlockIndex); + findInteractingBlocksKernel.setArg(11, numBlocks); } } @@ -617,7 +616,7 @@ cl::Kernel OpenCLNonbondedUtilities::createInteractionKernel(const string& sourc if (useCutoff) { kernel.setArg(index++, interactingTiles->getDeviceBuffer()); kernel.setArg(index++, interactionCount->getDeviceBuffer()); - index += 2; // The periodic box size arguments are set when the kernel is executed. + index += 5; // The periodic box size arguments are set when the kernel is executed. kernel.setArg(index++, interactingTiles->getSize()); kernel.setArg(index++, blockCenter->getDeviceBuffer()); kernel.setArg(index++, blockBoundingBox->getDeviceBuffer()); diff --git a/platforms/opencl/src/kernels/findInteractingBlocks.cl b/platforms/opencl/src/kernels/findInteractingBlocks.cl index 6a3c014f1..044db4d2f 100644 --- a/platforms/opencl/src/kernels/findInteractingBlocks.cl +++ b/platforms/opencl/src/kernels/findInteractingBlocks.cl @@ -5,15 +5,15 @@ /** * Find a bounding box for the atoms in each block. */ -__kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, __global const real4* restrict posq, - __global real4* restrict blockCenter, __global real4* restrict blockBoundingBox, __global int* restrict rebuildNeighborList, +__kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + __global const real4* restrict posq, __global real4* restrict blockCenter, __global real4* restrict blockBoundingBox, __global int* restrict rebuildNeighborList, __global real2* restrict sortedBlocks) { int index = get_global_id(0); int base = index*TILE_SIZE; while (base < numAtoms) { real4 pos = posq[base]; #ifdef USE_PERIODIC - pos.xyz -= floor(pos.xyz*invPeriodicBoxSize.xyz)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS(pos) #endif real4 minPos = pos; real4 maxPos = pos; @@ -22,7 +22,7 @@ __kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeri pos = posq[i]; #ifdef USE_PERIODIC real4 center = 0.5f*(maxPos+minPos); - pos.xyz -= floor((pos.xyz-center.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center) #endif minPos = min(minPos, pos); maxPos = max(maxPos, pos); @@ -65,9 +65,10 @@ __kernel void sortBoxData(__global const real2* restrict sortedBlock, __global c } } -__kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodicBoxSize, __global unsigned int* restrict interactionCount, - __global int* restrict interactingTiles, __global unsigned int* restrict interactingAtoms, __global const real4* restrict posq, unsigned int maxTiles, unsigned int startBlockIndex, - unsigned int numBlocks, __global real2* restrict sortedBlocks, __global const real4* restrict sortedBlockCenter, __global const real4* restrict sortedBlockBoundingBox, +__kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + __global unsigned int* restrict interactionCount, __global int* restrict interactingTiles, __global unsigned int* restrict interactingAtoms, + __global const real4* restrict posq, unsigned int maxTiles, unsigned int startBlockIndex, unsigned int numBlocks, __global real2* restrict sortedBlocks, + __global const real4* restrict sortedBlockCenter, __global const real4* restrict sortedBlockBoundingBox, __global const unsigned int* restrict exclusionIndices, __global const unsigned int* restrict exclusionRowIndices, __global real4* restrict oldPositions, __global const int* restrict rebuildNeighborList) { @@ -108,7 +109,7 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi // The box is small enough that we can just translate all the atoms into a single periodic // box, then skip having to apply periodic boundary conditions later. - pos1.xyz -= floor((pos1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos1, blockCenterX) } #endif posBuffer[get_local_id(0)] = pos1; @@ -136,7 +137,7 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi real4 blockSizeY = (block2 < NUM_BLOCKS ? sortedBlockBoundingBox[block2] : (real4) (0)); real4 blockDelta = blockCenterX-blockCenterY; #ifdef USE_PERIODIC - blockDelta.xyz -= floor(blockDelta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(blockDelta) #endif blockDelta.x = max((real) 0, fabs(blockDelta.x)-blockSizeX.x-blockSizeY.x); blockDelta.y = max((real) 0, fabs(blockDelta.y)-blockSizeX.y-blockSizeY.y); @@ -166,7 +167,7 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi real3 pos2 = posq[atom2].xyz; #ifdef USE_PERIODIC if (singlePeriodicCopy) - pos2.xyz -= floor((pos2.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos2, blockCenterX) #endif bool interacts = false; if (atom2 < NUM_ATOMS) { @@ -174,7 +175,7 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi if (!singlePeriodicCopy) { for (int j = 0; j < TILE_SIZE; j++) { real3 delta = pos2-posBuffer[warpStart+j]; - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) interacts |= (delta.x*delta.x+delta.y*delta.y+delta.z*delta.z < PADDED_CUTOFF_SQUARED); } } diff --git a/platforms/opencl/src/kernels/monteCarloBarostat.cl b/platforms/opencl/src/kernels/monteCarloBarostat.cl index 69c49a144..99aab72a7 100644 --- a/platforms/opencl/src/kernels/monteCarloBarostat.cl +++ b/platforms/opencl/src/kernels/monteCarloBarostat.cl @@ -2,7 +2,8 @@ * Scale the particle positions with each axis independent. */ -__kernel void scalePositions(float scaleX, float scaleY, float scaleZ, int numMolecules, real4 periodicBoxSize, real4 invPeriodicBoxSize, __global real4* restrict posq, +__kernel void scalePositions(float scaleX, float scaleY, float scaleZ, int numMolecules, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, __global real4* restrict posq, __global const int* restrict moleculeAtoms, __global const int* restrict moleculeStartIndex) { for (int index = get_global_id(0); index < numMolecules; index += get_global_size(0)) { int first = moleculeStartIndex[index]; @@ -11,19 +12,17 @@ __kernel void scalePositions(float scaleX, float scaleY, float scaleZ, int numMo // Find the center of each molecule. - real4 center = (real4) 0; + real3 center = (real3) 0; for (int atom = first; atom < last; atom++) - center += posq[moleculeAtoms[atom]]; + center += posq[moleculeAtoms[atom]].xyz; center /= (real) numAtoms; // Move it into the first periodic box. - int xcell = (int) floor(center.x*invPeriodicBoxSize.x); - int ycell = (int) floor(center.y*invPeriodicBoxSize.y); - int zcell = (int) floor(center.z*invPeriodicBoxSize.z); - real4 delta = (real4) (xcell*periodicBoxSize.x, ycell*periodicBoxSize.y, zcell*periodicBoxSize.z, 0); - real4 scaleXYZ = (real4) (scaleX, scaleY, scaleZ, 1); - center -= delta; + real3 oldCenter = center; + APPLY_PERIODIC_TO_POS(center) + real3 delta = oldCenter-center;; + real3 scaleXYZ = (real3) (scaleX, scaleY, scaleZ); // Now scale the position of the molecule center. diff --git a/platforms/opencl/src/kernels/nonbonded.cl b/platforms/opencl/src/kernels/nonbonded.cl index f000282b4..af242b48f 100644 --- a/platforms/opencl/src/kernels/nonbonded.cl +++ b/platforms/opencl/src/kernels/nonbonded.cl @@ -26,7 +26,8 @@ __kernel void computeNonbonded( __global const ushort2* restrict exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices #ifdef USE_CUTOFF , __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms #endif PARAMETER_ARGUMENTS) { const unsigned int totalWarps = get_global_size(0)/TILE_SIZE; @@ -67,7 +68,7 @@ __kernel void computeNonbonded( real4 posq2 = (real4) (localData[atom2].x, localData[atom2].y, localData[atom2].z, localData[atom2].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; real invR = RSQRT(r2); @@ -121,7 +122,7 @@ __kernel void computeNonbonded( real4 posq2 = (real4) (localData[atom2].x, localData[atom2].y, localData[atom2].z, localData[atom2].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef PRUNE_BY_CUTOFF @@ -289,10 +290,8 @@ __kernel void computeNonbonded( // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.xyz -= floor((posq1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; - localData[localAtomIndex].x -= floor((localData[localAtomIndex].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[localAtomIndex].y -= floor((localData[localAtomIndex].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[localAtomIndex].z -= floor((localData[localAtomIndex].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[localAtomIndex], blockCenterX) SYNC_WARPS; unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { @@ -349,7 +348,7 @@ __kernel void computeNonbonded( real4 posq2 = (real4) (localData[atom2].x, localData[atom2].y, localData[atom2].z, localData[atom2].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef PRUNE_BY_CUTOFF diff --git a/platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp b/platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp index d6fe7e68a..ed3ddc11d 100644 --- a/platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp +++ b/platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp @@ -7,7 +7,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2014 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -261,6 +261,65 @@ void testPeriodic() { ASSERT_EQUAL_TOL(1.9+1+0.9, state.getPotentialEnergy(), TOL); } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + CustomNonbondedForce* nonbonded = new CustomNonbondedForce("r"); + nonbonded->addParticle(vector()); + nonbonded->addParticle(vector()); + nonbonded->setNonbondedMethod(CustomNonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta/sqrt(delta.dot(delta)); + ASSERT_EQUAL_TOL(distance, state.getPotentialEnergy(), TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} + void testContinuous1DFunction() { System system; system.addParticle(1.0); @@ -924,6 +983,7 @@ int main(int argc, char* argv[]) { testExclusions(); testCutoff(); testPeriodic(); + testTriclinic(); testContinuous1DFunction(); testContinuous2DFunction(); testContinuous3DFunction(); diff --git a/platforms/opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp b/platforms/opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp index f1e2294e3..93da2412a 100644 --- a/platforms/opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp +++ b/platforms/opencl/tests/TestOpenCLMonteCarloAnisotropicBarostat.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman, Lee-Ping Wang * * Contributors: * * * @@ -236,6 +236,82 @@ void testRandomSeed() { } } +void testTriclinic() { + const int numParticles = 64; + const int frequency = 10; + const int steps = 1000; + const double pressure = 1.5; + const double pressureInMD = pressure*(AVOGADRO*1e-25); // pressure in kJ/mol/nm^3 + const double temperature = 300.0; + const double initialVolume = numParticles*BOLTZ*temperature/pressureInMD; + const double initialLength = std::pow(initialVolume, 1.0/3.0); + + // Create a gas of noninteracting particles. + + System system; + Vec3 initialBox[3]; + initialBox[0] = Vec3(initialLength, 0, 0); + initialBox[1] = Vec3(0.2*initialLength, initialLength, 0); + initialBox[2] = Vec3(0.1*initialLength, 0.3*initialLength, initialLength); + system.setDefaultPeriodicBoxVectors(initialBox[0], initialBox[1], initialBox[2]); + vector positions(numParticles); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int i = 0; i < numParticles; ++i) { + system.addParticle(1.0); + positions[i] = Vec3(initialLength*genrand_real2(sfmt), initialLength*genrand_real2(sfmt), initialLength*genrand_real2(sfmt)); + } + MonteCarloAnisotropicBarostat* barostat = new MonteCarloAnisotropicBarostat(Vec3(pressure, pressure, pressure), temperature, true, true, true, frequency); + system.addForce(barostat); + + // Run a simulation + + LangevinIntegrator integrator(temperature, 0.1, 0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + + // Let it equilibrate. + + integrator.step(10000); + + // Now run it for a while and see if the volume is correct. + + double volume = 0.0; + for (int j = 0; j < steps; ++j) { + Vec3 box[3]; + context.getState(0).getPeriodicBoxVectors(box[0], box[1], box[2]); + volume += box[0][0]*box[1][1]*box[2][2]; + integrator.step(frequency); + } + volume /= steps; + double expected = (numParticles+1)*BOLTZ*temperature/pressureInMD; + ASSERT_USUALLY_EQUAL_TOL(expected, volume, 3/std::sqrt((double) steps)); + + // Make sure the box vectors have been scaled consistently. + + State state = context.getState(State::Positions); + Vec3 box[3]; + state.getPeriodicBoxVectors(box[0], box[1], box[2]); + double xscale = box[2][0]/(0.1*initialLength); + double yscale = box[2][1]/(0.3*initialLength); + double zscale = box[2][2]/(1.0*initialLength); + for (int i = 0; i < 3; i++) { + ASSERT_EQUAL_VEC(Vec3(xscale*initialBox[i][0], yscale*initialBox[i][1], zscale*initialBox[i][2]), box[i], 1e-5); + } + + // The barostat should have put all particles inside the first periodic box. One integration step + // has happened since then, so they may have moved slightly outside it. + + for (int i = 0; i < numParticles; i++) { + Vec3 pos = state.getPositions()[i]; + ASSERT(pos[2]/box[2][2] > -1 && pos[2]/box[2][2] < 2); + pos -= box[2]*floor(pos[2]/box[2][2]); + ASSERT(pos[1]/box[1][1] > -1 && pos[1]/box[1][1] < 2); + pos -= box[1]*floor(pos[1]/box[1][1]); + ASSERT(pos[0]/box[0][0] > -1 && pos[0]/box[0][0] < 2); + } +} + /** * Run a constant pressure simulation on an anisotropic Einstein crystal * using isotropic and anisotropic barostats. There are a total of 15 simulations: @@ -389,6 +465,7 @@ int main(int argc, char* argv[]) { testIdealGasAxis(1); testIdealGasAxis(2); testRandomSeed(); + testTriclinic(); //testEinsteinCrystal(); } catch(const exception& e) { diff --git a/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp b/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp index 77878d55f..c336e7d6a 100644 --- a/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp +++ b/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -355,6 +355,67 @@ void testPeriodic() { ASSERT_EQUAL_TOL(2*ONE_4PI_EPS0*(1.0)*(1.0+krf*1.0-crf), state.getPotentialEnergy(), TOL); } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + VerletIntegrator integrator(0.01); + NonbondedForce* nonbonded = new NonbondedForce(); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->addParticle(1.0, 1, 0); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); + const double cutoff = 1.5; + nonbonded->setCutoffDistance(cutoff); + system.addForce(nonbonded); + Context context(system, integrator, platform); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + const double eps = 78.3; + const double krf = (1.0/(cutoff*cutoff*cutoff))*(eps-1.0)/(2.0*eps+1.0); + const double crf = (1.0/cutoff)*(3.0*eps)/(2.0*eps+1.0); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the force and energy are correct. + + State state = context.getState(State::Forces | State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[0], 0); + ASSERT_EQUAL_VEC(Vec3(0, 0, 0), state.getForces()[1], 0); + } + else { + const Vec3 force = delta*ONE_4PI_EPS0*(-1.0/(distance*distance*distance)+2.0*krf); + ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(1.0/distance+krf*distance*distance-crf), state.getPotentialEnergy(), TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + } + } +} void testLargeSystem() { const int numMolecules = 600; @@ -875,6 +936,7 @@ int main(int argc, char* argv[]) { testCutoff(); testCutoff14(); testPeriodic(); + testTriclinic(); testLargeSystem(); // testBlockInteractions(false); // testBlockInteractions(true); -- GitLab From 9bcba51e531409c5452344776ebe1b112939b121 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 7 Jan 2015 14:47:52 -0800 Subject: [PATCH 194/338] Continuing OpenCL support for triclinic boxes --- platforms/opencl/src/OpenCLKernels.cpp | 92 +++++++++---------- .../opencl/src/kernels/customGBEnergyN2.cl | 17 ++-- .../src/kernels/customGBEnergyN2_cpu.cl | 13 +-- .../opencl/src/kernels/customGBValueN2.cl | 17 ++-- .../opencl/src/kernels/customGBValueN2_cpu.cl | 13 +-- .../opencl/src/kernels/customHbondForce.cl | 16 ++-- .../opencl/src/kernels/customManyParticle.cl | 30 +++--- .../src/kernels/customNonbondedGroups.cl | 6 +- platforms/opencl/src/kernels/gbsaObc.cl | 30 +++--- .../TestOpenCLCustomManyParticleForce.cpp | 76 +++++++++++---- 10 files changed, 169 insertions(+), 141 deletions(-) diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 40177c220..01f0da1c7 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -77,13 +77,17 @@ static void setInvPeriodicBoxSizeArg(OpenCLContext& cl, cl::Kernel& kernel, int kernel.setArg(index, cl.getInvPeriodicBoxSize()); } -static void setPeriodicBoxVecArgs(OpenCLContext& cl, cl::Kernel& kernel, int index) { +static void setPeriodicBoxArgs(OpenCLContext& cl, cl::Kernel& kernel, int index) { if (cl.getUseDoublePrecision()) { + kernel.setArg(index++, cl.getPeriodicBoxSizeDouble()); + kernel.setArg(index++, cl.getInvPeriodicBoxSizeDouble()); kernel.setArg(index++, cl.getPeriodicBoxVecXDouble()); kernel.setArg(index++, cl.getPeriodicBoxVecYDouble()); kernel.setArg(index, cl.getPeriodicBoxVecZDouble()); } else { + kernel.setArg(index++, cl.getPeriodicBoxSize()); + kernel.setArg(index++, cl.getInvPeriodicBoxSize()); kernel.setArg(index++, cl.getPeriodicBoxVecX()); kernel.setArg(index++, cl.getPeriodicBoxVecY()); kernel.setArg(index, cl.getPeriodicBoxVecZ()); @@ -2400,8 +2404,8 @@ double OpenCLCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool interactionGroupKernel.setArg(index++, cl.getEnergyBuffer().getDeviceBuffer()); interactionGroupKernel.setArg(index++, cl.getPosq().getDeviceBuffer()); interactionGroupKernel.setArg(index++, interactionGroupData->getDeviceBuffer()); - setPeriodicBoxSizeArg(cl, interactionGroupKernel, index++); - setInvPeriodicBoxSizeArg(cl, interactionGroupKernel, index++); + setPeriodicBoxArgs(cl, interactionGroupKernel, index); + index += 5; for (int i = 0; i < (int) params->getBuffers().size(); i++) interactionGroupKernel.setArg(index++, params->getBuffers()[i].getMemory()); if (globals != NULL) @@ -2573,7 +2577,7 @@ double OpenCLCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeF if (nb.getUseCutoff()) { computeBornSumKernel.setArg(index++, nb.getInteractingTiles().getDeviceBuffer()); computeBornSumKernel.setArg(index++, nb.getInteractionCount().getDeviceBuffer()); - index += 2; // The periodic box size arguments are set when the kernel is executed. + index += 5; // The periodic box size arguments are set when the kernel is executed. computeBornSumKernel.setArg(index++, maxTiles); computeBornSumKernel.setArg(index++, nb.getBlockCenters().getDeviceBuffer()); computeBornSumKernel.setArg(index++, nb.getBlockBoundingBoxes().getDeviceBuffer()); @@ -2592,7 +2596,7 @@ double OpenCLCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeF if (nb.getUseCutoff()) { force1Kernel.setArg(index++, nb.getInteractingTiles().getDeviceBuffer()); force1Kernel.setArg(index++, nb.getInteractionCount().getDeviceBuffer()); - index += 2; // The periodic box size arguments are set when the kernel is executed. + index += 5; // The periodic box size arguments are set when the kernel is executed. force1Kernel.setArg(index++, maxTiles); force1Kernel.setArg(index++, nb.getBlockCenters().getDeviceBuffer()); force1Kernel.setArg(index++, nb.getBlockBoundingBoxes().getDeviceBuffer()); @@ -2625,18 +2629,16 @@ double OpenCLCalcGBSAOBCForceKernel::execute(ContextImpl& context, bool includeF reduceBornForceKernel.setArg(index++, obcChain->getDeviceBuffer()); } if (nb.getUseCutoff()) { - setPeriodicBoxSizeArg(cl, computeBornSumKernel, 5); - setInvPeriodicBoxSizeArg(cl, computeBornSumKernel, 6); - setPeriodicBoxSizeArg(cl, force1Kernel, 7); - setInvPeriodicBoxSizeArg(cl, force1Kernel, 8); + setPeriodicBoxArgs(cl, computeBornSumKernel, 5); + setPeriodicBoxArgs(cl, force1Kernel, 7); if (maxTiles < nb.getInteractingTiles().getSize()) { maxTiles = nb.getInteractingTiles().getSize(); computeBornSumKernel.setArg(3, nb.getInteractingTiles().getDeviceBuffer()); - computeBornSumKernel.setArg(7, maxTiles); - computeBornSumKernel.setArg(10, nb.getInteractingAtoms().getDeviceBuffer()); + computeBornSumKernel.setArg(10, maxTiles); + computeBornSumKernel.setArg(13, nb.getInteractingAtoms().getDeviceBuffer()); force1Kernel.setArg(5, nb.getInteractingTiles().getDeviceBuffer()); - force1Kernel.setArg(9, maxTiles); - force1Kernel.setArg(12, nb.getInteractingAtoms().getDeviceBuffer()); + force1Kernel.setArg(12, maxTiles); + force1Kernel.setArg(15, nb.getInteractingAtoms().getDeviceBuffer()); } } cl.executeKernel(computeBornSumKernel, nb.getNumForceThreadBlocks()*nb.getForceThreadBlockSize(), nb.getForceThreadBlockSize()); @@ -3450,7 +3452,7 @@ double OpenCLCalcCustomGBForceKernel::execute(ContextImpl& context, bool include if (nb.getUseCutoff()) { pairValueKernel.setArg(index++, nb.getInteractingTiles().getDeviceBuffer()); pairValueKernel.setArg(index++, nb.getInteractionCount().getDeviceBuffer()); - index += 2; // Periodic box size arguments are set when the kernel is executed. + index += 5; // Periodic box size arguments are set when the kernel is executed. pairValueKernel.setArg(index++, maxTiles); pairValueKernel.setArg(index++, nb.getBlockCenters().getDeviceBuffer()); pairValueKernel.setArg(index++, nb.getBlockBoundingBoxes().getDeviceBuffer()); @@ -3493,7 +3495,7 @@ double OpenCLCalcCustomGBForceKernel::execute(ContextImpl& context, bool include if (nb.getUseCutoff()) { pairEnergyKernel.setArg(index++, nb.getInteractingTiles().getDeviceBuffer()); pairEnergyKernel.setArg(index++, nb.getInteractionCount().getDeviceBuffer()); - index += 2; // Periodic box size arguments are set when the kernel is executed. + index += 5; // Periodic box size arguments are set when the kernel is executed. pairEnergyKernel.setArg(index++, maxTiles); pairEnergyKernel.setArg(index++, nb.getBlockCenters().getDeviceBuffer()); pairEnergyKernel.setArg(index++, nb.getBlockBoundingBoxes().getDeviceBuffer()); @@ -3577,18 +3579,16 @@ double OpenCLCalcCustomGBForceKernel::execute(ContextImpl& context, bool include globals->upload(globalParamValues); } if (nb.getUseCutoff()) { - setPeriodicBoxSizeArg(cl, pairValueKernel, 8); - setInvPeriodicBoxSizeArg(cl, pairValueKernel, 9); - setPeriodicBoxSizeArg(cl, pairEnergyKernel, 9); - setInvPeriodicBoxSizeArg(cl, pairEnergyKernel, 10); + setPeriodicBoxArgs(cl, pairValueKernel, 8); + setPeriodicBoxArgs(cl, pairEnergyKernel, 9); if (maxTiles < nb.getInteractingTiles().getSize()) { maxTiles = nb.getInteractingTiles().getSize(); pairValueKernel.setArg(6, nb.getInteractingTiles().getDeviceBuffer()); - pairValueKernel.setArg(10, maxTiles); - pairValueKernel.setArg(13, nb.getInteractingAtoms().getDeviceBuffer()); + pairValueKernel.setArg(13, maxTiles); + pairValueKernel.setArg(16, nb.getInteractingAtoms().getDeviceBuffer()); pairEnergyKernel.setArg(7, nb.getInteractingTiles().getDeviceBuffer()); - pairEnergyKernel.setArg(11, maxTiles); - pairEnergyKernel.setArg(14, nb.getInteractingAtoms().getDeviceBuffer()); + pairEnergyKernel.setArg(14, maxTiles); + pairEnergyKernel.setArg(17, nb.getInteractingAtoms().getDeviceBuffer()); } } cl.executeKernel(pairValueKernel, nb.getNumForceThreadBlocks()*nb.getForceThreadBlockSize(), nb.getForceThreadBlockSize()); @@ -4226,7 +4226,7 @@ double OpenCLCalcCustomHbondForceKernel::execute(ContextImpl& context, bool incl donorKernel.setArg(index++, acceptors->getDeviceBuffer()); donorKernel.setArg(index++, donorBufferIndices->getDeviceBuffer()); donorKernel.setArg(index++, 3*OpenCLContext::ThreadBlockSize*sizeof(mm_float4), NULL); - index += 2; // Periodic box size arguments are set when the kernel is executed. + index += 5; // Periodic box size arguments are set when the kernel is executed. if (globals != NULL) donorKernel.setArg(index++, globals->getDeviceBuffer()); for (int i = 0; i < (int) donorParams->getBuffers().size(); i++) { @@ -4248,7 +4248,7 @@ double OpenCLCalcCustomHbondForceKernel::execute(ContextImpl& context, bool incl acceptorKernel.setArg(index++, acceptors->getDeviceBuffer()); acceptorKernel.setArg(index++, acceptorBufferIndices->getDeviceBuffer()); acceptorKernel.setArg(index++, 3*OpenCLContext::ThreadBlockSize*sizeof(mm_float4), NULL); - index += 2; // Periodic box size arguments are set when the kernel is executed. + index += 5; // Periodic box size arguments are set when the kernel is executed. if (globals != NULL) acceptorKernel.setArg(index++, globals->getDeviceBuffer()); for (int i = 0; i < (int) donorParams->getBuffers().size(); i++) { @@ -4262,11 +4262,9 @@ double OpenCLCalcCustomHbondForceKernel::execute(ContextImpl& context, bool incl for (int i = 0; i < (int) tabulatedFunctions.size(); i++) acceptorKernel.setArg(index++, tabulatedFunctions[i]->getDeviceBuffer()); } - setPeriodicBoxSizeArg(cl, donorKernel, 8); - setInvPeriodicBoxSizeArg(cl, donorKernel, 9); + setPeriodicBoxArgs(cl, donorKernel, 8); cl.executeKernel(donorKernel, max(numDonors, numAcceptors)); - setPeriodicBoxSizeArg(cl, acceptorKernel, 8); - setInvPeriodicBoxSizeArg(cl, acceptorKernel, 9); + setPeriodicBoxArgs(cl, acceptorKernel, 8); cl.executeKernel(acceptorKernel, max(numDonors, numAcceptors)); return 0.0; } @@ -4853,7 +4851,7 @@ void OpenCLCalcCustomManyParticleForceKernel::initialize(const System& system, c const vector& atoms = iter->second; string deltaName = atomNames[atoms[0]]+atomNames[atoms[1]]; if (computedDeltas.count(deltaName) == 0) { - compute<<"real4 delta"<(index++, cl.getLongForceBuffer().getDeviceBuffer()); forceKernel.setArg(index++, cl.getEnergyBuffer().getDeviceBuffer()); forceKernel.setArg(index++, cl.getPosq().getDeviceBuffer()); - setPeriodicBoxSizeArg(cl, forceKernel, index++); - setInvPeriodicBoxSizeArg(cl, forceKernel, index++); + setPeriodicBoxArgs(cl, forceKernel, index); + index += 5; if (nonbondedMethod != NoCutoff) { forceKernel.setArg(index++, neighbors->getDeviceBuffer()); forceKernel.setArg(index++, neighborStartIndex->getDeviceBuffer()); @@ -5167,8 +5165,8 @@ double OpenCLCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bo // Set arguments for the block bounds kernel. index = 0; - setPeriodicBoxSizeArg(cl, blockBoundsKernel, index++); - setInvPeriodicBoxSizeArg(cl, blockBoundsKernel, index++); + setPeriodicBoxArgs(cl, blockBoundsKernel, index); + index += 5; blockBoundsKernel.setArg(index++, cl.getPosq().getDeviceBuffer()); blockBoundsKernel.setArg(index++, blockCenter->getDeviceBuffer()); blockBoundsKernel.setArg(index++, blockBoundingBox->getDeviceBuffer()); @@ -5177,8 +5175,8 @@ double OpenCLCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bo // Set arguments for the neighbor list kernel. index = 0; - setPeriodicBoxSizeArg(cl, neighborsKernel, index++); - setInvPeriodicBoxSizeArg(cl, neighborsKernel, index++); + setPeriodicBoxArgs(cl, neighborsKernel, index); + index += 5; neighborsKernel.setArg(index++, cl.getPosq().getDeviceBuffer()); neighborsKernel.setArg(index++, blockCenter->getDeviceBuffer()); neighborsKernel.setArg(index++, blockBoundingBox->getDeviceBuffer()); @@ -5224,7 +5222,7 @@ double OpenCLCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bo int* numPairs = (int*) cl.getPinnedBuffer(); cl::Event event; if (nonbondedMethod != NoCutoff) { - neighborsKernel.setArg(8, maxNeighborPairs); + neighborsKernel.setArg(11, maxNeighborPairs); startIndicesKernel.setArg(3, maxNeighborPairs); copyPairsKernel.setArg(3, maxNeighborPairs); cl.executeKernel(blockBoundsKernel, cl.getNumAtomBlocks()); @@ -5254,8 +5252,8 @@ double OpenCLCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bo maxNeighborPairs = (int) (1.1*(*numPairs)); neighborPairs = OpenCLArray::create(cl, maxNeighborPairs, "customManyParticleNeighborPairs"); neighbors = OpenCLArray::create(cl, maxNeighborPairs, "customManyParticleNeighbors"); - forceKernel.setArg(5, neighbors->getDeviceBuffer()); - neighborsKernel.setArg(5, neighborPairs->getDeviceBuffer()); + forceKernel.setArg(8, neighbors->getDeviceBuffer()); + neighborsKernel.setArg(8, neighborPairs->getDeviceBuffer()); copyPairsKernel.setArg(0, neighborPairs->getDeviceBuffer()); copyPairsKernel.setArg(1, neighbors->getDeviceBuffer()); continue; @@ -6656,9 +6654,7 @@ void OpenCLApplyMonteCarloBarostatKernel::scaleCoordinates(ContextImpl& context, kernel.setArg(0, (cl_float) scaleX); kernel.setArg(1, (cl_float) scaleY); kernel.setArg(2, (cl_float) scaleZ); - setPeriodicBoxSizeArg(cl, kernel, 4); - setInvPeriodicBoxSizeArg(cl, kernel, 5); - setPeriodicBoxVecArgs(cl, kernel, 6); + setPeriodicBoxArgs(cl, kernel, 4); cl.executeKernel(kernel, cl.getNumAtoms()); for (int i = 0; i < (int) cl.getPosCellOffsets().size(); i++) cl.getPosCellOffsets()[i] = mm_int4(0, 0, 0, 0); diff --git a/platforms/opencl/src/kernels/customGBEnergyN2.cl b/platforms/opencl/src/kernels/customGBEnergyN2.cl index f25808b8f..4d99e9844 100644 --- a/platforms/opencl/src/kernels/customGBEnergyN2.cl +++ b/platforms/opencl/src/kernels/customGBEnergyN2.cl @@ -20,8 +20,9 @@ __kernel void computeN2Energy( __global const real4* restrict posq, __local real4* restrict local_posq, __global const unsigned int* restrict exclusions, __global const ushort2* exclusionTiles, #ifdef USE_CUTOFF - __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms + __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms #else unsigned int numTiles #endif @@ -60,7 +61,7 @@ __kernel void computeN2Energy( real4 posq2 = local_posq[atom2]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -110,7 +111,7 @@ __kernel void computeN2Energy( real4 posq2 = local_posq[atom2]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -266,10 +267,8 @@ __kernel void computeN2Energy( // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.xyz -= floor((posq1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; - local_posq[get_local_id(0)].x -= floor((local_posq[get_local_id(0)].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - local_posq[get_local_id(0)].y -= floor((local_posq[get_local_id(0)].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - local_posq[get_local_id(0)].z -= floor((local_posq[get_local_id(0)].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(local_posq[get_local_id(0)], blockCenterX) SYNC_WARPS; unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { @@ -310,7 +309,7 @@ __kernel void computeN2Energy( real4 posq2 = local_posq[atom2]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/opencl/src/kernels/customGBEnergyN2_cpu.cl b/platforms/opencl/src/kernels/customGBEnergyN2_cpu.cl index 4ce59157d..5823c746c 100644 --- a/platforms/opencl/src/kernels/customGBEnergyN2_cpu.cl +++ b/platforms/opencl/src/kernels/customGBEnergyN2_cpu.cl @@ -20,8 +20,9 @@ __kernel void computeN2Energy( __global const real4* restrict posq, __local real4* restrict local_posq, __global const unsigned int* restrict exclusions, __global const ushort2* exclusionTiles, #ifdef USE_CUTOFF - __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms + __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms #else unsigned int numTiles #endif @@ -60,7 +61,7 @@ __kernel void computeN2Energy( real4 posq2 = local_posq[j]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF @@ -126,7 +127,7 @@ __kernel void computeN2Energy( real4 posq2 = local_posq[j]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF @@ -272,7 +273,7 @@ __kernel void computeN2Energy( real4 blockCenterX = blockCenter[x]; for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) - local_posq[tgx].xyz -= floor((local_posq[tgx].xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(local_posq[tgx], blockCenterX) for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { unsigned int atom1 = x*TILE_SIZE+tgx; real4 force = 0; @@ -332,7 +333,7 @@ __kernel void computeN2Energy( real4 posq2 = local_posq[j]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF diff --git a/platforms/opencl/src/kernels/customGBValueN2.cl b/platforms/opencl/src/kernels/customGBValueN2.cl index 31cf4b209..90a1a4d05 100644 --- a/platforms/opencl/src/kernels/customGBValueN2.cl +++ b/platforms/opencl/src/kernels/customGBValueN2.cl @@ -14,8 +14,9 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* #endif __local real* restrict local_value, #ifdef USE_CUTOFF - __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms + __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms #else unsigned int numTiles #endif @@ -52,7 +53,7 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* real4 posq2 = local_posq[atom2]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -100,7 +101,7 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* real4 posq2 = local_posq[atom2]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -239,10 +240,8 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.xyz -= floor((posq1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; - local_posq[get_local_id(0)].x -= floor((local_posq[get_local_id(0)].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - local_posq[get_local_id(0)].y -= floor((local_posq[get_local_id(0)].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - local_posq[get_local_id(0)].z -= floor((local_posq[get_local_id(0)].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(local_posq[get_local_id(0)], blockCenterX) SYNC_WARPS; unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { @@ -278,7 +277,7 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* real4 posq2 = local_posq[atom2]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/opencl/src/kernels/customGBValueN2_cpu.cl b/platforms/opencl/src/kernels/customGBValueN2_cpu.cl index 855243c0e..9f84b665a 100644 --- a/platforms/opencl/src/kernels/customGBValueN2_cpu.cl +++ b/platforms/opencl/src/kernels/customGBValueN2_cpu.cl @@ -14,8 +14,9 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* #endif __local real* restrict local_value, #ifdef USE_CUTOFF - __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms + __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms #else unsigned int numTiles #endif @@ -52,7 +53,7 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* real4 posq2 = local_posq[j]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF @@ -109,7 +110,7 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* real4 posq2 = local_posq[j]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF @@ -239,7 +240,7 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* real4 blockCenterX = blockCenter[x]; for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) - local_posq[tgx].xyz -= floor((local_posq[tgx].xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(local_posq[tgx], blockCenterX) for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { unsigned int atom1 = x*TILE_SIZE+tgx; real value = 0; @@ -287,7 +288,7 @@ __kernel void computeN2Value(__global const real4* restrict posq, __local real4* real4 posq2 = local_posq[j]; real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF diff --git a/platforms/opencl/src/kernels/customHbondForce.cl b/platforms/opencl/src/kernels/customHbondForce.cl index c4c3ea4c3..f171d4195 100644 --- a/platforms/opencl/src/kernels/customHbondForce.cl +++ b/platforms/opencl/src/kernels/customHbondForce.cl @@ -11,12 +11,10 @@ real4 delta(real4 vec1, real4 vec2) { * Compute the difference between two vectors, taking periodic boundary conditions into account * and setting the fourth component to the squared magnitude. */ -real4 deltaPeriodic(real4 vec1, real4 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize) { +real4 deltaPeriodic(real4 vec1, real4 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ) { real4 result = (real4) (vec1.x-vec2.x, vec1.y-vec2.y, vec1.z-vec2.z, 0); #ifdef USE_PERIODIC - result.x -= floor(result.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - result.y -= floor(result.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - result.z -= floor(result.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(result) #endif result.w = result.x*result.x + result.y*result.y + result.z*result.z; return result; @@ -56,7 +54,8 @@ real4 computeCross(real4 vec1, real4 vec2) { * Compute forces on donors. */ __kernel void computeDonorForces(__global real4* restrict forceBuffers, __global real* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict exclusions, - __global const int4* restrict donorAtoms, __global const int4* restrict acceptorAtoms, __global const int4* restrict donorBufferIndices, __local real4* posBuffer, real4 periodicBoxSize, real4 invPeriodicBoxSize + __global const int4* restrict donorAtoms, __global const int4* restrict acceptorAtoms, __global const int4* restrict donorBufferIndices, __local real4* posBuffer, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ PARAMETER_ARGUMENTS) { real energy = 0; real4 f1 = (real4) 0; @@ -102,7 +101,7 @@ __kernel void computeDonorForces(__global real4* restrict forceBuffers, __global real4 a1 = posBuffer[3*index]; real4 a2 = posBuffer[3*index+1]; real4 a3 = posBuffer[3*index+2]; - real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize); + real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); #ifdef USE_CUTOFF if (deltaD1A1.w < CUTOFF_SQUARED) { #endif @@ -144,7 +143,8 @@ __kernel void computeDonorForces(__global real4* restrict forceBuffers, __global * Compute forces on acceptors. */ __kernel void computeAcceptorForces(__global real4* restrict forceBuffers, __global real* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict exclusions, - __global const int4* restrict donorAtoms, __global const int4* restrict acceptorAtoms, __global const int4* restrict acceptorBufferIndices, __local real4* restrict posBuffer, real4 periodicBoxSize, real4 invPeriodicBoxSize + __global const int4* restrict donorAtoms, __global const int4* restrict acceptorAtoms, __global const int4* restrict acceptorBufferIndices, __local real4* restrict posBuffer, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ PARAMETER_ARGUMENTS) { real4 f1 = (real4) 0; real4 f2 = (real4) 0; @@ -189,7 +189,7 @@ __kernel void computeAcceptorForces(__global real4* restrict forceBuffers, __glo real4 d1 = posBuffer[3*index]; real4 d2 = posBuffer[3*index+1]; real4 d3 = posBuffer[3*index+2]; - real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize); + real4 deltaD1A1 = deltaPeriodic(d1, a1, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); #ifdef USE_CUTOFF if (deltaD1A1.w < CUTOFF_SQUARED) { #endif diff --git a/platforms/opencl/src/kernels/customManyParticle.cl b/platforms/opencl/src/kernels/customManyParticle.cl index 034208cf4..2fe70612b 100644 --- a/platforms/opencl/src/kernels/customManyParticle.cl +++ b/platforms/opencl/src/kernels/customManyParticle.cl @@ -14,12 +14,10 @@ inline void storeForce(int atom, real4 force, __global long* restrict forceBuffe * Compute the difference between two vectors, taking periodic boundary conditions into account * and setting the fourth component to the squared magnitude. */ -inline real4 delta(real4 vec1, real4 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize) { +inline real4 delta(real4 vec1, real4 vec2, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ) { real4 result = (real4) (vec1.x-vec2.x, vec1.y-vec2.y, vec1.z-vec2.z, 0.0f); #ifdef USE_PERIODIC - result.x -= floor(result.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - result.y -= floor(result.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - result.z -= floor(result.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(result) #endif result.w = result.x*result.x + result.y*result.y + result.z*result.z; return result; @@ -75,7 +73,7 @@ inline bool isInteractionExcluded(int atom1, int atom2, __global int* restrict e */ __kernel void computeInteraction( __global long* restrict forceBuffers, __global real* restrict energyBuffer, __global const real4* restrict posq, - real4 periodicBoxSize, real4 invPeriodicBoxSize + real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ #ifdef USE_CUTOFF , __global const int* restrict neighbors, __global const int* restrict neighborStartIndex #endif @@ -138,16 +136,14 @@ __kernel void computeInteraction( /** * Find a bounding box for the atoms in each block. */ -__kernel void findBlockBounds(real4 periodicBoxSize, real4 invPeriodicBoxSize, __global const real4* restrict posq, - __global real4* restrict blockCenter, __global real4* restrict blockBoundingBox, __global int* restrict numNeighborPairs) { +__kernel void findBlockBounds(real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + __global const real4* restrict posq, __global real4* restrict blockCenter, __global real4* restrict blockBoundingBox, __global int* restrict numNeighborPairs) { int index = get_global_id(0); int base = index*TILE_SIZE; while (base < NUM_ATOMS) { real4 pos = posq[base]; #ifdef USE_PERIODIC - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS(pos) #endif real4 minPos = pos; real4 maxPos = pos; @@ -156,9 +152,7 @@ __kernel void findBlockBounds(real4 periodicBoxSize, real4 invPeriodicBoxSize, _ pos = posq[i]; #ifdef USE_PERIODIC real4 center = 0.5f*(maxPos+minPos); - pos.x -= floor((pos.x-center.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - pos.y -= floor((pos.y-center.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - pos.z -= floor((pos.z-center.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center) #endif minPos = (real4) (min(minPos.x,pos.x), min(minPos.y,pos.y), min(minPos.z,pos.z), 0); maxPos = (real4) (max(maxPos.x,pos.x), max(maxPos.y,pos.y), max(maxPos.z,pos.z), 0); @@ -176,8 +170,8 @@ __kernel void findBlockBounds(real4 periodicBoxSize, real4 invPeriodicBoxSize, _ /** * Find a list of neighbors for each atom. */ -__kernel void findNeighbors(real4 periodicBoxSize, real4 invPeriodicBoxSize, __global const real4* restrict posq, - __global const real4* restrict blockCenter, __global const real4* restrict blockBoundingBox, __global int2* restrict neighborPairs, +__kernel void findNeighbors(real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + __global const real4* restrict posq, __global const real4* restrict blockCenter, __global const real4* restrict blockBoundingBox, __global int2* restrict neighborPairs, __global int* restrict numNeighborPairs, __global int* restrict numNeighborsForAtom, int maxNeighborPairs #ifdef USE_EXCLUSIONS , __global int* restrict exclusions, __global int* restrict exclusionStartIndex @@ -212,9 +206,7 @@ __kernel void findNeighbors(real4 periodicBoxSize, real4 invPeriodicBoxSize, __g real4 blockSize2 = blockBoundingBox[block2]; real4 blockDelta = blockCenter1-blockCenter2; #ifdef USE_PERIODIC - blockDelta.x -= floor(blockDelta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - blockDelta.y -= floor(blockDelta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - blockDelta.z -= floor(blockDelta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(blockDelta) #endif blockDelta.x = max((real) 0, fabs(blockDelta.x)-blockSize1.x-blockSize2.x); blockDelta.y = max((real) 0, fabs(blockDelta.y)-blockSize1.y-blockSize2.y); @@ -243,7 +235,7 @@ __kernel void findNeighbors(real4 periodicBoxSize, real4 invPeriodicBoxSize, __g // Decide whether to include this atom pair in the neighbor list. - real4 atomDelta = delta(pos1, pos2, periodicBoxSize, invPeriodicBoxSize); + real4 atomDelta = delta(pos1, pos2, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); #ifdef USE_CENTRAL_PARTICLE bool includeAtom = (atom2 != atom1 && atom2 < NUM_ATOMS && atomDelta.w < CUTOFF_SQUARED); #else diff --git a/platforms/opencl/src/kernels/customNonbondedGroups.cl b/platforms/opencl/src/kernels/customNonbondedGroups.cl index a28b8e51f..dc70e4bca 100644 --- a/platforms/opencl/src/kernels/customNonbondedGroups.cl +++ b/platforms/opencl/src/kernels/customNonbondedGroups.cl @@ -42,8 +42,8 @@ __kernel void computeInteractionGroups( #else __global real4* restrict forceBuffers, #endif - __global real* restrict energyBuffer, __global const real4* restrict posq, - __global const int4* restrict groupData, real4 periodicBoxSize, real4 invPeriodicBoxSize + __global real* restrict energyBuffer, __global const real4* restrict posq, __global const int4* restrict groupData, + real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ PARAMETER_ARGUMENTS) { const unsigned int totalWarps = get_global_size(0)/TILE_SIZE; const unsigned int warp = get_global_id(0)/TILE_SIZE; // global warpIndex @@ -82,7 +82,7 @@ __kernel void computeInteractionGroups( posq2 = (real4) (localData[localIndex].x, localData[localIndex].y, localData[localIndex].z, localData[localIndex].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/opencl/src/kernels/gbsaObc.cl b/platforms/opencl/src/kernels/gbsaObc.cl index d83ecdb18..a34c54c91 100644 --- a/platforms/opencl/src/kernels/gbsaObc.cl +++ b/platforms/opencl/src/kernels/gbsaObc.cl @@ -22,7 +22,8 @@ __kernel void computeBornSum( __global const real4* restrict posq, __global const float2* restrict global_params, #ifdef USE_CUTOFF __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, #else unsigned int numTiles, #endif @@ -58,7 +59,7 @@ __kernel void computeBornSum( for (unsigned int j = 0; j < TILE_SIZE; j++) { real4 delta = (real4) (localData[tbx+j].x-posq1.x, localData[tbx+j].y-posq1.y, localData[tbx+j].z-posq1.z, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -105,7 +106,7 @@ __kernel void computeBornSum( for (j = 0; j < TILE_SIZE; j++) { real4 delta = (real4) (localData[tbx+tj].x-posq1.x, localData[tbx+tj].y-posq1.y, localData[tbx+tj].z-posq1.z, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -256,10 +257,8 @@ __kernel void computeBornSum( // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.xyz -= floor((posq1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; - localData[get_local_id(0)].x -= floor((localData[get_local_id(0)].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[get_local_id(0)].y -= floor((localData[get_local_id(0)].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[get_local_id(0)].z -= floor((localData[get_local_id(0)].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[get_local_id(0)], blockCenterX) SYNC_WARPS; unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { @@ -307,7 +306,7 @@ __kernel void computeBornSum( for (j = 0; j < TILE_SIZE; j++) { real4 delta = (real4) (localData[tbx+tj].x-posq1.x, localData[tbx+tj].y-posq1.y, localData[tbx+tj].z-posq1.z, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; int atom2 = atomIndices[tbx+tj]; @@ -391,7 +390,8 @@ __kernel void computeGBSAForce1( __global real* restrict energyBuffer, __global const real4* restrict posq, __global const real* restrict global_bornRadii, #ifdef USE_CUTOFF __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, #else unsigned int numTiles, #endif @@ -430,7 +430,7 @@ __kernel void computeGBSAForce1( real4 posq2 = (real4) (localData[tbx+j].x, localData[tbx+j].y, localData[tbx+j].z, localData[tbx+j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -485,7 +485,7 @@ __kernel void computeGBSAForce1( real4 posq2 = (real4) (localData[tbx+tj].x, localData[tbx+tj].y, localData[tbx+tj].z, localData[tbx+tj].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -645,10 +645,8 @@ __kernel void computeGBSAForce1( // box, then skip having to apply periodic boundary conditions later. real4 blockCenterX = blockCenter[x]; - posq1.xyz -= floor((posq1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; - localData[get_local_id(0)].x -= floor((localData[get_local_id(0)].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[get_local_id(0)].y -= floor((localData[get_local_id(0)].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[get_local_id(0)].z -= floor((localData[get_local_id(0)].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[get_local_id(0)], blockCenterX) SYNC_WARPS; unsigned int tj = tgx; for (j = 0; j < TILE_SIZE; j++) { @@ -700,7 +698,7 @@ __kernel void computeGBSAForce1( real4 posq2 = (real4) (localData[tbx+tj].x, localData[tbx+tj].y, localData[tbx+tj].z, localData[tbx+tj].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF diff --git a/platforms/opencl/tests/TestOpenCLCustomManyParticleForce.cpp b/platforms/opencl/tests/TestOpenCLCustomManyParticleForce.cpp index 9c6aaaa63..29b35f387 100644 --- a/platforms/opencl/tests/TestOpenCLCustomManyParticleForce.cpp +++ b/platforms/opencl/tests/TestOpenCLCustomManyParticleForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2014 Stanford University and the Authors. * + * Portions copyright (c) 2014-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -55,7 +55,17 @@ const double TOL = 1e-5; OpenCLPlatform platform; -void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize) { +Vec3 computeDelta(const Vec3& pos1, const Vec3& pos2, bool periodic, const Vec3* periodicBoxVectors) { + Vec3 diff = pos1-pos2; + if (periodic) { + diff -= periodicBoxVectors[2]*floor(diff[2]/periodicBoxVectors[2][2]+0.5); + diff -= periodicBoxVectors[1]*floor(diff[1]/periodicBoxVectors[1][1]+0.5); + diff -= periodicBoxVectors[0]*floor(diff[0]/periodicBoxVectors[0][0]+0.5); + } + return diff; +} + +void validateAxilrodTeller(CustomManyParticleForce* force, const vector& positions, const vector& expectedSets, double boxSize, bool triclinic) { // Create a System and Context. int numParticles = force->getNumParticles(); @@ -63,7 +73,18 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p System system; for (int i = 0; i < numParticles; i++) system.addParticle(1.0); - system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); + Vec3 boxVectors[3]; + if (triclinic) { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0.2*boxSize, boxSize, 0); + boxVectors[2] = Vec3(-0.3*boxSize, -0.1*boxSize, boxSize); + } + else { + boxVectors[0] = Vec3(boxSize, 0, 0); + boxVectors[1] = Vec3(0, boxSize, 0); + boxVectors[2] = Vec3(0, 0, boxSize); + } + system.setDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); system.addForce(force); VerletIntegrator integrator(0.001); Context context(system, integrator, platform); @@ -74,20 +95,14 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p // See if the energy matches the expected value. double expectedEnergy = 0; + bool periodic = (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic); for (int i = 0; i < (int) expectedSets.size(); i++) { int p1 = expectedSets[i][0]; int p2 = expectedSets[i][1]; int p3 = expectedSets[i][2]; - Vec3 d12 = positions[p2]-positions[p1]; - Vec3 d13 = positions[p3]-positions[p1]; - Vec3 d23 = positions[p3]-positions[p2]; - if (nonbondedMethod == CustomManyParticleForce::CutoffPeriodic) { - for (int j = 0; j < 3; j++) { - d12[j] -= floor(d12[j]/boxSize+0.5f)*boxSize; - d13[j] -= floor(d13[j]/boxSize+0.5f)*boxSize; - d23[j] -= floor(d23[j]/boxSize+0.5f)*boxSize; - } - } + Vec3 d12 = computeDelta(positions[p2], positions[p1], periodic, boxVectors); + Vec3 d13 = computeDelta(positions[p3], positions[p1], periodic, boxVectors); + Vec3 d23 = computeDelta(positions[p3], positions[p2], periodic, boxVectors); double r12 = sqrt(d12.dot(d12)); double r13 = sqrt(d13.dot(d13)); double r23 = sqrt(d23.dot(d23)); @@ -210,7 +225,7 @@ void testNoCutoff() { positions.push_back(Vec3(0.4, 0, -0.8)); int sets[4][3] = {{0,1,2}, {1,2,3}, {2,3,0}, {3,0,1}}; vector expectedSets(&sets[0], &sets[4]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testCutoff() { @@ -235,7 +250,7 @@ void testCutoff() { positions.push_back(Vec3(0.2, 0.5, -0.1)); int sets[7][3] = {{0,1,2}, {0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,2,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[7]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testPeriodic() { @@ -261,7 +276,33 @@ void testPeriodic() { double boxSize = 2.1; int sets[5][3] = {{0,1,3}, {0,1,4}, {0,2,4}, {0,3,4}, {1,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, boxSize); + validateAxilrodTeller(force, positions, expectedSets, boxSize, false); +} + +void testTriclinic() { + CustomManyParticleForce* force = new CustomManyParticleForce(3, + "C*(1+3*cos(theta1)*cos(theta2)*cos(theta3))/(r12*r13*r23)^3;" + "theta1=angle(p1,p2,p3); theta2=angle(p2,p3,p1); theta3=angle(p3,p1,p2);" + "r12=distance(p1,p2); r13=distance(p1,p3); r23=distance(p2,p3)"); + force->addGlobalParameter("C", 1.5); + force->setNonbondedMethod(CustomManyParticleForce::CutoffPeriodic); + force->setCutoffDistance(1.05); + vector params; + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + force->addParticle(params); + vector positions; + positions.push_back(Vec3(0, 0, 0)); + positions.push_back(Vec3(1, 0, 0)); + positions.push_back(Vec3(0, 1.1, 0.3)); + positions.push_back(Vec3(0.4, 0, -0.8)); + positions.push_back(Vec3(0.2, 0.5, -0.1)); + double boxSize = 2.1; + int sets[4][3] = {{0,1,3}, {0,1,4}, {0,3,4}, {1,3,4}}; + vector expectedSets(&sets[0], &sets[4]); + validateAxilrodTeller(force, positions, expectedSets, boxSize, true); } void testExclusions() { @@ -286,7 +327,7 @@ void testExclusions() { force->addExclusion(0, 3); int sets[5][3] = {{0,1,4}, {1,2,3}, {1,2,4}, {1,3,4}, {2,3,4}}; vector expectedSets(&sets[0], &sets[5]); - validateAxilrodTeller(force, positions, expectedSets, 2.0); + validateAxilrodTeller(force, positions, expectedSets, 2.0, false); } void testAllTerms() { @@ -672,6 +713,7 @@ int main(int argc, char* argv[]) { testNoCutoff(); testCutoff(); testPeriodic(); + testTriclinic(); testExclusions(); testAllTerms(); testParameters(); -- GitLab From 295ae0011e28644dfa7fb2cfa6f9fad41e299116 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 7 Jan 2015 17:04:15 -0800 Subject: [PATCH 195/338] OpenCL supports PME with triclinic boxes --- platforms/opencl/src/OpenCLKernels.cpp | 94 +++++++++++++++++----- platforms/opencl/src/kernels/pme.cl | 90 ++++++++++++--------- platforms/opencl/tests/TestOpenCLEwald.cpp | 52 ++++++++++++ 3 files changed, 177 insertions(+), 59 deletions(-) diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 01f0da1c7..986fa59b2 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -70,13 +70,6 @@ static void setPeriodicBoxSizeArg(OpenCLContext& cl, cl::Kernel& kernel, int ind kernel.setArg(index, cl.getPeriodicBoxSize()); } -static void setInvPeriodicBoxSizeArg(OpenCLContext& cl, cl::Kernel& kernel, int index) { - if (cl.getUseDoublePrecision()) - kernel.setArg(index, cl.getInvPeriodicBoxSizeDouble()); - else - kernel.setArg(index, cl.getInvPeriodicBoxSize()); -} - static void setPeriodicBoxArgs(OpenCLContext& cl, cl::Kernel& kernel, int index) { if (cl.getUseDoublePrecision()) { kernel.setArg(index++, cl.getPeriodicBoxSizeDouble()); @@ -1786,7 +1779,7 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ pmeInterpolateForceKernel.setArg(0, cl.getPosq().getDeviceBuffer()); pmeInterpolateForceKernel.setArg(1, cl.getForceBuffers().getDeviceBuffer()); pmeInterpolateForceKernel.setArg(2, pmeGrid->getDeviceBuffer()); - pmeInterpolateForceKernel.setArg(5, pmeAtomGridIndex->getDeviceBuffer()); + pmeInterpolateForceKernel.setArg(7, pmeAtomGridIndex->getDeviceBuffer()); if (cl.getSupports64BitGlobalAtomics()) { pmeFinishSpreadChargeKernel = cl::Kernel(program, "finishSpreadCharge"); pmeFinishSpreadChargeKernel.setArg(0, pmeGrid->getDeviceBuffer()); @@ -1815,44 +1808,105 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ if (pmeGrid != NULL && includeReciprocal) { if (usePmeQueue) cl.setQueue(pmeQueue); + + // Invert the periodic box vectors. + + Vec3 boxVectors[3]; + cl.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); + double determinant = boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]; + double scale = 1.0/determinant; + mm_double4 recipBoxVectors[3]; + recipBoxVectors[0] = mm_double4(boxVectors[1][1]*boxVectors[2][2]*scale, 0, 0, 0); + recipBoxVectors[1] = mm_double4(-boxVectors[1][0]*boxVectors[2][2]*scale, boxVectors[0][0]*boxVectors[2][2]*scale, 0, 0); + recipBoxVectors[2] = mm_double4((boxVectors[1][0]*boxVectors[2][1]-boxVectors[1][1]*boxVectors[2][0])*scale, -boxVectors[0][0]*boxVectors[2][1]*scale, boxVectors[0][0]*boxVectors[1][1]*scale, 0); + mm_float4 recipBoxVectorsFloat[3]; + for (int i = 0; i < 3; i++) + recipBoxVectorsFloat[i] = mm_float4((float) recipBoxVectors[i].x, (float) recipBoxVectors[i].y, (float) recipBoxVectors[i].z, 0); + + // Execute the reciprocal space kernels. + setPeriodicBoxSizeArg(cl, pmeUpdateBsplinesKernel, 4); - setInvPeriodicBoxSizeArg(cl, pmeUpdateBsplinesKernel, 5); + if (cl.getUseDoublePrecision()) { + pmeUpdateBsplinesKernel.setArg(5, recipBoxVectors[0]); + pmeUpdateBsplinesKernel.setArg(6, recipBoxVectors[1]); + pmeUpdateBsplinesKernel.setArg(7, recipBoxVectors[2]); + } + else { + pmeUpdateBsplinesKernel.setArg(5, recipBoxVectorsFloat[0]); + pmeUpdateBsplinesKernel.setArg(6, recipBoxVectorsFloat[1]); + pmeUpdateBsplinesKernel.setArg(7, recipBoxVectorsFloat[2]); + } cl.executeKernel(pmeUpdateBsplinesKernel, cl.getNumAtoms()); if (deviceIsCpu) { setPeriodicBoxSizeArg(cl, pmeSpreadChargeKernel, 5); - setInvPeriodicBoxSizeArg(cl, pmeSpreadChargeKernel, 6); + if (cl.getUseDoublePrecision()) { + pmeSpreadChargeKernel.setArg(6, recipBoxVectors[0]); + pmeSpreadChargeKernel.setArg(7, recipBoxVectors[1]); + pmeSpreadChargeKernel.setArg(8, recipBoxVectors[2]); + } + else { + pmeSpreadChargeKernel.setArg(6, recipBoxVectorsFloat[0]); + pmeSpreadChargeKernel.setArg(7, recipBoxVectorsFloat[1]); + pmeSpreadChargeKernel.setArg(8, recipBoxVectorsFloat[2]); + } cl.executeKernel(pmeSpreadChargeKernel, 2*cl.getDevice().getInfo(), 1); } else { sort->sort(*pmeAtomGridIndex); if (cl.getSupports64BitGlobalAtomics()) { setPeriodicBoxSizeArg(cl, pmeSpreadChargeKernel, 5); - setInvPeriodicBoxSizeArg(cl, pmeSpreadChargeKernel, 6); + if (cl.getUseDoublePrecision()) { + pmeSpreadChargeKernel.setArg(6, recipBoxVectors[0]); + pmeSpreadChargeKernel.setArg(7, recipBoxVectors[1]); + pmeSpreadChargeKernel.setArg(8, recipBoxVectors[2]); + } + else { + pmeSpreadChargeKernel.setArg(6, recipBoxVectorsFloat[0]); + pmeSpreadChargeKernel.setArg(7, recipBoxVectorsFloat[1]); + pmeSpreadChargeKernel.setArg(8, recipBoxVectorsFloat[2]); + } cl.executeKernel(pmeSpreadChargeKernel, cl.getNumAtoms()); cl.executeKernel(pmeFinishSpreadChargeKernel, pmeGrid->getSize()); } else { - setPeriodicBoxSizeArg(cl, pmeAtomRangeKernel, 3); - setInvPeriodicBoxSizeArg(cl, pmeAtomRangeKernel, 4); cl.executeKernel(pmeAtomRangeKernel, cl.getNumAtoms()); setPeriodicBoxSizeArg(cl, pmeZIndexKernel, 2); - setInvPeriodicBoxSizeArg(cl, pmeZIndexKernel, 3); + if (cl.getUseDoublePrecision()) + pmeZIndexKernel.setArg(3, recipBoxVectors[2]); + else + pmeZIndexKernel.setArg(3, recipBoxVectorsFloat[2]); cl.executeKernel(pmeZIndexKernel, cl.getNumAtoms()); cl.executeKernel(pmeSpreadChargeKernel, cl.getNumAtoms()); } } fft->execFFT(*pmeGrid, *pmeGrid2, true); - setInvPeriodicBoxSizeArg(cl, pmeConvolutionKernel, 5); mm_double4 boxSize = cl.getPeriodicBoxSizeDouble(); double scaleFactor = 1.0/(M_PI*boxSize.x*boxSize.y*boxSize.z); - if (cl.getUseDoublePrecision()) - pmeConvolutionKernel.setArg(6, scaleFactor); - else - pmeConvolutionKernel.setArg(6, (float) scaleFactor); + if (cl.getUseDoublePrecision()) { + pmeConvolutionKernel.setArg(5, recipBoxVectors[0]); + pmeConvolutionKernel.setArg(6, recipBoxVectors[1]); + pmeConvolutionKernel.setArg(7, recipBoxVectors[2]); + pmeConvolutionKernel.setArg(8, scaleFactor); + } + else { + pmeConvolutionKernel.setArg(5, recipBoxVectorsFloat[0]); + pmeConvolutionKernel.setArg(6, recipBoxVectorsFloat[1]); + pmeConvolutionKernel.setArg(7, recipBoxVectorsFloat[2]); + pmeConvolutionKernel.setArg(8, (float) scaleFactor); + } cl.executeKernel(pmeConvolutionKernel, cl.getNumAtoms()); fft->execFFT(*pmeGrid2, *pmeGrid, false); setPeriodicBoxSizeArg(cl, pmeInterpolateForceKernel, 3); - setInvPeriodicBoxSizeArg(cl, pmeInterpolateForceKernel, 4); + if (cl.getUseDoublePrecision()) { + pmeInterpolateForceKernel.setArg(4, recipBoxVectors[0]); + pmeInterpolateForceKernel.setArg(5, recipBoxVectors[1]); + pmeInterpolateForceKernel.setArg(6, recipBoxVectors[2]); + } + else { + pmeInterpolateForceKernel.setArg(4, recipBoxVectorsFloat[0]); + pmeInterpolateForceKernel.setArg(5, recipBoxVectorsFloat[1]); + pmeInterpolateForceKernel.setArg(6, recipBoxVectorsFloat[2]); + } if (deviceIsCpu) cl.executeKernel(pmeInterpolateForceKernel, 2*cl.getDevice().getInfo(), 1); else diff --git a/platforms/opencl/src/kernels/pme.cl b/platforms/opencl/src/kernels/pme.cl index eedf1290e..030d1f211 100644 --- a/platforms/opencl/src/kernels/pme.cl +++ b/platforms/opencl/src/kernels/pme.cl @@ -1,15 +1,18 @@ __kernel void updateBsplines(__global const real4* restrict posq, __global real4* restrict pmeBsplineTheta, __local real4* restrict bsplinesCache, - __global int2* restrict pmeAtomGridIndex, real4 periodicBoxSize, real4 invPeriodicBoxSize) { + __global int2* restrict pmeAtomGridIndex, real4 periodicBoxSize, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) { const real4 scale = 1/(real) (PME_ORDER-1); for (int i = get_global_id(0); i < NUM_ATOMS; i += get_global_size(0)) { __local real4* data = &bsplinesCache[get_local_id(0)*PME_ORDER]; real4 pos = posq[i]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; - real4 t = (real4) ((pos.x*invPeriodicBoxSize.x)*GRID_SIZE_X, - (pos.y*invPeriodicBoxSize.y)*GRID_SIZE_Y, - (pos.z*invPeriodicBoxSize.z)*GRID_SIZE_Z, 0.0f); + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + real3 t = (real3) (pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, + pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, + pos.z*recipBoxVecZ.z); + t.x = (t.x-floor(t.x))*GRID_SIZE_X; + t.y = (t.y-floor(t.y))*GRID_SIZE_Y; + t.z = (t.z-floor(t.z))*GRID_SIZE_Z; real4 dr = (real4) (t.x-(int) t.x, t.y-(int) t.y, t.z-(int) t.z, 0.0f); int4 gridIndex = (int4) (((int) t.x) % GRID_SIZE_X, ((int) t.y) % GRID_SIZE_Y, @@ -41,7 +44,7 @@ __kernel void updateBsplines(__global const real4* restrict posq, __global real4 /** * For each grid point, find the range of sorted atoms associated with that point. */ -__kernel void findAtomRangeForGrid(__global int2* restrict pmeAtomGridIndex, __global int* restrict pmeAtomRange, __global const real4* restrict posq, real4 periodicBoxSize, real4 invPeriodicBoxSize) { +__kernel void findAtomRangeForGrid(__global int2* restrict pmeAtomGridIndex, __global int* restrict pmeAtomRange, __global const real4* restrict posq) { int start = (NUM_ATOMS*get_global_id(0))/get_global_size(0); int end = (NUM_ATOMS*(get_global_id(0)+1))/get_global_size(0); int last = (start == 0 ? -1 : pmeAtomGridIndex[start-1].y); @@ -68,13 +71,13 @@ __kernel void findAtomRangeForGrid(__global int2* restrict pmeAtomGridIndex, __g * The grid index won't be needed again. Reuse that component to hold the z index, thus saving * some work in the charge spreading kernel. */ -__kernel void recordZIndex(__global int2* restrict pmeAtomGridIndex, __global const real4* restrict posq, real4 periodicBoxSize, real4 invPeriodicBoxSize) { +__kernel void recordZIndex(__global int2* restrict pmeAtomGridIndex, __global const real4* restrict posq, real4 periodicBoxSize, real4 recipBoxVecZ) { int start = (NUM_ATOMS*get_global_id(0))/get_global_size(0); int end = (NUM_ATOMS*(get_global_id(0)+1))/get_global_size(0); for (int i = start; i < end; ++i) { real posz = posq[pmeAtomGridIndex[i].x].z; - posz -= floor(posz*invPeriodicBoxSize.z)*periodicBoxSize.z; - int z = ((int) ((posz*invPeriodicBoxSize.z)*GRID_SIZE_Z)) % GRID_SIZE_Z; + posz -= floor(posz*recipBoxVecZ.z)*periodicBoxSize.z; + int z = ((int) ((posz*recipBoxVecZ.z)*GRID_SIZE_Z)) % GRID_SIZE_Z; pmeAtomGridIndex[i].y = z; } } @@ -83,7 +86,7 @@ __kernel void recordZIndex(__global int2* restrict pmeAtomGridIndex, __global co #pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable __kernel void gridSpreadCharge(__global const real4* restrict posq, __global const int2* restrict pmeAtomGridIndex, __global const int* restrict pmeAtomRange, - __global long* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta, real4 periodicBoxSize, real4 invPeriodicBoxSize) { + __global long* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta, real4 periodicBoxSize, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) { const real4 scale = 1/(real) (PME_ORDER-1); real4 data[PME_ORDER]; @@ -93,12 +96,15 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con for (int i = get_global_id(0); i < NUM_ATOMS; i += get_global_size(0)) { int atom = pmeAtomGridIndex[i].x; real4 pos = posq[atom]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; - real4 t = (real4) ((pos.x*invPeriodicBoxSize.x)*GRID_SIZE_X, - (pos.y*invPeriodicBoxSize.y)*GRID_SIZE_Y, - (pos.z*invPeriodicBoxSize.z)*GRID_SIZE_Z, 0.0f); + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + real3 t = (real3) (pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, + pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, + pos.z*recipBoxVecZ.z); + t.x = (t.x-floor(t.x))*GRID_SIZE_X; + t.y = (t.y-floor(t.y))*GRID_SIZE_Y; + t.z = (t.z-floor(t.z))*GRID_SIZE_Z; int4 gridIndex = (int4) (((int) t.x) % GRID_SIZE_X, ((int) t.y) % GRID_SIZE_Y, ((int) t.z) % GRID_SIZE_Z, 0); @@ -163,7 +169,7 @@ __kernel void finishSpreadCharge(__global long* restrict pmeGrid) { } #elif defined(DEVICE_IS_CPU) __kernel void gridSpreadCharge(__global const real4* restrict posq, __global const int2* restrict pmeAtomGridIndex, __global const int* restrict pmeAtomRange, - __global real2* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta, real4 periodicBoxSize, real4 invPeriodicBoxSize) { + __global real2* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta, real4 periodicBoxSize, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) { const int firstx = get_global_id(0)*GRID_SIZE_X/get_global_size(0); const int lastx = (get_global_id(0)+1)*GRID_SIZE_X/get_global_size(0); if (firstx == lastx) @@ -177,12 +183,15 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con for (int i = 0; i < NUM_ATOMS; i++) { int atom = i;//pmeAtomGridIndex[i].x; real4 pos = posq[atom]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; - real4 t = (real4) ((pos.x*invPeriodicBoxSize.x)*GRID_SIZE_X, - (pos.y*invPeriodicBoxSize.y)*GRID_SIZE_Y, - (pos.z*invPeriodicBoxSize.z)*GRID_SIZE_Z, 0.0f); + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + real3 t = (real3) (pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, + pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, + pos.z*recipBoxVecZ.z); + t.x = (t.x-floor(t.x))*GRID_SIZE_X; + t.y = (t.y-floor(t.y))*GRID_SIZE_Y; + t.z = (t.z-floor(t.z))*GRID_SIZE_Z; int4 gridIndex = (int4) (((int) t.x) % GRID_SIZE_X, ((int) t.y) % GRID_SIZE_Y, ((int) t.z) % GRID_SIZE_Z, 0); @@ -290,7 +299,7 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con #endif __kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global real* restrict energyBuffer, __global const real* restrict pmeBsplineModuliX, - __global const real* restrict pmeBsplineModuliY, __global const real* restrict pmeBsplineModuliZ, real4 invPeriodicBoxSize, real recipScaleFactor) { + __global const real* restrict pmeBsplineModuliY, __global const real* restrict pmeBsplineModuliZ, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ, real recipScaleFactor) { const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; real energy = 0.0f; for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { @@ -303,9 +312,9 @@ __kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global r int mx = (kx < (GRID_SIZE_X+1)/2) ? kx : (kx-GRID_SIZE_X); int my = (ky < (GRID_SIZE_Y+1)/2) ? ky : (ky-GRID_SIZE_Y); int mz = (kz < (GRID_SIZE_Z+1)/2) ? kz : (kz-GRID_SIZE_Z); - real mhx = mx*invPeriodicBoxSize.x; - real mhy = my*invPeriodicBoxSize.y; - real mhz = mz*invPeriodicBoxSize.z; + real mhx = mx*recipBoxVecX.x; + real mhy = mx*recipBoxVecY.x+my*recipBoxVecY.y; + real mhz = mx*recipBoxVecZ.x+my*recipBoxVecZ.y+mz*recipBoxVecZ.z; real bx = pmeBsplineModuliX[kx]; real by = pmeBsplineModuliY[ky]; real bz = pmeBsplineModuliZ[kz]; @@ -320,7 +329,7 @@ __kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global r } __kernel void gridInterpolateForce(__global const real4* restrict posq, __global real4* restrict forceBuffers, __global const real2* restrict pmeGrid, - real4 periodicBoxSize, real4 invPeriodicBoxSize, __global int2* restrict pmeAtomGridIndex) { + real4 periodicBoxSize, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ, __global int2* restrict pmeAtomGridIndex) { const real4 scale = 1/(real) (PME_ORDER-1); real4 data[PME_ORDER]; real4 ddata[PME_ORDER]; @@ -332,12 +341,15 @@ __kernel void gridInterpolateForce(__global const real4* restrict posq, __global int atom = pmeAtomGridIndex[i].x; real4 force = 0.0f; real4 pos = posq[atom]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; - real4 t = (real4) ((pos.x*invPeriodicBoxSize.x)*GRID_SIZE_X, - (pos.y*invPeriodicBoxSize.y)*GRID_SIZE_Y, - (pos.z*invPeriodicBoxSize.z)*GRID_SIZE_Z, 0.0f); + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + real3 t = (real3) (pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, + pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, + pos.z*recipBoxVecZ.z); + t.x = (t.x-floor(t.x))*GRID_SIZE_X; + t.y = (t.y-floor(t.y))*GRID_SIZE_Y; + t.z = (t.z-floor(t.z))*GRID_SIZE_Z; int4 gridIndex = (int4) (((int) t.x) % GRID_SIZE_X, ((int) t.y) % GRID_SIZE_Y, ((int) t.z) % GRID_SIZE_Z, 0); @@ -385,9 +397,9 @@ __kernel void gridInterpolateForce(__global const real4* restrict posq, __global } real4 totalForce = forceBuffers[atom]; real q = pos.w*EPSILON_FACTOR; - totalForce.x -= q*force.x*GRID_SIZE_X*invPeriodicBoxSize.x; - totalForce.y -= q*force.y*GRID_SIZE_Y*invPeriodicBoxSize.y; - totalForce.z -= q*force.z*GRID_SIZE_Z*invPeriodicBoxSize.z; + totalForce.x -= q*(force.x*GRID_SIZE_X*recipBoxVecX.x); + totalForce.y -= q*(force.x*GRID_SIZE_X*recipBoxVecY.x+force.y*GRID_SIZE_Y*recipBoxVecY.y); + totalForce.z -= q*(force.x*GRID_SIZE_X*recipBoxVecZ.x+force.y*GRID_SIZE_Y*recipBoxVecZ.y+force.z*GRID_SIZE_Z*recipBoxVecZ.z); forceBuffers[atom] = totalForce; } } diff --git a/platforms/opencl/tests/TestOpenCLEwald.cpp b/platforms/opencl/tests/TestOpenCLEwald.cpp index 419ab1071..1ac3f72bf 100644 --- a/platforms/opencl/tests/TestOpenCLEwald.cpp +++ b/platforms/opencl/tests/TestOpenCLEwald.cpp @@ -201,6 +201,57 @@ void testEwald2Ions() { ASSERT_EQUAL_TOL(-217.276, state.getPotentialEnergy(), 0.01/*10*TOL*/); } +void testTriclinic() { + // Create a triclinic box containing eight particles. + + System system; + system.setDefaultPeriodicBoxVectors(Vec3(2.5, 0, 0), Vec3(0.5, 3.0, 0), Vec3(0.7, 0.9, 3.5)); + for (int i = 0; i < 8; i++) + system.addParticle(1.0); + NonbondedForce* force = new NonbondedForce(); + system.addForce(force); + force->setNonbondedMethod(NonbondedForce::PME); + force->setCutoffDistance(1.0); + force->setPMEParameters(3.45891, 32, 40, 48); + for (int i = 0; i < 4; i++) + force->addParticle(-1, 0.440104, 0.4184); // Cl parameters + for (int i = 0; i < 4; i++) + force->addParticle(1, 0.332840, 0.0115897); // Na parameters + vector positions(8); + positions[0] = Vec3(1.744, 2.788, 3.162); + positions[1] = Vec3(1.048, 0.762, 2.340); + positions[2] = Vec3(2.489, 1.570, 2.817); + positions[3] = Vec3(1.027, 1.893, 3.271); + positions[4] = Vec3(0.937, 0.825, 0.009); + positions[5] = Vec3(2.290, 1.887, 3.352); + positions[6] = Vec3(1.266, 1.111, 2.894); + positions[7] = Vec3(0.933, 1.862, 3.490); + + // Compute the forces and energy. + + VerletIntegrator integ(0.001); + Context context(system, integ, platform); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + + // Compare them to values computed by Gromacs. + + double expectedEnergy = -963.370; + vector expectedForce(8); + expectedForce[0] = Vec3(4.25253e+01, -1.23503e+02, 1.22139e+02); + expectedForce[1] = Vec3(9.74752e+01, 1.68213e+02, 1.93169e+02); + expectedForce[2] = Vec3(-1.50348e+02, 1.29165e+02, 3.70435e+02); + expectedForce[3] = Vec3(9.18644e+02, -3.52571e+00, -1.34772e+03); + expectedForce[4] = Vec3(-1.61193e+02, 9.01528e+01, -7.12904e+01); + expectedForce[5] = Vec3(2.82630e+02, 2.78029e+01, -3.72864e+02); + expectedForce[6] = Vec3(-1.47454e+02, -2.14448e+02, -3.55789e+02); + expectedForce[7] = Vec3(-8.82195e+02, -7.39132e+01, 1.46202e+03); + for (int i = 0; i < 8; i++) { + ASSERT_EQUAL_VEC(expectedForce[i], state.getForces()[i], 1e-4); + } + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), 1e-4); +} + void testErrorTolerance(NonbondedForce::NonbondedMethod method) { // Create a cloud of random point charges. @@ -307,6 +358,7 @@ int main(int argc, char* argv[]) { testEwaldPME(false); testEwaldPME(true); // testEwald2Ions(); + testTriclinic(); testErrorTolerance(NonbondedForce::Ewald); testErrorTolerance(NonbondedForce::PME); testPMEParameters(); -- GitLab From 53690fef7d5995b219b647bc35945f81deee10ef Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 8 Jan 2015 11:05:20 -0800 Subject: [PATCH 196/338] Do not allow Ewald to be used with triclinic boxes, since it isn't implemented. --- openmmapi/src/NonbondedForceImpl.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openmmapi/src/NonbondedForceImpl.cpp b/openmmapi/src/NonbondedForceImpl.cpp index 30d32d03a..e86f10d4c 100644 --- a/openmmapi/src/NonbondedForceImpl.cpp +++ b/openmmapi/src/NonbondedForceImpl.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2014 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -98,6 +98,8 @@ void NonbondedForceImpl::initialize(ContextImpl& context) { double cutoff = owner.getCutoffDistance(); if (cutoff > 0.5*boxVectors[0][0] || cutoff > 0.5*boxVectors[1][1] || cutoff > 0.5*boxVectors[2][2]) throw OpenMMException("NonbondedForce: The cutoff distance cannot be greater than half the periodic box size."); + if (owner.getNonbondedMethod() == NonbondedForce::Ewald && (boxVectors[1][0] != 0.0 || boxVectors[2][0] != 0.0 || boxVectors[2][1] != 0)) + throw OpenMMException("NonbondedForce: Ewald is not supported with non-rectangular boxes. Use PME instead."); } kernel.getAs().initialize(context.getSystem(), owner); } -- GitLab From 46f7b76bbe4e97a67026515b85311efe771a1fe8 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 8 Jan 2015 14:11:33 -0800 Subject: [PATCH 197/338] AmoebaVdwForce works with triclinic boxes --- .../cuda/tests/TestCudaAmoebaVdwForce.cpp | 62 ++++++++++++++++++ .../reference/src/AmoebaReferenceKernels.cpp | 8 +-- .../AmoebaReferenceVdwForce.cpp | 63 +++++++++---------- .../SimTKReference/AmoebaReferenceVdwForce.h | 19 ++---- .../tests/TestReferenceAmoebaVdwForce.cpp | 62 ++++++++++++++++++ 5 files changed, 162 insertions(+), 52 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp index bac75b324..03c4c6c4d 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp @@ -39,6 +39,7 @@ #include "openmm/System.h" #include "openmm/AmoebaVdwForce.h" #include "openmm/LangevinIntegrator.h" +#include "sfmt/SFMT.h" #include #include #include @@ -50,6 +51,7 @@ using namespace OpenMM; +using namespace std; extern "C" void registerAmoebaCudaKernelFactories(); @@ -1981,6 +1983,62 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { } } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + LangevinIntegrator integrator(0.0, 0.1, 0.01); + AmoebaVdwForce* vdw = new AmoebaVdwForce(); + vdw->setUseDispersionCorrection(false); + vdw->addParticle(0, 0.5, 1.0, 0.0); + vdw->addParticle(1, 0.5, 1.0, 0.0); + vdw->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); + const double cutoff = 1.5; + vdw->setCutoff(cutoff); + system.addForce(vdw); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the energy is correct. + + State state = context.getState(State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + } + else if (distance < 0.9*cutoff) { + const double energy = pow(1.07/(distance+0.07), 7.0)*(1.12/(pow(distance, 7.0)+0.12)-2); + ASSERT_EQUAL_TOL(energy, state.getPotentialEnergy(), TOL); + } + } +} + int main(int argc, char* argv[]) { try { std::cout << "TestCudaAmoebaVdwForce running test..." << std::endl; @@ -2029,6 +2087,10 @@ int main(int argc, char* argv[]) { includeVdwDispersionCorrection = 1; testVdwWater( includeVdwDispersionCorrection, log ); + + // test triclinic boxes + + testTriclinic(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp index dc6114c89..97517f488 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp @@ -976,14 +976,14 @@ double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool inc computeNeighborListVoxelHash( *neighborList, numParticles, posData, allExclusions, extractBoxVectors(context), usePBC, cutoff, 0.0); if( usePBC ){ vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::CutoffPeriodic); - RealVec& box = extractBoxSize(context); + RealVec* boxVectors = extractBoxVectors(context); double minAllowedSize = 1.999999*cutoff; - if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize){ + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize){ throw OpenMMException("The periodic box size has decreased to less than twice the cutoff."); } - vdwForce.setPeriodicBox(box); + vdwForce.setPeriodicBox(boxVectors); energy = vdwForce.calculateForceAndEnergy( numParticles, posData, indexIVs, sigmas, epsilons, reductions, *neighborList, forceData); - energy += dispersionCoefficient/(box[0]*box[1]*box[2]); + energy += dispersionCoefficient/(boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]); } else { vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::CutoffNonPeriodic); } diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp index 16a3ecb44..aa396ff06 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp @@ -24,18 +24,18 @@ #include "AmoebaReferenceForce.h" #include "AmoebaReferenceVdwForce.h" +#include "ReferenceForce.h" #include #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( ) : _nonbondedMethod(NoCutoff), _cutoff(1.0e+10), _taperCutoffFactor(0.9) { setTaperCoefficients( _cutoff ); setSigmaCombiningRule( "ARITHMETIC" ); setEpsilonCombiningRule( "GEOMETRIC" ); - _periodicBoxDimensions = RealVec( 0.0, 0.0, 0.0 ); } @@ -44,7 +44,6 @@ AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( const std::string& sigmaCombin setTaperCoefficients( _cutoff ); setSigmaCombiningRule( sigmaCombiningRule ); setEpsilonCombiningRule( epsilonCombiningRule ); - _periodicBoxDimensions = RealVec( 0.0, 0.0, 0.0 ); } AmoebaReferenceVdwForce::NonbondedMethod AmoebaReferenceVdwForce::getNonbondedMethod( void ) const { @@ -77,12 +76,10 @@ double AmoebaReferenceVdwForce::getCutoff( void ) const { return _cutoff; } -void AmoebaReferenceVdwForce::setPeriodicBox( const RealVec& box ){ - _periodicBoxDimensions = box; -} - -RealVec AmoebaReferenceVdwForce::getPeriodicBox( void ) const { - return _periodicBoxDimensions; +void AmoebaReferenceVdwForce::setPeriodicBox(OpenMM::RealVec* vectors) { + _periodicBoxVectors[0] = vectors[0]; + _periodicBoxVectors[1] = vectors[1]; + _periodicBoxVectors[2] = vectors[2]; } void AmoebaReferenceVdwForce::setSigmaCombiningRule( const std::string& sigmaCombiningRule ){ @@ -181,7 +178,7 @@ void AmoebaReferenceVdwForce::addReducedForce( unsigned int particleI, unsigned forces[particleIV][2] += sign*force[2]*(one - reduction); } -RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combindedSigma, RealOpenMM combindedEpsilon, +RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combinedSigma, RealOpenMM combinedEpsilon, const Vec3& particleIPosition, const Vec3& particleJPosition, Vec3& force ) const { @@ -197,36 +194,34 @@ RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combindedSigma, // --------------------------------------------------------------------------------------- - RealOpenMM xr = particleIPosition[0] - particleJPosition[0]; - RealOpenMM yr = particleIPosition[1] - particleJPosition[1]; - RealOpenMM zr = particleIPosition[2] - particleJPosition[2]; + // get deltaR, R2, and R between 2 atoms - if( _nonbondedMethod == CutoffPeriodic ){ - xr -= static_cast((floor(xr/_periodicBoxDimensions[0]+0.5)*_periodicBoxDimensions[0])); - yr -= static_cast((floor(yr/_periodicBoxDimensions[1]+0.5)*_periodicBoxDimensions[1])); - zr -= static_cast((floor(zr/_periodicBoxDimensions[2]+0.5)*_periodicBoxDimensions[2])); - } + RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; + if (_nonbondedMethod == CutoffPeriodic) + ReferenceForce::getDeltaRPeriodic(particleJPosition, particleIPosition, _periodicBoxVectors, deltaR); + else + ReferenceForce::getDeltaR(particleJPosition, particleIPosition, deltaR); - RealOpenMM r_ij_2 = xr*xr + yr*yr + zr*zr; - RealOpenMM r_ij = SQRT(r_ij_2); - RealOpenMM sigma_7 = combindedSigma*combindedSigma*combindedSigma; - sigma_7 = sigma_7*sigma_7*combindedSigma; + RealOpenMM r_ij_2 = deltaR[ReferenceForce::R2Index]; + RealOpenMM r_ij = deltaR[ReferenceForce::RIndex]; + RealOpenMM sigma_7 = combinedSigma*combinedSigma*combinedSigma; + sigma_7 = sigma_7*sigma_7*combinedSigma; RealOpenMM r_ij_6 = r_ij_2*r_ij_2*r_ij_2; RealOpenMM r_ij_7 = r_ij_6*r_ij; RealOpenMM rho = r_ij_7 + ghal*sigma_7; - RealOpenMM tau = (dhal + one)/(r_ij + dhal*combindedSigma); + RealOpenMM tau = (dhal + one)/(r_ij + dhal*combinedSigma); RealOpenMM tau_7 = tau*tau*tau; tau_7 = tau_7*tau_7*tau; RealOpenMM dtau = tau/(dhal + one); RealOpenMM ratio = (sigma_7/rho); - RealOpenMM gtau = combindedEpsilon*tau_7*r_ij_6*(ghal+one)*ratio*ratio; + RealOpenMM gtau = combinedEpsilon*tau_7*r_ij_6*(ghal+one)*ratio*ratio; - RealOpenMM energy = combindedEpsilon*tau_7*sigma_7*( (ghal+one)*sigma_7/rho - two); + RealOpenMM energy = combinedEpsilon*tau_7*sigma_7*( (ghal+one)*sigma_7/rho - two); RealOpenMM dEdR = -seven*(dtau*energy + gtau); @@ -242,9 +237,9 @@ RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combindedSigma, dEdR /= r_ij; - force[0] = dEdR*xr; - force[1] = dEdR*yr; - force[2] = dEdR*zr; + force[0] = dEdR*deltaR[0]; + force[1] = dEdR*deltaR[1]; + force[2] = dEdR*deltaR[2]; return energy; @@ -315,11 +310,11 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, for( unsigned int jj = ii+1; jj < static_cast(numParticles); jj++ ){ if( exclusions[jj] == 0 ){ - RealOpenMM combindedSigma = (this->*_combineSigmas)(sigmaI, sigmas[jj] ); - RealOpenMM combindedEpsilon = (this->*_combineEpsilons)(epsilonI, epsilons[jj] ); + RealOpenMM combinedSigma = (this->*_combineSigmas)(sigmaI, sigmas[jj] ); + RealOpenMM combinedEpsilon = (this->*_combineEpsilons)(epsilonI, epsilons[jj] ); Vec3 force; - energy += calculatePairIxn( combindedSigma, combindedEpsilon, + energy += calculatePairIxn( combinedSigma, combinedEpsilon, reducedPositions[ii], reducedPositions[jj], force ); @@ -384,11 +379,11 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, int siteI = pair.first; int siteJ = pair.second; - RealOpenMM combindedSigma = (this->*_combineSigmas)( sigmas[siteI], sigmas[siteJ] ); - RealOpenMM combindedEpsilon = (this->*_combineEpsilons)( epsilons[siteI], epsilons[siteJ] ); + RealOpenMM combinedSigma = (this->*_combineSigmas)( sigmas[siteI], sigmas[siteJ] ); + RealOpenMM combinedEpsilon = (this->*_combineEpsilons)( epsilons[siteI], epsilons[siteJ] ); Vec3 force; - energy += calculatePairIxn( combindedSigma, combindedEpsilon, + energy += calculatePairIxn( combinedSigma, combinedEpsilon, reducedPositions[siteI], reducedPositions[siteJ], force ); if( indexIVs[siteI] == siteI ){ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h index 5cdd939c7..4c7089bf2 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h @@ -31,7 +31,7 @@ #include #include -using namespace OpenMM; +namespace OpenMM { class AmoebaReferenceVdwForce; typedef RealOpenMM (AmoebaReferenceVdwForce::*CombiningFunction)( RealOpenMM x, RealOpenMM y) const; @@ -174,21 +174,11 @@ public: Set box dimensions - @param box box dimensions + @param vectors the vectors defining the periodic box --------------------------------------------------------------------------------------- */ - void setPeriodicBox( const RealVec& box ); - - /**--------------------------------------------------------------------------------------- - - Get box dimensions - - @return box dimensions - - --------------------------------------------------------------------------------------- */ - - RealVec getPeriodicBox( void ) const; + void setPeriodicBox(OpenMM::RealVec* vectors); /**--------------------------------------------------------------------------------------- @@ -253,7 +243,7 @@ private: double _taperCutoffFactor; double _taperCutoff; RealOpenMM _taperCoefficients[3]; - RealVec _periodicBoxDimensions; + RealVec _periodicBoxVectors[3]; CombiningFunction _combineSigmas; RealOpenMM arithmeticSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const; RealOpenMM geometricSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const; @@ -333,6 +323,7 @@ private: }; +} // --------------------------------------------------------------------------------------- #endif // _AmoebaReferenceVdwForce___ diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp index f45d30d34..1b8d68179 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp @@ -39,6 +39,7 @@ #include "openmm/System.h" #include "openmm/AmoebaVdwForce.h" #include "openmm/LangevinIntegrator.h" +#include "sfmt/SFMT.h" #include #include #include @@ -50,6 +51,7 @@ using namespace OpenMM; +using namespace std; extern "C" OPENMM_EXPORT void registerAmoebaReferenceKernelFactories(); @@ -1981,6 +1983,62 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { } } +void testTriclinic() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + Vec3 a(3.1, 0, 0); + Vec3 b(0.4, 3.5, 0); + Vec3 c(-0.1, -0.5, 4.0); + system.setDefaultPeriodicBoxVectors(a, b, c); + LangevinIntegrator integrator(0.0, 0.1, 0.01); + AmoebaVdwForce* vdw = new AmoebaVdwForce(); + vdw->setUseDispersionCorrection(false); + vdw->addParticle(0, 0.5, 1.0, 0.0); + vdw->addParticle(1, 0.5, 1.0, 0.0); + vdw->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); + const double cutoff = 1.5; + vdw->setCutoff(cutoff); + system.addForce(vdw); + Context context(system, integrator, Platform::getPlatformByName("Reference")); + vector positions(2); + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int iteration = 0; iteration < 50; iteration++) { + // Generate random positions for the two particles. + + positions[0] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + positions[1] = a*genrand_real2(sfmt) + b*genrand_real2(sfmt) + c*genrand_real2(sfmt); + context.setPositions(positions); + + // Loop over all possible periodic copies and find the nearest one. + + Vec3 delta; + double distance2 = 100.0; + for (int i = -1; i < 2; i++) + for (int j = -1; j < 2; j++) + for (int k = -1; k < 2; k++) { + Vec3 d = positions[1]-positions[0]+a*i+b*j+c*k; + if (d.dot(d) < distance2) { + delta = d; + distance2 = d.dot(d); + } + } + double distance = sqrt(distance2); + + // See if the energy is correct. + + State state = context.getState(State::Energy); + if (distance >= cutoff) { + ASSERT_EQUAL(0.0, state.getPotentialEnergy()); + } + else if (distance < 0.9*cutoff) { + const double energy = pow(1.07/(distance+0.07), 7.0)*(1.12/(pow(distance, 7.0)+0.12)-2); + ASSERT_EQUAL_TOL(energy, state.getPotentialEnergy(), TOL); + } + } +} + int main( int numberOfArguments, char* argv[] ) { try { @@ -2029,6 +2087,10 @@ int main( int numberOfArguments, char* argv[] ) { includeVdwDispersionCorrection = 1; testVdwWater( includeVdwDispersionCorrection, log ); + + // test triclinic boxes + + testTriclinic(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; -- GitLab From 38acdd6e54a86d3549c023865973c33523c9863d Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 8 Jan 2015 14:14:16 -0800 Subject: [PATCH 198/338] Adjusted the tolerance on a test that was failing on some computers --- platforms/cpu/tests/TestCpuNonbondedForce.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platforms/cpu/tests/TestCpuNonbondedForce.cpp b/platforms/cpu/tests/TestCpuNonbondedForce.cpp index 21a150f00..65dc0dd65 100644 --- a/platforms/cpu/tests/TestCpuNonbondedForce.cpp +++ b/platforms/cpu/tests/TestCpuNonbondedForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -409,8 +409,8 @@ void testTriclinic() { else { const Vec3 force = delta*ONE_4PI_EPS0*(-1.0/(distance*distance*distance)+2.0*krf); ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(1.0/distance+krf*distance*distance-crf), state.getPotentialEnergy(), 1e-4); - ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); - ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + ASSERT_EQUAL_VEC(force, state.getForces()[0], 2e-5); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], 2e-5); } } } -- GitLab From 601a696fc0463764d1f9f2f0471ae455fd42b015 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 9 Jan 2015 06:29:39 -0500 Subject: [PATCH 199/338] Convert a random seed set to 0 into one based on the wall clock in more places. This commit hits the CPU platform (I had previously thought it just used the Reference generator) as well as the CustomIntegrator stream that is set separately from the standard "integrator" stream attached to each platform for CUDA and OpenCL platforms (it seemed to me that the Reference platform's CustomIntegrator just used the integrator random stream). --- platforms/cpu/src/CpuRandom.cpp | 7 ++++++- platforms/cuda/src/CudaKernels.cpp | 7 ++++++- platforms/opencl/src/OpenCLKernels.cpp | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/platforms/cpu/src/CpuRandom.cpp b/platforms/cpu/src/CpuRandom.cpp index bfd380100..a06282492 100644 --- a/platforms/cpu/src/CpuRandom.cpp +++ b/platforms/cpu/src/CpuRandom.cpp @@ -24,6 +24,7 @@ #include "CpuRandom.h" #include "openmm/OpenMMException.h" +#include "openmm/OSRngSeed.h" #include using namespace std; @@ -49,9 +50,13 @@ void CpuRandom::initialize(int seed, int numThreads) { nextGaussian.resize(numThreads); nextGaussianIsValid.resize(numThreads, false); - // Use a quick and dirty RNG to pick seeds for the real random number generator. + /* Use a quick and dirty RNG to pick seeds for the real random number generator. + * A random seed of 0 means pick a new random seed based on wall clock + */ unsigned int r = (unsigned int) seed; + if (r == 0) + r = (unsigned int) osrngseed(); for (int i = 0; i < numThreads; i++) { r = (1664525*r + 1013904223) & 0xFFFFFFFF; threadRandom[i] = new OpenMM_SFMT::SFMT(); diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 950acb35f..ce2aa677f 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -36,6 +36,7 @@ #include "openmm/internal/CustomManyParticleForceImpl.h" #include "openmm/internal/CustomNonbondedForceImpl.h" #include "openmm/internal/NonbondedForceImpl.h" +#include "openmm/internal/OSRngSeed.h" #include "CudaBondedUtilities.h" #include "CudaExpressionUtilities.h" #include "CudaIntegrationUtilities.h" @@ -5967,7 +5968,11 @@ void CudaIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context, uniformRandoms = CudaArray::create(cu, maxUniformRandoms, "uniformRandoms"); randomSeed = CudaArray::create(cu, cu.getNumThreadBlocks()*CudaContext::ThreadBlockSize, "randomSeed"); vector seed(randomSeed->getSize()); - unsigned int r = integrator.getRandomNumberSeed()+1; + int rseed = integrator.getRandomNumberSeed(); + // A random seed of 0 means generate a new one from the wall clock + if (rseed == 0) + rseed = osrngseed(); + unsigned int r = (unsigned int) (rseed+1); for (int i = 0; i < randomSeed->getSize(); i++) { seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 03df4e49c..197f16261 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -36,6 +36,7 @@ #include "openmm/internal/CustomManyParticleForceImpl.h" #include "openmm/internal/CustomNonbondedForceImpl.h" #include "openmm/internal/NonbondedForceImpl.h" +#include "openmm/internal/OSRngSeed.h" #include "OpenCLBondedUtilities.h" #include "OpenCLExpressionUtilities.h" #include "OpenCLIntegrationUtilities.h" @@ -6200,7 +6201,11 @@ void OpenCLIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context uniformRandoms = OpenCLArray::create(cl, maxUniformRandoms, "uniformRandoms"); randomSeed = OpenCLArray::create(cl, cl.getNumThreadBlocks()*OpenCLContext::ThreadBlockSize, "randomSeed"); vector seed(randomSeed->getSize()); - unsigned int r = integrator.getRandomNumberSeed()+1; + int rseed = integrator.getRandomNumberSeed(); + // A random seed of 0 means generate a new one from the wall clock + if (rseed == 0) + rseed = osrngseed(); + unsigned int r = (unsigned int) (rseed+1); for (int i = 0; i < randomSeed->getSize(); i++) { seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; -- GitLab From b705a22e84752ddd4c037010419cfbc25aef53d2 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 9 Jan 2015 06:36:21 -0500 Subject: [PATCH 200/338] Add notes in the doxygen comments about setRandomNumberSeed resulting in a "truly" random seed being generated from the wall clock upon Context creation. --- openmmapi/include/openmm/AndersenThermostat.h | 3 +++ openmmapi/include/openmm/BrownianIntegrator.h | 3 +++ openmmapi/include/openmm/CustomIntegrator.h | 3 +++ openmmapi/include/openmm/LangevinIntegrator.h | 3 +++ openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h | 3 +++ openmmapi/include/openmm/MonteCarloBarostat.h | 3 +++ openmmapi/include/openmm/MonteCarloMembraneBarostat.h | 3 +++ openmmapi/include/openmm/VariableLangevinIntegrator.h | 3 +++ 8 files changed, 24 insertions(+) diff --git a/openmmapi/include/openmm/AndersenThermostat.h b/openmmapi/include/openmm/AndersenThermostat.h index 4750c9bf5..3ff381cc8 100644 --- a/openmmapi/include/openmm/AndersenThermostat.h +++ b/openmmapi/include/openmm/AndersenThermostat.h @@ -114,6 +114,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/BrownianIntegrator.h b/openmmapi/include/openmm/BrownianIntegrator.h index ce2458bfe..31db2d808 100644 --- a/openmmapi/include/openmm/BrownianIntegrator.h +++ b/openmmapi/include/openmm/BrownianIntegrator.h @@ -99,6 +99,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/CustomIntegrator.h b/openmmapi/include/openmm/CustomIntegrator.h index 4045fbc91..4c1907c83 100644 --- a/openmmapi/include/openmm/CustomIntegrator.h +++ b/openmmapi/include/openmm/CustomIntegrator.h @@ -444,6 +444,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/LangevinIntegrator.h b/openmmapi/include/openmm/LangevinIntegrator.h index ea9371712..08b64ed92 100644 --- a/openmmapi/include/openmm/LangevinIntegrator.h +++ b/openmmapi/include/openmm/LangevinIntegrator.h @@ -99,6 +99,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h index 68c60fe09..5e403f7d6 100644 --- a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h +++ b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h @@ -167,6 +167,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index c78b569fe..f905f26e4 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -123,6 +123,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h index 05220f43a..3a7f1136e 100644 --- a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -220,6 +220,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/VariableLangevinIntegrator.h b/openmmapi/include/openmm/VariableLangevinIntegrator.h index b72e6aafc..74166919c 100644 --- a/openmmapi/include/openmm/VariableLangevinIntegrator.h +++ b/openmmapi/include/openmm/VariableLangevinIntegrator.h @@ -121,6 +121,9 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system + * clock when a Context is created from this Force. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; -- GitLab From 3129342e849a193ef00e74b32b74eedd47bcd12a Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 9 Jan 2015 06:43:17 -0500 Subject: [PATCH 201/338] Add a little more explanation. --- openmmapi/include/openmm/AndersenThermostat.h | 3 ++- openmmapi/include/openmm/BrownianIntegrator.h | 3 ++- openmmapi/include/openmm/CustomIntegrator.h | 3 ++- openmmapi/include/openmm/LangevinIntegrator.h | 3 ++- openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h | 3 ++- openmmapi/include/openmm/MonteCarloBarostat.h | 3 ++- openmmapi/include/openmm/MonteCarloMembraneBarostat.h | 3 ++- openmmapi/include/openmm/VariableLangevinIntegrator.h | 3 ++- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/openmmapi/include/openmm/AndersenThermostat.h b/openmmapi/include/openmm/AndersenThermostat.h index 3ff381cc8..e5253aae0 100644 --- a/openmmapi/include/openmm/AndersenThermostat.h +++ b/openmmapi/include/openmm/AndersenThermostat.h @@ -116,7 +116,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/BrownianIntegrator.h b/openmmapi/include/openmm/BrownianIntegrator.h index 31db2d808..88a76ef86 100644 --- a/openmmapi/include/openmm/BrownianIntegrator.h +++ b/openmmapi/include/openmm/BrownianIntegrator.h @@ -101,7 +101,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/CustomIntegrator.h b/openmmapi/include/openmm/CustomIntegrator.h index 4c1907c83..ad9390296 100644 --- a/openmmapi/include/openmm/CustomIntegrator.h +++ b/openmmapi/include/openmm/CustomIntegrator.h @@ -446,7 +446,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/LangevinIntegrator.h b/openmmapi/include/openmm/LangevinIntegrator.h index 08b64ed92..9ce6dc6df 100644 --- a/openmmapi/include/openmm/LangevinIntegrator.h +++ b/openmmapi/include/openmm/LangevinIntegrator.h @@ -101,7 +101,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h index 5e403f7d6..7308b83a4 100644 --- a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h +++ b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h @@ -169,7 +169,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index f905f26e4..41fac19b1 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -125,7 +125,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h index 3a7f1136e..1265818c9 100644 --- a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -222,7 +222,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/VariableLangevinIntegrator.h b/openmmapi/include/openmm/VariableLangevinIntegrator.h index 74166919c..622979ba6 100644 --- a/openmmapi/include/openmm/VariableLangevinIntegrator.h +++ b/openmmapi/include/openmm/VariableLangevinIntegrator.h @@ -123,7 +123,8 @@ public: * results on successive runs, even if those runs were initialized identically. * * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. + * clock when a Context is created from this Force. This is done to ensure that each Context receives + * unique random seeds without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; -- GitLab From 118aab89bd2cd0b95f3975c9a487d01321798624 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 9 Jan 2015 06:48:14 -0500 Subject: [PATCH 202/338] Fix an include. --- platforms/cpu/src/CpuRandom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/cpu/src/CpuRandom.cpp b/platforms/cpu/src/CpuRandom.cpp index a06282492..f2389f60b 100644 --- a/platforms/cpu/src/CpuRandom.cpp +++ b/platforms/cpu/src/CpuRandom.cpp @@ -23,8 +23,8 @@ */ #include "CpuRandom.h" +#include "openmm/internal/OSRngSeed.h" #include "openmm/OpenMMException.h" -#include "openmm/OSRngSeed.h" #include using namespace std; -- GitLab From d422c30687beffa45fce4d671b611f78f326b8f7 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 10 Jan 2015 09:36:55 -0500 Subject: [PATCH 203/338] Change comments so that it does not reference generating seeds from the clock. --- openmmapi/include/openmm/AndersenThermostat.h | 6 +++--- openmmapi/include/openmm/BrownianIntegrator.h | 6 +++--- openmmapi/include/openmm/CustomIntegrator.h | 6 +++--- openmmapi/include/openmm/LangevinIntegrator.h | 6 +++--- openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h | 6 +++--- openmmapi/include/openmm/MonteCarloBarostat.h | 6 +++--- openmmapi/include/openmm/MonteCarloMembraneBarostat.h | 6 +++--- openmmapi/include/openmm/VariableLangevinIntegrator.h | 6 +++--- openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp | 2 +- openmmapi/src/MonteCarloBarostatImpl.cpp | 2 +- openmmapi/src/MonteCarloMembraneBarostatImpl.cpp | 2 +- platforms/cpu/src/CpuRandom.cpp | 2 +- platforms/cuda/src/CudaKernels.cpp | 2 +- platforms/opencl/src/OpenCLIntegrationUtilities.cpp | 2 +- platforms/opencl/src/OpenCLKernels.cpp | 2 +- .../reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp | 2 +- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/openmmapi/include/openmm/AndersenThermostat.h b/openmmapi/include/openmm/AndersenThermostat.h index e5253aae0..735e17c43 100644 --- a/openmmapi/include/openmm/AndersenThermostat.h +++ b/openmmapi/include/openmm/AndersenThermostat.h @@ -115,9 +115,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/BrownianIntegrator.h b/openmmapi/include/openmm/BrownianIntegrator.h index 88a76ef86..7d8e5dfd4 100644 --- a/openmmapi/include/openmm/BrownianIntegrator.h +++ b/openmmapi/include/openmm/BrownianIntegrator.h @@ -100,9 +100,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/CustomIntegrator.h b/openmmapi/include/openmm/CustomIntegrator.h index ad9390296..dcf842917 100644 --- a/openmmapi/include/openmm/CustomIntegrator.h +++ b/openmmapi/include/openmm/CustomIntegrator.h @@ -445,9 +445,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/LangevinIntegrator.h b/openmmapi/include/openmm/LangevinIntegrator.h index 9ce6dc6df..27bb6beea 100644 --- a/openmmapi/include/openmm/LangevinIntegrator.h +++ b/openmmapi/include/openmm/LangevinIntegrator.h @@ -100,9 +100,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h index 7308b83a4..8c355366f 100644 --- a/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h +++ b/openmmapi/include/openmm/MonteCarloAnisotropicBarostat.h @@ -168,9 +168,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloBarostat.h b/openmmapi/include/openmm/MonteCarloBarostat.h index 41fac19b1..9ab73be32 100644 --- a/openmmapi/include/openmm/MonteCarloBarostat.h +++ b/openmmapi/include/openmm/MonteCarloBarostat.h @@ -124,9 +124,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h index 1265818c9..f3f87ca41 100644 --- a/openmmapi/include/openmm/MonteCarloMembraneBarostat.h +++ b/openmmapi/include/openmm/MonteCarloMembraneBarostat.h @@ -221,9 +221,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/include/openmm/VariableLangevinIntegrator.h b/openmmapi/include/openmm/VariableLangevinIntegrator.h index 622979ba6..1ed3f6574 100644 --- a/openmmapi/include/openmm/VariableLangevinIntegrator.h +++ b/openmmapi/include/openmm/VariableLangevinIntegrator.h @@ -122,9 +122,9 @@ public: * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. * - * If seed is set to 0 (which is the default value assigned), a new seed is generated from the system - * clock when a Context is created from this Force. This is done to ensure that each Context receives - * unique random seeds without you needing to set them explicitly. + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp b/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp index cb8b24827..407011486 100644 --- a/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloAnisotropicBarostatImpl.cpp @@ -62,7 +62,7 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) { numAccepted[i] = 0; } int randSeed = owner.getRandomNumberSeed(); - // A random seed of 0 means pull a new one from the clock + // A random seed of 0 means use a unique one if (randSeed == 0) randSeed = osrngseed(); init_gen_rand(randSeed, random); } diff --git a/openmmapi/src/MonteCarloBarostatImpl.cpp b/openmmapi/src/MonteCarloBarostatImpl.cpp index 82f38b9cf..2ad44ee28 100644 --- a/openmmapi/src/MonteCarloBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloBarostatImpl.cpp @@ -60,7 +60,7 @@ void MonteCarloBarostatImpl::initialize(ContextImpl& context) { numAttempted = 0; numAccepted = 0; int randSeed = owner.getRandomNumberSeed(); - // A random seed of 0 means pull a new one from the clock + // A random seed of 0 means use a unique one if (randSeed == 0) randSeed = osrngseed(); init_gen_rand(randSeed, random); } diff --git a/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp index 4028a82fd..044658d61 100644 --- a/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp +++ b/openmmapi/src/MonteCarloMembraneBarostatImpl.cpp @@ -62,7 +62,7 @@ void MonteCarloMembraneBarostatImpl::initialize(ContextImpl& context) { numAccepted[i] = 0; } int randSeed = owner.getRandomNumberSeed(); - // A random seed of 0 means pull a new one from the clock + // A random seed of 0 means use a unique one if (randSeed == 0) randSeed = osrngseed(); init_gen_rand(randSeed, random); } diff --git a/platforms/cpu/src/CpuRandom.cpp b/platforms/cpu/src/CpuRandom.cpp index f2389f60b..9814c9ce2 100644 --- a/platforms/cpu/src/CpuRandom.cpp +++ b/platforms/cpu/src/CpuRandom.cpp @@ -51,7 +51,7 @@ void CpuRandom::initialize(int seed, int numThreads) { nextGaussianIsValid.resize(numThreads, false); /* Use a quick and dirty RNG to pick seeds for the real random number generator. - * A random seed of 0 means pick a new random seed based on wall clock + * A random seed of 0 means pick a unique seed */ unsigned int r = (unsigned int) seed; diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index ce2aa677f..1ea57b720 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -5969,7 +5969,7 @@ void CudaIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context, randomSeed = CudaArray::create(cu, cu.getNumThreadBlocks()*CudaContext::ThreadBlockSize, "randomSeed"); vector seed(randomSeed->getSize()); int rseed = integrator.getRandomNumberSeed(); - // A random seed of 0 means generate a new one from the wall clock + // A random seed of 0 means use a unique one if (rseed == 0) rseed = osrngseed(); unsigned int r = (unsigned int) (rseed+1); diff --git a/platforms/opencl/src/OpenCLIntegrationUtilities.cpp b/platforms/opencl/src/OpenCLIntegrationUtilities.cpp index f619da473..24be42646 100644 --- a/platforms/opencl/src/OpenCLIntegrationUtilities.cpp +++ b/platforms/opencl/src/OpenCLIntegrationUtilities.cpp @@ -1004,7 +1004,7 @@ void OpenCLIntegrationUtilities::initRandomNumberGenerator(unsigned int randomNu vector seed(randomSeed->getSize()); unsigned int r = randomNumberSeed; - // A seed of 0 means pull one from the clock + // A seed of 0 means use a unique one if (r == 0) r = (unsigned int) osrngseed(); for (int i = 0; i < randomSeed->getSize(); i++) { seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 197f16261..3b96aa4e2 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -6202,7 +6202,7 @@ void OpenCLIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context randomSeed = OpenCLArray::create(cl, cl.getNumThreadBlocks()*OpenCLContext::ThreadBlockSize, "randomSeed"); vector seed(randomSeed->getSize()); int rseed = integrator.getRandomNumberSeed(); - // A random seed of 0 means generate a new one from the wall clock + // A random seed of 0 means use a unique one if (rseed == 0) rseed = osrngseed(); unsigned int r = (unsigned int) (rseed+1); diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp index 1fef5c137..ba7511dde 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp @@ -362,7 +362,7 @@ void SimTKOpenMMUtilities::setRandomNumberSeed( uint32_t seed ) { // --------------------------------------------------------------------------------------- - // If the seed is 0, generate one from the clock + // If the seed is 0, use a unique seed if (seed == 0) _randomNumberSeed = (uint32_t) osrngseed(); else -- GitLab From be8bd376c5980733a8dafd01e67598f2fa59f2ce Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 10 Jan 2015 09:39:06 -0500 Subject: [PATCH 204/338] The Drude and RPMD plugins both also use random numbers -- change default seed to 0 here as well. --- .../drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h | 4 ++++ plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp | 3 +-- plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h | 4 ++++ plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp | 5 ++--- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/plugins/drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h b/plugins/drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h index fa0793f0c..cbccb5fc5 100644 --- a/plugins/drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h +++ b/plugins/drude/openmmapi/include/openmm/DrudeLangevinIntegrator.h @@ -142,6 +142,10 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp b/plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp index 806dbef2b..0df7f5f14 100644 --- a/plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp +++ b/plugins/drude/openmmapi/src/DrudeLangevinIntegrator.cpp @@ -33,7 +33,6 @@ #include "openmm/Context.h" #include "openmm/OpenMMException.h" #include "openmm/internal/ContextImpl.h" -#include "openmm/internal/OSRngSeed.h" #include "openmm/DrudeKernels.h" #include #include @@ -49,7 +48,7 @@ DrudeLangevinIntegrator::DrudeLangevinIntegrator(double temperature, double fric setDrudeFriction(drudeFrictionCoeff); setStepSize(stepSize); setConstraintTolerance(1e-5); - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } void DrudeLangevinIntegrator::initialize(ContextImpl& contextRef) { diff --git a/plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h b/plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h index 477085e09..b8037e595 100644 --- a/plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h +++ b/plugins/rpmd/openmmapi/include/openmm/RPMDIntegrator.h @@ -155,6 +155,10 @@ public: * the other hand, no guarantees are made about the behavior of simulations that use the same seed. * In particular, Platforms are permitted to use non-deterministic algorithms which produce different * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. */ void setRandomNumberSeed(int seed) { randomNumberSeed = seed; diff --git a/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp b/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp index d6fcfc88a..a705be1e5 100644 --- a/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp +++ b/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp @@ -33,7 +33,6 @@ #include "openmm/Context.h" #include "openmm/OpenMMException.h" #include "openmm/internal/ContextImpl.h" -#include "openmm/internal/OSRngSeed.h" #include "openmm/RpmdKernels.h" #include "SimTKOpenMMRealType.h" #include @@ -48,7 +47,7 @@ RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictio setFriction(frictionCoeff); setStepSize(stepSize); setConstraintTolerance(1e-5); - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictionCoeff, double stepSize) : @@ -57,7 +56,7 @@ RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictio setFriction(frictionCoeff); setStepSize(stepSize); setConstraintTolerance(1e-5); - setRandomNumberSeed(osrngseed()); + setRandomNumberSeed(0); } void RPMDIntegrator::initialize(ContextImpl& contextRef) { -- GitLab From 40632e11b620956bff44841f1182e5256ddf503a Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 12 Jan 2015 00:54:03 -0800 Subject: [PATCH 205/338] bytes issue --- .../swig_doxygen/swig_lib/python/pythoncode.i | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i index 475200935..c9e5db8a8 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i @@ -9,6 +9,10 @@ import sys import math RMIN_PER_SIGMA=math.pow(2, 1/6.0) RVDW_PER_SIGMA=math.pow(2, 1/6.0)/2.0 +if sys.version_info[0] == 2: + _string_types = (basestring,) +else: + _string_types = (bytes, str) import simtk.unit as unit from simtk.openmm.vec3 import Vec3 @@ -19,7 +23,7 @@ class State(_object): current state of a simulation at a point in time. You create it by calling getState() on a Context. - + When a State is created, you specify what information should be stored in it. This saves time and memory by only copying in @@ -103,7 +107,7 @@ class State(_object): returnValue = unit.Quantity(returnValue, unit.nanometers) return returnValue - + def getPeriodicBoxVolume(self): """Get the volume of the periodic box.""" a = self._periodicBoxVectorsList[0] @@ -215,28 +219,9 @@ class State(_object): return self._paramMap -# Strings can cause trouble -# as can any container that has infinite levels of containment -def _is_string(x): - # step 1) String is always a container - # and its contents are themselves containers. - try: - first_item = iter(x).next() - inner_item = iter(first_item).next() - if first_item == inner_item: - return True - else: - return False - except TypeError: - return False - except StopIteration: - return False - except ValueError: - return False - def stripUnits(args): """ - getState(self, quantity) + getState(self, quantity) -> value with *no* units Examples @@ -282,13 +267,13 @@ def stripUnits(args): if arg.unit.is_compatible(unit.bar): arg = arg / unit.bar else: - arg=arg.value_in_unit_system(unit.md_unit_system) + arg = arg.value_in_unit_system(unit.md_unit_system) # JDC: End workaround. elif isinstance(arg, dict): newKeys = stripUnits(arg.keys()) newValues = stripUnits(arg.values()) arg = dict(zip(newKeys, newValues)) - elif not _is_string(arg): + elif not isinstance(arg, _string_types): try: iter(arg) # Reclusively strip units from all quantities -- GitLab From e197379cd131b9dc8605650f28a3a5cb93013811 Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 12 Jan 2015 00:55:18 -0800 Subject: [PATCH 206/338] that statement doesn't do anything --- wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i | 1 - 1 file changed, 1 deletion(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i index c9e5db8a8..67f22e089 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/pythoncode.i @@ -275,7 +275,6 @@ def stripUnits(args): arg = dict(zip(newKeys, newValues)) elif not isinstance(arg, _string_types): try: - iter(arg) # Reclusively strip units from all quantities arg=stripUnits(arg) except TypeError: -- GitLab From 7a4b3601df1d904c8ec58a74b8d8c53ed6e12f7e Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 12 Jan 2015 01:11:05 -0800 Subject: [PATCH 207/338] Fix typemap for str/bytes -> std::string --- .../swig_doxygen/swig_lib/python/typemaps.i | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i b/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i index a002a7f3a..8524d89d8 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i @@ -43,7 +43,7 @@ int i, n; PyObject *pyList; - n=(*$1).size(); + n=(*$1).size(); pyList=PyList_New(n); PyObject* mm = PyImport_AddModule("simtk.openmm"); PyObject* vec3 = PyObject_GetAttrString(mm, "Vec3"); @@ -169,11 +169,10 @@ $result = PyBytes_FromStringAndSize($1.c_str(), $1.length()); } - -%typemap(in) std::string { - // if we have a C++ method that takes in a std::string, we're most happy to accept - // a python bytes object. But if the user passes in a unicode object we'll try - // to recover by encoding it to UTF-8 bytes +%typemap(in) const std::string & { + // if we have a C++ method that takes in a std::string, we're most happy to + // accept a python bytes object. But if the user passes in a unicode object + // we'll try to recover by encoding it to UTF-8 bytes PyObject* temp = NULL; char* c_str = NULL; Py_ssize_t len = 0; @@ -181,19 +180,24 @@ if (PyUnicode_Check($input)) { temp = PyUnicode_AsUTF8String($input); if (temp == NULL) { - SWIG_exception_fail(SWIG_TypeError, "'utf-8' codec can't decode byte"); + SWIG_exception_fail(SWIG_TypeError, "$symname: 'utf-8' codec can't decode byte"); } PyBytes_AsStringAndSize(temp, &c_str, &len); Py_XDECREF(temp); } else if (PyBytes_Check($input)) { PyBytes_AsStringAndSize($input, &c_str, &len); } else { - SWIG_exception_fail(SWIG_TypeError, "argument must be str or bytes"); + SWIG_exception_fail(SWIG_TypeError, "$symname: argument must be str or bytes"); } if (c_str == NULL) { - SWIG_exception_fail(SWIG_TypeError, "argument must be str or bytes"); + SWIG_exception_fail(SWIG_TypeError, "$symname: argument must be str or bytes"); } - $1 = std::string(c_str, len); -} \ No newline at end of file + std::string temp2(c_str, len); + $1 = &temp2; +} + +%typemap(freearg) const std::string & { + // Don't delete me +} -- GitLab From 1d450fd8b8d3d54c568a0feba0657be54d3b4bf8 Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 12 Jan 2015 11:05:19 -0800 Subject: [PATCH 208/338] .message -> str() --- wrappers/python/simtk/testInstallation.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wrappers/python/simtk/testInstallation.py b/wrappers/python/simtk/testInstallation.py index 66ec2efad..73d4c0f7c 100644 --- a/wrappers/python/simtk/testInstallation.py +++ b/wrappers/python/simtk/testInstallation.py @@ -6,7 +6,7 @@ import sys class TestingError(Exception): """ - An error is encountered when + An error is encountered when """ pass @@ -16,7 +16,7 @@ try: from simtk.unit import * except ImportError as err: simtk_import_failed = True - simtk_import_error = err.message + simtk_import_error = str(err) else: simtk_import_failed = False @@ -59,9 +59,9 @@ def run_tests(): pdb = PDBFile(os.path.join(data_dir, 'test.pdb')) forcefield = ForceField('amber99sb.xml', 'tip3p.xml') system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) - + # List all installed platforms and compute forces with each one. - + numPlatforms = Platform.getNumPlatforms() print("There are", numPlatforms, "Platforms available:") print() @@ -80,15 +80,15 @@ def run_tests(): except: print("- Error computing forces with", platform.getName(), "platform") platformErrors[platform.getName()] = sys.exc_info()[1] - + # Give details of any errors. - + for platform in platformErrors: print() print("%s platform error: %s" % (platform, platformErrors[platform])) - + # See how well the platforms agree. - + if numPlatforms > 1: print() print("Median difference in forces between platforms:") -- GitLab From 29856d18a60152674b21946bdf0b3ab6e3e23cc6 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 12 Jan 2015 14:40:59 -0800 Subject: [PATCH 209/338] Fixed bug in reference CustomCompoundBondForce --- .../src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp index bc797e3d8..19e5287d7 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2009-2010 Stanford University and Simbios. +/* Portions copyright (c) 2009-2015 Stanford University and Simbios. * Contributors: Peter Eastman * * Permission is hereby granted, free of charge, to any person obtaining @@ -127,7 +127,7 @@ void ReferenceCustomCompoundBondIxn::calculateOneIxn(int bond, vector& const vector& atoms = bondAtoms[bond]; for (int i = 0; i < (int) particleTerms.size(); i++) { const ParticleTermInfo& term = particleTerms[i]; - variables[term.name] = atomCoordinates[term.atom][term.component]; + variables[term.name] = atomCoordinates[atoms[term.atom]][term.component]; } for (int i = 0; i < (int) distanceTerms.size(); i++) { const DistanceTermInfo& term = distanceTerms[i]; -- GitLab From 5ae844b2882b345f18c259a7ac33d12f8d79afb3 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 12 Jan 2015 14:48:28 -0800 Subject: [PATCH 210/338] Updated test cases to catch a bug that was just fixed --- .../cuda/tests/TestCudaCustomCompoundBondForce.cpp | 14 +++++++------- .../tests/TestOpenCLCustomCompoundBondForce.cpp | 14 +++++++------- .../tests/TestReferenceCustomCompoundBondForce.cpp | 14 +++++++------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/platforms/cuda/tests/TestCudaCustomCompoundBondForce.cpp b/platforms/cuda/tests/TestCudaCustomCompoundBondForce.cpp index 4afa84c88..fdd61f61b 100644 --- a/platforms/cuda/tests/TestCudaCustomCompoundBondForce.cpp +++ b/platforms/cuda/tests/TestCudaCustomCompoundBondForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2012 Stanford University and the Authors. * + * Portions copyright (c) 2012-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -152,21 +152,21 @@ void testPositionDependence() { custom->addGlobalParameter("scale1", 0.3); custom->addGlobalParameter("scale2", 0.2); vector particles(2); - particles[0] = 0; - particles[1] = 1; + particles[0] = 1; + particles[1] = 0; vector parameters; custom->addBond(particles, parameters); customSystem.addForce(custom); vector positions(2); - positions[0] = Vec3(0.5, 1, 0); - positions[1] = Vec3(1.5, 1, 0); + positions[0] = Vec3(1.5, 1, 0); + positions[1] = Vec3(0.5, 1, 0); VerletIntegrator integrator(0.01); Context context(customSystem, integrator, platform); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); ASSERT_EQUAL_TOL(0.3*1.0+0.2*0.5+2*1, state.getPotentialEnergy(), 1e-5); - ASSERT_EQUAL_VEC(Vec3(0.3-0.2, 0, 0), state.getForces()[0], 1e-5); - ASSERT_EQUAL_VEC(Vec3(-0.3, -2, 0), state.getForces()[1], 1e-5); + ASSERT_EQUAL_VEC(Vec3(-0.3, -2, 0), state.getForces()[0], 1e-5); + ASSERT_EQUAL_VEC(Vec3(0.3-0.2, 0, 0), state.getForces()[1], 1e-5); } void testParallelComputation() { diff --git a/platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp b/platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp index e5cfdbe6c..8e7d6fd82 100644 --- a/platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp +++ b/platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2012 Stanford University and the Authors. * + * Portions copyright (c) 2012-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -152,21 +152,21 @@ void testPositionDependence() { custom->addGlobalParameter("scale1", 0.3); custom->addGlobalParameter("scale2", 0.2); vector particles(2); - particles[0] = 0; - particles[1] = 1; + particles[0] = 1; + particles[1] = 0; vector parameters; custom->addBond(particles, parameters); customSystem.addForce(custom); vector positions(2); - positions[0] = Vec3(0.5, 1, 0); - positions[1] = Vec3(1.5, 1, 0); + positions[0] = Vec3(1.5, 1, 0); + positions[1] = Vec3(0.5, 1, 0); VerletIntegrator integrator(0.01); Context context(customSystem, integrator, platform); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); ASSERT_EQUAL_TOL(0.3*1.0+0.2*0.5+2*1, state.getPotentialEnergy(), 1e-5); - ASSERT_EQUAL_VEC(Vec3(0.3-0.2, 0, 0), state.getForces()[0], 1e-5); - ASSERT_EQUAL_VEC(Vec3(-0.3, -2, 0), state.getForces()[1], 1e-5); + ASSERT_EQUAL_VEC(Vec3(-0.3, -2, 0), state.getForces()[0], 1e-5); + ASSERT_EQUAL_VEC(Vec3(0.3-0.2, 0, 0), state.getForces()[1], 1e-5); } void testParallelComputation() { diff --git a/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp b/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp index d70cd07f3..a1738e603 100644 --- a/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2012 Stanford University and the Authors. * + * Portions copyright (c) 2012-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -153,21 +153,21 @@ void testPositionDependence() { custom->addGlobalParameter("scale1", 0.3); custom->addGlobalParameter("scale2", 0.2); vector particles(2); - particles[0] = 0; - particles[1] = 1; + particles[0] = 1; + particles[1] = 0; vector parameters; custom->addBond(particles, parameters); customSystem.addForce(custom); vector positions(2); - positions[0] = Vec3(0.5, 1, 0); - positions[1] = Vec3(1.5, 1, 0); + positions[0] = Vec3(1.5, 1, 0); + positions[1] = Vec3(0.5, 1, 0); VerletIntegrator integrator(0.01); Context context(customSystem, integrator, platform); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); ASSERT_EQUAL_TOL(0.3*1.0+0.2*0.5+2*1, state.getPotentialEnergy(), 1e-5); - ASSERT_EQUAL_VEC(Vec3(0.3-0.2, 0, 0), state.getForces()[0], 1e-5); - ASSERT_EQUAL_VEC(Vec3(-0.3, -2, 0), state.getForces()[1], 1e-5); + ASSERT_EQUAL_VEC(Vec3(-0.3, -2, 0), state.getForces()[0], 1e-5); + ASSERT_EQUAL_VEC(Vec3(0.3-0.2, 0, 0), state.getForces()[1], 1e-5); } void testContinuous2DFunction() { -- GitLab From 21bf9597b8fb24fbf463705de2caea2fb7495a29 Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Mon, 12 Jan 2015 16:59:13 -0800 Subject: [PATCH 211/338] might fix segfault --- wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i b/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i index 8524d89d8..0f9316840 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i @@ -169,7 +169,7 @@ $result = PyBytes_FromStringAndSize($1.c_str(), $1.length()); } -%typemap(in) const std::string & { +%typemap(in) const std::string & (std::string temp2) { // if we have a C++ method that takes in a std::string, we're most happy to // accept a python bytes object. But if the user passes in a unicode object // we'll try to recover by encoding it to UTF-8 bytes @@ -194,10 +194,10 @@ SWIG_exception_fail(SWIG_TypeError, "$symname: argument must be str or bytes"); } - std::string temp2(c_str, len); + temp2 = std::string(c_str, len); $1 = &temp2; } %typemap(freearg) const std::string & { - // Don't delete me + // pass } -- GitLab From 2f42ac0a06a47aa7a36accbc1c944a540865e521 Mon Sep 17 00:00:00 2001 From: "Robert T. McGibbon" Date: Tue, 13 Jan 2015 23:17:08 +0000 Subject: [PATCH 212/338] Some windows changes --- wrappers/python/simtk/openmm/__init__.py | 13 +++++++- .../swig_doxygen/swig_lib/python/typemaps.i | 33 ------------------- 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/wrappers/python/simtk/openmm/__init__.py b/wrappers/python/simtk/openmm/__init__.py index 7e47b1103..942fe8d33 100644 --- a/wrappers/python/simtk/openmm/__init__.py +++ b/wrappers/python/simtk/openmm/__init__.py @@ -10,11 +10,22 @@ It also tries to load any plugin modules it can find. __author__ = "Randall J. Radmer" import os, os.path +import sys +from simtk.openmm import version + +if sys.platform == 'win32': + _path = os.environ['PATH'] + os.environ['PATH'] = '%(lib)s;%(lib)s\plugins' % {'lib': version.openmm_library_path} + from simtk.openmm.openmm import * from simtk.openmm.vec3 import Vec3 -from simtk.openmm import version + if os.getenv('OPENMM_PLUGIN_DIR') is None and os.path.isdir(version.openmm_library_path): pluginLoadedLibNames = Platform.loadPluginsFromDirectory(os.path.join(version.openmm_library_path, 'plugins')) else: pluginLoadedLibNames = Platform.loadPluginsFromDirectory(Platform.getDefaultPluginsDirectory()) + +if sys.platform == 'win32': + os.environ['PATH'] = _path + del _path __version__ = Platform.getOpenMMVersion() diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i b/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i index 0f9316840..709d2c095 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/typemaps.i @@ -168,36 +168,3 @@ // createCheckpoint returns a bytes object $result = PyBytes_FromStringAndSize($1.c_str(), $1.length()); } - -%typemap(in) const std::string & (std::string temp2) { - // if we have a C++ method that takes in a std::string, we're most happy to - // accept a python bytes object. But if the user passes in a unicode object - // we'll try to recover by encoding it to UTF-8 bytes - PyObject* temp = NULL; - char* c_str = NULL; - Py_ssize_t len = 0; - - if (PyUnicode_Check($input)) { - temp = PyUnicode_AsUTF8String($input); - if (temp == NULL) { - SWIG_exception_fail(SWIG_TypeError, "$symname: 'utf-8' codec can't decode byte"); - } - PyBytes_AsStringAndSize(temp, &c_str, &len); - Py_XDECREF(temp); - } else if (PyBytes_Check($input)) { - PyBytes_AsStringAndSize($input, &c_str, &len); - } else { - SWIG_exception_fail(SWIG_TypeError, "$symname: argument must be str or bytes"); - } - - if (c_str == NULL) { - SWIG_exception_fail(SWIG_TypeError, "$symname: argument must be str or bytes"); - } - - temp2 = std::string(c_str, len); - $1 = &temp2; -} - -%typemap(freearg) const std::string & { - // pass -} -- GitLab From d05092476e8bd2c4be22c089476d0a013590baeb Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Wed, 14 Jan 2015 11:57:26 -0800 Subject: [PATCH 213/338] append to path instead --- wrappers/python/simtk/openmm/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/__init__.py b/wrappers/python/simtk/openmm/__init__.py index 942fe8d33..3092e3e27 100644 --- a/wrappers/python/simtk/openmm/__init__.py +++ b/wrappers/python/simtk/openmm/__init__.py @@ -15,7 +15,7 @@ from simtk.openmm import version if sys.platform == 'win32': _path = os.environ['PATH'] - os.environ['PATH'] = '%(lib)s;%(lib)s\plugins' % {'lib': version.openmm_library_path} + os.environ['PATH'] += '%(lib)s;%(lib)s\plugins' % {'lib': version.openmm_library_path} from simtk.openmm.openmm import * from simtk.openmm.vec3 import Vec3 -- GitLab From 3b2579a5fd04d21e5f4aefd23922bbc2a19612c3 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 14 Jan 2015 14:27:34 -0800 Subject: [PATCH 214/338] Removed some unneeded code --- platforms/cuda/src/kernels/pme.cu | 7 +------ platforms/opencl/src/kernels/pme.cl | 3 --- platforms/reference/src/SimTKReference/ReferencePME.cpp | 2 -- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/platforms/cuda/src/kernels/pme.cu b/platforms/cuda/src/kernels/pme.cu index 4dd21a6c5..710f85c46 100644 --- a/platforms/cuda/src/kernels/pme.cu +++ b/platforms/cuda/src/kernels/pme.cu @@ -4,9 +4,6 @@ extern "C" __global__ void findAtomGridIndex(const real4* __restrict__ posq, int for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { real4 pos = posq[i]; - pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; real3 t = make_real3(pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, pos.z*recipBoxVecZ.z); @@ -30,8 +27,6 @@ extern "C" __global__ void gridSpreadCharge(const real4* __restrict__ posq, real for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int atom = pmeAtomGridIndex[i].x; - real charge = posq[atom].w; - real3 force = make_real3(0); real4 pos = posq[atom]; pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; @@ -84,7 +79,7 @@ extern "C" __global__ void gridSpreadCharge(const real4* __restrict__ posq, real zindex -= (zindex >= GRID_SIZE_Z ? GRID_SIZE_Z : 0); int index = ybase + zindex; - real add = charge*dx*dy*data[iz].z; + real add = pos.w*dx*dy*data[iz].z; #ifdef USE_DOUBLE_PRECISION unsigned long long * ulonglong_p = (unsigned long long *) originalPmeGrid; atomicAdd(&ulonglong_p[index], static_cast((long long) (add*0x100000000))); diff --git a/platforms/opencl/src/kernels/pme.cl b/platforms/opencl/src/kernels/pme.cl index 030d1f211..563a53492 100644 --- a/platforms/opencl/src/kernels/pme.cl +++ b/platforms/opencl/src/kernels/pme.cl @@ -4,9 +4,6 @@ __kernel void updateBsplines(__global const real4* restrict posq, __global real4 for (int i = get_global_id(0); i < NUM_ATOMS; i += get_global_size(0)) { __local real4* data = &bsplinesCache[get_local_id(0)*PME_ORDER]; real4 pos = posq[i]; - pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; real3 t = (real3) (pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x, pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y, pos.z*recipBoxVecZ.z); diff --git a/platforms/reference/src/SimTKReference/ReferencePME.cpp b/platforms/reference/src/SimTKReference/ReferencePME.cpp index b5d89327f..df9ef153f 100644 --- a/platforms/reference/src/SimTKReference/ReferencePME.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePME.cpp @@ -252,8 +252,6 @@ pme_update_grid_index_and_fraction(pme_t pme, * (And, by adding 100.0 box lengths, we would lose a bit of numerical accuracy here!) */ RealVec coord = atomCoordinates[i]; - for(d=0;d<3;d++) - coord[d] -= floor(coord[d]*recipBoxVectors[d][d])*periodicBoxVectors[d][d]; for(d=0;d<3;d++) { t = coord[0]*recipBoxVectors[0][d]+coord[1]*recipBoxVectors[1][d]+coord[2]*recipBoxVectors[2][d]; -- GitLab From c2191b6138ba7266ca625a922d1fb01e828a7764 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 15 Jan 2015 13:17:32 -0500 Subject: [PATCH 215/338] Add a section at the end of the manual about stochastic forces, integrators, and random numbers. Add 2 citations about Langevin synchronization. Convert the references.bib file to UNIX line endings. --- docs-source/usersguide/references.bib | 922 +++++++++++++------------- docs-source/usersguide/theory.rst | 62 ++ 2 files changed, 537 insertions(+), 447 deletions(-) diff --git a/docs-source/usersguide/references.bib b/docs-source/usersguide/references.bib index c7b07c9cd..81360064a 100644 --- a/docs-source/usersguide/references.bib +++ b/docs-source/usersguide/references.bib @@ -1,447 +1,475 @@ -@article{Andersen1980 - author = {Andersen, Hans C.}, - title = {Molecular dynamics simulations at constant pressure and/or temperature}, - journal = {Journal of Chemical Physics}, - volume = {72}, - number = {4}, - pages = {2384-2393}, - year = {1980}, - type = {Journal Article} -} - -@article{Aqvist2004 - author = {Ã…qvist, Johan and Wennerström, Petra and Nervall, Martin and Bjelic, Sinisa and Brandsdal, Bjørn O.}, - title = {Molecular dynamics simulations of water and biomolecules with a {Monte Carlo} constant pressure algorithm}, - journal = {Chemical Physics Letters}, - volume = {384}, - pages = {288-294}, - year = {2004}, - type = {Journal Article} -} - -@article{Berendsen1987 - author = {Berendsen, H. J. C. and Grigera, J. R. and Straatsma, T. P.}, - title = {The missing term in effective pair potentials}, - journal = {Journal of Physical Chemistry}, - volume = {91}, - pages = {6269-6271}, - year = {1987}, - type = {Journal Article} -} - -@article{Ceriotti2010 - author = {Ceriotti, M. and Parrinello, M. and Markland, Thomas E. and Manolopoulos, David E.}, - title = {Efficient stochastic thermostatting of path integral molecular dynamics}, - journal = {Journal of Chemical Physics}, - volume = {133}, - number = {12}, - year = {2010}, - type = {Journal Article} -} - -@article{Chow1995 - author = {Chow, Kim-Hung and Ferguson, David M.}, - title = {Isothermal-isobaric molecular dynamics simulations with {Monte Carlo} volume sampling}, - journal = {Computer Physics Communications}, - volume = {91}, - pages = {283-289}, - year = {1995}, - type = {Journal Article} -} - -@article{Craig2004 - author = {Craig, I. R. and Manolopoulos, David E.}, - title = {Quantum statistics and classical mechanics: Real time correlation functions from ring polymer molecular dynamics}, - journal = {Journal of Chemical Physics}, - volume = {121}, - pages = {3368-3373}, - year = {2004}, - type = {Journal Article} -} - -@article{Duan2003 - author = {Duan, Y.; Wu, C. and Chowdhury, S. and Lee, M.C. and Xiong, G. and Zhang, W. and Yang, R. and Cieplak, P. and Luo, R. and Lee, T.}, - title = {A point-charge force field for molecular mechanics simulations of proteins based on condensed-phase quantum mechanical calculations}, - journal = {Journal of Computational Chemistry}, - volume = {24}, - pages = {1999-2012}, - year = {2003}, - type = {Journal Article} -} - -@article{Essmann1995 - author = {Essmann, Ulrich and Perera, Lalith and Berkowitz, Max L. and Darden, Tom and Lee, Hsing and Pedersen, Lee G.}, - title = {A smooth particle mesh {Ewald} method}, - journal = {Journal of Chemical Physics}, - volume = {103}, - number = {19}, - pages = {8577-8593}, - year = {1995}, - type = {Journal Article} -} - -@article{Hall1984 - author = {Hall, Randall W. and Berne, B. J.}, - title = {Nonergodicity in path integral molecular dynamics}, - journal = {Journal of Chemical Physics}, - volume = {81}, - number = {8}, - year = {1984}, - type = {Journal Article} -} - -@article{Hawkins1995 - author = {Hawkins, Gregory D. and Cramer, Christopher J. and Truhlar, Donald G.}, - title = {Pairwise solute descreening of solute charges from a dielectric medium}, - journal = {Chemical Physics Letters}, - volume = {246}, - number = {1-2}, - pages = {122-129}, - year = {1995}, - type = {Journal Article} -} - -@article{Horn2004 - author = {Horn, Hans W. and Swope, William C. and Pitera, Jed W. and Madura, Jeffry D. and Dick, Thomas J. and Hura, Greg L. and Head-Gordon, Teresa}, - title = {Development of an improved four-site water model for biomolecular simulations: {TIP4P-Ew}}, - journal = {Journal of Chemical Physics}, - volume = {120}, - pages = {9665-9678}, - year = {2004}, - type = {Journal Article} -} - -@article{Hornak2006 - author = {Hornak, V. and Abel, R. and Okur, A. and Strockbine, B. and Roitberg, A. and Simmerling, C.}, - title = {Comparison of multiple {Amber} force fields and development of improved protein backbone parameters}, - journal = {Proteins}, - volume = {65}, - pages = {712-725}, - year = {2006}, - type = {Journal Article} -} - -@article{Izaguirre2010 - author = {Izaguirre, Jesús A. and Sweet, Chris R. and Pande, Vijay S.}, - title = {Multiscale dynamics of macromolecules using {Normal Mode Langevin}}, - journal = {Pacific Symposium on Biocomputing}, - volume = {15}, - pages = {240-251}, - year = {2010}, - type = {Journal Article} -} - -@article{Jorgensen1983 - author = {Jorgensen, William L. and Chandrasekhar, Jayaraman and Madura, Jeffry D. and Impey, Roger W. and Klein, Michael L.}, - title = {Comparison of simple potential functions for simulating liquid water}, - journal = {Journal of Chemical Physics}, - volume = {79}, - pages = {926-935}, - year = {1983}, - type = {Journal Article} -} - -@inbook{Kollman1997 - author = {Kollman, P.A. and Dixon, R. and Cornell, W. and Fox, T. and Chipot, C. and Pohorille, A.}, - title = {Computer Simulation of Biomolecular Systems}, - editor = {Wilkinson, A. and Weiner, P. and van Gunsteren, Wilfred F.}, - publisher = {Elsevier}, - volume = {3}, - pages = {83-96}, - year = {1997}, - type = {Book Section} -} - -@article{Labute2008 - author = {Labute, Paul}, - title = {The generalized {Born}/volume integral implicit solvent model: Estimation of the free energy of hydration using {London} dispersion instead of atomic surface area}, - journal = {Journal of Computational Chemistry}, - volume = {29}, - number = {10}, - pages = {1693-1698}, - year = {2008}, - type = {Journal Article} -} - -@article{Lamoureux2006 - author = {Lamoureux, Guillaume and Harder, Edward and Vorobyov, Igor V. and Roux, Benoit and MacKerell Jr., Alexander D.}, - title = {A polarizable model of water for molecular dynamics simulations of biomolecules}, - journal = {Chemical Physics Letters}, - volume = {418}, - number = {1-3}, - pages = {245-249}, - year = {2006}, - type = {Journal Article} -} - -@article{Lamoureux2003 - author = {Lamoureux, Guillaume and Roux, Benoit}, - title = {Modeling induced polarization with classical {Drude} oscillators: Theory and molecular dynamics simulation algorithm}, - journal = {Journal of Chemical Physics}, - volume = {119}, - number = {6}, - pages = {3025-3039}, - year = {2003}, - type = {Journal Article} -} - -@article{Li2010 - author = {Li, D.W. and Br{\"u}schweiler, R.}, - title = {{NMR}-based protein potentials}, - journal = {Angewandte Chemie International Edition}, - volume = {49}, - pages = {6778-6780}, - year = {2010}, - type = {Journal Article} -} - -@article{Lindorff-Larsen2010 - author = {Lindorff-Larsen, K. and Piana, S. and Palmo, K. and Maragakis, P. and Klepeis, J. and Dror, R.O. and Shaw, D.E.}, - title = {Improved side-chain torsion potentials for the {Amber ff99SB} protein force field}, - journal = {Proteins}, - volume = {78}, - pages = {1950-1958}, - year = {2010}, - type = {Journal Article} -} - -@article{Liu1989 - author = {Liu, Dong C. and Nocedal, Jorge}, - title = {On the Limited Memory {BFGS} Method For Large Scale Optimization}, - journal = {Mathematical Programming}, - volume = {45}, - pages = {503-528}, - year = {1989}, - type = {Journal Article} -} - -@article{Lopes2013, - author = {Lopes, Pedro E. M. and Huang, Jing and Shim, Jihyun and Luo, Yun and Li, Hui and Roux, Benoît and MacKerell, Alexander D.}, - title = {Polarizable Force Field for Peptides and Proteins Based on the Classical {Drude} Oscillator}, - journal = {Journal of Chemical Theory and Computation}, - volume = {9}, - number = {12}, - pages = {5430-5449}, - year = {2013}, - type = {Journal Article} -} - -@article{Mahoney2000 - author = {Mahoney, Michael W. and Jorgensen, William L.}, - title = {A five-site model for liquid water and the reproduction of the density anomaly by rigid, nonpolarizable potential functions}, - journal = {Journal of Chemical Physics}, - volume = {112}, - pages = {8910-8922}, - year = {2000}, - type = {Journal Article} -} - -@article{Markland2008 - author = {Markland, Thomas E. and Manolopoulos, David E.}, - title = {An efficient ring polymer contraction scheme for imaginary time path integral simulations}, - journal = {Journal of Chemical Physics}, - volume = {129}, - number = {2}, - year = {2008}, - type = {Journal Article} -} - -@article{Mongan2007 - author = {Mongan, John and Simmerling, Carlos and McCammon, J. Andrew and Case, David A. and Onufriev, Alexey}, - title = {Generalized {Born} model with a simple, robust molecular volume correction}, - journal = {Journal of Chemical Theory and Computation}, - volume = {3}, - number = {1}, - pages = {156-169}, - year = {2007}, - type = {Journal Article} -} - -@article{Nguyen2013 - author = {Nguyen, Hai and Roe, Daniel R. and Simmerling, Carlos}, - title = {Improved Generalized {Born} Solvent Model Parameters for Protein Simulations}, - journal = {Journal of Chemical Theory and Computation}, - volume = {9}, - number = {4}, - pages = {2020-2034}, - year = {2013}, - type = {Journal Article} -} - -@article{Onufriev2004 - author = {Onufriev, Alexey and Bashford, Donald and Case, David A.}, - title = {Exploring protein native states and large-scale conformational changes with a modified generalized {Born} model}, - journal = {Proteins}, - volume = {55}, - number = {22}, - pages = {383-394}, - year = {2004}, - type = {Journal Article} -} - -@article{Parrinello1984 - author = {Parrinello, M. and Rahman, A.}, - title = {Study of an {F} center in molten {KCl}}, - journal = {Journal of Chemical Physics}, - volume = {80}, - number = {2}, - pages = {860-867}, - year = {1984}, - type = {Journal Article} -} - -@misc{Ponder - author = {Ponder, Jay W.}, - title = {Personal communication}, - type = {Personal Communication} -} - -@article{Ren2002 - author = {Ren, P. and Ponder, Jay W.}, - title = {A Consistent Treatment of Inter- and Intramolecular Polarization in Molecular Mechanics Calculations}, - journal = {Journal of Computational Chemistry}, - volume = {23}, - pages = {1497-1506}, - year = {2002}, - type = {Journal Article} -} - -@article{Ren2003 - author = {Ren, P. and Ponder, Jay W.}, - title = {Polarizable Atomic Multipole Water Model for Molecular Mechanics Simulation}, - journal = {Journal of Physical Chemistry B}, - volume = {107}, - pages = {5933-5947}, - year = {2003}, - type = {Journal Article} -} - -@article{Schaefer1998 - author = {Schaefer, Michael and Bartels, Christian and Karplus, Martin}, - title = {Solution conformations and thermodynamics of structured peptides: molecular dynamics simulation with an implicit solvation model}, - journal = {Journal of Molecular Biology}, - volume = {284}, - number = {3}, - pages = {835-848}, - year = {1998}, - type = {Journal Article} -} - -@article{Schnieders2007 - author = {Schnieders, Michael J. and Ponder, Jay W.}, - title = {Polarizable Atomic Multipole Solutes in a Generalized {Kirkwood} Continuum}, - journal = {Journal of Chemical Theory and Computation}, - volume = {3}, - pages = {2083-2097}, - year = {2007}, - type = {Journal Article} -} - -@article{Shirts2008 - author = {Shirts, Michael R. and Chodera, John D.}, - title = {Statistically optimal analysis of samples from multiple equilibrium states}, - journal = {Journal of Chemical Physics}, - volume = {129}, - pages = {124105}, - year = {2008}, - type = {Journal Article} -} - -@article{Shi2013 - author = {Shi, Yue and Xia, Zhen and Zhang, Jiajing and Best, Robert and Wu, Chuanjie and Ponder, Jay W. and Ren, Pengyu}, - title = {Polarizable Atomic Multipole-Based {AMOEBA} Force Field for Proteins}, - journal = {Journal of Chemical Theory and Computation}, - volume = {9}, - number = {9}, - pages = {4046-4063}, - year = {2013}, - type = {Journal Article} -} - -@article{Shirts2007 - author = {Shirts, Michael R. and Mobley, David L. and Chodera, John D. and Pande, Vijay S.}, - title = {Accurate and Efficient Corrections for Missing Dispersion Interactions in Molecular Simulations}, - journal = {Journal of Physical Chemistry B}, - volume = {111}, - pages = {13052-13063}, - year = {2007}, - type = {Journal Article} -} - -@article{Shirts2005 - author = {Shirts, Michael R. and Pande, Vijay S.}, - title = {Solvation free energies of amino acid side chain analogs for common molecular mechanics water models}, - journal = {Journal of Chemical Physics}, - volume = {132}, - pages = {134508}, - year = {2005}, - type = {Journal Article} -} - -@article{Srinivasan1999 - author = {Srinivasan, J and Trevathan, M. W. and Beroza, P. and Case, D. A.}, - title = {Application of a pairwise generalized {Born} model to proteins and nucleic acids: inclusion of salt effects}, - journal = {Theor. Chem. Acc.}, - volume = {101}, - pages = {426-434}, - year = {1999}, - type = {Journal Article} -} - -@article{Thole1981 - author = {Thole, B. T.}, - title = {Molecular polarizabilities calculated with a modified dipole interaction}, - journal = {Chemical Physics}, - volume = {59}, - number = {3}, - pages = {341-350}, - year = {1981}, - type = {Journal Article} -} - -@misc{Tinker - author = {Ponder, Jay W.}, - title = {{TINKER - Software Tools for Molecular Design, 4.2}}, - year = {2004} -} - -@article{Tironi1995 - author = {Tironi, Ilario G. and Sperb, René and Smith, Paul E. and van Gunsteren, Wilfred F.}, - title = {A generalized reaction field method for molecular dynamics simulations}, - journal = {Journal of Chemical Physics}, - volume = {102}, - number = {13}, - pages = {5451-5459}, - year = {1995}, - type = {Journal Article} -} - -@article{Toukmaji1996 - author = {Toukmaji, Abdulnour Y. and Board Jr, John A.}, - title = {{Ewald} summation techniques in perspective: a survey}, - journal = {Computer Physics Communications}, - volume = {95}, - pages = {73-92}, - year = {1996}, - type = {Journal Article} -} - -@article{Wang2000 - author = {Wang, J. and Cieplak, P. and Kollman, P.A.}, - title = {How well does a restrained electrostatic potential ({RESP}) model perform in calculating conformational energies of organic and biological molecules?}, - journal = {Journal of Computational Chemistry}, - volume = {21}, - pages = {1049-1074}, - year = {2000}, - type = {Journal Article} -} - -@article{Wang2014 - author = {Wang, Lee-Ping and Martinez, Todd J. and Pande, Vijay S.}, - title = {Building force fields: an automatic, systematic, and reproducible approach}, - journal = {Journal of Physical Chemistry Letters}, - volume = {5}, - pages = {1885-1891}, - year = {2014}, - type = {Journal Article} -} +@article{Andersen1980 + author = {Andersen, Hans C.}, + title = {Molecular dynamics simulations at constant pressure and/or temperature}, + journal = {Journal of Chemical Physics}, + volume = {72}, + number = {4}, + pages = {2384-2393}, + year = {1980}, + type = {Journal Article} +} + +@article{Aqvist2004 + author = {Ã…qvist, Johan and Wennerström, Petra and Nervall, Martin and Bjelic, Sinisa and Brandsdal, Bjørn O.}, + title = {Molecular dynamics simulations of water and biomolecules with a {Monte Carlo} constant pressure algorithm}, + journal = {Chemical Physics Letters}, + volume = {384}, + pages = {288-294}, + year = {2004}, + type = {Journal Article} +} + +@article{Berendsen1987 + author = {Berendsen, H. J. C. and Grigera, J. R. and Straatsma, T. P.}, + title = {The missing term in effective pair potentials}, + journal = {Journal of Physical Chemistry}, + volume = {91}, + pages = {6269-6271}, + year = {1987}, + type = {Journal Article} +} + +@article{Ceriotti2010 + author = {Ceriotti, M. and Parrinello, M. and Markland, Thomas E. and Manolopoulos, David E.}, + title = {Efficient stochastic thermostatting of path integral molecular dynamics}, + journal = {Journal of Chemical Physics}, + volume = {133}, + number = {12}, + year = {2010}, + type = {Journal Article} +} + +@article{Chow1995 + author = {Chow, Kim-Hung and Ferguson, David M.}, + title = {Isothermal-isobaric molecular dynamics simulations with {Monte Carlo} volume sampling}, + journal = {Computer Physics Communications}, + volume = {91}, + pages = {283-289}, + year = {1995}, + type = {Journal Article} +} + +@article{Craig2004 + author = {Craig, I. R. and Manolopoulos, David E.}, + title = {Quantum statistics and classical mechanics: Real time correlation functions from ring polymer molecular dynamics}, + journal = {Journal of Chemical Physics}, + volume = {121}, + pages = {3368-3373}, + year = {2004}, + type = {Journal Article} +} + +@article{Duan2003 + author = {Duan, Y.; Wu, C. and Chowdhury, S. and Lee, M.C. and Xiong, G. and Zhang, W. and Yang, R. and Cieplak, P. and Luo, R. and Lee, T.}, + title = {A point-charge force field for molecular mechanics simulations of proteins based on condensed-phase quantum mechanical calculations}, + journal = {Journal of Computational Chemistry}, + volume = {24}, + pages = {1999-2012}, + year = {2003}, + type = {Journal Article} +} + +@article{Essmann1995 + author = {Essmann, Ulrich and Perera, Lalith and Berkowitz, Max L. and Darden, Tom and Lee, Hsing and Pedersen, Lee G.}, + title = {A smooth particle mesh {Ewald} method}, + journal = {Journal of Chemical Physics}, + volume = {103}, + number = {19}, + pages = {8577-8593}, + year = {1995}, + type = {Journal Article} +} + +@article{Hall1984 + author = {Hall, Randall W. and Berne, B. J.}, + title = {Nonergodicity in path integral molecular dynamics}, + journal = {Journal of Chemical Physics}, + volume = {81}, + number = {8}, + year = {1984}, + type = {Journal Article} +} + +@article{Hawkins1995 + author = {Hawkins, Gregory D. and Cramer, Christopher J. and Truhlar, Donald G.}, + title = {Pairwise solute descreening of solute charges from a dielectric medium}, + journal = {Chemical Physics Letters}, + volume = {246}, + number = {1-2}, + pages = {122-129}, + year = {1995}, + type = {Journal Article} +} + +@article{Horn2004 + author = {Horn, Hans W. and Swope, William C. and Pitera, Jed W. and Madura, Jeffry D. and Dick, Thomas J. and Hura, Greg L. and Head-Gordon, Teresa}, + title = {Development of an improved four-site water model for biomolecular simulations: {TIP4P-Ew}}, + journal = {Journal of Chemical Physics}, + volume = {120}, + pages = {9665-9678}, + year = {2004}, + type = {Journal Article} +} + +@article{Hornak2006 + author = {Hornak, V. and Abel, R. and Okur, A. and Strockbine, B. and Roitberg, A. and Simmerling, C.}, + title = {Comparison of multiple {Amber} force fields and development of improved protein backbone parameters}, + journal = {Proteins}, + volume = {65}, + pages = {712-725}, + year = {2006}, + type = {Journal Article} +} + +@article{Izaguirre2010 + author = {Izaguirre, Jesús A. and Sweet, Chris R. and Pande, Vijay S.}, + title = {Multiscale dynamics of macromolecules using {Normal Mode Langevin}}, + journal = {Pacific Symposium on Biocomputing}, + volume = {15}, + pages = {240-251}, + year = {2010}, + type = {Journal Article} +} + +@article{Jorgensen1983 + author = {Jorgensen, William L. and Chandrasekhar, Jayaraman and Madura, Jeffry D. and Impey, Roger W. and Klein, Michael L.}, + title = {Comparison of simple potential functions for simulating liquid water}, + journal = {Journal of Chemical Physics}, + volume = {79}, + pages = {926-935}, + year = {1983}, + type = {Journal Article} +} + +@inbook{Kollman1997 + author = {Kollman, P.A. and Dixon, R. and Cornell, W. and Fox, T. and Chipot, C. and Pohorille, A.}, + title = {Computer Simulation of Biomolecular Systems}, + editor = {Wilkinson, A. and Weiner, P. and van Gunsteren, Wilfred F.}, + publisher = {Elsevier}, + volume = {3}, + pages = {83-96}, + year = {1997}, + type = {Book Section} +} + +@article{Labute2008 + author = {Labute, Paul}, + title = {The generalized {Born}/volume integral implicit solvent model: Estimation of the free energy of hydration using {London} dispersion instead of atomic surface area}, + journal = {Journal of Computational Chemistry}, + volume = {29}, + number = {10}, + pages = {1693-1698}, + year = {2008}, + type = {Journal Article} +} + +@article{Lamoureux2006 + author = {Lamoureux, Guillaume and Harder, Edward and Vorobyov, Igor V. and Roux, Benoit and MacKerell Jr., Alexander D.}, + title = {A polarizable model of water for molecular dynamics simulations of biomolecules}, + journal = {Chemical Physics Letters}, + volume = {418}, + number = {1-3}, + pages = {245-249}, + year = {2006}, + type = {Journal Article} +} + +@article{Lamoureux2003 + author = {Lamoureux, Guillaume and Roux, Benoit}, + title = {Modeling induced polarization with classical {Drude} oscillators: Theory and molecular dynamics simulation algorithm}, + journal = {Journal of Chemical Physics}, + volume = {119}, + number = {6}, + pages = {3025-3039}, + year = {2003}, + type = {Journal Article} +} + +@article{Li2010 + author = {Li, D.W. and Br{\"u}schweiler, R.}, + title = {{NMR}-based protein potentials}, + journal = {Angewandte Chemie International Edition}, + volume = {49}, + pages = {6778-6780}, + year = {2010}, + type = {Journal Article} +} + +@article{Lindorff-Larsen2010 + author = {Lindorff-Larsen, K. and Piana, S. and Palmo, K. and Maragakis, P. and Klepeis, J. and Dror, R.O. and Shaw, D.E.}, + title = {Improved side-chain torsion potentials for the {Amber ff99SB} protein force field}, + journal = {Proteins}, + volume = {78}, + pages = {1950-1958}, + year = {2010}, + type = {Journal Article} +} + +@article{Liu1989 + author = {Liu, Dong C. and Nocedal, Jorge}, + title = {On the Limited Memory {BFGS} Method For Large Scale Optimization}, + journal = {Mathematical Programming}, + volume = {45}, + pages = {503-528}, + year = {1989}, + type = {Journal Article} +} + +@article{Lopes2013, + author = {Lopes, Pedro E. M. and Huang, Jing and Shim, Jihyun and Luo, Yun and Li, Hui and Roux, Benoît and MacKerell, Alexander D.}, + title = {Polarizable Force Field for Peptides and Proteins Based on the Classical {Drude} Oscillator}, + journal = {Journal of Chemical Theory and Computation}, + volume = {9}, + number = {12}, + pages = {5430-5449}, + year = {2013}, + type = {Journal Article} +} + +@article{Mahoney2000 + author = {Mahoney, Michael W. and Jorgensen, William L.}, + title = {A five-site model for liquid water and the reproduction of the density anomaly by rigid, nonpolarizable potential functions}, + journal = {Journal of Chemical Physics}, + volume = {112}, + pages = {8910-8922}, + year = {2000}, + type = {Journal Article} +} + +@article{Markland2008 + author = {Markland, Thomas E. and Manolopoulos, David E.}, + title = {An efficient ring polymer contraction scheme for imaginary time path integral simulations}, + journal = {Journal of Chemical Physics}, + volume = {129}, + number = {2}, + year = {2008}, + type = {Journal Article} +} + +@article{Mongan2007 + author = {Mongan, John and Simmerling, Carlos and McCammon, J. Andrew and Case, David A. and Onufriev, Alexey}, + title = {Generalized {Born} model with a simple, robust molecular volume correction}, + journal = {Journal of Chemical Theory and Computation}, + volume = {3}, + number = {1}, + pages = {156-169}, + year = {2007}, + type = {Journal Article} +} + +@article{Nguyen2013 + author = {Nguyen, Hai and Roe, Daniel R. and Simmerling, Carlos}, + title = {Improved Generalized {Born} Solvent Model Parameters for Protein Simulations}, + journal = {Journal of Chemical Theory and Computation}, + volume = {9}, + number = {4}, + pages = {2020-2034}, + year = {2013}, + type = {Journal Article} +} + +@article{Onufriev2004 + author = {Onufriev, Alexey and Bashford, Donald and Case, David A.}, + title = {Exploring protein native states and large-scale conformational changes with a modified generalized {Born} model}, + journal = {Proteins}, + volume = {55}, + number = {22}, + pages = {383-394}, + year = {2004}, + type = {Journal Article} +} + +@article{Parrinello1984 + author = {Parrinello, M. and Rahman, A.}, + title = {Study of an {F} center in molten {KCl}}, + journal = {Journal of Chemical Physics}, + volume = {80}, + number = {2}, + pages = {860-867}, + year = {1984}, + type = {Journal Article} +} + +@misc{Ponder + author = {Ponder, Jay W.}, + title = {Personal communication}, + type = {Personal Communication} +} + +@article{Ren2002 + author = {Ren, P. and Ponder, Jay W.}, + title = {A Consistent Treatment of Inter- and Intramolecular Polarization in Molecular Mechanics Calculations}, + journal = {Journal of Computational Chemistry}, + volume = {23}, + pages = {1497-1506}, + year = {2002}, + type = {Journal Article} +} + +@article{Ren2003 + author = {Ren, P. and Ponder, Jay W.}, + title = {Polarizable Atomic Multipole Water Model for Molecular Mechanics Simulation}, + journal = {Journal of Physical Chemistry B}, + volume = {107}, + pages = {5933-5947}, + year = {2003}, + type = {Journal Article} +} + +@article{Schaefer1998 + author = {Schaefer, Michael and Bartels, Christian and Karplus, Martin}, + title = {Solution conformations and thermodynamics of structured peptides: molecular dynamics simulation with an implicit solvation model}, + journal = {Journal of Molecular Biology}, + volume = {284}, + number = {3}, + pages = {835-848}, + year = {1998}, + type = {Journal Article} +} + +@article{Schnieders2007 + author = {Schnieders, Michael J. and Ponder, Jay W.}, + title = {Polarizable Atomic Multipole Solutes in a Generalized {Kirkwood} Continuum}, + journal = {Journal of Chemical Theory and Computation}, + volume = {3}, + pages = {2083-2097}, + year = {2007}, + type = {Journal Article} +} + +@article{Shirts2008 + author = {Shirts, Michael R. and Chodera, John D.}, + title = {Statistically optimal analysis of samples from multiple equilibrium states}, + journal = {Journal of Chemical Physics}, + volume = {129}, + pages = {124105}, + year = {2008}, + type = {Journal Article} +} + +@article{Shi2013 + author = {Shi, Yue and Xia, Zhen and Zhang, Jiajing and Best, Robert and Wu, Chuanjie and Ponder, Jay W. and Ren, Pengyu}, + title = {Polarizable Atomic Multipole-Based {AMOEBA} Force Field for Proteins}, + journal = {Journal of Chemical Theory and Computation}, + volume = {9}, + number = {9}, + pages = {4046-4063}, + year = {2013}, + type = {Journal Article} +} + +@article{Shirts2007 + author = {Shirts, Michael R. and Mobley, David L. and Chodera, John D. and Pande, Vijay S.}, + title = {Accurate and Efficient Corrections for Missing Dispersion Interactions in Molecular Simulations}, + journal = {Journal of Physical Chemistry B}, + volume = {111}, + pages = {13052-13063}, + year = {2007}, + type = {Journal Article} +} + +@article{Shirts2005 + author = {Shirts, Michael R. and Pande, Vijay S.}, + title = {Solvation free energies of amino acid side chain analogs for common molecular mechanics water models}, + journal = {Journal of Chemical Physics}, + volume = {132}, + pages = {134508}, + year = {2005}, + type = {Journal Article} +} + +@article{Sindhikara2009, + author = {Sindhikara, Daniel J. and Kim, Seonah and Voter, + Arthur F. and Roitberg, Adrian E.}, + title = {{Bad Seeds Sprout Perilous Dynamics: Stochastic + Thermostat Induced Trajectory Synchronization in + Biomolecules}}, + journal = {Journal of Chemical Theory and Computation}, + year = 2009, + volume = 5, + number = 6, + pages = {1624--1631}, + month = {April}, +} + +@article{Srinivasan1999 + author = {Srinivasan, J and Trevathan, M. W. and Beroza, P. and Case, D. A.}, + title = {Application of a pairwise generalized {Born} model to proteins and nucleic acids: inclusion of salt effects}, + journal = {Theor. Chem. Acc.}, + volume = {101}, + pages = {426-434}, + year = {1999}, + type = {Journal Article} +} + +@article{Thole1981 + author = {Thole, B. T.}, + title = {Molecular polarizabilities calculated with a modified dipole interaction}, + journal = {Chemical Physics}, + volume = {59}, + number = {3}, + pages = {341-350}, + year = {1981}, + type = {Journal Article} +} + +@misc{Tinker + author = {Ponder, Jay W.}, + title = {{TINKER - Software Tools for Molecular Design, 4.2}}, + year = {2004} +} + +@article{Tironi1995 + author = {Tironi, Ilario G. and Sperb, René and Smith, Paul E. and van Gunsteren, Wilfred F.}, + title = {A generalized reaction field method for molecular dynamics simulations}, + journal = {Journal of Chemical Physics}, + volume = {102}, + number = {13}, + pages = {5451-5459}, + year = {1995}, + type = {Journal Article} +} + +@article{Toukmaji1996 + author = {Toukmaji, Abdulnour Y. and Board Jr, John A.}, + title = {{Ewald} summation techniques in perspective: a survey}, + journal = {Computer Physics Communications}, + volume = {95}, + pages = {73-92}, + year = {1996}, + type = {Journal Article} +} + +@article{Uberuaga2004, + author = {Blas P. Uberuaga and Marian Anghel and Arthur + F. Voter}, + title = {{Synchronization of trajectories in canonical + molecular-dynamics simulations: observation, + explanation, and exploitation}}, + journal = {Journal of Chemical Physics}, + year = 2004, + key = {synchronization, parallelization}, + volume = 120, + number = 14, + pages = {6363--6374}, +} + +@article{Wang2000 + author = {Wang, J. and Cieplak, P. and Kollman, P.A.}, + title = {How well does a restrained electrostatic potential ({RESP}) model perform in calculating conformational energies of organic and biological molecules?}, + journal = {Journal of Computational Chemistry}, + volume = {21}, + pages = {1049-1074}, + year = {2000}, + type = {Journal Article} +} + +@article{Wang2014 + author = {Wang, Lee-Ping and Martinez, Todd J. and Pande, Vijay S.}, + title = {Building force fields: an automatic, systematic, and reproducible approach}, + journal = {Journal of Physical Chemistry Letters}, + volume = {5}, + pages = {1885-1891}, + year = {2014}, + type = {Journal Article} +} diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index 6322a18ae..d7595656c 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -1379,3 +1379,65 @@ specific types of rules. They are: .. math:: \mathbf{r}=\mathbf{o}+p_1\mathbf{\hat{x}}+p_2\mathbf{\hat{y}}+p_3\mathbf{\hat{z}} .. + +Random Numbers with Stochastic Integrators and Forces +***************************************************** + +OpenMM includes many stochastic integrators and forces that make extensive use +of random numbers. It is impossible to generate truly random numbers on a +computer like you would with a dice roll or coin flip in real life---instead +programs rely on pseudo-random number generators (PRNGs) that take some sort of +initial "seed" value and steps through a sequence of seemingly random numbers. + +The exact implementation of the PRNGs is not important (in fact, each platform +may have its own PRNG whose performance is optimized for that hardware). What +*is* important, however, is that the PRNG must generate a uniform distribution +of random numbers between 0 and 1. Random numbers drawn from this distribution +can be manipulated to yield random integers in a desired range or even a random +number from a different type of probability distribution function (e.g., a +normal distribution). + +What this means is that the random numbers used by integrators and forces within +OpenMM cannot have any discernible pattern to them. Patterns can be induced in +PRNGs in two principle ways: + 1. The PRNG uses a bad algorithm with a short period. + 2. Two PRNGs are started using the same seed + +All PRNG algorithms in common use are periodic---that is their sequence of +random numbers repeats after a given *period*, defined by the number of "unique" +random numbers in the repeating pattern. As long as this period is longer than +the total number of random numbers your application requires (preferably by +orders of magnitude), the first problem described above is avoided. All PRNGs +employed by OpenMM have periods far longer than any current simulation can cycle +through. + +Point two is far more common in biomolecular simulation, and can result in very +strange artifacts that may be difficult to detect. For example, with Langevin +dynamics, two simulations that use the same sequence of random numbers appear to +synchronize in their global movements.\ :cite:`Uberuaga2004`\ +:cite:`Sindhikara2009` It is therefore very important that the stochastic forces +and integrators in OpenMM generate unique sequences of pseudo-random numbers not +only within a single simulation, but between two different simulations of the +same system as well (including any restarts of previous simulations). + +Every stochastic force and integrator that does (or could) make use of random +numbers has two instance methods attached to it: ``getRandomNumberSeed()`` and +``setRandomNumberSeed(int seed)``. If you set a unique random seed for two +different simulations (or different forces/integrators if applicable), OpenMM +guarantees that the generated sequences of random numbers will be different (by +contrast, no guarantee is made that the same seed will result in identical +random number sequences). + +Since breaking simulations up into pieces and/or running multiple replicates of +a system to obtain more complete statistics is common practice, a new strategy +has been employed for OpenMM versions 6.3 and later with the aim of trying to +ensure that each simulation will be started with a unique random seed. A random +seed value of 0 (the default) will cause a unique random seed to be generated +when a new ``Context`` is instantiated. + +Prior to the introduction of this feature, deserializing a serialized +``System`` XML file would result in each stochastic force or integrator being +assigned the same random seed as the original instance that was serialized. If +you use a ``System`` XML file generated by a version of OpenMM older than 6.3 +to start a new simulation, you should manually set the random number seed of +each stochastic force or integrator to 0 (or another unique value). -- GitLab From 7dc2ff9eb4cee8cfdd9fb7af9dd3c0a8a405c391 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 15 Jan 2015 11:24:14 -0800 Subject: [PATCH 216/338] Catch nan coordinates before they can produce a segfault --- platforms/cpu/src/CpuKernels.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 2aa3fd963..93c92c571 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2013-2014 Stanford University and the Authors. * + * Portions copyright (c) 2013-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -140,7 +140,7 @@ public: class CpuCalcForcesAndEnergyKernel::InitForceTask : public ThreadPool::Task { public: - InitForceTask(int numParticles, ContextImpl& context, CpuPlatform::PlatformData& data) : numParticles(numParticles), context(context), data(data) { + InitForceTask(int numParticles, ContextImpl& context, CpuPlatform::PlatformData& data) : numParticles(numParticles), positionsValid(true), context(context), data(data) { } void execute(ThreadPool& threads, int threadIndex) { // Convert the positions to single precision and apply periodic boundary conditions @@ -166,6 +166,12 @@ public: posq[4*i+1] = (float) posData[i][1]; posq[4*i+2] = (float) posData[i][2]; } + + // Check for invalid positions. + + for (int i = 4*start; i < 4*end; i++) + if (posq[i] != posq[i]) + positionsValid = false; // Clear the forces. @@ -174,6 +180,7 @@ public: zero.store(&data.threadForce[threadIndex][j*4]); } int numParticles; + bool positionsValid; ContextImpl& context; CpuPlatform::PlatformData& data; }; @@ -198,6 +205,8 @@ void CpuCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool i InitForceTask task(context.getSystem().getNumParticles(), context, data); data.threads.execute(task); data.threads.waitForThreads(); + if (!task.positionsValid) + throw OpenMMException("Particle coordinate is nan"); } double CpuCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { -- GitLab From e16acd1bdd225ec0e58291d4489142d82f0662dd Mon Sep 17 00:00:00 2001 From: Robert McGibbon Date: Thu, 15 Jan 2015 14:32:50 -0800 Subject: [PATCH 217/338] whoops --- wrappers/python/simtk/openmm/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/__init__.py b/wrappers/python/simtk/openmm/__init__.py index 3092e3e27..4730cc9ac 100644 --- a/wrappers/python/simtk/openmm/__init__.py +++ b/wrappers/python/simtk/openmm/__init__.py @@ -15,7 +15,8 @@ from simtk.openmm import version if sys.platform == 'win32': _path = os.environ['PATH'] - os.environ['PATH'] += '%(lib)s;%(lib)s\plugins' % {'lib': version.openmm_library_path} + os.environ['PATH'] = '%(lib)s;%(lib)s\plugins;%(path)s' % { + 'lib': version.openmm_library_path, 'path': _path} from simtk.openmm.openmm import * from simtk.openmm.vec3 import Vec3 -- GitLab From c2505aad18cd95733f1a81b40ccc6decef08225a Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 15 Jan 2015 17:36:31 -0500 Subject: [PATCH 218/338] ``XXX`` -> :class:`XXX` principle -> principal... I'm a bozo. --- docs-source/usersguide/theory.rst | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index d7595656c..26f1f5d18 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -1399,7 +1399,7 @@ normal distribution). What this means is that the random numbers used by integrators and forces within OpenMM cannot have any discernible pattern to them. Patterns can be induced in -PRNGs in two principle ways: +PRNGs in two principal ways: 1. The PRNG uses a bad algorithm with a short period. 2. Two PRNGs are started using the same seed @@ -1421,23 +1421,24 @@ only within a single simulation, but between two different simulations of the same system as well (including any restarts of previous simulations). Every stochastic force and integrator that does (or could) make use of random -numbers has two instance methods attached to it: ``getRandomNumberSeed()`` and -``setRandomNumberSeed(int seed)``. If you set a unique random seed for two -different simulations (or different forces/integrators if applicable), OpenMM -guarantees that the generated sequences of random numbers will be different (by -contrast, no guarantee is made that the same seed will result in identical -random number sequences). +numbers has two instance methods attached to it: :class:`getRandomNumberSeed()` +and :class:`setRandomNumberSeed(int seed)`. If you set a unique random seed for +two different simulations (or different forces/integrators if applicable), +OpenMM guarantees that the generated sequences of random numbers will be +different (by contrast, no guarantee is made that the same seed will result in +identical random number sequences). Since breaking simulations up into pieces and/or running multiple replicates of a system to obtain more complete statistics is common practice, a new strategy has been employed for OpenMM versions 6.3 and later with the aim of trying to ensure that each simulation will be started with a unique random seed. A random seed value of 0 (the default) will cause a unique random seed to be generated -when a new ``Context`` is instantiated. +when a new :class:`Context` is instantiated. Prior to the introduction of this feature, deserializing a serialized -``System`` XML file would result in each stochastic force or integrator being -assigned the same random seed as the original instance that was serialized. If -you use a ``System`` XML file generated by a version of OpenMM older than 6.3 -to start a new simulation, you should manually set the random number seed of -each stochastic force or integrator to 0 (or another unique value). +:class:`System` XML file would result in each stochastic force or integrator +being assigned the same random seed as the original instance that was +serialized. If you use a :class:`System` XML file generated by a version of +OpenMM older than 6.3 to start a new simulation, you should manually set the +random number seed of each stochastic force or integrator to 0 (or another +unique value). -- GitLab From 8a2e438ee4be4e8bcd2e3dc3325244eca81087c0 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 15 Jan 2015 17:44:51 -0500 Subject: [PATCH 219/338] :class: -> :meth: where appropriate. --- docs-source/usersguide/theory.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index 26f1f5d18..6b7137559 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -1421,8 +1421,8 @@ only within a single simulation, but between two different simulations of the same system as well (including any restarts of previous simulations). Every stochastic force and integrator that does (or could) make use of random -numbers has two instance methods attached to it: :class:`getRandomNumberSeed()` -and :class:`setRandomNumberSeed(int seed)`. If you set a unique random seed for +numbers has two instance methods attached to it: :meth:`getRandomNumberSeed()` +and :meth:`setRandomNumberSeed(int seed)`. If you set a unique random seed for two different simulations (or different forces/integrators if applicable), OpenMM guarantees that the generated sequences of random numbers will be different (by contrast, no guarantee is made that the same seed will result in -- GitLab From df99352d9bec6c0f1dcf643f57436b278844ace4 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 15 Jan 2015 17:47:24 -0500 Subject: [PATCH 220/338] Tweak numbering formatting. --- docs-source/usersguide/theory.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index 6b7137559..d7e799698 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -1400,8 +1400,9 @@ normal distribution). What this means is that the random numbers used by integrators and forces within OpenMM cannot have any discernible pattern to them. Patterns can be induced in PRNGs in two principal ways: - 1. The PRNG uses a bad algorithm with a short period. - 2. Two PRNGs are started using the same seed + +1. The PRNG uses a bad algorithm with a short period. +2. Two PRNGs are started using the same seed All PRNG algorithms in common use are periodic---that is their sequence of random numbers repeats after a given *period*, defined by the number of "unique" -- GitLab From bd01a379e0ca5992782518f5af3e29bef3776b7d Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 16 Jan 2015 16:34:32 -0800 Subject: [PATCH 221/338] Variable step size integrators were scaling the step size incorrectly --- platforms/cuda/src/kernels/langevin.cu | 2 +- platforms/cuda/src/kernels/verlet.cu | 2 +- platforms/opencl/src/kernels/langevin.cl | 2 +- platforms/opencl/src/kernels/verlet.cl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platforms/cuda/src/kernels/langevin.cu b/platforms/cuda/src/kernels/langevin.cu index e93aa8f5f..eb8e9719d 100644 --- a/platforms/cuda/src/kernels/langevin.cu +++ b/platforms/cuda/src/kernels/langevin.cu @@ -90,7 +90,7 @@ extern "C" __global__ void selectLangevinStepSize(int numAtoms, int paddedNumAto while (index < numAtoms) { mixed3 f = make_mixed3(scale*force[index], scale*force[index+paddedNumAtoms], scale*force[index+paddedNumAtoms*2]); mixed invMass = velm[index].w; - err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass; + err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass*invMass; index += blockDim.x*gridDim.x; } error[threadIdx.x] = err; diff --git a/platforms/cuda/src/kernels/verlet.cu b/platforms/cuda/src/kernels/verlet.cu index fa23adc46..0f364d3e6 100644 --- a/platforms/cuda/src/kernels/verlet.cu +++ b/platforms/cuda/src/kernels/verlet.cu @@ -89,7 +89,7 @@ extern "C" __global__ void selectVerletStepSize(int numAtoms, int paddedNumAtoms for (int index = threadIdx.x; index < numAtoms; index += blockDim.x*gridDim.x) { mixed3 f = make_mixed3(scale*force[index], scale*force[index+paddedNumAtoms], scale*force[index+paddedNumAtoms*2]); mixed invMass = velm[index].w; - err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass; + err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass*invMass; } error[threadIdx.x] = err; __syncthreads(); diff --git a/platforms/opencl/src/kernels/langevin.cl b/platforms/opencl/src/kernels/langevin.cl index 94e5cc80c..986a5f84e 100644 --- a/platforms/opencl/src/kernels/langevin.cl +++ b/platforms/opencl/src/kernels/langevin.cl @@ -81,7 +81,7 @@ __kernel void selectLangevinStepSize(mixed maxStepSize, mixed errorTol, mixed ta while (index < NUM_ATOMS) { real4 f = force[index]; mixed invMass = velm[index].w; - err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass; + err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass*invMass; index += get_global_size(0); } error[get_local_id(0)] = err; diff --git a/platforms/opencl/src/kernels/verlet.cl b/platforms/opencl/src/kernels/verlet.cl index 1611488be..8fa327a36 100644 --- a/platforms/opencl/src/kernels/verlet.cl +++ b/platforms/opencl/src/kernels/verlet.cl @@ -85,7 +85,7 @@ __kernel void selectVerletStepSize(int numAtoms, mixed maxStepSize, mixed errorT while (index < numAtoms) { real4 f = force[index]; mixed invMass = velm[index].w; - err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass; + err += (f.x*f.x + f.y*f.y + f.z*f.z)*invMass*invMass; index += get_global_size(0); } error[get_local_id(0)] = err; -- GitLab From 6ad2aff3fbc637aeba18e50ac452e66cc971e193 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 17 Jan 2015 11:45:56 -0500 Subject: [PATCH 222/338] Grammar fixes in the doxygen comments. --- openmmapi/include/openmm/BrownianIntegrator.h | 2 +- openmmapi/include/openmm/LangevinIntegrator.h | 2 +- openmmapi/include/openmm/VerletIntegrator.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openmmapi/include/openmm/BrownianIntegrator.h b/openmmapi/include/openmm/BrownianIntegrator.h index 7d8e5dfd4..a11c4bde7 100644 --- a/openmmapi/include/openmm/BrownianIntegrator.h +++ b/openmmapi/include/openmm/BrownianIntegrator.h @@ -49,7 +49,7 @@ public: * * @param temperature the temperature of the heat bath (in Kelvin) * @param frictionCoeff the friction coefficient which couples the system to the heat bath, measured in 1/ps - * @param stepSize the step size with which to integrator the system (in picoseconds) + * @param stepSize the step size with which to integrate the system (in picoseconds) */ BrownianIntegrator(double temperature, double frictionCoeff, double stepSize); /** diff --git a/openmmapi/include/openmm/LangevinIntegrator.h b/openmmapi/include/openmm/LangevinIntegrator.h index 27bb6beea..b527b2c48 100644 --- a/openmmapi/include/openmm/LangevinIntegrator.h +++ b/openmmapi/include/openmm/LangevinIntegrator.h @@ -49,7 +49,7 @@ public: * * @param temperature the temperature of the heat bath (in Kelvin) * @param frictionCoeff the friction coefficient which couples the system to the heat bath (in inverse picoseconds) - * @param stepSize the step size with which to integrator the system (in picoseconds) + * @param stepSize the step size with which to integrate the system (in picoseconds) */ LangevinIntegrator(double temperature, double frictionCoeff, double stepSize); /** diff --git a/openmmapi/include/openmm/VerletIntegrator.h b/openmmapi/include/openmm/VerletIntegrator.h index 433ff9417..0876f24b4 100644 --- a/openmmapi/include/openmm/VerletIntegrator.h +++ b/openmmapi/include/openmm/VerletIntegrator.h @@ -47,7 +47,7 @@ public: /** * Create a VerletIntegrator. * - * @param stepSize the step size with which to integrator the system (in picoseconds) + * @param stepSize the step size with which to integrate the system (in picoseconds) */ explicit VerletIntegrator(double stepSize); /** -- GitLab From f9bd59efa91782c82699482ead1f8c01d6b4deba Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sun, 18 Jan 2015 16:03:32 -0500 Subject: [PATCH 223/338] Fix Amber custom GB models with both a salt concentration *and* a cutoff. --- wrappers/python/simtk/openmm/app/internal/customgbforces.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/customgbforces.py b/wrappers/python/simtk/openmm/app/internal/customgbforces.py index e8f6619f3..2d43f7839 100644 --- a/wrappers/python/simtk/openmm/app/internal/customgbforces.py +++ b/wrappers/python/simtk/openmm/app/internal/customgbforces.py @@ -217,7 +217,7 @@ def _createEnergyTerms(force, solventDielectric, soluteDielectric, SA, cutoff, k "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"+params, CustomGBForce.ParticlePairNoExclusions) else: if kappa > 0: - force.addEnergyTerm("-138.935485*(1/soluteDielectric-kappa/solventDielectric)*q1*q2*(1/f-"+str(1/cutoff)+");" + force.addEnergyTerm("-138.935485*(1/soluteDielectric-exp(-kappa*f)/solventDielectric)*q1*q2*(1/f-"+str(1/cutoff)+");" "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))"+params, CustomGBForce.ParticlePairNoExclusions) else: force.addEnergyTerm("-138.935485*(1/soluteDielectric-1/solventDielectric)*q1*q2*(1/f-"+str(1/cutoff)+");" @@ -380,4 +380,4 @@ def convertParameters(params, gbmodel): newparams[i] = list(params[i]) newparams[i][0] -= offset newparams[i][1] *= newparams[i][0] - return newparams \ No newline at end of file + return newparams -- GitLab From 2228188c10c3115b81a3803d2c71c5c938ff22d6 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sun, 18 Jan 2015 21:28:10 -0500 Subject: [PATCH 224/338] Update CHARMM OBC2 nonperiodic salt force save file for recent fix. --- .../OBC2_NonPeriodic_Salt.xml | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml index b1f2c1487..6acd4d950 100644 --- a/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml +++ b/wrappers/python/tests/systems/ala-ala-ala-implicit-forces/OBC2_NonPeriodic_Salt.xml @@ -6,38 +6,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 91e353a85c8478bf9ad01e7521562638b64f658f Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sun, 18 Jan 2015 21:33:06 -0500 Subject: [PATCH 225/338] Fix the Amber test suite for recent fix to nonperiodic salt concentration with cutoff GB. --- .../OBC2_NonPeriodic_Salt.xml | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml index c9571da7a..ae8fdb3e2 100644 --- a/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml +++ b/wrappers/python/tests/systems/alanine-dipeptide-implicit-forces/OBC2_NonPeriodic_Salt.xml @@ -6,27 +6,27 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 690c80f1e998c32726b928878676fe0ae33c5001 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 20 Jan 2015 11:15:37 -0800 Subject: [PATCH 226/338] Fixed Fortran compilation errors caused by function names being too long --- wrappers/generateWrappers.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wrappers/generateWrappers.py b/wrappers/generateWrappers.py index f19433e2f..bd4d1eb9c 100644 --- a/wrappers/generateWrappers.py +++ b/wrappers/generateWrappers.py @@ -974,6 +974,7 @@ class FortranHeaderGenerator(WrapperGenerator): hasReturnValue = (returnType in ('integer*4', 'real*8')) hasReturnArg = not (hasReturnValue or returnType == 'void') functionName = "%s_%s" % (typeName, methodName) + functionName = functionName[:63] if hasReturnValue: self.out.write(" function ") else: @@ -1517,8 +1518,9 @@ class FortranSourceGenerator(WrapperGenerator): # There are two identical methods that differ only in whether they are const. Skip the const one. continue functionName = "%s_%s" % (typeName, methodName) - self.writeOneMethod(classNode, methodNode, functionName, functionName.lower()+'_') - self.writeOneMethod(classNode, methodNode, functionName, functionName.upper()) + truncatedName = functionName[:63] + self.writeOneMethod(classNode, methodNode, functionName, truncatedName.lower()+'_') + self.writeOneMethod(classNode, methodNode, functionName, truncatedName.upper()) def writeOneConstructor(self, classNode, methodNode, functionName, wrapperFunctionName): className = getText("compoundname", classNode) -- GitLab From f75bf1bdbc1e68f3f8462d978995955e22e27cd5 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 20 Jan 2015 11:42:07 -0800 Subject: [PATCH 227/338] Check for nan positions was being done incorrectly --- platforms/cpu/src/CpuKernels.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 93c92c571..12febc441 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -169,8 +169,8 @@ public: // Check for invalid positions. - for (int i = 4*start; i < 4*end; i++) - if (posq[i] != posq[i]) + for (int i = 4*start; i < 4*end; i += 4) + if (posq[i] != posq[i] || posq[i+1] != posq[i+1] || posq[i+2] != posq[i+2]) positionsValid = false; // Clear the forces. -- GitLab From 5e3a0a0555d3dc14bc61a7315faf21749fc6e656 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 22 Jan 2015 13:59:27 -0800 Subject: [PATCH 228/338] Began implementing triclinic boxes for reference AmoebaMultipoleForce (not yet debugged) --- .../reference/src/AmoebaReferenceKernels.cpp | 20 +- .../AmoebaReferenceMultipoleForce.cpp | 432 ++++++++++++------ .../AmoebaReferenceMultipoleForce.h | 41 +- 3 files changed, 317 insertions(+), 176 deletions(-) diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp index 97517f488..ec6078616 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp @@ -640,17 +640,17 @@ AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmo } else if( usePme ) { - AmoebaReferencePmeMultipoleForce* amoebaReferencePmeMultipoleForce = new AmoebaReferencePmeMultipoleForce( ); - amoebaReferencePmeMultipoleForce->setAlphaEwald( alphaEwald ); - amoebaReferencePmeMultipoleForce->setCutoffDistance( cutoffDistance ); - amoebaReferencePmeMultipoleForce->setPmeGridDimensions( pmeGridDimension ); - RealVec& box = extractBoxSize(context); - double minAllowedSize = 1.999999*cutoffDistance; - if (box[0] < minAllowedSize || box[1] < minAllowedSize || box[2] < minAllowedSize){ + AmoebaReferencePmeMultipoleForce* amoebaReferencePmeMultipoleForce = new AmoebaReferencePmeMultipoleForce( ); + amoebaReferencePmeMultipoleForce->setAlphaEwald( alphaEwald ); + amoebaReferencePmeMultipoleForce->setCutoffDistance( cutoffDistance ); + amoebaReferencePmeMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + RealVec* boxVectors = extractBoxVectors(context); + double minAllowedSize = 1.999999*cutoffDistance; + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize){ throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); - } - amoebaReferencePmeMultipoleForce->setPeriodicBoxSize(box); - amoebaReferenceMultipoleForce = static_cast(amoebaReferencePmeMultipoleForce); + } + amoebaReferencePmeMultipoleForce->setPeriodicBoxSize(boxVectors); + amoebaReferenceMultipoleForce = static_cast(amoebaReferencePmeMultipoleForce); } else { amoebaReferenceMultipoleForce = new AmoebaReferenceMultipoleForce( AmoebaReferenceMultipoleForce::NoCutoff ); diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp index 62a06d456..6937ee840 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp @@ -4608,22 +4608,24 @@ void AmoebaReferencePmeMultipoleForce::setPmeGridDimensions(vector& pmeGrid initializeBSplineModuli(); }; -void AmoebaReferencePmeMultipoleForce::setPeriodicBoxSize(RealVec& boxSize) +void AmoebaReferencePmeMultipoleForce::setPeriodicBoxSize(OpenMM::RealVec* vectors) { - if (boxSize[0] == 0.0 || boxSize[1] == 0.0 || boxSize[2] == 0.0) { + if (vectors[0][0] == 0.0 || vectors[1][1] == 0.0 || vectors[2][2] == 0.0) { std::stringstream message; message << "Box size of zero is invalid."; throw OpenMMException(message.str()); } - _periodicBoxSize = boxSize; - - _invPeriodicBoxSize[0] = 1.0/boxSize[0]; - _invPeriodicBoxSize[1] = 1.0/boxSize[1]; - _invPeriodicBoxSize[2] = 1.0/boxSize[2]; - - return; + _periodicBoxVectors[0] = vectors[0]; + _periodicBoxVectors[1] = vectors[1]; + _periodicBoxVectors[2] = vectors[2]; + RealOpenMM determinant = vectors[0][0]*vectors[1][1]*vectors[2][2]; + assert(determinant > 0); + RealOpenMM scale = 1.0/determinant; + _recipBoxVectors[0] = RealVec(vectors[1][1]*vectors[2][2], 0, 0)*scale; + _recipBoxVectors[1] = RealVec(-vectors[1][0]*vectors[2][2], vectors[0][0]*vectors[2][2], 0)*scale; + _recipBoxVectors[2] = RealVec(vectors[1][0]*vectors[2][1]-vectors[1][1]*vectors[2][0], -vectors[0][0]*vectors[2][1], vectors[0][0]*vectors[1][1])*scale; }; int compareInt2(const int2& v1, const int2& v2) @@ -4672,16 +4674,9 @@ void AmoebaReferencePmeMultipoleForce::initializePmeGrid() void AmoebaReferencePmeMultipoleForce::getPeriodicDelta(RealVec& deltaR) const { - deltaR[0] -= FLOOR(deltaR[0]*_invPeriodicBoxSize[0]+0.5)*_periodicBoxSize[0]; - deltaR[1] -= FLOOR(deltaR[1]*_invPeriodicBoxSize[1]+0.5)*_periodicBoxSize[1]; - deltaR[2] -= FLOOR(deltaR[2]*_invPeriodicBoxSize[2]+0.5)*_periodicBoxSize[2]; -} - -void AmoebaReferencePmeMultipoleForce::getPmeScale(RealVec& scale) const -{ - scale[0] = static_cast(_pmeGridDimensions[0])*_invPeriodicBoxSize[0]; - scale[1] = static_cast(_pmeGridDimensions[1])*_invPeriodicBoxSize[1]; - scale[2] = static_cast(_pmeGridDimensions[2])*_invPeriodicBoxSize[2]; + deltaR -= _periodicBoxVectors[2]*FLOOR(deltaR[2]*_recipBoxVectors[2][2]+0.5); + deltaR -= _periodicBoxVectors[1]*FLOOR(deltaR[1]*_recipBoxVectors[1][1]+0.5); + deltaR -= _periodicBoxVectors[0]*FLOOR(deltaR[0]*_recipBoxVectors[0][0]+0.5); } void AmoebaReferencePmeMultipoleForce::getDampedInverseDistances(const MultipoleParticleData& particleI, @@ -5039,7 +5034,7 @@ void AmoebaReferencePmeMultipoleForce::computeAmoebaBsplines(const vector(fr); w = fr - ifr; @@ -5095,8 +5090,8 @@ void AmoebaReferencePmeMultipoleForce::findAmoebaAtomRangeForGrid(const vector(fr)) - AMOEBA_PME_ORDER + 1; _pmeAtomGridIndex[ii][1] = z; @@ -5116,8 +5111,7 @@ void AmoebaReferencePmeMultipoleForce::getGridPointGivenGridIndex(int gridIndex, return; } -RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(const vector& particleData, - const int2& particleGridIndices, const RealVec& scale, +RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(const int2& particleGridIndices, int ix, int iy, const IntVec& gridPoint) const { @@ -5131,17 +5125,17 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(con iz -= _pmeGridDimensions[2]; } - RealOpenMM atomCharge = particleData[atomIndex].charge; - RealVec atomDipole = RealVec(scale[0]*particleData[atomIndex].dipole[0], - scale[1]*particleData[atomIndex].dipole[1], - scale[2]*particleData[atomIndex].dipole[2]); + RealOpenMM atomCharge = _transformed[atomIndex].charge; + RealVec atomDipole = RealVec(_transformed[atomIndex].dipole[0], + _transformed[atomIndex].dipole[1], + _transformed[atomIndex].dipole[2]); - RealOpenMM atomQuadrupoleXX = scale[0]*scale[0]*particleData[atomIndex].quadrupole[QXX]; - RealOpenMM atomQuadrupoleXY = 2.0*scale[0]*scale[1]*particleData[atomIndex].quadrupole[QXY]; - RealOpenMM atomQuadrupoleXZ = 2.0*scale[0]*scale[2]*particleData[atomIndex].quadrupole[QXZ]; - RealOpenMM atomQuadrupoleYY = scale[1]*scale[1]*particleData[atomIndex].quadrupole[QYY]; - RealOpenMM atomQuadrupoleYZ = 2.0*scale[1]*scale[2]*particleData[atomIndex].quadrupole[QYZ]; - RealOpenMM atomQuadrupoleZZ = scale[2]*scale[2]*particleData[atomIndex].quadrupole[QZZ]; + RealOpenMM atomQuadrupoleXX = _transformed[atomIndex].quadrupole[QXX]; + RealOpenMM atomQuadrupoleXY = _transformed[atomIndex].quadrupole[QXY]; + RealOpenMM atomQuadrupoleXZ = _transformed[atomIndex].quadrupole[QXZ]; + RealOpenMM atomQuadrupoleYY = _transformed[atomIndex].quadrupole[QYY]; + RealOpenMM atomQuadrupoleYZ = _transformed[atomIndex].quadrupole[QYZ]; + RealOpenMM atomQuadrupoleZZ = _transformed[atomIndex].quadrupole[QZZ]; RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix]; RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy]; @@ -5154,11 +5148,86 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(con return gridValue; } +void AmoebaReferencePmeMultipoleForce::transformMultipolesToFractionalCoordinates(const vector& particleData) { + // Build matrices for transforming the dipoles and quadrupoles. + + RealVec a[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + a[j][i] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; + int index1[] = {0, 0, 0, 1, 1, 2}; + int index2[] = {0, 1, 2, 1, 2, 2}; + RealOpenMM b[6][6]; + for (int i = 0; i < 6; i++) { + for (int j = 0; j < 6; j++) { + b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; + if (index1[i] != index2[i]) + b[i][j] += a[index1[i]][index2[j]]*a[index2[i]][index1[j]]; + } + } + + // Transform the multipoles. + + _transformed.resize(particleData.size()); + double quadScale[] = {1, 2, 2, 1, 2, 1}; + for (int i = 0; i < (int) particleData.size(); i++) { + _transformed[i].charge = particleData[i].charge; + _transformed[i].dipole = Vec3(); + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + _transformed[i].dipole[j] += a[j][k]*particleData[i].dipole[k]; + for (int j = 0; j < 6; j++) { + _transformed[i].quadrupole[j] = 0; + for (int k = 0; k < 6; k++) + _transformed[i].quadrupole[j] += quadScale[k]*b[j][k]*particleData[i].quadrupole[k]; + } + } +} + +void AmoebaReferencePmeMultipoleForce::transformPotentialToCartesianCoordinates(const vector& fphi, vector& cphi) const { + // Build a matrix for transforming the potential. + + RealVec a[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + a[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; + int index1[] = {0, 1, 2, 0, 0, 1}; + int index2[] = {0, 1, 2, 1, 2, 2}; + RealOpenMM b[6][6]; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 6; j++) { + b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; + if (index1[i] != index2[i]) + b[i][j] *= 2; + } + } + for (int i = 3; i < 6; i++) { + for (int j = 0; j < 6; j++) { + b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; + if (index1[i] != index2[i]) + b[i][j] += a[index1[i]][index2[j]]*a[index2[i]][index1[j]]; + } + } + + // Transform the potential. + + for (int i = 0; i < _numParticles; i++) { + cphi[10*i] = fphi[20*i]; + cphi[10*i+1] = a[0][0]*fphi[20*i+1] + a[0][1]*fphi[20*i+2] + a[0][2]*fphi[20*i+3]; + cphi[10*i+2] = a[1][0]*fphi[20*i+1] + a[1][1]*fphi[20*i+2] + a[1][2]*fphi[20*i+3]; + cphi[10*i+3] = a[2][0]*fphi[20*i+1] + a[2][1]*fphi[20*i+2] + a[2][2]*fphi[20*i+3]; + for (int j = 0; j < 6; j++) { + cphi[10*i+4+j] = 0; + for (int k = 0; k < 6; k++) + cphi[10*i+4+j] += b[j][k]*fphi[20*i+4+k]; + } + } +} + void AmoebaReferencePmeMultipoleForce::spreadFixedMultipolesOntoGrid(const vector& particleData) { - RealVec scale; - getPmeScale(scale); + transformMultipolesToFractionalCoordinates(particleData); for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) { @@ -5179,13 +5248,13 @@ void AmoebaReferencePmeMultipoleForce::spreadFixedMultipolesOntoGrid(const vecto int2 particleGridIndices; particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z1; particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z2; - result += computeFixedMultipolesGridValue(particleData, particleGridIndices, scale, ix, iy, gridPoint); + result += computeFixedMultipolesGridValue(particleGridIndices, ix, iy, gridPoint); if (z1 > gridPoint[2]) { particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]; particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+gridPoint[2]; - result += computeFixedMultipolesGridValue(particleData, particleGridIndices, scale, ix, iy, gridPoint); + result += computeFixedMultipolesGridValue(particleGridIndices, ix, iy, gridPoint); } } } @@ -5198,7 +5267,7 @@ void AmoebaReferencePmeMultipoleForce::performAmoebaReciprocalConvolution() { RealOpenMM expFactor = (M_PI*M_PI)/(_alphaEwald*_alphaEwald); - RealOpenMM scaleFactor = 1.0/(M_PI*_periodicBoxSize[0]*_periodicBoxSize[1]*_periodicBoxSize[2]); + RealOpenMM scaleFactor = 1.0/(M_PI*_periodicBoxVectors[0][0]*_periodicBoxVectors[1][1]*_periodicBoxVectors[2][2]); for (int index = 0; index < _totalGridSize; index++) { @@ -5216,9 +5285,9 @@ void AmoebaReferencePmeMultipoleForce::performAmoebaReciprocalConvolution() int my = (ky < (_pmeGridDimensions[1]+1)/2) ? ky : (ky-_pmeGridDimensions[1]); int mz = (kz < (_pmeGridDimensions[2]+1)/2) ? kz : (kz-_pmeGridDimensions[2]); - RealOpenMM mhx = mx*_invPeriodicBoxSize[0]; - RealOpenMM mhy = my*_invPeriodicBoxSize[1]; - RealOpenMM mhz = mz*_invPeriodicBoxSize[2]; + RealOpenMM mhx = mx*_recipBoxVectors[0][0]; + RealOpenMM mhy = mx*_recipBoxVectors[1][0]+my*_recipBoxVectors[1][1]; + RealOpenMM mhz = mx*_recipBoxVectors[2][0]+my*_recipBoxVectors[2][1]+mz*_recipBoxVectors[2][2]; RealOpenMM bx = _pmeBsplineModuli[0][kx]; RealOpenMM by = _pmeBsplineModuli[1][ky]; @@ -5341,7 +5410,7 @@ void AmoebaReferencePmeMultipoleForce::computeFixedPotentialFromGrid() } } -t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const int2& particleGridIndices, const RealVec& scale, int ix, int iy, +t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const int2& particleGridIndices, const RealVec* fracToCart, int ix, int iy, const IntVec& gridPoint, const vector& inputInducedDipole, const vector& inputInducedDipolePolar) const @@ -5361,13 +5430,16 @@ t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const if (iz >= _pmeGridDimensions[2]) { iz -= _pmeGridDimensions[2]; } - RealVec inducedDipole = RealVec(scale[0]*inputInducedDipole[atomIndex][0], - scale[1]*inputInducedDipole[atomIndex][1], - scale[2]*inputInducedDipole[atomIndex][2]); + RealVec inducedDipole = RealVec(inputInducedDipole[atomIndex][0]*fracToCart[0][0] + inputInducedDipole[atomIndex][1]*fracToCart[0][1] + inputInducedDipole[atomIndex][2]*fracToCart[0][2], + inputInducedDipole[atomIndex][0]*fracToCart[1][0] + inputInducedDipole[atomIndex][1]*fracToCart[1][1] + inputInducedDipole[atomIndex][2]*fracToCart[1][2], + inputInducedDipole[atomIndex][0]*fracToCart[2][0] + inputInducedDipole[atomIndex][1]*fracToCart[2][1] + inputInducedDipole[atomIndex][2]*fracToCart[2][2]); + RealVec inducedDipolePolar = RealVec(inputInducedDipolePolar[atomIndex][0]*fracToCart[0][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[0][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[0][2], + inputInducedDipolePolar[atomIndex][0]*fracToCart[1][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[1][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[1][2], + inputInducedDipolePolar[atomIndex][0]*fracToCart[2][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[2][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[2][2]); - RealVec inducedDipolePolar = RealVec(scale[0]*inputInducedDipolePolar[atomIndex][0], - scale[1]*inputInducedDipolePolar[atomIndex][1], - scale[2]*inputInducedDipolePolar[atomIndex][2]); +// RealVec inducedDipolePolar = RealVec(scale[0]*inputInducedDipolePolar[atomIndex][0], +// scale[1]*inputInducedDipolePolar[atomIndex][1], +// scale[2]*inputInducedDipolePolar[atomIndex][2]); RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix]; RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy]; @@ -5388,8 +5460,10 @@ t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector& inputInducedDipole, const vector& inputInducedDipolePolar) { - RealVec scale; - getPmeScale(scale); + RealVec fracToCart[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) { @@ -5412,13 +5486,13 @@ void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector gridPoint[2]) { particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]; particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+gridPoint[2]; - gridValue += computeInducedDipoleGridValue(particleGridIndices, scale, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar); + gridValue += computeInducedDipoleGridValue(particleGridIndices, fracToCart, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar); } } } @@ -5638,8 +5712,14 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19}; const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16}; const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18}; - RealVec scale; - getPmeScale(scale); + vector cphi(10*_numParticles); + transformPotentialToCartesianCoordinates(_phi, cphi); +// RealVec scale; +// getPmeScale(scale); + RealVec fracToCart[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; RealOpenMM energy = 0.0; for (int i = 0; i < _numParticles; i++) { @@ -5659,46 +5739,73 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol multipole[8] = particleData[i].quadrupole[QXZ]*2.0; multipole[9] = particleData[i].quadrupole[QYZ]*2.0; - const RealOpenMM* phi = &_phi[20*i]; - torques[i][0] += _electric*(multipole[3]*scale[1]*phi[2] - multipole[2]*scale[2]*phi[3] - + 2.0*(multipole[6]-multipole[5])*scale[1]*scale[2]*phi[9] - + multipole[8]*scale[0]*scale[1]*phi[7] + multipole[9]*scale[1]*scale[1]*phi[5] - - multipole[7]*scale[0]*scale[2]*phi[8] - multipole[9]*scale[2]*scale[2]*phi[6]); - - torques[i][1] += _electric*(multipole[1]*scale[2]*phi[3] - multipole[3]*scale[0]*phi[1] - + 2.0*(multipole[4]-multipole[6])*scale[0]*scale[2]*phi[8] - + multipole[7]*scale[1]*scale[2]*phi[9] + multipole[8]*scale[2]*scale[2]*phi[6] - - multipole[8]*scale[0]*scale[0]*phi[4] - multipole[9]*scale[0]*scale[1]*phi[7]); - - torques[i][2] += _electric*(multipole[2]*scale[0]*phi[1] - multipole[1]*scale[1]*phi[2] - + 2.0*(multipole[5]-multipole[4])*scale[0]*scale[1]*phi[7] - + multipole[7]*scale[0]*scale[0]*phi[4] + multipole[9]*scale[0]*scale[2]*phi[8] - - multipole[7]*scale[1]*scale[1]*phi[5] - multipole[8]*scale[1]*scale[2]*phi[9]); +// const RealOpenMM* phi = &_phi[20*i]; +// torques[i][0] += _electric*(multipole[3]*scale[1]*phi[2] - multipole[2]*scale[2]*phi[3] +// + 2.0*(multipole[6]-multipole[5])*scale[1]*scale[2]*phi[9] +// + multipole[8]*scale[0]*scale[1]*phi[7] + multipole[9]*scale[1]*scale[1]*phi[5] +// - multipole[7]*scale[0]*scale[2]*phi[8] - multipole[9]*scale[2]*scale[2]*phi[6]); +// +// torques[i][1] += _electric*(multipole[1]*scale[2]*phi[3] - multipole[3]*scale[0]*phi[1] +// + 2.0*(multipole[4]-multipole[6])*scale[0]*scale[2]*phi[8] +// + multipole[7]*scale[1]*scale[2]*phi[9] + multipole[8]*scale[2]*scale[2]*phi[6] +// - multipole[8]*scale[0]*scale[0]*phi[4] - multipole[9]*scale[0]*scale[1]*phi[7]); +// +// torques[i][2] += _electric*(multipole[2]*scale[0]*phi[1] - multipole[1]*scale[1]*phi[2] +// + 2.0*(multipole[5]-multipole[4])*scale[0]*scale[1]*phi[7] +// + multipole[7]*scale[0]*scale[0]*phi[4] + multipole[9]*scale[0]*scale[2]*phi[8] +// - multipole[7]*scale[1]*scale[1]*phi[5] - multipole[8]*scale[1]*scale[2]*phi[9]); + + const RealOpenMM* phi = &cphi[10*i]; + torques[i][0] += _electric*(multipole[3]*phi[2] - multipole[2]*phi[3] + + 2.0*(multipole[6]-multipole[5])*phi[9] + + multipole[8]*phi[7] + multipole[9]*phi[5] + - multipole[7]*phi[8] - multipole[9]*phi[6]); + + torques[i][1] += _electric*(multipole[1]*phi[3] - multipole[3]*phi[1] + + 2.0*(multipole[4]-multipole[6])*phi[8] + + multipole[7]*phi[9] + multipole[8]*phi[6] + - multipole[8]*phi[4] - multipole[9]*phi[7]); + + torques[i][2] += _electric*(multipole[2]*phi[1] - multipole[1]*phi[2] + + 2.0*(multipole[5]-multipole[4])*phi[7] + + multipole[7]*phi[4] + multipole[9]*phi[8] + - multipole[7]*phi[5] - multipole[8]*phi[9]); // Compute the force and energy. - multipole[1] *= scale[0]; - multipole[2] *= scale[1]; - multipole[3] *= scale[2]; - multipole[4] *= scale[0]*scale[0]; - multipole[5] *= scale[1]*scale[1]; - multipole[6] *= scale[2]*scale[2]; - multipole[7] *= scale[0]*scale[1]; - multipole[8] *= scale[0]*scale[2]; - multipole[9] *= scale[1]*scale[2]; + multipole[1] = _transformed[i].dipole[0]; + multipole[2] = _transformed[i].dipole[1]; + multipole[3] = _transformed[i].dipole[2]; + multipole[4] = _transformed[i].quadrupole[QXX]; + multipole[5] = _transformed[i].quadrupole[QYY]; + multipole[6] = _transformed[i].quadrupole[QZZ]; + multipole[7] = _transformed[i].quadrupole[QXY]; + multipole[8] = _transformed[i].quadrupole[QXZ]; + multipole[9] = _transformed[i].quadrupole[QYZ]; +// multipole[1] *= scale[0]; +// multipole[2] *= scale[1]; +// multipole[3] *= scale[2]; +// multipole[4] *= scale[0]*scale[0]; +// multipole[5] *= scale[1]*scale[1]; +// multipole[6] *= scale[2]*scale[2]; +// multipole[7] *= scale[0]*scale[1]; +// multipole[8] *= scale[0]*scale[2]; +// multipole[9] *= scale[1]*scale[2]; RealVec f = RealVec(0.0, 0.0, 0.0); for (int k = 0; k < 10; k++) { - energy += multipole[k]*phi[k]; - f[0] += multipole[k]*phi[deriv1[k]]; - f[1] += multipole[k]*phi[deriv2[k]]; - f[2] += multipole[k]*phi[deriv3[k]]; + energy += multipole[k]*_phi[20*i+k]; + f[0] += multipole[k]*_phi[20*i+deriv1[k]]; + f[1] += multipole[k]*_phi[20*i+deriv2[k]]; + f[2] += multipole[k]*_phi[20*i+deriv3[k]]; } - f[0] *= scale[0]; - f[1] *= scale[1]; - f[2] *= scale[2]; +// f[0] *= scale[0]; +// f[1] *= scale[1]; +// f[2] *= scale[2]; f *= (_electric); - forces[i] -= f; + forces[i] -= RealVec(f[0]*fracToCart[0][0] + f[1]*fracToCart[0][1] + f[2]*fracToCart[0][2], + f[0]*fracToCart[1][0] + f[1]*fracToCart[1][1] + f[2]*fracToCart[1][2], + f[0]*fracToCart[2][0] + f[1]*fracToCart[2][1] + f[2]*fracToCart[2][2]); } return (0.5*_electric*energy); @@ -5719,8 +5826,14 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19}; const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16}; const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18}; - RealVec scale; - getPmeScale(scale); + vector cphi(10*_numParticles); + transformPotentialToCartesianCoordinates(_phidp, cphi); + RealVec cartToFrac[3], fracToCart[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + cartToFrac[j][i] = fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; +// RealVec scale; +// getPmeScale(scale); RealOpenMM energy = 0.0; for (int i = 0; i < _numParticles; i++) { @@ -5741,45 +5854,54 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole multipole[8] = particleData[i].quadrupole[QXZ]*2.0; multipole[9] = particleData[i].quadrupole[QYZ]*2.0; - torques[iIndex][0] += 0.5*_electric*(multipole[3]*scale[1]*_phidp[20*i+2] - multipole[2]*scale[2]*_phidp[20*i+3] - + 2.0*(multipole[6]-multipole[5])*scale[1]*scale[2]*_phidp[20*i+9] - + multipole[8]*scale[0]*scale[1]*_phidp[20*i+7] + multipole[9]*scale[1]*scale[1]*_phidp[20*i+5] - - multipole[7]*scale[0]*scale[2]*_phidp[20*i+8] - multipole[9]*scale[2]*scale[2]*_phidp[20*i+6]); + const RealOpenMM* phi = &cphi[10*i]; + torques[iIndex][0] += 0.5*_electric*(multipole[3]*phi[2] - multipole[2]*phi[3] + + 2.0*(multipole[6]-multipole[5])*phi[9] + + multipole[8]*phi[7] + multipole[9]*phi[5] + - multipole[7]*phi[8] - multipole[9]*phi[6]); - torques[iIndex][1] += 0.5*_electric*(multipole[1]*scale[2]*_phidp[20*i+3] - multipole[3]*scale[0]*_phidp[20*i+1] - + 2.0*(multipole[4]-multipole[6])*scale[0]*scale[2]*_phidp[20*i+8] - + multipole[7]*scale[1]*scale[2]*_phidp[20*i+9] + multipole[8]*scale[2]*scale[2]*_phidp[20*i+6] - - multipole[8]*scale[0]*scale[0]*_phidp[20*i+4] - multipole[9]*scale[0]*scale[1]*_phidp[20*i+7]); + torques[iIndex][1] += 0.5*_electric*(multipole[1]*phi[3] - multipole[3]*phi[1] + + 2.0*(multipole[4]-multipole[6])*phi[8] + + multipole[7]*phi[9] + multipole[8]*phi[6] + - multipole[8]*phi[4] - multipole[9]*phi[7]); - torques[iIndex][2] += 0.5*_electric*(multipole[2]*scale[0]*_phidp[20*i+1] - multipole[1]*scale[1]*_phidp[20*i+2] - + 2.0*(multipole[5]-multipole[4])*scale[0]*scale[1]*_phidp[20*i+7] - + multipole[7]*scale[0]*scale[0]*_phidp[20*i+4] + multipole[9]*scale[0]*scale[2]*_phidp[20*i+8] - - multipole[7]*scale[1]*scale[1]*_phidp[20*i+5] - multipole[8]*scale[1]*scale[2]*_phidp[20*i+9]); + torques[iIndex][2] += 0.5*_electric*(multipole[2]*phi[1] - multipole[1]*phi[2] + + 2.0*(multipole[5]-multipole[4])*phi[7] + + multipole[7]*phi[4] + multipole[9]*phi[8] + - multipole[7]*phi[5] - multipole[8]*phi[9]); // Compute the force and energy. - multipole[1] *= scale[0]; - multipole[2] *= scale[1]; - multipole[3] *= scale[2]; - - multipole[4] *= scale[0]*scale[0]; - multipole[5] *= scale[1]*scale[1]; - multipole[6] *= scale[2]*scale[2]; - multipole[7] *= scale[0]*scale[1]; - multipole[8] *= scale[0]*scale[2]; - multipole[9] *= scale[1]*scale[2]; - - inducedDipole[0] = _inducedDipole[i][0]; - inducedDipole[1] = _inducedDipole[i][1]; - inducedDipole[2] = _inducedDipole[i][2]; - - inducedDipolePolar[0] = _inducedDipolePolar[i][0]; - inducedDipolePolar[1] = _inducedDipolePolar[i][1]; - inducedDipolePolar[2] = _inducedDipolePolar[i][2]; - - energy += scale[0]*inducedDipole[0]*_phi[20*i+1]; - energy += scale[1]*inducedDipole[1]*_phi[20*i+2]; - energy += scale[2]*inducedDipole[2]*_phi[20*i+3]; + multipole[1] = _transformed[i].dipole[0]; + multipole[2] = _transformed[i].dipole[1]; + multipole[3] = _transformed[i].dipole[2]; + multipole[4] = _transformed[i].quadrupole[QXX]; + multipole[5] = _transformed[i].quadrupole[QYY]; + multipole[6] = _transformed[i].quadrupole[QZZ]; + multipole[7] = _transformed[i].quadrupole[QXY]; + multipole[8] = _transformed[i].quadrupole[QXZ]; + multipole[9] = _transformed[i].quadrupole[QYZ]; +// multipole[1] *= scale[0]; +// multipole[2] *= scale[1]; +// multipole[3] *= scale[2]; +// +// multipole[4] *= scale[0]*scale[0]; +// multipole[5] *= scale[1]*scale[1]; +// multipole[6] *= scale[2]*scale[2]; +// multipole[7] *= scale[0]*scale[1]; +// multipole[8] *= scale[0]*scale[2]; +// multipole[9] *= scale[1]*scale[2]; + + inducedDipole[0] = _inducedDipole[i][0]*cartToFrac[0][0] + _inducedDipole[i][1]*cartToFrac[0][1] + _inducedDipole[i][2]*cartToFrac[0][2]; + inducedDipole[1] = _inducedDipole[i][0]*cartToFrac[1][0] + _inducedDipole[i][1]*cartToFrac[1][1] + _inducedDipole[i][2]*cartToFrac[1][2]; + inducedDipole[2] = _inducedDipole[i][0]*cartToFrac[2][0] + _inducedDipole[i][1]*cartToFrac[2][1] + _inducedDipole[i][2]*cartToFrac[2][2]; + inducedDipolePolar[0] = _inducedDipolePolar[i][0]*cartToFrac[0][0] + _inducedDipolePolar[i][1]*cartToFrac[0][1] + _inducedDipolePolar[i][2]*cartToFrac[0][2]; + inducedDipolePolar[1] = _inducedDipolePolar[i][0]*cartToFrac[1][0] + _inducedDipolePolar[i][1]*cartToFrac[1][1] + _inducedDipolePolar[i][2]*cartToFrac[1][2]; + inducedDipolePolar[2] = _inducedDipolePolar[i][0]*cartToFrac[2][0] + _inducedDipolePolar[i][1]*cartToFrac[2][1] + _inducedDipolePolar[i][2]*cartToFrac[2][2]; + + energy += inducedDipole[0]*_phi[20*i+1]; + energy += inducedDipole[1]*_phi[20*i+2]; + energy += inducedDipole[2]*_phi[20*i+3]; RealVec f = RealVec(0.0, 0.0, 0.0); @@ -5789,47 +5911,49 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole int j2 = deriv2[k+1]; int j3 = deriv3[k+1]; - f[0] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j1]*(scale[k]/scale[0]); - f[1] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j2]*(scale[k]/scale[1]); - f[2] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j3]*(scale[k]/scale[2]); + f[0] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j1]; + f[1] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j2]; + f[2] += (inducedDipole[k]+inducedDipolePolar[k])*_phi[20*i+j3]; if (polarizationType == AmoebaReferenceMultipoleForce::Mutual) { - f[0] += (inducedDipole[k]*_phip[10*i+j1] + inducedDipolePolar[k]*_phid[10*i+j1])*(scale[k]/scale[0]); - f[1] += (inducedDipole[k]*_phip[10*i+j2] + inducedDipolePolar[k]*_phid[10*i+j2])*(scale[k]/scale[1]); - f[2] += (inducedDipole[k]*_phip[10*i+j3] + inducedDipolePolar[k]*_phid[10*i+j3])*(scale[k]/scale[2]); + f[0] += (inducedDipole[k]*_phip[10*i+j1] + inducedDipolePolar[k]*_phid[10*i+j1]); + f[1] += (inducedDipole[k]*_phip[10*i+j2] + inducedDipolePolar[k]*_phid[10*i+j2]); + f[2] += (inducedDipole[k]*_phip[10*i+j3] + inducedDipolePolar[k]*_phid[10*i+j3]); } } - f[0] *= scale[0]; - f[1] *= scale[1]; - f[2] *= scale[2]; - for (int k = 0; k < 10; k++) { f[0] += multipole[k]*_phidp[20*i+deriv1[k]]; f[1] += multipole[k]*_phidp[20*i+deriv2[k]]; f[2] += multipole[k]*_phidp[20*i+deriv3[k]]; } - f[0] *= scale[0]; - f[1] *= scale[1]; - f[2] *= scale[2]; +// f[0] *= scale[0]; +// f[1] *= scale[1]; +// f[2] *= scale[2]; f *= (0.5*_electric); - forces[iIndex] -= f; + forces[iIndex] -= RealVec(f[0]*fracToCart[0][0] + f[1]*fracToCart[0][1] + f[2]*fracToCart[0][2], + f[0]*fracToCart[1][0] + f[1]*fracToCart[1][1] + f[2]*fracToCart[1][2], + f[0]*fracToCart[2][0] + f[1]*fracToCart[2][1] + f[2]*fracToCart[2][2]); } return (0.5*_electric*energy); } void AmoebaReferencePmeMultipoleForce::recordFixedMultipoleField() { - RealVec scale; - getPmeScale(scale); - scale *= -1.0; +// RealVec scale; +// getPmeScale(scale); +// scale *= -1.0; + RealVec fracToCart[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; for (int i = 0; i < _numParticles; i++) { - _fixedMultipoleField[i][0] = scale[0]*_phi[20*i+1]; - _fixedMultipoleField[i][1] = scale[1]*_phi[20*i+2]; - _fixedMultipoleField[i][2] = scale[2]*_phi[20*i+3]; + _fixedMultipoleField[i][0] = -(_phi[20*i+1]*fracToCart[0][0] + _phi[20*i+2]*fracToCart[0][1] + _phi[20*i+3]*fracToCart[0][2]); + _fixedMultipoleField[i][1] = -(_phi[20*i+1]*fracToCart[1][0] + _phi[20*i+2]*fracToCart[1][1] + _phi[20*i+3]*fracToCart[1][2]); + _fixedMultipoleField[i][2] = -(_phi[20*i+1]*fracToCart[2][0] + _phi[20*i+2]*fracToCart[2][1] + _phi[20*i+3]*fracToCart[2][2]); } return; } @@ -5844,18 +5968,22 @@ void AmoebaReferencePmeMultipoleForce::initializeInducedDipoles(vector& field, vector& fieldPolar) { - RealVec scale; - getPmeScale(scale); - scale *= -1.0; +// RealVec scale; +// getPmeScale(scale); +// scale *= -1.0; + RealVec fracToCart[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; for (int i = 0; i < _numParticles; i++) { - field[i][0] += scale[0]*_phid[10*i+1]; - field[i][1] += scale[1]*_phid[10*i+2]; - field[i][2] += scale[2]*_phid[10*i+3]; + field[i][0] -= _phid[10*i+1]*fracToCart[0][0] + _phid[10*i+2]*fracToCart[0][1] + _phid[10*i+3]*fracToCart[0][2]; + field[i][1] -= _phid[10*i+1]*fracToCart[1][0] + _phid[10*i+2]*fracToCart[1][1] + _phid[10*i+3]*fracToCart[1][2]; + field[i][2] -= _phid[10*i+1]*fracToCart[2][0] + _phid[10*i+2]*fracToCart[2][1] + _phid[10*i+3]*fracToCart[2][2]; - fieldPolar[i][0] += scale[0]*_phip[10*i+1]; - fieldPolar[i][1] += scale[1]*_phip[10*i+2]; - fieldPolar[i][2] += scale[2]*_phip[10*i+3]; + fieldPolar[i][0] -= _phip[10*i+1]*fracToCart[0][0] + _phip[10*i+2]*fracToCart[0][1] + _phip[10*i+3]*fracToCart[0][2]; + fieldPolar[i][1] -= _phip[10*i+1]*fracToCart[1][0] + _phip[10*i+2]*fracToCart[1][1] + _phip[10*i+3]*fracToCart[1][2]; + fieldPolar[i][2] -= _phip[10*i+1]*fracToCart[2][0] + _phip[10*i+2]*fracToCart[2][1] + _phip[10*i+3]*fracToCart[2][2]; } return; } diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h index 95a260d46..3cf43b58e 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h @@ -591,6 +591,16 @@ protected: RealOpenMM dampingFactor; RealOpenMM polarity; }; + + /** + * Particle parameters transformed into fractional coordinates + */ + class TransformedMultipole { + public: + RealOpenMM charge; + RealVec dipole; + RealOpenMM quadrupole[6]; + }; /* * Helper class used in calculating induced dipoles @@ -618,6 +628,7 @@ protected: RealOpenMM _mScale[5]; RealOpenMM _uScale[5]; + std::vector _transformed; std::vector _fixedMultipoleField; std::vector _fixedMultipoleFieldPolar; std::vector _inducedDipole; @@ -1327,9 +1338,9 @@ public: /** * Set periodic box size. * - * @param boxSize box dimensions + * @param vectors the vectors defining the periodic box */ - void setPeriodicBoxSize(RealVec& boxSize); + void setPeriodicBoxSize(OpenMM::RealVec* vectors); private: @@ -1340,8 +1351,8 @@ private: RealOpenMM _cutoffDistance; RealOpenMM _cutoffDistanceSquared; - RealVec _invPeriodicBoxSize; - RealVec _periodicBoxSize; + RealVec _recipBoxVectors[3]; + RealVec _periodicBoxVectors[3]; int _totalGridSize; IntVec _pmeGridDimensions; @@ -1382,12 +1393,6 @@ private: */ void getPeriodicDelta(RealVec& deltaR) const; - /** - * Get PME scale. - * - */ - void getPmeScale(RealVec& scale) const; - /** * Calculate damped inverse distances. * @@ -1460,7 +1465,6 @@ private: /** * Compute induced dipole grid value. * - * @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...) * @param particleGridIndices particle grid indices * @param scale integer grid dimension/box size for each dimension * @param ix x-dimension offset value @@ -1469,8 +1473,17 @@ private: * @param inputInducedDipole induced dipole value * @param inputInducedDipolePolar induced dipole value */ - RealOpenMM computeFixedMultipolesGridValue(const vector& particleData, - const int2& particleGridIndices, const RealVec& scale, int ix, int iy, const IntVec& gridPoint) const; + RealOpenMM computeFixedMultipolesGridValue(const int2& particleGridIndices, int ix, int iy, const IntVec& gridPoint) const; + + /** + * Transform multipoles from cartesian coordinates to fractional coordinates. + */ + void transformMultipolesToFractionalCoordinates(const vector& particleData); + + /** + * Transform potential from fractional coordinates to cartesian coordinates. + */ + void transformPotentialToCartesianCoordinates(const std::vector& fphi, std::vector& cphi) const; /** * Spread fixed multipoles onto PME grid. @@ -1568,7 +1581,7 @@ private: * @param inputInducedDipole induced dipole value * @param inputInducedDipolePolar induced dipole polar value */ - t_complex computeInducedDipoleGridValue(const int2& atomIndices, const RealVec& scale, int ix, int iy, const IntVec& gridPoint, + t_complex computeInducedDipoleGridValue(const int2& atomIndices, const RealVec* fracToCart, int ix, int iy, const IntVec& gridPoint, const std::vector& inputInducedDipole, const std::vector& inputInducedDipolePolar) const; -- GitLab From 26574a3e4cad63b67615985f79c5f5d75dfb380e Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 2 Feb 2015 12:19:40 -0500 Subject: [PATCH 229/338] Add error checking for the input GB radii in the GBn methods. The radii must be between 1 and 2 Angstroms, or they fall outside the bounds of the neck lookup tables. At least on my Mac, this results in a C++ exception that does not get translated into a Python exception (i.e., it is not catchable and crashes the application) --- .../simtk/openmm/app/internal/amber_file_parser.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 78f55cdea..076ecbc1b 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -564,6 +564,12 @@ class PrmtopLoader(object): screen[i] = 0.602256336067 else: screen[i] = 0.5 + # radii is currently in Angstroms right now. GBn lookup tables + # only support radii between 1.0 and 2.0 + if radii[r] < 1.0 or radii[r] > 2.0: + raise ValueError('GBn requires intrinsic radii between 1 and ' + '2 Angstroms (%.3f found for atom %d)' % + (radii[r], i)) if gbmodel == 'GBn2': if elements is None: raise Exception('GBn2 model requires element information') @@ -598,6 +604,12 @@ class PrmtopLoader(object): alpha[i] = 1.0 beta[i] = 0.8 gamma[i] = 4.85 + # radii is currently in Angstroms right now. GBn lookup tables + # only support radii between 1.0 and 2.0 + if radii[r] < 1.0 or radii[r] > 2.0: + raise ValueError('GBn2 requires intrinsic radii between 1 and ' + '2 Angstroms (%.3f found for atom %d)' % + (radii[r], i)) lengthConversionFactor = units.angstrom.conversion_factor_to(units.nanometer) if gbmodel == 'GBn2': for rad, scr, alp, bet, gam in zip(radii, screen, alpha, beta, gamma): -- GitLab From 5d8e92ff31d1951b4c4ac97ec2a23bdf3d29de9d Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 2 Feb 2015 14:06:31 -0500 Subject: [PATCH 230/338] Use the correct index this time. --- .../python/simtk/openmm/app/internal/amber_file_parser.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 076ecbc1b..1558ce34f 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -566,10 +566,10 @@ class PrmtopLoader(object): screen[i] = 0.5 # radii is currently in Angstroms right now. GBn lookup tables # only support radii between 1.0 and 2.0 - if radii[r] < 1.0 or radii[r] > 2.0: + if radii[i] < 1.0 or radii[i] > 2.0: raise ValueError('GBn requires intrinsic radii between 1 and ' '2 Angstroms (%.3f found for atom %d)' % - (radii[r], i)) + (radii[i], i)) if gbmodel == 'GBn2': if elements is None: raise Exception('GBn2 model requires element information') @@ -606,10 +606,10 @@ class PrmtopLoader(object): gamma[i] = 4.85 # radii is currently in Angstroms right now. GBn lookup tables # only support radii between 1.0 and 2.0 - if radii[r] < 1.0 or radii[r] > 2.0: + if radii[i] < 1.0 or radii[i] > 2.0: raise ValueError('GBn2 requires intrinsic radii between 1 and ' '2 Angstroms (%.3f found for atom %d)' % - (radii[r], i)) + (radii[i], i)) lengthConversionFactor = units.angstrom.conversion_factor_to(units.nanometer) if gbmodel == 'GBn2': for rad, scr, alp, bet, gam in zip(radii, screen, alpha, beta, gamma): -- GitLab From 82e118fbf16d2bb920718e78bef35571507c8038 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Tue, 3 Feb 2015 11:34:32 -0800 Subject: [PATCH 231/338] Bug fixes to triclinic boxes for reference AmoebaMultipoleForce --- .../AmoebaReferenceMultipoleForce.cpp | 88 +++--------- .../AmoebaReferenceMultipoleForce.h | 18 +-- .../TestReferenceAmoebaMultipoleForce.cpp | 135 +++++++++++++++++- 3 files changed, 157 insertions(+), 84 deletions(-) diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp index 6937ee840..f21d20951 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2006-2014 Stanford University and Simbios. +/* Portions copyright (c) 2006-2015 Stanford University and Simbios. * Contributors: Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -5036,7 +5036,7 @@ void AmoebaReferencePmeMultipoleForce::computeAmoebaBsplines(const vector(fr); + int ifr = static_cast(floor(fr)); w = fr - ifr; igrid[jj] = ifr - AMOEBA_PME_ORDER + 1; igrid[jj] += igrid[jj] < 0 ? _pmeGridDimensions[jj] : 0; @@ -5197,14 +5197,14 @@ void AmoebaReferencePmeMultipoleForce::transformPotentialToCartesianCoordinates( for (int i = 0; i < 3; i++) { for (int j = 0; j < 6; j++) { b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; - if (index1[i] != index2[i]) + if (index1[j] != index2[j]) b[i][j] *= 2; } } for (int i = 3; i < 6; i++) { for (int j = 0; j < 6; j++) { b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; - if (index1[i] != index2[i]) + if (index1[j] != index2[j]) b[i][j] += a[index1[i]][index2[j]]*a[index2[i]][index1[j]]; } } @@ -5410,7 +5410,7 @@ void AmoebaReferencePmeMultipoleForce::computeFixedPotentialFromGrid() } } -t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const int2& particleGridIndices, const RealVec* fracToCart, int ix, int iy, +t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const int2& particleGridIndices, const RealVec* cartToFrac, int ix, int iy, const IntVec& gridPoint, const vector& inputInducedDipole, const vector& inputInducedDipolePolar) const @@ -5430,16 +5430,12 @@ t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const if (iz >= _pmeGridDimensions[2]) { iz -= _pmeGridDimensions[2]; } - RealVec inducedDipole = RealVec(inputInducedDipole[atomIndex][0]*fracToCart[0][0] + inputInducedDipole[atomIndex][1]*fracToCart[0][1] + inputInducedDipole[atomIndex][2]*fracToCart[0][2], - inputInducedDipole[atomIndex][0]*fracToCart[1][0] + inputInducedDipole[atomIndex][1]*fracToCart[1][1] + inputInducedDipole[atomIndex][2]*fracToCart[1][2], - inputInducedDipole[atomIndex][0]*fracToCart[2][0] + inputInducedDipole[atomIndex][1]*fracToCart[2][1] + inputInducedDipole[atomIndex][2]*fracToCart[2][2]); - RealVec inducedDipolePolar = RealVec(inputInducedDipolePolar[atomIndex][0]*fracToCart[0][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[0][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[0][2], - inputInducedDipolePolar[atomIndex][0]*fracToCart[1][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[1][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[1][2], - inputInducedDipolePolar[atomIndex][0]*fracToCart[2][0] + inputInducedDipolePolar[atomIndex][1]*fracToCart[2][1] + inputInducedDipolePolar[atomIndex][2]*fracToCart[2][2]); - -// RealVec inducedDipolePolar = RealVec(scale[0]*inputInducedDipolePolar[atomIndex][0], -// scale[1]*inputInducedDipolePolar[atomIndex][1], -// scale[2]*inputInducedDipolePolar[atomIndex][2]); + RealVec inducedDipole = RealVec(inputInducedDipole[atomIndex][0]*cartToFrac[0][0] + inputInducedDipole[atomIndex][1]*cartToFrac[0][1] + inputInducedDipole[atomIndex][2]*cartToFrac[0][2], + inputInducedDipole[atomIndex][0]*cartToFrac[1][0] + inputInducedDipole[atomIndex][1]*cartToFrac[1][1] + inputInducedDipole[atomIndex][2]*cartToFrac[1][2], + inputInducedDipole[atomIndex][0]*cartToFrac[2][0] + inputInducedDipole[atomIndex][1]*cartToFrac[2][1] + inputInducedDipole[atomIndex][2]*cartToFrac[2][2]); + RealVec inducedDipolePolar = RealVec(inputInducedDipolePolar[atomIndex][0]*cartToFrac[0][0] + inputInducedDipolePolar[atomIndex][1]*cartToFrac[0][1] + inputInducedDipolePolar[atomIndex][2]*cartToFrac[0][2], + inputInducedDipolePolar[atomIndex][0]*cartToFrac[1][0] + inputInducedDipolePolar[atomIndex][1]*cartToFrac[1][1] + inputInducedDipolePolar[atomIndex][2]*cartToFrac[1][2], + inputInducedDipolePolar[atomIndex][0]*cartToFrac[2][0] + inputInducedDipolePolar[atomIndex][1]*cartToFrac[2][1] + inputInducedDipolePolar[atomIndex][2]*cartToFrac[2][2]); RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix]; RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy]; @@ -5460,10 +5456,10 @@ t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector& inputInducedDipole, const vector& inputInducedDipolePolar) { - RealVec fracToCart[3]; + RealVec cartToFrac[3]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) - fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; + cartToFrac[j][i] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) { @@ -5486,13 +5482,13 @@ void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector gridPoint[2]) { particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]; particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+gridPoint[2]; - gridValue += computeInducedDipoleGridValue(particleGridIndices, fracToCart, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar); + gridValue += computeInducedDipoleGridValue(particleGridIndices, cartToFrac, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar); } } } @@ -5714,8 +5710,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18}; vector cphi(10*_numParticles); transformPotentialToCartesianCoordinates(_phi, cphi); -// RealVec scale; -// getPmeScale(scale); RealVec fracToCart[3]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) @@ -5739,22 +5733,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol multipole[8] = particleData[i].quadrupole[QXZ]*2.0; multipole[9] = particleData[i].quadrupole[QYZ]*2.0; -// const RealOpenMM* phi = &_phi[20*i]; -// torques[i][0] += _electric*(multipole[3]*scale[1]*phi[2] - multipole[2]*scale[2]*phi[3] -// + 2.0*(multipole[6]-multipole[5])*scale[1]*scale[2]*phi[9] -// + multipole[8]*scale[0]*scale[1]*phi[7] + multipole[9]*scale[1]*scale[1]*phi[5] -// - multipole[7]*scale[0]*scale[2]*phi[8] - multipole[9]*scale[2]*scale[2]*phi[6]); -// -// torques[i][1] += _electric*(multipole[1]*scale[2]*phi[3] - multipole[3]*scale[0]*phi[1] -// + 2.0*(multipole[4]-multipole[6])*scale[0]*scale[2]*phi[8] -// + multipole[7]*scale[1]*scale[2]*phi[9] + multipole[8]*scale[2]*scale[2]*phi[6] -// - multipole[8]*scale[0]*scale[0]*phi[4] - multipole[9]*scale[0]*scale[1]*phi[7]); -// -// torques[i][2] += _electric*(multipole[2]*scale[0]*phi[1] - multipole[1]*scale[1]*phi[2] -// + 2.0*(multipole[5]-multipole[4])*scale[0]*scale[1]*phi[7] -// + multipole[7]*scale[0]*scale[0]*phi[4] + multipole[9]*scale[0]*scale[2]*phi[8] -// - multipole[7]*scale[1]*scale[1]*phi[5] - multipole[8]*scale[1]*scale[2]*phi[9]); - const RealOpenMM* phi = &cphi[10*i]; torques[i][0] += _electric*(multipole[3]*phi[2] - multipole[2]*phi[3] + 2.0*(multipole[6]-multipole[5])*phi[9] @@ -5782,15 +5760,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol multipole[7] = _transformed[i].quadrupole[QXY]; multipole[8] = _transformed[i].quadrupole[QXZ]; multipole[9] = _transformed[i].quadrupole[QYZ]; -// multipole[1] *= scale[0]; -// multipole[2] *= scale[1]; -// multipole[3] *= scale[2]; -// multipole[4] *= scale[0]*scale[0]; -// multipole[5] *= scale[1]*scale[1]; -// multipole[6] *= scale[2]*scale[2]; -// multipole[7] *= scale[0]*scale[1]; -// multipole[8] *= scale[0]*scale[2]; -// multipole[9] *= scale[1]*scale[2]; RealVec f = RealVec(0.0, 0.0, 0.0); for (int k = 0; k < 10; k++) { @@ -5799,9 +5768,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipol f[1] += multipole[k]*_phi[20*i+deriv2[k]]; f[2] += multipole[k]*_phi[20*i+deriv3[k]]; } -// f[0] *= scale[0]; -// f[1] *= scale[1]; -// f[2] *= scale[2]; f *= (_electric); forces[i] -= RealVec(f[0]*fracToCart[0][0] + f[1]*fracToCart[0][1] + f[2]*fracToCart[0][2], f[0]*fracToCart[1][0] + f[1]*fracToCart[1][1] + f[2]*fracToCart[1][2], @@ -5832,8 +5798,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) cartToFrac[j][i] = fracToCart[i][j] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; -// RealVec scale; -// getPmeScale(scale); RealOpenMM energy = 0.0; for (int i = 0; i < _numParticles; i++) { @@ -5881,16 +5845,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole multipole[7] = _transformed[i].quadrupole[QXY]; multipole[8] = _transformed[i].quadrupole[QXZ]; multipole[9] = _transformed[i].quadrupole[QYZ]; -// multipole[1] *= scale[0]; -// multipole[2] *= scale[1]; -// multipole[3] *= scale[2]; -// -// multipole[4] *= scale[0]*scale[0]; -// multipole[5] *= scale[1]*scale[1]; -// multipole[6] *= scale[2]*scale[2]; -// multipole[7] *= scale[0]*scale[1]; -// multipole[8] *= scale[0]*scale[2]; -// multipole[9] *= scale[1]*scale[2]; inducedDipole[0] = _inducedDipole[i][0]*cartToFrac[0][0] + _inducedDipole[i][1]*cartToFrac[0][1] + _inducedDipole[i][2]*cartToFrac[0][2]; inducedDipole[1] = _inducedDipole[i][0]*cartToFrac[1][0] + _inducedDipole[i][1]*cartToFrac[1][1] + _inducedDipole[i][2]*cartToFrac[1][2]; @@ -5930,9 +5884,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole f[2] += multipole[k]*_phidp[20*i+deriv3[k]]; } -// f[0] *= scale[0]; -// f[1] *= scale[1]; -// f[2] *= scale[2]; f *= (0.5*_electric); forces[iIndex] -= RealVec(f[0]*fracToCart[0][0] + f[1]*fracToCart[0][1] + f[2]*fracToCart[0][2], f[0]*fracToCart[1][0] + f[1]*fracToCart[1][1] + f[2]*fracToCart[1][2], @@ -5943,9 +5894,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceInducedDipole void AmoebaReferencePmeMultipoleForce::recordFixedMultipoleField() { -// RealVec scale; -// getPmeScale(scale); -// scale *= -1.0; RealVec fracToCart[3]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) @@ -5968,9 +5916,6 @@ void AmoebaReferencePmeMultipoleForce::initializeInducedDipoles(vector& field, vector& fieldPolar) { -// RealVec scale; -// getPmeScale(scale); -// scale *= -1.0; RealVec fracToCart[3]; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) @@ -6152,7 +6097,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector RealOpenMM term = 2.0*_alphaEwald*_alphaEwald; RealOpenMM energy = (cii + term*(dii/3.0 + 2.0*term*qii/5.0)); energy *= -(_electric*_alphaEwald/(_dielectric*SQRT_PI)); - return energy; } @@ -6898,7 +6842,7 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculateElectrostatic(const vector } } - calculatePmeSelfTorque(particleData, torques); + calculatePmeSelfTorque(particleData, torques); energy += computeReciprocalSpaceInducedDipoleForceAndEnergy(getPolarizationType(), particleData, forces, torques); energy += computeReciprocalSpaceFixedMultipoleForceAndEnergy(particleData, forces, torques); energy += calculatePmeSelfEnergy(particleData); diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h index 3cf43b58e..2d065e995 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h @@ -1,4 +1,4 @@ -/* Portions copyright (c) 2006-2014 Stanford University and Simbios. +/* Portions copyright (c) 2006-2015 Stanford University and Simbios. * Contributors: Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -973,7 +973,7 @@ protected: * @param particleK positions and parameters (charge, labFrame dipoles, quadrupoles, ...) for particle K * @param scalingFactors scaling factors for interaction * @param forces vector of particle forces to be updated - * @param torques vector of particle torques to be updated + * @param torque vector of particle torques to be updated */ RealOpenMM calculateElectrostaticPairIxn(const MultipoleParticleData& particleI, const MultipoleParticleData& particleK, const std::vector& scalingFactors, std::vector& forces, std::vector& torque) const; @@ -987,6 +987,7 @@ protected: * @param particleW particle3 of lab frame for particleI * @param axisType axis type (Bisector/Z-then-X, ...) * @param torque torque on particle I + * @param forces vector of particle forces to be updated */ void mapTorqueToForceForParticle(const MultipoleParticleData& particleI, const MultipoleParticleData& particleU, @@ -1004,8 +1005,6 @@ protected: * @param axisType vector of axis types (Bisector/Z-then-X, ...) for particles * @param torques output torques * @param forces output forces - * - * @return energy */ void mapTorqueToForce(std::vector& particleData, const std::vector& multipoleAtomXs, @@ -1388,7 +1387,7 @@ private: /** * Modify input vector of differences in particle positions for periodic boundary conditions. * - * @param delta input vector of difference in particle positios; on output adjusted for + * @param delta input vector of difference in particle positions; on output adjusted for * periodic boundary conditions */ void getPeriodicDelta(RealVec& deltaR) const; @@ -1466,12 +1465,9 @@ private: * Compute induced dipole grid value. * * @param particleGridIndices particle grid indices - * @param scale integer grid dimension/box size for each dimension * @param ix x-dimension offset value * @param iy y-dimension offset value * @param gridPoint grid point for which value is to be computed - * @param inputInducedDipole induced dipole value - * @param inputInducedDipolePolar induced dipole value */ RealOpenMM computeFixedMultipolesGridValue(const int2& particleGridIndices, int ix, int iy, const IntVec& gridPoint) const; @@ -1542,7 +1538,7 @@ private: * @param jIndex particle J index * @param preFactor1 first factor used in calculating field * @param preFactor2 second factor used in calculating field - * @param deltaR delta in particle positions after adjusting for periodic boundary conditions + * @param delta delta in particle positions after adjusting for periodic boundary conditions * @param inducedDipole vector of induced dipoles * @param field vector of field at each particle due induced dipole of other particles */ @@ -1574,14 +1570,14 @@ private: * Compute induced dipole grid value. * * @param atomIndices indices of first and last atom contiputing to grid point value - * @param scale integer grid dimension/box size for each dimension + * @param cartToFrac transformation matrix from Cartesian to fractional coordinates * @param ix x-dimension offset value * @param iy y-dimension offset value * @param gridPoint grid point for which value is to be computed * @param inputInducedDipole induced dipole value * @param inputInducedDipolePolar induced dipole polar value */ - t_complex computeInducedDipoleGridValue(const int2& atomIndices, const RealVec* fracToCart, int ix, int iy, const IntVec& gridPoint, + t_complex computeInducedDipoleGridValue(const int2& atomIndices, const RealVec* cartToFrac, int ix, int iy, const IntVec& gridPoint, const std::vector& inputInducedDipole, const std::vector& inputInducedDipolePolar) const; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp index ea5d00cd5..8d4103daa 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2012 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -39,6 +39,7 @@ #include "openmm/System.h" #include "openmm/AmoebaMultipoleForce.h" #include "openmm/LangevinIntegrator.h" +#include "openmm/Vec3.h" #include #include #include @@ -50,6 +51,7 @@ using namespace OpenMM; +using namespace std; extern "C" OPENMM_EXPORT void registerAmoebaReferenceKernelFactories(); @@ -2802,6 +2804,133 @@ static void testMultipoleGridPotential( FILE* log ) { } +void testTriclinic() { + // Create a triclinic box containing eight particles. + + System system; + system.setDefaultPeriodicBoxVectors(Vec3(1.8643, 0, 0), Vec3(-0.16248445120445926, 1.8572057756524414, 0), Vec3(0.16248445120445906, -0.14832299817478897, 1.8512735025730875)); + for (int i = 0; i < 24; i++) + system.addParticle(1.0); + AmoebaMultipoleForce* force = new AmoebaMultipoleForce(); + system.addForce(force); + force->setNonbondedMethod(AmoebaMultipoleForce::PME); + force->setCutoffDistance(0.7); + force->setMutualInducedTargetEpsilon(1e-6); + vector grid(3); + grid[0] = grid[1] = grid[2] = 24; + force->setPmeGridDimensions(grid); + force->setAEwald(5.4459051633620055); + double o_charge = -0.42616, h_charge = 0.21308; + vector o_dipole(3), h_dipole(3), o_quadrupole(9, 0.0), h_quadrupole(9, 0.0); + o_dipole[0] = 0; + o_dipole[1] = 0; + o_dipole[2] = 0.0033078867454609203; + h_dipole[0] = -0.0053536858428776405; + h_dipole[1] = 0; + h_dipole[2] = -0.014378273997907321; + + o_quadrupole[0] = 0.00016405937591036892; + o_quadrupole[4] = -0.00021618201787005826; + o_quadrupole[8] = 5.212264195968935e-05; + h_quadrupole[0] = 0.00011465301060008312; + h_quadrupole[4] = 8.354184196619263e-05; + h_quadrupole[8] = -0.00019819485256627578; + h_quadrupole[2] = h_quadrupole[6] = -6.523731100577879e-05; + + for (int i = 0; i < 8; i++) { + int atom1 = 3*i, atom2 = 3*i+1, atom3 = 3*i+2; + force->addMultipole(o_charge, o_dipole, o_quadrupole, 1, atom2, atom3, -1, 0.39, pow(0.001*0.92, 1.0/6.0), 0.001*0.92); + force->addMultipole(h_charge, h_dipole, h_quadrupole, 0, atom1, atom3, -1, 0.39, pow(0.001*0.539, 1.0/6.0), 0.001*0.539); + force->addMultipole(h_charge, h_dipole, h_quadrupole, 0, atom1, atom2, -1, 0.39, pow(0.001*0.539, 1.0/6.0), 0.001*0.539); + vector coval1_12(2); + coval1_12[0] = atom2; + coval1_12[1] = atom3; + force->setCovalentMap(atom1, AmoebaMultipoleForce::Covalent12, coval1_12); + vector coval2_12(1); + coval2_12[0] = atom1; + force->setCovalentMap(atom2, AmoebaMultipoleForce::Covalent12, coval2_12); + force->setCovalentMap(atom3, AmoebaMultipoleForce::Covalent12, coval2_12); + vector coval2_13(1); + coval2_13[0] = atom3; + force->setCovalentMap(atom2, AmoebaMultipoleForce::Covalent13, coval2_13); + vector coval3_13(1); + coval3_13[0] = atom2; + force->setCovalentMap(atom3, AmoebaMultipoleForce::Covalent13, coval3_13); + vector polar(3); + polar[0] = atom1; + polar[1] = atom2; + polar[2] = atom3; + force->setCovalentMap(atom1, AmoebaMultipoleForce::PolarizationCovalent11, polar); + force->setCovalentMap(atom2, AmoebaMultipoleForce::PolarizationCovalent11, polar); + force->setCovalentMap(atom3, AmoebaMultipoleForce::PolarizationCovalent11, polar); + } + vector positions(24); + positions[0] = Vec3(0.867966, 0.708769, -0.0696862); + positions[1] = Vec3(0.780946, 0.675579, -0.0382259); + positions[2] = Vec3(0.872223, 0.681424, -0.161756); + positions[3] = Vec3(-0.0117313, 0.824445, 0.683762); + positions[4] = Vec3(0.0216892, 0.789544, 0.605003); + positions[5] = Vec3(0.0444268, 0.782601, 0.75302); + positions[6] = Vec3(0.837906, -0.0092611, 0.681463); + positions[7] = Vec3(0.934042, 0.0098069, 0.673406); + positions[8] = Vec3(0.793962, 0.0573676, 0.626984); + positions[9] = Vec3(0.658995, 0.184432, -0.692317); + positions[10] = Vec3(0.588543, 0.240231, -0.671793); + positions[11] = Vec3(0.618153, 0.106275, -0.727368); + positions[12] = Vec3(0.71466, 0.575358, 0.233152); + positions[13] = Vec3(0.636812, 0.612604, 0.286268); + positions[14] = Vec3(0.702502, 0.629465, 0.15182); + positions[15] = Vec3(-0.242658, -0.850419, -0.250483); + positions[16] = Vec3(-0.169206, -0.836825, -0.305829); + positions[17] = Vec3(-0.279321, -0.760247, -0.24031); + positions[18] = Vec3(-0.803838, -0.360559, 0.230369); + positions[19] = Vec3(-0.811375, -0.424813, 0.301849); + positions[20] = Vec3(-0.761939, -0.2863, 0.270962); + positions[21] = Vec3(-0.148063, 0.824409, -0.827221); + positions[22] = Vec3(-0.20902, 0.868798, -0.7677); + positions[23] = Vec3(-0.0700878, 0.882333, -0.832221); + + // Compute the forces and energy. + + LangevinIntegrator integrator(0.0, 0.1, 0.01); + Context context(system, integrator, Platform::getPlatformByName("Reference")); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + + // Compare them to values computed by Gromacs. + + double expectedEnergy = 6.8278696; + vector expectedForce(24); + expectedForce[0] = Vec3(-104.755, 14.0833, 34.359); + expectedForce[1] = Vec3(97.324, -1.41419, -142.976); + expectedForce[2] = Vec3(29.3968, -6.31784, -3.8702); + expectedForce[3] = Vec3(39.1915, 66.852, -28.5767); + expectedForce[4] = Vec3(-8.17554, -6.71532, 7.63162); + expectedForce[5] = Vec3(-87.3745, -91.8639, 35.4761); + expectedForce[6] = Vec3(-19.7568, -40.8693, 5.60238); + expectedForce[7] = Vec3(0.840984, 26.878, 10.7822); + expectedForce[8] = Vec3(14.3469, 12.0583, -12.075); + expectedForce[9] = Vec3(13.757, 16.9954, 46.9403); + expectedForce[10] = Vec3(-5.04172, -14.008, -15.3804); + expectedForce[11] = Vec3(-2.1715, 3.7405, -37.2209); + expectedForce[12] = Vec3(-70.2284, -9.10438, -40.1287); + expectedForce[13] = Vec3(4.46014, 3.89949, 4.64842); + expectedForce[14] = Vec3(43.045, -4.79905, 151.879); + expectedForce[15] = Vec3(20.2129, -0.895376, -27.2086); + expectedForce[16] = Vec3(-5.10448, 3.57732, 17.0498); + expectedForce[17] = Vec3(-13.7695, -1.03345, 12.3093); + expectedForce[18] = Vec3(2.94972, 0.338904, -10.9914); + expectedForce[19] = Vec3(0.69036, 1.22591, 4.50198); + expectedForce[20] = Vec3(-4.61495, -2.76981, 3.57732); + expectedForce[21] = Vec3(73.1489, 16.167, -99.5834); + expectedForce[22] = Vec3(-31.8235, 6.11282, -21.125); + expectedForce[23] = Vec3(13.167, 7.42242, 103.102); + for (int i = 0; i < 24; i++) { + ASSERT_EQUAL_VEC(expectedForce[i], state.getForces()[i], 1e-2); + } + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), 1e-2); +} + int main( int numberOfArguments, char* argv[] ) { try { @@ -2849,6 +2978,10 @@ int main( int numberOfArguments, char* argv[] ) { // large box of water testPMEMutualPolarizationLargeWater( log ); + + // triclinic box of water + + testTriclinic(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; -- GitLab From c83f2a1276e4a816f4026b869188c79bc0e980cb Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 4 Feb 2015 14:54:08 -0800 Subject: [PATCH 232/338] Began CUDA implementation of triclinic boxes for AmoebaMultipoleForce --- .../platforms/cuda/src/AmoebaCudaKernels.cpp | 76 ++++- .../platforms/cuda/src/AmoebaCudaKernels.h | 3 + .../src/kernels/multipoleElectrostatics.cu | 4 +- .../cuda/src/kernels/multipoleFixedField.cu | 16 +- .../cuda/src/kernels/multipoleInducedField.cu | 15 +- .../cuda/src/kernels/multipolePme.cu | 317 +++++++++++------- .../platforms/cuda/src/kernels/multipoles.cu | 6 +- .../src/kernels/pmeMultipoleElectrostatics.cu | 17 +- 8 files changed, 286 insertions(+), 168 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp index 9b053ca75..eebfe8552 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp @@ -796,8 +796,8 @@ private: CudaCalcAmoebaMultipoleForceKernel::CudaCalcAmoebaMultipoleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) : CalcAmoebaMultipoleForceKernel(name, platform), cu(cu), system(system), hasInitializedScaleFactors(false), hasInitializedFFT(false), multipolesAreValid(false), - multipoleParticles(NULL), molecularDipoles(NULL), molecularQuadrupoles(NULL), labFrameDipoles(NULL), labFrameQuadrupoles(NULL), - field(NULL), fieldPolar(NULL), inducedField(NULL), inducedFieldPolar(NULL), torque(NULL), dampingAndThole(NULL), inducedDipole(NULL), + multipoleParticles(NULL), molecularDipoles(NULL), molecularQuadrupoles(NULL), labFrameDipoles(NULL), labFrameQuadrupoles(NULL), fracDipoles(NULL), + fracQuadrupoles(NULL), field(NULL), fieldPolar(NULL), inducedField(NULL), inducedFieldPolar(NULL), torque(NULL), dampingAndThole(NULL), inducedDipole(NULL), diisCoefficients(NULL), inducedDipolePolar(NULL), inducedDipoleErrors(NULL), prevDipoles(NULL), prevDipolesPolar(NULL), prevDipolesGk(NULL), prevDipolesGkPolar(NULL), prevErrors(NULL), diisMatrix(NULL), polarizability(NULL), covalentFlags(NULL), polarizationGroupFlags(NULL), pmeGrid(NULL), pmeBsplineModuliX(NULL), pmeBsplineModuliY(NULL), pmeBsplineModuliZ(NULL), pmeIgrid(NULL), pmePhi(NULL), @@ -816,6 +816,10 @@ CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() { delete labFrameDipoles; if (labFrameQuadrupoles != NULL) delete labFrameQuadrupoles; + if (fracDipoles != NULL) + delete fracDipoles; + if (fracQuadrupoles != NULL) + delete fracQuadrupoles; if (field != NULL) delete field; if (fieldPolar != NULL) @@ -968,7 +972,9 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const int elementSize = (cu.getUseDoublePrecision() ? sizeof(double) : sizeof(float)); labFrameDipoles = new CudaArray(cu, 3*paddedNumAtoms, elementSize, "labFrameDipoles"); - labFrameQuadrupoles = new CudaArray(cu, 9*paddedNumAtoms, elementSize, "labFrameQuadrupoles"); + labFrameQuadrupoles = new CudaArray(cu, 5*paddedNumAtoms, elementSize, "labFrameQuadrupoles"); + fracDipoles = new CudaArray(cu, 3*paddedNumAtoms, elementSize, "fracDipoles"); + fracQuadrupoles = new CudaArray(cu, 6*paddedNumAtoms, elementSize, "fracQuadrupoles"); field = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "field"); fieldPolar = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "fieldPolar"); torque = new CudaArray(cu, 3*paddedNumAtoms, sizeof(long long), "torque"); @@ -1185,6 +1191,7 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const pmeDefines["DIRECT_POLARIZATION"] = ""; CUmodule module = cu.createModule(CudaKernelSources::vectorOps+CudaAmoebaKernelSources::multipolePme, pmeDefines); pmeGridIndexKernel = cu.getKernel(module, "findAtomGridIndex"); + pmeTransformMultipolesKernel = cu.getKernel(module, "transformMultipolesToFractionalCoordinates"); pmeSpreadFixedMultipolesKernel = cu.getKernel(module, "gridSpreadFixedMultipoles"); pmeSpreadInducedDipolesKernel = cu.getKernel(module, "gridSpreadInducedDipoles"); pmeFinishSpreadChargeKernel = cu.getKernel(module, "finishSpreadCharge"); @@ -1483,15 +1490,44 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in gkKernel->finishComputation(*torque, *labFrameDipoles, *labFrameQuadrupoles, *inducedDipole, *inducedDipolePolar, *dampingAndThole, *covalentFlags, *polarizationGroupFlags); } else { + // Compute reciprocal box vectors. + + Vec3 boxVectors[3]; + cu.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); + double determinant = boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]; + double scale = 1.0/determinant; + double3 recipBoxVectors[3]; + recipBoxVectors[0] = make_double3(boxVectors[1][1]*boxVectors[2][2]*scale, 0, 0); + recipBoxVectors[1] = make_double3(-boxVectors[1][0]*boxVectors[2][2]*scale, boxVectors[0][0]*boxVectors[2][2]*scale, 0); + recipBoxVectors[2] = make_double3((boxVectors[1][0]*boxVectors[2][1]-boxVectors[1][1]*boxVectors[2][0])*scale, -boxVectors[0][0]*boxVectors[2][1]*scale, boxVectors[0][0]*boxVectors[1][1]*scale); + float3 recipBoxVectorsFloat[3]; + void* recipBoxVectorPointer[3]; + if (cu.getUseDoublePrecision()) { + recipBoxVectorPointer[0] = &recipBoxVectors[0]; + recipBoxVectorPointer[1] = &recipBoxVectors[1]; + recipBoxVectorPointer[2] = &recipBoxVectors[2]; + } + else { + recipBoxVectorsFloat[0] = make_float3((float) recipBoxVectors[0].x, 0, 0); + recipBoxVectorsFloat[1] = make_float3((float) recipBoxVectors[1].x, (float) recipBoxVectors[1].y, 0); + recipBoxVectorsFloat[2] = make_float3((float) recipBoxVectors[2].x, (float) recipBoxVectors[2].y, (float) recipBoxVectors[2].z); + recipBoxVectorPointer[0] = &recipBoxVectorsFloat[0]; + recipBoxVectorPointer[1] = &recipBoxVectorsFloat[1]; + recipBoxVectorPointer[2] = &recipBoxVectorsFloat[2]; + } + // Reciprocal space calculation. unsigned int maxTiles = nb.getInteractingTiles().getSize(); void* gridIndexArgs[] = {&cu.getPosq().getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), - cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeGridIndexKernel, gridIndexArgs, cu.getNumAtoms(), cu.ThreadBlockSize, cu.ThreadBlockSize*PmeOrder*PmeOrder*elementSize); sort->sort(*pmeAtomGridIndex); - void* pmeSpreadFixedMultipolesArgs[] = {&cu.getPosq().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), - &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + void* pmeTransformMultipolesArgs[] = {&labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), + &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; + cu.executeKernel(pmeTransformMultipolesKernel, pmeTransformMultipolesArgs, cu.getNumAtoms()); + void* pmeSpreadFixedMultipolesArgs[] = {&cu.getPosq().getDevicePointer(), &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), + &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeSpreadFixedMultipolesKernel, pmeSpreadFixedMultipolesArgs, cu.getNumAtoms()); void* finishSpreadArgs[] = {&pmeGrid->getDevicePointer()}; if (cu.getUseDoublePrecision()) @@ -1501,7 +1537,7 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in else cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_FORWARD); void* pmeConvolutionArgs[] = {&pmeGrid->getDevicePointer(), &pmeBsplineModuliX->getDevicePointer(), &pmeBsplineModuliY->getDevicePointer(), - &pmeBsplineModuliZ->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + &pmeBsplineModuliZ->getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeConvolutionKernel, pmeConvolutionArgs, cu.getNumAtoms()); if (cu.getUseDoublePrecision()) cufftExecZ2Z(fft, (double2*) pmeGrid->getDevicePointer(), (double2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE); @@ -1509,11 +1545,12 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE); void* pmeFixedPotentialArgs[] = {&pmeGrid->getDevicePointer(), &pmePhi->getDevicePointer(), &field->getDevicePointer(), &fieldPolar ->getDevicePointer(), &cu.getPosq().getDevicePointer(), &labFrameDipoles->getDevicePointer(), - cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), &pmeAtomGridIndex->getDevicePointer()}; + cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeFixedPotentialKernel, pmeFixedPotentialArgs, cu.getNumAtoms()); void* pmeFixedForceArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &torque->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), - &pmePhi->getDevicePointer(), cu.getInvPeriodicBoxSizePointer()}; + &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), &pmePhi->getDevicePointer(), + recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeFixedForceKernel, pmeFixedForceArgs, cu.getNumAtoms()); // Direct space calculation. @@ -1521,7 +1558,8 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in void* computeFixedFieldArgs[] = {&field->getDevicePointer(), &fieldPolar->getDevicePointer(), &cu.getPosq().getDevicePointer(), &covalentFlags->getDevicePointer(), &polarizationGroupFlags->getDevicePointer(), &nb.getExclusionTiles().getDevicePointer(), &startTileIndex, &numTileIndices, &nb.getInteractingTiles().getDevicePointer(), &nb.getInteractionCount().getDevicePointer(), cu.getPeriodicBoxSizePointer(), - cu.getInvPeriodicBoxSizePointer(), &maxTiles, &nb.getBlockCenters().getDevicePointer(), &nb.getInteractingAtoms().getDevicePointer(), + cu.getInvPeriodicBoxSizePointer(), cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), + &maxTiles, &nb.getBlockCenters().getDevicePointer(), &nb.getInteractingAtoms().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &dampingAndThole->getDevicePointer()}; cu.executeKernel(computeFixedFieldKernel, computeFixedFieldArgs, numForceThreadBlocks*fixedFieldThreads, fixedFieldThreads); void* recordInducedDipolesArgs[] = {&field->getDevicePointer(), &fieldPolar->getDevicePointer(), @@ -1532,7 +1570,7 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in cu.clearBuffer(*pmeGrid); void* pmeSpreadInducedDipolesArgs[] = {&cu.getPosq().getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), - &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeSpreadInducedDipolesKernel, pmeSpreadInducedDipolesArgs, cu.getNumAtoms()); if (cu.getUseDoublePrecision()) cu.executeKernel(pmeFinishSpreadChargeKernel, finishSpreadArgs, pmeGrid->getSize()); @@ -1546,7 +1584,7 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in else cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE); void* pmeInducedPotentialArgs[] = {&pmeGrid->getDevicePointer(), &pmePhid->getDevicePointer(), &pmePhip->getDevicePointer(), - &pmePhidp->getDevicePointer(), &cu.getPosq().getDevicePointer(), cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), + &pmePhidp->getDevicePointer(), &cu.getPosq().getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeInducedPotentialKernel, pmeInducedPotentialArgs, cu.getNumAtoms()); @@ -1559,7 +1597,8 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in void* computeInducedFieldArgs[] = {&inducedField->getDevicePointer(), &inducedFieldPolar->getDevicePointer(), &cu.getPosq().getDevicePointer(), &nb.getExclusionTiles().getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), &startTileIndex, &numTileIndices, &nb.getInteractingTiles().getDevicePointer(), &nb.getInteractionCount().getDevicePointer(), cu.getPeriodicBoxSizePointer(), - cu.getInvPeriodicBoxSizePointer(), &maxTiles, &nb.getBlockCenters().getDevicePointer(), &nb.getInteractingAtoms().getDevicePointer(), + cu.getInvPeriodicBoxSizePointer(), cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), + &maxTiles, &nb.getBlockCenters().getDevicePointer(), &nb.getInteractingAtoms().getDevicePointer(), &dampingAndThole->getDevicePointer()}; cu.executeKernel(computeInducedFieldKernel, computeInducedFieldArgs, numForceThreadBlocks*inducedFieldThreads, inducedFieldThreads); cu.clearBuffer(*pmeGrid); @@ -1577,7 +1616,7 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE); cu.executeKernel(pmeInducedPotentialKernel, pmeInducedPotentialArgs, cu.getNumAtoms()); void* pmeRecordInducedFieldDipolesArgs[] = {&pmePhid->getDevicePointer(), &pmePhip->getDevicePointer(), - &inducedField->getDevicePointer(), &inducedFieldPolar->getDevicePointer(), cu.getInvPeriodicBoxSizePointer()}; + &inducedField->getDevicePointer(), &inducedFieldPolar->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeRecordInducedFieldDipolesKernel, pmeRecordInducedFieldDipolesArgs, cu.getNumAtoms()); bool converged = iterateDipolesByDIIS(i); if (converged) @@ -1590,14 +1629,16 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in &cu.getPosq().getDevicePointer(), &covalentFlags->getDevicePointer(), &polarizationGroupFlags->getDevicePointer(), &nb.getExclusionTiles().getDevicePointer(), &startTileIndex, &numTileIndices, &nb.getInteractingTiles().getDevicePointer(), &nb.getInteractionCount().getDevicePointer(), - cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), &maxTiles, &nb.getBlockCenters().getDevicePointer(), &nb.getInteractingAtoms().getDevicePointer(), + cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), + &maxTiles, &nb.getBlockCenters().getDevicePointer(), &nb.getInteractingAtoms().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), &dampingAndThole->getDevicePointer()}; cu.executeKernel(electrostaticsKernel, electrostaticsArgs, numForceThreadBlocks*electrostaticsThreads, electrostaticsThreads); void* pmeInducedForceArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &torque->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), + &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), &pmePhi->getDevicePointer(), &pmePhid->getDevicePointer(), - &pmePhip->getDevicePointer(), &pmePhidp->getDevicePointer(), cu.getInvPeriodicBoxSizePointer()}; + &pmePhip->getDevicePointer(), &pmePhidp->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeInducedForceKernel, pmeInducedForceArgs, cu.getNumAtoms()); } @@ -1785,7 +1826,8 @@ void CudaCalcAmoebaMultipoleForceKernel::getElectrostaticPotential(ContextImpl& void* computePotentialArgs[] = {&cu.getPosq().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &inducedDipole->getDevicePointer(), &points.getDevicePointer(), - &potential.getDevicePointer(), &numPoints, cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer()}; + &potential.getDevicePointer(), &numPoints, cu.getPeriodicBoxSizePointer(), cu.getInvPeriodicBoxSizePointer(), + cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer()}; int blockSize = 128; cu.executeKernel(computePotentialKernel, computePotentialArgs, numPoints, blockSize, blockSize*15*elementSize); outputElectrostaticPotential.resize(numPoints); diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h index fa3230fba..aff868336 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h @@ -391,6 +391,8 @@ private: CudaArray* molecularQuadrupoles; CudaArray* labFrameDipoles; CudaArray* labFrameQuadrupoles; + CudaArray* fracDipoles; + CudaArray* fracQuadrupoles; CudaArray* field; CudaArray* fieldPolar; CudaArray* inducedField; @@ -428,6 +430,7 @@ private: CUfunction pmeGridIndexKernel, pmeSpreadFixedMultipolesKernel, pmeSpreadInducedDipolesKernel, pmeFinishSpreadChargeKernel, pmeConvolutionKernel; CUfunction pmeFixedPotentialKernel, pmeInducedPotentialKernel, pmeFixedForceKernel, pmeInducedForceKernel, pmeRecordInducedFieldDipolesKernel, computePotentialKernel; CUfunction recordDIISDipolesKernel, buildMatrixKernel; + CUfunction pmeTransformMultipolesKernel; CudaCalcAmoebaGeneralizedKirkwoodForceKernel* gkKernel; static const int PmeOrder = 5; static const int MaxPrevDIISDipoles = 20; diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipoleElectrostatics.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipoleElectrostatics.cu index 990e6b093..7b1ee0f78 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipoleElectrostatics.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipoleElectrostatics.cu @@ -65,7 +65,9 @@ extern "C" __global__ void computeElectrostatics( const real4* __restrict__ posq, const uint2* __restrict__ covalentFlags, const unsigned int* __restrict__ polarizationGroupFlags, const ushort2* __restrict__ exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, unsigned int maxTiles, const real4* __restrict__ blockCenter, const unsigned int* __restrict__ interactingAtoms, + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const unsigned int* __restrict__ interactingAtoms, #endif const real* __restrict__ labFrameDipole, const real* __restrict__ labFrameQuadrupole, const real* __restrict__ inducedDipole, const real* __restrict__ inducedDipolePolar, const float2* __restrict__ dampingAndThole) { diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipoleFixedField.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipoleFixedField.cu index 8eb4ce93d..49f980fdf 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipoleFixedField.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipoleFixedField.cu @@ -440,7 +440,9 @@ extern "C" __global__ void computeFixedField( const uint2* __restrict__ covalentFlags, const unsigned int* __restrict__ polarizationGroupFlags, const ushort2* __restrict__ exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, unsigned int maxTiles, const real4* __restrict__ blockCenter, const unsigned int* __restrict__ interactingAtoms, + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const unsigned int* __restrict__ interactingAtoms, #elif defined USE_GK const real* __restrict__ bornRadii, unsigned long long* __restrict__ gkFieldBuffers, #endif @@ -494,9 +496,7 @@ extern "C" __global__ void computeFixedField( for (unsigned int j = 0; j < TILE_SIZE; j++) { real3 delta = trimTo3(localData[tbx+j].posq-data.posq); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif int atom2 = y*TILE_SIZE+j; if (atom1 != atom2 && atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) { @@ -532,9 +532,7 @@ extern "C" __global__ void computeFixedField( for (j = 0; j < TILE_SIZE; j++) { real3 delta = trimTo3(localData[tbx+tj].posq-data.posq); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif int atom2 = y*TILE_SIZE+tj; if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) { @@ -675,9 +673,7 @@ extern "C" __global__ void computeFixedField( for (j = 0; j < TILE_SIZE; j++) { real3 delta = trimTo3(localData[tbx+tj].posq-data.posq); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif int atom2 = atomIndices[tbx+tj]; if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) { diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu index a1242f42e..58a0127e8 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipoleInducedField.cu @@ -207,7 +207,8 @@ extern "C" __global__ void computeInducedField( unsigned long long* __restrict__ field, unsigned long long* __restrict__ fieldPolar, const real4* __restrict__ posq, const ushort2* __restrict__ exclusionTiles, const real* __restrict__ inducedDipole, const real* __restrict__ inducedDipolePolar, unsigned int startTileIndex, unsigned int numTileIndices, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, unsigned int maxTiles, const real4* __restrict__ blockCenter, const unsigned int* __restrict__ interactingAtoms, + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, const unsigned int* __restrict__ interactingAtoms, #elif defined USE_GK unsigned long long* __restrict__ fieldS, unsigned long long* __restrict__ fieldPolarS, const real* __restrict__ inducedDipoleS, const real* __restrict__ inducedDipolePolarS, const real* __restrict__ bornRadii, @@ -251,9 +252,7 @@ extern "C" __global__ void computeInducedField( for (unsigned int j = 0; j < TILE_SIZE; j++) { real3 delta = localData[tbx+j].pos-data.pos; #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif int atom2 = y*TILE_SIZE+j; if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) @@ -273,9 +272,7 @@ extern "C" __global__ void computeInducedField( for (unsigned int j = 0; j < TILE_SIZE; j++) { real3 delta = localData[tbx+tj].pos-data.pos; #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif int atom2 = y*TILE_SIZE+j; if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) @@ -404,9 +401,7 @@ extern "C" __global__ void computeInducedField( for (j = 0; j < TILE_SIZE; j++) { real3 delta = localData[tbx+tj].pos-data.pos; #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif int atom2 = atomIndices[tbx+tj]; if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu index 7d7a10edf..d125728c8 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu @@ -73,30 +73,30 @@ __device__ void computeBSplinePoint(real4* thetai, real w, real* array) { * Compute the index of the grid point each atom is associated with. */ extern "C" __global__ void findAtomGridIndex(const real4* __restrict__ posq, int2* __restrict__ pmeAtomGridIndex, - real4 periodicBoxSize, real4 invPeriodicBoxSize) { + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { real4 pos = posq[i]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; // First axis. - real w = pos.x*invPeriodicBoxSize.x; + real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); int ifr = (int) fr; int igrid1 = ifr-PME_ORDER+1; // Second axis. - w = pos.y*invPeriodicBoxSize.y; + w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; int igrid2 = ifr-PME_ORDER+1; // Third axis. - w = pos.z*invPeriodicBoxSize.z; + w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; int igrid3 = ifr-PME_ORDER+1; @@ -109,13 +109,61 @@ extern "C" __global__ void findAtomGridIndex(const real4* __restrict__ posq, int pmeAtomGridIndex[i] = make_int2(i, igrid1*GRID_SIZE_Y*GRID_SIZE_Z+igrid2*GRID_SIZE_Z+igrid3); } } +/** + * Convert the fixed multipoles from Cartesian to fractional coordinates. + */ +extern "C" __global__ void transformMultipolesToFractionalCoordinates(const real* __restrict__ labFrameDipole, const real* __restrict__ labFrameQuadrupole, + real* __restrict__ fracDipole, real* __restrict__ fracQuadrupole, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + // Build matrices for transforming the dipoles and quadrupoles. + + __shared__ real a[3][3]; + if (threadIdx.x == 0) { + a[0][0] = GRID_SIZE_X*recipBoxVecX.x; + a[0][1] = GRID_SIZE_X*recipBoxVecY.x; + a[0][2] = GRID_SIZE_X*recipBoxVecZ.x; + a[1][0] = GRID_SIZE_Y*recipBoxVecX.y; + a[1][1] = GRID_SIZE_Y*recipBoxVecY.y; + a[1][2] = GRID_SIZE_Y*recipBoxVecZ.y; + a[2][0] = GRID_SIZE_Z*recipBoxVecX.z; + a[2][1] = GRID_SIZE_Z*recipBoxVecY.z; + a[2][2] = GRID_SIZE_Z*recipBoxVecZ.z; + } + __syncthreads(); + int index1[] = {0, 0, 0, 1, 1, 2}; + int index2[] = {0, 1, 2, 1, 2, 2}; + __shared__ real b[6][6]; + if (threadIdx.x < 36) { + int i = threadIdx.x/6; + int j = threadIdx.x-6*i; + b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; + if (index1[i] != index2[i]) + b[i][j] += a[index1[i]][index2[j]]*a[index2[i]][index1[j]]; + } + __syncthreads(); + + // Transform the multipoles. + + real quadScale[] = {1, 2, 2, 1, 2, 1}; + for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { + for (int j = 0; j < 3; j++) { + real dipole = 0; + for (int k = 0; k < 3; k++) + dipole += a[j][k]*labFrameDipole[3*i+k]; + fracDipole[3*i+j] = dipole; + } + for (int j = 0; j < 6; j++) { + real quadrupole = 0; + for (int k = 0; k < 5; k++) + quadrupole += quadScale[k]*b[j][k]*labFrameQuadrupole[5*i+k]; + quadrupole -= quadScale[5]*b[j][5]*(labFrameQuadrupole[5*i]+labFrameQuadrupole[5*i+3]); + fracQuadrupole[6*i+j] = quadrupole; + } + } +} -extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ posq, const real* __restrict__ labFrameDipole, - const real* __restrict__ labFrameQuadrupole, real2* __restrict__ pmeGrid, int2* __restrict__ pmeAtomGridIndex, - real4 periodicBoxSize, real4 invPeriodicBoxSize) { - const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x; - const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y; - const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z; +extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ posq, const real* __restrict__ fracDipole, + const real* __restrict__ fracQuadrupole, real2* __restrict__ pmeGrid, int2* __restrict__ pmeAtomGridIndex, + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; @@ -127,26 +175,26 @@ extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ p for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. - real w = pos.x*invPeriodicBoxSize.x; + real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); int ifr = (int) fr; w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); - w = pos.y*invPeriodicBoxSize.y; + w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); - w = pos.z*invPeriodicBoxSize.z; + w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; @@ -177,15 +225,15 @@ extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ p real4 v = theta3[iz]; real atomCharge = pos.w; - real atomDipoleX = xscale*labFrameDipole[m*3]; - real atomDipoleY = yscale*labFrameDipole[m*3+1]; - real atomDipoleZ = zscale*labFrameDipole[m*3+2]; - real atomQuadrupoleXX = xscale*xscale*labFrameQuadrupole[m*5]; - real atomQuadrupoleXY = 2*xscale*yscale*labFrameQuadrupole[m*5+1]; - real atomQuadrupoleXZ = 2*xscale*zscale*labFrameQuadrupole[m*5+2]; - real atomQuadrupoleYY = yscale*yscale*labFrameQuadrupole[m*5+3]; - real atomQuadrupoleYZ = 2*yscale*zscale*labFrameQuadrupole[m*5+4]; - real atomQuadrupoleZZ = -zscale*zscale*(labFrameQuadrupole[m*5]+labFrameQuadrupole[m*5+3]); + real atomDipoleX = fracDipole[m*3]; + real atomDipoleY = fracDipole[m*3+1]; + real atomDipoleZ = fracDipole[m*3+2]; + real atomQuadrupoleXX = fracQuadrupole[m*6]; + real atomQuadrupoleXY = fracQuadrupole[m*6+1]; + real atomQuadrupoleXZ = fracQuadrupole[m*6+2]; + real atomQuadrupoleYY = fracQuadrupole[m*6+3]; + real atomQuadrupoleYZ = fracQuadrupole[m*6+4]; + real atomQuadrupoleZZ = fracQuadrupole[m*6+5]; real term0 = atomCharge*u.x*v.x + atomDipoleY*u.y*v.x + atomDipoleZ*u.x*v.y + atomQuadrupoleYY*u.z*v.x + atomQuadrupoleZZ*u.x*v.z + atomQuadrupoleYZ*u.y*v.y; real term1 = atomDipoleX*u.x*v.x + atomQuadrupoleXY*u.y*v.x + atomQuadrupoleXZ*u.x*v.y; real term2 = atomQuadrupoleXX * u.x * v.x; @@ -204,10 +252,10 @@ extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ p extern "C" __global__ void gridSpreadInducedDipoles(const real4* __restrict__ posq, const real* __restrict__ inducedDipole, const real* __restrict__ inducedDipolePolar, real2* __restrict__ pmeGrid, int2* __restrict__ pmeAtomGridIndex, - real4 periodicBoxSize, real4 invPeriodicBoxSize) { - const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x; - const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y; - const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z; + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + const real xscale = GRID_SIZE_X*recipBoxVecX.x; + const real yscale = GRID_SIZE_Y*recipBoxVecY.y; + const real zscale = GRID_SIZE_Z*recipBoxVecZ.z; real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; @@ -219,26 +267,26 @@ extern "C" __global__ void gridSpreadInducedDipoles(const real4* __restrict__ po for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. - real w = pos.x*invPeriodicBoxSize.x; + real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); int ifr = (int) fr; w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); - w = pos.y*invPeriodicBoxSize.y; + w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); - w = pos.z*invPeriodicBoxSize.z; + w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; @@ -306,7 +354,8 @@ extern "C" __global__ void finishSpreadCharge(long long* __restrict__ pmeGrid) { } extern "C" __global__ void reciprocalConvolution(real2* __restrict__ pmeGrid, const real* __restrict__ pmeBsplineModuliX, - const real* __restrict__ pmeBsplineModuliY, const real* __restrict__ pmeBsplineModuliZ, real4 periodicBoxSize, real4 invPeriodicBoxSize) { + const real* __restrict__ pmeBsplineModuliY, const real* __restrict__ pmeBsplineModuliZ, real4 periodicBoxSize, + real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; real expFactor = M_PI*M_PI/(EWALD_ALPHA*EWALD_ALPHA); real scaleFactor = RECIP(M_PI*periodicBoxSize.x*periodicBoxSize.y*periodicBoxSize.z); @@ -322,9 +371,9 @@ extern "C" __global__ void reciprocalConvolution(real2* __restrict__ pmeGrid, co int mx = (kx < (GRID_SIZE_X+1)/2) ? kx : (kx-GRID_SIZE_X); int my = (ky < (GRID_SIZE_Y+1)/2) ? ky : (ky-GRID_SIZE_Y); int mz = (kz < (GRID_SIZE_Z+1)/2) ? kz : (kz-GRID_SIZE_Z); - real mhx = mx*invPeriodicBoxSize.x; - real mhy = my*invPeriodicBoxSize.y; - real mhz = mz*invPeriodicBoxSize.z; + real mhx = mx*recipBoxVecX.x; + real mhy = mx*recipBoxVecY.x+my*recipBoxVecY.y; + real mhz = mx*recipBoxVecZ.x+my*recipBoxVecZ.y+mz*recipBoxVecZ.z; real bx = pmeBsplineModuliX[kx]; real by = pmeBsplineModuliY[ky]; real bz = pmeBsplineModuliZ[kz]; @@ -338,7 +387,7 @@ extern "C" __global__ void reciprocalConvolution(real2* __restrict__ pmeGrid, co extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict__ pmeGrid, real* __restrict__ phi, long long* __restrict__ fieldBuffers, long long* __restrict__ fieldPolarBuffers, const real4* __restrict__ posq, - const real* __restrict__ labFrameDipole, real4 periodicBoxSize, real4 invPeriodicBoxSize, int2* __restrict__ pmeAtomGridIndex) { + const real* __restrict__ labFrameDipole, real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ, int2* __restrict__ pmeAtomGridIndex) { real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; @@ -350,26 +399,26 @@ extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. - real w = pos.x*invPeriodicBoxSize.x; + real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); int ifr = (int) fr; w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); - w = pos.y*invPeriodicBoxSize.y; + w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); - w = pos.z*invPeriodicBoxSize.z; + w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; @@ -481,13 +530,13 @@ extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict phi[20*m+18] = tuv012; phi[20*m+19] = tuv111; real dipoleScale = (4/(real) 3)*(EWALD_ALPHA*EWALD_ALPHA*EWALD_ALPHA)/SQRT_PI; - long long fieldx = (long long) ((dipoleScale*labFrameDipole[m*3]-GRID_SIZE_X*invPeriodicBoxSize.x*tuv100)*0x100000000); + long long fieldx = (long long) ((dipoleScale*labFrameDipole[m*3]-GRID_SIZE_X*recipBoxVecX.x*tuv100)*0x100000000); fieldBuffers[m] = fieldx; fieldPolarBuffers[m] = fieldx; - long long fieldy = (long long) ((dipoleScale*labFrameDipole[m*3+1]-GRID_SIZE_Y*invPeriodicBoxSize.y*tuv010)*0x100000000); + long long fieldy = (long long) ((dipoleScale*labFrameDipole[m*3+1]-GRID_SIZE_Y*recipBoxVecY.y*tuv010)*0x100000000); fieldBuffers[m+PADDED_NUM_ATOMS] = fieldy; fieldPolarBuffers[m+PADDED_NUM_ATOMS] = fieldy; - long long fieldz = (long long) ((dipoleScale*labFrameDipole[m*3+2]-GRID_SIZE_Z*invPeriodicBoxSize.z*tuv001)*0x100000000); + long long fieldz = (long long) ((dipoleScale*labFrameDipole[m*3+2]-GRID_SIZE_Z*recipBoxVecZ.z*tuv001)*0x100000000); fieldBuffers[m+2*PADDED_NUM_ATOMS] = fieldz; fieldPolarBuffers[m+2*PADDED_NUM_ATOMS] = fieldz; } @@ -495,7 +544,7 @@ extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict extern "C" __global__ void computeInducedPotentialFromGrid(const real2* __restrict__ pmeGrid, real* __restrict__ phid, real* __restrict__ phip, real* __restrict__ phidp, const real4* __restrict__ posq, - real4 periodicBoxSize, real4 invPeriodicBoxSize, int2* __restrict__ pmeAtomGridIndex) { + real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ, int2* __restrict__ pmeAtomGridIndex) { real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; @@ -507,26 +556,26 @@ extern "C" __global__ void computeInducedPotentialFromGrid(const real2* __restri for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*invPeriodicBoxSize.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*invPeriodicBoxSize.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*invPeriodicBoxSize.z)*periodicBoxSize.z; + pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; + pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; + pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. - real w = pos.x*invPeriodicBoxSize.x; + real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); int ifr = (int) fr; w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); - w = pos.y*invPeriodicBoxSize.y; + w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); - w = pos.z*invPeriodicBoxSize.z; + w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); ifr = (int) fr; w = fr - ifr; @@ -736,15 +785,29 @@ extern "C" __global__ void computeInducedPotentialFromGrid(const real2* __restri extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict__ posq, unsigned long long* __restrict__ forceBuffers, long long* __restrict__ torqueBuffers, real* __restrict__ energyBuffer, const real* __restrict__ labFrameDipole, - const real* __restrict__ labFrameQuadrupole, const real* __restrict__ phi_global, real4 invPeriodicBoxSize) { + const real* __restrict__ labFrameQuadrupole, const real* __restrict__ fracDipole, const real* __restrict__ fracQuadrupole, + const real* __restrict__ phi_global, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { real multipole[10]; const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19}; const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16}; const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18}; - const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x; - const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y; - const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z; + const real xscale = GRID_SIZE_X*recipBoxVecX.x; + const real yscale = GRID_SIZE_Y*recipBoxVecY.y; + const real zscale = GRID_SIZE_Z*recipBoxVecZ.z; real energy = 0; + __shared__ real fracToCart[3][3]; + if (threadIdx.x == 0) { + fracToCart[0][0] = GRID_SIZE_X*recipBoxVecX.x; + fracToCart[1][0] = GRID_SIZE_X*recipBoxVecY.x; + fracToCart[2][0] = GRID_SIZE_X*recipBoxVecZ.x; + fracToCart[0][1] = GRID_SIZE_Y*recipBoxVecX.y; + fracToCart[1][1] = GRID_SIZE_Y*recipBoxVecY.y; + fracToCart[2][1] = GRID_SIZE_Y*recipBoxVecZ.y; + fracToCart[0][2] = GRID_SIZE_Z*recipBoxVecX.z; + fracToCart[1][2] = GRID_SIZE_Z*recipBoxVecY.z; + fracToCart[2][2] = GRID_SIZE_Z*recipBoxVecZ.z; + } + __syncthreads(); for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { // Compute the torque. @@ -778,15 +841,15 @@ extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict // Compute the force and energy. - multipole[1] *= xscale; - multipole[2] *= yscale; - multipole[3] *= zscale; - multipole[4] *= xscale*xscale; - multipole[5] *= yscale*yscale; - multipole[6] *= zscale*zscale; - multipole[7] *= xscale*yscale; - multipole[8] *= xscale*zscale; - multipole[9] *= yscale*zscale; + multipole[1] = fracDipole[i*3]; + multipole[2] = fracDipole[i*3+1]; + multipole[3] = fracDipole[i*3+2]; + multipole[4] = fracQuadrupole[i*6]; + multipole[5] = fracQuadrupole[i*6+3]; + multipole[6] = fracQuadrupole[i*6+5]; + multipole[7] = fracQuadrupole[i*6+1]; + multipole[8] = fracQuadrupole[i*6+2]; + multipole[9] = fracQuadrupole[i*6+4]; real4 f = make_real4(0, 0, 0, 0); for (int k = 0; k < 10; k++) { @@ -795,9 +858,9 @@ extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict f.y += multipole[k]*phi[deriv2[k]]; f.z += multipole[k]*phi[deriv3[k]]; } - f.x *= EPSILON_FACTOR*xscale; - f.y *= EPSILON_FACTOR*yscale; - f.z *= EPSILON_FACTOR*zscale; + f = make_real4(EPSILON_FACTOR*(f.x*fracToCart[0][0] + f.y*fracToCart[0][1] + f.z*fracToCart[0][2]), + EPSILON_FACTOR*(f.x*fracToCart[1][0] + f.y*fracToCart[1][1] + f.z*fracToCart[1][2]), + EPSILON_FACTOR*(f.x*fracToCart[2][0] + f.y*fracToCart[2][1] + f.z*fracToCart[2][2]), 0); forceBuffers[i] -= static_cast((long long) (f.x*0x100000000)); forceBuffers[i+PADDED_NUM_ATOMS] -= static_cast((long long) (f.y*0x100000000)); forceBuffers[i+PADDED_NUM_ATOMS*2] -= static_cast((long long) (f.z*0x100000000)); @@ -807,23 +870,37 @@ extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict extern "C" __global__ void computeInducedDipoleForceAndEnergy(real4* __restrict__ posq, unsigned long long* __restrict__ forceBuffers, long long* __restrict__ torqueBuffers, real* __restrict__ energyBuffer, const real* __restrict__ labFrameDipole, - const real* __restrict__ labFrameQuadrupole, const real* __restrict__ inducedDipole_global, const real* __restrict__ inducedDipolePolar_global, + const real* __restrict__ labFrameQuadrupole, const real* __restrict__ fracDipole, const real* __restrict__ fracQuadrupole, + const real* __restrict__ inducedDipole_global, const real* __restrict__ inducedDipolePolar_global, const real* __restrict__ phi_global, const real* __restrict__ phid_global, const real* __restrict__ phip_global, - const real* __restrict__ phidp_global, real4 invPeriodicBoxSize) { + const real* __restrict__ phidp_global, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { real multipole[10]; - real inducedDipole[3]; - real inducedDipolePolar[3]; + real cinducedDipole[3], inducedDipole[3]; + real cinducedDipolePolar[3], inducedDipolePolar[3]; real scales[3]; const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19}; const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16}; const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18}; - const real xscale = GRID_SIZE_X*invPeriodicBoxSize.x; - const real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y; - const real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z; + const real xscale = GRID_SIZE_X*recipBoxVecX.x; + const real yscale = GRID_SIZE_Y*recipBoxVecY.y; + const real zscale = GRID_SIZE_Z*recipBoxVecZ.z; scales[0] = xscale; scales[1] = yscale; scales[2] = zscale; real energy = 0; + __shared__ real fracToCart[3][3]; + if (threadIdx.x == 0) { + fracToCart[0][0] = GRID_SIZE_X*recipBoxVecX.x; + fracToCart[1][0] = GRID_SIZE_X*recipBoxVecY.x; + fracToCart[2][0] = GRID_SIZE_X*recipBoxVecZ.x; + fracToCart[0][1] = GRID_SIZE_Y*recipBoxVecX.y; + fracToCart[1][1] = GRID_SIZE_Y*recipBoxVecY.y; + fracToCart[2][1] = GRID_SIZE_Y*recipBoxVecZ.y; + fracToCart[0][2] = GRID_SIZE_Z*recipBoxVecX.z; + fracToCart[1][2] = GRID_SIZE_Z*recipBoxVecY.z; + fracToCart[2][2] = GRID_SIZE_Z*recipBoxVecZ.z; + } + __syncthreads(); for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { // Compute the torque. @@ -856,56 +933,62 @@ extern "C" __global__ void computeInducedDipoleForceAndEnergy(real4* __restrict_ // Compute the force and energy. - multipole[1] *= xscale; - multipole[2] *= yscale; - multipole[3] *= zscale; - multipole[4] *= xscale*xscale; - multipole[5] *= yscale*yscale; - multipole[6] *= zscale*zscale; - multipole[7] *= xscale*yscale; - multipole[8] *= xscale*zscale; - multipole[9] *= yscale*zscale; - - inducedDipole[0] = inducedDipole_global[i*3]; - inducedDipole[1] = inducedDipole_global[i*3+1]; - inducedDipole[2] = inducedDipole_global[i*3+2]; - inducedDipolePolar[0] = inducedDipolePolar_global[i*3]; - inducedDipolePolar[1] = inducedDipolePolar_global[i*3+1]; - inducedDipolePolar[2] = inducedDipolePolar_global[i*3+2]; + multipole[1] = fracDipole[i*3]; + multipole[2] = fracDipole[i*3+1]; + multipole[3] = fracDipole[i*3+2]; + multipole[4] = fracQuadrupole[i*6]; + multipole[5] = fracQuadrupole[i*6+3]; + multipole[6] = fracQuadrupole[i*6+5]; + multipole[7] = fracQuadrupole[i*6+1]; + multipole[8] = fracQuadrupole[i*6+2]; + multipole[9] = fracQuadrupole[i*6+4]; + + cinducedDipole[0] = inducedDipole_global[i*3]; + cinducedDipole[1] = inducedDipole_global[i*3+1]; + cinducedDipole[2] = inducedDipole_global[i*3+2]; + cinducedDipolePolar[0] = inducedDipolePolar_global[i*3]; + cinducedDipolePolar[1] = inducedDipolePolar_global[i*3+1]; + cinducedDipolePolar[2] = inducedDipolePolar_global[i*3+2]; + + // Multiply the dipoles by cartToFrac, which is just the transpose of fracToCart. + + inducedDipole[0] = cinducedDipole[0]*fracToCart[0][0] + cinducedDipole[1]*fracToCart[1][0] + cinducedDipole[2]*fracToCart[2][0]; + inducedDipole[1] = cinducedDipole[0]*fracToCart[0][1] + cinducedDipole[1]*fracToCart[1][1] + cinducedDipole[2]*fracToCart[2][1]; + inducedDipole[2] = cinducedDipole[0]*fracToCart[0][2] + cinducedDipole[1]*fracToCart[1][2] + cinducedDipole[2]*fracToCart[2][2]; + inducedDipolePolar[0] = cinducedDipolePolar[0]*fracToCart[0][0] + cinducedDipolePolar[1]*fracToCart[1][0] + cinducedDipolePolar[2]*fracToCart[2][0]; + inducedDipolePolar[1] = cinducedDipolePolar[0]*fracToCart[0][1] + cinducedDipolePolar[1]*fracToCart[1][1] + cinducedDipolePolar[2]*fracToCart[2][1]; + inducedDipolePolar[2] = cinducedDipolePolar[0]*fracToCart[0][2] + cinducedDipolePolar[1]*fracToCart[1][2] + cinducedDipolePolar[2]*fracToCart[2][2]; const real* phi = &phi_global[20*i]; const real* phip = &phip_global[10*i]; const real* phid = &phid_global[10*i]; real4 f = make_real4(0, 0, 0, 0); - energy += GRID_SIZE_X*invPeriodicBoxSize.x*inducedDipole[0]*phi[1]; - energy += GRID_SIZE_Y*invPeriodicBoxSize.y*inducedDipole[1]*phi[2]; - energy += GRID_SIZE_Z*invPeriodicBoxSize.z*inducedDipole[2]*phi[3]; + energy += inducedDipole[0]*phi[1]; + energy += inducedDipole[1]*phi[2]; + energy += inducedDipole[2]*phi[3]; for (int k = 0; k < 3; k++) { int j1 = deriv1[k+1]; int j2 = deriv2[k+1]; int j3 = deriv3[k+1]; - f.x += (inducedDipole[k]+inducedDipolePolar[k])*phi[j1]*(scales[k]/xscale); - f.y += (inducedDipole[k]+inducedDipolePolar[k])*phi[j2]*(scales[k]/yscale); - f.z += (inducedDipole[k]+inducedDipolePolar[k])*phi[j3]*(scales[k]/zscale); + f.x += (inducedDipole[k]+inducedDipolePolar[k])*phi[j1]; + f.y += (inducedDipole[k]+inducedDipolePolar[k])*phi[j2]; + f.z += (inducedDipole[k]+inducedDipolePolar[k])*phi[j3]; #ifndef DIRECT_POLARIZATION - f.x += (inducedDipole[k]*phip[j1] + inducedDipolePolar[k]*phid[j1])*(scales[k]/xscale); - f.y += (inducedDipole[k]*phip[j2] + inducedDipolePolar[k]*phid[j2])*(scales[k]/yscale); - f.z += (inducedDipole[k]*phip[j3] + inducedDipolePolar[k]*phid[j3])*(scales[k]/zscale); + f.x += (inducedDipole[k]*phip[j1] + inducedDipolePolar[k]*phid[j1]); + f.y += (inducedDipole[k]*phip[j2] + inducedDipolePolar[k]*phid[j2]); + f.z += (inducedDipole[k]*phip[j3] + inducedDipolePolar[k]*phid[j3]); #endif } - f.x *= GRID_SIZE_X*invPeriodicBoxSize.x; - f.y *= GRID_SIZE_Y*invPeriodicBoxSize.y; - f.z *= GRID_SIZE_Z*invPeriodicBoxSize.z; for (int k = 0; k < 10; k++) { f.x += multipole[k]*phidp[deriv1[k]]; f.y += multipole[k]*phidp[deriv2[k]]; f.z += multipole[k]*phidp[deriv3[k]]; } - f.x *= 0.5f*EPSILON_FACTOR*xscale; - f.y *= 0.5f*EPSILON_FACTOR*yscale; - f.z *= 0.5f*EPSILON_FACTOR*zscale; + f = make_real4(0.5f*EPSILON_FACTOR*(f.x*fracToCart[0][0] + f.y*fracToCart[0][1] + f.z*fracToCart[0][2]), + 0.5f*EPSILON_FACTOR*(f.x*fracToCart[1][0] + f.y*fracToCart[1][1] + f.z*fracToCart[1][2]), + 0.5f*EPSILON_FACTOR*(f.x*fracToCart[2][0] + f.y*fracToCart[2][1] + f.z*fracToCart[2][2]), 0); forceBuffers[i] -= static_cast((long long) (f.x*0x100000000)); forceBuffers[i+PADDED_NUM_ATOMS] -= static_cast((long long) (f.y*0x100000000)); forceBuffers[i+PADDED_NUM_ATOMS*2] -= static_cast((long long) (f.z*0x100000000)); @@ -914,10 +997,10 @@ extern "C" __global__ void computeInducedDipoleForceAndEnergy(real4* __restrict_ } extern "C" __global__ void recordInducedFieldDipoles(const real* __restrict__ phid, real* const __restrict__ phip, - long long* __restrict__ inducedField, long long* __restrict__ inducedFieldPolar, real4 invPeriodicBoxSize) { - real xscale = GRID_SIZE_X*invPeriodicBoxSize.x*0x100000000; - real yscale = GRID_SIZE_Y*invPeriodicBoxSize.y*0x100000000; - real zscale = GRID_SIZE_Z*invPeriodicBoxSize.z*0x100000000; + long long* __restrict__ inducedField, long long* __restrict__ inducedFieldPolar, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + real xscale = GRID_SIZE_X*recipBoxVecX.x*0x100000000; + real yscale = GRID_SIZE_Y*recipBoxVecY.y*0x100000000; + real zscale = GRID_SIZE_Z*recipBoxVecZ.z*0x100000000; for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { inducedField[i] -= (long long) (xscale*phid[10*i+1]); inducedField[i+PADDED_NUM_ATOMS] -= (long long) (yscale*phid[10*i+2]); diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipoles.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipoles.cu index d4e0667fe..b3e29ca1b 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipoles.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipoles.cu @@ -448,7 +448,7 @@ extern "C" __global__ void mapTorqueToForce(unsigned long long* __restrict__ for */ extern "C" __global__ void computePotentialAtPoints(const real4* __restrict__ posq, const real* __restrict__ labFrameDipole, const real* __restrict__ labFrameQuadrupole, const real* __restrict__ inducedDipole, const real4* __restrict__ points, - real* __restrict__ potential, int numPoints, real4 periodicBoxSize, real4 invPeriodicBoxSize) { + real* __restrict__ potential, int numPoints, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ) { extern __shared__ real4 localPosq[]; real3* localDipole = (real3*) &localPosq[blockDim.x]; real3* localInducedDipole = (real3*) &localDipole[blockDim.x]; @@ -481,9 +481,7 @@ extern "C" __global__ void computePotentialAtPoints(const real4* __restrict__ po for (int i = 0; i < end; i++) { real3 delta = trimTo3(localPosq[i]-pointPos); #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta, delta); real rInv = RSQRT(r2); diff --git a/plugins/amoeba/platforms/cuda/src/kernels/pmeMultipoleElectrostatics.cu b/plugins/amoeba/platforms/cuda/src/kernels/pmeMultipoleElectrostatics.cu index 735824bb0..96da990f3 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/pmeMultipoleElectrostatics.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/pmeMultipoleElectrostatics.cu @@ -65,7 +65,7 @@ __device__ float computePScaleFactor(uint2 covalent, unsigned int polarizationGr } __device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, bool hasExclusions, float dScale, float pScale, float mScale, float forceFactor, - real& energy, real4 periodicBoxSize, real4 invPeriodicBoxSize) { + real& energy, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ) { real4 delta; delta.x = atom2.pos.x - atom1.pos.x; delta.y = atom2.pos.y - atom1.pos.y; @@ -73,10 +73,7 @@ __device__ void computeOneInteraction(AtomData& atom1, AtomData& atom2, bool has // periodic box - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; - + APPLY_PERIODIC_TO_DELTA(delta) delta.w = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; if (delta.w > CUTOFF_SQUARED) return; @@ -203,7 +200,9 @@ extern "C" __global__ void computeElectrostatics( const real4* __restrict__ posq, const uint2* __restrict__ covalentFlags, const unsigned int* __restrict__ polarizationGroupFlags, const ushort2* __restrict__ exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices, #ifdef USE_CUTOFF - const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, unsigned int maxTiles, const real4* __restrict__ blockCenter, const unsigned int* __restrict__ interactingAtoms, + const int* __restrict__ tiles, const unsigned int* __restrict__ interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, const real4* __restrict__ blockCenter, + const unsigned int* __restrict__ interactingAtoms, #endif const real* __restrict__ labFrameDipole, const real* __restrict__ labFrameQuadrupole, const real* __restrict__ inducedDipole, const real* __restrict__ inducedDipolePolar, const float2* __restrict__ dampingAndThole) { @@ -255,7 +254,7 @@ extern "C" __global__ void computeElectrostatics( float d = computeDScaleFactor(polarizationGroup, j); float p = computePScaleFactor(covalent, polarizationGroup, j); float m = computeMScaleFactor(covalent, j); - computeOneInteraction(data, localData[tbx+j], true, d, p, m, 0.5f, energy, periodicBoxSize, invPeriodicBoxSize); + computeOneInteraction(data, localData[tbx+j], true, d, p, m, 0.5f, energy, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); } } if (atom1 < NUM_ATOMS) @@ -283,7 +282,7 @@ extern "C" __global__ void computeElectrostatics( float d = computeDScaleFactor(polarizationGroup, tj); float p = computePScaleFactor(covalent, polarizationGroup, tj); float m = computeMScaleFactor(covalent, tj); - computeOneInteraction(data, localData[tbx+tj], true, d, p, m, 1, energy, periodicBoxSize, invPeriodicBoxSize); + computeOneInteraction(data, localData[tbx+tj], true, d, p, m, 1, energy, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); } tj = (tj + 1) & (TILE_SIZE - 1); } @@ -386,7 +385,7 @@ extern "C" __global__ void computeElectrostatics( for (j = 0; j < TILE_SIZE; j++) { int atom2 = atomIndices[tbx+tj]; if (atom1 < NUM_ATOMS && atom2 < NUM_ATOMS) { - computeOneInteraction(data, localData[tbx+tj], false, 1, 1, 1, 1, energy, periodicBoxSize, invPeriodicBoxSize); + computeOneInteraction(data, localData[tbx+tj], false, 1, 1, 1, 1, energy, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ); } tj = (tj + 1) & (TILE_SIZE - 1); } -- GitLab From 3b91c94563412d2973c4f371e8dd3c48a8bb3db8 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 5 Feb 2015 10:53:04 -0800 Subject: [PATCH 233/338] Continuing CUDA implementation of triclinic boxes for AmoebaMultipoleForce --- .../platforms/cuda/src/AmoebaCudaKernels.cpp | 25 +- .../platforms/cuda/src/AmoebaCudaKernels.h | 5 +- .../cuda/src/kernels/multipolePme.cu | 236 ++++++++++++------ 3 files changed, 176 insertions(+), 90 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp index eebfe8552..27d55c020 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman, Mark Friedrichs * * Contributors: * * * @@ -801,7 +801,7 @@ CudaCalcAmoebaMultipoleForceKernel::CudaCalcAmoebaMultipoleForceKernel(std::stri diisCoefficients(NULL), inducedDipolePolar(NULL), inducedDipoleErrors(NULL), prevDipoles(NULL), prevDipolesPolar(NULL), prevDipolesGk(NULL), prevDipolesGkPolar(NULL), prevErrors(NULL), diisMatrix(NULL), polarizability(NULL), covalentFlags(NULL), polarizationGroupFlags(NULL), pmeGrid(NULL), pmeBsplineModuliX(NULL), pmeBsplineModuliY(NULL), pmeBsplineModuliZ(NULL), pmeIgrid(NULL), pmePhi(NULL), - pmePhid(NULL), pmePhip(NULL), pmePhidp(NULL), pmeAtomGridIndex(NULL), lastPositions(NULL), sort(NULL), gkKernel(NULL) { + pmePhid(NULL), pmePhip(NULL), pmePhidp(NULL), pmeCphi(NULL), pmeAtomGridIndex(NULL), lastPositions(NULL), sort(NULL), gkKernel(NULL) { } CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() { @@ -876,6 +876,8 @@ CudaCalcAmoebaMultipoleForceKernel::~CudaCalcAmoebaMultipoleForceKernel() { delete pmePhip; if (pmePhidp != NULL) delete pmePhidp; + if (pmeCphi != NULL) + delete pmeCphi; if (pmeAtomGridIndex != NULL) delete pmeAtomGridIndex; if (lastPositions != NULL) @@ -1192,6 +1194,7 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const CUmodule module = cu.createModule(CudaKernelSources::vectorOps+CudaAmoebaKernelSources::multipolePme, pmeDefines); pmeGridIndexKernel = cu.getKernel(module, "findAtomGridIndex"); pmeTransformMultipolesKernel = cu.getKernel(module, "transformMultipolesToFractionalCoordinates"); + pmeTransformPotentialKernel = cu.getKernel(module, "transformPotentialToCartesianCoordinates"); pmeSpreadFixedMultipolesKernel = cu.getKernel(module, "gridSpreadFixedMultipoles"); pmeSpreadInducedDipolesKernel = cu.getKernel(module, "gridSpreadInducedDipoles"); pmeFinishSpreadChargeKernel = cu.getKernel(module, "finishSpreadCharge"); @@ -1219,6 +1222,7 @@ void CudaCalcAmoebaMultipoleForceKernel::initialize(const System& system, const pmePhid = new CudaArray(cu, 10*numMultipoles, elementSize, "pmePhid"); pmePhip = new CudaArray(cu, 10*numMultipoles, elementSize, "pmePhip"); pmePhidp = new CudaArray(cu, 20*numMultipoles, elementSize, "pmePhidp"); + pmeCphi = new CudaArray(cu, 10*numMultipoles, elementSize, "pmeCphi"); pmeAtomRange = CudaArray::create(cu, gridSizeX*gridSizeY*gridSizeZ+1, "pmeAtomRange"); pmeAtomGridIndex = CudaArray::create(cu, numMultipoles, "pmeAtomGridIndex"); sort = new CudaSort(cu, new SortTrait(), cu.getNumAtoms()); @@ -1520,14 +1524,16 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in unsigned int maxTiles = nb.getInteractingTiles().getSize(); void* gridIndexArgs[] = {&cu.getPosq().getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), - cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; + cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), + recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeGridIndexKernel, gridIndexArgs, cu.getNumAtoms(), cu.ThreadBlockSize, cu.ThreadBlockSize*PmeOrder*PmeOrder*elementSize); sort->sort(*pmeAtomGridIndex); void* pmeTransformMultipolesArgs[] = {&labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeTransformMultipolesKernel, pmeTransformMultipolesArgs, cu.getNumAtoms()); void* pmeSpreadFixedMultipolesArgs[] = {&cu.getPosq().getDevicePointer(), &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), - &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; + &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), + recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeSpreadFixedMultipolesKernel, pmeSpreadFixedMultipolesArgs, cu.getNumAtoms()); void* finishSpreadArgs[] = {&pmeGrid->getDevicePointer()}; if (cu.getUseDoublePrecision()) @@ -1547,9 +1553,11 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in &fieldPolar ->getDevicePointer(), &cu.getPosq().getDevicePointer(), &labFrameDipoles->getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeFixedPotentialKernel, pmeFixedPotentialArgs, cu.getNumAtoms()); + void* pmeTransformFixedPotentialArgs[] = {&pmePhi->getDevicePointer(), &pmeCphi->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; + cu.executeKernel(pmeTransformPotentialKernel, pmeTransformFixedPotentialArgs, cu.getNumAtoms()); void* pmeFixedForceArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &torque->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), - &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), &pmePhi->getDevicePointer(), + &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), &pmePhi->getDevicePointer(), &pmeCphi->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeFixedForceKernel, pmeFixedForceArgs, cu.getNumAtoms()); @@ -1570,7 +1578,8 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in cu.clearBuffer(*pmeGrid); void* pmeSpreadInducedDipolesArgs[] = {&cu.getPosq().getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), - &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; + &pmeGrid->getDevicePointer(), &pmeAtomGridIndex->getDevicePointer(), cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), + recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeSpreadInducedDipolesKernel, pmeSpreadInducedDipolesArgs, cu.getNumAtoms()); if (cu.getUseDoublePrecision()) cu.executeKernel(pmeFinishSpreadChargeKernel, finishSpreadArgs, pmeGrid->getSize()); @@ -1634,11 +1643,13 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), &dampingAndThole->getDevicePointer()}; cu.executeKernel(electrostaticsKernel, electrostaticsArgs, numForceThreadBlocks*electrostaticsThreads, electrostaticsThreads); + void* pmeTransformInducedPotentialArgs[] = {&pmePhidp->getDevicePointer(), &pmeCphi->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; + cu.executeKernel(pmeTransformPotentialKernel, pmeTransformInducedPotentialArgs, cu.getNumAtoms()); void* pmeInducedForceArgs[] = {&cu.getPosq().getDevicePointer(), &cu.getForce().getDevicePointer(), &torque->getDevicePointer(), &cu.getEnergyBuffer().getDevicePointer(), &labFrameDipoles->getDevicePointer(), &labFrameQuadrupoles->getDevicePointer(), &fracDipoles->getDevicePointer(), &fracQuadrupoles->getDevicePointer(), &inducedDipole->getDevicePointer(), &inducedDipolePolar->getDevicePointer(), &pmePhi->getDevicePointer(), &pmePhid->getDevicePointer(), - &pmePhip->getDevicePointer(), &pmePhidp->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; + &pmePhip->getDevicePointer(), &pmePhidp->getDevicePointer(), &pmeCphi->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeInducedForceKernel, pmeInducedForceArgs, cu.getNumAtoms()); } diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h index aff868336..8b17fc780 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Mark Friedrichs, Peter Eastman * * Contributors: * * * @@ -421,6 +421,7 @@ private: CudaArray* pmePhid; CudaArray* pmePhip; CudaArray* pmePhidp; + CudaArray* pmeCphi; CudaArray* pmeAtomRange; CudaArray* pmeAtomGridIndex; CudaArray* lastPositions; @@ -430,7 +431,7 @@ private: CUfunction pmeGridIndexKernel, pmeSpreadFixedMultipolesKernel, pmeSpreadInducedDipolesKernel, pmeFinishSpreadChargeKernel, pmeConvolutionKernel; CUfunction pmeFixedPotentialKernel, pmeInducedPotentialKernel, pmeFixedForceKernel, pmeInducedForceKernel, pmeRecordInducedFieldDipolesKernel, computePotentialKernel; CUfunction recordDIISDipolesKernel, buildMatrixKernel; - CUfunction pmeTransformMultipolesKernel; + CUfunction pmeTransformMultipolesKernel, pmeTransformPotentialKernel; CudaCalcAmoebaGeneralizedKirkwoodForceKernel* gkKernel; static const int PmeOrder = 5; static const int MaxPrevDIISDipoles = 20; diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu index d125728c8..4af677ceb 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu @@ -73,12 +73,12 @@ __device__ void computeBSplinePoint(real4* thetai, real w, real* array) { * Compute the index of the grid point each atom is associated with. */ extern "C" __global__ void findAtomGridIndex(const real4* __restrict__ posq, int2* __restrict__ pmeAtomGridIndex, - real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { real4 pos = posq[i]; - pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + pos -= periodicBoxVecZ*floor(pos.z*recipBoxVecZ.z+0.5f); + pos -= periodicBoxVecY*floor(pos.y*recipBoxVecY.z+0.5f); + pos -= periodicBoxVecX*floor(pos.x*recipBoxVecX.z+0.5f); // First axis. @@ -109,6 +109,7 @@ extern "C" __global__ void findAtomGridIndex(const real4* __restrict__ posq, int pmeAtomGridIndex[i] = make_int2(i, igrid1*GRID_SIZE_Y*GRID_SIZE_Z+igrid2*GRID_SIZE_Z+igrid3); } } + /** * Convert the fixed multipoles from Cartesian to fractional coordinates. */ @@ -161,9 +162,55 @@ extern "C" __global__ void transformMultipolesToFractionalCoordinates(const real } } +/** + * Convert the potential from fractional to Cartesian coordinates. + */ +extern "C" __global__ void transformPotentialToCartesianCoordinates(const real* __restrict__ fphi, real* __restrict__ cphi, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + // Build matrices for transforming the potential. + + __shared__ real a[3][3]; + if (threadIdx.x == 0) { + a[0][0] = GRID_SIZE_X*recipBoxVecX.x; + a[1][0] = GRID_SIZE_X*recipBoxVecY.x; + a[2][0] = GRID_SIZE_X*recipBoxVecZ.x; + a[0][1] = GRID_SIZE_Y*recipBoxVecX.y; + a[1][1] = GRID_SIZE_Y*recipBoxVecY.y; + a[2][1] = GRID_SIZE_Y*recipBoxVecZ.y; + a[0][2] = GRID_SIZE_Z*recipBoxVecX.z; + a[1][2] = GRID_SIZE_Z*recipBoxVecY.z; + a[2][2] = GRID_SIZE_Z*recipBoxVecZ.z; + } + __syncthreads(); + int index1[] = {0, 1, 2, 0, 0, 1}; + int index2[] = {0, 1, 2, 1, 2, 2}; + __shared__ real b[6][6]; + if (threadIdx.x < 36) { + int i = threadIdx.x/6; + int j = threadIdx.x-6*i; + b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; + if (index1[i] != index2[i]) + b[i][j] += (i < 3 ? b[i][j] : a[index1[i]][index2[j]]*a[index2[i]][index1[j]]); + } + __syncthreads(); + + // Transform the potential. + + for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { + cphi[10*i] = fphi[20*i]; + cphi[10*i+1] = a[0][0]*fphi[20*i+1] + a[0][1]*fphi[20*i+2] + a[0][2]*fphi[20*i+3]; + cphi[10*i+2] = a[1][0]*fphi[20*i+1] + a[1][1]*fphi[20*i+2] + a[1][2]*fphi[20*i+3]; + cphi[10*i+3] = a[2][0]*fphi[20*i+1] + a[2][1]*fphi[20*i+2] + a[2][2]*fphi[20*i+3]; + for (int j = 0; j < 6; j++) { + cphi[10*i+4+j] = 0; + for (int k = 0; k < 6; k++) + cphi[10*i+4+j] += b[j][k]*fphi[20*i+4+k]; + } + } +} + extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ posq, const real* __restrict__ fracDipole, const real* __restrict__ fracQuadrupole, real2* __restrict__ pmeGrid, int2* __restrict__ pmeAtomGridIndex, - real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; @@ -175,28 +222,28 @@ extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ p for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + pos -= periodicBoxVecZ*floor(pos.z*recipBoxVecZ.z+0.5f); + pos -= periodicBoxVecY*floor(pos.y*recipBoxVecY.z+0.5f); + pos -= periodicBoxVecX*floor(pos.x*recipBoxVecX.z+0.5f); // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); - int ifr = (int) fr; + int ifr = (int) floor(fr); w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid3 = ifr-PME_ORDER+1; computeBSplinePoint(theta3, w, array); @@ -252,14 +299,24 @@ extern "C" __global__ void gridSpreadFixedMultipoles(const real4* __restrict__ p extern "C" __global__ void gridSpreadInducedDipoles(const real4* __restrict__ posq, const real* __restrict__ inducedDipole, const real* __restrict__ inducedDipolePolar, real2* __restrict__ pmeGrid, int2* __restrict__ pmeAtomGridIndex, - real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { - const real xscale = GRID_SIZE_X*recipBoxVecX.x; - const real yscale = GRID_SIZE_Y*recipBoxVecY.y; - const real zscale = GRID_SIZE_Z*recipBoxVecZ.z; + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; real4 theta3[PME_ORDER]; + __shared__ real cartToFrac[3][3]; + if (threadIdx.x == 0) { + cartToFrac[0][0] = GRID_SIZE_X*recipBoxVecX.x; + cartToFrac[0][1] = GRID_SIZE_X*recipBoxVecY.x; + cartToFrac[0][2] = GRID_SIZE_X*recipBoxVecZ.x; + cartToFrac[1][0] = GRID_SIZE_Y*recipBoxVecX.y; + cartToFrac[1][1] = GRID_SIZE_Y*recipBoxVecY.y; + cartToFrac[1][2] = GRID_SIZE_Y*recipBoxVecZ.y; + cartToFrac[2][0] = GRID_SIZE_Z*recipBoxVecX.z; + cartToFrac[2][1] = GRID_SIZE_Z*recipBoxVecY.z; + cartToFrac[2][2] = GRID_SIZE_Z*recipBoxVecZ.z; + } + __syncthreads(); // Process the atoms in spatially sorted order. This improves cache performance when loading // the grid values. @@ -267,28 +324,28 @@ extern "C" __global__ void gridSpreadInducedDipoles(const real4* __restrict__ po for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + pos -= periodicBoxVecZ*floor(pos.z*recipBoxVecZ.z+0.5f); + pos -= periodicBoxVecY*floor(pos.y*recipBoxVecY.z+0.5f); + pos -= periodicBoxVecX*floor(pos.x*recipBoxVecX.z+0.5f); // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); - int ifr = (int) fr; + int ifr = (int) floor(fr); w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid3 = ifr-PME_ORDER+1; computeBSplinePoint(theta3, w, array); @@ -316,16 +373,18 @@ extern "C" __global__ void gridSpreadInducedDipoles(const real4* __restrict__ po int index = ybase + zindex; real4 v = theta3[iz]; - real inducedDipoleX = xscale*inducedDipole[m*3]; - real inducedDipoleY = yscale*inducedDipole[m*3+1]; - real inducedDipoleZ = zscale*inducedDipole[m*3+2]; - real inducedDipolePolarX = xscale*inducedDipolePolar[m*3]; - real inducedDipolePolarY = yscale*inducedDipolePolar[m*3+1]; - real inducedDipolePolarZ = zscale*inducedDipolePolar[m*3+2]; - real term01 = inducedDipoleY*u.y*v.x + inducedDipoleZ*u.x*v.y; - real term11 = inducedDipoleX*u.x*v.x; - real term02 = inducedDipolePolarY*u.y*v.x + inducedDipolePolarZ*u.x*v.y; - real term12 = inducedDipolePolarX*u.x*v.x; + real3 cinducedDipole = make_real3(inducedDipole[m*3], inducedDipole[m*3+1], inducedDipole[m*3+2]); + real3 cinducedDipolePolar = make_real3(inducedDipolePolar[m*3], inducedDipolePolar[m*3+1], inducedDipolePolar[m*3+2]); + real3 finducedDipole = make_real3(cinducedDipole.x*cartToFrac[0][0] + cinducedDipole.y*cartToFrac[0][1] + cinducedDipole.z*cartToFrac[0][2], + cinducedDipole.x*cartToFrac[1][0] + cinducedDipole.y*cartToFrac[1][1] + cinducedDipole.z*cartToFrac[1][2], + cinducedDipole.x*cartToFrac[2][0] + cinducedDipole.y*cartToFrac[2][1] + cinducedDipole.z*cartToFrac[2][2]); + real3 finducedDipolePolar = make_real3(cinducedDipolePolar.x*cartToFrac[0][0] + cinducedDipolePolar.y*cartToFrac[0][1] + cinducedDipolePolar.z*cartToFrac[0][2], + cinducedDipolePolar.x*cartToFrac[1][0] + cinducedDipolePolar.y*cartToFrac[1][1] + cinducedDipolePolar.z*cartToFrac[1][2], + cinducedDipolePolar.x*cartToFrac[2][0] + cinducedDipolePolar.y*cartToFrac[2][1] + cinducedDipolePolar.z*cartToFrac[2][2]); + real term01 = finducedDipole.y*u.y*v.x + finducedDipole.z*u.x*v.y; + real term11 = finducedDipole.x*u.x*v.x; + real term02 = finducedDipolePolar.y*u.y*v.x + finducedDipolePolar.z*u.x*v.y; + real term12 = finducedDipolePolar.x*u.x*v.x; real add1 = term01*t.x + term11*t.y; real add2 = term02*t.x + term12*t.y; #ifdef USE_DOUBLE_PRECISION @@ -392,6 +451,19 @@ extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; real4 theta3[PME_ORDER]; + __shared__ real fracToCart[3][3]; + if (threadIdx.x == 0) { + fracToCart[0][0] = GRID_SIZE_X*recipBoxVecX.x; + fracToCart[1][0] = GRID_SIZE_X*recipBoxVecY.x; + fracToCart[2][0] = GRID_SIZE_X*recipBoxVecZ.x; + fracToCart[0][1] = GRID_SIZE_Y*recipBoxVecX.y; + fracToCart[1][1] = GRID_SIZE_Y*recipBoxVecY.y; + fracToCart[2][1] = GRID_SIZE_Y*recipBoxVecZ.y; + fracToCart[0][2] = GRID_SIZE_Z*recipBoxVecX.z; + fracToCart[1][2] = GRID_SIZE_Z*recipBoxVecY.z; + fracToCart[2][2] = GRID_SIZE_Z*recipBoxVecZ.z; + } + __syncthreads(); // Process the atoms in spatially sorted order. This improves cache performance when loading // the grid values. @@ -530,13 +602,13 @@ extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict phi[20*m+18] = tuv012; phi[20*m+19] = tuv111; real dipoleScale = (4/(real) 3)*(EWALD_ALPHA*EWALD_ALPHA*EWALD_ALPHA)/SQRT_PI; - long long fieldx = (long long) ((dipoleScale*labFrameDipole[m*3]-GRID_SIZE_X*recipBoxVecX.x*tuv100)*0x100000000); + long long fieldx = (long long) ((dipoleScale*labFrameDipole[m*3]-tuv100*fracToCart[0][0]-tuv010*fracToCart[0][1]-tuv001*fracToCart[0][2])*0x100000000); fieldBuffers[m] = fieldx; fieldPolarBuffers[m] = fieldx; - long long fieldy = (long long) ((dipoleScale*labFrameDipole[m*3+1]-GRID_SIZE_Y*recipBoxVecY.y*tuv010)*0x100000000); + long long fieldy = (long long) ((dipoleScale*labFrameDipole[m*3+1]-tuv100*fracToCart[1][0]-tuv010*fracToCart[1][1]-tuv001*fracToCart[1][2])*0x100000000); fieldBuffers[m+PADDED_NUM_ATOMS] = fieldy; fieldPolarBuffers[m+PADDED_NUM_ATOMS] = fieldy; - long long fieldz = (long long) ((dipoleScale*labFrameDipole[m*3+2]-GRID_SIZE_Z*recipBoxVecZ.z*tuv001)*0x100000000); + long long fieldz = (long long) ((dipoleScale*labFrameDipole[m*3+2]-tuv100*fracToCart[2][0]-tuv010*fracToCart[2][1]-tuv001*fracToCart[2][2])*0x100000000); fieldBuffers[m+2*PADDED_NUM_ATOMS] = fieldz; fieldPolarBuffers[m+2*PADDED_NUM_ATOMS] = fieldz; } @@ -786,14 +858,11 @@ extern "C" __global__ void computeInducedPotentialFromGrid(const real2* __restri extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict__ posq, unsigned long long* __restrict__ forceBuffers, long long* __restrict__ torqueBuffers, real* __restrict__ energyBuffer, const real* __restrict__ labFrameDipole, const real* __restrict__ labFrameQuadrupole, const real* __restrict__ fracDipole, const real* __restrict__ fracQuadrupole, - const real* __restrict__ phi_global, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + const real* __restrict__ phi_global, const real* __restrict__ cphi_global, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { real multipole[10]; const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19}; const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16}; const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18}; - const real xscale = GRID_SIZE_X*recipBoxVecX.x; - const real yscale = GRID_SIZE_Y*recipBoxVecY.y; - const real zscale = GRID_SIZE_Z*recipBoxVecZ.z; real energy = 0; __shared__ real fracToCart[3][3]; if (threadIdx.x == 0) { @@ -822,22 +891,22 @@ extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict multipole[8] = 2*labFrameQuadrupole[i*5+2]; multipole[9] = 2*labFrameQuadrupole[i*5+4]; - const real* phi = &phi_global[20*i]; + const real* cphi = &cphi_global[10*i]; - torqueBuffers[i] = (long long) (EPSILON_FACTOR*(multipole[3]*yscale*phi[2] - multipole[2]*zscale*phi[3] - + 2*(multipole[6]-multipole[5])*yscale*zscale*phi[9] - + multipole[8]*xscale*yscale*phi[7] + multipole[9]*yscale*yscale*phi[5] - - multipole[7]*xscale*zscale*phi[8] - multipole[9]*zscale*zscale*phi[6])*0x100000000); + torqueBuffers[i] = (long long) (EPSILON_FACTOR*(multipole[3]*cphi[2] - multipole[2]*cphi[3] + + 2*(multipole[6]-multipole[5])*cphi[9] + + multipole[8]*cphi[7] + multipole[9]*cphi[5] + - multipole[7]*cphi[8] - multipole[9]*cphi[6])*0x100000000); - torqueBuffers[i+PADDED_NUM_ATOMS] = (long long) (EPSILON_FACTOR*(multipole[1]*zscale*phi[3] - multipole[3]*xscale*phi[1] - + 2*(multipole[4]-multipole[6])*xscale*zscale*phi[8] - + multipole[7]*yscale*zscale*phi[9] + multipole[8]*zscale*zscale*phi[6] - - multipole[8]*xscale*xscale*phi[4] - multipole[9]*xscale*yscale*phi[7])*0x100000000); + torqueBuffers[i+PADDED_NUM_ATOMS] = (long long) (EPSILON_FACTOR*(multipole[1]*cphi[3] - multipole[3]*cphi[1] + + 2*(multipole[4]-multipole[6])*cphi[8] + + multipole[7]*cphi[9] + multipole[8]*cphi[6] + - multipole[8]*cphi[4] - multipole[9]*cphi[7])*0x100000000); - torqueBuffers[i+PADDED_NUM_ATOMS*2] = (long long) (EPSILON_FACTOR*(multipole[2]*xscale*phi[1] - multipole[1]*yscale*phi[2] - + 2*(multipole[5]-multipole[4])*xscale*yscale*phi[7] - + multipole[7]*xscale*xscale*phi[4] + multipole[9]*xscale*zscale*phi[8] - - multipole[7]*yscale*yscale*phi[5] - multipole[8]*yscale*zscale*phi[9])*0x100000000); + torqueBuffers[i+PADDED_NUM_ATOMS*2] = (long long) (EPSILON_FACTOR*(multipole[2]*cphi[1] - multipole[1]*cphi[2] + + 2*(multipole[5]-multipole[4])*cphi[7] + + multipole[7]*cphi[4] + multipole[9]*cphi[8] + - multipole[7]*cphi[5] - multipole[8]*cphi[9])*0x100000000); // Compute the force and energy. @@ -851,6 +920,7 @@ extern "C" __global__ void computeFixedMultipoleForceAndEnergy(real4* __restrict multipole[8] = fracQuadrupole[i*6+2]; multipole[9] = fracQuadrupole[i*6+4]; + const real* phi = &phi_global[20*i]; real4 f = make_real4(0, 0, 0, 0); for (int k = 0; k < 10; k++) { energy += multipole[k]*phi[k]; @@ -873,20 +943,13 @@ extern "C" __global__ void computeInducedDipoleForceAndEnergy(real4* __restrict_ const real* __restrict__ labFrameQuadrupole, const real* __restrict__ fracDipole, const real* __restrict__ fracQuadrupole, const real* __restrict__ inducedDipole_global, const real* __restrict__ inducedDipolePolar_global, const real* __restrict__ phi_global, const real* __restrict__ phid_global, const real* __restrict__ phip_global, - const real* __restrict__ phidp_global, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { + const real* __restrict__ phidp_global, const real* __restrict__ cphi_global, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { real multipole[10]; real cinducedDipole[3], inducedDipole[3]; real cinducedDipolePolar[3], inducedDipolePolar[3]; - real scales[3]; const int deriv1[] = {1, 4, 7, 8, 10, 15, 17, 13, 14, 19}; const int deriv2[] = {2, 7, 5, 9, 13, 11, 18, 15, 19, 16}; const int deriv3[] = {3, 8, 9, 6, 14, 16, 12, 19, 17, 18}; - const real xscale = GRID_SIZE_X*recipBoxVecX.x; - const real yscale = GRID_SIZE_Y*recipBoxVecY.y; - const real zscale = GRID_SIZE_Z*recipBoxVecZ.z; - scales[0] = xscale; - scales[1] = yscale; - scales[2] = zscale; real energy = 0; __shared__ real fracToCart[3][3]; if (threadIdx.x == 0) { @@ -914,22 +977,22 @@ extern "C" __global__ void computeInducedDipoleForceAndEnergy(real4* __restrict_ multipole[7] = 2*labFrameQuadrupole[i*5+1]; multipole[8] = 2*labFrameQuadrupole[i*5+2]; multipole[9] = 2*labFrameQuadrupole[i*5+4]; - const real* phidp = &phidp_global[20*i]; + const real* cphi = &cphi_global[10*i]; - torqueBuffers[i] += (long long) (0.5f*EPSILON_FACTOR*(multipole[3]*yscale*phidp[2] - multipole[2]*zscale*phidp[3] - + 2*(multipole[6]-multipole[5])*yscale*zscale*phidp[9] - + multipole[8]*xscale*yscale*phidp[7] + multipole[9]*yscale*yscale*phidp[5] - - multipole[7]*xscale*zscale*phidp[8] - multipole[9]*zscale*zscale*phidp[6])*0x100000000); + torqueBuffers[i] += (long long) (0.5f*EPSILON_FACTOR*(multipole[3]*cphi[2] - multipole[2]*cphi[3] + + 2*(multipole[6]-multipole[5])*cphi[9] + + multipole[8]*cphi[7] + multipole[9]*cphi[5] + - multipole[7]*cphi[8] - multipole[9]*cphi[6])*0x100000000); - torqueBuffers[i+PADDED_NUM_ATOMS] += (long long) (0.5f*EPSILON_FACTOR*(multipole[1]*zscale*phidp[3] - multipole[3]*xscale*phidp[1] - + 2*(multipole[4]-multipole[6])*xscale*zscale*phidp[8] - + multipole[7]*yscale*zscale*phidp[9] + multipole[8]*zscale*zscale*phidp[6] - - multipole[8]*xscale*xscale*phidp[4] - multipole[9]*xscale*yscale*phidp[7])*0x100000000); + torqueBuffers[i+PADDED_NUM_ATOMS] += (long long) (0.5f*EPSILON_FACTOR*(multipole[1]*cphi[3] - multipole[3]*cphi[1] + + 2*(multipole[4]-multipole[6])*cphi[8] + + multipole[7]*cphi[9] + multipole[8]*cphi[6] + - multipole[8]*cphi[4] - multipole[9]*cphi[7])*0x100000000); - torqueBuffers[i+PADDED_NUM_ATOMS*2] += (long long) (0.5f*EPSILON_FACTOR*(multipole[2]*xscale*phidp[1] - multipole[1]*yscale*phidp[2] - + 2*(multipole[5]-multipole[4])*xscale*yscale*phidp[7] - + multipole[7]*xscale*xscale*phidp[4] + multipole[9]*xscale*zscale*phidp[8] - - multipole[7]*yscale*yscale*phidp[5] - multipole[8]*yscale*zscale*phidp[9])*0x100000000); + torqueBuffers[i+PADDED_NUM_ATOMS*2] += (long long) (0.5f*EPSILON_FACTOR*(multipole[2]*cphi[1] - multipole[1]*cphi[2] + + 2*(multipole[5]-multipole[4])*cphi[7] + + multipole[7]*cphi[4] + multipole[9]*cphi[8] + - multipole[7]*cphi[5] - multipole[8]*cphi[9])*0x100000000); // Compute the force and energy. @@ -981,6 +1044,7 @@ extern "C" __global__ void computeInducedDipoleForceAndEnergy(real4* __restrict_ #endif } + const real* phidp = &phidp_global[20*i]; for (int k = 0; k < 10; k++) { f.x += multipole[k]*phidp[deriv1[k]]; f.y += multipole[k]*phidp[deriv2[k]]; @@ -998,15 +1062,25 @@ extern "C" __global__ void computeInducedDipoleForceAndEnergy(real4* __restrict_ extern "C" __global__ void recordInducedFieldDipoles(const real* __restrict__ phid, real* const __restrict__ phip, long long* __restrict__ inducedField, long long* __restrict__ inducedFieldPolar, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ) { - real xscale = GRID_SIZE_X*recipBoxVecX.x*0x100000000; - real yscale = GRID_SIZE_Y*recipBoxVecY.y*0x100000000; - real zscale = GRID_SIZE_Z*recipBoxVecZ.z*0x100000000; + __shared__ real fracToCart[3][3]; + if (threadIdx.x == 0) { + fracToCart[0][0] = GRID_SIZE_X*recipBoxVecX.x; + fracToCart[1][0] = GRID_SIZE_X*recipBoxVecY.x; + fracToCart[2][0] = GRID_SIZE_X*recipBoxVecZ.x; + fracToCart[0][1] = GRID_SIZE_Y*recipBoxVecX.y; + fracToCart[1][1] = GRID_SIZE_Y*recipBoxVecY.y; + fracToCart[2][1] = GRID_SIZE_Y*recipBoxVecZ.y; + fracToCart[0][2] = GRID_SIZE_Z*recipBoxVecX.z; + fracToCart[1][2] = GRID_SIZE_Z*recipBoxVecY.z; + fracToCart[2][2] = GRID_SIZE_Z*recipBoxVecZ.z; + } + __syncthreads(); for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { - inducedField[i] -= (long long) (xscale*phid[10*i+1]); - inducedField[i+PADDED_NUM_ATOMS] -= (long long) (yscale*phid[10*i+2]); - inducedField[i+PADDED_NUM_ATOMS*2] -= (long long) (zscale*phid[10*i+3]); - inducedFieldPolar[i] -= (long long) (xscale*phip[10*i+1]); - inducedFieldPolar[i+PADDED_NUM_ATOMS] -= (long long) (yscale*phip[10*i+2]); - inducedFieldPolar[i+PADDED_NUM_ATOMS*2] -= (long long) (zscale*phip[10*i+3]); + inducedField[i] -= (long long) (0x100000000*(phid[10*i+1]*fracToCart[0][0] + phid[10*i+2]*fracToCart[0][1] + phid[10*i+3]*fracToCart[0][2])); + inducedField[i+PADDED_NUM_ATOMS] -= (long long) (0x100000000*(phid[10*i+1]*fracToCart[1][0] + phid[10*i+2]*fracToCart[1][1] + phid[10*i+3]*fracToCart[1][2])); + inducedField[i+PADDED_NUM_ATOMS*2] -= (long long) (0x100000000*(phid[10*i+1]*fracToCart[2][0] + phid[10*i+2]*fracToCart[2][1] + phid[10*i+3]*fracToCart[2][2])); + inducedFieldPolar[i] -= (long long) (0x100000000*(phip[10*i+1]*fracToCart[0][0] + phip[10*i+2]*fracToCart[0][1] + phip[10*i+3]*fracToCart[0][2])); + inducedFieldPolar[i+PADDED_NUM_ATOMS] -= (long long) (0x100000000*(phip[10*i+1]*fracToCart[1][0] + phip[10*i+2]*fracToCart[1][1] + phip[10*i+3]*fracToCart[1][2])); + inducedFieldPolar[i+PADDED_NUM_ATOMS*2] -= (long long) (0x100000000*(phip[10*i+1]*fracToCart[2][0] + phip[10*i+2]*fracToCart[2][1] + phip[10*i+3]*fracToCart[2][2])); } } -- GitLab From 5b846af6bc70a927266b67457c88341306efe981 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 5 Feb 2015 15:03:49 -0800 Subject: [PATCH 234/338] Finished CUDA implementation of triclinic boxes for AmoebaMultipoleForce --- .../platforms/cuda/src/AmoebaCudaKernels.cpp | 6 +- .../cuda/src/kernels/multipolePme.cu | 32 ++-- .../tests/TestCudaAmoebaMultipoleForce.cpp | 177 ++++++++++++++++++ .../TestReferenceAmoebaMultipoleForce.cpp | 2 +- 4 files changed, 199 insertions(+), 18 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp index 27d55c020..2bcf7e0f3 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp @@ -1551,7 +1551,8 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE); void* pmeFixedPotentialArgs[] = {&pmeGrid->getDevicePointer(), &pmePhi->getDevicePointer(), &field->getDevicePointer(), &fieldPolar ->getDevicePointer(), &cu.getPosq().getDevicePointer(), &labFrameDipoles->getDevicePointer(), - cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; + cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), cu.getPeriodicBoxVecZPointer(), + recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeFixedPotentialKernel, pmeFixedPotentialArgs, cu.getNumAtoms()); void* pmeTransformFixedPotentialArgs[] = {&pmePhi->getDevicePointer(), &pmeCphi->getDevicePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2]}; cu.executeKernel(pmeTransformPotentialKernel, pmeTransformFixedPotentialArgs, cu.getNumAtoms()); @@ -1593,7 +1594,8 @@ double CudaCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool in else cufftExecC2C(fft, (float2*) pmeGrid->getDevicePointer(), (float2*) pmeGrid->getDevicePointer(), CUFFT_INVERSE); void* pmeInducedPotentialArgs[] = {&pmeGrid->getDevicePointer(), &pmePhid->getDevicePointer(), &pmePhip->getDevicePointer(), - &pmePhidp->getDevicePointer(), &cu.getPosq().getDevicePointer(), cu.getPeriodicBoxSizePointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], + &pmePhidp->getDevicePointer(), &cu.getPosq().getDevicePointer(), cu.getPeriodicBoxVecXPointer(), cu.getPeriodicBoxVecYPointer(), + cu.getPeriodicBoxVecZPointer(), recipBoxVectorPointer[0], recipBoxVectorPointer[1], recipBoxVectorPointer[2], &pmeAtomGridIndex->getDevicePointer()}; cu.executeKernel(pmeInducedPotentialKernel, pmeInducedPotentialArgs, cu.getNumAtoms()); diff --git a/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu b/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu index 4af677ceb..253dacac5 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/multipolePme.cu @@ -188,7 +188,7 @@ extern "C" __global__ void transformPotentialToCartesianCoordinates(const real* int i = threadIdx.x/6; int j = threadIdx.x-6*i; b[i][j] = a[index1[i]][index1[j]]*a[index2[i]][index2[j]]; - if (index1[i] != index2[i]) + if (index1[j] != index2[j]) b[i][j] += (i < 3 ? b[i][j] : a[index1[i]][index2[j]]*a[index2[i]][index1[j]]); } __syncthreads(); @@ -446,7 +446,8 @@ extern "C" __global__ void reciprocalConvolution(real2* __restrict__ pmeGrid, co extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict__ pmeGrid, real* __restrict__ phi, long long* __restrict__ fieldBuffers, long long* __restrict__ fieldPolarBuffers, const real4* __restrict__ posq, - const real* __restrict__ labFrameDipole, real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ, int2* __restrict__ pmeAtomGridIndex) { + const real* __restrict__ labFrameDipole, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ, int2* __restrict__ pmeAtomGridIndex) { real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; @@ -471,28 +472,28 @@ extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + pos -= periodicBoxVecZ*floor(pos.z*recipBoxVecZ.z+0.5f); + pos -= periodicBoxVecY*floor(pos.y*recipBoxVecY.z+0.5f); + pos -= periodicBoxVecX*floor(pos.x*recipBoxVecX.z+0.5f); // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); - int ifr = (int) fr; + int ifr = (int) floor(fr); w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid3 = ifr-PME_ORDER+1; computeBSplinePoint(theta3, w, array); @@ -616,7 +617,8 @@ extern "C" __global__ void computeFixedPotentialFromGrid(const real2* __restrict extern "C" __global__ void computeInducedPotentialFromGrid(const real2* __restrict__ pmeGrid, real* __restrict__ phid, real* __restrict__ phip, real* __restrict__ phidp, const real4* __restrict__ posq, - real4 periodicBoxSize, real3 recipBoxVecX, real3 recipBoxVecY, real3 recipBoxVecZ, int2* __restrict__ pmeAtomGridIndex) { + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, real3 recipBoxVecX, + real3 recipBoxVecY, real3 recipBoxVecZ, int2* __restrict__ pmeAtomGridIndex) { real array[PME_ORDER*PME_ORDER]; real4 theta1[PME_ORDER]; real4 theta2[PME_ORDER]; @@ -628,28 +630,28 @@ extern "C" __global__ void computeInducedPotentialFromGrid(const real2* __restri for (int i = blockIdx.x*blockDim.x+threadIdx.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { int m = pmeAtomGridIndex[i].x; real4 pos = posq[m]; - pos.x -= floor(pos.x*recipBoxVecX.x)*periodicBoxSize.x; - pos.y -= floor(pos.y*recipBoxVecY.y)*periodicBoxSize.y; - pos.z -= floor(pos.z*recipBoxVecZ.z)*periodicBoxSize.z; + pos -= periodicBoxVecZ*floor(pos.z*recipBoxVecZ.z+0.5f); + pos -= periodicBoxVecY*floor(pos.y*recipBoxVecY.z+0.5f); + pos -= periodicBoxVecX*floor(pos.x*recipBoxVecX.z+0.5f); // Since we need the full set of thetas, it's faster to compute them here than load them // from global memory. real w = pos.x*recipBoxVecX.x+pos.y*recipBoxVecY.x+pos.z*recipBoxVecZ.x; real fr = GRID_SIZE_X*(w-(int)(w+0.5f)+0.5f); - int ifr = (int) fr; + int ifr = (int) floor(fr); w = fr - ifr; int igrid1 = ifr-PME_ORDER+1; computeBSplinePoint(theta1, w, array); w = pos.y*recipBoxVecY.y+pos.z*recipBoxVecZ.y; fr = GRID_SIZE_Y*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid2 = ifr-PME_ORDER+1; computeBSplinePoint(theta2, w, array); w = pos.z*recipBoxVecZ.z; fr = GRID_SIZE_Z*(w-(int)(w+0.5f)+0.5f); - ifr = (int) fr; + ifr = (int) floor(fr); w = fr - ifr; int igrid3 = ifr-PME_ORDER+1; computeBSplinePoint(theta3, w, array); diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp index b015d62af..9273189d9 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp @@ -2963,6 +2963,179 @@ static void testNoQuadrupoles(bool usePme) { ASSERT(threwException); } +void testTriclinic() { + // Create a triclinic box containing eight water molecules. + + System system; + system.setDefaultPeriodicBoxVectors(Vec3(1.8643, 0, 0), Vec3(-0.16248445120445926, 1.8572057756524414, 0), Vec3(0.16248445120445906, -0.14832299817478897, 1.8512735025730875)); + for (int i = 0; i < 24; i++) + system.addParticle(1.0); + AmoebaMultipoleForce* force = new AmoebaMultipoleForce(); + system.addForce(force); + force->setNonbondedMethod(AmoebaMultipoleForce::PME); + force->setCutoffDistance(0.7); + force->setMutualInducedTargetEpsilon(1e-6); + vector grid(3); + grid[0] = grid[1] = grid[2] = 24; + force->setPmeGridDimensions(grid); + force->setAEwald(5.4459051633620055); + double o_charge = -0.42616, h_charge = 0.21308; + vector o_dipole(3), h_dipole(3), o_quadrupole(9, 0.0), h_quadrupole(9, 0.0); + o_dipole[0] = 0; + o_dipole[1] = 0; + o_dipole[2] = 0.0033078867454609203; + h_dipole[0] = -0.0053536858428776405; + h_dipole[1] = 0; + h_dipole[2] = -0.014378273997907321; + + o_quadrupole[0] = 0.00016405937591036892; + o_quadrupole[4] = -0.00021618201787005826; + o_quadrupole[8] = 5.212264195968935e-05; + h_quadrupole[0] = 0.00011465301060008312; + h_quadrupole[4] = 8.354184196619263e-05; + h_quadrupole[8] = -0.00019819485256627578; + h_quadrupole[2] = h_quadrupole[6] = -6.523731100577879e-05; + + for (int i = 0; i < 8; i++) { + int atom1 = 3*i, atom2 = 3*i+1, atom3 = 3*i+2; + force->addMultipole(o_charge, o_dipole, o_quadrupole, 1, atom2, atom3, -1, 0.39, pow(0.001*0.92, 1.0/6.0), 0.001*0.92); + force->addMultipole(h_charge, h_dipole, h_quadrupole, 0, atom1, atom3, -1, 0.39, pow(0.001*0.539, 1.0/6.0), 0.001*0.539); + force->addMultipole(h_charge, h_dipole, h_quadrupole, 0, atom1, atom2, -1, 0.39, pow(0.001*0.539, 1.0/6.0), 0.001*0.539); + vector coval1_12(2); + coval1_12[0] = atom2; + coval1_12[1] = atom3; + force->setCovalentMap(atom1, AmoebaMultipoleForce::Covalent12, coval1_12); + vector coval2_12(1); + coval2_12[0] = atom1; + force->setCovalentMap(atom2, AmoebaMultipoleForce::Covalent12, coval2_12); + force->setCovalentMap(atom3, AmoebaMultipoleForce::Covalent12, coval2_12); + vector coval2_13(1); + coval2_13[0] = atom3; + force->setCovalentMap(atom2, AmoebaMultipoleForce::Covalent13, coval2_13); + vector coval3_13(1); + coval3_13[0] = atom2; + force->setCovalentMap(atom3, AmoebaMultipoleForce::Covalent13, coval3_13); + vector polar(3); + polar[0] = atom1; + polar[1] = atom2; + polar[2] = atom3; + force->setCovalentMap(atom1, AmoebaMultipoleForce::PolarizationCovalent11, polar); + force->setCovalentMap(atom2, AmoebaMultipoleForce::PolarizationCovalent11, polar); + force->setCovalentMap(atom3, AmoebaMultipoleForce::PolarizationCovalent11, polar); + } + vector positions(24); + positions[0] = Vec3(0.867966, 0.708769, -0.0696862); + positions[1] = Vec3(0.780946, 0.675579, -0.0382259); + positions[2] = Vec3(0.872223, 0.681424, -0.161756); + positions[3] = Vec3(-0.0117313, 0.824445, 0.683762); + positions[4] = Vec3(0.0216892, 0.789544, 0.605003); + positions[5] = Vec3(0.0444268, 0.782601, 0.75302); + positions[6] = Vec3(0.837906, -0.0092611, 0.681463); + positions[7] = Vec3(0.934042, 0.0098069, 0.673406); + positions[8] = Vec3(0.793962, 0.0573676, 0.626984); + positions[9] = Vec3(0.658995, 0.184432, -0.692317); + positions[10] = Vec3(0.588543, 0.240231, -0.671793); + positions[11] = Vec3(0.618153, 0.106275, -0.727368); + positions[12] = Vec3(0.71466, 0.575358, 0.233152); + positions[13] = Vec3(0.636812, 0.612604, 0.286268); + positions[14] = Vec3(0.702502, 0.629465, 0.15182); + positions[15] = Vec3(-0.242658, -0.850419, -0.250483); + positions[16] = Vec3(-0.169206, -0.836825, -0.305829); + positions[17] = Vec3(-0.279321, -0.760247, -0.24031); + positions[18] = Vec3(-0.803838, -0.360559, 0.230369); + positions[19] = Vec3(-0.811375, -0.424813, 0.301849); + positions[20] = Vec3(-0.761939, -0.2863, 0.270962); + positions[21] = Vec3(-0.148063, 0.824409, -0.827221); + positions[22] = Vec3(-0.20902, 0.868798, -0.7677); + positions[23] = Vec3(-0.0700878, 0.882333, -0.832221); + + // Compute the forces and energy. + + LangevinIntegrator integrator(0.0, 0.1, 0.01); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + + // Compare them to values computed by Gromacs. + + double expectedEnergy = 6.8278696; + vector expectedForce(24); + expectedForce[0] = Vec3(-104.755, 14.0833, 34.359); + expectedForce[1] = Vec3(97.324, -1.41419, -142.976); + expectedForce[2] = Vec3(29.3968, -6.31784, -3.8702); + expectedForce[3] = Vec3(39.1915, 66.852, -28.5767); + expectedForce[4] = Vec3(-8.17554, -6.71532, 7.63162); + expectedForce[5] = Vec3(-87.3745, -91.8639, 35.4761); + expectedForce[6] = Vec3(-19.7568, -40.8693, 5.60238); + expectedForce[7] = Vec3(0.840984, 26.878, 10.7822); + expectedForce[8] = Vec3(14.3469, 12.0583, -12.075); + expectedForce[9] = Vec3(13.757, 16.9954, 46.9403); + expectedForce[10] = Vec3(-5.04172, -14.008, -15.3804); + expectedForce[11] = Vec3(-2.1715, 3.7405, -37.2209); + expectedForce[12] = Vec3(-70.2284, -9.10438, -40.1287); + expectedForce[13] = Vec3(4.46014, 3.89949, 4.64842); + expectedForce[14] = Vec3(43.045, -4.79905, 151.879); + expectedForce[15] = Vec3(20.2129, -0.895376, -27.2086); + expectedForce[16] = Vec3(-5.10448, 3.57732, 17.0498); + expectedForce[17] = Vec3(-13.7695, -1.03345, 12.3093); + expectedForce[18] = Vec3(2.94972, 0.338904, -10.9914); + expectedForce[19] = Vec3(0.69036, 1.22591, 4.50198); + expectedForce[20] = Vec3(-4.61495, -2.76981, 3.57732); + expectedForce[21] = Vec3(73.1489, 16.167, -99.5834); + expectedForce[22] = Vec3(-31.8235, 6.11282, -21.125); + expectedForce[23] = Vec3(13.167, 7.42242, 103.102); + for (int i = 0; i < 24; i++) { + ASSERT_EQUAL_VEC(expectedForce[i], state.getForces()[i], 1e-2); + } + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), 1e-2); + + // Make sure that the induced dipoles match values that were computed with the reference platform. + + vector dipole, expectedDipole(24); + expectedDipole[0] = Vec3(0.001139674, 6.100086e-05, -9.047545e-05); + expectedDipole[1] = Vec3(0.001196926, 4.956102e-05, -0.001802801); + expectedDipole[2] = Vec3(0.0004220728, -0.0001239729, -0.0005876792); + expectedDipole[3] = Vec3(-8.251352e-05, -0.0004572975, 0.000231773); + expectedDipole[4] = Vec3(-9.605857e-05, -1.712989e-05, 0.0001950891); + expectedDipole[5] = Vec3(-0.000673353, -0.000748613, 0.0004138051); + expectedDipole[6] = Vec3(0.0001657927, 0.0003224215, -8.527183e-05); + expectedDipole[7] = Vec3(4.321082e-05, 0.0001842417, 0.0001044274); + expectedDipole[8] = Vec3(4.656055e-05, 0.0001173723, -0.000111185); + expectedDipole[9] = Vec3(-0.0001234674, -0.0002114879, -0.0003179444); + expectedDipole[10] = Vec3(3.941253e-05, -0.0001807048, -0.0001442925); + expectedDipole[11] = Vec3(-2.111804e-05, -0.0001092564, -0.0003528088); + expectedDipole[12] = Vec3(0.0006598309, -9.950432e-05, 0.0002676833); + expectedDipole[13] = Vec3(-0.0001790531, 6.770892e-05, 0.0003118193); + expectedDipole[14] = Vec3(4.071723e-05, -7.97693e-05, 0.001696929); + expectedDipole[15] = Vec3(-0.0002070313, 1.716257e-05, 0.0002235802); + expectedDipole[16] = Vec3(-0.0001630692, 6.042542e-05, 0.0002146744); + expectedDipole[17] = Vec3(-0.0001572073, 9.014017e-05, 0.0001155261); + expectedDipole[18] = Vec3(-1.415344e-05, -2.113717e-05, 8.32503e-05); + expectedDipole[19] = Vec3(-5.514418e-06, -1.676616e-05, 5.401816e-05); + expectedDipole[20] = Vec3(-3.962031e-05, -2.67952e-05, 2.322013e-05); + expectedDipole[21] = Vec3(-0.0007098042, -0.0003138399, 0.000827001); + expectedDipole[22] = Vec3(-0.0004787119, 0.0001518272, 2.344478e-05); + expectedDipole[23] = Vec3(-0.0001339792, -1.357387e-05, 0.0008341705); + force->getInducedDipoles(context, dipole); + for (int i = 0; i < 24; i++) { + ASSERT_EQUAL_VEC(expectedDipole[i], dipole[i], 1e-4); + } + + // Make sure that the electrostatic potential matches values that were computed with the reference platform. + + vector points; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + points.push_back(Vec3(0.5*i, 0.5*j, 0.5*k)); + vector potential; + force->getElectrostaticPotential(points, context, potential); + double expectedPotential[] = {15.79581, 11.61804, 7.143405, 15.55374, 20.84724, -117.8448, 10.65319, -23.70798, + 30.26213, -0.008813862, 7.123444, 22.09409, 41.93532, 41.92756, 24.00818, 20.77822, 22.8576, 29.88276, + -16.35481, 44.62139, -64.10894, -64.28645, -26.05954, -1.25711, -54.76624, -6.754965, 10.83449}; + for (int i = 0; i < 27; i++) + ASSERT_EQUAL_TOL(expectedPotential[i], potential[i], 1e-4); +} int main(int argc, char* argv[]) { try { @@ -3014,6 +3187,10 @@ int main(int argc, char* argv[]) { testNoQuadrupoles(false); testNoQuadrupoles(true); + + // triclinic box of water + + testTriclinic(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp index 8d4103daa..90b720e53 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp @@ -2805,7 +2805,7 @@ static void testMultipoleGridPotential( FILE* log ) { } void testTriclinic() { - // Create a triclinic box containing eight particles. + // Create a triclinic box containing eight water molecules. System system; system.setDefaultPeriodicBoxVectors(Vec3(1.8643, 0, 0), Vec3(-0.16248445120445926, 1.8572057756524414, 0), Vec3(0.16248445120445906, -0.14832299817478897, 1.8512735025730875)); -- GitLab From 050e1262842e1d827326b96f9175acc55531d149 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Thu, 5 Feb 2015 17:10:27 -0800 Subject: [PATCH 235/338] Bug fixes to triclinic boxes --- platforms/cuda/src/CudaContext.cpp | 25 ++++++++++------- platforms/cuda/src/CudaKernels.cpp | 9 +++--- .../cuda/tests/TestCudaNonbondedForce.cpp | 28 +++++++++++++++++++ platforms/opencl/src/OpenCLContext.cpp | 25 ++++++++++------- platforms/opencl/src/OpenCLKernels.cpp | 9 +++--- .../opencl/tests/TestOpenCLNonbondedForce.cpp | 28 +++++++++++++++++++ 6 files changed, 96 insertions(+), 28 deletions(-) diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 569e9ee1b..8cb097c33 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -1138,16 +1138,21 @@ void CudaContext::reorderAtomsImpl() { // Move each molecule position into the same box. for (int i = 0; i < numMolecules; i++) { - int xcell = (int) floor(molPos[i].x*invPeriodicBoxSize.x); - int ycell = (int) floor(molPos[i].y*invPeriodicBoxSize.y); - int zcell = (int) floor(molPos[i].z*invPeriodicBoxSize.z); - Real dx = xcell*periodicBoxSize.x; - Real dy = ycell*periodicBoxSize.y; - Real dz = zcell*periodicBoxSize.z; - if (dx != 0.0f || dy != 0.0f || dz != 0.0f) { - molPos[i].x -= dx; - molPos[i].y -= dy; - molPos[i].z -= dz; + Real4 center = molPos[i]; + int zcell = (int) floor(center.z*invPeriodicBoxSize.z); + center.x -= zcell*periodicBoxVecZ.x; + center.y -= zcell*periodicBoxVecZ.y; + center.z -= zcell*periodicBoxVecZ.z; + int ycell = (int) floor(center.y*invPeriodicBoxSize.y); + center.x -= ycell*periodicBoxVecY.x; + center.y -= ycell*periodicBoxVecY.y; + int xcell = (int) floor(center.x*invPeriodicBoxSize.x); + center.x -= xcell*periodicBoxVecX.x; + if (xcell != 0 || ycell != 0 || zcell != 0) { + Real dx = molPos[i].x-center.x; + Real dy = molPos[i].y-center.y; + Real dz = molPos[i].z-center.z; + molPos[i] = center; for (int j = 0; j < (int) atoms.size(); j++) { int atom = atoms[j]+mol.offsets[i]; Real4 p = oldPosq[atom]; diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 1805bc9c7..2b341203a 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -147,14 +147,15 @@ void CudaUpdateStateDataKernel::getPositions(ContextImpl& context, vector& const vector& order = cu.getAtomIndex(); int numParticles = context.getSystem().getNumParticles(); positions.resize(numParticles); - double4 periodicBoxSize = cu.getPeriodicBoxSize(); + Vec3 boxVectors[3]; + cu.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); if (cu.getUseDoublePrecision()) { double4* posq = (double4*) cu.getPinnedBuffer(); cu.getPosq().download(posq); for (int i = 0; i < numParticles; ++i) { double4 pos = posq[i]; int4 offset = cu.getPosCellOffsets()[i]; - positions[order[i]] = Vec3(pos.x-offset.x*periodicBoxSize.x, pos.y-offset.y*periodicBoxSize.y, pos.z-offset.z*periodicBoxSize.z); + positions[order[i]] = Vec3(pos.x, pos.y, pos.z)-boxVectors[0]*offset.x-boxVectors[1]*offset.y-boxVectors[2]*offset.z; } } else if (cu.getUseMixedPrecision()) { @@ -166,7 +167,7 @@ void CudaUpdateStateDataKernel::getPositions(ContextImpl& context, vector& float4 pos1 = posq[i]; float4 pos2 = posCorrection[i]; int4 offset = cu.getPosCellOffsets()[i]; - positions[order[i]] = Vec3((double)pos1.x+(double)pos2.x-offset.x*periodicBoxSize.x, (double)pos1.y+(double)pos2.y-offset.y*periodicBoxSize.y, (double)pos1.z+(double)pos2.z-offset.z*periodicBoxSize.z); + positions[order[i]] = Vec3((double)pos1.x+(double)pos2.x, (double)pos1.y+(double)pos2.y, (double)pos1.z+(double)pos2.z)-boxVectors[0]*offset.x-boxVectors[1]*offset.y-boxVectors[2]*offset.z; } } else { @@ -175,7 +176,7 @@ void CudaUpdateStateDataKernel::getPositions(ContextImpl& context, vector& for (int i = 0; i < numParticles; ++i) { float4 pos = posq[i]; int4 offset = cu.getPosCellOffsets()[i]; - positions[order[i]] = Vec3(pos.x-offset.x*periodicBoxSize.x, pos.y-offset.y*periodicBoxSize.y, pos.z-offset.z*periodicBoxSize.z); + positions[order[i]] = Vec3(pos.x, pos.y, pos.z)-boxVectors[0]*offset.x-boxVectors[1]*offset.y-boxVectors[2]*offset.z; } } } diff --git a/platforms/cuda/tests/TestCudaNonbondedForce.cpp b/platforms/cuda/tests/TestCudaNonbondedForce.cpp index 2164e672c..602d51ed2 100644 --- a/platforms/cuda/tests/TestCudaNonbondedForce.cpp +++ b/platforms/cuda/tests/TestCudaNonbondedForce.cpp @@ -923,6 +923,33 @@ void testSwitchingFunction(NonbondedForce::NonbondedMethod method) { } } +void testReordering() { + // Check that reordering of atoms doesn't alter their positions. + + const int numParticles = 200; + System system; + system.setDefaultPeriodicBoxVectors(Vec3(6, 0, 0), Vec3(2.1, 6, 0), Vec3(-1.5, -0.5, 6)); + NonbondedForce *nonbonded = new NonbondedForce(); + nonbonded->setNonbondedMethod(NonbondedForce::PME); + system.addForce(nonbonded); + vector positions; + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int i = 0; i < numParticles; i++) { + system.addParticle(1.0); + nonbonded->addParticle(0.0, 0.0, 0.0); + positions.push_back(Vec3(genrand_real2(sfmt)-0.5, genrand_real2(sfmt)-0.5, genrand_real2(sfmt)-0.5)*20); + } + VerletIntegrator integrator(0.001); + Context context(system, integrator, platform); + context.setPositions(positions); + integrator.step(1); + State state = context.getState(State::Positions | State::Velocities); + for (int i = 0; i < numParticles; i++) { + ASSERT_EQUAL_VEC(positions[i], state.getPositions()[i], 1e-6); + } +} + int main(int argc, char* argv[]) { try { if (argc > 1) @@ -944,6 +971,7 @@ int main(int argc, char* argv[]) { testParallelComputation(NonbondedForce::PME); testSwitchingFunction(NonbondedForce::CutoffNonPeriodic); testSwitchingFunction(NonbondedForce::PME); + testReordering(); } catch(const exception& e) { cout << "exception: " << e.what() << endl; diff --git a/platforms/opencl/src/OpenCLContext.cpp b/platforms/opencl/src/OpenCLContext.cpp index 34616289b..120e651bf 100644 --- a/platforms/opencl/src/OpenCLContext.cpp +++ b/platforms/opencl/src/OpenCLContext.cpp @@ -1087,16 +1087,21 @@ void OpenCLContext::reorderAtomsImpl() { // Move each molecule position into the same box. for (int i = 0; i < numMolecules; i++) { - int xcell = (int) floor(molPos[i].x*invPeriodicBoxSizeDouble.x); - int ycell = (int) floor(molPos[i].y*invPeriodicBoxSizeDouble.y); - int zcell = (int) floor(molPos[i].z*invPeriodicBoxSizeDouble.z); - Real dx = xcell*periodicBoxSizeDouble.x; - Real dy = ycell*periodicBoxSizeDouble.y; - Real dz = zcell*periodicBoxSizeDouble.z; - if (dx != 0.0f || dy != 0.0f || dz != 0.0f) { - molPos[i].x -= dx; - molPos[i].y -= dy; - molPos[i].z -= dz; + Real4 center = molPos[i]; + int zcell = (int) floor(center.z*invPeriodicBoxSize.z); + center.x -= zcell*periodicBoxVecZ.x; + center.y -= zcell*periodicBoxVecZ.y; + center.z -= zcell*periodicBoxVecZ.z; + int ycell = (int) floor(center.y*invPeriodicBoxSize.y); + center.x -= ycell*periodicBoxVecY.x; + center.y -= ycell*periodicBoxVecY.y; + int xcell = (int) floor(center.x*invPeriodicBoxSize.x); + center.x -= xcell*periodicBoxVecX.x; + if (xcell != 0 || ycell != 0 || zcell != 0) { + Real dx = molPos[i].x-center.x; + Real dy = molPos[i].y-center.y; + Real dz = molPos[i].z-center.z; + molPos[i] = center; for (int j = 0; j < (int) atoms.size(); j++) { int atom = atoms[j]+mol.offsets[i]; Real4 p = oldPosq[atom]; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 986fa59b2..f460c5dac 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -170,14 +170,15 @@ void OpenCLUpdateStateDataKernel::getPositions(ContextImpl& context, vector& order = cl.getAtomIndex(); int numParticles = context.getSystem().getNumParticles(); positions.resize(numParticles); - mm_double4 periodicBoxSize = cl.getPeriodicBoxSizeDouble(); + Vec3 boxVectors[3]; + cl.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]); if (cl.getUseDoublePrecision()) { mm_double4* posq = (mm_double4*) cl.getPinnedBuffer(); cl.getPosq().download(posq); for (int i = 0; i < numParticles; ++i) { mm_double4 pos = posq[i]; mm_int4 offset = cl.getPosCellOffsets()[i]; - positions[order[i]] = Vec3(pos.x-offset.x*periodicBoxSize.x, pos.y-offset.y*periodicBoxSize.y, pos.z-offset.z*periodicBoxSize.z); + positions[order[i]] = Vec3(pos.x, pos.y, pos.z)-boxVectors[0]*offset.x-boxVectors[1]*offset.y-boxVectors[2]*offset.z; } } else if (cl.getUseMixedPrecision()) { @@ -189,7 +190,7 @@ void OpenCLUpdateStateDataKernel::getPositions(ContextImpl& context, vectorsetNonbondedMethod(NonbondedForce::PME); + system.addForce(nonbonded); + vector positions; + OpenMM_SFMT::SFMT sfmt; + init_gen_rand(0, sfmt); + for (int i = 0; i < numParticles; i++) { + system.addParticle(1.0); + nonbonded->addParticle(0.0, 0.0, 0.0); + positions.push_back(Vec3(genrand_real2(sfmt)-0.5, genrand_real2(sfmt)-0.5, genrand_real2(sfmt)-0.5)*20); + } + VerletIntegrator integrator(0.001); + Context context(system, integrator, platform); + context.setPositions(positions); + integrator.step(1); + State state = context.getState(State::Positions | State::Velocities); + for (int i = 0; i < numParticles; i++) { + ASSERT_EQUAL_VEC(positions[i], state.getPositions()[i], 1e-6); + } +} + int main(int argc, char* argv[]) { try { if (argc > 1) @@ -947,6 +974,7 @@ int main(int argc, char* argv[]) { testParallelComputation(NonbondedForce::PME); testSwitchingFunction(NonbondedForce::CutoffNonPeriodic); testSwitchingFunction(NonbondedForce::PME); + testReordering(); } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From de927414d86f7774e49e8ce47b29365d8d644c0b Mon Sep 17 00:00:00 2001 From: Christopher Dembia Date: Fri, 6 Feb 2015 15:43:48 -0800 Subject: [PATCH 236/338] Fixes vs2013 warnings 4251, 4267. The pragma to ignore 4251 already existed in windowsIncludes.h, and it works when compiling lepton itself. However, when clients use lepton, they get this warning. I think this is why @sherm1 put the define as shown here: https://github.com/simbody/simbody/blob/master/SimTKcommon/include/SimTKcommon/internal/common.h#L168 (whether or not the shared library is being built or used). --- libraries/lepton/include/lepton/windowsIncludes.h | 8 ++++---- libraries/lepton/src/CompiledExpression.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/lepton/include/lepton/windowsIncludes.h b/libraries/lepton/include/lepton/windowsIncludes.h index 3fc5ba09e..798229850 100644 --- a/libraries/lepton/include/lepton/windowsIncludes.h +++ b/libraries/lepton/include/lepton/windowsIncludes.h @@ -25,14 +25,14 @@ #ifdef _MSC_VER // We don't want to hear about how sprintf is "unsafe". #pragma warning(disable:4996) + // Keep MS VC++ quiet about lack of dll export of private members. + #pragma warning(disable:4251) #if defined(LEPTON_BUILDING_SHARED_LIBRARY) #define LEPTON_EXPORT __declspec(dllexport) - // Keep MS VC++ quiet about lack of dll export of private members. - #pragma warning(disable:4251) #elif defined(LEPTON_BUILDING_STATIC_LIBRARY) || defined(LEPTON_USE_STATIC_LIBRARIES) - #define LEPTON_EXPORT + #define LEPTON_EXPORT #else - #define LEPTON_EXPORT __declspec(dllimport) // i.e., a client of a shared library + #define LEPTON_EXPORT __declspec(dllimport) // i.e., a client of a shared library #endif #else #define LEPTON_EXPORT // Linux, Mac diff --git a/libraries/lepton/src/CompiledExpression.cpp b/libraries/lepton/src/CompiledExpression.cpp index bce301050..b2eaf0cb4 100644 --- a/libraries/lepton/src/CompiledExpression.cpp +++ b/libraries/lepton/src/CompiledExpression.cpp @@ -121,7 +121,7 @@ void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vecto arguments[stepIndex] = args; } } - temps.push_back(make_pair(node, workspace.size())); + temps.push_back(make_pair(node, (int) workspace.size())); workspace.push_back(0.0); } @@ -368,4 +368,4 @@ void CompiledExpression::generateSingleArgCall(X86Compiler& c, X86XmmVar& dest, call->setArg(0, arg); call->setRet(0, dest); } -#endif \ No newline at end of file +#endif -- GitLab From 4e62a24fcf572f45a01d156824be384aefa69e80 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Fri, 6 Feb 2015 16:41:04 -0800 Subject: [PATCH 237/338] Adding triclinic box support to Python layer --- wrappers/python/CMakeLists.txt | 1 + .../python/simtk/openmm/app/forcefield.py | 8 ++-- .../python/simtk/openmm/app/gromacsgrofile.py | 29 ++++++++++-- .../simtk/openmm/app/internal/pdbstructure.py | 36 ++++++++++++--- wrappers/python/simtk/openmm/app/modeller.py | 12 ++--- wrappers/python/simtk/openmm/app/pdbfile.py | 2 +- wrappers/python/simtk/openmm/app/pdbxfile.py | 19 +++++++- wrappers/python/simtk/openmm/app/topology.py | 46 ++++++++++++++++--- wrappers/python/tests/TestForceField.py | 14 +++++- wrappers/python/tests/TestGromacsGroFile.py | 42 +++++++++++++++++ wrappers/python/tests/systems/triclinic.gro | 11 +++++ 11 files changed, 191 insertions(+), 29 deletions(-) create mode 100644 wrappers/python/tests/TestGromacsGroFile.py create mode 100644 wrappers/python/tests/systems/triclinic.gro diff --git a/wrappers/python/CMakeLists.txt b/wrappers/python/CMakeLists.txt index 6169ec33c..ecf37c5b5 100644 --- a/wrappers/python/CMakeLists.txt +++ b/wrappers/python/CMakeLists.txt @@ -58,6 +58,7 @@ foreach(SUBDIR ${SUBDIRS}) "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.prm" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.inpcrd" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.crd" + "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.gro" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.parm7" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.rst7" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.ncrst" diff --git a/wrappers/python/simtk/openmm/app/forcefield.py b/wrappers/python/simtk/openmm/app/forcefield.py index fc9dd7430..8762a7b11 100644 --- a/wrappers/python/simtk/openmm/app/forcefield.py +++ b/wrappers/python/simtk/openmm/app/forcefield.py @@ -6,7 +6,7 @@ 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) 2012-2014 Stanford University and the Authors. +Portions copyright (c) 2012-2015 Stanford University and the Authors. Authors: Peter Eastman, Mark Friedrichs Contributors: @@ -403,9 +403,9 @@ class ForceField(object): # Set periodic boundary conditions. - boxSize = topology.getUnitCellDimensions() - if boxSize is not None: - sys.setDefaultPeriodicBoxVectors((boxSize[0], 0, 0), (0, boxSize[1], 0), (0, 0, boxSize[2])) + boxVectors = topology.getPeriodicBoxVectors() + if boxVectors is not None: + sys.setDefaultPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]) elif nonbondedMethod is not NoCutoff and nonbondedMethod is not CutoffNonPeriodic: raise ValueError('Requested periodic boundary conditions for a Topology that does not specify periodic box dimensions') diff --git a/wrappers/python/simtk/openmm/app/gromacsgrofile.py b/wrappers/python/simtk/openmm/app/gromacsgrofile.py index 268fdcf9d..b79173c1f 100644 --- a/wrappers/python/simtk/openmm/app/gromacsgrofile.py +++ b/wrappers/python/simtk/openmm/app/gromacsgrofile.py @@ -89,6 +89,18 @@ def _is_gro_box(line): else: return 0 +def _construct_box_vectors(line): + """Create the periodic box vectors based on the values stored in the file. + + @param[in] line The line containing the description + """ + + sline = line.split() + values = [float(i) for i in sline] + if len(sline) == 3: + return (Vec3(values[0], 0, 0), Vec3(0, values[1], 0), Vec3(0, 0, values[2]))*nanometers + return (Vec3(values[0], values[3], values[4]), Vec3(values[5], values[1], values[6]), Vec3(values[7], values[8], values[2]))*nanometers + class GromacsGroFile(object): """GromacsGroFile parses a Gromacs .gro file and constructs a set of atom positions from it. @@ -140,7 +152,7 @@ class GromacsGroFile(object): xyz.append(Vec3(pos[0], pos[1], pos[2])) elif _is_gro_box(line) and ln == na + 2: sline = line.split() - boxes.append(tuple([float(i) for i in sline])*nanometers) + boxes.append(_construct_box_vectors(line)) xyzs.append(xyz*nanometers) xyz = [] ln = -1 @@ -160,7 +172,7 @@ class GromacsGroFile(object): ## A list containing the name of the residue that each atom belongs to self.residueNames = resname self._positions = xyzs - self._unitCellDimensions = boxes + self._periodicBoxVectors = boxes self._numpyPositions = None def getNumFrames(self): @@ -182,10 +194,21 @@ class GromacsGroFile(object): return self._numpyPositions[frame] return self._positions[frame] + def getPeriodicBoxVectors(self, frame=0): + """Get the vectors defining the periodic box. + + Parameters: + - frame (int=0) the index of the frame for which to get the box vectors + """ + return self._periodicBoxVectors[frame] + def getUnitCellDimensions(self, frame=0): """Get the dimensions of the crystallographic unit cell. Parameters: - frame (int=0) the index of the frame for which to get the unit cell dimensions """ - return self._unitCellDimensions[frame] + xsize = self._periodicBoxVectors[frame][0][0].value_in_unit(nanometers) + ysize = self._periodicBoxVectors[frame][1][1].value_in_unit(nanometers) + zsize = self._periodicBoxVectors[frame][2][2].value_in_unit(nanometers) + return Vec3(xsize, ysize, zsize)*nanometers diff --git a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py index 55062992f..5baed4fd1 100644 --- a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py +++ b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py @@ -39,6 +39,7 @@ import simtk.unit as unit from .. import element import warnings import sys +import math class PdbStructure(object): """ @@ -137,7 +138,7 @@ class PdbStructure(object): self._current_model = None self.default_model = None self.models_by_number = {} - self._unit_cell_dimensions = None + self._periodic_box_vectors = None self.sequences = [] self.modified_residues = [] # read file @@ -170,7 +171,7 @@ class PdbStructure(object): self._current_model._current_chain._add_ter_record() self._reset_residue_numbers() elif (pdb_line.find("CRYST1") == 0): - self._unit_cell_dimensions = Vec3(float(pdb_line[6:15]), float(pdb_line[15:24]), float(pdb_line[24:33]))*unit.angstroms + self._compute_periodic_box_vectors(pdb_line) elif (pdb_line.find("CONECT") == 0): atoms = [int(pdb_line[6:11])] for pos in (11,16,21,26): @@ -187,7 +188,30 @@ class PdbStructure(object): elif (pdb_line.find("MODRES") == 0): self.modified_residues.append(ModifiedResidue(pdb_line[16], int(pdb_line[18:22]), pdb_line[12:15].strip(), pdb_line[24:27].strip())) self._finalize() - + + def _compute_periodic_box_vectors(self, line): + """Parse a CRYST1 record to compute the periodic box vectors.""" + a_length = float(line[6:15]) + b_length = float(line[15:24]) + c_length = float(line[24:33]) + alpha = float(line[33:40])*math.pi/180.0 + beta = float(line[40:47])*math.pi/180.0 + gamma = float(line[47:54])*math.pi/180.0 + a = [a_length, 0, 0] + b = [b_length*math.cos(gamma), b_length*math.sin(gamma), 0] + cx = c_length*math.cos(beta) + cy = c_length*(math.cos(alpha)-math.cos(beta)*math.cos(gamma)) + cz = math.sqrt(c_length*c_length-cx*cx-cy*cy) + c = [cx, cy, cz] + for i in range(3): + if abs(a[i]) < 1e-6: + a[i] = 0.0 + if abs(b[i]) < 1e-6: + b[i] = 0.0 + if abs(c[i]) < 1e-6: + c[i] = 0.0 + self._periodic_box_vectors = (Vec3(*a), Vec3(*b), Vec3(*c))*unit.angstroms + def _reset_atom_numbers(self): self._atom_numbers_are_hex = False self._next_atom_number = 1 @@ -283,9 +307,9 @@ class PdbStructure(object): for model in self.models: model._finalize() - def get_unit_cell_dimensions(self): - """Get the dimensions of the crystallographic unit cell (may be None).""" - return self._unit_cell_dimensions + def get_periodic_box_vectors(self): + """Get the vectors defining the crystallographic unit cell (may be None).""" + return self._periodic_box_vectors class Sequence(object): diff --git a/wrappers/python/simtk/openmm/app/modeller.py b/wrappers/python/simtk/openmm/app/modeller.py index c59324d7c..1090172ab 100644 --- a/wrappers/python/simtk/openmm/app/modeller.py +++ b/wrappers/python/simtk/openmm/app/modeller.py @@ -94,7 +94,7 @@ class Modeller(object): # Copy over the existing model. newTopology = Topology() - newTopology.setUnitCellDimensions(deepcopy(self.topology.getUnitCellDimensions())) + newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): @@ -140,7 +140,7 @@ class Modeller(object): - toDelete (list) a list of Atoms, Residues, Chains, and bonds (specified as tuples of Atoms) to delete """ newTopology = Topology() - newTopology.setUnitCellDimensions(deepcopy(self.topology.getUnitCellDimensions())) + newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) newAtoms = {} newPositions = []*nanometer deleteSet = set(toDelete) @@ -189,7 +189,7 @@ class Modeller(object): else: raise ValueError('Unknown water model: %s' % model) newTopology = Topology() - newTopology.setUnitCellDimensions(deepcopy(self.topology.getUnitCellDimensions())) + newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): @@ -472,7 +472,7 @@ class Modeller(object): for atom2 in molAtoms: if atom2.element == elem.hydrogen: newTopology.addBond(atom1, atom2) - newTopology.setUnitCellDimensions(deepcopy(box)*nanometer) + newTopology.setUnitCellDimensions(box*nanometer) self.topology = newTopology self.positions = newPositions @@ -610,7 +610,7 @@ class Modeller(object): # Loop over residues. newTopology = Topology() - newTopology.setUnitCellDimensions(deepcopy(self.topology.getUnitCellDimensions())) + newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) newAtoms = {} newPositions = []*nanometer newIndices = [] @@ -883,7 +883,7 @@ class Modeller(object): # Create the new Topology. newTopology = Topology() - newTopology.setUnitCellDimensions(deepcopy(self.topology.getUnitCellDimensions())) + newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): diff --git a/wrappers/python/simtk/openmm/app/pdbfile.py b/wrappers/python/simtk/openmm/app/pdbfile.py index 630f84cea..3a84f86c2 100644 --- a/wrappers/python/simtk/openmm/app/pdbfile.py +++ b/wrappers/python/simtk/openmm/app/pdbfile.py @@ -142,7 +142,7 @@ class PDBFile(object): self._positions.append(coords*nanometers) ## The atom positions read from the PDB file. If the file contains multiple frames, these are the positions in the first frame. self.positions = self._positions[0] - self.topology.setUnitCellDimensions(pdb.get_unit_cell_dimensions()) + self.topology.setPeriodicBoxVectors(pdb.get_periodic_box_vectors()) self.topology.createStandardBonds() self.topology.createDisulfideBonds(self.positions) self._numpyPositions = None diff --git a/wrappers/python/simtk/openmm/app/pdbxfile.py b/wrappers/python/simtk/openmm/app/pdbxfile.py index d4de47c9c..ece960e50 100644 --- a/wrappers/python/simtk/openmm/app/pdbxfile.py +++ b/wrappers/python/simtk/openmm/app/pdbxfile.py @@ -33,6 +33,7 @@ __version__ = "1.0" import os import sys +import math from simtk.openmm import Vec3 from simtk.openmm.app.internal.pdbx.reader.PdbxReader import PdbxReader from simtk.openmm.app import Topology @@ -145,8 +146,22 @@ class PDBxFile(object): cell = block.getObj('cell') if cell is not None and cell.getRowCount() > 0: row = cell.getRow(0) - cellSize = [float(row[cell.getAttributeIndex(attribute)]) for attribute in ('length_a', 'length_b', 'length_c')]*angstroms - self.topology.setUnitCellDimensions(cellSize) + (a, b, c) = [float(row[cell.getAttributeIndex(attribute)]) for attribute in ('length_a', 'length_b', 'length_c')] + (alpha, beta, gamma) = [float(row[cell.getAttributeIndex(attribute)]) for attribute in ('angle_alpha', 'angle_beta', 'angle_gamma')*math.pi/180.0] + a = [a_length, 0, 0] + b = [b_length*math.cos(gamma), b_length*math.sin(gamma), 0] + cx = c_length*math.cos(beta) + cy = c_length*(math.cos(alpha)-math.cos(beta)*math.cos(gamma)) + cz = math.sqrt(c_length*c_length-cx*cx-cy*cy) + c = [cx, cy, cz] + for i in range(3): + if abs(a[i]) < 1e-6: + a[i] = 0.0 + if abs(b[i]) < 1e-6: + b[i] = 0.0 + if abs(c[i]) < 1e-6: + c[i] = 0.0 + self.topology.setPeriodicBoxVectors((Vec3(*a), Vec3(*b), Vec3(*c))*unit.angstroms) # Add bonds based on struct_conn records. diff --git a/wrappers/python/simtk/openmm/app/topology.py b/wrappers/python/simtk/openmm/app/topology.py index 5cacbb211..3c5d1e3e2 100644 --- a/wrappers/python/simtk/openmm/app/topology.py +++ b/wrappers/python/simtk/openmm/app/topology.py @@ -6,7 +6,7 @@ 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) 2012-2013 Stanford University and the Authors. +Portions copyright (c) 2012-2015 Stanford University and the Authors. Authors: Peter Eastman Contributors: @@ -33,7 +33,9 @@ __version__ = "1.0" import os import xml.etree.ElementTree as etree -from simtk.unit import nanometers, sqrt +from simtk.openmm.vec3 import Vec3 +from simtk.unit import nanometers, sqrt, is_quantity +from copy import deepcopy class Topology(object): """Topology stores the topological information about a system. @@ -55,7 +57,7 @@ class Topology(object): self._numResidues = 0 self._numAtoms = 0 self._bonds = [] - self._unitCellDimensions = None + self._periodicBoxVectors = None def addChain(self): """Create a new Chain and add it to the Topology. @@ -123,16 +125,48 @@ class Topology(object): """Iterate over all bonds (each represented as a tuple of two Atoms) in the Topology.""" return iter(self._bonds) + def getPeriodicBoxVectors(self): + """Get the vectors defining the periodic box. + + The return value may be None if this Topology does not represent a periodic structure.""" + return self._periodicBoxVectors + + def setPeriodicBoxVectors(self, vectors): + """Set the vectors defining the periodic box.""" + if vectors is not None: + if not is_quantity(vectors[0][0]): + vectors = vectors*nanometers + if vectors[0][1] != 0*nanometers or vectors[0][2] != 0*nanometers: + raise ValueError("First periodic box vector must be parallel to x."); + if vectors[1][2] != 0*nanometers: + raise ValueError("Second periodic box vector must be in the x-y plane."); + if vectors[0][0] <= 0*nanometers or vectors[1][1] <= 0*nanometers or vectors[2][2] <= 0*nanometers or vectors[0][0] < 2*abs(vectors[1][0]) or vectors[0][0] < 2*abs(vectors[2][0]) or vectors[1][1] < 2*abs(vectors[2][1]): + raise ValueError("Periodic box vectors must be in reduced form."); + self._periodicBoxVectors = deepcopy(vectors) + def getUnitCellDimensions(self): """Get the dimensions of the crystallographic unit cell. The return value may be None if this Topology does not represent a periodic structure. """ - return self._unitCellDimensions + if self._periodicBoxVectors is None: + return None + xsize = self._periodicBoxVectors[0][0].value_in_unit(nanometers) + ysize = self._periodicBoxVectors[1][1].value_in_unit(nanometers) + zsize = self._periodicBoxVectors[2][2].value_in_unit(nanometers) + return Vec3(xsize, ysize, zsize)*nanometers def setUnitCellDimensions(self, dimensions): - """Set the dimensions of the crystallographic unit cell.""" - self._unitCellDimensions = dimensions + """Set the dimensions of the crystallographic unit cell. + + This method is an alternative to setPeriodicBoxVectors() for the case of a rectangular box. It sets + the box vectors to be orthogonal to each other and to have the specified lengths.""" + if dimensions is None: + self._periodicBoxVectors = None + else: + if is_quantity(dimensions): + dimensions = dimensions.value_in_unit(nanometers) + self._periodicBoxVectors = (Vec3(dimensions[0], 0, 0), Vec3(0, dimensions[1], 0), Vec3(0, 0, dimensions[2]))*nanometers @staticmethod def loadBondDefinitions(file): diff --git a/wrappers/python/tests/TestForceField.py b/wrappers/python/tests/TestForceField.py index 4aff23096..740462f08 100644 --- a/wrappers/python/tests/TestForceField.py +++ b/wrappers/python/tests/TestForceField.py @@ -20,7 +20,7 @@ class TestForceField(unittest.TestCase): self.topology1 = self.pdb1.topology self.topology1.setUnitCellDimensions(Vec3(2, 2, 2)) - # alalnine dipeptide with implicit water + # alanine dipeptide with implicit water self.pdb2 = PDBFile('systems/alanine-dipeptide-implicit.pdb') self.forcefield2 = ForceField('amber99sb.xml', 'amber99_obc.xml') @@ -186,6 +186,18 @@ class TestForceField(unittest.TestCase): system2 = ff2.createSystem(modeller.topology) self.assertEqual(XmlSerializer.serialize(system1), XmlSerializer.serialize(system2)) + def test_PeriodicBoxVectors(self): + """Test setting the periodic box vectors.""" + + vectors = (Vec3(5, 0, 0), Vec3(-1.5, 4.5, 0), Vec3(0.4, 0.8, 7.5))*nanometers + self.pdb1.topology.setPeriodicBoxVectors(vectors) + self.assertEqual(Vec3(5, 4.5, 7.5)*nanometers, self.pdb1.topology.getUnitCellDimensions()) + system = self.forcefield1.createSystem(self.pdb1.topology) + for i in range(3): + self.assertEqual(vectors[i], self.pdb1.topology.getPeriodicBoxVectors()[i]) + self.assertEqual(vectors[i], system.getDefaultPeriodicBoxVectors()[i]) + + class AmoebaTestForceField(unittest.TestCase): """Test the ForceField.createSystem() method with the AMOEBA forcefield.""" diff --git a/wrappers/python/tests/TestGromacsGroFile.py b/wrappers/python/tests/TestGromacsGroFile.py new file mode 100644 index 000000000..a4a002626 --- /dev/null +++ b/wrappers/python/tests/TestGromacsGroFile.py @@ -0,0 +1,42 @@ +import unittest +from simtk.openmm.app import * +from simtk.openmm import * +from simtk.unit import * +import simtk.openmm.app.element as elem + +class TestGromacsGroFile(unittest.TestCase): + """Test the Gromacs GRO file parser""" + + def test_Triclinic(self): + """Test parsing a file that describes a triclinic box.""" + gro = GromacsGroFile('systems/triclinic.gro') + self.assertEqual(len(gro.positions), 8) + expectedPositions = [ + Vec3(1.744, 2.788, 3.162), + Vec3(1.048, 0.762, 2.340), + Vec3(2.489, 1.570, 2.817), + Vec3(1.027, 1.893, 3.271), + Vec3(0.937, 0.825, 0.009), + Vec3(2.290, 1.887, 3.352), + Vec3(1.266, 1.111, 2.894), + Vec3(0.933, 1.862, 3.490)]*nanometers + for (p1, p2) in zip(expectedPositions, gro.positions): + self.assertEqual(p1, p2) + expectedVectors = [ + Vec3(2.5, 0, 0), + Vec3(0.5, 3.0, 0), + Vec3(0.7, 0.9, 3.5)]*nanometers + for (v1, v2) in zip(expectedVectors, gro.getPeriodicBoxVectors()): + self.assertEqual(v1, v2) + self.assertEqual(Vec3(2.5, 3.0, 3.5)*nanometers, gro.getUnitCellDimensions()) + for i in range(4): + self.assertEqual(elem.chlorine, gro.elements[i]) + self.assertEqual('Cl', gro.atomNames[i]) + self.assertEqual('Cl', gro.residueNames[i]) + for i in range(4, 8): + self.assertEqual(elem.sodium, gro.elements[i]) + self.assertEqual('Na', gro.atomNames[i]) + self.assertEqual('Na', gro.residueNames[i]) + +if __name__ == '__main__': + unittest.main() diff --git a/wrappers/python/tests/systems/triclinic.gro b/wrappers/python/tests/systems/triclinic.gro new file mode 100644 index 000000000..723fe1033 --- /dev/null +++ b/wrappers/python/tests/systems/triclinic.gro @@ -0,0 +1,11 @@ +Triclinic test system + 8 + 1Cl Cl 1 1.744 2.788 3.162 + 2Cl Cl 2 1.048 0.762 2.340 + 3Cl Cl 3 2.489 1.570 2.817 + 4Cl Cl 4 1.027 1.893 3.271 + 5Na Na 5 0.937 0.825 0.009 + 6Na Na 6 2.290 1.887 3.352 + 7Na Na 7 1.266 1.111 2.894 + 8Na Na 8 0.933 1.862 3.490 + 2.50000 3.00000 3.50000 0.00000 0.00000 0.50000 0.00000 0.70000 0.90000 -- GitLab From 94ca75c6d65404cf9239e6c33ecdb22d657af5e9 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 19:51:38 -0500 Subject: [PATCH 238/338] First stab at adjusting AmoebaStretchBendForce to take 2 force constants instead of just 1. Backwards compatibility is provided by making the 2nd force constant default to -1, which is reinterpreted as "copy the first force constant". Updates both the reference and CUDA kernels. --- .../include/openmm/AmoebaStretchBendForce.h | 26 +++++++------ .../openmmapi/src/AmoebaStretchBendForce.cpp | 20 ++++++---- .../platforms/cuda/src/AmoebaCudaKernels.cpp | 37 +++++++++++-------- .../platforms/cuda/src/AmoebaCudaKernels.h | 3 +- .../src/kernels/amoebaStretchBendForce.cu | 18 +++++---- .../reference/src/AmoebaReferenceKernels.cpp | 17 +++++---- .../reference/src/AmoebaReferenceKernels.h | 3 +- .../AmoebaReferenceStretchBendForce.cpp | 12 +++--- .../src/AmoebaStretchBendForceProxy.cpp | 8 ++-- .../TestSerializeAmoebaStretchBendForce.cpp | 9 +++-- 10 files changed, 90 insertions(+), 63 deletions(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index ad26d045d..bc747e035 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -71,11 +71,12 @@ public: * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm * @param angle the equilibrium angle in radians - * @param k the force constant for the stretch-bend + * @param k1 the force constant of the product of bond ab and angle a-b-c + * @param k2 the force constant of the product of bond bc and angle a-b-c (optional, default is the same as k1) * @return the index of the stretch-bend that was added */ int addStretchBend(int particle1, int particle2, int particle3, double lengthAB, double lengthCB, double angle, - double k ); + double k1, double k2=-1.0); /** * Get the force field parameters for a stretch-bend term. @@ -87,10 +88,11 @@ public: * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm * @param angle the equilibrium angle in radians - * @param k the force constant for the stretch-bend + * @param k1 the force constant of the product of bond ab and angle a-b-c + * @param k2 the force constant of the product of bond bc and angle a-b-c */ - void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, - double& lengthAB, double& lengthCB, double& angle, double& k ) const; + void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB, + double& lengthCB, double& angle, double& k1, double& k2) const; /** * Set the force field parameters for a stretch-bend term. @@ -102,10 +104,11 @@ public: * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm * @param angle the equilibrium angle in radians - * @param k the force constant for the stretch-bend + * @param k1 the force constant of the product of bond ab and angle a-b-c + * @param k2 the force constant of the product of bond bc and angle a-b-c (optional, default is the same as k1) */ void setStretchBendParameters(int index, int particle1, int particle2, int particle3, - double lengthAB, double lengthCB, double angle, double k ); + double lengthAB, double lengthCB, double angle, double k1, double k2=-1.0 ); /** * Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. @@ -139,16 +142,15 @@ private: class AmoebaStretchBendForce::StretchBendInfo { public: int particle1, particle2, particle3; - double lengthAB, lengthCB, angle, k; + double lengthAB, lengthCB, angle, k1, k2; StretchBendInfo() { particle1 = particle2 = particle3 = -1; - lengthAB = lengthCB = angle = k = 0.0; + lengthAB = lengthCB = angle = k1 = k2 = 0.0; } StretchBendInfo(int particle1, int particle2, int particle3, - double lengthAB, double lengthCB, double angle, double k ) : + double lengthAB, double lengthCB, double angle, double k1, double k2 ) : particle1(particle1), particle2(particle2), particle3(particle3), - lengthAB(lengthAB), lengthCB(lengthCB), angle(angle), k(k) { - + lengthAB(lengthAB), lengthCB(lengthCB), angle(angle), k1(k1), k2(k2) { } }; diff --git a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp index 4efc237da..adea684c4 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp @@ -40,31 +40,37 @@ AmoebaStretchBendForce::AmoebaStretchBendForce() { } int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int particle3, - double lengthAB, double lengthCB, double angle, double k) { - stretchBends.push_back(StretchBendInfo(particle1, particle2, particle3, lengthAB, lengthCB, angle, k)); + double lengthAB, double lengthCB, double angle, double k1, double k2) { + if (k2 == -1.0) k2 = k1 + stretchBends.push_back(StretchBendInfo(particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2)); return stretchBends.size()-1; } void AmoebaStretchBendForce::getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, - double& lengthAB, double& lengthCB, double& angle, double& k ) const { + double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2 ) const { particle1 = stretchBends[index].particle1; particle2 = stretchBends[index].particle2; particle3 = stretchBends[index].particle3; lengthAB = stretchBends[index].lengthAB; lengthCB = stretchBends[index].lengthCB; angle = stretchBends[index].angle; - k = stretchBends[index].k; + k1 = stretchBends[index].k1; + k2 = stretchBends[index].k2; } -void AmoebaStretchBendForce::setStretchBendParameters(int index, int particle1, int particle2, int particle3, - double lengthAB, double lengthCB, double angle, double k) { +void AmoebaStretchBendForce::setStretchBendParameters(int index, int particle1, int particle2, int particle3, + double lengthAB, double lengthCB, double angle, double k1, double k2) { stretchBends[index].particle1 = particle1; stretchBends[index].particle2 = particle2; stretchBends[index].particle3 = particle3; stretchBends[index].lengthAB = lengthAB; stretchBends[index].lengthCB = lengthCB; stretchBends[index].angle = angle; - stretchBends[index].k = k; + stretchBends[index].k1 = k1; + if (k2 == -1.0) + stretchBends[index].k2 = k1; + else + stretchBends[index].k2 = k2; } ForceImpl* AmoebaStretchBendForce::createImpl() const { diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp index 2bcf7e0f3..bd19bdf0b 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp @@ -464,8 +464,8 @@ public: } void getParticlesInGroup(int index, std::vector& particles) { int particle1, particle2, particle3; - double lengthAB, lengthCB, angle, k; - force.getStretchBendParameters(index, particle1, particle2, particle3, lengthAB, lengthCB, angle, k); + double lengthAB, lengthCB, angle, k1, k2; + force.getStretchBendParameters(index, particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2); particles.resize(3); particles[0] = particle1; particles[1] = particle2; @@ -473,10 +473,10 @@ public: } bool areGroupsIdentical(int group1, int group2) { int particle1, particle2, particle3; - double lengthAB1, lengthAB2, lengthCB1, lengthCB2, angle1, angle2, k1, k2; - force.getStretchBendParameters(group1, particle1, particle2, particle3, lengthAB1, lengthCB1, angle1, k1); - force.getStretchBendParameters(group2, particle1, particle2, particle3, lengthAB2, lengthCB2, angle2, k2); - return (lengthAB1 == lengthAB2 && lengthCB1 == lengthCB2 && angle1 == angle2 && k1 == k2); + double lengthAB1, lengthAB2, lengthCB1, lengthCB2, angle1, angle2, k11, k12, k21, k22; + force.getStretchBendParameters(group1, particle1, particle2, particle3, lengthAB1, lengthCB1, angle1, k11, k12); + force.getStretchBendParameters(group2, particle1, particle2, particle3, lengthAB2, lengthCB2, angle2, k21, k22); + return (lengthAB1 == lengthAB2 && lengthCB1 == lengthCB2 && angle1 == angle2 && k11 == k21 && k12 == k22); } private: const AmoebaStretchBendForce& force; @@ -488,8 +488,10 @@ CudaCalcAmoebaStretchBendForceKernel::CudaCalcAmoebaStretchBendForceKernel(std:: CudaCalcAmoebaStretchBendForceKernel::~CudaCalcAmoebaStretchBendForceKernel() { cu.setAsCurrent(); - if (params != NULL) - delete params; + if (params1 != NULL) + delete params1; + if (params2 != NULL) + delete params2; } void CudaCalcAmoebaStretchBendForceKernel::initialize(const System& system, const AmoebaStretchBendForce& force) { @@ -501,16 +503,21 @@ void CudaCalcAmoebaStretchBendForceKernel::initialize(const System& system, cons if (numStretchBends == 0) return; vector > atoms(numStretchBends, vector(3)); - params = CudaArray::create(cu, numStretchBends, "stretchBendParams"); - vector paramVector(numStretchBends); + params1 = CudaArray::create(cu, numStretchBends, "stretchBendParams"); + params2 = CudaArray::create(cu, numStretchBends, "stretchBendForceConstants"); + vector paramVector(numStretchBends); + vector paramVectorK(numStretchBends); for (int i = 0; i < numStretchBends; i++) { - double lengthAB, lengthCB, angle, k; - force.getStretchBendParameters(startIndex+i, atoms[i][0], atoms[i][1], atoms[i][2], lengthAB, lengthCB, angle, k); - paramVector[i] = make_float4((float) lengthAB, (float) lengthCB, (float) angle, (float) k); + double lengthAB, lengthCB, angle, k1, k2; + force.getStretchBendParameters(startIndex+i, atoms[i][0], atoms[i][1], atoms[i][2], lengthAB, lengthCB, angle, k1, k2); + paramVector[i] = make_float3((float) lengthAB, (float) lengthCB, (float) angle); + paramVectorK[i] = make_float2((float) k1, (float) k2); } - params->upload(paramVector); + params1->upload(paramVector); + params2->upload(paramVectorK); map replacements; - replacements["PARAMS"] = cu.getBondedUtilities().addArgument(params->getDevicePointer(), "float4"); + replacements["PARAMS"] = cu.getBondedUtilities().addArgument(params1->getDevicePointer(), "float3"); + replacements["FORCE_CONSTANTS"] = cu.getBondedUtilities().addArgument(params2->getDevicePointer(), "float2"); replacements["RAD_TO_DEG"] = cu.doubleToString(180/M_PI); cu.getBondedUtilities().addInteraction(atoms, cu.replaceStrings(CudaAmoebaKernelSources::amoebaStretchBendForce, replacements), force.getForceGroup()); cu.addForce(new ForceInfo(force)); diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h index 8b17fc780..eed60f81a 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h @@ -229,7 +229,8 @@ private: int numStretchBends; CudaContext& cu; const System& system; - CudaArray* params; + CudaArray* params1; // Equilibrium values + CudaArray* params2; // force constants }; /** diff --git a/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu b/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu index ee65e3010..668c5104b 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu @@ -25,7 +25,8 @@ real angle = ACOS(cosine); // find chain rule terms for the bond angle deviation -float4 parameters = PARAMS[index]; +float3 parameters = PARAMS[index]; +float2 force_constants = FORCE_CONSTANTS[index]; real dt = RAD_TO_DEG*(angle - parameters.z); real terma = rab*rp != 0 ? (-RAD_TO_DEG/(rab*rab*rp)) : (real) 0; @@ -41,11 +42,15 @@ real ddtdzic = termc * (xcb*yp-ycb*xp); // find chain rule terms for the bond length deviations -real dr = (parameters.x > 0 ? (rab - parameters.x) : (real) 0); +real dr1 = (parameters.x > 0 ? (rab - parameters.x) : (real) 0); terma = (parameters.x > 0 ? RECIP(rab) : (real) 0); -dr += (parameters.y > 0 ? (rcb - parameters.y) : (real) 0); +real dr2 = (parameters.y > 0 ? (rcb - parameters.y) : (real) 0); termc = (parameters.y > 0 ? RECIP(rcb) : (real) 0); +real frc1 = ((rp != 0) ? force_constants.x : (real) 0); +real frc2 = ((rp != 0) ? force_constants.y : (real) 0); + +real drkk = dr1*frc1 + dr2*frc2; real ddrdxia = terma * xab; real ddrdyia = terma * yab; @@ -57,9 +62,8 @@ real ddrdzic = termc * zcb; // get the energy and master chain rule terms for derivatives -real term = ((rp != 0) ? parameters.w : (real) 0); -energy += term*dt*dr; +energy += dt*drkk; -real3 force1 = make_real3(-term*(dt*ddrdxia+ddtdxia*dr), -term*(dt*ddrdyia+ddtdyia*dr), -term*(dt*ddrdzia+ddtdzia*dr)); -real3 force3 = make_real3(-term*(dt*ddrdxic+ddtdxic*dr), -term*(dt*ddrdyic+ddtdyic*dr), -term*(dt*ddrdzic+ddtdzic*dr)); +real3 force1 = make_real3(-frc1*dt*ddrdxia+ddtdxia*drkk, -frc1*dt*ddrdyia+ddtdyia*drkk, -frc1*dt*ddrdzia+ddtdzia*drkk); +real3 force3 = make_real3(-frc2*dt*ddrdxic+ddtdxic*drkk, -frc2*dt*ddrdyic+ddtdyic*drkk, -frc2*dt*ddrdzic+ddtdzic*drkk); real3 force2 = make_real3(-force1.x-force3.x, -force1.y-force3.y, -force1.z-force3.z); diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp index ec6078616..98fc6fdef 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp @@ -307,15 +307,16 @@ void ReferenceCalcAmoebaStretchBendForceKernel::initialize(const System& system, numStretchBends = force.getNumStretchBends(); for ( int ii = 0; ii < numStretchBends; ii++) { int particle1Index, particle2Index, particle3Index; - double lengthAB, lengthCB, angle, k; - force.getStretchBendParameters(ii, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k); + double lengthAB, lengthCB, angle, k1, k2; + force.getStretchBendParameters(ii, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k1, k2); particle1.push_back( particle1Index ); particle2.push_back( particle2Index ); particle3.push_back( particle3Index ); lengthABParameters.push_back( static_cast(lengthAB) ); lengthCBParameters.push_back( static_cast(lengthCB) ); angleParameters.push_back( static_cast(angle) ); - kParameters.push_back( static_cast(k) ); + k1Parameters.push_back( static_cast(k1) ); + k2Parameters.push_back( static_cast(k2) ); } } @@ -324,7 +325,8 @@ double ReferenceCalcAmoebaStretchBendForceKernel::execute(ContextImpl& context, vector& forceData = extractForces(context); AmoebaReferenceStretchBendForce amoebaReferenceStretchBendForce; RealOpenMM energy = amoebaReferenceStretchBendForce.calculateForceAndEnergy( numStretchBends, posData, particle1, particle2, particle3, - lengthABParameters, lengthCBParameters, angleParameters, kParameters, forceData ); + lengthABParameters, lengthCBParameters, angleParameters, k1Parameters, + k2Parameters, forceData ); return static_cast(energy); } @@ -336,14 +338,15 @@ void ReferenceCalcAmoebaStretchBendForceKernel::copyParametersToContext(ContextI for (int i = 0; i < numStretchBends; ++i) { int particle1Index, particle2Index, particle3Index; - double lengthAB, lengthCB, angle, k; - force.getStretchBendParameters(i, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k); + double lengthAB, lengthCB, angle, k1, k2; + force.getStretchBendParameters(i, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k1, k2); if (particle1Index != particle1[i] || particle2Index != particle2[i] || particle3Index != particle3[i]) throw OpenMMException("updateParametersInContext: The set of particles in a stretch-bend has changed"); lengthABParameters[i] = (RealOpenMM) lengthAB; lengthCBParameters[i] = (RealOpenMM) lengthCB; angleParameters[i] = (RealOpenMM) angle; - kParameters[i] = (RealOpenMM) k; + k1Parameters[i] = (RealOpenMM) k1; + k1Parameters[i] = (RealOpenMM) k2; } } diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h index dd0359e37..19017fd63 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h @@ -248,7 +248,8 @@ private: std::vector lengthABParameters; std::vector lengthCBParameters; std::vector angleParameters; - std::vector kParameters; + std::vector k1Parameters; + std::vector k2Parameters; const System& system; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp index 3be1acaab..4b9055e8b 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp @@ -53,7 +53,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV const RealVec& positionAtomC, RealOpenMM lengthAB, RealOpenMM lengthCB, RealOpenMM idealAngle, RealOpenMM kParameter, - RealVec* forces ) const { + RealOpenMM k2Parameter, RealVec* forces ) const { // --------------------------------------------------------------------------------------- @@ -112,7 +112,9 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV deltaR[CBxP][ii] *= termC; } - RealOpenMM dr = rAB - lengthAB + rCB - lengthCB; + RealOpenMM dr1 = rAB - lengthAB; + RealOpenMM dr2 = rCB - lengthCB; + RealOpenMM drkk = dr1*k1Parameter + dr2*k2Parameter; termA = one/rAB; termC = one/rCB; @@ -129,8 +131,8 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV } RealOpenMM dt = angle - idealAngle*RADIAN; for( int jj = 0; jj < 3; jj++ ){ - subForce[A][jj] = kParameter*(dt*termA*deltaR[AB][jj] + dr*deltaR[ABxP][jj] ); - subForce[C][jj] = kParameter*(dt*termC*deltaR[CB][jj] + dr*deltaR[CBxP][jj] ); + subForce[A][jj] = k1Parameter*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj]; + subForce[C][jj] = k2Parameter*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj]; subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); } @@ -144,7 +146,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV // --------------------------------------------------------------------------------------- - return (kParameter*dt*dr); + return dt*drkk; } RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStretchBends, vector& posData, diff --git a/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp index 6c14ac8f0..5d91bb783 100644 --- a/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp @@ -47,9 +47,9 @@ void AmoebaStretchBendForceProxy::serialize(const void* object, SerializationNod SerializationNode& bonds = node.createChildNode("StretchBendAngles"); for (unsigned int ii = 0; ii < static_cast(force.getNumStretchBends()); ii++) { int particle1, particle2, particle3; - double distanceAB, distanceCB, angle, k; - force.getStretchBendParameters(ii, particle1, particle2, particle3, distanceAB, distanceCB, angle, k); - bonds.createChildNode("StretchBendAngle").setIntProperty("p1", particle1).setIntProperty("p2", particle2).setIntProperty("p3", particle3).setDoubleProperty("dAB", distanceAB).setDoubleProperty("dCB", distanceCB).setDoubleProperty("angle", angle).setDoubleProperty("k", k); + double distanceAB, distanceCB, angle, k1, k2; + force.getStretchBendParameters(ii, particle1, particle2, particle3, distanceAB, distanceCB, angle, k1, k2); + bonds.createChildNode("StretchBendAngle").setIntProperty("p1", particle1).setIntProperty("p2", particle2).setIntProperty("p3", particle3).setDoubleProperty("dAB", distanceAB).setDoubleProperty("dCB", distanceCB).setDoubleProperty("angle", angle).setDoubleProperty("k1", k1).setDoubleProperty("k2", k2); } } @@ -62,7 +62,7 @@ void* AmoebaStretchBendForceProxy::deserialize(const SerializationNode& node) co const SerializationNode& bonds = node.getChildNode("StretchBendAngles"); for ( unsigned int ii = 0; ii < (int) bonds.getChildren().size(); ii++) { const SerializationNode& bond = bonds.getChildren()[ii]; - force->addStretchBend(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getIntProperty("p3"), bond.getDoubleProperty("dAB"), bond.getDoubleProperty("dCB"), bond.getDoubleProperty("angle"), bond.getDoubleProperty("k")); + force->addStretchBend(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getIntProperty("p3"), bond.getDoubleProperty("dAB"), bond.getDoubleProperty("dCB"), bond.getDoubleProperty("angle"), bond.getDoubleProperty("k1"), bond.getDoubleProperty("k2")); } } diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp index f8b0d171d..584a88f89 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp @@ -64,10 +64,10 @@ void testSerialization() { double dAB1, dAB2; double dCB1, dCB2; double angle1, angle2; - double k1, k2; + double k11, k12, k21, k22; - force1.getStretchBendParameters(ii, p11, p12, p13, dAB1, dCB1, angle1, k1); - force2.getStretchBendParameters(ii, p21, p22, p23, dAB2, dCB2, angle2, k2); + force1.getStretchBendParameters(ii, p11, p12, p13, dAB1, dCB1, angle1, k11, k12); + force2.getStretchBendParameters(ii, p21, p22, p23, dAB2, dCB2, angle2, k21, k22); ASSERT_EQUAL(p11, p21); ASSERT_EQUAL(p12, p22); @@ -75,7 +75,8 @@ void testSerialization() { ASSERT_EQUAL(dAB1, dAB2); ASSERT_EQUAL(dCB1, dCB2); ASSERT_EQUAL(angle1, angle2); - ASSERT_EQUAL(k1, k2); + ASSERT_EQUAL(k11, k21); + ASSERT_EQUAL(k12, k22); } } -- GitLab From cf843edbd78e9bbd827b02025a9f8e48dddd6c7d Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 20:05:33 -0500 Subject: [PATCH 239/338] Update return unit call structure for getStretchBendParameters --- wrappers/python/src/swig_doxygen/swigInputConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/src/swig_doxygen/swigInputConfig.py b/wrappers/python/src/swig_doxygen/swigInputConfig.py index b7611881e..38c59693b 100755 --- a/wrappers/python/src/swig_doxygen/swigInputConfig.py +++ b/wrappers/python/src/swig_doxygen/swigInputConfig.py @@ -277,7 +277,7 @@ UNITS = { ("AmoebaPiTorsionForce", "getPiTorsionParameters") : ( None, (None, None, None, None, None, None, 'unit.kilojoule_per_mole')), ("AmoebaStretchBendForce", "getNumStretchBends") : ( None, ()), -("AmoebaStretchBendForce", "getStretchBendParameters") : ( None, (None, None, None, 'unit.nanometer', 'unit.nanometer', 'unit.radian', 'unit.kilojoule_per_mole/unit.nanometer/unit.degree')), +("AmoebaStretchBendForce", "getStretchBendParameters") : ( None, (None, None, None, 'unit.nanometer', 'unit.nanometer', 'unit.radian', 'unit.kilojoule_per_mole/unit.nanometer/unit.degree', 'unit.kilojoule_per_mole/unit.nanometer/unit.degree')), ("AmoebaTorsionTorsionForce", "getNumTorsionTorsions") : ( None, ()), ("AmoebaTorsionTorsionForce", "getNumTorsionTorsionGrids") : ( None, ()), -- GitLab From 99628218eced72ce4ed104f5c08bda91b041906b Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 20:07:32 -0500 Subject: [PATCH 240/338] Add missing ; --- plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp index adea684c4..85176cd20 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp @@ -41,7 +41,7 @@ AmoebaStretchBendForce::AmoebaStretchBendForce() { int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int particle3, double lengthAB, double lengthCB, double angle, double k1, double k2) { - if (k2 == -1.0) k2 = k1 + if (k2 == -1.0) k2 = k1; stretchBends.push_back(StretchBendInfo(particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2)); return stretchBends.size()-1; } -- GitLab From 480c695c091d2a72dd228e1b9d6d9e998a77194b Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 20:17:40 -0500 Subject: [PATCH 241/338] A few fixes. --- .../include/openmm/AmoebaStretchBendForce.h | 18 ++++++++++++++++++ .../platforms/cuda/src/AmoebaCudaKernels.cpp | 15 +++++++++------ .../AmoebaReferenceStretchBendForce.cpp | 10 ++++++---- .../AmoebaReferenceStretchBendForce.h | 3 ++- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index bc747e035..778e345de 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -94,6 +94,24 @@ public: void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2) const; + /** + * Get the force field parameters for a stretch-bend term, provided for + * backwards-compatibility. Since the two force constants may be different, + * you are recommended to call the other version of getStretchBendParameters + * with both a k1 and k2 + * + * @param index the index of the stretch-bend for which to get parameters + * @param particle1 the index of the first particle connected by the stretch-bend + * @param particle2 the index of the second particle connected by the stretch-bend + * @param particle3 the index of the third particle connected by the stretch-bend + * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm + * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm + * @param angle the equilibrium angle in radians + * @param k1 the force constant + */ + void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB, + double& lengthCB, double& angle, double& k1) const; + /** * Set the force field parameters for a stretch-bend term. * diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp index bd19bdf0b..d07025552 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp @@ -483,7 +483,7 @@ private: }; CudaCalcAmoebaStretchBendForceKernel::CudaCalcAmoebaStretchBendForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) : - CalcAmoebaStretchBendForceKernel(name, platform), cu(cu), system(system), params(NULL) { + CalcAmoebaStretchBendForceKernel(name, platform), cu(cu), system(system), params1(NULL), params2(NULL) { } CudaCalcAmoebaStretchBendForceKernel::~CudaCalcAmoebaStretchBendForceKernel() { @@ -539,14 +539,17 @@ void CudaCalcAmoebaStretchBendForceKernel::copyParametersToContext(ContextImpl& // Record the per-stretch-bend parameters. - vector paramVector(numStretchBends); + vector paramVector(numStretchBends); + vector paramVector1(numStretchBends); for (int i = 0; i < numStretchBends; i++) { int atom1, atom2, atom3; - double lengthAB, lengthCB, angle, k; - force.getStretchBendParameters(startIndex+i, atom1, atom2, atom3, lengthAB, lengthCB, angle, k); - paramVector[i] = make_float4((float) lengthAB, (float) lengthCB, (float) angle, (float) k); + double lengthAB, lengthCB, angle, k1, k2; + force.getStretchBendParameters(startIndex+i, atom1, atom2, atom3, lengthAB, lengthCB, angle, k1, k2); + paramVector[i] = make_float3((float) lengthAB, (float) lengthCB, (float) angle); + paramVector1[i] = make_flaot2((float) k1, (float) k2); } - params->upload(paramVector); + params1->upload(paramVector); + params2->upload(paramVector1); // Mark that the current reordering may be invalid. diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp index 4b9055e8b..8df2ec4c4 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp @@ -52,7 +52,7 @@ using OpenMM::RealVec; RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, const RealVec& positionAtomC, RealOpenMM lengthAB, RealOpenMM lengthCB, - RealOpenMM idealAngle, RealOpenMM kParameter, + RealOpenMM idealAngle, RealOpenMM k1Parameter, RealOpenMM k2Parameter, RealVec* forces ) const { // --------------------------------------------------------------------------------------- @@ -156,7 +156,8 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStre const std::vector& lengthABParameters, const std::vector& lengthCBParameters, const std::vector& angle, - const std::vector& kQuadratic, + const std::vector& k1Quadratic, + const std::vector& k2Quadratic, vector& forceData) const { RealOpenMM energy = 0.0; for (unsigned int ii = 0; ii < static_cast(numStretchBends); ii++) { @@ -166,10 +167,11 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStre RealOpenMM abLength = lengthABParameters[ii]; RealOpenMM cbLength = lengthCBParameters[ii]; RealOpenMM idealAngle = angle[ii]; - RealOpenMM angleK = kQuadratic[ii]; + RealOpenMM angleK1 = k1Quadratic[ii]; + RealOpenMM angleK2 = k2Quadratic[ii]; RealVec forces[3]; energy += calculateStretchBendIxn( posData[particle1Index], posData[particle2Index], posData[particle3Index], - abLength, cbLength, idealAngle, angleK, forces ); + abLength, cbLength, idealAngle, angleK1, anglek2, forces ); // accumulate forces for( int jj = 0; jj < 3; jj++ ){ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h index 873b2d620..67f689ab9 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h @@ -77,7 +77,8 @@ public: const std::vector& lengthABParameters, const std::vector& lengthCBParameters, const std::vector& angle, - const std::vector& kQuadratic, + const std::vector& k1Quadratic, + const std::vector& k2Quadratic, std::vector& forceData ) const; -- GitLab From d006ac4595f2869d7145a7e9dd992d17b98ed62a Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 20:19:57 -0500 Subject: [PATCH 242/338] Typo fix. --- plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp index d07025552..403066605 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp @@ -546,7 +546,7 @@ void CudaCalcAmoebaStretchBendForceKernel::copyParametersToContext(ContextImpl& double lengthAB, lengthCB, angle, k1, k2; force.getStretchBendParameters(startIndex+i, atom1, atom2, atom3, lengthAB, lengthCB, angle, k1, k2); paramVector[i] = make_float3((float) lengthAB, (float) lengthCB, (float) angle); - paramVector1[i] = make_flaot2((float) k1, (float) k2); + paramVector1[i] = make_float2((float) k1, (float) k2); } params1->upload(paramVector); params2->upload(paramVector1); -- GitLab From 72f998303657d698deb5af124722253e053c0d16 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 20:52:44 -0500 Subject: [PATCH 243/338] Fix a handful of issues -- Reference Amoeba plugin now builds and finishes the stretch-bend test correctly. The potential energy calculation done in the ReferenceStretchBendTest file was updated to mirror that of the Reference kernel, but first I made sure that the test passed *before* updating to the new energy expression, just to make sure that the energies and forces didn't *change* with the new expression. --- .../include/openmm/AmoebaStretchBendForce.h | 18 ------------------ .../reference/src/AmoebaReferenceKernels.cpp | 2 +- .../AmoebaReferenceStretchBendForce.cpp | 2 +- .../AmoebaReferenceStretchBendForce.h | 7 ++++--- .../TestReferenceAmoebaStretchBendForce.cpp | 19 ++++++++++--------- 5 files changed, 16 insertions(+), 32 deletions(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index 778e345de..bc747e035 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -94,24 +94,6 @@ public: void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2) const; - /** - * Get the force field parameters for a stretch-bend term, provided for - * backwards-compatibility. Since the two force constants may be different, - * you are recommended to call the other version of getStretchBendParameters - * with both a k1 and k2 - * - * @param index the index of the stretch-bend for which to get parameters - * @param particle1 the index of the first particle connected by the stretch-bend - * @param particle2 the index of the second particle connected by the stretch-bend - * @param particle3 the index of the third particle connected by the stretch-bend - * @param lengthAB the equilibrium length of the stretch-bend in bond ab [particle1, particle2], measured in nm - * @param lengthCB the equilibrium length of the stretch-bend in bond cb [particle3, particle2], measured in nm - * @param angle the equilibrium angle in radians - * @param k1 the force constant - */ - void getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, double& lengthAB, - double& lengthCB, double& angle, double& k1) const; - /** * Set the force field parameters for a stretch-bend term. * diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp index 98fc6fdef..1483c0199 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp @@ -346,7 +346,7 @@ void ReferenceCalcAmoebaStretchBendForceKernel::copyParametersToContext(ContextI lengthCBParameters[i] = (RealOpenMM) lengthCB; angleParameters[i] = (RealOpenMM) angle; k1Parameters[i] = (RealOpenMM) k1; - k1Parameters[i] = (RealOpenMM) k2; + k2Parameters[i] = (RealOpenMM) k2; } } diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp index 8df2ec4c4..68d26e85b 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp @@ -171,7 +171,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStre RealOpenMM angleK2 = k2Quadratic[ii]; RealVec forces[3]; energy += calculateStretchBendIxn( posData[particle1Index], posData[particle2Index], posData[particle3Index], - abLength, cbLength, idealAngle, angleK1, anglek2, forces ); + abLength, cbLength, idealAngle, angleK1, angleK2, forces ); // accumulate forces for( int jj = 0; jj < 3; jj++ ){ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h index 67f689ab9..78cba2c01 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h @@ -94,7 +94,8 @@ private: @param lengthAB ideal AB bondlength @param lengthCB ideal CB bondlength @param idealAngle ideal angle - @param kParameter k + @param k1Parameter k for distance A-B * angle A-B-C + @param k2Parameter k for distance B-C * angle A-B-C @param forces force vector @return energy @@ -104,8 +105,8 @@ private: RealOpenMM calculateStretchBendIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, const OpenMM::RealVec& positionAtomC, RealOpenMM lengthAB, RealOpenMM lengthCB, - RealOpenMM idealAngle, RealOpenMM kParameter, - OpenMM::RealVec* forces ) const; + RealOpenMM idealAngle, RealOpenMM k1Parameter, + RealOpenMM k2Parameter, OpenMM::RealVec* forces ) const; }; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp index e321e3d2f..40e2eb27d 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp @@ -83,14 +83,14 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos std::vector& forces, double* energy, FILE* log ) { int particle1, particle2, particle3; - double abBondLength, cbBondLength, angleStretchBend, kStretchBend; + double abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend; - amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend); + amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); angleStretchBend *= RADIAN; #ifdef AMOEBA_DEBUG if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k=%10.3e\n", - bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend ); + (void) fprintf( log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k1=%10.3e k2=%10.3e\n", + bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend ); (void) fflush( log ); } #endif @@ -149,12 +149,13 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos deltaR[CBxP][ii] *= termC; } - double dr = rAB - abBondLength + rCB - cbBondLength; + double dr1 = rAB - abBondLength; + double dr2 = rCB - cbBondLength; termA = 1.0/rAB; termC = 1.0/rCB; - double term = kStretchBend; + double drkk = dr1 * kStretchBend + dr2 * k2StretchBend; // --------------------------------------------------------------------------------------- @@ -166,8 +167,8 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos double subForce[LastAtomIndex][3]; double dt = angle - angleStretchBend; for( int jj = 0; jj < 3; jj++ ){ - subForce[A][jj] = term*(dt*termA*deltaR[AB][jj] + dr*deltaR[ABxP][jj] ); - subForce[C][jj] = term*(dt*termC*deltaR[CB][jj] + dr*deltaR[CBxP][jj] ); + subForce[A][jj] = kStretchBend*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj]; + subForce[C][jj] = k2StretchBend*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj]; subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); } @@ -187,7 +188,7 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos forces[particle3][1] -= subForce[2][1]; forces[particle3][2] -= subForce[2][2]; - *energy += term*dt*dr; + *energy += dt*drkk; #ifdef AMOEBA_DEBUG if( log ){ (void) fprintf( log, "computeAmoebaStretchBendForce: angle=%10.3e dt=%10.3e dr=%10.3e\n", angle, dt, dr ); -- GitLab From 104e827e72287b469740d649cb3157f58dac7a92 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 20:59:59 -0500 Subject: [PATCH 244/338] Update the CUDA Amoeba stretch-bend test with the same computeStretchBend as the one in the Reference platform (pulled over via meld to limit possible mistakes). --- .../tests/TestCudaAmoebaStretchBendForce.cpp | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp index 2142d4cc5..b3d9ba616 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp @@ -82,14 +82,14 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos std::vector& forces, double* energy, FILE* log ) { int particle1, particle2, particle3; - double abBondLength, cbBondLength, angleStretchBend, kStretchBend; + double abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend; - amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend); + amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); angleStretchBend *= RADIAN; #ifdef AMOEBA_DEBUG if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k=%10.3e\n", - bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend ); + (void) fprintf( log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k1=%10.3e k2=%10.3e\n", + bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend ); (void) fflush( log ); } #endif @@ -128,9 +128,11 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos double angle; if( cosine >= 1.0 ){ angle = 0.0; - } else if( cosine <= -1.0 ){ + } + else if( cosine <= -1.0 ){ angle = PI_M; - } else { + } + else { angle = RADIAN*acos(cosine); } @@ -146,12 +148,13 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos deltaR[CBxP][ii] *= termC; } - double dr = rAB - abBondLength + rCB - cbBondLength; + double dr1 = rAB - abBondLength; + double dr2 = rCB - cbBondLength; termA = 1.0/rAB; termC = 1.0/rCB; - double term = kStretchBend; + double drkk = dr1 * kStretchBend + dr2 * k2StretchBend; // --------------------------------------------------------------------------------------- @@ -163,8 +166,8 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos double subForce[LastAtomIndex][3]; double dt = angle - angleStretchBend; for( int jj = 0; jj < 3; jj++ ){ - subForce[A][jj] = term*(dt*termA*deltaR[AB][jj] + dr*deltaR[ABxP][jj] ); - subForce[C][jj] = term*(dt*termC*deltaR[CB][jj] + dr*deltaR[CBxP][jj] ); + subForce[A][jj] = kStretchBend*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj]; + subForce[C][jj] = k2StretchBend*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj]; subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); } @@ -184,8 +187,7 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos forces[particle3][1] -= subForce[2][1]; forces[particle3][2] -= subForce[2][2]; - *energy += term*dt*dr; - + *energy += dt*drkk; #ifdef AMOEBA_DEBUG if( log ){ (void) fprintf( log, "computeAmoebaStretchBendForce: angle=%10.3e dt=%10.3e dr=%10.3e\n", angle, dt, dr ); -- GitLab From e6dbc49680a0579fd2bba9bc49ea435029698b84 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 21:07:48 -0500 Subject: [PATCH 245/338] Oops, forgot to distribute the negative --- .../platforms/cuda/src/kernels/amoebaStretchBendForce.cu | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu b/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu index 668c5104b..288a8d2fc 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/amoebaStretchBendForce.cu @@ -64,6 +64,6 @@ real ddrdzic = termc * zcb; energy += dt*drkk; -real3 force1 = make_real3(-frc1*dt*ddrdxia+ddtdxia*drkk, -frc1*dt*ddrdyia+ddtdyia*drkk, -frc1*dt*ddrdzia+ddtdzia*drkk); -real3 force3 = make_real3(-frc2*dt*ddrdxic+ddtdxic*drkk, -frc2*dt*ddrdyic+ddtdyic*drkk, -frc2*dt*ddrdzic+ddtdzic*drkk); +real3 force1 = make_real3(-frc1*dt*ddrdxia-ddtdxia*drkk, -frc1*dt*ddrdyia-ddtdyia*drkk, -frc1*dt*ddrdzia-ddtdzia*drkk); +real3 force3 = make_real3(-frc2*dt*ddrdxic-ddtdxic*drkk, -frc2*dt*ddrdyic-ddtdyic*drkk, -frc2*dt*ddrdzic-ddtdzic*drkk); real3 force2 = make_real3(-force1.x-force3.x, -force1.y-force3.y, -force1.z-force3.z); -- GitLab From 8a01b345bfd5d056fe1f3a117fda1fb2e86252e8 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 22:56:50 -0500 Subject: [PATCH 246/338] Remove default and kludgey way to half-support backwards compatibility. Update the Python application layer to use both force constants when building the AmoebaStretchBendForce. --- .../openmmapi/include/openmm/AmoebaStretchBendForce.h | 4 ++-- plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp | 6 +----- .../platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp | 4 ++-- .../reference/tests/TestReferenceAmoebaStretchBendForce.cpp | 4 ++-- wrappers/python/simtk/openmm/app/forcefield.py | 2 +- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index bc747e035..dbaf8221d 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -76,7 +76,7 @@ public: * @return the index of the stretch-bend that was added */ int addStretchBend(int particle1, int particle2, int particle3, double lengthAB, double lengthCB, double angle, - double k1, double k2=-1.0); + double k1, double k2); /** * Get the force field parameters for a stretch-bend term. @@ -108,7 +108,7 @@ public: * @param k2 the force constant of the product of bond bc and angle a-b-c (optional, default is the same as k1) */ void setStretchBendParameters(int index, int particle1, int particle2, int particle3, - double lengthAB, double lengthCB, double angle, double k1, double k2=-1.0 ); + double lengthAB, double lengthCB, double angle, double k1, double k2); /** * Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. diff --git a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp index 85176cd20..0be297e51 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp @@ -41,7 +41,6 @@ AmoebaStretchBendForce::AmoebaStretchBendForce() { int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int particle3, double lengthAB, double lengthCB, double angle, double k1, double k2) { - if (k2 == -1.0) k2 = k1; stretchBends.push_back(StretchBendInfo(particle1, particle2, particle3, lengthAB, lengthCB, angle, k1, k2)); return stretchBends.size()-1; } @@ -67,10 +66,7 @@ void AmoebaStretchBendForce::setStretchBendParameters(int index, int particle1, stretchBends[index].lengthCB = lengthCB; stretchBends[index].angle = angle; stretchBends[index].k1 = k1; - if (k2 == -1.0) - stretchBends[index].k2 = k1; - else - stretchBends[index].k2 = k2; + stretchBends[index].k2 = k2; } ForceImpl* AmoebaStretchBendForce::createImpl() const { diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp index b3d9ba616..f5a683c2d 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp @@ -276,7 +276,7 @@ void testOneStretchBend( FILE* log ) { //double kStretchBend = 0.750491578E-01; double kStretchBend = 1.0; - amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend ); + amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend ); system.addForce(amoebaStretchBendForce); Context context(system, integrator, Platform::getPlatformByName( "CUDA")); @@ -292,7 +292,7 @@ void testOneStretchBend( FILE* log ) { // Try changing the stretch-bend parameters and make sure it's still correct. - amoebaStretchBendForce->setStretchBendParameters(0, 0, 1, 2, 1.1*abLength, 1.2*cbLength, 1.3*angleStretchBend, 1.4*kStretchBend); + amoebaStretchBendForce->setStretchBendParameters(0, 0, 1, 2, 1.1*abLength, 1.2*cbLength, 1.3*angleStretchBend, 1.4*kStretchBend, 1.4*kStretchBend); bool exceptionThrown = false; try { // This should throw an exception. diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp index 40e2eb27d..f64a3e153 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp @@ -275,7 +275,7 @@ void testOneStretchBend( FILE* log ) { //double kStretchBend = 0.750491578E-01; double kStretchBend = 1.0; - amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend ); + amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend ); system.addForce(amoebaStretchBendForce); ASSERT(!amoebaStretchBendForce->usesPeriodicBoundaryConditions()); @@ -293,7 +293,7 @@ void testOneStretchBend( FILE* log ) { // Try changing the stretch-bend parameters and make sure it's still correct. - amoebaStretchBendForce->setStretchBendParameters(0, 0, 1, 2, 1.1*abLength, 1.2*cbLength, 1.3*angleStretchBend, 1.4*kStretchBend); + amoebaStretchBendForce->setStretchBendParameters(0, 0, 1, 2, 1.1*abLength, 1.2*cbLength, 1.3*angleStretchBend, 1.4*kStretchBend, 1.4*kStretchBend); bool exceptionThrown = false; try { // This should throw an exception. diff --git a/wrappers/python/simtk/openmm/app/forcefield.py b/wrappers/python/simtk/openmm/app/forcefield.py index fc9dd7430..e6de04e79 100644 --- a/wrappers/python/simtk/openmm/app/forcefield.py +++ b/wrappers/python/simtk/openmm/app/forcefield.py @@ -3086,7 +3086,7 @@ class AmoebaStretchBendGenerator: raise ValueError(outputString) else: - force.addStretchBend(angle[0], angle[1], angle[2], bondAB, bondCB, angleDict['idealAngle']/radian, self.k1[i]) + force.addStretchBend(angle[0], angle[1], angle[2], bondAB, bondCB, angleDict['idealAngle']/radian, self.k1[i], self.k2[i]) break -- GitLab From 033eed5ccb0484b31fc01074efd796f8aa2f6aa4 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Sat, 7 Feb 2015 23:01:28 -0500 Subject: [PATCH 247/338] Oops, forgot to update the serialization test for the removal of the default argument. --- .../tests/TestSerializeAmoebaStretchBendForce.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp index 584a88f89..8927100f3 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaStretchBendForce.cpp @@ -45,9 +45,9 @@ void testSerialization() { // Create a Force. AmoebaStretchBendForce force1; - force1.addStretchBend(0, 1, 3, 1.0, 1.2, 150.1, 83.2); - force1.addStretchBend(2, 4, 4, 1.1, 2.2, 180.1, 89.2); - force1.addStretchBend(5, 0, 1, 3.1, 8.2, 140.1, 98.2); + force1.addStretchBend(0, 1, 3, 1.0, 1.2, 150.1, 83.2, 100.); + force1.addStretchBend(2, 4, 4, 1.1, 2.2, 180.1, 89.2, 100.); + force1.addStretchBend(5, 0, 1, 3.1, 8.2, 140.1, 98.2, 100.); // Serialize and then deserialize it. -- GitLab From d127d7c2974ea7f80635b4995a0aedcd18640e20 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 9 Feb 2015 16:12:34 -0500 Subject: [PATCH 248/338] Fix for unit cell vector calculation (had no effect for orthorhombic boxes, but now that triclinics are supported this is important). --- wrappers/python/simtk/openmm/app/charmmpsffile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/charmmpsffile.py b/wrappers/python/simtk/openmm/app/charmmpsffile.py index 6da569c44..23c12e7b4 100644 --- a/wrappers/python/simtk/openmm/app/charmmpsffile.py +++ b/wrappers/python/simtk/openmm/app/charmmpsffile.py @@ -8,7 +8,7 @@ Structures at Stanford, funded under the NIH Roadmap for Medical Research, grant U54 GM072970. See https://simtk.org. This code was originally part of the ParmEd program and was ported for use with OpenMM. -Copyright (c) 2014 the Authors +Copyright (c) 2014-2015 the Authors Author: Jason M. Swails Contributors: @@ -1560,7 +1560,7 @@ def _box_vectors_from_lengths_angles(a, b, c, alpha, beta, gamma): by = b * sin(gamma) bz = 0.0 cx = c * cos(beta) - cy = c * (cos(alpha) - cos(beta) * cos(gamma)) + cy = c * (cos(alpha) - cos(beta) * cos(gamma)) / sin(gamma) cz = sqrt(c * c - cx * cx - cy * cy) # Make sure any components that are close to zero are set to zero exactly -- GitLab From 0a0f0214690df41c24660cd4526691735ed5cae8 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Mon, 9 Feb 2015 13:28:15 -0800 Subject: [PATCH 249/338] Continuing triclinic box support in Python layer --- wrappers/python/CMakeLists.txt | 1 + .../python/simtk/openmm/app/gromacsgrofile.py | 2 +- .../python/simtk/openmm/app/gromacstopfile.py | 15 +++- .../simtk/openmm/app/internal/pdbstructure.py | 65 ++++++++------ wrappers/python/simtk/openmm/app/pdbfile.py | 18 ++-- wrappers/python/simtk/openmm/app/pdbxfile.py | 20 +---- wrappers/python/tests/TestPdbFile.py | 53 ++++++++++++ wrappers/python/tests/TestPdbxFile.py | 53 ++++++++++++ wrappers/python/tests/systems/triclinic.pdb | 11 +++ wrappers/python/tests/systems/triclinic.pdbx | 86 +++++++++++++++++++ 10 files changed, 272 insertions(+), 52 deletions(-) create mode 100644 wrappers/python/tests/TestPdbFile.py create mode 100644 wrappers/python/tests/TestPdbxFile.py create mode 100644 wrappers/python/tests/systems/triclinic.pdb create mode 100644 wrappers/python/tests/systems/triclinic.pdbx diff --git a/wrappers/python/CMakeLists.txt b/wrappers/python/CMakeLists.txt index ecf37c5b5..63f4371b5 100644 --- a/wrappers/python/CMakeLists.txt +++ b/wrappers/python/CMakeLists.txt @@ -54,6 +54,7 @@ foreach(SUBDIR ${SUBDIRS}) "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.sh" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.xml" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.pdb" + "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.pdbx" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.prmtop" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.prm" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.inpcrd" diff --git a/wrappers/python/simtk/openmm/app/gromacsgrofile.py b/wrappers/python/simtk/openmm/app/gromacsgrofile.py index b79173c1f..967769aea 100644 --- a/wrappers/python/simtk/openmm/app/gromacsgrofile.py +++ b/wrappers/python/simtk/openmm/app/gromacsgrofile.py @@ -6,7 +6,7 @@ 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) 2012 Stanford University and the Authors. +Portions copyright (c) 2012-2015 Stanford University and the Authors. Authors: Lee-Ping Wang, Peter Eastman Contributors: diff --git a/wrappers/python/simtk/openmm/app/gromacstopfile.py b/wrappers/python/simtk/openmm/app/gromacstopfile.py index 7bad309f8..a5634c545 100644 --- a/wrappers/python/simtk/openmm/app/gromacstopfile.py +++ b/wrappers/python/simtk/openmm/app/gromacstopfile.py @@ -6,7 +6,7 @@ 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) 2012-2014 Stanford University and the Authors. +Portions copyright (c) 2012-2015 Stanford University and the Authors. Authors: Peter Eastman Contributors: @@ -358,12 +358,14 @@ class GromacsTopFile(object): raise ValueError('Unsupported function type in [ cmaptypes ] line: '+line); self._cmapTypes[tuple(fields[:5])] = fields - def __init__(self, file, unitCellDimensions=None, includeDir=None, defines=None): + def __init__(self, file, periodicBoxVectors=None, unitCellDimensions=None, includeDir=None, defines=None): """Load a top file. Parameters: - file (string) the name of the file to load - - unitCellDimensions (Vec3=None) the dimensions of the crystallographic unit cell + - periodicBoxVectors (tuple of Vec3=None) the vectors defining the periodic box + - unitCellDimensions (Vec3=None) the dimensions of the crystallographic unit cell. For + non-rectangular unit cells, specify periodicBoxVectors instead. - includeDir (string=None) A directory in which to look for other files included from the top file. If not specified, we will attempt to locate a gromacs installation on your system. When gromacs is installed in /usr/local, this will resolve @@ -403,7 +405,12 @@ class GromacsTopFile(object): top = Topology() ## The Topology read from the prmtop file self.topology = top - top.setUnitCellDimensions(unitCellDimensions) + if periodicBoxVectors is not None: + if unitCellDimensions is not None: + raise ValueError("specify either periodicBoxVectors or unitCellDimensions, but not both") + top.setPeriodicBoxVectors(periodicBoxVectors) + else: + top.setUnitCellDimensions(unitCellDimensions) PDBFile._loadNameReplacementTables() for moleculeName, moleculeCount in self._molecules: if moleculeName not in self._moleculeTypes: diff --git a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py index 5baed4fd1..09021cb5a 100644 --- a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py +++ b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py @@ -8,7 +8,7 @@ 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) 2012-2013 Stanford University and the Authors. +Portions copyright (c) 2012-2015 Stanford University and the Authors. Authors: Christopher M. Bruns Contributors: Peter Eastman @@ -41,6 +41,38 @@ import warnings import sys import math +def computePeriodicBoxVectors(a_length, b_length, c_length, alpha, beta, gamma): + """Convert lengths and angles from a CRYST1 record to periodic box vectors.""" + + # Compute the vectors. + + a = [a_length, 0, 0] + b = [b_length*math.cos(gamma), b_length*math.sin(gamma), 0] + cx = c_length*math.cos(beta) + cy = c_length*(math.cos(alpha)-math.cos(beta)*math.cos(gamma))/math.sin(gamma) + cz = math.sqrt(c_length*c_length-cx*cx-cy*cy) + c = [cx, cy, cz] + + # If any elements are very close to 0, set them to exactly 0. + + for i in range(3): + if abs(a[i]) < 1e-6: + a[i] = 0.0 + if abs(b[i]) < 1e-6: + b[i] = 0.0 + if abs(c[i]) < 1e-6: + c[i] = 0.0 + a = Vec3(*a) + b = Vec3(*b) + c = Vec3(*c) + + # Make sure they're in the reduced form required by OpenMM. + + c = c - b*round(c[1]/b[1]) + c = c - a*round(c[0]/a[0]) + b = b - a*round(b[0]/a[0]) + return (a, b, c)*unit.angstroms + class PdbStructure(object): """ PdbStructure object holds a parsed Protein Data Bank format file. @@ -171,7 +203,13 @@ class PdbStructure(object): self._current_model._current_chain._add_ter_record() self._reset_residue_numbers() elif (pdb_line.find("CRYST1") == 0): - self._compute_periodic_box_vectors(pdb_line) + a_length = float(pdb_line[6:15]) + b_length = float(pdb_line[15:24]) + c_length = float(pdb_line[24:33]) + alpha = float(pdb_line[33:40])*math.pi/180.0 + beta = float(pdb_line[40:47])*math.pi/180.0 + gamma = float(pdb_line[47:54])*math.pi/180.0 + self._periodic_box_vectors = computePeriodicBoxVectors(a_length, b_length, c_length, alpha, beta, gamma) elif (pdb_line.find("CONECT") == 0): atoms = [int(pdb_line[6:11])] for pos in (11,16,21,26): @@ -189,29 +227,6 @@ class PdbStructure(object): self.modified_residues.append(ModifiedResidue(pdb_line[16], int(pdb_line[18:22]), pdb_line[12:15].strip(), pdb_line[24:27].strip())) self._finalize() - def _compute_periodic_box_vectors(self, line): - """Parse a CRYST1 record to compute the periodic box vectors.""" - a_length = float(line[6:15]) - b_length = float(line[15:24]) - c_length = float(line[24:33]) - alpha = float(line[33:40])*math.pi/180.0 - beta = float(line[40:47])*math.pi/180.0 - gamma = float(line[47:54])*math.pi/180.0 - a = [a_length, 0, 0] - b = [b_length*math.cos(gamma), b_length*math.sin(gamma), 0] - cx = c_length*math.cos(beta) - cy = c_length*(math.cos(alpha)-math.cos(beta)*math.cos(gamma)) - cz = math.sqrt(c_length*c_length-cx*cx-cy*cy) - c = [cx, cy, cz] - for i in range(3): - if abs(a[i]) < 1e-6: - a[i] = 0.0 - if abs(b[i]) < 1e-6: - b[i] = 0.0 - if abs(c[i]) < 1e-6: - c[i] = 0.0 - self._periodic_box_vectors = (Vec3(*a), Vec3(*b), Vec3(*c))*unit.angstroms - def _reset_atom_numbers(self): self._atom_numbers_are_hex = False self._next_atom_number = 1 diff --git a/wrappers/python/simtk/openmm/app/pdbfile.py b/wrappers/python/simtk/openmm/app/pdbfile.py index 3a84f86c2..7d23bed7d 100644 --- a/wrappers/python/simtk/openmm/app/pdbfile.py +++ b/wrappers/python/simtk/openmm/app/pdbfile.py @@ -6,7 +6,7 @@ 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) 2012 Stanford University and the Authors. +Portions copyright (c) 2012-2015 Stanford University and the Authors. Authors: Peter Eastman Contributors: @@ -40,7 +40,7 @@ from datetime import date from simtk.openmm import Vec3, Platform from simtk.openmm.app.internal.pdbstructure import PdbStructure from simtk.openmm.app import Topology -from simtk.unit import nanometers, angstroms, is_quantity, norm, Quantity +from simtk.unit import nanometers, angstroms, is_quantity, norm, Quantity, dot import element as elem try: import numpy @@ -250,10 +250,16 @@ class PDBFile(object): - file (file=stdout) A file to write the file to """ print >>file, "REMARK 1 CREATED WITH OPENMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())) - boxSize = topology.getUnitCellDimensions() - if boxSize is not None: - size = boxSize.value_in_unit(angstroms) - print >>file, "CRYST1%9.3f%9.3f%9.3f 90.00 90.00 90.00 P 1 1 " % size + vectors = topology.getPeriodicBoxVectors() + if vectors is not None: + (a, b, c) = vectors.value_in_unit(angstroms) + a_length = norm(a) + b_length = norm(b) + c_length = norm(c) + alpha = math.acos(dot(b, c)/(b_length*c_length))*180.0/math.pi + beta = math.acos(dot(c, a)/(c_length*a_length))*180.0/math.pi + gamma = math.acos(dot(a, b)/(a_length*b_length))*180.0/math.pi + print >>file, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P 1 1 " % (a_length, b_length, c_length, alpha, beta, gamma) @staticmethod def writeModel(topology, positions, file=sys.stdout, modelIndex=None): diff --git a/wrappers/python/simtk/openmm/app/pdbxfile.py b/wrappers/python/simtk/openmm/app/pdbxfile.py index ece960e50..cfa3e05a6 100644 --- a/wrappers/python/simtk/openmm/app/pdbxfile.py +++ b/wrappers/python/simtk/openmm/app/pdbxfile.py @@ -6,7 +6,7 @@ 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) 2014 Stanford University and the Authors. +Portions copyright (c) 2014-2015 Stanford University and the Authors. Authors: Peter Eastman Contributors: @@ -36,6 +36,7 @@ import sys import math from simtk.openmm import Vec3 from simtk.openmm.app.internal.pdbx.reader.PdbxReader import PdbxReader +from simtk.openmm.app.internal.pdbstructure import computePeriodicBoxVectors from simtk.openmm.app import Topology from simtk.unit import nanometers, angstroms, is_quantity, norm, Quantity import element as elem @@ -147,21 +148,8 @@ class PDBxFile(object): if cell is not None and cell.getRowCount() > 0: row = cell.getRow(0) (a, b, c) = [float(row[cell.getAttributeIndex(attribute)]) for attribute in ('length_a', 'length_b', 'length_c')] - (alpha, beta, gamma) = [float(row[cell.getAttributeIndex(attribute)]) for attribute in ('angle_alpha', 'angle_beta', 'angle_gamma')*math.pi/180.0] - a = [a_length, 0, 0] - b = [b_length*math.cos(gamma), b_length*math.sin(gamma), 0] - cx = c_length*math.cos(beta) - cy = c_length*(math.cos(alpha)-math.cos(beta)*math.cos(gamma)) - cz = math.sqrt(c_length*c_length-cx*cx-cy*cy) - c = [cx, cy, cz] - for i in range(3): - if abs(a[i]) < 1e-6: - a[i] = 0.0 - if abs(b[i]) < 1e-6: - b[i] = 0.0 - if abs(c[i]) < 1e-6: - c[i] = 0.0 - self.topology.setPeriodicBoxVectors((Vec3(*a), Vec3(*b), Vec3(*c))*unit.angstroms) + (alpha, beta, gamma) = [float(row[cell.getAttributeIndex(attribute)])*math.pi/180.0 for attribute in ('angle_alpha', 'angle_beta', 'angle_gamma')] + self.topology.setPeriodicBoxVectors(computePeriodicBoxVectors(a, b, c, alpha, beta, gamma)) # Add bonds based on struct_conn records. diff --git a/wrappers/python/tests/TestPdbFile.py b/wrappers/python/tests/TestPdbFile.py new file mode 100644 index 000000000..b15425335 --- /dev/null +++ b/wrappers/python/tests/TestPdbFile.py @@ -0,0 +1,53 @@ +import unittest +from simtk.openmm.app import * +from simtk.openmm import * +from simtk.unit import * +import simtk.openmm.app.element as elem + +class TestPdbFile(unittest.TestCase): + """Test the PDB file parser""" + + def test_Triclinic(self): + """Test parsing a file that describes a triclinic box.""" + pdb = PDBFile('systems/triclinic.pdb') + self.assertEqual(len(pdb.positions), 8) + expectedPositions = [ + Vec3(1.744, 2.788, 3.162), + Vec3(1.048, 0.762, 2.340), + Vec3(2.489, 1.570, 2.817), + Vec3(1.027, 1.893, 3.271), + Vec3(0.937, 0.825, 0.009), + Vec3(2.290, 1.887, 3.352), + Vec3(1.266, 1.111, 2.894), + Vec3(0.933, 1.862, 3.490)]*nanometers + for (p1, p2) in zip(expectedPositions, pdb.positions): + self.assertVecAlmostEqual(p1, p2) + expectedVectors = [ + Vec3(2.5, 0, 0), + Vec3(0.5, 3.0, 0), + Vec3(0.7, 0.9, 3.5)]*nanometers + for (v1, v2) in zip(expectedVectors, pdb.topology.getPeriodicBoxVectors()): + self.assertVecAlmostEqual(v1, v2, 1e-4) + self.assertVecAlmostEqual(Vec3(2.5, 3.0, 3.5)*nanometers, pdb.topology.getUnitCellDimensions(), 1e-4) + for atom in pdb.topology.atoms(): + if atom.index < 4: + self.assertEqual(elem.chlorine, atom.element) + self.assertEqual('Cl', atom.name) + self.assertEqual('Cl', atom.residue.name) + else: + self.assertEqual(elem.sodium, atom.element) + self.assertEqual('Na', atom.name) + self.assertEqual('Na', atom.residue.name) + + def assertVecAlmostEqual(self, p1, p2, tol=1e-7): + unit = p1.unit + p1 = p1.value_in_unit(unit) + p2 = p2.value_in_unit(unit) + scale = max(1.0, norm(p1),) + for i in range(3): + diff = abs(p1[i]-p2[i])/scale + self.assertTrue(diff < tol) + + +if __name__ == '__main__': + unittest.main() diff --git a/wrappers/python/tests/TestPdbxFile.py b/wrappers/python/tests/TestPdbxFile.py new file mode 100644 index 000000000..a74743e33 --- /dev/null +++ b/wrappers/python/tests/TestPdbxFile.py @@ -0,0 +1,53 @@ +import unittest +from simtk.openmm.app import * +from simtk.openmm import * +from simtk.unit import * +import simtk.openmm.app.element as elem + +class TestPdbxFile(unittest.TestCase): + """Test the PDBx/mmCIF file parser""" + + def test_Triclinic(self): + """Test parsing a file that describes a triclinic box.""" + pdb = PDBxFile('systems/triclinic.pdbx') + self.assertEqual(len(pdb.positions), 8) + expectedPositions = [ + Vec3(1.744, 2.788, 3.162), + Vec3(1.048, 0.762, 2.340), + Vec3(2.489, 1.570, 2.817), + Vec3(1.027, 1.893, 3.271), + Vec3(0.937, 0.825, 0.009), + Vec3(2.290, 1.887, 3.352), + Vec3(1.266, 1.111, 2.894), + Vec3(0.933, 1.862, 3.490)]*nanometers + for (p1, p2) in zip(expectedPositions, pdb.positions): + self.assertVecAlmostEqual(p1, p2) + expectedVectors = [ + Vec3(2.5, 0, 0), + Vec3(0.5, 3.0, 0), + Vec3(0.7, 0.9, 3.5)]*nanometers + for (v1, v2) in zip(expectedVectors, pdb.topology.getPeriodicBoxVectors()): + self.assertVecAlmostEqual(v1, v2, 1e-6) + self.assertVecAlmostEqual(Vec3(2.5, 3.0, 3.5)*nanometers, pdb.topology.getUnitCellDimensions(), 1e-6) + for atom in pdb.topology.atoms(): + if atom.index < 4: + self.assertEqual(elem.chlorine, atom.element) + self.assertEqual('Cl', atom.name) + self.assertEqual('Cl', atom.residue.name) + else: + self.assertEqual(elem.sodium, atom.element) + self.assertEqual('Na', atom.name) + self.assertEqual('Na', atom.residue.name) + + def assertVecAlmostEqual(self, p1, p2, tol=1e-7): + unit = p1.unit + p1 = p1.value_in_unit(unit) + p2 = p2.value_in_unit(unit) + scale = max(1.0, norm(p1),) + for i in range(3): + diff = abs(p1[i]-p2[i])/scale + self.assertTrue(diff < tol) + + +if __name__ == '__main__': + unittest.main() diff --git a/wrappers/python/tests/systems/triclinic.pdb b/wrappers/python/tests/systems/triclinic.pdb new file mode 100644 index 000000000..e715c78ac --- /dev/null +++ b/wrappers/python/tests/systems/triclinic.pdb @@ -0,0 +1,11 @@ +CRYST1 25.000 30.414 36.810 74.19 79.04 80.54 P 1 1 +ATOM 1 Cl Cl A 1 17.440 27.880 31.620 1.00 0.00 Cl +ATOM 2 Cl Cl A 2 10.480 7.620 23.400 1.00 0.00 Cl +ATOM 3 Cl Cl A 3 24.890 15.700 28.170 1.00 0.00 Cl +ATOM 4 Cl Cl A 4 10.270 18.930 32.710 1.00 0.00 Cl +ATOM 5 Na Na A 5 9.370 8.250 0.090 1.00 0.00 Na +ATOM 6 Na Na A 6 22.900 18.870 33.520 1.00 0.00 Na +ATOM 7 Na Na A 7 12.660 11.110 28.940 1.00 0.00 Na +ATOM 8 Na Na A 8 9.330 18.620 34.900 1.00 0.00 Na +TER 9 Na A 8 +END diff --git a/wrappers/python/tests/systems/triclinic.pdbx b/wrappers/python/tests/systems/triclinic.pdbx new file mode 100644 index 000000000..a325a3208 --- /dev/null +++ b/wrappers/python/tests/systems/triclinic.pdbx @@ -0,0 +1,86 @@ +data_PHPWKVVWM +# +loop_ +_pdbx_nonpoly_scheme.asym_id +_pdbx_nonpoly_scheme.entity_id +_pdbx_nonpoly_scheme.mon_id +_pdbx_nonpoly_scheme.ndb_seq_num +_pdbx_nonpoly_scheme.pdb_seq_num +_pdbx_nonpoly_scheme.auth_seq_num +_pdbx_nonpoly_scheme.pdb_mon_id +_pdbx_nonpoly_scheme.auth_mon_id +_pdbx_nonpoly_scheme.pdb_strand_id +_pdbx_nonpoly_scheme.pdb_ins_code +A 1 Cl 1 1 1 Cl Cl A . +B 1 Cl 1 2 2 Cl Cl A . +C 1 Cl 1 3 3 Cl Cl A . +D 1 Cl 1 4 4 Cl Cl A . +E 2 Na 1 5 5 Na Na A . +F 2 Na 1 6 6 Na Na A . +G 2 Na 1 7 7 Na Na A . +H 2 Na 1 8 8 Na Na A . +# +_cell.entry_id PHPWKVVWM +_cell.length_a 25.000 +_cell.length_b 30.4138126515 +_cell.length_c 36.8103246386 +_cell.angle_alpha 74.1909185129 +_cell.angle_beta 79.0376425369 +_cell.angle_gamma 80.537677792 +_cell.Z_PDB 1 +_cell.pdbx_unique_axis ? +# +loop_ +_atom_type.symbol +Cl +Na +# +loop_ +_pdbx_entity_nonpoly.entity_id +_pdbx_entity_nonpoly.name +_pdbx_entity_nonpoly.comp_id +1 ? Cl +2 ? Na +# +loop_ +_atom_site.group_PDB +_atom_site.id +_atom_site.type_symbol +_atom_site.label_atom_id +_atom_site.label_alt_id +_atom_site.label_comp_id +_atom_site.label_asym_id +_atom_site.label_entity_id +_atom_site.label_seq_id +_atom_site.pdbx_label_seq_num +_atom_site.pdbx_PDB_ins_code +_atom_site.Cartn_x +_atom_site.Cartn_y +_atom_site.Cartn_z +_atom_site.occupancy +_atom_site.B_iso_or_equiv +_atom_site.Cartn_x_esd +_atom_site.Cartn_y_esd +_atom_site.Cartn_z_esd +_atom_site.occupancy_esd +_atom_site.B_iso_or_equiv_esd +_atom_site.footnote_id +_atom_site.pdbx_formal_charge +_atom_site.auth_seq_id +_atom_site.auth_comp_id +_atom_site.auth_asym_id +_atom_site.auth_atom_id +_atom_site.pdbx_auth_seq_id +_atom_site.pdbx_auth_comp_id +_atom_site.pdbx_auth_asym_id +_atom_site.pdbx_auth_atom_name +_atom_site.pdbx_PDB_model_num +HETATM 1 Cl Cl . Cl A 1 . 1 ? 17.440 27.880 31.620 1.00 0.00 ? ? ? ? ? ? ? 1 Cl A Cl 1 Cl A Cl 1 +HETATM 2 Cl Cl . Cl B 1 . 1 ? 10.480 7.620 23.400 1.00 0.00 ? ? ? ? ? ? ? 2 Cl A Cl 2 Cl A Cl 1 +HETATM 3 Cl Cl . Cl C 1 . 1 ? 24.890 15.700 28.170 1.00 0.00 ? ? ? ? ? ? ? 3 Cl A Cl 3 Cl A Cl 1 +HETATM 4 Cl Cl . Cl D 1 . 1 ? 10.270 18.930 32.710 1.00 0.00 ? ? ? ? ? ? ? 4 Cl A Cl 4 Cl A Cl 1 +HETATM 5 Na Na . Na E 2 . 1 ? 9.370 8.250 0.090 1.00 0.00 ? ? ? ? ? ? ? 5 Na A Na 5 Na A Na 1 +HETATM 6 Na Na . Na F 2 . 1 ? 22.900 18.870 33.520 1.00 0.00 ? ? ? ? ? ? ? 6 Na A Na 6 Na A Na 1 +HETATM 7 Na Na . Na G 2 . 1 ? 12.660 11.110 28.940 1.00 0.00 ? ? ? ? ? ? ? 7 Na A Na 7 Na A Na 1 +HETATM 8 Na Na . Na H 2 . 1 ? 9.330 18.620 34.900 1.00 0.00 ? ? ? ? ? ? ? 8 Na A Na 8 Na A Na 1 +# -- GitLab From 21a39eaf11d0cedc9c1dc419b9ac4a0a6633f6a8 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Mon, 9 Feb 2015 17:23:03 -0800 Subject: [PATCH 250/338] Modeller supports triclinic boxes --- wrappers/python/simtk/openmm/app/modeller.py | 49 ++++++++++++------- wrappers/python/tests/TestModeller.py | 50 +++++++++++++------- 2 files changed, 65 insertions(+), 34 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/modeller.py b/wrappers/python/simtk/openmm/app/modeller.py index 1090172ab..a5f240dc7 100644 --- a/wrappers/python/simtk/openmm/app/modeller.py +++ b/wrappers/python/simtk/openmm/app/modeller.py @@ -6,7 +6,7 @@ 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) 2012-2013 Stanford University and the Authors. +Portions copyright (c) 2012-2015 Stanford University and the Authors. Authors: Peter Eastman Contributors: @@ -94,7 +94,7 @@ class Modeller(object): # Copy over the existing model. newTopology = Topology() - newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) + newTopology.setPeriodicBoxVectors(self.topology.getPeriodicBoxVectors()) newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): @@ -140,7 +140,7 @@ class Modeller(object): - toDelete (list) a list of Atoms, Residues, Chains, and bonds (specified as tuples of Atoms) to delete """ newTopology = Topology() - newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) + newTopology.setPeriodicBoxVectors(self.topology.getPeriodicBoxVectors()) newAtoms = {} newPositions = []*nanometer deleteSet = set(toDelete) @@ -189,7 +189,7 @@ class Modeller(object): else: raise ValueError('Unknown water model: %s' % model) newTopology = Topology() - newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) + newTopology.setPeriodicBoxVectors(self.topology.getPeriodicBoxVectors()) newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): @@ -240,7 +240,7 @@ class Modeller(object): self.topology = newTopology self.positions = newPositions - def addSolvent(self, forcefield, model='tip3p', boxSize=None, padding=None, positiveIon='Na+', negativeIon='Cl-', ionicStrength=0*molar): + def addSolvent(self, forcefield, model='tip3p', boxSize=None, boxVectors=None, padding=None, positiveIon='Na+', negativeIon='Cl-', ionicStrength=0*molar): """Add solvent (both water and ions) to the model to fill a rectangular box. The algorithm works as follows: @@ -250,15 +250,17 @@ class Modeller(object): randomly selecting a water molecule and replacing it with the ion. 4. Ion pairs are added to give the requested total ionic strength. - The box size can be specified in three ways. First, you can explicitly give a box size to use. Alternatively, you can + The box size can be specified in four ways. First, you can explicitly give the vectors defining the periodic box to + use. Alternatively, for a rectangular box you can simply give the dimensions of the unit cell. Third, you can give a padding distance. The largest dimension of the solute (along the x, y, or z axis) is determined, and a cubic - box of size (largest dimension)+2*padding is used. Finally, if neither a box size nor a padding distance is specified, - the existing Topology's unit cell dimensions are used. + box of size (largest dimension)+2*padding is used. Finally, if neither box vectors, box size, nor padding distance is specified, + the existing Topology's box vectors are used. Parameters: - forcefield (ForceField) the ForceField to use for determining van der Waals radii and atomic charges - model (string='tip3p') the water model to use. Supported values are 'tip3p', 'spce', 'tip4pew', and 'tip5p'. - boxSize (Vec3=None) the size of the box to fill with water + - boxVectors (tuple of Vec3=None) the vectors defining the periodic box to fill with water - padding (distance=None) the padding distance to use - positiveIon (string='Na+') the type of positive ion to add. Allowed values are 'Cs+', 'K+', 'Li+', 'Na+', and 'Rb+' - negativeIon (string='Cl-') the type of negative ion to add. Allowed values are 'Cl-', 'Br-', 'F-', and 'I-'. Be aware @@ -268,18 +270,28 @@ class Modeller(object): """ # Pick a unit cell size. - if boxSize is not None: + if boxVectors is not None: + if is_quantity(boxVectors[0]): + boxVectors = (boxVectors[0].value_in_unit(nanometer), boxVectors[1].value_in_unit(nanometer), boxVectors[2].value_in_unit(nanometer)) + box = Vec3(boxVectors[0][0], boxVectors[1][1], boxVectors[2][2]) + vectors = boxVectors + elif boxSize is not None: if is_quantity(boxSize): boxSize = boxSize.value_in_unit(nanometer) - box = Vec3(boxSize[0], boxSize[1], boxSize[2])*nanometer + box = Vec3(boxSize[0], boxSize[1], boxSize[2]) + vectors = (Vec3(boxSize[0], 0, 0), Vec3(0, boxSize[1], 0), Vec3(0, 0, boxSize[2])) elif padding is not None: + if is_quantity(padding): + padding = padding.value_in_unit(nanometer) maxSize = max(max((pos[i] for pos in self.positions))-min((pos[i] for pos in self.positions)) for i in range(3)) + maxSize = maxSize.value_in_unit(nanometer) box = (maxSize+2*padding)*Vec3(1, 1, 1) + vectors = (Vec3(maxSize+2*padding, 0, 0), Vec3(0, maxSize+2*padding, 0), Vec3(0, 0, maxSize+2*padding)) else: - box = self.topology.getUnitCellDimensions() + box = self.topology.getUnitCellDimensions().value_in_unit(nanometer) + vectors = self.topology.getPeriodicBoxVectors().value_in_unit(nanometer) if box is None: - raise ValueError('Neither the box size nor padding was specified, and the Topology does not define unit cell dimensions') - box = box.value_in_unit(nanometer) + raise ValueError('Neither the box size, box vectors, nor padding was specified, and the Topology does not define unit cell dimensions') invBox = Vec3(1.0/box[0], 1.0/box[1], 1.0/box[2]) # Identify the ion types. @@ -331,7 +343,7 @@ class Modeller(object): # Copy the solute over. newTopology = Topology() - newTopology.setUnitCellDimensions(box) + newTopology.setPeriodicBoxVectors(vectors*nanometer) newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): @@ -378,7 +390,9 @@ class Modeller(object): def periodicDistance(pos1, pos2): delta = pos1-pos2 - delta = [delta[i]-floor(delta[i]*invBox[i]+0.5)*box[i] for i in range(3)] + delta -= vectors[2]*floor(delta[2]*invBox[2]+0.5) + delta -= vectors[1]*floor(delta[1]*invBox[1]+0.5) + delta -= vectors[0]*floor(delta[0]*invBox[0]+0.5) return norm(delta) # Find the list of water molecules to add. @@ -472,7 +486,6 @@ class Modeller(object): for atom2 in molAtoms: if atom2.element == elem.hydrogen: newTopology.addBond(atom1, atom2) - newTopology.setUnitCellDimensions(box*nanometer) self.topology = newTopology self.positions = newPositions @@ -610,7 +623,7 @@ class Modeller(object): # Loop over residues. newTopology = Topology() - newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) + newTopology.setPeriodicBoxVectors(self.topology.getPeriodicBoxVectors()) newAtoms = {} newPositions = []*nanometer newIndices = [] @@ -883,7 +896,7 @@ class Modeller(object): # Create the new Topology. newTopology = Topology() - newTopology.setUnitCellDimensions(self.topology.getUnitCellDimensions()) + newTopology.setPeriodicBoxVectors(self.topology.getPeriodicBoxVectors()) newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): diff --git a/wrappers/python/tests/TestModeller.py b/wrappers/python/tests/TestModeller.py index 58b46fbd6..2a256dcfa 100644 --- a/wrappers/python/tests/TestModeller.py +++ b/wrappers/python/tests/TestModeller.py @@ -308,44 +308,56 @@ class TestModeller(unittest.TestCase): self.assertTrue(len(matoms)==0 and len(m1atoms)==1 and len(m2atoms)==1) def test_addSolventPeriodicBox(self): - """ Test the addSolvent() method; test that the three ways of passing in the periodic box all work. """ + """ Test the addSolvent() method; test that the four ways of passing in the periodic box all work. """ - # First way of passing in periodic box dimensions: set it in the original topology. + # First way of passing in periodic box vectors: set it in the original topology. topology_start = self.pdb.topology topology_start.setUnitCellDimensions(Vec3(3.5, 4.5, 5.5)*nanometers) modeller = Modeller(topology_start, self.positions) modeller.deleteWater() modeller.addSolvent(self.forcefield) topology_after = modeller.getTopology() - dim3 = topology_after.getUnitCellDimensions() + dim3 = topology_after.getPeriodicBoxVectors() - self.assertAlmostEqual(dim3[0]/nanometers, 3.5) - self.assertAlmostEqual(dim3[1]/nanometers, 4.5) - self.assertAlmostEqual(dim3[2]/nanometers, 5.5) + self.assertVecAlmostEqual(dim3[0]/nanometers, Vec3(3.5, 0, 0)) + self.assertVecAlmostEqual(dim3[1]/nanometers, Vec3(0, 4.5, 0)) + self.assertVecAlmostEqual(dim3[2]/nanometers, Vec3(0, 0, 5.5)) - # Second way of passing in the periodic box dimensions: as a parameter to addSolvent() + # Second way of passing in the periodic box vectors: with the boxSize parameter to addSolvent() topology_start = self.pdb.topology modeller = Modeller(topology_start, self.positions) modeller.deleteWater() modeller.addSolvent(self.forcefield, boxSize = Vec3(3.6, 4.6, 5.6)*nanometers) topology_after = modeller.getTopology() - dim3 = topology_after.getUnitCellDimensions() + dim3 = topology_after.getPeriodicBoxVectors() - self.assertAlmostEqual(dim3[0]/nanometers, 3.6) - self.assertAlmostEqual(dim3[1]/nanometers, 4.6) - self.assertAlmostEqual(dim3[2]/nanometers, 5.6) + self.assertVecAlmostEqual(dim3[0]/nanometers, Vec3(3.6, 0, 0)) + self.assertVecAlmostEqual(dim3[1]/nanometers, Vec3(0, 4.6, 0)) + self.assertVecAlmostEqual(dim3[2]/nanometers, Vec3(0, 0, 5.6)) - # Third way of passing in the periodic box dimensions: pass a 'padding' value to addSolvent() + # Third way of passing in the periodic box vectors: with the boxVectors parameter to addSolvent() + topology_start = self.pdb.topology + modeller = Modeller(topology_start, self.positions) + modeller.deleteWater() + modeller.addSolvent(self.forcefield, boxVectors = (Vec3(3.4, 0, 0), Vec3(0.5, 4.4, 0), Vec3(-1.0, -1.5, 5.4))*nanometers) + topology_after = modeller.getTopology() + dim3 = topology_after.getPeriodicBoxVectors() + + self.assertVecAlmostEqual(dim3[0]/nanometers, Vec3(3.4, 0, 0)) + self.assertVecAlmostEqual(dim3[1]/nanometers, Vec3(0.5, 4.4, 0)) + self.assertVecAlmostEqual(dim3[2]/nanometers, Vec3(-1.0, -1.5, 5.4)) + + # Fourth way of passing in the periodic box vectors: pass a 'padding' value to addSolvent() topology_start = self.pdb.topology modeller = Modeller(topology_start, self.positions) modeller.deleteWater() modeller.addSolvent(self.forcefield, padding = 1.0*nanometers) topology_after = modeller.getTopology() - dim3 = topology_after.getUnitCellDimensions() + dim3 = topology_after.getPeriodicBoxVectors() - self.assertAlmostEqual(dim3[0]/nanometers, 2.8802) - self.assertAlmostEqual(dim3[1]/nanometers, 2.8802) - self.assertAlmostEqual(dim3[2]/nanometers, 2.8802) + self.assertVecAlmostEqual(dim3[0]/nanometers, Vec3(2.8802, 0, 0)) + self.assertVecAlmostEqual(dim3[1]/nanometers, Vec3(0, 2.8802, 0)) + self.assertVecAlmostEqual(dim3[2]/nanometers, Vec3(0, 0, 2.8802)) def test_addSolventNeutralSolvent(self): """ Test the addSolvent() method; test adding ions to neutral solvent. """ @@ -874,6 +886,12 @@ class TestModeller(unittest.TestCase): validate_equivalence(self, topology_LYN, topology_after) + def assertVecAlmostEqual(self, p1, p2, tol=1e-7): + scale = max(1.0, norm(p1),) + for i in range(3): + diff = abs(p1[i]-p2[i])/scale + self.assertTrue(diff < tol) + if __name__ == '__main__': unittest.main() -- GitLab From 30a5370239fb315b886f15e17dfbfd91205e086c Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Tue, 10 Feb 2015 11:18:17 -0800 Subject: [PATCH 251/338] More support for triclinic boxes --- docs-source/usersguide/application.rst | 10 +-- examples/simulateGromacs.py | 2 +- wrappers/python/simtk/openmm/app/dcdfile.py | 33 ++++--- .../simtk/openmm/app/internal/pdbstructure.py | 39 +-------- .../simtk/openmm/app/internal/unitcell.py | 87 +++++++++++++++++++ wrappers/python/simtk/openmm/app/pdbxfile.py | 4 +- wrappers/python/tests/TestPdbFile.py | 21 +++++ 7 files changed, 143 insertions(+), 53 deletions(-) create mode 100644 wrappers/python/simtk/openmm/app/internal/unitcell.py diff --git a/docs-source/usersguide/application.rst b/docs-source/usersguide/application.rst index a52d55513..5f8b97290 100644 --- a/docs-source/usersguide/application.rst +++ b/docs-source/usersguide/application.rst @@ -572,7 +572,7 @@ with the name :file:`simulateGromacs.py`. from sys import stdout gro = GromacsGroFile('input.gro') - top = GromacsTopFile('input.top', unitCellDimensions=gro.getUnitCellDimensions(), + top = GromacsTopFile('input.top', periodicBoxVectors=gro.getPeriodicBoxVectors(), includeDir='/usr/local/gromacs/share/gromacs/top') system = top.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) @@ -593,10 +593,10 @@ This script is nearly identical to the previous one, just replacing :class:`AmberInpcrdFile` and :class:`AmberPrmtopFile` with :class:`GromacsGroFile` and :class:`GromacsTopFile`. Note that when we create the :class:`GromacsTopFile`, we specify values for two extra options. First, we specify -:code:`unitCellDimensions=gro.getUnitCellDimensions()`\ . Unlike OpenMM and -AMBER, which can store periodic unit cell dimensions with the topology, Gromacs -only stores them with the coordinates. To let :class:`GromacsTopFile` create a :class:`Topology` -object, we therefore need to tell it the unit cell dimensions that were loaded +:code:`periodicBoxVectors=gro.getPeriodicBoxVectors()`\ . Unlike OpenMM and +AMBER, which can store periodic unit cell information with the topology, Gromacs +only stores it with the coordinates. To let :class:`GromacsTopFile` create a :class:`Topology` +object, we therefore need to tell it the periodic box vectors that were loaded from the :file:`gro` file. You only need to do this if you are simulating a periodic system. For implicit solvent simulations, it usually can be omitted. diff --git a/examples/simulateGromacs.py b/examples/simulateGromacs.py index 65bd4e340..e0513a043 100644 --- a/examples/simulateGromacs.py +++ b/examples/simulateGromacs.py @@ -4,7 +4,7 @@ from simtk.unit import * from sys import stdout gro = GromacsGroFile('input.gro') -top = GromacsTopFile('input.top', unitCellDimensions=gro.getUnitCellDimensions(), includeDir='/usr/local/gromacs/share/gromacs/top') +top = GromacsTopFile('input.top', periodicBoxVectors=gro.getPeriodicBoxVectors(), includeDir='/usr/local/gromacs/share/gromacs/top') system = top.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) simulation = Simulation(top.topology, system, integrator) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index 024c871b1..ba9007366 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -77,14 +77,17 @@ class DCDFile(object): header += struct.pack('<4i', 164, 4, len(list(topology.atoms())), 4) file.write(header) - def writeModel(self, positions, unitCellDimensions=None): + def writeModel(self, positions, unitCellDimensions=None, periodicBoxVectors=None): """Write out a model to the DCD file. + The periodic box can be specified either by the unit cell dimensions (for a rectangular box), or the full set of box + vectors (for an arbitrary triclinic box). If neither is specified, the box vectors specified in the Topology will be + used. Regardless of the value specified, no dimensions will be written if the Topology does not represent a periodic system. + Parameters: - positions (list) The list of atomic positions to write - - unitCellDimensions (Vec3=None) The dimensions of the crystallographic unit cell. If None, the dimensions specified in - the Topology will be used. Regardless of the value specified, no dimensions will be written if the Topology does not - represent a periodic system. + - unitCellDimensions (Vec3=None) The dimensions of the crystallographic unit cell. + - periodicBoxVectors (tuple of Vec3=None) The vectors defining the periodic box. """ if len(list(self._topology.atoms())) != len(positions): raise ValueError('The number of positions must match the number of atoms') @@ -107,12 +110,22 @@ class DCDFile(object): # Write the data. file.seek(0, os.SEEK_END) - boxSize = self._topology.getUnitCellDimensions() - if boxSize is not None: - if unitCellDimensions is not None: - boxSize = unitCellDimensions - size = boxSize.value_in_unit(angstroms) - file.write(struct.pack(' 0: row = cell.getRow(0) - (a, b, c) = [float(row[cell.getAttributeIndex(attribute)]) for attribute in ('length_a', 'length_b', 'length_c')] + (a, b, c) = [float(row[cell.getAttributeIndex(attribute)])*0.1 for attribute in ('length_a', 'length_b', 'length_c')] (alpha, beta, gamma) = [float(row[cell.getAttributeIndex(attribute)])*math.pi/180.0 for attribute in ('angle_alpha', 'angle_beta', 'angle_gamma')] self.topology.setPeriodicBoxVectors(computePeriodicBoxVectors(a, b, c, alpha, beta, gamma)) diff --git a/wrappers/python/tests/TestPdbFile.py b/wrappers/python/tests/TestPdbFile.py index b15425335..5c9ad3a9d 100644 --- a/wrappers/python/tests/TestPdbFile.py +++ b/wrappers/python/tests/TestPdbFile.py @@ -3,6 +3,7 @@ from simtk.openmm.app import * from simtk.openmm import * from simtk.unit import * import simtk.openmm.app.element as elem +import cStringIO class TestPdbFile(unittest.TestCase): """Test the PDB file parser""" @@ -39,6 +40,26 @@ class TestPdbFile(unittest.TestCase): self.assertEqual('Na', atom.name) self.assertEqual('Na', atom.residue.name) + def test_WriteFile(self): + """Write a file, read it back, and make sure it matches the original.""" + pdb1 = PDBFile('systems/triclinic.pdb') + output = cStringIO.StringIO() + PDBFile.writeFile(pdb1.topology, pdb1.positions, output) + input = cStringIO.StringIO(output.getvalue()) + pdb2 = PDBFile(input) + output.close(); + input.close(); + self.assertEqual(len(pdb2.positions), 8) + for (p1, p2) in zip(pdb1.positions, pdb2.positions): + self.assertVecAlmostEqual(p1, p2) + for (v1, v2) in zip(pdb1.topology.getPeriodicBoxVectors(), pdb2.topology.getPeriodicBoxVectors()): + self.assertVecAlmostEqual(v1, v2, 1e-4) + self.assertVecAlmostEqual(pdb1.topology.getUnitCellDimensions(), pdb2.topology.getUnitCellDimensions(), 1e-4) + for atom1, atom2 in zip(pdb1.topology.atoms(), pdb2.topology.atoms()): + self.assertEqual(atom1.element, atom2.element) + self.assertEqual(atom1.name, atom2.name) + self.assertEqual(atom1.residue.name, atom2.residue.name) + def assertVecAlmostEqual(self, p1, p2, tol=1e-7): unit = p1.unit p1 = p1.value_in_unit(unit) -- GitLab From 8aff3b7426840a53b7fb410e02b1cec484ccb66a Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Tue, 10 Feb 2015 15:22:13 -0800 Subject: [PATCH 252/338] Replaced TinyXML with irrXML --- docs-source/licenses/Licenses.txt | 25 +- libraries/irrxml/changes.txt | 33 + libraries/irrxml/doc/irrXML.chm | Bin 0 -> 63988 bytes libraries/irrxml/doc/readme.txt | 2 + libraries/irrxml/example/Makefile | 24 + libraries/irrxml/example/config.xml | 26 + libraries/irrxml/example/irrXML.dev | 76 + libraries/irrxml/example/irrXML.dsp | 124 ++ libraries/irrxml/example/irrXML.dsw | 29 + libraries/irrxml/example/irrxml.sln | 21 + libraries/irrxml/example/irrxml.vcproj | 147 ++ libraries/irrxml/example/test.cpp | 40 + libraries/irrxml/include/CXMLReaderImpl.h | 797 +++++++ libraries/irrxml/include/fast_atof.h | 139 ++ libraries/irrxml/include/heapsort.h | 73 + libraries/irrxml/include/irrArray.h | 444 ++++ libraries/irrxml/include/irrString.h | 664 ++++++ libraries/irrxml/include/irrTypes.h | 101 + libraries/irrxml/include/irrXML.h | 540 +++++ libraries/irrxml/readme.txt | 110 + libraries/irrxml/src/irrXML.cpp | 147 ++ .../openmm/serialization/XmlSerializer.h | 6 +- serialization/src/XmlSerializer.cpp | 147 +- serialization/src/tinyxml.cpp | 1839 ----------------- serialization/src/tinyxml.h | 1799 ---------------- serialization/src/tinyxmlerror.cpp | 52 - serialization/src/tinyxmlparser.cpp | 1635 --------------- 27 files changed, 3693 insertions(+), 5347 deletions(-) create mode 100644 libraries/irrxml/changes.txt create mode 100644 libraries/irrxml/doc/irrXML.chm create mode 100644 libraries/irrxml/doc/readme.txt create mode 100644 libraries/irrxml/example/Makefile create mode 100644 libraries/irrxml/example/config.xml create mode 100644 libraries/irrxml/example/irrXML.dev create mode 100644 libraries/irrxml/example/irrXML.dsp create mode 100644 libraries/irrxml/example/irrXML.dsw create mode 100644 libraries/irrxml/example/irrxml.sln create mode 100644 libraries/irrxml/example/irrxml.vcproj create mode 100644 libraries/irrxml/example/test.cpp create mode 100644 libraries/irrxml/include/CXMLReaderImpl.h create mode 100644 libraries/irrxml/include/fast_atof.h create mode 100644 libraries/irrxml/include/heapsort.h create mode 100644 libraries/irrxml/include/irrArray.h create mode 100644 libraries/irrxml/include/irrString.h create mode 100644 libraries/irrxml/include/irrTypes.h create mode 100644 libraries/irrxml/include/irrXML.h create mode 100644 libraries/irrxml/readme.txt create mode 100644 libraries/irrxml/src/irrXML.cpp delete mode 100644 serialization/src/tinyxml.cpp delete mode 100644 serialization/src/tinyxml.h delete mode 100644 serialization/src/tinyxmlerror.cpp delete mode 100644 serialization/src/tinyxmlparser.cpp diff --git a/docs-source/licenses/Licenses.txt b/docs-source/licenses/Licenses.txt index 7981e0175..f42b3584c 100644 --- a/docs-source/licenses/Licenses.txt +++ b/docs-source/licenses/Licenses.txt @@ -2,7 +2,7 @@ OpenMM was developed by 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 � 2008-2014 Stanford University and the Authors. +Portions copyright � 2008-2015 Stanford University and the Authors. There are several licenses which cover different parts of OpenMM as described below. @@ -126,4 +126,25 @@ freely, subject to the following restrictions: OpenMM uses the PDBx/mmCIF parser written by John Westbrook. It is distributed under the Creative Commons Attribution 3.0 Unported license. For details, see https://creativecommons.org/licenses/by/3.0. This library was modified to move -it inside the simtk.openmm.app.internal module. \ No newline at end of file +it inside the simtk.openmm.app.internal module. + +7. irrXML + +OpenMM uses the irrXML library which is copyright 2002-2005 Nikolaus Gebhardt. +It may be used under the following terms: + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. diff --git a/libraries/irrxml/changes.txt b/libraries/irrxml/changes.txt new file mode 100644 index 000000000..ecf0a4637 --- /dev/null +++ b/libraries/irrxml/changes.txt @@ -0,0 +1,33 @@ +------------------------------------------------------------------------------------- +Changes in version 1.2 (13 November 2005) + +- irrXML now supports CDATA. + +- some small bug fixes have been made, making irrXML compatible for .NET users who + have to struggle with the famous bool return bug in the .NET framework. + +- There are two new method overloads: getAttributeValueAsInt() and + getAttributeValueAsFloat() now also take the index of the attribute as parameter. + Thanks to Patrik Müller who suggested and implemented this initially, the same + for the CDATA support. + +------------------------------------------------------------------------------------- +Changes in version 1.1 (02 July 2005) + +- irrxml is now also able to parse embedded text correctly when it is shorter than + 2 characters. + +- irrxml now treats whitespace quite intelligent and doesn't report it when it is + obviously used for formatting the xml file. (Text won't be reported when it only contains + whitespace and is shorter than 3 characters) + +- irrxml won't crash anymore when the xml file is malformatted and an attribute has + an opening but no closing attribute. + +- Removed a documentation which claimed that the xml parser doesn't work as the xml standard + when replacing special characters, which wasn't true. + +------------------------------------------------------------------------------------- +Changes in version 1.0 (14 May 2005) + +- Initial release diff --git a/libraries/irrxml/doc/irrXML.chm b/libraries/irrxml/doc/irrXML.chm new file mode 100644 index 0000000000000000000000000000000000000000..69448cbef38eef42ba589a6b1c4103440e691452 GIT binary patch literal 63988 zcmeFZWpEtJvOhRtwwRfjnVHdIW@ct)X0#-WnZaTvi!8|kif8N`7Blhiw zjo1&TI;yfNp)%_?-4k8eJtL{CBnAQi0Q5g9&_~rR)w6qjQ>U7eoy*QZXW;8f47p#N(#S4${!W_H}gXu_=EiB zy?>P7tl#B#|2Gc`6acVH1lFM=oI=cg{1ek}+u!nk7X?{y8C9s?R)6z>=syOK^u&@P z>JlP~KuO1{x&Im}3w=cJA%dbOR#H}!loMA1O8&+eCH$ePq@koNDhmh%&%^i_Da$KJ z3V#TrR3q#^hAN6OANoMaS)S?ae}>9JGC;{GVqq*FQ>jVHiO8!d0mUCc2FSqBlZZ*0 zI$OvZSl9w3`V$5mvqI66$O}nH$|)%WB^(*1@T1a`sHq7$IoTOm7&u$Fn#fq#S~>lW z823L46ddjBO&py)K8$ri5r3;ln|Qd{IU4^TJGB476jF9HF#(D{RKAe;m$(0BA!6Wc z0F_7a#GGYD?$$trhj{u(Dz}D8z*}&Pvn9khU#u_N312%~Uj^4=H zz{$zP=`Y?SN3sIjAD)GyqaLFkqlMk?R?kAu)WX_C&(XxdSkK77+FH-hz{rZ$#>B?Z z#PKiVh&sF!J-Yw3@gI-jS7u%8%>UWwcLeTwHhR|oa%9xpG|L-jS_=*_v z2~0C2{m&+U92puonfy_XPNPYufu%RLbN4Vav86L|asrC4{nYFUL;o9yzm^=Bf){5D zPjBjCYvgQUXZvpycOVOBQ2yrX{g(fkH8hMR-wKZ2%-YV-!1^!s=o-uVxc32??6s!q(WtozC3c z2q-qjA&KE{h80k39$`SUGt9qLexD%$Vt3>@aPPIfMiMt@BjSOk2Bi1gp& zf8qE#;wVj!rp@rGMSaFM}En-OYwgxsPPWA>y zCLh{=fz(D8PlWN`1b@!Nzr>>wfu;Cpf6M>dSs0V;m!pCGKZO4U)|hRzgwOv;<8OR# zDbgkXgT~)L$8@SEiv9!uF!5p+6K3MzWMQD?6k%qh zWn>ij=m{~g(=sp!G6-`rigF6G3;WPZ+B!KK*czGqUcvA0TZ{jXT_~D3nK&yO7+RYE z0>A@49R5@OLEs+*{z2d$1pYzb9|ZnE;2#A3_Xv=KgMrzD?t-|0064stfc?jKV;@PtLdVWR$HC6P^dTqtS5D=(&F{$n9sPu;j#c*l z;J=3-tAPRhwY&S+x&c4{5P*;Ul)9`80Q^t)VZm^e`a|8ox%C9wDSY%-{apV|0kTk?EfMEAn*?Y{~+)W0{1b)zmd3|c zU6W|uKc1bN?pTftIW@?JL#0eGX(~!nD9bsPc!dOwMxF1=eN81)ZrzR*#(SvY>wyP| zh8!%6@s?_ZV|m^6l4%W3WGkZhyE@rP|F{J70RY6z08ul*yKnpb`l{FRneF`w7q?^8 zay3`G%5m!I-V&{jnfkaZc*W8{(+cNkEh-RI6Bp+Yi8NR$N$^-M%HRioS9f#GaI+{+0#d$|bVhwRI!pM|OFOJH zOdb@N*H_0>^Nd#cjN%gOki{P5;Y99y(g_JK5ib%XWpfJ_TzMWzF_etYP;oKf zQ%oTq?ac)}Lgaz|naLH&G@X2ffC`dtlr+$aGPEoKa9c>Pi_VFLPvdJpAXc4HV0$wBeUF($ zu?$sVPl!Ndp!cxMy}MiZt8f9JK6}iO$>7sy4m&2|ml)r^+0Xqf^jM{d?6jUc@tm52 z(?{cb?{X#jY?G+)R9pm{7R^eE6L&>C$a0q-~-X{E&!aV0n= zYNzm);Au|4rU87)WKgH9(+B!M85-?^`HeV=QoL{RM00F?ElTjOnm-+eNf(QkF1AK0 zY{v(_mfc!&R+eSWEXW>2OBX*V-O)w)&JGlW6qwrVt!0kLu=ekR--GMrsQ19uO59#t zfp+I1*hN5A8_$w2GdCHO6fjFb9VY_y29sC$L>N8v;*w{Wz3i^lxN z4?@`kqXftM`#oZ;a_``Z*lbx$Tqk>~5R=idLuwsZFZ$h?Z{*Vn=!&rqfj%*8xGAvZ zWIZIL;W=%1Cn{mRI2gzDWKJ)yXIX+2VcCQR^kOv!u@#;)u@=Ik_Xrh`(?Qbi@wRYl zV}9udIqzi=O*9CVsl?GnAwf_Er+;Z_jD|NGpQynyC>UdNG^wjSr@gUgwl>?DC=IYH z$Vpdj84nME2uV*C;hpNmQ1DD3V5wOa#JP!Ppu;zcM~T1`8Cz)zA|BUpgxgQX;=o!J zE2=b!RsB9sMf4foSpft+o%87{ExE`>Tg>-OR}$^ZSUstodjBB?23O=K2}-KtDefH!=L!Eyg;O&2ut{T?*(QB` zu_f4Y8Q@Kx_RA)CgSpk)GL68R9QJ;U)GQPDvQFEri4TqLoCxPd- zvtMF8c>|W*K0Jf@72Bmtgz5rK?-31gzCnaaa|CP{Z=Bqh1Fm80Tn*qbo+)2S>2m~f z3E}#Mwvn$6DAEK8l*3%L!N?8|`$n>k5+ZECK3+KZjA0V2SUcRRiueu@>Vd=i#2g7T zL&9B0LBXWz!E1W~9FJd`X%q8|@)aoDGo#Uwlw9l%JzU}GFG^+u*r$SSn^EeTs~GQU z8}HaPnGVo;OkDi^d$9fP*31t40l-TB0BdeL->K2k>Adx#;%<|aMqF&*W(*k{Stw@VRx*G6bdF)$M!@Q-C~;D1hl`q1U%f4SWT=5LXaRU>umK zC=>}fWqpJZZ2bgC+kr}kI!k<7Z5aaSxFgTB)#K_;p)XxN_E5s6T4K) zMg0NwIICRThEZ<#TAI0o$8e>rXGg|1`oQC1iLL@apJWoaX1a(A!gvTltYCynAEZ)F zVoGA<<)TtSOUbnf`Wok3Qc5ulb^*DJ!nMSw??sd_f{ilHS1Asli0GXHA>wE*Vi(^@ zy@s!QrB@Fb;~UfzeWG-!=X{d=KUu+U)xn|ZEE{E_%tK%x=uGL$?eIx0sN zo7X!)L{OH@oV1OXGS`J}#1hPoX-p*3O@(^Sun|Vn2*K~8!V;mmbrDU5- ziW%pjJhMO;k<1euKpmslV;-7xl=V7WR^22G&V_>e6?ia_**}u0<1;nQic<5?azYE$ z8Y3}DTMlFKVOtXZosN~4U$)nru=VKoyzN}l+Cz{NO46!6s+F#R6(92V1C9i_lG033 zSGV~7da@Cb=2pk@2&44PwvsU9pP`UURwcNifku19JdBdkw=6H;xbU5yej!f^$V#KC znG$F3Ge0C3mE|H*Eu{<>DY`B-sPD7Z-l4oGevh?ToiHa_U!Z!v@0L~~ja0_bv6)m@ z#m_*ZkbR^)Tuc%wi8&z|SorakpHPvJoyD1z(|nN~i-bbD37k--K?0L(h9RyX_9s#U zK5jhtZF#t6Re6ECHLMeDUtr0p79Cn0*NsD;RXS6~FyH1NbvIH^?lSBN+x?EaLBCKJ zdfrw%5kEVYnSb7k^-BCwk3?$S5(}P5eoqXP=0H=HJkC%0U$7+}iYB_`Z|MVpKVnLq+fdW#zkpWPe{FAMA$nwgn+t;OU}-yhudE6g;8#bI$RM18+(4`X&~ zK27yeoief)3k9@eSS>bTvN=)_v&eY3>WwpfqWq2m32S#rG%7HI-7^|vTnv5e*!hO_ z8s*$_Cdd{?V%2ewqiMIgkr@gFCP8tb@l3Z*Dfe`PiQRGkQ#_9v<(l4NCPw2+3Ir=V zCxc4XLe=vxA3q!I?!)=Le;-zDCrUWQ5t`rU{Sc1X50)*es4F!nQqK@DhqVC^N*jq`Z73S4qAFk6cI6&ClgQG+ zNquuNg7S68i6s)xh07l963xrw*}C^+R5~l)dd5mQ%M8TKUtnFlO@;nt+Il&>R)8U| zeGB@ros$JX^A8-5Q{nPppBI?8vg?-8KG9pRBZ2Uo@V!XXyCFUFpJ#aj|U1 ze#JAdK4(HP&qaFbprB2GqA0FhQoG-IT?~0w^vZIJXU89vHtQurWGn#lf+Bua-gFdn zFJ8v`sxO`!?S5HqdUUoHGFz-JU_rc3bYDi^s_S5#niQP!@^jT?$CSVoZ9o-Hr@YN9GgRtK8a-@QQ=8JCtiO6s+;c;e ze`cfICRC)+rGOYHqsLPbB}D>Cro%n+C1Vr*OJq z5XUU+yAvysfe^46RqNf9*y;zpVPQ_rxBRFlzOW~>~>4MKxsUebzSV5Pm@V%1~f|Oz3vv}1gsUGfhtl!LD z?%z$}-BL@?^nvpq=We~D zff4;V7r$rD-PGZ5rTehF8R=o_e#@p7hg_KG*(7;uK zn#41$a^_V|t_@S4i)rrwbgVaF;n-nOmo1o#7d+fB459 zVapR4opTUV3>N&D4dHE-#gy)1Ib!dNz=N$YSRV7)ARI8(-2l<)ru%XaIU8iK=wcuI ziP(n;#r0ln}ExZrFv!be?q) zDE!Bc`FVM0hi+bBR{z}!Ilb6q8fR=1<@c{l^vajzMKvy4DS@_b5F8K%4Eml!C8oHv z#t{2zDQ)>_blwmv749a3aVV5Ms27)6%*x0dPnWAw%}jN zBvLeHpa)?i;ORVC*g*wL)_|@H@H-9`PMNeT67esCX8ckEdrtd>sxRxczZ=?zfYbQX zLc@#r96rgOu6Q?u5;T|Va0SsOoH7lbkGhiOWcCK#Q(7f=;mJciaaE$SQYqxEVjRXe z-1scpM%wODEJ~!y-X!YrzF+>w&AS*)lQ|1cZfor2yaPAawumbQcey<)oUazQi#F>y ze0Rb+dIT|O??MBT_SuC@?(%9DQF8g3wW_UG*MT`iGb$_R*WdtXXZBA z-$RK%6KJo49JTEXbm=ZeFT5Hhl1x%wP07(Tqyr)RQnji!Q=TP)fpNiHbYnxyrMX$> z)kbq!#<32r5oUWpyK@9>$KBH=(Ax~+Y%snKTFgWPSM6)>432wmmg2^KoMvvPNjoJA zP6r-=oNnK3y>S(F<~^y|COBhXmEGXA<;b{Vyw|`72hx}8-!|H? zaq=hAiU-F7ANd2GM3@y(&3xHWQK$~_t@wGQ^=zarZA|S6TUr{vyV;6}DrJv7yX0(N zsz09`l_x&#HsB9&kWU2S)oT@PdH58)8G^jLb?0Jn>bF~PL_ym)FetG0z35+uH4l0G&N=ikZ1s+qBR0hyz2~0^E3KelGUk$=)CkBL@YNSQ{lB?bavc zaXpR}zKLhWb|-Mbh|2?~O9a9*8huL|?19Q#O9qI)g?=wHFca0V$j29GMkP&d65sHK zP0u0L3I<`gkPoWi@;dMUE6|RkPLl0eabi0GJ@!V>BdYx>LNVYEf5s>V>)k@(-J;u7 zO23AteHRol9xl{J(Kk3c3M~K2s!T_f8dwrvyXgs5zX<^*}s_OZ#i|k z*1@3rHEYgXFiT%s8<$`XX&1tIpYr>j#!#xxGf1i(wGyMi&`|PZj4ARKOBX&rHMm4h zH?-v=l-lw0TXwL*XKGEqZL zB~g6AbuI!1C{@s2qWiKP77vTA_tI8b~`X z7ww|6alztLu0?7i-sn%SOL3Fj*ic#sqbW4TM7+EjYy{Tq-Q9i)Fj+P8RZY{*he4$H z_Vr?9c|e?E7xGEw9WXp?HucNm$4!ZsAfcl=1qG--g`V_$AvO53ncZ-b$W5F)^zqPW z`VaXub#sYsQ|=8#e0RRNB>ZpWU!`e(sEPUXkpk`F;a^#;nN_kHN-ylT4!}rhKZo&C zOuHUNwh=TCzqfzJA2rrZ?eo99HSZPU<_C03UbKT;5e%QvvvH4NdDKUX%ivgsZs)}p z>zoH!qSVb!YN@kKU|~`yNd% z?d0mwtSd64T7D*_)SR=}T}mNwM#h`Qa0!B}vQ6XJQNtWe!%;NbytCVZiI4HCIf>RM zCmtHc@M%1)+*ndoDyKw(OvamYN?g4m5nZ`qjbyxb_3KPAD&8P4%SB_C;;#I(=d_D# z8uQws6c5aKePjERWQxwn!Ouq+E1Jr$Rb5KESD5B8=r_-1az3tiV>TI0uqXR732Md~ z`)ybrQj{4D*uTm;wj5aZ^Rk`Rb%C!^Y&1r+?5ut=$D)t=*ULuIkCyMK&^%W*v~kg| zYtM1{$@AH8-*&oQ(x#feU39q?k5FZ^DP2pAPgf5oI?R@}idspPue>A~1=5gDzBFBF zP;0!BD>$v484sl%e56-O79Y1QcZ;ACy-A>mSjb(-8}iT8Ot1%*g-&p3P)ZJFIk&zZ zeVawfnODK=yP0?OZBIRwl(rOpN}*y#4Jb+$&`;pkLvKNiNuIg$nNI^IleuD_5n))p z^4afRazMN8T~Vt?v)#z#0@gk0!&LXtPJ<;knI?NSNr@eien_E6m)G=j86p4NZi-In z8Y#<@(#qFLbw=|*6(s!KTTT9IYgLJSU}H(yZTQs$-BHm=l;kD3rn^bFtNo4t*J5WZ z$((~roLJNzPow7JV9KnM-ssMB6qXnfUMZUSx^JTB6wl2Uyfj}UdepvEG~^gorD0Ug zhfhC_wtY3~l7_4U(ToG1x+EIxeRjE33}Kr|QhVqR7g9r`?;M)((>`k*IyuL|>q!w7 z77aAR6hA{F$#IMNhBQ3+NE|x|efL%Ao9c9{c?!bO=*02&21I=M!`q67^ZdRY>ixlMXx|M?asWMi3w%h=b ze-A#vWl2ZKX!pH;odkhCFl3gIQFRu#8*yrd;5RcyTdZSQZDIWKz5_b`xHyQ6BK9)u z3Pf6#a*R2|Z&9B@=MSFD)a1`n+EZq*j9->)GM!aha#F+}?Fy>IpMFHqPEmWvO9qUD z*`PGckkY9`cvPaOUT)qoh7uo5GSNzPQq#T1H4VpGW?#uQ;)i&oE?-xwJ~`U;xoQWD zp5XZeBe`_=C&wvAL@aNf9!%}tKOF{d9W%A&^IRWWqHxhCYx_@!7_#-=LvdoRW~XZl zU z2aJh-VWo|ZI(wm=%}Jo^c932P3`}ugV<8`ZhHLEPEdRoQA}n`^vm<$jJ}qxEP;#n) z{k)@2%VS`A(i9^E%G{nJA+RrV?w0QNbz>Ea%PSBWY(jBbU*!kaShuo6-K$HRr09U6 z@XdSUkXoSH7qv}lgiHqEOf!BuOv4XYrUibnURAY6H=NcnLmzNH2mrVTTc;3zr@ z+>x|(2SN*cS;UbcbuM7poFw4~mWvtCzyo|@+&emO;!}wxbVhF%pxIxVbcUT4b_>el z$3Pjbsu2he=g%#n6}gvT!mZi>H;_5F(Z+chS>Qa$Nd-w$e0bxl-NcoX28Zv~yW*g+ zk65N%l&%7*>)5xE_YabX5C|%lgSVmZjqd~gkAvctfaQ55Gwc%Y3q1V`*Uj3^CW@qS z!5Uf5eDO8e=$bC}*uzd-hL>uSS&meLxz|JgoetNZj@GGa+Z;Hbr@WZLMZ>vnSXaby zas6ip*$s;r>ER$7fiPM^ zMwA~|CWQC@dg_&ace?;Lt82KT2LgIq@0HW8m^mnA;DYLsrlaHD?y7cooMiBQb;>6b z)aSF7jwT60q){imMd`DVkylRad*PST1^gOJbY`1*ASy3kE0sBl=D{48)3-!s~B?S67jyRU>_Q-jGxg;h9Oqv z;5FcZ#)7`kct1^%-Nt6r&YV^)MqaJl-aJZSGomQKZVj0bw7pti8mZEd{p&&WV6uFiK zRk!?6B=kIGgV{nvBl1;Vege<2Q&4}(_cV&|*V^Q)#&tyhe7{s{(}MeS*I-wM!a5l} zZ%E(bBNIQ}JuJr|OE2dqLx0%qs(z!3edwu3;;zG+Xz)o!d%z~6s+05jd-uiZO9A&I zhww25ZrKSCQvCe8Jf*kTl$Zp{MWpL{(oXUlIsd8aTeLi3I(ifTm+Gh5(`c_Vrs|T{ zHN_iz)u2Z$BClMx;$pjOottPhE09{T*AoPTtNTLViMyN@;;SKj7*J@YXJXdTE}Z-c zwOi`kbF==*0f6~mPhdd=KAynBt8`Nx0G}umG@Z^e_=9QzB4y6Xi?mloW3!_w_p5nO?OCg$@HeAT6WKE};`k=L{E{M_t{x~mS=&o9JUO$90oOjelR#< zJ)-0DX`64m;jTkf5-kCL7(11a)LlMK!rc9$kfhnBMxsgO!r$#YOohsz;(bKBf zoBM8{$W}ug=TR-Sn2f^6o-E6NkIY{BK@1Zw&eEKaUb$6)R`}I})6fif6~e|ADT=UI zb%L}Gw`CJq{D60A9N-dF?^?fYS~!afcE25rN`KmOJ+<^yedJARltdy)neuim5PN3}rU<+2{L;#@6gojs zJuj56Ip&Mmk<^$pXIIYHs9_AJP2gzv^|6W$@-g^hKBo%3<+#z{ZLfF~?QZoCu_sgR z%sDRZvN6$KkId3oTAqry!)yr$CB&1w>Mv!J-Ia!EOMyEF$tTElMSL$$;McDytZcHL zh}cD$3;Uo{=sU^CTtUOdDQ5Mv3GNg}=Xa)+HJZbrnPxEMp0h8BW>&ra4cMzW_ic9T z-aWovVDR*P-bfzRU>uLd7rGO~{ENK=4oWn;t8%&)GFgc057IEQ!6id>>>^-c{E`x| zvz?Hz^r6Zfa7uT;X05D=nLC9Nq|-#YnWPA0A=5ey%BTx|I%5~Aw^#w! zW2jIz ze-=-Vn&%BulJ7BN9O-fwDe<|ku|aim>9Zus4_bbycQ`4-i7g|aIL#`Z8PC4nqeR~S z0T+E_y9QT=qFSiJ*8${C#YrBBhw;cJEKY;aWo%bAK;pc$+WX8w>;_rp3q)ddwZWx$&YlTvL&nXUK6tNhxD zOftzX>6<+(r~z-`D})fSkAb1Z>S8eQflN<9spX6E(`6BneC?g_nRteP zB#tKSXU}3o`&~!8>;A*vM+S(|Et@b@V4)Z`u4MTY5ZI`}c~MaSp|BDv%kA1mXx~GRk7Se0EB%oq2&IZ!( zD+Jla!A>17zb7vPC`x3Y9mwjtMUUmee$oi&uWUbT&K|xREzMKJ6(cI`J&zv(w~svv zy!5056fO>&;N82$=3(<;+-;3Cxb=;HFkLS$XwcRiUWhaRm1p9Uy@bl62 zC6FSWA8lUWEL7s?1oMzo;1f@E1p;~jTY=ye9V)5r;6iq-Mmzor4ekzz-8zlc-jd2VyX4e8$$wlOQ`?Nl z{o$nJ#z(yw($lK!nA7h0hPY)kJhAH^`}XC||0i5%w{_jh&i1yFn><%`w2ha3V+HkX z_2if^$|Uc1(CaU9XLFyzEMABN+W9Shz}(;n*^`r;o$*mfHS^Jo=kLQ*{!~D_C6m*m zTZ>&SzAUqBi#VTjUoum(q8;#G?YLPp279w0fp!}pquN}8IFqsy`X%(4{#HZ_+i4eg zA~TJ(^Zi_xyOM(6=1%Z9yVD*~?i4#&eW$5C#YV^2i~U#Xw|bY_CCmO$w_@!O6EZMY z`!y1EVplm`C#_#5!D|HE8Zx0qoXSe%a`H;J9f%y*00T&X`}qV83kbNw-J5JMzgfVl zA31;AfwBCL)a-<1u98@x##gllA`qfUjKv5)4==Uz=?1muN@2Uh)K!9L;XCaXYjb}<%+P38Z)GXOv z0W9Q{-jXai$%aRXSg@AV-d|%&V6$-M2`#ODD09;>MQ*NAAxEEqa0LP~0b;o{c~l#H zi~tmb^8t)mAO#?kPYM7;9UyU_@4`qFTy?|V(`9kW>hYds)C&OhEgRs0av@1}fWQKP zBS}bKV8nhC1{y`+9>ksmEGQt6pl=if1Q05wGP=;&H*4{IG=#t`l;BJ9605U~HkOJQ z6qpnzVg9DiAkT}zH@PpmZT3FRFk|(WOh}IWFkJOQgyem)$oF+2I<@nvje`SbQ0vs3 zvO`mJSM`JUeS?_NU%l;QT|m{*@6qWah^U0z2P)rbNij>mnbDcYfmir`oAbzobBOY7 zjffC8Nmt|h$_>qGB7OY!^`wS4+on;C3X`|`kYG-`V)E= zDl1@y=|{`RV%N!Qg6ea1c1e|~YWY?GIy95f_hfN=#2H1bs~nyO<>Q$!^VEtvyPrP7 zDQ%wUpBbW2T|CzA3%jkRIWE~=#yph^X}H>q1s8$`vT{FvzQ8ot<77NB&CtEIn#e(- zA|j!@lHitQ{t1UOb{{CWkU7Wp_)K*Q{Kh|Ou$}{1Uof6Y{sZ%+x9pIKb&VByESpRo z>5Cv&=agie@WU_h}z5Su$uzJ`#`D1{M|W`&Mr3xW6X;%CU{-)Simpd=i&h7c@rEURQ(G*5*Mu_oOX7 z_a0iZ9m_&=6pnu!-oS{t<_(2NVqYtYpR}PMq?mTg#OA1hG(ME^IJ{%6GDk6Pn{;#ECcVQf5rTpfrkR@oNzW_u&>vlr?^wByUMR-p_8>z|%(ufDmx=)RDU z+_5~x+l3|$6OsL2RwHRV4^m@ZTj#H%ysXPlO=qQFrubcv2buk(UP%1BA-v^U5)SU8 zFU1)u-110UQt8oRP7ZN+@8J=w&m*EcHr8ys|x=uy5f*^ z+E9s)(*X7Q8)lyZ=16C>jP;EFvBgFKPnQfu*9(bf5|)33SmBg0h2D+JCw#GiMPq^L z4J;6Vq&Gj1_5iy-Kwt}O2%Uagg$HmH)5nd>@|>p7gDNG>iQa3Xu0xbHS|UL{clW~F126Y-6(e_o;o05GuI_s#W(1Q4fP zGx(8py77mlO>(DY0>|kU`p<3b<#7b>PRJdt`6e`%Z{W-`>?zbE(*F1i%w)1lY| zm1`tY>j7$Q^pzMN>E=c5EqdX6s|Sv%jCEsfyvQ}bqvSp{Bnbugx>sGZhO9UE()AW4 zf8G;K16F_7pk8$&m2WDw&`XZayQlc28@kh>l8lpb#EcVcUzFnLx0Nj^(g+8O;4)DM z0jSmM{bT9GRmF_!hhVz;Y*@5Hs5rt$PF1letI6iUJlFkAgr2F!;N}?&q1AVP<~kPB z+EFok=!&%1vneD9=YY}{VZ)uZM#t`85Pioi=8Tk~W!%(DfRe#QK^3iTXTgQ8)wVsJ1T zQXl~M`i=D-y17Xk>~xrfyo+S1W9-Ik%^dxVeNT8&VzU4X*%AS)Suqdc@FpUusbSID z%MIel81P^74gzRf5#)y2VnK%|oCF2fs`{y@7zsu0*g$ZfNA_g6c8dcDSOi$oJ5=!? z{3RtpL_vD2SsZEOL&C#b@hZ@kvWb)tpId9uZElCEOce9KDB>9kr>bWIk8qtQC{2tE>V%=2WAK7p+DXlnD> zDdS`#x|JXuDHI+388Xd4nxt?rKX8{VBKH32{xhGgG88c#QLW!dSB|5?7eqGq;LPrP z+>aZwNygSFD(eoY8~ePQ_qU-$`r%H5U(tf-Sn;rmOLOr*55BYoA>tsJTFa*NtilcX zOCrFAUS&+H5sNih9+k2f738xvt3|>`pTc8rz`*ZH#r?Qs)?>o}AOSvp=05#Qd>fPY zVHNQES_c8_3PvAjGjG~`j+CUd3y%IQ_BjACqN*m+Ae>`)sOKggL)2dl5>_Rq?u4&j z7auVDC)Z-c{5#j;=TbA;=AUh;5U`*xPq`B4p91wsb7{S*ke|iojc#RO`E0ducA+)q z`JCwuK)?(l$_%gvhfw}GM-S7eU(idI28Hzq5sqtB458xHg?R>3s^=x@@!i9a=%51RuRJ+=CcCM|-Bw@7Ci_)e7RM1~< z%Q7tdXc(D8)b5p8z2e00qGIj~5UE0m>o0 zSZY*LmQb8g4^Q5wn))L zEvthBk-R%6+nK&kwcRYFgVH!Mb$gnmA^QY!eqSsYXYUuhi1V29zLxN;h-pv<#}dUM zQJ(j92u{V~hqC(d7h4qS{faidy+6v?+E0GIo0vU94U z-tUw-o0;w%TLCGv%_?6GSgWJpXfEf|2F%sa*9?Uy7~2k%+Yv1F*t42*&)~_faCBOf zLV={lGh&kA)`7I@M@faG{p8~hhe^FJw6I8!Bt$7V)twX-27IHts6f2bZjZI9Fw`QS zMrF{h=FljwP>9goahtO~sD$p1fk4=XKhwW5PIP8fGQ1_KqlFD;MOqL#DemaiM}J?! zCI*`kOQ(!nC*FZum+d-jmKUuA;#L!MZ_=(9EGmw5svP}g8rZ}aKo3`)ck-*$3I~F} zfS%Sh2)S4BG&V%j5zsAlWdEEbv!T!3k$fxwhyAK4eE%8gOri^!CwQME!API;nSoG< ziCpeIhvgE2iNf?dqt2rz+t1AziStyOSMMY4d%uZ;R`2HT-Mh-PbDQ$|eN~7;+;vs? z&?rM?c|*eG!zLqY@p(iGGOSaW!-8bO^vj?n7eDzVLkjdowA5IUbc_xyJ%SAG&_ZB? zF<4A?@09Fa-K#msLeB5>6FbscSorc#gVPZP_Zl`+@&+TL40T53M%^ltemv~$i9cS5 zXvgb3%*GMVV_opDS?QgINa|NjzGZuV=JxdCIpO$pf3q!mjc{4x#Q8e+9V`qdIyF5k zp%NySoeEKZULLGmWvQ~Mj_DQ(0Ja@ypf2?Ol~tXv$i@6|L@2Gv*D+z#u&+fSRf2Y> zGF-WJS-r}{K5uo)!@ft8y;bVq(;n21#ZR4DYAPj}Wd3M*H!D^;5y!2crL?|+s0ZTvn!QnvK+I+x-th%dD14sh~2%^P9Desw{mQXYi zfahlEZ;<6_&sxFw>$9-l-!F88G+m}w@Wp2nKUHsa9sQ*g>Bf3O) ztjs`UIb|HmL5JB)SFPwJX6XkCJug0EAL>B^oPVO=g~CRr>xpu|Nln*X(v9(8C+qr* zSCJ{l9kn?AdMylA*QUY7v-G9>(%yE?kWoS>VrC+pxSf;vkY!a(lP)yv0~u-RUB!I<8!4-oqa<2b0x0OZeMxK|dg3m`fGtJxyP00@ZhoS<;x%58{c zK?0mtw#WMybNSc+h-QgF8Y1yK`l$dw8y0vFI!#c<0T?3=CcwvE#teXHs*4D#mJ2W~ z1{$yO$>(O3Fb1U=05$Oc{N>k?wfZap0}yJpaGbDlC~czL`@*`@2z9IsU*)IWCajg< zv-J=HRfIw7`l>$Oh2iRT+p#6XKq{zRHKZ? zy?k}rabgk4S2D$+zuBQ@duIE%sJ!C{Z~j`C_0`aXduAXHm|~TQct>tXWy+#^m1b zO@(GK_4E-;jvq~yaZBbn-kivY#R2h}7Fvn_v^g*pxk{$;YoB1WJEg_H312~uSQFqo z4YqEeneMG*mh*|ZC$Oihn?dDC?jGGYh1)e>;whO-lO4_u$C*-1Pr|b-jGNp14(hcq z#{cOx-VC}028}9ldfMv!`m@(yvKbWlI~elltxvI@|A^j}S2Hxb=(e!y{WPzc{))Ky zeR0u>cs-YTgK2)fjTc+1iOKuioAZ+rZf$}aSU+4%V>NS9A}M9T5kw%0NMtRPHJe@qIyBYdeJw!&rA@8h!@ax51{g}?0`}=H9}0{z z&yKBcRQxDNKBtaE5#Xj2pSKjs^W5}n8vgVs#jN>A7F$#Na(n5q6xDN8REiIh6mWxcK8~N z<-_oy?ayQU!`skchvb&_JCAnF<=4uxMkY23CD>u(ci>uc$1;6PF|hj8#mg_8p6SiM zU^xoz6l=z6hV*TeZj?`Q88j1Hi}ISiwQP@Y*FEBizoAyfA5QiNXK*f#-5CdL7416R z!rKjk-1m+6$2~X~s;>2!E%bZL#~BS6sZAN(%HI?^tTFGzucN<3645_bP8=&Y2UEyh zM`n1G&aYfMAt}d2sqM6qPa+DBQEM)suI-b%VQd(3hcMQ63nWud?x@x9XqMs}F;!bv z84eZJMiSz=QPv(rmiDmxm}9Sfrr+M?SFXeZ+dC{3Ha$bSFL+V9i9g#IX~DSQdld(2 z6iB0|07g&Hs*{_x6!@-G*YvI7-8s+*qEW2?o-2w9jN?$FZto?`4a=t(AN;I;PbD95 zTKaxrUG9DmR@XrV%5mK$YWI@=SS4pRW3p>*RgTbDDCt_OSM&HB!Vgk6EHU;8N6jRdE#6svaC_sw}!zDVWn%h;KE4zW@3U?}a z?@xSs#bCNTmtZh)N;eq_K%A;z*&_>E9fNIl*x$!Sk5DfcK2qbns;p8FuC+MWE;Cp; zn=!<=>Lf0>d+w_wogV#}%D?w`zkc<(2p3)UogOdF;Be;K8~R1(MZ?m%P|_v(`@q4I zk;5}(Am&HC68U|yx~zKE?8*t=#-5We3RFAlMne;Ll8oY#BKgJ_CV4tDk1vM&e^Bn}2}RG9i=OM%tWn4nZvVhO z;107VHckTR5`=+Hb}IzlfLyGd(7Plc(&U-oYS4IkN98KiB1ucFrRG+gT})|2mjytw z0nqb@Gx)2&BlWoyob_|LrDJV(Z5iz&>3KGdo^h&_W|1KCe*6u27X-TuEu6Lg=MaxN z>V74weqSgaAg^G{)?2o3Y9T+LxLqvNgjb=_J@@wDcEysJ4u9O@OE9`m$%cFBw@C#S z@rSw{J;dQ8O<6oNA|1GIiiZji{ou{v)U*FytpC|)21-?K*zw22X9SLQd(Yq3FpqnE2;}Os4nc+UXj;~as zh@e5D$q<(*-?KSIO};*oj#%*(HvuBxz0WL(p&BpYZVeg@#@ZG2p7twh33VwQ`>}Q& zEEKz4dtQgB90_}mqDrPJyW|M!GiRGwUT@e#1Ic58JXAr@7;JVE{#~1fmS-{Ra(kVV zMOO=-eN;;+2cj^!$5D53a|S_Lqw)lXf2*SGy^B9%)R<-V&s+sPxAj?J4j-=sm?a4% zkz6YL@g2YkHiN|P`yB7}rjcX!3*<~(Lu+(&!X=(mk(?ZE^u_^gN#d+mZs zKE6uhQ@;Y|K@Vv1?#MJTVTgU4lFx0;Cr1D{1DKDkPu1o6)t6jgbP`CL=igv6*$23*vv zP^>cS16HQL_JFurCTaYVe6~C%~X(fz{e@|!^%%&Ez za%XY;Xl3KkB2HUdP1vdQE!eL;lL&+M6;G0rthTlbZ<7k&kDSq?jw)E7WQz*SXO3(J zX1;swH)GcZ-}~AB1M@!_KRIMMFF*OXS+ujmeHQLdm?cmU%YOh@n0CF=e#!3?BZcD#-EF32PY?j~UYgjW%V45Q{3^F5)9H;%ad4 ze+s0Xc8N~}VI$+zA-#x@|L?ekxg z$R9LL^j@MZ&a*F9S=HgD)#EiGP4J?svY}5=PpwJUq*GFgrQYDdKh-4YhK%4eNsw^2 z{-cMYbG13ZFU#EXvI<6oS^pzyNwya?@^(?VK%ikI zuQasIKe+mh9R79!{x5FGyD@aeEH;Tb#$RzA1O1oI(<^TisR|mdOVjDIv5hF+%5zPa z)a^CSuWA6pcJpz-+5J+9A)0{q5BATYW;i+kE&kd)lPHGb{V~5u9xqbSHvl>h0AM^8 z8X!B3#18eQOpQ|x%K){kr<59E;m(1T==v!8{oIk3>%fc$SMQ*dRTwa(4zPnAN5R|1 z^G;M8Q=l*gAS1`xnPeE2z~u)m+JRvWFh$RrX|G91^;4FRng9S!d8`Giz`O-BK#R3U zp(A6oMzqYIEmwz@c_9yg?27-b8);G}h@lwbT$l6QfLH)H?@bO9&s=g!n4JWTmuk)geGw#7NfhV^DlONni zP9IarRw@H$3$4ZS-s^R?q;@aXMLiY$1c@m5p1(>v-=h#Ru819HKfY|;4gS+U^}N3$ zr_)8EJT9B+aS=%VVyVX>I?N*90#j}9#nVrq1r+}!$?Hq;GO^T=wiyD~grHsc=P-mWw|DQ|M*=xy{s3gUXq^{XevbTZu{LK>;U z4>VZW0zUYXxoLkA?*AWv$wSIt1LrC&-(4Zw$>77D1F@RFScLs^&)?wOl1JV}N*CAc z2DHxH^$T6wN>;`Ua*ab3`zES-ZsivjUv5F`fByucks|YYj=|n30UjHULs5aFcvui; z)xeoMaNK@YECIlhBg|Ce1IVKHluezv+_X4YuB40?wwejg@ZV10VwZb0(B-PEE5x^C zsc6vZ$EvLMYMhl<;$T%&X<3OVmX$I`f^h%hE{TJ@6QFEX<~=Eg<*y`yz(UAY7R)Gw z5Uf;7vIyZ-iA9GYgjnUQ8;{yRT@Vle0000&000yK0674MN<|qcS46x&Eh$>odp&|* z8}WEN^zc6^+ig;!LZZ@A8$R&%s><564?EF~ zwskePwgm0>lRDynBr3zeZ(Ixk2q*v`K>0g>5C8y(9Kz8S0KOk?_w(!7Zr-}^f6`tiI|sjgkuyi zYoL=OO(%ITjfgR6X>0_`!zalSqEP(*#o-qVuPWv%STJke*=hoqoua|*7=iO6`)~c$ z`m%&Tpm~xnC}gNMqclMjA28DD&qs`i`pS`F0z;jQ2g820^8oY+9ejR`fgc1;pMj0HM|p_^EfxCom#en0X|BF^J?>@r?l7u{0;+b#*hHhKk!$1nmAcQTY(@TodU#u zpvaoRu?epLn?Xv><14%{Bf{&6vFn{kF99$vBC5w%9n{+qI>?Nt=Lo%!v*W#uXNo_;L}ABy z5-&txm_LW3<18oXI5LF%+={_rWTK(Dam!Q6W+yPij5CS``{WtAKhFTB_bABpbmtdw zn4b44+6OK4L?ulhApfO*2xC2N-j*J;-#m8-qVZ&^Lm6d6_ak~v0~hEaKRUm(PXhYq z`PZNlKEJ=5*Cc3b(R#!2&IJSXPPY-vgpk@D2vixr145ZKp%S#KsJ@tuWZ9zj(&~{f*k7_eEAxS2ixLU8(3!UkVJD*Qpr?p5N?7WY7wfVF|IYW|Xtpng|1JC=zctAqSXygPxZz2f zs8@osTBxZ61b1dCLIBzpPZ^r_H|Ci5sAz`m9qt*rjPe0h=(JgYMhUDC&< zlqY}X|5HKgM>{g>J3o;<)){{nBpu?Mg2oA0>wdqE9qrbGk-33Dw(Se*jt%3tU zIsSDFR89ZD><~dsIHEkzyXP}#(tjOY+M3aU_LE9Elt-RyoHOCCcu0VwG&<3|kr$jo zyy9~}R!W8uEBxPo?hkQq`*Y*?)Ncyw5AJ{d*nwJr41_SVKr86HM-XsehFkP?v|f(R zqNm9#?Uwg}Sf-`J{vPP<zGB4EI{pzF#00@% z9v+JHM*hx+GJBb(U)Kx&GLMO|M{m1Rs7JGc9L)6~;k*|pEFXUmSl(H&d-)Xm-?Szo z&Mni0&bAhOUPLlbwRKq6fzM5_`leB zUF25;`U(55v+}0<8%?b75@qIPMonZs0@C|4^Sn1PUe|JuqraoX)XKk7-p}|a-evWI z|2UdjUQhlnDDZUXW2K$upT=l>d;<+9@-yFb&IMae6VkJjna_i3Uux7qzBA_))K&IO z_4>6KYPfwb-%+&ki`0WhvxnkY@0cw9gL0M!8m@Xf!G3(x=n z0AB=#;1rg6O7xgabz@`9=RcHhMs(7-@9AUT&Hci?`Z8cI|2cg_+160iPvZ*#y=)!{ z{Vw+5C+`FKBxp2}mXjv)iSC1*r@ify?8kex5BGEb#W?sG_^}S&(>>H9@+aBD`MPhh zzoz^pAOE8T*mC}?Pe0!(Lj*^>N1DGr2zem&J%H8<4B!X%Lb3P`B+dLM&SdEH8F&9d zOQ@5dedt$B03)KRHV_zwg18Dg7_xGr!f9aH`~f035n?(;$O#1=^$H;veKY#mL(jrQ zs|r8@rl838BM(YsUYBp>BYv(weX890ETyq=hydiO>Z8el)P5G#BZNatO_&Uy0yp^a z6Rf1Ds8$tCl`>C2h!!Gjj3C`4V8tKLCWNgb0A~6?75Z0JgBX26`+gqCb|N6Ev^u1< zH5O2Zrq`V0CxZkEcIl+Idj*35JLC>uK)l50001GfK&i1gL;zPoLlnQ0M^{Z&`<#Y00000 z02csgh{=?5>Jn{)5orewAuOQy2MUM)zyJUM0R9K3o|s7JZ>bIEKXc^ygADXxMSUXt z0;e?ktfvWe)30xGYTvrI?V|sD04z^^v8OHVuKnMyBujJ8c%Lfm&e@Y{B_}6JyiL?} z_}%q-ru8(UodkNRTBhf!MZ=rbBH>H(k&{#-)KRTJ&#JknH%6S@y%IfLEz`5rBH`KC zk>|QbuGO^yJ+3tjpI3|YL{`b!N)qUmu+@`cCHyKQG635E0000V04%a8dvofaV&QTA z2$F6`0RR910002F14pvdlmF(-o%^{f6iJKqJ(ws4n>+!a?MQn0-#NyVE;bMjG!SWL$Bp`TK-y&v%w(kiP$VZP z0#Q(Qgni=_;`Yz1|Niht4a3u(-^J97G*=#US5M36^4Gin0PoA}3E6lr#K&B(myOJQ+s|>>THGZ>XeAg{-c@R^V0B;L~bwSRMX1uFLNrFGBLq35!se^Tkq@|BOnKVAf-k3xqJ zv1Pj^OO>jBXh7;h%Kwuu+C|eJ)Q7@1@iC9~5&p`kPsrnKOpj@#q+x9m_yJJ1fd_v4 z%%BfsI_cGd;3hSY+t_pg8DY}~Wl4eGJqX2jT_a?qq5;7S0AMKfW}4lp{0O{ZU;spp zr1~<(O@OFGVDSM%2&c-(a7ZUX>r%^`e2sI&q!7*b0{F)aZf0N~35Mi`w(4AkdsnYiiC8obE!+aiu?`&2neIuUL+X%JfMdyVt|Ad1p| z0kN~4>Gxx09yfpP&CNcR_>lU4t%kAPCcPZ?HECYh)Q6cxD)1p4k&Ek!&~0?W1sV%J%Ao9>z%2U|e*lQJP850BeSlC*%uZ?Kr9+h9A40K?mlS1X zej-aL82c^(M$bQ5vVmv^f;vhbjd+`uMaje|@g7;t{A&y6K9}6NA@(6dy zGr122F^O-8yB8oF^rs7uUw-OCge2pR4;b401%L-b%0gmc_%hmJ6C3gcG44A3NoB8H zNjmid?5+Jj9!=VcJ`c9FvP3-}N4jN(dN)O$X8wq@k3NNLaJCOBd1yb{KBz>5^s?P` zRBo~=*^pS;K9yu4vQGB2BoF^-wBsdvWD;oXUAD(1kv7`0ZL3W7I3(5}s%(!+^4yqY z+aH(qQ65r=Q^aqn6p&gVJ&$)+}7jf=h#QtC&Nh6looVFgF zHy!~?wvptx3=IGP0FNKMXJ?22002_}0QjTCk2G-QJmUztX_3se`dDO$*f#AcLW|zv zPfvF(hG}Wi@LPJl)BhDusVs)HDgHmzUd=oD{r8moTez18h{o$%OQ{){booamWXqGa z)QRFZR^|~)VqDan1o7M{_F*MG3=S&l3WBzx!m9Ehhe5G5J?3LS(ULGxQKb2@6yLzs zngzxfT!Iq+|4=tnVWwFAJb zD7S@jVNw?^%mD+mdlk0bBBf?wq>8S(&RGB+ZsZ6`p%$hAjSYnyYn6 zMKv@Um>~PKMW*Vaj?Ju_AJkb>UjyXgH=rXqTHS{V=;6{IOYnQSSaf*B zWi$FU+h9FK#mz$Yfuk%1H5vu4VycNm9q&GPb?emqlA@?fISm)Nw=PR6lXn|u_RPYA z606fezRYIJ=2c+XEI3Lums11-u>?9V|0yYfa^h>u>wLBxfe>|Dh3Y#96d@zIFdH|% z6I~m2TjN@T!RG{4P|^fwZ%s`=tlO`xPEpj%R1MAI8MhUfv4kvQWciKwF6Z($M8qC4 z9~E@&eIKH#CtkBb2hboKkJ7dQedq#^xn@vY7OvV6>qU$t;2LFc)^`C)p=Po@N!RpO zc+6IumMxf(+)SBzvmWf&Bq&Rjs6&_EnqMPN68O`Ks#UGUa8N8nrFYoK1TB|8GO!F& zo|9^Embz2DrJ!K1b5+a1Iy#nvpuAmZtYOeM44Q{h95(DXdoFv1%MW{zS-gijI$2FG z;CZ)GlNkyuZ*kDVkXtV{wWBE*m}vc3VO9Mzhmn_B%9l8pTJDSAab{)@FPfaFg^k;= z>*WoWV%rbiUNj?Ey0-{#0l4mz?_-pnynomWx}|E-Gbm28i~NJN%Bo zpX0{COt{`}!bWB+`k4w9lsD043~u5mzQ$3s3XFnWTDa+CXtZXllyO9-@1i4#-cb{~ zeIXx9UJwaASCa*_g#Mp~oBn_{!6>UOe$`eAgbIH`0^H{+Fdjly4qEyvToOS>v;UVCAS)r;~| z%%3!TnZL^^WQpdHh@i#uC{lpfQ26BBuP&m_eCeO2lC@%5!U*B2$u3 zH~pKPjv?V}XPCPWmg0C(4JuKZ8}MQlN=&rokoBuHY@8MbolGx;qp2_tTNHdXV{%)r zgEGQ9CoHy%T+m}OWOmRS>5Mgg6UI^&4hKD`NL_o051@81UMcl;E7z;-u3}FVjTP!> z*~fwrlwuGV7`UXBXfw^l&7p`J=v_T^f6lKFW2FVS-IF=3YDw3sQo$8K%3tJQ-C zGXDO$*g`F2%e{xN?zpIRDc1Y!g+$MZO|XSF;PnbIEr)T)Q%APo2&C0E(rw74F{`EQ zrRy-k091#-QSe|DMGR9;M!gP1n>kB7OIOu3?3>e5Ce18X;5{}oJ6KaHorh7p1&u4a zbIX!$HIr?63x*Ot3dd8^J-o6A6` zXWi_Z`dKWRBS^gx?4i*PPISJL=T-{SmwmZgmRDE5xLAf-wI$YvESog|#dxIe4GO&O zn=lV?yj3R$KyZpU(~^a$ZReT~IL)Z7rU1NGvmi4!p1%;dC-BP73KS+7E%Y)yCiP*V z*-Ej&h6%pAn$3GfPcsWf5jz%MFcrTthH$&aw^X=|wVv!v%~g+^BFZHYw=&tItx|?o z|Gh8<;bxn%i4oxwrm|h~TG4Qk>BEjfmmb>Zp^0#)HTOd&!RiU-cJ_?3)fxrLl)593 zF1W$Vs8}Z#+q$hbJi^8a9>IO9@+%1ZQtlq4J2d4K6Y7>m1z9=@3nAi8^c*!86MloZ z(-P5!L)OPwbRey2z!yj5Era98w=^ac>g?Q^m_x0@O5sWw%+>1Ju%-NrECX|{)$eE) zI&X2q=nGbe@@hAwH6+)Q6CF4j43m~{PQSNi<2&t(RM(!>5ApZqQeZ?*p>0lj__2KZ`3M!n$Vob#SYuJ8}DZW30MYIe9XD=1io{0$@V2>cX6x+=*x5>AP!7#>H&B z_D8L#;Y+?2Yop{zc?YP7lw2q>iZp-LeKuUDI>@&xzPpp=g~N>C(s5_?7C0`G%F&pXKQVRre_2)*(Q0$yEViDE~BrdY+i&JLx(#?6WkX1Jd> zLKSMH&qLN9Rl#Pj$)Tnl$uZ3L8x=_g|#BZKcuAvp4wHbV=~@_ds0h`Z)n3iHoJH=$=OKcS>mqmDp(Qe7e0(vz0&UeTTgrY zdbo<)C`{g{RbG&la>vdtw*N}IVer8;=9;ehENe;jqbIES6sd;60LOdQ6hoH>mF2QB zGt~sQ7YYl@3(WDiX#f*u`;ST6LhVbAw-vm^hx;YTOn&YbS}xje5Hd^~*SEZy=efHd zOJpNgH_UH7!5co$+^b5}5&4LweRq?z2VAR-BBm@299PGzAgrs-%H;W!GhB#7Vqn=BzOPFDB zt#&%2d=30HwN#+}b_Jf7n(?F(uQ^yT$T>aJm z0qu;7vlSX=!VAXGWg795o%~*i19H>>yJN<>E7$a5svKSSd)6u}Hr<^{-e%B+PG^0W#vk?k zN(l#94D|Z=O~10@psjDgu+8(dd&#y3Z;Lxw&{>dTi`8ui=`y@2KURXQR0^qTPMMSL zb0)9~AyiG3kViGMPM#W$G(M*lYwwP-)_r$ul`6}FajY^wlff6R7CjT5>9?%sh)w%K z`}+JB`*^e1nB$Z5EJQKZR;uFH{aGO|>6c-&UU&tlQK3C+YSEIHuBaZ^it-$!#9JaE zHF=?0mSYXaZG&D|NwUTXL`y$ExnUXMYqb;&3b=`7{QK^5l1nWa@60vQ50~BG^IFlX zELMU5+Y09FHLDpuyCDrhziE|e+e6dpPQ^w~waK)T+ehx20WJhG7360qtj-D-{NhSH z#75RT3H_!UZ_l%Am!>G)9SajLC?~3PE26d9A$J=Jd)pyyoq}nQH1VCH1lw3V%YyA_3kRX)%@I2^`v*Ce)D zY`OtmmizK1HE_yU@DW)I*iYHv+Fu{w0kcy;dC*5p{TLSm+i*?L-*@x2s_Kh7((300 zrtK}AwA&&mQrbu6vrROWz0pH<<{MAkxZp7a%|Mo-Y#8v7TJkx2U#;4`?eVkzs*mEZ zS5(=xthIwO3;U-ItY?i>ns|xxbMeu-b0x znfmJ+eKWd&Y$odXRHZv=MPK%Gd+tv0(J)Kq_eG9B#dnN!7syS#Dxeo}-}eNjE*pE% zw=iYyQnAIVH{Pcxvi&cnt$?`= zDzallz71#?Euv2Tp&YBOyX`9#($U7PU`z~)`_|#HXt%#z9u?q|@R>^;h53fsQ3qSQ zRx-?9y{4fnVJT1TJIyr$0mCIUa_&MXCbGf-oyoOK-3gIh;spzc0w<3J+3TLFKowhL9pX-Ck}yo1;^;Z<98wOYPWIPaol!`}OSC#XM9%zS>*K9oUB#>dbGx@A zZ1&xULoHK6Phr{JtL}>(db^j}!Xq{&BBXn*^qJ;418&F_m4wG{x}noIQucY%p1EZY zc5mMin@W2Xa|4?&U>Cm|H|y&H+Su-)gG%42M-^=%L|L4gHp{bie(gB@p0R(a_ABJV z3Ia@gbzR+Rv(K!-7Vm~T>`hApUYHFP45ez@F*`z&Z#}|l-r-{Ge9R+rT|Hd}xbC{Q zD;u<0Twl|}RIeQ>lwPjmUo#s6c}zQGcZ!n_J@1tJVHyqRiSmNT|L@*-Mh%WXnzuVAPA~~l#x}%p`z^XH zyuG>bG(u(jZo_eTUUM%vk52FC?M|*uSI>TNCt$!ZFoQUhgN=kSb5fa496xMhwDBLG zq2na`TivPDjBu)Ja`bgOHaX6)<5T=-+a0RAxd=%CWe+VITa$#9*5U8q4Ju86eX<&m zj=k1VXI*(OC?K})3Qz2KxSlKVtoR)pnLeruwiLFWp>C};vLhQMo<(nLkK^%yXlo)GMGch49K^2<%A}f2|`Ilkxu@Ai*AM1&Y_TU;9 zBj$~ePYW4J^u~}O{K;*+Wy_WwJ9g-kz}Fr%Y836uBZ{IHrQYHB=b!J?sgpj{o;`bx z9zDuud-A-F!5ewK@&XRz`s=SZEPVIw-Ff>mB{6I`{*?!ttrm?gAeEPUj=pR|4PRw7 z{y+?ZrPK*@{Mpe2e-suKV?czQi9E>4H(wnn%0Ht|j&c6v$L5z;h~#zjQ`Az1{`$A) z$xunDk1HCZ#p%z$>j_oq-4C37tcQh_odn-#yU(+!3(O%VFj9(+41Ir z(SMnzpFP4b?ediNfQXp+R72!i!%)D=bI(0zcwk0aS{fW}J_65hYu<0 zxN+k~j323K%~pBIwVY-krje)YMc`ppsC#2F=jsp)vLa`BUb69vc4?oqy1Krh)Rj$GDLyO-A$7CvUu{QrJ2-C6BaHz`!Nf+3n_%*x7I zwrrU`IeyK|%mj~&I0$I#TTe>v)< zo_N$5$QChl*8?x0Qdd(-rUPWucLyZ#h){+xKq zz%WDZ_2k0q&%Cn(DLty>E;ZEuI)jO(g)lW5zJQ!V3mF1#@Ue0Z`cO}X1=T)VG$Td6 zaRmP546bqg>0y5L6l*z8`F{y>@&c{&VbszpuhQ_0a)%V|$EoC6k|B;OO_ga%CGS0y zU(*pdBHI!8*8r#t4m-yWJB*~6nvFH*Fj)!+xgkSMr;#{pi_Ii@g~nEqCZWx@>*E#Y zQIAxwliG{x^!8p{mv$A`Uk0`pXnVAexc<3MqpI2zS$5*Z8mrmNOj^wliTyKxn`0>C z^=wn^NTC=@(mCgJ*m(y}{e6WZ4t94YxWzS5Iscby6tCNn;Bh>&Cuq*Utr*ikq?N@Z z-FwyRl`3zgB#5g+jj?ceI|w~I=-~G67_R_W*RQn5v%y4#zMGdHVkC@l2QAd|Iqrr@ zSW;6{_wCyUeV@;V8~m>#dGu$_oZ*93^|7ZGPmrO0m!_F5MGc9ZJb5x};+}#e^(FC} z2My~zxvg8b-gx7UbdTgackZ;dW!46U6{4soeBdFjhK2e0=bxz(tSi~DJ~^$gE@J_p z3iaxCt1wf6rO>2U2d~njgMtpRYl6}v0XP01)BU^cEel#e3MD{^sT{Z#6co@2an_JJ ze*E~vi4*DYiTm!mkB*>Z9aJAZF>6b+Cvsuz*uwSm&p)TxKU}~1>MPCH!X>d&43>@^ zJJM-S$P?DPb?auwmPNJ86{4uy16QwJO-R)j248hfPEOEDwoW_VE4XP=ofjo$ybcc( zyCnSSH`ia+jrZ?P_aB??FUa)!=ZQbxJaK<`I-WNjQW|2wJ*{0>L#m{tq-W2b7FI0A zuGUY8GHu$zH8V4lzlX((7wenZtl_O)lZ=cEH0M)KJvDdkT-Fb2%T9%~Yu65~9v>f% zuNU`v%@HF;5G;aLvPIfSDvZ)qNUi80?ti>lY>KY~)4Y-5x^9yHv*`jx{)K-3QonzN zxcZj*3+9REo74SE&ClQR>%^k2Et1F$kD`D0;fHhP%;9q{SqGGkkJvCDvnLj{W?>6g zPzXh7;)>o%lOdO+Q5~P64z|Hb;0X>u3u?;(QgVghi{(ssTmEIzXEeh#}occ-%ZmVitbCY z+02T%zKHk4cl^Z{Ur?x|+@lX2I@By-&?h!+@s)iYn%yxhNn=?GS)uPk3vmFNg)Iw6 z=_>@-B8L@M`NN~veCM5aoiBj2xl)mGmekW)%v!K%HpGNurcCHw?K^O?)PU*-O@`IGA^MibY zGG$tqNte<;U?!a_{*e4YZA#QZM^?8%BV*~1$ECT^Xby~Y0v7FZV3ONhPkc%&*5D(E zWq#VAoaR=E4lLFxpg4gx8FCI_kh zeX@HGDd6cdCD_a5dGK{e;qvA8oME7V9JyS2c9Zg4iNzXf8oDGN_LY!AhoBq!ZQBNU zUKmRW0RC_>GYYWpXm>x~KuH*NUa*!&~QnXwWAr~t|#CkH60;$zu1dEdha7cDatXw~fMQ|m= zS^T$H_*fG-lm-gJ0F)g+-;wjS6y^jL=PLUoii&d;ffeNWKzS|&zR2@xv&~{-`k;xD z2s5Nar1QQH()-v<-_2wREGhOa*XNc!ziBfkOFpydnBVNB9wikzj+Gm|U*CD(nBBvN z(&q-L8@0#U{J8&jM(5{x-hSN-qwquTe7QGOJ?@^rR(t*f`6^!CPmcZN00000NkvXX zu0mjfiBL{Q4GJ0x0000DNk~Le000130000V2m$~A0PL!rw*UYD6?8>dbVG7wVRUJ4 zZXi@?ZDjxl)dda+Cl5Dp!b1Q600(qQO+^RQ1r7)?8k00|4*&oF32;bRa{vGe@Bjb` z@Bu=sG?)MY4zWo@K~#9!?U{LSR8-ec$tJUYoUC(DrKy!(BQkX0C%7?TMNt&73u2EppfMg{G$>C+H#7&h-5leU zO|s2uwJ3^T@|Tr)++`kbxvz#|sts-yWP$!x7&UD_U+>0VrT*a0)m5s(F)c#Z{CEMMf72@PMtc? z3vEkFOK;t}#TIl%B)El!hT3d4q~eG>ckaNJMYgb5&HHpiNZtEC7SpUf>~?KSKDcL- zu++Ul6dfcU_PwYLo_otgh1rEE_>9ARC)}Dz^#Kg9*N$>Z0@7yj-Ke8)r z-%nC$S%Aala9GgqNVx`v6Gx3qm-T$~^$(xsQvxufZ9NXsj zCHj!i`q7PB#V7P#ws7w4;u0K^FTVKV%9Sex1qF*1 zEjoVuI4j&|Qc@Ckhz`t+o=iYxXJ-=&Oi=9X*|Y35YT?y}@D4p6aj00V)ewrFEexi( zXI#n8Sv-H1Gr$@gL=0FQj)3N^yY~J=lF6(@MmMb+*5KBSeB+V(ccpAgSrZ&+4|Li| z3IuZ3-XmLe=)YH zaeTMOQ^ulMAplTV zU>!$z^wCG_*RPNBi*zXHQ8g|ujtQZGF9<`Vrlw+9wlrwaK#=Km;kOw=wV$p`g~GDQ zSkfgw&hK)Um%6ASo`y}@C>Ax}l(|a$K9AL^aPzVOC-_u9^p?6j$XV|7HEG^KyecU! zv|7x#m7)nM3hM0Hv*Y9A)wd-js3+tZJ9aDyqF%jv#0BZFN?envQ>RW$E?l@kS)sTP z`TO?mV}&f^a5!|b-)acuz7*jR(N8`5s#^av3}CZaqheYL0CFz#aPh5c&Hx()R5xYE zE`6dJHWh$@y6SWWM#Z!iulA*Gpvu^67Nt@**y8!~=g%K9WC#H)7O_i@9z8Gtu_KCt zQJ%()8}o{MNot^coI7_;q{H^@+vn!y>TLh}hHwT3x9{Am+9IBulXYUtx|I%x1>ID; zR36V{(W6K8EkFPKGsuGcN3h@&7)8%w0(Z4))#}WdGwJE+ zq=thB4@#Pw5J%+E->Sbp)K~&V>%~$Pyz)mZPzzt0JZ%2laeKF|Dc5pjL{!s|kUDO+ z%Tw;3q)HB(e)xR$)Zu^s+w++xcEN@`5Ywy;ntN2p3~;WhYC=6=-}LFz$$Yv@ z0IL1__p>f=r16!o1yR5gSdo*HbL!M77I6o&Hh#V4e#4Mz;)q%Y_eYvc+q3b|?(fC6 zK@b1ATaQE#ftEeXwf>@#SaY$$8`pQHe4cwgos|G*$hbef8W|N+>Z0a&%C&Yt5R(@c zE?g*p1J$8XqehYj@V@)*JM^T2;P#XTV|m5|En2hyDPthgWPX1BuQY_{%0w3D??zr5lqjvYI;c=2K(3IPus1`#qxy&rz~0gnJ;iT0u5-qZ%i5)~CinqY;bK==?5 zgoZ;K|3(Xh#HK_X<>pr9U@qE_nue$?&r~KKkH>v5b*<1XD7bF#e#7yGl2U59#{fpE zI20EZ;6!2`+p=@Z*6|cn%`e=NRxiQ-U}xqL5fK2*2OoU!nP;96r)}T99k(wmEJR#D zq|RS-mI(<7%xP74(pKOgSi#spSxdivPT z!s}{N1hO19dJ;PuyE7v}5Uy*oGprywp+ z>4OhG5Dg+o0lz>19b%v=aFfE(ty?!e5YUH`!Co46vBDghYPP6#nAH1H&8L=6lqk5G zqgE-O&vmzeHUYg$ONw&N9VNdMUcVF)o}yojoH;J^W}@TgIv2yC5l_3G7P`-?BW2nqlcef8B> zefsp-x^*kymq;dVPo6ya?z`{OSrOI7zbQ)4u%dL8Wt7?{vk)wFB#7c z4GjedJonsl;2iN);>jnUgzd6@&<6Dn=A_;! zQ>Gy5h!G=vezQ+ffBcf!VYQk=oLspSXqDSXn|e2EF{JJ1D<9kV>7!Fd#76{Ind6?& zcvu@8#+6cXKl$VnCgkK5D^`5=*=M*6K0?6<`9cFY;U4s6iE518OO`C@+_|&Jpj);e{7)F^Jo=X@du$8%CcqXO3_g>;mSY*G^7Oe&?NcI2VNh)UZuS zNr48)cvGNz{!b5Q9~OqQrz^#UA{!z$UVlsc(NxYQ(4GFc?MDPeF}LS)4B2b(Y7 zd}`i~OsN{O1np9C@B;2CF)tlh)t-r@gxw|uU}7_ zz?>ovdc_??H_Zy@VA`~4YCemN6-)rR%a$#ZG+=`TCrp^IbLY;vbLV1H7Qg=b>)pF| z<7k5h4dQNqp@h$d4I3m4gNeRV7$Pk#ZRygbhYuenvz*(s4lq|{k_%mm>rRRN7HTV! z%O_pFDK#@oW~=&H)^+#H!Mrv9NL#k~)Ww^3NtRXRQ{)2i9i5azsFMp=!DA7Z?tts! z+VN7rFElM%w&XssS4FOljb%>M0FBU`jKg;L&@$l^;%_SAFBc3Xmb4F(z#iRSI(F=s zk&(ectW($#09?$k@$vDwxw-J+M9hZ(L=dNlT^uU@CI(c+eYh(7q@yut!GyyXA~76K->TTVhq4a005r=*Zc0hA=L^AWbkql=#tR&7kni| z?Ov5rQRSZrlJI&@x-QHnGBa#!V~yCvH8TyDm%=ej+6?A11TZ5*S2O?s2L|2!>)qb_ z3H0vnVQ6L+3jifRdv$sV2et@x){7s>!g^K( zwSh25WSgZU2&@jEGgPKR&CJ276q}Bbv!vj2*8; z_W$1I-R5@5lgTa{LPoT$*{DEB77!4C5egpQ|B)Y ztHm8anW#?LF`IO4)e|$WR`cpHs*9`WENrVQt7>CRXKVEawS_fixT$p1Ze(#%6#}XU zEUvJyFEUK4Sd~~8U>L64nrxbwm6m4Rb~QOx_>fs!gI}r&@au;q>$up%R#t}lL5#SU z2Lvmtvjht9Fr=Z?WFiK|dsURM)DZQK#q**vzBj0MdcF|x9YZT-9M}rQey~>zCk~mk zMg4{nu8#zy5|UF;l0XyDCy|%YXj8NlY)Y;C5)DS3pG48TeFGvaRV)iY*}c` z_oQUH>{k|+og>Gyph3Kde@7w32Wuyi!UN+C)BSi%5OIM9Q_YI9X!-#xiD=oyXn^j5K3Het`g;1YjvhKtxmNK|k z?jkl8z+YY*Y}iE{zOvQ$mpa)%;ei`X|30*^C0qA2>(1hQ*qDC^CuB*vHVqy)t-Xee z9VzR}kPkDx_Jqf$zNGu*U*jKhHS@mQpY7|vkIjr)IF?k{?p**cdF2ezTY*-b3rTO` zcYu4I*hQ}46gm_QHA~c3a=;x<7(0O&Jn;5p~K1_@%#2>5db^VKiRjc z-el93*w&kRN9OayYizarHR^0DJbbUR-o##_@i#E4^TA%8uvWpfdJRuIx%U@vH1eIF zCyDRy3#skUE3RSI#k~{kDz}~g*b`sSmV~17yMeVeoREBwq@+$PYVh_OkN>8+8d~Xe$0peCsYB)tk z^U)&q?;9+>Kc{v!M~Q5qJz*BkzKHX>XTxy+yT%0$rs$&;e?KRt(k6Ei_1C|RY9F^A z2m{|Ux2*=g) zj9unz<{idZME4=1z}$@lyRB6fETcPqV{U;r85}q5s{2ZB!|k?zq6W z=W|Z>w7$oO!x(7Q>&j3Z@c~|+Z+!ns^u}Y9Oy@4PrithK(ED0~lHI`EJkC#r z7t%Am{pYRT`}wi=Dt?(f)X}kDc%ay@e9U)R{H<|ZT;SMt;@cnZ+8*~a@iN|FaK4u| zX7T;e8&+NWnCu6p|8Q%n1?f89f$V?wJx=iN&eKM_{P&z{Xk_N~IxoEJ(l5s`W0?Ei zF{PO+syxND;a?^tHf=cDZQSj=lLn(pp2PCDjZe~-7>vl{dJ^@BkP=Rv#HO4&_-9$u zDW?$;jYSVXVvu$`+kI{oX*JEiv1CWZ_*oX$cc?$+`+sTjXd*z7rkZDWQT}4jN%5qg zrXxH}Dt~OthCBx&sraRRU`N)2PDMPr7K2^ZvAOzt6V=h*5A7r71dq8JZxCL1(xF@S zIP3gZyy$RT6(NSj^U43ur_@V$2N1)$;Q!zD2?-DupxFkHV*oqvBrTMAj{7oI+#?%f z66aCzn}DS!dnMeJ^e5|3Bm1FW7a;5xpxDKY+j!7SV9W_L@<;K9P-TD?10DznCE)wL z2fzO$K>2ZOO~jU=7xqoP?ZOX6hLAJcVaGhxI0|4CU=cy|pacM-Bw>gIGP6Vpjy+=- zlTSg(W8flGuZj0v?JLIw%J0l3FJ%h5EYD{#rQs1N1RmAg=woVwewdaUAi7fGXi;fB zQ^24=DDWz=$tdU%>gbY!i0$Dkj`huO6tSVK{2&x~mcF2?D9K+dR4NGnRds9-C!<^+9rViM^l*b!8R71(lWD1*8$l2>6#L*T(IS95z7EvK4!0VyS9I50NI{p!T zV@hoHEnJWm%;d&~nKjXrv-}HEp-5t|{6Y{)VsSYt?Yg@a@#ew0$- zDLs+7O3Hh-a~lp&3gTfV-0YFCR2DJh^FTdFlFd;HaW)=f=un5J9uw+t4pm>Or|gpZ zNn#s9{XMF=_>l^Od*CehMdZ_@`>hm9I*&TU;f zY32VXVMH?fveO}pz2Pd{QFy|PK+}M%IY23n4PM{Lo1lI%3Rw(;9IcQ#VI9 zTPvz*QhKrB-%f4Gt3Wmas@)Wyyu7>e6vnC@UKc%oKG}ov)O%m|AZ-x2KuOOjaXuaS z87eePa4toZ`|g4hHl01jhUf3NpJojq<@jZ1?J%=-~2qD zIWbC!eo%E05J`xl$$bQoB2$5j8MmmE7;;lq#tmCzFtH=H#tkvpphMciaRrcmo(hWu z|MI`kQ5Q?S#b64OH(h5ee-{r?3j;BG)VHFmk_cdm+e7pA8H`S$HjM1zA&+6u%v=jM zN|jNFA=bi`M(LEIqUzH*l!e;s)f68Gz2KKFlB1%AKH_ew^bG#HGM{r&`vli*Se)J( zj44SOtd8bA5ZlU6h9Y0w7$cODTlWcLMzQ_?m_OT^Q%;O>{J|@~y+!V{$;SB?L;=#?Slw^wz@a^6k`Y|El&X?qjCjJCNa>WL#Fw{pDGMXz zck<9Qf!?+KhBjx z*x}e_9D^Pn#^>T7QG_ngz%A||?;jXzv@d@0{^$GT5W%faAnZ5|nEw>Q#q-ko+$i$i z+~J2i?r_5$#r_ADxBa-o4tLz)hdcjpp5fNpA`|&_>bK^f2+?bP$+9)Z*Rf&9BnHAO z`!RscE8y>kg(b3^l#0g|C^x?S0iI7fWj}lCIr{YfLjq~{VBY zho{fS=kd?drRR%Z-^V{o3dk3~zL5WxF6gpZ;6E{1W3<9QR?g{qrAXMmLl{6i4|{| z5-Oya-(so&M~Yo6QjB6jsQi+o+QlUWFBTPOEHvU?EGc`jskmaP(f5T(;EPR#e~TA1 zo4|jT0%H7d%l-!$|6~GO{B&Rcb^`SMu@pRkT`U2px5e1*L(xjp0sKy-uU=<+%^2=0#m*q{ELeOP*EZr~OHbhVMgyU{qT)5RMM*#dRMgPkYKfgrMu3cQ&z^|eypd#PD)XQB& z{_YeXUPKTt{)8f`dGp@AmfmxOkv-vcRS_L@b^#m_HP^(5Ry{%l8%A9WN0`kwrp#4O z7vbc~3owYYZfUE4(j4K4fUj2L->AsRKbi1Fq)$ER7rvf7hAC&xI0`Z2FolBPqElC|iMRBNnsG9EMXbMm$ml&W zQ%~{j3s%7gc`@nSlTM#M8278r_Np%ZL4z^w9lA~lMVs`ZPH$ULGJ2j4VZ)9o>Cy;( zqvw>->BogM9WqKUBU7p z=;_9+{9%9V>1e!oBzamLJsM`lW5?|%vSiH^Y*{mRot&lDt* zsZ&HEfu^jjhNfrFqA6@_)hR7nGzFV>O-ZUH_|)#ev>Us&OkfJHx-jZ7 z-TBdViHU)!;$G(!+91plF6_b^S?t4jPcx_6{p#w?Z7(58p9AYlSXf4Xt@d+jst#`(Ay4tM_HG`ECQ zR;m&ubo|SS%QW~btdZ8fnei{U;hQyC8ghjGqMPp(k}QS2MNC)1RmfEtL7bIVt`kmV zX2;X4Nukcjgfy#e(i><|o7zeb&XFctAUdR3Fb#}8U z$Rx<&2;&jCk;xIukE#32NzB&fuwXcMtz^Y{_sL9kdR9#e2YELIX zsk&Qbj?_>9Qd7Ca=O|KCnW{TDZBl}$wV-uW&+XZ#DhiNFCFNn@(1M?!`%z)8BB~>5 zz*7S&LI$}s+V+#9mQfqk?O>WjYI`+;^HQGMXyYdJxD7B6MTHYiO%%GJr=A-Ok!n!1 zf&-|&6y_>X@QtK)qc-RQLUp-)g7S>rl^q?^)J%D+Dv+*F1HPg*lIhmBOa$)|xA~`q zM?vb73NwKPtgptQQ59~AqEw6oQIu_$8|X?IX?)5=_oY0yPUOdK5o>cUBz*R0B@d+s&^5{M+U!JO~=3V*Q5cZFX80yO`{fw_72E8TZq zW{Z>2dZ8D-*z-r?w1QQ!N#<#RzR zzN$Lt^y6zQ8fq@1aSbuu@oth;El+#W<(#^KDaXdUO~io2aOs+m+cUY?rmKxG1|^bf zYjKlvwzK@^H-<7WqPf=%a)8IV?k1jqKv&)BIS3$KDk#_uY?PF)2HA(ShE#>hWCph? z6NbllRlMCq<8HI5V?$kloGq251~twrQD;Cq@&?zoJ0gjm-0=Wg@Qox1wOLUXQg|%U z^Rll(&@^;zeq^&^l{MqEk6lhj&f|G03vS_UUJMgRS}?RmxsK_l^Qd(aJsGe*UwiKm z$;$V6j9W{Q^n#6W@6@tz`C%IJ;CZu|>8%&H{&@(P?`hHrPK-qZx??-I_2o=g1p9sG zXk-Hpl0zEqo_bM6o2o2)f2-dew{WgePAS}HlI#M#tq`a!7*<-y8Z?>7AvB?20a#h+ zdaUYN^Zj2dkzJi+_2?7)rMvegWH`mEr%J+nEPUw>_y-LwIu)ZTs=8i^QXy>nvgbC_ z6MYzZk<38~_tht-2TZp3s0t|E!)d@M9PFK&4vbVy83`IZWQ3-zwP&H@cNl~EfcbZO zAL)&YtkQ>ss}fQ)j3nvFu_en*n+!5?PA5D!rN026#YtKk?6`!T*rYAS>n!7{!V_0c zpkWr_qIGoi_n*R5(=zsOe=eoTD~!# z>;{Foy6W+Gx(4*oC;NQ~-4G5vea8caZb}t&XY73{&~p&q*J{#+Qz?#XjY4vUSC4KM zas(;X-en8u9*9lwP4jse==6_F@EWua4J0MEzsH3gBvquy|eDLIeic%$A&N{v@1 zTP;a0x(P&m=1-`FXktsb%eRk)mmrd(*;_hZ%eWc(xz(blAgmn8Az8p?y18V)0bQKi zVyZ?gR&qK8H0AhaYEW382n`L0(%4-YwlynN^aQe;(s+gHGin)C;lZK{lsul{`WN{M z?FAE(j;2n@-{gG%c;EO=!c$WN(`9xhkV+s`t>mZuusG4w|yI zxe3_sZ0ZfYK3O0C8`5Jk8B?SB0KJM1c^9gXR?WmvQ$|nFK&wpn#JLphdIUN$9q670 zy8dHEuOdNXYRn|pxYCruo7iMl&4~(`1UQ{>==QpF1xY-+T7h^r*TYt*qzY-IxYXK} zi&sjIa}%;>HSKdEgi6^-#Q9C3$_htM2cGW$&nxqFGLUus_}3yG@Bi72lvfkxg)vAJ-vk#c(rq)EPs6rE;|p(OZ*37cPB_Ei1bqA zv3@e6l+1P62Vh4$uB&t9prFv=$jPUH&4I%WB@@jf>NL*i>ZE`p*qKSEaV&2;4G(Bo zmEFV}NC6`?zXG!W9nUaU)vPwNIv5M|3%I@q{eRtLV;QeMVCBmytU&cRv)1rGx|+4E zyk^1GG4n8G9C%9NBgCUCoG&S#0Pzr#f|$bS!_&VBfw_Y86#JFskkVk!E~r%Ltzp`- zVTQ_1K|4aM*#h>CwTOJTL|RzxBB+R0p0@PRakT(a04l5GZPt}U+6TnpiO>xryR(gG zkflD=_Z{bp?x@UMHPb8R2R8Z{c%Vc#(Vlgy3;jPw)J8l;;fBBH9N(FG-rC54)y&Bx+s5Q%l)H33X?{)KN zrQ_YI-{<<}5-5_}73x0v>y(HUUKt~|Uc8cepgd!lvrM0y56EhHt2B|PNVMev)s0B0 z)JHfx0@}c&&h|C~1buLJP5s)&osFA14^UL81_^)c(70eU%IG#cH%S$ZZ9%^Z!XEnA zI)nF)2f&T)9+NU7ICo`{PACVq{c(q4wUE#XH`)pee4SGkUZmKm*wCD6V+hL|#&WG- z+E?3kpKAOq-(Q809xtZU1*$V$HJG!Ycf6G!PomCk^Od2N=|tP}h@9SSM#TX{4m@3K z;e?qQPd(R|Myj^p-+^RRy^N_f#W|~=+993&biQyJ&Bjv$VTZJaXcJ!ta(3%?vTa|* zzkWE8(BOd2=+5(CDXgT@z4xdF z8U)Y1X&W<%yHw5!J&a4PXFkGCAGPD=s_EI}c`;7R%c@V|fid8{r%)Ykczz`uwH4Q5 z5HF=>=H6zsmegqLvyxWaPgI;SFt;ar-k$H2F`{R~!wO8LOH!2KYt^{~;KU8$o0MVQ$cdEXTVTE(VL?V#uxa zJe$Mbz!&tz&M_~BV)1_thTN+EBY_=$41xwYW-vbiN}fPEZCHGW|G05DGv4IBWF+|pryreeenZuZE!2Hx%tPo9lo)G%PL>AT2Kxo@QP!Hsu#KiWUnT zo%&wVqK*#(2Lp+rU;r`r3nK^Ygru{7fF5Y}DEIB{jgj8=d0+8gfV94)cH>_Tme}k> zOiNGxmZUI9g(jv8Gj^v?i2+a9t*5{=l%It1yU^4UfLJ)XJ7F|irg`%e>30R@W=B9h zq%hD^Dr1gC_En3+z)|E9T0n68R+r7z!ch!kB3A1K1xBNAA@~N1Gqr4FVDTY~)qs!u zNH&%TRpcmWYX1~`HzwgGZ2LKIi*Q^K7sGs5yrYBNfEVk<!ZJPQEM}(MMcw9F0uf4_7@rA?jO0E?w)|7XqE>F-? z#YeM+*;>iAy)%92^iP`Iws|O;x#tGb(KJnBwMJ_vfHz#n&{ORygn^C>1q*x(CIU?& zBVa*;uL$_jC=M^NDAGs>IEYCiJKM<5ZLmrLJolZ0pR7u)*a`~yNmD1RU}TUnEN!za z0ND|fqk_H~wE-+G#@EyD(kta4>^YcNp~a+DwEvjVZAB8$RDtbxf=5!ZLQU;>HmEd{ zt_%Dr*3)2kH7k8d8=ZuF2u#6u?tu7|;HFBGVGr3f=pJvS7_eRvuflCUO8v(Q^V@)A z->d{4Lo2W~9WNdb@Mu??kjL;m!$q;YOf*G_?a4?Uk^hji-U%*{eR%BLJ z+kvm=VvLBzmHmM)e=dh7bAWr06j4zjx_2gtLhqA|WMGD4*3=#d37lhM9%1{d=QwH% z78DpiS0PmP6Dpuo*^!ml_Qk{sRWa+oFT(Oo@;9qu1S{~tMRS&Su@}ZBev8Kx@UC7_ z%_Y@@!pHUKxt+c&#R;%vuEqz$a4TU(^$bwhbCGoqkuw$~s)zq8$<{w2R`@ZI7_P@v zR;z7zhVO@rU}8bt#(*zIJmJAX&Bt3j+|eoqvNmSaD{JaokE8jh7J8pg?geg#5)=f1 zpiSuRt2}D38xa^5x5m21$UtLC{#xo`PyDKTHq4OqKoUr!H_M|8y&S^C%o16kRD_?C z=&9U-n;&^TGoyl?abNB#9paYS8ZHYmH;RljRh6%70?>1M=j5<~fo{tIiQ-~gzwk*F zqHiy3s|(6KLgV5>4cx)BUYf-5Hl-L$j-LfZJEqA!~ddC^|s}Fzg?Z2ZF?#Oq(4cC3Xb2wPLIkRz-AhEMF<05Bg*J&5k9*n*Y0r~9C*-dy+`-(VGoBnT zS=V^;Wix|y4a)eckA*;dSyyo2O0&MgM9Uo@8olJkgj-3|2253QFn-B8NK|&6&5tY@L9rhrm(aZ z%s4!2Y!$%-qO_R5d3pr*n1VclpMX_BQiI4h$DxF-P9o!ZD>g0m0mM&ZygsjBJsk5a zU(vH~(CJJPh%}yk4M7?nvwTm4)IPCdBbiI$duItad23Y|u)~>^j;aBc4z550B?&Ab zT_m<1`@D~AB6)eS4c+;xaf6I1i;K`_{EuNL{zbr8_ErKzz z!1wvsF$jxBJ++P1WI_Oq^1web7UTPADmHccc?7UObOx?7k6&*U4?`vtTZgPY6q*;z zR}Swa;L^q*SPLT)qN_I-3hRMg=jwcVEGr+xu<+vp9wAo+)=(ABaYD9vSQI+T8{3m>uLOY6 zK+|j@ci*(6fht9q$ZX(pGdN^jbZHYQJV__f@<;~-?Gh)>>dC9lG%`QvgfdUuX`a`@ zU$?iMjj)q@4w&zAkPFj`4hJl2AsR#^Xzbk?4H)X~K2=bOz8n;xrOn&{Sd2i_*9g$O zHtakns6zv^!)!7*K}H;+U)|RQPBLT!<1~z#KmLOpZbtIPYb6v?7J#tkvSqPMLOzWj zZw+P}(}vwZsRoElO$ly&T(ZvPK-9TZHT2_bkpY+v6mY5yfgDt`sBb54vsF+kty(^b zaVM#%wAFYiWIIQlu?}^jC#ph1Gkg0&=}vRa-1E5$&b6su z4WmciHm@kkG;TE40j#1sf-9ay+`}MNGFy>q+)9nW;8M%o0h1pG$_vg21R&Iw0*zlu znt*3F)mfVH_-3`iX>&etPf!CZOSBvs4BezFD|m=A0@Y##3Su0Y!%AtU46Y5&-^nVo2wmXo6z2v- z-G}j^8SB%mN_ZegwmGIaHYh5UvEa>>gdZ}5S_fy`4eF)uL0Re|p0PX4U4EQIrE5O30H07Umrn#d@q-)EspwlqYc3i+>3W7V7(tks7RNzSF9b<1@n z6Dl@&Ax}h#=~@VL$>NW#Wo^>8R+Oj3#ZyLCS1k>%lQt!%|5`Cotmp~o3|JE8B4lF8 zS-JVry}`N+D}P*~odhst_w}g@nC*1oCD}l7rg6`(rBcxM*A~(S>&d{BeLv~S5^qO~ zi-cVTZ7HOKYUPqfnG>nRQF*jB(VT2S6-(zOf~+&^O4;@S^-LpUkt_{oE3Cy-D=->2 zGp{8gkxJ-V#&Ghi)Xl}a1i?w=%P9;PTM0JG9uBm#XZIcur|_i?f_BGtDl0B4sGFT( z&hnPi_6i1<(J6rig%)1ZR_J+W)ZCt*NDC;T@La`}Ogum~LLtn_)#qB5KTwJH`u^hv zp3vr2y~>Qi_EkBS8BebWk z@YU1@@S097wpIKFD(d7~r-`N)IJMw9wk>0|*-^bJ6~n}(7xjF)W5%b8>*+tdwL5~1>5y%5E}Y%f zp?Xyr0bCBK4w%NCH=*Rr=V#mFx$Znyc?R=nC@Y+As}B0)DXbPe@rqYmzHpSOE5Eh7 zv*ooF5o8%Uo6KdcYeJJ88=2CM8|&9|SFxG&sf-e{z@(5&kbt;G+h7?Lj#OXrKl3}Y zeT$0EQiI2enFS%)f+}s?lgtyQkZwR!lC`6+_9;EMU7Y3h^bg4z>E4-~-136-kD^%4 zB=mJ{)fU5CmU>NH89_}wM@Ds2|MOX@^;AG104Ry2qaaa@)stWuu8O&N>Hd7j=*&J0}M!GuQ*QquOpqvV1{Rvf&a( zIHgmc$bos^c3f^9r(&S%1dvXukSNE@dg7n#77b5^1)ZIi$mQ$|vnAbP_#!01- z^Lr!T{SI*V3W400;BPs*{{Xk59m^mqGT{E_d7Yi8ql6@w(PZBnT&fAwBqgJ zB{7}{HD|Ou9eeNHYS~{S&pWoSsQ_d z?e4kGgQs$}u52#&s79Px?bQ0tXvLJ#YS3!e>1nk(_p27JO2?m7mr1fUPO-7j)qvRA zu(~8K>lkY{|5?e}v(7y7xSP9g!^w^oto`=R?d(m5o6fp2rrD-AOHsPKd9rXiW9EO> z6sd{LGjhK%nXEZU!A*>|+?1RGoqsj6)!^FadPY3429|b+MOB%zJd`5)^+0!OQsz<(~9r^~{gjDO&$tT^-6m?$uU3TV^N9ZZDZ7WZi zV3m@xQ>NH!sq=ch$i_&kWF^l^Wyy|o(2~r?hK>bVR^qH8*aK6R{;i?5{iEnqXm%k{XN0%w?~c+s?{`b7l!5<-lYQ z;DA*$qTk7N59n4*C?~Hcfg!=47sIAIsZ*&sct+u(%nN-EnAd{?K~aeRk>RJ(E8n@E zOX0`o28rT*WuA5Vu9PFIT4RXdUfHkJ7&wdl6Tnv6Qkc5Ld zDx98#4J%Ze-EJ(*!XSJqr?24|OJH!Q6hoq0N$_Jaod(jPO0 zKT#vB*M?(xfNIhd)NF1s9j%!@_cGB==XIAnC|oTp(+p;+tGumU%xJUNR##T0y<3;^ z&dlfT>mq&!*REztL0LWEau}qfl^h$*zG@K8R(O~@ZiZ#TpQ++HGaqb1=aQM6YnV~` zKOLJdC#zlavPQ{Ct8y!@E=J@%aA38e^#Jj^@< zgUfi8*Cz0)kXP;O^cnDL82C|f?NBzYNHX#|WTsNAJQFwk zGNTpEJYnCI>ljTwTs+HmPkt5=f|SzLcRkipGKoZ0ey zWz)WOdt0GL)&+n`W}Mh@<=ehKXmX3?tEr9Xv8fK4D6S^WUUoSd6ESu&Ch2x2aOF+F zS6Dgh4}91_^g2ibncHYDv8fiwhbYptmUWs_H9o7Oujd9mrh3a{I7ryGc;u`}k8_|j zkLy>`!B}Zga{|zTuM4iy+R~aaABG4R>B!|qrC zmM%Gm?`1}_Ezfee8r&t_&hDV}0`4*k%oQFT1bCq)H?zGF3>r1wHEQxV*=_Af00`%) za<=YmYw6K0j#Do!pa;0qU2=;D)7q8yoZ!cT%@g9cW8K!|gSk;^aXpw%!t^`!r@wsq z2qw-$TELvUArCLF6bBTrAny;tpZX8&L+jp?Eg*8BHV&Nq1GjjVsm%k$D^0tpwi2#_ zD&3fY!)ga_j(bDny+sDIm52=YD2$=99@C%%P|voMj9d7O?$z|VPO*T#irvb0S?R4% z-H>ayGPVqTXXzA=HiaDznY&x*_Pxa@^>`W_IcT6$^)rF?^s-CQHDcG)53vVCpC-yJ zIbiWm2?D6;FpT^-0&%Gc|DLClk1gKs-%t7{%KfXa9h)4w!R>amZ*e7nU|Dx2DN57y zl|Eor*AlLwy2pNc+;tE2B^7`tl6N2?u9op*Gc4Kb%=zoPn@BhfLNKuI|MvKQjbfA-y^}^ zN80gc4(>V$mSpdBlJ6(EL3(z}GWZ(e^Jvgy!H&Dpv_eznvep{P@6nXM1@i`1p7JiC z9Z&k}Pri=Nr#>1fQv(TgM`@xMRDlN}AZiIz0jPcq``iRi6Pz#{%xgY(VoIb-vdxEd zf)<_Mc&RNQ;X_-}>ky4WE9V~}7VBKkTY}s_p?m(S-z5f7m z0&oJW`2SyS=6_VPY95hJ`8GCrhg*?W-ZC3p$?OJt_URz+!8-oApRdvN) z77D(ug%FRQjAp1ls;`EZA%_sDcL}4sQauy(RG5Nb0a6ts6}Ikqc3P1$c}&3+_J@zG zJr%p-Au|S&HAX;=H`T$%c`1mbzp?GLRlf;v%9fFy1`g9~Da~4NE=pNE5i%ZEqR#!Q zvM(yJHG9brKNBU=kgM=a*U($lS$5e|h~Pzscx~*0A{uP?umbM&8byI(ca}oV9tyhv zt4w9}Rrr{L!KYSYXCfQAER6bF#xR||iVXZWE^Y}@p-Oc%c3)R-A=oRHl`BcTM9xC5 zt6$iCn*Yi3+*=_J?YgS2zpY=-k0EsxYhMQ{Ji}Uy0;_w-9BMumauNo`Ak>B-jK=eS ziXTvrUf|W>#l61E%oyLY84>|q44w@W*45+<YqrVk`JD(#2nb2pq;tOZ}jDCk}66{4{IvVu{xW82C&`AHsG)lJ*3r(hS9;G2}!TG z=CY}zyS2k-ho-#?cds*iC55{q5crJW5`39zovTVCjG)|<0z(VzZmh=im!GbF=CiR#Qb1mD z@_ES>9De{|NWPAd}sL0>xH^j<7%%+pqFM&A>`AYR8ONeTLwLo^{KmukrY zkRn}VF8lWqShGK?yT~rZIYDS_ZCLC_a_?9F;9~EkMUjyIIQl3-0IK`ozzL8?-PK|W zjVs9usEoI@DoO|BDJb7Q`4x((&*~Yn)Pvdgx&#Dt9&3X%tiP3Al6@9|-Jt`ykMCNH z5&RfC`*qb?WdI3on;*wVEU_1PAY0&}3aNzOs~d#eeO!8o&BMI^=H~mGt^YG(^9^bS zGxqWy*9?CAdmaP8LbLb-)^@cYFRI;B@R&xvt?n{yF>O0~6*{vOstWSIiahpWM<@&S zlO?|w;yw-~6ape@Vl=YXk`+148x!tNZM#!X^;K zQubPY`iY9q0I+n)Bn8Qe8*a~Yjocxsms!wZ&)z8GidarPRRR+|9OgW6zADkUBYSQx z-Q)1d{D{M3Uncln6GH*GG_#VP7cBZ^KCS5 z{Z-S$pF@~E;KdLh8{Y!zY#7WZTYpmgai#nhThF_QUKKa-9KkWN)r1WMca6uF!tYwe zoM1EN)V-8wJ-NKf0oZ7ITnf=FXIqU@XV|htH|l$^ED&QpFUkcfhZsl>QQqs zPGg!KpAC4xu+m;6uy+_a`)SQ;O@tCGhD=Vfa@T+K$?e8BAmBkFz6-|r{4oV|H97Vf zjuR43mOmYaJbu;$1cSz<;*rb78t|APWb&;w5b$BIPM3Y|`GS?$?{#fV4g6=pFG=rF zl4Z~&6cd|bWTUuWv6F!xB98IVR3u=27Q=%11=m6)pAFJm#a>l`3S{sRL{QN9#RUyc zymz3+@Gd-QlSLDhvW?pNZ|;?mk1b>NBXid97W*bD?kDV_l2MSK{(}zBCtY3p&Bf>B z4oGlJc_oi+-uzV$li@z`{Q?H80)-eCY@jQh)ck|fmEvVMyneT-8&X13?eW<0 z^q4CGaEXvWO28vRIv0Rp1yFh#RureHCa450+t=o1T#P3gG~!wWsbJ`?)AHN~gu53J zSmA6#^V2ILOlUnxWS%rc&FhQ z*TMq-B}toPk96I^!toh701`3)KmY&$05Ao71%`hC7$6qoqai$OsP7O|p;`nM420j< zp&Nkw>ZP?+HzJg}y0wS70-Z{+?u3<epEL~TEnL#8hn=(6(nE00+mli zw+psVf2kk>MOKl5&aM6DXNdBm)@&LDYP#>de|zIur@Jhbc7Enb|92k`uZ!Zvl)-H~8v zE?o`Gb2Xw9a-kPTui)LY&1wo!)`;_07?j&S8}aOaX%-}R(vg)+>l1FQHHEcTCOkM_Ba6s{VMF^Vvm@1!WgF zyuqPiN&BD2g92oT+fz85$n^k9L0s_DLVrXAjmRG|VQX0R(4dhuH7ddO*oAf&ScT_G zVYRPz2vl|Eb4my}u_Im}239LT+f!LI>x*IfmdbGRmD(b-0%7ozKp|gUX?Z;epg%vwrMe_Ez^@o^5tW?baH$>n-^*3R5^>~H5cxmmatyROE`8YA*gsChwq7Cx>h!s zZSqv?C6{nSFbCwloOeypMldTqdAg_w%*&QwW4s&5C(Oy#J`P}VB~LT8yVFovdRIqn zu(*$&Ib`b5H1usZzJZ}*HZ+fd)~=4}leid@B`fEMI&pXEXzS;^4M{ z`v`^&0%PxYO=Uo0b7T^M&qriXarh1$gFMTX$#yH4jW8p5CnHD;7AJbfRP&~nn8nI0 zVXs978ahz-OWI8`v|!|fQ zdL2-Sg^I|Yu%Wu6y1`;g$$S~PPvr7QqdLOK-j20^H@Mqeylfexu1j#sdhr}{p{%7^ z@9%TN_y1~aO1e)D6pB!;^R(2L;NS#=LA%th(}muEn`i5nn2BbLWXQ~|<)fJl5q8EA zJeynSG`DyGJCmKVZERaP*Of+hjX=+whx|(i2;yDHw3r8@R03TGQzlDX&TW>Gjfw@4 z49-xj6?!}tzFzGhqvT>Yp>trup~QCVgM8o#gJF;7OHO-@Jf+4U?pWCo2P$k zzNQvieba+jlrj2O++JTSV4~D3?l)KC*by!Ig<{=AdoW#~ccd9;w>#YKKVk(`!Hi5e;=~ zyLP`JajxM;*ah^s6y93}TE~CGhMXqR$OEmh_Cy4+9*q@Pa=%kfEKio77SoSgtYerP zQ2d_4tX?3C2Pwt;NbZVyp+r90qq3woXJ(JC_kKz0+J+uzE4NZy8BHdEMzTpN?_bt`+D zlaRh%3CXr#jEz>2JxGJ_eFO92^_t{Il-higdZjy*$R``Gy>xmdI*!H$0(L}vzBg`f zPml%WQ!-`(QLMM>J0EI)vO-9iJCk}zo5O}Kq?KS5CM?{}%V*9eSbD76a+8+d15kV_ z9>h{4G(4PfZ%~6W=>4NHaGFbmt0#MhovE|=u6G0<&O(mUfJCU7z!}JM)6TEpx-jQ% z!}c-c{@7v>#BhSMRaa@d$b!C@9lPfj*WyVro{YNsO{IF+Gup0c2j61SXbc>FURRGEZOs`xTV=fnmdj$5A_b^K)2q`EdJZlfaiIs2J+lgA?wsuiXrP>rP&Ss%;+ z?`^@lMQHoRL~MIl=hg);xnyU(L+^3qY6}S$y79_!Mj=3NR)Uz7w;S6zJ#=$D@AjC4 zlgu;svk%sqb5wko)GckWxG`OD+@$He|3OBF*ka+pMGnW$*EtP5ex%B6 zoK!bs!bw2a$fRKwvKs{F07465;n_lJkEjBPFMC;Vjr=DPN_pB@Wy#9`a^q4t*{3|e zaF&$WmtADtUJmgKuErLT%k0H&4c(#nAqDlyzRmN=Vn%6OM9r7iEzc-aZ@LoM8*c6t zgVvjjW8#jL&F$xzp{jF!4(s$n@zP-Q;B$@-As88l_6QYJK_QOT#2Z@?o=+qukP4++B@5G=sVh%wiy1msV7&gn>U@HMkehE#ec*D zupj~$IHwAtp1ha*Fow=fu2mYXbk z4&HU~A5&dXn1Lt|Z@JmpG#R*DLj{(M6LQE+HZk8Y{Gj*mx-&y1mASu1@ay_h6$yXj z8Svt_tOoXKW*wTs9lxay1U}#~$Y1wp&-}c>Sp-t+c&;fPqJ;86{}nMGA1!8xUrLLe z&zL%06#90`Xt>1c(J|wFyJ50ky){%Knp0m*wBD}pixn&mIKsinUr3Irg}mK$8Vf{? zsTpWtQ7HI(_n}gu1J9G>xME|b^nJaBW+7q#%xGk0T_g9tP$)OKSPT$VBJtT*R(cUj z&``9HvhlYGi**s$Fq}4Hos zA$umQira4=uq)^m`_l(o6h-@$EBxyDRAGi4^ei#I3=B!M_j;i%K&Jf@&GkN5F+!oY z7E45bXeh{@+|PkQfXUM0%c}svRZ}2)J#x0G5K4q*mNyziKB}Y_hxyQyn_SP5Pj>II zP9t=}!9{QS?cUkbn9`I2B9$*b9%3~nqQgNlen4^}O(j!-I5$c1{{2mPkKuWuAdxw~ z*S`fm+gFPmB002)R2EjKmVKF%SKu3yUod)!Eu49rtPt}aX*FTM|0idbndk@1>60h8 z>1nEibRvloYM_)ZnZz=YQ$0PLk5D2drS?$RUpmWx*Z&dU$>qIfS3N`pE^roKX3>G9 zv0F11+DR`ycs(%)dp>V?K`6h%2l|K_dOMm9{fT@9Qj1Cb{1YMQ=HP7+UFs4myG|UT zFk5I>`XQ=a_j@#L7Tjmgmy)y$d@aEH_U!ksD_i>@1+vOxL-6QqvD0b-F;dBaDnbmj z1aYU$z5H(8h@Fnk>##KaGuv>zQx$+|TR-G**Fel01+FlP=HL5Z|L>M%f5xy?moN*?{x~Y>EuJfBq3QgYaZQ{R`f}C!?u8 z<>2NM?DzcQ@51>3F!wpf%%L3ZyazdRG`|{XHf~#Z|ECSN)F*EAl~#2++z?%duT>8N z5#I~BSfj@wEZjJ=NBSM?rt(OD-n`I3&WP@mAAoD1``0v$e&`@T8~?HNU}p923o-hr zQAokfOJ90)PL^1TT@t^qz=yC*{0z@W=b?uFJ1mcfA-g6%=y}t+>%JhNTy)ggtuJYAAFdvZ*(j}96@)R#hRqH{Z&7}V?ix1v7I)qd$ zRU%sQ7kEF)OuCn>0^|%FFh8e@)H@docVPUf3SFYU4}`{+;NG2HcRJi@qzh}ASFm`_byp^_tJRawE>oG)MaLW6rTo9f$613^b(2$2|$DqAPE3* z697a405u{2U;qGZZ*)4ev>MbeDpL!zRc~*%ZK zcSpv^*W;~bfT9qH&wRGa1#80000ZGEe{vR0#WG5dzq%7E9;CFKtraOH2Lc-`Yz^o|IBQr5^VS z-@`yw>vYi=*nZLMfqJzMSfQE=)JCp!jPU|P+B2h_-|=e>h~4#mprCw%^nil3?00w7 zTx3KR2X!y00X9d~>wtc_gEMvlyP!hUGpl2jpgY@MU5*-(=uvo!&N$k#%A+yjH%KE$ zI1dWt=yFDcf+4Aea4`Mw)gH83U&s407|x`>iDm@GUiE#g>o!+XIU{sz6KXcH2Vf^? zB7LHID>g?G!u9H*dS2VY5%`ixK1LytB)mb)2X3#)fgFt&F$s;18ks1hfvG2X9Ah&l zsWB!d5LnL1V2lNCFm+I?2IT*U3Qz2U57W zw@xKhNnjl3`xA5D! zZ;fcp@@~|-0@NF{7R~EJjJ??`d}6k13(JlFTbN0Xx~M{VI8NyNH4=Bt`&Tbn$F=kC z43ec6_6lm=`}O=eyI;r>pPlp#1wIV-IR4@>IE>KY0EEUzU@#^u(YJFBKbC5q4`=Jo zcbo7%?>`6a?%=~AzvZ7BG(6H*&9nZ>oY;HLN02&a&Y`D1M>O?5T6$tZB=l~EhDm?F z?K)FQCrZa+G(sqz(I$*>e~=!9L#5+l5qw;~sG*CExCZt(wQKK=qSo+ywGFj6AmR-o zj!vYH2?a%Y)1+}1q+f2^s`8_IANq=oCwvMr>1hCN`vhtJD-Pb z+f}P-2J0N`Sjk%`b|A_*$zzg}D9tFJ*ZI3r2#M1ojS~$;nnfBYn!z+Cn*6kBX{lB` zqL-?FZ6{XstEmZPePykp>1%0P+jq}1TQiSya!#Ch>dk9&;!nJc{beuxwFu{6mnv$)nC+PcY49`dS@4l|IwL^Tbsu#pBeh)y0uY%d5s5cUh4y8z&##C-M|IvUX3Mayy;%{ip33#qI4C zi{xVcHG27_it>>~8~cqeCRJ9YO4NO4r+Kc{EIuUk;3-wz`p + + + +Welcome to the Mesh Viewer of the "Irrlicht Engine". This program is able to load and display all 3D geometry and models, the Irrlicht Engine can. + +Controls: +- Left mouse to rotate +- Right mouse to move +- Both buttons to zoom + +Supported formats are: +- 3D Studio (.3ds) +- Cartography shop 4 (.csm) +- DirectX (.x) +- Maya (.obj) +- Milkshape (.ms3d) +- My3D (.my3D) +- OCT (.oct) +- Pulsar LMTools (.lmts) +- Quake 3 levels (.bsp) +- Quake 2 models (.md2) + +Please note that this program is also a demo of the user interface capabilities of the engine, so for example the combo box in the toolbar has no function. + + \ No newline at end of file diff --git a/libraries/irrxml/example/irrXML.dev b/libraries/irrxml/example/irrXML.dev new file mode 100644 index 000000000..4466b7ec8 --- /dev/null +++ b/libraries/irrxml/example/irrXML.dev @@ -0,0 +1,76 @@ +[Project] +FileName=C:\Development\Irrlicht\irrxml\example\irrXML.dev +Name=irrXML +Ver=1 +IsCpp=1 +Type=1 +Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_CONSOLE -D_MBCS +CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_CONSOLE -D_MBCS +Includes=../src +Linker=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 +Libs= +UnitCount=9 +Folders=parser +[Unit1] +FileName=../src/CXMLReaderImpl.h +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit2] +FileName=../src/fast_atof.h +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit3] +FileName=../src/heapsort.h +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit4] +FileName=../src/irrArray.h +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit5] +FileName=../src/irrString.h +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit6] +FileName=../src/irrTypes.h +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit7] +FileName=../src/irrXML.cpp +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit8] +FileName=../src/irrXML.h +Folder=parser +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +[Unit9] +FileName=./test.cpp +Folder= +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 diff --git a/libraries/irrxml/example/irrXML.dsp b/libraries/irrxml/example/irrXML.dsp new file mode 100644 index 000000000..86ca01b36 --- /dev/null +++ b/libraries/irrxml/example/irrXML.dsp @@ -0,0 +1,124 @@ +# Microsoft Developer Studio Project File - Name="irrXML" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=irrXML - Win32 Debug +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "irrXML.mak". +!MESSAGE +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "irrXML.mak" CFG="irrXML - Win32 Debug" +!MESSAGE +!MESSAGE Für die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "irrXML - Win32 Release" (basierend auf "Win32 (x86) Console Application") +!MESSAGE "irrXML - Win32 Debug" (basierend auf "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "irrXML - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0xc07 /d "NDEBUG" +# ADD RSC /l 0xc07 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "irrXML - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0xc07 /d "_DEBUG" +# ADD RSC /l 0xc07 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "irrXML - Win32 Release" +# Name "irrXML - Win32 Debug" +# Begin Group "parser" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\src\CXMLReaderImpl.h +# End Source File +# Begin Source File + +SOURCE=..\src\fast_atof.h +# End Source File +# Begin Source File + +SOURCE=..\src\heapsort.h +# End Source File +# Begin Source File + +SOURCE=..\src\irrArray.h +# End Source File +# Begin Source File + +SOURCE=..\src\irrString.h +# End Source File +# Begin Source File + +SOURCE=..\src\irrTypes.h +# End Source File +# Begin Source File + +SOURCE=..\src\irrXML.cpp +# End Source File +# Begin Source File + +SOURCE=..\src\irrXML.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\test.cpp +# End Source File +# End Target +# End Project diff --git a/libraries/irrxml/example/irrXML.dsw b/libraries/irrxml/example/irrXML.dsw new file mode 100644 index 000000000..b6398573b --- /dev/null +++ b/libraries/irrxml/example/irrXML.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! + +############################################################################### + +Project: "irrXML"=.\irrXML.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/libraries/irrxml/example/irrxml.sln b/libraries/irrxml/example/irrxml.sln new file mode 100644 index 000000000..5945f34a7 --- /dev/null +++ b/libraries/irrxml/example/irrxml.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "irrxml", "irrxml.vcproj", "{2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Debug.ActiveCfg = Debug|Win32 + {2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Debug.Build.0 = Debug|Win32 + {2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Release.ActiveCfg = Release|Win32 + {2CDC9E2F-2CE6-4917-8BB9-DBA8E44C9A82}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/libraries/irrxml/example/irrxml.vcproj b/libraries/irrxml/example/irrxml.vcproj new file mode 100644 index 000000000..5bc2c20e0 --- /dev/null +++ b/libraries/irrxml/example/irrxml.vcproj @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/irrxml/example/test.cpp b/libraries/irrxml/example/test.cpp new file mode 100644 index 000000000..3272aee58 --- /dev/null +++ b/libraries/irrxml/example/test.cpp @@ -0,0 +1,40 @@ +#include +using namespace irr; +using namespace io; + +#include // we use STL strings to store data in this example + +int main() +{ + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + // strings for storing the data we want to get out of the file + std::string modelFile; + std::string messageText; + std::string caption; + + // parse the file until end reached + while(xml && xml->read()) + { + switch(xml->getNodeType()) + { + case EXN_TEXT: + // in this xml file, the only text which occurs is the messageText + messageText = xml->getNodeData(); + break; + case EXN_ELEMENT: + { + if (!strcmp("startUpModel", xml->getNodeName())) + modelFile = xml->getAttributeValue("file"); + else + if (!strcmp("messageText", xml->getNodeName())) + caption = xml->getAttributeValue("caption"); + } + break; + } + } + + // delete the xml parser after usage + delete xml; + return 0; +} diff --git a/libraries/irrxml/include/CXMLReaderImpl.h b/libraries/irrxml/include/CXMLReaderImpl.h new file mode 100644 index 000000000..859a657b8 --- /dev/null +++ b/libraries/irrxml/include/CXMLReaderImpl.h @@ -0,0 +1,797 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __ICXML_READER_IMPL_H_INCLUDED__ +#define __ICXML_READER_IMPL_H_INCLUDED__ + +#include "irrXML.h" +#include "irrString.h" +#include "irrArray.h" +#include "fast_atof.h" + +#ifdef _DEBUG +#define IRR_DEBUGPRINT(x) printf((x)); +#else // _DEBUG +#define IRR_DEBUGPRINT(x) +#endif // _DEBUG + + +namespace irr +{ +namespace io +{ + + +//! implementation of the IrrXMLReader +template +class CXMLReaderImpl : public IIrrXMLReader +{ +public: + + //! Constructor + CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true) + : TextData(0), P(0), TextSize(0), TextBegin(0), CurrentNodeType(EXN_NONE), + SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII) + { + if (!callback) + return; + + storeTargetFormat(); + + // read whole xml file + + readFile(callback); + + // clean up + + if (deleteCallBack) + delete callback; + + // create list with special characters + + createSpecialCharacterList(); + + // set pointer to text begin + P = TextBegin; + } + + + //! Destructor + virtual ~CXMLReaderImpl() + { + delete [] TextData; + } + + + //! Reads forward to the next xml node. + //! \return Returns false, if there was no further node. + virtual bool read() + { + // if not end reached, parse the node + if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0) + { + parseCurrentNode(); + return true; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const + { + return CurrentNodeType; + } + + + //! Returns attribute count of the current XML node. + virtual int getAttributeCount() const + { + return Attributes.size(); + } + + + //! Returns name of an attribute. + virtual const char_type* getAttributeName(int idx) const + { + if (idx < 0 || idx >= (int)Attributes.size()) + return 0; + + return Attributes[idx].Name.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(int idx) const + { + if (idx < 0 || idx >= (int)Attributes.size()) + return 0; + + return Attributes[idx].Value.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + return attr->Value.c_str(); + } + + + //! Returns the value of an attribute + virtual const char_type* getAttributeValueSafe(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return EmptyString.c_str(); + + return attr->Value.c_str(); + } + + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(const char_type* name) const + { + return (int)getAttributeValueAsFloat(name); + } + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(int idx) const + { + return (int)getAttributeValueAsFloat(idx); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + core::stringc c = attr->Value.c_str(); + return core::fast_atof(c.c_str()); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(int idx) const + { + const char_type* attrvalue = getAttributeValue(idx); + if (!attrvalue) + return 0; + + core::stringc c = attrvalue; + return core::fast_atof(c.c_str()); + } + + + //! Returns the name of the current node. + virtual const char_type* getNodeName() const + { + return NodeName.c_str(); + } + + + //! Returns data of the current node. + virtual const char_type* getNodeData() const + { + return NodeName.c_str(); + } + + + //! Returns if an element is an empty element, like + virtual bool isEmptyElement() const + { + return IsEmptyElement; + } + + //! Returns format of the source xml file. + virtual ETEXT_FORMAT getSourceFormat() const + { + return SourceFormat; + } + + //! Returns format of the strings returned by the parser. + virtual ETEXT_FORMAT getParserFormat() const + { + return TargetFormat; + } + +private: + + // Reads the current xml node + void parseCurrentNode() + { + char_type* start = P; + + // more forward until '<' found + while(*P != L'<' && *P) + ++P; + + if (!*P) + return; + + if (P - start > 0) + { + // we found some text, store it + if (setText(start, P)) + return; + } + + ++P; + + // based on current token, parse and report next element + switch(*P) + { + case L'/': + parseClosingXMLElement(); + break; + case L'?': + ignoreDefinition(); + break; + case L'!': + if (!parseCDATA()) + parseComment(); + break; + default: + parseOpeningXMLElement(); + break; + } + } + + + //! sets the state that text was found. Returns true if set should be set + bool setText(char_type* start, char_type* end) + { + // check if text is more than 2 characters, and if not, check if there is + // only white space, so that this text won't be reported + if (end - start < 3) + { + char_type* p = start; + for(; p != end; ++p) + if (!isWhiteSpace(*p)) + break; + + if (p == end) + return false; + } + + // set current text to the parsed text, and replace xml special characters + core::string s(start, (int)(end - start)); + NodeName = replaceSpecialCharacters(s); + + // current XML node type is text + CurrentNodeType = EXN_TEXT; + + return true; + } + + + + //! ignores an xml definition like + void ignoreDefinition() + { + CurrentNodeType = EXN_UNKNOWN; + + // move until end marked with '>' reached + while(*P != L'>') + ++P; + + ++P; + } + + + //! parses a comment + void parseComment() + { + CurrentNodeType = EXN_COMMENT; + P += 1; + + char_type *pCommentBegin = P; + + int count = 1; + + // move until end of comment reached + while(count) + { + if (*P == L'>') + --count; + else + if (*P == L'<') + ++count; + + ++P; + } + + P -= 3; + NodeName = core::string(pCommentBegin+2, (int)(P - pCommentBegin-2)); + P += 3; + } + + + //! parses an opening xml element and reads attributes + void parseOpeningXMLElement() + { + CurrentNodeType = EXN_ELEMENT; + IsEmptyElement = false; + Attributes.clear(); + + // find name + const char_type* startName = P; + + // find end of element + while(*P != L'>' && !isWhiteSpace(*P)) + ++P; + + const char_type* endName = P; + + // find Attributes + while(*P != L'>') + { + if (isWhiteSpace(*P)) + ++P; + else + { + if (*P != L'/') + { + // we've got an attribute + + // read the attribute names + const char_type* attributeNameBegin = P; + + while(!isWhiteSpace(*P) && *P != L'=') + ++P; + + const char_type* attributeNameEnd = P; + ++P; + + // read the attribute value + // check for quotes and single quotes, thx to murphy + while( (*P != L'\"') && (*P != L'\'') && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type attributeQuoteChar = *P; + + ++P; + const char_type* attributeValueBegin = P; + + while(*P != attributeQuoteChar && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type* attributeValueEnd = P; + ++P; + + SAttribute attr; + attr.Name = core::string(attributeNameBegin, + (int)(attributeNameEnd - attributeNameBegin)); + + core::string s(attributeValueBegin, + (int)(attributeValueEnd - attributeValueBegin)); + + attr.Value = replaceSpecialCharacters(s); + Attributes.push_back(attr); + } + else + { + // tag is closed directly + ++P; + IsEmptyElement = true; + break; + } + } + } + + // check if this tag is closing directly + if (endName > startName && *(endName-1) == L'/') + { + // directly closing tag + IsEmptyElement = true; + endName--; + } + + NodeName = core::string(startName, (int)(endName - startName)); + + ++P; + } + + + //! parses an closing xml tag + void parseClosingXMLElement() + { + CurrentNodeType = EXN_ELEMENT_END; + IsEmptyElement = false; + Attributes.clear(); + + ++P; + const char_type* pBeginClose = P; + + while(*P != L'>') + ++P; + + NodeName = core::string(pBeginClose, (int)(P - pBeginClose)); + ++P; + } + + //! parses a possible CDATA section, returns false if begin was not a CDATA section + bool parseCDATA() + { + if (*(P+1) != L'[') + return false; + + CurrentNodeType = EXN_CDATA; + + // skip '' && + (*(P-1) == L']') && + (*(P-2) == L']')) + { + cDataEnd = P - 2; + } + + ++P; + } + + if ( cDataEnd ) + NodeName = core::string(cDataBegin, (int)(cDataEnd - cDataBegin)); + else + NodeName = ""; + + return true; + } + + + // structure for storing attribute-name pairs + struct SAttribute + { + core::string Name; + core::string Value; + }; + + // finds a current attribute by name, returns 0 if not found + const SAttribute* getAttributeByName(const char_type* name) const + { + if (!name) + return 0; + + core::string n = name; + + for (int i=0; i<(int)Attributes.size(); ++i) + if (Attributes[i].Name == n) + return &Attributes[i]; + + return 0; + } + + // replaces xml special characters in a string and creates a new one + core::string replaceSpecialCharacters( + core::string& origstr) + { + int pos = origstr.findFirst(L'&'); + int oldPos = 0; + + if (pos == -1) + return origstr; + + core::string newstr; + + while(pos != -1 && pos < origstr.size()-2) + { + // check if it is one of the special characters + + int specialChar = -1; + for (int i=0; i<(int)SpecialCharacters.size(); ++i) + { + const char_type* p = &origstr.c_str()[pos]+1; + + if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1)) + { + specialChar = i; + break; + } + } + + if (specialChar != -1) + { + newstr.append(origstr.subString(oldPos, pos - oldPos)); + newstr.append(SpecialCharacters[specialChar][0]); + pos += SpecialCharacters[specialChar].size(); + } + else + { + newstr.append(origstr.subString(oldPos, pos - oldPos + 1)); + pos += 1; + } + + // find next & + oldPos = pos; + pos = origstr.findNext(L'&', pos); + } + + if (oldPos < origstr.size()-1) + newstr.append(origstr.subString(oldPos, origstr.size()-oldPos)); + + return newstr; + } + + + + //! reads the xml file and converts it into the wanted character format. + bool readFile(IFileReadCallBack* callback) + { + int size = callback->getSize(); + size += 4; // We need two terminating 0's at the end. + // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4. + + char* data8 = new char[size]; + + if (!callback->read(data8, size-4)) + { + delete [] data8; + return false; + } + + // add zeros at end + + data8[size-1] = 0; + data8[size-2] = 0; + data8[size-3] = 0; + data8[size-4] = 0; + + char16* data16 = reinterpret_cast(data8); + char32* data32 = reinterpret_cast(data8); + + // now we need to convert the data to the desired target format + // based on the byte order mark. + + const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF; + const int UTF16_BE = 0xFFFE; + const int UTF16_LE = 0xFEFF; + const int UTF32_BE = 0xFFFE0000; + const int UTF32_LE = 0x0000FEFF; + + // check source for all utf versions and convert to target data format + + if (size >= 4 && data32[0] == (char32)UTF32_BE) + { + // UTF-32, big endian + SourceFormat = ETF_UTF32_BE; + convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header + } + else + if (size >= 4 && data32[0] == (char32)UTF32_LE) + { + // UTF-32, little endian + SourceFormat = ETF_UTF32_LE; + convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_BE) + { + // UTF-16, big endian + SourceFormat = ETF_UTF16_BE; + convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_LE) + { + // UTF-16, little endian + SourceFormat = ETF_UTF16_LE; + convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header + } + else + if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2]) + { + // UTF-8 + SourceFormat = ETF_UTF8; + convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header + } + else + { + // ASCII + SourceFormat = ETF_ASCII; + convertTextData(data8, data8, size); + } + + return true; + } + + + //! converts the text file into the desired format. + //! \param source: begin of the text (without byte order mark) + //! \param pointerToStore: pointer to text data block which can be + //! stored or deleted based on the nesessary conversion. + //! \param sizeWithoutHeader: Text size in characters without header + template + void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader) + { + // convert little to big endian if necessary + if (sizeof(src_char_type) > 1 && + isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat)) + convertToLittleEndian(source); + + // check if conversion is necessary: + if (sizeof(src_char_type) == sizeof(char_type)) + { + // no need to convert + TextBegin = (char_type*)source; + TextData = (char_type*)pointerToStore; + TextSize = sizeWithoutHeader; + } + else + { + // convert source into target data format. + // TODO: implement a real conversion. This one just + // copies bytes. This is a problem when there are + // unicode symbols using more than one character. + + TextData = new char_type[sizeWithoutHeader]; + + for (int i=0; i + void convertToLittleEndian(src_char_type* t) + { + if (sizeof(src_char_type) == 4) + { + // 32 bit + + while(*t) + { + *t = ((*t & 0xff000000) >> 24) | + ((*t & 0x00ff0000) >> 8) | + ((*t & 0x0000ff00) << 8) | + ((*t & 0x000000ff) << 24); + ++t; + } + } + else + { + // 16 bit + + while(*t) + { + *t = (*t >> 8) | (*t << 8); + ++t; + } + } + } + + //! returns if a format is little endian + inline bool isLittleEndian(ETEXT_FORMAT f) + { + return f == ETF_ASCII || + f == ETF_UTF8 || + f == ETF_UTF16_LE || + f == ETF_UTF32_LE; + } + + + //! returns true if a character is whitespace + inline bool isWhiteSpace(char_type c) + { + return (c==' ' || c=='\t' || c=='\n' || c=='\r'); + } + + + //! generates a list with xml special characters + void createSpecialCharacterList() + { + // list of strings containing special symbols, + // the first character is the special character, + // the following is the symbol string without trailing &. + + SpecialCharacters.push_back("&"); + SpecialCharacters.push_back("gt;"); + SpecialCharacters.push_back("\"quot;"); + SpecialCharacters.push_back("'apos;"); + + } + + + //! compares the first n characters of the strings + bool equalsn(const char_type* str1, const char_type* str2, int len) + { + int i; + for(i=0; str1[i] && str2[i] && i < len; ++i) + if (str1[i] != str2[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (str1[i] == 0 && str2[i] == 0); + } + + + //! stores the target text format + void storeTargetFormat() + { + // get target format. We could have done this using template specialization, + // but VisualStudio 6 don't like it and we want to support it. + + switch(sizeof(char_type)) + { + case 1: + TargetFormat = ETF_UTF8; + break; + case 2: + TargetFormat = ETF_UTF16_LE; + break; + case 4: + TargetFormat = ETF_UTF32_LE; + break; + default: + TargetFormat = ETF_ASCII; // should never happen. + } + } + + + // instance variables: + + char_type* TextData; // data block of the text file + char_type* P; // current point in text to parse + char_type* TextBegin; // start of text to parse + unsigned int TextSize; // size of text to parse in characters, not bytes + + EXML_NODE CurrentNodeType; // type of the currently parsed node + ETEXT_FORMAT SourceFormat; // source format of the xml file + ETEXT_FORMAT TargetFormat; // output format of this parser + + core::string NodeName; // name of the node currently in + core::string EmptyString; // empty string to be returned by getSafe() methods + + bool IsEmptyElement; // is the currently parsed node empty? + + core::array< core::string > SpecialCharacters; // see createSpecialCharacterList() + + core::array Attributes; // attributes of current element + +}; // end CXMLReaderImpl + + +} // end namespace +} // end namespace + +#endif diff --git a/libraries/irrxml/include/fast_atof.h b/libraries/irrxml/include/fast_atof.h new file mode 100644 index 000000000..da5c65f75 --- /dev/null +++ b/libraries/irrxml/include/fast_atof.h @@ -0,0 +1,139 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __FAST_A_TO_F_H_INCLUDED__ +#define __FAST_A_TO_F_H_INCLUDED__ + +#include +#include + +namespace irr +{ +namespace core +{ + +const float fast_atof_table[] = { + 0.f, + 0.1f, + 0.01f, + 0.001f, + 0.0001f, + 0.00001f, + 0.000001f, + 0.0000001f, + 0.00000001f, + 0.000000001f, + 0.0000000001f, + 0.00000000001f, + 0.000000000001f, + 0.0000000000001f, + 0.00000000000001f, + 0.000000000000001f + }; + +//! Provides a fast function for converting a string into a float, +//! about 6 times faster than atof in win32. +// If you find any bugs, please send them to me, niko (at) irrlicht3d.org. +inline char* fast_atof_move(char* c, float& out) +{ + bool inv = false; + char *t; + float f; + + if (*c=='-') + { + c++; + inv = true; + } + + f = (float)strtol(c, &t, 10); + + c = t; + + if (*c == '.') + { + c++; + + float pl = (float)strtol(c, &t, 10); + pl *= fast_atof_table[t-c]; + + f += pl; + + c = t; + + if (*c == 'e') + { + ++c; + float exp = (float)strtol(c, &t, 10); + f *= (float)pow(10.0f, exp); + c = t; + } + } + + if (inv) + f *= -1.0f; + + out = f; + return c; +} + +//! Provides a fast function for converting a string into a float, +//! about 6 times faster than atof in win32. +// If you find any bugs, please send them to me, niko (at) irrlicht3d.org. +inline const char* fast_atof_move_const(const char* c, float& out) +{ + bool inv = false; + char *t; + float f; + + if (*c=='-') + { + c++; + inv = true; + } + + f = (float)strtol(c, &t, 10); + + c = t; + + if (*c == '.') + { + c++; + + float pl = (float)strtol(c, &t, 10); + pl *= fast_atof_table[t-c]; + + f += pl; + + c = t; + + if (*c == 'e') + { + ++c; + f32 exp = (f32)strtol(c, &t, 10); + f *= (f32)powf(10.0f, exp); + c = t; + } + } + + if (inv) + f *= -1.0f; + + out = f; + return c; +} + + +inline float fast_atof(const char* c) +{ + float ret; + fast_atof_move_const(c, ret); + return ret; +} + +} // end namespace core +}// end namespace irr + +#endif + diff --git a/libraries/irrxml/include/heapsort.h b/libraries/irrxml/include/heapsort.h new file mode 100644 index 000000000..4395119df --- /dev/null +++ b/libraries/irrxml/include/heapsort.h @@ -0,0 +1,73 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_HEAPSORT_H_INCLUDED__ +#define __IRR_HEAPSORT_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace core +{ + +//! Sinks an element into the heap. +template +inline void heapsink(T*array, s32 element, s32 max) +{ + while ((element<<1) < max) // there is a left child + { + s32 j = (element<<1); + + if (j+1 < max && array[j] < array[j+1]) + j = j+1; // take right child + + if (array[element] < array[j]) + { + T t = array[j]; // swap elements + array[j] = array[element]; + array[element] = t; + element = j; + } + else + return; + } +} + + +//! Sorts an array with size 'size' using heapsort. +template +inline void heapsort(T* array_, s32 size) +{ + // for heapsink we pretent this is not c++, where + // arrays start with index 0. So we decrease the array pointer, + // the maximum always +2 and the element always +1 + + T* virtualArray = array_ - 1; + s32 virtualSize = size + 2; + s32 i; + + // build heap + + for (i=((size-1)/2); i>=0; --i) + heapsink(virtualArray, i+1, virtualSize-1); + + // sort array + + for (i=size-1; i>=0; --i) + { + T t = array_[0]; + array_[0] = array_[i]; + array_[i] = t; + heapsink(virtualArray, 1, i + 1); + } +} + +} // end namespace core +} // end namespace irr + + + +#endif + diff --git a/libraries/irrxml/include/irrArray.h b/libraries/irrxml/include/irrArray.h new file mode 100644 index 000000000..5347f829a --- /dev/null +++ b/libraries/irrxml/include/irrArray.h @@ -0,0 +1,444 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h + +#ifndef __IRR_ARRAY_H_INCLUDED__ +#define __IRR_ARRAY_H_INCLUDED__ + +#include "irrTypes.h" +#include "heapsort.h" + +namespace irr +{ +namespace core +{ + +//! Self reallocating template array (like stl vector) with additional features. +/** Some features are: Heap sorting, binary search methods, easier debugging. +*/ +template +class array +{ + +public: + + array() + : data(0), used(0), allocated(0), + free_when_destroyed(true), is_sorted(true) + { + } + + //! Constructs a array and allocates an initial chunk of memory. + //! \param start_count: Amount of elements to allocate. + array(u32 start_count) + : data(0), used(0), allocated(0), + free_when_destroyed(true), is_sorted(true) + { + reallocate(start_count); + } + + + //! Copy constructor + array(const array& other) + : data(0) + { + *this = other; + } + + + + //! Destructor. Frees allocated memory, if set_free_when_destroyed + //! was not set to false by the user before. + ~array() + { + if (free_when_destroyed) + delete [] data; + } + + + + //! Reallocates the array, make it bigger or smaller. + //! \param new_size: New size of array. + void reallocate(u32 new_size) + { + T* old_data = data; + + data = new T[new_size]; + allocated = new_size; + + s32 end = used < new_size ? used : new_size; + for (s32 i=0; i allocated) + { + // reallocate(used * 2 +1); + // this doesn't work if the element is in the same array. So + // we'll copy the element first to be sure we'll get no data + // corruption + + T e; + e = element; // copy element + reallocate(used * 2 +1); // increase data block + data[used++] = e; // push_back + is_sorted = false; + return; + } + + data[used++] = element; + is_sorted = false; + } + + + //! Adds an element at the front of the array. If the array is to small to + //! add this new element, the array is made bigger. Please note that this + //! is slow, because the whole array needs to be copied for this. + //! \param element: Element to add at the back of the array. + void push_front(const T& element) + { + if (used + 1 > allocated) + reallocate(used * 2 +1); + + for (int i=(int)used; i>0; --i) + data[i] = data[i-1]; + + data[0] = element; + is_sorted = false; + ++used; + } + + + //! Insert item into array at specified position. Please use this + //! only if you know what you are doing (possible performance loss). + //! The preferred method of adding elements should be push_back(). + //! \param element: Element to be inserted + //! \param index: Where position to insert the new element. + void insert(const T& element, u32 index=0) + { + _IRR_DEBUG_BREAK_IF(index>used) // access violation + + if (used + 1 > allocated) + reallocate(used * 2 +1); + + for (u32 i=used++; i>index; i--) + data[i] = data[i-1]; + + data[index] = element; + is_sorted = false; + } + + + + + //! Clears the array and deletes all allocated memory. + void clear() + { + delete [] data; + data = 0; + used = 0; + allocated = 0; + is_sorted = true; + } + + + + //! Sets pointer to new array, using this as new workspace. + //! \param newPointer: Pointer to new array of elements. + //! \param size: Size of the new array. + void set_pointer(T* newPointer, u32 size) + { + delete [] data; + data = newPointer; + allocated = size; + used = size; + is_sorted = false; + } + + + + //! Sets if the array should delete the memory it used. + //! \param f: If true, the array frees the allocated memory in its + //! destructor, otherwise not. The default is true. + void set_free_when_destroyed(bool f) + { + free_when_destroyed = f; + } + + + + //! Sets the size of the array. + //! \param usedNow: Amount of elements now used. + void set_used(u32 usedNow) + { + if (allocated < usedNow) + reallocate(usedNow); + + used = usedNow; + } + + + + //! Assignement operator + void operator=(const array& other) + { + if (data) + delete [] data; + + //if (allocated < other.allocated) + if (other.allocated == 0) + data = 0; + else + data = new T[other.allocated]; + + used = other.used; + free_when_destroyed = other.free_when_destroyed; + is_sorted = other.is_sorted; + allocated = other.allocated; + + for (u32 i=0; i=used) // access violation + + return data[index]; + } + + + + //! Direct access operator + const T& operator [](u32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // access violation + + return data[index]; + } + + //! Gets last frame + const T& getLast() const + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + //! Gets last frame + T& getLast() + { + _IRR_DEBUG_BREAK_IF(!used) // access violation + + return data[used-1]; + } + + + //! Returns a pointer to the array. + //! \return Pointer to the array. + T* pointer() + { + return data; + } + + + + //! Returns a const pointer to the array. + //! \return Pointer to the array. + const T* const_pointer() const + { + return data; + } + + + + //! Returns size of used array. + //! \return Size of elements in the array. + u32 size() const + { + return used; + } + + + + //! Returns amount memory allocated. + //! \return Returns amount of memory allocated. The amount of bytes + //! allocated would be allocated_size() * sizeof(ElementsUsed); + u32 allocated_size() const + { + return allocated; + } + + + + //! Returns true if array is empty + //! \return True if the array is empty, false if not. + bool empty() const + { + return used == 0; + } + + + + //! Sorts the array using heapsort. There is no additional memory waste and + //! the algorithm performs (O) n log n in worst case. + void sort() + { + if (is_sorted || used<2) + return; + + heapsort(data, used); + is_sorted = true; + } + + + + //! Performs a binary search for an element, returns -1 if not found. + //! The array will be sorted before the binary search if it is not + //! already sorted. + //! \param element: Element to search for. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 binary_search(const T& element) + { + return binary_search(element, 0, used-1); + } + + + + //! Performs a binary search for an element, returns -1 if not found. + //! The array will be sorted before the binary search if it is not + //! already sorted. + //! \param element: Element to search for. + //! \param left: First left index + //! \param right: Last right index. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 binary_search(const T& element, s32 left, s32 right) + { + if (!used) + return -1; + + sort(); + + s32 m; + + do + { + m = (left+right)>>1; + + if (element < data[m]) + right = m - 1; + else + left = m + 1; + + } while((element < data[m] || data[m] < element) && left<=right); + + // this last line equals to: + // " while((element != array[m]) && left<=right);" + // but we only want to use the '<' operator. + // the same in next line, it is "(element == array[m])" + + if (!(element < data[m]) && !(data[m] < element)) + return m; + + return -1; + } + + + //! Finds an element in linear time, which is very slow. Use + //! binary_search for faster finding. Only works if =operator is implemented. + //! \param element: Element to search for. + //! \return Returns position of the searched element if it was found, + //! otherwise -1 is returned. + s32 linear_search(T& element) + { + for (u32 i=0; i=0; --i) + if (data[i] == element) + return (s32)i; + + return -1; + } + + + + //! Erases an element from the array. May be slow, because all elements + //! following after the erased element have to be copied. + //! \param index: Index of element to be erased. + void erase(u32 index) + { + _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation + + for (u32 i=index+1; i=used || index<0 || count<1 || index+count>used) // access violation + + for (u32 i=index+count; i and string work both with unicode AND ascii, +so you can assign unicode to string and ascii to string +(and the other way round) if your ever would want to. +Note that the conversation between both is not done using an encoding. + +Known bugs: +Special characters like 'Ä', 'Ü' and 'Ö' are ignored in the +methods make_upper, make_lower and equals_ignore_case. +*/ +template +class string +{ +public: + + //! Default constructor + string() + : allocated(1), used(1), array(0) + { + array = new T[1]; + array[0] = 0x0; + } + + + + //! Constructor + string(const string& other) + : allocated(0), used(0), array(0) + { + *this = other; + } + + + //! Constructs a string from an int + string(int number) + : allocated(0), used(0), array(0) + { + // store if negative and make positive + + bool negative = false; + if (number < 0) + { + number *= -1; + negative = true; + } + + // temporary buffer for 16 numbers + + c8 tmpbuf[16]; + tmpbuf[15] = 0; + s32 idx = 15; + + // special case '0' + + if (!number) + { + tmpbuf[14] = '0'; + *this = &tmpbuf[14]; + return; + } + + // add numbers + + while(number && idx) + { + idx--; + tmpbuf[idx] = (c8)('0' + (number % 10)); + number = number / 10; + } + + // add sign + + if (negative) + { + idx--; + tmpbuf[idx] = '-'; + } + + *this = &tmpbuf[idx]; + } + + + + //! Constructor for copying a string from a pointer with a given lenght + template + string(const B* c, s32 lenght) + : allocated(0), used(0), array(0) + { + if (!c) + return; + + allocated = used = lenght+1; + array = new T[used]; + + for (s32 l = 0; l + string(const B* c) + : allocated(0), used(0), array(0) + { + *this = c; + } + + + + //! destructor + ~string() + { + delete [] array; + } + + + + //! Assignment operator + string& operator=(const string& other) + { + if (this == &other) + return *this; + + delete [] array; + allocated = used = other.size()+1; + array = new T[used]; + + const T* p = other.c_str(); + for (s32 i=0; i + string& operator=(const B* c) + { + if (!c) + { + if (!array) + { + array = new T[1]; + allocated = 1; + used = 1; + } + array[0] = 0x0; + return *this; + } + + if ((void*)c == (void*)array) + return *this; + + s32 len = 0; + const B* p = c; + while(*p) + { + ++len; + ++p; + } + + // we'll take the old string for a while, because the new string could be + // a part of the current string. + T* oldArray = array; + + allocated = used = len+1; + array = new T[used]; + + for (s32 l = 0; l operator+(const string& other) + { + string str(*this); + str.append(other); + + return str; + } + + //! Add operator for strings, ascii and unicode + template + string operator+(const B* c) + { + string str(*this); + str.append(c); + + return str; + } + + + + //! Direct access operator + T& operator [](const s32 index) const + { + _IRR_DEBUG_BREAK_IF(index>=used) // bad index + + return array[index]; + } + + + //! Comparison operator + bool operator ==(const T* str) const + { + int i; + for(i=0; array[i] && str[i]; ++i) + if (array[i] != str[i]) + return false; + + return !array[i] && !str[i]; + } + + + + //! Comparison operator + bool operator ==(const string& other) const + { + for(s32 i=0; array[i] && other.array[i]; ++i) + if (array[i] != other.array[i]) + return false; + + return used == other.used; + } + + + + //! Is smaller operator + bool operator <(const string& other) const + { + for(s32 i=0; array[i] && other.array[i]; ++i) + if (array[i] != other.array[i]) + return (array[i] < other.array[i]); + + return used < other.used; + } + + + + //! Equals not operator + bool operator !=(const string& other) const + { + return !(*this == other); + } + + + + //! Returns length of string + /** \return Returns length of the string in characters. */ + s32 size() const + { + return used-1; + } + + + + //! Returns character string + /** \return Returns pointer to C-style zero terminated string. */ + const T* c_str() const + { + return array; + } + + + + //! Makes the string lower case. + void make_lower() + { + const T A = (T)'A'; + const T Z = (T)'Z'; + const T diff = (T)'a' - A; + + for (s32 i=0; i=A && array[i]<=Z) + array[i] += diff; + } + } + + + + //! Makes the string upper case. + void make_upper() + { + const T a = (T)'a'; + const T z = (T)'z'; + const T diff = (T)'A' - a; + + for (s32 i=0; i=a && array[i]<=z) + array[i] += diff; + } + } + + + + //! Compares the string ignoring case. + /** \param other: Other string to compare. + \return Returns true if the string are equal ignoring case. */ + bool equals_ignore_case(const string& other) const + { + for(s32 i=0; array[i] && other[i]; ++i) + if (toLower(array[i]) != toLower(other[i])) + return false; + + return used == other.used; + } + + + //! compares the first n characters of the strings + bool equalsn(const string& other, int len) + { + int i; + for(i=0; array[i] && other[i] && i < len; ++i) + if (array[i] != other[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (used == other.used); + } + + + //! compares the first n characters of the strings + bool equalsn(const T* str, int len) + { + int i; + for(i=0; array[i] && str[i] && i < len; ++i) + if (array[i] != str[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (array[i] == 0 && str[i] == 0); + } + + + //! Appends a character to this string + /** \param character: Character to append. */ + void append(T character) + { + if (used + 1 > allocated) + reallocate((s32)used + 1); + + used += 1; + + array[used-2] = character; + array[used-1] = 0; + } + + //! Appends a string to this string + /** \param other: String to append. */ + void append(const string& other) + { + --used; + + s32 len = other.size(); + + if (used + len + 1 > allocated) + reallocate((s32)used + (s32)len + 1); + + for (s32 l=0; l& other, s32 length) + { + s32 len = other.size(); + + if (len < length) + { + append(other); + return; + } + + len = length; + --used; + + if (used + len > allocated) + reallocate((s32)used + (s32)len); + + for (s32 l=0; l + s32 findFirstCharNotInList(B* c, int count) const + { + for (int i=0; i + s32 findLastCharNotInList(B* c, int count) const + { + for (int i=used-2; i>=0; --i) + { + int j; + for (j=0; j=0; --i) + if (array[i] == c) + return i; + + return -1; + } + + + //! Returns a substring + //! \param begin: Start of substring. + //! \param length: Length of substring. + string subString(s32 begin, s32 length) + { + if (length <= 0) + return string(""); + + string o; + o.reserve(length+1); + + for (s32 i=0; i& other) + { + append(other); + } + + void operator += (int i) + { + append(string(i)); + } + + //! replaces all characters of a special type with another one + void replace(T toReplace, T replaceWith) + { + for (s32 i=0; i=used || index<0) // access violation + + for (int i=index+1; i=(T)'A' && t<=(T)'Z') + return t + ((T)'a' - (T)'A'); + else + return t; + } + + //! Reallocate the array, make it bigger or smaler + void reallocate(s32 new_size) + { + T* old_array = array; + + array = new T[new_size]; + allocated = new_size; + + s32 amount = used < new_size ? used : new_size; + for (s32 i=0; i stringc; + +//! Typedef for wide character strings +typedef string stringw; + +} // end namespace core +} // end namespace irr + +#endif + diff --git a/libraries/irrxml/include/irrTypes.h b/libraries/irrxml/include/irrTypes.h new file mode 100644 index 000000000..aa2254d1c --- /dev/null +++ b/libraries/irrxml/include/irrTypes.h @@ -0,0 +1,101 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_TYPES_H_INCLUDED__ +#define __IRR_TYPES_H_INCLUDED__ + +namespace irr +{ + +//! 8 bit unsigned variable. +/** This is a typedef for unsigned char, it ensures portability of the engine. */ +typedef unsigned char u8; + +//! 8 bit signed variable. +/** This is a typedef for signed char, it ensures portability of the engine. */ +typedef signed char s8; + +//! 8 bit character variable. +/** This is a typedef for char, it ensures portability of the engine. */ +typedef char c8; + + + +//! 16 bit unsigned variable. +/** This is a typedef for unsigned short, it ensures portability of the engine. */ +typedef unsigned short u16; + +//! 16 bit signed variable. +/** This is a typedef for signed short, it ensures portability of the engine. */ +typedef signed short s16; + + + +//! 32 bit unsigned variable. +/** This is a typedef for unsigned int, it ensures portability of the engine. */ +typedef unsigned int u32; + +//! 32 bit signed variable. +/** This is a typedef for signed int, it ensures portability of the engine. */ +typedef signed int s32; + + + +// 64 bit signed variable. +// This is a typedef for __int64, it ensures portability of the engine. +// This type is currently not used by the engine and not supported by compilers +// other than Microsoft Compilers, so it is outcommented. +//typedef __int64 s64; + + + +//! 32 bit floating point variable. +/** This is a typedef for float, it ensures portability of the engine. */ +typedef float f32; + +//! 64 bit floating point variable. +/** This is a typedef for double, it ensures portability of the engine. */ +typedef double f64; + + +} // end namespace + + +// define the wchar_t type if not already built in. +#ifdef _MSC_VER +#ifndef _WCHAR_T_DEFINED +//! A 16 bit wide character type. +/** + Defines the wchar_t-type. + In VS6, its not possible to tell + the standard compiler to treat wchar_t as a built-in type, and + sometimes we just don't want to include the huge stdlib.h or wchar.h, + so we'll use this. +*/ +typedef unsigned short wchar_t; +#define _WCHAR_T_DEFINED +#endif // wchar is not defined +#endif // microsoft compiler + +//! define a break macro for debugging only in Win32 mode. +#if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG) +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) if (_CONDITION_) {_asm int 3} +#else +#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) +#endif + +//! Defines a small statement to work around a microsoft compiler bug. +/** The microsft compiler 7.0 - 7.1 has a bug: +When you call unmanaged code that returns a bool type value of false from managed code, +the return value may appear as true. See +http://support.microsoft.com/default.aspx?kbid=823071 for details. +Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/ +#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400) +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX __asm mov eax,100 +#else +#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX +#endif // _IRR_MANAGED_MARSHALLING_BUGFIX + +#endif // __IRR_TYPES_H_INCLUDED__ + diff --git a/libraries/irrxml/include/irrXML.h b/libraries/irrxml/include/irrXML.h new file mode 100644 index 000000000..23eb2a11b --- /dev/null +++ b/libraries/irrxml/include/irrXML.h @@ -0,0 +1,540 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __IRR_XML_H_INCLUDED__ +#define __IRR_XML_H_INCLUDED__ + +#include + +/** \mainpage irrXML 1.2 API documentation +
+ + \section intro Introduction + + Welcome to the irrXML API documentation. + Here you'll find any information you'll need to develop applications with + irrXML. If you look for a tutorial on how to start, take a look at the \ref irrxmlexample, + at the homepage of irrXML at
xml.irrlicht3d.org + or into the SDK in the directory \example. + + irrXML is intended to be a high speed and easy-to-use XML Parser for C++, and + this documentation is an important part of it. If you have any questions or + suggestions, just send a email to the author of the engine, Nikolaus Gebhardt + (niko (at) irrlicht3d.org). For more informations about this parser, see \ref history. + + \section features Features + + irrXML provides forward-only, read-only + access to a stream of non validated XML data. It was fully implemented by + Nikolaus Gebhardt. Its current features are: + + - It it fast as lighting and has very low memory usage. It was + developed with the intention of being used in 3D games, as it already has been. + - irrXML is very small: It only consists of 60 KB of code and can be added easily + to your existing project. + - Of course, it is platform independent and works with lots of compilers. + - It is able to parse ASCII, UTF-8, UTF-16 and UTF-32 text files, both in + little and big endian format. + - Independent of the input file format, the parser can return all strings in ASCII, UTF-8, + UTF-16 and UTF-32 format. + - With its optional file access abstraction it has the advantage that it can read not + only from files but from any type of data (memory, network, ...). For example when + used with the Irrlicht Engine, it directly reads from compressed .zip files. + - Just like the Irrlicht Engine for which it was originally created, it is extremely easy + to use. + - It has no external dependencies, it does not even need the STL. + + Although irrXML has some strenghts, it currently also has the following limitations: + + - The input xml file is not validated and assumed to be correct. + + \section irrxmlexample Example + + The following code demonstrates the basic usage of irrXML. A simple xml + file like this is parsed: + \code + + + + + + Welcome to the Mesh Viewer of the "Irrlicht Engine". + + + \endcode + + The code for parsing this file would look like this: + \code + #include + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + #include // we use STL strings to store data in this example + + void main() + { + // create the reader using one of the factory functions + + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + // strings for storing the data we want to get out of the file + std::string modelFile; + std::string messageText; + std::string caption; + + // parse the file until end reached + + while(xml && xml->read()) + { + switch(xml->getNodeType()) + { + case EXN_TEXT: + // in this xml file, the only text which occurs is the messageText + messageText = xml->getNodeData(); + break; + case EXN_ELEMENT: + { + if (!strcmp("model", xml->getNodeName())) + modelFile = xml->getAttributeValue("file"); + else + if (!strcmp("messageText", xml->getNodeName())) + caption = xml->getAttributeValue("caption"); + } + break; + } + } + + // delete the xml parser after usage + delete xml; + } + \endcode + + \section howto How to use + + Simply add the source files in the /src directory of irrXML to your project. Done. + + \section license License + + The irrXML license is based on the zlib license. Basicly, this means you can do with + irrXML whatever you want: + + Copyright (C) 2002-2005 Nikolaus Gebhardt + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + \section history History + + As lots of references in this documentation and the source show, this xml + parser has originally been a part of the + Irrlicht Engine. But because + the parser has become very useful with the latest release, people asked for a + separate version of it, to be able to use it in non Irrlicht projects. With + irrXML 1.0, this has now been done. +*/ + +namespace irr +{ +namespace io +{ + //! Enumeration of all supported source text file formats + enum ETEXT_FORMAT + { + //! ASCII, file without byte order mark, or not a text file + ETF_ASCII, + + //! UTF-8 format + ETF_UTF8, + + //! UTF-16 format, big endian + ETF_UTF16_BE, + + //! UTF-16 format, little endian + ETF_UTF16_LE, + + //! UTF-32 format, big endian + ETF_UTF32_BE, + + //! UTF-32 format, little endian + ETF_UTF32_LE, + }; + + + //! Enumeration for all xml nodes which are parsed by IrrXMLReader + enum EXML_NODE + { + //! No xml node. This is usually the node if you did not read anything yet. + EXN_NONE, + + //! A xml element, like + EXN_ELEMENT, + + //! End of an xml element, like + EXN_ELEMENT_END, + + //! Text within a xml element: this is the text. + EXN_TEXT, + + //! An xml comment like <!-- I am a comment --> or a DTD definition. + EXN_COMMENT, + + //! An xml cdata section like <![CDATA[ this is some CDATA ]]> + EXN_CDATA, + + //! Unknown element. + EXN_UNKNOWN + }; + + //! Callback class for file read abstraction. + /** With this, it is possible to make the xml parser read in other things + than just files. The Irrlicht engine is using this for example to + read xml from compressed .zip files. To make the parser read in + any other data, derive a class from this interface, implement the + two methods to read your data and give a pointer to an instance of + your implementation when calling createIrrXMLReader(), + createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */ + class IFileReadCallBack + { + public: + + //! virtual destructor + virtual ~IFileReadCallBack() {}; + + //! Reads an amount of bytes from the file. + /** \param buffer: Pointer to buffer where to read bytes will be written to. + \param sizeToRead: Amount of bytes to read from the file. + \return Returns how much bytes were read. */ + virtual int read(void* buffer, int sizeToRead) = 0; + + //! Returns size of file in bytes + virtual int getSize() = 0; + }; + + //! Empty class to be used as parent class for IrrXMLReader. + /** If you need another class as base class for the xml reader, you can do this by creating + the reader using for example new CXMLReaderImpl(yourcallback); + The Irrlicht Engine for example needs IUnknown as base class for every object to + let it automaticly reference countend, hence it replaces IXMLBase with IUnknown. + See irrXML.cpp on how this can be done in detail. */ + class IXMLBase + { + }; + + //! Interface providing easy read access to a XML file. + /** You can create an instance of this reader using one of the factory functions + createIrrXMLReader(), createIrrXMLReaderUTF16() and createIrrXMLReaderUTF32(). + If using the parser from the Irrlicht Engine, please use IFileSystem::createXMLReader() + instead. + For a detailed intro how to use the parser, see \ref irrxmlexample and \ref features. + + The typical usage of this parser looks like this: + \code + #include + using namespace irr; // irrXML is located in the namespace irr::io + using namespace io; + + void main() + { + // create the reader using one of the factory functions + IrrXMLReader* xml = createIrrXMLReader("config.xml"); + + if (xml == 0) + return; // file could not be opened + + // parse the file until end reached + while(xml->read()) + { + // based on xml->getNodeType(), do something. + } + + // delete the xml parser after usage + delete xml; + } + \endcode + See \ref irrxmlexample for a more detailed example. + */ + template + class IIrrXMLReader : public super_class + { + public: + + //! Destructor + virtual ~IIrrXMLReader() {}; + + //! Reads forward to the next xml node. + /** \return Returns false, if there was no further node. */ + virtual bool read() = 0; + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const = 0; + + //! Returns attribute count of the current XML node. + /** This is usually + non null if the current node is EXN_ELEMENT, and the element has attributes. + \return Returns amount of attributes of this xml node. */ + virtual int getAttributeCount() const = 0; + + //! Returns name of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Name of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeName(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute, 0 if an attribute with this index does not exist. */ + virtual const char_type* getAttributeValue(int idx) const = 0; + + //! Returns the value of an attribute. + /** \param name: Name of the attribute. + \return Value of the attribute, 0 if an attribute with this name does not exist. */ + virtual const char_type* getAttributeValue(const char_type* name) const = 0; + + //! Returns the value of an attribute in a safe way. + /** Like getAttributeValue(), but does not + return 0 if the attribute does not exist. An empty string ("") is returned then. + \param name: Name of the attribute. + \return Value of the attribute, and "" if an attribute with this name does not exist */ + virtual const char_type* getAttributeValueSafe(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param name Name of the attribute. + \return Value of the attribute as integer, and 0 if an attribute with this name does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(const char_type* name) const = 0; + + //! Returns the value of an attribute as integer. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as integer, and 0 if an attribute with this index does not exist or + the value could not be interpreted as integer. */ + virtual int getAttributeValueAsInt(int idx) const = 0; + + //! Returns the value of an attribute as float. + /** \param name: Name of the attribute. + \return Value of the attribute as float, and 0 if an attribute with this name does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(const char_type* name) const = 0; + + //! Returns the value of an attribute as float. + /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1. + \return Value of the attribute as float, and 0 if an attribute with this index does not exist or + the value could not be interpreted as float. */ + virtual float getAttributeValueAsFloat(int idx) const = 0; + + //! Returns the name of the current node. + /** Only non null, if the node type is EXN_ELEMENT. + \return Name of the current node or 0 if the node has no name. */ + virtual const char_type* getNodeName() const = 0; + + //! Returns data of the current node. + /** Only non null if the node has some + data and it is of type EXN_TEXT or EXN_UNKNOWN. */ + virtual const char_type* getNodeData() const = 0; + + //! Returns if an element is an empty element, like + virtual bool isEmptyElement() const = 0; + + //! Returns format of the source xml file. + /** It is not necessary to use + this method because the parser will convert the input file format + to the format wanted by the user when creating the parser. This + method is useful to get/display additional informations. */ + virtual ETEXT_FORMAT getSourceFormat() const = 0; + + //! Returns format of the strings returned by the parser. + /** This will be UTF8 for example when you created a parser with + IrrXMLReaderUTF8() and UTF32 when it has been created using + IrrXMLReaderUTF32. It should not be necessary to call this + method and only exists for informational purposes. */ + virtual ETEXT_FORMAT getParserFormat() const = 0; + }; + + + //! defines the utf-16 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef unsigned short char16; + + //! defines the utf-32 type. + /** Not using wchar_t for this because + wchar_t has 16 bit on windows and 32 bit on other operating systems. */ + typedef unsigned long char32; + + //! A UTF-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser. + The file to read can be in any format, it will be converted to UTF-8 if it is not + in this format. + Create an instance of this with createIrrXMLReader(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReader; + + //! A UTF-16 xml parser. + /** This means that all character data will be returned in UTF-16 by this parser. + The file to read can be in any format, it will be converted to UTF-16 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF16(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReaderUTF16; + + //! A UTF-32 xml parser. + /** This means that all character data will be returned in UTF-32 by this parser. + The file to read can be in any format, it will be converted to UTF-32 if it is not + in this format. + Create an instance of this with createIrrXMLReaderUTF32(); + See IIrrXMLReader for description on how to use it. */ + typedef IIrrXMLReader IrrXMLReaderUTF32; + + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. + The file to read can be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReader* createIrrXMLReader(const char* filename); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReader* createIrrXMLReader(FILE* file); + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can + be in any format, it will be converted to UTF-8 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReaderUTF8() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that + all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file); + + //! Creates an instance of an UFT-16 xml parser. + /** This means that all character data will be returned in UTF-16. The file to read can + be in any format, it will be converted to UTF-16 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback); + + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param filename: Name of file to be opened. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + if you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param file: Pointer to opened file, must have been opened in binary mode, e.g. + using fopen("foo.bar", "wb"); The file will not be closed after it has been read. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file); + + //! Creates an instance of an UFT-32 xml parser. + /** This means that + all character data will be returned in UTF-32. The file to read can + be in any format, it will be converted to UTF-32 if it is not in this format. + If you are using the Irrlicht Engine, it is better not to use this function but + IFileSystem::createXMLReader() instead. + \param callback: Callback for file read abstraction. Implement your own + callback to make the xml parser read in other things than just files. See + IFileReadCallBack for more information about this. + \return Returns a pointer to the created xml parser. This pointer should be + deleted using 'delete' after no longer needed. Returns 0 if an error occured + and the file could not be opened. */ + IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback); + + + /*! \file irrxml.h + \brief Header file of the irrXML, the Irrlicht XML parser. + + This file includes everything needed for using irrXML, + the XML parser of the Irrlicht Engine. To use irrXML, + you only need to include this file in your project: + + \code + #include + \endcode + + It is also common to use the two namespaces in which irrXML is included, + directly after #including irrXML.h: + + \code + #include + using namespace irr; + using namespace io; + \endcode + */ + +} // end namespace io +} // end namespace irr + +#endif // __IRR_XML_H_INCLUDED__ + diff --git a/libraries/irrxml/readme.txt b/libraries/irrxml/readme.txt new file mode 100644 index 000000000..2384dc435 --- /dev/null +++ b/libraries/irrxml/readme.txt @@ -0,0 +1,110 @@ +========================================================================== +irrXML 1.2 +========================================================================== + + Welcome to irrXML + + Content of this file: + + 1. Directory structure overview + 2. How to use + 3. Requirements + 5. License + 6. Contact + + + +========================================================================== +1. Directory structure overview +========================================================================== + + You will find some directories after decompressing the archive in which + came the SDK. These are: + + \doc Documentation of irrXML. + \example A short example showing how to use the parser with solution + and make files. + \src The source code of irrXML. + +========================================================================== +2. How to use +========================================================================== + + For Linux/Unix users: Simply go into the directory /example and run + 'make'. This will create a sample project using irrXML. + + Windows users: Just add the source files to your project. That's all. + For more information see the documentation in the \doc directory. + + Alternatively, you could compile irrXML as .lib, after this you would + only need to use the irrXML.h header file, nothing more. + + +========================================================================== +3. Requirements +========================================================================== + + You can use one of the following compilers/IDEs to develop applications + with irrXML. However, other compilers/IDEs make work as well, + we simply didn't test them. + + * gcc 3.2 + * gcc 3.3 + * Visual Studio 6.0 + * Visual Studio.NET (7.0) + * Visual Studio.NET 2003 (7.1) + * Visual Studio.NET 2005 (8.0) + * DevC++ 4.9 & gcc (project files included) + +========================================================================== +5. License +========================================================================== + + The license of irrXML is based on the zlib/libpng license. + Even though this license does not require you to mention that you are + using the Irrlicht Engine in your product, an acknowledgement + would be highly appreciated. + + The irrXML License + =========================== + + Copyright (C) 2002-2005 Nikolaus Gebhardt + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + + +========================================================================== +6. Contact +========================================================================== + + If you have problems, questions or suggestions, please visit the + official homepage of irrXML: + + http://xml.irrlicht3d.org + + You will find forums, patches, documentation, and other stuff + which will help you out. + + If want to contact the author of the engine, please send an email to + Nikolaus Gebhardt: + + irrlicht@users.sourceforge.net + + + + \ No newline at end of file diff --git a/libraries/irrxml/src/irrXML.cpp b/libraries/irrxml/src/irrXML.cpp new file mode 100644 index 000000000..b3080af1c --- /dev/null +++ b/libraries/irrxml/src/irrXML.cpp @@ -0,0 +1,147 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#include "irrXML.h" +#include "irrString.h" +#include "irrArray.h" +#include "fast_atof.h" +#include "CXMLReaderImpl.h" + +namespace irr +{ +namespace io +{ + +//! Implementation of the file read callback for ordinary files +class CFileReadCallBack : public IFileReadCallBack +{ +public: + + //! construct from filename + CFileReadCallBack(const char* filename) + : File(0), Size(0), Close(true) + { + // open file + File = fopen(filename, "rb"); + + if (File) + getFileSize(); + } + + //! construct from FILE pointer + CFileReadCallBack(FILE* file) + : File(file), Size(0), Close(false) + { + if (File) + getFileSize(); + } + + //! destructor + virtual ~CFileReadCallBack() + { + if (Close && File) + fclose(File); + } + + //! Reads an amount of bytes from the file. + virtual int read(void* buffer, int sizeToRead) + { + if (!File) + return 0; + + return (int)fread(buffer, 1, sizeToRead, File); + } + + //! Returns size of file in bytes + virtual int getSize() + { + return Size; + } + +private: + + //! retrieves the file size of the open file + void getFileSize() + { + fseek(File, 0, SEEK_END); + Size = ftell(File); + fseek(File, 0, SEEK_SET); + } + + FILE* File; + int Size; + bool Close; + +}; // end class CFileReadCallBack + + + +// FACTORY FUNCTIONS: + + +//! Creates an instance of an UFT-8 or ASCII character xml parser. +IrrXMLReader* createIrrXMLReader(const char* filename) +{ + return new CXMLReaderImpl(new CFileReadCallBack(filename)); +} + + +//! Creates an instance of an UFT-8 or ASCII character xml parser. +IrrXMLReader* createIrrXMLReader(FILE* file) +{ + return new CXMLReaderImpl(new CFileReadCallBack(file)); +} + + +//! Creates an instance of an UFT-8 or ASCII character xml parser. +IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback) +{ + return new CXMLReaderImpl(callback, false); +} + + +//! Creates an instance of an UTF-16 xml parser. +IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename) +{ + return new CXMLReaderImpl(new CFileReadCallBack(filename)); +} + + +//! Creates an instance of an UTF-16 xml parser. +IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file) +{ + return new CXMLReaderImpl(new CFileReadCallBack(file)); +} + + +//! Creates an instance of an UTF-16 xml parser. +IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback) +{ + return new CXMLReaderImpl(callback, false); +} + + +//! Creates an instance of an UTF-32 xml parser. +IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename) +{ + return new CXMLReaderImpl(new CFileReadCallBack(filename)); +} + + +//! Creates an instance of an UTF-32 xml parser. +IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file) +{ + return new CXMLReaderImpl(new CFileReadCallBack(file)); +} + + +//! Creates an instance of an UTF-32 xml parser. +IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback) +{ + return new CXMLReaderImpl(callback, false); +} + + +} // end namespace io +} // end namespace irr diff --git a/serialization/include/openmm/serialization/XmlSerializer.h b/serialization/include/openmm/serialization/XmlSerializer.h index ef53a15eb..5726296d0 100644 --- a/serialization/include/openmm/serialization/XmlSerializer.h +++ b/serialization/include/openmm/serialization/XmlSerializer.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010-2014 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -38,8 +38,6 @@ #include "openmm/internal/windowsExport.h" #include -class TiXmlElement; - namespace OpenMM { /** @@ -77,10 +75,10 @@ public: return reinterpret_cast(deserializeStream(stream)); } private: + class StreamReader; static void serialize(const SerializationNode& node, std::ostream& stream); static void* deserializeStream(std::istream& stream); static void encodeNode(const SerializationNode& node, std::ostream& stream, int depth); - static void decodeNode(SerializationNode& node, const TiXmlElement& element); }; } // namespace OpenMM diff --git a/serialization/src/XmlSerializer.cpp b/serialization/src/XmlSerializer.cpp index 97a27e111..debd09ac5 100644 --- a/serialization/src/XmlSerializer.cpp +++ b/serialization/src/XmlSerializer.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010-2014 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -30,10 +30,81 @@ * -------------------------------------------------------------------------- */ #include "openmm/serialization/XmlSerializer.h" -#include "tinyxml.h" +#include "irrXML.h" +#include +#include +#include using namespace OpenMM; using namespace std; +using namespace irr; +using namespace io; + +/** + * Apply XML encoding to a string. This is adapted from TinyXML (written by Lee Thomason). + */ +static void encodeString(const string& str, string* outString) { + static map entities; + static bool hasInitialized = false; + if (!hasInitialized) { + hasInitialized = true; + entities['&'] = "&"; + entities['<'] = "<"; + entities['>'] = ">"; + entities['\"'] = """; + entities['\''] = "'"; + } + + int i=0; + + while (i<(int)str.length()) { + unsigned char c = (unsigned char) str[i]; + + if (c == '&' + && i < ((int)str.length() - 2) + && str[i+1] == '#' + && str[i+2] == 'x') { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while (i<(int)str.length()-1) { + outString->append(str.c_str() + i, 1); + ++i; + if (str[i] == ';') + break; + } + } + else if (entities.find(c) != entities.end()) { + outString->append(entities[c]); + ++i; + } + else if (c < 32) { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + + snprintf(buf, sizeof(buf), "&#x%02X;", (unsigned) (c & 0xff)); + + //*ME: warning C4267: convert 'size_t' to 'int' + //*ME: Int-Cast to make compiler happy ... + outString->append(buf, (int)strlen(buf)); + ++i; + } + else { + //char realc = (char) c; + //outString->append(&realc, 1); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } +} void XmlSerializer::serialize(const SerializationNode& node, std::ostream& stream) { stream << "\n"; @@ -47,8 +118,8 @@ void XmlSerializer::encodeNode(const SerializationNode& node, std::ostream& stre const map& properties = node.getProperties(); for (map::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) { string name, value; - TiXmlBase::EncodeString(iter->first, &name); - TiXmlBase::EncodeString(iter->second, &value); + encodeString(iter->first, &name); + encodeString(iter->second, &value); stream << ' ' << name << "=\"" << value << '\"'; } const vector& children = node.getChildren(); @@ -64,20 +135,64 @@ void XmlSerializer::encodeNode(const SerializationNode& node, std::ostream& stre } } +/** + * Adapter class to let irrXML read a C++ stream. + */ +class XmlSerializer::StreamReader : public IFileReadCallBack { +public: + StreamReader(std::istream& stream) : stream(stream) { + stream.seekg(0, ios_base::end); + size = stream.tellg(); + stream.seekg(0); + } + int read(void* buffer, int sizeToRead) { + stream.read((char*) buffer, sizeToRead); + return stream.gcount(); + } + int getSize() { + return size; + } +private: + std::istream& stream; + int size; +}; + +/** + * Process an XML node, storing its content into a SerializationNode. + */ +static void decodeNode(SerializationNode& node, IrrXMLReader& xml) { + for (int i = 0; i < xml.getAttributeCount(); i++) + node.setStringProperty(xml.getAttributeName(i), xml.getAttributeValue(i)); + if (xml.isEmptyElement()) + return; + while (xml.read()) { + switch (xml.getNodeType()) { + case EXN_ELEMENT: + { + SerializationNode& childNode = node.createChildNode(xml.getNodeName()); + decodeNode(childNode, xml); + break; + } + case EXN_ELEMENT_END: + return; + } + } +} + void* XmlSerializer::deserializeStream(std::istream& stream) { - TiXmlDocument doc; - stream >> doc; SerializationNode root; - decodeNode(root, *doc.FirstChildElement()); + StreamReader reader(stream); + IrrXMLReader* xml = createIrrXMLReader(&reader); + + // Find the root node in the file. + + while (xml->read() && xml->getNodeType() != EXN_ELEMENT) + ; + decodeNode(root, *xml); + delete xml; + + // Process the SerializationNodes. + const SerializationProxy& proxy = SerializationProxy::getProxy(root.getStringProperty("type")); return proxy.deserialize(root); } - -void XmlSerializer::decodeNode(SerializationNode& node, const TiXmlElement& element) { - for (const TiXmlAttribute* attribute = element.FirstAttribute(); attribute != NULL; attribute = attribute->Next()) - node.setStringProperty(attribute->NameTStr(), attribute->ValueStr()); - for (const TiXmlElement* child = element.FirstChildElement(); child != NULL; child = child->NextSiblingElement()) { - SerializationNode& childNode = node.createChildNode(child->ValueTStr()); - decodeNode(childNode, *child); - } -} \ No newline at end of file diff --git a/serialization/src/tinyxml.cpp b/serialization/src/tinyxml.cpp deleted file mode 100644 index 9be6c6a66..000000000 --- a/serialization/src/tinyxml.cpp +++ /dev/null @@ -1,1839 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include - -#ifdef TIXML_USE_STL -#include -#include -#endif - -#include "tinyxml.h" - -FILE* TiXmlFOpen( const char* filename, const char* mode ); - -bool TiXmlBase::condenseWhiteSpace = true; - -// Microsoft compiler security -FILE* TiXmlFOpen( const char* filename, const char* mode ) -{ - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - FILE* fp = 0; - errno_t err = fopen_s( &fp, filename, mode ); - if ( !err && fp ) - return fp; - return 0; - #else - return fopen( filename, mode ); - #endif -} - -void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) -{ - int i=0; - - while( i<(int)str.length() ) - { - unsigned char c = (unsigned char) str[i]; - - if ( c == '&' - && i < ( (int)str.length() - 2 ) - && str[i+1] == '#' - && str[i+2] == 'x' ) - { - // Hexadecimal character reference. - // Pass through unchanged. - // © -- copyright symbol, for example. - // - // The -1 is a bug fix from Rob Laveaux. It keeps - // an overflow from happening if there is no ';'. - // There are actually 2 ways to exit this loop - - // while fails (error case) and break (semicolon found). - // However, there is no mechanism (currently) for - // this function to return an error. - while ( i<(int)str.length()-1 ) - { - outString->append( str.c_str() + i, 1 ); - ++i; - if ( str[i] == ';' ) - break; - } - } - else if ( c == '&' ) - { - outString->append( entity[0].str, entity[0].strLength ); - ++i; - } - else if ( c == '<' ) - { - outString->append( entity[1].str, entity[1].strLength ); - ++i; - } - else if ( c == '>' ) - { - outString->append( entity[2].str, entity[2].strLength ); - ++i; - } - else if ( c == '\"' ) - { - outString->append( entity[3].str, entity[3].strLength ); - ++i; - } - else if ( c == '\'' ) - { - outString->append( entity[4].str, entity[4].strLength ); - ++i; - } - else if ( c < 32 ) - { - // Easy pass at non-alpha/numeric/symbol - // Below 32 is symbolic. - char buf[ 32 ]; - - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); - #else - sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); - #endif - - //*ME: warning C4267: convert 'size_t' to 'int' - //*ME: Int-Cast to make compiler happy ... - outString->append( buf, (int)strlen( buf ) ); - ++i; - } - else - { - //char realc = (char) c; - //outString->append( &realc, 1 ); - *outString += (char) c; // somewhat more efficient function call. - ++i; - } - } -} - - -TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() -{ - parent = 0; - type = _type; - firstChild = 0; - lastChild = 0; - prev = 0; - next = 0; -} - - -TiXmlNode::~TiXmlNode() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } -} - - -void TiXmlNode::CopyTo( TiXmlNode* target ) const -{ - target->SetValue (value.c_str() ); - target->userData = userData; - target->location = location; -} - - -void TiXmlNode::Clear() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } - - firstChild = 0; - lastChild = 0; -} - - -TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) -{ - assert( node->parent == 0 || node->parent == this ); - assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); - - if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - delete node; - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - node->parent = this; - - node->prev = lastChild; - node->next = 0; - - if ( lastChild ) - lastChild->next = node; - else - firstChild = node; // it was an empty list. - - lastChild = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) -{ - if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - - return LinkEndChild( node ); -} - - -TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -{ - if ( !beforeThis || beforeThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->next = beforeThis; - node->prev = beforeThis->prev; - if ( beforeThis->prev ) - { - beforeThis->prev->next = node; - } - else - { - assert( firstChild == beforeThis ); - firstChild = node; - } - beforeThis->prev = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) -{ - if ( !afterThis || afterThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->prev = afterThis; - node->next = afterThis->next; - if ( afterThis->next ) - { - afterThis->next->prev = node; - } - else - { - assert( lastChild == afterThis ); - lastChild = node; - } - afterThis->next = node; - return node; -} - - -TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) -{ - if ( !replaceThis ) - return 0; - - if ( replaceThis->parent != this ) - return 0; - - if ( withThis.ToDocument() ) { - // A document can never be a child. Thanks to Noam. - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = withThis.Clone(); - if ( !node ) - return 0; - - node->next = replaceThis->next; - node->prev = replaceThis->prev; - - if ( replaceThis->next ) - replaceThis->next->prev = node; - else - lastChild = node; - - if ( replaceThis->prev ) - replaceThis->prev->next = node; - else - firstChild = node; - - delete replaceThis; - node->parent = this; - return node; -} - - -bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) -{ - if ( !removeThis ) { - return false; - } - - if ( removeThis->parent != this ) - { - assert( 0 ); - return false; - } - - if ( removeThis->next ) - removeThis->next->prev = removeThis->prev; - else - lastChild = removeThis->prev; - - if ( removeThis->prev ) - removeThis->prev->next = removeThis->next; - else - firstChild = removeThis->next; - - delete removeThis; - return true; -} - -const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = firstChild; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = lastChild; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild(); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling(); - } -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild( val ); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling( val ); - } -} - - -const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = next; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = prev; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -void TiXmlElement::RemoveAttribute( const char * name ) -{ - #ifdef TIXML_USE_STL - TIXML_STRING str( name ); - TiXmlAttribute* node = attributeSet.Find( str ); - #else - TiXmlAttribute* node = attributeSet.Find( name ); - #endif - if ( node ) - { - attributeSet.Remove( node ); - delete node; - } -} - -const TiXmlElement* TiXmlNode::FirstChildElement() const -{ - const TiXmlNode* node; - - for ( node = FirstChild(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = FirstChild( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement() const -{ - const TiXmlNode* node; - - for ( node = NextSibling(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = NextSibling( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlDocument* TiXmlNode::GetDocument() const -{ - const TiXmlNode* node; - - for( node = this; node; node = node->parent ) - { - if ( node->ToDocument() ) - return node->ToDocument(); - } - return 0; -} - - -TiXmlElement::TiXmlElement (const char * _value) - : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) -{ - firstChild = lastChild = 0; - value = _value; -} - - -#ifdef TIXML_USE_STL -TiXmlElement::TiXmlElement( const std::string& _value ) - : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) -{ - firstChild = lastChild = 0; - value = _value; -} -#endif - - -TiXmlElement::TiXmlElement( const TiXmlElement& copy) - : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) -{ - firstChild = lastChild = 0; - copy.CopyTo( this ); -} - - -void TiXmlElement::operator=( const TiXmlElement& base ) -{ - ClearThis(); - base.CopyTo( this ); -} - - -TiXmlElement::~TiXmlElement() -{ - ClearThis(); -} - - -void TiXmlElement::ClearThis() -{ - Clear(); - while( attributeSet.First() ) - { - TiXmlAttribute* node = attributeSet.First(); - attributeSet.Remove( node ); - delete node; - } -} - - -const char* TiXmlElement::Attribute( const char* name ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - return node->Value(); - return 0; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - if ( attrib ) - return &attrib->ValueStr(); - return 0; -} -#endif - - -const char* TiXmlElement::Attribute( const char* name, int* i ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - const char* result = 0; - - if ( attrib ) { - result = attrib->Value(); - if ( i ) { - attrib->QueryIntValue( i ); - } - } - return result; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - const std::string* result = 0; - - if ( attrib ) { - result = &attrib->ValueStr(); - if ( i ) { - attrib->QueryIntValue( i ); - } - } - return result; -} -#endif - - -const char* TiXmlElement::Attribute( const char* name, double* d ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - const char* result = 0; - - if ( attrib ) { - result = attrib->Value(); - if ( d ) { - attrib->QueryDoubleValue( d ); - } - } - return result; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - const std::string* result = 0; - - if ( attrib ) { - result = &attrib->ValueStr(); - if ( d ) { - attrib->QueryDoubleValue( d ); - } - } - return result; -} -#endif - - -int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - if ( !attrib ) - return TIXML_NO_ATTRIBUTE; - return attrib->QueryIntValue( ival ); -} - - -#ifdef TIXML_USE_STL -int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - if ( !attrib ) - return TIXML_NO_ATTRIBUTE; - return attrib->QueryIntValue( ival ); -} -#endif - - -int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - if ( !attrib ) - return TIXML_NO_ATTRIBUTE; - return attrib->QueryDoubleValue( dval ); -} - - -#ifdef TIXML_USE_STL -int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const -{ - const TiXmlAttribute* attrib = attributeSet.Find( name ); - if ( !attrib ) - return TIXML_NO_ATTRIBUTE; - return attrib->QueryDoubleValue( dval ); -} -#endif - - -void TiXmlElement::SetAttribute( const char * name, int val ) -{ - TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); - if ( attrib ) { - attrib->SetIntValue( val ); - } -} - - -#ifdef TIXML_USE_STL -void TiXmlElement::SetAttribute( const std::string& name, int val ) -{ - TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); - if ( attrib ) { - attrib->SetIntValue( val ); - } -} -#endif - - -void TiXmlElement::SetDoubleAttribute( const char * name, double val ) -{ - TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); - if ( attrib ) { - attrib->SetDoubleValue( val ); - } -} - - -#ifdef TIXML_USE_STL -void TiXmlElement::SetDoubleAttribute( const std::string& name, double val ) -{ - TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); - if ( attrib ) { - attrib->SetDoubleValue( val ); - } -} -#endif - - -void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) -{ - TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname ); - if ( attrib ) { - attrib->SetValue( cvalue ); - } -} - - -#ifdef TIXML_USE_STL -void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value ) -{ - TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name ); - if ( attrib ) { - attrib->SetValue( _value ); - } -} -#endif - - -void TiXmlElement::Print( FILE* cfile, int depth ) const -{ - int i; - assert( cfile ); - for ( i=0; iNext() ) - { - fprintf( cfile, " " ); - attrib->Print( cfile, depth ); - } - - // There are 3 different formatting approaches: - // 1) An element without children is printed as a node - // 2) An element with only a text child is printed as text - // 3) An element with children is printed on multiple lines. - TiXmlNode* node; - if ( !firstChild ) - { - fprintf( cfile, " />" ); - } - else if ( firstChild == lastChild && firstChild->ToText() ) - { - fprintf( cfile, ">" ); - firstChild->Print( cfile, depth + 1 ); - fprintf( cfile, "", value.c_str() ); - } - else - { - fprintf( cfile, ">" ); - - for ( node = firstChild; node; node=node->NextSibling() ) - { - if ( !node->ToText() ) - { - fprintf( cfile, "\n" ); - } - node->Print( cfile, depth+1 ); - } - fprintf( cfile, "\n" ); - for( i=0; i", value.c_str() ); - } -} - - -void TiXmlElement::CopyTo( TiXmlElement* target ) const -{ - // superclass: - TiXmlNode::CopyTo( target ); - - // Element class: - // Clone the attributes, then clone the children. - const TiXmlAttribute* attribute = 0; - for( attribute = attributeSet.First(); - attribute; - attribute = attribute->Next() ) - { - target->SetAttribute( attribute->Name(), attribute->Value() ); - } - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - -bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this, attributeSet.First() ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -TiXmlNode* TiXmlElement::Clone() const -{ - TiXmlElement* clone = new TiXmlElement( Value() ); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -const char* TiXmlElement::GetText() const -{ - const TiXmlNode* child = this->FirstChild(); - if ( child ) { - const TiXmlText* childText = child->ToText(); - if ( childText ) { - return childText->Value(); - } - } - return 0; -} - - -TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - ClearError(); -} - -TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} - - -#ifdef TIXML_USE_STL -TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} -#endif - - -TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) -{ - copy.CopyTo( this ); -} - - -void TiXmlDocument::operator=( const TiXmlDocument& copy ) -{ - Clear(); - copy.CopyTo( this ); -} - - -bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) -{ - return LoadFile( Value(), encoding ); -} - - -bool TiXmlDocument::SaveFile() const -{ - return SaveFile( Value() ); -} - -bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) -{ - TIXML_STRING filename( _filename ); - value = filename; - - // reading in binary mode so that tinyxml can normalize the EOL - FILE* file = TiXmlFOpen( value.c_str (), "rb" ); - - if ( file ) - { - bool result = LoadFile( file, encoding ); - fclose( file ); - return result; - } - else - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } -} - -bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) -{ - if ( !file ) - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Delete the existing data: - Clear(); - location.Clear(); - - // Get the file size, so we can pre-allocate the string. HUGE speed impact. - long length = 0; - fseek( file, 0, SEEK_END ); - length = ftell( file ); - fseek( file, 0, SEEK_SET ); - - // Strange case, but good to handle up front. - if ( length <= 0 ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Subtle bug here. TinyXml did use fgets. But from the XML spec: - // 2.11 End-of-Line Handling - // - // - // ...the XML processor MUST behave as if it normalized all line breaks in external - // parsed entities (including the document entity) on input, before parsing, by translating - // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to - // a single #xA character. - // - // - // It is not clear fgets does that, and certainly isn't clear it works cross platform. - // Generally, you expect fgets to translate from the convention of the OS to the c/unix - // convention, and not work generally. - - /* - while( fgets( buf, sizeof(buf), file ) ) - { - data += buf; - } - */ - - char* buf = new char[ length+1 ]; - buf[0] = 0; - - if ( fread( buf, length, 1, file ) != 1 ) { - delete [] buf; - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Process the buffer in place to normalize new lines. (See comment above.) - // Copies from the 'p' to 'q' pointer, where p can advance faster if - // a newline-carriage return is hit. - // - // Wikipedia: - // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or - // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... - // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others - // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS - // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 - - const char* p = buf; // the read head - char* q = buf; // the write head - const char CR = 0x0d; - const char LF = 0x0a; - - buf[length] = 0; - while( *p ) { - assert( p < (buf+length) ); - assert( q <= (buf+length) ); - assert( q <= p ); - - if ( *p == CR ) { - *q++ = LF; - p++; - if ( *p == LF ) { // check for CR+LF (and skip LF) - p++; - } - } - else { - *q++ = *p++; - } - } - assert( q <= (buf+length) ); - *q = 0; - - Parse( buf, 0, encoding ); - - delete [] buf; - return !Error(); -} - - -bool TiXmlDocument::SaveFile( const char * filename ) const -{ - // The old c stuff lives on... - FILE* fp = TiXmlFOpen( filename, "w" ); - if ( fp ) - { - bool result = SaveFile( fp ); - fclose( fp ); - return result; - } - return false; -} - - -bool TiXmlDocument::SaveFile( FILE* fp ) const -{ - if ( useMicrosoftBOM ) - { - const unsigned char TIXML_UTF_LEAD_0 = 0xefU; - const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; - const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - - fputc( TIXML_UTF_LEAD_0, fp ); - fputc( TIXML_UTF_LEAD_1, fp ); - fputc( TIXML_UTF_LEAD_2, fp ); - } - Print( fp, 0 ); - return (ferror(fp) == 0); -} - - -void TiXmlDocument::CopyTo( TiXmlDocument* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->error = error; - target->errorId = errorId; - target->errorDesc = errorDesc; - target->tabsize = tabsize; - target->errorLocation = errorLocation; - target->useMicrosoftBOM = useMicrosoftBOM; - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - - -TiXmlNode* TiXmlDocument::Clone() const -{ - TiXmlDocument* clone = new TiXmlDocument(); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlDocument::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - node->Print( cfile, depth ); - fprintf( cfile, "\n" ); - } -} - - -bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -const TiXmlAttribute* TiXmlAttribute::Next() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} - -/* -TiXmlAttribute* TiXmlAttribute::Next() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} -*/ - -const TiXmlAttribute* TiXmlAttribute::Previous() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} - -/* -TiXmlAttribute* TiXmlAttribute::Previous() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} -*/ - -void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - TIXML_STRING n, v; - - EncodeString( name, &n ); - EncodeString( value, &v ); - - if (value.find ('\"') == TIXML_STRING::npos) { - if ( cfile ) { - fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; - } - } - else { - if ( cfile ) { - fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; - } - } -} - - -int TiXmlAttribute::QueryIntValue( int* ival ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -int TiXmlAttribute::QueryDoubleValue( double* dval ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -void TiXmlAttribute::SetIntValue( int _value ) -{ - char buf [64]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); - #else - sprintf (buf, "%d", _value); - #endif - SetValue (buf); -} - -void TiXmlAttribute::SetDoubleValue( double _value ) -{ - char buf [256]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value); - #else - sprintf (buf, "%g", _value); - #endif - SetValue (buf); -} - -int TiXmlAttribute::IntValue() const -{ - return atoi (value.c_str ()); -} - -double TiXmlAttribute::DoubleValue() const -{ - return atof (value.c_str ()); -} - - -TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) -{ - copy.CopyTo( this ); -} - - -void TiXmlComment::operator=( const TiXmlComment& base ) -{ - Clear(); - base.CopyTo( this ); -} - - -void TiXmlComment::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - for ( int i=0; i", value.c_str() ); -} - - -void TiXmlComment::CopyTo( TiXmlComment* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlComment::Clone() const -{ - TiXmlComment* clone = new TiXmlComment(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlText::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - if ( cdata ) - { - int i; - fprintf( cfile, "\n" ); - for ( i=0; i\n", value.c_str() ); // unformatted output - } - else - { - TIXML_STRING buffer; - EncodeString( value, &buffer ); - fprintf( cfile, "%s", buffer.c_str() ); - } -} - - -void TiXmlText::CopyTo( TiXmlText* target ) const -{ - TiXmlNode::CopyTo( target ); - target->cdata = cdata; -} - - -bool TiXmlText::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlText::Clone() const -{ - TiXmlText* clone = 0; - clone = new TiXmlText( "" ); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlDeclaration::TiXmlDeclaration( const char * _version, - const char * _encoding, - const char * _standalone ) - : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} - - -#ifdef TIXML_USE_STL -TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ) - : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} -#endif - - -TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) - : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) -{ - copy.CopyTo( this ); -} - - -void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) -{ - Clear(); - copy.CopyTo( this ); -} - - -void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - if ( cfile ) fprintf( cfile, "" ); - if ( str ) (*str) += "?>"; -} - - -void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->version = version; - target->encoding = encoding; - target->standalone = standalone; -} - - -bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlDeclaration::Clone() const -{ - TiXmlDeclaration* clone = new TiXmlDeclaration(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlUnknown::Print( FILE* cfile, int depth ) const -{ - for ( int i=0; i", value.c_str() ); -} - - -void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlUnknown::Clone() const -{ - TiXmlUnknown* clone = new TiXmlUnknown(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlAttributeSet::TiXmlAttributeSet() -{ - sentinel.next = &sentinel; - sentinel.prev = &sentinel; -} - - -TiXmlAttributeSet::~TiXmlAttributeSet() -{ - assert( sentinel.next == &sentinel ); - assert( sentinel.prev == &sentinel ); -} - - -void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) -{ - #ifdef TIXML_USE_STL - assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. - #else - assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. - #endif - - addMe->next = &sentinel; - addMe->prev = sentinel.prev; - - sentinel.prev->next = addMe; - sentinel.prev = addMe; -} - -void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) -{ - TiXmlAttribute* node; - - for( node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node == removeMe ) - { - node->prev->next = node->next; - node->next->prev = node->prev; - node->next = 0; - node->prev = 0; - return; - } - } - assert( 0 ); // we tried to remove a non-linked attribute. -} - - -#ifdef TIXML_USE_STL -TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; -} - -TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name ) -{ - TiXmlAttribute* attrib = Find( _name ); - if ( !attrib ) { - attrib = new TiXmlAttribute(); - Add( attrib ); - attrib->SetName( _name ); - } - return attrib; -} -#endif - - -TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; -} - - -TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name ) -{ - TiXmlAttribute* attrib = Find( _name ); - if ( !attrib ) { - attrib = new TiXmlAttribute(); - Add( attrib ); - attrib->SetName( _name ); - } - return attrib; -} - - -#ifdef TIXML_USE_STL -std::istream& operator>> (std::istream & in, TiXmlNode & base) -{ - TIXML_STRING tag; - tag.reserve( 8 * 1000 ); - base.StreamIn( &in, &tag ); - - base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); - return in; -} -#endif - - -#ifdef TIXML_USE_STL -std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out << printer.Str(); - - return out; -} - - -std::string& operator<< (std::string& out, const TiXmlNode& base ) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out.append( printer.Str() ); - - return out; -} -#endif - - -TiXmlHandle TiXmlHandle::FirstChild() const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement() const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild(); - for ( i=0; - child && iNextSibling(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild( value ); - for ( i=0; - child && iNextSibling( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement(); - for ( i=0; - child && iNextSiblingElement(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement( value ); - for ( i=0; - child && iNextSiblingElement( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) -{ - DoIndent(); - buffer += "<"; - buffer += element.Value(); - - for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) - { - buffer += " "; - attrib->Print( 0, 0, &buffer ); - } - - if ( !element.FirstChild() ) - { - buffer += " />"; - DoLineBreak(); - } - else - { - buffer += ">"; - if ( element.FirstChild()->ToText() - && element.LastChild() == element.FirstChild() - && element.FirstChild()->ToText()->CDATA() == false ) - { - simpleTextPrint = true; - // no DoLineBreak()! - } - else - { - DoLineBreak(); - } - } - ++depth; - return true; -} - - -bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) -{ - --depth; - if ( !element.FirstChild() ) - { - // nothing. - } - else - { - if ( simpleTextPrint ) - { - simpleTextPrint = false; - } - else - { - DoIndent(); - } - buffer += ""; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlText& text ) -{ - if ( text.CDATA() ) - { - DoIndent(); - buffer += ""; - DoLineBreak(); - } - else if ( simpleTextPrint ) - { - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - } - else - { - DoIndent(); - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) -{ - DoIndent(); - declaration.Print( 0, 0, &buffer ); - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlComment& comment ) -{ - DoIndent(); - buffer += ""; - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) -{ - DoIndent(); - buffer += "<"; - buffer += unknown.Value(); - buffer += ">"; - DoLineBreak(); - return true; -} - diff --git a/serialization/src/tinyxml.h b/serialization/src/tinyxml.h deleted file mode 100644 index 01822911c..000000000 --- a/serialization/src/tinyxml.h +++ /dev/null @@ -1,1799 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - - -#ifndef TINYXML_INCLUDED -#define TINYXML_INCLUDED - -#ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4530 ) -#pragma warning( disable : 4786 ) -#endif - -#include -#include -#include -#include -#include - -// Help out windows: -#if defined( _DEBUG ) && !defined( DEBUG ) -#define DEBUG -#endif - -#ifdef TIXML_USE_STL - #include - #include - #include - #define TIXML_STRING std::string -#else - #include "tinystr.h" - #define TIXML_STRING TiXmlString -#endif - -// Deprecated library function hell. Compilers want to use the -// new safe versions. This probably doesn't fully address the problem, -// but it gets closer. There are too many compilers for me to fully -// test. If you get compilation troubles, undefine TIXML_SAFE -#define TIXML_SAFE - -#ifdef TIXML_SAFE - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - // Microsoft visual studio, version 2005 and higher. - #define TIXML_SNPRINTF _snprintf_s - #define TIXML_SSCANF sscanf_s - #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - //#pragma message( "Using _sn* functions." ) - #define TIXML_SNPRINTF _snprintf - #define TIXML_SSCANF sscanf - #elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_SSCANF sscanf - #else - #define TIXML_SNPRINTF snprintf - #define TIXML_SSCANF sscanf - #endif -#endif - -class TiXmlDocument; -class TiXmlElement; -class TiXmlComment; -class TiXmlUnknown; -class TiXmlAttribute; -class TiXmlText; -class TiXmlDeclaration; -class TiXmlParsingData; - -const int TIXML_MAJOR_VERSION = 2; -const int TIXML_MINOR_VERSION = 6; -const int TIXML_PATCH_VERSION = 1; - -/* Internal structure for tracking location of items - in the XML file. -*/ -struct TiXmlCursor -{ - TiXmlCursor() { Clear(); } - void Clear() { row = col = -1; } - - int row; // 0 based. - int col; // 0 based. -}; - - -/** - Implements the interface to the "Visitor pattern" (see the Accept() method.) - If you call the Accept() method, it requires being passed a TiXmlVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves - are simply called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, no children of this node or its sibilings will be Visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. - - You should never change the document from a callback. - - @sa TiXmlNode::Accept() -*/ -class TiXmlVisitor -{ -public: - virtual ~TiXmlVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } - /// Visit a document. - virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } - - /// Visit an element. - virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } - /// Visit an element. - virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } - - /// Visit a declaration - virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } - /// Visit a text node - virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } - /// Visit a comment node - virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } - /// Visit an unknow node - virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } -}; - -// Only used by Attribute::Query functions -enum -{ - TIXML_SUCCESS, - TIXML_NO_ATTRIBUTE, - TIXML_WRONG_TYPE -}; - - -// Used by the parsing routines. -enum TiXmlEncoding -{ - TIXML_ENCODING_UNKNOWN, - TIXML_ENCODING_UTF8, - TIXML_ENCODING_LEGACY -}; - -const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; - -/** TiXmlBase is a base class for every class in TinyXml. - It does little except to establish that TinyXml classes - can be printed and provide some utility functions. - - In XML, the document and elements can contain - other elements and other types of nodes. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - A Decleration contains: Attributes (not on tree) - @endverbatim -*/ -class TiXmlBase -{ - friend class TiXmlNode; - friend class TiXmlElement; - friend class TiXmlDocument; - -public: - TiXmlBase() : userData(0) {} - virtual ~TiXmlBase() {} - - /** All TinyXml classes can print themselves to a filestream - or the string class (TiXmlString in non-STL mode, std::string - in STL mode.) Either or both cfile and str can be null. - - This is a formatted print, and will insert - tabs and newlines. - - (For an unformatted stream, use the << operator.) - */ - virtual void Print( FILE* cfile, int depth ) const = 0; - - /** The world does not agree on whether white space should be kept or - not. In order to make everyone happy, these global, static functions - are provided to set whether or not TinyXml will condense all white space - into a single space or not. The default is to condense. Note changing this - value is not thread safe. - */ - static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } - - /// Return the current white space setting. - static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } - - /** Return the position, in the original source file, of this node or attribute. - The row and column are 1-based. (That is the first row and first column is - 1,1). If the returns values are 0 or less, then the parser does not have - a row and column value. - - Generally, the row and column value will be set when the TiXmlDocument::Load(), - TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set - when the DOM was created from operator>>. - - The values reflect the initial load. Once the DOM is modified programmatically - (by adding or changing nodes and attributes) the new values will NOT update to - reflect changes in the document. - - There is a minor performance cost to computing the row and column. Computation - can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. - - @sa TiXmlDocument::SetTabSize() - */ - int Row() const { return location.row + 1; } - int Column() const { return location.col + 1; } ///< See Row() - - void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. - void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. - const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. - - // Table that returs, for a given lead byte, the total number of bytes - // in the UTF-8 sequence. - static const int utf8ByteTable[256]; - - virtual const char* Parse( const char* p, - TiXmlParsingData* data, - TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; - - /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, - or they will be transformed into entities! - */ - static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); - - enum - { - TIXML_NO_ERROR = 0, - TIXML_ERROR, - TIXML_ERROR_OPENING_FILE, - TIXML_ERROR_PARSING_ELEMENT, - TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, - TIXML_ERROR_READING_ELEMENT_VALUE, - TIXML_ERROR_READING_ATTRIBUTES, - TIXML_ERROR_PARSING_EMPTY, - TIXML_ERROR_READING_END_TAG, - TIXML_ERROR_PARSING_UNKNOWN, - TIXML_ERROR_PARSING_COMMENT, - TIXML_ERROR_PARSING_DECLARATION, - TIXML_ERROR_DOCUMENT_EMPTY, - TIXML_ERROR_EMBEDDED_NULL, - TIXML_ERROR_PARSING_CDATA, - TIXML_ERROR_DOCUMENT_TOP_ONLY, - - TIXML_ERROR_STRING_COUNT - }; - -protected: - - static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); - - inline static bool IsWhiteSpace( char c ) - { - return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); - } - inline static bool IsWhiteSpace( int c ) - { - if ( c < 256 ) - return IsWhiteSpace( (char) c ); - return false; // Again, only truly correct for English/Latin...but usually works. - } - - #ifdef TIXML_USE_STL - static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); - static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); - #endif - - /* Reads an XML name into the string provided. Returns - a pointer just past the last character of the name, - or 0 if the function has an error. - */ - static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); - - /* Reads text. Returns a pointer past the given end tag. - Wickedly complex options, but it keeps the (sensitive) code in one place. - */ - static const char* ReadText( const char* in, // where to start - TIXML_STRING* text, // the string read - bool ignoreWhiteSpace, // whether to keep the white space - const char* endTag, // what ends this text - bool ignoreCase, // whether to ignore case in the end tag - TiXmlEncoding encoding ); // the current encoding - - // If an entity has been found, transform it into a character. - static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); - - // Get a character, while interpreting entities. - // The length can be from 0 to 4 bytes. - inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) - { - assert( p ); - if ( encoding == TIXML_ENCODING_UTF8 ) - { - *length = utf8ByteTable[ *((const unsigned char*)p) ]; - assert( *length >= 0 && *length < 5 ); - } - else - { - *length = 1; - } - - if ( *length == 1 ) - { - if ( *p == '&' ) - return GetEntity( p, _value, length, encoding ); - *_value = *p; - return p+1; - } - else if ( *length ) - { - //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), - // and the null terminator isn't needed - for( int i=0; p[i] && i<*length; ++i ) { - _value[i] = p[i]; - } - return p + (*length); - } - else - { - // Not valid text. - return 0; - } - } - - // Return true if the next characters in the stream are any of the endTag sequences. - // Ignore case only works for english, and should only be relied on when comparing - // to English words: StringEqual( p, "version", true ) is fine. - static bool StringEqual( const char* p, - const char* endTag, - bool ignoreCase, - TiXmlEncoding encoding ); - - static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; - - TiXmlCursor location; - - /// Field containing a generic user pointer - void* userData; - - // None of these methods are reliable for any language except English. - // Good for approximation, not great for accuracy. - static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); - static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); - inline static int ToLower( int v, TiXmlEncoding encoding ) - { - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( v < 128 ) return tolower( v ); - return v; - } - else - { - return tolower( v ); - } - } - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); - -private: - TiXmlBase( const TiXmlBase& ); // not implemented. - void operator=( const TiXmlBase& base ); // not allowed. - - struct Entity - { - const char* str; - unsigned int strLength; - char chr; - }; - enum - { - NUM_ENTITY = 5, - MAX_ENTITY_LENGTH = 6 - - }; - static Entity entity[ NUM_ENTITY ]; - static bool condenseWhiteSpace; -}; - - -/** The parent class for everything in the Document Object Model. - (Except for attributes). - Nodes have siblings, a parent, and children. A node can be - in a document, or stand on its own. The type of a TiXmlNode - can be queried, and it can be cast to its more defined type. -*/ -class TiXmlNode : public TiXmlBase -{ - friend class TiXmlDocument; - friend class TiXmlElement; - -public: - #ifdef TIXML_USE_STL - - /** An input stream operator, for every class. Tolerant of newlines and - formatting, but doesn't expect them. - */ - friend std::istream& operator >> (std::istream& in, TiXmlNode& base); - - /** An output stream operator, for every class. Note that this outputs - without any newlines or formatting, as opposed to Print(), which - includes tabs and new lines. - - The operator<< and operator>> are not completely symmetric. Writing - a node to a stream is very well defined. You'll get a nice stream - of output, without any extra whitespace or newlines. - - But reading is not as well defined. (As it always is.) If you create - a TiXmlElement (for example) and read that from an input stream, - the text needs to define an element or junk will result. This is - true of all input streams, but it's worth keeping in mind. - - A TiXmlDocument will read nodes until it reads a root element, and - all the children of that root element. - */ - friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); - - /// Appends the XML node or attribute to a std::string. - friend std::string& operator<< (std::string& out, const TiXmlNode& base ); - - #endif - - /** The types of XML nodes supported by TinyXml. (All the - unsupported types are picked up by UNKNOWN.) - */ - enum NodeType - { - TINYXML_DOCUMENT, - TINYXML_ELEMENT, - TINYXML_COMMENT, - TINYXML_UNKNOWN, - TINYXML_TEXT, - TINYXML_DECLARATION, - TINYXML_TYPECOUNT - }; - - virtual ~TiXmlNode(); - - /** The meaning of 'value' changes for the specific type of - TiXmlNode. - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - - The subclasses will wrap this function. - */ - const char *Value() const { return value.c_str (); } - - #ifdef TIXML_USE_STL - /** Return Value() as a std::string. If you only use STL, - this is more efficient than calling Value(). - Only available in STL mode. - */ - const std::string& ValueStr() const { return value; } - #endif - - const TIXML_STRING& ValueTStr() const { return value; } - - /** Changes the value of the node. Defined as: - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - void SetValue(const char * _value) { value = _value;} - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Delete all the children of this node. Does not affect 'this'. - void Clear(); - - /// One step up the DOM. - TiXmlNode* Parent() { return parent; } - const TiXmlNode* Parent() const { return parent; } - - const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. - TiXmlNode* FirstChild() { return firstChild; } - const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. - /// The first child of this node with the matching 'value'. Will be null if none found. - TiXmlNode* FirstChild( const char * _value ) { - // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) - // call the method, cast the return back to non-const. - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); - } - const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. - TiXmlNode* LastChild() { return lastChild; } - - const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. - TiXmlNode* LastChild( const char * _value ) { - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. - #endif - - /** An alternate way to walk the children of a node. - One way to iterate over nodes is: - @verbatim - for( child = parent->FirstChild(); child; child = child->NextSibling() ) - @endverbatim - - IterateChildren does the same thing with the syntax: - @verbatim - child = 0; - while( child = parent->IterateChildren( child ) ) - @endverbatim - - IterateChildren takes the previous child as input and finds - the next one. If the previous child is null, it returns the - first. IterateChildren will return null when done. - */ - const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); - } - - /// This flavor of IterateChildren searches for children with a particular 'value' - const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - #endif - - /** Add a new node related to this. Adds a child past the LastChild. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); - - - /** Add a new node related to this. Adds a child past the LastChild. - - NOTE: the node to be added is passed by pointer, and will be - henceforth owned (and deleted) by tinyXml. This method is efficient - and avoids an extra copy, but should be used with care as it - uses a different memory model than the other insert functions. - - @sa InsertEndChild - */ - TiXmlNode* LinkEndChild( TiXmlNode* addThis ); - - /** Add a new node related to this. Adds a child before the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); - - /** Add a new node related to this. Adds a child after the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); - - /** Replace a child of this node. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); - - /// Delete a child of this node. - bool RemoveChild( TiXmlNode* removeThis ); - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling() const { return prev; } - TiXmlNode* PreviousSibling() { return prev; } - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling( const char * ) const; - TiXmlNode* PreviousSibling( const char *_prev ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Navigate to a sibling node. - const TiXmlNode* NextSibling() const { return next; } - TiXmlNode* NextSibling() { return next; } - - /// Navigate to a sibling node with the given 'value'. - const TiXmlNode* NextSibling( const char * ) const; - TiXmlNode* NextSibling( const char* _next ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement() const; - TiXmlElement* NextSiblingElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement( const char * ) const; - TiXmlElement* NextSiblingElement( const char *_next ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement() const; - TiXmlElement* FirstChildElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); - } - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement( const char * _value ) const; - TiXmlElement* FirstChildElement( const char * _value ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /** Query the type (as an enumerated value, above) of this node. - The possible types are: DOCUMENT, ELEMENT, COMMENT, - UNKNOWN, TEXT, and DECLARATION. - */ - int Type() const { return type; } - - /** Return a pointer to the Document this node lives in. - Returns null if not in a document. - */ - const TiXmlDocument* GetDocument() const; - TiXmlDocument* GetDocument() { - return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); - } - - /// Returns true if this node has no children. - bool NoChildren() const { return !firstChild; } - - virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - /** Create an exact duplicate of this node and return it. The memory must be deleted - by the caller. - */ - virtual TiXmlNode* Clone() const = 0; - - /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the TiXmlVisitor interface. - - This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - TiXmlPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( TiXmlVisitor* visitor ) const = 0; - -protected: - TiXmlNode( NodeType _type ); - - // Copy to the allocated object. Shared functionality between Clone, Copy constructor, - // and the assignment operator. - void CopyTo( TiXmlNode* target ) const; - - #ifdef TIXML_USE_STL - // The real work of the input operator. - virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; - #endif - - // Figure out what is at *p, and parse it. Returns null if it is not an xml node. - TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); - - TiXmlNode* parent; - NodeType type; - - TiXmlNode* firstChild; - TiXmlNode* lastChild; - - TIXML_STRING value; - - TiXmlNode* prev; - TiXmlNode* next; - -private: - TiXmlNode( const TiXmlNode& ); // not implemented. - void operator=( const TiXmlNode& base ); // not allowed. -}; - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not TiXmlNodes, since they are not - part of the tinyXML document object model. There are other - suggested ways to look at this problem. -*/ -class TiXmlAttribute : public TiXmlBase -{ - friend class TiXmlAttributeSet; - -public: - /// Construct an empty attribute. - TiXmlAttribute() : TiXmlBase() - { - document = 0; - prev = next = 0; - } - - #ifdef TIXML_USE_STL - /// std::string constructor. - TiXmlAttribute( const std::string& _name, const std::string& _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - #endif - - /// Construct an attribute with a name and value. - TiXmlAttribute( const char * _name, const char * _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - - const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. - const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. - #ifdef TIXML_USE_STL - const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. - #endif - int IntValue() const; ///< Return the value of this attribute, converted to an integer. - double DoubleValue() const; ///< Return the value of this attribute, converted to a double. - - // Get the tinyxml string representation - const TIXML_STRING& NameTStr() const { return name; } - - /** QueryIntValue examines the value string. It is an alternative to the - IntValue() method with richer error checking. - If the value is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. - - A specialized but useful call. Note that for success it returns 0, - which is the opposite of almost all other TinyXml calls. - */ - int QueryIntValue( int* _value ) const; - /// QueryDoubleValue examines the value string. See QueryIntValue(). - int QueryDoubleValue( double* _value ) const; - - void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. - void SetValue( const char* _value ) { value = _value; } ///< Set the value. - - void SetIntValue( int _value ); ///< Set the value from an integer. - void SetDoubleValue( double _value ); ///< Set the value from a double. - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetName( const std::string& _name ) { name = _name; } - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Get the next sibling attribute in the DOM. Returns null at end. - const TiXmlAttribute* Next() const; - TiXmlAttribute* Next() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); - } - - /// Get the previous sibling attribute in the DOM. Returns null at beginning. - const TiXmlAttribute* Previous() const; - TiXmlAttribute* Previous() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); - } - - bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } - bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } - bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } - - /* Attribute parsing starts: first letter of the name - returns: the next char after the value end quote - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - // Prints this Attribute to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - - // [internal use] - // Set the document pointer so the attribute can report errors. - void SetDocument( TiXmlDocument* doc ) { document = doc; } - -private: - TiXmlAttribute( const TiXmlAttribute& ); // not implemented. - void operator=( const TiXmlAttribute& base ); // not allowed. - - TiXmlDocument* document; // A pointer back to a document, for error reporting. - TIXML_STRING name; - TIXML_STRING value; - TiXmlAttribute* prev; - TiXmlAttribute* next; -}; - - -/* A class used to manage a group of attributes. - It is only used internally, both by the ELEMENT and the DECLARATION. - - The set can be changed transparent to the Element and Declaration - classes that use it, but NOT transparent to the Attribute - which has to implement a next() and previous() method. Which makes - it a bit problematic and prevents the use of STL. - - This version is implemented with circular lists because: - - I like circular lists - - it demonstrates some independence from the (typical) doubly linked list. -*/ -class TiXmlAttributeSet -{ -public: - TiXmlAttributeSet(); - ~TiXmlAttributeSet(); - - void Add( TiXmlAttribute* attribute ); - void Remove( TiXmlAttribute* attribute ); - - const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - - TiXmlAttribute* Find( const char* _name ) const; - TiXmlAttribute* FindOrCreate( const char* _name ); - -# ifdef TIXML_USE_STL - TiXmlAttribute* Find( const std::string& _name ) const; - TiXmlAttribute* FindOrCreate( const std::string& _name ); -# endif - - -private: - //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), - //*ME: this class must be also use a hidden/disabled copy-constructor !!! - TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed - void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) - - TiXmlAttribute sentinel; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class TiXmlElement : public TiXmlNode -{ -public: - /// Construct an element. - TiXmlElement (const char * in_value); - - #ifdef TIXML_USE_STL - /// std::string constructor. - TiXmlElement( const std::string& _value ); - #endif - - TiXmlElement( const TiXmlElement& ); - - void operator=( const TiXmlElement& base ); - - virtual ~TiXmlElement(); - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - */ - const char* Attribute( const char* name ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an integer, - the integer value will be put in the return 'i', if 'i' - is non-null. - */ - const char* Attribute( const char* name, int* i ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an double, - the double value will be put in the return 'd', if 'd' - is non-null. - */ - const char* Attribute( const char* name, double* d ) const; - - /** QueryIntAttribute examines the attribute - it is an alternative to the - Attribute() method with richer error checking. - If the attribute is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. If the attribute - does not exist, then TIXML_NO_ATTRIBUTE is returned. - */ - int QueryIntAttribute( const char* name, int* _value ) const; - /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). - int QueryDoubleAttribute( const char* name, double* _value ) const; - /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). - int QueryFloatAttribute( const char* name, float* _value ) const { - double d; - int result = QueryDoubleAttribute( name, &d ); - if ( result == TIXML_SUCCESS ) { - *_value = (float)d; - } - return result; - } - - #ifdef TIXML_USE_STL - /// QueryStringAttribute examines the attribute - see QueryIntAttribute(). - int QueryStringAttribute( const char* name, std::string* _value ) const { - const char* cstr = Attribute( name ); - if ( cstr ) { - *_value = std::string( cstr ); - return TIXML_SUCCESS; - } - return TIXML_NO_ATTRIBUTE; - } - - /** Template form of the attribute query which will try to read the - attribute into the specified type. Very easy, very powerful, but - be careful to make sure to call this with the correct type. - - NOTE: This method doesn't work correctly for 'string' types that contain spaces. - - @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE - */ - template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - - std::stringstream sstream( node->ValueStr() ); - sstream >> *outValue; - if ( !sstream.fail() ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; - } - - int QueryValueAttribute( const std::string& name, std::string* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - *outValue = node->ValueStr(); - return TIXML_SUCCESS; - } - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char* name, const char * _value ); - - #ifdef TIXML_USE_STL - const std::string* Attribute( const std::string& name ) const; - const std::string* Attribute( const std::string& name, int* i ) const; - const std::string* Attribute( const std::string& name, double* d ) const; - int QueryIntAttribute( const std::string& name, int* _value ) const; - int QueryDoubleAttribute( const std::string& name, double* _value ) const; - - /// STL std::string form. - void SetAttribute( const std::string& name, const std::string& _value ); - ///< STL std::string form. - void SetAttribute( const std::string& name, int _value ); - ///< STL std::string form. - void SetDoubleAttribute( const std::string& name, double value ); - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char * name, int value ); - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetDoubleAttribute( const char * name, double value ); - - /** Deletes an attribute with the given name. - */ - void RemoveAttribute( const char * name ); - #ifdef TIXML_USE_STL - void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. - #endif - - const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. - TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } - const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. - TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the TiXmlText child - and accessing it directly. - - If the first child of 'this' is a TiXmlText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - This is text - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - This is text - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - This is text - @endverbatim - GetText() will return "This is ". - - WARNING: GetText() accesses a child node - don't become confused with the - similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are - safe type casts on the referenced node. - */ - const char* GetText() const; - - /// Creates a new Element and returns it - the returned element is a copy. - virtual TiXmlNode* Clone() const; - // Print the Element to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: next char past '<' - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - - void CopyTo( TiXmlElement* target ) const; - void ClearThis(); // like clear, but initializes 'this' object as well - - // Used to be public [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - /* [internal use] - Reads the "value" of the element -- another element, or text. - This should terminate with the current end tag. - */ - const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - -private: - TiXmlAttributeSet attributeSet; -}; - - -/** An XML comment. -*/ -class TiXmlComment : public TiXmlNode -{ -public: - /// Constructs an empty comment. - TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {} - /// Construct a comment from text. - TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) { - SetValue( _value ); - } - TiXmlComment( const TiXmlComment& ); - void operator=( const TiXmlComment& base ); - - virtual ~TiXmlComment() {} - - /// Returns a copy of this Comment. - virtual TiXmlNode* Clone() const; - // Write this Comment to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: at the ! of the !-- - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlComment* target ) const; - - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif -// virtual void StreamOut( TIXML_OSTREAM * out ) const; - -private: - -}; - - -/** XML text. A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCDATA() and query it with CDATA(). -*/ -class TiXmlText : public TiXmlNode -{ - friend class TiXmlElement; -public: - /** Constructor for text element. By default, it is treated as - normal, encoded text. If you want it be output as a CDATA text - element, set the parameter _cdata to 'true' - */ - TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) - { - SetValue( initValue ); - cdata = false; - } - virtual ~TiXmlText() {} - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) - { - SetValue( initValue ); - cdata = false; - } - #endif - - TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); } - void operator=( const TiXmlText& base ) { base.CopyTo( this ); } - - // Write this text object to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /// Queries whether this represents text using a CDATA section. - bool CDATA() const { return cdata; } - /// Turns on or off a CDATA representation of text. - void SetCDATA( bool _cdata ) { cdata = _cdata; } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - /// [internal use] Creates a new Element and returns it. - virtual TiXmlNode* Clone() const; - void CopyTo( TiXmlText* target ) const; - - bool Blank() const; // returns true if all white space and new lines - // [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - bool cdata; // true if this should be input and output as a CDATA style text element -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - - @endverbatim - - TinyXml will happily read or write files without a declaration, - however. There are 3 possible attributes to the declaration: - version, encoding, and standalone. - - Note: In this version of the code, the attributes are - handled as special cases, not generic attributes, simply - because there can only be at most 3 and they are always the same. -*/ -class TiXmlDeclaration : public TiXmlNode -{ -public: - /// Construct an empty declaration. - TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {} - -#ifdef TIXML_USE_STL - /// Constructor. - TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ); -#endif - - /// Construct. - TiXmlDeclaration( const char* _version, - const char* _encoding, - const char* _standalone ); - - TiXmlDeclaration( const TiXmlDeclaration& copy ); - void operator=( const TiXmlDeclaration& copy ); - - virtual ~TiXmlDeclaration() {} - - /// Version. Will return an empty string if none was found. - const char *Version() const { return version.c_str (); } - /// Encoding. Will return an empty string if none was found. - const char *Encoding() const { return encoding.c_str (); } - /// Is this a standalone document? - const char *Standalone() const { return standalone.c_str (); } - - /// Creates a copy of this Declaration and returns it. - virtual TiXmlNode* Clone() const; - // Print this declaration to a FILE stream. - virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlDeclaration* target ) const; - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - - TIXML_STRING version; - TIXML_STRING encoding; - TIXML_STRING standalone; -}; - - -/** Any tag that tinyXml doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into TiXmlUnknowns. -*/ -class TiXmlUnknown : public TiXmlNode -{ -public: - TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {} - virtual ~TiXmlUnknown() {} - - TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); } - void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } - - /// Creates a copy of this Unknown and returns it. - virtual TiXmlNode* Clone() const; - // Print this Unknown to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected: - void CopyTo( TiXmlUnknown* target ) const; - - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - -}; - - -/** Always the top level node. A document binds together all the - XML pieces. It can be saved, loaded, and printed to the screen. - The 'value' of a document node is the xml file name. -*/ -class TiXmlDocument : public TiXmlNode -{ -public: - /// Create an empty document, that has no name. - TiXmlDocument(); - /// Create a document with a name. The name of the document is also the filename of the xml. - TiXmlDocument( const char * documentName ); - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlDocument( const std::string& documentName ); - #endif - - TiXmlDocument( const TiXmlDocument& copy ); - void operator=( const TiXmlDocument& copy ); - - virtual ~TiXmlDocument() {} - - /** Load a file using the current document value. - Returns true if successful. Will delete any existing - document data before loading. - */ - bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the current document value. Returns true if successful. - bool SaveFile() const; - /// Load a file using the given filename. Returns true if successful. - bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given filename. Returns true if successful. - bool SaveFile( const char * filename ) const; - /** Load a file using the given FILE*. Returns true if successful. Note that this method - doesn't stream - the entire object pointed at by the FILE* - will be interpreted as an XML file. TinyXML doesn't stream in XML from the current - file location. Streaming may be added in the future. - */ - bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given FILE*. Returns true if successful. - bool SaveFile( FILE* ) const; - - #ifdef TIXML_USE_STL - bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. - { - return LoadFile( filename.c_str(), encoding ); - } - bool SaveFile( const std::string& filename ) const ///< STL std::string version. - { - return SaveFile( filename.c_str() ); - } - #endif - - /** Parse the given null terminated block of xml data. Passing in an encoding to this - method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml - to use that encoding, regardless of what TinyXml might otherwise try to detect. - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - - /** Get the root element -- the only top level element -- of the document. - In well formed XML, there should only be one. TinyXml is tolerant of - multiple elements at the document level. - */ - const TiXmlElement* RootElement() const { return FirstChildElement(); } - TiXmlElement* RootElement() { return FirstChildElement(); } - - /** If an error occurs, Error will be set to true. Also, - - The ErrorId() will contain the integer identifier of the error (not generally useful) - - The ErrorDesc() method will return the name of the error. (very useful) - - The ErrorRow() and ErrorCol() will return the location of the error (if known) - */ - bool Error() const { return error; } - - /// Contains a textual (english) description of the error if one occurs. - const char * ErrorDesc() const { return errorDesc.c_str (); } - - /** Generally, you probably want the error string ( ErrorDesc() ). But if you - prefer the ErrorId, this function will fetch it. - */ - int ErrorId() const { return errorId; } - - /** Returns the location (if known) of the error. The first column is column 1, - and the first row is row 1. A value of 0 means the row and column wasn't applicable - (memory errors, for example, have no row/column) or the parser lost the error. (An - error in the error reporting, in that case.) - - @sa SetTabSize, Row, Column - */ - int ErrorRow() const { return errorLocation.row+1; } - int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() - - /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) - to report the correct values for row and column. It does not change the output - or input in any way. - - By calling this method, with a tab size - greater than 0, the row and column of each node and attribute is stored - when the file is loaded. Very useful for tracking the DOM back in to - the source file. - - The tab size is required for calculating the location of nodes. If not - set, the default of 4 is used. The tabsize is set per document. Setting - the tabsize to 0 disables row/column tracking. - - Note that row and column tracking is not supported when using operator>>. - - The tab size needs to be enabled before the parse or load. Correct usage: - @verbatim - TiXmlDocument doc; - doc.SetTabSize( 8 ); - doc.Load( "myfile.xml" ); - @endverbatim - - @sa Row, Column - */ - void SetTabSize( int _tabsize ) { tabsize = _tabsize; } - - int TabSize() const { return tabsize; } - - /** If you have handled the error, it can be reset with this call. The error - state is automatically cleared if you Parse a new XML block. - */ - void ClearError() { error = false; - errorId = 0; - errorDesc = ""; - errorLocation.row = errorLocation.col = 0; - //errorLocation.last = 0; - } - - /** Write the document to standard out using formatted printing ("pretty print"). */ - void Print() const { Print( stdout, 0 ); } - - /* Write the document to a string using formatted printing ("pretty print"). This - will allocate a character array (new char[]) and return it as a pointer. The - calling code pust call delete[] on the return char* to avoid a memory leak. - */ - //char* PrintToMemory() const; - - /// Print this Document to a FILE stream. - virtual void Print( FILE* cfile, int depth = 0 ) const; - // [internal use] - void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - - virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - // [internal use] - virtual TiXmlNode* Clone() const; - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - void CopyTo( TiXmlDocument* target ) const; - - bool error; - int errorId; - TIXML_STRING errorDesc; - int tabsize; - TiXmlCursor errorLocation; - bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. -}; - - -/** - A TiXmlHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - - - - - - - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - TiXmlElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - TiXmlElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - TiXmlElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - TiXmlElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity - of such code. A TiXmlHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - TiXmlHandle docHandle( &document ); - TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - TiXmlHandle handleCopy = handle; - @endverbatim - - What they should not be used for is iteration: - - @verbatim - int i=0; - while ( true ) - { - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); - if ( !child ) - break; - // do something - ++i; - } - @endverbatim - - It seems reasonable, but it is in fact two embedded while loops. The Child method is - a linear walk to find the element, so this code would iterate much more than it needs - to. Instead, prefer: - - @verbatim - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); - - for( child; child; child=child->NextSiblingElement() ) - { - // do something - } - @endverbatim -*/ -class TiXmlHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } - /// Copy constructor - TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } - TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } - - /// Return a handle to the first child node. - TiXmlHandle FirstChild() const; - /// Return a handle to the first child node with the given name. - TiXmlHandle FirstChild( const char * value ) const; - /// Return a handle to the first child element. - TiXmlHandle FirstChildElement() const; - /// Return a handle to the first child element with the given name. - TiXmlHandle FirstChildElement( const char * value ) const; - - /** Return a handle to the "index" child with the given name. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( const char* value, int index ) const; - /** Return a handle to the "index" child. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( int index ) const; - /** Return a handle to the "index" child element with the given name. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( const char* value, int index ) const; - /** Return a handle to the "index" child element. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( int index ) const; - - #ifdef TIXML_USE_STL - TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } - TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } - - TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } - TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } - #endif - - /** Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* ToNode() const { return node; } - /** Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } - /** Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } - /** Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } - - /** @deprecated use ToNode. - Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* Node() const { return ToNode(); } - /** @deprecated use ToElement. - Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* Element() const { return ToElement(); } - /** @deprecated use ToText() - Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* Text() const { return ToText(); } - /** @deprecated use ToUnknown() - Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* Unknown() const { return ToUnknown(); } - -private: - TiXmlNode* node; -}; - - -/** Print to memory functionality. The TiXmlPrinter is useful when you need to: - - -# Print to memory (especially in non-STL mode) - -# Control formatting (line endings, etc.) - - When constructed, the TiXmlPrinter is in its default "pretty printing" mode. - Before calling Accept() you can call methods to control the printing - of the XML document. After TiXmlNode::Accept() is called, the printed document can - be accessed via the CStr(), Str(), and Size() methods. - - TiXmlPrinter uses the Visitor API. - @verbatim - TiXmlPrinter printer; - printer.SetIndent( "\t" ); - - doc.Accept( &printer ); - fprintf( stdout, "%s", printer.CStr() ); - @endverbatim -*/ -class TiXmlPrinter : public TiXmlVisitor -{ -public: - TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), - buffer(), indent( " " ), lineBreak( "\n" ) {} - - virtual bool VisitEnter( const TiXmlDocument& doc ); - virtual bool VisitExit( const TiXmlDocument& doc ); - - virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); - virtual bool VisitExit( const TiXmlElement& element ); - - virtual bool Visit( const TiXmlDeclaration& declaration ); - virtual bool Visit( const TiXmlText& text ); - virtual bool Visit( const TiXmlComment& comment ); - virtual bool Visit( const TiXmlUnknown& unknown ); - - /** Set the indent characters for printing. By default 4 spaces - but tab (\t) is also useful, or null/empty string for no indentation. - */ - void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } - /// Query the indention string. - const char* Indent() { return indent.c_str(); } - /** Set the line breaking string. By default set to newline (\n). - Some operating systems prefer other characters, or can be - set to the null/empty string for no indenation. - */ - void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } - /// Query the current line breaking string. - const char* LineBreak() { return lineBreak.c_str(); } - - /** Switch over to "stream printing" which is the most dense formatting without - linebreaks. Common when the XML is needed for network transmission. - */ - void SetStreamPrinting() { indent = ""; - lineBreak = ""; - } - /// Return the result. - const char* CStr() { return buffer.c_str(); } - /// Return the length of the result string. - size_t Size() { return buffer.size(); } - - #ifdef TIXML_USE_STL - /// Return the result. - const std::string& Str() { return buffer; } - #endif - -private: - void DoIndent() { - for( int i=0; i -#include - -#include "tinyxml.h" - -//#define DEBUG_PARSER -#if defined( DEBUG_PARSER ) -# if defined( DEBUG ) && defined( _MSC_VER ) -# include -# define TIXML_LOG OutputDebugString -# else -# define TIXML_LOG printf -# endif -#endif - -// Note tha "PutString" hardcodes the same list. This -// is less flexible than it appears. Changing the entries -// or order will break putstring. -TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = -{ - { "&", 5, '&' }, - { "<", 4, '<' }, - { ">", 4, '>' }, - { """, 6, '\"' }, - { "'", 6, '\'' } -}; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// Including the basic of this table, which determines the #bytes in the -// sequence from the lead byte. 1 placed for invalid sequences -- -// although the result will be junk, pass it through as much as possible. -// Beware of the non-characters in UTF-8: -// ef bb bf (Microsoft "lead bytes") -// ef bf be -// ef bf bf - -const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - -const int TiXmlBase::utf8ByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte - 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -}; - - -void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) - *length = 1; - else if ( input < 0x800 ) - *length = 2; - else if ( input < 0x10000 ) - *length = 3; - else if ( input < 0x200000 ) - *length = 4; - else - { *length = 0; return; } // This code won't covert this correctly anyway. - - output += *length; - - // Scary scary fall throughs. - switch (*length) - { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - } -} - - -/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalpha( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalpha( anyByte ); -// } -} - - -/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalnum( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalnum( anyByte ); -// } -} - - -class TiXmlParsingData -{ - friend class TiXmlDocument; - public: - void Stamp( const char* now, TiXmlEncoding encoding ); - - const TiXmlCursor& Cursor() { return cursor; } - - private: - // Only used by the document! - TiXmlParsingData( const char* start, int _tabsize, int row, int col ) - { - assert( start ); - stamp = start; - tabsize = _tabsize; - cursor.row = row; - cursor.col = col; - } - - TiXmlCursor cursor; - const char* stamp; - int tabsize; -}; - - -void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) -{ - assert( now ); - - // Do nothing if the tabsize is 0. - if ( tabsize < 1 ) - { - return; - } - - // Get the current row, column. - int row = cursor.row; - int col = cursor.col; - const char* p = stamp; - assert( p ); - - while ( p < now ) - { - // Treat p as unsigned, so we have a happy compiler. - const unsigned char* pU = (const unsigned char*)p; - - // Code contributed by Fletcher Dunn: (modified by lee) - switch (*pU) { - case 0: - // We *should* never get here, but in case we do, don't - // advance past the terminating null character, ever - return; - - case '\r': - // bump down to the next line - ++row; - col = 0; - // Eat the character - ++p; - - // Check for \r\n sequence, and treat this as a single character - if (*p == '\n') { - ++p; - } - break; - - case '\n': - // bump down to the next line - ++row; - col = 0; - - // Eat the character - ++p; - - // Check for \n\r sequence, and treat this as a single - // character. (Yes, this bizarre thing does occur still - // on some arcane platforms...) - if (*p == '\r') { - ++p; - } - break; - - case '\t': - // Eat the character - ++p; - - // Skip to next tab stop - col = (col / tabsize + 1) * tabsize; - break; - - case TIXML_UTF_LEAD_0: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( *(p+1) && *(p+2) ) - { - // In these cases, don't advance the column. These are - // 0-width spaces. - if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) - p += 3; - else - { p +=3; ++col; } // A normal character. - } - } - else - { - ++p; - ++col; - } - break; - - default: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // Eat the 1 to 4 byte utf8 character. - int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; - if ( step == 0 ) - step = 1; // Error case from bad encoding, but handle gracefully. - p += step; - - // Just advance one column, of course. - ++col; - } - else - { - ++p; - ++col; - } - break; - } - } - cursor.row = row; - cursor.col = col; - assert( cursor.row >= -1 ); - assert( cursor.col >= -1 ); - stamp = p; - assert( stamp ); -} - - -const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) -{ - if ( !p || !*p ) - { - return 0; - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - while ( *p ) - { - const unsigned char* pU = (const unsigned char*)p; - - // Skip the stupid Microsoft UTF-8 Byte order marks - if ( *(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==TIXML_UTF_LEAD_1 - && *(pU+2)==TIXML_UTF_LEAD_2 ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbeU ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbfU ) - { - p += 3; - continue; - } - - if ( IsWhiteSpace( *p ) ) // Still using old rules for white space. - ++p; - else - break; - } - } - else - { - while ( *p && IsWhiteSpace( *p ) ) - ++p; - } - - return p; -} - -#ifdef TIXML_USE_STL -/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) -{ - for( ;; ) - { - if ( !in->good() ) return false; - - int c = in->peek(); - // At this scope, we can't get to a document. So fail silently. - if ( !IsWhiteSpace( c ) || c <= 0 ) - return true; - - *tag += (char) in->get(); - } -} - -/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) -{ - //assert( character > 0 && character < 128 ); // else it won't work in utf-8 - while ( in->good() ) - { - int c = in->peek(); - if ( c == character ) - return true; - if ( c <= 0 ) // Silent failure: can't get document at this scope - return false; - - in->get(); - *tag += (char) c; - } - return false; -} -#endif - -// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The -// "assign" optimization removes over 10% of the execution time. -// -const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) -{ - // Oddly, not supported on some comilers, - //name->clear(); - // So use this: - *name = ""; - assert( p ); - - // Names start with letters or underscores. - // Of course, in unicode, tinyxml has no idea what a letter *is*. The - // algorithm is generous. - // - // After that, they can be letters, underscores, numbers, - // hyphens, or colons. (Colons are valid ony for namespaces, - // but tinyxml can't tell namespaces from names.) - if ( p && *p - && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) - { - const char* start = p; - while( p && *p - && ( IsAlphaNum( (unsigned char ) *p, encoding ) - || *p == '_' - || *p == '-' - || *p == '.' - || *p == ':' ) ) - { - //(*name) += *p; // expensive - ++p; - } - if ( p-start > 0 ) { - name->assign( start, p-start ); - } - return p; - } - return 0; -} - -const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) -{ - // Presume an entity, and pull it out. - TIXML_STRING ent; - int i; - *length = 0; - - if ( *(p+1) && *(p+1) == '#' && *(p+2) ) - { - unsigned long ucs = 0; - ptrdiff_t delta = 0; - unsigned mult = 1; - - if ( *(p+2) == 'x' ) - { - // Hexadecimal. - if ( !*(p+3) ) return 0; - - const char* q = p+3; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != 'x' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else if ( *q >= 'a' && *q <= 'f' ) - ucs += mult * (*q - 'a' + 10); - else if ( *q >= 'A' && *q <= 'F' ) - ucs += mult * (*q - 'A' + 10 ); - else - return 0; - mult *= 16; - --q; - } - } - else - { - // Decimal. - if ( !*(p+2) ) return 0; - - const char* q = p+2; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != '#' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else - return 0; - mult *= 10; - --q; - } - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - } - else - { - *value = (char)ucs; - *length = 1; - } - return p + delta + 1; - } - - // Now try to match it. - for( i=0; iappend( cArr, len ); - } - } - else - { - bool whitespace = false; - - // Remove leading white space: - p = SkipWhiteSpace( p, encoding ); - while ( p && *p - && !StringEqual( p, endTag, caseInsensitive, encoding ) ) - { - if ( *p == '\r' || *p == '\n' ) - { - whitespace = true; - ++p; - } - else if ( IsWhiteSpace( *p ) ) - { - whitespace = true; - ++p; - } - else - { - // If we've found whitespace, add it before the - // new character. Any whitespace just becomes a space. - if ( whitespace ) - { - (*text) += ' '; - whitespace = false; - } - int len; - char cArr[4] = { 0, 0, 0, 0 }; - p = GetChar( p, cArr, &len, encoding ); - if ( len == 1 ) - (*text) += cArr[0]; // more efficient - else - text->append( cArr, len ); - } - } - } - if ( p && *p ) - p += strlen( endTag ); - return p; -} - -#ifdef TIXML_USE_STL - -void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - // The basic issue with a document is that we don't know what we're - // streaming. Read something presumed to be a tag (and hope), then - // identify it, and call the appropriate stream method on the tag. - // - // This "pre-streaming" will never read the closing ">" so the - // sub-tag can orient itself. - - if ( !StreamTo( in, '<', tag ) ) - { - SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - while ( in->good() ) - { - int tagIndex = (int) tag->length(); - while ( in->good() && in->peek() != '>' ) - { - int c = in->get(); - if ( c <= 0 ) - { - SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - break; - } - (*tag) += (char) c; - } - - if ( in->good() ) - { - // We now have something we presume to be a node of - // some sort. Identify it, and call the node to - // continue streaming. - TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); - - if ( node ) - { - node->StreamIn( in, tag ); - bool isElement = node->ToElement() != 0; - delete node; - node = 0; - - // If this is the root element, we're done. Parsing will be - // done by the >> operator. - if ( isElement ) - { - return; - } - } - else - { - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - } - } - // We should have returned sooner. - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -} - -#endif - -const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) -{ - ClearError(); - - // Parse away, at the document level. Since a document - // contains nothing but other tags, most of what happens - // here is skipping white space. - if ( !p || !*p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - // Note that, for a document, this needs to come - // before the while space skip, so that parsing - // starts from the pointer we are given. - location.Clear(); - if ( prevData ) - { - location.row = prevData->cursor.row; - location.col = prevData->cursor.col; - } - else - { - location.row = 0; - location.col = 0; - } - TiXmlParsingData data( p, TabSize(), location.row, location.col ); - location = data.Cursor(); - - if ( encoding == TIXML_ENCODING_UNKNOWN ) - { - // Check for the Microsoft UTF-8 lead bytes. - const unsigned char* pU = (const unsigned char*)p; - if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 - && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 - && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) - { - encoding = TIXML_ENCODING_UTF8; - useMicrosoftBOM = true; - } - } - - p = SkipWhiteSpace( p, encoding ); - if ( !p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - while ( p && *p ) - { - TiXmlNode* node = Identify( p, encoding ); - if ( node ) - { - p = node->Parse( p, &data, encoding ); - LinkEndChild( node ); - } - else - { - break; - } - - // Did we get encoding info? - if ( encoding == TIXML_ENCODING_UNKNOWN - && node->ToDeclaration() ) - { - TiXmlDeclaration* dec = node->ToDeclaration(); - const char* enc = dec->Encoding(); - assert( enc ); - - if ( *enc == 0 ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice - else - encoding = TIXML_ENCODING_LEGACY; - } - - p = SkipWhiteSpace( p, encoding ); - } - - // Was this empty? - if ( !firstChild ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); - return 0; - } - - // All is well. - return p; -} - -void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - // The first error in a chain is more accurate - don't set again! - if ( error ) - return; - - assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); - error = true; - errorId = err; - errorDesc = errorString[ errorId ]; - - errorLocation.Clear(); - if ( pError && data ) - { - data->Stamp( pError, encoding ); - errorLocation = data->Cursor(); - } -} - - -TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) -{ - TiXmlNode* returnNode = 0; - - p = SkipWhiteSpace( p, encoding ); - if( !p || !*p || *p != '<' ) - { - return 0; - } - - p = SkipWhiteSpace( p, encoding ); - - if ( !p || !*p ) - { - return 0; - } - - // What is this thing? - // - Elements start with a letter or underscore, but xml is reserved. - // - Comments: "; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // [ 1475201 ] TinyXML parses entities in comments - // Oops - ReadText doesn't work, because we don't want to parse the entities. - // p = ReadText( p, &value, false, endTag, false, encoding ); - // - // from the XML spec: - /* - [Definition: Comments may appear anywhere in a document outside other markup; in addition, - they may appear within the document type declaration at places allowed by the grammar. - They are not part of the document's character data; an XML processor MAY, but need not, - make it possible for an application to retrieve the text of comments. For compatibility, - the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity - references MUST NOT be recognized within comments. - - An example of a comment: - - - */ - - value = ""; - // Keep all the white space. - while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) - { - value.append( p, 1 ); - ++p; - } - if ( p && *p ) - p += strlen( endTag ); - - return p; -} - - -const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) return 0; - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - // Read the name, the '=' and the value. - const char* pErr = p; - p = ReadName( p, &name, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); - return 0; - } - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p || *p != '=' ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - ++p; // skip '=' - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - const char* end; - const char SINGLE_QUOTE = '\''; - const char DOUBLE_QUOTE = '\"'; - - if ( *p == SINGLE_QUOTE ) - { - ++p; - end = "\'"; // single quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else if ( *p == DOUBLE_QUOTE ) - { - ++p; - end = "\""; // double quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else - { - // All attribute values should be in single or double quotes. - // But this is such a common error that the parser will try - // its best, even without them. - value = ""; - while ( p && *p // existence - && !IsWhiteSpace( *p ) // whitespace - && *p != '/' && *p != '>' ) // tag end - { - if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { - // [ 1451649 ] Attribute values with trailing quotes not handled correctly - // We did not have an opening quote but seem to have a - // closing one. Give up and throw an error. - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - value += *p; - ++p; - } - } - return p; -} - -#ifdef TIXML_USE_STL -void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->peek(); - if ( !cdata && (c == '<' ) ) - { - return; - } - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - (*tag) += (char) c; - in->get(); // "commits" the peek made above - - if ( cdata && c == '>' && tag->size() >= 3 ) { - size_t len = tag->size(); - if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { - // terminator of cdata. - return; - } - } - } -} -#endif - -const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - value = ""; - TiXmlDocument* document = GetDocument(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - - const char* const startTag = ""; - - if ( cdata || StringEqual( p, startTag, false, encoding ) ) - { - cdata = true; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // Keep all the white space, ignore the encoding, etc. - while ( p && *p - && !StringEqual( p, endTag, false, encoding ) - ) - { - value += *p; - ++p; - } - - TIXML_STRING dummy; - p = ReadText( p, &dummy, false, endTag, false, encoding ); - return p; - } - else - { - bool ignoreWhite = true; - - const char* end = "<"; - p = ReadText( p, &value, ignoreWhite, end, false, encoding ); - if ( p ) - return p-1; // don't truncate the '<' - return 0; - } -} - -#ifdef TIXML_USE_STL -void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - (*tag) += (char) c; - - if ( c == '>' ) - { - // All is well. - return; - } - } -} -#endif - -const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) -{ - p = SkipWhiteSpace( p, _encoding ); - // Find the beginning, find the end, and look for - // the stuff in-between. - TiXmlDocument* document = GetDocument(); - if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); - return 0; - } - if ( data ) - { - data->Stamp( p, _encoding ); - location = data->Cursor(); - } - p += 5; - - version = ""; - encoding = ""; - standalone = ""; - - while ( p && *p ) - { - if ( *p == '>' ) - { - ++p; - return p; - } - - p = SkipWhiteSpace( p, _encoding ); - if ( StringEqual( p, "version", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - version = attrib.Value(); - } - else if ( StringEqual( p, "encoding", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - encoding = attrib.Value(); - } - else if ( StringEqual( p, "standalone", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - standalone = attrib.Value(); - } - else - { - // Read over whatever it is. - while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) - ++p; - } - } - return 0; -} - -bool TiXmlText::Blank() const -{ - for ( unsigned i=0; i Date: Tue, 10 Feb 2015 15:47:10 -0800 Subject: [PATCH 253/338] Added irrXML to top level CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cff1cff3..4cc7f83c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,7 @@ ENDIF(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) # 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 . openmmapi olla libraries/jama libraries/quern libraries/lepton libraries/sfmt libraries/lbfgs libraries/hilbert libraries/csha1 platforms/reference serialization libraries/validate) +SET(OPENMM_SOURCE_SUBDIRS . openmmapi olla libraries/jama libraries/quern libraries/lepton libraries/sfmt libraries/lbfgs libraries/hilbert libraries/csha1 platforms/reference serialization libraries/validate libraries/irrxml) IF(WIN32) SET(OPENMM_SOURCE_SUBDIRS ${OPENMM_SOURCE_SUBDIRS} libraries/pthreads) ADD_CUSTOM_TARGET(PthreadsLibraries ALL) -- GitLab From 10be282af28b996dbfdb638585dc19862a4f4e38 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 11 Feb 2015 08:17:47 -0500 Subject: [PATCH 254/338] Beginnings of improvements for amber_file_parser and the CHARMM PSF file parser to support triclinic cells. Also extend unitcell.computePeriodicBoxVectors to take Quantity inputs rather than *just* scalars assumed to be nanometers. --- .../python/simtk/openmm/app/charmmpsffile.py | 58 +-------------- .../openmm/app/internal/amber_file_parser.py | 71 ++++--------------- .../simtk/openmm/app/internal/unitcell.py | 10 ++- 3 files changed, 26 insertions(+), 113 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/charmmpsffile.py b/wrappers/python/simtk/openmm/app/charmmpsffile.py index 23c12e7b4..fa45470ac 100644 --- a/wrappers/python/simtk/openmm/app/charmmpsffile.py +++ b/wrappers/python/simtk/openmm/app/charmmpsffile.py @@ -44,6 +44,7 @@ from simtk.openmm.app import (forcefield as ff, Topology, element) from simtk.openmm.app.amberprmtopfile import HCT, OBC1, OBC2, GBn, GBn2 from simtk.openmm.app.internal.customgbforces import (GBSAHCTForce, GBSAOBC1Force, GBSAOBC2Force, GBSAGBnForce, GBSAGBn2Force, convertParameters) +from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors # CHARMM imports from simtk.openmm.app.internal.charmm.topologyobjects import ( ResidueList, AtomList, TrackedList, Bond, Angle, Dihedral, @@ -744,7 +745,7 @@ class CharmmPsfFile(object): Parameters: - a, b, c (floats) : Lengths of the periodic cell - alpha, beta, gamma (floats, optional) : Angles between the - periodic cells. + periodic cell vectors. """ try: # Since we are setting the box, delete the cached box lengths if we @@ -752,8 +753,7 @@ class CharmmPsfFile(object): del self._boxLengths except AttributeError: pass - self.box_vectors = _box_vectors_from_lengths_angles(a, b, c, - alpha, beta, gamma) + self.box_vectors = computePeriodicBoxVectors(a, b, c, alpha, beta, gamma) # If we already have a _topology instance, then we have possibly changed # the existence of box information (whether or not this is a periodic # system), so delete any cached reference to a topology so it's @@ -1523,58 +1523,6 @@ class CharmmPsfFile(object): """ Deletes the CMAP terms from the CHARMM PSF """ self.cmap_list = TrackedList() -def _box_vectors_from_lengths_angles(a, b, c, alpha, beta, gamma): - """ - This method takes the lengths and angles from a unit cell and creates unit - cell vectors. - - Parameters: - - a (unit, dimension length): Length of the first vector - - b (unit, dimension length): Length of the second vector - - c (unit, dimension length): Length of the third vector - - alpha (float): Angle between b and c in degrees - - beta (float): Angle between a and c in degrees - - gamma (float): Angle between a and b in degrees - - Returns: - Tuple of box vectors (as Vec3 instances) - """ - if not (u.is_quantity(a) and u.is_quantity(b) and u.is_quantity(c)): - raise TypeError('a, b, and c must be units of dimension length') - if u.is_quantity(alpha): alpha = alpha.value_in_unit(u.degree) - if u.is_quantity(beta): beta = beta.value_in_unit(u.degree) - if u.is_quantity(gamma): gamma = gamma.value_in_unit(u.degree) - a = a.value_in_unit(u.angstrom) - b = b.value_in_unit(u.angstrom) - c = c.value_in_unit(u.angstrom) - - if alpha <= 2 * pi and beta <= 2 * pi and gamma <= 2 * pi: - raise ValueError('box angles must be given in degrees') - - alpha *= pi / 180 - beta *= pi / 180 - gamma *= pi / 180 - - av = Vec3(a, 0.0, 0.0) * u.angstrom - bx = b * cos(gamma) - by = b * sin(gamma) - bz = 0.0 - cx = c * cos(beta) - cy = c * (cos(alpha) - cos(beta) * cos(gamma)) / sin(gamma) - cz = sqrt(c * c - cx * cx - cy * cy) - - # Make sure any components that are close to zero are set to zero exactly - if abs(bx) < TINY: bx = 0.0 - if abs(by) < TINY: by = 0.0 - if abs(cx) < TINY: cx = 0.0 - if abs(cy) < TINY: cy = 0.0 - if abs(cz) < TINY: cz = 0.0 - - bv = Vec3(bx, by, bz) * u.angstrom - cv = Vec3(cx, cy, cz) * u.angstrom - - return (av, bv, cv) - # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def set_molecules(atom_list): diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 1558ce34f..00c8160ef 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -820,17 +820,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode # System is periodic. # Set periodic box vectors for periodic system (boxBeta, boxX, boxY, boxZ) = prmtop.getBoxBetaAndDimensions() - boxBeta = boxBeta.value_in_unit(units.degrees) - boxX = boxX.value_in_unit(units.angstroms) - boxY = boxY.value_in_unit(units.angstroms) - boxZ = boxZ.value_in_unit(units.angstroms) - tmp = [[0.0, 0.0, 0.0],[0.0, 0.0, 0.0],[0.0, 0.0, 0.0]] - _box_vectors_from_lengths_angles([boxX, boxY, boxZ], - [boxBeta, boxBeta, boxBeta], - tmp) - xVec = units.Quantity(tmp[0], units.angstroms) - yVec = units.Quantity(tmp[1], units.angstroms) - zVec = units.Quantity(tmp[2], units.angstroms) + xVec, yVec, zVec = computePeriodicBoxVectors(boxX, boxY, boxZ, boxBeta, boxBeta, boxBeta) system.setDefaultPeriodicBoxVectors(xVec, yVec, zVec) # Set cutoff. @@ -1286,10 +1276,10 @@ class AmberAsciiRestart(object): except (IndexError, ValueError): raise ValueError('Could not parse box line in %s' % self.filename) - lengths = tmp[:3] - angles = tmp[3:] - _box_vectors_from_lengths_angles(lengths, angles, boxVectors) - self.boxVectors = [units.Quantity(Vec3(*x), units.angstrom) for x in boxVectors] + lengths = tmp[:3] * units.angstroms + angles = tmp[3:] * units.degrees + self.boxVectors = computePeriodicBoxVectors(lengths[0], lengths[1], + lengths[2], angles[0], angles[1], angles[2]) class AmberNetcdfRestart(object): """ @@ -1360,11 +1350,12 @@ class AmberNetcdfRestart(object): if ('cell_lengths' in ncfile.variables and 'cell_angles' in ncfile.variables): self.boxVectors = np.zeros((3,3), np.float32) - _box_vectors_from_lengths_angles( - ncfile.variables['cell_lengths'][:], - ncfile.variables['cell_angles'][:], - self.boxVectors, - ) + leng = units.Quantity(ncfile.variables['cell_lengths'][:], + units.angstroms) + angl = units.Quantity(ncfile.variables['cell_angles'][:], + units.degrees) + self.boxVectors = computePeriodicBoxVectors(leng[0], leng[1], + leng[2], angl[0], angl[1], angl[2]) if 'time' in ncfile.variables: self.time = ncfile.variables['time'].getValue() finally: @@ -1375,52 +1366,18 @@ class AmberNetcdfRestart(object): self.coordinates = [Vec3(*x) for x in self.coordinates] if self.velocities is not None: self.velocities = [Vec3(*x) for x in self.velocities] + else: if self.boxVectors is not None: - self.boxVectors = [Vec3(*x) for x in self.boxVectors] + self.boxVectors = np.asarray(self.boxVectors.value_in_unit(units.nanometers)) + self.boxVectors = units.Quantity(self.boxVectors, units.nanometers) # Now add the units self.coordinates = units.Quantity(self.coordinates, units.angstroms) if self.velocities is not None: self.velocities = units.Quantity(self.velocities, units.angstroms/units.picoseconds) - if self.boxVectors is not None: - self.boxVectors = [units.Quantity(x, units.angstroms) for x in self.boxVectors] self.time = units.Quantity(self.time, units.picosecond) -def _box_vectors_from_lengths_angles(lengths, angles, boxVectors): - """ - Converts lengths and angles into a series of box vectors and modifies - boxVectors in-place (it must be a mutable sequence) - - Parameters - ---------- - lengths : 3-element array of floats - Lengths of the 3 periodic box vectors - angles : 3-element array of floats - Angles (in degrees) between the 3 periodic box vectors - boxVectors : mutable 3x3 sequence - """ - alpha = angles[0] * pi / 180.0 - beta = angles[1] * pi / 180.0 - gamma = angles[2] * pi / 180.0 - - boxVectors[0][0] = lengths[0] - - boxVectors[1][0] = lengths[1] * cos(gamma) - boxVectors[1][1] = lengths[1] * sin(gamma) - - boxVectors[2][0] = cx = lengths[2] * cos(beta) - boxVectors[2][1] = cy = lengths[2] * (cos(alpha) - cos(beta) * cos(gamma)) - boxVectors[2][2] = sqrt(lengths[2]*lengths[2] - cx*cx - cy*cy) - - boxVectors[0][1] = boxVectors[0][2] = boxVectors[1][2] = 0.0 - - # Now make sure any vector close to zero is zero exactly - for i in range(3): - for j in range(3): - if abs(boxVectors[i][j]) < TINY: - boxVectors[i][j] = 0.0 - def readAmberCoordinates(filename, asNumpy=False): """ Read atomic coordinates (and optionally, box vectors) from Amber formatted coordinate file. diff --git a/wrappers/python/simtk/openmm/app/internal/unitcell.py b/wrappers/python/simtk/openmm/app/internal/unitcell.py index 97e52107b..f3329148a 100644 --- a/wrappers/python/simtk/openmm/app/internal/unitcell.py +++ b/wrappers/python/simtk/openmm/app/internal/unitcell.py @@ -39,9 +39,17 @@ import math def computePeriodicBoxVectors(a_length, b_length, c_length, alpha, beta, gamma): """Convert lengths and angles to periodic box vectors. - Lengths should be given in nanometers and angles in radians. + Lengths should be given in nanometers and angles in radians (or as Quantity + instances) """ + if u.is_quantity(a_length): a_length = a_length.value_in_unit(u.nanometers) + if u.is_quantity(b_length): a_length = a_length.value_in_unit(u.nanometers) + if u.is_quantity(c_length): a_length = a_length.value_in_unit(u.nanometers) + if u.is_quantity(alpha): alpha = alpha.value_in_unit(u.radians) + if u.is_quantity(beta): beta = beta.value_in_unit(u.radians) + if u.is_quantity(gamma): gamma = gamma.value_in_unit(u.radians) + # Compute the vectors. a = [a_length, 0, 0] -- GitLab From 0746deda1e65df65749027bf7c8527316cb7c0f5 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 11 Feb 2015 14:14:40 -0500 Subject: [PATCH 255/338] Add support for triclinic boxes to the Amber and CHARMM file parsers. --- .../simtk/openmm/app/amberprmtopfile.py | 4 +++- .../openmm/app/internal/amber_file_parser.py | 2 +- .../simtk/openmm/app/internal/unitcell.py | 20 ++++++++++--------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/amberprmtopfile.py b/wrappers/python/simtk/openmm/app/amberprmtopfile.py index 0fa2c3506..04c05c062 100644 --- a/wrappers/python/simtk/openmm/app/amberprmtopfile.py +++ b/wrappers/python/simtk/openmm/app/amberprmtopfile.py @@ -39,6 +39,7 @@ import forcefield as ff import element as elem import simtk.unit as unit import simtk.openmm as mm +from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors # Enumerated values for implicit solvent model @@ -141,7 +142,8 @@ class AmberPrmtopFile(object): # Set the periodic box size. if prmtop.getIfBox(): - top.setUnitCellDimensions(tuple(x.value_in_unit(unit.nanometer) for x in prmtop.getBoxBetaAndDimensions()[1:4])*unit.nanometer) + box = prmtop.getBoxBetaAndDimensions() + top.setPeriodicBoxVectors(computePeriodicBoxVectors(*(box[1:4] + box[0:1]*3))) def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0*unit.nanometer, constraints=None, rigidWater=True, implicitSolvent=None, diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 00c8160ef..9e1e90217 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -52,6 +52,7 @@ except: import simtk.unit as units import simtk.openmm from simtk.openmm.app import element as elem +from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors from simtk.openmm.vec3 import Vec3 import customgbforces as customgb @@ -691,7 +692,6 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode >>> system = readAmberSystem(prmtop_filename) """ - if prmtop_filename is None and prmtop_loader is None: raise Exception("Must specify a filename or loader") if prmtop_filename is not None and prmtop_loader is not None: diff --git a/wrappers/python/simtk/openmm/app/internal/unitcell.py b/wrappers/python/simtk/openmm/app/internal/unitcell.py index f3329148a..1c4e6d6ba 100644 --- a/wrappers/python/simtk/openmm/app/internal/unitcell.py +++ b/wrappers/python/simtk/openmm/app/internal/unitcell.py @@ -32,7 +32,7 @@ __author__ = "Peter Eastman" __version__ = "1.0" from simtk.openmm import Vec3 -from simtk.unit import nanometers, is_quantity, norm, dot +from simtk.unit import nanometers, is_quantity, norm, dot, radians import math @@ -43,12 +43,12 @@ def computePeriodicBoxVectors(a_length, b_length, c_length, alpha, beta, gamma): instances) """ - if u.is_quantity(a_length): a_length = a_length.value_in_unit(u.nanometers) - if u.is_quantity(b_length): a_length = a_length.value_in_unit(u.nanometers) - if u.is_quantity(c_length): a_length = a_length.value_in_unit(u.nanometers) - if u.is_quantity(alpha): alpha = alpha.value_in_unit(u.radians) - if u.is_quantity(beta): beta = beta.value_in_unit(u.radians) - if u.is_quantity(gamma): gamma = gamma.value_in_unit(u.radians) + if is_quantity(a_length): a_length = a_length.value_in_unit(nanometers) + if is_quantity(b_length): b_length = b_length.value_in_unit(nanometers) + if is_quantity(c_length): c_length = c_length.value_in_unit(nanometers) + if is_quantity(alpha): alpha = alpha.value_in_unit(radians) + if is_quantity(beta): beta = beta.value_in_unit(radians) + if is_quantity(gamma): gamma = gamma.value_in_unit(radians) # Compute the vectors. @@ -84,8 +84,10 @@ def computeLengthsAndAngles(periodicBoxVectors): Lengths are returned in nanometers and angles in radians. """ - - (a, b, c) = vectors.value_in_unit(nanometers) + if is_quantity(periodicBoxVectors): + (a, b, c) = vectors.value_in_unit(nanometers) + else: + a, b, c = vectors a_length = norm(a) b_length = norm(b) c_length = norm(c) -- GitLab From 918d17ac4218d8477da1a7dd07664c8119cf3c6a Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Wed, 11 Feb 2015 17:27:48 -0500 Subject: [PATCH 256/338] Fix AmberPrmtopFile for building with IFBOX != 1 or 2. Also Add tests for a truncated octahedron inpcrd and prmtop file. --- .../openmm/app/internal/amber_file_parser.py | 3 - wrappers/python/tests/TestAmberInpcrdFile.py | 24 + wrappers/python/tests/TestAmberPrmtopFile.py | 28 +- .../python/tests/systems/tz2.truncoct.parm7 | 11792 ++++++++++++++++ .../python/tests/systems/tz2.truncoct.rst7 | 2917 ++++ 5 files changed, 14760 insertions(+), 4 deletions(-) create mode 100644 wrappers/python/tests/systems/tz2.truncoct.parm7 create mode 100644 wrappers/python/tests/systems/tz2.truncoct.rst7 diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 9e1e90217..16459f131 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -709,9 +709,6 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode if prmtop.getIfPert()>0: raise Exception("perturbation not currently supported") - if prmtop.getIfBox()>1: - raise Exception("only standard periodic boxes are currently supported") - if prmtop.has_scee_scnb and (scee is not None or scnb is not None): warnings.warn("1-4 scaling parameters in topology file are being ignored. " "This is not recommended unless you know what you are doing.") diff --git a/wrappers/python/tests/TestAmberInpcrdFile.py b/wrappers/python/tests/TestAmberInpcrdFile.py index e5643b809..06b04632a 100644 --- a/wrappers/python/tests/TestAmberInpcrdFile.py +++ b/wrappers/python/tests/TestAmberInpcrdFile.py @@ -60,5 +60,29 @@ class TestAmberInpcrdFile(unittest.TestCase): self.assertTrue(inpcrd.boxVectors is None) self.assertTrue(inpcrd.velocities is None) + def test_CrdBoxTruncoct(self): + # Check that the box vectors come out correct. + inpcrd = AmberInpcrdFile('systems/tz2.truncoct.rst7') + ac = Vec3(42.4388485, 0.0, 0.0) * angstroms + bc = Vec3(-14.146281691908937, 40.011730483685835, 0.0) * angstroms + cc = Vec3(-14.146281691908937, -20.0058628205162, 34.651176446201672) * angstroms + a, b, c = inpcrd.getBoxVectors() + diffa = ac - a + diffb = bc - b + diffc = cc - c + self.assertAlmostEqual(norm(diffa)/angstroms, 0) + self.assertAlmostEqual(norm(diffb)/angstroms, 0) + self.assertAlmostEqual(norm(diffc)/angstroms, 0) + # Make sure angles and lengths come out about right + la = norm(a).in_units_of(angstroms) + lb = norm(b).in_units_of(angstroms) + lc = norm(c).in_units_of(angstroms) + self.assertAlmostEqual(la/angstroms, 42.4388485, 6) + self.assertAlmostEqual(lb/angstroms, 42.4388485, 6) + self.assertAlmostEqual(lc/angstroms, 42.4388485, 6) + self.assertAlmostEqual(dot(a,b)/la/lb, cos(109.4712190*degrees), 6) + self.assertAlmostEqual(dot(a,c)/la/lc, cos(109.4712190*degrees), 6) + self.assertAlmostEqual(dot(b,c)/lc/lb, cos(109.4712190*degrees), 6) + if __name__ == '__main__': unittest.main() diff --git a/wrappers/python/tests/TestAmberPrmtopFile.py b/wrappers/python/tests/TestAmberPrmtopFile.py index 7b5982ea4..529c95eb6 100644 --- a/wrappers/python/tests/TestAmberPrmtopFile.py +++ b/wrappers/python/tests/TestAmberPrmtopFile.py @@ -9,6 +9,7 @@ prmtop1 = AmberPrmtopFile('systems/alanine-dipeptide-explicit.prmtop') prmtop2 = AmberPrmtopFile('systems/alanine-dipeptide-implicit.prmtop') prmtop3 = AmberPrmtopFile('systems/ff14ipq.parm7') prmtop4 = AmberPrmtopFile('systems/Mg_water.prmtop') +prmtop5 = AmberPrmtopFile('systems/tz2.truncoct.parm7') inpcrd3 = AmberInpcrdFile('systems/ff14ipq.rst7') inpcrd4 = AmberInpcrdFile('systems/Mg_water.inpcrd') @@ -229,7 +230,32 @@ class TestAmberPrmtopFile(unittest.TestCase): # Make sure the energy is relatively close to the value we get with # Amber using this force field. self.assertAlmostEqual(-7307.2735621/ene, 1, places=3) - + + def test_triclinicParm(self): + """ Check that triclinic unit cells work correctly """ + system = prmtop5.createSystem(nonbondedMethod=PME) + refa = Vec3(4.48903851, 0.0, 0.0) * nanometer + refb = Vec3(-1.4963460492639706, 4.232306137924705, 0.0) * nanometer + refc = Vec3(-1.4963460492639706, -2.116152812842565, 3.6652847799064165) * nanometer + a, b, c = system.getDefaultPeriodicBoxVectors() + la = norm(a) + lb = norm(b) + lc = norm(c) + diffa = a - refa + diffb = b - refb + diffc = c - refc + self.assertAlmostEqual(norm(diffa)/nanometers, 0) + self.assertAlmostEqual(norm(diffb)/nanometers, 0) + self.assertAlmostEqual(norm(diffc)/nanometers, 0) + self.assertAlmostEqual(dot(a, b)/la/lb, cos(109.4712190*degrees)) + self.assertAlmostEqual(dot(a, c)/la/lc, cos(109.4712190*degrees)) + self.assertAlmostEqual(dot(c, b)/lc/lb, cos(109.4712190*degrees)) + self.assertAlmostEqual(la/nanometers, 4.48903851) + self.assertAlmostEqual(lb/nanometers, 4.48903851) + self.assertAlmostEqual(lc/nanometers, 4.48903851) + # Now make sure that the context builds correctly; then we can bail + self.assertTrue(Context(system, VerletIntegrator(1*femtoseconds))) + def test_ImplicitSolventForces(self): """Compute forces for different implicit solvent types, and compare them to ones generated with a previous version of OpenMM to ensure they haven't changed.""" diff --git a/wrappers/python/tests/systems/tz2.truncoct.parm7 b/wrappers/python/tests/systems/tz2.truncoct.parm7 new file mode 100644 index 000000000..113d9affe --- /dev/null +++ b/wrappers/python/tests/systems/tz2.truncoct.parm7 @@ -0,0 +1,11792 @@ +%VERSION VERSION_STAMP = V0001.000 DATE = 10/13/11 11:08:51 +%FLAG TITLE +%FORMAT(20a4) + +%FLAG POINTERS +%FORMAT(10I8) + 5827 14 5711 123 233 169 481 372 0 0 + 8687 1882 123 169 372 33 68 35 23 1 + 0 0 0 0 0 0 0 2 24 0 + 0 +%FLAG ATOM_NAME +%FORMAT(20a4) +N H1 H2 H3 CA HA CB HB2 HB3 OG HG C O N H CA HA CB HB2 HB3 +CG CD1 HD1 NE1 HE1 CE2 CZ2 HZ2 CH2 HH2 CZ3 HZ3 CE3 HE3 CD2 C O N H CA +HA CB HB CG2 HG21HG22HG23OG1 HG1 C O N H CA HA CB HB2 HB3 CG CD1 +HD1 NE1 HE1 CE2 CZ2 HZ2 CH2 HH2 CZ3 HZ3 CE3 HE3 CD2 C O N H CA HA CB +HB2 HB3 CG HG2 HG3 CD OE1 OE2 C O N H CA HA CB HB2 HB3 CG OD1 ND2 +HD21HD22C O N H CA HA2 HA3 C O N H CA HA CB HB2 HB3 CG HG2 +HG3 CD HD2 HD3 CE HE2 HE3 NZ HZ1 HZ2 HZ3 C O N H CA HA CB HB2 HB3 +CG CD1 HD1 NE1 HE1 CE2 CZ2 HZ2 CH2 HH2 CZ3 HZ3 CE3 HE3 CD2 C O N H CA +HA CB HB CG2 HG21HG22HG23OG1 HG1 C O N H CA HA CB HB2 HB3 CG CD1 +HD1 NE1 HE1 CE2 CZ2 HZ2 CH2 HH2 CZ3 HZ3 CE3 HE3 CD2 C O N H CA HA CB +HB2 HB3 CG HG2 HG3 CD HD2 HD3 CE HE2 HE3 NZ HZ1 HZ2 HZ3 C O N HN1 HN2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O +H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 +O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 H2 O H1 +H2 O H1 H2 O H1 H2 +%FLAG CHARGE +%FORMAT(5E16.8) + 3.36930327E+00 3.45859254E+00 3.45859254E+00 3.45859254E+00 1.03320441E+00 + 1.42498386E+00 4.73050908E+00 4.97468790E-01 4.97468790E-01 -1.22344522E+01 + 7.72443297E+00 1.12304035E+01 -1.04268001E+01 -7.57501011E+00 4.95464337E+00 + -5.01113250E-01 2.04636429E+00 -9.11115000E-02 6.17735970E-01 6.17735970E-01 + -2.57845545E+00 -2.98481274E+00 3.75743826E+00 -6.22838214E+00 6.21744876E+00 + 2.51467740E+00 -4.73962023E+00 2.86454556E+00 -2.06640882E+00 2.58209991E+00 + -3.59343756E+00 2.63676681E+00 -4.34966301E+00 3.09779100E+00 2.26503189E+00 + 1.08841798E+01 -1.03484442E+01 -7.57501011E+00 4.95464337E+00 -7.08847470E-01 + 1.83498561E+00 6.65842842E+00 7.83558900E-02 -4.44259674E+00 1.16987166E+00 + 1.16987166E+00 1.16987166E+00 -1.23200970E+01 7.47478746E+00 1.08841798E+01 + -1.03484442E+01 -7.57501011E+00 4.95464337E+00 -5.01113250E-01 2.04636429E+00 + -9.11115000E-02 6.17735970E-01 6.17735970E-01 -2.57845545E+00 -2.98481274E+00 + 3.75743826E+00 -6.22838214E+00 6.21744876E+00 2.51467740E+00 -4.73962023E+00 + 2.86454556E+00 -2.06640882E+00 2.58209991E+00 -3.59343756E+00 2.63676681E+00 + -4.34966301E+00 3.09779100E+00 2.26503189E+00 1.08841798E+01 -1.03484442E+01 + -9.40817349E+00 5.35006728E+00 7.23425310E-01 2.01356415E+00 1.02044880E+00 + -3.15245790E-01 -3.15245790E-01 2.47823280E-01 -7.74447750E-01 -7.74447750E-01 + 1.46762404E+01 -1.49204192E+01 -1.49204192E+01 9.77808618E+00 -1.06035564E+01 + -7.57501011E+00 4.95464337E+00 2.60578890E-01 1.90969704E+00 -3.71917143E+00 + 1.45231731E+00 1.45231731E+00 1.29924999E+01 -1.08076461E+01 -1.67481159E+01 + 7.64607708E+00 7.64607708E+00 1.08841798E+01 -1.03484442E+01 -7.57501011E+00 + 4.95464337E+00 -4.59201960E-01 1.27191654E+00 1.27191654E+00 1.08841798E+01 + -1.03484442E+01 -6.33953817E+00 5.00566581E+00 -4.37335200E+00 2.59849998E+00 + -1.71289620E-01 6.59647260E-01 6.59647260E-01 3.40757010E-01 1.87689690E-01 + 1.87689690E-01 -8.72848170E-01 1.13160483E+00 1.13160483E+00 -2.60578890E-01 + 2.06823105E+00 2.06823105E+00 -7.02287442E+00 6.19558200E+00 6.19558200E+00 + 6.19558200E+00 1.33769904E+01 -1.07402236E+01 -7.57501011E+00 4.95464337E+00 + -5.01113250E-01 2.04636429E+00 -9.11115000E-02 6.17735970E-01 6.17735970E-01 + -2.57845545E+00 -2.98481274E+00 3.75743826E+00 -6.22838214E+00 6.21744876E+00 + 2.51467740E+00 -4.73962023E+00 2.86454556E+00 -2.06640882E+00 2.58209991E+00 + -3.59343756E+00 2.63676681E+00 -4.34966301E+00 3.09779100E+00 2.26503189E+00 + 1.08841798E+01 -1.03484442E+01 -7.57501011E+00 4.95464337E+00 -7.08847470E-01 + 1.83498561E+00 6.65842842E+00 7.83558900E-02 -4.44259674E+00 1.16987166E+00 + 1.16987166E+00 1.16987166E+00 -1.23200970E+01 7.47478746E+00 1.08841798E+01 + -1.03484442E+01 -7.57501011E+00 4.95464337E+00 -5.01113250E-01 2.04636429E+00 + -9.11115000E-02 6.17735970E-01 6.17735970E-01 -2.57845545E+00 -2.98481274E+00 + 3.75743826E+00 -6.22838214E+00 6.21744876E+00 2.51467740E+00 -4.73962023E+00 + 2.86454556E+00 -2.06640882E+00 2.58209991E+00 -3.59343756E+00 2.63676681E+00 + -4.34966301E+00 3.09779100E+00 2.26503189E+00 1.08841798E+01 -1.03484442E+01 + -6.33953817E+00 5.00566581E+00 -4.37335200E+00 2.59849998E+00 -1.71289620E-01 + 6.59647260E-01 6.59647260E-01 3.40757010E-01 1.87689690E-01 1.87689690E-01 + -8.72848170E-01 1.13160483E+00 1.13160483E+00 -2.60578890E-01 2.06823105E+00 + 2.06823105E+00 -7.02287442E+00 6.19558200E+00 6.19558200E+00 6.19558200E+00 + 1.33769904E+01 -1.07402236E+01 -8.43692490E+00 4.21846245E+00 4.21846245E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 + -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 7.59869910E+00 + 7.59869910E+00 -1.51973982E+01 7.59869910E+00 7.59869910E+00 -1.51973982E+01 + 7.59869910E+00 7.59869910E+00 +%FLAG MASS +%FORMAT(5E16.8) + 1.40100000E+01 1.00800000E+00 1.00800000E+00 1.00800000E+00 1.20100000E+01 + 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.20100000E+01 1.60000000E+01 1.40100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.00800000E+00 + 1.20100000E+01 1.20100000E+01 1.00800000E+00 1.40100000E+01 1.00800000E+00 + 1.20100000E+01 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 + 1.20100000E+01 1.60000000E+01 1.40100000E+01 1.00800000E+00 1.20100000E+01 + 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.20100000E+01 + 1.60000000E+01 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.20100000E+01 + 1.00800000E+00 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.20100000E+01 + 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.20100000E+01 1.60000000E+01 + 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 + 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.00800000E+00 + 1.20100000E+01 1.60000000E+01 1.60000000E+01 1.20100000E+01 1.60000000E+01 + 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 + 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.60000000E+01 1.40100000E+01 + 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.60000000E+01 1.40100000E+01 + 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.00800000E+00 1.20100000E+01 + 1.60000000E+01 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.00800000E+00 1.20100000E+01 + 1.00800000E+00 1.00800000E+00 1.40100000E+01 1.00800000E+00 1.00800000E+00 + 1.00800000E+00 1.20100000E+01 1.60000000E+01 1.40100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.00800000E+00 + 1.20100000E+01 1.20100000E+01 1.00800000E+00 1.40100000E+01 1.00800000E+00 + 1.20100000E+01 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 + 1.20100000E+01 1.60000000E+01 1.40100000E+01 1.00800000E+00 1.20100000E+01 + 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.20100000E+01 + 1.60000000E+01 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.20100000E+01 + 1.00800000E+00 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.20100000E+01 + 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.20100000E+01 1.20100000E+01 1.60000000E+01 + 1.40100000E+01 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.20100000E+01 + 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.00800000E+00 1.00800000E+00 + 1.20100000E+01 1.00800000E+00 1.00800000E+00 1.20100000E+01 1.00800000E+00 + 1.00800000E+00 1.40100000E+01 1.00800000E+00 1.00800000E+00 1.00800000E+00 + 1.20100000E+01 1.60000000E+01 1.40100000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 +%FLAG ATOM_TYPE_INDEX +%FORMAT(10I8) + 1 2 2 2 3 4 3 5 5 6 + 7 8 9 1 2 3 5 3 10 10 + 8 8 11 1 2 8 8 12 8 12 + 8 12 8 12 8 8 9 1 2 3 + 5 3 5 3 10 10 10 6 7 8 + 9 1 2 3 5 3 10 10 8 8 + 11 1 2 8 8 12 8 12 8 12 + 8 12 8 8 9 1 2 3 5 3 + 10 10 3 10 10 8 9 9 8 9 + 1 2 3 5 3 10 10 8 9 1 + 2 2 8 9 1 2 3 5 5 8 + 9 1 2 3 5 3 10 10 3 10 + 10 3 10 10 3 4 4 1 2 2 + 2 8 9 1 2 3 5 3 10 10 + 8 8 11 1 2 8 8 12 8 12 + 8 12 8 12 8 8 9 1 2 3 + 5 3 5 3 10 10 10 6 7 8 + 9 1 2 3 5 3 10 10 8 8 + 11 1 2 8 8 12 8 12 8 12 + 8 12 8 8 9 1 2 3 5 3 + 10 10 3 10 10 3 10 10 3 4 + 4 1 2 2 2 8 9 1 2 2 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 13 14 14 + 13 14 14 13 14 14 13 14 14 13 + 14 14 13 14 14 13 14 14 13 14 + 14 13 14 14 13 14 14 +%FLAG NUMBER_EXCLUDED_ATOMS +%FORMAT(10I8) + 12 6 5 4 11 7 7 4 3 2 + 1 7 3 10 4 12 7 12 5 4 + 11 7 4 7 3 8 7 4 6 3 + 4 3 2 1 1 7 3 10 4 14 + 7 10 7 6 3 2 1 2 1 7 + 3 10 4 12 7 12 5 4 11 7 + 4 7 3 8 7 4 6 3 4 3 + 2 1 1 7 3 10 4 13 7 11 + 6 5 6 4 3 2 1 1 7 3 + 10 4 12 7 10 5 4 5 3 2 + 1 1 7 3 7 4 7 4 3 7 + 3 10 4 13 7 12 6 5 10 5 + 4 9 5 4 6 5 4 3 2 1 + 1 7 3 10 4 12 7 12 5 4 + 11 7 4 7 3 8 7 4 6 3 + 4 3 2 1 1 7 3 10 4 14 + 7 10 7 6 3 2 1 2 1 7 + 3 10 4 12 7 12 5 4 11 7 + 4 7 3 8 7 4 6 3 4 3 + 2 1 1 7 3 10 4 13 7 12 + 6 5 10 5 4 9 5 4 6 5 + 4 3 2 1 1 4 3 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 +%FLAG NONBONDED_PARM_INDEX +%FORMAT(10I8) + 1 2 4 7 11 16 22 29 37 46 + 56 67 79 92 2 3 5 8 12 17 + 23 30 38 47 57 68 80 93 4 5 + 6 9 13 18 24 31 39 48 58 69 + 81 94 7 8 9 10 14 19 25 32 + 40 49 59 70 82 95 11 12 13 14 + 15 20 26 33 41 50 60 71 83 96 + 16 17 18 19 20 21 27 34 42 51 + 61 72 84 97 22 23 24 25 26 27 + 28 35 43 52 62 73 85 98 29 30 + 31 32 33 34 35 36 44 53 63 74 + 86 99 37 38 39 40 41 42 43 44 + 45 54 64 75 87 100 46 47 48 49 + 50 51 52 53 54 55 65 76 88 101 + 56 57 58 59 60 61 62 63 64 65 + 66 77 89 102 67 68 69 70 71 72 + 73 74 75 76 77 78 90 103 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 -1 92 93 94 95 96 97 98 99 + 100 101 102 103 -1 105 +%FLAG RESIDUE_LABEL +%FORMAT(20a4) +SER TRP THR TRP GLU ASN GLY LYS TRP THR TRP LYS NHE WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT WAT +WAT WAT +%FLAG RESIDUE_POINTER +%FORMAT(10I8) + 1 14 38 52 76 91 105 112 134 158 + 172 196 218 221 224 227 230 233 236 239 + 242 245 248 251 254 257 260 263 266 269 + 272 275 278 281 284 287 290 293 296 299 + 302 305 308 311 314 317 320 323 326 329 + 332 335 338 341 344 347 350 353 356 359 + 362 365 368 371 374 377 380 383 386 389 + 392 395 398 401 404 407 410 413 416 419 + 422 425 428 431 434 437 440 443 446 449 + 452 455 458 461 464 467 470 473 476 479 + 482 485 488 491 494 497 500 503 506 509 + 512 515 518 521 524 527 530 533 536 539 + 542 545 548 551 554 557 560 563 566 569 + 572 575 578 581 584 587 590 593 596 599 + 602 605 608 611 614 617 620 623 626 629 + 632 635 638 641 644 647 650 653 656 659 + 662 665 668 671 674 677 680 683 686 689 + 692 695 698 701 704 707 710 713 716 719 + 722 725 728 731 734 737 740 743 746 749 + 752 755 758 761 764 767 770 773 776 779 + 782 785 788 791 794 797 800 803 806 809 + 812 815 818 821 824 827 830 833 836 839 + 842 845 848 851 854 857 860 863 866 869 + 872 875 878 881 884 887 890 893 896 899 + 902 905 908 911 914 917 920 923 926 929 + 932 935 938 941 944 947 950 953 956 959 + 962 965 968 971 974 977 980 983 986 989 + 992 995 998 1001 1004 1007 1010 1013 1016 1019 + 1022 1025 1028 1031 1034 1037 1040 1043 1046 1049 + 1052 1055 1058 1061 1064 1067 1070 1073 1076 1079 + 1082 1085 1088 1091 1094 1097 1100 1103 1106 1109 + 1112 1115 1118 1121 1124 1127 1130 1133 1136 1139 + 1142 1145 1148 1151 1154 1157 1160 1163 1166 1169 + 1172 1175 1178 1181 1184 1187 1190 1193 1196 1199 + 1202 1205 1208 1211 1214 1217 1220 1223 1226 1229 + 1232 1235 1238 1241 1244 1247 1250 1253 1256 1259 + 1262 1265 1268 1271 1274 1277 1280 1283 1286 1289 + 1292 1295 1298 1301 1304 1307 1310 1313 1316 1319 + 1322 1325 1328 1331 1334 1337 1340 1343 1346 1349 + 1352 1355 1358 1361 1364 1367 1370 1373 1376 1379 + 1382 1385 1388 1391 1394 1397 1400 1403 1406 1409 + 1412 1415 1418 1421 1424 1427 1430 1433 1436 1439 + 1442 1445 1448 1451 1454 1457 1460 1463 1466 1469 + 1472 1475 1478 1481 1484 1487 1490 1493 1496 1499 + 1502 1505 1508 1511 1514 1517 1520 1523 1526 1529 + 1532 1535 1538 1541 1544 1547 1550 1553 1556 1559 + 1562 1565 1568 1571 1574 1577 1580 1583 1586 1589 + 1592 1595 1598 1601 1604 1607 1610 1613 1616 1619 + 1622 1625 1628 1631 1634 1637 1640 1643 1646 1649 + 1652 1655 1658 1661 1664 1667 1670 1673 1676 1679 + 1682 1685 1688 1691 1694 1697 1700 1703 1706 1709 + 1712 1715 1718 1721 1724 1727 1730 1733 1736 1739 + 1742 1745 1748 1751 1754 1757 1760 1763 1766 1769 + 1772 1775 1778 1781 1784 1787 1790 1793 1796 1799 + 1802 1805 1808 1811 1814 1817 1820 1823 1826 1829 + 1832 1835 1838 1841 1844 1847 1850 1853 1856 1859 + 1862 1865 1868 1871 1874 1877 1880 1883 1886 1889 + 1892 1895 1898 1901 1904 1907 1910 1913 1916 1919 + 1922 1925 1928 1931 1934 1937 1940 1943 1946 1949 + 1952 1955 1958 1961 1964 1967 1970 1973 1976 1979 + 1982 1985 1988 1991 1994 1997 2000 2003 2006 2009 + 2012 2015 2018 2021 2024 2027 2030 2033 2036 2039 + 2042 2045 2048 2051 2054 2057 2060 2063 2066 2069 + 2072 2075 2078 2081 2084 2087 2090 2093 2096 2099 + 2102 2105 2108 2111 2114 2117 2120 2123 2126 2129 + 2132 2135 2138 2141 2144 2147 2150 2153 2156 2159 + 2162 2165 2168 2171 2174 2177 2180 2183 2186 2189 + 2192 2195 2198 2201 2204 2207 2210 2213 2216 2219 + 2222 2225 2228 2231 2234 2237 2240 2243 2246 2249 + 2252 2255 2258 2261 2264 2267 2270 2273 2276 2279 + 2282 2285 2288 2291 2294 2297 2300 2303 2306 2309 + 2312 2315 2318 2321 2324 2327 2330 2333 2336 2339 + 2342 2345 2348 2351 2354 2357 2360 2363 2366 2369 + 2372 2375 2378 2381 2384 2387 2390 2393 2396 2399 + 2402 2405 2408 2411 2414 2417 2420 2423 2426 2429 + 2432 2435 2438 2441 2444 2447 2450 2453 2456 2459 + 2462 2465 2468 2471 2474 2477 2480 2483 2486 2489 + 2492 2495 2498 2501 2504 2507 2510 2513 2516 2519 + 2522 2525 2528 2531 2534 2537 2540 2543 2546 2549 + 2552 2555 2558 2561 2564 2567 2570 2573 2576 2579 + 2582 2585 2588 2591 2594 2597 2600 2603 2606 2609 + 2612 2615 2618 2621 2624 2627 2630 2633 2636 2639 + 2642 2645 2648 2651 2654 2657 2660 2663 2666 2669 + 2672 2675 2678 2681 2684 2687 2690 2693 2696 2699 + 2702 2705 2708 2711 2714 2717 2720 2723 2726 2729 + 2732 2735 2738 2741 2744 2747 2750 2753 2756 2759 + 2762 2765 2768 2771 2774 2777 2780 2783 2786 2789 + 2792 2795 2798 2801 2804 2807 2810 2813 2816 2819 + 2822 2825 2828 2831 2834 2837 2840 2843 2846 2849 + 2852 2855 2858 2861 2864 2867 2870 2873 2876 2879 + 2882 2885 2888 2891 2894 2897 2900 2903 2906 2909 + 2912 2915 2918 2921 2924 2927 2930 2933 2936 2939 + 2942 2945 2948 2951 2954 2957 2960 2963 2966 2969 + 2972 2975 2978 2981 2984 2987 2990 2993 2996 2999 + 3002 3005 3008 3011 3014 3017 3020 3023 3026 3029 + 3032 3035 3038 3041 3044 3047 3050 3053 3056 3059 + 3062 3065 3068 3071 3074 3077 3080 3083 3086 3089 + 3092 3095 3098 3101 3104 3107 3110 3113 3116 3119 + 3122 3125 3128 3131 3134 3137 3140 3143 3146 3149 + 3152 3155 3158 3161 3164 3167 3170 3173 3176 3179 + 3182 3185 3188 3191 3194 3197 3200 3203 3206 3209 + 3212 3215 3218 3221 3224 3227 3230 3233 3236 3239 + 3242 3245 3248 3251 3254 3257 3260 3263 3266 3269 + 3272 3275 3278 3281 3284 3287 3290 3293 3296 3299 + 3302 3305 3308 3311 3314 3317 3320 3323 3326 3329 + 3332 3335 3338 3341 3344 3347 3350 3353 3356 3359 + 3362 3365 3368 3371 3374 3377 3380 3383 3386 3389 + 3392 3395 3398 3401 3404 3407 3410 3413 3416 3419 + 3422 3425 3428 3431 3434 3437 3440 3443 3446 3449 + 3452 3455 3458 3461 3464 3467 3470 3473 3476 3479 + 3482 3485 3488 3491 3494 3497 3500 3503 3506 3509 + 3512 3515 3518 3521 3524 3527 3530 3533 3536 3539 + 3542 3545 3548 3551 3554 3557 3560 3563 3566 3569 + 3572 3575 3578 3581 3584 3587 3590 3593 3596 3599 + 3602 3605 3608 3611 3614 3617 3620 3623 3626 3629 + 3632 3635 3638 3641 3644 3647 3650 3653 3656 3659 + 3662 3665 3668 3671 3674 3677 3680 3683 3686 3689 + 3692 3695 3698 3701 3704 3707 3710 3713 3716 3719 + 3722 3725 3728 3731 3734 3737 3740 3743 3746 3749 + 3752 3755 3758 3761 3764 3767 3770 3773 3776 3779 + 3782 3785 3788 3791 3794 3797 3800 3803 3806 3809 + 3812 3815 3818 3821 3824 3827 3830 3833 3836 3839 + 3842 3845 3848 3851 3854 3857 3860 3863 3866 3869 + 3872 3875 3878 3881 3884 3887 3890 3893 3896 3899 + 3902 3905 3908 3911 3914 3917 3920 3923 3926 3929 + 3932 3935 3938 3941 3944 3947 3950 3953 3956 3959 + 3962 3965 3968 3971 3974 3977 3980 3983 3986 3989 + 3992 3995 3998 4001 4004 4007 4010 4013 4016 4019 + 4022 4025 4028 4031 4034 4037 4040 4043 4046 4049 + 4052 4055 4058 4061 4064 4067 4070 4073 4076 4079 + 4082 4085 4088 4091 4094 4097 4100 4103 4106 4109 + 4112 4115 4118 4121 4124 4127 4130 4133 4136 4139 + 4142 4145 4148 4151 4154 4157 4160 4163 4166 4169 + 4172 4175 4178 4181 4184 4187 4190 4193 4196 4199 + 4202 4205 4208 4211 4214 4217 4220 4223 4226 4229 + 4232 4235 4238 4241 4244 4247 4250 4253 4256 4259 + 4262 4265 4268 4271 4274 4277 4280 4283 4286 4289 + 4292 4295 4298 4301 4304 4307 4310 4313 4316 4319 + 4322 4325 4328 4331 4334 4337 4340 4343 4346 4349 + 4352 4355 4358 4361 4364 4367 4370 4373 4376 4379 + 4382 4385 4388 4391 4394 4397 4400 4403 4406 4409 + 4412 4415 4418 4421 4424 4427 4430 4433 4436 4439 + 4442 4445 4448 4451 4454 4457 4460 4463 4466 4469 + 4472 4475 4478 4481 4484 4487 4490 4493 4496 4499 + 4502 4505 4508 4511 4514 4517 4520 4523 4526 4529 + 4532 4535 4538 4541 4544 4547 4550 4553 4556 4559 + 4562 4565 4568 4571 4574 4577 4580 4583 4586 4589 + 4592 4595 4598 4601 4604 4607 4610 4613 4616 4619 + 4622 4625 4628 4631 4634 4637 4640 4643 4646 4649 + 4652 4655 4658 4661 4664 4667 4670 4673 4676 4679 + 4682 4685 4688 4691 4694 4697 4700 4703 4706 4709 + 4712 4715 4718 4721 4724 4727 4730 4733 4736 4739 + 4742 4745 4748 4751 4754 4757 4760 4763 4766 4769 + 4772 4775 4778 4781 4784 4787 4790 4793 4796 4799 + 4802 4805 4808 4811 4814 4817 4820 4823 4826 4829 + 4832 4835 4838 4841 4844 4847 4850 4853 4856 4859 + 4862 4865 4868 4871 4874 4877 4880 4883 4886 4889 + 4892 4895 4898 4901 4904 4907 4910 4913 4916 4919 + 4922 4925 4928 4931 4934 4937 4940 4943 4946 4949 + 4952 4955 4958 4961 4964 4967 4970 4973 4976 4979 + 4982 4985 4988 4991 4994 4997 5000 5003 5006 5009 + 5012 5015 5018 5021 5024 5027 5030 5033 5036 5039 + 5042 5045 5048 5051 5054 5057 5060 5063 5066 5069 + 5072 5075 5078 5081 5084 5087 5090 5093 5096 5099 + 5102 5105 5108 5111 5114 5117 5120 5123 5126 5129 + 5132 5135 5138 5141 5144 5147 5150 5153 5156 5159 + 5162 5165 5168 5171 5174 5177 5180 5183 5186 5189 + 5192 5195 5198 5201 5204 5207 5210 5213 5216 5219 + 5222 5225 5228 5231 5234 5237 5240 5243 5246 5249 + 5252 5255 5258 5261 5264 5267 5270 5273 5276 5279 + 5282 5285 5288 5291 5294 5297 5300 5303 5306 5309 + 5312 5315 5318 5321 5324 5327 5330 5333 5336 5339 + 5342 5345 5348 5351 5354 5357 5360 5363 5366 5369 + 5372 5375 5378 5381 5384 5387 5390 5393 5396 5399 + 5402 5405 5408 5411 5414 5417 5420 5423 5426 5429 + 5432 5435 5438 5441 5444 5447 5450 5453 5456 5459 + 5462 5465 5468 5471 5474 5477 5480 5483 5486 5489 + 5492 5495 5498 5501 5504 5507 5510 5513 5516 5519 + 5522 5525 5528 5531 5534 5537 5540 5543 5546 5549 + 5552 5555 5558 5561 5564 5567 5570 5573 5576 5579 + 5582 5585 5588 5591 5594 5597 5600 5603 5606 5609 + 5612 5615 5618 5621 5624 5627 5630 5633 5636 5639 + 5642 5645 5648 5651 5654 5657 5660 5663 5666 5669 + 5672 5675 5678 5681 5684 5687 5690 5693 5696 5699 + 5702 5705 5708 5711 5714 5717 5720 5723 5726 5729 + 5732 5735 5738 5741 5744 5747 5750 5753 5756 5759 + 5762 5765 5768 5771 5774 5777 5780 5783 5786 5789 + 5792 5795 5798 5801 5804 5807 5810 5813 5816 5819 + 5822 5825 +%FLAG BOND_FORCE_CONSTANT +%FORMAT(5E16.8) + 5.70000000E+02 4.90000000E+02 5.53000000E+02 3.40000000E+02 3.20000000E+02 + 3.40000000E+02 3.10000000E+02 3.17000000E+02 4.34000000E+02 3.67000000E+02 + 3.67000000E+02 4.69000000E+02 4.69000000E+02 4.69000000E+02 4.47000000E+02 + 4.34000000E+02 4.28000000E+02 3.67000000E+02 4.27000000E+02 5.46000000E+02 + 3.88000000E+02 3.40000000E+02 3.17000000E+02 3.40000000E+02 4.34000000E+02 + 3.37000000E+02 3.10000000E+02 6.56000000E+02 3.17000000E+02 3.40000000E+02 + 3.67000000E+02 5.53000000E+02 5.53000000E+02 +%FLAG BOND_EQUIL_VALUE +%FORMAT(5E16.8) + 1.22900000E+00 1.33500000E+00 9.60000000E-01 1.09000000E+00 1.41000000E+00 + 1.09000000E+00 1.52600000E+00 1.52200000E+00 1.01000000E+00 1.47100000E+00 + 1.08000000E+00 1.40400000E+00 1.40000000E+00 1.40000000E+00 1.41900000E+00 + 1.01000000E+00 1.38000000E+00 1.08000000E+00 1.38100000E+00 1.35200000E+00 + 1.45900000E+00 1.09000000E+00 1.49500000E+00 1.09000000E+00 1.01000000E+00 + 1.44900000E+00 1.52600000E+00 1.25000000E+00 1.52200000E+00 1.09000000E+00 + 1.47100000E+00 9.57200000E-01 1.51360000E+00 +%FLAG ANGLE_FORCE_CONSTANT +%FORMAT(5E16.8) + 8.00000000E+01 5.00000000E+01 5.00000000E+01 5.00000000E+01 3.50000000E+01 + 6.30000000E+01 5.50000000E+01 5.00000000E+01 5.00000000E+01 5.00000000E+01 + 5.00000000E+01 8.00000000E+01 7.00000000E+01 5.00000000E+01 3.50000000E+01 + 5.00000000E+01 8.00000000E+01 8.00000000E+01 5.00000000E+01 5.00000000E+01 + 6.30000000E+01 6.30000000E+01 6.30000000E+01 5.00000000E+01 6.30000000E+01 + 6.30000000E+01 5.00000000E+01 7.00000000E+01 7.00000000E+01 5.00000000E+01 + 6.30000000E+01 5.00000000E+01 7.00000000E+01 5.00000000E+01 7.00000000E+01 + 6.30000000E+01 6.30000000E+01 5.00000000E+01 3.50000000E+01 7.00000000E+01 + 7.00000000E+01 5.00000000E+01 5.00000000E+01 5.00000000E+01 6.30000000E+01 + 5.00000000E+01 5.00000000E+01 8.00000000E+01 6.30000000E+01 5.00000000E+01 + 5.00000000E+01 5.00000000E+01 4.00000000E+01 8.00000000E+01 5.00000000E+01 + 7.00000000E+01 6.30000000E+01 3.50000000E+01 8.00000000E+01 7.00000000E+01 + 6.30000000E+01 3.50000000E+01 5.00000000E+01 3.50000000E+01 5.00000000E+01 + 5.00000000E+01 8.00000000E+01 4.00000000E+01 +%FLAG ANGLE_EQUIL_VALUE +%FORMAT(5E16.8) + 2.14501057E+00 2.09439600E+00 2.12755727E+00 1.91113635E+00 1.91113635E+00 + 1.93906163E+00 1.89368305E+00 1.91113635E+00 1.91113635E+00 1.91113635E+00 + 1.91113635E+00 2.10137732E+00 2.03505478E+00 1.91113635E+00 1.91113635E+00 + 1.91113635E+00 1.94080696E+00 1.94080696E+00 2.09439600E+00 2.09439600E+00 + 2.09439600E+00 2.09439600E+00 2.14151991E+00 2.09439600E+00 2.09439600E+00 + 2.02807346E+00 2.14850123E+00 2.31779824E+00 1.82212452E+00 2.09439600E+00 + 1.85703112E+00 2.09439600E+00 1.94778828E+00 2.09439600E+00 1.89717371E+00 + 1.89891904E+00 2.35445017E+00 1.91113635E+00 1.91113635E+00 2.18166250E+00 + 2.24449438E+00 1.91113635E+00 1.91113635E+00 1.91113635E+00 2.01760148E+00 + 2.06018753E+00 1.91113635E+00 1.91462701E+00 1.92160833E+00 1.91113635E+00 + 1.91113635E+00 1.91113635E+00 1.91113635E+00 2.19911580E+00 1.91113635E+00 + 2.04203610E+00 1.93906163E+00 2.09439600E+00 2.10137732E+00 2.03505478E+00 + 1.93906163E+00 1.91113635E+00 1.91113635E+00 1.91113635E+00 1.91113635E+00 + 1.91113635E+00 1.94080696E+00 1.91113635E+00 +%FLAG DIHEDRAL_FORCE_CONSTANT +%FORMAT(5E16.8) + 2.00000000E+00 2.50000000E+00 0.00000000E+00 2.00000000E+00 4.00000000E-01 + 0.00000000E+00 0.00000000E+00 2.70000000E-01 4.20000000E-01 1.55555556E-01 + 1.66666667E-01 2.00000000E-01 2.00000000E-01 2.50000000E-01 1.60000000E-01 + 3.62500000E+00 3.00000000E+00 3.50000000E+00 1.52500000E+00 6.52500000E+00 + 1.50000000E+00 1.67500000E+00 8.00000000E-01 8.00000000E-02 4.50000000E-01 + 1.58000000E+00 5.50000000E-01 0.00000000E+00 1.50000000E-01 2.00000000E-01 + 2.50000000E-01 1.80000000E-01 1.05000000E+01 1.10000000E+00 1.00000000E+00 +%FLAG DIHEDRAL_PERIODICITY +%FORMAT(5E16.8) + 1.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 3.00000000E+00 + 4.00000000E+00 1.00000000E+00 2.00000000E+00 3.00000000E+00 3.00000000E+00 + 3.00000000E+00 1.00000000E+00 2.00000000E+00 1.00000000E+00 3.00000000E+00 + 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 + 2.00000000E+00 2.00000000E+00 1.00000000E+00 3.00000000E+00 1.00000000E+00 + 2.00000000E+00 3.00000000E+00 3.00000000E+00 3.00000000E+00 1.00000000E+00 + 2.00000000E+00 3.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 +%FLAG DIHEDRAL_PHASE +%FORMAT(5E16.8) + 0.00000000E+00 3.14159400E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 3.14159400E+00 3.14159400E+00 3.14159400E+00 3.14159400E+00 3.14159400E+00 + 3.14159400E+00 3.14159400E+00 0.00000000E+00 3.14159400E+00 3.14159400E+00 + 3.14159400E+00 3.14159400E+00 0.00000000E+00 0.00000000E+00 3.14159400E+00 + 3.14159400E+00 0.00000000E+00 3.14159400E+00 3.14159400E+00 3.14159400E+00 +%FLAG SCEE_SCALE_FACTOR +%FORMAT(5E16.8) + 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 + 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 + 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 + 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 + 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 + 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 1.20000000E+00 + 1.20000000E+00 1.20000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 +%FLAG SCNB_SCALE_FACTOR +%FORMAT(5E16.8) + 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 + 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 + 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 + 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 + 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 + 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 2.00000000E+00 + 2.00000000E+00 2.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 +%FLAG SOLTY +%FORMAT(5E16.8) + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 +%FLAG LENNARD_JONES_ACOEF +%FORMAT(5E16.8) + 9.44293233E+05 2.12601181E+03 1.39982777E-01 9.95480466E+05 2.56678134E+03 + 1.04308023E+06 2.01791425E+04 9.14716912E+00 2.27401052E+04 2.01823541E+02 + 6.20665997E+04 5.94667300E+01 6.78771368E+04 8.79040886E+02 3.25969625E+03 + 7.44975864E+05 1.40467023E+03 7.91544157E+05 1.45985502E+04 4.66922514E+04 + 5.81803229E+05 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.82619071E+05 2.27577561E+03 + 9.24822270E+05 2.01619733E+04 6.01816484E+04 7.01803794E+05 0.00000000E+00 + 8.19971662E+05 6.06829342E+05 1.02595236E+03 6.47841731E+05 1.12780457E+04 + 3.69471530E+04 4.71003287E+05 0.00000000E+00 5.74393458E+05 3.79876399E+05 + 8.96776989E+04 1.07193646E+02 9.71708117E+04 1.41077189E+03 4.98586848E+03 + 6.82786631E+04 0.00000000E+00 8.61541883E+04 5.44261042E+04 7.51607703E+03 + 6.58473870E+04 6.63368273E+01 7.18621074E+04 9.55000044E+02 3.50301067E+03 + 4.96707306E+04 0.00000000E+00 6.37148278E+04 3.93690817E+04 5.34045360E+03 + 3.76169105E+03 7.91627154E+04 8.90987508E+01 8.59947003E+04 1.21014911E+03 + 4.33325458E+03 6.00750218E+04 0.00000000E+00 7.62451550E+04 4.77908183E+04 + 6.55825601E+03 4.64559155E+03 5.71629601E+03 7.42364908E+05 1.52094041E+03 + 7.85890042E+05 1.51483906E+04 4.75728872E+04 5.82511344E+05 0.00000000E+00 + 6.96790708E+05 4.72934643E+05 6.91773368E+04 5.05435913E+04 6.09592309E+04 + 5.81935564E+05 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 +%FLAG LENNARD_JONES_BCOEF +%FORMAT(5E16.8) + 8.01323529E+02 2.09604198E+01 9.37598976E-02 7.36907417E+02 2.06278363E+01 + 6.75612247E+02 6.45756063E+01 7.57919667E-01 6.13981767E+01 3.56012899E+00 + 1.13252061E+02 1.93248820E+00 1.06076943E+02 7.42992380E+00 1.43076527E+01 + 7.50714425E+02 1.79702257E+01 6.93079947E+02 5.79323581E+01 1.03606917E+02 + 6.99746810E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 6.53361429E+02 1.82891803E+01 + 5.99015525E+02 5.44372326E+01 9.40505980E+01 6.14502845E+02 0.00000000E+00 + 5.31102864E+02 6.77220874E+02 1.53505284E+01 6.26720080E+02 5.08951803E+01 + 9.21192136E+01 6.29300710E+02 0.00000000E+00 5.55666448E+02 5.64885984E+02 + 1.36131731E+02 2.59456373E+00 1.26919150E+02 9.41257003E+00 1.76949863E+01 + 1.25287818E+02 0.00000000E+00 1.12529845E+02 1.11805549E+02 2.17257828E+01 + 1.15327881E+02 2.01792524E+00 1.07908863E+02 7.65648470E+00 1.46638650E+01 + 1.05648788E+02 0.00000000E+00 9.56748258E+01 9.40124296E+01 1.81057616E+01 + 1.50233639E+01 1.26451907E+02 2.33864085E+00 1.18043746E+02 8.61880722E+00 + 1.63092814E+01 1.16187983E+02 0.00000000E+00 1.04660679E+02 1.03580945E+02 + 2.00642027E+01 1.66953734E+01 1.85196588E+01 6.90894667E+02 1.72393904E+01 + 6.36687196E+02 5.44062826E+01 9.64152120E+01 6.45512297E+02 0.00000000E+00 + 5.64503554E+02 5.81361517E+02 1.16264660E+02 9.82532117E+01 1.07902982E+02 + 5.94825035E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 +%FLAG BONDS_INC_HYDROGEN +%FORMAT(10I8) + 27 30 3 18 21 4 18 24 4 12 + 15 6 0 3 9 0 6 9 0 9 + 9 96 99 11 90 93 11 84 87 11 + 78 81 11 69 72 16 63 66 18 51 + 54 22 51 57 22 45 48 24 39 42 + 25 141 144 3 129 132 22 129 135 22 + 129 138 22 123 126 4 117 120 24 111 + 114 25 210 213 11 204 207 11 198 201 + 11 192 195 11 183 186 16 177 180 18 + 165 168 22 165 171 22 159 162 24 153 + 156 25 246 249 22 246 252 22 237 240 + 22 237 243 22 231 234 24 225 228 25 + 297 300 25 297 303 25 282 285 22 282 + 288 22 276 279 24 270 273 25 318 321 + 24 318 324 24 312 315 25 381 384 9 + 381 387 9 381 390 9 372 375 30 372 + 378 30 363 366 22 363 369 22 354 357 + 22 354 360 22 345 348 22 345 351 22 + 339 342 24 333 336 25 456 459 11 450 + 453 11 444 447 11 438 441 11 429 432 + 16 423 426 18 411 414 22 411 417 22 + 405 408 24 399 402 25 501 504 3 489 + 492 22 489 495 22 489 498 22 483 486 + 4 477 480 24 471 474 25 570 573 11 + 564 567 11 558 561 11 552 555 11 543 + 546 16 537 540 18 525 528 22 525 531 + 22 519 522 24 513 516 25 633 636 9 + 633 639 9 633 642 9 624 627 30 624 + 630 30 615 618 22 615 621 22 606 609 + 22 606 612 22 597 600 22 597 603 22 + 591 594 24 585 588 25 651 654 25 651 + 657 25 663 660 32 666 660 32 666 663 + 33 672 669 32 675 669 32 675 672 33 + 681 678 32 684 678 32 684 681 33 690 + 687 32 693 687 32 693 690 33 699 696 + 32 702 696 32 702 699 33 708 705 32 + 711 705 32 711 708 33 717 714 32 720 + 714 32 720 717 33 726 723 32 729 723 + 32 729 726 33 735 732 32 738 732 32 + 738 735 33 744 741 32 747 741 32 747 + 744 33 753 750 32 756 750 32 756 753 + 33 762 759 32 765 759 32 765 762 33 + 771 768 32 774 768 32 774 771 33 780 + 777 32 783 777 32 783 780 33 789 786 + 32 792 786 32 792 789 33 798 795 32 + 801 795 32 801 798 33 807 804 32 810 + 804 32 810 807 33 816 813 32 819 813 + 32 819 816 33 825 822 32 828 822 32 + 828 825 33 834 831 32 837 831 32 837 + 834 33 843 840 32 846 840 32 846 843 + 33 852 849 32 855 849 32 855 852 33 + 861 858 32 864 858 32 864 861 33 870 + 867 32 873 867 32 873 870 33 879 876 + 32 882 876 32 882 879 33 888 885 32 + 891 885 32 891 888 33 897 894 32 900 + 894 32 900 897 33 906 903 32 909 903 + 32 909 906 33 915 912 32 918 912 32 + 918 915 33 924 921 32 927 921 32 927 + 924 33 933 930 32 936 930 32 936 933 + 33 942 939 32 945 939 32 945 942 33 + 951 948 32 954 948 32 954 951 33 960 + 957 32 963 957 32 963 960 33 969 966 + 32 972 966 32 972 969 33 978 975 32 + 981 975 32 981 978 33 987 984 32 990 + 984 32 990 987 33 996 993 32 999 993 + 32 999 996 33 1005 1002 32 1008 1002 32 + 1008 1005 33 1014 1011 32 1017 1011 32 1017 + 1014 33 1023 1020 32 1026 1020 32 1026 1023 + 33 1032 1029 32 1035 1029 32 1035 1032 33 + 1041 1038 32 1044 1038 32 1044 1041 33 1050 + 1047 32 1053 1047 32 1053 1050 33 1059 1056 + 32 1062 1056 32 1062 1059 33 1068 1065 32 + 1071 1065 32 1071 1068 33 1077 1074 32 1080 + 1074 32 1080 1077 33 1086 1083 32 1089 1083 + 32 1089 1086 33 1095 1092 32 1098 1092 32 + 1098 1095 33 1104 1101 32 1107 1101 32 1107 + 1104 33 1113 1110 32 1116 1110 32 1116 1113 + 33 1122 1119 32 1125 1119 32 1125 1122 33 + 1131 1128 32 1134 1128 32 1134 1131 33 1140 + 1137 32 1143 1137 32 1143 1140 33 1149 1146 + 32 1152 1146 32 1152 1149 33 1158 1155 32 + 1161 1155 32 1161 1158 33 1167 1164 32 1170 + 1164 32 1170 1167 33 1176 1173 32 1179 1173 + 32 1179 1176 33 1185 1182 32 1188 1182 32 + 1188 1185 33 1194 1191 32 1197 1191 32 1197 + 1194 33 1203 1200 32 1206 1200 32 1206 1203 + 33 1212 1209 32 1215 1209 32 1215 1212 33 + 1221 1218 32 1224 1218 32 1224 1221 33 1230 + 1227 32 1233 1227 32 1233 1230 33 1239 1236 + 32 1242 1236 32 1242 1239 33 1248 1245 32 + 1251 1245 32 1251 1248 33 1257 1254 32 1260 + 1254 32 1260 1257 33 1266 1263 32 1269 1263 + 32 1269 1266 33 1275 1272 32 1278 1272 32 + 1278 1275 33 1284 1281 32 1287 1281 32 1287 + 1284 33 1293 1290 32 1296 1290 32 1296 1293 + 33 1302 1299 32 1305 1299 32 1305 1302 33 + 1311 1308 32 1314 1308 32 1314 1311 33 1320 + 1317 32 1323 1317 32 1323 1320 33 1329 1326 + 32 1332 1326 32 1332 1329 33 1338 1335 32 + 1341 1335 32 1341 1338 33 1347 1344 32 1350 + 1344 32 1350 1347 33 1356 1353 32 1359 1353 + 32 1359 1356 33 1365 1362 32 1368 1362 32 + 1368 1365 33 1374 1371 32 1377 1371 32 1377 + 1374 33 1383 1380 32 1386 1380 32 1386 1383 + 33 1392 1389 32 1395 1389 32 1395 1392 33 + 1401 1398 32 1404 1398 32 1404 1401 33 1410 + 1407 32 1413 1407 32 1413 1410 33 1419 1416 + 32 1422 1416 32 1422 1419 33 1428 1425 32 + 1431 1425 32 1431 1428 33 1437 1434 32 1440 + 1434 32 1440 1437 33 1446 1443 32 1449 1443 + 32 1449 1446 33 1455 1452 32 1458 1452 32 + 1458 1455 33 1464 1461 32 1467 1461 32 1467 + 1464 33 1473 1470 32 1476 1470 32 1476 1473 + 33 1482 1479 32 1485 1479 32 1485 1482 33 + 1491 1488 32 1494 1488 32 1494 1491 33 1500 + 1497 32 1503 1497 32 1503 1500 33 1509 1506 + 32 1512 1506 32 1512 1509 33 1518 1515 32 + 1521 1515 32 1521 1518 33 1527 1524 32 1530 + 1524 32 1530 1527 33 1536 1533 32 1539 1533 + 32 1539 1536 33 1545 1542 32 1548 1542 32 + 1548 1545 33 1554 1551 32 1557 1551 32 1557 + 1554 33 1563 1560 32 1566 1560 32 1566 1563 + 33 1572 1569 32 1575 1569 32 1575 1572 33 + 1581 1578 32 1584 1578 32 1584 1581 33 1590 + 1587 32 1593 1587 32 1593 1590 33 1599 1596 + 32 1602 1596 32 1602 1599 33 1608 1605 32 + 1611 1605 32 1611 1608 33 1617 1614 32 1620 + 1614 32 1620 1617 33 1626 1623 32 1629 1623 + 32 1629 1626 33 1635 1632 32 1638 1632 32 + 1638 1635 33 1644 1641 32 1647 1641 32 1647 + 1644 33 1653 1650 32 1656 1650 32 1656 1653 + 33 1662 1659 32 1665 1659 32 1665 1662 33 + 1671 1668 32 1674 1668 32 1674 1671 33 1680 + 1677 32 1683 1677 32 1683 1680 33 1689 1686 + 32 1692 1686 32 1692 1689 33 1698 1695 32 + 1701 1695 32 1701 1698 33 1707 1704 32 1710 + 1704 32 1710 1707 33 1716 1713 32 1719 1713 + 32 1719 1716 33 1725 1722 32 1728 1722 32 + 1728 1725 33 1734 1731 32 1737 1731 32 1737 + 1734 33 1743 1740 32 1746 1740 32 1746 1743 + 33 1752 1749 32 1755 1749 32 1755 1752 33 + 1761 1758 32 1764 1758 32 1764 1761 33 1770 + 1767 32 1773 1767 32 1773 1770 33 1779 1776 + 32 1782 1776 32 1782 1779 33 1788 1785 32 + 1791 1785 32 1791 1788 33 1797 1794 32 1800 + 1794 32 1800 1797 33 1806 1803 32 1809 1803 + 32 1809 1806 33 1815 1812 32 1818 1812 32 + 1818 1815 33 1824 1821 32 1827 1821 32 1827 + 1824 33 1833 1830 32 1836 1830 32 1836 1833 + 33 1842 1839 32 1845 1839 32 1845 1842 33 + 1851 1848 32 1854 1848 32 1854 1851 33 1860 + 1857 32 1863 1857 32 1863 1860 33 1869 1866 + 32 1872 1866 32 1872 1869 33 1878 1875 32 + 1881 1875 32 1881 1878 33 1887 1884 32 1890 + 1884 32 1890 1887 33 1896 1893 32 1899 1893 + 32 1899 1896 33 1905 1902 32 1908 1902 32 + 1908 1905 33 1914 1911 32 1917 1911 32 1917 + 1914 33 1923 1920 32 1926 1920 32 1926 1923 + 33 1932 1929 32 1935 1929 32 1935 1932 33 + 1941 1938 32 1944 1938 32 1944 1941 33 1950 + 1947 32 1953 1947 32 1953 1950 33 1959 1956 + 32 1962 1956 32 1962 1959 33 1968 1965 32 + 1971 1965 32 1971 1968 33 1977 1974 32 1980 + 1974 32 1980 1977 33 1986 1983 32 1989 1983 + 32 1989 1986 33 1995 1992 32 1998 1992 32 + 1998 1995 33 2004 2001 32 2007 2001 32 2007 + 2004 33 2013 2010 32 2016 2010 32 2016 2013 + 33 2022 2019 32 2025 2019 32 2025 2022 33 + 2031 2028 32 2034 2028 32 2034 2031 33 2040 + 2037 32 2043 2037 32 2043 2040 33 2049 2046 + 32 2052 2046 32 2052 2049 33 2058 2055 32 + 2061 2055 32 2061 2058 33 2067 2064 32 2070 + 2064 32 2070 2067 33 2076 2073 32 2079 2073 + 32 2079 2076 33 2085 2082 32 2088 2082 32 + 2088 2085 33 2094 2091 32 2097 2091 32 2097 + 2094 33 2103 2100 32 2106 2100 32 2106 2103 + 33 2112 2109 32 2115 2109 32 2115 2112 33 + 2121 2118 32 2124 2118 32 2124 2121 33 2130 + 2127 32 2133 2127 32 2133 2130 33 2139 2136 + 32 2142 2136 32 2142 2139 33 2148 2145 32 + 2151 2145 32 2151 2148 33 2157 2154 32 2160 + 2154 32 2160 2157 33 2166 2163 32 2169 2163 + 32 2169 2166 33 2175 2172 32 2178 2172 32 + 2178 2175 33 2184 2181 32 2187 2181 32 2187 + 2184 33 2193 2190 32 2196 2190 32 2196 2193 + 33 2202 2199 32 2205 2199 32 2205 2202 33 + 2211 2208 32 2214 2208 32 2214 2211 33 2220 + 2217 32 2223 2217 32 2223 2220 33 2229 2226 + 32 2232 2226 32 2232 2229 33 2238 2235 32 + 2241 2235 32 2241 2238 33 2247 2244 32 2250 + 2244 32 2250 2247 33 2256 2253 32 2259 2253 + 32 2259 2256 33 2265 2262 32 2268 2262 32 + 2268 2265 33 2274 2271 32 2277 2271 32 2277 + 2274 33 2283 2280 32 2286 2280 32 2286 2283 + 33 2292 2289 32 2295 2289 32 2295 2292 33 + 2301 2298 32 2304 2298 32 2304 2301 33 2310 + 2307 32 2313 2307 32 2313 2310 33 2319 2316 + 32 2322 2316 32 2322 2319 33 2328 2325 32 + 2331 2325 32 2331 2328 33 2337 2334 32 2340 + 2334 32 2340 2337 33 2346 2343 32 2349 2343 + 32 2349 2346 33 2355 2352 32 2358 2352 32 + 2358 2355 33 2364 2361 32 2367 2361 32 2367 + 2364 33 2373 2370 32 2376 2370 32 2376 2373 + 33 2382 2379 32 2385 2379 32 2385 2382 33 + 2391 2388 32 2394 2388 32 2394 2391 33 2400 + 2397 32 2403 2397 32 2403 2400 33 2409 2406 + 32 2412 2406 32 2412 2409 33 2418 2415 32 + 2421 2415 32 2421 2418 33 2427 2424 32 2430 + 2424 32 2430 2427 33 2436 2433 32 2439 2433 + 32 2439 2436 33 2445 2442 32 2448 2442 32 + 2448 2445 33 2454 2451 32 2457 2451 32 2457 + 2454 33 2463 2460 32 2466 2460 32 2466 2463 + 33 2472 2469 32 2475 2469 32 2475 2472 33 + 2481 2478 32 2484 2478 32 2484 2481 33 2490 + 2487 32 2493 2487 32 2493 2490 33 2499 2496 + 32 2502 2496 32 2502 2499 33 2508 2505 32 + 2511 2505 32 2511 2508 33 2517 2514 32 2520 + 2514 32 2520 2517 33 2526 2523 32 2529 2523 + 32 2529 2526 33 2535 2532 32 2538 2532 32 + 2538 2535 33 2544 2541 32 2547 2541 32 2547 + 2544 33 2553 2550 32 2556 2550 32 2556 2553 + 33 2562 2559 32 2565 2559 32 2565 2562 33 + 2571 2568 32 2574 2568 32 2574 2571 33 2580 + 2577 32 2583 2577 32 2583 2580 33 2589 2586 + 32 2592 2586 32 2592 2589 33 2598 2595 32 + 2601 2595 32 2601 2598 33 2607 2604 32 2610 + 2604 32 2610 2607 33 2616 2613 32 2619 2613 + 32 2619 2616 33 2625 2622 32 2628 2622 32 + 2628 2625 33 2634 2631 32 2637 2631 32 2637 + 2634 33 2643 2640 32 2646 2640 32 2646 2643 + 33 2652 2649 32 2655 2649 32 2655 2652 33 + 2661 2658 32 2664 2658 32 2664 2661 33 2670 + 2667 32 2673 2667 32 2673 2670 33 2679 2676 + 32 2682 2676 32 2682 2679 33 2688 2685 32 + 2691 2685 32 2691 2688 33 2697 2694 32 2700 + 2694 32 2700 2697 33 2706 2703 32 2709 2703 + 32 2709 2706 33 2715 2712 32 2718 2712 32 + 2718 2715 33 2724 2721 32 2727 2721 32 2727 + 2724 33 2733 2730 32 2736 2730 32 2736 2733 + 33 2742 2739 32 2745 2739 32 2745 2742 33 + 2751 2748 32 2754 2748 32 2754 2751 33 2760 + 2757 32 2763 2757 32 2763 2760 33 2769 2766 + 32 2772 2766 32 2772 2769 33 2778 2775 32 + 2781 2775 32 2781 2778 33 2787 2784 32 2790 + 2784 32 2790 2787 33 2796 2793 32 2799 2793 + 32 2799 2796 33 2805 2802 32 2808 2802 32 + 2808 2805 33 2814 2811 32 2817 2811 32 2817 + 2814 33 2823 2820 32 2826 2820 32 2826 2823 + 33 2832 2829 32 2835 2829 32 2835 2832 33 + 2841 2838 32 2844 2838 32 2844 2841 33 2850 + 2847 32 2853 2847 32 2853 2850 33 2859 2856 + 32 2862 2856 32 2862 2859 33 2868 2865 32 + 2871 2865 32 2871 2868 33 2877 2874 32 2880 + 2874 32 2880 2877 33 2886 2883 32 2889 2883 + 32 2889 2886 33 2895 2892 32 2898 2892 32 + 2898 2895 33 2904 2901 32 2907 2901 32 2907 + 2904 33 2913 2910 32 2916 2910 32 2916 2913 + 33 2922 2919 32 2925 2919 32 2925 2922 33 + 2931 2928 32 2934 2928 32 2934 2931 33 2940 + 2937 32 2943 2937 32 2943 2940 33 2949 2946 + 32 2952 2946 32 2952 2949 33 2958 2955 32 + 2961 2955 32 2961 2958 33 2967 2964 32 2970 + 2964 32 2970 2967 33 2976 2973 32 2979 2973 + 32 2979 2976 33 2985 2982 32 2988 2982 32 + 2988 2985 33 2994 2991 32 2997 2991 32 2997 + 2994 33 3003 3000 32 3006 3000 32 3006 3003 + 33 3012 3009 32 3015 3009 32 3015 3012 33 + 3021 3018 32 3024 3018 32 3024 3021 33 3030 + 3027 32 3033 3027 32 3033 3030 33 3039 3036 + 32 3042 3036 32 3042 3039 33 3048 3045 32 + 3051 3045 32 3051 3048 33 3057 3054 32 3060 + 3054 32 3060 3057 33 3066 3063 32 3069 3063 + 32 3069 3066 33 3075 3072 32 3078 3072 32 + 3078 3075 33 3084 3081 32 3087 3081 32 3087 + 3084 33 3093 3090 32 3096 3090 32 3096 3093 + 33 3102 3099 32 3105 3099 32 3105 3102 33 + 3111 3108 32 3114 3108 32 3114 3111 33 3120 + 3117 32 3123 3117 32 3123 3120 33 3129 3126 + 32 3132 3126 32 3132 3129 33 3138 3135 32 + 3141 3135 32 3141 3138 33 3147 3144 32 3150 + 3144 32 3150 3147 33 3156 3153 32 3159 3153 + 32 3159 3156 33 3165 3162 32 3168 3162 32 + 3168 3165 33 3174 3171 32 3177 3171 32 3177 + 3174 33 3183 3180 32 3186 3180 32 3186 3183 + 33 3192 3189 32 3195 3189 32 3195 3192 33 + 3201 3198 32 3204 3198 32 3204 3201 33 3210 + 3207 32 3213 3207 32 3213 3210 33 3219 3216 + 32 3222 3216 32 3222 3219 33 3228 3225 32 + 3231 3225 32 3231 3228 33 3237 3234 32 3240 + 3234 32 3240 3237 33 3246 3243 32 3249 3243 + 32 3249 3246 33 3255 3252 32 3258 3252 32 + 3258 3255 33 3264 3261 32 3267 3261 32 3267 + 3264 33 3273 3270 32 3276 3270 32 3276 3273 + 33 3282 3279 32 3285 3279 32 3285 3282 33 + 3291 3288 32 3294 3288 32 3294 3291 33 3300 + 3297 32 3303 3297 32 3303 3300 33 3309 3306 + 32 3312 3306 32 3312 3309 33 3318 3315 32 + 3321 3315 32 3321 3318 33 3327 3324 32 3330 + 3324 32 3330 3327 33 3336 3333 32 3339 3333 + 32 3339 3336 33 3345 3342 32 3348 3342 32 + 3348 3345 33 3354 3351 32 3357 3351 32 3357 + 3354 33 3363 3360 32 3366 3360 32 3366 3363 + 33 3372 3369 32 3375 3369 32 3375 3372 33 + 3381 3378 32 3384 3378 32 3384 3381 33 3390 + 3387 32 3393 3387 32 3393 3390 33 3399 3396 + 32 3402 3396 32 3402 3399 33 3408 3405 32 + 3411 3405 32 3411 3408 33 3417 3414 32 3420 + 3414 32 3420 3417 33 3426 3423 32 3429 3423 + 32 3429 3426 33 3435 3432 32 3438 3432 32 + 3438 3435 33 3444 3441 32 3447 3441 32 3447 + 3444 33 3453 3450 32 3456 3450 32 3456 3453 + 33 3462 3459 32 3465 3459 32 3465 3462 33 + 3471 3468 32 3474 3468 32 3474 3471 33 3480 + 3477 32 3483 3477 32 3483 3480 33 3489 3486 + 32 3492 3486 32 3492 3489 33 3498 3495 32 + 3501 3495 32 3501 3498 33 3507 3504 32 3510 + 3504 32 3510 3507 33 3516 3513 32 3519 3513 + 32 3519 3516 33 3525 3522 32 3528 3522 32 + 3528 3525 33 3534 3531 32 3537 3531 32 3537 + 3534 33 3543 3540 32 3546 3540 32 3546 3543 + 33 3552 3549 32 3555 3549 32 3555 3552 33 + 3561 3558 32 3564 3558 32 3564 3561 33 3570 + 3567 32 3573 3567 32 3573 3570 33 3579 3576 + 32 3582 3576 32 3582 3579 33 3588 3585 32 + 3591 3585 32 3591 3588 33 3597 3594 32 3600 + 3594 32 3600 3597 33 3606 3603 32 3609 3603 + 32 3609 3606 33 3615 3612 32 3618 3612 32 + 3618 3615 33 3624 3621 32 3627 3621 32 3627 + 3624 33 3633 3630 32 3636 3630 32 3636 3633 + 33 3642 3639 32 3645 3639 32 3645 3642 33 + 3651 3648 32 3654 3648 32 3654 3651 33 3660 + 3657 32 3663 3657 32 3663 3660 33 3669 3666 + 32 3672 3666 32 3672 3669 33 3678 3675 32 + 3681 3675 32 3681 3678 33 3687 3684 32 3690 + 3684 32 3690 3687 33 3696 3693 32 3699 3693 + 32 3699 3696 33 3705 3702 32 3708 3702 32 + 3708 3705 33 3714 3711 32 3717 3711 32 3717 + 3714 33 3723 3720 32 3726 3720 32 3726 3723 + 33 3732 3729 32 3735 3729 32 3735 3732 33 + 3741 3738 32 3744 3738 32 3744 3741 33 3750 + 3747 32 3753 3747 32 3753 3750 33 3759 3756 + 32 3762 3756 32 3762 3759 33 3768 3765 32 + 3771 3765 32 3771 3768 33 3777 3774 32 3780 + 3774 32 3780 3777 33 3786 3783 32 3789 3783 + 32 3789 3786 33 3795 3792 32 3798 3792 32 + 3798 3795 33 3804 3801 32 3807 3801 32 3807 + 3804 33 3813 3810 32 3816 3810 32 3816 3813 + 33 3822 3819 32 3825 3819 32 3825 3822 33 + 3831 3828 32 3834 3828 32 3834 3831 33 3840 + 3837 32 3843 3837 32 3843 3840 33 3849 3846 + 32 3852 3846 32 3852 3849 33 3858 3855 32 + 3861 3855 32 3861 3858 33 3867 3864 32 3870 + 3864 32 3870 3867 33 3876 3873 32 3879 3873 + 32 3879 3876 33 3885 3882 32 3888 3882 32 + 3888 3885 33 3894 3891 32 3897 3891 32 3897 + 3894 33 3903 3900 32 3906 3900 32 3906 3903 + 33 3912 3909 32 3915 3909 32 3915 3912 33 + 3921 3918 32 3924 3918 32 3924 3921 33 3930 + 3927 32 3933 3927 32 3933 3930 33 3939 3936 + 32 3942 3936 32 3942 3939 33 3948 3945 32 + 3951 3945 32 3951 3948 33 3957 3954 32 3960 + 3954 32 3960 3957 33 3966 3963 32 3969 3963 + 32 3969 3966 33 3975 3972 32 3978 3972 32 + 3978 3975 33 3984 3981 32 3987 3981 32 3987 + 3984 33 3993 3990 32 3996 3990 32 3996 3993 + 33 4002 3999 32 4005 3999 32 4005 4002 33 + 4011 4008 32 4014 4008 32 4014 4011 33 4020 + 4017 32 4023 4017 32 4023 4020 33 4029 4026 + 32 4032 4026 32 4032 4029 33 4038 4035 32 + 4041 4035 32 4041 4038 33 4047 4044 32 4050 + 4044 32 4050 4047 33 4056 4053 32 4059 4053 + 32 4059 4056 33 4065 4062 32 4068 4062 32 + 4068 4065 33 4074 4071 32 4077 4071 32 4077 + 4074 33 4083 4080 32 4086 4080 32 4086 4083 + 33 4092 4089 32 4095 4089 32 4095 4092 33 + 4101 4098 32 4104 4098 32 4104 4101 33 4110 + 4107 32 4113 4107 32 4113 4110 33 4119 4116 + 32 4122 4116 32 4122 4119 33 4128 4125 32 + 4131 4125 32 4131 4128 33 4137 4134 32 4140 + 4134 32 4140 4137 33 4146 4143 32 4149 4143 + 32 4149 4146 33 4155 4152 32 4158 4152 32 + 4158 4155 33 4164 4161 32 4167 4161 32 4167 + 4164 33 4173 4170 32 4176 4170 32 4176 4173 + 33 4182 4179 32 4185 4179 32 4185 4182 33 + 4191 4188 32 4194 4188 32 4194 4191 33 4200 + 4197 32 4203 4197 32 4203 4200 33 4209 4206 + 32 4212 4206 32 4212 4209 33 4218 4215 32 + 4221 4215 32 4221 4218 33 4227 4224 32 4230 + 4224 32 4230 4227 33 4236 4233 32 4239 4233 + 32 4239 4236 33 4245 4242 32 4248 4242 32 + 4248 4245 33 4254 4251 32 4257 4251 32 4257 + 4254 33 4263 4260 32 4266 4260 32 4266 4263 + 33 4272 4269 32 4275 4269 32 4275 4272 33 + 4281 4278 32 4284 4278 32 4284 4281 33 4290 + 4287 32 4293 4287 32 4293 4290 33 4299 4296 + 32 4302 4296 32 4302 4299 33 4308 4305 32 + 4311 4305 32 4311 4308 33 4317 4314 32 4320 + 4314 32 4320 4317 33 4326 4323 32 4329 4323 + 32 4329 4326 33 4335 4332 32 4338 4332 32 + 4338 4335 33 4344 4341 32 4347 4341 32 4347 + 4344 33 4353 4350 32 4356 4350 32 4356 4353 + 33 4362 4359 32 4365 4359 32 4365 4362 33 + 4371 4368 32 4374 4368 32 4374 4371 33 4380 + 4377 32 4383 4377 32 4383 4380 33 4389 4386 + 32 4392 4386 32 4392 4389 33 4398 4395 32 + 4401 4395 32 4401 4398 33 4407 4404 32 4410 + 4404 32 4410 4407 33 4416 4413 32 4419 4413 + 32 4419 4416 33 4425 4422 32 4428 4422 32 + 4428 4425 33 4434 4431 32 4437 4431 32 4437 + 4434 33 4443 4440 32 4446 4440 32 4446 4443 + 33 4452 4449 32 4455 4449 32 4455 4452 33 + 4461 4458 32 4464 4458 32 4464 4461 33 4470 + 4467 32 4473 4467 32 4473 4470 33 4479 4476 + 32 4482 4476 32 4482 4479 33 4488 4485 32 + 4491 4485 32 4491 4488 33 4497 4494 32 4500 + 4494 32 4500 4497 33 4506 4503 32 4509 4503 + 32 4509 4506 33 4515 4512 32 4518 4512 32 + 4518 4515 33 4524 4521 32 4527 4521 32 4527 + 4524 33 4533 4530 32 4536 4530 32 4536 4533 + 33 4542 4539 32 4545 4539 32 4545 4542 33 + 4551 4548 32 4554 4548 32 4554 4551 33 4560 + 4557 32 4563 4557 32 4563 4560 33 4569 4566 + 32 4572 4566 32 4572 4569 33 4578 4575 32 + 4581 4575 32 4581 4578 33 4587 4584 32 4590 + 4584 32 4590 4587 33 4596 4593 32 4599 4593 + 32 4599 4596 33 4605 4602 32 4608 4602 32 + 4608 4605 33 4614 4611 32 4617 4611 32 4617 + 4614 33 4623 4620 32 4626 4620 32 4626 4623 + 33 4632 4629 32 4635 4629 32 4635 4632 33 + 4641 4638 32 4644 4638 32 4644 4641 33 4650 + 4647 32 4653 4647 32 4653 4650 33 4659 4656 + 32 4662 4656 32 4662 4659 33 4668 4665 32 + 4671 4665 32 4671 4668 33 4677 4674 32 4680 + 4674 32 4680 4677 33 4686 4683 32 4689 4683 + 32 4689 4686 33 4695 4692 32 4698 4692 32 + 4698 4695 33 4704 4701 32 4707 4701 32 4707 + 4704 33 4713 4710 32 4716 4710 32 4716 4713 + 33 4722 4719 32 4725 4719 32 4725 4722 33 + 4731 4728 32 4734 4728 32 4734 4731 33 4740 + 4737 32 4743 4737 32 4743 4740 33 4749 4746 + 32 4752 4746 32 4752 4749 33 4758 4755 32 + 4761 4755 32 4761 4758 33 4767 4764 32 4770 + 4764 32 4770 4767 33 4776 4773 32 4779 4773 + 32 4779 4776 33 4785 4782 32 4788 4782 32 + 4788 4785 33 4794 4791 32 4797 4791 32 4797 + 4794 33 4803 4800 32 4806 4800 32 4806 4803 + 33 4812 4809 32 4815 4809 32 4815 4812 33 + 4821 4818 32 4824 4818 32 4824 4821 33 4830 + 4827 32 4833 4827 32 4833 4830 33 4839 4836 + 32 4842 4836 32 4842 4839 33 4848 4845 32 + 4851 4845 32 4851 4848 33 4857 4854 32 4860 + 4854 32 4860 4857 33 4866 4863 32 4869 4863 + 32 4869 4866 33 4875 4872 32 4878 4872 32 + 4878 4875 33 4884 4881 32 4887 4881 32 4887 + 4884 33 4893 4890 32 4896 4890 32 4896 4893 + 33 4902 4899 32 4905 4899 32 4905 4902 33 + 4911 4908 32 4914 4908 32 4914 4911 33 4920 + 4917 32 4923 4917 32 4923 4920 33 4929 4926 + 32 4932 4926 32 4932 4929 33 4938 4935 32 + 4941 4935 32 4941 4938 33 4947 4944 32 4950 + 4944 32 4950 4947 33 4956 4953 32 4959 4953 + 32 4959 4956 33 4965 4962 32 4968 4962 32 + 4968 4965 33 4974 4971 32 4977 4971 32 4977 + 4974 33 4983 4980 32 4986 4980 32 4986 4983 + 33 4992 4989 32 4995 4989 32 4995 4992 33 + 5001 4998 32 5004 4998 32 5004 5001 33 5010 + 5007 32 5013 5007 32 5013 5010 33 5019 5016 + 32 5022 5016 32 5022 5019 33 5028 5025 32 + 5031 5025 32 5031 5028 33 5037 5034 32 5040 + 5034 32 5040 5037 33 5046 5043 32 5049 5043 + 32 5049 5046 33 5055 5052 32 5058 5052 32 + 5058 5055 33 5064 5061 32 5067 5061 32 5067 + 5064 33 5073 5070 32 5076 5070 32 5076 5073 + 33 5082 5079 32 5085 5079 32 5085 5082 33 + 5091 5088 32 5094 5088 32 5094 5091 33 5100 + 5097 32 5103 5097 32 5103 5100 33 5109 5106 + 32 5112 5106 32 5112 5109 33 5118 5115 32 + 5121 5115 32 5121 5118 33 5127 5124 32 5130 + 5124 32 5130 5127 33 5136 5133 32 5139 5133 + 32 5139 5136 33 5145 5142 32 5148 5142 32 + 5148 5145 33 5154 5151 32 5157 5151 32 5157 + 5154 33 5163 5160 32 5166 5160 32 5166 5163 + 33 5172 5169 32 5175 5169 32 5175 5172 33 + 5181 5178 32 5184 5178 32 5184 5181 33 5190 + 5187 32 5193 5187 32 5193 5190 33 5199 5196 + 32 5202 5196 32 5202 5199 33 5208 5205 32 + 5211 5205 32 5211 5208 33 5217 5214 32 5220 + 5214 32 5220 5217 33 5226 5223 32 5229 5223 + 32 5229 5226 33 5235 5232 32 5238 5232 32 + 5238 5235 33 5244 5241 32 5247 5241 32 5247 + 5244 33 5253 5250 32 5256 5250 32 5256 5253 + 33 5262 5259 32 5265 5259 32 5265 5262 33 + 5271 5268 32 5274 5268 32 5274 5271 33 5280 + 5277 32 5283 5277 32 5283 5280 33 5289 5286 + 32 5292 5286 32 5292 5289 33 5298 5295 32 + 5301 5295 32 5301 5298 33 5307 5304 32 5310 + 5304 32 5310 5307 33 5316 5313 32 5319 5313 + 32 5319 5316 33 5325 5322 32 5328 5322 32 + 5328 5325 33 5334 5331 32 5337 5331 32 5337 + 5334 33 5343 5340 32 5346 5340 32 5346 5343 + 33 5352 5349 32 5355 5349 32 5355 5352 33 + 5361 5358 32 5364 5358 32 5364 5361 33 5370 + 5367 32 5373 5367 32 5373 5370 33 5379 5376 + 32 5382 5376 32 5382 5379 33 5388 5385 32 + 5391 5385 32 5391 5388 33 5397 5394 32 5400 + 5394 32 5400 5397 33 5406 5403 32 5409 5403 + 32 5409 5406 33 5415 5412 32 5418 5412 32 + 5418 5415 33 5424 5421 32 5427 5421 32 5427 + 5424 33 5433 5430 32 5436 5430 32 5436 5433 + 33 5442 5439 32 5445 5439 32 5445 5442 33 + 5451 5448 32 5454 5448 32 5454 5451 33 5460 + 5457 32 5463 5457 32 5463 5460 33 5469 5466 + 32 5472 5466 32 5472 5469 33 5478 5475 32 + 5481 5475 32 5481 5478 33 5487 5484 32 5490 + 5484 32 5490 5487 33 5496 5493 32 5499 5493 + 32 5499 5496 33 5505 5502 32 5508 5502 32 + 5508 5505 33 5514 5511 32 5517 5511 32 5517 + 5514 33 5523 5520 32 5526 5520 32 5526 5523 + 33 5532 5529 32 5535 5529 32 5535 5532 33 + 5541 5538 32 5544 5538 32 5544 5541 33 5550 + 5547 32 5553 5547 32 5553 5550 33 5559 5556 + 32 5562 5556 32 5562 5559 33 5568 5565 32 + 5571 5565 32 5571 5568 33 5577 5574 32 5580 + 5574 32 5580 5577 33 5586 5583 32 5589 5583 + 32 5589 5586 33 5595 5592 32 5598 5592 32 + 5598 5595 33 5604 5601 32 5607 5601 32 5607 + 5604 33 5613 5610 32 5616 5610 32 5616 5613 + 33 5622 5619 32 5625 5619 32 5625 5622 33 + 5631 5628 32 5634 5628 32 5634 5631 33 5640 + 5637 32 5643 5637 32 5643 5640 33 5649 5646 + 32 5652 5646 32 5652 5649 33 5658 5655 32 + 5661 5655 32 5661 5658 33 5667 5664 32 5670 + 5664 32 5670 5667 33 5676 5673 32 5679 5673 + 32 5679 5676 33 5685 5682 32 5688 5682 32 + 5688 5685 33 5694 5691 32 5697 5691 32 5697 + 5694 33 5703 5700 32 5706 5700 32 5706 5703 + 33 5712 5709 32 5715 5709 32 5715 5712 33 + 5721 5718 32 5724 5718 32 5724 5721 33 5730 + 5727 32 5733 5727 32 5733 5730 33 5739 5736 + 32 5742 5736 32 5742 5739 33 5748 5745 32 + 5751 5745 32 5751 5748 33 5757 5754 32 5760 + 5754 32 5760 5757 33 5766 5763 32 5769 5763 + 32 5769 5766 33 5775 5772 32 5778 5772 32 + 5778 5775 33 5784 5781 32 5787 5781 32 5787 + 5784 33 5793 5790 32 5796 5790 32 5796 5793 + 33 5802 5799 32 5805 5799 32 5805 5802 33 + 5811 5808 32 5814 5808 32 5814 5811 33 5820 + 5817 32 5823 5817 32 5823 5820 33 5829 5826 + 32 5832 5826 32 5832 5829 33 5838 5835 32 + 5841 5835 32 5841 5838 33 5847 5844 32 5850 + 5844 32 5850 5847 33 5856 5853 32 5859 5853 + 32 5859 5856 33 5865 5862 32 5868 5862 32 + 5868 5865 33 5874 5871 32 5877 5871 32 5877 + 5874 33 5883 5880 32 5886 5880 32 5886 5883 + 33 5892 5889 32 5895 5889 32 5895 5892 33 + 5901 5898 32 5904 5898 32 5904 5901 33 5910 + 5907 32 5913 5907 32 5913 5910 33 5919 5916 + 32 5922 5916 32 5922 5919 33 5928 5925 32 + 5931 5925 32 5931 5928 33 5937 5934 32 5940 + 5934 32 5940 5937 33 5946 5943 32 5949 5943 + 32 5949 5946 33 5955 5952 32 5958 5952 32 + 5958 5955 33 5964 5961 32 5967 5961 32 5967 + 5964 33 5973 5970 32 5976 5970 32 5976 5973 + 33 5982 5979 32 5985 5979 32 5985 5982 33 + 5991 5988 32 5994 5988 32 5994 5991 33 6000 + 5997 32 6003 5997 32 6003 6000 33 6009 6006 + 32 6012 6006 32 6012 6009 33 6018 6015 32 + 6021 6015 32 6021 6018 33 6027 6024 32 6030 + 6024 32 6030 6027 33 6036 6033 32 6039 6033 + 32 6039 6036 33 6045 6042 32 6048 6042 32 + 6048 6045 33 6054 6051 32 6057 6051 32 6057 + 6054 33 6063 6060 32 6066 6060 32 6066 6063 + 33 6072 6069 32 6075 6069 32 6075 6072 33 + 6081 6078 32 6084 6078 32 6084 6081 33 6090 + 6087 32 6093 6087 32 6093 6090 33 6099 6096 + 32 6102 6096 32 6102 6099 33 6108 6105 32 + 6111 6105 32 6111 6108 33 6117 6114 32 6120 + 6114 32 6120 6117 33 6126 6123 32 6129 6123 + 32 6129 6126 33 6135 6132 32 6138 6132 32 + 6138 6135 33 6144 6141 32 6147 6141 32 6147 + 6144 33 6153 6150 32 6156 6150 32 6156 6153 + 33 6162 6159 32 6165 6159 32 6165 6162 33 + 6171 6168 32 6174 6168 32 6174 6171 33 6180 + 6177 32 6183 6177 32 6183 6180 33 6189 6186 + 32 6192 6186 32 6192 6189 33 6198 6195 32 + 6201 6195 32 6201 6198 33 6207 6204 32 6210 + 6204 32 6210 6207 33 6216 6213 32 6219 6213 + 32 6219 6216 33 6225 6222 32 6228 6222 32 + 6228 6225 33 6234 6231 32 6237 6231 32 6237 + 6234 33 6243 6240 32 6246 6240 32 6246 6243 + 33 6252 6249 32 6255 6249 32 6255 6252 33 + 6261 6258 32 6264 6258 32 6264 6261 33 6270 + 6267 32 6273 6267 32 6273 6270 33 6279 6276 + 32 6282 6276 32 6282 6279 33 6288 6285 32 + 6291 6285 32 6291 6288 33 6297 6294 32 6300 + 6294 32 6300 6297 33 6306 6303 32 6309 6303 + 32 6309 6306 33 6315 6312 32 6318 6312 32 + 6318 6315 33 6324 6321 32 6327 6321 32 6327 + 6324 33 6333 6330 32 6336 6330 32 6336 6333 + 33 6342 6339 32 6345 6339 32 6345 6342 33 + 6351 6348 32 6354 6348 32 6354 6351 33 6360 + 6357 32 6363 6357 32 6363 6360 33 6369 6366 + 32 6372 6366 32 6372 6369 33 6378 6375 32 + 6381 6375 32 6381 6378 33 6387 6384 32 6390 + 6384 32 6390 6387 33 6396 6393 32 6399 6393 + 32 6399 6396 33 6405 6402 32 6408 6402 32 + 6408 6405 33 6414 6411 32 6417 6411 32 6417 + 6414 33 6423 6420 32 6426 6420 32 6426 6423 + 33 6432 6429 32 6435 6429 32 6435 6432 33 + 6441 6438 32 6444 6438 32 6444 6441 33 6450 + 6447 32 6453 6447 32 6453 6450 33 6459 6456 + 32 6462 6456 32 6462 6459 33 6468 6465 32 + 6471 6465 32 6471 6468 33 6477 6474 32 6480 + 6474 32 6480 6477 33 6486 6483 32 6489 6483 + 32 6489 6486 33 6495 6492 32 6498 6492 32 + 6498 6495 33 6504 6501 32 6507 6501 32 6507 + 6504 33 6513 6510 32 6516 6510 32 6516 6513 + 33 6522 6519 32 6525 6519 32 6525 6522 33 + 6531 6528 32 6534 6528 32 6534 6531 33 6540 + 6537 32 6543 6537 32 6543 6540 33 6549 6546 + 32 6552 6546 32 6552 6549 33 6558 6555 32 + 6561 6555 32 6561 6558 33 6567 6564 32 6570 + 6564 32 6570 6567 33 6576 6573 32 6579 6573 + 32 6579 6576 33 6585 6582 32 6588 6582 32 + 6588 6585 33 6594 6591 32 6597 6591 32 6597 + 6594 33 6603 6600 32 6606 6600 32 6606 6603 + 33 6612 6609 32 6615 6609 32 6615 6612 33 + 6621 6618 32 6624 6618 32 6624 6621 33 6630 + 6627 32 6633 6627 32 6633 6630 33 6639 6636 + 32 6642 6636 32 6642 6639 33 6648 6645 32 + 6651 6645 32 6651 6648 33 6657 6654 32 6660 + 6654 32 6660 6657 33 6666 6663 32 6669 6663 + 32 6669 6666 33 6675 6672 32 6678 6672 32 + 6678 6675 33 6684 6681 32 6687 6681 32 6687 + 6684 33 6693 6690 32 6696 6690 32 6696 6693 + 33 6702 6699 32 6705 6699 32 6705 6702 33 + 6711 6708 32 6714 6708 32 6714 6711 33 6720 + 6717 32 6723 6717 32 6723 6720 33 6729 6726 + 32 6732 6726 32 6732 6729 33 6738 6735 32 + 6741 6735 32 6741 6738 33 6747 6744 32 6750 + 6744 32 6750 6747 33 6756 6753 32 6759 6753 + 32 6759 6756 33 6765 6762 32 6768 6762 32 + 6768 6765 33 6774 6771 32 6777 6771 32 6777 + 6774 33 6783 6780 32 6786 6780 32 6786 6783 + 33 6792 6789 32 6795 6789 32 6795 6792 33 + 6801 6798 32 6804 6798 32 6804 6801 33 6810 + 6807 32 6813 6807 32 6813 6810 33 6819 6816 + 32 6822 6816 32 6822 6819 33 6828 6825 32 + 6831 6825 32 6831 6828 33 6837 6834 32 6840 + 6834 32 6840 6837 33 6846 6843 32 6849 6843 + 32 6849 6846 33 6855 6852 32 6858 6852 32 + 6858 6855 33 6864 6861 32 6867 6861 32 6867 + 6864 33 6873 6870 32 6876 6870 32 6876 6873 + 33 6882 6879 32 6885 6879 32 6885 6882 33 + 6891 6888 32 6894 6888 32 6894 6891 33 6900 + 6897 32 6903 6897 32 6903 6900 33 6909 6906 + 32 6912 6906 32 6912 6909 33 6918 6915 32 + 6921 6915 32 6921 6918 33 6927 6924 32 6930 + 6924 32 6930 6927 33 6936 6933 32 6939 6933 + 32 6939 6936 33 6945 6942 32 6948 6942 32 + 6948 6945 33 6954 6951 32 6957 6951 32 6957 + 6954 33 6963 6960 32 6966 6960 32 6966 6963 + 33 6972 6969 32 6975 6969 32 6975 6972 33 + 6981 6978 32 6984 6978 32 6984 6981 33 6990 + 6987 32 6993 6987 32 6993 6990 33 6999 6996 + 32 7002 6996 32 7002 6999 33 7008 7005 32 + 7011 7005 32 7011 7008 33 7017 7014 32 7020 + 7014 32 7020 7017 33 7026 7023 32 7029 7023 + 32 7029 7026 33 7035 7032 32 7038 7032 32 + 7038 7035 33 7044 7041 32 7047 7041 32 7047 + 7044 33 7053 7050 32 7056 7050 32 7056 7053 + 33 7062 7059 32 7065 7059 32 7065 7062 33 + 7071 7068 32 7074 7068 32 7074 7071 33 7080 + 7077 32 7083 7077 32 7083 7080 33 7089 7086 + 32 7092 7086 32 7092 7089 33 7098 7095 32 + 7101 7095 32 7101 7098 33 7107 7104 32 7110 + 7104 32 7110 7107 33 7116 7113 32 7119 7113 + 32 7119 7116 33 7125 7122 32 7128 7122 32 + 7128 7125 33 7134 7131 32 7137 7131 32 7137 + 7134 33 7143 7140 32 7146 7140 32 7146 7143 + 33 7152 7149 32 7155 7149 32 7155 7152 33 + 7161 7158 32 7164 7158 32 7164 7161 33 7170 + 7167 32 7173 7167 32 7173 7170 33 7179 7176 + 32 7182 7176 32 7182 7179 33 7188 7185 32 + 7191 7185 32 7191 7188 33 7197 7194 32 7200 + 7194 32 7200 7197 33 7206 7203 32 7209 7203 + 32 7209 7206 33 7215 7212 32 7218 7212 32 + 7218 7215 33 7224 7221 32 7227 7221 32 7227 + 7224 33 7233 7230 32 7236 7230 32 7236 7233 + 33 7242 7239 32 7245 7239 32 7245 7242 33 + 7251 7248 32 7254 7248 32 7254 7251 33 7260 + 7257 32 7263 7257 32 7263 7260 33 7269 7266 + 32 7272 7266 32 7272 7269 33 7278 7275 32 + 7281 7275 32 7281 7278 33 7287 7284 32 7290 + 7284 32 7290 7287 33 7296 7293 32 7299 7293 + 32 7299 7296 33 7305 7302 32 7308 7302 32 + 7308 7305 33 7314 7311 32 7317 7311 32 7317 + 7314 33 7323 7320 32 7326 7320 32 7326 7323 + 33 7332 7329 32 7335 7329 32 7335 7332 33 + 7341 7338 32 7344 7338 32 7344 7341 33 7350 + 7347 32 7353 7347 32 7353 7350 33 7359 7356 + 32 7362 7356 32 7362 7359 33 7368 7365 32 + 7371 7365 32 7371 7368 33 7377 7374 32 7380 + 7374 32 7380 7377 33 7386 7383 32 7389 7383 + 32 7389 7386 33 7395 7392 32 7398 7392 32 + 7398 7395 33 7404 7401 32 7407 7401 32 7407 + 7404 33 7413 7410 32 7416 7410 32 7416 7413 + 33 7422 7419 32 7425 7419 32 7425 7422 33 + 7431 7428 32 7434 7428 32 7434 7431 33 7440 + 7437 32 7443 7437 32 7443 7440 33 7449 7446 + 32 7452 7446 32 7452 7449 33 7458 7455 32 + 7461 7455 32 7461 7458 33 7467 7464 32 7470 + 7464 32 7470 7467 33 7476 7473 32 7479 7473 + 32 7479 7476 33 7485 7482 32 7488 7482 32 + 7488 7485 33 7494 7491 32 7497 7491 32 7497 + 7494 33 7503 7500 32 7506 7500 32 7506 7503 + 33 7512 7509 32 7515 7509 32 7515 7512 33 + 7521 7518 32 7524 7518 32 7524 7521 33 7530 + 7527 32 7533 7527 32 7533 7530 33 7539 7536 + 32 7542 7536 32 7542 7539 33 7548 7545 32 + 7551 7545 32 7551 7548 33 7557 7554 32 7560 + 7554 32 7560 7557 33 7566 7563 32 7569 7563 + 32 7569 7566 33 7575 7572 32 7578 7572 32 + 7578 7575 33 7584 7581 32 7587 7581 32 7587 + 7584 33 7593 7590 32 7596 7590 32 7596 7593 + 33 7602 7599 32 7605 7599 32 7605 7602 33 + 7611 7608 32 7614 7608 32 7614 7611 33 7620 + 7617 32 7623 7617 32 7623 7620 33 7629 7626 + 32 7632 7626 32 7632 7629 33 7638 7635 32 + 7641 7635 32 7641 7638 33 7647 7644 32 7650 + 7644 32 7650 7647 33 7656 7653 32 7659 7653 + 32 7659 7656 33 7665 7662 32 7668 7662 32 + 7668 7665 33 7674 7671 32 7677 7671 32 7677 + 7674 33 7683 7680 32 7686 7680 32 7686 7683 + 33 7692 7689 32 7695 7689 32 7695 7692 33 + 7701 7698 32 7704 7698 32 7704 7701 33 7710 + 7707 32 7713 7707 32 7713 7710 33 7719 7716 + 32 7722 7716 32 7722 7719 33 7728 7725 32 + 7731 7725 32 7731 7728 33 7737 7734 32 7740 + 7734 32 7740 7737 33 7746 7743 32 7749 7743 + 32 7749 7746 33 7755 7752 32 7758 7752 32 + 7758 7755 33 7764 7761 32 7767 7761 32 7767 + 7764 33 7773 7770 32 7776 7770 32 7776 7773 + 33 7782 7779 32 7785 7779 32 7785 7782 33 + 7791 7788 32 7794 7788 32 7794 7791 33 7800 + 7797 32 7803 7797 32 7803 7800 33 7809 7806 + 32 7812 7806 32 7812 7809 33 7818 7815 32 + 7821 7815 32 7821 7818 33 7827 7824 32 7830 + 7824 32 7830 7827 33 7836 7833 32 7839 7833 + 32 7839 7836 33 7845 7842 32 7848 7842 32 + 7848 7845 33 7854 7851 32 7857 7851 32 7857 + 7854 33 7863 7860 32 7866 7860 32 7866 7863 + 33 7872 7869 32 7875 7869 32 7875 7872 33 + 7881 7878 32 7884 7878 32 7884 7881 33 7890 + 7887 32 7893 7887 32 7893 7890 33 7899 7896 + 32 7902 7896 32 7902 7899 33 7908 7905 32 + 7911 7905 32 7911 7908 33 7917 7914 32 7920 + 7914 32 7920 7917 33 7926 7923 32 7929 7923 + 32 7929 7926 33 7935 7932 32 7938 7932 32 + 7938 7935 33 7944 7941 32 7947 7941 32 7947 + 7944 33 7953 7950 32 7956 7950 32 7956 7953 + 33 7962 7959 32 7965 7959 32 7965 7962 33 + 7971 7968 32 7974 7968 32 7974 7971 33 7980 + 7977 32 7983 7977 32 7983 7980 33 7989 7986 + 32 7992 7986 32 7992 7989 33 7998 7995 32 + 8001 7995 32 8001 7998 33 8007 8004 32 8010 + 8004 32 8010 8007 33 8016 8013 32 8019 8013 + 32 8019 8016 33 8025 8022 32 8028 8022 32 + 8028 8025 33 8034 8031 32 8037 8031 32 8037 + 8034 33 8043 8040 32 8046 8040 32 8046 8043 + 33 8052 8049 32 8055 8049 32 8055 8052 33 + 8061 8058 32 8064 8058 32 8064 8061 33 8070 + 8067 32 8073 8067 32 8073 8070 33 8079 8076 + 32 8082 8076 32 8082 8079 33 8088 8085 32 + 8091 8085 32 8091 8088 33 8097 8094 32 8100 + 8094 32 8100 8097 33 8106 8103 32 8109 8103 + 32 8109 8106 33 8115 8112 32 8118 8112 32 + 8118 8115 33 8124 8121 32 8127 8121 32 8127 + 8124 33 8133 8130 32 8136 8130 32 8136 8133 + 33 8142 8139 32 8145 8139 32 8145 8142 33 + 8151 8148 32 8154 8148 32 8154 8151 33 8160 + 8157 32 8163 8157 32 8163 8160 33 8169 8166 + 32 8172 8166 32 8172 8169 33 8178 8175 32 + 8181 8175 32 8181 8178 33 8187 8184 32 8190 + 8184 32 8190 8187 33 8196 8193 32 8199 8193 + 32 8199 8196 33 8205 8202 32 8208 8202 32 + 8208 8205 33 8214 8211 32 8217 8211 32 8217 + 8214 33 8223 8220 32 8226 8220 32 8226 8223 + 33 8232 8229 32 8235 8229 32 8235 8232 33 + 8241 8238 32 8244 8238 32 8244 8241 33 8250 + 8247 32 8253 8247 32 8253 8250 33 8259 8256 + 32 8262 8256 32 8262 8259 33 8268 8265 32 + 8271 8265 32 8271 8268 33 8277 8274 32 8280 + 8274 32 8280 8277 33 8286 8283 32 8289 8283 + 32 8289 8286 33 8295 8292 32 8298 8292 32 + 8298 8295 33 8304 8301 32 8307 8301 32 8307 + 8304 33 8313 8310 32 8316 8310 32 8316 8313 + 33 8322 8319 32 8325 8319 32 8325 8322 33 + 8331 8328 32 8334 8328 32 8334 8331 33 8340 + 8337 32 8343 8337 32 8343 8340 33 8349 8346 + 32 8352 8346 32 8352 8349 33 8358 8355 32 + 8361 8355 32 8361 8358 33 8367 8364 32 8370 + 8364 32 8370 8367 33 8376 8373 32 8379 8373 + 32 8379 8376 33 8385 8382 32 8388 8382 32 + 8388 8385 33 8394 8391 32 8397 8391 32 8397 + 8394 33 8403 8400 32 8406 8400 32 8406 8403 + 33 8412 8409 32 8415 8409 32 8415 8412 33 + 8421 8418 32 8424 8418 32 8424 8421 33 8430 + 8427 32 8433 8427 32 8433 8430 33 8439 8436 + 32 8442 8436 32 8442 8439 33 8448 8445 32 + 8451 8445 32 8451 8448 33 8457 8454 32 8460 + 8454 32 8460 8457 33 8466 8463 32 8469 8463 + 32 8469 8466 33 8475 8472 32 8478 8472 32 + 8478 8475 33 8484 8481 32 8487 8481 32 8487 + 8484 33 8493 8490 32 8496 8490 32 8496 8493 + 33 8502 8499 32 8505 8499 32 8505 8502 33 + 8511 8508 32 8514 8508 32 8514 8511 33 8520 + 8517 32 8523 8517 32 8523 8520 33 8529 8526 + 32 8532 8526 32 8532 8529 33 8538 8535 32 + 8541 8535 32 8541 8538 33 8547 8544 32 8550 + 8544 32 8550 8547 33 8556 8553 32 8559 8553 + 32 8559 8556 33 8565 8562 32 8568 8562 32 + 8568 8565 33 8574 8571 32 8577 8571 32 8577 + 8574 33 8583 8580 32 8586 8580 32 8586 8583 + 33 8592 8589 32 8595 8589 32 8595 8592 33 + 8601 8598 32 8604 8598 32 8604 8601 33 8610 + 8607 32 8613 8607 32 8613 8610 33 8619 8616 + 32 8622 8616 32 8622 8619 33 8628 8625 32 + 8631 8625 32 8631 8628 33 8637 8634 32 8640 + 8634 32 8640 8637 33 8646 8643 32 8649 8643 + 32 8649 8646 33 8655 8652 32 8658 8652 32 + 8658 8655 33 8664 8661 32 8667 8661 32 8667 + 8664 33 8673 8670 32 8676 8670 32 8676 8673 + 33 8682 8679 32 8685 8679 32 8685 8682 33 + 8691 8688 32 8694 8688 32 8694 8691 33 8700 + 8697 32 8703 8697 32 8703 8700 33 8709 8706 + 32 8712 8706 32 8712 8709 33 8718 8715 32 + 8721 8715 32 8721 8718 33 8727 8724 32 8730 + 8724 32 8730 8727 33 8736 8733 32 8739 8733 + 32 8739 8736 33 8745 8742 32 8748 8742 32 + 8748 8745 33 8754 8751 32 8757 8751 32 8757 + 8754 33 8763 8760 32 8766 8760 32 8766 8763 + 33 8772 8769 32 8775 8769 32 8775 8772 33 + 8781 8778 32 8784 8778 32 8784 8781 33 8790 + 8787 32 8793 8787 32 8793 8790 33 8799 8796 + 32 8802 8796 32 8802 8799 33 8808 8805 32 + 8811 8805 32 8811 8808 33 8817 8814 32 8820 + 8814 32 8820 8817 33 8826 8823 32 8829 8823 + 32 8829 8826 33 8835 8832 32 8838 8832 32 + 8838 8835 33 8844 8841 32 8847 8841 32 8847 + 8844 33 8853 8850 32 8856 8850 32 8856 8853 + 33 8862 8859 32 8865 8859 32 8865 8862 33 + 8871 8868 32 8874 8868 32 8874 8871 33 8880 + 8877 32 8883 8877 32 8883 8880 33 8889 8886 + 32 8892 8886 32 8892 8889 33 8898 8895 32 + 8901 8895 32 8901 8898 33 8907 8904 32 8910 + 8904 32 8910 8907 33 8916 8913 32 8919 8913 + 32 8919 8916 33 8925 8922 32 8928 8922 32 + 8928 8925 33 8934 8931 32 8937 8931 32 8937 + 8934 33 8943 8940 32 8946 8940 32 8946 8943 + 33 8952 8949 32 8955 8949 32 8955 8952 33 + 8961 8958 32 8964 8958 32 8964 8961 33 8970 + 8967 32 8973 8967 32 8973 8970 33 8979 8976 + 32 8982 8976 32 8982 8979 33 8988 8985 32 + 8991 8985 32 8991 8988 33 8997 8994 32 9000 + 8994 32 9000 8997 33 9006 9003 32 9009 9003 + 32 9009 9006 33 9015 9012 32 9018 9012 32 + 9018 9015 33 9024 9021 32 9027 9021 32 9027 + 9024 33 9033 9030 32 9036 9030 32 9036 9033 + 33 9042 9039 32 9045 9039 32 9045 9042 33 + 9051 9048 32 9054 9048 32 9054 9051 33 9060 + 9057 32 9063 9057 32 9063 9060 33 9069 9066 + 32 9072 9066 32 9072 9069 33 9078 9075 32 + 9081 9075 32 9081 9078 33 9087 9084 32 9090 + 9084 32 9090 9087 33 9096 9093 32 9099 9093 + 32 9099 9096 33 9105 9102 32 9108 9102 32 + 9108 9105 33 9114 9111 32 9117 9111 32 9117 + 9114 33 9123 9120 32 9126 9120 32 9126 9123 + 33 9132 9129 32 9135 9129 32 9135 9132 33 + 9141 9138 32 9144 9138 32 9144 9141 33 9150 + 9147 32 9153 9147 32 9153 9150 33 9159 9156 + 32 9162 9156 32 9162 9159 33 9168 9165 32 + 9171 9165 32 9171 9168 33 9177 9174 32 9180 + 9174 32 9180 9177 33 9186 9183 32 9189 9183 + 32 9189 9186 33 9195 9192 32 9198 9192 32 + 9198 9195 33 9204 9201 32 9207 9201 32 9207 + 9204 33 9213 9210 32 9216 9210 32 9216 9213 + 33 9222 9219 32 9225 9219 32 9225 9222 33 + 9231 9228 32 9234 9228 32 9234 9231 33 9240 + 9237 32 9243 9237 32 9243 9240 33 9249 9246 + 32 9252 9246 32 9252 9249 33 9258 9255 32 + 9261 9255 32 9261 9258 33 9267 9264 32 9270 + 9264 32 9270 9267 33 9276 9273 32 9279 9273 + 32 9279 9276 33 9285 9282 32 9288 9282 32 + 9288 9285 33 9294 9291 32 9297 9291 32 9297 + 9294 33 9303 9300 32 9306 9300 32 9306 9303 + 33 9312 9309 32 9315 9309 32 9315 9312 33 + 9321 9318 32 9324 9318 32 9324 9321 33 9330 + 9327 32 9333 9327 32 9333 9330 33 9339 9336 + 32 9342 9336 32 9342 9339 33 9348 9345 32 + 9351 9345 32 9351 9348 33 9357 9354 32 9360 + 9354 32 9360 9357 33 9366 9363 32 9369 9363 + 32 9369 9366 33 9375 9372 32 9378 9372 32 + 9378 9375 33 9384 9381 32 9387 9381 32 9387 + 9384 33 9393 9390 32 9396 9390 32 9396 9393 + 33 9402 9399 32 9405 9399 32 9405 9402 33 + 9411 9408 32 9414 9408 32 9414 9411 33 9420 + 9417 32 9423 9417 32 9423 9420 33 9429 9426 + 32 9432 9426 32 9432 9429 33 9438 9435 32 + 9441 9435 32 9441 9438 33 9447 9444 32 9450 + 9444 32 9450 9447 33 9456 9453 32 9459 9453 + 32 9459 9456 33 9465 9462 32 9468 9462 32 + 9468 9465 33 9474 9471 32 9477 9471 32 9477 + 9474 33 9483 9480 32 9486 9480 32 9486 9483 + 33 9492 9489 32 9495 9489 32 9495 9492 33 + 9501 9498 32 9504 9498 32 9504 9501 33 9510 + 9507 32 9513 9507 32 9513 9510 33 9519 9516 + 32 9522 9516 32 9522 9519 33 9528 9525 32 + 9531 9525 32 9531 9528 33 9537 9534 32 9540 + 9534 32 9540 9537 33 9546 9543 32 9549 9543 + 32 9549 9546 33 9555 9552 32 9558 9552 32 + 9558 9555 33 9564 9561 32 9567 9561 32 9567 + 9564 33 9573 9570 32 9576 9570 32 9576 9573 + 33 9582 9579 32 9585 9579 32 9585 9582 33 + 9591 9588 32 9594 9588 32 9594 9591 33 9600 + 9597 32 9603 9597 32 9603 9600 33 9609 9606 + 32 9612 9606 32 9612 9609 33 9618 9615 32 + 9621 9615 32 9621 9618 33 9627 9624 32 9630 + 9624 32 9630 9627 33 9636 9633 32 9639 9633 + 32 9639 9636 33 9645 9642 32 9648 9642 32 + 9648 9645 33 9654 9651 32 9657 9651 32 9657 + 9654 33 9663 9660 32 9666 9660 32 9666 9663 + 33 9672 9669 32 9675 9669 32 9675 9672 33 + 9681 9678 32 9684 9678 32 9684 9681 33 9690 + 9687 32 9693 9687 32 9693 9690 33 9699 9696 + 32 9702 9696 32 9702 9699 33 9708 9705 32 + 9711 9705 32 9711 9708 33 9717 9714 32 9720 + 9714 32 9720 9717 33 9726 9723 32 9729 9723 + 32 9729 9726 33 9735 9732 32 9738 9732 32 + 9738 9735 33 9744 9741 32 9747 9741 32 9747 + 9744 33 9753 9750 32 9756 9750 32 9756 9753 + 33 9762 9759 32 9765 9759 32 9765 9762 33 + 9771 9768 32 9774 9768 32 9774 9771 33 9780 + 9777 32 9783 9777 32 9783 9780 33 9789 9786 + 32 9792 9786 32 9792 9789 33 9798 9795 32 + 9801 9795 32 9801 9798 33 9807 9804 32 9810 + 9804 32 9810 9807 33 9816 9813 32 9819 9813 + 32 9819 9816 33 9825 9822 32 9828 9822 32 + 9828 9825 33 9834 9831 32 9837 9831 32 9837 + 9834 33 9843 9840 32 9846 9840 32 9846 9843 + 33 9852 9849 32 9855 9849 32 9855 9852 33 + 9861 9858 32 9864 9858 32 9864 9861 33 9870 + 9867 32 9873 9867 32 9873 9870 33 9879 9876 + 32 9882 9876 32 9882 9879 33 9888 9885 32 + 9891 9885 32 9891 9888 33 9897 9894 32 9900 + 9894 32 9900 9897 33 9906 9903 32 9909 9903 + 32 9909 9906 33 9915 9912 32 9918 9912 32 + 9918 9915 33 9924 9921 32 9927 9921 32 9927 + 9924 33 9933 9930 32 9936 9930 32 9936 9933 + 33 9942 9939 32 9945 9939 32 9945 9942 33 + 9951 9948 32 9954 9948 32 9954 9951 33 9960 + 9957 32 9963 9957 32 9963 9960 33 9969 9966 + 32 9972 9966 32 9972 9969 33 9978 9975 32 + 9981 9975 32 9981 9978 33 9987 9984 32 9990 + 9984 32 9990 9987 33 9996 9993 32 9999 9993 + 32 9999 9996 33 10005 10002 32 10008 10002 32 + 10008 10005 33 10014 10011 32 10017 10011 32 10017 + 10014 33 10023 10020 32 10026 10020 32 10026 10023 + 33 10032 10029 32 10035 10029 32 10035 10032 33 + 10041 10038 32 10044 10038 32 10044 10041 33 10050 + 10047 32 10053 10047 32 10053 10050 33 10059 10056 + 32 10062 10056 32 10062 10059 33 10068 10065 32 + 10071 10065 32 10071 10068 33 10077 10074 32 10080 + 10074 32 10080 10077 33 10086 10083 32 10089 10083 + 32 10089 10086 33 10095 10092 32 10098 10092 32 + 10098 10095 33 10104 10101 32 10107 10101 32 10107 + 10104 33 10113 10110 32 10116 10110 32 10116 10113 + 33 10122 10119 32 10125 10119 32 10125 10122 33 + 10131 10128 32 10134 10128 32 10134 10131 33 10140 + 10137 32 10143 10137 32 10143 10140 33 10149 10146 + 32 10152 10146 32 10152 10149 33 10158 10155 32 + 10161 10155 32 10161 10158 33 10167 10164 32 10170 + 10164 32 10170 10167 33 10176 10173 32 10179 10173 + 32 10179 10176 33 10185 10182 32 10188 10182 32 + 10188 10185 33 10194 10191 32 10197 10191 32 10197 + 10194 33 10203 10200 32 10206 10200 32 10206 10203 + 33 10212 10209 32 10215 10209 32 10215 10212 33 + 10221 10218 32 10224 10218 32 10224 10221 33 10230 + 10227 32 10233 10227 32 10233 10230 33 10239 10236 + 32 10242 10236 32 10242 10239 33 10248 10245 32 + 10251 10245 32 10251 10248 33 10257 10254 32 10260 + 10254 32 10260 10257 33 10266 10263 32 10269 10263 + 32 10269 10266 33 10275 10272 32 10278 10272 32 + 10278 10275 33 10284 10281 32 10287 10281 32 10287 + 10284 33 10293 10290 32 10296 10290 32 10296 10293 + 33 10302 10299 32 10305 10299 32 10305 10302 33 + 10311 10308 32 10314 10308 32 10314 10311 33 10320 + 10317 32 10323 10317 32 10323 10320 33 10329 10326 + 32 10332 10326 32 10332 10329 33 10338 10335 32 + 10341 10335 32 10341 10338 33 10347 10344 32 10350 + 10344 32 10350 10347 33 10356 10353 32 10359 10353 + 32 10359 10356 33 10365 10362 32 10368 10362 32 + 10368 10365 33 10374 10371 32 10377 10371 32 10377 + 10374 33 10383 10380 32 10386 10380 32 10386 10383 + 33 10392 10389 32 10395 10389 32 10395 10392 33 + 10401 10398 32 10404 10398 32 10404 10401 33 10410 + 10407 32 10413 10407 32 10413 10410 33 10419 10416 + 32 10422 10416 32 10422 10419 33 10428 10425 32 + 10431 10425 32 10431 10428 33 10437 10434 32 10440 + 10434 32 10440 10437 33 10446 10443 32 10449 10443 + 32 10449 10446 33 10455 10452 32 10458 10452 32 + 10458 10455 33 10464 10461 32 10467 10461 32 10467 + 10464 33 10473 10470 32 10476 10470 32 10476 10473 + 33 10482 10479 32 10485 10479 32 10485 10482 33 + 10491 10488 32 10494 10488 32 10494 10491 33 10500 + 10497 32 10503 10497 32 10503 10500 33 10509 10506 + 32 10512 10506 32 10512 10509 33 10518 10515 32 + 10521 10515 32 10521 10518 33 10527 10524 32 10530 + 10524 32 10530 10527 33 10536 10533 32 10539 10533 + 32 10539 10536 33 10545 10542 32 10548 10542 32 + 10548 10545 33 10554 10551 32 10557 10551 32 10557 + 10554 33 10563 10560 32 10566 10560 32 10566 10563 + 33 10572 10569 32 10575 10569 32 10575 10572 33 + 10581 10578 32 10584 10578 32 10584 10581 33 10590 + 10587 32 10593 10587 32 10593 10590 33 10599 10596 + 32 10602 10596 32 10602 10599 33 10608 10605 32 + 10611 10605 32 10611 10608 33 10617 10614 32 10620 + 10614 32 10620 10617 33 10626 10623 32 10629 10623 + 32 10629 10626 33 10635 10632 32 10638 10632 32 + 10638 10635 33 10644 10641 32 10647 10641 32 10647 + 10644 33 10653 10650 32 10656 10650 32 10656 10653 + 33 10662 10659 32 10665 10659 32 10665 10662 33 + 10671 10668 32 10674 10668 32 10674 10671 33 10680 + 10677 32 10683 10677 32 10683 10680 33 10689 10686 + 32 10692 10686 32 10692 10689 33 10698 10695 32 + 10701 10695 32 10701 10698 33 10707 10704 32 10710 + 10704 32 10710 10707 33 10716 10713 32 10719 10713 + 32 10719 10716 33 10725 10722 32 10728 10722 32 + 10728 10725 33 10734 10731 32 10737 10731 32 10737 + 10734 33 10743 10740 32 10746 10740 32 10746 10743 + 33 10752 10749 32 10755 10749 32 10755 10752 33 + 10761 10758 32 10764 10758 32 10764 10761 33 10770 + 10767 32 10773 10767 32 10773 10770 33 10779 10776 + 32 10782 10776 32 10782 10779 33 10788 10785 32 + 10791 10785 32 10791 10788 33 10797 10794 32 10800 + 10794 32 10800 10797 33 10806 10803 32 10809 10803 + 32 10809 10806 33 10815 10812 32 10818 10812 32 + 10818 10815 33 10824 10821 32 10827 10821 32 10827 + 10824 33 10833 10830 32 10836 10830 32 10836 10833 + 33 10842 10839 32 10845 10839 32 10845 10842 33 + 10851 10848 32 10854 10848 32 10854 10851 33 10860 + 10857 32 10863 10857 32 10863 10860 33 10869 10866 + 32 10872 10866 32 10872 10869 33 10878 10875 32 + 10881 10875 32 10881 10878 33 10887 10884 32 10890 + 10884 32 10890 10887 33 10896 10893 32 10899 10893 + 32 10899 10896 33 10905 10902 32 10908 10902 32 + 10908 10905 33 10914 10911 32 10917 10911 32 10917 + 10914 33 10923 10920 32 10926 10920 32 10926 10923 + 33 10932 10929 32 10935 10929 32 10935 10932 33 + 10941 10938 32 10944 10938 32 10944 10941 33 10950 + 10947 32 10953 10947 32 10953 10950 33 10959 10956 + 32 10962 10956 32 10962 10959 33 10968 10965 32 + 10971 10965 32 10971 10968 33 10977 10974 32 10980 + 10974 32 10980 10977 33 10986 10983 32 10989 10983 + 32 10989 10986 33 10995 10992 32 10998 10992 32 + 10998 10995 33 11004 11001 32 11007 11001 32 11007 + 11004 33 11013 11010 32 11016 11010 32 11016 11013 + 33 11022 11019 32 11025 11019 32 11025 11022 33 + 11031 11028 32 11034 11028 32 11034 11031 33 11040 + 11037 32 11043 11037 32 11043 11040 33 11049 11046 + 32 11052 11046 32 11052 11049 33 11058 11055 32 + 11061 11055 32 11061 11058 33 11067 11064 32 11070 + 11064 32 11070 11067 33 11076 11073 32 11079 11073 + 32 11079 11076 33 11085 11082 32 11088 11082 32 + 11088 11085 33 11094 11091 32 11097 11091 32 11097 + 11094 33 11103 11100 32 11106 11100 32 11106 11103 + 33 11112 11109 32 11115 11109 32 11115 11112 33 + 11121 11118 32 11124 11118 32 11124 11121 33 11130 + 11127 32 11133 11127 32 11133 11130 33 11139 11136 + 32 11142 11136 32 11142 11139 33 11148 11145 32 + 11151 11145 32 11151 11148 33 11157 11154 32 11160 + 11154 32 11160 11157 33 11166 11163 32 11169 11163 + 32 11169 11166 33 11175 11172 32 11178 11172 32 + 11178 11175 33 11184 11181 32 11187 11181 32 11187 + 11184 33 11193 11190 32 11196 11190 32 11196 11193 + 33 11202 11199 32 11205 11199 32 11205 11202 33 + 11211 11208 32 11214 11208 32 11214 11211 33 11220 + 11217 32 11223 11217 32 11223 11220 33 11229 11226 + 32 11232 11226 32 11232 11229 33 11238 11235 32 + 11241 11235 32 11241 11238 33 11247 11244 32 11250 + 11244 32 11250 11247 33 11256 11253 32 11259 11253 + 32 11259 11256 33 11265 11262 32 11268 11262 32 + 11268 11265 33 11274 11271 32 11277 11271 32 11277 + 11274 33 11283 11280 32 11286 11280 32 11286 11283 + 33 11292 11289 32 11295 11289 32 11295 11292 33 + 11301 11298 32 11304 11298 32 11304 11301 33 11310 + 11307 32 11313 11307 32 11313 11310 33 11319 11316 + 32 11322 11316 32 11322 11319 33 11328 11325 32 + 11331 11325 32 11331 11328 33 11337 11334 32 11340 + 11334 32 11340 11337 33 11346 11343 32 11349 11343 + 32 11349 11346 33 11355 11352 32 11358 11352 32 + 11358 11355 33 11364 11361 32 11367 11361 32 11367 + 11364 33 11373 11370 32 11376 11370 32 11376 11373 + 33 11382 11379 32 11385 11379 32 11385 11382 33 + 11391 11388 32 11394 11388 32 11394 11391 33 11400 + 11397 32 11403 11397 32 11403 11400 33 11409 11406 + 32 11412 11406 32 11412 11409 33 11418 11415 32 + 11421 11415 32 11421 11418 33 11427 11424 32 11430 + 11424 32 11430 11427 33 11436 11433 32 11439 11433 + 32 11439 11436 33 11445 11442 32 11448 11442 32 + 11448 11445 33 11454 11451 32 11457 11451 32 11457 + 11454 33 11463 11460 32 11466 11460 32 11466 11463 + 33 11472 11469 32 11475 11469 32 11475 11472 33 + 11481 11478 32 11484 11478 32 11484 11481 33 11490 + 11487 32 11493 11487 32 11493 11490 33 11499 11496 + 32 11502 11496 32 11502 11499 33 11508 11505 32 + 11511 11505 32 11511 11508 33 11517 11514 32 11520 + 11514 32 11520 11517 33 11526 11523 32 11529 11523 + 32 11529 11526 33 11535 11532 32 11538 11532 32 + 11538 11535 33 11544 11541 32 11547 11541 32 11547 + 11544 33 11553 11550 32 11556 11550 32 11556 11553 + 33 11562 11559 32 11565 11559 32 11565 11562 33 + 11571 11568 32 11574 11568 32 11574 11571 33 11580 + 11577 32 11583 11577 32 11583 11580 33 11589 11586 + 32 11592 11586 32 11592 11589 33 11598 11595 32 + 11601 11595 32 11601 11598 33 11607 11604 32 11610 + 11604 32 11610 11607 33 11616 11613 32 11619 11613 + 32 11619 11616 33 11625 11622 32 11628 11622 32 + 11628 11625 33 11634 11631 32 11637 11631 32 11637 + 11634 33 11643 11640 32 11646 11640 32 11646 11643 + 33 11652 11649 32 11655 11649 32 11655 11652 33 + 11661 11658 32 11664 11658 32 11664 11661 33 11670 + 11667 32 11673 11667 32 11673 11670 33 11679 11676 + 32 11682 11676 32 11682 11679 33 11688 11685 32 + 11691 11685 32 11691 11688 33 11697 11694 32 11700 + 11694 32 11700 11697 33 11706 11703 32 11709 11703 + 32 11709 11706 33 11715 11712 32 11718 11712 32 + 11718 11715 33 11724 11721 32 11727 11721 32 11727 + 11724 33 11733 11730 32 11736 11730 32 11736 11733 + 33 11742 11739 32 11745 11739 32 11745 11742 33 + 11751 11748 32 11754 11748 32 11754 11751 33 11760 + 11757 32 11763 11757 32 11763 11760 33 11769 11766 + 32 11772 11766 32 11772 11769 33 11778 11775 32 + 11781 11775 32 11781 11778 33 11787 11784 32 11790 + 11784 32 11790 11787 33 11796 11793 32 11799 11793 + 32 11799 11796 33 11805 11802 32 11808 11802 32 + 11808 11805 33 11814 11811 32 11817 11811 32 11817 + 11814 33 11823 11820 32 11826 11820 32 11826 11823 + 33 11832 11829 32 11835 11829 32 11835 11832 33 + 11841 11838 32 11844 11838 32 11844 11841 33 11850 + 11847 32 11853 11847 32 11853 11850 33 11859 11856 + 32 11862 11856 32 11862 11859 33 11868 11865 32 + 11871 11865 32 11871 11868 33 11877 11874 32 11880 + 11874 32 11880 11877 33 11886 11883 32 11889 11883 + 32 11889 11886 33 11895 11892 32 11898 11892 32 + 11898 11895 33 11904 11901 32 11907 11901 32 11907 + 11904 33 11913 11910 32 11916 11910 32 11916 11913 + 33 11922 11919 32 11925 11919 32 11925 11922 33 + 11931 11928 32 11934 11928 32 11934 11931 33 11940 + 11937 32 11943 11937 32 11943 11940 33 11949 11946 + 32 11952 11946 32 11952 11949 33 11958 11955 32 + 11961 11955 32 11961 11958 33 11967 11964 32 11970 + 11964 32 11970 11967 33 11976 11973 32 11979 11973 + 32 11979 11976 33 11985 11982 32 11988 11982 32 + 11988 11985 33 11994 11991 32 11997 11991 32 11997 + 11994 33 12003 12000 32 12006 12000 32 12006 12003 + 33 12012 12009 32 12015 12009 32 12015 12012 33 + 12021 12018 32 12024 12018 32 12024 12021 33 12030 + 12027 32 12033 12027 32 12033 12030 33 12039 12036 + 32 12042 12036 32 12042 12039 33 12048 12045 32 + 12051 12045 32 12051 12048 33 12057 12054 32 12060 + 12054 32 12060 12057 33 12066 12063 32 12069 12063 + 32 12069 12066 33 12075 12072 32 12078 12072 32 + 12078 12075 33 12084 12081 32 12087 12081 32 12087 + 12084 33 12093 12090 32 12096 12090 32 12096 12093 + 33 12102 12099 32 12105 12099 32 12105 12102 33 + 12111 12108 32 12114 12108 32 12114 12111 33 12120 + 12117 32 12123 12117 32 12123 12120 33 12129 12126 + 32 12132 12126 32 12132 12129 33 12138 12135 32 + 12141 12135 32 12141 12138 33 12147 12144 32 12150 + 12144 32 12150 12147 33 12156 12153 32 12159 12153 + 32 12159 12156 33 12165 12162 32 12168 12162 32 + 12168 12165 33 12174 12171 32 12177 12171 32 12177 + 12174 33 12183 12180 32 12186 12180 32 12186 12183 + 33 12192 12189 32 12195 12189 32 12195 12192 33 + 12201 12198 32 12204 12198 32 12204 12201 33 12210 + 12207 32 12213 12207 32 12213 12210 33 12219 12216 + 32 12222 12216 32 12222 12219 33 12228 12225 32 + 12231 12225 32 12231 12228 33 12237 12234 32 12240 + 12234 32 12240 12237 33 12246 12243 32 12249 12243 + 32 12249 12246 33 12255 12252 32 12258 12252 32 + 12258 12255 33 12264 12261 32 12267 12261 32 12267 + 12264 33 12273 12270 32 12276 12270 32 12276 12273 + 33 12282 12279 32 12285 12279 32 12285 12282 33 + 12291 12288 32 12294 12288 32 12294 12291 33 12300 + 12297 32 12303 12297 32 12303 12300 33 12309 12306 + 32 12312 12306 32 12312 12309 33 12318 12315 32 + 12321 12315 32 12321 12318 33 12327 12324 32 12330 + 12324 32 12330 12327 33 12336 12333 32 12339 12333 + 32 12339 12336 33 12345 12342 32 12348 12342 32 + 12348 12345 33 12354 12351 32 12357 12351 32 12357 + 12354 33 12363 12360 32 12366 12360 32 12366 12363 + 33 12372 12369 32 12375 12369 32 12375 12372 33 + 12381 12378 32 12384 12378 32 12384 12381 33 12390 + 12387 32 12393 12387 32 12393 12390 33 12399 12396 + 32 12402 12396 32 12402 12399 33 12408 12405 32 + 12411 12405 32 12411 12408 33 12417 12414 32 12420 + 12414 32 12420 12417 33 12426 12423 32 12429 12423 + 32 12429 12426 33 12435 12432 32 12438 12432 32 + 12438 12435 33 12444 12441 32 12447 12441 32 12447 + 12444 33 12453 12450 32 12456 12450 32 12456 12453 + 33 12462 12459 32 12465 12459 32 12465 12462 33 + 12471 12468 32 12474 12468 32 12474 12471 33 12480 + 12477 32 12483 12477 32 12483 12480 33 12489 12486 + 32 12492 12486 32 12492 12489 33 12498 12495 32 + 12501 12495 32 12501 12498 33 12507 12504 32 12510 + 12504 32 12510 12507 33 12516 12513 32 12519 12513 + 32 12519 12516 33 12525 12522 32 12528 12522 32 + 12528 12525 33 12534 12531 32 12537 12531 32 12537 + 12534 33 12543 12540 32 12546 12540 32 12546 12543 + 33 12552 12549 32 12555 12549 32 12555 12552 33 + 12561 12558 32 12564 12558 32 12564 12561 33 12570 + 12567 32 12573 12567 32 12573 12570 33 12579 12576 + 32 12582 12576 32 12582 12579 33 12588 12585 32 + 12591 12585 32 12591 12588 33 12597 12594 32 12600 + 12594 32 12600 12597 33 12606 12603 32 12609 12603 + 32 12609 12606 33 12615 12612 32 12618 12612 32 + 12618 12615 33 12624 12621 32 12627 12621 32 12627 + 12624 33 12633 12630 32 12636 12630 32 12636 12633 + 33 12642 12639 32 12645 12639 32 12645 12642 33 + 12651 12648 32 12654 12648 32 12654 12651 33 12660 + 12657 32 12663 12657 32 12663 12660 33 12669 12666 + 32 12672 12666 32 12672 12669 33 12678 12675 32 + 12681 12675 32 12681 12678 33 12687 12684 32 12690 + 12684 32 12690 12687 33 12696 12693 32 12699 12693 + 32 12699 12696 33 12705 12702 32 12708 12702 32 + 12708 12705 33 12714 12711 32 12717 12711 32 12717 + 12714 33 12723 12720 32 12726 12720 32 12726 12723 + 33 12732 12729 32 12735 12729 32 12735 12732 33 + 12741 12738 32 12744 12738 32 12744 12741 33 12750 + 12747 32 12753 12747 32 12753 12750 33 12759 12756 + 32 12762 12756 32 12762 12759 33 12768 12765 32 + 12771 12765 32 12771 12768 33 12777 12774 32 12780 + 12774 32 12780 12777 33 12786 12783 32 12789 12783 + 32 12789 12786 33 12795 12792 32 12798 12792 32 + 12798 12795 33 12804 12801 32 12807 12801 32 12807 + 12804 33 12813 12810 32 12816 12810 32 12816 12813 + 33 12822 12819 32 12825 12819 32 12825 12822 33 + 12831 12828 32 12834 12828 32 12834 12831 33 12840 + 12837 32 12843 12837 32 12843 12840 33 12849 12846 + 32 12852 12846 32 12852 12849 33 12858 12855 32 + 12861 12855 32 12861 12858 33 12867 12864 32 12870 + 12864 32 12870 12867 33 12876 12873 32 12879 12873 + 32 12879 12876 33 12885 12882 32 12888 12882 32 + 12888 12885 33 12894 12891 32 12897 12891 32 12897 + 12894 33 12903 12900 32 12906 12900 32 12906 12903 + 33 12912 12909 32 12915 12909 32 12915 12912 33 + 12921 12918 32 12924 12918 32 12924 12921 33 12930 + 12927 32 12933 12927 32 12933 12930 33 12939 12936 + 32 12942 12936 32 12942 12939 33 12948 12945 32 + 12951 12945 32 12951 12948 33 12957 12954 32 12960 + 12954 32 12960 12957 33 12966 12963 32 12969 12963 + 32 12969 12966 33 12975 12972 32 12978 12972 32 + 12978 12975 33 12984 12981 32 12987 12981 32 12987 + 12984 33 12993 12990 32 12996 12990 32 12996 12993 + 33 13002 12999 32 13005 12999 32 13005 13002 33 + 13011 13008 32 13014 13008 32 13014 13011 33 13020 + 13017 32 13023 13017 32 13023 13020 33 13029 13026 + 32 13032 13026 32 13032 13029 33 13038 13035 32 + 13041 13035 32 13041 13038 33 13047 13044 32 13050 + 13044 32 13050 13047 33 13056 13053 32 13059 13053 + 32 13059 13056 33 13065 13062 32 13068 13062 32 + 13068 13065 33 13074 13071 32 13077 13071 32 13077 + 13074 33 13083 13080 32 13086 13080 32 13086 13083 + 33 13092 13089 32 13095 13089 32 13095 13092 33 + 13101 13098 32 13104 13098 32 13104 13101 33 13110 + 13107 32 13113 13107 32 13113 13110 33 13119 13116 + 32 13122 13116 32 13122 13119 33 13128 13125 32 + 13131 13125 32 13131 13128 33 13137 13134 32 13140 + 13134 32 13140 13137 33 13146 13143 32 13149 13143 + 32 13149 13146 33 13155 13152 32 13158 13152 32 + 13158 13155 33 13164 13161 32 13167 13161 32 13167 + 13164 33 13173 13170 32 13176 13170 32 13176 13173 + 33 13182 13179 32 13185 13179 32 13185 13182 33 + 13191 13188 32 13194 13188 32 13194 13191 33 13200 + 13197 32 13203 13197 32 13203 13200 33 13209 13206 + 32 13212 13206 32 13212 13209 33 13218 13215 32 + 13221 13215 32 13221 13218 33 13227 13224 32 13230 + 13224 32 13230 13227 33 13236 13233 32 13239 13233 + 32 13239 13236 33 13245 13242 32 13248 13242 32 + 13248 13245 33 13254 13251 32 13257 13251 32 13257 + 13254 33 13263 13260 32 13266 13260 32 13266 13263 + 33 13272 13269 32 13275 13269 32 13275 13272 33 + 13281 13278 32 13284 13278 32 13284 13281 33 13290 + 13287 32 13293 13287 32 13293 13290 33 13299 13296 + 32 13302 13296 32 13302 13299 33 13308 13305 32 + 13311 13305 32 13311 13308 33 13317 13314 32 13320 + 13314 32 13320 13317 33 13326 13323 32 13329 13323 + 32 13329 13326 33 13335 13332 32 13338 13332 32 + 13338 13335 33 13344 13341 32 13347 13341 32 13347 + 13344 33 13353 13350 32 13356 13350 32 13356 13353 + 33 13362 13359 32 13365 13359 32 13365 13362 33 + 13371 13368 32 13374 13368 32 13374 13371 33 13380 + 13377 32 13383 13377 32 13383 13380 33 13389 13386 + 32 13392 13386 32 13392 13389 33 13398 13395 32 + 13401 13395 32 13401 13398 33 13407 13404 32 13410 + 13404 32 13410 13407 33 13416 13413 32 13419 13413 + 32 13419 13416 33 13425 13422 32 13428 13422 32 + 13428 13425 33 13434 13431 32 13437 13431 32 13437 + 13434 33 13443 13440 32 13446 13440 32 13446 13443 + 33 13452 13449 32 13455 13449 32 13455 13452 33 + 13461 13458 32 13464 13458 32 13464 13461 33 13470 + 13467 32 13473 13467 32 13473 13470 33 13479 13476 + 32 13482 13476 32 13482 13479 33 13488 13485 32 + 13491 13485 32 13491 13488 33 13497 13494 32 13500 + 13494 32 13500 13497 33 13506 13503 32 13509 13503 + 32 13509 13506 33 13515 13512 32 13518 13512 32 + 13518 13515 33 13524 13521 32 13527 13521 32 13527 + 13524 33 13533 13530 32 13536 13530 32 13536 13533 + 33 13542 13539 32 13545 13539 32 13545 13542 33 + 13551 13548 32 13554 13548 32 13554 13551 33 13560 + 13557 32 13563 13557 32 13563 13560 33 13569 13566 + 32 13572 13566 32 13572 13569 33 13578 13575 32 + 13581 13575 32 13581 13578 33 13587 13584 32 13590 + 13584 32 13590 13587 33 13596 13593 32 13599 13593 + 32 13599 13596 33 13605 13602 32 13608 13602 32 + 13608 13605 33 13614 13611 32 13617 13611 32 13617 + 13614 33 13623 13620 32 13626 13620 32 13626 13623 + 33 13632 13629 32 13635 13629 32 13635 13632 33 + 13641 13638 32 13644 13638 32 13644 13641 33 13650 + 13647 32 13653 13647 32 13653 13650 33 13659 13656 + 32 13662 13656 32 13662 13659 33 13668 13665 32 + 13671 13665 32 13671 13668 33 13677 13674 32 13680 + 13674 32 13680 13677 33 13686 13683 32 13689 13683 + 32 13689 13686 33 13695 13692 32 13698 13692 32 + 13698 13695 33 13704 13701 32 13707 13701 32 13707 + 13704 33 13713 13710 32 13716 13710 32 13716 13713 + 33 13722 13719 32 13725 13719 32 13725 13722 33 + 13731 13728 32 13734 13728 32 13734 13731 33 13740 + 13737 32 13743 13737 32 13743 13740 33 13749 13746 + 32 13752 13746 32 13752 13749 33 13758 13755 32 + 13761 13755 32 13761 13758 33 13767 13764 32 13770 + 13764 32 13770 13767 33 13776 13773 32 13779 13773 + 32 13779 13776 33 13785 13782 32 13788 13782 32 + 13788 13785 33 13794 13791 32 13797 13791 32 13797 + 13794 33 13803 13800 32 13806 13800 32 13806 13803 + 33 13812 13809 32 13815 13809 32 13815 13812 33 + 13821 13818 32 13824 13818 32 13824 13821 33 13830 + 13827 32 13833 13827 32 13833 13830 33 13839 13836 + 32 13842 13836 32 13842 13839 33 13848 13845 32 + 13851 13845 32 13851 13848 33 13857 13854 32 13860 + 13854 32 13860 13857 33 13866 13863 32 13869 13863 + 32 13869 13866 33 13875 13872 32 13878 13872 32 + 13878 13875 33 13884 13881 32 13887 13881 32 13887 + 13884 33 13893 13890 32 13896 13890 32 13896 13893 + 33 13902 13899 32 13905 13899 32 13905 13902 33 + 13911 13908 32 13914 13908 32 13914 13911 33 13920 + 13917 32 13923 13917 32 13923 13920 33 13929 13926 + 32 13932 13926 32 13932 13929 33 13938 13935 32 + 13941 13935 32 13941 13938 33 13947 13944 32 13950 + 13944 32 13950 13947 33 13956 13953 32 13959 13953 + 32 13959 13956 33 13965 13962 32 13968 13962 32 + 13968 13965 33 13974 13971 32 13977 13971 32 13977 + 13974 33 13983 13980 32 13986 13980 32 13986 13983 + 33 13992 13989 32 13995 13989 32 13995 13992 33 + 14001 13998 32 14004 13998 32 14004 14001 33 14010 + 14007 32 14013 14007 32 14013 14010 33 14019 14016 + 32 14022 14016 32 14022 14019 33 14028 14025 32 + 14031 14025 32 14031 14028 33 14037 14034 32 14040 + 14034 32 14040 14037 33 14046 14043 32 14049 14043 + 32 14049 14046 33 14055 14052 32 14058 14052 32 + 14058 14055 33 14064 14061 32 14067 14061 32 14067 + 14064 33 14073 14070 32 14076 14070 32 14076 14073 + 33 14082 14079 32 14085 14079 32 14085 14082 33 + 14091 14088 32 14094 14088 32 14094 14091 33 14100 + 14097 32 14103 14097 32 14103 14100 33 14109 14106 + 32 14112 14106 32 14112 14109 33 14118 14115 32 + 14121 14115 32 14121 14118 33 14127 14124 32 14130 + 14124 32 14130 14127 33 14136 14133 32 14139 14133 + 32 14139 14136 33 14145 14142 32 14148 14142 32 + 14148 14145 33 14154 14151 32 14157 14151 32 14157 + 14154 33 14163 14160 32 14166 14160 32 14166 14163 + 33 14172 14169 32 14175 14169 32 14175 14172 33 + 14181 14178 32 14184 14178 32 14184 14181 33 14190 + 14187 32 14193 14187 32 14193 14190 33 14199 14196 + 32 14202 14196 32 14202 14199 33 14208 14205 32 + 14211 14205 32 14211 14208 33 14217 14214 32 14220 + 14214 32 14220 14217 33 14226 14223 32 14229 14223 + 32 14229 14226 33 14235 14232 32 14238 14232 32 + 14238 14235 33 14244 14241 32 14247 14241 32 14247 + 14244 33 14253 14250 32 14256 14250 32 14256 14253 + 33 14262 14259 32 14265 14259 32 14265 14262 33 + 14271 14268 32 14274 14268 32 14274 14271 33 14280 + 14277 32 14283 14277 32 14283 14280 33 14289 14286 + 32 14292 14286 32 14292 14289 33 14298 14295 32 + 14301 14295 32 14301 14298 33 14307 14304 32 14310 + 14304 32 14310 14307 33 14316 14313 32 14319 14313 + 32 14319 14316 33 14325 14322 32 14328 14322 32 + 14328 14325 33 14334 14331 32 14337 14331 32 14337 + 14334 33 14343 14340 32 14346 14340 32 14346 14343 + 33 14352 14349 32 14355 14349 32 14355 14352 33 + 14361 14358 32 14364 14358 32 14364 14361 33 14370 + 14367 32 14373 14367 32 14373 14370 33 14379 14376 + 32 14382 14376 32 14382 14379 33 14388 14385 32 + 14391 14385 32 14391 14388 33 14397 14394 32 14400 + 14394 32 14400 14397 33 14406 14403 32 14409 14403 + 32 14409 14406 33 14415 14412 32 14418 14412 32 + 14418 14415 33 14424 14421 32 14427 14421 32 14427 + 14424 33 14433 14430 32 14436 14430 32 14436 14433 + 33 14442 14439 32 14445 14439 32 14445 14442 33 + 14451 14448 32 14454 14448 32 14454 14451 33 14460 + 14457 32 14463 14457 32 14463 14460 33 14469 14466 + 32 14472 14466 32 14472 14469 33 14478 14475 32 + 14481 14475 32 14481 14478 33 14487 14484 32 14490 + 14484 32 14490 14487 33 14496 14493 32 14499 14493 + 32 14499 14496 33 14505 14502 32 14508 14502 32 + 14508 14505 33 14514 14511 32 14517 14511 32 14517 + 14514 33 14523 14520 32 14526 14520 32 14526 14523 + 33 14532 14529 32 14535 14529 32 14535 14532 33 + 14541 14538 32 14544 14538 32 14544 14541 33 14550 + 14547 32 14553 14547 32 14553 14550 33 14559 14556 + 32 14562 14556 32 14562 14559 33 14568 14565 32 + 14571 14565 32 14571 14568 33 14577 14574 32 14580 + 14574 32 14580 14577 33 14586 14583 32 14589 14583 + 32 14589 14586 33 14595 14592 32 14598 14592 32 + 14598 14595 33 14604 14601 32 14607 14601 32 14607 + 14604 33 14613 14610 32 14616 14610 32 14616 14613 + 33 14622 14619 32 14625 14619 32 14625 14622 33 + 14631 14628 32 14634 14628 32 14634 14631 33 14640 + 14637 32 14643 14637 32 14643 14640 33 14649 14646 + 32 14652 14646 32 14652 14649 33 14658 14655 32 + 14661 14655 32 14661 14658 33 14667 14664 32 14670 + 14664 32 14670 14667 33 14676 14673 32 14679 14673 + 32 14679 14676 33 14685 14682 32 14688 14682 32 + 14688 14685 33 14694 14691 32 14697 14691 32 14697 + 14694 33 14703 14700 32 14706 14700 32 14706 14703 + 33 14712 14709 32 14715 14709 32 14715 14712 33 + 14721 14718 32 14724 14718 32 14724 14721 33 14730 + 14727 32 14733 14727 32 14733 14730 33 14739 14736 + 32 14742 14736 32 14742 14739 33 14748 14745 32 + 14751 14745 32 14751 14748 33 14757 14754 32 14760 + 14754 32 14760 14757 33 14766 14763 32 14769 14763 + 32 14769 14766 33 14775 14772 32 14778 14772 32 + 14778 14775 33 14784 14781 32 14787 14781 32 14787 + 14784 33 14793 14790 32 14796 14790 32 14796 14793 + 33 14802 14799 32 14805 14799 32 14805 14802 33 + 14811 14808 32 14814 14808 32 14814 14811 33 14820 + 14817 32 14823 14817 32 14823 14820 33 14829 14826 + 32 14832 14826 32 14832 14829 33 14838 14835 32 + 14841 14835 32 14841 14838 33 14847 14844 32 14850 + 14844 32 14850 14847 33 14856 14853 32 14859 14853 + 32 14859 14856 33 14865 14862 32 14868 14862 32 + 14868 14865 33 14874 14871 32 14877 14871 32 14877 + 14874 33 14883 14880 32 14886 14880 32 14886 14883 + 33 14892 14889 32 14895 14889 32 14895 14892 33 + 14901 14898 32 14904 14898 32 14904 14901 33 14910 + 14907 32 14913 14907 32 14913 14910 33 14919 14916 + 32 14922 14916 32 14922 14919 33 14928 14925 32 + 14931 14925 32 14931 14928 33 14937 14934 32 14940 + 14934 32 14940 14937 33 14946 14943 32 14949 14943 + 32 14949 14946 33 14955 14952 32 14958 14952 32 + 14958 14955 33 14964 14961 32 14967 14961 32 14967 + 14964 33 14973 14970 32 14976 14970 32 14976 14973 + 33 14982 14979 32 14985 14979 32 14985 14982 33 + 14991 14988 32 14994 14988 32 14994 14991 33 15000 + 14997 32 15003 14997 32 15003 15000 33 15009 15006 + 32 15012 15006 32 15012 15009 33 15018 15015 32 + 15021 15015 32 15021 15018 33 15027 15024 32 15030 + 15024 32 15030 15027 33 15036 15033 32 15039 15033 + 32 15039 15036 33 15045 15042 32 15048 15042 32 + 15048 15045 33 15054 15051 32 15057 15051 32 15057 + 15054 33 15063 15060 32 15066 15060 32 15066 15063 + 33 15072 15069 32 15075 15069 32 15075 15072 33 + 15081 15078 32 15084 15078 32 15084 15081 33 15090 + 15087 32 15093 15087 32 15093 15090 33 15099 15096 + 32 15102 15096 32 15102 15099 33 15108 15105 32 + 15111 15105 32 15111 15108 33 15117 15114 32 15120 + 15114 32 15120 15117 33 15126 15123 32 15129 15123 + 32 15129 15126 33 15135 15132 32 15138 15132 32 + 15138 15135 33 15144 15141 32 15147 15141 32 15147 + 15144 33 15153 15150 32 15156 15150 32 15156 15153 + 33 15162 15159 32 15165 15159 32 15165 15162 33 + 15171 15168 32 15174 15168 32 15174 15171 33 15180 + 15177 32 15183 15177 32 15183 15180 33 15189 15186 + 32 15192 15186 32 15192 15189 33 15198 15195 32 + 15201 15195 32 15201 15198 33 15207 15204 32 15210 + 15204 32 15210 15207 33 15216 15213 32 15219 15213 + 32 15219 15216 33 15225 15222 32 15228 15222 32 + 15228 15225 33 15234 15231 32 15237 15231 32 15237 + 15234 33 15243 15240 32 15246 15240 32 15246 15243 + 33 15252 15249 32 15255 15249 32 15255 15252 33 + 15261 15258 32 15264 15258 32 15264 15261 33 15270 + 15267 32 15273 15267 32 15273 15270 33 15279 15276 + 32 15282 15276 32 15282 15279 33 15288 15285 32 + 15291 15285 32 15291 15288 33 15297 15294 32 15300 + 15294 32 15300 15297 33 15306 15303 32 15309 15303 + 32 15309 15306 33 15315 15312 32 15318 15312 32 + 15318 15315 33 15324 15321 32 15327 15321 32 15327 + 15324 33 15333 15330 32 15336 15330 32 15336 15333 + 33 15342 15339 32 15345 15339 32 15345 15342 33 + 15351 15348 32 15354 15348 32 15354 15351 33 15360 + 15357 32 15363 15357 32 15363 15360 33 15369 15366 + 32 15372 15366 32 15372 15369 33 15378 15375 32 + 15381 15375 32 15381 15378 33 15387 15384 32 15390 + 15384 32 15390 15387 33 15396 15393 32 15399 15393 + 32 15399 15396 33 15405 15402 32 15408 15402 32 + 15408 15405 33 15414 15411 32 15417 15411 32 15417 + 15414 33 15423 15420 32 15426 15420 32 15426 15423 + 33 15432 15429 32 15435 15429 32 15435 15432 33 + 15441 15438 32 15444 15438 32 15444 15441 33 15450 + 15447 32 15453 15447 32 15453 15450 33 15459 15456 + 32 15462 15456 32 15462 15459 33 15468 15465 32 + 15471 15465 32 15471 15468 33 15477 15474 32 15480 + 15474 32 15480 15477 33 15486 15483 32 15489 15483 + 32 15489 15486 33 15495 15492 32 15498 15492 32 + 15498 15495 33 15504 15501 32 15507 15501 32 15507 + 15504 33 15513 15510 32 15516 15510 32 15516 15513 + 33 15522 15519 32 15525 15519 32 15525 15522 33 + 15531 15528 32 15534 15528 32 15534 15531 33 15540 + 15537 32 15543 15537 32 15543 15540 33 15549 15546 + 32 15552 15546 32 15552 15549 33 15558 15555 32 + 15561 15555 32 15561 15558 33 15567 15564 32 15570 + 15564 32 15570 15567 33 15576 15573 32 15579 15573 + 32 15579 15576 33 15585 15582 32 15588 15582 32 + 15588 15585 33 15594 15591 32 15597 15591 32 15597 + 15594 33 15603 15600 32 15606 15600 32 15606 15603 + 33 15612 15609 32 15615 15609 32 15615 15612 33 + 15621 15618 32 15624 15618 32 15624 15621 33 15630 + 15627 32 15633 15627 32 15633 15630 33 15639 15636 + 32 15642 15636 32 15642 15639 33 15648 15645 32 + 15651 15645 32 15651 15648 33 15657 15654 32 15660 + 15654 32 15660 15657 33 15666 15663 32 15669 15663 + 32 15669 15666 33 15675 15672 32 15678 15672 32 + 15678 15675 33 15684 15681 32 15687 15681 32 15687 + 15684 33 15693 15690 32 15696 15690 32 15696 15693 + 33 15702 15699 32 15705 15699 32 15705 15702 33 + 15711 15708 32 15714 15708 32 15714 15711 33 15720 + 15717 32 15723 15717 32 15723 15720 33 15729 15726 + 32 15732 15726 32 15732 15729 33 15738 15735 32 + 15741 15735 32 15741 15738 33 15747 15744 32 15750 + 15744 32 15750 15747 33 15756 15753 32 15759 15753 + 32 15759 15756 33 15765 15762 32 15768 15762 32 + 15768 15765 33 15774 15771 32 15777 15771 32 15777 + 15774 33 15783 15780 32 15786 15780 32 15786 15783 + 33 15792 15789 32 15795 15789 32 15795 15792 33 + 15801 15798 32 15804 15798 32 15804 15801 33 15810 + 15807 32 15813 15807 32 15813 15810 33 15819 15816 + 32 15822 15816 32 15822 15819 33 15828 15825 32 + 15831 15825 32 15831 15828 33 15837 15834 32 15840 + 15834 32 15840 15837 33 15846 15843 32 15849 15843 + 32 15849 15846 33 15855 15852 32 15858 15852 32 + 15858 15855 33 15864 15861 32 15867 15861 32 15867 + 15864 33 15873 15870 32 15876 15870 32 15876 15873 + 33 15882 15879 32 15885 15879 32 15885 15882 33 + 15891 15888 32 15894 15888 32 15894 15891 33 15900 + 15897 32 15903 15897 32 15903 15900 33 15909 15906 + 32 15912 15906 32 15912 15909 33 15918 15915 32 + 15921 15915 32 15921 15918 33 15927 15924 32 15930 + 15924 32 15930 15927 33 15936 15933 32 15939 15933 + 32 15939 15936 33 15945 15942 32 15948 15942 32 + 15948 15945 33 15954 15951 32 15957 15951 32 15957 + 15954 33 15963 15960 32 15966 15960 32 15966 15963 + 33 15972 15969 32 15975 15969 32 15975 15972 33 + 15981 15978 32 15984 15978 32 15984 15981 33 15990 + 15987 32 15993 15987 32 15993 15990 33 15999 15996 + 32 16002 15996 32 16002 15999 33 16008 16005 32 + 16011 16005 32 16011 16008 33 16017 16014 32 16020 + 16014 32 16020 16017 33 16026 16023 32 16029 16023 + 32 16029 16026 33 16035 16032 32 16038 16032 32 + 16038 16035 33 16044 16041 32 16047 16041 32 16047 + 16044 33 16053 16050 32 16056 16050 32 16056 16053 + 33 16062 16059 32 16065 16059 32 16065 16062 33 + 16071 16068 32 16074 16068 32 16074 16071 33 16080 + 16077 32 16083 16077 32 16083 16080 33 16089 16086 + 32 16092 16086 32 16092 16089 33 16098 16095 32 + 16101 16095 32 16101 16098 33 16107 16104 32 16110 + 16104 32 16110 16107 33 16116 16113 32 16119 16113 + 32 16119 16116 33 16125 16122 32 16128 16122 32 + 16128 16125 33 16134 16131 32 16137 16131 32 16137 + 16134 33 16143 16140 32 16146 16140 32 16146 16143 + 33 16152 16149 32 16155 16149 32 16155 16152 33 + 16161 16158 32 16164 16158 32 16164 16161 33 16170 + 16167 32 16173 16167 32 16173 16170 33 16179 16176 + 32 16182 16176 32 16182 16179 33 16188 16185 32 + 16191 16185 32 16191 16188 33 16197 16194 32 16200 + 16194 32 16200 16197 33 16206 16203 32 16209 16203 + 32 16209 16206 33 16215 16212 32 16218 16212 32 + 16218 16215 33 16224 16221 32 16227 16221 32 16227 + 16224 33 16233 16230 32 16236 16230 32 16236 16233 + 33 16242 16239 32 16245 16239 32 16245 16242 33 + 16251 16248 32 16254 16248 32 16254 16251 33 16260 + 16257 32 16263 16257 32 16263 16260 33 16269 16266 + 32 16272 16266 32 16272 16269 33 16278 16275 32 + 16281 16275 32 16281 16278 33 16287 16284 32 16290 + 16284 32 16290 16287 33 16296 16293 32 16299 16293 + 32 16299 16296 33 16305 16302 32 16308 16302 32 + 16308 16305 33 16314 16311 32 16317 16311 32 16317 + 16314 33 16323 16320 32 16326 16320 32 16326 16323 + 33 16332 16329 32 16335 16329 32 16335 16332 33 + 16341 16338 32 16344 16338 32 16344 16341 33 16350 + 16347 32 16353 16347 32 16353 16350 33 16359 16356 + 32 16362 16356 32 16362 16359 33 16368 16365 32 + 16371 16365 32 16371 16368 33 16377 16374 32 16380 + 16374 32 16380 16377 33 16386 16383 32 16389 16383 + 32 16389 16386 33 16395 16392 32 16398 16392 32 + 16398 16395 33 16404 16401 32 16407 16401 32 16407 + 16404 33 16413 16410 32 16416 16410 32 16416 16413 + 33 16422 16419 32 16425 16419 32 16425 16422 33 + 16431 16428 32 16434 16428 32 16434 16431 33 16440 + 16437 32 16443 16437 32 16443 16440 33 16449 16446 + 32 16452 16446 32 16452 16449 33 16458 16455 32 + 16461 16455 32 16461 16458 33 16467 16464 32 16470 + 16464 32 16470 16467 33 16476 16473 32 16479 16473 + 32 16479 16476 33 16485 16482 32 16488 16482 32 + 16488 16485 33 16494 16491 32 16497 16491 32 16497 + 16494 33 16503 16500 32 16506 16500 32 16506 16503 + 33 16512 16509 32 16515 16509 32 16515 16512 33 + 16521 16518 32 16524 16518 32 16524 16521 33 16530 + 16527 32 16533 16527 32 16533 16530 33 16539 16536 + 32 16542 16536 32 16542 16539 33 16548 16545 32 + 16551 16545 32 16551 16548 33 16557 16554 32 16560 + 16554 32 16560 16557 33 16566 16563 32 16569 16563 + 32 16569 16566 33 16575 16572 32 16578 16572 32 + 16578 16575 33 16584 16581 32 16587 16581 32 16587 + 16584 33 16593 16590 32 16596 16590 32 16596 16593 + 33 16602 16599 32 16605 16599 32 16605 16602 33 + 16611 16608 32 16614 16608 32 16614 16611 33 16620 + 16617 32 16623 16617 32 16623 16620 33 16629 16626 + 32 16632 16626 32 16632 16629 33 16638 16635 32 + 16641 16635 32 16641 16638 33 16647 16644 32 16650 + 16644 32 16650 16647 33 16656 16653 32 16659 16653 + 32 16659 16656 33 16665 16662 32 16668 16662 32 + 16668 16665 33 16674 16671 32 16677 16671 32 16677 + 16674 33 16683 16680 32 16686 16680 32 16686 16683 + 33 16692 16689 32 16695 16689 32 16695 16692 33 + 16701 16698 32 16704 16698 32 16704 16701 33 16710 + 16707 32 16713 16707 32 16713 16710 33 16719 16716 + 32 16722 16716 32 16722 16719 33 16728 16725 32 + 16731 16725 32 16731 16728 33 16737 16734 32 16740 + 16734 32 16740 16737 33 16746 16743 32 16749 16743 + 32 16749 16746 33 16755 16752 32 16758 16752 32 + 16758 16755 33 16764 16761 32 16767 16761 32 16767 + 16764 33 16773 16770 32 16776 16770 32 16776 16773 + 33 16782 16779 32 16785 16779 32 16785 16782 33 + 16791 16788 32 16794 16788 32 16794 16791 33 16800 + 16797 32 16803 16797 32 16803 16800 33 16809 16806 + 32 16812 16806 32 16812 16809 33 16818 16815 32 + 16821 16815 32 16821 16818 33 16827 16824 32 16830 + 16824 32 16830 16827 33 16836 16833 32 16839 16833 + 32 16839 16836 33 16845 16842 32 16848 16842 32 + 16848 16845 33 16854 16851 32 16857 16851 32 16857 + 16854 33 16863 16860 32 16866 16860 32 16866 16863 + 33 16872 16869 32 16875 16869 32 16875 16872 33 + 16881 16878 32 16884 16878 32 16884 16881 33 16890 + 16887 32 16893 16887 32 16893 16890 33 16899 16896 + 32 16902 16896 32 16902 16899 33 16908 16905 32 + 16911 16905 32 16911 16908 33 16917 16914 32 16920 + 16914 32 16920 16917 33 16926 16923 32 16929 16923 + 32 16929 16926 33 16935 16932 32 16938 16932 32 + 16938 16935 33 16944 16941 32 16947 16941 32 16947 + 16944 33 16953 16950 32 16956 16950 32 16956 16953 + 33 16962 16959 32 16965 16959 32 16965 16962 33 + 16971 16968 32 16974 16968 32 16974 16971 33 16980 + 16977 32 16983 16977 32 16983 16980 33 16989 16986 + 32 16992 16986 32 16992 16989 33 16998 16995 32 + 17001 16995 32 17001 16998 33 17007 17004 32 17010 + 17004 32 17010 17007 33 17016 17013 32 17019 17013 + 32 17019 17016 33 17025 17022 32 17028 17022 32 + 17028 17025 33 17034 17031 32 17037 17031 32 17037 + 17034 33 17043 17040 32 17046 17040 32 17046 17043 + 33 17052 17049 32 17055 17049 32 17055 17052 33 + 17061 17058 32 17064 17058 32 17064 17061 33 17070 + 17067 32 17073 17067 32 17073 17070 33 17079 17076 + 32 17082 17076 32 17082 17079 33 17088 17085 32 + 17091 17085 32 17091 17088 33 17097 17094 32 17100 + 17094 32 17100 17097 33 17106 17103 32 17109 17103 + 32 17109 17106 33 17115 17112 32 17118 17112 32 + 17118 17115 33 17124 17121 32 17127 17121 32 17127 + 17124 33 17133 17130 32 17136 17130 32 17136 17133 + 33 17142 17139 32 17145 17139 32 17145 17142 33 + 17151 17148 32 17154 17148 32 17154 17151 33 17160 + 17157 32 17163 17157 32 17163 17160 33 17169 17166 + 32 17172 17166 32 17172 17169 33 17178 17175 32 + 17181 17175 32 17181 17178 33 17187 17184 32 17190 + 17184 32 17190 17187 33 17196 17193 32 17199 17193 + 32 17199 17196 33 17205 17202 32 17208 17202 32 + 17208 17205 33 17214 17211 32 17217 17211 32 17217 + 17214 33 17223 17220 32 17226 17220 32 17226 17223 + 33 17232 17229 32 17235 17229 32 17235 17232 33 + 17241 17238 32 17244 17238 32 17244 17241 33 17250 + 17247 32 17253 17247 32 17253 17250 33 17259 17256 + 32 17262 17256 32 17262 17259 33 17268 17265 32 + 17271 17265 32 17271 17268 33 17277 17274 32 17280 + 17274 32 17280 17277 33 17286 17283 32 17289 17283 + 32 17289 17286 33 17295 17292 32 17298 17292 32 + 17298 17295 33 17304 17301 32 17307 17301 32 17307 + 17304 33 17313 17310 32 17316 17310 32 17316 17313 + 33 17322 17319 32 17325 17319 32 17325 17322 33 + 17331 17328 32 17334 17328 32 17334 17331 33 17340 + 17337 32 17343 17337 32 17343 17340 33 17349 17346 + 32 17352 17346 32 17352 17349 33 17358 17355 32 + 17361 17355 32 17361 17358 33 17367 17364 32 17370 + 17364 32 17370 17367 33 17376 17373 32 17379 17373 + 32 17379 17376 33 17385 17382 32 17388 17382 32 + 17388 17385 33 17394 17391 32 17397 17391 32 17397 + 17394 33 17403 17400 32 17406 17400 32 17406 17403 + 33 17412 17409 32 17415 17409 32 17415 17412 33 + 17421 17418 32 17424 17418 32 17424 17421 33 17430 + 17427 32 17433 17427 32 17433 17430 33 17439 17436 + 32 17442 17436 32 17442 17439 33 17448 17445 32 + 17451 17445 32 17451 17448 33 17457 17454 32 17460 + 17454 32 17460 17457 33 17466 17463 32 17469 17463 + 32 17469 17466 33 17475 17472 32 17478 17472 32 + 17478 17475 33 +%FLAG BONDS_WITHOUT_HYDROGEN +%FORMAT(10I8) + 33 36 1 33 39 2 18 27 5 12 + 18 7 12 33 8 0 12 10 105 108 + 1 105 111 2 96 102 12 90 96 13 + 84 90 13 78 84 13 75 78 14 75 + 102 15 69 75 17 63 69 19 60 63 + 20 60 102 21 51 60 23 45 51 7 + 45 105 8 39 45 26 147 150 1 147 + 153 2 123 129 27 123 141 5 117 123 + 7 117 147 8 111 117 26 219 222 1 + 219 225 2 210 216 12 204 210 13 198 + 204 13 192 198 13 189 192 14 189 216 + 15 183 189 17 177 183 19 174 177 20 + 174 216 21 165 174 23 159 165 7 159 + 219 8 153 159 26 264 267 1 264 270 + 2 255 258 28 255 261 28 246 255 29 + 237 246 27 231 237 7 231 264 8 225 + 231 26 306 309 1 306 312 2 291 294 + 1 291 297 2 282 291 29 276 282 7 + 276 306 8 270 276 26 327 330 1 327 + 333 2 318 327 8 312 318 26 393 396 + 1 393 399 2 372 381 31 363 372 27 + 354 363 27 345 354 27 339 345 7 339 + 393 8 333 339 26 465 468 1 465 471 + 2 456 462 12 450 456 13 444 450 13 + 438 444 13 435 438 14 435 462 15 429 + 435 17 423 429 19 420 423 20 420 462 + 21 411 420 23 405 411 7 405 465 8 + 399 405 26 507 510 1 507 513 2 483 + 489 27 483 501 5 477 483 7 477 507 + 8 471 477 26 579 582 1 579 585 2 + 570 576 12 564 570 13 558 564 13 552 + 558 13 549 552 14 549 576 15 543 549 + 17 537 543 19 534 537 20 534 576 21 + 525 534 23 519 525 7 519 579 8 513 + 519 26 645 648 1 645 651 2 624 633 + 31 615 624 27 606 615 27 597 606 27 + 591 597 7 591 645 8 585 591 26 +%FLAG ANGLES_INC_HYDROGEN +%FORMAT(10I8) + 33 39 42 2 24 18 27 4 21 18 + 24 5 21 18 27 4 18 27 30 7 + 15 12 18 8 15 12 33 9 12 18 + 21 10 12 18 24 10 9 0 12 14 + 6 0 9 15 6 0 12 14 3 0 + 6 15 3 0 9 15 3 0 12 14 + 0 12 15 16 105 111 114 2 99 96 + 102 19 93 90 96 20 90 96 99 20 + 87 84 90 20 84 90 93 20 81 78 + 84 20 78 84 87 20 75 78 81 24 + 72 69 75 27 66 63 69 30 63 69 + 72 32 60 63 66 34 57 51 60 38 + 54 51 57 39 54 51 60 38 48 45 + 51 42 48 45 105 43 45 51 54 44 + 45 51 57 44 42 39 45 46 39 45 + 48 47 147 153 156 2 135 129 138 39 + 132 129 135 39 132 129 138 39 126 123 + 129 51 126 123 141 4 123 129 132 52 + 123 129 135 52 123 129 138 52 123 141 + 144 7 120 117 123 42 120 117 147 43 + 117 123 126 10 114 111 117 46 111 117 + 120 47 219 225 228 2 213 210 216 19 + 207 204 210 20 204 210 213 20 201 198 + 204 20 198 204 207 20 195 192 198 20 + 192 198 201 20 189 192 195 24 186 183 + 189 27 180 177 183 30 177 183 186 32 + 174 177 180 34 171 165 174 38 168 165 + 171 39 168 165 174 38 162 159 165 42 + 162 159 219 43 159 165 168 44 159 165 + 171 44 156 153 159 46 153 159 162 47 + 264 270 273 2 252 246 255 55 249 246 + 252 39 249 246 255 55 243 237 246 52 + 240 237 243 39 240 237 246 52 237 246 + 249 52 237 246 252 52 234 231 237 42 + 234 231 264 43 231 237 240 44 231 237 + 243 44 228 225 231 46 225 231 234 47 + 306 312 315 2 300 297 303 58 291 297 + 300 2 291 297 303 2 288 282 291 55 + 285 282 288 39 285 282 291 55 279 276 + 282 42 279 276 306 43 276 282 285 44 + 276 282 288 44 273 270 276 46 270 276 + 279 47 327 333 336 2 324 318 327 43 + 321 318 324 62 321 318 327 43 315 312 + 318 46 312 318 321 47 312 318 324 47 + 393 399 402 2 387 381 390 15 384 381 + 387 15 384 381 390 15 378 372 381 63 + 375 372 378 64 375 372 381 63 372 381 + 384 65 372 381 387 65 372 381 390 65 + 369 363 372 52 366 363 369 39 366 363 + 372 52 363 372 375 66 363 372 378 66 + 360 354 363 52 357 354 360 39 357 354 + 363 52 354 363 366 52 354 363 369 52 + 351 345 354 52 348 345 351 39 348 345 + 354 52 345 354 357 52 345 354 360 52 + 342 339 345 42 342 339 393 43 339 345 + 348 44 339 345 351 44 336 333 339 46 + 333 339 342 47 465 471 474 2 459 456 + 462 19 453 450 456 20 450 456 459 20 + 447 444 450 20 444 450 453 20 441 438 + 444 20 438 444 447 20 435 438 441 24 + 432 429 435 27 426 423 429 30 423 429 + 432 32 420 423 426 34 417 411 420 38 + 414 411 417 39 414 411 420 38 408 405 + 411 42 408 405 465 43 405 411 414 44 + 405 411 417 44 402 399 405 46 399 405 + 408 47 507 513 516 2 495 489 498 39 + 492 489 495 39 492 489 498 39 486 483 + 489 51 486 483 501 4 483 489 492 52 + 483 489 495 52 483 489 498 52 483 501 + 504 7 480 477 483 42 480 477 507 43 + 477 483 486 10 474 471 477 46 471 477 + 480 47 579 585 588 2 573 570 576 19 + 567 564 570 20 564 570 573 20 561 558 + 564 20 558 564 567 20 555 552 558 20 + 552 558 561 20 549 552 555 24 546 543 + 549 27 540 537 543 30 537 543 546 32 + 534 537 540 34 531 525 534 38 528 525 + 531 39 528 525 534 38 522 519 525 42 + 522 519 579 43 519 525 528 44 519 525 + 531 44 516 513 519 46 513 519 522 47 + 645 651 654 2 645 651 657 2 639 633 + 642 15 636 633 639 15 636 633 642 15 + 630 624 633 63 627 624 630 64 627 624 + 633 63 624 633 636 65 624 633 639 65 + 624 633 642 65 621 615 624 52 618 615 + 621 39 618 615 624 52 615 624 627 66 + 615 624 630 66 612 606 615 52 609 606 + 612 39 609 606 615 52 606 615 618 52 + 606 615 621 52 603 597 606 52 600 597 + 603 39 600 597 606 52 597 606 609 52 + 597 606 612 52 594 591 597 42 594 591 + 645 43 591 597 600 44 591 597 603 44 + 588 585 591 46 585 591 594 47 654 651 + 657 58 +%FLAG ANGLES_WITHOUT_HYDROGEN +%FORMAT(10I8) + 36 33 39 1 33 39 45 3 18 12 + 33 6 12 18 27 11 12 33 36 12 + 12 33 39 13 0 12 18 17 0 12 + 33 18 108 105 111 1 105 111 117 3 + 90 96 102 21 84 90 96 22 78 75 + 102 23 78 84 90 22 75 78 84 25 + 75 102 96 26 69 75 78 28 69 75 + 102 29 63 60 102 31 63 69 75 33 + 60 63 69 35 60 102 75 36 60 102 + 96 37 51 45 105 6 51 60 63 40 + 51 60 102 41 45 51 60 45 45 105 + 108 12 45 105 111 13 39 45 51 48 + 39 45 105 49 150 147 153 1 147 153 + 159 3 129 123 141 50 123 117 147 6 + 117 123 129 53 117 123 141 11 117 147 + 150 12 117 147 153 13 111 117 123 48 + 111 117 147 49 222 219 225 1 219 225 + 231 3 204 210 216 21 198 204 210 22 + 192 189 216 23 192 198 204 22 189 192 + 198 25 189 216 210 26 183 189 192 28 + 183 189 216 29 177 174 216 31 177 183 + 189 33 174 177 183 35 174 216 189 36 + 174 216 210 37 165 159 219 6 165 174 + 177 40 165 174 216 41 159 165 174 45 + 159 219 222 12 159 219 225 13 153 159 + 165 48 153 159 219 49 267 264 270 1 + 264 270 276 3 258 255 261 54 246 255 + 258 56 246 255 261 56 237 231 264 6 + 237 246 255 57 231 237 246 53 231 264 + 267 12 231 264 270 13 225 231 237 48 + 225 231 264 49 309 306 312 1 306 312 + 318 3 294 291 297 1 282 276 306 6 + 282 291 294 59 282 291 297 60 276 282 + 291 61 276 306 309 12 276 306 312 13 + 270 276 282 48 270 276 306 49 330 327 + 333 1 327 333 339 3 318 327 330 12 + 318 327 333 13 312 318 327 49 396 393 + 399 1 393 399 405 3 363 372 381 67 + 354 363 372 68 345 339 393 6 345 354 + 363 68 339 345 354 53 339 393 396 12 + 339 393 399 13 333 339 345 48 333 339 + 393 49 468 465 471 1 465 471 477 3 + 450 456 462 21 444 450 456 22 438 435 + 462 23 438 444 450 22 435 438 444 25 + 435 462 456 26 429 435 438 28 429 435 + 462 29 423 420 462 31 423 429 435 33 + 420 423 429 35 420 462 435 36 420 462 + 456 37 411 405 465 6 411 420 423 40 + 411 420 462 41 405 411 420 45 405 465 + 468 12 405 465 471 13 399 405 411 48 + 399 405 465 49 510 507 513 1 507 513 + 519 3 489 483 501 50 483 477 507 6 + 477 483 489 53 477 483 501 11 477 507 + 510 12 477 507 513 13 471 477 483 48 + 471 477 507 49 582 579 585 1 579 585 + 591 3 564 570 576 21 558 564 570 22 + 552 549 576 23 552 558 564 22 549 552 + 558 25 549 576 570 26 543 549 552 28 + 543 549 576 29 537 534 576 31 537 543 + 549 33 534 537 543 35 534 576 549 36 + 534 576 570 37 525 519 579 6 525 534 + 537 40 525 534 576 41 519 525 534 45 + 519 579 582 12 519 579 585 13 513 519 + 525 48 513 519 579 49 648 645 651 1 + 615 624 633 67 606 615 624 68 597 591 + 645 6 597 606 615 68 591 597 606 53 + 591 645 648 12 591 645 651 13 585 591 + 597 48 585 591 645 49 +%FLAG DIHEDRALS_INC_HYDROGEN +%FORMAT(10I8) + 36 33 39 42 1 36 33 -39 42 2 + 33 39 45 48 3 24 18 12 33 10 + 24 18 27 30 11 21 18 12 33 10 + 21 18 27 30 11 15 12 18 21 10 + 15 12 18 24 10 15 12 18 27 10 + 15 12 33 36 3 15 12 33 39 3 + 12 18 27 30 14 12 18 -27 30 15 + 12 33 39 42 2 9 0 12 15 10 + 9 0 12 18 10 9 0 12 33 10 + 6 0 12 15 10 6 0 12 18 10 + 6 0 12 33 10 3 0 12 15 10 + 3 0 12 18 10 3 0 12 33 10 + 0 12 18 21 10 0 12 18 24 10 + 108 105 111 114 1 108 105 -111 114 2 + 105 111 117 120 3 93 90 96 99 16 + 93 90 96 102 16 87 84 90 93 16 + 87 84 90 96 16 84 90 96 99 16 + 81 78 75 102 16 81 78 84 87 16 + 81 78 84 90 16 78 84 90 93 16 + 75 78 84 87 16 75 102 96 99 18 + 72 69 75 78 19 72 69 75 102 19 + 69 75 78 81 16 66 63 60 102 20 + 66 63 69 72 21 66 63 69 75 21 + 60 63 69 72 21 60 102 96 99 18 + 57 51 45 105 10 57 51 60 63 3 + 57 51 60 102 3 54 51 45 105 10 + 54 51 60 63 3 54 51 60 102 3 + 51 60 63 66 20 48 45 51 54 10 + 48 45 51 57 10 48 45 51 60 10 + 48 45 105 108 23 48 45 -105 108 3 + 48 45 -105 108 24 48 45 105 111 3 + 45 105 111 114 2 42 39 45 48 3 + 42 39 45 51 3 42 39 45 105 3 + 39 45 51 54 10 39 45 51 57 10 + 150 147 153 156 1 150 147 -153 156 2 + 147 153 159 162 3 138 129 123 141 14 + 138 129 -123 141 28 135 129 123 141 14 + 135 129 -123 141 28 132 129 123 141 14 + 132 129 -123 141 28 129 123 141 144 14 + 129 123 -141 144 15 126 123 117 147 10 + 126 123 129 132 10 126 123 129 135 10 + 126 123 129 138 10 126 123 141 144 11 + 120 117 123 126 10 120 117 123 129 10 + 120 117 123 141 14 120 117 -123 141 28 + 120 117 147 150 23 120 117 -147 150 3 + 120 117 -147 150 24 120 117 147 153 3 + 117 123 129 132 15 117 123 129 135 15 + 117 123 129 138 15 117 123 141 144 14 + 117 123 -141 144 15 117 147 153 156 2 + 114 111 117 120 3 114 111 117 123 3 + 114 111 117 147 3 111 117 123 126 10 + 222 219 225 228 1 222 219 -225 228 2 + 219 225 231 234 3 207 204 210 213 16 + 207 204 210 216 16 201 198 204 207 16 + 201 198 204 210 16 198 204 210 213 16 + 195 192 189 216 16 195 192 198 201 16 + 195 192 198 204 16 192 198 204 207 16 + 189 192 198 201 16 189 216 210 213 18 + 186 183 189 192 19 186 183 189 216 19 + 183 189 192 195 16 180 177 174 216 20 + 180 177 183 186 21 180 177 183 189 21 + 174 177 183 186 21 174 216 210 213 18 + 171 165 159 219 10 171 165 174 177 3 + 171 165 174 216 3 168 165 159 219 10 + 168 165 174 177 3 168 165 174 216 3 + 165 174 177 180 20 162 159 165 168 10 + 162 159 165 171 10 162 159 165 174 10 + 162 159 219 222 23 162 159 -219 222 3 + 162 159 -219 222 24 162 159 219 225 3 + 159 219 225 228 2 156 153 159 162 3 + 156 153 159 165 3 156 153 159 219 3 + 153 159 165 168 10 153 159 165 171 10 + 267 264 270 273 1 267 264 -270 273 2 + 264 270 276 279 3 252 246 255 258 3 + 252 246 255 261 3 249 246 255 258 3 + 249 246 255 261 3 243 237 231 264 10 + 243 237 246 249 29 243 237 246 252 29 + 243 237 246 255 10 240 237 231 264 10 + 240 237 246 249 29 240 237 246 252 29 + 240 237 246 255 10 234 231 237 240 10 + 234 231 237 243 10 234 231 237 246 10 + 234 231 264 267 23 234 231 -264 267 3 + 234 231 -264 267 24 234 231 264 270 3 + 231 237 246 249 15 231 237 246 252 15 + 231 264 270 273 2 228 225 231 234 3 + 228 225 231 237 3 228 225 231 264 3 + 225 231 237 240 10 225 231 237 243 10 + 309 306 312 315 1 309 306 -312 315 2 + 306 312 318 321 3 306 312 318 324 3 + 294 291 297 300 1 294 291 -297 300 2 + 294 291 297 303 1 294 291 -297 303 2 + 288 282 276 306 10 288 282 291 294 23 + 288 282 -291 294 3 288 282 -291 294 24 + 288 282 291 297 3 285 282 276 306 10 + 285 282 291 294 23 285 282 -291 294 3 + 285 282 -291 294 24 285 282 291 297 3 + 282 291 297 300 2 282 291 297 303 2 + 279 276 282 285 10 279 276 282 288 10 + 279 276 282 291 10 279 276 306 309 23 + 279 276 -306 309 3 279 276 -306 309 24 + 279 276 306 312 3 276 306 312 315 2 + 273 270 276 279 3 273 270 276 282 3 + 273 270 276 306 3 270 276 282 285 10 + 270 276 282 288 10 330 327 333 336 1 + 330 327 -333 336 2 327 333 339 342 3 + 324 318 327 330 23 324 318 -327 330 3 + 324 318 -327 330 24 324 318 327 333 3 + 321 318 327 330 23 321 318 -327 330 3 + 321 318 -327 330 24 321 318 327 333 3 + 318 327 333 336 2 315 312 318 321 3 + 315 312 318 324 3 315 312 318 327 3 + 396 393 399 402 1 396 393 -399 402 2 + 393 399 405 408 3 378 372 381 384 10 + 378 372 381 387 10 378 372 381 390 10 + 375 372 381 384 10 375 372 381 387 10 + 375 372 381 390 10 369 363 372 375 10 + 369 363 372 378 10 369 363 372 381 10 + 366 363 372 375 10 366 363 372 378 10 + 366 363 372 381 10 363 372 381 384 10 + 363 372 381 387 10 363 372 381 390 10 + 360 354 363 366 29 360 354 363 369 29 + 360 354 363 372 15 357 354 363 366 29 + 357 354 363 369 29 357 354 363 372 15 + 354 363 372 375 10 354 363 372 378 10 + 351 345 339 393 10 351 345 354 357 29 + 351 345 354 360 29 351 345 354 363 15 + 348 345 339 393 10 348 345 354 357 29 + 348 345 354 360 29 348 345 354 363 15 + 345 354 363 366 15 345 354 363 369 15 + 342 339 345 348 10 342 339 345 351 10 + 342 339 345 354 10 342 339 393 396 23 + 342 339 -393 396 3 342 339 -393 396 24 + 342 339 393 399 3 339 345 354 357 15 + 339 345 354 360 15 339 393 399 402 2 + 336 333 339 342 3 336 333 339 345 3 + 336 333 339 393 3 333 339 345 348 10 + 333 339 345 351 10 468 465 471 474 1 + 468 465 -471 474 2 465 471 477 480 3 + 453 450 456 459 16 453 450 456 462 16 + 447 444 450 453 16 447 444 450 456 16 + 444 450 456 459 16 441 438 435 462 16 + 441 438 444 447 16 441 438 444 450 16 + 438 444 450 453 16 435 438 444 447 16 + 435 462 456 459 18 432 429 435 438 19 + 432 429 435 462 19 429 435 438 441 16 + 426 423 420 462 20 426 423 429 432 21 + 426 423 429 435 21 420 423 429 432 21 + 420 462 456 459 18 417 411 405 465 10 + 417 411 420 423 3 417 411 420 462 3 + 414 411 405 465 10 414 411 420 423 3 + 414 411 420 462 3 411 420 423 426 20 + 408 405 411 414 10 408 405 411 417 10 + 408 405 411 420 10 408 405 465 468 23 + 408 405 -465 468 3 408 405 -465 468 24 + 408 405 465 471 3 405 465 471 474 2 + 402 399 405 408 3 402 399 405 411 3 + 402 399 405 465 3 399 405 411 414 10 + 399 405 411 417 10 510 507 513 516 1 + 510 507 -513 516 2 507 513 519 522 3 + 498 489 483 501 14 498 489 -483 501 28 + 495 489 483 501 14 495 489 -483 501 28 + 492 489 483 501 14 492 489 -483 501 28 + 489 483 501 504 14 489 483 -501 504 15 + 486 483 477 507 10 486 483 489 492 10 + 486 483 489 495 10 486 483 489 498 10 + 486 483 501 504 11 480 477 483 486 10 + 480 477 483 489 10 480 477 483 501 14 + 480 477 -483 501 28 480 477 507 510 23 + 480 477 -507 510 3 480 477 -507 510 24 + 480 477 507 513 3 477 483 489 492 15 + 477 483 489 495 15 477 483 489 498 15 + 477 483 501 504 14 477 483 -501 504 15 + 477 507 513 516 2 474 471 477 480 3 + 474 471 477 483 3 474 471 477 507 3 + 471 477 483 486 10 582 579 585 588 1 + 582 579 -585 588 2 579 585 591 594 3 + 567 564 570 573 16 567 564 570 576 16 + 561 558 564 567 16 561 558 564 570 16 + 558 564 570 573 16 555 552 549 576 16 + 555 552 558 561 16 555 552 558 564 16 + 552 558 564 567 16 549 552 558 561 16 + 549 576 570 573 18 546 543 549 552 19 + 546 543 549 576 19 543 549 552 555 16 + 540 537 534 576 20 540 537 543 546 21 + 540 537 543 549 21 534 537 543 546 21 + 534 576 570 573 18 531 525 519 579 10 + 531 525 534 537 3 531 525 534 576 3 + 528 525 519 579 10 528 525 534 537 3 + 528 525 534 576 3 525 534 537 540 20 + 522 519 525 528 10 522 519 525 531 10 + 522 519 525 534 10 522 519 579 582 23 + 522 519 -579 582 3 522 519 -579 582 24 + 522 519 579 585 3 519 579 585 588 2 + 516 513 519 522 3 516 513 519 525 3 + 516 513 519 579 3 513 519 525 528 10 + 513 519 525 531 10 648 645 651 654 1 + 648 645 -651 654 2 648 645 651 657 1 + 648 645 -651 657 2 630 624 633 636 10 + 630 624 633 639 10 630 624 633 642 10 + 627 624 633 636 10 627 624 633 639 10 + 627 624 633 642 10 621 615 624 627 10 + 621 615 624 630 10 621 615 624 633 10 + 618 615 624 627 10 618 615 624 630 10 + 618 615 624 633 10 615 624 633 636 10 + 615 624 633 639 10 615 624 633 642 10 + 612 606 615 618 29 612 606 615 621 29 + 612 606 615 624 15 609 606 615 618 29 + 609 606 615 621 29 609 606 615 624 15 + 606 615 624 627 10 606 615 624 630 10 + 603 597 591 645 10 603 597 606 609 29 + 603 597 606 612 29 603 597 606 615 15 + 600 597 591 645 10 600 597 606 609 29 + 600 597 606 612 29 600 597 606 615 15 + 597 606 615 618 15 597 606 615 621 15 + 594 591 597 600 10 594 591 597 603 10 + 594 591 597 606 10 594 591 645 648 23 + 594 591 -645 648 3 594 591 -645 648 24 + 594 591 645 651 3 591 597 606 609 15 + 591 597 606 612 15 591 645 651 654 2 + 591 645 651 657 2 588 585 591 594 3 + 588 585 591 597 3 588 585 591 645 3 + 585 591 597 600 10 585 591 597 603 10 + 90 102 -96 -99 34 84 96 -90 -93 34 + 78 90 -84 -87 34 75 84 -78 -81 34 + 63 75 -69 -72 35 60 69 -63 -66 34 + 33 45 -39 -42 34 105 117 -111 -114 34 + 204 216 -210 -213 34 198 210 -204 -207 34 + 192 204 -198 -201 34 189 198 -192 -195 34 + 177 189 -183 -186 35 174 183 -177 -180 34 + 147 159 -153 -156 34 219 231 -225 -228 34 + 291 300 -297 -303 35 264 276 -270 -273 34 + 306 318 -312 -315 34 327 339 -333 -336 34 + 450 462 -456 -459 34 444 456 -450 -453 34 + 438 450 -444 -447 34 435 444 -438 -441 34 + 423 435 -429 -432 35 420 429 -423 -426 34 + 393 405 -399 -402 34 465 477 -471 -474 34 + 564 576 -570 -573 34 558 570 -564 -567 34 + 552 564 -558 -561 34 549 558 -552 -555 34 + 537 549 -543 -546 35 534 543 -537 -540 34 + 507 519 -513 -516 34 579 591 -585 -588 34 + 645 654 -651 -657 35 +%FLAG DIHEDRALS_WITHOUT_HYDROGEN +%FORMAT(10I8) + 36 33 39 45 2 33 39 45 51 1 + 33 39 -45 51 4 33 39 -45 51 5 + 33 39 -45 51 6 33 39 45 105 7 + 33 39 -45 105 8 33 39 -45 105 9 + 33 39 -45 105 6 27 18 12 33 10 + 18 12 33 36 3 18 12 33 39 12 + 18 12 -33 39 13 18 12 -33 39 5 + 18 12 -33 39 6 12 33 39 45 2 + 0 12 18 27 10 0 12 33 36 3 + 0 12 33 39 3 108 105 111 117 2 + 105 111 117 123 1 105 111 -117 123 4 + 105 111 -117 123 5 105 111 -117 123 6 + 105 111 117 147 7 105 111 -117 147 8 + 105 111 -117 147 9 105 111 -117 147 6 + 84 78 75 102 16 84 90 -96 102 16 + 78 75 102 96 17 78 84 -90 96 16 + 75 78 84 90 16 75 102 -96 90 18 + 69 63 -60 102 20 69 75 78 84 16 + 69 75 102 96 17 63 60 -102 75 22 + 63 60 102 96 22 63 69 75 78 19 + 63 69 -75 102 19 60 51 45 105 10 + 60 63 -69 75 21 60 102 -75 69 17 + 60 102 75 78 17 60 102 96 90 18 + 51 45 105 108 3 51 45 105 111 12 + 51 45 -105 111 13 51 45 -105 111 5 + 51 45 -105 111 6 51 60 63 69 20 + 51 60 102 75 22 51 60 102 96 22 + 45 51 60 63 3 45 51 60 102 3 + 45 105 111 117 2 39 45 51 60 10 + 39 45 105 108 3 39 45 105 111 25 + 39 45 -105 111 26 39 45 -105 111 27 + 39 45 -105 111 6 150 147 153 159 2 + 147 153 159 165 1 147 153 -159 165 4 + 147 153 -159 165 5 147 153 -159 165 6 + 147 153 159 219 7 147 153 -159 219 8 + 147 153 -159 219 9 147 153 -159 219 6 + 141 123 117 147 10 129 123 117 147 10 + 123 117 147 150 3 123 117 147 153 12 + 123 117 -147 153 13 123 117 -147 153 5 + 123 117 -147 153 6 117 147 153 159 2 + 111 117 123 129 10 111 117 123 141 10 + 111 117 147 150 3 111 117 147 153 25 + 111 117 -147 153 26 111 117 -147 153 27 + 111 117 -147 153 6 222 219 225 231 2 + 219 225 231 237 1 219 225 -231 237 4 + 219 225 -231 237 5 219 225 -231 237 6 + 219 225 231 264 7 219 225 -231 264 8 + 219 225 -231 264 9 219 225 -231 264 6 + 198 192 189 216 16 198 204 -210 216 16 + 192 189 216 210 17 192 198 -204 210 16 + 189 192 198 204 16 189 216 -210 204 18 + 183 177 -174 216 20 183 189 192 198 16 + 183 189 216 210 17 177 174 -216 189 22 + 177 174 216 210 22 177 183 189 192 19 + 177 183 -189 216 19 174 165 159 219 10 + 174 177 -183 189 21 174 216 -189 183 17 + 174 216 189 192 17 174 216 210 204 18 + 165 159 219 222 3 165 159 219 225 12 + 165 159 -219 225 13 165 159 -219 225 5 + 165 159 -219 225 6 165 174 177 183 20 + 165 174 216 189 22 165 174 216 210 22 + 159 165 174 177 3 159 165 174 216 3 + 159 219 225 231 2 153 159 165 174 10 + 153 159 219 222 3 153 159 219 225 25 + 153 159 -219 225 26 153 159 -219 225 27 + 153 159 -219 225 6 267 264 270 276 2 + 264 270 276 282 1 264 270 -276 282 4 + 264 270 -276 282 5 264 270 -276 282 6 + 264 270 276 306 7 264 270 -276 306 8 + 264 270 -276 306 9 264 270 -276 306 6 + 246 237 231 264 10 237 231 264 267 3 + 237 231 264 270 12 237 231 -264 270 13 + 237 231 -264 270 5 237 231 -264 270 6 + 237 246 255 258 3 237 246 255 261 3 + 231 237 246 255 10 231 264 270 276 2 + 225 231 237 246 10 225 231 264 267 3 + 225 231 264 270 25 225 231 -264 270 26 + 225 231 -264 270 27 225 231 -264 270 6 + 309 306 312 318 2 306 312 318 327 7 + 306 312 -318 327 8 306 312 -318 327 9 + 306 312 -318 327 6 291 282 276 306 10 + 282 276 306 309 3 282 276 306 312 12 + 282 276 -306 312 13 282 276 -306 312 5 + 282 276 -306 312 6 276 282 291 294 3 + 276 282 291 297 12 276 282 -291 297 13 + 276 282 -291 297 5 276 282 -291 297 6 + 276 306 312 318 2 270 276 282 291 10 + 270 276 306 309 3 270 276 306 312 25 + 270 276 -306 312 26 270 276 -306 312 27 + 270 276 -306 312 6 330 327 333 339 2 + 327 333 339 345 1 327 333 -339 345 4 + 327 333 -339 345 5 327 333 -339 345 6 + 327 333 339 393 7 327 333 -339 393 8 + 327 333 -339 393 9 327 333 -339 393 6 + 318 327 333 339 2 312 318 327 330 3 + 312 318 327 333 25 312 318 -327 333 26 + 312 318 -327 333 27 312 318 -327 333 6 + 396 393 399 405 2 393 399 405 411 1 + 393 399 -405 411 4 393 399 -405 411 5 + 393 399 -405 411 6 393 399 405 465 7 + 393 399 -405 465 8 393 399 -405 465 9 + 393 399 -405 465 6 354 345 339 393 10 + 354 363 372 381 10 345 339 393 396 3 + 345 339 393 399 12 345 339 -393 399 13 + 345 339 -393 399 5 345 339 -393 399 6 + 345 354 363 372 30 345 354 -363 372 31 + 345 354 -363 372 32 339 345 354 363 30 + 339 345 -354 363 31 339 345 -354 363 32 + 339 393 399 405 2 333 339 345 354 10 + 333 339 393 396 3 333 339 393 399 25 + 333 339 -393 399 26 333 339 -393 399 27 + 333 339 -393 399 6 468 465 471 477 2 + 465 471 477 483 1 465 471 -477 483 4 + 465 471 -477 483 5 465 471 -477 483 6 + 465 471 477 507 7 465 471 -477 507 8 + 465 471 -477 507 9 465 471 -477 507 6 + 444 438 435 462 16 444 450 -456 462 16 + 438 435 462 456 17 438 444 -450 456 16 + 435 438 444 450 16 435 462 -456 450 18 + 429 423 -420 462 20 429 435 438 444 16 + 429 435 462 456 17 423 420 -462 435 22 + 423 420 462 456 22 423 429 435 438 19 + 423 429 -435 462 19 420 411 405 465 10 + 420 423 -429 435 21 420 462 -435 429 17 + 420 462 435 438 17 420 462 456 450 18 + 411 405 465 468 3 411 405 465 471 12 + 411 405 -465 471 13 411 405 -465 471 5 + 411 405 -465 471 6 411 420 423 429 20 + 411 420 462 435 22 411 420 462 456 22 + 405 411 420 423 3 405 411 420 462 3 + 405 465 471 477 2 399 405 411 420 10 + 399 405 465 468 3 399 405 465 471 25 + 399 405 -465 471 26 399 405 -465 471 27 + 399 405 -465 471 6 510 507 513 519 2 + 507 513 519 525 1 507 513 -519 525 4 + 507 513 -519 525 5 507 513 -519 525 6 + 507 513 519 579 7 507 513 -519 579 8 + 507 513 -519 579 9 507 513 -519 579 6 + 501 483 477 507 10 489 483 477 507 10 + 483 477 507 510 3 483 477 507 513 12 + 483 477 -507 513 13 483 477 -507 513 5 + 483 477 -507 513 6 477 507 513 519 2 + 471 477 483 489 10 471 477 483 501 10 + 471 477 507 510 3 471 477 507 513 25 + 471 477 -507 513 26 471 477 -507 513 27 + 471 477 -507 513 6 582 579 585 591 2 + 579 585 591 597 1 579 585 -591 597 4 + 579 585 -591 597 5 579 585 -591 597 6 + 579 585 591 645 7 579 585 -591 645 8 + 579 585 -591 645 9 579 585 -591 645 6 + 558 552 549 576 16 558 564 -570 576 16 + 552 549 576 570 17 552 558 -564 570 16 + 549 552 558 564 16 549 576 -570 564 18 + 543 537 -534 576 20 543 549 552 558 16 + 543 549 576 570 17 537 534 -576 549 22 + 537 534 576 570 22 537 543 549 552 19 + 537 543 -549 576 19 534 525 519 579 10 + 534 537 -543 549 21 534 576 -549 543 17 + 534 576 549 552 17 534 576 570 564 18 + 525 519 579 582 3 525 519 579 585 12 + 525 519 -579 585 13 525 519 -579 585 5 + 525 519 -579 585 6 525 534 537 543 20 + 525 534 576 549 22 525 534 576 570 22 + 519 525 534 537 3 519 525 534 576 3 + 519 579 585 591 2 513 519 525 534 10 + 513 519 579 582 3 513 519 579 585 25 + 513 519 -579 585 26 513 519 -579 585 27 + 513 519 -579 585 6 606 597 591 645 10 + 606 615 624 633 10 597 591 645 648 3 + 597 591 645 651 12 597 591 -645 651 13 + 597 591 -645 651 5 597 591 -645 651 6 + 597 606 615 624 30 597 606 -615 624 31 + 597 606 -615 624 32 591 597 606 615 30 + 591 597 -606 615 31 591 597 -606 615 32 + 585 591 597 606 10 585 591 645 648 3 + 585 591 645 651 25 585 591 -645 651 26 + 585 591 -645 651 27 585 591 -645 651 6 + 12 39 -33 -36 33 45 111 -105 -108 33 + 102 51 -60 -63 34 117 153 -147 -150 33 + 159 225 -219 -222 33 216 165 -174 -177 34 + 231 270 -264 -267 33 246 258 -255 -261 33 + 276 312 -306 -309 33 282 297 -291 -294 33 + 318 333 -327 -330 33 339 399 -393 -396 33 + 405 471 -465 -468 33 462 411 -420 -423 34 + 477 513 -507 -510 33 519 585 -579 -582 33 + 576 525 -534 -537 34 591 651 -645 -648 33 +%FLAG EXCLUDED_ATOMS_LIST +%FORMAT(10I8) + 2 3 4 5 6 7 8 9 10 12 + 13 14 3 4 5 6 7 12 4 5 + 6 7 12 5 6 7 12 6 7 8 + 9 10 11 12 13 14 15 16 7 8 + 9 10 12 13 14 8 9 10 11 12 + 13 14 9 10 11 12 10 11 12 11 + 12 0 13 14 15 16 17 18 36 14 + 15 16 15 16 17 18 19 20 21 36 + 37 38 16 17 18 36 17 18 19 20 + 21 22 35 36 37 38 39 40 18 19 + 20 21 36 37 38 19 20 21 22 23 + 24 26 33 35 36 37 38 20 21 22 + 35 36 21 22 35 36 22 23 24 25 + 26 27 31 33 34 35 36 23 24 25 + 26 27 33 35 24 25 26 35 25 26 + 27 28 29 33 35 26 27 35 27 28 + 29 30 31 33 34 35 28 29 30 31 + 32 33 35 29 30 31 35 30 31 32 + 33 34 35 31 32 33 32 33 34 35 + 33 34 35 34 35 35 0 37 38 39 + 40 41 42 50 38 39 40 39 40 41 + 42 43 44 48 50 51 52 40 41 42 + 50 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 42 43 44 48 50 + 51 52 43 44 45 46 47 48 49 50 + 51 52 44 45 46 47 48 49 50 45 + 46 47 48 49 50 46 47 48 47 48 + 48 49 50 0 51 52 53 54 55 56 + 74 52 53 54 53 54 55 56 57 58 + 59 74 75 76 54 55 56 74 55 56 + 57 58 59 60 73 74 75 76 77 78 + 56 57 58 59 74 75 76 57 58 59 + 60 61 62 64 71 73 74 75 76 58 + 59 60 73 74 59 60 73 74 60 61 + 62 63 64 65 69 71 72 73 74 61 + 62 63 64 65 71 73 62 63 64 73 + 63 64 65 66 67 71 73 64 65 73 + 65 66 67 68 69 71 72 73 66 67 + 68 69 70 71 73 67 68 69 73 68 + 69 70 71 72 73 69 70 71 70 71 + 72 73 71 72 73 72 73 73 0 75 + 76 77 78 79 80 89 76 77 78 77 + 78 79 80 81 82 83 89 90 91 78 + 79 80 89 79 80 81 82 83 84 85 + 86 89 90 91 92 93 80 81 82 83 + 89 90 91 81 82 83 84 85 86 87 + 88 89 90 91 82 83 84 85 86 89 + 83 84 85 86 89 84 85 86 87 88 + 89 85 86 87 88 86 87 88 87 88 + 88 0 90 91 92 93 94 95 103 91 + 92 93 92 93 94 95 96 97 98 103 + 104 105 93 94 95 103 94 95 96 97 + 98 99 100 103 104 105 106 107 95 96 + 97 98 103 104 105 96 97 98 99 100 + 101 102 103 104 105 97 98 99 100 103 + 98 99 100 103 99 100 101 102 103 100 + 101 102 101 102 102 0 104 105 106 107 + 108 109 110 105 106 107 106 107 108 109 + 110 111 112 107 108 109 110 108 109 110 + 111 112 113 114 109 110 111 112 110 111 + 112 111 112 113 114 115 116 132 112 113 + 114 113 114 115 116 117 118 119 132 133 + 134 114 115 116 132 115 116 117 118 119 + 120 121 122 132 133 134 135 136 116 117 + 118 119 132 133 134 117 118 119 120 121 + 122 123 124 125 132 133 134 118 119 120 + 121 122 132 119 120 121 122 132 120 121 + 122 123 124 125 126 127 128 132 121 122 + 123 124 125 122 123 124 125 123 124 125 + 126 127 128 129 130 131 124 125 126 127 + 128 125 126 127 128 126 127 128 129 130 + 131 127 128 129 130 131 128 129 130 131 + 129 130 131 130 131 131 0 133 134 135 + 136 137 138 156 134 135 136 135 136 137 + 138 139 140 141 156 157 158 136 137 138 + 156 137 138 139 140 141 142 155 156 157 + 158 159 160 138 139 140 141 156 157 158 + 139 140 141 142 143 144 146 153 155 156 + 157 158 140 141 142 155 156 141 142 155 + 156 142 143 144 145 146 147 151 153 154 + 155 156 143 144 145 146 147 153 155 144 + 145 146 155 145 146 147 148 149 153 155 + 146 147 155 147 148 149 150 151 153 154 + 155 148 149 150 151 152 153 155 149 150 + 151 155 150 151 152 153 154 155 151 152 + 153 152 153 154 155 153 154 155 154 155 + 155 0 157 158 159 160 161 162 170 158 + 159 160 159 160 161 162 163 164 168 170 + 171 172 160 161 162 170 161 162 163 164 + 165 166 167 168 169 170 171 172 173 174 + 162 163 164 168 170 171 172 163 164 165 + 166 167 168 169 170 171 172 164 165 166 + 167 168 169 170 165 166 167 168 169 170 + 166 167 168 167 168 168 169 170 0 171 + 172 173 174 175 176 194 172 173 174 173 + 174 175 176 177 178 179 194 195 196 174 + 175 176 194 175 176 177 178 179 180 193 + 194 195 196 197 198 176 177 178 179 194 + 195 196 177 178 179 180 181 182 184 191 + 193 194 195 196 178 179 180 193 194 179 + 180 193 194 180 181 182 183 184 185 189 + 191 192 193 194 181 182 183 184 185 191 + 193 182 183 184 193 183 184 185 186 187 + 191 193 184 185 193 185 186 187 188 189 + 191 192 193 186 187 188 189 190 191 193 + 187 188 189 193 188 189 190 191 192 193 + 189 190 191 190 191 192 193 191 192 193 + 192 193 193 0 195 196 197 198 199 200 + 216 196 197 198 197 198 199 200 201 202 + 203 216 217 218 198 199 200 216 199 200 + 201 202 203 204 205 206 216 217 218 219 + 220 200 201 202 203 216 217 218 201 202 + 203 204 205 206 207 208 209 216 217 218 + 202 203 204 205 206 216 203 204 205 206 + 216 204 205 206 207 208 209 210 211 212 + 216 205 206 207 208 209 206 207 208 209 + 207 208 209 210 211 212 213 214 215 208 + 209 210 211 212 209 210 211 212 210 211 + 212 213 214 215 211 212 213 214 215 212 + 213 214 215 213 214 215 214 215 215 0 + 217 218 219 220 218 219 220 219 220 220 + 0 222 223 223 0 225 226 226 0 228 + 229 229 0 231 232 232 0 234 235 235 + 0 237 238 238 0 240 241 241 0 243 + 244 244 0 246 247 247 0 249 250 250 + 0 252 253 253 0 255 256 256 0 258 + 259 259 0 261 262 262 0 264 265 265 + 0 267 268 268 0 270 271 271 0 273 + 274 274 0 276 277 277 0 279 280 280 + 0 282 283 283 0 285 286 286 0 288 + 289 289 0 291 292 292 0 294 295 295 + 0 297 298 298 0 300 301 301 0 303 + 304 304 0 306 307 307 0 309 310 310 + 0 312 313 313 0 315 316 316 0 318 + 319 319 0 321 322 322 0 324 325 325 + 0 327 328 328 0 330 331 331 0 333 + 334 334 0 336 337 337 0 339 340 340 + 0 342 343 343 0 345 346 346 0 348 + 349 349 0 351 352 352 0 354 355 355 + 0 357 358 358 0 360 361 361 0 363 + 364 364 0 366 367 367 0 369 370 370 + 0 372 373 373 0 375 376 376 0 378 + 379 379 0 381 382 382 0 384 385 385 + 0 387 388 388 0 390 391 391 0 393 + 394 394 0 396 397 397 0 399 400 400 + 0 402 403 403 0 405 406 406 0 408 + 409 409 0 411 412 412 0 414 415 415 + 0 417 418 418 0 420 421 421 0 423 + 424 424 0 426 427 427 0 429 430 430 + 0 432 433 433 0 435 436 436 0 438 + 439 439 0 441 442 442 0 444 445 445 + 0 447 448 448 0 450 451 451 0 453 + 454 454 0 456 457 457 0 459 460 460 + 0 462 463 463 0 465 466 466 0 468 + 469 469 0 471 472 472 0 474 475 475 + 0 477 478 478 0 480 481 481 0 483 + 484 484 0 486 487 487 0 489 490 490 + 0 492 493 493 0 495 496 496 0 498 + 499 499 0 501 502 502 0 504 505 505 + 0 507 508 508 0 510 511 511 0 513 + 514 514 0 516 517 517 0 519 520 520 + 0 522 523 523 0 525 526 526 0 528 + 529 529 0 531 532 532 0 534 535 535 + 0 537 538 538 0 540 541 541 0 543 + 544 544 0 546 547 547 0 549 550 550 + 0 552 553 553 0 555 556 556 0 558 + 559 559 0 561 562 562 0 564 565 565 + 0 567 568 568 0 570 571 571 0 573 + 574 574 0 576 577 577 0 579 580 580 + 0 582 583 583 0 585 586 586 0 588 + 589 589 0 591 592 592 0 594 595 595 + 0 597 598 598 0 600 601 601 0 603 + 604 604 0 606 607 607 0 609 610 610 + 0 612 613 613 0 615 616 616 0 618 + 619 619 0 621 622 622 0 624 625 625 + 0 627 628 628 0 630 631 631 0 633 + 634 634 0 636 637 637 0 639 640 640 + 0 642 643 643 0 645 646 646 0 648 + 649 649 0 651 652 652 0 654 655 655 + 0 657 658 658 0 660 661 661 0 663 + 664 664 0 666 667 667 0 669 670 670 + 0 672 673 673 0 675 676 676 0 678 + 679 679 0 681 682 682 0 684 685 685 + 0 687 688 688 0 690 691 691 0 693 + 694 694 0 696 697 697 0 699 700 700 + 0 702 703 703 0 705 706 706 0 708 + 709 709 0 711 712 712 0 714 715 715 + 0 717 718 718 0 720 721 721 0 723 + 724 724 0 726 727 727 0 729 730 730 + 0 732 733 733 0 735 736 736 0 738 + 739 739 0 741 742 742 0 744 745 745 + 0 747 748 748 0 750 751 751 0 753 + 754 754 0 756 757 757 0 759 760 760 + 0 762 763 763 0 765 766 766 0 768 + 769 769 0 771 772 772 0 774 775 775 + 0 777 778 778 0 780 781 781 0 783 + 784 784 0 786 787 787 0 789 790 790 + 0 792 793 793 0 795 796 796 0 798 + 799 799 0 801 802 802 0 804 805 805 + 0 807 808 808 0 810 811 811 0 813 + 814 814 0 816 817 817 0 819 820 820 + 0 822 823 823 0 825 826 826 0 828 + 829 829 0 831 832 832 0 834 835 835 + 0 837 838 838 0 840 841 841 0 843 + 844 844 0 846 847 847 0 849 850 850 + 0 852 853 853 0 855 856 856 0 858 + 859 859 0 861 862 862 0 864 865 865 + 0 867 868 868 0 870 871 871 0 873 + 874 874 0 876 877 877 0 879 880 880 + 0 882 883 883 0 885 886 886 0 888 + 889 889 0 891 892 892 0 894 895 895 + 0 897 898 898 0 900 901 901 0 903 + 904 904 0 906 907 907 0 909 910 910 + 0 912 913 913 0 915 916 916 0 918 + 919 919 0 921 922 922 0 924 925 925 + 0 927 928 928 0 930 931 931 0 933 + 934 934 0 936 937 937 0 939 940 940 + 0 942 943 943 0 945 946 946 0 948 + 949 949 0 951 952 952 0 954 955 955 + 0 957 958 958 0 960 961 961 0 963 + 964 964 0 966 967 967 0 969 970 970 + 0 972 973 973 0 975 976 976 0 978 + 979 979 0 981 982 982 0 984 985 985 + 0 987 988 988 0 990 991 991 0 993 + 994 994 0 996 997 997 0 999 1000 1000 + 0 1002 1003 1003 0 1005 1006 1006 0 1008 + 1009 1009 0 1011 1012 1012 0 1014 1015 1015 + 0 1017 1018 1018 0 1020 1021 1021 0 1023 + 1024 1024 0 1026 1027 1027 0 1029 1030 1030 + 0 1032 1033 1033 0 1035 1036 1036 0 1038 + 1039 1039 0 1041 1042 1042 0 1044 1045 1045 + 0 1047 1048 1048 0 1050 1051 1051 0 1053 + 1054 1054 0 1056 1057 1057 0 1059 1060 1060 + 0 1062 1063 1063 0 1065 1066 1066 0 1068 + 1069 1069 0 1071 1072 1072 0 1074 1075 1075 + 0 1077 1078 1078 0 1080 1081 1081 0 1083 + 1084 1084 0 1086 1087 1087 0 1089 1090 1090 + 0 1092 1093 1093 0 1095 1096 1096 0 1098 + 1099 1099 0 1101 1102 1102 0 1104 1105 1105 + 0 1107 1108 1108 0 1110 1111 1111 0 1113 + 1114 1114 0 1116 1117 1117 0 1119 1120 1120 + 0 1122 1123 1123 0 1125 1126 1126 0 1128 + 1129 1129 0 1131 1132 1132 0 1134 1135 1135 + 0 1137 1138 1138 0 1140 1141 1141 0 1143 + 1144 1144 0 1146 1147 1147 0 1149 1150 1150 + 0 1152 1153 1153 0 1155 1156 1156 0 1158 + 1159 1159 0 1161 1162 1162 0 1164 1165 1165 + 0 1167 1168 1168 0 1170 1171 1171 0 1173 + 1174 1174 0 1176 1177 1177 0 1179 1180 1180 + 0 1182 1183 1183 0 1185 1186 1186 0 1188 + 1189 1189 0 1191 1192 1192 0 1194 1195 1195 + 0 1197 1198 1198 0 1200 1201 1201 0 1203 + 1204 1204 0 1206 1207 1207 0 1209 1210 1210 + 0 1212 1213 1213 0 1215 1216 1216 0 1218 + 1219 1219 0 1221 1222 1222 0 1224 1225 1225 + 0 1227 1228 1228 0 1230 1231 1231 0 1233 + 1234 1234 0 1236 1237 1237 0 1239 1240 1240 + 0 1242 1243 1243 0 1245 1246 1246 0 1248 + 1249 1249 0 1251 1252 1252 0 1254 1255 1255 + 0 1257 1258 1258 0 1260 1261 1261 0 1263 + 1264 1264 0 1266 1267 1267 0 1269 1270 1270 + 0 1272 1273 1273 0 1275 1276 1276 0 1278 + 1279 1279 0 1281 1282 1282 0 1284 1285 1285 + 0 1287 1288 1288 0 1290 1291 1291 0 1293 + 1294 1294 0 1296 1297 1297 0 1299 1300 1300 + 0 1302 1303 1303 0 1305 1306 1306 0 1308 + 1309 1309 0 1311 1312 1312 0 1314 1315 1315 + 0 1317 1318 1318 0 1320 1321 1321 0 1323 + 1324 1324 0 1326 1327 1327 0 1329 1330 1330 + 0 1332 1333 1333 0 1335 1336 1336 0 1338 + 1339 1339 0 1341 1342 1342 0 1344 1345 1345 + 0 1347 1348 1348 0 1350 1351 1351 0 1353 + 1354 1354 0 1356 1357 1357 0 1359 1360 1360 + 0 1362 1363 1363 0 1365 1366 1366 0 1368 + 1369 1369 0 1371 1372 1372 0 1374 1375 1375 + 0 1377 1378 1378 0 1380 1381 1381 0 1383 + 1384 1384 0 1386 1387 1387 0 1389 1390 1390 + 0 1392 1393 1393 0 1395 1396 1396 0 1398 + 1399 1399 0 1401 1402 1402 0 1404 1405 1405 + 0 1407 1408 1408 0 1410 1411 1411 0 1413 + 1414 1414 0 1416 1417 1417 0 1419 1420 1420 + 0 1422 1423 1423 0 1425 1426 1426 0 1428 + 1429 1429 0 1431 1432 1432 0 1434 1435 1435 + 0 1437 1438 1438 0 1440 1441 1441 0 1443 + 1444 1444 0 1446 1447 1447 0 1449 1450 1450 + 0 1452 1453 1453 0 1455 1456 1456 0 1458 + 1459 1459 0 1461 1462 1462 0 1464 1465 1465 + 0 1467 1468 1468 0 1470 1471 1471 0 1473 + 1474 1474 0 1476 1477 1477 0 1479 1480 1480 + 0 1482 1483 1483 0 1485 1486 1486 0 1488 + 1489 1489 0 1491 1492 1492 0 1494 1495 1495 + 0 1497 1498 1498 0 1500 1501 1501 0 1503 + 1504 1504 0 1506 1507 1507 0 1509 1510 1510 + 0 1512 1513 1513 0 1515 1516 1516 0 1518 + 1519 1519 0 1521 1522 1522 0 1524 1525 1525 + 0 1527 1528 1528 0 1530 1531 1531 0 1533 + 1534 1534 0 1536 1537 1537 0 1539 1540 1540 + 0 1542 1543 1543 0 1545 1546 1546 0 1548 + 1549 1549 0 1551 1552 1552 0 1554 1555 1555 + 0 1557 1558 1558 0 1560 1561 1561 0 1563 + 1564 1564 0 1566 1567 1567 0 1569 1570 1570 + 0 1572 1573 1573 0 1575 1576 1576 0 1578 + 1579 1579 0 1581 1582 1582 0 1584 1585 1585 + 0 1587 1588 1588 0 1590 1591 1591 0 1593 + 1594 1594 0 1596 1597 1597 0 1599 1600 1600 + 0 1602 1603 1603 0 1605 1606 1606 0 1608 + 1609 1609 0 1611 1612 1612 0 1614 1615 1615 + 0 1617 1618 1618 0 1620 1621 1621 0 1623 + 1624 1624 0 1626 1627 1627 0 1629 1630 1630 + 0 1632 1633 1633 0 1635 1636 1636 0 1638 + 1639 1639 0 1641 1642 1642 0 1644 1645 1645 + 0 1647 1648 1648 0 1650 1651 1651 0 1653 + 1654 1654 0 1656 1657 1657 0 1659 1660 1660 + 0 1662 1663 1663 0 1665 1666 1666 0 1668 + 1669 1669 0 1671 1672 1672 0 1674 1675 1675 + 0 1677 1678 1678 0 1680 1681 1681 0 1683 + 1684 1684 0 1686 1687 1687 0 1689 1690 1690 + 0 1692 1693 1693 0 1695 1696 1696 0 1698 + 1699 1699 0 1701 1702 1702 0 1704 1705 1705 + 0 1707 1708 1708 0 1710 1711 1711 0 1713 + 1714 1714 0 1716 1717 1717 0 1719 1720 1720 + 0 1722 1723 1723 0 1725 1726 1726 0 1728 + 1729 1729 0 1731 1732 1732 0 1734 1735 1735 + 0 1737 1738 1738 0 1740 1741 1741 0 1743 + 1744 1744 0 1746 1747 1747 0 1749 1750 1750 + 0 1752 1753 1753 0 1755 1756 1756 0 1758 + 1759 1759 0 1761 1762 1762 0 1764 1765 1765 + 0 1767 1768 1768 0 1770 1771 1771 0 1773 + 1774 1774 0 1776 1777 1777 0 1779 1780 1780 + 0 1782 1783 1783 0 1785 1786 1786 0 1788 + 1789 1789 0 1791 1792 1792 0 1794 1795 1795 + 0 1797 1798 1798 0 1800 1801 1801 0 1803 + 1804 1804 0 1806 1807 1807 0 1809 1810 1810 + 0 1812 1813 1813 0 1815 1816 1816 0 1818 + 1819 1819 0 1821 1822 1822 0 1824 1825 1825 + 0 1827 1828 1828 0 1830 1831 1831 0 1833 + 1834 1834 0 1836 1837 1837 0 1839 1840 1840 + 0 1842 1843 1843 0 1845 1846 1846 0 1848 + 1849 1849 0 1851 1852 1852 0 1854 1855 1855 + 0 1857 1858 1858 0 1860 1861 1861 0 1863 + 1864 1864 0 1866 1867 1867 0 1869 1870 1870 + 0 1872 1873 1873 0 1875 1876 1876 0 1878 + 1879 1879 0 1881 1882 1882 0 1884 1885 1885 + 0 1887 1888 1888 0 1890 1891 1891 0 1893 + 1894 1894 0 1896 1897 1897 0 1899 1900 1900 + 0 1902 1903 1903 0 1905 1906 1906 0 1908 + 1909 1909 0 1911 1912 1912 0 1914 1915 1915 + 0 1917 1918 1918 0 1920 1921 1921 0 1923 + 1924 1924 0 1926 1927 1927 0 1929 1930 1930 + 0 1932 1933 1933 0 1935 1936 1936 0 1938 + 1939 1939 0 1941 1942 1942 0 1944 1945 1945 + 0 1947 1948 1948 0 1950 1951 1951 0 1953 + 1954 1954 0 1956 1957 1957 0 1959 1960 1960 + 0 1962 1963 1963 0 1965 1966 1966 0 1968 + 1969 1969 0 1971 1972 1972 0 1974 1975 1975 + 0 1977 1978 1978 0 1980 1981 1981 0 1983 + 1984 1984 0 1986 1987 1987 0 1989 1990 1990 + 0 1992 1993 1993 0 1995 1996 1996 0 1998 + 1999 1999 0 2001 2002 2002 0 2004 2005 2005 + 0 2007 2008 2008 0 2010 2011 2011 0 2013 + 2014 2014 0 2016 2017 2017 0 2019 2020 2020 + 0 2022 2023 2023 0 2025 2026 2026 0 2028 + 2029 2029 0 2031 2032 2032 0 2034 2035 2035 + 0 2037 2038 2038 0 2040 2041 2041 0 2043 + 2044 2044 0 2046 2047 2047 0 2049 2050 2050 + 0 2052 2053 2053 0 2055 2056 2056 0 2058 + 2059 2059 0 2061 2062 2062 0 2064 2065 2065 + 0 2067 2068 2068 0 2070 2071 2071 0 2073 + 2074 2074 0 2076 2077 2077 0 2079 2080 2080 + 0 2082 2083 2083 0 2085 2086 2086 0 2088 + 2089 2089 0 2091 2092 2092 0 2094 2095 2095 + 0 2097 2098 2098 0 2100 2101 2101 0 2103 + 2104 2104 0 2106 2107 2107 0 2109 2110 2110 + 0 2112 2113 2113 0 2115 2116 2116 0 2118 + 2119 2119 0 2121 2122 2122 0 2124 2125 2125 + 0 2127 2128 2128 0 2130 2131 2131 0 2133 + 2134 2134 0 2136 2137 2137 0 2139 2140 2140 + 0 2142 2143 2143 0 2145 2146 2146 0 2148 + 2149 2149 0 2151 2152 2152 0 2154 2155 2155 + 0 2157 2158 2158 0 2160 2161 2161 0 2163 + 2164 2164 0 2166 2167 2167 0 2169 2170 2170 + 0 2172 2173 2173 0 2175 2176 2176 0 2178 + 2179 2179 0 2181 2182 2182 0 2184 2185 2185 + 0 2187 2188 2188 0 2190 2191 2191 0 2193 + 2194 2194 0 2196 2197 2197 0 2199 2200 2200 + 0 2202 2203 2203 0 2205 2206 2206 0 2208 + 2209 2209 0 2211 2212 2212 0 2214 2215 2215 + 0 2217 2218 2218 0 2220 2221 2221 0 2223 + 2224 2224 0 2226 2227 2227 0 2229 2230 2230 + 0 2232 2233 2233 0 2235 2236 2236 0 2238 + 2239 2239 0 2241 2242 2242 0 2244 2245 2245 + 0 2247 2248 2248 0 2250 2251 2251 0 2253 + 2254 2254 0 2256 2257 2257 0 2259 2260 2260 + 0 2262 2263 2263 0 2265 2266 2266 0 2268 + 2269 2269 0 2271 2272 2272 0 2274 2275 2275 + 0 2277 2278 2278 0 2280 2281 2281 0 2283 + 2284 2284 0 2286 2287 2287 0 2289 2290 2290 + 0 2292 2293 2293 0 2295 2296 2296 0 2298 + 2299 2299 0 2301 2302 2302 0 2304 2305 2305 + 0 2307 2308 2308 0 2310 2311 2311 0 2313 + 2314 2314 0 2316 2317 2317 0 2319 2320 2320 + 0 2322 2323 2323 0 2325 2326 2326 0 2328 + 2329 2329 0 2331 2332 2332 0 2334 2335 2335 + 0 2337 2338 2338 0 2340 2341 2341 0 2343 + 2344 2344 0 2346 2347 2347 0 2349 2350 2350 + 0 2352 2353 2353 0 2355 2356 2356 0 2358 + 2359 2359 0 2361 2362 2362 0 2364 2365 2365 + 0 2367 2368 2368 0 2370 2371 2371 0 2373 + 2374 2374 0 2376 2377 2377 0 2379 2380 2380 + 0 2382 2383 2383 0 2385 2386 2386 0 2388 + 2389 2389 0 2391 2392 2392 0 2394 2395 2395 + 0 2397 2398 2398 0 2400 2401 2401 0 2403 + 2404 2404 0 2406 2407 2407 0 2409 2410 2410 + 0 2412 2413 2413 0 2415 2416 2416 0 2418 + 2419 2419 0 2421 2422 2422 0 2424 2425 2425 + 0 2427 2428 2428 0 2430 2431 2431 0 2433 + 2434 2434 0 2436 2437 2437 0 2439 2440 2440 + 0 2442 2443 2443 0 2445 2446 2446 0 2448 + 2449 2449 0 2451 2452 2452 0 2454 2455 2455 + 0 2457 2458 2458 0 2460 2461 2461 0 2463 + 2464 2464 0 2466 2467 2467 0 2469 2470 2470 + 0 2472 2473 2473 0 2475 2476 2476 0 2478 + 2479 2479 0 2481 2482 2482 0 2484 2485 2485 + 0 2487 2488 2488 0 2490 2491 2491 0 2493 + 2494 2494 0 2496 2497 2497 0 2499 2500 2500 + 0 2502 2503 2503 0 2505 2506 2506 0 2508 + 2509 2509 0 2511 2512 2512 0 2514 2515 2515 + 0 2517 2518 2518 0 2520 2521 2521 0 2523 + 2524 2524 0 2526 2527 2527 0 2529 2530 2530 + 0 2532 2533 2533 0 2535 2536 2536 0 2538 + 2539 2539 0 2541 2542 2542 0 2544 2545 2545 + 0 2547 2548 2548 0 2550 2551 2551 0 2553 + 2554 2554 0 2556 2557 2557 0 2559 2560 2560 + 0 2562 2563 2563 0 2565 2566 2566 0 2568 + 2569 2569 0 2571 2572 2572 0 2574 2575 2575 + 0 2577 2578 2578 0 2580 2581 2581 0 2583 + 2584 2584 0 2586 2587 2587 0 2589 2590 2590 + 0 2592 2593 2593 0 2595 2596 2596 0 2598 + 2599 2599 0 2601 2602 2602 0 2604 2605 2605 + 0 2607 2608 2608 0 2610 2611 2611 0 2613 + 2614 2614 0 2616 2617 2617 0 2619 2620 2620 + 0 2622 2623 2623 0 2625 2626 2626 0 2628 + 2629 2629 0 2631 2632 2632 0 2634 2635 2635 + 0 2637 2638 2638 0 2640 2641 2641 0 2643 + 2644 2644 0 2646 2647 2647 0 2649 2650 2650 + 0 2652 2653 2653 0 2655 2656 2656 0 2658 + 2659 2659 0 2661 2662 2662 0 2664 2665 2665 + 0 2667 2668 2668 0 2670 2671 2671 0 2673 + 2674 2674 0 2676 2677 2677 0 2679 2680 2680 + 0 2682 2683 2683 0 2685 2686 2686 0 2688 + 2689 2689 0 2691 2692 2692 0 2694 2695 2695 + 0 2697 2698 2698 0 2700 2701 2701 0 2703 + 2704 2704 0 2706 2707 2707 0 2709 2710 2710 + 0 2712 2713 2713 0 2715 2716 2716 0 2718 + 2719 2719 0 2721 2722 2722 0 2724 2725 2725 + 0 2727 2728 2728 0 2730 2731 2731 0 2733 + 2734 2734 0 2736 2737 2737 0 2739 2740 2740 + 0 2742 2743 2743 0 2745 2746 2746 0 2748 + 2749 2749 0 2751 2752 2752 0 2754 2755 2755 + 0 2757 2758 2758 0 2760 2761 2761 0 2763 + 2764 2764 0 2766 2767 2767 0 2769 2770 2770 + 0 2772 2773 2773 0 2775 2776 2776 0 2778 + 2779 2779 0 2781 2782 2782 0 2784 2785 2785 + 0 2787 2788 2788 0 2790 2791 2791 0 2793 + 2794 2794 0 2796 2797 2797 0 2799 2800 2800 + 0 2802 2803 2803 0 2805 2806 2806 0 2808 + 2809 2809 0 2811 2812 2812 0 2814 2815 2815 + 0 2817 2818 2818 0 2820 2821 2821 0 2823 + 2824 2824 0 2826 2827 2827 0 2829 2830 2830 + 0 2832 2833 2833 0 2835 2836 2836 0 2838 + 2839 2839 0 2841 2842 2842 0 2844 2845 2845 + 0 2847 2848 2848 0 2850 2851 2851 0 2853 + 2854 2854 0 2856 2857 2857 0 2859 2860 2860 + 0 2862 2863 2863 0 2865 2866 2866 0 2868 + 2869 2869 0 2871 2872 2872 0 2874 2875 2875 + 0 2877 2878 2878 0 2880 2881 2881 0 2883 + 2884 2884 0 2886 2887 2887 0 2889 2890 2890 + 0 2892 2893 2893 0 2895 2896 2896 0 2898 + 2899 2899 0 2901 2902 2902 0 2904 2905 2905 + 0 2907 2908 2908 0 2910 2911 2911 0 2913 + 2914 2914 0 2916 2917 2917 0 2919 2920 2920 + 0 2922 2923 2923 0 2925 2926 2926 0 2928 + 2929 2929 0 2931 2932 2932 0 2934 2935 2935 + 0 2937 2938 2938 0 2940 2941 2941 0 2943 + 2944 2944 0 2946 2947 2947 0 2949 2950 2950 + 0 2952 2953 2953 0 2955 2956 2956 0 2958 + 2959 2959 0 2961 2962 2962 0 2964 2965 2965 + 0 2967 2968 2968 0 2970 2971 2971 0 2973 + 2974 2974 0 2976 2977 2977 0 2979 2980 2980 + 0 2982 2983 2983 0 2985 2986 2986 0 2988 + 2989 2989 0 2991 2992 2992 0 2994 2995 2995 + 0 2997 2998 2998 0 3000 3001 3001 0 3003 + 3004 3004 0 3006 3007 3007 0 3009 3010 3010 + 0 3012 3013 3013 0 3015 3016 3016 0 3018 + 3019 3019 0 3021 3022 3022 0 3024 3025 3025 + 0 3027 3028 3028 0 3030 3031 3031 0 3033 + 3034 3034 0 3036 3037 3037 0 3039 3040 3040 + 0 3042 3043 3043 0 3045 3046 3046 0 3048 + 3049 3049 0 3051 3052 3052 0 3054 3055 3055 + 0 3057 3058 3058 0 3060 3061 3061 0 3063 + 3064 3064 0 3066 3067 3067 0 3069 3070 3070 + 0 3072 3073 3073 0 3075 3076 3076 0 3078 + 3079 3079 0 3081 3082 3082 0 3084 3085 3085 + 0 3087 3088 3088 0 3090 3091 3091 0 3093 + 3094 3094 0 3096 3097 3097 0 3099 3100 3100 + 0 3102 3103 3103 0 3105 3106 3106 0 3108 + 3109 3109 0 3111 3112 3112 0 3114 3115 3115 + 0 3117 3118 3118 0 3120 3121 3121 0 3123 + 3124 3124 0 3126 3127 3127 0 3129 3130 3130 + 0 3132 3133 3133 0 3135 3136 3136 0 3138 + 3139 3139 0 3141 3142 3142 0 3144 3145 3145 + 0 3147 3148 3148 0 3150 3151 3151 0 3153 + 3154 3154 0 3156 3157 3157 0 3159 3160 3160 + 0 3162 3163 3163 0 3165 3166 3166 0 3168 + 3169 3169 0 3171 3172 3172 0 3174 3175 3175 + 0 3177 3178 3178 0 3180 3181 3181 0 3183 + 3184 3184 0 3186 3187 3187 0 3189 3190 3190 + 0 3192 3193 3193 0 3195 3196 3196 0 3198 + 3199 3199 0 3201 3202 3202 0 3204 3205 3205 + 0 3207 3208 3208 0 3210 3211 3211 0 3213 + 3214 3214 0 3216 3217 3217 0 3219 3220 3220 + 0 3222 3223 3223 0 3225 3226 3226 0 3228 + 3229 3229 0 3231 3232 3232 0 3234 3235 3235 + 0 3237 3238 3238 0 3240 3241 3241 0 3243 + 3244 3244 0 3246 3247 3247 0 3249 3250 3250 + 0 3252 3253 3253 0 3255 3256 3256 0 3258 + 3259 3259 0 3261 3262 3262 0 3264 3265 3265 + 0 3267 3268 3268 0 3270 3271 3271 0 3273 + 3274 3274 0 3276 3277 3277 0 3279 3280 3280 + 0 3282 3283 3283 0 3285 3286 3286 0 3288 + 3289 3289 0 3291 3292 3292 0 3294 3295 3295 + 0 3297 3298 3298 0 3300 3301 3301 0 3303 + 3304 3304 0 3306 3307 3307 0 3309 3310 3310 + 0 3312 3313 3313 0 3315 3316 3316 0 3318 + 3319 3319 0 3321 3322 3322 0 3324 3325 3325 + 0 3327 3328 3328 0 3330 3331 3331 0 3333 + 3334 3334 0 3336 3337 3337 0 3339 3340 3340 + 0 3342 3343 3343 0 3345 3346 3346 0 3348 + 3349 3349 0 3351 3352 3352 0 3354 3355 3355 + 0 3357 3358 3358 0 3360 3361 3361 0 3363 + 3364 3364 0 3366 3367 3367 0 3369 3370 3370 + 0 3372 3373 3373 0 3375 3376 3376 0 3378 + 3379 3379 0 3381 3382 3382 0 3384 3385 3385 + 0 3387 3388 3388 0 3390 3391 3391 0 3393 + 3394 3394 0 3396 3397 3397 0 3399 3400 3400 + 0 3402 3403 3403 0 3405 3406 3406 0 3408 + 3409 3409 0 3411 3412 3412 0 3414 3415 3415 + 0 3417 3418 3418 0 3420 3421 3421 0 3423 + 3424 3424 0 3426 3427 3427 0 3429 3430 3430 + 0 3432 3433 3433 0 3435 3436 3436 0 3438 + 3439 3439 0 3441 3442 3442 0 3444 3445 3445 + 0 3447 3448 3448 0 3450 3451 3451 0 3453 + 3454 3454 0 3456 3457 3457 0 3459 3460 3460 + 0 3462 3463 3463 0 3465 3466 3466 0 3468 + 3469 3469 0 3471 3472 3472 0 3474 3475 3475 + 0 3477 3478 3478 0 3480 3481 3481 0 3483 + 3484 3484 0 3486 3487 3487 0 3489 3490 3490 + 0 3492 3493 3493 0 3495 3496 3496 0 3498 + 3499 3499 0 3501 3502 3502 0 3504 3505 3505 + 0 3507 3508 3508 0 3510 3511 3511 0 3513 + 3514 3514 0 3516 3517 3517 0 3519 3520 3520 + 0 3522 3523 3523 0 3525 3526 3526 0 3528 + 3529 3529 0 3531 3532 3532 0 3534 3535 3535 + 0 3537 3538 3538 0 3540 3541 3541 0 3543 + 3544 3544 0 3546 3547 3547 0 3549 3550 3550 + 0 3552 3553 3553 0 3555 3556 3556 0 3558 + 3559 3559 0 3561 3562 3562 0 3564 3565 3565 + 0 3567 3568 3568 0 3570 3571 3571 0 3573 + 3574 3574 0 3576 3577 3577 0 3579 3580 3580 + 0 3582 3583 3583 0 3585 3586 3586 0 3588 + 3589 3589 0 3591 3592 3592 0 3594 3595 3595 + 0 3597 3598 3598 0 3600 3601 3601 0 3603 + 3604 3604 0 3606 3607 3607 0 3609 3610 3610 + 0 3612 3613 3613 0 3615 3616 3616 0 3618 + 3619 3619 0 3621 3622 3622 0 3624 3625 3625 + 0 3627 3628 3628 0 3630 3631 3631 0 3633 + 3634 3634 0 3636 3637 3637 0 3639 3640 3640 + 0 3642 3643 3643 0 3645 3646 3646 0 3648 + 3649 3649 0 3651 3652 3652 0 3654 3655 3655 + 0 3657 3658 3658 0 3660 3661 3661 0 3663 + 3664 3664 0 3666 3667 3667 0 3669 3670 3670 + 0 3672 3673 3673 0 3675 3676 3676 0 3678 + 3679 3679 0 3681 3682 3682 0 3684 3685 3685 + 0 3687 3688 3688 0 3690 3691 3691 0 3693 + 3694 3694 0 3696 3697 3697 0 3699 3700 3700 + 0 3702 3703 3703 0 3705 3706 3706 0 3708 + 3709 3709 0 3711 3712 3712 0 3714 3715 3715 + 0 3717 3718 3718 0 3720 3721 3721 0 3723 + 3724 3724 0 3726 3727 3727 0 3729 3730 3730 + 0 3732 3733 3733 0 3735 3736 3736 0 3738 + 3739 3739 0 3741 3742 3742 0 3744 3745 3745 + 0 3747 3748 3748 0 3750 3751 3751 0 3753 + 3754 3754 0 3756 3757 3757 0 3759 3760 3760 + 0 3762 3763 3763 0 3765 3766 3766 0 3768 + 3769 3769 0 3771 3772 3772 0 3774 3775 3775 + 0 3777 3778 3778 0 3780 3781 3781 0 3783 + 3784 3784 0 3786 3787 3787 0 3789 3790 3790 + 0 3792 3793 3793 0 3795 3796 3796 0 3798 + 3799 3799 0 3801 3802 3802 0 3804 3805 3805 + 0 3807 3808 3808 0 3810 3811 3811 0 3813 + 3814 3814 0 3816 3817 3817 0 3819 3820 3820 + 0 3822 3823 3823 0 3825 3826 3826 0 3828 + 3829 3829 0 3831 3832 3832 0 3834 3835 3835 + 0 3837 3838 3838 0 3840 3841 3841 0 3843 + 3844 3844 0 3846 3847 3847 0 3849 3850 3850 + 0 3852 3853 3853 0 3855 3856 3856 0 3858 + 3859 3859 0 3861 3862 3862 0 3864 3865 3865 + 0 3867 3868 3868 0 3870 3871 3871 0 3873 + 3874 3874 0 3876 3877 3877 0 3879 3880 3880 + 0 3882 3883 3883 0 3885 3886 3886 0 3888 + 3889 3889 0 3891 3892 3892 0 3894 3895 3895 + 0 3897 3898 3898 0 3900 3901 3901 0 3903 + 3904 3904 0 3906 3907 3907 0 3909 3910 3910 + 0 3912 3913 3913 0 3915 3916 3916 0 3918 + 3919 3919 0 3921 3922 3922 0 3924 3925 3925 + 0 3927 3928 3928 0 3930 3931 3931 0 3933 + 3934 3934 0 3936 3937 3937 0 3939 3940 3940 + 0 3942 3943 3943 0 3945 3946 3946 0 3948 + 3949 3949 0 3951 3952 3952 0 3954 3955 3955 + 0 3957 3958 3958 0 3960 3961 3961 0 3963 + 3964 3964 0 3966 3967 3967 0 3969 3970 3970 + 0 3972 3973 3973 0 3975 3976 3976 0 3978 + 3979 3979 0 3981 3982 3982 0 3984 3985 3985 + 0 3987 3988 3988 0 3990 3991 3991 0 3993 + 3994 3994 0 3996 3997 3997 0 3999 4000 4000 + 0 4002 4003 4003 0 4005 4006 4006 0 4008 + 4009 4009 0 4011 4012 4012 0 4014 4015 4015 + 0 4017 4018 4018 0 4020 4021 4021 0 4023 + 4024 4024 0 4026 4027 4027 0 4029 4030 4030 + 0 4032 4033 4033 0 4035 4036 4036 0 4038 + 4039 4039 0 4041 4042 4042 0 4044 4045 4045 + 0 4047 4048 4048 0 4050 4051 4051 0 4053 + 4054 4054 0 4056 4057 4057 0 4059 4060 4060 + 0 4062 4063 4063 0 4065 4066 4066 0 4068 + 4069 4069 0 4071 4072 4072 0 4074 4075 4075 + 0 4077 4078 4078 0 4080 4081 4081 0 4083 + 4084 4084 0 4086 4087 4087 0 4089 4090 4090 + 0 4092 4093 4093 0 4095 4096 4096 0 4098 + 4099 4099 0 4101 4102 4102 0 4104 4105 4105 + 0 4107 4108 4108 0 4110 4111 4111 0 4113 + 4114 4114 0 4116 4117 4117 0 4119 4120 4120 + 0 4122 4123 4123 0 4125 4126 4126 0 4128 + 4129 4129 0 4131 4132 4132 0 4134 4135 4135 + 0 4137 4138 4138 0 4140 4141 4141 0 4143 + 4144 4144 0 4146 4147 4147 0 4149 4150 4150 + 0 4152 4153 4153 0 4155 4156 4156 0 4158 + 4159 4159 0 4161 4162 4162 0 4164 4165 4165 + 0 4167 4168 4168 0 4170 4171 4171 0 4173 + 4174 4174 0 4176 4177 4177 0 4179 4180 4180 + 0 4182 4183 4183 0 4185 4186 4186 0 4188 + 4189 4189 0 4191 4192 4192 0 4194 4195 4195 + 0 4197 4198 4198 0 4200 4201 4201 0 4203 + 4204 4204 0 4206 4207 4207 0 4209 4210 4210 + 0 4212 4213 4213 0 4215 4216 4216 0 4218 + 4219 4219 0 4221 4222 4222 0 4224 4225 4225 + 0 4227 4228 4228 0 4230 4231 4231 0 4233 + 4234 4234 0 4236 4237 4237 0 4239 4240 4240 + 0 4242 4243 4243 0 4245 4246 4246 0 4248 + 4249 4249 0 4251 4252 4252 0 4254 4255 4255 + 0 4257 4258 4258 0 4260 4261 4261 0 4263 + 4264 4264 0 4266 4267 4267 0 4269 4270 4270 + 0 4272 4273 4273 0 4275 4276 4276 0 4278 + 4279 4279 0 4281 4282 4282 0 4284 4285 4285 + 0 4287 4288 4288 0 4290 4291 4291 0 4293 + 4294 4294 0 4296 4297 4297 0 4299 4300 4300 + 0 4302 4303 4303 0 4305 4306 4306 0 4308 + 4309 4309 0 4311 4312 4312 0 4314 4315 4315 + 0 4317 4318 4318 0 4320 4321 4321 0 4323 + 4324 4324 0 4326 4327 4327 0 4329 4330 4330 + 0 4332 4333 4333 0 4335 4336 4336 0 4338 + 4339 4339 0 4341 4342 4342 0 4344 4345 4345 + 0 4347 4348 4348 0 4350 4351 4351 0 4353 + 4354 4354 0 4356 4357 4357 0 4359 4360 4360 + 0 4362 4363 4363 0 4365 4366 4366 0 4368 + 4369 4369 0 4371 4372 4372 0 4374 4375 4375 + 0 4377 4378 4378 0 4380 4381 4381 0 4383 + 4384 4384 0 4386 4387 4387 0 4389 4390 4390 + 0 4392 4393 4393 0 4395 4396 4396 0 4398 + 4399 4399 0 4401 4402 4402 0 4404 4405 4405 + 0 4407 4408 4408 0 4410 4411 4411 0 4413 + 4414 4414 0 4416 4417 4417 0 4419 4420 4420 + 0 4422 4423 4423 0 4425 4426 4426 0 4428 + 4429 4429 0 4431 4432 4432 0 4434 4435 4435 + 0 4437 4438 4438 0 4440 4441 4441 0 4443 + 4444 4444 0 4446 4447 4447 0 4449 4450 4450 + 0 4452 4453 4453 0 4455 4456 4456 0 4458 + 4459 4459 0 4461 4462 4462 0 4464 4465 4465 + 0 4467 4468 4468 0 4470 4471 4471 0 4473 + 4474 4474 0 4476 4477 4477 0 4479 4480 4480 + 0 4482 4483 4483 0 4485 4486 4486 0 4488 + 4489 4489 0 4491 4492 4492 0 4494 4495 4495 + 0 4497 4498 4498 0 4500 4501 4501 0 4503 + 4504 4504 0 4506 4507 4507 0 4509 4510 4510 + 0 4512 4513 4513 0 4515 4516 4516 0 4518 + 4519 4519 0 4521 4522 4522 0 4524 4525 4525 + 0 4527 4528 4528 0 4530 4531 4531 0 4533 + 4534 4534 0 4536 4537 4537 0 4539 4540 4540 + 0 4542 4543 4543 0 4545 4546 4546 0 4548 + 4549 4549 0 4551 4552 4552 0 4554 4555 4555 + 0 4557 4558 4558 0 4560 4561 4561 0 4563 + 4564 4564 0 4566 4567 4567 0 4569 4570 4570 + 0 4572 4573 4573 0 4575 4576 4576 0 4578 + 4579 4579 0 4581 4582 4582 0 4584 4585 4585 + 0 4587 4588 4588 0 4590 4591 4591 0 4593 + 4594 4594 0 4596 4597 4597 0 4599 4600 4600 + 0 4602 4603 4603 0 4605 4606 4606 0 4608 + 4609 4609 0 4611 4612 4612 0 4614 4615 4615 + 0 4617 4618 4618 0 4620 4621 4621 0 4623 + 4624 4624 0 4626 4627 4627 0 4629 4630 4630 + 0 4632 4633 4633 0 4635 4636 4636 0 4638 + 4639 4639 0 4641 4642 4642 0 4644 4645 4645 + 0 4647 4648 4648 0 4650 4651 4651 0 4653 + 4654 4654 0 4656 4657 4657 0 4659 4660 4660 + 0 4662 4663 4663 0 4665 4666 4666 0 4668 + 4669 4669 0 4671 4672 4672 0 4674 4675 4675 + 0 4677 4678 4678 0 4680 4681 4681 0 4683 + 4684 4684 0 4686 4687 4687 0 4689 4690 4690 + 0 4692 4693 4693 0 4695 4696 4696 0 4698 + 4699 4699 0 4701 4702 4702 0 4704 4705 4705 + 0 4707 4708 4708 0 4710 4711 4711 0 4713 + 4714 4714 0 4716 4717 4717 0 4719 4720 4720 + 0 4722 4723 4723 0 4725 4726 4726 0 4728 + 4729 4729 0 4731 4732 4732 0 4734 4735 4735 + 0 4737 4738 4738 0 4740 4741 4741 0 4743 + 4744 4744 0 4746 4747 4747 0 4749 4750 4750 + 0 4752 4753 4753 0 4755 4756 4756 0 4758 + 4759 4759 0 4761 4762 4762 0 4764 4765 4765 + 0 4767 4768 4768 0 4770 4771 4771 0 4773 + 4774 4774 0 4776 4777 4777 0 4779 4780 4780 + 0 4782 4783 4783 0 4785 4786 4786 0 4788 + 4789 4789 0 4791 4792 4792 0 4794 4795 4795 + 0 4797 4798 4798 0 4800 4801 4801 0 4803 + 4804 4804 0 4806 4807 4807 0 4809 4810 4810 + 0 4812 4813 4813 0 4815 4816 4816 0 4818 + 4819 4819 0 4821 4822 4822 0 4824 4825 4825 + 0 4827 4828 4828 0 4830 4831 4831 0 4833 + 4834 4834 0 4836 4837 4837 0 4839 4840 4840 + 0 4842 4843 4843 0 4845 4846 4846 0 4848 + 4849 4849 0 4851 4852 4852 0 4854 4855 4855 + 0 4857 4858 4858 0 4860 4861 4861 0 4863 + 4864 4864 0 4866 4867 4867 0 4869 4870 4870 + 0 4872 4873 4873 0 4875 4876 4876 0 4878 + 4879 4879 0 4881 4882 4882 0 4884 4885 4885 + 0 4887 4888 4888 0 4890 4891 4891 0 4893 + 4894 4894 0 4896 4897 4897 0 4899 4900 4900 + 0 4902 4903 4903 0 4905 4906 4906 0 4908 + 4909 4909 0 4911 4912 4912 0 4914 4915 4915 + 0 4917 4918 4918 0 4920 4921 4921 0 4923 + 4924 4924 0 4926 4927 4927 0 4929 4930 4930 + 0 4932 4933 4933 0 4935 4936 4936 0 4938 + 4939 4939 0 4941 4942 4942 0 4944 4945 4945 + 0 4947 4948 4948 0 4950 4951 4951 0 4953 + 4954 4954 0 4956 4957 4957 0 4959 4960 4960 + 0 4962 4963 4963 0 4965 4966 4966 0 4968 + 4969 4969 0 4971 4972 4972 0 4974 4975 4975 + 0 4977 4978 4978 0 4980 4981 4981 0 4983 + 4984 4984 0 4986 4987 4987 0 4989 4990 4990 + 0 4992 4993 4993 0 4995 4996 4996 0 4998 + 4999 4999 0 5001 5002 5002 0 5004 5005 5005 + 0 5007 5008 5008 0 5010 5011 5011 0 5013 + 5014 5014 0 5016 5017 5017 0 5019 5020 5020 + 0 5022 5023 5023 0 5025 5026 5026 0 5028 + 5029 5029 0 5031 5032 5032 0 5034 5035 5035 + 0 5037 5038 5038 0 5040 5041 5041 0 5043 + 5044 5044 0 5046 5047 5047 0 5049 5050 5050 + 0 5052 5053 5053 0 5055 5056 5056 0 5058 + 5059 5059 0 5061 5062 5062 0 5064 5065 5065 + 0 5067 5068 5068 0 5070 5071 5071 0 5073 + 5074 5074 0 5076 5077 5077 0 5079 5080 5080 + 0 5082 5083 5083 0 5085 5086 5086 0 5088 + 5089 5089 0 5091 5092 5092 0 5094 5095 5095 + 0 5097 5098 5098 0 5100 5101 5101 0 5103 + 5104 5104 0 5106 5107 5107 0 5109 5110 5110 + 0 5112 5113 5113 0 5115 5116 5116 0 5118 + 5119 5119 0 5121 5122 5122 0 5124 5125 5125 + 0 5127 5128 5128 0 5130 5131 5131 0 5133 + 5134 5134 0 5136 5137 5137 0 5139 5140 5140 + 0 5142 5143 5143 0 5145 5146 5146 0 5148 + 5149 5149 0 5151 5152 5152 0 5154 5155 5155 + 0 5157 5158 5158 0 5160 5161 5161 0 5163 + 5164 5164 0 5166 5167 5167 0 5169 5170 5170 + 0 5172 5173 5173 0 5175 5176 5176 0 5178 + 5179 5179 0 5181 5182 5182 0 5184 5185 5185 + 0 5187 5188 5188 0 5190 5191 5191 0 5193 + 5194 5194 0 5196 5197 5197 0 5199 5200 5200 + 0 5202 5203 5203 0 5205 5206 5206 0 5208 + 5209 5209 0 5211 5212 5212 0 5214 5215 5215 + 0 5217 5218 5218 0 5220 5221 5221 0 5223 + 5224 5224 0 5226 5227 5227 0 5229 5230 5230 + 0 5232 5233 5233 0 5235 5236 5236 0 5238 + 5239 5239 0 5241 5242 5242 0 5244 5245 5245 + 0 5247 5248 5248 0 5250 5251 5251 0 5253 + 5254 5254 0 5256 5257 5257 0 5259 5260 5260 + 0 5262 5263 5263 0 5265 5266 5266 0 5268 + 5269 5269 0 5271 5272 5272 0 5274 5275 5275 + 0 5277 5278 5278 0 5280 5281 5281 0 5283 + 5284 5284 0 5286 5287 5287 0 5289 5290 5290 + 0 5292 5293 5293 0 5295 5296 5296 0 5298 + 5299 5299 0 5301 5302 5302 0 5304 5305 5305 + 0 5307 5308 5308 0 5310 5311 5311 0 5313 + 5314 5314 0 5316 5317 5317 0 5319 5320 5320 + 0 5322 5323 5323 0 5325 5326 5326 0 5328 + 5329 5329 0 5331 5332 5332 0 5334 5335 5335 + 0 5337 5338 5338 0 5340 5341 5341 0 5343 + 5344 5344 0 5346 5347 5347 0 5349 5350 5350 + 0 5352 5353 5353 0 5355 5356 5356 0 5358 + 5359 5359 0 5361 5362 5362 0 5364 5365 5365 + 0 5367 5368 5368 0 5370 5371 5371 0 5373 + 5374 5374 0 5376 5377 5377 0 5379 5380 5380 + 0 5382 5383 5383 0 5385 5386 5386 0 5388 + 5389 5389 0 5391 5392 5392 0 5394 5395 5395 + 0 5397 5398 5398 0 5400 5401 5401 0 5403 + 5404 5404 0 5406 5407 5407 0 5409 5410 5410 + 0 5412 5413 5413 0 5415 5416 5416 0 5418 + 5419 5419 0 5421 5422 5422 0 5424 5425 5425 + 0 5427 5428 5428 0 5430 5431 5431 0 5433 + 5434 5434 0 5436 5437 5437 0 5439 5440 5440 + 0 5442 5443 5443 0 5445 5446 5446 0 5448 + 5449 5449 0 5451 5452 5452 0 5454 5455 5455 + 0 5457 5458 5458 0 5460 5461 5461 0 5463 + 5464 5464 0 5466 5467 5467 0 5469 5470 5470 + 0 5472 5473 5473 0 5475 5476 5476 0 5478 + 5479 5479 0 5481 5482 5482 0 5484 5485 5485 + 0 5487 5488 5488 0 5490 5491 5491 0 5493 + 5494 5494 0 5496 5497 5497 0 5499 5500 5500 + 0 5502 5503 5503 0 5505 5506 5506 0 5508 + 5509 5509 0 5511 5512 5512 0 5514 5515 5515 + 0 5517 5518 5518 0 5520 5521 5521 0 5523 + 5524 5524 0 5526 5527 5527 0 5529 5530 5530 + 0 5532 5533 5533 0 5535 5536 5536 0 5538 + 5539 5539 0 5541 5542 5542 0 5544 5545 5545 + 0 5547 5548 5548 0 5550 5551 5551 0 5553 + 5554 5554 0 5556 5557 5557 0 5559 5560 5560 + 0 5562 5563 5563 0 5565 5566 5566 0 5568 + 5569 5569 0 5571 5572 5572 0 5574 5575 5575 + 0 5577 5578 5578 0 5580 5581 5581 0 5583 + 5584 5584 0 5586 5587 5587 0 5589 5590 5590 + 0 5592 5593 5593 0 5595 5596 5596 0 5598 + 5599 5599 0 5601 5602 5602 0 5604 5605 5605 + 0 5607 5608 5608 0 5610 5611 5611 0 5613 + 5614 5614 0 5616 5617 5617 0 5619 5620 5620 + 0 5622 5623 5623 0 5625 5626 5626 0 5628 + 5629 5629 0 5631 5632 5632 0 5634 5635 5635 + 0 5637 5638 5638 0 5640 5641 5641 0 5643 + 5644 5644 0 5646 5647 5647 0 5649 5650 5650 + 0 5652 5653 5653 0 5655 5656 5656 0 5658 + 5659 5659 0 5661 5662 5662 0 5664 5665 5665 + 0 5667 5668 5668 0 5670 5671 5671 0 5673 + 5674 5674 0 5676 5677 5677 0 5679 5680 5680 + 0 5682 5683 5683 0 5685 5686 5686 0 5688 + 5689 5689 0 5691 5692 5692 0 5694 5695 5695 + 0 5697 5698 5698 0 5700 5701 5701 0 5703 + 5704 5704 0 5706 5707 5707 0 5709 5710 5710 + 0 5712 5713 5713 0 5715 5716 5716 0 5718 + 5719 5719 0 5721 5722 5722 0 5724 5725 5725 + 0 5727 5728 5728 0 5730 5731 5731 0 5733 + 5734 5734 0 5736 5737 5737 0 5739 5740 5740 + 0 5742 5743 5743 0 5745 5746 5746 0 5748 + 5749 5749 0 5751 5752 5752 0 5754 5755 5755 + 0 5757 5758 5758 0 5760 5761 5761 0 5763 + 5764 5764 0 5766 5767 5767 0 5769 5770 5770 + 0 5772 5773 5773 0 5775 5776 5776 0 5778 + 5779 5779 0 5781 5782 5782 0 5784 5785 5785 + 0 5787 5788 5788 0 5790 5791 5791 0 5793 + 5794 5794 0 5796 5797 5797 0 5799 5800 5800 + 0 5802 5803 5803 0 5805 5806 5806 0 5808 + 5809 5809 0 5811 5812 5812 0 5814 5815 5815 + 0 5817 5818 5818 0 5820 5821 5821 0 5823 + 5824 5824 0 5826 5827 5827 0 +%FLAG HBOND_ACOEF +%FORMAT(5E16.8) + 0.00000000E+00 +%FLAG HBOND_BCOEF +%FORMAT(5E16.8) + 0.00000000E+00 +%FLAG HBCUT +%FORMAT(5E16.8) + 0.00000000E+00 +%FLAG AMBER_ATOM_TYPE +%FORMAT(20a4) +N3 H H H CX HP CT H1 H1 OH HO C O N H CX H1 CT HC HC +C* CW H4 NA H CN CA HA CA HA CA HA CA HA CB C O N H CX +H1 CT H1 CT HC HC HC OH HO C O N H CX H1 CT HC HC C* CW +H4 NA H CN CA HA CA HA CA HA CA HA CB C O N H CX H1 CT +HC HC CT HC HC C O2 O2 C O N H CX H1 CT HC HC C O N +H H C O N H CX H1 H1 C O N H CX H1 CT HC HC CT HC +HC CT HC HC CT HP HP N3 H H H C O N H CX H1 CT HC HC +C* CW H4 NA H CN CA HA CA HA CA HA CA HA CB C O N H CX +H1 CT H1 CT HC HC HC OH HO C O N H CX H1 CT HC HC C* CW +H4 NA H CN CA HA CA HA CA HA CA HA CB C O N H CX H1 CT +HC HC CT HC HC CT HC HC CT HP HP N3 H H H C O N H H +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW +HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW +OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW HW OW HW +HW OW HW HW OW HW HW +%FLAG TREE_CHAIN_CLASSIFICATION +%FORMAT(20a4) +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA M E M E 3 E E +B B E B E S B E B E B E S E E M E M E M +E 3 E 3 E E E S E M E M E M E 3 E E B B +E B E S B E B E B E S E E M E M E M E 3 +E E 3 E E B E E M E M E M E 3 E E B E B +E E M E M E M E E M E M E M E 3 E E 3 E +E 3 E E 3 E E 3 E E E M E M E M E 3 E E +B B E B E S B E B E B E S E E M E M E M +E 3 E 3 E E E S E M E M E M E 3 E E B B +E B E S B E B E B E S E E M E M E M E 3 +E E 3 E E 3 E E 3 E E 3 E E E M E BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA +%FLAG JOIN_ARRAY +%FORMAT(10I8) + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 +%FLAG IROTAT +%FORMAT(10I8) + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 +%FLAG SOLVENT_POINTERS +%FORMAT(3I8) + 13 1870 2 +%FLAG ATOMS_PER_MOLECULE +%FORMAT(10I8) + 220 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 +%FLAG BOX_DIMENSIONS +%FORMAT(5E16.8) + 1.09471219E+02 4.48903851E+01 4.48903851E+01 4.48903851E+01 +%FLAG RADIUS_SET +%FORMAT(1a80) +modified Bondi radii (mbondi) +%FLAG RADII +%FORMAT(5E16.8) + 1.55000000E+00 1.30000000E+00 1.30000000E+00 1.30000000E+00 1.70000000E+00 + 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.30000000E+00 1.50000000E+00 + 8.00000000E-01 1.70000000E+00 1.50000000E+00 1.55000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.30000000E+00 + 1.70000000E+00 1.70000000E+00 1.30000000E+00 1.55000000E+00 1.30000000E+00 + 1.70000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 + 1.70000000E+00 1.50000000E+00 1.55000000E+00 1.30000000E+00 1.70000000E+00 + 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.30000000E+00 1.30000000E+00 1.50000000E+00 8.00000000E-01 1.70000000E+00 + 1.50000000E+00 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.70000000E+00 + 1.30000000E+00 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.70000000E+00 + 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.70000000E+00 1.50000000E+00 + 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 + 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.30000000E+00 + 1.70000000E+00 1.50000000E+00 1.50000000E+00 1.70000000E+00 1.50000000E+00 + 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 + 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.50000000E+00 1.55000000E+00 + 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.50000000E+00 1.55000000E+00 + 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.30000000E+00 1.70000000E+00 + 1.50000000E+00 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.30000000E+00 1.70000000E+00 + 1.30000000E+00 1.30000000E+00 1.55000000E+00 1.30000000E+00 1.30000000E+00 + 1.30000000E+00 1.70000000E+00 1.50000000E+00 1.55000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.30000000E+00 + 1.70000000E+00 1.70000000E+00 1.30000000E+00 1.55000000E+00 1.30000000E+00 + 1.70000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 + 1.70000000E+00 1.50000000E+00 1.55000000E+00 1.30000000E+00 1.70000000E+00 + 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.30000000E+00 1.30000000E+00 1.50000000E+00 8.00000000E-01 1.70000000E+00 + 1.50000000E+00 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.70000000E+00 + 1.30000000E+00 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.70000000E+00 + 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.70000000E+00 1.70000000E+00 1.50000000E+00 + 1.55000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.70000000E+00 + 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 1.30000000E+00 + 1.70000000E+00 1.30000000E+00 1.30000000E+00 1.70000000E+00 1.30000000E+00 + 1.30000000E+00 1.55000000E+00 1.30000000E+00 1.30000000E+00 1.30000000E+00 + 1.70000000E+00 1.50000000E+00 1.55000000E+00 1.30000000E+00 1.30000000E+00 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 +%FLAG SCREEN +%FORMAT(5E16.8) + 7.90000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 8.50000000E-01 + 7.20000000E-01 7.20000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 + 7.20000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 + 7.20000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 7.90000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 7.20000000E-01 + 8.50000000E-01 7.90000000E-01 8.50000000E-01 7.20000000E-01 7.20000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 7.20000000E-01 7.20000000E-01 8.50000000E-01 + 7.90000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.90000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.90000000E-01 + 8.50000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.90000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 7.90000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 8.50000000E-01 + 7.20000000E-01 7.20000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 + 7.20000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 + 7.20000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 7.90000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 7.20000000E-01 + 8.50000000E-01 7.90000000E-01 8.50000000E-01 7.20000000E-01 7.20000000E-01 + 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 7.20000000E-01 7.20000000E-01 8.50000000E-01 + 7.90000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 7.20000000E-01 + 8.50000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 8.50000000E-01 7.20000000E-01 8.50000000E-01 + 8.50000000E-01 7.90000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 7.20000000E-01 8.50000000E-01 7.90000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 diff --git a/wrappers/python/tests/systems/tz2.truncoct.rst7 b/wrappers/python/tests/systems/tz2.truncoct.rst7 new file mode 100644 index 000000000..0638c2c68 --- /dev/null +++ b/wrappers/python/tests/systems/tz2.truncoct.rst7 @@ -0,0 +1,2917 @@ +Cpptraj Generated Restart + 5827 0.0000000E+00 + 0.0776278 3.1744082 -8.8438578 0.9994704 3.4310632 -8.5206947 + -0.1829471 2.3064334 -8.3979597 -0.5930547 3.8407547 -8.4885159 + 0.0983145 3.0748012 -10.3219843 -0.7794463 2.5384104 -10.6824360 + 0.1531776 4.4627404 -10.8604641 -0.8405319 4.7610207 -10.5262938 + 1.0107003 4.8797073 -10.3323603 0.3651973 4.4990749 -12.2662716 + -0.2943575 5.1386967 -12.5446091 1.2474704 2.2004344 -10.7783003 + 2.3603754 2.3767095 -10.2312479 1.0442290 1.4644449 -11.8690414 + 0.1332841 1.4886173 -12.3045816 2.1041365 0.6385385 -12.4315958 + 2.7862945 0.2887911 -11.6567173 1.4865171 -0.6527897 -12.9602785 + 0.6295859 -0.4475743 -13.6018829 2.2537491 -1.1273209 -13.5720596 + 1.0919044 -1.5835990 -11.9144564 -0.1669921 -2.0736656 -11.4988575 + -1.0821159 -1.6935753 -11.9283686 0.0335973 -2.9456878 -10.4433737 + -0.7420030 -3.4041440 -9.9869070 1.3525777 -3.2751472 -10.2792892 + 2.0091274 -4.3620973 -9.7345114 1.3261223 -5.0700884 -9.2888041 + 3.4012065 -4.4813142 -9.8062553 3.8465905 -5.3638430 -9.3713093 + 4.1342859 -3.5038335 -10.4950428 5.1967421 -3.6950724 -10.5270042 + 3.4676330 -2.5965247 -11.2125721 4.0367346 -1.9676875 -11.8812189 + 2.0539677 -2.4075398 -11.1707716 2.7834589 1.3833985 -13.6165895 + 2.1655352 2.0711393 -14.4206181 4.1260099 1.2661990 -13.8055029 + 4.6566715 0.6956928 -13.1628361 4.8419390 2.0759325 -14.7543869 + 4.2046695 2.3715615 -15.5878086 5.4700780 3.2252600 -13.9243460 + 6.0306849 2.8473024 -13.0693789 6.4981861 4.0285106 -14.7510042 + 7.3386097 3.4042666 -15.0545006 6.0902829 4.3752203 -15.7004824 + 6.8939958 4.8692555 -14.1812782 4.4322071 4.0506334 -13.3659105 + 3.9984112 3.4523380 -12.7531595 5.8288264 1.0395170 -15.3772812 + 6.2435031 0.0870451 -14.6699343 6.2003045 1.2529933 -16.6119862 + 5.9052186 2.1249716 -17.0275326 7.2103639 0.4807253 -17.3780632 + 7.4290900 -0.4906318 -16.9345264 6.7566376 0.1610883 -18.7986774 + 5.8480878 -0.4409216 -18.8135948 6.5741668 1.1345847 -19.2537708 + 7.7573185 -0.6625586 -19.5748272 8.5375328 -0.2851950 -20.5987492 + 8.5485840 0.6949738 -21.0521202 9.1723328 -1.3683645 -21.1514130 + 9.8673058 -1.3679836 -21.8842926 8.9496145 -2.4806449 -20.3810024 + 9.5093527 -3.7770355 -20.4527340 10.2154408 -4.0349350 -21.2281876 + 9.1359205 -4.7368269 -19.5122242 9.3820925 -5.7882485 -19.5298672 + 8.3078327 -4.3569918 -18.3999920 7.9533296 -5.0954280 -17.6961174 + 7.7008133 -3.1002383 -18.4468594 6.9078526 -2.8239198 -17.7676964 + 8.0072489 -2.0729594 -19.4019928 8.4421577 1.2974975 -17.3752289 + 8.5385742 2.1842787 -18.1811066 9.4409943 1.0187329 -16.5573654 + 9.3887005 0.3176833 -15.8321791 10.6237736 1.8722904 -16.5986557 + 10.6474228 2.5297625 -17.4677200 10.5410891 2.7009382 -15.3390827 + 9.6569920 3.3384778 -15.3351727 10.3548374 2.0676742 -14.4716778 + 11.6778231 3.6499827 -15.1048479 12.6248426 3.1106467 -15.0855303 + 11.6344843 4.3868179 -15.9069052 11.5741854 4.3806787 -13.7674570 + 11.5420628 3.6929266 -12.7150755 11.6250267 5.6041770 -13.7599783 + 11.8387089 1.0631253 -16.5531883 11.9512415 0.1492195 -15.6752167 + 12.8055658 1.3872519 -17.4635563 12.5734406 2.1033926 -18.1368771 + 14.0687408 0.7145303 -17.6627483 14.4484673 0.9919378 -18.6460857 + 15.1477270 1.2798742 -16.7256451 14.6886787 1.2944881 -15.7371311 + 15.9635830 0.5571126 -16.7156620 15.7119713 2.6229022 -17.0475445 + 15.7445116 3.0190187 -18.1725540 16.2657185 3.2357800 -16.0291023 + 16.1663170 2.8008199 -15.1229944 16.8817329 4.0267811 -16.1513405 + 13.9534130 -0.8824645 -17.6409512 14.7817621 -1.5360614 -17.0182667 + 12.9879112 -1.5220087 -18.3106766 12.2527428 -1.0537653 -18.8209476 + 12.9408131 -2.9645107 -18.4043865 12.6700191 -3.3156881 -19.4001026 + 13.8893089 -3.4897811 -18.2923737 11.9953527 -3.7070427 -17.4867077 + 11.9685268 -4.9764390 -17.5291214 11.3644257 -2.9911199 -16.5170612 + 11.6123009 -2.0191991 -16.3986206 10.5572767 -3.6250954 -15.4738207 + 10.3205004 -4.6454697 -15.7752733 11.4427948 -3.6137683 -14.1822376 + 12.5239086 -3.6375592 -14.3190832 11.2784863 -2.7244811 -13.5737295 + 11.1368160 -4.8408766 -13.2957869 11.6179476 -4.7163119 -12.3256855 + 10.0720654 -4.8391910 -13.0625439 11.5189867 -6.2102299 -13.8805714 + 11.1290874 -6.4452009 -14.8709593 12.5915899 -6.2602482 -14.0679760 + 11.2758169 -7.3926463 -13.0232382 11.8072433 -8.2430143 -13.4505091 + 11.6613340 -7.2959089 -12.0082912 9.8515930 -7.8025384 -13.0779848 + 9.2641821 -7.1515689 -12.5767002 9.5197334 -7.7750568 -14.0315142 + 9.7579556 -8.7154255 -12.6561203 9.2377815 -2.8809488 -15.1527224 + 9.2588720 -1.6564533 -14.9603872 8.1464872 -3.6094031 -15.0053062 + 8.1935730 -4.5949740 -15.2210207 6.9868922 -3.0673270 -14.3507671 + 6.7464099 -2.1081257 -14.8092556 5.7757502 -4.0246248 -14.3510265 + 6.0384150 -4.9826422 -13.9023485 5.0114660 -3.5191810 -13.7606916 + 5.2735372 -4.3483930 -15.7329025 5.2664204 -5.5838885 -16.3462353 + 5.6814113 -6.4794168 -15.9078159 4.7507010 -5.4160976 -17.6090736 + 4.5710406 -6.1481781 -18.2812939 4.2254086 -4.1747327 -17.8464928 + 3.5471611 -3.6623385 -18.9381104 3.2856052 -4.2306442 -19.8184605 + 3.0375364 -2.3982589 -18.8010139 2.5356293 -1.9880699 -19.6648617 + 3.1735263 -1.6528186 -17.6144543 2.6014802 -0.7373357 -17.5818634 + 4.0772624 -2.1233094 -16.6832733 4.2347016 -1.5069915 -15.8104811 + 4.6049886 -3.4398794 -16.7114601 7.3217716 -2.8057399 -12.8325148 + 7.8013639 -3.7097685 -12.1053600 7.1857500 -1.5459522 -12.4693060 + 6.8114324 -0.9677603 -13.2080078 7.4283624 -1.0845578 -11.0867891 + 7.4395094 -1.8892341 -10.3516216 8.8564310 -0.4942475 -10.8987494 + 9.5537367 -1.3013248 -11.1234522 9.1514626 0.7232180 -11.7549171 + 10.0875750 1.1910253 -11.4500389 9.2938194 0.3383687 -12.7647324 + 8.4340811 1.5438614 -11.7577753 9.1093063 -0.1273156 -9.5680475 + 10.0221376 -0.3525510 -9.3741169 6.3356891 -0.1602753 -10.6163950 + 5.5761447 0.3868482 -11.4118185 6.2830296 0.0169779 -9.2923441 + 6.9575505 -0.5166337 -8.7628317 5.2335329 0.7917467 -8.5966873 + 4.3619933 0.7643466 -9.2507277 4.8499389 0.1270844 -7.2662754 + 4.6403375 -0.9213554 -7.4782691 5.6752353 0.1181769 -6.5543013 + 3.6380470 0.8071982 -6.6492062 3.6016977 1.7481261 -5.7104177 + 4.3601422 2.1714013 -5.0685453 2.3824148 2.2726600 -5.5634751 + 2.1768332 3.0994093 -5.0209608 1.5046650 1.5045537 -6.2760167 + 0.0872209 1.4933833 -6.2567716 -0.5259362 2.2055857 -5.7246003 + -0.5376400 0.5423068 -7.1219516 -1.5997845 0.5270291 -7.3169279 + 0.2572207 -0.2950256 -7.9836540 -0.2426765 -1.0273542 -8.6002560 + 1.6725560 -0.2555747 -8.0259981 2.2691176 -1.0226629 -8.4972630 + 2.2917781 0.6071771 -7.0490279 5.6411295 2.2533545 -8.4274368 + 6.7993884 2.4842191 -8.0241632 4.7267270 3.1971257 -8.5887775 + 3.8229737 2.8425753 -8.8673887 4.8770194 4.6564174 -8.5003405 + 5.7065668 4.8206820 -7.8126135 5.1107850 5.3346057 -9.8234987 + 4.2357383 5.3723564 -10.4723215 5.4467483 6.3660212 -9.7166767 + 6.2663379 4.7313890 -10.7121983 6.0822601 3.6836271 -10.9497070 + 6.3277888 5.1070709 -11.7335634 7.7185769 4.8617830 -10.0686703 + 7.9174752 5.9185185 -9.8901958 7.7546244 4.3639216 -9.0996838 + 8.8258705 4.4510212 -10.9531794 8.6324797 3.5454943 -11.5282640 + 8.8619661 5.2714901 -11.6698570 10.1323471 4.4023848 -10.2776928 + 10.8946056 4.3811202 -10.9399691 10.2381725 5.2103710 -9.6809807 + 10.1857586 3.6107042 -9.6528006 3.6130378 5.2756710 -7.8560696 + 2.5298717 4.7585077 -8.0476656 3.6904993 6.3912878 -7.2158513 + 4.5615330 6.8440776 -6.9783950 2.7804537 6.5906057 -6.8257365 + 5.0734220 10.4199162 6.3298407 5.0558081 11.2001944 5.7756848 + 4.9017944 10.7488775 7.2122011 6.3026237 -7.7664156 -13.6427116 + 5.3928642 -7.8583999 -13.3596773 6.7669854 -7.4645591 -12.8620167 + 1.9083470 -2.8243258 16.5871067 0.9799601 -2.7081106 16.7891560 + 1.9943842 -2.5321026 15.6796732 2.4079783 -11.9960012 7.2981677 + 2.8519907 -11.8877239 6.4571199 2.1856842 -11.1049643 7.5681143 + -3.5469587 -5.9187493 8.1687717 -3.7765973 -6.4618707 7.4147701 + -2.7077084 -5.5236282 7.9326148 11.6538248 11.5826530 11.2727795 + 10.7761831 11.9392767 11.4098768 12.2354183 12.2010908 11.7149525 + 20.3874989 15.5546722 -0.2573065 20.6313343 15.0230064 0.5003929 + 19.6697674 15.0721388 -0.6674947 -4.5022941 -16.7428360 -7.8444824 + -4.8598704 -17.6063251 -8.0512629 -5.0802932 -16.4013710 -7.1621699 + 1.7431451 -1.6693950 14.0117254 1.2715534 -1.0718125 13.4314432 + 1.6012821 -2.5356541 13.6300163 9.0426340 -0.1106416 14.1681614 + 8.6495037 -0.6068457 14.8861179 8.3945847 0.5620138 13.9588814 + 13.9616518 -5.8260775 -10.2374201 13.9331837 -5.3939342 -11.0910444 + 14.8442879 -5.6523232 -9.9103203 10.7888365 -17.4713516 11.1186733 + 11.7165899 -17.2455864 11.1860266 10.7733965 -18.4282856 11.1351061 + 19.8936901 11.2305784 -4.7136431 19.7114811 11.4798479 -3.8076098 + 19.3131828 10.4876871 -4.8790388 -8.0797520 -10.7527676 -13.4088545 + -8.7186804 -11.3470230 -13.8023787 -7.9897304 -10.0428076 -14.0445309 + 9.1015587 0.9177361 3.6163263 8.4318342 1.5936188 3.5120058 + 9.2987967 0.6360950 2.7230136 -5.1186309 -14.4449224 -13.0623446 + -4.9328341 -13.5308971 -13.2774477 -6.0742292 -14.4972572 -13.0443153 + -1.8578620 6.8587418 15.0050459 -1.9541266 7.5758715 15.6316957 + -1.9453011 6.0654821 15.5335579 1.5674264 1.7557251 6.4435754 + 0.6949456 1.3636314 6.4792361 2.0555363 1.1991149 5.8368087 + 19.3893795 3.1084843 6.8391290 20.0033607 2.7136257 6.2199802 + 19.9414158 3.6198828 7.4307013 2.2670457 10.3891058 14.7933979 + 2.2782352 9.6267357 15.3721008 3.0521328 10.2922287 14.2544308 + -4.5928030 10.1632023 -20.7654839 -4.0291634 9.4185085 -20.9751797 + -4.3500643 10.8343868 -21.4033108 12.1202154 0.8604196 9.0192366 + 11.9928389 0.0347032 8.5521173 13.0529127 1.0508666 8.9190521 + 1.7968255 7.2554636 -2.9312670 1.7099653 6.7128272 -3.7149971 + 1.1124665 7.9185281 -3.0219853 -14.6947308 13.6960754 0.5329631 + -14.6521626 13.3605509 -0.3624937 -15.1312056 13.0027885 1.0280130 + 8.5889559 10.0659971 7.8683553 8.8613682 10.0918121 6.9511003 + 7.6325421 10.0854635 7.8348031 7.3054314 -12.8699322 -1.9748825 + 7.1851697 -12.1360569 -1.3722260 7.0652709 -13.6421776 -1.4628347 + -8.0195227 -6.2795043 2.8150506 -8.7774982 -5.7231956 2.6355343 + -7.3467360 -5.9707623 2.2081997 15.5681877 -14.4489050 -6.5682769 + 16.3167419 -14.7751713 -6.0688286 14.8755798 -15.0898609 -6.4079561 + 0.5497890 18.1518650 3.6685221 0.5312645 17.6661358 4.4931159 + -0.3402278 18.0743942 3.3248649 6.0860753 15.8890257 -9.9161987 + 6.0883274 14.9318342 -9.9194775 5.1751451 16.1257992 -9.7419100 + 16.9515400 -15.4572315 2.4296587 17.8813915 -15.4043360 2.2087359 + 16.5156689 -14.9319191 1.7586179 7.6634693 6.0214391 7.3081775 + 7.0487318 6.7216268 7.0889359 7.9968905 6.2577686 8.1737471 + 18.2401066 -11.2991123 3.4285910 17.9203949 -11.6054611 4.2772169 + 17.6987076 -10.5350466 3.2302914 9.2586870 13.1181211 11.7032595 + 9.1998215 12.7617865 12.5897083 9.5492096 14.0217133 11.8271494 + -4.9043083 5.8158050 6.2036324 -4.5565715 6.6247706 5.8282857 + -5.8446946 5.8558683 6.0295634 15.7318325 10.0188055 -1.3822379 + 16.4177151 9.5790195 -0.8798591 14.9654856 9.4531469 -1.2874982 + -14.5057535 15.6617441 -2.5117245 -14.5337296 14.7065477 -2.5669453 + -14.9667788 15.9605751 -3.2955534 7.3343344 -5.2472367 6.5152130 + 6.4919167 -5.4493790 6.9222784 7.5796056 -4.3975921 6.8815160 + 11.2797222 0.8635864 18.0645370 11.8314800 1.6246789 17.8841667 + 11.1420822 0.4591458 17.2079659 1.9593285 7.5110650 4.5070825 + 2.6937404 7.7614889 3.9465835 1.9162239 6.5576587 4.4336624 + 19.8714008 6.9513483 6.1426759 20.2810402 7.7858105 6.3709326 + 18.9431400 7.1606560 6.0389824 -17.0939789 -17.5971794 -7.4082656 + -17.3873348 -17.0401268 -6.6872482 -16.1403713 -17.5145512 -7.4020815 + -12.4966516 -6.9271307 -1.9276990 -12.4192944 -6.8192835 -0.9797450 + -11.6680307 -7.3270564 -2.1916666 12.4406776 9.6688242 3.2478762 + 13.2993975 9.2583895 3.3497288 12.3095341 10.1550303 4.0619016 + 11.4054203 1.2425549 15.0087242 10.6070309 0.8358182 14.6720171 + 11.5602837 1.9853201 14.4251585 17.3999920 17.8958206 0.7614577 + 16.9514751 17.0630569 0.9083292 18.0944233 17.9132538 1.4200113 + 13.3399754 2.7248070 17.5843601 14.0811949 3.0404954 18.1012402 + 12.8273115 3.5108662 17.3958950 -7.1285172 18.4744949 -16.6202660 + -7.1833153 19.3296680 -16.1937599 -6.9169364 17.8666191 -15.9117813 + -14.9362001 14.9653978 9.8032665 -15.6288567 14.5278845 10.2982826 + -14.1814308 14.9605188 10.3919353 9.6927786 -3.1289771 15.3635950 + 10.2308979 -2.7045681 16.0318279 8.8475313 -2.6830707 15.4179726 + 17.7347660 7.7064972 8.0441923 16.9423962 7.9750962 7.5791793 + 17.4357147 7.5063481 8.9311771 -17.8673077 -0.0005082 -17.2492619 + -17.1887722 0.6433184 -17.4525127 -18.6873283 0.4330248 -17.4855804 + 0.2295380 -22.2546444 7.4303193 0.9277044 -21.9223118 6.8660941 + -0.3278010 -22.7674427 6.8449612 7.2246051 -17.0019112 -10.7199316 + 6.9174008 -17.4199638 -9.9155130 6.4400616 -16.9204960 -11.2622366 + 2.1617825 -12.6581154 -10.2637386 1.8501371 -12.7529593 -9.3636751 + 3.0241151 -12.2517891 -10.1770563 -2.1605463 18.5635910 2.9410334 + -2.5620856 17.6948700 2.9230762 -2.3869331 18.9496288 2.0948915 + -0.6023999 -14.3294992 2.3086376 0.0175326 -14.3415089 1.5794111 + -0.0860640 -14.0303164 3.0570486 1.2925072 -16.4343510 -15.2448320 + 1.4968102 -15.9491234 -14.4454288 1.8432986 -16.0321922 -15.9164925 + 17.5941238 3.1774843 -3.0753686 17.3386459 3.6479204 -3.8688753 + 17.5764103 2.2543952 -3.3280046 -2.2261183 16.7989464 14.3278465 + -1.3132817 16.5586472 14.1690483 -2.7266610 16.0279217 14.0609941 + 5.3878393 11.2972755 8.9394884 6.0354061 10.9501963 9.5530233 + 4.6069250 11.4442110 9.4731693 -9.9230947 -3.9724951 5.6155829 + -9.5710840 -4.7040153 5.1084356 -10.5370064 -3.5420084 5.0205832 + -15.0128746 10.8197279 1.2363992 -15.6580563 10.2584095 0.8064056 + -14.1754332 10.5595255 0.8527091 11.1000948 6.4544373 -0.0453179 + 11.3585253 5.6602964 0.4224277 10.2216234 6.2636008 -0.3741049 + -5.6720095 -11.3416834 -11.6708784 -6.4139376 -11.5167809 -12.2497702 + -6.0713825 -11.0521727 -10.8505640 20.1435585 4.4309602 -2.2171326 + 19.4587975 3.9506075 -2.6825309 20.0249386 5.3409700 -2.4892411 + -15.4860678 6.9123397 2.1159492 -15.7798586 6.9470353 1.2056112 + -15.0164318 6.0810947 2.1845453 -15.4596443 4.5076723 -10.7782249 + -15.6551037 3.8061230 -10.1570511 -15.0464239 4.0636725 -11.5187273 + 7.1984310 -15.7899199 -18.6404915 6.2748013 -15.8196955 -18.8899956 + 7.1865096 -15.7182178 -17.6860542 -6.7273097 20.2372799 -2.2824368 + -6.1755090 19.4808178 -2.0836544 -7.6200209 19.8920593 -2.2714076 + -17.2146645 -1.1380062 -6.4488306 -16.3018875 -1.2972826 -6.6890440 + -17.7167339 -1.7280306 -7.0109954 7.9280920 -14.3784466 -10.5275106 + 8.8663683 -14.4039640 -10.7151756 7.5841894 -15.1828785 -10.9159079 + 1.2018068 1.3950831 24.5620594 0.9655231 1.3709612 23.6347942 + 2.0385928 1.8593457 24.5839977 1.3140373 -13.4802628 -2.6447761 + 2.0231032 -12.9204473 -2.9611051 0.5359604 -12.9238167 -2.6793613 + 2.8886111 21.8270683 10.4034443 2.4233415 22.1446667 9.6295671 + 3.0633919 20.9047928 10.2161102 -19.3709335 -4.7076817 0.9206843 + -18.6578522 -5.0645304 1.4502174 -20.1671753 -5.0324020 1.3411460 + -3.7317197 -10.1382847 3.7359173 -3.8370712 -11.0733805 3.9112144 + -2.8026037 -9.9686308 3.8914580 -17.8451633 13.2254496 -2.2498529 + -17.5341625 12.6546783 -2.9525123 -18.0239925 14.0609293 -2.6813898 + 10.3025694 -6.8997908 13.4289207 10.8262863 -6.2633753 12.9421673 + 10.9293585 -7.5727463 13.6944370 -4.1554394 -19.6727409 -0.7344016 + -4.2038321 -20.4330750 -1.3138682 -5.0657659 -19.4915085 -0.5005367 + -9.0557699 12.6158962 -7.9039817 -8.9451628 12.8515759 -6.9828668 + -9.9078321 12.1811886 -7.9393349 -3.9984701 6.6762195 -8.0843210 + -4.7968035 7.1269870 -7.8091774 -4.0422134 6.6737990 -9.0405178 + 2.5372274 -20.4424534 7.5819983 2.3482389 -20.5423603 6.6489744 + 2.5666909 -19.4957676 7.7203784 -14.7169266 -2.7320125 12.2653379 + -14.4310808 -3.6350400 12.4034157 -15.5898046 -2.6946416 12.6563873 + -2.3517702 -16.6228943 2.8411870 -2.2506413 -17.0915775 2.0127304 + -1.9576497 -15.7654428 2.6809425 4.9327598 6.3776507 -19.6419964 + 5.4776583 5.8396449 -19.0676556 5.4798241 7.1348186 -19.8509216 + -4.1038833 19.7442532 11.8566799 -4.9093008 19.7584553 11.3396378 + -4.3951311 19.8845768 12.7576323 16.9351864 -10.9977570 -14.7537460 + 16.9067001 -11.9490423 -14.6513910 16.6504974 -10.6569910 -13.9057713 + 20.0259228 -7.3188648 -2.5310490 19.8545818 -7.3634253 -1.5903640 + 20.5458527 -6.5229273 -2.6423585 13.4021044 0.1889687 19.6197548 + 13.6165237 1.1083614 19.7777843 12.6003399 0.2163460 19.0975914 + 4.1177320 -17.9892483 8.2591724 3.7955329 -18.0463142 9.1587076 + 4.7257948 -17.2500629 8.2690001 8.1029205 -11.1511526 -7.1374435 + 8.6963835 -11.6873016 -6.6115365 8.4403172 -11.2256889 -8.0301027 + 4.6279411 -20.5797329 -2.4520614 4.0451608 -19.8220348 -2.4021363 + 4.4496517 -21.0722294 -1.6508796 12.5861835 -6.1626296 10.9653463 + 11.8194304 -6.6156249 10.6144686 12.4832020 -5.2566423 10.6741190 + 2.6420212 -10.0671377 -11.7024307 3.3577044 -10.6791201 -11.8742094 + 2.7403934 -9.3896828 -12.3714676 -4.9659882 3.4844635 4.4426641 + -5.1540203 4.1909084 5.0605731 -5.4415689 2.7297580 4.7897587 + -14.1150732 -9.6141777 7.4537091 -13.8694696 -9.5900211 8.3785486 + -15.0098581 -9.9541616 7.4523187 1.5000403 -7.2188911 -7.4281149 + 1.9970198 -7.9217558 -7.8467126 0.5939877 -7.5274386 -7.4380565 + -8.0120649 -14.1407356 -13.2033014 -8.0233698 -15.0689421 -13.4368353 + -8.7890568 -13.7773895 -13.6281481 1.5184495 -16.2267914 8.1944628 + 0.6041232 -15.9487391 8.2485609 1.5711287 -16.7186508 7.3749928 + 13.0688734 -12.8862009 4.2415576 13.8005781 -12.5622845 4.7668371 + 13.3167276 -13.7818413 4.0121498 13.6913881 -15.5825396 3.2197373 + 14.4991245 -15.7881441 3.6903982 13.9852753 -15.1581364 2.4136703 + -17.7691708 -4.3649626 -1.3426670 -17.5076504 -5.2743812 -1.1984595 + -18.0249157 -4.0489941 -0.4760700 -2.8016922 17.2493877 -8.2133656 + -3.3410220 17.7878990 -8.7924681 -2.9596932 17.6056042 -7.3390784 + -2.9466734 13.0259571 3.2817636 -3.8394954 13.2626162 3.0305803 + -2.4048445 13.3272848 2.5524797 -19.3207283 1.5608051 -14.6364050 + -19.0723858 0.7080854 -14.2794361 -19.6393147 1.3677611 -15.5181465 + -1.3818030 10.5809536 2.3934410 -1.7610083 11.0097952 3.1605983 + -1.2077463 9.6848860 2.6815350 -12.2027197 4.8222427 -0.1451070 + -12.1654472 3.9107199 -0.4348806 -11.3987303 5.2147856 -0.4853181 + 16.6527252 -6.3183045 9.8615599 17.4976768 -5.8704267 9.8203850 + 16.2529507 -6.0015235 10.6715374 12.1999493 16.1866188 -5.1092200 + 12.4755068 15.5155325 -4.4847660 11.8667154 15.6937027 -5.8590341 + -20.6756382 -8.4933777 3.1248610 -19.9999714 -8.4858437 3.8028359 + -20.8848991 -9.4197721 3.0055499 16.3142986 12.7744436 -5.0889163 + 15.4355240 12.5114050 -5.3624105 16.4904385 13.5736923 -5.5853109 + 19.1954250 -11.1292019 -1.7517672 20.0554352 -11.4906054 -1.9662522 + 18.9337482 -11.5904617 -0.9549003 -7.2167811 -16.4419270 -5.9210954 + -6.8174272 -17.2789936 -5.6843095 -7.9859118 -16.6812572 -6.4381933 + 1.9115963 -5.6916351 -16.5343494 2.8197567 -5.5177236 -16.7817993 + 1.4179869 -4.9602833 -16.9054375 -5.8690124 -0.7786558 -11.5975018 + -5.8260322 -1.7210746 -11.4355412 -6.0959454 -0.3997910 -10.7482700 + 4.4932699 -15.5000553 -13.5890198 3.7016618 -14.9749069 -13.4715166 + 4.5361776 -16.0473862 -12.8049154 7.0123367 -3.7763591 -2.4862063 + 7.3530431 -3.5804703 -3.3590057 7.7169304 -4.2621675 -2.0575218 + -8.2716160 14.1200104 4.7785268 -8.7903690 14.8823643 5.0353208 + -7.5349379 14.1147022 5.3896799 20.5053844 6.9532328 -8.0720186 + 20.6626682 6.3713059 -7.3284764 21.0102615 6.5683374 -8.7883883 + 3.6278224 18.2968082 -13.8873997 2.8082659 18.6524086 -14.2310677 + 3.4120643 17.3991642 -13.6345844 -7.2752070 5.8293357 18.1884174 + -7.4888854 5.5541878 17.2968655 -7.7033100 6.6799254 18.2856636 + -5.9681115 19.1522255 -5.5084271 -6.6615024 18.8355255 -4.9295120 + -6.1505785 20.0861378 -5.6120887 9.4529257 -16.8064842 4.2901478 + 9.5047359 -17.5957546 3.7510741 10.1414280 -16.9185085 4.9456224 + -3.6587863 -9.0957069 0.9170539 -2.9244206 -8.8740797 0.3444982 + -3.7037373 -8.3707266 1.5404439 1.9612195 10.7503986 1.8394978 + 1.7765944 9.8711767 1.5091741 1.6075903 10.7512321 2.7289793 + 11.7731581 -10.7851896 -14.2240677 12.5765400 -10.3009844 -14.0333996 + 11.9369879 -11.1962662 -15.0728359 9.9328156 -13.0720530 -6.2611070 + 9.2895145 -13.6430502 -5.8411574 10.6894913 -13.0921307 -5.6752133 + -15.4522715 2.9512239 0.5733716 -15.4713106 1.9942704 0.5838401 + -16.0949020 3.1963005 -0.0923567 -7.3761110 18.7121029 3.6328034 + -6.4818435 18.4341030 3.4347274 -7.9276009 18.0130272 3.2815416 + -1.7414825 21.4515228 -7.9280047 -1.3154775 21.5844917 -8.7748051 + -2.5166988 22.0121441 -7.9592285 13.2518196 -6.3678851 -5.5070591 + 13.9151115 -7.0569420 -5.4686465 12.6640987 -6.5601826 -4.7764168 + 3.1868799 -11.5350752 4.3426051 3.1625762 -12.4180412 3.9738050 + 4.0487266 -11.1973543 4.0988917 5.2698116 8.7000427 -5.8565788 + 4.5804372 9.3435583 -6.0205374 5.6076608 8.9264765 -4.9900818 + 2.3608010 -17.6894093 1.1896516 1.8774368 -17.8372021 2.0025158 + 3.0465050 -17.0658073 1.4287415 11.3244209 -5.9752274 4.4449234 + 10.5748463 -6.4467139 4.8083386 11.5525093 -5.3333049 5.1173391 + -1.9799293 -2.5031042 -5.0694833 -2.1814485 -2.9580166 -5.8872094 + -1.0842423 -2.1862819 -5.1861038 -6.1661024 -23.6389294 -9.1569471 + -6.2631383 -22.7192917 -9.4040899 -5.9635525 -24.0874825 -9.9779263 + 6.8707881 22.7283573 -2.7331178 6.9189839 21.8502827 -3.1111324 + 7.5377660 22.7304935 -2.0465555 13.6279860 0.1539779 -10.9398432 + 14.3331652 0.7575703 -10.7061129 13.1760626 0.5834020 -11.6661987 + 6.7068648 8.3285828 11.0895662 6.1102266 8.0455599 10.3966360 + 6.7685494 9.2774601 10.9797468 14.1804543 6.2523322 5.8022285 + 13.7453575 5.5243726 5.3583846 15.0040951 6.3643813 5.3275785 + -13.3571396 7.6143098 13.6905279 -13.6852322 7.6119933 12.7913160 + -12.6753426 6.9425049 13.6984510 7.8633313 -15.4240122 18.6108360 + 8.7412062 -15.7452326 18.4049587 7.3157649 -16.2091160 18.6145172 + 8.7165222 4.6293960 0.1146459 8.3614321 3.7416699 0.1603101 + 8.0185556 5.1847100 0.4620652 8.6870699 -4.7825098 -0.4534148 + 8.1798697 -5.5624065 -0.2281565 8.8315945 -4.3408375 0.3834066 + -12.5546455 -3.6968358 -15.2610817 -11.8612175 -3.1384463 -15.6126356 + -12.2433109 -3.9462228 -14.3909616 12.2513332 -11.5580902 -10.8498030 + 13.1945047 -11.6189966 -11.0012980 12.1260548 -11.9180145 -9.9717417 + 8.7074699 -18.1864929 -0.5341508 8.1235752 -18.8786774 -0.8442793 + 8.5406694 -17.4506607 -1.1231859 13.7281399 3.8630173 -1.1210375 + 14.0772219 4.5167542 -1.7268441 12.9132462 3.5697219 -1.5286626 + -8.9779654 -1.2098911 -19.0592709 -8.2553854 -0.9469771 -19.6293468 + -8.9808197 -2.1661439 -19.1017456 5.3499413 -11.5526571 0.8301946 + 5.7143188 -10.9241781 0.2069167 4.9860444 -12.2488565 0.2832775 + -20.1666679 -1.9206216 9.0912056 -19.6601467 -1.1736922 8.7722006 + -21.0232391 -1.5534244 9.3095694 -1.1724024 21.4270535 13.5382280 + -0.9538432 21.2782345 12.6182728 -0.8579856 22.3129177 13.7188301 + -18.2313595 14.9461603 4.5958576 -18.9303780 15.4897690 4.9593048 + -18.4676304 14.0530672 4.8464422 -11.7896824 -6.7957239 5.9070396 + -11.7450399 -6.0760965 6.5366235 -12.7251472 -6.9774237 5.8169117 + -9.7565680 -11.6495085 3.7984192 -10.3971977 -12.0239553 3.1937575 + -9.4261885 -10.8729792 3.3466632 9.7975302 -14.1073160 -2.6251194 + 9.3183756 -14.9143496 -2.4371278 9.1160383 -13.4639864 -2.8198714 + 9.9643421 -7.7655787 -7.4991460 10.6696339 -8.1640120 -8.0090933 + 10.4105816 -7.3287544 -6.7736897 7.1467609 -2.7365506 7.4335685 + 7.0654473 -2.0999076 6.7234235 7.6356516 -2.2745693 8.1145906 + 15.1675539 -13.2691841 1.5773880 15.3352394 -12.8177671 0.7501422 + 14.3981228 -12.8291140 1.9386998 -3.9533167 10.0900993 8.9973660 + -4.2498279 10.3845615 8.1362019 -3.7469738 10.8973341 9.4685631 + -9.8891840 10.8563786 18.1526585 -10.2239704 11.1479540 17.3046398 + -10.3902693 10.0647087 18.3486271 -18.6718140 -13.0700712 10.5512438 + -19.1092300 -12.2499599 10.7799683 -19.1516056 -13.3927774 9.7884254 + 21.2892323 -11.4650984 3.7134073 20.3738956 -11.7440290 3.6891885 + 21.6959763 -11.9135637 2.9720097 16.4580841 -4.2342710 0.9085425 + 16.6457882 -5.0303807 0.4113421 15.5161028 -4.2719293 1.0743258 + -13.3321934 -15.3318691 -3.6821446 -12.8737192 -15.9490032 -3.1118991 + -12.9440575 -15.4703369 -4.5460949 15.2129259 9.2055979 3.1365325 + 15.5989447 9.4813652 3.9679010 15.3916550 8.2664185 3.0893106 + 5.4984546 -13.9619303 -8.4895868 6.4530954 -13.9204054 -8.4332962 + 5.2985587 -14.8979931 -8.4818068 -2.3902907 2.7361639 20.9758377 + -3.2687316 3.0459890 20.7554245 -2.3477564 2.7957599 21.9302330 + 15.9827843 6.2423635 3.6534250 15.5158358 5.7724566 2.9624994 + 16.7103500 5.6654458 3.8858993 -11.8138819 16.6762371 -9.8293266 + -12.5701876 17.2023392 -10.0890369 -11.1252060 16.9264297 -10.4452496 + 18.3830452 8.2477074 3.7571814 17.7173462 7.5716691 3.6304934 + 19.0072460 8.1055317 3.0455711 -14.6120167 4.6961031 19.1295605 + -14.8402672 5.6118751 19.2892303 -14.4506969 4.6502757 18.1871662 + 14.9913654 10.8882952 9.3161697 14.1704988 11.3451385 9.1325817 + 14.7689896 10.2646980 10.0074778 11.7889805 -13.6123056 -0.9749427 + 11.2864666 -14.0255747 -0.2728601 11.2418747 -13.7151508 -1.7536145 + -3.7607489 3.2059941 -7.0045791 -4.5012407 3.2027347 -6.3980370 + -3.0610492 3.6504767 -6.5259480 -18.8797321 -7.0353885 -3.1362739 + -18.6146755 -7.3441420 -2.2698741 -19.4356956 -6.2763305 -2.9603007 + -10.9990587 -2.8929741 -7.5938005 -10.2636204 -3.4312587 -7.3012052 + -10.8060484 -2.7023315 -8.5117512 10.5154314 -2.0153091 -5.1632085 + 10.0967340 -2.6920414 -4.6312699 10.9002848 -1.4136878 -4.5258927 + -20.6358585 -11.5018253 -2.6771908 -20.0381241 -10.9996119 -3.2310216 + -20.0615997 -12.0215044 -2.1147025 9.7060556 5.9675531 -4.3718863 + 9.3306837 6.8223224 -4.5833025 9.3563051 5.7600689 -3.5053666 + 5.1672268 -7.9257164 -5.1133933 6.0520978 -7.8677077 -4.7530179 + 5.2749538 -8.4002075 -5.9377022 9.3026829 -18.2564030 7.1003866 + 10.1242332 -17.9588737 7.4912343 9.5653038 -18.6756477 6.2809377 + 12.1859827 12.0239630 -11.7915049 13.0955524 11.8805447 -12.0529366 + 12.1967859 11.9513264 -10.8371258 18.8847427 -8.4398088 -4.7688584 + 19.2985878 -8.2609892 -3.9244726 19.0635967 -9.3659077 -4.9319048 + 8.3753281 6.0875468 13.5660505 9.0333023 5.4289699 13.3433895 + 7.5393643 5.6289835 13.4816923 -17.1943817 -6.6842370 -5.1159911 + -16.5203209 -6.7494197 -4.4395113 -18.0209885 -6.7190695 -4.6345983 + 3.8629408 -10.1768961 11.1619663 2.9359815 -9.9389715 11.1812153 + 3.8649507 -11.1339579 11.1781139 5.7772527 22.8138676 8.8028364 + 6.0618844 22.0587292 9.3176031 6.1275425 23.5702572 9.2733698 + -19.5874405 -8.5013037 -0.6367647 -20.2510662 -7.8460703 -0.4211248 + -20.0750389 -9.2031441 -1.0679247 0.7578055 -9.8419466 8.1340389 + 1.2157574 -9.5269842 7.3547382 -0.1592836 -9.6142082 7.9813476 + 13.1657677 8.0836658 -1.1502423 12.5863256 7.4640303 -0.7069243 + 14.0080423 7.6314774 -1.1985213 -3.2613819 -6.1350808 4.8569942 + -3.3232050 -5.2126546 4.6089220 -4.1540294 -6.3771200 5.1036305 + 4.5252748 1.4566172 8.2471075 5.2138948 1.9907191 8.6430492 + 3.7161496 1.7723083 8.6494589 19.3055210 -14.2355375 -0.1400531 + 19.3872623 -14.6646194 -0.9917803 19.5405464 -14.9136658 0.4933003 + -6.6967783 1.4490967 1.7608819 -6.7429657 2.1915932 2.3632088 + -5.7598662 1.3132700 1.6195363 -5.3840284 -15.8206644 13.8804407 + -5.9922228 -15.5207939 14.5560217 -4.8834357 -16.5192776 14.3018408 + 18.3085690 -3.1778173 -13.0981550 17.4145241 -3.0517709 -12.7803097 + 18.7783756 -2.3959329 -12.8080320 2.4465225 18.6262703 -5.9102654 + 1.6431857 19.1248837 -6.0594888 2.2780113 18.1357479 -5.1057644 + 0.6726356 -1.0441967 3.1177602 1.1408877 -0.2282751 2.9410007 + -0.1603518 -0.7648346 3.4976559 -7.6839957 -5.7222052 -3.8141513 + -8.2620049 -5.0256324 -4.1254778 -6.8008890 -5.3762865 -3.9433589 + -0.1286857 -5.4408770 6.8605170 -0.2056609 -6.1901321 6.2698193 + 0.5752362 -5.6819496 7.4626880 19.1513367 -5.3404975 9.4615088 + 19.9246273 -4.8794050 9.7865429 19.4127331 -5.6699591 8.6016493 + 16.0854397 -5.4775405 12.9315920 15.8868542 -6.3562579 13.2550898 + 16.6973305 -5.1183805 13.5741072 11.1299620 8.7445927 8.1602001 + 11.4411373 8.9256716 9.0471125 10.2168827 9.0318327 8.1634188 + 7.8126063 -16.2858162 -2.3375111 7.1799922 -15.7719469 -1.8355451 + 7.2783122 -16.9099159 -2.8286941 11.6683521 -12.0200186 -8.3159933 + 11.9550676 -12.9331722 -8.3027287 11.0875044 -11.9403391 -7.5593562 + 14.7244310 9.3970509 11.4069595 14.4168167 10.0031013 12.0809832 + 13.9671974 8.8421183 11.2202015 16.4049263 -10.4464636 -2.5264175 + 16.3599606 -9.5900955 -2.1011596 17.3129807 -10.5207376 -2.8199377 + -19.6178646 4.6909094 13.3962069 -20.2226105 4.1932516 13.9465265 + -19.6077423 4.2186580 12.5636749 -2.4783602 -5.6355958 -0.3296441 + -1.7913784 -5.0996203 -0.7258994 -2.2786770 -5.6272068 0.6064585 + -13.4297476 9.8178215 -6.4650097 -14.2249346 9.5386896 -6.9188752 + -13.1584673 9.0495214 -5.9626603 4.1697793 4.9176211 -4.6148410 + 4.9940867 5.0113158 -5.0923028 4.4035616 5.0753083 -3.7001212 + -8.8218164 11.7009878 13.8914776 -8.7353745 11.8102713 14.8384819 + -9.1011534 12.5603456 13.5757151 8.5859108 13.8593245 8.9769650 + 8.9774332 13.7396383 9.8421917 9.2825699 13.6239462 8.3641882 + 20.6837387 10.6785488 3.3292129 21.3735752 11.2842312 3.0580902 + 20.7212009 10.6854992 4.2856545 -15.7035599 -13.4782124 7.9684715 + -15.9916811 -14.1782427 8.5542841 -15.1555605 -12.9170885 8.5171680 + 5.5355334 -3.6524107 -0.3527138 6.1350951 -4.0704827 0.2653261 + 5.9805355 -3.7152286 -1.1978523 -13.3199139 13.0282717 -9.0669842 + -13.0369577 12.8451929 -9.9628906 -13.9531145 13.7404900 -9.1566124 + -16.9833565 2.7774138 -1.6644396 -17.7344036 3.3625257 -1.7634602 + -16.8721695 2.3819938 -2.5290272 13.7115641 -1.2156035 -6.2560577 + 14.1863003 -0.5252936 -6.7190156 12.8298397 -1.1906321 -6.6277704 + 15.3529015 -13.6903553 -9.0391073 15.3862743 -13.9629726 -8.1221571 + 14.5682564 -14.1143675 -9.3866377 -6.0626478 7.1256704 -2.1104949 + -6.9679737 7.0987630 -2.4201601 -6.0734673 6.6246271 -1.2949766 + 15.7308044 10.3503399 5.9442701 15.6539927 11.2578869 6.2387028 + 15.4639339 9.8294172 6.7016683 20.4949780 12.5533018 0.2334053 + 19.9560375 12.2861290 0.9779810 21.3458385 12.1457300 0.3951228 + 3.6912405 6.6236873 -12.8393192 4.1372738 5.8345056 -13.1466923 + 2.7782099 6.4990263 -13.0982914 12.0479040 9.5880089 -3.6803901 + 12.4952469 9.2159615 -2.9203267 11.4647493 10.2525206 -3.3135271 + 20.0113354 2.3852842 -16.2321987 19.6651745 1.4935277 -16.2664680 + 19.3354225 2.8872478 -15.7767811 9.2746763 0.4801199 6.2265396 + 9.8621473 1.1964900 6.4672132 9.2164860 0.5283865 5.2723303 + -4.5839248 4.5263729 1.9724512 -4.0684714 5.2116013 2.3978944 + -4.7074332 3.8631163 2.6514711 0.6269127 -1.4134140 -4.9097810 + 0.5360497 -0.5634871 -5.3405938 1.5278912 -1.4230747 -4.5867076 + 6.9081836 -4.0698705 2.1193042 6.2698460 -4.2817168 2.8003900 + 7.6376266 -3.6681678 2.5913000 -18.5450497 -12.4763279 -1.3850331 + -17.8176994 -11.9795675 -1.7597662 -18.3988819 -12.4388170 -0.4398030 + -19.2796745 -2.2923322 -8.1451082 -19.4499702 -3.2287169 -8.0430555 + -20.0444012 -1.9596210 -8.6149244 -17.0356197 10.1608381 -0.8915162 + -16.8352814 10.5563116 -1.7398661 -16.8806458 9.2251644 -1.0208561 + 14.3506832 -7.8392630 -2.6682291 14.8346500 -7.0230441 -2.7939079 + 14.1786242 -7.8732328 -1.7272329 14.6822739 13.2177639 -0.5020654 + 15.3331575 13.2085466 -1.2038474 14.9581232 12.5177593 0.0896545 + -6.3991861 -15.8414230 4.8387198 -6.6604729 -14.9244986 4.7538037 + -7.2209010 -16.3300304 4.7909884 4.9276791 -8.7432346 9.0970201 + 5.0824022 -9.3804369 8.3996925 4.4685311 -9.2378120 9.7758484 + 8.1468639 24.1759071 -0.2142407 9.0961351 24.0924873 -0.3045581 + 7.9299903 23.6345196 0.5447690 10.2803640 -16.7921047 -8.2776899 + 9.6218710 -16.7873383 -7.5829992 10.1842604 -15.9408092 -8.7046452 + 3.9094536 -14.4905977 18.0505810 4.7954550 -14.1966143 17.8389034 + 3.3400712 -13.9453583 17.5076733 -1.7086265 -7.7391329 -14.3593111 + -1.4867427 -7.4066706 -15.2290630 -1.0406898 -7.3673730 -13.7832146 + -20.5846825 10.1722374 5.9139981 -21.1594200 9.8921051 6.6263413 + -20.1273975 9.3746881 5.6474671 6.6347313 -10.3957119 11.7639465 + 5.9136281 -10.0069733 11.2688465 6.3232274 -10.4107237 12.6689177 + -10.8334799 2.5553949 22.9020634 -10.5598984 2.2549074 22.0354080 + -11.2130709 3.4203017 22.7468910 6.0201063 -10.4011259 17.7464790 + 5.0891538 -10.5976276 17.8511009 6.1248951 -9.5287151 18.1261501 + -9.7897606 -10.2640676 14.4887476 -10.0261393 -10.1364756 13.5700111 + -8.9863396 -10.7835751 14.4594297 -2.2523782 14.0893373 16.4959564 + -2.7206299 14.9210634 16.4238110 -2.7471914 13.4869385 15.9405222 + 15.9579906 -1.7124910 -1.7534447 15.1182146 -1.8684555 -1.3213757 + 16.3290863 -0.9607775 -1.2914419 -9.1584969 5.6569128 22.2059212 + -8.8880396 6.5624728 22.0541134 -10.1009836 5.7117071 22.3638725 + -7.5641942 4.4973636 20.5974655 -7.6173081 4.7058930 19.6647663 + -8.2663641 5.0100589 20.9978809 15.0573540 14.3244324 10.4259605 + 15.4160433 15.2020130 10.5579681 15.7637186 13.8385057 10.0003376 + 16.9847927 -6.1077271 -1.0320742 16.7371845 -7.0315776 -1.0697880 + 16.4370747 -5.6857491 -1.6940194 -7.8784881 15.4369259 -1.5244772 + -8.4007168 14.8880806 -2.1095219 -7.0113091 15.4607534 -1.9290318 + -5.5169997 -13.0501003 -7.9796057 -5.5287499 -13.7148762 -8.6682034 + -4.8709135 -12.4092255 -8.2763958 14.3553038 -4.2381158 -7.0057826 + 13.7393513 -4.8334494 -6.5786853 14.3141260 -3.4364035 -6.4844441 + 7.8440380 -8.3710823 -8.9108257 7.9793262 -8.7075548 -9.7966671 + 8.7073650 -8.4225073 -8.5006371 -5.3083439 -15.2643137 -0.7259731 + -5.2908878 -14.3397570 -0.4787421 -6.1074877 -15.6047287 -0.3238302 + -14.3018970 -18.6169853 -3.8690028 -13.4527693 -18.7907753 -3.4627879 + -14.7873430 -19.4358673 -3.7689793 -16.8298244 2.0064864 -18.6915951 + -16.4716721 1.6136891 -19.4876289 -17.3820210 2.7226121 -19.0054035 + 19.4269886 -12.9985113 5.4897861 19.8915424 -13.4447994 4.7817969 + 18.8525124 -13.6690607 5.8593445 -1.1509010 4.1887159 -3.9056144 + -0.2318459 4.2159491 -4.1717496 -1.5587997 4.9140968 -4.3785553 + 14.6331062 -14.9648018 -1.4507403 13.6760120 -14.9615688 -1.4369024 + 14.8833818 -14.2403908 -0.8773090 -11.0552292 -17.8513737 10.6012688 + -10.3989906 -17.6576614 11.2706404 -10.6440601 -17.5855942 9.7787514 + 14.8798275 11.4841881 1.6017630 14.6036396 12.0643148 2.3112733 + 14.9317427 10.6184292 2.0067291 6.2740560 18.0743294 -1.4253204 + 5.8339496 18.5227470 -0.7031986 5.5740151 17.8792477 -2.0483112 + 7.2516818 -6.9306588 -0.1587292 7.6378636 -7.7449508 0.1637978 + 7.2618861 -7.0216646 -1.1115385 -8.1896067 17.9790287 -4.1890683 + -8.9944401 18.1631241 -4.6734066 -8.4338617 18.0848236 -3.2696235 + -15.3595676 -6.5904598 -2.6929524 -16.0389500 -6.8833208 -2.0855765 + -14.5369940 -6.8265719 -2.2641690 -15.4730740 2.2446313 -15.2816925 + -15.1035089 1.9956576 -16.1288433 -15.1481361 3.1321459 -15.1301508 + -6.2597504 9.4412966 -3.7230175 -6.7318735 9.9800491 -3.0881338 + -5.9463868 8.6925230 -3.2156975 10.3697309 -2.6538720 1.1659917 + 11.1555891 -3.1830921 1.3023171 10.7016506 -1.7959884 0.9012336 + 7.2524886 -4.2537818 -7.9514413 6.7741780 -4.9075351 -8.4613991 + 8.0117702 -4.0366778 -8.4923573 -7.2651968 18.7948227 17.1179352 + -7.2065144 18.1110687 16.4506512 -8.1743679 18.7616997 17.4154949 + -15.2686625 -3.9031255 -2.9364662 -15.9300375 -3.8296516 -2.2484131 + -15.1652908 -4.8453560 -3.0696883 13.8456621 -2.7409678 -11.8343611 + 13.8313169 -2.3300157 -10.9699860 13.2158012 -2.2369990 -12.3496504 + -15.1449776 16.3635197 -6.8740716 -14.2040701 16.4127102 -6.7052402 + -15.2176409 15.8466625 -7.6764493 5.0692801 21.8831348 -0.0812377 + 5.5390763 21.9573116 -0.9119127 4.2532587 22.3626957 -0.2239292 + 13.9598541 -7.2340040 5.4907279 14.1897202 -6.5036831 6.0652056 + 13.0199776 -7.1334486 5.3398905 16.0875702 -3.5793054 5.4902630 + 16.3727036 -4.4923234 5.4538045 16.4287777 -3.1895044 4.6853623 + 19.9272251 -2.2420435 2.1471474 19.4195004 -2.4829988 1.3722999 + 20.4179401 -1.4648941 1.8798103 -2.6077008 -14.0412149 -0.0016793 + -2.6200771 -14.9850941 -0.1603308 -2.5860946 -13.9588585 0.9517264 + 0.7862485 -17.5069504 -7.4894104 0.1046198 -17.1133995 -8.0341415 + 0.3491703 -17.6977711 -6.6594815 7.7641640 -1.1895254 16.6640053 + 7.0320168 -1.5229673 16.1453438 7.4954133 -0.3065665 16.9177532 + -7.9809856 -11.2680149 -4.1467729 -7.8121414 -12.1253910 -4.5374513 + -7.1128883 -10.9296427 -3.9273565 19.8159542 2.8214734 -9.7768898 + 20.1736221 2.0994954 -9.2601175 20.5852623 3.3069866 -10.0746737 + 15.8336611 1.3374676 0.9353865 16.4083767 0.7157513 1.3819327 + 14.9527836 1.0999460 1.2249907 19.1621628 11.4022274 7.7922354 + 19.9088459 10.8707476 8.0683241 19.0831223 11.2347059 6.8531289 + -6.3577461 -0.4184516 -1.8543782 -5.7420397 0.2973209 -1.6968753 + -6.0346518 -0.8416376 -2.6498375 13.4345617 -3.0489421 -9.1648388 + 13.9749289 -3.4607866 -8.4905844 12.5576992 -3.0165820 -8.7823505 + -19.7902088 -10.3831253 10.7805719 -20.0512981 -10.2488861 9.8695040 + -20.4490128 -9.9117250 11.2904644 5.9895062 3.1099832 -2.5565066 + 6.0289712 2.5221639 -3.3109221 6.5300031 3.8589170 -2.8078887 + -15.1452579 0.2967422 -13.5468483 -15.4238892 0.9924477 -14.1423235 + -15.9551067 -0.0048105 -13.1352139 12.3361712 7.0544124 13.4778290 + 12.1924973 7.2262635 14.4084511 11.8129683 6.2740307 13.2948103 + 7.0059724 -14.1752796 11.4392643 7.8671088 -14.1605272 11.0215816 + 7.1894069 -14.3634081 12.3596935 2.6668854 -6.9767985 23.0765648 + 2.1959443 -6.9089875 22.2459927 3.5827436 -6.8209715 22.8460140 + -10.8139172 9.3305531 1.6698406 -10.3932552 8.5389042 2.0053511 + -11.5535603 9.4770317 2.2595053 -17.9158039 -12.0746183 -8.4037390 + -17.6624928 -12.9890060 -8.2774076 -17.2987728 -11.7430887 -9.0561132 + 6.2924562 -14.7421408 -0.1209153 5.3389325 -14.6665144 -0.0847857 + 6.5657973 -14.7653608 0.7961329 5.8342786 2.8804913 20.9151840 + 6.6161141 2.8554769 20.3635159 5.4848952 1.9901959 20.8759766 + -3.6468263 -3.8673055 18.8280945 -3.5555351 -4.8194962 18.8631821 + -4.2693233 -3.6605277 19.5252113 -17.1730099 -3.1427186 9.6273642 + -16.8579750 -2.6002400 8.9043827 -17.4118366 -2.5162029 10.3104973 + 3.1443346 11.7859535 -14.7117949 3.7746894 12.2244492 -15.2832899 + 2.3084531 11.8658466 -15.1713066 -1.4736665 -9.5788794 -6.0014019 + -1.5153062 -9.0880337 -6.8221140 -0.5462120 -9.7908344 -5.8958783 + -18.7360630 -7.6968040 -7.8189416 -19.2995052 -7.4466548 -7.0866919 + -18.2846584 -8.4844913 -7.5156035 18.0299473 3.1967900 1.4200950 + 17.8719654 3.3154595 2.3566797 17.3622208 2.5698116 1.1421208 + 8.3062916 -17.8596859 -13.0983982 7.8483696 -17.0997200 -13.4575510 + 8.2285366 -17.7598190 -12.1496029 -14.4585905 -18.2842808 4.6318874 + -14.1125498 -19.1679840 4.5071669 -13.6954803 -17.7604580 4.8758240 + -17.9239521 7.9734797 11.0162086 -18.1479530 7.6762080 11.8980732 + -17.2227631 7.3852034 10.7360392 4.5956368 -1.5650728 22.8726177 + 4.5674005 -1.5676839 23.8293972 4.8086648 -2.4679859 22.6368237 + 17.1231575 -5.9433618 5.5230341 17.3149738 -6.6135435 4.8670654 + 17.8919373 -5.9394040 6.0932932 -11.8471746 -3.1518838 3.7596965 + -12.7367287 -3.5044768 3.7351153 -11.9603386 -2.2082350 3.6458871 + -18.8063526 -1.7974917 11.5284004 -19.1469593 -2.2915313 12.2741518 + -19.4534206 -1.9324117 10.8360624 -19.9420567 -5.9601722 11.8844318 + -20.4205265 -5.2224207 11.5062494 -19.6862011 -5.6582232 12.7559805 + -16.3679485 3.9277544 10.8688335 -17.3134251 4.0310740 10.9766827 + -16.2633801 3.0506542 10.5000620 -20.1732006 -2.6628788 -2.8161852 + -19.5168056 -3.0985205 -2.2725000 -19.9345417 -2.8965364 -3.7132235 + 20.1753941 2.5341835 -0.3132613 20.2893944 3.3214505 -0.8456584 + 19.6020966 2.8097131 0.4020313 2.5041707 16.6200695 -4.0714264 + 2.9910429 16.9131355 -3.3011670 3.1135809 16.0464935 -4.5360360 + -9.8266602 -10.7709608 -11.3299837 -10.5194149 -11.3316965 -11.6791220 + -9.2518950 -10.6067076 -12.0775776 -12.0056391 15.1223078 -7.5873866 + -12.3336735 14.3650723 -8.0723810 -11.8029480 15.7697487 -8.2626400 + -15.4084816 -15.0257368 3.7104371 -14.9444752 -14.6518984 4.4595528 + -15.9837627 -15.6889935 4.0917187 1.4063126 5.0042615 -5.0503778 + 1.1170384 5.8107767 -5.4770923 2.3620729 5.0459247 -5.0822825 + 11.9327192 -5.1870952 7.2287221 11.4873028 -5.2542520 8.0733080 + 12.8620911 -5.2747035 7.4404392 -7.5232320 -10.1877518 9.4256392 + -7.1394172 -11.0590715 9.5242290 -7.2023082 -9.6976156 10.1826105 + 17.7672729 2.1120083 17.1138458 17.7843723 1.2698740 16.6591492 + 18.1114368 1.9202210 17.9861984 10.7747679 15.3157082 -7.3689618 + 11.0832891 15.3523741 -8.2743359 10.0887947 14.6481638 -7.3765311 + -20.5482426 7.4513807 13.0882664 -21.3569279 7.3211527 13.5835466 + -20.1490326 6.5823026 13.0486841 0.1591374 7.5720515 10.4917021 + -0.3503656 6.8384628 10.8359203 0.8073038 7.1647568 9.9170513 + 16.8008595 9.8625078 -10.3757648 16.8299217 10.8050976 -10.2117167 + 15.8833847 9.6834078 -10.5816679 2.8380251 -5.4133263 3.2215507 + 3.5545156 -5.8411870 2.7527132 2.3394797 -4.9642925 2.5388701 + -5.3421044 0.6572199 20.9487667 -5.9822254 0.7494308 21.6544399 + -4.6185632 1.2288843 21.2055130 -8.4251432 -0.4808845 -4.5192928 + -8.9650497 -1.2624434 -4.4013972 -7.5266790 -0.7912234 -4.4066734 + -14.7981501 -0.1056060 -8.9301081 -13.9121847 0.2049244 -8.7433767 + -14.6757507 -0.8111598 -9.5652800 10.9332161 3.0437050 2.0580163 + 10.1769915 3.4869761 2.4425492 10.6723375 2.8652205 1.1545134 + 0.1928013 -4.0912113 -17.4949322 -0.1368540 -4.1047077 -18.3934746 + -0.2788031 -3.3703454 -17.0775909 20.6193275 7.1829100 -3.5558820 + 21.4568577 7.4453592 -3.1739197 19.9885273 7.8114676 -3.2048287 + 17.0770416 -16.6915951 -1.4407785 17.8447647 -16.2323170 -1.7812150 + 16.3441944 -16.1053219 -1.6290619 5.8755312 -9.5139217 -7.2959309 + 6.5095267 -10.1662722 -6.9980707 6.2896261 -9.1076937 -8.0573349 + 9.2781544 2.3469222 -8.3074417 8.3681030 2.4451313 -8.0274515 + 9.3111420 1.4817142 -8.7155581 8.3213377 6.0899868 9.9382811 + 7.7508049 5.6027260 10.5326729 8.4953451 6.9132810 10.3945045 + 21.0803280 5.7110772 -5.6611028 21.5192108 4.9780951 -5.2294197 + 20.9575233 6.3589520 -4.9672666 -9.9433031 -2.3409517 -2.5658627 + -10.7613220 -2.0563376 -2.1583419 -9.3234215 -2.4051273 -1.8393235 + 9.7327662 -10.7895269 -1.8180636 9.4868383 -10.8737001 -0.8968330 + 10.6677761 -10.9936543 -1.8359716 -6.1306276 8.5691805 -10.4663448 + -5.7215538 9.2300844 -11.0250006 -5.5912857 7.7874718 -10.5858164 + -16.1820126 2.6478260 19.8039875 -17.0112877 2.8269293 19.3607521 + -15.6844244 3.4610887 19.7188892 5.0636010 -18.8859997 4.0199008 + 5.6409006 -19.6306267 4.1886849 4.8482866 -18.5480061 4.8891716 + 16.7019348 -9.6911526 6.1334200 15.8058882 -9.9196920 5.8862286 + 16.6044254 -9.1618366 6.9249682 12.3327312 7.3099627 -11.9589262 + 11.5206223 7.6384768 -11.5731945 12.0575714 6.5743604 -12.5061073 + -3.9148135 -5.3418174 -14.4323063 -2.9908195 -5.1003628 -14.4968567 + -3.9863133 -6.1524386 -14.9363031 -18.0737209 11.2226334 -6.0454183 + -17.6074753 12.0585890 -6.0503097 -18.8246861 11.3638544 -6.6219091 + 8.2824554 -6.6698494 -15.2271748 7.5729046 -7.2278786 -14.9087830 + 8.4804859 -7.0088944 -16.1001377 14.7550535 8.6650734 -4.9522672 + 13.7980881 8.6675701 -4.9732952 14.9830971 7.8390365 -4.5257797 + -16.9036484 10.5313110 12.1546431 -16.0117168 10.1856098 12.1202583 + -17.4522247 9.8097172 11.8470793 14.7169962 8.6985312 -12.1524801 + 13.8365688 8.4334669 -11.8863573 15.1044159 7.9052405 -12.5223818 + 3.1173923 -18.1303139 -4.4347544 2.7142823 -17.4118462 -3.9473758 + 2.5202491 -18.8681641 -4.3113470 -11.1215258 16.6468143 -4.4143372 + -11.2328434 16.5716286 -3.4666100 -11.0125294 15.7446251 -4.7150145 + -19.2095299 5.2251267 -3.4459591 -19.0817795 6.1700335 -3.5299969 + -19.5911293 5.1115079 -2.5754964 -16.5914192 -10.2150431 -2.3681712 + -16.4889412 -9.2656574 -2.3018591 -16.7666397 -10.5002489 -1.4714066 + 13.4343061 -2.1515293 -0.2310345 13.3429451 -1.3257235 0.2442865 + 13.5480652 -2.8106709 0.4536721 17.7794132 5.4214587 -13.8963776 + 18.7197285 5.4709654 -13.7243614 17.7143440 5.3291321 -14.8468895 + 6.7701354 5.5429502 -5.6062913 7.4680290 5.6356225 -4.9577637 + 7.0313468 6.1206136 -6.3234420 -11.5867395 12.8387461 12.9501200 + -11.6983747 11.9450254 13.2742081 -11.2876854 13.3343620 13.7124605 + 16.3128834 -5.6611280 -8.4509392 15.8174467 -6.4497194 -8.6720705 + 15.8708572 -5.3093863 -7.6782026 19.9159203 -5.3899889 6.7528958 + 20.5518742 -4.8688178 7.2429733 20.0003014 -5.0837598 5.8499365 + -3.9709129 -2.4093962 5.4231763 -4.2446022 -1.5026580 5.5615664 + -3.4461658 -2.6216569 6.1950688 -12.1272202 -10.5814342 -9.2232523 + -11.3141537 -10.9273672 -9.5913363 -11.8685617 -9.7643766 -8.7969370 + 15.5795927 -7.8820410 -15.5515614 16.5003033 -8.0895824 -15.3920259 + 15.5723953 -6.9401131 -15.7217131 8.2922430 -9.5483818 -4.0364003 + 8.8118982 -9.3849726 -4.8234758 8.8624296 -10.0773983 -3.4784937 + -10.4270411 5.6228209 9.7214184 -9.6667099 5.9019356 9.2112980 + -10.1841784 5.8005543 10.6300774 15.2537746 -11.2879705 -10.2270336 + 15.4260921 -12.1667595 -9.8889961 15.8061800 -10.7144461 -9.6958561 + -6.7204905 -1.9770887 -14.6569405 -6.0682883 -2.1034205 -13.9678078 + -6.8388081 -1.0283822 -14.7037268 -2.6525795 7.6974607 18.9784184 + -3.0524611 6.8699164 18.7110291 -2.0692730 7.4597535 19.6991673 + 16.0856724 -8.4101286 -5.6360378 16.8948574 -8.1214075 -5.2140293 + 16.1402016 -9.3657560 -5.6300564 -5.4027834 17.4243393 2.7952974 + -4.6788735 16.8778229 3.1010835 -5.5609770 17.1320438 1.8976508 + -20.8356171 -12.7366924 0.9527309 -20.9581203 -13.6858110 0.9727042 + -21.6306267 -12.4012489 0.5384007 11.3784370 -9.0927181 -3.6698377 + 12.2875061 -9.3920870 -3.6555886 10.9696636 -9.5327158 -2.9244938 + -0.3939829 -15.1312542 -10.1089010 -0.5484438 -15.3422861 -11.0296831 + -0.9238535 -15.7652912 -9.6257181 -18.9013920 -14.7105522 2.8932278 + -18.4471760 -14.0263929 2.4014492 -18.6532345 -15.5249205 2.4556711 + 14.4500723 -8.4133558 9.2308989 13.9200068 -7.7011995 9.5888042 + 15.3469696 -8.1949587 9.4840965 -4.2210188 6.6898184 -10.9075975 + -5.0067124 6.1562123 -11.0266848 -3.5664611 6.2822542 -11.4747629 + -9.5768471 6.9281759 6.1675434 -10.2268505 6.8360076 5.4709578 + -9.6841440 7.8273144 6.4778166 -6.2056561 1.7431604 6.0160928 + -7.0130506 1.3659651 5.6667075 -6.4718933 2.1633501 6.8338885 + 17.0855160 -9.9846430 -8.7127638 17.6981449 -9.3798943 -8.2942009 + 17.5552368 -10.8180866 -8.7438288 15.2942410 -5.0525274 -16.7939758 + 14.3633480 -4.8531256 -16.6944294 15.6499195 -4.9841328 -15.9079475 + 6.1425657 11.5964003 13.9715405 6.9695454 11.7227955 14.4366856 + 5.6012464 12.3390493 14.2392673 18.3058434 -0.0076512 -16.2154751 + 18.0864220 -0.1151718 -15.2899876 17.8050919 -0.6908299 -16.6612854 + 19.1680737 -5.3290954 -5.2311802 18.7032623 -4.8389425 -4.5529981 + 19.3839931 -6.1647401 -4.8172860 9.0159578 16.5122261 -4.8566899 + 9.1704884 17.4222240 -4.6032004 9.8792143 16.1836472 -5.1077986 + 6.0562963 -10.4683065 14.8200521 5.5070214 -11.1989183 14.5359125 + 6.1073861 -10.5628319 15.7712030 4.5544014 22.8010330 -9.4545546 + 4.2170248 22.6000938 -10.3274984 4.8447118 21.9566040 -9.1097488 + -11.8387680 -7.7504239 11.1438675 -12.2742195 -7.8118758 11.9940662 + -12.5525274 -7.7778125 10.5066633 -19.8454247 2.0931334 9.0773916 + -19.4079227 1.2477705 9.1783104 -20.7402897 1.9372519 9.3793030 + 17.5708961 -8.5197754 -11.1171789 18.4945335 -8.6811714 -11.3097343 + 17.4029579 -9.0160913 -10.3161173 -0.7100293 12.8973751 0.8662331 + -0.1294880 12.5920506 0.1691098 -0.9882864 12.0981150 1.3134340 + 1.1051507 -21.3926563 -11.2873678 0.4719123 -22.0058899 -11.6604443 + 0.6237908 -20.9450684 -10.5915298 -20.4870663 -3.2190506 -15.6710825 + -20.6735802 -3.7035573 -14.8669081 -21.3379135 -2.8800936 -15.9492912 + 15.5890970 4.7081742 -11.5934906 15.0391836 5.3793793 -11.9976082 + 16.4833012 4.9609823 -11.8230972 -19.2283592 -15.9487667 -8.5952187 + -18.4369202 -16.2526836 -8.1508188 -19.6835155 -15.4206581 -7.9393487 + -10.6733570 9.0755386 15.8758841 -11.4271450 9.6589603 15.9633760 + -10.1632156 9.4494333 15.1574211 -18.1970196 -5.5978093 -14.8456650 + -17.8809471 -5.0663004 -15.5762997 -18.6583309 -4.9780416 -14.2805882 + 6.9089518 2.2133989 -5.2774968 6.8626947 2.4990253 -6.1899166 + 7.2500033 1.3201842 -5.3231349 12.3376522 -10.9773617 -1.5927522 + 12.3838291 -11.8614807 -1.2288387 13.0565090 -10.9402122 -2.2237003 + 2.7809687 -7.5390015 16.7032890 2.5563152 -6.9770660 15.9616747 + 3.6811819 -7.2982674 16.9221382 -12.3313370 3.6434152 -14.3394194 + -12.1640043 3.2335882 -15.1881084 -11.4969683 3.5807564 -13.8745174 + -19.6864491 -1.7287272 0.8860288 -20.4847221 -2.2234478 0.7009833 + -19.7021980 -1.5943351 1.8336166 9.4441128 -12.7873249 2.0759101 + 10.1571360 -13.4203300 1.9914505 8.6512413 -13.3226004 2.1085713 + 11.2554617 2.5151641 5.9207339 12.1263161 2.8841500 5.7734489 + 10.6569958 3.2475822 5.7736464 -0.0922419 -9.6064987 12.5535126 + -1.0274320 -9.4024487 12.5573559 0.2561737 -9.1191530 11.8069658 + -14.3964052 -2.1642349 -13.0795956 -14.8556194 -1.4046105 -13.4378195 + -13.9898643 -2.5790715 -13.8404293 -5.1022801 19.7458210 14.3371201 + -4.7516780 20.0024509 15.1900282 -6.0067196 20.0591030 14.3458443 + 18.6581097 -11.7624311 0.6928239 18.7907829 -12.7102671 0.7081771 + 18.5168247 -11.5254822 1.6094075 18.2863102 6.7408128 13.7292767 + 17.8813610 6.8054171 12.8643646 17.9848061 5.8997431 14.0726852 + 0.4736978 -7.8478522 -18.1850300 -0.2805146 -7.4186497 -17.7810745 + 0.7241319 -7.2663031 -18.9028854 -16.3789940 -10.4871578 -10.0556984 + -15.9172478 -9.6977758 -9.7730341 -16.8665695 -10.2141027 -10.8328362 + 15.9483309 -11.7517986 -6.0642362 15.2994843 -11.5289688 -6.7317514 + 15.9709253 -12.7087297 -6.0621867 4.1650515 3.4178581 1.0965452 + 3.7517259 2.5903091 0.8504618 4.0378170 3.4768770 2.0434139 + -7.3495736 -0.5234753 -21.2445793 -7.9856730 0.1912651 -21.2170925 + -6.8322458 -0.3535540 -22.0318089 10.0841227 19.1506271 -9.6106176 + 10.1258497 18.8277340 -8.7104883 9.1701841 19.0275078 -9.8671131 + -2.0894167 -3.5091882 7.1287189 -1.7288189 -2.7822824 7.6364679 + -1.4450634 -4.2106199 7.2237687 -10.9111824 -12.4503880 6.7227812 + -10.3303299 -12.2795391 5.9813952 -10.9204502 -11.6289282 7.2140546 + -4.8180585 5.7540956 16.1607189 -4.9895163 6.6456037 15.8573256 + -3.8640602 5.6994615 16.2166996 18.8441830 -5.1691432 -7.9481573 + 17.9695492 -5.4124289 -8.2515688 18.8077621 -5.2806277 -6.9981694 + 6.2016802 -7.5719147 14.3402090 6.4889493 -8.4485960 14.5954313 + 6.6340928 -7.4129767 13.5011683 -12.1757030 -13.7505541 10.5570564 + -11.2418804 -13.6272840 10.7273827 -12.4894466 -12.8826437 10.3030319 + -6.0820508 -17.6793289 11.8826218 -5.3240986 -17.8961620 11.3397369 + -5.8865776 -16.8091869 12.2302914 -2.8439348 -7.2713757 14.4653959 + -3.1920140 -8.0886889 14.8218670 -2.7091143 -7.4538722 13.5354767 + 9.2723541 -12.0509129 5.1894975 9.8681402 -12.7822933 5.3518343 + 9.1811552 -12.0231447 4.2370567 -5.3308172 -16.2573681 7.3727193 + -6.1765199 -16.4217834 7.7898359 -5.5508213 -16.0095596 6.4747100 + -1.5854505 1.0960798 0.4105773 -0.9718887 1.4674742 1.0444857 + -2.0292013 1.8557070 0.0333724 -8.1866226 12.8344126 18.0128231 + -8.7347527 12.0518055 18.0703716 -8.4447918 13.3636675 18.7674561 + -11.2326622 3.2493432 5.5522466 -12.0005636 3.8185430 5.5015340 + -10.9136934 3.3567197 6.4483275 5.4172301 9.3057365 15.3661652 + 5.3092871 8.5555992 14.7814655 5.6413474 10.0323219 14.7847204 + -2.9453766 3.3323078 -0.1936604 -2.1905797 3.8536263 -0.4670470 + -3.0529881 3.5356030 0.7354911 -14.6190224 4.3544679 -4.4855790 + -13.8924704 4.0962434 -3.9184163 -14.2955370 4.2022395 -5.3735065 + -7.0993495 -0.3145687 13.9407320 -6.9669657 -1.2154071 14.2360229 + -7.9872518 -0.0974285 14.2248306 -16.5186520 -7.3570728 7.5015388 + -16.7901878 -8.2747297 7.4813643 -16.7568130 -7.0560470 8.3784056 + 3.4125137 20.2529240 5.2020025 3.1055088 20.7327461 4.4327502 + 3.7587187 20.9295177 5.7838912 -12.2611609 -5.5132055 -5.7774353 + -12.6701946 -6.3495274 -5.5549731 -12.9112997 -5.0650053 -6.3184242 + -9.8768044 1.9896629 14.0836153 -10.0679646 1.5628301 14.9187822 + -10.7318439 2.2684813 13.7558956 4.6853085 -9.6595078 2.9709628 + 4.3947544 -8.9261303 2.4287753 4.9482017 -10.3322973 2.3428912 + 3.9576137 13.2385826 12.1380968 3.8349497 13.0078173 13.0589294 + 4.6344142 13.9153805 12.1488914 -17.7137623 -9.9426870 -6.6809001 + -16.8104019 -9.7029085 -6.4743094 -17.6494312 -10.8238440 -7.0492167 + 11.9187479 -16.8963566 5.4064798 12.2815647 -17.2858810 4.6109514 + 12.4237585 -17.2902431 6.1178513 7.9320197 -14.5579710 14.1430330 + 7.3665628 -14.7020531 14.9018021 7.8463273 -15.3583317 13.6250448 + 19.3318539 0.3471531 7.0558076 18.6215878 0.1511618 6.4447889 + 19.3546486 1.3031567 7.0978708 -6.9501081 -7.7929220 -5.8295565 + -7.1515861 -7.5607748 -4.9230542 -6.1838799 -7.2624474 -6.0480123 + -14.5790110 0.0612654 2.7698932 -15.1110153 -0.1634812 2.0065501 + -13.7205105 -0.3189996 2.5838666 17.6489582 -0.4565246 1.9570441 + 18.2549171 0.2708664 2.0982792 18.1485538 -1.2354348 2.2018585 + 19.1261311 -3.4174407 -15.8981838 18.5340385 -3.3504558 -15.1490688 + 18.5768223 -3.2178371 -16.6562405 20.6985912 -3.7278802 11.7003345 + 19.8183670 -3.3523083 11.7198963 21.2096100 -3.1712494 12.2879190 + 0.0077874 14.7293835 2.4573164 -0.1408998 14.0015726 1.8536484 + 0.9050419 15.0101852 2.2775483 -0.7481901 0.0916455 6.5288777 + -1.2565448 0.0199638 5.7209983 -0.9552403 -0.7072207 7.0138259 + 1.4275992 -16.3939400 -2.9843416 1.3991084 -15.4377098 -3.0166388 + 0.5454391 -16.6684341 -3.2346973 -20.5534439 -1.1603549 -11.6158819 + -21.4541531 -1.3945663 -11.3920498 -20.5704746 -0.2081796 -11.7123394 + 1.8967352 20.7138062 -2.4393702 2.1522832 21.5817623 -2.1269939 + 2.3297858 20.6278267 -3.2886679 18.8700752 -7.3801255 3.9103854 + 19.4600887 -6.6353335 3.7946191 19.4518204 -8.1352472 3.9975357 + 7.2864075 22.0713062 -10.1332493 6.4979844 22.4243679 -9.7209787 + 7.9925041 22.2876263 -9.5242634 -3.3716669 -8.5891504 -10.7945213 + -3.9636500 -9.0554428 -10.2043009 -3.7669961 -8.6914101 -11.6602516 + -6.3596792 4.9140964 -11.5822687 -6.5420327 5.3560972 -12.4114933 + -6.0553432 4.0430522 -11.8370104 -19.0350361 -1.1571782 -15.0620012 + -19.4381104 -1.9796115 -15.3401508 -18.6302891 -0.8082091 -15.8561249 + -4.3909211 -13.9270287 -5.3114767 -4.6357989 -14.1978216 -6.1963143 + -3.7453256 -13.2327633 -5.4435158 -17.6803894 -0.4116434 -12.5403347 + -18.1556892 -0.9223476 -13.1956997 -17.8130703 -0.8897066 -11.7217493 + 4.2140899 6.2830777 0.8961434 3.2757752 6.4682250 0.9351008 + 4.2716737 5.3284130 0.9352817 20.8872833 2.1549294 4.6909409 + 20.8152905 3.0748785 4.4364958 21.7436485 1.8817403 4.3619432 + -7.7219872 -4.2910800 7.2837076 -8.3975143 -4.1307693 6.6247730 + -7.2039466 -3.4862781 7.2963471 -14.4624014 -12.5008631 -10.3421917 + -15.1134577 -11.8004503 -10.3843670 -13.7376719 -12.1870937 -10.8830681 + -17.0792465 13.4281816 11.0261469 -17.8241253 13.5931444 11.6042242 + -16.9467545 12.4812336 11.0705013 1.4915879 -8.4994984 10.3114204 + 1.3829733 -9.2385197 9.7128534 1.6986275 -7.7584863 9.7419758 + -16.7307377 13.4334106 -6.0011644 -15.8325129 13.3953362 -6.3297567 + -17.0538807 14.2882605 -6.2858438 -2.0186236 12.4140320 -6.9578695 + -2.3120027 13.0559816 -7.6044469 -1.4486719 11.8224688 -7.4492340 + 2.5207970 -3.2929199 -1.1303082 3.3583093 -3.5486884 -0.7438016 + 2.0039318 -2.9721901 -0.3912448 -5.3297691 6.6092453 -20.1880302 + -4.7190695 6.1697807 -20.7797623 -6.1607637 6.1526265 -20.3191013 + -9.9301519 -12.5008535 -7.1133900 -9.5115499 -13.2172699 -6.6361570 + -9.4450893 -11.7198830 -6.8468723 0.7219723 7.0455480 -14.0134020 + 0.7074035 7.4307094 -14.8895693 0.7015790 6.1009164 -14.1666574 + 4.2467499 -0.7181336 4.5160036 5.0147681 -0.5937901 3.9584031 + 4.5522451 -1.2896159 5.2204981 -4.5543504 -10.1317177 9.9650049 + -3.6672206 -10.4482508 9.7945938 -4.8741717 -9.8435163 9.1100864 + 14.9962254 1.0323111 8.5319967 15.1127291 0.3490335 7.8718524 + 15.6811743 0.8603585 9.1781454 -7.4244828 -13.2855234 10.0375767 + -7.4233198 -14.0552473 9.4685812 -6.6920228 -13.4294901 10.6367493 + -1.9900199 10.5782766 -2.2556517 -2.5136387 9.7863903 -2.1332951 + -2.5556078 11.1640148 -2.7588942 -7.5620155 -13.7377825 -5.7623363 + -6.8114228 -13.5096045 -6.3107681 -7.4549580 -14.6726274 -5.5867343 + 10.0465956 -2.2662022 18.1786728 10.0199251 -2.0041778 19.0989246 + 9.4926853 -1.6264371 17.7313290 -18.2479801 8.8174095 -10.3005123 + -17.9852200 9.7099009 -10.0754604 -17.4232292 8.3562479 -10.4533157 + 0.1855332 18.6241493 -8.3280411 0.7806884 19.1843300 -8.8262558 + -0.5031682 19.2159309 -8.0251951 -2.2496808 14.9027357 -0.4379627 + -1.8085485 14.1732121 -0.0027267 -1.5646346 15.3192501 -0.9608958 + 8.8207436 -2.6188576 3.5774863 9.3876324 -2.4191105 2.8325236 + 9.4245815 -2.7631955 4.3060312 -3.2911506 -0.4644464 -11.7633295 + -3.0990121 -0.8848962 -10.9251556 -4.2240105 -0.2548335 -11.7178631 + -5.0767760 -19.0614491 -11.4146662 -5.0306625 -19.9262409 -11.8223915 + -5.2332883 -18.4610481 -12.1435375 4.3156757 4.9423604 19.2944565 + 4.6568608 4.1041679 19.6063194 3.4400361 5.0016050 19.6765270 + -2.4336643 15.9274588 2.3849626 -1.4940821 15.7482605 2.4210887 + -2.6752408 15.7566595 1.4746327 11.0915308 1.0635661 -6.2454562 + 11.3430891 0.8875927 -5.3388233 11.6474552 1.7963799 -6.5103402 + 11.1914873 4.9285755 12.3883581 12.0896502 4.9465766 12.0578861 + 10.8883581 4.0383811 12.2097569 -13.4128847 -12.4044123 -7.4031553 + -13.9248323 -12.3621359 -8.2108393 -12.5325737 -12.1328888 -7.6630759 + 7.7894459 -3.0349302 22.5051689 7.7839756 -2.6282585 21.6386700 + 8.3828621 -2.4898233 23.0218372 -14.5757208 -17.4300537 -6.3652225 + -13.8175850 -16.8459015 -6.3501625 -14.4965229 -17.9459915 -5.5628715 + -9.0886211 -2.4488456 10.6151409 -9.3428020 -1.5951457 10.9655981 + -8.3244677 -2.7023990 11.1328392 15.8850479 -12.4451399 -0.9634064 + 16.1446095 -11.6906080 -1.4921221 16.5578632 -13.1030970 -1.1384566 + 17.3059921 17.7123337 -3.6920738 17.0673141 17.1213608 -4.4062290 + 16.6147003 17.5925789 -3.0409155 -12.0820618 9.2553425 -15.0622625 + -11.4377499 9.6655741 -15.6391544 -12.6987667 8.8286152 -15.6570826 + 5.8876801 19.8273563 6.6192327 6.1799841 18.9249744 6.4907970 + 5.0151772 19.8546886 6.2265196 -2.3666255 12.3864117 -4.2538819 + -1.6627277 13.0049086 -4.0583777 -2.2781627 12.2111979 -5.1907415 + -8.7682734 17.0199966 -7.9835773 -9.1839266 17.7854710 -7.5866981 + -9.4521437 16.6323013 -8.5296965 -1.8408154 2.9062417 15.2950745 + -2.5798368 2.5029244 14.8396463 -1.1354545 2.2631564 15.2233858 + 0.4689521 12.6328773 7.1159396 0.7744521 11.7306547 7.2102499 + -0.2410655 12.5796928 6.4761910 -3.0853696 6.1466241 3.6936929 + -2.2873342 5.8853498 4.1531572 -3.4918694 6.7945337 4.2691951 + -4.8314972 2.9077232 10.3701019 -4.7471418 3.7205102 9.8716116 + -4.6853814 2.2152326 9.7256346 -4.8147769 -21.2752476 -3.7669170 + -5.6144323 -21.3251648 -3.2431884 -4.2955589 -22.0278378 -3.4836249 + 17.0326214 9.9405060 -4.7910089 16.3035297 9.3204889 -4.8063078 + 16.6167545 10.8007202 -4.8486075 -4.9230962 9.4067688 3.1601305 + -5.7402000 8.9971619 2.8758864 -4.8473434 10.1917858 2.6176887 + -1.0935402 4.7073684 -1.2197220 -1.1518130 5.6581030 -1.1251711 + -0.8307285 4.5728893 -2.1302588 -10.3320303 -7.6597419 8.7793646 + -10.1701784 -6.7312016 8.6124859 -10.9267406 -7.6681943 9.5293512 + -9.7737160 -0.0505879 12.1767216 -10.0128069 0.6481531 11.5677643 + -9.4181738 0.4069552 12.9386110 2.8698566 -3.6734853 -23.8718243 + 2.9144013 -2.7633374 -23.5787735 3.0900311 -3.6364553 -24.8026218 + 18.9386978 15.2465591 7.2310896 19.2878246 14.6344309 6.5832925 + 19.4888668 15.1173058 8.0036440 -8.3937216 18.5044441 11.0436649 + -8.9231920 18.2871819 10.2764034 -7.6005774 17.9778805 10.9442425 + 0.3990457 2.2441220 1.9332216 0.7319045 3.1130266 1.7086293 + 1.1844223 1.7092478 2.0486550 9.2215862 2.0979695 20.6588707 + 8.6850042 2.2878933 19.8892994 9.9290476 2.7417068 20.6223698 + 2.1767783 16.3944244 0.3828853 2.5685675 15.7206526 0.9385527 + 2.3246107 17.2122765 0.8577476 1.9576509 3.3934731 8.7250929 + 1.1520892 3.2657843 9.2260895 1.7374369 3.1041167 7.8396487 + 9.3210669 10.9652538 1.2474608 9.4771271 11.8769188 1.4939216 + 10.1851215 10.6308870 1.0069585 -1.2611843 5.3898683 -7.6635041 + -1.0187795 6.3146853 -7.7102470 -2.2180300 5.3940687 -7.6378059 + -17.5468559 3.0567796 -4.6841946 -16.7712727 3.6155283 -4.7342134 + -18.1836739 3.5745130 -4.1916013 -10.9668760 3.2694206 17.7097282 + -11.1421862 2.9206052 18.5837002 -10.0800543 2.9719284 17.5065613 + 6.0356669 9.6614981 -16.8979378 6.7128115 10.2789183 -16.6213512 + 5.2861433 10.2128410 -17.1225872 11.8275948 0.1673742 -8.8754807 + 12.1189213 0.7716929 -8.1927214 12.5823507 0.0822938 -9.4580069 + 9.7404718 1.9461287 -1.4458652 10.0292578 1.9562615 -2.3584068 + 8.9031677 1.4826669 -1.4647541 20.9778538 2.4940386 13.2836323 + 20.3973579 2.8319824 13.9655790 21.5111465 1.8349771 13.7280064 + -19.2484665 15.0577011 -0.0594005 -18.9426727 14.3636742 -0.6433945 + -20.1515312 15.2197361 -0.3322591 -4.6605306 16.3349686 -13.0574217 + -4.5636368 17.2432480 -13.3435593 -3.7631867 16.0264759 -12.9315758 + -3.0843687 18.6907177 -2.4774845 -2.4906521 18.0681705 -2.8972068 + -3.7286856 18.1425438 -2.0296085 -14.7749882 5.8726029 11.7268314 + -14.1850958 6.0150695 10.9865866 -15.4190493 5.2433014 11.4021807 + -2.7159662 5.9693155 -5.0309072 -2.9077132 6.8757391 -5.2714505 + -3.4933646 5.6784492 -4.5541677 -7.5278153 -0.8056911 -7.2265754 + -8.2043066 -0.9311472 -6.5611038 -7.2976594 -1.6923399 -7.5042696 + 7.8164196 13.6635170 -3.8177509 8.4628534 13.8204403 -3.1294701 + 7.5461311 14.5384426 -4.0964642 -2.1349585 6.0169802 9.3176928 + -2.9892938 5.6022878 9.1978045 -1.5947645 5.3393955 9.7242651 + 15.5874815 13.1759710 6.2215695 16.0404549 13.8121576 5.6681132 + 15.4717245 13.6260300 7.0583963 -3.8818567 1.5488515 -16.6557369 + -4.7229705 1.1613494 -16.8978138 -3.4002342 0.8345042 -16.2386265 + 12.1178951 0.6343432 -3.7759678 13.0092545 0.8430805 -3.4964340 + 11.8992815 -0.1671486 -3.3005199 -9.5012722 9.1106920 -7.3123455 + -9.2082691 9.9421368 -6.9394107 -8.6975994 8.6867752 -7.6134052 + 13.5765362 14.7293234 8.3200493 13.8935165 14.8087559 9.2197418 + 13.5277586 15.6311007 8.0027962 7.1017551 -15.5827551 -14.2712488 + 6.8886242 -14.8519230 -14.8514996 6.3681469 -15.6232824 -13.6577272 + 2.5803404 -10.5786572 16.8780823 3.0028596 -10.9155474 16.0880089 + 1.9887204 -9.8962955 16.5609074 -1.9065022 1.7093341 -3.0423203 + -1.0971218 1.3841423 -2.6481304 -1.6679201 2.5590775 -3.4127884 + 2.8837454 -1.1829451 -3.0720532 3.3072219 -1.9510145 -3.4554183 + 2.5930882 -1.4758081 -2.2083511 -17.2967091 13.7952738 -10.6548557 + -18.0615635 13.4265709 -10.2129431 -17.5845051 13.9323149 -11.5574217 + -4.3430119 10.5769253 -7.3781137 -4.4614835 11.3327675 -6.8028755 + -4.9203954 10.7491589 -8.1218853 13.9771376 -9.5121460 6.8847046 + 14.2875252 -9.1372890 7.7089453 14.1529751 -8.8343534 6.2320867 + 10.4878378 -2.4048867 5.8880792 10.5107870 -2.8245227 6.7480850 + 10.0106869 -1.5878291 6.0329113 6.1998911 13.0682077 -10.1175203 + 6.7002859 12.2584972 -10.0164948 5.6278791 12.9042997 -10.8672991 + -11.1884642 -4.3870635 18.2293777 -10.5612478 -4.9237866 18.7138977 + -12.0242357 -4.5380411 18.6708794 7.7346644 2.1582811 14.4064207 + 8.0116529 2.8925519 14.9544678 6.7910700 2.0924826 14.5531559 + 3.7159019 0.6599168 0.1362343 3.2892506 0.7352081 -0.7173064 + 4.4161701 0.0220347 -0.0014705 -17.8921127 2.7633927 -12.2830257 + -17.9883232 2.4998534 -13.1981878 -17.1498108 2.2507901 -11.9629354 + -12.4789705 3.1573296 -3.0065696 -11.8100653 2.5300102 -3.2809212 + -12.9458857 2.7149091 -2.2977068 7.8214054 18.5882225 10.8625298 + 7.1360297 19.1108055 10.4461184 7.4435763 17.7117386 10.9350052 + 17.5819378 -0.0777956 13.0965939 17.4210224 0.8654050 13.0699244 + 17.9004421 -0.2414236 13.9842949 -7.8465161 2.2227340 22.0939369 + -7.6927686 3.0433545 21.6257744 -7.2601438 2.2644641 22.8493557 + 5.6406474 7.7683196 6.0181684 5.6384315 8.7254391 6.0059352 + 5.9669499 7.5184937 5.1536770 13.0284100 -5.6190271 13.5668259 + 12.9580498 -6.0062075 12.6942587 13.9410944 -5.7600231 13.8185377 + 3.4198904 16.3668385 -10.0828352 3.0161953 16.0570889 -9.2720842 + 2.9271486 17.1555042 -10.3096476 2.4521697 -21.1953354 3.0138593 + 2.1599185 -21.7156525 2.2654665 3.4077859 -21.2301617 2.9712362 + -0.3607358 9.3491554 -0.0600191 -0.7695025 9.7596626 0.7019688 + -0.5155597 9.9653835 -0.7759272 18.7817631 -12.1705856 -8.3414078 + 18.6497631 -13.0175734 -8.7673426 19.7279129 -12.0298223 -8.3762846 + 10.7319450 16.8531971 -1.7777842 10.4736814 17.3901405 -2.5269332 + 10.0408888 16.1948414 -1.7053877 0.6580039 7.2403255 -10.1799860 + 1.5344545 7.5995135 -10.3180084 0.7211382 6.7667122 -9.3505669 + 2.6579368 -9.2231598 6.2274151 3.5613301 -8.9697714 6.4169059 + 2.7371337 -10.0314007 5.7207527 -2.8273680 14.6565695 -8.2477207 + -3.5879309 14.7341976 -7.6717434 -2.6221814 15.5578709 -8.4962893 + 1.9685016 20.4422245 -9.2173977 1.8401777 21.2227154 -8.6783247 + 2.8243289 20.5715141 -9.6261473 -3.8120682 -5.8382621 -9.7301254 + -3.7705624 -6.7678165 -9.9547091 -3.3217831 -5.4014664 -10.4265890 + -4.1775441 -7.7673893 -15.7298956 -4.6026535 -8.6238594 -15.7743177 + -3.3138821 -7.9476433 -15.3586435 8.9054642 8.4042253 -1.4974294 + 8.8161211 9.2231417 -1.9848982 9.4444370 8.6336966 -0.7404066 + -6.7724304 5.8119397 -5.1769843 -6.3685122 6.3629351 -5.8474212 + -6.2938156 4.9844818 -5.2267184 19.0229530 11.8739529 -2.0032468 + 18.2253513 12.3843727 -2.1430147 19.3324928 12.1451378 -1.1390268 + 9.9731894 20.0611706 10.0980339 10.4542189 19.7451344 10.8628626 + 9.2984810 19.3987789 9.9489193 2.2712920 15.8706570 -7.3052969 + 2.8010619 16.6674786 -7.2797971 1.4267561 16.1327019 -6.9387951 + 7.3964725 12.4175005 5.4946070 7.9781408 13.0099115 5.9709935 + 7.8616748 11.5809975 5.4855795 -7.2658081 10.5180225 -6.0119901 + -7.0298662 10.2330837 -5.1291690 -7.5298548 11.4319715 -5.9061260 + -14.2791805 15.0042124 3.5140414 -14.7972736 15.7167225 3.1396871 + -14.8222609 14.6601524 4.2232089 7.1745486 -17.3670330 1.8543104 + 7.0742097 -18.2313232 2.2532651 7.6722913 -17.5294437 1.0529948 + -1.3604198 11.1355104 19.5295677 -2.3106122 11.0214205 19.5108719 + -1.1501113 11.2414064 20.4573536 -10.3327360 16.4842949 14.1191692 + -10.9132318 16.3179684 13.3764763 -10.3597775 17.4339142 14.2363262 + 18.9126759 -14.5458937 -9.7926474 18.9061184 -15.4733315 -9.5559053 + 19.2850666 -14.5263634 -10.6742229 5.4502411 -9.3189793 6.1044884 + 5.4655986 -9.0642357 5.1819367 6.3725247 -9.3571968 6.3577957 + -17.7360516 3.8517075 -16.3366489 -17.2529945 3.8490770 -17.1630154 + -17.4607449 3.0479510 -15.8957262 -6.8265734 -19.6022835 -5.4875865 + -6.1724048 -19.8076134 -4.8196535 -6.7840638 -20.3378773 -6.0985904 + 2.3792439 -18.2168598 -9.8578672 2.9460077 -18.9615555 -9.6567688 + 1.8866485 -18.0660458 -9.0511227 18.2159920 10.9890451 4.9815617 + 17.3051682 10.7601986 5.1666632 18.6169739 10.1668806 4.6996198 + 7.2492881 9.3757334 2.3800864 7.8118520 9.8492374 1.7672675 + 7.8300261 8.7372313 2.7939591 2.6540573 -17.4449883 10.7632780 + 2.5958867 -16.6444206 11.2847576 2.2602160 -17.2122803 9.9224634 + 9.7495871 5.0735483 5.5599627 9.1789560 5.3570218 6.2742839 + 10.6014032 5.4580145 5.7669101 12.0866995 0.0192857 3.7072735 + 12.3116989 0.4638017 4.5245938 11.1503553 0.1834302 3.5952625 + 12.0747280 15.4863997 1.9054759 12.4295464 15.3394089 2.7822483 + 11.4317789 16.1859665 2.0214684 2.8368607 11.6444654 9.5561619 + 2.7232671 12.5153093 9.9368982 1.9489642 11.2921562 9.4949293 + 4.2793622 -11.7561340 -13.4615202 3.9225321 -12.5475788 -13.0583830 + 3.9328439 -11.7647066 -14.3537550 13.8169260 12.3673897 4.2396970 + 14.6355019 12.4092073 4.7340822 13.2361841 11.8342819 4.7826219 + -12.8577528 7.6310935 -10.6493626 -12.9953985 7.1043339 -11.4366426 + -11.9395247 7.8972526 -10.6967812 18.1984329 3.3602364 10.0597849 + 17.5899315 3.8420758 10.6199541 18.2453728 3.8780439 9.2561035 + 20.2592793 -9.1387835 -10.9781551 21.0292568 -9.3178749 -10.4384394 + 20.6062908 -8.6897669 -11.7489986 -11.8183336 -15.5711660 8.1114140 + -11.5366888 -14.7793179 7.6532817 -12.1990242 -15.2519293 8.9295788 + 4.5510287 -16.5775490 2.5331933 5.4120569 -16.4245586 2.1440194 + 4.6580071 -17.3803577 3.0433755 -16.1358490 7.0656419 -0.6629115 + -15.1854391 7.0021815 -0.7573808 -16.4669380 7.0566902 -1.5609832 + -14.6852884 8.0543318 4.4660215 -15.4905539 8.4283314 4.8236589 + -14.9292746 7.7528129 3.5909278 -6.3251090 5.9424481 0.2385865 + -5.8150067 5.2715082 0.6923119 -7.1448727 5.9933181 0.7301469 + 3.6356108 8.6445713 -1.8259878 3.2292171 9.5006390 -1.9609897 + 3.0383389 8.0267353 -2.2476225 -2.1757541 -0.4496153 10.5218248 + -2.8529084 -0.6170024 11.1773214 -2.6388547 -0.0179089 9.8039122 + -6.0906868 -4.4651399 -1.0968868 -5.6858525 -4.2890816 -1.9462068 + -6.0044417 -5.4115009 -0.9820178 -9.3556461 6.5806413 2.0032685 + -9.6613617 6.2428408 1.1614490 -9.9209881 6.1586823 2.6502392 + -13.8236151 4.5609860 2.1116793 -14.5258532 3.9517868 1.8837091 + -13.1600075 4.4254713 1.4352977 8.4223299 10.5682354 -3.7294714 + 7.7141118 9.9929781 -3.4400969 8.2784433 11.3846416 -3.2509215 + -19.3776340 11.5606031 9.9223642 -19.2245197 12.3117123 9.3491077 + -19.5857487 11.9470234 10.7730112 -7.1484466 4.3268027 -23.6574631 + -7.9734049 4.8098640 -23.7057037 -6.5777159 4.8801312 -23.1242409 + 2.2570441 -13.9223261 9.4522352 2.1088650 -14.7342987 8.9674921 + 2.0599253 -13.2283983 8.8230772 4.3911638 -3.5065210 15.4061451 + 3.6437311 -3.3918767 15.9930286 4.1779671 -4.2883492 14.8967104 + 7.0196109 -10.9726620 -12.2797823 6.3417192 -11.2326832 -12.9035482 + 7.7000299 -10.5701809 -12.8194771 12.0375042 20.1984844 1.4624810 + 11.5534906 19.3915062 1.6378379 12.2826719 20.1349468 0.5393953 + -19.3216972 -13.9397564 -4.0206985 -18.5882111 -13.3297729 -3.9422722 + -19.7174988 -13.9517088 -3.1492450 -9.5352421 -19.0999546 -0.3007447 + -10.1123266 -18.4486580 0.0980260 -9.8202496 -19.9336071 0.0734559 + -13.4692116 10.3591537 13.6726465 -13.8685427 10.4582005 12.8083811 + -13.1047459 9.4740686 13.6680813 -19.9270000 12.8778925 5.4838905 + -20.8782101 12.8792706 5.3769770 -19.6883392 11.9509668 5.4929247 + 1.6464329 10.1634312 -5.7913852 2.5017605 10.5644560 -5.9457402 + 1.1043520 10.4677773 -6.5192270 -4.3726177 1.4341133 -1.6250014 + -3.9268143 1.8384860 -0.8807072 -3.6947508 1.3552638 -2.2962029 + 0.3609681 -6.2746592 0.2964567 0.2165205 -6.0535679 -0.6235896 + 1.0341506 -6.9548492 0.2764977 -1.6643419 14.7402239 5.3884168 + -1.8902847 14.0857754 4.7274489 -2.2523308 14.5541935 6.1204643 + 9.3965693 -0.5697879 20.3883190 9.4728842 0.3840063 20.4144821 + 8.4706488 -0.7310959 20.2069836 -10.8817301 8.3978786 -18.3355389 + -10.6934080 9.3295403 -18.4485588 -10.0656013 8.0276251 -17.9992714 + -19.0397472 2.3261645 3.5768239 -18.8661404 2.5355668 2.6590862 + -18.7722702 3.1103358 4.0561595 -15.6189117 -13.8912344 -6.3792200 + -16.0870838 -14.1330671 -7.1783218 -14.7405605 -13.6559105 -6.6781402 + 4.5651255 -1.1829079 8.6534567 5.1940141 -1.5785578 8.0499735 + 4.5425577 -0.2590261 8.4041281 -13.3423643 9.5566225 18.0779285 + -13.1629229 10.4420729 18.3941708 -12.6463490 9.0207977 18.4583073 + -15.3849068 5.3957472 -16.3793678 -16.1513004 5.9434409 -16.5493793 + -15.5375271 5.0346546 -15.5061264 1.8249289 4.6265516 4.9642649 + 1.7363000 3.6823473 5.0940905 2.7695954 4.7747221 4.9208765 + -6.9732909 15.2604036 -12.0885439 -7.1226106 15.0892191 -11.1586885 + -6.0231142 15.2086105 -12.1920509 -6.7387376 14.3440695 16.1200943 + -7.2496367 13.8823853 16.7849712 -7.2177725 15.1597195 15.9735613 + 6.8706913 1.2108260 11.9323521 5.9881916 0.8403311 11.9197016 + 6.9314795 1.6559685 12.7775640 -3.9691188 8.4728127 -5.5248699 + -4.0741587 9.0493479 -6.2817087 -4.4253211 8.9242697 -4.8147306 + 9.8601465 -10.0170660 -10.9957390 9.3428211 -10.5692673 -10.4094973 + 10.5242367 -10.6054220 -11.3549786 -3.0904555 12.3811693 10.3695774 + -2.5648882 12.0481176 11.0969610 -2.5363424 13.0440531 9.9575396 + 9.4024553 9.3700418 -7.6461620 10.2569017 9.5391283 -8.0431042 + 9.5764694 9.3435898 -6.7052841 -16.4503975 -12.0994473 5.6700788 + -16.3867054 -12.6060305 6.4797387 -16.9820728 -12.6430311 5.0886402 + 4.0323982 11.2701244 -6.2980485 3.3776042 11.7964888 -6.7567616 + 4.8570266 11.7340031 -6.4430895 4.7105203 7.8709140 9.0377207 + 4.4546828 6.9746957 8.8196115 4.1360903 8.4204559 8.5045557 + -4.1939788 -13.1592512 -10.5081520 -4.3574195 -13.8782730 -11.1185017 + -4.6192021 -12.4020367 -10.9106989 -4.3362036 4.9226246 -2.9291759 + -4.7555938 5.7403340 -2.6614156 -4.0002546 4.5479360 -2.1149411 + -13.6260405 -2.0734265 -4.5924869 -14.1397352 -2.8016691 -4.2431836 + -13.5970945 -1.4365599 -3.8784873 -10.0914764 2.0036550 1.4258955 + -10.1622686 1.1490662 1.0005741 -9.5525837 2.5238931 0.8299261 + -7.7189603 11.2325916 -2.1502495 -7.8670216 11.3165226 -1.2083018 + -8.5104523 10.8072224 -2.4801493 -12.4627504 -4.3202724 14.6936817 + -13.1343641 -3.6796639 14.9277487 -12.4391861 -4.3038616 13.7369127 + 6.1297736 -0.9569150 -0.4430122 6.9518557 -0.7857951 -0.9025019 + 5.9386978 -1.8763587 -0.6283362 9.5490475 -18.9051647 2.1426320 + 9.6945143 -18.5058823 1.2849344 8.9790192 -19.6533165 1.9649664 + -0.8100930 4.1863308 11.1380301 -1.4850777 4.5489936 11.7117052 + -0.1166683 3.9024982 11.7337084 0.3714466 12.3499069 -1.5763823 + -0.4418607 11.8957224 -1.7965643 0.6813277 12.7038975 -2.4099867 + 1.1324304 19.5349274 7.3405495 1.5096784 19.7499599 6.4875093 + 1.8574406 19.1499805 7.8328981 -18.6322479 -10.7147455 -4.2493596 + -17.9361115 -10.8126392 -3.5997121 -18.2034454 -10.3033161 -4.9997506 + 7.2785115 14.6211090 0.4107114 6.4212098 14.3280849 0.1018384 + 7.3484187 14.2652330 1.2965426 -19.2056236 -1.3230398 16.2337837 + -18.4715767 -1.7128134 16.7086372 -19.9424553 -1.3815625 16.8419666 + 4.6159530 3.5178323 4.3094344 4.9618521 2.6442142 4.1267414 + 5.1671262 3.8503404 5.0178680 4.0159459 14.5146103 -5.3492537 + 3.5104353 14.6642351 -6.1481929 4.8689103 14.9105806 -5.5278344 + -3.8186650 -1.6612509 -16.3095913 -4.2851400 -2.0485911 -17.0502682 + -4.4110112 -1.7767373 -15.5666113 19.8337250 -8.1087809 8.0030966 + 19.6454372 -7.2853789 7.5527749 19.8111458 -8.7704544 7.3117871 + -2.3320689 -15.0721684 -3.9247265 -1.8764534 -14.3272438 -3.5326376 + -3.1026618 -14.6883612 -4.3431883 -15.2136917 -4.6138635 -10.3055286 + -15.3752460 -5.2875233 -9.6449871 -14.7245655 -5.0653219 -10.9934034 + 0.9750761 -20.5387020 -0.9125167 1.5415645 -20.6285572 -0.1461949 + 0.0880645 -20.6431370 -0.5682262 16.3172779 4.1924767 -5.5590792 + 16.0151176 4.7469821 -6.2784219 17.2243710 3.9837165 -5.7823186 + -11.7461443 -16.5318432 -5.7751226 -11.3562870 -17.3758316 -6.0029907 + -11.6163826 -15.9901028 -6.5535264 16.3413525 -13.4888773 8.3093328 + 15.9632368 -12.6663847 7.9982600 15.6469326 -13.8888760 8.8327971 + 1.1344275 -18.8594570 2.9937820 1.5047427 -19.7023945 3.2556088 + 0.2406335 -18.8738174 3.3360651 -9.3830338 0.6394109 -10.7779484 + -8.7041559 1.0344023 -10.2308292 -9.7387571 -0.0703295 -10.2431955 + -15.7535496 -15.4921770 -2.3791389 -16.3347301 -14.8261127 -2.7463152 + -15.0777245 -15.6142502 -3.0459154 -16.6135921 11.8868389 3.3634896 + -16.0603657 11.7494087 2.5945387 -17.4342651 12.2298985 3.0098855 + 4.6298966 12.7974367 -12.1909523 4.5839624 13.6747723 -12.5709581 + 4.4750171 12.2082310 -12.9292479 0.7416167 -5.3618512 -2.2910058 + 0.1544716 -4.6143618 -2.4039302 1.4692057 -5.0186801 -1.7722768 + -2.3593652 -7.2356434 -19.7109947 -2.5823197 -8.1635561 -19.7851639 + -1.9125189 -7.0302978 -20.5322094 11.0497713 20.4307785 -5.2496715 + 10.9563141 21.0380344 -4.5156832 10.7353640 20.9221439 -6.0085783 + 14.6792402 17.3039951 9.1280775 15.4830856 17.4683399 8.6350718 + 14.2900076 18.1703243 9.2472525 -0.9570355 -0.0775176 15.3995695 + -1.7648146 -0.1590377 14.8925400 -0.8640811 -0.9225320 15.8395042 + -13.1118250 -5.9979677 -11.8881350 -12.2690563 -5.5461950 -11.8448362 + -13.4963522 -5.7088051 -12.7156343 0.3906432 16.8594685 -10.3422976 + -0.0247379 17.3941536 -11.0189085 0.3294822 17.3891354 -9.5473480 + 7.6103172 -13.9868546 -5.1383653 7.2749896 -14.4544725 -4.3734331 + 6.9038458 -13.3887825 -5.3821654 14.3685255 15.9554005 -0.0701203 + 13.7347746 15.9354315 0.6469524 14.3803558 15.0585289 -0.4043565 + 5.7400737 22.1114902 3.6469035 6.1508107 22.4345512 4.4488750 + 6.1459689 21.2576523 3.4971042 -0.0051299 -12.6427946 -13.8526917 + 0.2597412 -12.7573586 -14.7653532 -0.2635407 -11.7231407 -13.7919283 + -12.0171251 -16.9121494 5.5530429 -12.4037876 -16.0420666 5.4546518 + -11.0731640 -16.7619114 5.5020638 -0.5808958 6.0604253 4.9121661 + 0.2316927 5.5547628 4.9275675 -0.4998764 6.6664400 5.6486540 + 0.3838533 19.7462025 10.4738226 -0.5239882 19.4521065 10.3992405 + 0.6980617 19.7849045 9.5704918 3.9849937 14.8280144 4.3528275 + 4.2606111 15.1378460 5.2155395 3.4959571 14.0248594 4.5317626 + 16.8952904 -8.7657280 2.6093609 16.0091248 -8.5064383 2.8617682 + 17.4671116 -8.2413731 3.1699901 5.7890730 -4.1313853 4.4429197 + 6.4834027 -4.3862472 5.0505242 5.1155143 -3.7403016 4.9993405 + -0.9692531 -20.7106247 -4.5222321 -0.0252013 -20.7162781 -4.3642249 + -1.3153596 -20.0878639 -3.8830047 -18.1695576 1.2756439 -6.9712229 + -17.9280701 1.7493542 -6.1752872 -18.0296974 0.3541447 -6.7532549 + 8.4845514 0.0310335 -5.4236965 8.5283012 -0.8913231 -5.6758394 + 9.2745380 0.4197366 -5.7992783 -13.3270817 -16.2021523 2.3556807 + -13.9020128 -16.3948307 1.6150309 -13.8957930 -15.7732935 2.9951174 + 1.6103548 -11.7429352 13.5661383 1.1546752 -12.0832901 12.7962379 + 1.1856980 -10.9037933 13.7442942 -19.8018875 0.6252686 14.3280020 + -18.9215012 0.7444432 13.9717035 -19.6775360 0.0581727 15.0890350 + 13.6427374 -2.5385919 20.2734127 13.4945898 -1.6017723 20.1443653 + 12.8153257 -2.8655059 20.6266136 10.8872995 -14.0700893 5.5718637 + 11.4672546 -13.7189655 4.8961444 11.0426531 -15.0144253 5.5537796 + 10.3193340 18.3994579 -6.8192744 10.7581797 17.5579853 -6.9440489 + 10.8983908 18.8870316 -6.2334456 -5.3714967 -7.7194743 -2.7870612 + -4.8934126 -7.4560466 -2.0007577 -5.3266206 -6.9554129 -3.3618903 + -3.1407816 -12.7991486 12.6117706 -2.9752696 -12.2561483 11.8410645 + -2.8712986 -13.6787567 12.3473835 -7.2305126 -16.0939274 9.2777233 + -7.1835093 -16.5025501 10.1420450 -8.1590462 -16.1265926 9.0475273 + 1.6017530 17.6420040 11.2494707 1.2552761 18.5315838 11.1799583 + 0.9172925 17.0883369 10.8737049 2.2354555 16.1464348 7.6338277 + 1.7347673 15.9725113 6.8367743 3.1057696 15.7917871 7.4521413 + 7.6372814 10.7363300 -9.9050646 8.1420374 10.0245972 -9.5115051 + 7.9352493 10.7670555 -10.8141870 7.9339070 11.7377100 -0.8738011 + 8.5805140 11.3863392 -0.2616985 7.0998378 11.3749990 -0.5754710 + -15.0094318 -10.5177212 -5.6991525 -14.5770416 -11.0867662 -6.3359084 + -14.4998856 -10.6262140 -4.8961434 -2.5061069 2.0772974 23.6936722 + -2.9677436 1.6413044 24.4099350 -1.9668237 2.7403083 24.1247425 + -1.1841645 -2.2859030 16.8642159 -1.8337317 -1.7561042 17.3263931 + -1.3200685 -3.1738009 17.1949711 -17.2420940 4.7291346 7.6048365 + -18.1399307 4.9880743 7.3972960 -17.3371773 4.0461917 8.2687492 + -13.8592653 -3.5260730 17.8643055 -13.4365282 -2.9629574 18.5127068 + -13.7852545 -3.0418489 17.0419426 -12.7715797 6.5774794 -19.3258438 + -12.5481863 6.0636387 -20.1019211 -12.0324116 7.1751537 -19.2133846 + 12.9869328 18.5515251 3.6166790 13.7356853 18.8572121 3.1046665 + 12.2670355 19.1251698 3.3541675 7.0771480 19.2685661 2.7334263 + 7.2578321 18.8583736 1.8876555 6.4198442 18.7027760 3.1384754 + 6.6915040 2.8877995 0.0303165 6.5260763 2.6844683 -0.8902929 + 5.8393974 3.1576166 0.3728729 -8.2321396 -19.1525211 4.9887419 + -8.8481016 -19.1823864 4.2566681 -7.7055950 -19.9459171 4.8912439 + -21.1457481 5.3188944 4.5148125 -20.4796371 5.2068915 5.1930327 + -21.7685623 5.9407401 4.8911672 -16.0881901 6.8587356 9.0290575 + -16.5567951 6.1658587 8.5636950 -15.1632528 6.6722836 8.8679333 + -1.8963252 -23.4325066 5.3865323 -2.7226727 -23.8030281 5.0765400 + -1.8971288 -22.5345650 5.0549703 17.0099735 15.2103682 4.7062950 + 16.5104046 15.9319677 4.3242497 17.7277889 15.0634918 4.0903392 + 16.4559345 12.7455540 -2.4976070 16.3772163 12.8482361 -3.4460225 + 16.2984123 11.8140411 -2.3436544 -14.2143650 12.5598440 -1.9654918 + -13.6231174 12.3958864 -2.7001863 -14.8730078 11.8681993 -2.0291364 + -20.1215038 -13.9138575 -7.0619626 -20.3404827 -13.0021706 -7.2545948 + -19.9283485 -13.9208498 -6.1244798 -1.7254055 -17.2113857 -8.4179354 + -2.6433878 -17.0112438 -8.2349520 -1.5538567 -18.0165501 -7.9295578 + -18.7330475 15.5371952 -6.7121463 -19.0599251 15.1839294 -7.5395436 + -19.1735497 15.0180120 -6.0393615 5.2554231 2.3455966 -22.1076965 + 6.2076087 2.2738080 -22.0412102 5.0971022 3.2722340 -22.2880001 + -11.5891876 16.2075157 -1.9341294 -11.4752607 15.2805643 -1.7243298 + -12.5311527 16.3080082 -2.0713720 1.4764249 -3.6819289 -14.6408234 + 1.5915884 -2.8619688 -15.1210680 1.4252412 -4.3529921 -15.3214750 + 9.1892700 21.1032677 -1.3710438 10.0095444 21.4870872 -1.6809855 + 9.3617601 20.8749237 -0.4576226 -5.3910885 -10.3515053 -3.1945603 + -5.4859128 -9.4184561 -3.3860264 -5.8533573 -10.4740467 -2.3653903 + -6.0133638 -6.3128824 5.6177473 -6.5450654 -6.6487141 4.8961229 + -6.6456485 -5.9148116 6.2160678 6.5731792 -4.6622386 16.8491535 + 5.8620877 -4.2005734 16.4048061 7.1011186 -5.0285211 16.1396828 + -1.6537395 -5.0172710 -7.7559547 -1.5216808 -5.9524188 -7.9118099 + -0.7688991 -4.6567149 -7.6986041 8.0685892 9.2724438 16.3228683 + 7.1569743 9.1338110 16.0660210 8.5788679 8.9327211 15.5877256 + -8.3860817 10.5078754 9.2691116 -8.2099638 10.2688913 10.1791115 + -9.1859426 11.0320997 9.3096504 -11.5966558 0.7008615 4.4016614 + -11.9431677 0.4120839 3.5574050 -11.5632477 1.6550205 4.3331332 + 16.8099365 0.6383719 10.3052778 17.1804085 -0.1052564 10.7806711 + 17.5501118 1.2306440 10.1726618 13.6304693 -10.8846292 -4.0130491 + 13.4967556 -10.6072254 -4.9193606 14.5812311 -10.9409628 -3.9176028 + 3.1285067 3.6116941 15.0628624 3.0232487 3.1084642 15.8702736 + 2.4530675 4.2881217 15.1124563 5.4270806 7.0693526 13.6079416 + 4.5829906 6.8319631 13.2240276 5.9920621 7.2436028 12.8551702 + 7.4713159 2.8398206 18.7708416 6.8161697 2.3118153 18.3145237 + 7.7143998 3.5175257 18.1400814 12.6810389 -14.7145586 -8.6581306 + 12.5654001 -15.5511637 -9.1086311 12.6073236 -14.9308672 -7.7286096 + -19.5777111 8.8005733 9.2049866 -18.8379822 8.5085831 9.7376919 + -19.5081577 9.7552357 9.2013083 21.1292725 -7.1714401 -12.8714046 + 20.4152603 -6.8020439 -13.3909845 21.4197407 -6.4484897 -12.3153448 + -5.4853406 -4.9873013 1.8663788 -6.2381225 -4.4069786 1.9794117 + -4.7990899 -4.5976887 2.4081299 19.5240116 15.2352848 2.8969738 + 19.2128048 16.1402817 2.9160056 20.4782810 15.3101177 2.8965127 + -3.9719055 20.2931061 4.6626682 -3.9364841 19.3763733 4.9357557 + -3.6663208 20.2847881 3.7555957 8.0209932 -18.1522198 -4.5020227 + 7.6369014 -18.5751362 -3.7340086 8.9587831 -18.3296604 -4.4292455 + -7.8437629 -3.5187104 -5.9319534 -7.8806801 -3.9246604 -6.7980213 + -8.6616488 -3.7809741 -5.5094452 -0.3237951 -11.4922390 -3.0162790 + -0.0532248 -11.0771065 -3.8352346 -1.2774497 -11.4101849 -3.0098155 + -16.3202152 7.0849280 -3.3988774 -15.7848558 6.3205848 -3.6119542 + -16.4103718 7.5531077 -4.2288842 3.0606081 -8.1178074 -15.9789209 + 2.6510413 -8.7711496 -16.5460453 2.5918355 -7.3057952 -16.1715889 + -1.6752999 -8.0426207 -8.4174280 -0.9543353 -8.6722479 -8.4208355 + -2.0663342 -8.1215506 -9.2875395 0.6024702 9.6201000 -3.1819386 + -0.2166346 10.0460148 -2.9291625 0.8443151 10.0375767 -4.0086527 + 3.2980471 -9.1019230 -7.8184147 4.2057538 -9.1040325 -7.5146127 + 3.1929054 -9.9421415 -8.2647438 -0.5408950 -12.3159800 5.4108067 + 0.0674094 -11.9090939 6.0277681 -0.0972005 -13.1160975 5.1294188 + -8.3431005 -3.6699915 -8.5792866 -8.2880201 -2.9818628 -9.2423677 + -7.9679103 -4.4417834 -9.0033169 7.0832305 -1.2490730 5.3144445 + 7.0729699 -0.3275385 5.0557933 7.5748625 -1.6873347 4.6198540 + -6.7128372 -18.5292034 -0.0863989 -7.6272426 -18.8094482 -0.1258666 + -6.7022033 -17.8392563 0.5769951 -1.3023266 17.7703686 7.5384884 + -0.8717311 16.9957085 7.9000406 -0.5882296 18.2928219 7.1733313 + -18.3380432 -3.8983567 6.6157022 -19.2046185 -4.0818057 6.9785066 + -17.8735065 -4.7334423 6.6711016 -14.1004019 -2.2996657 15.5385227 + -13.6779327 -1.4806784 15.2796574 -14.9950752 -2.2228673 15.2070217 + -2.1101103 -19.7648335 -11.3251791 -1.2261314 -19.5102654 -11.5897713 + -2.6491146 -18.9988213 -11.5224886 4.6542249 -1.4459683 17.7121601 + 5.2151303 -2.1957955 17.5137272 4.1565061 -1.7167022 18.4836597 + -3.7089868 5.1978889 -21.8737221 -3.7544591 5.9767890 -22.4282303 + -2.7757728 5.0877886 -21.6914558 -12.7340069 0.4304314 -14.7922211 + -13.4899006 0.2838970 -14.2235527 -13.1067801 0.5107219 -15.6701880 + -12.2432518 3.5411341 -9.7911978 -12.7431889 3.0985231 -10.4770479 + -12.8891354 3.7367923 -9.1123877 -2.6703856 19.0617943 0.5102032 + -3.0547328 19.1740761 -0.3592230 -2.0684221 19.8001938 0.6031451 + 0.1147716 -2.5988224 -22.4492989 -0.1967666 -2.6245823 -23.3540154 + 1.0637867 -2.7019682 -22.5197487 9.2199860 16.2441235 6.2235866 + 10.1443615 16.4695148 6.3282747 8.9963350 15.7717314 7.0254960 + -3.7915916 -3.6812415 -7.1700587 -4.3433499 -4.4404521 -6.9819269 + -3.0514424 -4.0387263 -7.6605844 -5.3971128 -9.3295870 7.2791247 + -6.1833324 -8.7959194 7.3944044 -5.3668361 -9.5116892 6.3398948 + 0.0874527 -2.9733126 20.6760559 0.5378216 -2.6687682 21.4638710 + -0.5321208 -2.2737362 20.4688034 1.4889838 -9.7668467 2.6553288 + 0.7261720 -9.9816933 3.1921628 2.2330217 -10.1166477 3.1455109 + 4.4192390 -17.4401951 -11.5637474 4.5172601 -18.3915710 -11.6025639 + 3.7131531 -17.2976856 -10.9333773 -14.0352478 -17.6425819 8.5279341 + -13.5030499 -17.2682629 7.8258786 -13.6924076 -17.2431011 9.3273764 + 8.5880136 20.1112766 6.8477635 8.8058596 20.1637459 7.7783666 + 7.6403890 19.9772968 6.8307915 14.6252985 -5.3265691 19.0025368 + 15.1361589 -5.5038829 19.7923546 13.7164364 -5.4650617 19.2690334 + -8.6887846 -22.1693974 5.8298078 -9.1394205 -22.9252319 6.2064681 + -7.7644358 -22.3177681 6.0293021 3.1584427 2.9319079 -1.9715902 + 4.0857391 2.7116892 -2.0602314 3.1299105 3.8852789 -2.0522218 + 20.2447529 14.8358231 -6.5208173 20.1301250 13.8997488 -6.3569336 + 20.0005970 14.9498339 -7.4393058 -12.1061649 -21.0593853 -9.0651941 + -12.4396620 -20.1867714 -9.2738943 -12.5576487 -21.3012657 -8.2565613 + -15.1342220 -6.5988865 -7.6278291 -15.8122797 -6.5063257 -6.9585738 + -14.7723322 -5.7181382 -7.7255516 -6.0370364 -3.6789730 -11.0966663 + -5.1815262 -3.9734893 -10.7842665 -6.2874155 -4.3266635 -11.7554836 + -0.5045993 -15.2692490 -12.6493683 -1.3444442 -15.5622292 -13.0029993 + -0.3585604 -14.4149523 -13.0556698 -0.8085904 19.2424927 15.4035301 + -0.9944825 19.9327812 14.7669954 -1.3679327 18.5131912 15.1361599 + -10.1857262 2.3558252 -6.9083300 -9.5285597 1.6611344 -6.9503884 + -9.6769056 3.1619205 -6.8214736 18.7225819 1.6433086 -12.3042145 + 19.6301365 1.7899690 -12.0376301 18.2451077 2.3943944 -11.9519081 + 12.7304726 -12.5034828 -16.2446728 12.5227747 -12.2853842 -17.1532574 + 13.5686531 -12.0714550 -16.0802441 10.3938475 -4.1041245 -2.6645160 + 9.8919201 -4.1847644 -1.8534687 10.8629427 -4.9351225 -2.7395060 + -19.3310108 11.1674824 -11.2260399 -19.8346367 11.9480581 -10.9951839 + -19.6079903 10.5071936 -10.5907974 0.2034839 -14.0829401 -6.3721519 + -0.5905689 -13.5885286 -6.1690021 -0.0478160 -14.9989319 -6.2536654 + 14.9385366 -1.8567047 11.3557396 14.7659712 -1.0577152 11.8538055 + 15.1967678 -2.4995959 12.0162249 -7.0954561 1.0298233 -13.4472399 + -6.5769291 0.4475882 -12.8919344 -7.9798274 0.6648533 -13.4169655 + 13.6011362 -4.6808114 0.8000486 13.7311792 -4.8026743 1.7405113 + 13.1501951 -5.4757848 0.5156177 -11.4568491 5.9107304 14.6021309 + -11.0718508 6.7419262 14.8798409 -10.7152338 5.3997264 14.2779198 + -14.4734087 -8.3625307 -12.2624750 -13.9566450 -7.5689960 -12.4020815 + -14.4821453 -8.4786005 -11.3123789 13.4205151 7.1456833 9.6885490 + 13.4292002 6.2509618 10.0285931 12.6763115 7.5604982 10.1248064 + -6.3744793 -4.6558790 -15.6911201 -6.5432615 -3.7244403 -15.5491123 + -5.8620796 -4.9253807 -14.9288559 -14.4958258 -16.7552814 -0.1534806 + -15.0330248 -16.1902714 -0.7088289 -13.6886129 -16.8832951 -0.6517298 + 1.6467071 12.6227169 -12.5247021 2.1293154 12.1959419 -13.2326460 + 2.0819058 12.3261480 -11.7254019 -3.1092989 -12.4072914 -2.2941489 + -3.0418322 -12.9670315 -1.5206044 -4.0343885 -12.1647520 -2.3343389 + 15.5711899 -2.4954112 15.8950090 14.6336918 -2.4577632 16.0845108 + 15.9625816 -2.8521645 16.6923618 -10.6714411 -2.6449530 -10.2006817 + -10.6466312 -3.5525429 -10.5038271 -11.4789114 -2.2901804 -10.5726490 + 0.3817320 -9.4872561 -8.5045071 0.7348287 -10.2819309 -8.1044493 + 0.3610819 -9.6798439 -9.4419050 11.8028240 20.1371937 7.3457251 + 11.3052092 20.3837051 8.1253681 12.1983423 20.9554787 7.0453820 + 5.1731853 17.1648560 3.4909532 4.7797637 16.3368416 3.7663493 + 4.4542561 17.6477337 3.0832751 -16.1690235 -12.2291069 10.7915745 + -16.3455677 -11.3402662 11.0998392 -17.0039806 -12.6868200 10.8894348 + -7.0010748 -12.2957878 3.0128672 -7.6510825 -12.7397623 3.5574856 + -6.8618183 -11.4531364 3.4450457 -11.7316303 -16.5832386 -1.8534851 + -10.8563700 -16.2987900 -2.1166227 -11.6593647 -16.7407303 -0.9121002 + 5.8752165 24.1924553 -6.3695626 6.0058522 24.8441124 -5.6807156 + 6.1772327 24.6246090 -7.1684761 -11.1978045 13.4869204 1.6012650 + -11.6804323 12.7898674 2.0455830 -11.3026152 14.2503405 2.1690998 + 13.6138554 -12.2149353 7.1346154 13.8284473 -11.2829266 7.0953422 + 12.6585865 -12.2432394 7.0808320 -11.8168926 14.9870615 -12.8344879 + -11.9332647 14.1692619 -12.3508625 -12.6331091 15.4668379 -12.6936445 + -6.6474357 0.6723239 -9.3298273 -6.7438407 1.5919920 -9.0825453 + -7.0407338 0.1868299 -8.6046762 -9.4792728 4.3303752 -15.2771616 + -8.7409153 3.7496450 -15.4610395 -10.1585865 4.0565915 -15.8934460 + -14.5536432 10.2151480 10.8896513 -14.7522249 9.6799164 10.1213255 + -14.2582531 11.0512590 10.5292425 -4.4477544 -10.1920519 -5.8100853 + -4.1262622 -9.4861622 -5.2491984 -4.8212748 -10.8299294 -5.2019510 + -8.3731470 -2.1261244 18.9497013 -9.0319815 -2.2243624 18.2623024 + -8.8736830 -1.8810703 19.7279339 6.3176031 -13.5988255 -16.2632046 + 5.6998420 -13.1822262 -16.8640785 7.0731382 -13.0112448 -16.2510471 + 17.1140423 4.7482634 -0.8414702 17.4890327 4.1985731 -0.1533898 + 17.3469162 4.3038230 -1.6566231 -8.5514727 14.4865932 13.1409035 + -9.1134853 15.1371984 13.5617199 -8.7531452 14.5631981 12.2083302 + -16.3431664 -14.3724680 -8.9235640 -16.0523529 -13.8536043 -9.6735239 + -15.7626381 -15.1335201 -8.9192915 5.2611809 20.0711308 -9.3092394 + 5.9190331 20.0913944 -10.0042582 5.7308583 20.3589420 -8.5264244 + 13.4625988 -3.7612138 9.8904629 13.0030966 -3.0071261 9.5210829 + 14.2324390 -3.3864973 10.3184414 -1.4820874 -20.6191845 0.1018537 + -1.8186885 -21.3617992 -0.3995982 -2.1680245 -19.9548512 0.0356529 + -1.9481448 -6.4453111 -17.1573238 -2.1715035 -6.9502354 -17.9392414 + -2.4162319 -5.6173506 -17.2650661 2.7944696 -5.3112807 -12.7199354 + 2.4742718 -4.6541862 -13.3379412 3.0430655 -4.8091383 -11.9438658 + 4.2014608 -12.3631477 14.0417156 4.2722216 -12.7369547 13.1633682 + 3.3135748 -12.0075731 14.0798740 3.6048083 9.7358770 17.6993484 + 4.1431594 9.4630756 16.9563885 3.6916928 10.6888809 17.7209568 + -2.4294884 -1.1330036 -22.9322243 -2.8483343 -1.8688862 -22.4858189 + -1.9356302 -0.6856806 -22.2450275 -3.4058867 -17.7132092 13.6605015 + -3.0507622 -17.4496269 14.5094080 -2.9522886 -18.5305386 13.4544592 + -2.5887172 -17.8459492 0.4500562 -3.1679270 -18.5947132 0.3082817 + -2.7905278 -17.2474670 -0.2691949 14.3550234 1.1982195 -1.8620653 + 14.4754066 2.0184212 -2.3406138 14.6982327 1.3789049 -0.9869698 + 3.2951512 -19.9744492 -12.3652020 3.4424686 -20.9199200 -12.3899689 + 2.3791914 -19.8815479 -12.1032505 10.7376900 4.5546260 8.9406080 + 10.9327726 5.3510923 8.4468317 9.9321556 4.7586303 9.4157162 + 3.7288206 -13.9616299 0.4640176 3.6874506 -14.0124846 1.4189700 + 2.8265936 -14.1031342 0.1773207 12.4575615 -2.9192374 3.1811399 + 12.2574339 -2.0005190 3.3604093 12.5059299 -3.3269672 4.0458069 + -2.7490096 -13.4466944 15.8311949 -2.7779138 -12.8597059 15.0756540 + -3.5617130 -13.2682343 16.3043728 -5.4168572 -19.4104176 -8.2954750 + -5.0690765 -19.4285831 -9.1870747 -5.2708716 -20.2961998 -7.9633479 + 7.7737961 0.2410722 -2.7388234 6.8544621 0.3328213 -2.9891000 + 8.2153578 -0.0293265 -3.5438950 -5.9533505 6.6969171 11.2811956 + -6.5829225 6.0653844 11.6290998 -6.4923701 7.3580418 10.8469095 + 13.7477207 -15.1815453 6.7538891 12.8477583 -15.3355665 6.4665246 + 13.7990141 -14.2345467 6.8834844 5.5683918 -4.1635184 23.2623291 + 6.4364438 -3.9486983 22.9209061 5.2525511 -4.8632073 22.6905670 + 18.1925335 2.1704526 4.1656294 19.1322727 1.9953235 4.1161189 + 17.8329048 1.4172920 4.6342959 19.0635395 -15.2376862 -2.5973184 + 19.1233540 -14.5457945 -3.2560589 19.4945812 -15.9908695 -3.0012379 + 1.0279096 1.3385944 -3.0495803 1.2359502 0.4406711 -3.3078144 + 1.8738946 1.7862282 -3.0367277 -15.9584026 2.1762402 -8.9744406 + -16.7963638 1.9310457 -8.5820961 -15.4793282 1.3511209 -9.0512352 + -0.8164331 -1.6673908 8.5551958 -0.0101427 -2.0090628 8.9417038 + -1.2555282 -1.2166479 9.2764854 18.0303631 11.5633106 11.7422352 + 18.0077076 12.3372126 12.3050804 18.1989937 11.9093790 10.8658600 + -13.1450243 12.2978249 3.2898011 -13.7482204 12.7251959 2.6817381 + -13.4180002 12.6057358 4.1540389 -0.9893134 6.3656454 21.4386845 + -0.9652873 7.2836952 21.7085705 -0.4174257 5.9177098 22.0620060 + 0.2658682 -12.7089071 -16.7942352 0.5976463 -12.0408525 -17.3941154 + 0.4226141 -13.5371561 -17.2477398 19.0619717 3.8147004 -5.6483550 + 19.8251457 4.3578320 -5.8453493 19.4238930 2.9442427 -5.4823790 + -7.3282967 5.5251231 4.9566679 -7.6155901 4.8103981 4.3884578 + -8.1229935 5.8034101 5.4119101 -8.6604757 -9.7319365 -7.4422517 + -8.2014523 -9.4071045 -6.6676469 -9.5144491 -9.3005323 -7.4130764 + -17.0034695 -7.0152130 -0.5217468 -17.7898502 -7.4603758 -0.2060452 + -16.5451756 -6.7453794 0.2741098 1.8056448 12.9201813 -3.9416070 + 2.1206834 12.0948124 -4.3100486 2.1021204 13.5874195 -4.5605798 + 7.1208682 -18.5611248 -8.3596907 7.8041234 -17.9768620 -8.0310125 + 6.3258953 -18.2779903 -7.9079337 -2.2228684 -10.4681377 -13.3612671 + -2.2148783 -10.4724398 -12.4041100 -1.8514428 -9.6188755 -13.6000729 + -2.1058853 0.0438618 3.6405170 -3.0507498 0.0227288 3.4888055 + -1.8548317 0.9501119 3.4618700 -9.2993078 -15.6509695 -2.9111078 + -9.7401218 -14.8809795 -3.2703159 -8.8642578 -16.0509281 -3.6640987 + 0.4252318 18.5883408 -1.6540023 0.8567959 19.3610325 -2.0185976 + -0.2690705 18.9418087 -1.0979124 2.6476405 12.1122179 4.5366721 + 2.2430277 11.2510767 4.6413498 3.2807274 11.9948893 3.8283875 + -5.3822970 12.1768646 19.7391624 -5.9422226 12.3355236 20.4991245 + -4.7641892 12.9077358 19.7403145 -3.9140337 2.5429940 -24.0880871 + -4.6128173 2.6013594 -23.4365292 -4.1552768 1.7928245 -24.6314831 + 4.2504873 -18.1817780 -14.6299086 4.4037094 -17.2828407 -14.3389339 + 3.8640349 -18.6169300 -13.8699551 -3.9223688 14.8908882 12.0840006 + -3.1457446 14.4050798 12.3616285 -4.6273923 14.5504522 12.6347075 + -12.4106913 3.6230404 20.5452976 -13.0794725 3.6255226 19.8604927 + -12.3778057 2.7144558 20.8446712 5.5451083 12.3758011 -4.2610722 + 5.0037637 13.0596390 -4.6554618 6.3779597 12.8084164 -4.0728321 + 11.1093550 7.2670746 -15.9580555 11.2227402 6.5212178 -15.3689251 + 11.3178511 8.0309553 -15.4202375 -14.5170755 -16.2324657 -9.3063231 + -14.0330925 -15.9924202 -10.0964947 -14.0818663 -17.0242043 -8.9901371 + 10.2978964 8.0929270 2.0449040 10.6073914 7.7396183 1.2108669 + 11.0038433 8.6693001 2.3375890 -14.4219923 -3.9307888 4.3936167 + -14.4416409 -4.6214199 5.0560927 -15.2973509 -3.5447168 4.4240675 + -2.4069228 -19.5962849 -7.0312514 -1.9737294 -19.7634296 -6.1942105 + -3.3132172 -19.3970928 -6.7963357 4.5013728 5.2228284 7.3370557 + 4.9284673 5.9452047 6.8766270 5.0502815 4.4614034 7.1495361 + 8.6609755 -9.4426403 20.8609657 8.7280388 -9.0989847 21.7518272 + 9.5682535 -9.5778685 20.5874844 -10.0280733 -4.2351170 -4.3917589 + -10.8337460 -4.6958489 -4.6259584 -10.2798748 -3.6674705 -3.6633320 + -3.7857521 -22.8303280 -1.2543198 -3.4384935 -23.5216675 -1.8179630 + -4.3221145 -23.2930069 -0.6105222 -16.5294952 -12.9937382 -3.3288736 + -16.2142620 -13.3802977 -4.1458383 -16.0406876 -12.1748276 -3.2471175 + 12.1717863 -5.9954491 16.4003944 11.3372431 -6.1016226 15.9437799 + 12.7138824 -5.4904757 15.7942877 -4.2727385 18.3299007 -10.5009317 + -4.8403535 18.5399323 -9.7593575 -4.8591084 17.9374352 -11.1477489 + -13.4055128 -0.7054540 7.1427975 -13.9183788 0.0655519 7.3851829 + -13.0033226 -0.4722325 6.3060884 -6.7060714 3.7427814 16.0866699 + -6.1090689 4.4858165 16.1745281 -6.2551150 3.1420596 15.4933710 + -11.2580261 11.6891680 6.0958958 -10.6736593 11.9470091 5.3829684 + -10.7374678 11.0854959 6.6258311 18.6160679 -3.0565639 -0.0946358 + 18.2573891 -3.3120153 -0.9445331 17.9828720 -3.3881826 0.5420146 + 2.5670903 -18.7265606 13.0366812 2.2261398 -17.9976368 13.5550013 + 2.7290304 -18.3501968 12.1716042 1.9278088 -10.1742601 -17.9473934 + 2.1653161 -10.2552147 -18.8711185 1.2718655 -9.4773893 -17.9289303 + -10.1286726 17.3787346 -11.9324694 -9.5101519 18.0760212 -11.7146273 + -9.7285557 16.5844555 -11.5785465 1.0529491 6.5370274 -21.1033211 + 0.3128633 5.9417500 -20.9843674 1.0871773 6.6909423 -22.0474453 + 3.2941766 -5.7578630 -6.1542497 3.9162083 -6.4260612 -5.8664660 + 2.6063340 -6.2487245 -6.6038709 -10.4816713 -1.4322968 14.4977541 + -10.4214249 -1.1009092 13.6017714 -10.7179070 -2.3543675 14.3967094 + -5.8366160 -10.2810087 -0.0778746 -5.8807201 -10.6411924 0.8078761 + -5.1027575 -9.6670589 -0.0505074 -4.2009850 -0.0997230 -8.2473850 + -5.0007925 0.4240742 -8.2940369 -4.0755291 -0.2625864 -7.3125224 + -0.8231279 11.3096333 -13.0190496 -1.6113517 11.7776785 -12.7436066 + -0.1005563 11.8299551 -12.6677837 7.4597201 18.3054504 -10.4673586 + 6.9079514 18.4641800 -11.2332497 7.0438242 17.5676880 -10.0212975 + -0.8034613 -0.6713281 -19.7524986 0.0579056 -0.2596034 -19.6834946 + -0.6278759 -1.5316103 -20.1337032 9.8277025 -12.8739662 -16.8451653 + 10.7375517 -13.0010710 -16.5763721 9.7771139 -13.2710829 -17.7146320 + 13.7319536 -15.8621616 13.9304247 14.0644684 -15.1702394 14.5021858 + 13.1707516 -15.4057789 13.3035288 14.9421177 8.1676960 7.5747681 + 14.4874830 8.0320024 8.4061089 14.5552759 7.5231123 6.9822335 + 14.5432329 4.9808483 -3.4356267 14.0353727 5.4688683 -4.0838137 + 15.2777176 4.6179252 -3.9306521 3.7933791 -4.1643362 9.5026274 + 4.5605001 -4.7259827 9.6135788 4.1490326 -3.2761412 9.4734392 + 7.7435994 -6.2704720 -11.6704903 7.8100286 -5.3196640 -11.7587128 + 7.2563257 -6.4020853 -10.8571796 6.3002968 1.5720600 2.6731405 + 6.2602773 1.8118976 1.7473391 6.0868430 0.6390867 2.6883068 + 18.6353245 -11.2718878 -5.5762196 17.6800652 -11.3322744 -5.5843425 + 18.9079285 -11.6769428 -6.3995352 5.7546697 20.0583401 9.4151888 + 5.9180484 19.9625664 8.4769096 4.9904499 19.5068684 9.5827513 + -11.4812460 -2.6386473 8.1510706 -11.1457167 -2.8557653 7.2812943 + -12.0235891 -1.8623365 8.0116529 19.8164787 -13.3482018 -4.3289623 + 19.3513565 -12.5674171 -4.6294103 20.6264133 -13.0117779 -3.9454823 + 11.7479544 9.8046484 -14.5858316 12.3142567 10.1784868 -15.2609453 + 12.1438646 10.0830154 -13.7600002 6.8363948 7.8818846 -12.7753515 + 7.7345409 7.5803576 -12.9119053 6.3562694 7.5570421 -13.5370531 + 12.9977446 3.8674312 -10.3114624 13.7443714 3.2796538 -10.1961451 + 12.7375717 3.7477973 -11.2248240 11.0674314 -2.5945985 -7.8431497 + 10.7907276 -2.5382564 -6.9285502 11.3636208 -1.7102637 -8.0586853 + -7.0856333 18.1096039 -11.8094311 -6.4939656 18.6952114 -12.2818975 + -7.0933266 17.3061581 -12.3296690 0.0139481 18.1383934 -14.3785801 + -0.7604547 17.6008663 -14.2124577 0.2012702 18.5549984 -13.5374002 + 1.7060126 -2.1937656 10.3314075 2.1928444 -1.4142649 10.5989990 + 2.2601640 -2.9263663 10.6005621 0.6705160 10.8756313 -8.4633865 + 1.3236326 10.9812326 -9.1551371 0.5013730 9.9339094 -8.4354229 + 20.5777550 8.8971510 7.9885654 19.8465805 8.4453344 8.4098463 + 21.3563328 8.5520601 8.4255571 -12.6633167 11.1250992 -3.9752998 + -12.0433874 10.4055758 -4.0944924 -13.1217251 11.1875839 -4.8132668 + 7.3266559 -19.1467438 11.6111231 6.5170774 -19.5740738 11.8907728 + 7.3621917 -19.2958870 10.6662817 6.1805925 -13.3794556 17.6785469 + 6.3808632 -12.5115738 18.0291233 6.9818931 -13.8844271 17.8169422 + -0.2594044 -0.5633743 12.3543434 -0.5140978 -0.0439423 13.1169405 + -0.7670195 -0.1933128 11.6321154 -9.8102875 -7.8463969 15.3887777 + -9.0141544 -7.4269600 15.0624704 -9.9323130 -8.6052303 14.8182411 + 3.8816555 11.8168030 -2.0857983 2.9835854 12.0932894 -2.2681646 + 4.3126740 11.8239193 -2.9404349 -18.3618202 -0.1487437 8.1848459 + -17.6068172 -0.7004802 7.9804230 -18.4823666 0.3912326 7.4037399 + -12.9272585 13.8725395 6.6127086 -13.7637033 13.7404957 6.1664395 + -12.4027882 13.1097670 6.3691106 0.8821198 9.7347984 5.5449877 + -0.0380209 9.9649229 5.4160867 0.9536991 8.8394461 5.2141514 + 9.4836283 18.9849377 -3.4493856 10.0359411 19.3838100 -4.1217575 + 9.1077213 19.7275391 -2.9766622 18.1261711 -4.3473024 14.7273188 + 18.2638092 -4.0680394 15.6324701 18.8623085 -4.9303875 14.5419922 + 9.3558741 6.9332862 -13.1415100 9.6519651 7.6881900 -12.6329021 + 10.1569719 6.5691748 -13.5182028 -19.0418396 11.1454306 0.4266655 + -18.2807808 10.8862658 -0.0928108 -18.7408943 11.9004765 0.9322047 + -0.3764256 -4.1628857 -20.1816216 -0.0450969 -3.8576941 -21.0261993 + -1.3262459 -4.1971912 -20.2951832 5.2183156 -6.2763085 7.8740959 + 4.4504867 -6.2575827 7.3028517 5.2728009 -7.1841950 8.1724348 + 0.2494133 0.7063269 -16.0378399 0.5729061 1.3422650 -16.6759357 + 0.7622671 0.8774998 -15.2479582 10.2592955 -8.1540537 8.0957365 + 10.4483957 -7.2954969 8.4743557 11.0094538 -8.6950569 8.3423338 + -12.0063267 2.6598978 -21.5027027 -12.8697767 3.0348969 -21.3293209 + -12.0444860 2.3840990 -22.4185143 -2.8991435 -20.5436954 11.6415482 + -2.3657918 -21.0427876 11.0229416 -2.2897372 -20.2941227 12.3362207 + 12.4002695 6.4953270 -4.4270058 11.4911451 6.2971058 -4.6515799 + 12.3514271 6.8889627 -3.5558586 6.1350574 8.6631498 -3.1906722 + 6.7343497 8.2773333 -2.5517464 5.2658896 8.5383015 -2.8096321 + -18.2850571 -5.7433000 9.3551941 -18.4939175 -5.5257745 10.2636499 + -17.7660675 -5.0014381 9.0445147 -2.0245194 4.9491086 16.9910774 + -1.9401197 4.2991123 16.2934990 -1.9610162 4.4416857 17.8002243 + -6.6728172 3.4910152 -8.8657770 -7.1193142 4.1220851 -8.3013096 + -6.5767708 3.9446795 -9.7031507 -2.0086815 -5.0841489 -11.8537855 + -2.0115111 -4.7869191 -12.7636633 -1.3287275 -5.7571979 -11.8237963 + -5.3097963 -9.3901148 18.1831150 -4.4165921 -9.4898825 17.8537750 + -5.5263667 -8.4731827 18.0141048 -4.2840786 -21.4564362 -10.2369757 + -3.6544707 -20.7673779 -10.4491644 -3.9331386 -21.8663578 -9.4463825 + -11.5414457 -4.4423079 -18.4268379 -11.0348635 -3.7215633 -18.0524940 + -11.9053631 -4.8986459 -17.6681881 -3.7679923 -14.5377626 9.1264296 + -4.5580578 -14.9206285 8.7450600 -3.8363132 -14.7296085 10.0617151 + -0.8009187 8.1391745 2.9869647 -0.9482408 7.4651742 3.6504791 + -0.0196734 7.8465466 2.5176497 -2.9685910 7.4191298 1.1781452 + -3.7575707 7.1565981 1.6522967 -2.4318750 7.8640437 1.8340564 + -16.5826015 9.7117205 4.9745197 -16.6275330 10.2883606 5.7372117 + -16.6644650 10.3002901 4.2241096 12.2935362 -8.7421160 -9.0280952 + 13.2369347 -8.6723824 -8.8819160 12.2049093 -9.4142160 -9.7038603 + -1.1790618 -5.0006266 17.5929527 -1.8446275 -5.6801281 17.7003403 + -0.8538361 -4.8417468 18.4790783 -13.8427553 3.7632680 -17.7326260 + -14.5370245 3.2596030 -18.1575298 -14.3040428 4.4583974 -17.2633286 + 13.4257565 18.5191669 -4.1338291 12.7457209 17.9435673 -4.4837832 + 13.8317604 18.0108891 -3.4316561 8.0488758 -6.4976435 -6.0345716 + 8.6696873 -6.9218783 -6.6268969 7.6584072 -5.7978001 -6.5580077 + 14.2359200 1.2122259 -7.1107845 14.9543962 1.7481965 -7.4465823 + 13.6191511 1.8434682 -6.7401624 -10.0778532 0.7999678 16.4997444 + -10.1142998 0.5174217 17.4135666 -10.0569677 -0.0147886 15.9977808 + -1.1707683 -19.4234638 13.5915003 -0.6299908 -18.6342545 13.5608606 + -0.5493755 -20.1334877 13.7526484 12.3584356 1.1018368 -13.0198212 + 11.8808765 1.8860577 -12.7493277 11.8298855 0.7314442 -13.7266979 + 18.1461067 -3.3186522 -3.2026021 18.7130451 -2.6763053 -3.6294558 + 17.4600525 -2.7949860 -2.7886760 -0.7639308 7.2516952 7.2780199 + 0.0277817 6.9280400 7.7077532 -1.4642527 7.0843492 7.9087148 + -1.9417218 -9.1325102 8.5936193 -2.0033486 -8.5286436 9.3337412 + -2.3101923 -8.6459856 7.8562217 10.7930326 11.5644264 -2.1018355 + 10.4095554 12.4290323 -1.9547540 11.2173691 11.3463068 -1.2720199 + 20.4208431 -4.8410392 4.1010756 20.7762661 -3.9608686 3.9777617 + 20.7770691 -5.3476171 3.3712034 15.5076532 2.2120061 -10.6013699 + 15.6434727 3.1440575 -10.7718554 16.0806847 2.0182202 -9.8595381 + -19.7856960 4.3242054 6.7563705 -19.9348030 3.3949664 6.9310536 + -20.2828770 4.7785602 7.4365206 7.6565928 -7.0180602 -3.0777948 + 7.7922111 -7.8777075 -3.4763494 7.6389437 -6.4110966 -3.8177376 + 14.9577942 7.5924230 13.8808050 14.0613165 7.3146005 13.6927223 + 15.3648491 6.8280687 14.2886057 17.2022610 16.3068237 -8.8615408 + 17.3684216 17.2445240 -8.9581900 16.2585506 16.2159653 -8.9934063 + -0.5291440 14.4179630 -3.7237172 0.2835248 13.9570971 -3.9320538 + -0.2874219 15.0257339 -3.0248497 0.9142565 -2.2889223 0.5904459 + 0.0218790 -2.1400802 0.2778115 0.9663610 -1.7963709 1.4095370 + 8.4183416 14.7391911 -13.0592489 9.2904320 14.3447428 -13.0692568 + 8.3321657 15.1075754 -12.1799889 -0.9047182 -5.6275253 10.7529268 + -0.9298841 -4.6876593 10.9325113 -0.0883647 -5.7573757 10.2702904 + -15.5183659 -9.0238972 13.9437771 -15.0278606 -9.8119478 14.1774693 + -15.7115993 -8.6045971 14.7822762 11.5310011 -6.4695783 -2.9408276 + 11.2863083 -7.3677292 -3.1637223 12.3254318 -6.5612988 -2.4148047 + -1.3001980 8.2149096 -7.3089385 -1.6997700 8.5956659 -8.0909863 + -2.0414929 7.9882507 -6.7473874 -13.1923380 -10.5124817 -3.5736401 + -13.2088499 -10.2635031 -2.6495359 -12.2620201 -10.5434942 -3.7967513 + -20.8268929 -5.1383982 -1.7097933 -20.8253822 -4.3024721 -2.1761172 + -20.4675503 -4.9319696 -0.8469543 -7.3574095 2.2070045 -19.2495461 + -6.9822664 3.0268328 -18.9280167 -8.0448093 2.4801729 -19.8570747 + -12.6381626 -5.4487209 8.3137217 -13.0233364 -5.0204525 9.0782213 + -11.7073479 -5.2304969 8.3605585 6.4009385 4.3559375 12.3217545 + 5.9981413 3.7946022 12.9842415 5.8344145 4.2664461 11.5554161 + 5.9117203 10.0294285 -0.1630186 5.3488388 9.9515247 -0.9332963 + 5.8080215 9.1952143 0.2947632 -9.2570839 -16.6987438 5.3697772 + -9.1309443 -16.3438168 6.2497473 -8.8233624 -17.5517750 5.3911352 + -7.3359232 -11.6029806 14.8127489 -6.5295582 -12.1172905 14.7741203 + -7.0894442 -10.8060293 15.2821608 17.7526264 7.1851964 -8.2946930 + 17.6684399 8.1376534 -8.2503042 18.6968479 7.0283933 -8.3042059 + -19.7186127 13.3325138 -8.7328978 -20.4474583 13.3717661 -9.3521500 + -20.0366001 12.7736311 -8.0238371 5.3477912 -3.8809154 19.2602577 + 4.4313359 -3.6050243 19.2452278 5.3127642 -4.8331819 19.1697426 + 2.2941370 -8.3541803 0.7269030 1.8925487 -8.8976469 1.4048434 + 2.2796428 -8.9012594 -0.0584166 8.7483082 -4.8949885 18.4866829 + 9.1876545 -4.1715946 18.0395737 7.8248081 -4.7934060 18.2563362 + -9.6156816 5.8418298 -0.5698883 -9.3104429 6.3500209 -1.3214219 + -9.0469475 5.0720687 -0.5543544 11.3750439 -2.0887160 21.8804150 + 11.6243601 -1.2812904 22.3300114 10.4779520 -1.9316207 21.5858326 + -2.1791565 -0.7427102 20.9347858 -2.8955815 -0.3953516 21.4661140 + -2.5517190 -0.8288882 20.0572891 -4.3566537 9.1987000 20.5636692 + -4.1202888 8.5103025 19.9419994 -5.2245107 9.4880810 20.2820396 + 0.1369402 0.5937482 17.7901917 -0.1606118 -0.2753502 18.0591946 + -0.0906333 0.6481698 16.8620319 -10.4139252 -16.7860909 -10.2846937 + -10.3623495 -15.8515968 -10.4854231 -9.5114145 -17.0967331 -10.3568544 + 0.2549450 15.7830038 -1.5271499 0.4317309 16.7023315 -1.7266901 + 0.8014489 15.5941010 -0.7643386 11.3499060 12.8653212 -4.5518317 + 10.4594545 12.8909092 -4.9020801 11.2995272 12.2581749 -3.8135445 + -10.3755693 -0.0543856 -13.5362902 -11.2983704 0.0581948 -13.7643166 + -10.2968016 0.3264132 -12.6616364 -18.5735035 5.6289425 -11.3874874 + -18.2243309 4.8078175 -11.7339897 -17.8647861 5.9827538 -10.8501148 + -1.9223819 -23.2691727 -4.4399734 -1.6845064 -22.3670387 -4.2259636 + -1.6690587 -23.3725014 -5.3572421 -11.6340961 -0.9153636 -5.8368611 + -12.2360859 -1.3288324 -5.2180843 -11.4195910 -1.6081334 -6.4615922 + 2.1433530 -14.6741590 15.1518955 1.3909497 -14.1699495 15.4615631 + 2.1996150 -15.4153118 15.7550201 10.1367235 4.8129625 -7.1739912 + 9.9731092 5.2341652 -6.3301601 10.1356554 3.8760014 -6.9782000 + -13.2547054 5.1881676 4.7092657 -13.9772463 4.8710203 5.2510996 + -13.4152098 4.8041048 3.8473110 4.9447203 0.4918434 20.9641094 + 5.0473599 0.1499902 21.8522720 3.9976885 0.5513824 20.8383389 + -0.1800189 1.1220275 21.4294662 -0.8729541 1.7035691 21.1166058 + -0.6194773 0.2850763 21.5798683 -17.7797527 -9.1145010 -12.0744600 + -18.0179710 -9.6816864 -12.8077984 -18.6171494 -8.8581028 -11.6881199 + -20.5119019 -4.8587604 -7.2595396 -20.9730968 -5.0540581 -8.0752544 + -20.4972038 -5.6913228 -6.7874632 2.4760296 -3.0121329 19.0943031 + 2.2456045 -3.1094842 18.1703663 1.6343453 -2.9472873 19.5455170 + -14.0133896 -7.9006381 1.7849722 -14.3552332 -7.7659163 2.6688414 + -13.6788874 -8.7974634 1.7916569 8.5856638 -11.9759989 13.6281013 + 8.3161898 -12.8918447 13.6976824 7.8917069 -11.5603666 13.1163349 + -1.0032392 4.6032534 -21.3797245 -1.1083478 4.1369872 -20.5503998 + -0.7229737 3.9296546 -21.9993610 0.8352044 15.7387152 5.1557827 + -0.0984239 15.5295563 5.1271000 1.2512255 15.0486784 4.6390548 + -1.7013869 -19.6969013 6.7748389 -1.7032497 -19.7177372 5.8178678 + -2.4333375 -19.1239624 7.0033584 18.7691517 9.0316753 -2.4443502 + 18.9493389 9.8776808 -2.0344255 18.1386681 9.2303982 -3.1366150 + -19.2983418 7.9039745 -12.5614576 -19.2215958 8.5760250 -11.8841915 + -18.9270210 7.1175232 -12.1616488 -9.9833708 9.2617779 -2.4914343 + -9.1784878 8.7490377 -2.5655406 -10.5468063 8.9251432 -3.1881762 + -14.3322392 9.3584728 -2.3531888 -13.7852468 9.8523207 -1.7423319 + -14.0105982 8.4591837 -2.2894807 8.1542854 17.2061710 0.3355186 + 7.7143693 17.6060219 -0.4146976 7.7345638 16.3512802 0.4315889 + 3.4692309 -7.8278804 -13.1935854 3.2941236 -6.8924513 -13.0909119 + 3.3658471 -7.9893861 -14.1313810 3.0410028 4.4806070 -20.7007561 + 3.7473967 5.0335670 -20.3668785 2.3390524 5.0939894 -20.9181499 + -7.0352359 16.1654873 -14.6977911 -6.6371980 15.6798325 -15.4202433 + -6.6317759 15.7982397 -13.9112911 9.2273483 12.1739702 -6.3633523 + 9.2523651 11.7481728 -7.2202673 8.5474558 11.7029190 -5.8815966 + -9.9219093 -9.9798079 11.6948128 -10.4732256 -9.2873058 11.3305006 + -10.0983839 -10.7417088 11.1429110 -6.7028732 -22.9177265 3.1659844 + -6.2647376 -22.6259995 3.9654617 -6.8387880 -22.1159267 2.6611316 + -9.3948059 -6.3169031 11.5658922 -9.6394291 -5.6853032 10.8895245 + -10.2096891 -6.7749023 11.7718859 18.9483356 3.3368979 15.1036673 + 18.2986813 3.0413473 14.4658346 18.5957355 3.0614707 15.9498625 + 7.1126161 7.5833192 -7.5106192 6.6383500 8.0484772 -6.8214664 + 7.9851227 7.9769683 -7.5085435 -6.8790455 -6.3014803 9.3971424 + -6.9142728 -7.0141730 8.7591305 -7.0466180 -5.5114889 8.8832703 + -1.8093311 13.7922649 13.3682022 -1.0436399 14.3662090 13.3913918 + -1.5314831 13.0033379 13.8336325 5.4056873 -9.1908560 21.7217407 + 6.0624623 -9.8825903 21.6418552 5.0449700 -9.3034773 22.6011906 + 17.2602768 12.7619610 9.2032366 17.9811325 12.3925285 8.6932173 + 16.6538792 12.0313988 9.3248529 11.1195278 -6.1994238 -10.0903692 + 11.9027567 -5.6958132 -9.8686476 11.3067341 -7.0840578 -9.7763500 + 7.9845777 4.6865482 16.9439278 7.4120765 5.0551629 16.2711754 + 8.6083193 5.3863769 17.1373653 10.9965773 4.3553205 17.3341446 + 10.3863087 5.0859122 17.4343491 10.5038414 3.6971645 16.8439674 + -16.7256336 -5.7117939 2.0967882 -16.1182880 -5.1452756 2.5726230 + -16.6702919 -6.5544057 2.5475366 6.4387875 3.6621618 6.3828797 + 7.1044993 4.2795315 6.6860533 6.5890765 2.8731003 6.9034820 + -15.7813234 7.2685747 -11.2370481 -15.6290197 6.3238292 -11.2148809 + -14.9669180 7.6502218 -10.9094486 6.2782183 15.6563339 -6.0219107 + 7.1420488 16.0030289 -5.7986813 5.9183760 16.2907677 -6.6417799 + 8.4995747 -10.0604277 1.0772315 8.4927464 -9.3221617 1.6864517 + 8.8756189 -10.7826900 1.5803809 20.2916546 -3.4039595 -9.2140265 + 19.7422657 -3.9757826 -8.6779089 19.8058548 -2.5805516 -9.2612371 + -2.3673701 -12.3474779 -6.3448563 -2.0892625 -11.4640350 -6.1031613 + -2.1989758 -12.4026489 -7.2855110 -14.1860228 16.4438953 0.0346975 + -14.1708384 16.4148521 -0.9219413 -14.6861687 15.6686964 0.2899458 + 14.7782145 16.8712349 -2.3712695 14.7596006 16.6187878 -1.4481469 + 14.5854578 16.0620155 -2.8448086 -5.0404463 -9.3909826 -8.4776649 + -4.6620531 -9.2907906 -7.6041594 -5.8912082 -9.8020267 -8.3244381 + 17.8935852 8.0618401 -0.0479700 18.2552128 8.1101322 -0.9329134 + 18.6611099 8.0411730 0.5236158 4.2644625 -13.0809813 11.3448429 + 3.6612694 -13.6869125 10.9144516 5.1345711 -13.4233179 11.1400280 + -12.7411814 -8.1461658 13.7924471 -12.9003677 -7.6890798 14.6182575 + -13.4682570 -8.7641106 13.7167063 -3.2630122 -15.5332565 11.7226162 + -2.6436253 -16.0814991 11.2409315 -3.5989094 -16.1027184 12.4147997 + 1.5908782 -20.4801159 -7.6381140 1.4145645 -19.5869217 -7.3425603 + 0.7933929 -20.7419720 -8.0982018 6.8159914 -19.2280865 -15.3049679 + 7.3024402 -18.9666348 -14.5231476 5.9089007 -18.9898624 -15.1134796 + 0.9973662 -17.3642578 5.6448755 1.6610839 -17.7604256 5.0802851 + 0.2367524 -17.9391747 5.5601950 -5.8612585 13.6065865 13.4906197 + -5.8750734 13.6661444 14.4458656 -6.7371073 13.8827763 13.2207317 + 2.5811818 -6.3843331 11.7907143 2.3323293 -7.2619767 11.5008078 + 2.2537611 -5.8034320 11.1039963 10.1245775 8.8559093 -11.2235451 + 9.6508150 9.5841265 -11.6253910 10.5621338 9.2439089 -10.4657640 + 5.7852983 4.8674040 15.3120623 5.5602369 5.7371674 14.9817743 + 4.9567676 4.3880758 15.3085175 3.8267689 -5.8291750 14.1217632 + 4.6710234 -6.2762113 14.0615635 3.4103036 -5.9887958 13.2748213 + -11.3987827 11.6306725 -7.3861690 -12.0290747 12.1391420 -7.8964858 + -11.8657598 10.8256760 -7.1622386 1.7116385 4.6871648 20.0824261 + 1.1757526 5.4790754 20.1264305 1.1006075 3.9987714 19.8197727 + -1.5638076 -12.7255640 -9.3136654 -1.0062678 -13.4901943 -9.4576159 + -2.3490615 -12.9006777 -9.8322630 16.7915573 12.3979273 -8.8607807 + 16.6730080 12.7644300 -9.7370539 17.5893822 12.8132677 -8.5333691 + 5.1902995 -13.2981052 7.7955022 4.3492970 -13.1950026 8.2408295 + 5.7763004 -12.6904106 8.2466583 -1.0634865 -3.1261237 11.7474575 + -0.5684201 -3.6580131 12.3705425 -0.8557781 -2.2226250 11.9857416 + 13.6461287 12.6214314 -5.6190076 12.8186855 12.2918892 -5.2683339 + 13.5899153 13.5710802 -5.5129967 -18.3546143 0.5348043 5.5400777 + -18.7039833 1.1425151 4.8882642 -17.5063057 0.2665579 5.1870213 + -4.8976393 -5.4638848 14.3258505 -4.1883068 -6.1050110 14.3709812 + -4.5394306 -4.7468057 13.8026714 -0.1126127 -9.7303152 18.3034763 + 0.3886954 -9.0063238 18.6786537 0.0692276 -9.6864233 17.3647327 + 11.2850332 14.2323284 -12.9378901 11.7774878 14.3335943 -13.7524242 + 11.5859957 13.3978910 -12.5782118 17.0853138 -2.8501642 -7.4372973 + 16.1289139 -2.8236372 -7.4085035 17.3017921 -3.7787895 -7.3534908 + -2.8503304 -15.8644705 -14.2786684 -2.8939862 -15.6999435 -15.2206116 + -3.4886982 -15.2599802 -13.9001055 -11.3799524 -8.5968685 -7.1848011 + -11.7053041 -9.3370171 -6.6723967 -11.6905365 -7.8240366 -6.7131023 + -16.4116688 -10.8188486 0.3020197 -16.1962166 -11.4731035 0.9666719 + -16.6781845 -10.0477057 0.8025593 -3.2553556 -0.5884103 18.4622726 + -3.8976002 -1.2072802 18.8097687 -3.7814593 0.1232441 18.0975876 + 18.9251747 -8.2058983 -7.4154110 19.1890812 -7.3583732 -7.7735815 + 19.0668430 -8.1220264 -6.4724755 3.6463399 17.5515175 -1.6980908 + 3.5894914 18.2216549 -1.0169778 3.3379858 16.7512245 -1.2730260 + 7.0509243 2.3772454 9.3615541 7.9070992 2.3151367 8.9380703 + 7.2402506 2.3015811 10.2967882 -0.5340082 -17.1542721 -4.9946313 + -1.0053234 -17.7167416 -4.3800411 -0.9142611 -16.2855721 -4.8642392 + -12.5969095 9.4815960 3.7328765 -13.3658257 8.9688673 3.9820921 + -12.7972097 10.3709536 4.0246897 16.3159084 -14.8717260 -11.4294271 + 15.4146376 -14.7123737 -11.7096930 16.3077717 -14.7002478 -10.4877472 + -9.0817738 -5.3467574 -15.4988585 -9.2984781 -4.6862721 -14.8408079 + -8.2857161 -5.0171933 -15.9158840 -3.7091937 10.8774500 -11.4037151 + -4.6216168 11.0857201 -11.6045637 -3.3775346 11.6578722 -10.9596710 + 0.3976165 -18.5090809 -11.7956028 1.0539035 -18.4742565 -11.0996809 + 0.5756215 -17.7362442 -12.3315773 -11.7071943 13.7343245 -1.0051454 + -12.4160366 13.0972805 -1.0943061 -11.7176523 13.9762306 -0.0790765 + -21.3947735 5.6094794 -10.8016682 -21.7603626 5.4172807 -11.6651707 + -20.4468536 5.5903931 -10.9332504 -7.5370789 16.7821293 15.2375660 + -7.0422091 16.6436787 14.4299974 -8.2266989 17.3992786 14.9930573 + 1.4193225 22.0050201 0.4453436 1.8595999 22.4646320 -0.2695997 + 2.0962181 21.8970814 1.1134703 -9.0500650 3.7139275 3.5632048 + -9.3231535 3.3864248 2.7062352 -9.6527109 3.2999301 4.1809878 + -20.4804020 1.5707073 -12.2309685 -19.9965248 1.8823929 -12.9957876 + -19.8328056 1.5592031 -11.5261860 9.9586639 -8.1877518 -20.6573601 + 10.4549360 -8.5492926 -21.3916855 9.3267488 -7.5948987 -21.0641041 + -4.2334366 -6.5395055 -7.0995035 -3.9922652 -6.3289633 -8.0015783 + -3.5337572 -7.1162944 -6.7929163 1.0897485 -14.9819193 -0.1128630 + 0.6583017 -15.8216028 -0.2710307 1.2755390 -14.6396446 -0.9872553 + -5.5352783 19.3084011 -8.3299494 -5.5852098 19.1892071 -7.3815131 + -5.9672298 20.1476707 -8.4889393 -4.8724017 -8.9397917 12.7515459 + -4.6097898 -9.1403399 11.8531876 -5.8184934 -8.8038912 12.6998415 + 6.0161796 14.0435762 8.7947569 5.7542267 13.1235409 8.8286180 + 6.9715838 14.0187864 8.7416563 -12.7514515 -1.1982770 -0.5500424 + -13.2020636 -0.8362169 -1.3129929 -12.6320839 -2.1245892 -0.7596347 + -20.8726273 -11.6936140 -8.5716887 -20.6733761 -10.9639320 -7.9850926 + -20.0163612 -12.0420237 -8.8199787 -2.7425470 -2.3427641 23.1895256 + -2.6309526 -2.0363057 22.2896023 -3.1983004 -1.6265086 23.6316776 + 10.2676020 22.5560017 1.8090509 9.9665146 21.7433338 2.2154374 + 11.1616459 22.6683655 2.1319928 -11.6992664 7.5704823 -7.6340480 + -12.0559711 7.5357208 -8.5216208 -10.9343090 8.1414127 -7.7055349 + -9.2598782 -17.1744003 -7.6173315 -9.8289537 -16.4262295 -7.7979560 + -9.5290432 -17.8387203 -8.2517300 -17.7452106 -5.2971821 -8.5658646 + -18.2119350 -5.0813732 -9.3732233 -18.1163406 -6.1357675 -8.2915115 + 17.1136856 7.7357512 11.0481739 17.9872971 8.0281849 11.3080101 + 16.5838852 8.5329599 11.0499001 3.8745198 22.5564785 6.7543726 + 3.1466048 22.3711376 7.3476858 4.6504426 22.5395546 7.3146305 + -12.7316866 -20.6069984 -0.8679091 -12.4139099 -19.9877968 -1.5250539 + -12.0933046 -21.3200874 -0.8822453 8.1968956 -18.7814121 16.8648109 + 7.6785102 -18.0031147 16.6604595 7.5508089 -19.4811382 16.9606590 + 17.5942001 4.6570621 -9.5051546 18.2942066 4.4811735 -10.1338739 + 17.6787891 5.5897532 -9.3072567 -4.8239312 1.3340175 17.3788815 + -4.9668078 1.5349613 16.4539814 -5.6758180 1.4802800 17.7901325 + -12.3323193 -0.2363434 19.0792789 -13.0853214 -0.5515202 19.5791626 + -12.6717882 -0.1010714 18.1945782 -9.1509256 10.5637894 -19.1080837 + -9.4432573 10.8236246 -19.9817295 -8.2547684 10.2534647 -19.2378235 + -2.3580689 13.2931557 -10.5975351 -2.6860604 13.7173519 -9.8046227 + -1.4115415 13.4330015 -10.5699530 9.7713442 2.0943525 9.0422058 + 10.0823317 2.9923773 8.9278831 10.5482845 1.6042558 9.3112783 + -10.0972528 -21.6789761 3.4393249 -9.6403675 -21.8340282 4.2660327 + -11.0176325 -21.8506660 3.6384604 0.9892119 4.5903864 22.9268169 + 1.2545242 4.3434119 22.0409031 1.7952051 4.8986464 23.3410416 + -13.8399439 3.5232966 -7.4763250 -13.3988800 2.6989741 -7.2709317 + -14.7022600 3.2599449 -7.7977123 5.0911083 -16.6472187 -8.3531094 + 4.2630420 -16.2283211 -8.5877628 4.8574171 -17.2718334 -7.6664662 + -13.5038939 -20.0811234 2.1904504 -13.7773123 -19.2372417 1.8308151 + -13.3573427 -20.6327801 1.4220562 -20.2344952 9.2567301 -8.4994831 + -20.9270668 8.5991240 -8.4352074 -19.6175156 8.8934784 -9.1347904 + 4.3625407 -0.0810094 -21.3249168 4.8787389 -0.6921316 -21.8505592 + 4.5839043 0.7820302 -21.6747627 15.5671673 18.4218311 -6.1732478 + 14.8483896 18.6315708 -5.5769248 16.2557354 19.0473347 -5.9477425 + 0.0466197 -21.8951588 13.1344957 0.2734411 -21.8171673 12.2078342 + -0.5236449 -22.6627274 13.1777153 8.7728567 -5.5329466 15.1494932 + 9.2800903 -5.9734120 14.4676304 9.2491770 -4.7192178 15.3144045 + -7.9192667 0.7625088 18.8884583 -7.2690883 0.2147698 18.4485931 + -7.4153757 1.2652626 19.5284309 12.1249008 3.2190263 -7.6838441 + 11.6335125 4.0050097 -7.4450984 12.4656811 3.4060867 -8.5585489 + 5.5168109 -20.0413895 -10.5607958 5.7795224 -19.7529354 -9.6867189 + 6.2208352 -20.6258698 -10.8418016 -4.3679008 16.0560894 17.1471539 + -4.8203259 15.8562794 16.3276310 -5.0710316 16.1830940 17.7841072 + -14.5451336 -13.5844803 -0.7112817 -13.9725990 -13.7038021 -1.4690404 + -15.3674946 -14.0041103 -0.9639984 -1.9743463 4.4280601 -15.0237589 + -1.2323217 3.8236556 -15.0418224 -1.7146139 5.1435928 -15.6040897 + -1.5765475 7.1849561 -1.1768348 -1.1008838 7.9866776 -0.9595358 + -2.1739962 7.0539012 -0.4405526 13.2329531 -8.4028530 -0.3079596 + 13.0131016 -9.3344584 -0.3108751 13.0709476 -8.1213474 0.5924519 + -15.3954678 15.7089071 12.8712225 -14.5831499 15.3069992 12.5632601 + -15.7984972 15.0403290 13.4251204 -8.3697233 -13.4165077 -10.3016729 + -7.8030958 -12.6884909 -10.0464172 -7.8238392 -13.9556026 -10.8740540 + -2.9788308 9.0401659 -13.2484751 -3.0530052 9.6822157 -12.5424290 + -3.8634856 8.6877918 -13.3456898 19.8200359 13.2552109 4.6761475 + 19.5183105 13.8862066 4.0226655 19.0268803 12.7925034 4.9464035 + 6.4669557 -1.0831896 2.4071910 6.4406881 -0.8720359 1.4739407 + 6.6688557 -2.0184238 2.4355640 -18.6142292 -8.1722050 4.7852693 + -18.7628880 -7.5870895 5.5280833 -17.6783924 -8.3702927 4.8199520 + -6.3055482 20.2774277 9.0617046 -5.9705405 20.8287010 8.3545284 + -5.8227611 19.4555721 8.9739342 -2.3389237 -5.2672195 -4.1515107 + -1.9293852 -4.5951252 -3.6067178 -2.3378153 -4.8943882 -5.0331159 + 11.7017632 15.2034225 -10.3407230 11.5177498 14.5517397 -11.0172434 + 11.6091328 16.0449791 -10.7873058 -8.7044373 -8.9987640 2.4123843 + -9.1531448 -9.1966543 1.5903548 -8.7597942 -8.0465097 2.4922576 + -5.4895663 -22.0136299 5.2857475 -5.1719384 -22.2344551 6.1612930 + -5.0437145 -21.1949005 5.0686493 -3.0960186 -3.8755369 3.1513655 + -2.2666519 -4.3420954 3.0478966 -2.9760797 -3.3457282 3.9394958 + -17.9577293 -15.8357267 -5.5839763 -18.6015015 -15.5542898 -4.9339132 + -17.4384193 -15.0515671 -5.7618599 -1.3597127 -19.3545856 3.8076355 + -1.9418011 -20.1135426 3.7703938 -1.8837664 -18.6334743 3.4589245 + -13.9303865 -5.3694930 -17.1147461 -13.9720964 -4.6617675 -16.4716148 + -14.8262482 -5.4483609 -17.4425335 6.7324109 -1.4694989 20.1222305 + 6.0403242 -0.8150200 20.2165985 6.2659879 -2.3016300 20.0432453 + 10.9817686 10.0227547 14.4864197 11.3351192 9.3006067 15.0059166 + 10.1932755 9.6624632 14.0805855 1.0206275 9.3123541 -12.4344740 + 0.6480526 8.5561695 -12.8879118 0.5132311 10.0579090 -12.7552977 + -4.4057059 14.7777348 -2.2441030 -4.7052884 13.8738384 -2.3413258 + -3.7425122 14.7374525 -1.5550578 -15.7825251 9.3273468 -7.5266361 + -15.7811947 10.1482048 -8.0190001 -16.7047482 9.1718006 -7.3228197 + -1.2361954 -3.9173517 -14.3978128 -1.1584724 -3.1289282 -14.9350090 + -0.3733457 -4.0195713 -13.9962244 4.9243650 9.4606733 -11.3276587 + 5.4201126 8.8096104 -11.8242302 5.5336151 9.7630110 -10.6541328 + -10.6474743 5.1024184 -11.2229366 -11.1297255 4.6340671 -10.5415306 + -10.4889793 4.4442258 -11.8996143 -3.3528824 4.1723256 -12.3705044 + -2.7425470 4.2599802 -13.1026516 -3.7700717 3.3217041 -12.5069876 + -9.7699652 -12.1774092 10.1189375 -9.4831886 -11.6180019 9.3970966 + -9.1203508 -12.8797245 10.1503487 20.3176613 1.5752577 -5.0942478 + 19.9719601 1.0136427 -4.4004817 20.9986420 1.0481082 -5.5121117 + 1.2646424 22.6339893 8.3599949 0.6108918 21.9799957 8.1127405 + 0.8706719 23.4711342 8.1146250 11.9657993 -15.3767252 -6.1148701 + 11.8070059 -14.5453777 -5.6677923 11.2680826 -15.9532700 -5.8033900 + -9.1650667 11.3683023 0.6946449 -9.8157024 12.0650816 0.6086012 + -9.6631403 10.6126833 1.0064056 6.5253549 -6.7143784 -20.1732502 + 7.2226028 -6.5249934 -19.5453892 5.9631906 -7.3453875 -19.7237720 + 8.9203901 15.8349771 12.1157894 8.9294930 16.6826992 12.5602179 + 7.9939170 15.6623125 11.9482584 13.0236750 7.2827535 -8.5961657 + 13.4815645 6.7483401 -9.2449884 13.5717707 7.2307124 -7.8131490 + -19.5549412 -3.0001111 13.9208593 -19.5367203 -3.8680112 14.3241568 + -19.9118710 -2.4278309 14.6000710 -18.1100311 4.7309237 15.7628775 + -18.2271023 4.3505363 16.6334133 -18.9460621 4.5809078 15.3215399 + -14.1685495 -8.0864506 10.0625954 -14.9321280 -8.2957067 10.6005468 + -14.4308662 -7.3116713 9.5654640 14.3905334 1.8422412 11.4674826 + 15.1675367 1.3987215 11.1272068 13.9962263 1.2085520 12.0668077 + 15.8982620 -6.8350096 16.3183022 16.6613369 -7.1069169 16.8282185 + 15.5036783 -6.1318383 16.8341370 -0.6236692 -5.8568525 15.1045580 + -0.5482187 -5.7829728 16.0559158 -1.5107096 -6.1860113 14.9594870 + -4.9842110 19.5688591 -13.3223505 -4.4232826 19.6537724 -14.0933113 + -5.3131461 20.4542046 -13.1667938 20.6165066 2.0523260 10.6168432 + 19.8249149 2.5603721 10.4393463 20.7398300 2.1239042 11.5633631 + -16.1865387 -3.0059805 -15.8949575 -16.8826618 -3.1743405 -16.5300179 + -15.7843771 -2.1894579 -16.1912479 1.5005409 -11.7698565 -7.8628292 + 2.2716336 -12.0581083 -7.3744044 0.7710795 -12.2383499 -7.4570808 + -5.2040944 1.4602828 14.6424446 -5.8046336 0.7775152 14.3434258 + -5.2073874 2.1077225 13.9374323 -18.8938274 4.0140500 10.7898169 + -19.2066383 3.3398232 10.1866579 -19.5494308 4.7091599 10.7329130 + 1.0431191 -10.1017771 -5.1700792 1.8052139 -10.1864090 -5.7430367 + 1.1762273 -9.2698345 -4.7157822 6.4230714 -2.1240320 14.5281429 + 6.5263381 -1.8780167 13.6088800 5.5978966 -2.6083717 14.5552225 + -19.9169216 -1.4296423 3.7347600 -20.1100082 -1.4824060 4.6707973 + -20.3807793 -0.6465899 3.4382880 -3.1664224 -6.8787823 17.9230328 + -3.9804413 -6.9243779 17.4215088 -2.9090211 -7.7925601 18.0454521 + 4.0333352 5.3925633 -2.0542550 3.2860188 5.9821758 -2.1547887 + 4.7444119 5.9567881 -1.7505240 -11.7623186 3.0113153 12.4883022 + -12.0238590 2.3945746 11.8045931 -11.3224669 3.7189186 12.0170698 + -8.6168833 -0.4433262 8.2679405 -8.6760778 -1.1327147 8.9293575 + -8.6992836 0.3715703 8.7633047 2.9537883 1.8798343 16.9896297 + 3.0569117 1.6589530 17.9152699 2.9676893 1.0354991 16.5389233 + -10.3812332 -13.2801237 -4.0900850 -11.1474524 -12.9075584 -4.5263586 + -9.6561050 -12.7141132 -4.3547602 2.9008048 -15.3036537 -9.0181103 + 2.5572243 -14.4735794 -9.3485060 2.1230123 -15.8017330 -8.7667389 + 10.4794922 -5.5539875 9.6482716 9.8137188 -5.7882576 10.2948742 + 10.2779322 -4.6479354 9.4144449 -3.5284789 21.1461029 -4.0819254 + -2.7804577 21.1430492 -4.6791582 -3.2560489 20.5874290 -3.3539848 + 1.1372305 2.2922845 12.1711617 1.1176820 1.3616285 11.9481611 + 2.0328825 2.4480140 12.4708080 19.6869545 -1.1239990 9.2237606 + 18.9290848 -1.6938854 9.3545084 19.4348965 -0.5530031 8.4980459 + -5.9177866 -10.0237646 -15.6522160 -6.7194533 -9.5469589 -15.4372320 + -5.8810878 -10.0116549 -16.6086349 16.4957829 -10.6388197 11.0337954 + 16.3064117 -9.9650145 10.3808346 15.6356363 -10.9102240 11.3542948 + 20.0230141 -1.4616011 -3.5940800 19.8503742 -0.6804134 -3.0685587 + 20.8027878 -1.8497498 -3.1971838 -10.8243437 -14.2267122 -10.9738760 + -9.9886503 -13.9033890 -10.6372585 -11.0488977 -13.6204710 -11.6797647 + 14.3937569 6.2242422 -13.7170963 13.4439983 6.1512299 -13.8112192 + 14.6463213 6.8957396 -14.3507643 -16.2362041 1.6689049 9.4196558 + -15.7302475 0.8901518 9.6515675 -15.9976320 1.8474083 8.5100117 + -4.9852161 11.9307108 -2.0780499 -5.8249416 11.9186039 -2.5373383 + -4.8000736 11.0099764 -1.8931121 1.7279396 22.8057327 -7.8179297 + 2.2410989 22.7726383 -7.0105858 2.1619475 23.4722958 -8.3504372 + 13.2877617 4.4376230 10.5982962 13.7305946 3.5909348 10.5412941 + 12.5554171 4.3665862 9.9860401 -3.3190868 20.9866982 -10.4413319 + -3.6029217 21.5426903 -9.7156992 -3.9265473 20.2470703 -10.4281740 + -18.1007614 0.6217476 12.1880283 -17.6699314 0.9179205 11.3862190 + -18.4557552 -0.2388426 11.9653254 15.4177628 2.4753051 15.3626156 + 14.7631388 2.0668585 15.9290695 16.2303429 2.4334888 15.8667946 + 1.7964669 -1.6690093 22.8785954 1.8160864 -1.4691231 23.8144855 + 2.6851509 -1.9624413 22.6776714 4.3602376 -11.7260370 19.8879128 + 4.0175986 -12.5774918 20.1596775 5.2237535 -11.6735220 20.2975636 + -10.6302099 3.1010525 8.4418945 -10.0563402 2.5851898 9.0082788 + -10.5737505 3.9908056 8.7902966 -0.2629415 13.8441887 -16.0432034 + 0.3235692 13.2501373 -16.5115414 0.0006364 14.7179308 -16.3318768 + -11.8138971 11.6313381 16.2566853 -11.6400528 12.5197039 15.9455318 + -12.7494488 11.5018492 16.1010933 13.8229475 -9.1366882 -13.9690180 + 14.2805719 -8.7294016 -14.7044973 14.5221138 -9.4310303 -13.3852701 + 1.9873432 13.1208620 14.6336670 2.0855815 12.1775446 14.7630253 + 1.5248971 13.4229403 15.4154110 -4.1946616 -12.0020084 -14.5505953 + -3.4408910 -11.5496111 -14.1719160 -4.8300385 -11.3068600 -14.7217579 + 11.8735600 -5.8265696 19.1378288 10.9169054 -5.8467889 19.1630440 + 12.0915203 -5.9522133 18.2142811 -0.3905108 -0.1671285 -24.8626003 + -0.1468585 0.6475855 -25.3020382 -1.3175482 -0.0571877 -24.6510658 + 16.4023647 15.7157221 -6.1257458 16.7653751 15.7219543 -7.0114188 + 15.8304090 16.4826698 -6.0959215 13.2771273 0.1380321 13.4555407 + 12.7135077 0.5021393 14.1381750 13.5958519 -0.6865138 13.8226509 + 7.0752320 -10.7175388 -19.5299110 8.0159254 -10.7151394 -19.7068920 + 6.8140116 -9.8002062 -19.6105194 -19.5677719 -9.2626724 -9.7254658 + -18.9830837 -10.0104733 -9.6023188 -19.2329025 -8.5955830 -9.1262274 + 7.9103107 -11.5333767 -9.9048767 7.8031564 -12.4831333 -9.8527851 + 7.3919592 -11.2753105 -10.6670742 -2.0311978 17.6214752 -11.9919786 + -1.8915948 18.5660915 -12.0586300 -2.7209291 17.5270615 -11.3350248 + -19.8462086 -11.2388201 6.1418772 -20.2049294 -11.2897949 5.2559013 + -19.9035110 -12.1342173 6.4753618 11.3487835 -16.8528080 -1.3114302 + 10.5243196 -17.0342903 -1.7626017 12.0054455 -17.3431015 -1.8060406 + -11.1154413 16.7142143 11.3455973 -10.2944727 16.9550495 10.9163647 + -11.7352266 17.3912907 11.0741844 -4.0242448 0.4614630 1.5558041 + -4.2096028 -0.2640019 0.9595030 -3.1053274 0.6753851 1.3943740 + 5.0086927 -12.2752495 -18.6394863 4.6144800 -12.4225550 -19.4992142 + 5.7484708 -11.6927919 -18.8118305 -8.2063761 -8.6185265 -15.2135057 + -8.5907240 -8.0474243 -14.5484104 -8.6662312 -8.3890171 -16.0210266 + -1.3322836 21.2627106 0.2274271 -0.4491496 21.5966625 0.0700049 + -1.9084436 21.9031792 -0.1897892 -15.8648891 4.0511432 5.4052129 + -16.1456242 4.3387856 6.2739367 -16.5132961 4.4244270 4.8081713 + -4.7877364 10.7373505 17.1655731 -3.9234438 11.0720158 17.4048004 + -5.3444743 10.9558992 17.9129086 -13.0923538 -8.1138601 -4.9486275 + -13.4214382 -8.9833260 -4.7206726 -12.7426977 -7.7673006 -4.1277318 + -0.4630660 16.6127834 -6.6855168 -1.3707789 16.3476601 -6.5371962 + -0.5063127 17.2060337 -7.4354610 11.7120552 13.6824818 0.0364441 + 11.8270350 14.3082619 0.7515744 12.6026030 13.4802523 -0.2503632 + 0.9149325 6.7056885 13.5953617 1.2664956 6.7587452 14.4840803 + 0.0191122 7.0340776 13.6721621 -3.2819865 -16.5667725 -1.8376145 + -3.1324420 -16.0122147 -2.6033380 -4.0548058 -16.1903706 -1.4165397 + 4.7587614 13.7741508 15.1426516 3.8209898 13.7210703 14.9582624 + 4.8283978 13.6014490 16.0815639 0.4762727 5.9656463 17.7779503 + -0.2060119 5.5779309 17.2298660 0.8535448 5.2240663 18.2511902 + 17.3289585 -2.2186499 -17.6901245 16.4978065 -2.0764406 -17.2371407 + 17.1614418 -1.9410772 -18.5907478 2.7737331 -8.9920321 20.1799603 + 3.2354589 -9.3266716 20.9487629 3.2051659 -9.4159994 19.4381046 + -5.1398854 17.4278984 -1.3533909 -5.4656200 17.2474899 -0.4715847 + -4.8563695 16.5751743 -1.6831083 -9.4204426 16.5416298 2.2168410 + -10.0673418 16.5398064 1.5113270 -9.8731403 16.1390228 2.9579239 + 10.6831236 -15.1564569 15.4732847 9.7705116 -15.0201769 15.2187262 + 10.9121733 -14.3724890 15.9724455 19.5384083 -7.1248193 0.0855804 + 19.0347404 -7.9070764 0.3105819 18.8864040 -6.5071921 -0.2455699 + 1.3281347 8.7105236 19.2955761 0.8393490 7.9047184 19.1282482 + 1.6401447 8.9848433 18.4332352 17.1867294 -5.9165931 -11.6958990 + 17.2697544 -5.5219922 -10.8277817 17.1432056 -6.8579364 -11.5279408 + 4.2074213 -8.2543020 -19.7941151 3.5935400 -7.6325345 -20.1849957 + 3.7063801 -9.0656834 -19.7113533 4.0195737 8.5742807 3.2823212 + 4.0570030 8.5804024 2.3258729 4.6307287 9.2604971 3.5503302 + -3.9666376 0.3995151 5.8633585 -3.2203116 0.9984173 5.8867145 + -4.7309122 0.9717746 5.7952738 -1.4187530 9.3878078 17.4531784 + -1.8540007 8.7822590 18.0532627 -1.2330973 10.1610060 17.9860287 + -7.4947352 -10.8359261 -9.7811832 -7.8004169 -10.3140020 -9.0393028 + -8.2963638 -11.1249924 -10.2171469 -2.4195118 2.6936064 3.9685886 + -3.3378901 2.9568055 3.9090974 -2.0753155 3.1912069 4.7103124 + -16.6724663 -6.5530038 -12.4973192 -17.5370064 -6.8954067 -12.7243910 + -16.1398010 -7.3326149 -12.3401365 -6.5084338 8.5054073 9.2795057 + -7.1344552 9.2286043 9.3157835 -5.6998115 8.8703356 9.6389341 + 1.1286128 7.0889025 1.1950628 0.8319017 7.5391531 0.4041971 + 1.3104956 6.1942587 0.9073777 -6.5494132 -1.6202250 6.7143612 + -6.1396918 -1.1869317 5.9656172 -7.1588264 -0.9698496 7.0634451 + 8.6254740 20.7055855 -7.2287402 9.0237713 19.8362732 -7.1852946 + 9.2983150 21.2576809 -7.6271214 -19.4213753 13.9115715 8.1713228 + -18.6941109 14.5262890 8.0741634 -19.3938179 13.3802481 7.3756046 + 18.5068779 11.7249680 1.8003523 19.0712318 11.3240929 2.4614391 + 17.7342701 11.1606607 1.7709250 -5.3729296 3.7653165 12.9540462 + -4.8739147 4.5818667 12.9755316 -5.0990644 3.3385437 12.1422005 + -4.6893101 5.1887455 8.9903727 -4.6113210 5.2955394 8.0423508 + -5.1699009 5.9642234 9.2800245 -16.8060913 11.6958876 7.2047615 + -17.5430889 11.7935648 7.8076940 -16.1405640 11.2323427 7.7131238 + -8.7081432 0.6871434 5.4871607 -8.9464855 0.5001936 6.3951669 + -9.5286732 0.6017274 5.0017056 -4.9033604 12.6812887 -5.1403499 + -5.0058112 13.5867596 -4.8473349 -4.0934749 12.3852558 -4.7248006 + -3.7600837 -21.2318611 3.3571541 -4.4130397 -20.8862972 2.7484949 + -3.7337852 -22.1707268 3.1725695 10.0930290 -10.6456747 15.6845713 + 9.7150745 -9.8413553 16.0401745 9.4488239 -10.9510279 15.0458288 + 20.4826527 -11.8596220 -11.4204760 20.9312725 -12.0738659 -10.6025085 + 19.9958458 -11.0591888 -11.2241135 -6.3017344 12.9687004 10.2788458 + -5.4331579 13.3505344 10.4053745 -6.2231555 12.0771046 10.6181288 + -10.4622211 1.6493242 19.9843121 -9.5726385 1.3194113 19.8576946 + -11.0262403 0.9080967 19.7636395 7.7275157 -4.8395205 -24.0804787 + 7.8424869 -5.4755602 -24.7865009 7.4594827 -4.0348892 -24.5242805 + -19.5947914 -3.6244121 -12.6928425 -19.7997074 -2.7548413 -12.3492022 + -18.6468678 -3.7061217 -12.5879755 -20.5956345 -5.2453737 -10.7772512 + -20.1247540 -4.6830630 -11.3923197 -21.1746731 -4.6490092 -10.3025970 + -6.9293828 0.1917297 10.9227896 -7.0340619 -0.0675883 11.8382282 + -6.0019913 0.4143571 10.8414612 -10.5666695 -19.0547066 3.1883836 + -10.3677158 -19.9840050 3.0741377 -11.5224972 -19.0096397 3.1640036 + -4.5708852 -5.7359424 -17.6557865 -4.4646435 -6.4883246 -17.0736637 + -5.1471152 -5.1411800 -17.1757355 -20.4007587 -7.6036038 -5.5120420 + -19.9801083 -7.4328308 -4.6693549 -20.0972614 -8.4773083 -5.7585416 + 3.1423213 6.8284707 12.1378813 2.3412163 6.5546417 12.5845137 + 2.8685362 7.5563002 11.5797253 -8.2950354 6.2331328 -9.8827610 + -9.1469030 6.0369644 -10.2727232 -7.6735373 5.7106175 -10.3896637 + 18.5186615 -2.5617256 17.3612423 18.1145325 -2.7865632 18.1993122 + 19.3096752 -2.0779457 17.5989113 5.1553903 11.1134233 3.0494473 + 5.9282937 10.5958948 2.8235800 4.7246594 11.2791319 2.2108510 + 11.9384861 9.6311693 -9.1962938 12.6305294 10.2549591 -8.9767618 + 12.3142471 8.7748508 -8.9919529 -9.0709019 17.6192646 -0.3122762 + -8.6610117 16.8913116 -0.7795101 -8.8396444 17.4754333 0.6053645 + -2.5909328 10.8174467 12.6943483 -1.8087498 11.0677938 13.1860266 + -2.3076012 10.0812263 12.1521902 -7.3849244 -0.9293946 0.5144008 + -7.2373004 -0.0723995 0.9143987 -7.0739913 -0.8304629 -0.3854686 + 14.2856531 -11.6692333 11.8565331 13.4275618 -12.0744123 11.9819937 + 14.4809828 -11.2565746 12.6978359 0.0073775 -19.7422733 8.9058828 + 0.7546740 -20.1169376 8.4396143 -0.6856391 -19.6932030 8.2474365 + -8.2032051 8.5867386 -12.3261013 -7.9084167 8.4507380 -11.4256382 + -8.7826605 7.8456621 -12.5029335 -9.9642229 -18.9105053 -5.2064829 + -9.2062464 -19.2755127 -4.7498951 -9.5898142 -18.4215221 -5.9392486 + -19.7655411 8.6381769 0.2309787 -19.4719200 8.4147387 -0.6522505 + -19.4138012 9.5148592 0.3857003 0.0554873 18.3050270 -4.6430106 + 0.1709251 18.0479813 -3.7282243 0.0975976 17.4821415 -5.1301632 + -18.1543446 -0.6029595 -9.9559984 -18.1276417 -1.3152566 -9.3171310 + -19.0303650 -0.6565831 -10.3380241 17.1824036 -8.8122272 9.0922709 + 18.0660267 -8.9877033 8.7687721 17.2041397 -7.8941789 9.3623562 + 6.8296847 13.4108210 2.8711352 6.7947831 13.4501686 3.8268893 + 6.2373672 12.6956005 2.6390760 -5.3963323 13.9719610 2.6979461 + -5.8672814 13.1661015 2.9101465 -5.5056052 14.5241718 3.4721262 + -21.1124401 -0.9750977 -6.3303061 -20.2132092 -1.2904950 -6.2400784 + -21.6466446 -1.7693349 -6.3235340 -17.8536892 -9.1658239 1.7590758 + -18.5362835 -9.1653881 1.0880334 -18.3306351 -9.0946035 2.5859265 + -0.7226644 -5.1871028 2.5281010 -0.3251944 -5.8186703 3.1275773 + -0.2663870 -5.3248663 1.6980023 -8.0388498 6.0614886 8.1990356 + -8.2875776 6.2441339 7.2929416 -7.5019779 6.8112020 8.4558048 + -0.6008953 -22.2669182 2.4178038 -0.8482986 -21.4461384 1.9919558 + -0.2219307 -22.7961349 1.7159876 -3.5469859 14.6012297 7.5375638 + -4.0447989 13.8312349 7.8123775 -3.2959809 15.0289030 8.3562965 + 14.9630280 -4.7339163 -2.1202409 14.6879616 -4.4151645 -1.2606089 + 14.4396839 -4.2281237 -2.7419457 -5.7488475 14.7862577 6.0659709 + -4.9558768 14.9300442 6.5824542 -6.1528306 15.6516256 6.0014148 + 15.8747873 -10.0712786 -12.4739313 16.5133209 -9.3915825 -12.2582464 + 15.6153011 -10.4336176 -11.6268120 -7.6940794 -12.6271954 0.3541829 + -7.5499616 -12.8116913 1.2823118 -6.9756985 -12.0429049 0.1117670 + -9.6502199 5.6148109 12.3976994 -9.1810427 4.7826118 12.4572811 + -8.9870930 6.2778931 12.5895786 -10.0083361 -5.0116415 8.9489880 + -10.2674828 -4.0933475 9.0252199 -9.0669308 -4.9814763 8.7784681 + 11.5654144 -15.0040455 12.4039793 10.9162397 -15.1809855 13.0847836 + 11.0470285 -14.8246059 11.6195631 -1.7193408 -22.2967720 9.6253681 + -1.0599171 -22.2436981 8.9335775 -1.6295986 -23.1835880 9.9742775 + -9.8232975 -4.4099345 15.9630041 -10.4488592 -4.5441413 15.2510405 + -10.3587761 -4.4146361 16.7563972 -1.5680355 10.8756132 5.7165918 + -2.2526042 11.5206966 5.5392060 -1.8625647 10.4253550 6.5082684 + -2.9968855 13.4429293 -18.1425514 -2.6213486 12.5627823 -18.1658802 + -2.7851450 13.7705841 -17.2684574 5.8004193 -4.1634922 -21.0071144 + 6.2365170 -4.9952693 -20.8221893 5.7961907 -3.7034633 -20.1677170 + -3.5899670 -12.7216434 4.7025533 -4.2416544 -12.8228989 5.3962989 + -2.8011236 -12.4250250 5.1563983 3.6022720 -14.2793674 3.8845463 + 4.3416481 -13.9795418 4.4133749 3.9621890 -14.9859419 3.3484085 + 3.8362474 12.1579742 0.5728440 3.0465102 11.7045841 0.8677738 + 3.8869624 11.9661608 -0.3635679 -7.5358992 12.0021515 3.0349362 + -8.0330286 12.7513437 3.3632722 -7.9645486 11.7731104 2.2102959 + 4.7903252 15.7832098 6.7761126 5.2675352 15.1892166 7.3554869 + 5.3777242 16.5304184 6.6626496 -6.0319591 17.5073414 6.1459947 + -5.0945611 17.4256134 5.9703908 -6.3241534 18.2096291 5.5649223 + 11.5107946 -7.8070521 -17.5129452 11.7451248 -6.8843288 -17.4134312 + 12.3441353 -8.2498541 -17.6732597 2.4262362 18.7478943 2.2111747 + 1.7722981 18.2851658 2.7350807 2.5531850 19.5799866 2.6669610 + 19.9471169 -14.7100515 8.1747847 19.5247402 -14.0069389 7.6813641 + 19.3922234 -15.4752846 8.0239792 2.4126282 1.1982406 20.4117775 + 2.0543668 0.3531942 20.1401596 1.6544272 1.6891519 20.7285900 + 9.8544703 13.0793829 6.8397250 10.3224297 12.3180590 7.1826992 + 10.3388672 13.3228798 6.0508647 -3.4206407 -0.5428581 14.0717821 + -3.9570365 -1.3004409 13.8381596 -4.0392451 0.0801695 14.4530916 + -3.7865264 2.9805679 -19.1472435 -3.9317780 2.7109680 -18.2403545 + -2.9111247 3.3677340 -19.1447392 0.9099105 11.9605980 18.1316338 + 0.2969694 11.5742311 18.7571392 0.6166294 12.8668880 18.0375271 + -12.2773504 5.8596749 17.3281555 -11.5122890 5.3025484 17.4714108 + -12.4527121 5.7890911 16.3898067 -7.2671175 7.8473964 3.3103282 + -7.2009320 7.1214218 3.9306605 -8.0675926 7.6685715 2.8168781 + -0.9162490 -10.1739035 3.7699792 -0.9888570 -10.9262838 4.3572478 + -1.2778445 -10.4827194 2.9392486 13.4014301 -10.4859304 -6.8292704 + 13.0295277 -9.6355925 -7.0634627 12.8608656 -11.1212540 -7.2987237 + 8.7338514 -7.9033718 -17.6891365 8.7881403 -8.8143320 -17.4002838 + 9.6455069 -7.6270900 -17.7828579 -2.9094839 13.7850103 -15.4563627 + -2.7911279 13.9669485 -14.5240955 -2.0274441 13.5981321 -15.7777891 + 10.9462919 -0.0818683 0.0710957 11.4151125 -0.5764835 -0.6010606 + 10.4420357 0.5683271 -0.4179893 19.3702450 0.5865815 -2.1956682 + 18.9398575 -0.0418746 -1.6159780 19.6535721 1.2928892 -1.6150762 + -4.8804584 4.6760826 23.4493904 -4.7323685 5.6216817 23.4613647 + -4.9567013 4.4338841 24.3722973 11.8087549 -13.1312542 -4.4861050 + 11.2157965 -13.4846087 -3.8229523 12.3079119 -12.4564743 -4.0259461 + -2.1499276 -11.6330528 1.8232331 -2.0184391 -12.4412374 1.3274704 + -2.7480035 -11.1157885 1.2838128 3.7224796 -3.7265329 -4.2720704 + 4.3101530 -3.9734321 -3.5579884 3.6053734 -4.5322828 -4.7753448 + -3.8306289 8.3163633 5.3486700 -3.9016104 8.9604368 6.0531998 + -4.1775293 8.7654114 4.5777950 -16.5653248 11.0340481 -9.8232203 + -15.6492662 10.8576546 -10.0375891 -16.6767635 11.9683886 -9.9987831 + 8.9192572 -10.3067093 -14.4006987 8.6719513 -10.5718098 -15.2865839 + 9.8504028 -10.5195217 -14.3381634 12.0856218 -6.5025187 -20.2196293 + 11.3351192 -6.9340310 -19.8112469 12.8185692 -7.0979643 -20.0632191 + 0.1587463 -9.9264231 -11.2090712 1.0796278 -9.9397783 -11.4698982 + -0.0081134 -10.8074369 -10.8741026 -19.3845959 -3.4284086 -5.2065806 + -18.4895000 -3.5178399 -5.5337458 -19.9249496 -3.8656185 -5.8646822 + -7.3113179 10.1094170 5.0755849 -7.1566639 9.3123331 4.5686617 + -7.3675218 10.8036861 4.4190311 12.8280983 -2.4637344 17.0814247 + 12.0337677 -2.3875511 17.6100712 13.5439053 -2.3880014 17.7123890 + 0.3716079 15.3726025 14.4002171 0.9432190 14.7390547 13.9665012 + 0.7910259 15.5343599 15.2452936 11.6924915 17.3846512 6.1527519 + 11.9157810 17.5601788 5.2386603 11.7968273 18.2291088 6.5912013 + -7.1004920 9.8959589 20.1358147 -7.2769675 9.0519600 19.7201767 + -7.2193308 10.5374002 19.4353428 -8.5747852 8.2596312 17.6138725 + -9.5080528 8.1580582 17.4269848 -8.4310474 9.2059622 17.6084900 + 11.0203619 -16.6630440 8.4433727 10.2760944 -16.2253971 8.0301380 + 10.8375750 -16.6118832 9.3815641 -12.1690264 15.9017210 8.5606518 + -12.5011883 15.2775803 7.9154010 -12.7686100 16.6457787 8.5048943 + -3.3026099 -17.7290154 7.7935019 -2.6723208 -17.0200787 7.9214816 + -4.0725665 -17.3003922 7.4197617 6.9046159 4.2095895 -18.7681408 + 6.0490255 3.8498092 -19.0021381 7.4004469 3.4573760 -18.4447861 + -14.6537790 -5.8428254 6.5001869 -14.1110954 -5.4561872 7.1873822 + -15.3114920 -6.3528738 6.9729400 0.4250114 -17.1290283 14.0500526 + 0.7658460 -16.3498173 13.6108580 0.8925348 -17.1572342 14.8848324 + 11.9161749 -11.4670753 2.2406647 10.9785566 -11.6407995 2.3238676 + 12.3134642 -11.9420357 2.9706004 5.7664328 -15.8467102 8.9346361 + 5.9903469 -15.0428476 8.4657011 6.0455065 -15.6840162 9.8356810 + -8.2341537 -19.3121395 -2.7001951 -7.5708790 -18.6601219 -2.4739859 + -8.8630209 -19.2740459 -1.9795655 1.4598162 -2.8229616 5.3937659 + 0.5426047 -2.8089869 5.6671882 1.4786860 -2.3006032 4.5918822 + 5.4968314 24.1650505 1.7046037 5.5483279 23.2530613 1.4185029 + 5.8173227 24.1516132 2.6064556 -0.9999112 3.2152286 6.4962206 + -1.1643749 2.3969889 6.9649076 -0.0528750 3.3401437 6.5574622 + 0.8492491 -7.3656845 3.7412355 1.0396459 -8.1586933 3.2401183 + 1.6503737 -6.8454342 3.6798310 -15.3875065 4.5196018 16.2554493 + -14.9394417 4.5225782 15.4095993 -16.3102627 4.3887229 16.0372257 + 0.5693532 8.3084574 16.3266315 0.5863817 7.5144296 16.8609161 + -0.0989824 8.8581553 16.7357655 11.5691576 -13.5958805 -13.5861864 + 11.8265991 -12.7012825 -13.8090057 10.6290712 -13.5390320 -13.4151964 + -11.0042362 1.2641091 -4.3491836 -11.1282520 0.3860299 -4.7095013 + -10.9653826 1.8346856 -5.1167545 -14.4010572 -8.6705265 -9.6551352 + -13.5748463 -9.0756712 -9.3915720 -14.5163784 -7.9425378 -9.0444269 + 0.3977900 8.5724802 -16.4417191 1.0800266 9.2287340 -16.5835514 + -0.3694275 9.0785265 -16.1742764 12.6101370 10.7409735 6.0006766 + 12.2218523 9.9927979 6.4542189 12.7735987 11.3819609 6.6925192 + -8.6439619 5.5588236 15.5304880 -8.0814562 6.1333041 15.0110731 + -8.2014561 4.7102380 15.5125380 -2.2061095 19.0302067 9.6629133 + -2.9228797 18.6786442 10.1910009 -2.1345999 18.4262409 8.9237633 + -12.5609465 12.2712078 -11.7431173 -11.7320919 11.8319674 -11.9336414 + -13.1220322 12.0577707 -12.4886780 -0.4056883 13.4578705 9.5217638 + 0.0858754 13.0527639 8.8072805 -0.0681843 13.0379286 10.3129473 + -3.0314653 -2.0567214 -9.5465879 -3.4433479 -2.7460904 -9.0256701 + -3.3846397 -1.2423974 -9.1882915 9.6138821 -14.2568207 7.9513359 + 10.0934010 -14.0895615 7.1399679 8.7111588 -14.4053049 7.6697774 + -8.5568056 14.8870983 10.4086924 -8.0921593 14.1294050 10.0533953 + -9.3571873 14.9436016 9.8867474 -11.3255234 6.7550955 3.9824336 + -12.1373491 6.2573442 4.0794663 -11.6103249 7.6660662 3.9099574 + 5.6549616 -20.1603718 7.0398264 5.2020698 -19.3884449 7.3793077 + 6.2632122 -20.4069309 7.7365847 -18.2110519 13.5865717 1.9803009 + -18.5166836 14.1626415 1.2796118 -17.9514656 14.1817474 2.6835876 + 9.4177828 -4.1297593 -9.3113899 9.8770123 -3.5816300 -8.6750765 + 10.0866594 -4.7335510 -9.6343012 8.8959360 -8.4084558 16.6803379 + 8.5526485 -8.3391066 17.5711670 8.6366329 -7.5888939 16.2592545 + -3.7154369 -0.1607094 -5.1095400 -3.4721653 0.5507525 -4.5171947 + -3.1404777 -0.8850789 -4.8626747 4.4896026 -15.6807604 13.9210358 + 3.6381028 -15.5543327 14.3395996 4.8519955 -14.7981730 13.8439474 + 5.8662338 21.5594540 -6.9524770 5.7709599 22.4275608 -6.5606279 + 6.8121691 21.4303761 -7.0215926 -17.0348778 6.5458498 13.9531078 + -17.4606304 5.8118515 14.3960676 -16.4505062 6.1348038 13.3160973 + 11.7085514 -1.5310482 -2.4238315 12.5674715 -1.8200856 -2.1157010 + 11.1922960 -2.3349309 -2.4828668 5.2157860 -6.9017334 17.7381821 + 5.5374079 -6.1440649 17.2495804 5.9646978 -7.1834321 18.2635460 + 15.2093735 -7.7256761 13.9335098 15.2667007 -7.3899894 14.8280821 + 14.9177637 -8.6316109 14.0358677 0.6180112 -9.1528158 -1.2879188 + -0.2074617 -8.7245960 -1.0610832 0.3996798 -10.0835352 -1.3361256 + 15.3072958 -6.1095548 2.8510716 14.9516106 -6.0459247 3.7374525 + 16.1430511 -5.6449409 2.8944404 -9.3867760 -21.1302719 -9.0988789 + -10.1453457 -20.6989307 -8.7054958 -8.8595133 -21.4151917 -8.3525238 + -15.1124020 1.6234995 7.0077486 -15.6555872 1.0113164 6.5113482 + -15.0595512 2.4013731 6.4524546 17.8200264 4.7694836 4.8234682 + 18.7486553 4.8800144 5.0275779 17.6551170 3.8359637 4.9560494 + -6.6237793 -24.3550243 -4.3942204 -7.2256331 -23.8315086 -3.8651330 + -7.1128740 -24.5464916 -5.1944447 -0.7503532 11.3061075 14.7201099 + -1.1481870 10.7606955 15.3986998 0.1918843 11.2179470 14.8638039 + 9.4804764 14.2572517 -1.2646085 8.6886921 14.3681202 -0.7382838 + 10.1749249 14.1055698 -0.6235420 -9.1747894 -6.9828382 5.3461103 + -8.9145584 -6.8973975 4.4289346 -10.1247301 -6.8654923 5.3374782 + -17.7438049 7.4480252 -14.9836931 -17.3594685 8.3175831 -15.0949850 + -18.1965866 7.4922857 -14.1415167 11.1166534 -1.9150465 12.0964098 + 10.5144453 -1.9636513 12.8388472 11.9115810 -1.5232073 12.4580507 + 0.5504767 10.2736797 9.0851831 0.7037463 9.4911966 8.5555973 + 0.3461616 9.9363565 9.9573641 -2.5542932 -9.4784689 17.1374454 + -1.7082902 -9.7502480 17.4933224 -2.4607298 -9.5834522 16.1906319 + -12.7745609 -10.4056034 2.1458592 -12.8314857 -10.4738436 3.0989254 + -11.8953686 -10.0643005 1.9822587 -10.3665648 13.2179041 -16.6675720 + -9.5675020 13.3143549 -17.1856728 -10.2761574 13.8623943 -15.9656534 + 18.9374447 -11.7078018 10.2503738 18.0453434 -11.4601784 10.4934168 + 19.0691490 -11.3130856 9.3883495 15.1242065 4.2718534 1.6427814 + 15.1792898 3.4896686 1.0937961 14.7716484 4.9470186 1.0630518 + 3.6737423 7.1689668 -16.6134815 4.6059079 7.0445323 -16.7918510 + 3.6345518 7.9710155 -16.0925064 3.1346140 23.5231075 -5.5451374 + 3.2725413 22.7855549 -4.9508119 4.0165739 23.7904320 -5.8038187 + 6.7098064 -10.0819941 -1.0161178 7.2656083 -10.1087713 -0.2372729 + 7.3001919 -9.8207130 -1.7228068 -4.6436601 3.6605451 -15.0905533 + -4.3789697 2.9746275 -15.7034874 -3.8246093 4.0895891 -14.8429470 + -18.9635658 7.8966198 5.0681949 -18.6160717 7.0780072 4.7141418 + -18.2637901 8.5344534 4.9277897 -6.8035970 -20.4163895 2.3504868 + -6.2721262 -19.6219082 2.2997973 -7.2282677 -20.4754734 1.4946855 + -10.9513330 13.9247665 -5.6143475 -11.3146868 14.5048370 -6.2834687 + -10.7652225 13.1092854 -6.0797343 8.3103409 -9.7794428 7.0043612 + 8.7039175 -10.5151548 6.5352578 9.0537367 -9.2338505 7.2611170 + -2.8303194 17.4671688 -16.9904919 -1.8917516 17.6207657 -17.0987968 + -2.9004998 16.5294247 -16.8117714 -1.9265836 -16.1086502 15.8005600 + -1.0569923 -15.7243643 15.6893530 -2.5212095 -15.3585587 15.8044176 + -20.8820744 1.2094527 -8.2455873 -19.9669838 1.3506758 -8.0029001 + -21.1144714 0.3787839 -7.8306022 -16.2068596 -9.6545048 11.3219604 + -15.9482231 -9.5884485 12.2411861 -17.0237446 -9.1586399 11.2667627 + -8.3525553 -13.9764128 6.0935431 -8.7235394 -14.3184824 5.2801609 + -9.0607185 -13.4631853 6.4825597 -1.3933569 -18.4428253 -2.7631269 + -0.6481651 -18.4021797 -2.1637363 -2.0661252 -17.9049129 -2.3456743 + -2.2583616 1.8461546 -21.8114567 -2.8745036 2.2835526 -22.3990650 + -2.7189884 1.7985650 -20.9737282 6.5307484 -2.8883319 -5.5983825 + 5.7016778 -3.3632824 -5.5409722 6.8452015 -3.0617867 -6.4856620 + -5.6346583 -1.6404097 19.5290756 -5.5372362 -0.8722364 20.0917931 + -6.5809727 -1.7561716 19.4435196 -11.3625307 2.9790580 -17.3109951 + -11.1461201 2.0748196 -17.5384846 -12.2581358 3.0978177 -17.6272526 + -7.4993992 -3.0425005 14.8389540 -8.3423376 -3.4094932 15.1054192 + -6.8886108 -3.3270946 15.5187883 -4.9197974 8.9569941 14.8813820 + -4.9838905 9.5577240 15.6238413 -4.4871984 9.4674711 14.1969090 + -15.2502699 -5.3252859 9.5154877 -14.8223009 -5.2234378 10.3656054 + -15.6914291 -4.4887676 9.3676777 -8.5300388 6.8816056 -3.3649478 + -8.1354342 6.5655432 -4.1777353 -9.4727669 6.7975464 -3.5078831 + 6.1929531 -6.3075876 -9.3155022 5.3251910 -6.7093744 -9.3577929 + 6.7747693 -7.0211315 -9.0536308 11.0668869 2.1038315 12.1334286 + 10.2349463 1.8526275 11.7321777 11.7290487 1.6353958 11.6251545 + -4.3431377 -2.2443783 0.4947200 -4.1099334 -2.8079340 1.2324549 + -4.6911340 -2.8447044 -0.1646274 -1.1560882 21.2090778 3.2480710 + -0.5809169 21.5015392 2.5410519 -1.2828555 20.2748241 3.0827498 + -5.3799529 -3.9696093 16.5077152 -4.5938849 -3.8016098 17.0274315 + -5.1131463 -4.6413717 15.8801956 -13.1956444 6.3439350 9.6716995 + -12.3289375 5.9439635 9.7429209 -13.0730000 7.0750713 9.0661993 + -5.2666850 17.8873577 8.6749125 -5.3158965 17.0614624 9.1562719 + -5.6686726 17.6951447 7.8277454 -6.0751061 -13.5917931 12.9287062 + -5.2575369 -13.0957203 12.8871975 -5.8029633 -14.4847469 13.1403761 + 4.3618617 17.5639172 12.7097311 4.6108479 18.4816017 12.8196926 + 3.4208691 17.5901833 12.5363083 16.9465828 0.3115649 -13.7774715 + 17.6773453 0.5954766 -13.2282810 16.2097530 0.8530325 -13.4944038 + 3.4956131 -11.6895151 -16.3520107 4.1421404 -11.9025288 -17.0249596 + 2.9782152 -10.9800215 -16.7329960 -8.9656487 18.9480648 13.9350281 + -9.5856047 19.6571369 14.1056252 -8.9744883 18.8459816 12.9833279 + 15.0960321 2.3001301 -13.5035162 15.1046534 3.0211987 -12.8740578 + 14.3180609 1.7916262 -13.2745686 -5.5440440 17.1621552 13.3770409 + -5.5006642 18.0867996 13.6207209 -4.6801090 16.8151016 13.5993080 + 18.4588299 0.2812426 -7.0623112 19.2862930 0.3046694 -6.5816994 + 17.8090801 0.0241292 -6.4081316 -4.4498010 -19.0074387 10.0987444 + -3.8364346 -18.6283092 9.4692402 -3.9035494 -19.5473175 10.6700335 + 2.4637520 0.7684793 9.8646717 1.9059746 1.5242051 9.6802950 + 2.3916428 0.2211207 9.0827312 -6.7597370 5.9756131 -14.4067163 + -7.3500748 6.4924989 -14.9549522 -6.4596763 5.2687182 -14.9781141 + -1.6024801 -17.3411751 10.4161739 -1.2419487 -16.9332600 9.6288662 + -1.1987945 -18.2086792 10.4427633 -10.9904537 11.5891228 9.8804970 + -10.9833345 11.8975019 10.7866335 -11.6936111 12.0870743 9.4635487 + -15.3555756 14.9675903 -9.1020670 -15.1291456 15.6211748 -9.7637224 + -15.9663134 14.3791332 -9.5458565 4.7683020 19.3174038 0.7204145 + 3.8894703 19.1762619 1.0725019 4.9162989 20.2582664 0.8158433 + -8.0990791 10.4119492 -14.8633223 -7.9048505 11.2693281 -14.4846296 + -8.5152330 10.6094351 -15.7023973 -9.9781513 6.3467989 -13.5413904 + -9.7702971 5.6219668 -14.1310062 -10.1442795 5.9283323 -12.6966906 + 11.9850006 -9.4893131 11.3237352 11.9982967 -10.2437401 11.9127131 + 12.8164511 -9.5389881 10.8520851 -14.3004036 -5.3179631 12.5049934 + -13.9497747 -6.1973448 12.6463385 -15.2426147 -5.4102306 12.6462641 + -6.0559959 15.7073689 0.6880735 -6.7590251 15.3223372 0.1648788 + -5.8687062 15.0501232 1.3582844 17.9410591 9.8983469 -7.3711762 + 17.6859112 9.9137592 -6.4487367 17.1979446 10.2880459 -7.8317704 + -6.3530073 0.5009589 -17.4060211 -6.7825232 0.9553260 -18.1307964 + -6.3839107 -0.4238099 -17.6511326 -12.0791788 10.4399986 -0.8869622 + -11.4880857 10.7214127 -1.5852795 -11.5608187 9.8253593 -0.3675839 + -2.5963352 16.3341331 -3.9560413 -3.3129034 15.7180386 -3.8037586 + -1.8241268 15.7800350 -4.0696263 3.3895626 -14.5256424 -16.9410210 + 3.1677396 -13.8939190 -16.2569504 4.2547717 -14.8522024 -16.6940308 + 5.1507440 1.6082124 14.5089693 4.4899864 2.3007357 14.5024290 + 4.6998453 0.8504631 14.8814449 -11.8556881 6.4221292 20.0080318 + -11.7978849 5.5144181 20.3062782 -12.1594296 6.3578525 19.1025810 + -5.5630155 8.3474913 -13.5493069 -5.6996231 7.4048357 -13.6440229 + -6.4169331 8.6876011 -13.2821331 14.8056622 -10.4467402 14.4040241 + 15.4795694 -10.7176466 15.0274734 14.0145559 -10.9008808 14.6940918 + 3.5421572 -12.5930824 -6.4576111 4.2208195 -12.7971725 -7.1010365 + 3.9490793 -12.7821999 -5.6121049 5.5931487 -2.5478880 11.6108589 + 6.3775148 -2.4925950 11.0650167 5.4624591 -3.4861505 11.7480288 + 9.3574238 20.9142647 3.9603508 8.7980843 20.2384224 3.5774560 + 9.2237740 20.8292770 4.9043565 0.2571740 9.2313499 -19.7113171 + 0.3119131 8.3427896 -20.0630207 0.8267708 9.2199945 -18.9421215 + -15.5139189 1.6968476 13.1626139 -15.1084824 2.5287192 13.4072409 + -16.4395123 1.9081906 13.0407915 17.3392277 -14.7606430 6.3237948 + 16.5735607 -14.5426121 6.8552518 17.4301453 -15.7093668 6.4126120 + -10.1300106 -4.6022892 2.1016130 -10.7651958 -4.0008159 2.4902020 + -9.8263912 -4.1531549 1.3127375 -11.4324408 5.8955297 -3.6243689 + -11.5646763 5.0338044 -3.2291794 -11.6079197 5.7613792 -4.5557351 + -6.0474429 -2.1996181 -4.4765182 -5.2558928 -1.9045029 -4.9266152 + -6.5758286 -2.6064978 -5.1631689 9.2833662 -5.4731302 21.2943230 + 9.2773447 -5.0022750 20.4609623 8.5194216 -5.1384730 21.7640305 + 14.7374430 -5.3249102 7.6585774 14.5268717 -4.9767804 8.5250053 + 15.6744099 -5.1588178 7.5549521 10.6962976 17.6735516 0.9698970 + 9.7413473 17.6081352 0.9650469 10.9488516 17.5593204 0.0537096 + -18.6572018 -16.3050137 6.8891363 -17.9736443 -16.2991714 7.5591707 + -18.2384663 -16.6977558 6.1232085 -11.3775444 8.5392170 -4.7227011 + -11.7858219 7.6981201 -4.5175228 -11.2523174 8.5195599 -5.6714706 + 13.8113918 -14.3251123 -12.2182198 12.9128571 -14.1545267 -12.5006514 + 14.2958555 -14.4644442 -13.0319233 -13.8322706 7.7772069 -17.0708752 + -13.2924175 7.3008041 -17.7016125 -14.0986319 7.1138244 -16.4343166 + -2.1445689 -8.3017120 -0.9840410 -2.3026698 -7.3656344 -0.8615838 + -2.3862684 -8.4682627 -1.8951250 -19.9129581 6.1351557 2.1636333 + -20.4267483 6.8499794 1.7877609 -20.3701878 5.9121466 2.9744601 + 2.5569532 -6.2628655 20.1959763 1.8747392 -5.9058337 19.6273422 + 2.7248933 -7.1385550 19.8478451 -10.9617386 0.3915312 -18.3568573 + -11.3014746 0.7321360 -19.1843834 -10.2299347 -0.1704491 -18.6115589 + -1.9048518 14.3786831 -13.0686512 -0.9756994 14.6036243 -13.0205975 + -2.1372824 14.1285381 -12.1744280 -7.4626608 13.3620186 -14.6393032 + -7.3288832 14.2585230 -14.3317089 -8.2963896 13.3917208 -15.1086063 + -2.4755652 -12.2306833 9.6222782 -2.8811646 -13.0689373 9.4007998 + -1.9474146 -12.0100317 8.8550739 -4.9855118 10.9859495 6.6218276 + -5.7482157 10.4850397 6.3326845 -5.1956491 11.8926449 6.3982730 + 9.2919407 -16.5909786 -16.2686825 9.2943125 -17.5280991 -16.0736618 + 8.9405432 -16.1825752 -15.4775066 15.8358421 -2.0780537 -14.5417261 + 16.3278580 -1.3219305 -14.2216797 15.4368391 -1.7762167 -15.3577671 + -13.9960089 2.6246662 -12.2573156 -14.1886587 1.6875070 -12.2864790 + -13.5536146 2.8041759 -13.0869503 -14.0712910 9.9863672 -10.4084654 + -13.7409658 10.4966221 -11.1478958 -13.5398903 9.1902256 -10.4104128 + -9.7793055 14.8136759 -14.6632013 -9.2068453 15.5808229 -14.6606073 + -10.5235033 15.0683174 -14.1177111 -0.6204479 22.0996895 -2.8685834 + -0.8329142 21.5684414 -3.6359580 0.3224211 21.9840775 -2.7508411 + 17.7995415 -9.6319427 13.1898584 17.3932800 -10.2555227 12.5879192 + 17.1619129 -8.9220734 13.2656860 2.9196284 -18.3712997 -1.4026901 + 2.0600028 -18.1526260 -1.7624924 2.8199449 -18.2565937 -0.4576306 + -12.5343494 1.1883395 -7.7241926 -11.7617474 1.7531755 -7.7408872 + -12.5237846 0.7937745 -6.8521609 -5.3248119 12.6508684 -16.2107830 + -5.8554163 12.6923637 -15.4151897 -4.4442749 12.8934326 -15.9243422 + -2.7903354 2.0819390 -9.2758236 -3.3904653 2.4185853 -8.6104326 + -3.1210160 1.2061536 -9.4755297 1.1060610 -12.0963221 18.9514713 + 0.6089328 -11.3006134 19.1410599 1.8506984 -11.7951746 18.4308395 + 2.4510942 -14.0536337 -12.6324854 2.4170256 -13.7434826 -11.7275667 + 1.6369691 -13.7379971 -13.0246658 11.1903419 -14.7647648 2.7198284 + 10.5201750 -15.2284651 3.2219150 11.9492397 -15.3478498 2.7376556 + 4.2765651 7.6836739 19.7445202 4.3029389 6.8968129 19.2001057 + 4.0020881 8.3792601 19.1469803 20.9972153 -0.9938033 12.8240747 + 21.5921936 -0.4644787 13.3551569 20.4517193 -0.3543062 12.3661337 + -15.0160942 16.3949146 -11.3846302 -15.8266821 16.8213081 -11.6627827 + -14.8621006 15.7192497 -12.0449276 -15.2926483 -4.6811876 -13.6589260 + -15.9766073 -5.1574645 -13.1881914 -15.7694349 -4.0679102 -14.2182093 + -17.5836926 0.0808534 18.9709282 -17.8324795 -0.4572041 18.2193756 + -16.6265411 0.0743774 18.9637680 -19.8416214 -13.8093424 7.3963480 + -20.7926197 -13.9032202 7.3413992 -19.5045490 -14.6919785 7.2428317 + -1.1289535 21.0050144 -5.3706131 -1.3041582 21.1860676 -6.2940602 + -0.7648003 20.1198063 -5.3649931 -1.5711048 11.0433760 -17.7263756 + -1.8413200 10.5505667 -16.9515495 -0.6154931 11.0645943 -17.6755028 + -15.0188990 0.1918420 17.6168327 -15.0633469 1.1479720 17.6083622 + -14.7950020 -0.0455019 16.7169609 1.9266968 13.0430880 -7.0129433 + 1.2435888 12.5764112 -7.4944077 1.8205106 13.9581299 -7.2730489 + -5.1574917 2.7207420 -21.6871185 -4.9623079 2.5799816 -20.7606621 + -4.7727308 3.5743573 -21.8859463 -2.6466408 15.9803123 9.6079397 + -1.7336702 16.2489738 9.7105885 -2.8818791 15.6025639 10.4554071 + -21.3855095 0.5217201 1.2125753 -20.4983788 0.6830658 1.5338218 + -21.6147594 1.3173865 0.7323768 -5.0261097 14.4162550 -19.9433804 + -5.4742751 13.5933971 -19.7477150 -4.3148050 14.4594250 -19.3043079 + 6.3368411 -2.1659822 -22.4777985 7.1758208 -1.8219970 -22.1711750 + 6.2454348 -3.0076468 -22.0311699 14.6886587 11.3047266 -12.8887939 + 14.5396919 10.4508410 -12.4826908 15.3848581 11.1483192 -13.5268192 + -9.4893389 -7.6195459 -2.6553409 -9.1001539 -7.5830436 -1.7815934 + -8.9053392 -7.0916948 -3.1999056 -1.2213217 21.3073635 7.6368966 + -1.3300409 20.5970078 8.2692003 -1.7003627 22.0430222 8.0184174 + 3.3326993 18.4624023 9.2720222 2.9391356 18.1267853 10.0774422 + 3.4346390 17.6903362 8.7154684 -17.4739780 5.4959388 3.3287005 + -16.7751656 5.6550694 2.6942160 -18.2612667 5.8442764 2.9102888 + -15.2611713 9.3495493 8.4049683 -15.7688532 8.5493717 8.5399017 + -14.5868492 9.1015749 7.7724891 6.7355990 -7.0696683 23.6770954 + 6.2785501 -6.8571525 22.8633537 6.3656759 -7.9101982 23.9470921 + -10.2519131 10.6182680 -16.6602345 -9.8968849 10.4561081 -17.5342426 + -10.4154081 11.5611687 -16.6392803 -4.8506088 -1.9097232 -21.2076569 + -5.7731943 -1.6551914 -21.1908855 -4.4054790 -1.2303813 -20.7011147 + 7.8106771 -7.7439742 12.1613617 7.9271722 -8.6797142 11.9968882 + 8.6425247 -7.4623241 12.5420647 2.9485807 8.7714596 7.2590575 + 3.7088830 9.0495691 6.7483449 2.1975429 8.9801073 6.7035036 + 19.1469994 14.7363014 -8.8502607 18.3172474 15.1894445 -8.7005816 + 19.3961048 14.9809008 -9.7415237 -4.6093955 5.4053931 19.2898636 + -5.4351182 5.3417401 18.8099022 -4.6972003 4.7724409 20.0025291 + -10.2282543 -7.5795832 -17.1075401 -10.2300529 -6.8079267 -16.5411720 + -11.1467056 -7.8452711 -17.1532574 9.7858629 8.7483177 -5.0650020 + 10.6154652 8.7704792 -4.5880322 9.2715187 9.4600868 -4.6841259 + 12.7410088 -2.3795085 14.3264580 12.2924461 -2.1205738 15.1314278 + 12.6487322 -3.3317807 14.2965488 5.4617019 -0.3776888 -3.9732661 + 4.5093269 -0.4612676 -3.9260597 5.7518663 -1.1830003 -4.4016466 + 1.7275219 -15.0905743 12.1902924 1.1922253 -14.4586477 11.7103367 + 2.0269294 -14.6124296 12.9635744 8.8114471 12.5999355 14.4520016 + 9.3804159 11.9994879 14.9336329 8.7229900 13.3596163 15.0275812 + 8.2719278 6.9275303 3.8588977 8.5943127 6.2010350 4.3922868 + 8.9446411 7.0497975 3.1890173 -7.5732441 -6.4180675 -8.0887880 + -6.6278563 -6.4119763 -8.2385759 -7.6907067 -6.9794030 -7.3224092 + -1.0310153 -21.1833630 -8.5118885 -1.5249403 -20.5956268 -7.9401927 + -1.2396172 -22.0607586 -8.1911173 -1.1032087 -1.6699514 -15.8390617 + -2.0214894 -1.5065254 -16.0541992 -0.6705886 -0.8278571 -15.9803019 + -9.4278898 -19.8452015 7.6707807 -8.8396883 -20.2352657 7.0241747 + -8.9508581 -19.9096127 8.4981403 -6.1372037 -5.6522574 -12.7525539 + -6.4924717 -6.5389061 -12.6903381 -5.2490139 -5.7731338 -13.0883217 + -16.9673901 15.3743782 7.7470098 -16.2812328 15.1760683 8.3842640 + -16.4976978 15.5124693 6.9244823 6.6543970 -11.4605217 9.2539997 + 6.8518043 -11.3265753 10.1809959 7.0814123 -10.7279491 8.8098965 + 8.5956001 8.8396330 13.6852770 8.5265360 7.8886456 13.7694435 + 8.0729904 9.0501776 12.9114666 6.8350453 20.3429222 -4.0174298 + 7.3010201 19.5642357 -3.7128878 7.3509169 20.6553402 -4.7607355 + -13.1467209 2.0802286 -0.6018444 -14.0362482 2.2798536 -0.3100864 + -12.8031931 1.4866272 0.0658816 -13.6088152 -16.2209396 11.0957088 + -13.0727348 -15.4449100 10.9325256 -12.9840412 -16.8882847 11.3795033 + 6.5246172 6.7713418 -0.3975413 5.7038941 6.8572135 0.0875065 + 7.1151705 7.3998213 0.0177809 10.5256691 -2.8661325 9.7716093 + 9.6444798 -2.5663652 9.5482788 10.6724472 -2.5384173 10.6589031 + -5.4084835 11.0673151 12.4116249 -4.4754710 10.8588181 12.4590445 + -5.4843502 11.9232969 12.8332558 -4.2760720 -2.3623693 -13.6591358 + -3.6044168 -2.9958489 -13.9117508 -3.9788728 -2.0218225 -12.8153744 + -20.6133003 -4.4475417 8.8289194 -20.3440304 -3.5675807 9.0923452 + -19.8268776 -4.9818730 8.9396486 -5.8742342 -6.8970170 17.1647816 + -6.5332627 -7.0183334 16.4812641 -5.9418063 -5.9719253 17.4011517 + -14.4919453 0.0019398 -2.5830171 -15.1808662 -0.3838431 -3.1241190 + -14.1809454 0.7519289 -3.0899954 20.4461346 5.0696883 8.3749037 + 20.7472878 5.5988626 9.1134920 20.0735302 5.7036977 7.7621799 + 0.0063968 -17.6308365 -0.4429697 -0.7775656 -17.8594055 0.0564206 + 0.7153916 -17.6555634 0.1996397 -14.1323776 -10.3278341 4.7556119 + -14.0364180 -9.9534388 5.6313128 -14.8946619 -10.9028044 4.8231616 + -13.7511702 0.4226727 -17.2817554 -14.2173080 -0.1367417 -17.9030457 + -12.8510952 0.4435120 -17.6068153 -11.5087147 -13.3380585 2.3504663 + -11.6959839 -12.6671658 1.6939112 -12.1124201 -14.0513153 2.1430151 + -8.4119339 -6.9913678 -10.9192305 -8.5376682 -7.8407555 -10.4961901 + -8.0698376 -6.4268475 -10.2260361 -3.0132976 -4.0571270 -20.3295135 + -3.4835188 -4.6399302 -19.7333069 -3.6649976 -3.4074070 -20.5929203 + 0.8657575 -4.2294421 13.5261412 1.6338445 -4.7906804 13.4199076 + 0.3231834 -4.6852937 14.1696043 -16.3487206 4.6572695 -13.6961956 + -16.6924877 4.1504035 -12.9605713 -17.1216145 5.0614300 -14.0905561 + 3.2367492 14.5098991 1.8522533 3.6596942 13.8893795 1.2587014 + 3.7941413 14.5149488 2.6304052 4.0565667 -7.7698627 -10.1257401 + 4.0482488 -8.5278320 -10.7102432 3.5320065 -8.0422440 -9.3728275 + 0.6829196 -9.2770081 15.3418455 1.4502754 -8.7465696 15.1272945 + 0.3315517 -9.5444250 14.4925747 -13.9611511 -4.0672674 -7.3667703 + -13.1840677 -3.5426846 -7.5596066 -14.6462812 -3.4233851 -7.1872053 + -1.6117350 1.2241640 -12.7724304 -1.8090495 0.7722740 -13.5928535 + -2.1527262 0.7810553 -12.1188135 19.3147068 9.1713324 12.0837746 + 20.0518589 9.2569246 12.6883516 18.9242039 10.0448446 12.0570364 + 8.4447365 -16.8005733 12.1379776 7.9280725 -17.6002331 12.0388060 + 9.2545290 -16.9777279 11.6593504 -12.1715517 -6.6707735 16.3787479 + -12.1833525 -5.7637091 16.0732536 -11.2663450 -6.9546638 16.2513218 + -12.1370659 5.4707417 -6.1772261 -12.5599880 4.8067570 -6.7217374 + -12.1679735 6.2686167 -6.7051206 12.7538290 14.8098679 -2.8563862 + 12.3084812 13.9811649 -2.6799002 12.1632261 15.4779978 -2.5085032 + -7.1999373 3.0037222 8.1225033 -7.9608345 2.8612621 8.6855059 + -6.7381334 3.7389712 8.5254641 -16.7579823 -2.9497445 13.8598518 + -17.6875210 -2.8090146 14.0398092 -16.5465641 -3.7647047 14.3152351 + 15.8569927 -13.3142481 4.4094429 15.9066916 -13.5722466 3.4890089 + 16.3088093 -14.0151424 4.8793793 12.7420855 19.2913399 -1.0587651 + 12.3791590 18.4383087 -1.2972013 13.6894369 19.1546574 -1.0502212 + -10.7012024 -17.0484848 0.9254921 -10.1201143 -16.3255768 1.1620754 + -11.4525099 -16.9532909 1.5109035 18.9184227 -6.1942959 -13.8368654 + 18.3329372 -6.4027696 -13.1088705 19.0580158 -5.2497616 -13.7690353 + 9.5642309 -13.7263527 10.7702751 10.1318302 -12.9671459 10.9031944 + 9.7332287 -13.9966574 9.8677197 6.3828263 6.9303703 -17.0708904 + 6.1000319 7.8414483 -16.9921780 7.0431886 6.9435616 -17.7636948 + 3.1453772 21.7366009 2.7736874 4.0027785 21.9094620 3.1625493 + 2.7243483 22.5951614 2.7307899 0.3668775 0.9293279 -22.5368786 + 0.3191402 0.2554667 -23.2150116 -0.5454368 1.1658051 -22.3695679 + 20.5717087 -8.7573299 12.4353781 19.6264763 -8.8970776 12.4922915 + 20.9278889 -9.2160721 13.1962481 8.4524536 -7.7138243 2.6440661 + 8.8886938 -7.5536337 3.4808850 7.9066157 -6.9396443 2.5064492 + -12.0707226 -0.5086991 1.9410152 -12.3822384 -0.8398265 1.0986710 + -11.2573729 -0.9874763 2.1006000 -8.4084120 -22.0152817 -3.5104287 + -9.3555441 -22.1139278 -3.4132569 -8.2412796 -21.0950947 -3.3065765 + -3.0983088 5.6301360 12.7716827 -2.5241430 6.0659862 13.4014454 + -3.3251469 6.3137970 12.1412992 2.1764443 5.1987419 -17.7269402 + 1.5074382 5.6217566 -18.2651978 2.6388514 5.9235368 -17.3061256 + -12.8797684 14.8728094 11.5531349 -12.1590586 15.4690742 11.3499689 + -12.4779272 14.1821985 12.0802145 0.1274435 -12.7859745 11.0796223 + 0.8408738 -13.0773869 10.5118828 -0.6655747 -12.9409323 10.5664530 + 0.2991237 19.2910976 -11.8354559 -0.3624786 19.9170647 -12.1298666 + 0.9799728 19.8323936 -11.4358644 6.5664749 -4.3803010 9.7248535 + 6.2345066 -5.1006117 9.1889610 6.9109731 -3.7500558 9.0921268 + -8.2851124 7.3525901 -22.2255745 -7.9310994 8.2123146 -21.9980221 + -8.6572723 7.4704924 -23.0995464 -5.2382655 -17.8109303 3.0964899 + -5.8195553 -17.1762753 3.5154731 -4.3909211 -17.3677597 3.0536036 + -13.5096493 -11.3501205 10.3964396 -14.3461714 -11.6984186 10.7049036 + -13.6846848 -10.4252024 10.2228889 -11.9076786 -19.8033676 6.0674801 + -11.6680746 -18.9368401 5.7389193 -11.4533472 -19.8752823 6.9069099 + -7.0832577 -19.8729553 9.7178869 -6.3468580 -19.2808838 9.8708515 + -7.3695974 -20.1304359 10.5942125 7.1185327 22.8852978 5.9274702 + 7.8016896 23.3392143 6.4209170 6.7642946 22.2438564 6.5433431 + -10.9389458 -15.0487556 -8.0342731 -11.1697893 -14.1660671 -7.7447824 + -10.6250935 -14.9323025 -8.9310265 -15.8901424 -0.0578652 0.2154808 + -16.7240047 0.0136336 -0.2490544 -15.2339487 -0.1206897 -0.4785612 + 0.8106247 7.6183481 -5.7325335 -0.0443531 7.8123126 -6.1167507 + 1.2178437 8.4757748 -5.6091461 15.2488165 5.1302013 16.2208862 + 16.1374454 5.1416430 16.5764694 15.1385489 4.2424774 15.8802710 + 12.8900080 -12.4005260 15.1153507 12.3567839 -12.4577408 15.9082127 + 13.7350473 -12.7726593 15.3676558 -1.6333451 10.0364103 -15.2885189 + -1.4112607 10.8910522 -14.9190617 -1.9304411 9.5211477 -14.5385389 + 21.1611137 -6.1466084 2.0799122 20.4672718 -6.4224343 1.4809681 + 21.5104942 -6.9641995 2.4344678 -15.0753193 -7.9056859 4.4035597 + -14.7273903 -8.7718916 4.6153712 -15.0245266 -7.4193892 5.2264619 + 0.6904520 4.2708650 -15.3754654 1.2094458 3.5233626 -15.0786200 + 1.1887020 4.6324277 -16.1084404 -0.1086566 -13.9850826 16.8816566 + 0.3312179 -13.3479881 17.4445534 -1.0111600 -13.6713114 16.8244991 + 11.7221317 8.6428146 11.2709284 11.8261347 8.0207806 11.9909906 + 11.3919106 9.4386978 11.6877680 -10.4831629 -4.9562268 -11.6000290 + -10.0439568 -5.7977157 -11.4766350 -9.9082031 -4.4703908 -12.1913128 + 7.4593725 -7.8323836 19.1320591 7.8513684 -8.5480442 19.6324596 + 8.0126066 -7.0750952 19.3235760 9.1322470 10.1764565 5.2499585 + 8.6191177 10.0510473 4.4517088 9.9816017 9.7813129 5.0532613 + 4.8239083 17.9934216 -7.2500629 4.6137519 18.6003571 -7.9597778 + 4.1681414 18.1756477 -6.5770135 -16.9862709 -17.9889355 -2.8684814 + -16.2418575 -18.5283451 -2.6018043 -16.7976894 -17.1238461 -2.5047643 + 4.3238831 15.6073437 -12.7432261 5.2084336 15.9676180 -12.8065071 + 4.0989175 15.6861649 -11.8161831 -4.8640242 -4.8622932 -3.8341227 + -4.8860774 -3.9156210 -3.9739707 -3.9446914 -5.1006761 -3.9534245 + -20.2197838 -9.3503857 8.1750393 -21.0981636 -8.9828806 8.2731161 + -20.2583790 -9.8485823 7.3586192 2.7659202 0.8313585 2.6179090 + 3.1423542 0.2772772 3.3016658 3.3248603 0.6834700 1.8550546 + 6.1947041 15.3044510 11.5457687 5.6074824 16.0446968 11.6988678 + 5.9641738 14.9928827 10.6705475 -6.0618730 11.6999121 -18.5957966 + -5.6404991 11.9989967 -17.7900505 -5.5286260 10.9591856 -18.8842449 + -8.7302837 2.0611019 10.0807638 -8.7818489 2.7613668 10.7313042 + -8.0359955 1.4860122 10.4024277 4.8451390 -18.5612679 -6.3461647 + 4.2404437 -18.2213821 -5.6865792 4.7656980 -19.5126076 -6.2763510 + -7.9558001 13.0809317 -5.1102710 -8.6447868 13.0039520 -4.4502683 + -7.4347486 13.8319235 -4.8261089 -8.1847248 -10.8587713 6.7856631 + -8.9959621 -10.4243145 6.5222754 -7.8179073 -10.2907743 7.4631996 + 0.2143486 -6.7478409 -12.4541645 1.0793693 -6.3758469 -12.6261864 + 0.3748530 -7.4415450 -11.8144417 -1.6261532 6.8177605 -11.9708462 + -1.7929332 7.4715037 -12.6498423 -1.1120594 7.2833657 -11.3111868 + -8.3025198 -0.4961555 22.0125523 -8.1960535 0.4537544 21.9618759 + -9.2327623 -0.6424056 21.8408241 -12.4028597 1.3547462 10.3783665 + -13.1183710 0.7248390 10.4649248 -12.1185379 1.2706798 9.4682417 + -16.2023582 -15.8669167 9.1635723 -16.7476521 -16.2316971 9.8605814 + -15.3638992 -16.3198166 9.2535810 7.1341720 -14.5413551 2.6036963 + 6.8124838 -14.1220779 3.4017909 7.1998401 -15.4690342 2.8302593 + -7.7873845 -7.8240442 7.3875628 -8.3297958 -7.6101980 6.6284242 + -8.4140291 -8.0702705 8.0679455 2.9200420 9.5809412 -17.9711056 + 3.0468252 8.6458673 -18.1317120 3.3436477 10.0111361 -18.7138863 + 9.2244387 -7.1281786 5.5169573 8.3959112 -6.7225418 5.7723637 + 9.4377747 -7.7146211 6.2427702 13.5634594 12.9082718 12.7146339 + 14.3054581 12.7004375 13.2825022 13.9622850 13.1564589 11.8806238 + 0.5932273 9.6142168 12.0666866 0.9021263 9.2234745 12.8840809 + 0.2789853 8.8721027 11.5502071 -7.2772431 2.7470858 -16.0171108 + -6.5158720 2.6064715 -15.4542837 -7.4571409 1.8866929 -16.3960476 + -19.1813984 8.0656834 -2.8685606 -19.4473381 8.9799166 -2.9669712 + -18.3689346 7.9972739 -3.3700109 -0.4504632 2.1228251 9.2199154 + -0.9345964 1.3097185 9.0760250 -0.9667203 2.5967917 9.8718863 + 9.0229855 7.8571863 -17.7610607 8.4216557 8.5139666 -17.4099560 + 9.6037483 7.6486650 -17.0293045 1.2567009 -6.3619161 -20.2904835 + 0.5831981 -5.6837077 -20.2389126 2.0134439 -5.9192472 -20.6746922 + -8.5116987 -3.3875442 -0.2732317 -8.0160608 -2.6370163 0.0543092 + -7.8494053 -3.9640777 -0.6542941 -8.7985706 1.3143064 -2.1502659 + -9.7070923 1.1640624 -2.4115093 -8.2863121 0.7505955 -2.7299666 + -14.1726675 11.7253675 -13.9169512 -14.4551716 10.8359156 -13.7041178 + -14.3374071 11.8107471 -14.8559942 11.7437668 7.7812190 16.0882187 + 11.0021935 7.4998670 16.6240749 12.4550877 7.9144340 16.7147236 + 10.7901096 -13.0002346 16.8794441 10.3211174 -12.3066311 16.4155579 + 10.4967499 -12.9220057 17.7872181 -3.2685020 18.4039631 -5.7250619 + -2.9695415 17.8679829 -4.9905005 -3.9929585 18.9174385 -5.3676577 + -3.7494128 7.5957713 -17.8625622 -4.4787812 7.3106008 -18.4129543 + -4.1477838 8.1884851 -17.2252064 -5.9939070 -12.6546392 5.9779744 + -6.8257456 -13.1258917 6.0248513 -6.2365475 -11.7320366 6.0564795 + -13.0848436 6.6389308 -13.3718939 -12.1963596 6.6190076 -13.7274656 + -13.4594059 5.7924523 -13.6156349 -12.4988089 -3.5428913 10.4255552 + -12.1213923 -3.2399895 9.5996981 -13.0378180 -2.8108766 10.7253141 + -12.6206675 -3.9201193 -1.4996910 -12.3834352 -4.8460875 -1.4493353 + -13.5413170 -3.9226449 -1.7616638 -8.3926325 7.7856960 -15.6821480 + -9.1720476 7.5520978 -15.1779881 -8.1382113 8.6448545 -15.3454742 + 1.2706344 11.2389469 -17.0256062 1.8245442 10.5340948 -17.3611641 + 1.5861412 12.0246840 -17.4720421 -5.7386231 -13.4969654 -3.1030846 + -6.2329764 -14.3112411 -3.0092647 -5.2931447 -13.5829782 -3.9459264 + 19.1589222 -1.2048563 -11.0654716 19.0114956 -0.2804277 -11.2652941 + 18.2813644 -1.5857035 -11.0325956 13.4592342 -9.4795551 17.6031017 + 13.6985435 -10.3683910 17.3405514 13.0500059 -9.1018362 16.8245831 + -17.2818298 -2.7618494 4.2116132 -17.9845753 -2.3914135 3.6776106 + -17.7189674 -3.0603652 5.0091290 19.3905010 -10.1621361 6.4672456 + 19.6370201 -11.0093164 6.0961051 18.4736767 -10.0485516 6.2167192 + 16.2481918 -3.1152971 18.9517078 15.9507656 -2.4460492 19.5680485 + 15.6056614 -3.8199141 19.0347729 3.8802752 -2.9077878 6.4045200 + 3.0324423 -2.8265705 5.9676962 3.7037058 -2.6734245 7.3156343 + -18.4068890 -8.2335739 11.5769997 -18.9124203 -7.4704175 11.2972450 + -18.9425106 -8.9835701 11.3184490 -10.8156910 10.3806763 -12.6213503 + -9.9438286 10.1613483 -12.9499559 -11.4157639 10.0106945 -13.2688522 + -18.3156662 4.9245868 -0.2229739 -19.0914879 5.3102837 0.1839309 + -17.6338634 5.5876999 -0.1149987 12.0473442 10.2502918 0.3082895 + 12.6307001 9.5306578 0.0673406 12.2383556 10.4145164 1.2317486 + 15.6491213 17.9436569 4.4314399 15.8723955 18.6717510 5.0113192 + 14.7790613 18.1617336 4.0972695 -0.3371227 3.1048255 19.0497971 + -1.2150669 2.9341829 19.3908634 -0.0311110 2.2527666 18.7390156 + 20.2192192 8.4348860 1.6905664 21.0786133 8.4542732 1.2695007 + 20.1276875 9.3008089 2.0880988 -8.3723087 13.2893496 -18.3233490 + -7.5767264 12.7698669 -18.2075100 -8.5666351 13.2245655 -19.2583733 + -10.1746693 -2.4040356 -16.5499630 -10.2011728 -1.8489879 -17.3293533 + -9.4583721 -2.0462911 -16.0253963 9.5637093 7.0089793 17.5500317 + 9.5971451 7.1536226 18.4956493 9.1945086 7.8184056 17.1968288 + 17.0363331 2.8115461 13.3555527 16.8435745 3.4811134 12.6992331 + 16.1982594 2.6540978 13.7903786 -5.4379654 9.4356623 -16.1360416 + -5.4313078 9.0245209 -15.2716637 -4.9894657 10.2714138 -16.0072041 + 8.5564613 -0.8726341 9.1535177 8.7358379 -0.1038010 8.6122675 + 8.3845043 -0.5169292 10.0253763 -14.7860479 14.2859097 -13.0312548 + -15.4318972 14.3669996 -13.7330627 -14.4961004 13.3748121 -13.0766830 + -9.9794378 0.7896714 -21.3560715 -9.3710413 1.1820650 -21.9822617 + -10.7979288 1.2689639 -21.4848423 -10.4799871 8.9976311 -10.2584772 + -10.3360710 9.6972609 -10.8956890 -10.2492104 9.3895664 -9.4162416 + -7.0657048 9.3758850 -20.2744637 -7.2715702 8.6090412 -19.7398605 + -6.1098480 9.3832798 -20.3246193 -7.9085450 7.4961681 -18.5397186 + -7.8752718 7.5840511 -17.5871429 -7.8624158 6.5527692 -18.6949692 + 0.7297606 12.2333441 11.8689861 1.1394813 12.4957581 12.6933041 + 0.6307933 11.2840958 11.9422398 -15.8401413 -0.4761590 5.0332246 + -15.4033718 -0.1347745 4.2528911 -16.3299637 -1.2366205 4.7201676 + -6.6180935 7.8901815 -7.6641088 -6.5891218 8.8171005 -7.4270139 + -6.7110696 7.8894339 -8.6167822 7.7000213 5.4399781 -2.4814558 + 8.0158653 4.8075438 -1.8360871 7.2207990 6.0889168 -1.9662308 + 15.7248087 -1.8090860 7.4186230 15.6571655 -2.5115514 6.7719402 + 16.1713314 -2.2114923 8.1635523 4.0480838 20.9024715 -4.3090010 + 4.9704928 20.9508820 -4.0579033 3.9295464 20.0026379 -4.6131034 + 16.5264473 2.2405303 -8.1754551 16.9665298 3.0887129 -8.2315369 + 17.1653481 1.6666924 -7.7526703 -6.1766071 -2.1041696 -18.0790024 + -6.7156343 -2.8535132 -18.3323116 -5.5990114 -1.9603035 -18.8286133 + -4.2343454 9.1901817 -1.0169727 -3.5739145 8.6788445 -0.5494296 + -4.9834099 8.5994234 -1.0953234 -10.1044970 -11.9759741 -0.9653149 + -9.3205976 -12.4942760 -0.7833876 -10.3025331 -12.1557617 -1.8843850 + -5.1018796 -6.7091188 0.0636763 -5.3723736 -6.1884484 0.8199615 + -4.1768193 -6.4944577 -0.0563911 17.4855328 -2.9520736 9.2500858 + 17.4419346 -3.1342735 10.1887732 17.9905796 -3.6801181 8.8879938 + -6.3615065 11.7621565 -11.4044533 -6.7784090 11.9047947 -12.2542057 + -6.8228688 12.3529043 -10.8091431 6.6235404 17.4375591 5.7339325 + 6.1568146 17.1819592 4.9382768 7.5478773 17.3087158 5.5212541 + 16.8151455 -0.4488131 5.1101398 16.7694931 -1.1279904 4.4371867 + 16.4231853 -0.8522864 5.8846130 12.2130785 -7.2950191 2.1702855 + 12.7692881 -7.7438893 2.8069792 11.9228277 -6.5027666 2.6223049 + 11.1980448 -9.4773703 19.5954189 12.0313253 -9.7561588 19.9750919 + 11.4345207 -9.1053104 18.7457809 1.3003147 -21.1092339 10.9828539 + 1.7696130 -20.4158783 11.4468031 0.8064880 -20.6507473 10.3030329 + -10.3387814 -9.7093287 0.3755141 -10.2699280 -10.5210514 -0.1270759 + -10.5546131 -9.0419245 -0.2758074 4.1924977 9.2071238 -14.5534906 + 3.8056870 10.0137901 -14.2130527 3.8858027 8.5241451 -13.9570761 + -7.7014165 -7.7560601 -0.5057539 -7.5404019 -8.6934633 -0.6133712 + -6.8421369 -7.3874145 -0.3008850 -10.5404148 18.7847996 -6.0260029 + -10.9514399 18.1984329 -5.3908157 -11.2139301 18.9275188 -6.6910143 + -20.9057293 -1.5750350 6.2053070 -21.5908241 -1.3406099 6.8313437 + -20.1049576 -1.6100854 6.7285361 1.3330771 -7.9999762 -3.5016758 + 1.0797886 -8.5056095 -2.7293987 1.1738755 -7.0890841 -3.2543652 + 1.1203125 2.5992496 -18.7341175 1.3351929 1.9079129 -19.3603058 + 1.9563313 3.0305808 -18.5573177 8.2162113 10.1778212 -12.5315304 + 8.1106815 10.6137533 -13.3771420 7.5640063 9.4772606 -12.5401745 + 12.4224396 12.2471571 8.3939638 12.6480541 13.1764870 8.3530254 + 12.0588112 12.1273890 9.2712679 19.8536072 -6.1671653 12.8761063 + 20.2890186 -6.9381194 12.5124054 20.2133179 -5.4322824 12.3793278 + -16.0195751 -1.7770751 7.3601646 -16.1103153 -1.3458651 6.5104256 + -15.1050377 -2.0581100 7.3896918 18.0431786 -2.7588773 12.1719131 + 18.0294170 -1.8144590 12.3272085 18.0173569 -3.1459014 13.0469999 + -1.7610201 -1.5756963 -0.3337018 -2.6249642 -1.6705281 0.0673459 + -1.5467013 -0.6492011 -0.2245882 13.5849018 15.1787472 4.2195387 + 14.5226593 15.3513012 4.3036041 13.5204086 14.2250395 4.1693950 + -1.6406168 9.4525919 -9.9548359 -2.4453309 9.1648788 -10.3859825 + -1.0853395 9.7661095 -10.6687021 5.2082272 -6.4566936 21.2534294 + 4.4160762 -6.2492070 20.7577705 5.3486838 -7.3910766 21.1003532 + -16.9940224 -17.1906185 4.8785338 -17.4984436 -17.9183216 4.5148849 + -16.1042099 -17.5336189 4.9610901 10.7341404 14.6995344 4.6622229 + 10.1728621 15.3732119 5.0460944 11.6250572 15.0143566 4.8151445 + -13.6749029 0.2448686 14.9666300 -14.1299791 0.5532994 14.1830435 + -13.4009161 1.0449433 15.4150085 -4.8937836 7.7764730 23.1101494 + -4.4728169 8.3614931 22.4802532 -5.7978644 7.7053599 22.8038616 + -9.2260284 16.6299095 5.7974634 -9.2499514 16.6565952 6.7539921 + -8.5539207 17.2675533 5.5568047 4.7802405 -12.2841311 -10.4116096 + 5.6197424 -12.2991447 -10.8712215 4.9514995 -12.7357950 -9.5852308 + -3.7164636 -3.7717235 12.2693863 -3.8492823 -4.6015582 11.8111668 + -2.7811017 -3.5923376 12.1737261 -14.9694061 -0.1531137 11.1706848 + -15.3871288 0.3613741 11.8613672 -14.9580441 -1.0474052 11.5117798 + -1.3484184 -7.8666816 5.6748037 -1.9494815 -7.2024069 5.3376174 + -0.7842090 -8.0787392 4.9312100 -1.3060759 3.8839254 -18.5769958 + -0.5251081 3.3908165 -18.3256702 -1.3375522 4.6140685 -17.9588261 + -17.3650894 -9.9401808 7.4025397 -17.4579639 -10.5474768 6.6685109 + -18.2111053 -9.9730320 7.8490934 6.2616057 12.9964943 -7.3146496 + 6.9044237 13.4992161 -6.8143616 6.1827745 13.4670534 -8.1444635 + -14.5942545 9.2544298 -13.5299921 -15.1136160 8.6124897 -13.0458355 + -13.8023500 8.7800093 -13.7830620 -1.4265236 6.1311016 -17.0628109 + -0.8776750 6.8822980 -16.8376427 -2.1640532 6.5084820 -17.5422554 + -10.0027723 3.6829209 -19.9450817 -10.4138317 3.5689003 -19.0881920 + -10.5472679 3.1697810 -20.5421124 8.3990946 -5.3738661 11.3257122 + 7.8870764 -6.0553613 11.7611809 7.7462344 -4.7507067 11.0068436 + 9.5988455 13.2851286 2.4968011 8.6787186 13.5477905 2.5214365 + 10.0239258 13.8400517 3.1507118 15.9411707 4.8956962 11.5608940 + 16.1394405 5.8315697 11.5282984 14.9960279 4.8459773 11.4178381 + 7.9257145 -15.9642677 6.2863703 8.2037077 -16.7319393 6.7860026 + 8.3044128 -16.0943451 5.4169455 -2.8860736 8.0470409 -20.7864723 + -2.0898809 7.5215435 -20.8649673 -3.3299713 7.6954770 -20.0147266 + -2.9272451 -15.6188574 5.4194140 -3.3768942 -14.8982859 4.9780259 + -2.5405591 -16.1308422 4.7090778 -14.7642813 -10.8096552 -12.9588547 + -14.2363396 -10.7248230 -13.7527771 -14.7101145 -9.9496145 -12.5421677 + 8.4774170 3.6917996 3.2804279 8.6017361 4.0520501 4.1584916 + 7.5323138 3.7355700 3.1351824 -20.6306515 6.3998294 10.3978624 + -20.3159218 7.2770739 10.1796465 -20.8595085 6.4514380 11.3258677 + 14.6596050 15.6892061 -8.7554989 14.0747471 15.2665949 -9.3844452 + 14.0807781 16.2236443 -8.2118397 15.8192492 -4.8439131 -14.1986961 + 15.6978407 -3.9106278 -14.0241375 16.4244995 -5.1381402 -13.5180092 + -18.9232140 1.9172816 0.8678639 -18.5968456 2.6992581 0.4226368 + -19.0790234 1.2881061 0.1635246 -7.9205432 2.1007156 -22.4236298 + -7.1300516 2.1076319 -21.8839016 -7.8013182 2.8297324 -23.0323601 + -10.1725416 2.8705065 -12.6592369 -10.4193850 1.9571750 -12.5138903 + -9.4444962 2.8261132 -13.2790842 -13.4130859 2.5681970 16.7510681 + -13.9841757 3.3274257 16.6341896 -12.5777826 2.9384658 17.0363789 + 3.1721303 -5.7076616 6.4769058 3.1067696 -5.7303114 5.5222087 + 3.2457702 -4.7773776 6.6899333 1.9216523 6.2663684 8.4203377 + 2.2009568 7.0960245 8.0331793 2.2219598 5.6003461 7.8019028 + -16.5694618 -1.3067532 -3.7847984 -17.0455170 -1.1380745 -4.5979095 + -16.4677067 -2.2582009 -3.7597947 -0.5268530 -5.5662713 20.3341122 + -0.0226853 -5.9504609 21.0513611 -0.2745412 -4.6429267 20.3317032 + 0.0700461 16.1286125 9.4084702 0.8517126 16.0622711 8.8599920 + -0.1781922 15.2206907 9.5825052 -2.9810691 -10.1790819 14.1190538 + -3.0137646 -10.9997578 13.6274700 -3.6819515 -9.6465530 13.7430096 + -4.6611915 -21.8325272 -7.1545100 -4.7545090 -22.7849998 -7.1723976 + -3.9536805 -21.6728745 -6.5298734 -5.0822387 3.3396809 21.1940346 + -4.9998651 3.6886275 22.0815487 -5.8958979 3.7191229 20.8620491 + -13.0682573 7.5497637 7.2439404 -12.1790237 7.2606001 7.0392952 + -13.5541477 7.4253788 6.4286671 -2.4176128 8.7505932 10.8191614 + -2.9465320 9.2561913 10.2020340 -2.1707051 7.9632640 10.3340006 + -11.8168325 -12.3467913 -12.9434128 -12.3594017 -11.6170111 -13.2421951 + -11.1586285 -12.4527931 -13.6302624 -7.5220284 -8.5618773 12.3201456 + -8.3183403 -9.0698357 12.1649103 -7.5469275 -7.8696222 11.6595449 + -10.7690163 -9.3798456 6.3737974 -11.4685354 -8.8769274 5.9566917 + -10.5643988 -8.8903351 7.1705050 -8.1082287 3.5207553 12.3571272 + -7.1862679 3.3872044 12.5770941 -8.5875397 3.0402253 13.0320959 + 15.1447811 -8.3088951 -8.1273823 15.5217485 -8.1973944 -7.2546310 + 15.6096506 -9.0606394 -8.4948187 -1.0615900 -3.2428296 -2.2462232 + -1.3310279 -2.7073975 -1.4999340 -0.8791951 -2.6104691 -2.9412656 + 12.7952404 3.8634501 3.8525634 13.4959106 4.1568346 3.2701392 + 12.1547194 3.4552724 3.2700210 11.7401323 6.3144722 6.8116031 + 11.7131481 7.0668693 7.4027061 12.6487093 6.2771559 6.5127263 + 10.6261921 -14.4478455 -10.7647781 11.2190275 -13.6964846 -10.7494478 + 11.1746826 -15.1799917 -11.0464716 -8.4056940 -3.6429012 -19.8376579 + -8.7265244 -4.5417671 -19.9107323 -8.5764170 -3.2570610 -20.6968517 + -1.3211027 -15.6776114 8.0628290 -1.1670327 -15.5414896 7.1279678 + -2.0778604 -15.1269131 8.2635317 9.8944139 -10.6479511 -19.6042461 + 10.8288631 -10.7617998 -19.4308205 9.8006115 -9.7178926 -19.8102207 + -6.1400380 16.3744717 -8.1327801 -5.9790969 17.3084965 -8.2666702 + -7.0679374 16.2595177 -8.3377695 -7.4347663 7.6007624 13.8578024 + -6.5182991 7.5975084 14.1340437 -7.5546932 8.4514894 13.4357681 + 14.4449396 11.2936258 -8.3213139 15.3725805 11.5283175 -8.2961349 + 14.0643339 11.7399998 -7.5649276 -9.4725142 9.5711489 6.8076153 + -8.7678385 9.9078693 6.2541866 -9.2208138 9.8235979 7.6959553 + -10.5125637 -10.1182384 -3.9815104 -9.6629601 -10.5349760 -4.1255069 + -10.3037214 -9.2946653 -3.5406654 -5.9834380 15.0720797 -17.3253899 + -6.1656103 14.5833483 -18.1280022 -5.5148234 14.4509382 -16.7678814 + -9.3095856 -14.8255825 11.9230757 -8.7739029 -14.0697031 12.1637459 + -9.9778442 -14.8729801 12.6067533 -1.9214798 20.6489811 -12.7701254 + -1.9567339 21.3603764 -13.4095821 -2.7855101 20.6541348 -12.3582315 + -5.7729998 15.1507769 -5.4166474 -6.0096960 15.1584129 -6.3440895 + -6.1892529 15.9340096 -5.0567689 -20.8964043 11.4300976 -6.9596138 + -21.2926807 11.1937704 -6.1209564 -20.7361317 10.5920258 -7.3934126 + 16.5605602 -1.6923651 -10.8222742 16.3173485 -1.3779613 -9.9515104 + 15.7280779 -1.7795321 -11.2866077 17.5745544 -3.1221111 3.2762237 + 17.2549458 -3.4958336 2.4549968 18.5239010 -3.0736511 3.1638677 + -13.6520796 -2.3314583 -10.4862423 -14.0189724 -3.2068319 -10.3623772 + -14.0049229 -2.0406635 -11.3271770 -7.0934191 -3.7228518 11.8826265 + -6.5039048 -3.9801052 12.5915174 -7.7928033 -4.3760328 11.9037914 + 6.6463523 -16.5524368 15.6241493 6.2220254 -16.7847519 16.4501076 + 5.9988422 -16.7685604 14.9531403 -9.2449207 -6.7630272 18.3987045 + -9.3276777 -6.5238709 17.4755630 -8.4174576 -6.3690357 18.6749439 + 15.5124550 5.8284173 -7.4792314 16.3375320 6.2780104 -7.6618333 + 15.3365974 5.3197298 -8.2707758 -16.8542480 -4.0225983 -6.4194183 + -16.9317493 -4.8853660 -6.0121627 -17.1087513 -4.1644020 -7.3312030 + -7.8204193 -22.3364143 -7.3233395 -8.1982164 -23.0990753 -6.8853345 + -6.9170432 -22.5911446 -7.5111032 3.6847713 10.6356192 12.0143232 + 3.2458427 10.6861410 11.1651945 4.1164908 11.4843693 12.1116562 + -4.4919963 -5.9182844 10.6882401 -5.4281092 -6.0676131 10.5554762 + -4.1445265 -5.7781205 9.8074160 14.1154137 -2.5922835 -3.9256575 + 14.9414167 -2.1933577 -3.6521466 13.8320303 -2.0670962 -4.6740584 + 1.4589651 4.3551164 0.2383636 2.1426995 3.8585565 -0.2112666 + 0.6618404 4.1682372 -0.2575196 -7.1399894 -15.7263498 1.4154598 + -7.8547835 -15.3474674 1.9270737 -6.3771448 -15.1926746 1.6379246 + -8.5642967 4.5555663 -7.1936598 -9.1310186 5.2843928 -7.4463844 + -8.0565844 4.8918672 -6.4551735 -11.6700039 -19.1366310 -2.9917891 + -11.9010181 -18.2077332 -2.9883094 -10.9730778 -19.2076740 -3.6440756 + 12.9580812 -17.1681042 -10.3381119 13.6835756 -16.9955521 -10.9382086 + 12.4276752 -17.8266582 -10.7866745 -2.2779145 -8.1896572 -3.6642799 + -1.6880963 -8.7765074 -4.1375175 -2.2025483 -7.3530879 -4.1233039 + -8.1821365 -18.3686066 -9.8325596 -8.2142458 -19.2995319 -10.0529652 + -7.2641277 -18.1255665 -9.9526567 -7.4419904 13.8423500 -9.7500048 + -6.8304396 13.8197832 -9.0139828 -8.2702503 13.5335531 -9.3827686 + 5.8717604 1.2861350 17.4174404 5.2596841 0.5708086 17.5903645 + 5.4955578 1.7473036 16.6677551 -4.6417508 -1.6323134 10.7722006 + -4.1233449 -2.4100013 10.9788122 -5.5452619 -1.8918828 10.9525433 + 8.4988747 -10.6401567 -17.0367393 8.4315815 -10.5404720 -17.9863529 + 9.0563059 -11.4087944 -16.9155045 4.0266280 0.2022492 11.9648542 + 3.6320493 0.5131729 11.1500750 4.4270835 -0.6355577 11.7325897 + 2.5793784 10.3285666 -10.5166054 3.4708622 10.1728191 -10.8284245 + 2.0216460 9.8784790 -11.1511030 -12.0586452 -6.2546859 0.5601955 + -11.4445858 -5.8119249 1.1459647 -12.6763353 -6.6915712 1.1465589 + 19.6911869 10.6203318 -9.8921051 18.8111820 10.3040714 -9.6876431 + 20.2429333 10.2582064 -9.1988001 -7.2869792 -6.9465690 14.5249863 + -7.0586748 -7.5352421 13.8055611 -6.7413726 -6.1728821 14.3837290 + 6.9502673 25.0175304 4.3944254 7.7636790 25.1469402 3.9067302 + 7.1415639 24.2944050 4.9916921 4.1636581 4.3483129 10.8759680 + 4.0632563 5.2991209 10.8299742 3.9313934 4.0402889 9.9999504 + -16.0849915 -13.0755138 1.9553859 -15.8897104 -13.7179146 2.6376016 + -15.4873705 -13.2957850 1.2408502 13.2771301 0.0378134 1.3660408 + 13.1146250 0.0928480 2.3077388 12.4271002 0.2196529 0.9652730 + -9.3702374 -2.9758267 -13.4384413 -8.4391403 -2.8708143 -13.6340532 + -9.6786499 -2.0878711 -13.2577543 -9.5442934 -17.0219193 8.1751642 + -10.3989754 -16.6723671 7.9230480 -9.5906630 -17.9517193 7.9525590 + 5.4587617 -12.2540426 -4.1784906 6.0965924 -12.4834480 -3.5026376 + 5.0844760 -11.4241610 -3.8827920 -11.2364826 5.8145871 -21.3637314 + -10.4777451 6.0840373 -21.8813667 -10.9250641 5.0669580 -20.8535347 + 4.2720280 -6.5264335 1.3002484 3.6408110 -7.1902180 1.0224227 + 4.9550805 -6.5500956 0.6300907 3.3514438 -5.4477882 -21.8164673 + 4.1752210 -5.1215515 -21.4542618 3.1667767 -4.8657923 -22.5536308 + 8.1427183 -16.6534023 -6.6751494 7.5102172 -15.9430656 -6.5674567 + 8.0981493 -17.1405716 -5.8524036 0.4207174 14.2394123 -10.4518347 + 0.9054157 13.8365011 -11.1722250 0.5988293 15.1759796 -10.5375681 + -10.2316618 17.6438484 8.7387400 -10.8719196 16.9353237 8.6732101 + -10.6516790 18.3870201 8.3057117 20.6124992 5.2999077 -13.4841776 + 20.8429031 4.6354375 -14.1335039 20.9425373 6.1194019 -13.8526001 + 16.5099964 9.7716560 13.9550667 15.8693829 9.0618715 13.9097681 + 16.6476974 10.0285625 13.0433264 -11.5328693 14.3977890 15.6852732 + -12.1033087 14.6581507 16.4084911 -11.2299175 15.2244349 15.3096304 + -17.8303852 8.5064383 -5.2162771 -17.6821804 9.4304810 -5.4173064 + -18.3845787 8.1918354 -5.9305077 -7.5183282 -21.3520355 -0.1387017 + -7.4104609 -20.9705410 -1.0099410 -7.7094150 -22.2753735 -0.3035243 + -15.3880444 8.1293802 15.5025530 -15.9556866 7.5178871 15.0334158 + -14.5790663 8.1456728 14.9911633 -16.2174187 11.2020826 -3.3496702 + -16.4784317 11.4314528 -4.2415748 -15.5179052 10.5585699 -3.4628253 + -7.4870176 5.2699027 -20.6133099 -8.3274546 4.8382940 -20.4596481 + -7.7187986 6.1163816 -20.9953861 -17.1496868 -3.3746617 -11.8204880 + -16.3389645 -2.9405982 -12.0861015 -16.8664131 -4.0652037 -11.2212057 + -14.3029089 4.2708220 13.8335924 -14.4933929 4.8118815 13.0673018 + -13.3737698 4.0563326 13.7503633 3.8576758 -9.8193188 -3.5874143 + 2.9836328 -9.5453367 -3.3095384 4.2539549 -9.0261383 -3.9480517 + 8.2983627 -6.7659440 -22.1742039 7.5516758 -6.8650594 -21.5835552 + 8.1854982 -5.8968797 -22.5592003 -15.2967615 12.9638462 5.2890382 + -15.8857670 12.6609058 4.5980020 -15.4911680 12.3966293 6.0351639 + -7.1237130 -2.7851868 2.5721848 -7.0441670 -2.1948886 1.8228835 + -6.9230957 -2.2373462 3.3310361 -12.0279293 17.9120197 5.5450015 + -11.1531868 17.5294952 5.6137905 -12.2133245 17.9185314 4.6059499 + -9.8598480 13.9259520 -3.0841858 -10.4947081 13.8873224 -3.7995121 + -10.3898020 13.8601837 -2.2897961 7.0765324 -11.9102259 20.4524536 + 7.7290001 -11.8803129 21.1521835 7.3287072 -11.2024517 19.8594131 + -18.1248398 15.4173765 -3.8364491 -18.9496460 15.6610184 -4.2566457 + -17.4542332 15.8799868 -4.3389525 5.1926241 -17.4970818 -2.8874500 + 4.6653018 -17.4501419 -3.6849208 4.5513182 -17.5590572 -2.1795535 + 2.7914927 -0.9704872 -23.6365833 2.0826223 -0.4154065 -23.9615746 + 3.1746767 -0.4717086 -22.9150429 -13.5176306 -14.2257948 5.9035168 + -12.9303074 -13.4769869 6.0063248 -14.0012541 -14.2659121 6.7285805 + 0.9922959 -14.4659386 4.7027750 1.0041041 -15.3577785 5.0502148 + 1.8788429 -14.3268890 4.3697119 -5.3645973 3.3733239 -4.8266091 + -4.8921924 3.8557253 -4.1481152 -5.7695155 2.6409881 -4.3618975 + 16.7251320 -8.7462816 -0.1677474 16.8564835 -8.8948812 0.7686802 + 16.8929100 -9.5979090 -0.5712491 -8.9341764 -14.9009199 3.0517220 + -9.5856361 -14.2282095 3.2499459 -9.3631268 -15.7250185 3.2821445 + 1.6538526 18.4658775 14.1857824 0.7811750 18.5293274 14.5739059 + 1.5420425 17.8762474 13.4400845 21.0322609 -10.1001234 -6.4693584 + 20.5511494 -9.4412374 -6.9699912 20.3661232 -10.5223322 -5.9269261 + -14.4775534 11.1637783 15.9483271 -14.3031235 10.7551289 15.1005001 + -14.2225580 10.5013351 16.5904942 -19.9320812 10.5567856 -2.9733417 + -19.6099815 11.1233149 -2.2722511 -20.3008156 11.1601448 -3.6184967 + -3.4624889 -0.3155719 -19.4607983 -2.5306015 -0.5321543 -19.4306316 + -3.5219941 0.5447812 -19.0454884 -7.6615567 -4.8502297 19.3344746 + -7.6793232 -3.9017055 19.2071247 -7.1019411 -4.9786210 20.1003590 + 7.1246901 11.0310717 11.2024813 7.8927827 11.5533705 10.9712467 + 6.8135819 11.4129944 12.0232000 11.5433273 -11.7389059 12.7801762 + 10.6017838 -11.8809748 12.8778706 11.9016218 -11.8994207 13.6531553 + 15.6712151 6.6384921 0.0298237 16.1394119 6.0461588 -0.5585340 + 16.3146381 7.3104548 0.2549994 6.0198965 -13.7123919 5.1246181 + 5.6372471 -13.5189285 5.9804120 6.8356891 -14.1711721 5.3252029 + -19.0842419 -0.0338369 -1.0172304 -19.2754803 -0.3616693 -1.8959715 + -19.3403854 -0.7483324 -0.4340332 17.1208992 17.5750237 7.9839997 + 17.6962090 18.3380413 8.0392857 17.6646996 16.8931084 7.5896597 + 4.3649340 3.1933658 -18.6395969 3.9389355 4.0189576 -18.4090424 + 3.9114461 2.9026380 -19.4308338 -13.4975805 -10.2191887 -0.7132441 + -13.0269985 -10.3626013 0.1078631 -14.4163113 -10.3725910 -0.4927152 + 2.3296795 -20.9066582 14.4771309 1.6062752 -21.4743023 14.2112417 + 2.2745538 -20.1557045 13.8861456 1.9262142 0.5961763 -20.3288555 + 2.8420062 0.3843404 -20.5096397 1.5656651 0.8458388 -21.1796818 + -2.6387064 -7.7670846 11.6854610 -1.9082410 -7.1645803 11.5453167 + -3.3933327 -7.3225317 11.2992697 -11.6562281 17.0875931 0.8480020 + -11.1491575 16.8313961 0.0776293 -12.5490608 16.8032379 0.6524879 + -9.6223364 -1.5646744 1.7456104 -9.1401930 -2.1754823 2.3030009 + -8.9492273 -1.1515045 1.2048267 1.9707295 -20.4508133 -3.3395629 + 2.8607399 -20.7964706 -3.2714913 1.6583838 -20.4137554 -2.4355171 + -6.4037495 -9.8924732 4.1498423 -5.5350862 -9.5389547 3.9583225 + -6.9814568 -9.4633808 3.5186801 -8.3524837 3.4735546 -0.4938996 + -8.0906458 2.9081295 -1.2205129 -7.7803583 3.2153113 0.2287443 + 0.7048845 -3.6205146 -7.1249237 1.4884036 -4.1505065 -6.9785056 + 0.8842049 -2.7973211 -6.6705794 -6.5088763 16.5961723 10.8279867 + -7.2669797 16.0352097 10.9917974 -6.1426911 16.7635765 11.6963854 + -13.4359894 6.8897171 -1.6009564 -13.2587891 6.1309881 -1.0449325 + -12.9823675 6.6965632 -2.4214141 -4.9882216 -13.9967222 2.3776550 + -5.6399832 -13.2962084 2.4044819 -4.2251768 -13.6311998 2.8253021 + -7.8873692 -22.9383297 9.3307209 -7.4972315 -22.0678940 9.2509308 + -8.3779993 -22.9065266 10.1520014 -7.8202257 9.8131456 12.0560408 + -8.4295816 10.3051615 12.6063480 -6.9887280 10.2791920 12.1434746 + -16.7339230 -6.4149051 13.3066807 -17.6263733 -6.4530077 13.6506462 + -16.4497814 -7.3284507 13.2761955 -3.2693720 17.1268272 5.4516678 + -2.7385261 16.3372211 5.3469930 -2.8257592 17.6243439 6.1386290 + 1.7148230 14.8575573 -14.1109161 2.4313278 15.1698856 -13.5583735 + 1.5481063 13.9658127 -13.8055830 -4.7509356 -22.3601284 7.7755542 + -4.0287943 -22.9781113 7.8888712 -4.6437521 -21.7327957 8.4905348 + 17.4987335 -0.6818162 15.6895466 17.7560005 -1.3138200 16.3608265 + 16.7199135 -1.0648545 15.2858734 3.5853093 -0.4231341 15.5813370 + 3.0953567 -0.8398269 14.8724327 3.6913176 -1.1126369 16.2367611 + -11.6287222 15.4428225 3.6817937 -12.5036087 15.4953794 3.2970290 + -11.7856779 15.2924509 4.6139874 -4.4483337 0.2891986 8.8834314 + -4.6368022 0.1629583 7.9534988 -4.6459365 -0.5569813 9.2848845 + 1.7614691 -6.0312057 8.6894808 2.0474298 -6.1233339 7.7806516 + 2.1781790 -5.2239537 8.9910250 + 42.4388485 42.4388485 42.4388485 109.4712190 109.4712190 109.4712190 -- GitLab From 01da1b51dfc86ec413f237ab7d8fe54484f8756b Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 12 Feb 2015 16:47:51 -0800 Subject: [PATCH 257/338] Updated to latest asmjit, which supports 32 bit mode --- CMakeLists.txt | 14 +- libraries/asmjit/apibegin.h | 45 +- libraries/asmjit/apiend.h | 56 +- libraries/asmjit/asmjit.h | 22 +- libraries/asmjit/base/assembler.cpp | 38 +- libraries/asmjit/base/assembler.h | 37 +- libraries/asmjit/base/codegen.h | 12 +- libraries/asmjit/base/compiler.cpp | 4 +- libraries/asmjit/base/compiler.h | 293 +- libraries/asmjit/base/constpool.cpp | 16 +- libraries/asmjit/base/constpool.h | 4 + libraries/asmjit/base/context.cpp | 10 +- libraries/asmjit/base/cpuinfo.cpp | 12 +- libraries/asmjit/base/cpuinfo.h | 8 +- libraries/asmjit/base/cputicks.cpp | 2 +- libraries/asmjit/base/error.cpp | 2 + libraries/asmjit/base/error.h | 12 +- libraries/asmjit/base/globals.h | 22 +- libraries/asmjit/base/intutil.h | 88 +- libraries/asmjit/base/logger.cpp | 14 +- libraries/asmjit/base/logger.h | 21 +- libraries/asmjit/base/operand.h | 92 +- libraries/asmjit/base/runtime.cpp | 8 +- libraries/asmjit/base/runtime.h | 7 +- libraries/asmjit/base/string.h | 8 +- libraries/asmjit/base/vmem.cpp | 7 +- libraries/asmjit/base/vmem.h | 10 +- libraries/asmjit/base/zone.h | 2 +- libraries/asmjit/build.h | 117 +- libraries/asmjit/contrib.h | 18 - libraries/asmjit/host.h | 10 +- libraries/asmjit/x86/x86assembler.cpp | 1508 ++--- libraries/asmjit/x86/x86assembler.h | 631 ++- libraries/asmjit/x86/x86compiler.cpp | 108 +- libraries/asmjit/x86/x86compiler.h | 500 +- libraries/asmjit/x86/x86context.cpp | 332 +- libraries/asmjit/x86/x86context_p.h | 18 +- libraries/asmjit/x86/x86cpuinfo.cpp | 308 +- libraries/asmjit/x86/x86cpuinfo.h | 151 +- libraries/asmjit/x86/x86inst.cpp | 6593 +++++++++++----------- libraries/asmjit/x86/x86inst.h | 961 ++-- libraries/asmjit/x86/x86operand.h | 1101 +++- libraries/asmjit/x86/x86operand_regs.cpp | 409 +- libraries/asmjit/x86/x86scheduler.cpp | 2 +- serialization/src/XmlSerializer.cpp | 2 +- 45 files changed, 7604 insertions(+), 6031 deletions(-) delete mode 100644 libraries/asmjit/contrib.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cc7f83c8..2c54d7d28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,14 +274,12 @@ ELSE (ANDROID OR PNACL) SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/libraries/sfmt/src/SFMT.cpp PROPERTIES COMPILE_FLAGS "-DHAVE_SSE2=1") ENDIF(ANDROID OR PNACL) IF (NOT (ANDROID OR PNACL)) - IF (CMAKE_SIZEOF_VOID_P EQUAL 8) - FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*/*.cpp) - FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*.h) - SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) - SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) - INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit") - SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DLEPTON_USE_JIT") - ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 8) + FILE(GLOB src_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*/*.cpp) + FILE(GLOB incl_files ${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit/*.h) + SET(SOURCE_FILES ${SOURCE_FILES} ${src_files}) + SET(SOURCE_INCLUDE_FILES ${SOURCE_INCLUDE_FILES} ${incl_files}) + INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/libraries/asmjit") + SET(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DLEPTON_USE_JIT") ENDIF (NOT (ANDROID OR PNACL)) # If API wrappers are being generated, and add them to the build. diff --git a/libraries/asmjit/apibegin.h b/libraries/asmjit/apibegin.h index b025e2e96..07ff85385 100644 --- a/libraries/asmjit/apibegin.h +++ b/libraries/asmjit/apibegin.h @@ -4,12 +4,38 @@ // [License] // Zlib - See LICENSE.md file in the package. +// [Dependencies - AsmJit] #if !defined(_ASMJIT_BUILD_H) #include "build.h" #endif // !_ASMJIT_BUILD_H +// [Guard] +#if !defined(ASMJIT_API_SCOPE) +# define ASMJIT_API_SCOPE +#else +# error "AsmJit - Api-Scope is already active, previous scope not closed by apiend.h?" +#endif // ASMJIT_API_SCOPE + // ============================================================================ -// [MSVC] +// [Override] +// ============================================================================ + +#if !defined(ASMJIT_CC_HAS_OVERRIDE) && !defined(override) +# define override +# define ASMJIT_UNDEF_OVERRIDE +#endif // !ASMJIT_CC_HAS_OVERRIDE && !override + +// ============================================================================ +// [NoExcept] +// ============================================================================ + +#if !defined(ASMJIT_CC_HAS_NOEXCEPT) && !defined(noexcept) +# define noexcept ASMJIT_NOEXCEPT +# define ASMJIT_UNDEF_NOEXCEPT +#endif // !ASMJIT_CC_HAS_NOEXCEPT && !noexcept + +// ============================================================================ +// [MSC] // ============================================================================ #if defined(_MSC_VER) @@ -29,21 +55,30 @@ // Rename symbols. # if !defined(vsnprintf) -# define ASMJIT_DEFINED_VSNPRINTF +# define ASMJIT_UNDEF_VSNPRINTF # define vsnprintf _vsnprintf # endif // !vsnprintf # if !defined(snprintf) -# define ASMJIT_DEFINED_SNPRINTF +# define ASMJIT_UNDEF_SNPRINTF # define snprintf _snprintf # endif // !snprintf #endif // _MSC_VER // ============================================================================ -// [GNUC] +// [CLang] +// ============================================================================ + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunnamed-type-template-args" +#endif // __clang__ + +// ============================================================================ +// [GCC] // ============================================================================ #if defined(__GNUC__) && !defined(__clang__) # if __GNUC__ >= 4 && !defined(__MINGW32__) # pragma GCC visibility push(hidden) -# endif // __GNUC__ >= 4 +# endif // GCC 4+ #endif // __GNUC__ diff --git a/libraries/asmjit/apiend.h b/libraries/asmjit/apiend.h index 4ec7834cb..8341594d4 100644 --- a/libraries/asmjit/apiend.h +++ b/libraries/asmjit/apiend.h @@ -4,30 +4,64 @@ // [License] // Zlib - See LICENSE.md file in the package. +// [Guard] +#if defined(ASMJIT_API_SCOPE) +# undef ASMJIT_API_SCOPE +#else +# error "AsmJit - Api-Scope not active, forgot to include apibegin.h?" +#endif // ASMJIT_API_SCOPE + +// ============================================================================ +// [Override] +// ============================================================================ + +#if defined(ASMJIT_UNDEF_OVERRIDE) +# undef override +# undef ASMJIT_UNDEF_OVERRIDE +#endif // ASMJIT_UNDEF_OVERRIDE + +// ============================================================================ +// [NoExcept] +// ============================================================================ + +#if defined(ASMJIT_UNDEF_NOEXCEPT) +# undef noexcept +# undef ASMJIT_UNDEF_NOEXCEPT +#endif // ASMJIT_UNDEF_NOEXCEPT + // ============================================================================ -// [MSVC] +// [MSC] // ============================================================================ #if defined(_MSC_VER) -// Pop disabled warnings by ApiBegin.h # pragma warning(pop) -// Rename symbols back. -# if defined(ASMJIT_DEFINED_VSNPRINTF) -# undef ASMJIT_DEFINED_VSNPRINTF + +# if defined(ASMJIT_UNDEF_VSNPRINTF) # undef vsnprintf -# endif // ASMJIT_DEFINED_VSNPRINTF -# if defined(ASMJIT_DEFINED_SNPRINTF) -# undef ASMJIT_DEFINED_SNPRINTF +# undef ASMJIT_UNDEF_VSNPRINTF +# endif // ASMJIT_UNDEF_VSNPRINTF + +# if defined(ASMJIT_UNDEF_SNPRINTF) # undef snprintf -# endif // ASMJIT_DEFINED_SNPRINTF +# undef ASMJIT_UNDEF_SNPRINTF +# endif // ASMJIT_UNDEF_SNPRINTF + #endif // _MSC_VER // ============================================================================ -// [GNUC] +// [CLang] +// ============================================================================ + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif // __clang__ + +// ============================================================================ +// [GCC] // ============================================================================ #if defined(__GNUC__) && !defined(__clang__) # if __GNUC__ >= 4 && !defined(__MINGW32__) # pragma GCC visibility pop -# endif // __GNUC__ >= 4 +# endif // GCC 4+ #endif // __GNUC__ diff --git a/libraries/asmjit/asmjit.h b/libraries/asmjit/asmjit.h index 5737ff834..9b143d44d 100644 --- a/libraries/asmjit/asmjit.h +++ b/libraries/asmjit/asmjit.h @@ -235,15 +235,15 @@ //! `BaseMem` class. These functions are used to make operands that represents //! memory addresses: //! -//! - `asmjit::ptr()` -//! - `asmjit::byte_ptr()` -//! - `asmjit::word_ptr()` -//! - `asmjit::dword_ptr()` -//! - `asmjit::qword_ptr()` -//! - `asmjit::tword_ptr()` -//! - `asmjit::oword_ptr()` -//! - `asmjit::yword_ptr()` -//! - `asmjit::zword_ptr()` +//! - `asmjit::ptr()` - Address size not specified. +//! - `asmjit::byte_ptr()` - 1 byte. +//! - `asmjit::word_ptr()` - 2 bytes (Gpw size). +//! - `asmjit::dword_ptr()` - 4 bytes (Gpd size). +//! - `asmjit::qword_ptr()` - 8 bytes (Gpq/Mm size). +//! - `asmjit::tword_ptr()` - 10 bytes (FPU). +//! - `asmjit::oword_ptr()` - 16 bytes (Xmm size). +//! - `asmjit::yword_ptr()` - 32 bytes (Ymm size). +//! - `asmjit::zword_ptr()` - 64 bytes (Zmm size). //! //! Most useful function to make pointer should be `asmjit::ptr()`. It creates //! pointer to the target with unspecified size. Unspecified size works in all @@ -298,10 +298,10 @@ //! // Get `X86CpuInfo` global instance. //! const X86CpuInfo* cpuInfo = X86CpuInfo::getHost(); //! -//! if (cpuInfo->hasFeature(kX86CpuFeatureSse2)) { +//! if (cpuInfo->hasFeature(kX86CpuFeatureSSE2)) { //! // Processor has SSE2. //! } -//! else if (cpuInfo->hasFeature(kX86CpuFeatureMmx)) { +//! else if (cpuInfo->hasFeature(kX86CpuFeatureMMX)) { //! // Processor doesn't have SSE2, but has MMX. //! } //! else { diff --git a/libraries/asmjit/base/assembler.cpp b/libraries/asmjit/base/assembler.cpp index 3718bafee..fea8f664d 100644 --- a/libraries/asmjit/base/assembler.cpp +++ b/libraries/asmjit/base/assembler.cpp @@ -340,43 +340,35 @@ Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const } Error Assembler::emit(uint32_t code, int o0) { - Imm imm(o0); - return _emit(code, imm, NA, NA, NA); + return _emit(code, Imm(o0), NA, NA, NA); } -Error Assembler::emit(uint32_t code, uint64_t o0) { - Imm imm(o0); - return _emit(code, imm, NA, NA, NA); +Error Assembler::emit(uint32_t code, const Operand& o0, int o1) { + return _emit(code, o0, Imm(o1), NA, NA); } -Error Assembler::emit(uint32_t code, const Operand& o0, int o1) { - Imm imm(o1); - return _emit(code, o0, imm, NA, NA); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2) { + return _emit(code, o0, o1, Imm(o2), NA); } -Error Assembler::emit(uint32_t code, const Operand& o0, uint64_t o1) { - Imm imm(o1); - return _emit(code, o0, imm, NA, NA); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3) { + return _emit(code, o0, o1, o2, Imm(o3)); } -Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int o2) { - Imm imm(o2); - return _emit(code, o0, o1, imm, NA); +Error Assembler::emit(uint32_t code, int64_t o0) { + return _emit(code, Imm(o0), NA, NA, NA); } -Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2) { - Imm imm(o2); - return _emit(code, o0, o1, imm, NA); +Error Assembler::emit(uint32_t code, const Operand& o0, int64_t o1) { + return _emit(code, o0, Imm(o1), NA, NA); } -Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3) { - Imm imm(o3); - return _emit(code, o0, o1, o2, imm); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, int64_t o2) { + return _emit(code, o0, o1, Imm(o2), NA); } -Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3) { - Imm imm(o3); - return _emit(code, o0, o1, o2, imm); +Error Assembler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int64_t o3) { + return _emit(code, o0, o1, o2, Imm(o3)); } #undef NA diff --git a/libraries/asmjit/base/assembler.h b/libraries/asmjit/base/assembler.h index 42bd17abb..02c4cc3b5 100644 --- a/libraries/asmjit/base/assembler.h +++ b/libraries/asmjit/base/assembler.h @@ -26,23 +26,23 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::kInstId] +// [asmjit::InstId] // ============================================================================ //! Instruction codes (stub). -ASMJIT_ENUM(kInstId) { +ASMJIT_ENUM(InstId) { //! No instruction. kInstIdNone = 0 }; // ============================================================================ -// [asmjit::kInstOptions] +// [asmjit::InstOptions] // ============================================================================ -//! Instruction options (stub). -ASMJIT_ENUM(kInstOptions) { +//! Instruction options. +ASMJIT_ENUM(InstOptions) { //! No instruction options. - kInstOptionNone = 0x00, + kInstOptionNone = 0x00000000, //! Emit short form of the instruction. //! @@ -53,7 +53,8 @@ ASMJIT_ENUM(kInstOptions) { //! can be dangerous if the short jmp/jcc is required, but not encodable due //! to large displacement, in such case an error happens and the whole //! assembler/compiler stream is unusable. - kInstOptionShortForm = 0x01, + kInstOptionShortForm = 0x00000001, + //! Emit long form of the instruction. //! //! X86/X64: @@ -61,12 +62,13 @@ ASMJIT_ENUM(kInstOptions) { //! Long form is mosrlt related to jmp and jcc instructions, but like the //! `kInstOptionShortForm` option it can be used by other instructions //! supporting both 8-bit and 32-bit immediates. - kInstOptionLongForm = 0x02, + kInstOptionLongForm = 0x00000002, //! Condition is likely to be taken. - kInstOptionTaken = 0x04, + kInstOptionTaken = 0x00000004, + //! Condition is unlikely to be taken. - kInstOptionNotTaken = 0x08 + kInstOptionNotTaken = 0x00000008 }; // ============================================================================ @@ -474,19 +476,20 @@ struct ASMJIT_VCLASS Assembler : public CodeGen { //! Emit an instruction with integer immediate operand. ASMJIT_API Error emit(uint32_t code, int o0); //! \overload - ASMJIT_API Error emit(uint32_t code, uint64_t o0); - //! \overload ASMJIT_API Error emit(uint32_t code, const Operand& o0, int o1); //! \overload - ASMJIT_API Error emit(uint32_t code, const Operand& o0, uint64_t o1); - //! \overload ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int o2); //! \overload - ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2); - //! \overload ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3); + + //! \overload + ASMJIT_API Error emit(uint32_t code, int64_t o0); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, int64_t o1); + //! \overload + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, int64_t o2); //! \overload - ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3); + ASMJIT_API Error emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int64_t o3); //! Emit an instruction (virtual). virtual Error _emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, const Operand& o3) = 0; diff --git a/libraries/asmjit/base/codegen.h b/libraries/asmjit/base/codegen.h index 551b84bb1..5e2db4381 100644 --- a/libraries/asmjit/base/codegen.h +++ b/libraries/asmjit/base/codegen.h @@ -23,11 +23,11 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::kCodeGen] +// [asmjit::CodeGenFeatures] // ============================================================================ //! Features of \ref CodeGen. -ASMJIT_ENUM(kCodeGen) { +ASMJIT_ENUM(CodeGenFeatures) { //! Emit optimized code-alignment sequences (`Assembler` and `Compiler`). //! //! Default `true`. @@ -80,11 +80,11 @@ ASMJIT_ENUM(kCodeGen) { }; // ============================================================================ -// [asmjit::kAlignMode] +// [asmjit::AlignMode] // ============================================================================ //! Code aligning mode. -ASMJIT_ENUM(kAlignMode) { +ASMJIT_ENUM(AlignMode) { //! Align by emitting a sequence that can be executed (code). kAlignCode = 0, //! Align by emitting sequence that shouldn't be executed (data). @@ -92,11 +92,11 @@ ASMJIT_ENUM(kAlignMode) { }; // ============================================================================ -// [asmjit::kRelocMode] +// [asmjit::RelocMode] // ============================================================================ //! Relocation mode. -ASMJIT_ENUM(kRelocMode) { +ASMJIT_ENUM(RelocMode) { //! Relocate an absolute address to an absolute address. kRelocAbsToAbs = 0, //! Relocate a relative address to an absolute address. diff --git a/libraries/asmjit/base/compiler.cpp b/libraries/asmjit/base/compiler.cpp index 9828a2899..ae26de1e1 100644 --- a/libraries/asmjit/base/compiler.cpp +++ b/libraries/asmjit/base/compiler.cpp @@ -40,11 +40,11 @@ enum { kBaseCompilerDefaultLookAhead = 64 }; Compiler::Compiler(Runtime* runtime) : CodeGen(runtime), + _assembler(NULL), _nodeFlowId(0), _nodeFlags(0), _maxLookAhead(kBaseCompilerDefaultLookAhead), _targetVarMapping(NULL), - _assembler(NULL), _firstNode(NULL), _lastNode(NULL), _cursor(NULL), @@ -482,7 +482,7 @@ VarData* Compiler::_newVd(uint32_t type, uint32_t size, uint32_t c, const char* vd->_flags = 0; vd->_priority = 10; - vd->_state = kVarStateUnused; + vd->_state = kVarStateNone; vd->_regIndex = kInvalidReg; vd->_isStack = false; vd->_isMemArg = false; diff --git a/libraries/asmjit/base/compiler.h b/libraries/asmjit/base/compiler.h index 01b8aade6..ea6217150 100644 --- a/libraries/asmjit/base/compiler.h +++ b/libraries/asmjit/base/compiler.h @@ -43,14 +43,14 @@ struct InstNode; struct JumpNode; // ============================================================================ -// [asmjit::kConstScope] +// [asmjit::ConstScope] // ============================================================================ //! \addtogroup asmjit_base_compiler //! \{ //! Scope of the constant. -ASMJIT_ENUM(kConstScope) { +ASMJIT_ENUM(ConstScope) { //! Local constant, always embedded right after the current function. kConstScopeLocal = 0, //! Global constant, embedded at the end of the currently compiled code. @@ -58,10 +58,10 @@ ASMJIT_ENUM(kConstScope) { }; // ============================================================================ -// [asmjit::kVarType] +// [asmjit::VarType] // ============================================================================ -ASMJIT_ENUM(kVarType) { +ASMJIT_ENUM(VarType) { //! Variable is 8-bit signed integer. kVarTypeInt8 = 0, //! Variable is 8-bit unsigned integer. @@ -101,13 +101,13 @@ ASMJIT_ENUM(kVarType) { }; // ============================================================================ -// [asmjit::kVarFlags] +// [asmjit::VarFlags] // ============================================================================ //! \internal //! //! X86/X64 variable flags. -ASMJIT_ENUM(kVarFlags) { +ASMJIT_ENUM(VarFlags) { //! Variable contains single-precision floating-point(s). kVarFlagSp = 0x10, //! Variable contains double-precision floating-point(s). @@ -117,11 +117,11 @@ ASMJIT_ENUM(kVarFlags) { }; // ============================================================================ -// [asmjit::kVarAttrFlags] +// [asmjit::VarAttrFlags] // ============================================================================ //! Variable attribute flags. -ASMJIT_ENUM(kVarAttrFlags) { +ASMJIT_ENUM(VarAttrFlags) { //! Variable is accessed through register on input. kVarAttrInReg = 0x00000001, //! Variable is accessed through register on output. @@ -188,13 +188,13 @@ ASMJIT_ENUM(kVarAttrFlags) { }; // ============================================================================ -// [asmjit::kVarHint] +// [asmjit::VarHint] // ============================================================================ //! Variable hint (used by `Compiler)`. //! //! \sa Compiler. -ASMJIT_ENUM(kVarHint) { +ASMJIT_ENUM(VarHint) { //! Alloc variable. kVarHintAlloc = 0, //! Spill variable. @@ -211,35 +211,29 @@ ASMJIT_ENUM(kVarHint) { // [asmjit::kVarState] // ============================================================================ +// TODO: Rename `kVarState` or `VarState`. + //! State of variable. //! -//! \note State of variable is used only during make process and it's not -//! visible to the developer. +//! \note Variable states are used only during register allocation. ASMJIT_ENUM(kVarState) { //! Variable is currently not used. - kVarStateUnused = 0, - - //! Variable is in register. - //! + kVarStateNone = 0, //! Variable is currently allocated in register. kVarStateReg = 1, - - //! Variable is in memory location or spilled. - //! - //! Variable was spilled from register to memory or variable is used for - //! memory only storage. + //! Variable is currently allocated in memory (or has been spilled). kVarStateMem = 2 }; // ============================================================================ -// [asmjit::kFuncConv] +// [asmjit::FuncConv] // ============================================================================ //! Function calling convention. //! //! For a platform specific calling conventions, see: -//! - `kX86FuncConv` - X86/X64 calling conventions. -ASMJIT_ENUM(kFuncConv) { +//! - `X86FuncConv` - X86/X64 calling conventions. +ASMJIT_ENUM(FuncConv) { //! Calling convention is invalid (can't be used). kFuncConvNone = 0, @@ -267,14 +261,14 @@ ASMJIT_ENUM(kFuncConv) { }; // ============================================================================ -// [asmjit::kFuncHint] +// [asmjit::FuncHint] // ============================================================================ //! Function hints. //! //! For a platform specific calling conventions, see: -//! - `kX86FuncHint` - X86/X64 function hints. -ASMJIT_ENUM(kFuncHint) { +//! - `X86FuncHint` - X86/X64 function hints. +ASMJIT_ENUM(FuncHint) { //! Make a naked function (default true). //! //! Naked function is function without using standard prolog/epilog sequence). @@ -325,14 +319,14 @@ ASMJIT_ENUM(kFuncHint) { }; // ============================================================================ -// [asmjit::kFuncFlags] +// [asmjit::FuncFlags] // ============================================================================ //! Function flags. //! //! For a platform specific calling conventions, see: -//! - `kX86FuncFlags` - X86/X64 function flags. -ASMJIT_ENUM(kFuncFlags) { +//! - `X86FuncFlags` - X86/X64 function flags. +ASMJIT_ENUM(FuncFlags) { //! Whether the function is using naked (minimal) prolog / epilog. kFuncFlagIsNaked = 0x00000001, @@ -360,11 +354,11 @@ ASMJIT_ENUM(kFuncFlags) { }; // ============================================================================ -// [asmjit::kFuncDir] +// [asmjit::FuncDir] // ============================================================================ //! Function arguments direction. -ASMJIT_ENUM(kFuncDir) { +ASMJIT_ENUM(FuncDir) { //! Arguments are passed left to right. //! //! This arguments direction is unusual in C, however it's used in Pascal. @@ -377,11 +371,11 @@ ASMJIT_ENUM(kFuncDir) { }; // ============================================================================ -// [asmjit::kFuncArg] +// [asmjit::FuncArgIndex] // ============================================================================ -//! Function argument (lo/hi) specification. -ASMJIT_ENUM(kFuncArg) { +//! Function argument index (lo/hi). +ASMJIT_ENUM(FuncArgIndex) { //! Maxumum number of function arguments supported by AsmJit. kFuncArgCount = 16, //! Extended maximum number of arguments (used internally). @@ -401,11 +395,11 @@ ASMJIT_ENUM(kFuncArg) { }; // ============================================================================ -// [asmjit::kFuncRet] +// [asmjit::FuncRet] // ============================================================================ //! Function return value (lo/hi) specification. -ASMJIT_ENUM(kFuncRet) { +ASMJIT_ENUM(FuncRet) { //! Index to the LO part of function return value. kFuncRetLo = 0, //! Index to the HI part of function return value. @@ -416,17 +410,17 @@ ASMJIT_ENUM(kFuncRet) { // [asmjit::kFuncStackInvalid] // ============================================================================ -enum kFuncMisc { +enum { //! Invalid stack offset in function or function parameter. kFuncStackInvalid = -1 }; // ============================================================================ -// [asmjit::kNodeType] +// [asmjit::NodeType] // ============================================================================ //! Type of node, see \ref Node. -ASMJIT_ENUM(kNodeType) { +ASMJIT_ENUM(NodeType) { //! Invalid node (internal, can't be used). kNodeTypeNone = 0, //! Node is an .align directive, see \ref AlignNode. @@ -454,10 +448,10 @@ ASMJIT_ENUM(kNodeType) { }; // ============================================================================ -// [asmjit::kNodeFlags] +// [asmjit::NodeFlags] // ============================================================================ -ASMJIT_ENUM(kNodeFlags) { +ASMJIT_ENUM(NodeFlags) { //! Whether the node has been translated, thus contains only registers. kNodeFlagIsTranslated = 0x0001, @@ -558,6 +552,12 @@ struct Var : public Operand { return Var(*this); } + //! Reset Var operand. + ASMJIT_INLINE void reset() { + _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue); + _init_packed_d2_d3(kInvalidValue, kInvalidValue); + } + //! Get whether the variable has been initialized by `Compiler`. ASMJIT_INLINE bool isInitialized() const { return _vreg.id != kInvalidValue; @@ -987,11 +987,11 @@ struct VarAttr { //! Get whether `flag` is on. ASMJIT_INLINE bool hasFlag(uint32_t flag) { return (_flags & flag) != 0; } //! Add `flags`. - ASMJIT_INLINE void addFlags(uint32_t flags) { _flags |= flags; } + ASMJIT_INLINE void orFlags(uint32_t flags) { _flags |= flags; } //! Mask `flags`. ASMJIT_INLINE void andFlags(uint32_t flags) { _flags &= flags; } //! Clear `flags`. - ASMJIT_INLINE void delFlags(uint32_t flags) { _flags &= ~flags; } + ASMJIT_INLINE void andNotFlags(uint32_t flags) { _flags &= ~flags; } //! Get how many times the variable is used by the instruction/node. ASMJIT_INLINE uint32_t getVarCount() const { return _varCount; } @@ -1174,7 +1174,7 @@ struct DoubleType {}; #if !defined(ASMJIT_DOCGEN) template struct TypeId { - enum { kId = static_cast(::asmjit::kInvalidVar) }; + // Left empty to report any type, which is not known to asmjit. }; template @@ -1186,38 +1186,30 @@ struct TypeId { template<> \ struct TypeId<_T_> { enum { kId = _Id_ }; } -ASMJIT_TYPE_ID(void, kInvalidVar); -ASMJIT_TYPE_ID(Void, kInvalidVar); - -ASMJIT_TYPE_ID(int8_t, kVarTypeInt8); -ASMJIT_TYPE_ID(Int8Type, kVarTypeInt8); - -ASMJIT_TYPE_ID(uint8_t, kVarTypeUInt8); -ASMJIT_TYPE_ID(UInt8Type, kVarTypeUInt8); - -ASMJIT_TYPE_ID(int16_t, kVarTypeInt16); -ASMJIT_TYPE_ID(Int16Type, kVarTypeInt16); - -ASMJIT_TYPE_ID(uint16_t, kVarTypeUInt8); -ASMJIT_TYPE_ID(UInt16Type, kVarTypeUInt8); - -ASMJIT_TYPE_ID(int32_t, kVarTypeInt32); -ASMJIT_TYPE_ID(Int32Type, kVarTypeUInt8); - -ASMJIT_TYPE_ID(uint32_t, kVarTypeUInt32); -ASMJIT_TYPE_ID(UInt32Type, kVarTypeUInt8); - -ASMJIT_TYPE_ID(int64_t, kVarTypeInt64); -ASMJIT_TYPE_ID(Int64Type, kVarTypeUInt8); - -ASMJIT_TYPE_ID(uint64_t, kVarTypeUInt64); -ASMJIT_TYPE_ID(UInt64Type, kVarTypeUInt8); - -ASMJIT_TYPE_ID(float, kVarTypeFp32); -ASMJIT_TYPE_ID(FloatType, kVarTypeFp32); - -ASMJIT_TYPE_ID(double, kVarTypeFp64); -ASMJIT_TYPE_ID(DoubleType, kVarTypeFp64); +ASMJIT_TYPE_ID(void , kInvalidVar); +ASMJIT_TYPE_ID(char , IntTraits::kIsSigned ? kVarTypeInt8 : kVarTypeUInt8); +ASMJIT_TYPE_ID(signed char , kVarTypeInt8); +ASMJIT_TYPE_ID(unsigned char, kVarTypeUInt8); +ASMJIT_TYPE_ID(int16_t , kVarTypeInt16); +ASMJIT_TYPE_ID(uint16_t , kVarTypeUInt16); +ASMJIT_TYPE_ID(int32_t , kVarTypeInt32); +ASMJIT_TYPE_ID(uint32_t , kVarTypeUInt32); +ASMJIT_TYPE_ID(int64_t , kVarTypeInt64); +ASMJIT_TYPE_ID(uint64_t , kVarTypeUInt64); +ASMJIT_TYPE_ID(float , kVarTypeFp32); +ASMJIT_TYPE_ID(double , kVarTypeFp64); + +ASMJIT_TYPE_ID(Void , kInvalidVar); +ASMJIT_TYPE_ID(Int8Type , kVarTypeInt8); +ASMJIT_TYPE_ID(UInt8Type , kVarTypeUInt8); +ASMJIT_TYPE_ID(Int16Type , kVarTypeInt16); +ASMJIT_TYPE_ID(UInt16Type , kVarTypeUInt16); +ASMJIT_TYPE_ID(Int32Type , kVarTypeUInt32); +ASMJIT_TYPE_ID(UInt32Type , kVarTypeUInt32); +ASMJIT_TYPE_ID(Int64Type , kVarTypeUInt64); +ASMJIT_TYPE_ID(UInt64Type , kVarTypeUInt64); +ASMJIT_TYPE_ID(FloatType , kVarTypeFp32); +ASMJIT_TYPE_ID(DoubleType , kVarTypeFp64); #endif // !ASMJIT_DOCGEN // ============================================================================ @@ -1256,7 +1248,7 @@ struct FuncInOut { union { struct { - //! Variable type, see `kVarType`. + //! Variable type, see `VarType`. uint8_t _varType; //! Register index if argument / return value is a register. uint8_t _regIndex; @@ -1482,7 +1474,7 @@ struct FuncDecl { // [Accessors - Calling Convention] // -------------------------------------------------------------------------- - //! Get function calling convention, see `kFuncConv`. + //! Get function calling convention, see `FuncConv`. ASMJIT_INLINE uint32_t getConvention() const { return _convention; } //! Get whether the callee pops the stack. @@ -1550,7 +1542,7 @@ struct FuncDecl { uint8_t _convention; //! Whether a callee pops stack. uint8_t _calleePopsStack : 1; - //! Direction for arguments passed on the stack, see `kFuncDir`. + //! Direction for arguments passed on the stack, see `FuncDir`. uint8_t _direction : 1; //! Reserved #0 (alignment). uint8_t _reserved0 : 6; @@ -1636,7 +1628,7 @@ struct Node { // [Accessors - Type and Flags] // -------------------------------------------------------------------------- - //! Get type of node, see `kNodeType`. + //! Get node type, see `NodeType`. ASMJIT_INLINE uint32_t getType() const { return _type; } @@ -1646,24 +1638,29 @@ struct Node { return _flags; } - //! Set node flags to `flags`. - ASMJIT_INLINE void setFlags(uint32_t flags) { - _flags = static_cast(flags); - } - //! Get whether the instruction has flag `flag`. ASMJIT_INLINE bool hasFlag(uint32_t flag) const { return (static_cast(_flags) & flag) != 0; } + //! Set node flags to `flags`. + ASMJIT_INLINE void setFlags(uint32_t flags) { + _flags = static_cast(flags); + } + //! Add instruction `flags`. - ASMJIT_INLINE void addFlags(uint32_t flags) { + ASMJIT_INLINE void orFlags(uint32_t flags) { _flags |= static_cast(flags); } + //! And instruction `flags`. + ASMJIT_INLINE void andFlags(uint32_t flags) { + _flags &= static_cast(flags); + } + //! Clear instruction `flags`. - ASMJIT_INLINE void delFlags(uint32_t flags) { - _flags &= static_cast(~flags); + ASMJIT_INLINE void andNotFlags(uint32_t flags) { + _flags &= ~static_cast(flags); } //! Get whether the node has beed fetched. @@ -1689,18 +1686,18 @@ struct Node { return hasFlag(kNodeFlagIsInformative); } - //! Whether the instruction is an unconditional jump. + //! Whether the node is `InstNode` and unconditional jump. ASMJIT_INLINE bool isJmp() const { return hasFlag(kNodeFlagIsJmp); } - //! Whether the instruction is a conditional jump. + //! Whether the node is `InstNode` and conditional jump. ASMJIT_INLINE bool isJcc() const { return hasFlag(kNodeFlagIsJcc); } - //! Whether the instruction is an unconditional or conditional jump. + //! Whether the node is `InstNode` and conditional/unconditional jump. ASMJIT_INLINE bool isJmpOrJcc() const { return hasFlag(kNodeFlagIsJmp | kNodeFlagIsJcc); } - //! Whether the instruction is a return. + //! Whether the node is `InstNode` and return. ASMJIT_INLINE bool isRet() const { return hasFlag(kNodeFlagIsRet); } - //! Get whether the instruction is special. + //! Get whether the node is `InstNode` and the instruction is special. ASMJIT_INLINE bool isSpecial() const { return hasFlag(kNodeFlagIsSpecial); } - //! Get whether the instruction accesses FPU. + //! Get whether the node is `InstNode` and the instruction uses x87-FPU. ASMJIT_INLINE bool isFp() const { return hasFlag(kNodeFlagIsFp); } // -------------------------------------------------------------------------- @@ -1785,7 +1782,7 @@ struct Node { //! Next node. Node* _next; - //! Node type, see `kNodeType`. + //! Node type, see `NodeType`. uint8_t _type; //! Operands count (if the node has operands, otherwise zero). uint8_t _opCount; @@ -1863,7 +1860,7 @@ struct AlignNode : public Node { // [Members] // -------------------------------------------------------------------------- - //! Alignment mode, see \ref kAlignMode. + //! Alignment mode, see \ref AlignMode. uint32_t _mode; //! Alignment offset in bytes. uint32_t _offset; @@ -1891,7 +1888,9 @@ struct EmbedNode : public Node { // -------------------------------------------------------------------------- //! Create a new `EmbedNode` instance. - ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) : Node(compiler, kNodeTypeEmbed) { + ASMJIT_INLINE EmbedNode(Compiler* compiler, void* data, uint32_t size) : + Node(compiler, kNodeTypeEmbed) { + _size = size; if (size <= kInlineBufferSize) { if (data != NULL) @@ -1947,7 +1946,7 @@ struct CommentNode : public Node { //! Create a new `CommentNode` instance. ASMJIT_INLINE CommentNode(Compiler* compiler, const char* comment) : Node(compiler, kNodeTypeComment) { - addFlags(kNodeFlagIsInformative); + orFlags(kNodeFlagIsInformative); _comment = comment; } @@ -1968,8 +1967,10 @@ struct HintNode : public Node { // -------------------------------------------------------------------------- //! Create a new `HintNode` instance. - ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : Node(compiler, kNodeTypeHint) { - addFlags(kNodeFlagIsInformative); + ASMJIT_INLINE HintNode(Compiler* compiler, VarData* vd, uint32_t hint, uint32_t value) : + Node(compiler, kNodeTypeHint) { + + orFlags(kNodeFlagIsInformative); _vd = vd; _hint = hint; _value = value; @@ -2095,9 +2096,12 @@ struct InstNode : public Node { // -------------------------------------------------------------------------- //! Create a new `InstNode` instance. - ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t code, uint32_t options, Operand* opList, uint32_t opCount) : Node(compiler, kNodeTypeInst) { - _code = static_cast(code); - _options = static_cast(options); + ASMJIT_INLINE InstNode(Compiler* compiler, uint32_t instId, uint32_t instOptions, Operand* opList, uint32_t opCount) : + Node(compiler, kNodeTypeInst) { + + _instId = static_cast(instId); + _reserved = 0; + _instOptions = instOptions; _opCount = static_cast(opCount); _opList = opList; @@ -2112,18 +2116,17 @@ struct InstNode : public Node { // [Accessors] // -------------------------------------------------------------------------- - //! Get instruction code, see `kX86InstId`. - ASMJIT_INLINE uint32_t getCode() const { - return _code; + //! Get instruction ID, see `X86InstId`. + ASMJIT_INLINE uint32_t getInstId() const { + return _instId; } - //! Set instruction code to `code`. + //! Set instruction ID to `instId`. //! - //! Please do not modify instruction code if you are not know what you are - //! doing. Incorrect instruction code or operands can raise assertion() at - //! runtime. - ASMJIT_INLINE void setCode(uint32_t code) { - _code = static_cast(code); + //! Please do not modify instruction code if you don't know what are you + //! doing. Incorrect instruction code or operands can cause assertion failure. + ASMJIT_INLINE void setInstId(uint32_t instId) { + _instId = static_cast(instId); } //! Whether the instruction is an unconditional jump or whether the @@ -2134,23 +2137,23 @@ struct InstNode : public Node { //! Get emit options. ASMJIT_INLINE uint32_t getOptions() const { - return _options; + return _instOptions; } //! Set emit options. ASMJIT_INLINE void setOptions(uint32_t options) { - _options = static_cast(options); + _instOptions = options; } //! Add emit options. ASMJIT_INLINE void addOptions(uint32_t options) { - _options |= static_cast(options); + _instOptions |= options; } //! Mask emit options. ASMJIT_INLINE void andOptions(uint32_t options) { - _options &= static_cast(options); + _instOptions &= options; } //! Clear emit options. ASMJIT_INLINE void delOptions(uint32_t options) { - _options &= static_cast(~options); + _instOptions &= ~options; } //! Get operands list. @@ -2219,12 +2222,14 @@ _Update: // [Members] // -------------------------------------------------------------------------- - //! Instruction code, see `kInstId`. - uint16_t _code; - //! Instruction options, see `kInstOptions`. - uint8_t _options; + //! Instruction ID, see `InstId`. + uint16_t _instId; //! \internal uint8_t _memOpIndex; + //! \internal + uint8_t _reserved; + //! Instruction options, see `InstOptions`. + uint32_t _instOptions; //! Operands list. Operand* _opList; @@ -2468,7 +2473,7 @@ struct FuncNode : public Node { //! The "Red Zone" size - count of bytes which might be accessed without //! adjusting the stack pointer. uint16_t _redZoneSize; - //! Spill zone size (zone used by WIN64ABI). + //! Spill zone size (used by WIN64 ABI). uint16_t _spillZoneSize; //! Stack size needed for function arguments. @@ -2954,15 +2959,51 @@ struct ASMJIT_VCLASS Compiler : public CodeGen { ASMJIT_API void alloc(Var& var); //! Alloc variable `var` using `regIndex` as a register index. ASMJIT_API void alloc(Var& var, uint32_t regIndex); - //! Alloc variable `var` using `reg` as a demanded register. + //! Alloc variable `var` using `reg` as a register operand. ASMJIT_API void alloc(Var& var, const Reg& reg); //! Spill variable `var`. ASMJIT_API void spill(Var& var); - //! Save variable `var` if modified. + //! Save variable `var` if the status is `modified` at this point. ASMJIT_API void save(Var& var); //! Unuse variable `var`. ASMJIT_API void unuse(Var& var); + //! Alloc variable `var` (if initialized), but only if it's initialized. + ASMJIT_INLINE void allocUnsafe(Var& var) { + if (var.isInitialized()) + alloc(var); + } + + //! Alloc variable `var` (if initialized) using `regIndex` as a register index + ASMJIT_INLINE void allocUnsafe(Var& var, uint32_t regIndex) { + if (var.isInitialized()) + alloc(var, regIndex); + } + + //! Alloc variable `var` (if initialized) using `reg` as a register operand. + ASMJIT_INLINE void allocUnsafe(Var& var, const Reg& reg) { + if (var.isInitialized()) + alloc(var, reg); + } + + //! Spill variable `var` (if initialized). + ASMJIT_INLINE void spillUnsafe(Var& var) { + if (var.isInitialized()) + spill(var); + } + + //! Save variable `var` (if initialized) if the status is `modified` at this point. + ASMJIT_INLINE void saveUnsafe(Var& var) { + if (var.isInitialized()) + save(var); + } + + //! Unuse variable `var` (if initialized). + ASMJIT_INLINE void unuseUnsafe(Var& var) { + if (var.isInitialized()) + unuse(var); + } + //! Get priority of variable `var`. ASMJIT_API uint32_t getPriority(Var& var) const; //! Set priority of variable `var` to `priority`. @@ -3035,7 +3076,7 @@ struct ASMJIT_VCLASS Compiler : public CodeGen { //! registers. uint32_t _maxLookAhead; - //! Variable mapping (translates incoming kVarType into target). + //! Variable mapping (translates incoming VarType into target). const uint8_t* _targetVarMapping; //! First node. diff --git a/libraries/asmjit/base/constpool.cpp b/libraries/asmjit/base/constpool.cpp index d85ea3138..cd7e6d7fb 100644 --- a/libraries/asmjit/base/constpool.cpp +++ b/libraries/asmjit/base/constpool.cpp @@ -162,19 +162,6 @@ void ConstPool::reset() { // [asmjit::ConstPool - Ops] // ============================================================================ -static ASMJIT_INLINE size_t ConstPool_getGapIndex(size_t size) { - if (size <= 1) - return ConstPool::kIndex1; - else if (size <= 3) - return ConstPool::kIndex2; - else if (size <= 7) - return ConstPool::kIndex4; - else if (size <= 15) - return ConstPool::kIndex8; - else - return ConstPool::kIndex16; -} - static ASMJIT_INLINE ConstPoolGap* ConstPool_allocGap(ConstPool* self) { ConstPoolGap* gap = self->_gapPool; if (gap == NULL) @@ -396,7 +383,7 @@ UNIT(base_constpool) { EXPECT(prevOffset + 8 == curOffset, "pool.add() - Returned incorrect curOffset."); EXPECT(pool.getSize() == (i + 1) * 8, - "pool.getSize() - Reports incorrect size."); + "pool.getSize() - Reported incorrect size."); prevOffset = curOffset; } @@ -481,7 +468,6 @@ UNIT(base_constpool) { INFO("Checking pool alignment when combined constants are added."); { uint8_t bytes[32] = { 0 }; - uint64_t c = 0; size_t offset; pool.add(bytes, 1, offset); diff --git a/libraries/asmjit/base/constpool.h b/libraries/asmjit/base/constpool.h index c2c77c427..8f66b8b66 100644 --- a/libraries/asmjit/base/constpool.h +++ b/libraries/asmjit/base/constpool.h @@ -128,9 +128,12 @@ struct ConstPoolTree { if (link != NULL) { ASMJIT_ASSERT(top != kHeightLimit); stack[top++] = node; + + node = link; continue; } +_Visit: visitor.visit(node); link = node->_link[1]; @@ -143,6 +146,7 @@ struct ConstPoolTree { break; node = stack[--top]; + goto _Visit; } } diff --git a/libraries/asmjit/base/context.cpp b/libraries/asmjit/base/context.cpp index cedec0f42..aeadb245f 100644 --- a/libraries/asmjit/base/context.cpp +++ b/libraries/asmjit/base/context.cpp @@ -26,8 +26,8 @@ namespace asmjit { Context::Context(Compiler* compiler) : _compiler(compiler), - _varMapToVaListOffset(0), - _baseZone(8192 - kZoneOverhead) { + _baseZone(8192 - kZoneOverhead), + _varMapToVaListOffset(0) { Context::reset(); } @@ -217,7 +217,7 @@ Error Context::resolveCellOffsets() { // Vars - Allocated according to alignment/width. while (varCell != NULL) { uint32_t size = varCell->getSize(); - uint32_t offset; + uint32_t offset = 0; switch (size) { case 1: offset = pos1 ; pos1 += 1 ; break; @@ -234,13 +234,13 @@ Error Context::resolveCellOffsets() { varCell = varCell->_next; } - // Stack - Allocated according to alignment and width. + // Stack - Allocated according to alignment/width. while (stackCell != NULL) { uint32_t size = stackCell->getSize(); uint32_t alignment = stackCell->getAlignment(); uint32_t offset; - // Try to fill the gap between variables / stack first. + // Try to fill the gap between variables/stack first. if (size <= gapSize && alignment <= gapAlignment) { offset = gapPos; diff --git a/libraries/asmjit/base/cpuinfo.cpp b/libraries/asmjit/base/cpuinfo.cpp index 71d6858dd..1a6d7757c 100644 --- a/libraries/asmjit/base/cpuinfo.cpp +++ b/libraries/asmjit/base/cpuinfo.cpp @@ -10,11 +10,11 @@ // [Dependencies - AsmJit] #include "../base/cpuinfo.h" -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) #include "../x86/x86cpuinfo.h" #else // ? -#endif // ASMJIT_HOST || ASMJIT_HOST_X64 +#endif // [Dependencies - Posix] #if defined(ASMJIT_OS_POSIX) @@ -54,7 +54,7 @@ uint32_t CpuInfo::detectHwThreadsCount() { // [asmjit::CpuInfo - GetHost] // ============================================================================ -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) struct AutoX86CpuInfo : public X86CpuInfo { ASMJIT_INLINE AutoX86CpuInfo() : X86CpuInfo() { X86CpuUtil::detect(this); @@ -62,14 +62,14 @@ struct AutoX86CpuInfo : public X86CpuInfo { }; #else #error "AsmJit - Unsupported CPU." -#endif // ASMJIT_HOST || ASMJIT_HOST_X64 +#endif const CpuInfo* CpuInfo::getHost() { -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) static AutoX86CpuInfo cpuInfo; #else #error "AsmJit - Unsupported CPU." -#endif // ASMJIT_HOST || ASMJIT_HOST_X64 +#endif return &cpuInfo; } diff --git a/libraries/asmjit/base/cpuinfo.h b/libraries/asmjit/base/cpuinfo.h index 06ff636c5..04abb624e 100644 --- a/libraries/asmjit/base/cpuinfo.h +++ b/libraries/asmjit/base/cpuinfo.h @@ -20,7 +20,7 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::kCpuVendor] +// [asmjit::CpuVendor] // ============================================================================ //! Cpu vendor ID. @@ -30,7 +30,7 @@ namespace asmjit { //! calls. Some manufacturers changed their vendor strings and AsmJit is aware //! of that - it checks multiple combinations and decides which vendor ID should //! be used. -ASMJIT_ENUM(kCpuVendor) { +ASMJIT_ENUM(CpuVendor) { //! No/Unknown vendor. kCpuVendorNone = 0, @@ -59,7 +59,7 @@ struct CpuInfo { // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE CpuInfo(uint32_t size = sizeof(CpuInfo)) : _size(size) {} + ASMJIT_INLINE CpuInfo(uint32_t size) : _size(size) {} // -------------------------------------------------------------------------- // [Accessors] @@ -120,7 +120,7 @@ struct CpuInfo { //! Cpu long vendor string (brand). char _brandString[64]; - //! Cpu vendor id, see `asmjit::kCpuVendor`. + //! Cpu vendor id, see \ref CpuVendor. uint32_t _vendorId; //! Cpu family ID. uint32_t _family; diff --git a/libraries/asmjit/base/cputicks.cpp b/libraries/asmjit/base/cputicks.cpp index cb10ff14f..0c503316e 100644 --- a/libraries/asmjit/base/cputicks.cpp +++ b/libraries/asmjit/base/cputicks.cpp @@ -24,7 +24,7 @@ // [Dependencies - Windows] #if defined(ASMJIT_OS_WINDOWS) // `_InterlockedCompareExchange` is only available as intrinsic (MS Compiler). -# if defined(_MSC_VER) +# if defined(_MSC_VER) && _MSC_VER >= 1400 # include # pragma intrinsic(_InterlockedCompareExchange) # else diff --git a/libraries/asmjit/base/error.cpp b/libraries/asmjit/base/error.cpp index 3df410e40..51516fba4 100644 --- a/libraries/asmjit/base/error.cpp +++ b/libraries/asmjit/base/error.cpp @@ -64,7 +64,9 @@ static const char* findPackedString(const char* p, uint32_t id, uint32_t maxId) while (i < id) { while (p[0]) p++; + p++; + i++; } return p; diff --git a/libraries/asmjit/base/error.h b/libraries/asmjit/base/error.h index 46b40892f..6f76934c0 100644 --- a/libraries/asmjit/base/error.h +++ b/libraries/asmjit/base/error.h @@ -8,23 +8,23 @@ #ifndef _ASMJIT_BASE_ERROR_H #define _ASMJIT_BASE_ERROR_H -// [Api-Begin] -#include "../apibegin.h" - // [Dependencies - AsmJit] #include "../base/globals.h" +// [Api-Begin] +#include "../apibegin.h" + namespace asmjit { //! \addtogroup asmjit_base_general //! \{ // ============================================================================ -// [asmjit::kError] +// [asmjit::ErrorCode] // ============================================================================ //! AsmJit error codes. -ASMJIT_ENUM(kError) { +ASMJIT_ENUM(ErrorCode) { //! No error (success). //! //! This is default state and state you want. @@ -188,7 +188,7 @@ struct ASMJIT_VCLASS ErrorHandler { //! Error utilities. struct ErrorUtil { #if !defined(ASMJIT_DISABLE_NAMES) - //! Get printable version of AsmJit `kError` code. + //! Get a printable version of AsmJit `Error` code. static ASMJIT_API const char* asString(Error code); #endif // ASMJIT_DISABLE_NAMES }; diff --git a/libraries/asmjit/base/globals.h b/libraries/asmjit/base/globals.h index 036457895..5c1bcae3c 100644 --- a/libraries/asmjit/base/globals.h +++ b/libraries/asmjit/base/globals.h @@ -34,7 +34,7 @@ typedef uint64_t Ptr; typedef int64_t SignedPtr; // ============================================================================ -// [asmjit::kGlobals] +// [asmjit::GlobalDefs] // ============================================================================ //! Invalid index @@ -48,7 +48,7 @@ static const size_t kInvalidIndex = ~static_cast(0); static const Ptr kNoBaseAddress = static_cast(static_cast(-1)); //! Global constants. -ASMJIT_ENUM(kGlobals) { +ASMJIT_ENUM(GlobalDefs) { //! Invalid value or operand id. kInvalidValue = 0xFFFFFFFF, @@ -74,11 +74,11 @@ ASMJIT_ENUM(kGlobals) { }; // ============================================================================ -// [asmjit::kArch] +// [asmjit::ArchId] // ============================================================================ -//! Architecture. -ASMJIT_ENUM(kArch) { +//! CPU architecture identifier. +ASMJIT_ENUM(ArchId) { //! No/Unknown architecture. kArchNone = 0, @@ -90,17 +90,17 @@ ASMJIT_ENUM(kArch) { //! Arm architecture. kArchArm = 4, -#if defined(ASMJIT_HOST_X86) +#if defined(ASMJIT_ARCH_X86) kArchHost = kArchX86, -#endif // ASMJIT_HOST_X86 +#endif // ASMJIT_ARCH_X86 -#if defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X64) kArchHost = kArchX64, -#endif // ASMJIT_HOST_X64 +#endif // ASMJIT_ARCH_X64 -#if defined(ASMJIT_HOST_ARM) +#if defined(ASMJIT_ARCH_ARM) kArchHost = kArchArm, -#endif // ASMJIT_HOST_ARM +#endif // ASMJIT_ARCH_ARM //! Whether the host is 64-bit. kArchHost64Bit = sizeof(intptr_t) >= 8 diff --git a/libraries/asmjit/base/intutil.h b/libraries/asmjit/base/intutil.h index fe56479b7..44722b4e1 100644 --- a/libraries/asmjit/base/intutil.h +++ b/libraries/asmjit/base/intutil.h @@ -11,8 +11,9 @@ // [Dependencies - AsmJit] #include "../base/globals.h" -#if defined(_MSC_VER) -#pragma intrinsic(_BitScanForward) +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# include +# pragma intrinsic(_BitScanForward) #endif // ASMJIT_OS_WINDOWS // [Api-Begin] @@ -43,6 +44,31 @@ struct IntTraits { }; }; +// \internal +template +struct AsInt_ { typedef int64_t Int; }; + +template<> struct AsInt_<1, 0> { typedef int Int; }; +template<> struct AsInt_<1, 1> { typedef int Int; }; +template<> struct AsInt_<2, 0> { typedef int Int; }; +template<> struct AsInt_<2, 1> { typedef int Int; }; +template<> struct AsInt_<4, 1> { typedef int Int; }; + +// \internal +// +// Map an integer `T` to an `int` or `int64_t`, depending on the type. Used +// internally by AsmJit to dispatch an argument of arbitrary integer type into +// a function that accepts either `int` or `int64_t`. +template +struct AsInt { + typedef typename AsInt_::kIsSigned>::Int Int; +}; + +template +ASMJIT_INLINE typename AsInt::Int asInt(T value) { + return static_cast::Int>(value); +} + // ============================================================================ // [asmjit::IntUtil] // ============================================================================ @@ -82,29 +108,29 @@ struct IntUtil { //! Pack two 8-bit integer and one 16-bit integer into a 32-bit integer as it //! is an array of `{u0,u1,w2}`. static ASMJIT_INLINE uint32_t pack32_2x8_1x16(uint32_t u0, uint32_t u1, uint32_t w2) { -#if defined(ASMJIT_HOST_LE) +#if defined(ASMJIT_ARCH_LE) return u0 + (u1 << 8) + (w2 << 16); #else return (u0 << 24) + (u1 << 16) + (w2); -#endif // ASMJIT_HOST +#endif } //! Pack four 8-bit integer into a 32-bit integer as it is an array of `{u0,u1,u2,u3}`. static ASMJIT_INLINE uint32_t pack32_4x8(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) { -#if defined(ASMJIT_HOST_LE) +#if defined(ASMJIT_ARCH_LE) return u0 + (u1 << 8) + (u2 << 16) + (u3 << 24); #else return (u0 << 24) + (u1 << 16) + (u2 << 8) + u3; -#endif // ASMJIT_HOST +#endif } //! Pack two 32-bit integer into a 64-bit integer as it is an array of `{u0,u1}`. static ASMJIT_INLINE uint64_t pack64_2x32(uint32_t u0, uint32_t u1) { -#if defined(ASMJIT_HOST_LE) +#if defined(ASMJIT_ARCH_LE) return (static_cast(u1) << 32) + u0; #else return (static_cast(u0) << 32) + u1; -#endif // ASMJIT_HOST +#endif } // -------------------------------------------------------------------------- @@ -336,7 +362,7 @@ struct IntUtil { //! Find a first bit in `mask`. static ASMJIT_INLINE uint32_t findFirstBit(uint32_t mask) { -#if defined(_MSC_VER) +#if defined(_MSC_VER) && _MSC_VER >= 1400 DWORD i; if (_BitScanForward(&i, mask)) { ASMJIT_ASSERT(findFirstBitSlow(mask) == i); @@ -566,6 +592,26 @@ union UInt64 { return *this; } + // -------------------------------------------------------------------------- + // [AndNot] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE UInt64& andNot(uint64_t val) { + u64 &= ~val; + return *this; + } + + ASMJIT_INLINE UInt64& andNot(const UInt64& val) { + if (kArchHost64Bit) { + u64 &= ~val.u64; + } + else { + u32[0] &= ~val.u32[0]; + u32[1] &= ~val.u32[1]; + } + return *this; + } + // -------------------------------------------------------------------------- // [Or] // -------------------------------------------------------------------------- @@ -606,26 +652,6 @@ union UInt64 { return *this; } - // -------------------------------------------------------------------------- - // [Del] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE UInt64& del(uint64_t val) { - u64 &= ~val; - return *this; - } - - ASMJIT_INLINE UInt64& del(const UInt64& val) { - if (kArchHost64Bit) { - u64 &= ~val.u64; - } - else { - u32[0] &= ~val.u32[0]; - u32[1] &= ~val.u32[1]; - } - return *this; - } - // -------------------------------------------------------------------------- // [Eq] // -------------------------------------------------------------------------- @@ -694,11 +720,11 @@ union UInt64 { uint8_t u8[8]; struct { -#if defined(ASMJIT_HOST_LE) +#if defined(ASMJIT_ARCH_LE) uint32_t lo, hi; #else uint32_t hi, lo; -#endif // ASMJIT_HOST_LE +#endif // ASMJIT_ARCH_LE }; }; diff --git a/libraries/asmjit/base/logger.cpp b/libraries/asmjit/base/logger.cpp index 23a4de333..94e539f64 100644 --- a/libraries/asmjit/base/logger.cpp +++ b/libraries/asmjit/base/logger.cpp @@ -45,9 +45,12 @@ void Logger::logFormat(uint32_t style, const char* fmt, ...) { va_list ap; va_start(ap, fmt); - len = vsnprintf(buf, 1023, fmt, ap); + len = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); + if (len >= sizeof(buf)) + len = sizeof(buf) - 1; + logString(style, buf, len); } @@ -120,15 +123,6 @@ FileLogger::FileLogger(FILE* stream) : _stream(NULL) { FileLogger::~FileLogger() {} -// ============================================================================ -// [asmjit::FileLogger - Accessors] -// ============================================================================ - -//! Set file stream. -void FileLogger::setStream(FILE* stream) { - _stream = stream; -} - // ============================================================================ // [asmjit::FileLogger - Logging] // ============================================================================ diff --git a/libraries/asmjit/base/logger.h b/libraries/asmjit/base/logger.h index eb940b823..b787574f8 100644 --- a/libraries/asmjit/base/logger.h +++ b/libraries/asmjit/base/logger.h @@ -26,11 +26,11 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::kLoggerOption] +// [asmjit::LoggerOption] // ============================================================================ //! Logger options. -ASMJIT_ENUM(kLoggerOption) { +ASMJIT_ENUM(LoggerOption) { //! Whether to output instructions also in binary form. kLoggerOptionBinaryForm = 0, @@ -44,11 +44,11 @@ ASMJIT_ENUM(kLoggerOption) { }; // ============================================================================ -// [asmjit::kLoggerStyle] +// [asmjit::LoggerStyle] // ============================================================================ //! Logger style. -ASMJIT_ENUM(kLoggerStyle) { +ASMJIT_ENUM(LoggerStyle) { kLoggerStyleDefault = 0, kLoggerStyleDirective = 1, kLoggerStyleLabel = 2, @@ -133,7 +133,7 @@ struct ASMJIT_VCLASS Logger { // [Members] // -------------------------------------------------------------------------- - //! Options, see `kLoggerOption`. + //! Options, see \ref LoggerOption. uint32_t _options; //! Indentation. @@ -165,11 +165,15 @@ struct ASMJIT_VCLASS FileLogger : public Logger { //! Get `FILE*` stream. //! //! \note Return value can be `NULL`. - ASMJIT_INLINE FILE* getStream() const { return _stream; } + ASMJIT_INLINE FILE* getStream() const { + return _stream; + } //! Set `FILE*` stream, can be set to `NULL` to disable logging, although //! the `CodeGen` will still call `logString` even if there is no stream. - ASMJIT_API void setStream(FILE* stream); + ASMJIT_INLINE void setStream(FILE* stream) { + _stream = stream; + } // -------------------------------------------------------------------------- // [Logging] @@ -207,8 +211,7 @@ struct ASMJIT_VCLASS StringLogger : public Logger { // [Accessors] // -------------------------------------------------------------------------- - //! Get char* pointer which represents the resulting - //! string. + //! Get `char*` pointer which represents the resulting string. //! //! The pointer is owned by `StringLogger`, it can't be modified or freed. ASMJIT_INLINE const char* getString() const { diff --git a/libraries/asmjit/base/operand.h b/libraries/asmjit/base/operand.h index 4553e3399..1adc6e265 100644 --- a/libraries/asmjit/base/operand.h +++ b/libraries/asmjit/base/operand.h @@ -27,11 +27,11 @@ struct Compiler; //! \{ // ============================================================================ -// [asmjit::kOperandType] +// [asmjit::OperandType] // ============================================================================ //! Operand types that can be encoded in `Operand`. -ASMJIT_ENUM(kOperandType) { +ASMJIT_ENUM(OperandType) { //! Invalid operand, used only internally (not initialized Operand). kOperandTypeNone = 0, //! Operand is a register. @@ -47,11 +47,11 @@ ASMJIT_ENUM(kOperandType) { }; // ============================================================================ -// [asmjit::kOperandId] +// [asmjit::OperandId] // ============================================================================ //! Operand id masks used to determine the operand type. -ASMJIT_ENUM(kOperandId) { +ASMJIT_ENUM(OperandId) { //! Operand id refers to `Var`. kOperandIdVar = 0x80000000U, //! Operand id to real index mask. @@ -59,21 +59,21 @@ ASMJIT_ENUM(kOperandId) { }; // ============================================================================ -// [asmjit::kRegClass] +// [asmjit::RegClass] // ============================================================================ //! Register class. -ASMJIT_ENUM(kRegClass) { +ASMJIT_ENUM(RegClass) { //! Gp register class, compatible with all architectures. kRegClassGp = 0 }; // ============================================================================ -// [asmjit::kSize] +// [asmjit::SizeDefs] // ============================================================================ //! Common size of registers and pointers. -ASMJIT_ENUM(kSize) { +ASMJIT_ENUM(SizeDefs) { //! 1 byte size (BYTE). kSizeByte = 1, //! 2 bytes size (WORD). @@ -91,11 +91,11 @@ ASMJIT_ENUM(kSize) { }; // ============================================================================ -// [asmjit::kMemType] +// [asmjit::MemType] // ============================================================================ //! Type of memory operand. -ASMJIT_ENUM(kMemType) { +ASMJIT_ENUM(MemType) { //! Memory operand is a combination of base register and optional index register //! and displacement. //! @@ -135,7 +135,7 @@ struct Operand { //! //! Base operand data. struct BaseOp { - //! Type of operand, see `kOperandType`. + //! Type of operand, see \ref OperandType. uint8_t op; //! Size of operand (register, address, immediate, or variable). uint8_t size; @@ -170,7 +170,7 @@ struct Operand { //! Register type and index access. struct { -#if defined(ASMJIT_HOST_LE) +#if defined(ASMJIT_ARCH_LE) //! Register index. uint8_t index; //! Register type. @@ -180,7 +180,7 @@ struct Operand { uint8_t type; //! Register index. uint8_t index; -#endif // ASMJIT_HOST +#endif }; }; @@ -212,10 +212,10 @@ struct Operand { uint8_t op; //! Size of the pointer in bytes. uint8_t size; - //! Type of the memory operand, see `kMemType`. + //! Type of the memory operand, see `MemType`. uint8_t type; //! X86/X64 layout: - //! - segment [3 bits], see `kX86Seg`. + //! - segment [3 bits], see `X86Seg`. //! - shift [2 bits], index register shift (0 to 3). uint8_t flags; @@ -378,7 +378,7 @@ struct Operand { // [Type] // -------------------------------------------------------------------------- - //! Get type of the operand, see `kOperandType`. + //! Get type of the operand, see \ref OperandType. ASMJIT_INLINE uint32_t getOp() const { return _base.op; } //! Get whether the operand is none - `kOperandTypeNone`. @@ -659,7 +659,7 @@ struct BaseMem : public Operand { _init_packed_d2_d3(kInvalidValue, 0); } - //! Get the type of the memory operand, see `kMemType`. + //! Get the type of the memory operand, see `MemType`. ASMJIT_INLINE uint32_t getMemType() const { return _vmem.type; } @@ -774,17 +774,17 @@ struct Imm : public Operand { ASMJIT_INLINE bool isUInt32() const { return IntUtil::isUInt32(_imm.value._i64[0]); } //! Get immediate value as 8-bit signed integer. - ASMJIT_INLINE int8_t getInt8() const { return _imm.value._i8[_ASMJIT_HOST_INDEX(8, 0)]; } + ASMJIT_INLINE int8_t getInt8() const { return _imm.value._i8[_ASMJIT_ARCH_INDEX(8, 0)]; } //! Get immediate value as 8-bit unsigned integer. - ASMJIT_INLINE uint8_t getUInt8() const { return _imm.value._u8[_ASMJIT_HOST_INDEX(8, 0)]; } + ASMJIT_INLINE uint8_t getUInt8() const { return _imm.value._u8[_ASMJIT_ARCH_INDEX(8, 0)]; } //! Get immediate value as 16-bit signed integer. - ASMJIT_INLINE int16_t getInt16() const { return _imm.value._i16[_ASMJIT_HOST_INDEX(4, 0)]; } + ASMJIT_INLINE int16_t getInt16() const { return _imm.value._i16[_ASMJIT_ARCH_INDEX(4, 0)]; } //! Get immediate value as 16-bit unsigned integer. - ASMJIT_INLINE uint16_t getUInt16() const { return _imm.value._u16[_ASMJIT_HOST_INDEX(4, 0)]; } + ASMJIT_INLINE uint16_t getUInt16() const { return _imm.value._u16[_ASMJIT_ARCH_INDEX(4, 0)]; } //! Get immediate value as 32-bit signed integer. - ASMJIT_INLINE int32_t getInt32() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; } + ASMJIT_INLINE int32_t getInt32() const { return _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)]; } //! Get immediate value as 32-bit unsigned integer. - ASMJIT_INLINE uint32_t getUInt32() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; } + ASMJIT_INLINE uint32_t getUInt32() const { return _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)]; } //! Get immediate value as 64-bit signed integer. ASMJIT_INLINE int64_t getInt64() const { return _imm.value._i64[0]; } //! Get immediate value as 64-bit unsigned integer. @@ -807,13 +807,13 @@ struct Imm : public Operand { } //! Get low 32-bit signed integer. - ASMJIT_INLINE int32_t getInt32Lo() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)]; } + ASMJIT_INLINE int32_t getInt32Lo() const { return _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)]; } //! Get low 32-bit signed integer. - ASMJIT_INLINE uint32_t getUInt32Lo() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)]; } + ASMJIT_INLINE uint32_t getUInt32Lo() const { return _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)]; } //! Get high 32-bit signed integer. - ASMJIT_INLINE int32_t getInt32Hi() const { return _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)]; } + ASMJIT_INLINE int32_t getInt32Hi() const { return _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)]; } //! Get high 32-bit signed integer. - ASMJIT_INLINE uint32_t getUInt32Hi() const { return _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)]; } + ASMJIT_INLINE uint32_t getUInt32Hi() const { return _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)]; } //! Set immediate value to 8-bit signed integer `val`. ASMJIT_INLINE Imm& setInt8(int8_t val) { @@ -822,8 +822,8 @@ struct Imm : public Operand { } else { int32_t val32 = static_cast(val); - _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32; - _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31; + _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)] = val32; + _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)] = val32 >> 31; } return *this; } @@ -834,8 +834,8 @@ struct Imm : public Operand { _imm.value._u64[0] = static_cast(val); } else { - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast(val); - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] = static_cast(val); + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0; } return *this; } @@ -847,8 +847,8 @@ struct Imm : public Operand { } else { int32_t val32 = static_cast(val); - _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val32; - _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val32 >> 31; + _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)] = val32; + _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)] = val32 >> 31; } return *this; } @@ -859,8 +859,8 @@ struct Imm : public Operand { _imm.value._u64[0] = static_cast(val); } else { - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = static_cast(val); - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] = static_cast(val); + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0; } return *this; } @@ -871,8 +871,8 @@ struct Imm : public Operand { _imm.value._i64[0] = static_cast(val); } else { - _imm.value._i32[_ASMJIT_HOST_INDEX(2, 0)] = val; - _imm.value._i32[_ASMJIT_HOST_INDEX(2, 1)] = val >> 31; + _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 0)] = val; + _imm.value._i32[_ASMJIT_ARCH_INDEX(2, 1)] = val >> 31; } return *this; } @@ -883,8 +883,8 @@ struct Imm : public Operand { _imm.value._u64[0] = static_cast(val); } else { - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] = val; - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] = val; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0; } return *this; } @@ -921,8 +921,8 @@ struct Imm : public Operand { // -------------------------------------------------------------------------- ASMJIT_INLINE Imm& setFloat(float f) { - _imm.value._f32[_ASMJIT_HOST_INDEX(2, 0)] = f; - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + _imm.value._f32[_ASMJIT_ARCH_INDEX(2, 0)] = f; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0; return *this; } @@ -940,8 +940,8 @@ struct Imm : public Operand { _imm.value._u64[0] &= static_cast(0x000000FFU); } else { - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x000000FFU; - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] &= 0x000000FFU; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0; } return *this; } @@ -951,14 +951,14 @@ struct Imm : public Operand { _imm.value._u64[0] &= static_cast(0x0000FFFFU); } else { - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 0)] &= 0x0000FFFFU; - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 0)] &= 0x0000FFFFU; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0; } return *this; } ASMJIT_INLINE Imm& truncateTo32Bits() { - _imm.value._u32[_ASMJIT_HOST_INDEX(2, 1)] = 0; + _imm.value._u32[_ASMJIT_ARCH_INDEX(2, 1)] = 0; return *this; } diff --git a/libraries/asmjit/base/runtime.cpp b/libraries/asmjit/base/runtime.cpp index 258dbd1e5..eae4ef6ab 100644 --- a/libraries/asmjit/base/runtime.cpp +++ b/libraries/asmjit/base/runtime.cpp @@ -55,7 +55,7 @@ const CpuInfo* HostRuntime::getCpuInfo() { uint32_t HostRuntime::getStackAlignment() { uint32_t alignment = sizeof(intptr_t); -#if defined(ASMJIT_HOST_X86) +#if defined(ASMJIT_ARCH_X86) // Modern Linux, APPLE and UNIX guarantees 16-byte stack alignment, but I'm // not sure about all other UNIX operating systems, because 16-byte alignment // is addition to an older specification. @@ -69,7 +69,7 @@ uint32_t HostRuntime::getStackAlignment() { defined(__APPLE__) ) alignment = 16; # endif -#elif defined(ASMJIT_HOST_X64) +#elif defined(ASMJIT_ARCH_X64) alignment = 16; #endif @@ -78,14 +78,14 @@ uint32_t HostRuntime::getStackAlignment() { void HostRuntime::flush(void* p, size_t size) { // Only useful on non-x86 architectures. -#if !defined(ASMJIT_HOST_X86) && !defined(ASMJIT_HOST_X64) +#if !defined(ASMJIT_ARCH_X86) && !defined(ASMJIT_ARCH_X64) // Windows has built-in support in kernel32.dll. #if defined(ASMJIT_OS_WINDOWS) ::FlushInstructionCache(_memMgr.getProcessHandle(), p, size); #endif // ASMJIT_OS_WINDOWS -#endif // !ASMJIT_HOST_X86 && !ASMJIT_HOST_X64 +#endif // !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64 } // ============================================================================ diff --git a/libraries/asmjit/base/runtime.h b/libraries/asmjit/base/runtime.h index b355fc4a7..c484e2c6c 100644 --- a/libraries/asmjit/base/runtime.h +++ b/libraries/asmjit/base/runtime.h @@ -28,12 +28,11 @@ struct CpuInfo; //! \{ // ============================================================================ -// [asmjit::kRuntimeType] +// [asmjit::RuntimeType] // ============================================================================ -ASMJIT_ENUM(kRuntimeType) { +ASMJIT_ENUM(RuntimeType) { kRuntimeTypeNone = 0, - kRuntimeTypeJit = 1, kRuntimeTypeRemote = 2 }; @@ -90,7 +89,7 @@ struct ASMJIT_VCLASS Runtime { //! relocate it to the target location. //! //! The beginning of the memory allocated for the function is returned in - //! `dst`. Returns Status code as \ref kError, on failure `dst` is set to + //! `dst`. Returns Status code as \ref ErrorCode, on failure `dst` is set to //! `NULL`. virtual Error add(void** dst, Assembler* assembler) = 0; diff --git a/libraries/asmjit/base/string.h b/libraries/asmjit/base/string.h index 145a68978..1429a89ad 100644 --- a/libraries/asmjit/base/string.h +++ b/libraries/asmjit/base/string.h @@ -23,13 +23,13 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::kStringOp] +// [asmjit::StringOp] // ============================================================================ //! \internal //! //! String operation. -ASMJIT_ENUM(kStringOp) { +ASMJIT_ENUM(StringOp) { //! Replace the current string by a given content. kStringOpSet = 0, //! Append a given content to the current string. @@ -37,13 +37,13 @@ ASMJIT_ENUM(kStringOp) { }; // ============================================================================ -// [asmjit::kStringFormat] +// [asmjit::StringFormatFlags] // ============================================================================ //! \internal //! //! String format flags. -ASMJIT_ENUM(kStringFormat) { +ASMJIT_ENUM(StringFormatFlags) { kStringFormatShowSign = 0x00000001, kStringFormatShowSpace = 0x00000002, kStringFormatAlternate = 0x00000004, diff --git a/libraries/asmjit/base/vmem.cpp b/libraries/asmjit/base/vmem.cpp index f0c45d946..7be4f3d76 100644 --- a/libraries/asmjit/base/vmem.cpp +++ b/libraries/asmjit/base/vmem.cpp @@ -512,7 +512,7 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { } else { // False tree root. - RbNode head = { 0 }; + RbNode head = { { NULL, NULL }, 0, 0 }; // Grandparent & parent. RbNode* g = NULL; @@ -522,7 +522,8 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { RbNode* p = NULL; RbNode* q = t->node[1] = self->_root; - int dir = 0, last; + int dir = 0; + int last = 0; // Not needed to initialize, but makes some tools happy. // Search down the tree. for (;;) { @@ -590,7 +591,7 @@ static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) { //! the `node` passed. static MemNode* vMemMgrRemoveNode(VMemMgr* self, MemNode* node) { // False tree root. - RbNode head = { 0 }; + RbNode head = { { NULL, NULL }, 0, 0 }; // Helpers. RbNode* q = &head; diff --git a/libraries/asmjit/base/vmem.h b/libraries/asmjit/base/vmem.h index 998a49bb6..e8019daf5 100644 --- a/libraries/asmjit/base/vmem.h +++ b/libraries/asmjit/base/vmem.h @@ -8,7 +8,7 @@ #ifndef _ASMJIT_BASE_VMEM_H #define _ASMJIT_BASE_VMEM_H -// [Dependencies] +// [Dependencies - AsmJit] #include "../base/error.h" #include "../base/lock.h" @@ -21,11 +21,11 @@ namespace asmjit { //! \{ // ============================================================================ -// [asmjit::kVMemAlloc] +// [asmjit::VMemAllocType] // ============================================================================ //! Type of virtual memory allocation, see `VMemMgr::alloc()`. -ASMJIT_ENUM(kVMemAlloc) { +ASMJIT_ENUM(VMemAllocType) { //! Normal memory allocation, has to be freed by `VMemMgr::release()`. kVMemAllocFreeable = 0, //! Allocate permanent memory, can't be freed. @@ -33,11 +33,11 @@ ASMJIT_ENUM(kVMemAlloc) { }; // ============================================================================ -// [asmjit::kVMemFlags] +// [asmjit::VMemFlags] // ============================================================================ //! Type of virtual memory allocation, see `VMemMgr::alloc()`. -ASMJIT_ENUM(kVMemFlags) { +ASMJIT_ENUM(VMemFlags) { //! Memory is writable. kVMemFlagWritable = 0x00000001, //! Memory is executable. diff --git a/libraries/asmjit/base/zone.h b/libraries/asmjit/base/zone.h index 357890274..39f6253f7 100644 --- a/libraries/asmjit/base/zone.h +++ b/libraries/asmjit/base/zone.h @@ -8,7 +8,7 @@ #ifndef _ASMJIT_BASE_ZONE_H #define _ASMJIT_BASE_ZONE_H -// [Dependencies] +// [Dependencies - AsmJit] #include "../base/globals.h" // [Api-Begin] diff --git a/libraries/asmjit/build.h b/libraries/asmjit/build.h index e73b5551f..5fa80745d 100644 --- a/libraries/asmjit/build.h +++ b/libraries/asmjit/build.h @@ -8,14 +8,14 @@ #ifndef _ASMJIT_BUILD_H #define _ASMJIT_BUILD_H -// [Include] +// [Config] #if defined(ASMJIT_CONFIG_FILE) # include ASMJIT_CONFIG_FILE #else # include "./config.h" #endif // ASMJIT_CONFIG_FILE -// Turn off deprecation warnings when compiling AsmJit. +// [MSC - Turn off deprecation warnings when compiling AsmJit] #if defined(ASMJIT_EXPORTS) && defined(_MSC_VER) # if !defined(_CRT_SECURE_NO_DEPRECATE) # define _CRT_SECURE_NO_DEPRECATE @@ -26,6 +26,7 @@ #endif // ASMJIT_EXPORTS // [Dependencies - C] +#include #include #include #include @@ -34,7 +35,7 @@ #include // ============================================================================ -// [asmjit::build - Sanity] +// [asmjit::Build - Sanity] // ============================================================================ #if defined(ASMJIT_DISABLE_NAMES) && !defined(ASMJIT_DISABLE_LOGGER) @@ -42,7 +43,7 @@ #endif // ASMJIT_DISABLE_NAMES && !ASMJIT_DISABLE_LOGGER // ============================================================================ -// [asmjit::build - OS] +// [asmjit::Build - OS] // ============================================================================ #if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(_WIN64) @@ -57,34 +58,41 @@ # define ASMJIT_OS_POSIX # define ASMJIT_OS_MAC #else -# warning "AsmJit - Unable to detect host operating system, using ASMJIT_OS_POSIX" +# pragma message("AsmJit - Unable to detect host operating system, using ASMJIT_OS_POSIX.") # define ASMJIT_OS_POSIX #endif // ============================================================================ -// [asmjit::build - Arch] +// [asmjit::Build - Arch] // ============================================================================ -#if defined(_M_X64 ) || \ - defined(_M_AMD64 ) || \ - defined(_WIN64 ) || \ +// [X64] +#if defined(__x86_64__) || \ defined(__amd64__ ) || \ defined(__LP64 ) || \ - defined(__x86_64__) -# define ASMJIT_HOST_X64 -# define ASMJIT_HOST_LE -# define ASMJIT_HOST_UNALIGNED_16 -# define ASMJIT_HOST_UNALIGNED_32 -# define ASMJIT_HOST_UNALIGNED_64 + defined(_M_X64 ) || \ + defined(_M_AMD64 ) || \ + defined(_WIN64 ) + +# define ASMJIT_ARCH_X64 +# define ASMJIT_ARCH_LE +# define ASMJIT_ARCH_UNALIGNED_16 +# define ASMJIT_ARCH_UNALIGNED_32 +# define ASMJIT_ARCH_UNALIGNED_64 + +// [X86] #elif \ defined(_M_IX86 ) || \ defined(__INTEL__) || \ defined(__i386__ ) -# define ASMJIT_HOST_X86 -# define ASMJIT_HOST_LE -# define ASMJIT_HOST_UNALIGNED_16 -# define ASMJIT_HOST_UNALIGNED_32 -# define ASMJIT_HOST_UNALIGNED_64 + +# define ASMJIT_ARCH_X86 +# define ASMJIT_ARCH_LE +# define ASMJIT_ARCH_UNALIGNED_16 +# define ASMJIT_ARCH_UNALIGNED_32 +# define ASMJIT_ARCH_UNALIGNED_64 + +// [Arm] #elif \ defined(_ARM ) || \ defined(_M_ARM_FP ) || \ @@ -94,14 +102,17 @@ defined(__TARGET_ARCH_ARM ) || \ defined(__TARGET_ARCH_THUMB) || \ defined(__thumb__ ) -# define ASMJIT_HOST_ARM -# define ASMJIT_HOST_LE + +# define ASMJIT_ARCH_ARM +# define ASMJIT_ARCH_LE + +// [Unknown] #else -# warning "AsmJit - Unable to detect host architecture" +# error "AsmJit - Unable to detect host architecture." #endif // ============================================================================ -// [asmjit::build - Build] +// [asmjit::Build - Build] // ============================================================================ // Build host architecture if no architecture is selected. @@ -113,16 +124,16 @@ // Autodetect host architecture if enabled. #if defined(ASMJIT_BUILD_HOST) -# if defined(ASMJIT_HOST_X86) && !defined(ASMJIT_BUILD_X86) +# if defined(ASMJIT_ARCH_X86) && !defined(ASMJIT_BUILD_X86) # define ASMJIT_BUILD_X86 -# endif // ASMJIT_HOST_X86 && !ASMJIT_BUILD_X86 -# if defined(ASMJIT_HOST_X64) && !defined(ASMJIT_BUILD_X64) +# endif // ASMJIT_ARCH_X86 && !ASMJIT_BUILD_X86 +# if defined(ASMJIT_ARCH_X64) && !defined(ASMJIT_BUILD_X64) # define ASMJIT_BUILD_X64 -# endif // ASMJIT_HOST_X64 && !ASMJIT_BUILD_X64 +# endif // ASMJIT_ARCH_X64 && !ASMJIT_BUILD_X64 #endif // ASMJIT_BUILD_HOST // ============================================================================ -// [asmjit::build - Decorators] +// [asmjit::Build - Decorators] // ============================================================================ #if defined(ASMJIT_EMBED) && !defined(ASMJIT_STATIC) @@ -179,7 +190,7 @@ # define ASMJIT_INLINE inline #endif -#if defined(ASMJIT_HOST_X86) +#if defined(ASMJIT_ARCH_X86) # if defined(__GNUC__) || defined(__clang__) # define ASMJIT_REGPARM_1 __attribute__((regparm(1))) # define ASMJIT_REGPARM_2 __attribute__((regparm(2))) @@ -196,20 +207,20 @@ # define ASMJIT_FASTCALL # define ASMJIT_STDCALL # define ASMJIT_CDECL -#endif // ASMJIT_HOST_X86 +#endif // ASMJIT_ARCH_X86 // ============================================================================ -// [asmjit::build - Enum] +// [asmjit::Build - Enum] // ============================================================================ -#if defined(_MSC_VER) +#if defined(_MSC_VER) && _MSC_VER >= 1400 # define ASMJIT_ENUM(_Name_) enum _Name_ : uint32_t #else # define ASMJIT_ENUM(_Name_) enum _Name_ #endif // ============================================================================ -// [asmjit::build - Memory Management] +// [asmjit::Build - Memory Management] // ============================================================================ #if !defined(ASMJIT_ALLOC) && !defined(ASMJIT_REALLOC) && !defined(ASMJIT_FREE) @@ -223,32 +234,32 @@ #endif // !ASMJIT_ALLOC && !ASMJIT_REALLOC && !ASMJIT_FREE // ============================================================================ -// [asmjit::build - _ASMJIT_HOST_INDEX] +// [asmjit::Build - _ASMJIT_ARCH_INDEX] // ============================================================================ -#if defined(ASMJIT_HOST_LE) -# define _ASMJIT_HOST_INDEX(_Total_, _Index_) (_Index_) +#if defined(ASMJIT_ARCH_LE) +# define _ASMJIT_ARCH_INDEX(_Total_, _Index_) (_Index_) #else -# define _ASMJIT_HOST_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_)) +# define _ASMJIT_ARCH_INDEX(_Total_, _Index_) ((_Total_) - 1 - (_Index_)) #endif // ============================================================================ -// [asmjit::build - BLEND_OFFSET_OF] +// [asmjit::Build - BLEND_OFFSET_OF] // ============================================================================ //! Cross-platform solution to get offset of `_Field_` in `_Struct_`. #define ASMJIT_OFFSET_OF(_Struct_, _Field_) \ - ((size_t) ((const uint8_t*) &((const _Struct_*)0x1)->_Field_) - 1) + static_cast((intptr_t) ((const uint8_t*) &((const _Struct_*)0x1)->_Field_) - 1) // ============================================================================ -// [asmjit::build - ASMJIT_ARRAY_SIZE] +// [asmjit::Build - ASMJIT_ARRAY_SIZE] // ============================================================================ #define ASMJIT_ARRAY_SIZE(_Array_) \ (sizeof(_Array_) / sizeof(*_Array_)) // ============================================================================ -// [asmjit::build - ASMJIT_DEBUG / ASMJIT_TRACE] +// [asmjit::Build - ASMJIT_DEBUG / ASMJIT_TRACE] // ============================================================================ // If ASMJIT_DEBUG and ASMJIT_RELEASE is not defined ASMJIT_DEBUG will be @@ -263,7 +274,7 @@ // ASMJIT_TRACE is only used by sources and private headers. It's safe to make // it unavailable outside of AsmJit. #if defined(ASMJIT_EXPORTS) -namespace asmjit { static inline int disabledTrace(...) {} } +namespace asmjit { static inline int disabledTrace(...) { return 0; } } # if defined(ASMJIT_TRACE) # define ASMJIT_TSEC(_Section_) _Section_ # define ASMJIT_TLOG ::printf(__VA_ARGS__) @@ -274,7 +285,7 @@ namespace asmjit { static inline int disabledTrace(...) {} } #endif // ASMJIT_EXPORTS // ============================================================================ -// [asmjit::build - ASMJIT_UNUSED] +// [asmjit::Build - ASMJIT_UNUSED] // ============================================================================ #if !defined(ASMJIT_UNUSED) @@ -282,7 +293,7 @@ namespace asmjit { static inline int disabledTrace(...) {} } #endif // ASMJIT_UNUSED // ============================================================================ -// [asmjit::build - ASMJIT_NOP] +// [asmjit::Build - ASMJIT_NOP] // ============================================================================ #if !defined(ASMJIT_NOP) @@ -290,7 +301,7 @@ namespace asmjit { static inline int disabledTrace(...) {} } #endif // ASMJIT_NOP // ============================================================================ -// [asmjit::build - ASMJIT_NO_COPY] +// [asmjit::Build - ASMJIT_NO_COPY] // ============================================================================ #define ASMJIT_NO_COPY(_Type_) \ @@ -300,7 +311,7 @@ private: \ public: // ============================================================================ -// [asmjit::build - StdInt] +// [asmjit::Build - StdInt] // ============================================================================ #if defined(__MINGW32__) @@ -308,7 +319,7 @@ public: #endif // __MINGW32__ #if defined(_MSC_VER) && (_MSC_VER < 1600) -# if !defined(ASMJIT_SUPRESS_STD_TYPES) +# if !defined(ASMJIT_SUPPRESS_STD_TYPES) # if (_MSC_VER < 1300) typedef signed char int8_t; typedef signed short int16_t; @@ -328,7 +339,7 @@ typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; # endif // _MSC_VER -# endif // ASMJIT_SUPRESS_STD_TYPES +# endif // ASMJIT_SUPPRESS_STD_TYPES #else # include # include @@ -343,10 +354,10 @@ typedef unsigned __int64 uint64_t; #endif // ============================================================================ -// [asmjit::build - Windows] +// [asmjit::Build - Windows] // ============================================================================ -#if defined(ASMJIT_OS_WINDOWS) && !defined(ASMJIT_SUPRESS_WINDOWS_H) +#if defined(ASMJIT_OS_WINDOWS) && !defined(ASMJIT_SUPPRESS_WINDOWS_H) # if !defined(WIN32_LEAN_AND_MEAN) # define WIN32_LEAN_AND_MEAN @@ -370,10 +381,10 @@ typedef unsigned __int64 uint64_t; # undef ASMJIT_UNDEF_WIN32_LEAN_AND_MEAN # endif -#endif // ASMJIT_OS_WINDOWS && !ASMJIT_SUPRESS_WINDOWS_H +#endif // ASMJIT_OS_WINDOWS && !ASMJIT_SUPPRESS_WINDOWS_H // ============================================================================ -// [asmjit::build - Test] +// [asmjit::Build - Test] // ============================================================================ // Include a unit testing package if this is a `asmjit_test` build. diff --git a/libraries/asmjit/contrib.h b/libraries/asmjit/contrib.h deleted file mode 100644 index dece8b362..000000000 --- a/libraries/asmjit/contrib.h +++ /dev/null @@ -1,18 +0,0 @@ -// [AsmJit] -// Complete x86/x64 JIT and Remote Assembler for C++. -// -// [License] -// Zlib - See LICENSE.md file in this package. - -// [Guard] -#ifndef _ASMJIT_CONTRIB_H -#define _ASMJIT_CONTRIB_H - -// [Dependencies - Core] -#include "base.h" - -// [Dependencies - Contrib] -#include "contrib/winremoteruntime.h" - -// [Guard] -#endif // _ASMJIT_CONTRIB_H diff --git a/libraries/asmjit/host.h b/libraries/asmjit/host.h index 48d8ce4b1..6031a5cab 100644 --- a/libraries/asmjit/host.h +++ b/libraries/asmjit/host.h @@ -5,8 +5,8 @@ // Zlib - See LICENSE.md file in the package. // [Guard] -#ifndef _ASMJIT_HOST_H -#define _ASMJIT_HOST_H +#ifndef _ASMJIT_ARCH_H +#define _ASMJIT_ARCH_H // [Dependencies - Core] #include "base.h" @@ -15,7 +15,7 @@ // [asmjit::host - X86 / X64] // ============================================================================ -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) #include "x86.h" namespace asmjit { @@ -53,7 +53,7 @@ typedef X86YmmVar YmmVar; } // asmjit namespace -#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 +#endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64 // [Guard] -#endif // _ASMJIT_HOST_H +#endif // _ASMJIT_ARCH_H diff --git a/libraries/asmjit/x86/x86assembler.cpp b/libraries/asmjit/x86/x86assembler.cpp index 29d084c79..dac4f24b6 100644 --- a/libraries/asmjit/x86/x86assembler.cpp +++ b/libraries/asmjit/x86/x86assembler.cpp @@ -29,29 +29,63 @@ namespace asmjit { // [Constants] // ============================================================================ -enum { kRexShift = 6 }; -enum { kRexForbidden = 0x80 }; enum { kMaxCommentLength = 80 }; +enum { kX86RexNoRexMask = kX86InstOptionRex | _kX86InstOptionNoRex }; -// 2-byte VEX prefix. -// [0] kVex2Byte. -// [1] RvvvvLpp. -enum { kVex2Byte = 0xC5 }; - -// 3-byte VEX prefix. -// [0] kVex3Byte. -// [1] RXBmmmmm. -// [2] WvvvvLpp. -enum { kVex3Byte = 0xC4 }; - -// 3-byte XOP prefix. -// [0] kXopByte -// [1] RXBmmmmm -// [2] WvvvvLpp -enum { kXopByte = 0x8F }; +//! \internal +//! +//! X86/X64 bytes used to encode important prefixes. +enum X86Byte { + //! 1-byte REX prefix + kX86ByteRex = 0x40, + + //! 1-byte REX.W component. + kX86ByteRexW = 0x08, + + //! 2-byte VEX prefix: + //! - `[0]` - `0xC5`. + //! - `[1]` - `RvvvvLpp`. + kX86ByteVex2 = 0xC5, + + //! 3-byte VEX prefix. + //! - `[0]` - `0xC4`. + //! - `[1]` - `RXBmmmmm`. + //! - `[2]` - `WvvvvLpp`. + kX86ByteVex3 = 0xC4, + + //! 3-byte XOP prefix. + //! - `[0]` - `0x8F`. + //! - `[1]` - `RXBmmmmm`. + //! - `[2]` - `WvvvvLpp`. + kX86ByteXop3 = 0x8F, + + //! 4-byte EVEX prefix. + //! - `[0]` - `0x62`. + //! - `[1]` - Payload0 or `P[ 7: 0]` - `[R X B R' 0 0 m m]`. + //! - `[2]` - Payload1 or `P[15: 8]` - `[W v v v v 1 p p]`. + //! - `[3]` - Payload2 or `P[23:16]` - `[z L' L b V' a a a]`. + //! + //! Groups: + //! - `P[ 1: 0]` - EXT: VEX.mmmmm, only lowest 2 bits used. + //! - `P[ 3: 2]` - ___: Must be 0. + //! - `P[ 4]` - REG: EVEX.R'. + //! - `P[ 5]` - REG: EVEX.B. + //! - `P[ 6]` - REG: EVEX.X. + //! - `P[ 7]` - REG: EVEX.R. + //! - `P[ 9: 8]` - EXT: VEX.pp. + //! - `P[ 10]` - ___: Must be 1. + //! - `P[14:11]` - REG: 2nd SRC vector register (4 bits). + //! - `P[ 15]` - EXT: VEX.W. + //! - `P[18:16]` - REG: K registers k0...k7 (Merging/Zeroing Vector Ops.). + //! - `P[ 19]` - REG: 2nd SRC vector register (Hi bit). + //! - `P[ 20]` - EXT: Broadcast/Static-Rounding/SAE bit. + //! - `P[22.21]` - EXT: Vector Length/Rounding Control. + //! - `P[ 23]` - EXT: Destination result behavior (Merging/Zeroing Vector Ops.). + kX86ByteEvex4 = 0x62 +}; // AsmJit specific (used to encode VVVV field in XOP/VEX). -enum kVexVVVV { +enum VexVVVV { kVexVVVVShift = 12, kVexVVVVMask = 0xF << kVexVVVVShift }; @@ -109,7 +143,18 @@ static const uint8_t x86OpCodePopSeg[8] = { 0x00, 0x07, 0x00, 0x17, 0x1F, 0xA1, // [Utils] // ============================================================================ -//! Encode MODR/M. +static ASMJIT_INLINE uint32_t x86RexFromOpCodeAndOptions(uint32_t opCode, uint32_t options) { + uint32_t rex = (opCode >> (kX86InstOpCode_W_Shift - 3)); + ASMJIT_ASSERT((rex & ~static_cast(0x08)) == 0); + + return rex + (options & kX86RexNoRexMask); +} + +static ASMJIT_INLINE bool x86RexIsInvalid(uint32_t rex) { + return rex >= _kX86InstOptionNoRex; +} + +//! Encode ModR/M. static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) { return (m << 6) + (o << 3) + rm; } @@ -126,6 +171,26 @@ static ASMJIT_INLINE bool x64IsRelative(Ptr a, Ptr b) { return IntUtil::isInt32(diff); } +//! Cast `reg` to `X86Reg` and get the register index. +static ASMJIT_INLINE uint32_t x86OpReg(const Operand* reg) { + return static_cast(reg)->getRegIndex(); +} + +//! Cast `mem` to `X86Mem` and return it. +static ASMJIT_INLINE const X86Mem* x86OpMem(const Operand* mem) { + return static_cast(mem); +} + +//! Combine `regIndex` and `vvvvIndex` into single value (used by AVX and AVX-512). +static ASMJIT_INLINE uint32_t x86RegAndVvvv(uint32_t regIndex, uint32_t vvvvIndex) { + return regIndex + (vvvvIndex << kVexVVVVShift); +} + +//! Get `O` field of `opCode`. +static ASMJIT_INLINE uint32_t x86ExtractO(uint32_t opCode) { + return (opCode >> kX86InstOpCode_O_Shift) & 0x7; +} + // ============================================================================ // [Macros] // ============================================================================ @@ -146,24 +211,18 @@ static ASMJIT_INLINE bool x64IsRelative(Ptr a, Ptr b) { #define ADD_REX_W(_Exp_) \ do { \ if (Arch == kArchX64) \ - opX |= static_cast(_Exp_) << 3; \ + opCode |= static_cast(_Exp_) << kX86InstOpCode_W_Shift; \ } while (0) #define ADD_REX_W_BY_SIZE(_Size_) \ do { \ - if (Arch == kArchX64) \ - opX |= static_cast(_Size_) & 0x08; \ - } while (0) - -#define ADD_REX_B(_Reg_) \ - do { \ - if (Arch == kArchX64) \ - opX |= static_cast(_Reg_) >> 3; \ + if (Arch == kArchX64 && (_Size_) == 8) \ + opCode |= kX86InstOpCode_W; \ } while (0) #define ADD_VEX_W(_Exp_) \ do { \ - opX |= static_cast(_Exp_) << 3; \ + opCode |= static_cast(_Exp_) << kX86InstOpCode_W_Shift; \ } while (0) #define ADD_VEX_L(_Exp_) \ @@ -256,19 +315,11 @@ Error X86Assembler::setArch(uint32_t arch) { _regSize = 4; _regCount.reset(); - _regCount._gp = 8; - _regCount._fp = 8; - _regCount._mm = 8; - _regCount._xy = 8; - - zax = x86::eax; - zcx = x86::ecx; - zdx = x86::edx; - zbx = x86::ebx; - zsp = x86::esp; - zbp = x86::ebp; - zsi = x86::esi; - zdi = x86::edi; + _regCount._gp = 8; + _regCount._mm = 8; + _regCount._k = 8; + _regCount._xyz = 8; + ::memcpy(&zax, &x86RegData.gpd, sizeof(Operand) * 8); return kErrorOk; } @@ -280,19 +331,11 @@ Error X86Assembler::setArch(uint32_t arch) { _regSize = 8; _regCount.reset(); - _regCount._gp = 16; - _regCount._fp = 8; - _regCount._mm = 8; - _regCount._xy = 16; - - zax = x86::rax; - zcx = x86::rcx; - zdx = x86::rdx; - zbx = x86::rbx; - zsp = x86::rsp; - zbp = x86::rbp; - zsi = x86::rsi; - zdi = x86::rdi; + _regCount._gp = 16; + _regCount._mm = 8; + _regCount._k = 8; + _regCount._xyz = 16; + ::memcpy(&zax, &x86RegData.gpq, sizeof(Operand) * 8); return kErrorOk; } @@ -316,21 +359,21 @@ Error X86Assembler::embedLabel(const Label& op) { uint8_t* cursor = getCursor(); LabelData* label = getLabelData(op.getId()); - RelocData reloc; + RelocData rd; #if !defined(ASMJIT_DISABLE_LOGGER) if (_logger) _logger->logFormat(kLoggerStyleData, regSize == 4 ? ".dd L%u\n" : ".dq L%u\n", op.getId()); #endif // !ASMJIT_DISABLE_LOGGER - reloc.type = kRelocRelToAbs; - reloc.size = regSize; - reloc.from = static_cast(getOffset()); - reloc.data = 0; + rd.type = kRelocRelToAbs; + rd.size = regSize; + rd.from = static_cast(getOffset()); + rd.data = 0; if (label->offset != -1) { // Bound label. - reloc.data = static_cast(static_cast(label->offset)); + rd.data = static_cast(static_cast(label->offset)); } else { // Non-bound label. Need to chain. @@ -344,7 +387,7 @@ Error X86Assembler::embedLabel(const Label& op) { label->links = link; } - if (_relocList.append(reloc) != kErrorOk) + if (_relocList.append(rd) != kErrorOk) return setError(kErrorNoHeapMemory); // Emit dummy intptr_t (4 or 8 bytes; depends on the address size). @@ -495,22 +538,22 @@ size_t X86Assembler::_relocCode(void* _dst, Ptr baseAddress) const { // Relocate all recorded locations. size_t relocCount = _relocList.getLength(); - const RelocData* relocData = _relocList.getData(); + const RelocData* rdList = _relocList.getData(); for (size_t i = 0; i < relocCount; i++) { - const RelocData& r = relocData[i]; + const RelocData& rd = rdList[i]; // Make sure that the `RelocData` is correct. - Ptr ptr = r.data; + Ptr ptr = rd.data; - size_t offset = static_cast(r.from); - ASMJIT_ASSERT(offset + r.size <= static_cast(maxCodeSize)); + size_t offset = static_cast(rd.from); + ASMJIT_ASSERT(offset + rd.size <= static_cast(maxCodeSize)); // Whether to use trampoline, can be only used if relocation type is // kRelocAbsToRel on 64-bit. bool useTrampoline = false; - switch (r.type) { + switch (rd.type) { case kRelocAbsToAbs: break; @@ -519,13 +562,13 @@ size_t X86Assembler::_relocCode(void* _dst, Ptr baseAddress) const { break; case kRelocAbsToRel: - ptr -= baseAddress + r.from + 4; + ptr -= baseAddress + rd.from + 4; break; case kRelocTrampoline: - ptr -= baseAddress + r.from + 4; + ptr -= baseAddress + rd.from + 4; if (!IntUtil::isInt32(static_cast(ptr))) { - ptr = (Ptr)tramp - (baseAddress + r.from + 4); + ptr = (Ptr)tramp - (baseAddress + rd.from + 4); useTrampoline = true; } break; @@ -534,7 +577,7 @@ size_t X86Assembler::_relocCode(void* _dst, Ptr baseAddress) const { ASMJIT_ASSERT(!"Reached"); } - switch (r.size) { + switch (rd.size) { case 8: *reinterpret_cast(dst + offset) = static_cast(ptr); break; @@ -547,7 +590,7 @@ size_t X86Assembler::_relocCode(void* _dst, Ptr baseAddress) const { ASMJIT_ASSERT(!"Reached"); } - // Handle the case where trampoline has been used. + // Handle the trampoline case. if (useTrampoline) { // Bytes that replace [REX, OPCODE] bytes. uint32_t byte0 = 0xFF; @@ -566,14 +609,14 @@ size_t X86Assembler::_relocCode(void* _dst, Ptr baseAddress) const { dst[offset - 1] = byte1; // Absolute address. - ((uint64_t*)tramp)[0] = static_cast(r.data); + ((uint64_t*)tramp)[0] = static_cast(rd.data); // Advance trampoline pointer. tramp += 8; #if !defined(ASMJIT_DISABLE_LOGGER) if (logger) - logger->logFormat(kLoggerStyleComment, "; Trampoline %llX\n", r.data); + logger->logFormat(kLoggerStyleComment, "; Trampoline %llX\n", rd.data); #endif // !ASMJIT_DISABLE_LOGGER } } @@ -822,7 +865,8 @@ static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Ope static bool X86Assembler_dumpInstruction(StringBuilder& sb, uint32_t arch, - uint32_t code, uint32_t options, + uint32_t code, + uint32_t options, const Operand* o0, const Operand* o1, const Operand* o2, @@ -869,22 +913,22 @@ static bool X86Assembler_dumpInstruction(StringBuilder& sb, return true; } -static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_t* binData, size_t binLength, size_t dispSize, const char* comment) { - size_t currentLength = len; - size_t commentLength = comment ? StringUtil::nlen(comment, kMaxCommentLength) : 0; +static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_t* binData, size_t binLen, size_t dispLen, size_t imLen, const char* comment) { + size_t currentLen = len; + size_t commentLen = comment ? StringUtil::nlen(comment, kMaxCommentLength) : 0; - ASMJIT_ASSERT(binLength >= dispSize); + ASMJIT_ASSERT(binLen >= dispLen); - if (binLength || commentLength) { + if (binLen || commentLen) { size_t align = 36; char sep = ';'; - for (size_t i = (binLength == 0); i < 2; i++) { + for (size_t i = (binLen == 0); i < 2; i++) { size_t begin = sb.getLength(); // Append align. - if (currentLength < align) { - if (!sb.appendChars(' ', align - currentLength)) + if (currentLen < align) { + if (!sb.appendChars(' ', align - currentLen)) return false; } @@ -896,19 +940,21 @@ static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_ // Append binary data or comment. if (i == 0) { - if (!sb.appendHex(binData, binLength - dispSize)) + if (!sb.appendHex(binData, binLen - dispLen - imLen)) + return false; + if (!sb.appendChars('.', dispLen * 2)) return false; - if (!sb.appendChars('.', dispSize * 2)) + if (!sb.appendHex(binData + binLen - imLen, imLen)) return false; - if (commentLength == 0) + if (commentLen == 0) break; } else { - if (!sb.appendString(comment, commentLength)) + if (!sb.appendString(comment, commentLen)) return false; } - currentLength += sb.getLength() - begin; + currentLen += sb.getLength() - begin; align += 22; sep = '|'; } @@ -922,16 +968,18 @@ static bool X86Assembler_dumpComment(StringBuilder& sb, size_t len, const uint8_ // [asmjit::X86Assembler - Emit] // ============================================================================ +#define HI_REG(_Index_) ((_kX86RegTypePatchedGpbHi << 8) | _Index_) //! \internal static const Operand::VRegOp x86PatchedHiRegs[4] = { - // --------------+---+--------------------------------+--------------+------+ - // Operand | S | Register Code | OperandId |Unused| - // --------------+---+--------------------------------+--------------+------+ - { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 4, kInvalidValue, 0, 0 }, - { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 5, kInvalidValue, 0, 0 }, - { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 6, kInvalidValue, 0, 0 }, - { kOperandTypeReg, 1 , (_kX86RegTypePatchedGpbHi << 8) | 7, kInvalidValue, 0, 0 } + // --------------+---+--------------+--------------+------------+ + // Operand | S | Reg. Code | OperandId | Unused | + // --------------+---+--------------+--------------+------------+ + { kOperandTypeReg, 1 , { HI_REG(4) }, kInvalidValue, {{ 0, 0 }} }, + { kOperandTypeReg, 1 , { HI_REG(5) }, kInvalidValue, {{ 0, 0 }} }, + { kOperandTypeReg, 1 , { HI_REG(6) }, kInvalidValue, {{ 0, 0 }} }, + { kOperandTypeReg, 1 , { HI_REG(7) }, kInvalidValue, {{ 0, 0 }} } }; +#undef HI_REG template static Error ASMJIT_CDECL X86Assembler_emit(Assembler* self_, uint32_t code, const Operand* o0, const Operand* o1, const Operand* o2, const Operand* o3) { @@ -949,27 +997,15 @@ static Error ASMJIT_CDECL X86Assembler_emit(Assembler* self_, uint32_t code, con // Instruction opcode. uint32_t opCode; - // MODR/R opcode or register code. + // ModR/M opcode or register code. uint32_t opReg; - // REX or VEX prefix data. - // - // REX: - // 0x0008 - REX.W. - // 0x0040 - Always emit REX prefix. - // - // AVX: - // 0x0008 - AVX.W. - // 0xF000 - VVVV, zeros by default, see `kVexVVVV`. - // - uint32_t opX; - - // MOD/RM, both rmReg and rmMem should refer to the same variable since they - // are never used together - either rmReg or rmMem. + // ModR/M, both rmReg and rmMem should refer to the same variable since they + // are never used together - either `rmReg` or `rmMem`. union { - // MODR/M - register code. + // ModR/M - register code. uintptr_t rmReg; - // MODR/M - Memory operand. + // ModR/M - Memory operand. const X86Mem* rmMem; }; @@ -1010,49 +1046,43 @@ static Error ASMJIT_CDECL X86Assembler_emit(Assembler* self_, uint32_t code, con _Prepare: opCode = info.getPrimaryOpCode(); - opReg = opCode >> kX86InstOpCode_O_Shift; - opX = extendedInfo.getInstFlags() >> (15 - 3); + opReg = x86ExtractO(opCode); if (Arch == kArchX86) { - // AVX.W prefix. - opX &= 0x08; - // Check if one or more register operand is one of AH, BH, CH, or DH and // patch them to ensure that the binary code with correct byte-index (4-7) // is generated. if (o0->isRegType(kX86RegTypeGpbHi)) - o0 = (const Operand*)(&x86PatchedHiRegs[static_cast(o0)->getRegIndex()]); + o0 = (const Operand*)(&x86PatchedHiRegs[x86OpReg(o0)]); if (o1->isRegType(kX86RegTypeGpbHi)) - o1 = (const Operand*)(&x86PatchedHiRegs[static_cast(o1)->getRegIndex()]); + o1 = (const Operand*)(&x86PatchedHiRegs[x86OpReg(o1)]); } else { - ASMJIT_ASSERT(kX86InstOptionRex == 0x40); - - // AVX.W prefix and REX prefix. - opX |= options; - opX &= 0x48; + // `W` field. + ASMJIT_ASSERT(static_cast(kX86InstOptionRex) == + static_cast(kX86ByteRex)); // Check if one or more register operand is one of BPL, SPL, SIL, DIL and - // force a REX prefix in such case. + // force a REX prefix to be emitted in such case. if (X86Reg::isGpbReg(*o0)) { - uint32_t index = static_cast(o0)->getRegIndex(); + uint32_t index = x86OpReg(o0); if (static_cast(o0)->isGpbLo()) { - opX |= (index >= 4) << kRexShift; + options |= (index >= 4) ? kX86InstOptionRex : 0; } else { - opX |= kRexForbidden; + options |= _kX86InstOptionNoRex; o0 = reinterpret_cast(&x86PatchedHiRegs[index]); } } if (X86Reg::isGpbReg(*o1)) { - uint32_t index = static_cast(o1)->getRegIndex(); + uint32_t index = x86OpReg(o1); if (static_cast(o1)->isGpbLo()) { - opX |= (index >= 4) << kRexShift; + options |= (index >= 4) ? kX86InstOptionRex : 0; } else { - opX |= kRexForbidden; + options |= _kX86InstOptionNoRex; o1 = reinterpret_cast(&x86PatchedHiRegs[index]); } } @@ -1072,52 +1102,52 @@ _Prepare: // [Group] // -------------------------------------------------------------------------- - switch (info.getInstGroup()) { + switch (info.getEncodingId()) { // ------------------------------------------------------------------------ // [None] // ------------------------------------------------------------------------ - case kX86InstGroupNone: + case kX86InstEncodingIdNone: goto _EmitDone; // ------------------------------------------------------------------------ // [X86] // ------------------------------------------------------------------------ - case kX86InstGroupX86Op_66H: + case kX86InstEncodingIdX86Op_66H: ADD_66H_P(true); // ... Fall through ... - case kX86InstGroupX86Op: + case kX86InstEncodingIdX86Op: goto _EmitX86Op; - case kX86InstGroupX86Rm_B: + case kX86InstEncodingIdX86Rm_B: opCode += o0->getSize() != 1; // ... Fall through ... - case kX86InstGroupX86Rm: + case kX86InstEncodingIdX86Rm: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86RmReg: + case kX86InstEncodingIdX86RmReg: if (encoded == ENC_OPS(Reg, Reg, None)) { opCode += o0->getSize() != 1; ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -1126,58 +1156,58 @@ _Prepare: ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86RegRm: + case kX86InstEncodingIdX86RegRm: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, Reg, None)) { ASMJIT_ASSERT(o0->getSize() != 1); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { ASMJIT_ASSERT(o0->getSize() != 1); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupX86M: + case kX86InstEncodingIdX86M: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Arith: + case kX86InstEncodingIdX86Arith: if (encoded == ENC_OPS(Reg, Reg, None)) { - opCode +=(o0->getSize() != 1) + 2; + opCode += (o0->getSize() != 1) + 2; ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opCode +=(o0->getSize() != 1) + 2; + opCode += (o0->getSize() != 1) + 2; ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } @@ -1186,8 +1216,8 @@ _Prepare: ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } @@ -1197,7 +1227,7 @@ _Prepare: if (encoded == ENC_OPS(Reg, Imm, None)) { imVal = static_cast(o1)->getInt64(); imLen = IntUtil::isInt8(imVal) ? static_cast(1) : IntUtil::iMin(o0->getSize(), 4); - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); @@ -1206,7 +1236,7 @@ _Prepare: if (rmReg == 0 && (o0->getSize() == 1 || imLen != 1)) { opCode = ((opReg << 3) | (0x04 + (o0->getSize() != 1))); imLen = IntUtil::iMin(o0->getSize(), 4); - goto _EmitX86OpI; + goto _EmitX86Op; } opCode += o0->getSize() != 1 ? (imLen != 1 ? 1 : 3) : 0; @@ -1226,29 +1256,26 @@ _Prepare: ADD_66H_P_BY_SIZE(memSize); ADD_REX_W_BY_SIZE(memSize); - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86BSwap: + case kX86InstEncodingIdX86BSwap: if (encoded == ENC_OPS(Reg, None, None)) { - opReg = static_cast(o0)->getRegIndex(); - opCode += opReg & 0x7; - + opReg = x86OpReg(o0); ADD_REX_W_BY_SIZE(o0->getSize()); - ADD_REX_B(opReg); - goto _EmitX86Op; + goto _EmitX86OpWithOpReg; } break; - case kX86InstGroupX86BTest: + case kX86InstEncodingIdX86BTest: if (encoded == ENC_OPS(Reg, Reg, None)) { ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -1256,8 +1283,8 @@ _Prepare: ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } @@ -1266,13 +1293,13 @@ _Prepare: imLen = 1; opCode = extendedInfo.getSecondaryOpCode(); - opReg = opCode >> kX86InstOpCode_O_Shift; + opReg = x86ExtractO(opCode); ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, Imm, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -1280,19 +1307,19 @@ _Prepare: if (o0->getSize() == 0) goto _IllegalInst; - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Call: + case kX86InstEncodingIdX86Call: if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } @@ -1327,7 +1354,7 @@ _Prepare: } break; - case kX86InstGroupX86Enter: + case kX86InstEncodingIdX86Enter: if (encoded == ENC_OPS(Imm, Imm, None)) { EMIT_BYTE(0xC8); EMIT_WORD(static_cast(o1)->getUInt16()); @@ -1336,35 +1363,37 @@ _Prepare: } break; - case kX86InstGroupX86Imul: + case kX86InstEncodingIdX86Imul: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, None, None)) { - opCode = 0xF6 + (o0->getSize() != 1); + opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W; + opCode |= 0xF6 + (o0->getSize() != 1); opReg = 5; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { - opCode = 0xF6 + (o0->getSize() != 1); + opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W; + opCode |= 0xF6 + (o0->getSize() != 1); opReg = 5; - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } // The following instructions use 0x0FAF opcode. - opCode &= kX86InstOpCode_PP_66; + opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W; opCode |= kX86InstOpCode_MM_0F | 0xAF; if (encoded == ENC_OPS(Reg, Reg, None)) { ASMJIT_ASSERT(o0->getSize() != 1); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } @@ -1372,14 +1401,14 @@ _Prepare: if (encoded == ENC_OPS(Reg, Mem, None)) { ASMJIT_ASSERT(o0->getSize() != 1); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } // The following instructions use 0x69/0x6B opcode. - opCode &= kX86InstOpCode_PP_66; + opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W; opCode |= 0x6B; if (encoded == ENC_OPS(Reg, Imm, None)) { @@ -1393,7 +1422,7 @@ _Prepare: imLen = o0->getSize() == 2 ? 2 : 4; } - opReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o0); rmReg = opReg; goto _EmitX86R; } @@ -1409,8 +1438,8 @@ _Prepare: imLen = o0->getSize() == 2 ? 2 : 4; } - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } @@ -1425,22 +1454,22 @@ _Prepare: imLen = o0->getSize() == 2 ? 2 : 4; } - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupX86IncDec: + case kX86InstEncodingIdX86IncDec: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); // INC r16|r32 is not encodable in 64-bit mode. if (Arch == kArchX86 && (o0->getSize() == 2 || o0->getSize() == 4)) { - opCode &= kX86InstOpCode_PP_66; + opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W; opCode |= extendedInfo.getSecondaryOpCode() + (static_cast(rmReg) & 0x7); goto _EmitX86Op; } @@ -1452,12 +1481,12 @@ _Prepare: if (encoded == ENC_OPS(Mem, None, None)) { opCode += o0->getSize() != 1; - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Int: + case kX86InstEncodingIdX86Int: if (encoded == ENC_OPS(Imm, None, None)) { imVal = static_cast(o0)->getInt64(); uint8_t imm8 = static_cast(imVal & 0xFF); @@ -1473,7 +1502,7 @@ _Prepare: } break; - case kX86InstGroupX86Jcc: + case kX86InstEncodingIdX86Jcc: if (encoded == ENC_OPS(Label, None, None)) { label = self->getLabelData(static_cast(o0)->getId()); @@ -1529,9 +1558,9 @@ _Prepare: } break; - case kX86InstGroupX86Jecxz: + case kX86InstEncodingIdX86Jecxz: if (encoded == ENC_OPS(Reg, Label, None)) { - ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == kX86RegIndexCx); + ASMJIT_ASSERT(x86OpReg(o0) == kX86RegIndexCx); if ((Arch == kArchX86 && o0->getSize() == 2) || (Arch == kArchX64 && o0->getSize() == 4)) { @@ -1560,14 +1589,14 @@ _Prepare: } break; - case kX86InstGroupX86Jmp: + case kX86InstEncodingIdX86Jmp: if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } @@ -1623,21 +1652,21 @@ _Prepare: } break; - case kX86InstGroupX86Lea: + case kX86InstEncodingIdX86Lea: if (encoded == ENC_OPS(Reg, Mem, None)) { ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupX86Mov: + case kX86InstEncodingIdX86Mov: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); // Sreg <- Reg if (static_cast(o0)->isSeg()) { @@ -1674,8 +1703,8 @@ _Prepare: } if (encoded == ENC_OPS(Reg, Mem, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); // Sreg <- Mem if (static_cast(o0)->isRegType(kX86RegTypeSeg)) { @@ -1699,8 +1728,8 @@ _Prepare: } if (encoded == ENC_OPS(Mem, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); // X86Mem <- Sreg if (static_cast(o1)->isSeg()) { @@ -1728,7 +1757,7 @@ _Prepare: imLen = o0->getSize(); opReg = 0; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); // Optimize instruction size by using 32-bit immediate if possible. if (Arch == kArchX64 && imLen == 8 && IntUtil::isInt32(imVal)) { @@ -1738,10 +1767,11 @@ _Prepare: goto _EmitX86R; } else { - opCode = 0xB0 + (static_cast(o0->getSize() != 1) << 3) + (static_cast(rmReg) & 0x7); + opCode = 0xB0 + (static_cast(o0->getSize() != 1) << 3); + opReg = rmReg; + ADD_REX_W_BY_SIZE(imLen); - ADD_REX_B(rmReg); - goto _EmitX86OpI; + goto _EmitX86OpWithOpReg; } } @@ -1759,19 +1789,19 @@ _Prepare: ADD_66H_P_BY_SIZE(memSize); ADD_REX_W_BY_SIZE(memSize); - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86MovSxZx: + case kX86InstEncodingIdX86MovSxZx: if (encoded == ENC_OPS(Reg, Reg, None)) { opCode += o1->getSize() != 1; ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } @@ -1780,33 +1810,33 @@ _Prepare: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupX86MovSxd: + case kX86InstEncodingIdX86MovSxd: if (encoded == ENC_OPS(Reg, Reg, None)) { ADD_REX_W(true); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { ADD_REX_W(true); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupX86MovPtr: + case kX86InstEncodingIdX86MovPtr: if (encoded == ENC_OPS(Reg, Imm, None)) { - ASMJIT_ASSERT(static_cast(o0)->getRegIndex() == 0); + ASMJIT_ASSERT(x86OpReg(o0) == 0); opCode += o0->getSize() != 1; ADD_66H_P_BY_SIZE(o0->getSize()); @@ -1814,14 +1844,14 @@ _Prepare: imVal = static_cast(o1)->getInt64(); imLen = self->_regSize; - goto _EmitX86OpI; + goto _EmitX86Op; } // The following instruction uses the secondary opcode. opCode = extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Imm, Reg, None)) { - ASMJIT_ASSERT(static_cast(o1)->getRegIndex() == 0); + ASMJIT_ASSERT(x86OpReg(o1) == 0); opCode += o1->getSize() != 1; ADD_66H_P_BY_SIZE(o1->getSize()); @@ -1829,14 +1859,14 @@ _Prepare: imVal = static_cast(o0)->getInt64(); imLen = self->_regSize; - goto _EmitX86OpI; + goto _EmitX86Op; } break; - case kX86InstGroupX86Push: + case kX86InstEncodingIdX86Push: if (encoded == ENC_OPS(Reg, None, None)) { if (o0->isRegType(kX86RegTypeSeg)) { - uint32_t segment = static_cast(o0)->getRegIndex(); + uint32_t segment = x86OpReg(o0); ASMJIT_ASSERT(segment < kX86SegCount); if (segment >= kX86SegFs) @@ -1859,10 +1889,10 @@ _Prepare: } // ... Fall through ... - case kX86InstGroupX86Pop: + case kX86InstEncodingIdX86Pop: if (encoded == ENC_OPS(Reg, None, None)) { if (o0->isRegType(kX86RegTypeSeg)) { - uint32_t segment = static_cast(o0)->getRegIndex(); + uint32_t segment = x86OpReg(o0); ASMJIT_ASSERT(segment < kX86SegCount); if (segment >= kX86SegFs) @@ -1876,30 +1906,28 @@ _GroupPop_Gp: ASMJIT_ASSERT(static_cast(o0)->getSize() == 2 || static_cast(o0)->getSize() == self->_regSize); - opReg = static_cast(o0)->getRegIndex(); - opCode = extendedInfo.getSecondaryOpCode() + (opReg & 7); + opCode = extendedInfo.getSecondaryOpCode(); + opReg = x86OpReg(o0); ADD_66H_P_BY_SIZE(o0->getSize()); - ADD_REX_B(opReg); - - goto _EmitX86Op; + goto _EmitX86OpWithOpReg; } } if (encoded == ENC_OPS(Mem, None, None)) { ADD_66H_P_BY_SIZE(o0->getSize()); - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Rep: + case kX86InstEncodingIdX86Rep: // Emit REP 0xF2 or 0xF3 prefix first. EMIT_BYTE(0xF2 + opReg); goto _EmitX86Op; - case kX86InstGroupX86Ret: + case kX86InstEncodingIdX86Ret: if (encoded == ENC_OPS(None, None, None)) { EMIT_BYTE(0xC3); goto _EmitDone; @@ -1919,7 +1947,7 @@ _GroupPop_Gp: } break; - case kX86InstGroupX86Rot: + case kX86InstEncodingIdX86Rot: opCode += o0->getSize() != 1; ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); @@ -1927,14 +1955,14 @@ _GroupPop_Gp: if (encoded == ENC_OPS(Reg, Reg, None)) { ASMJIT_ASSERT(static_cast(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); opCode += 2; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, Reg, None)) { ASMJIT_ASSERT(static_cast(o1)->isRegCode(kX86RegTypeGpbLo, kX86RegIndexCx)); opCode += 2; - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } @@ -1943,7 +1971,7 @@ _GroupPop_Gp: imLen = imVal != 1; if (imLen) opCode -= 0x10; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -1955,28 +1983,28 @@ _GroupPop_Gp: imLen = imVal != 1; if (imLen) opCode -= 0x10; - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Set: + case kX86InstEncodingIdX86Set: if (encoded == ENC_OPS(Reg, None, None)) { ASMJIT_ASSERT(o0->getSize() == 1); - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } if (encoded == ENC_OPS(Mem, None, None)) { ASMJIT_ASSERT(o0->getSize() <= 1); - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Shlrd: + case kX86InstEncodingIdX86Shlrd: if (encoded == ENC_OPS(Reg, Reg, Imm)) { ASMJIT_ASSERT(o0->getSize() == o1->getSize()); @@ -1986,8 +2014,8 @@ _GroupPop_Gp: imVal = static_cast(o2)->getInt64(); imLen = 1; - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -1998,8 +2026,8 @@ _GroupPop_Gp: imVal = static_cast(o2)->getInt64(); imLen = 1; - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } @@ -2013,8 +2041,8 @@ _GroupPop_Gp: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -2024,13 +2052,13 @@ _GroupPop_Gp: ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Test: + case kX86InstEncodingIdX86Test: if (encoded == ENC_OPS(Reg, Reg, None)) { ASMJIT_ASSERT(o0->getSize() == o1->getSize()); @@ -2038,8 +2066,8 @@ _GroupPop_Gp: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -2048,14 +2076,14 @@ _GroupPop_Gp: ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } // The following instructions use the secondary opcode. opCode = extendedInfo.getSecondaryOpCode() + (o0->getSize() != 1); - opReg = opCode >> kX86InstOpCode_O_Shift; + opReg = x86ExtractO(opCode); if (encoded == ENC_OPS(Reg, Imm, None)) { imVal = static_cast(o1)->getInt64(); @@ -2065,13 +2093,13 @@ _GroupPop_Gp: ADD_REX_W_BY_SIZE(o0->getSize()); // Alternate Form - AL, AX, EAX, RAX. - if (static_cast(o0)->getRegIndex() == 0) { - opCode &= kX86InstOpCode_PP_66; + if (x86OpReg(o0) == 0) { + opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W; opCode |= 0xA8 + (o0->getSize() != 1); - goto _EmitX86OpI; + goto _EmitX86Op; } - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -2085,46 +2113,38 @@ _GroupPop_Gp: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupX86Xchg: + case kX86InstEncodingIdX86Xchg: if (encoded == ENC_OPS(Reg, Mem, None)) { opCode += o0->getSize() != 1; ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } // ... fall through ... - case kX86InstGroupX86Xadd: + case kX86InstEncodingIdX86Xadd: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); // Special opcode for 'xchg ?ax, reg'. if (code == kX86InstIdXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) { - // One of them is zero, it doesn't matter if the instruction's form is - // 'xchg ?ax, reg' or 'xchg reg, ?ax'. + opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W; + opCode |= 0x90; + // One of `xchg a, b` or `xchg b, a` is AX/EAX/RAX. opReg += rmReg; - - // Rex.B (0x01). - if (Arch == kArchX64) { - opX += opReg >> 3; - opReg &= 0x7; - } - - opCode &= kX86InstOpCode_PP_66; - opCode |= 0x90 + opReg; - goto _EmitX86Op; + goto _EmitX86OpWithOpReg; } opCode += o0->getSize() != 1; @@ -2136,8 +2156,8 @@ _GroupPop_Gp: ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; @@ -2146,13 +2166,13 @@ _GroupPop_Gp: // [Fpu] // ------------------------------------------------------------------------ - case kX86InstGroupFpuOp: + case kX86InstEncodingIdFpuOp: goto _EmitFpuOp; - case kX86InstGroupFpuArith: + case kX86InstEncodingIdFpuArith: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); rmReg += opReg; // We switch to the alternative opcode if the first operand is zero. @@ -2172,19 +2192,19 @@ _EmitFpArith_Reg: // set already. _EmitFpArith_Mem: opCode = (o0->getSize() == 4) ? 0xD8 : 0xDC; - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupFpuCom: + case kX86InstEncodingIdFpuCom: if (encoded == ENC_OPS(None, None, None)) { rmReg = 1; goto _EmitFpArith_Reg; } if (encoded == ENC_OPS(Reg, None, None)) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitFpArith_Reg; } @@ -2193,9 +2213,9 @@ _EmitFpArith_Mem: } break; - case kX86InstGroupFpuFldFst: + case kX86InstEncodingIdFpuFldFst: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); if (o0->getSize() == 4 && info.hasInstFlag(kX86InstFlagMem4)) { goto _EmitX86M; @@ -2208,33 +2228,33 @@ _EmitFpArith_Mem: if (o0->getSize() == 10 && info.hasInstFlag(kX86InstFlagMem10)) { opCode = extendedInfo.getSecondaryOpCode(); - opReg = opCode >> kX86InstOpCode_O_Shift; + opReg = x86ExtractO(opCode); goto _EmitX86M; } } if (encoded == ENC_OPS(Reg, None, None)) { if (code == kX86InstIdFld) { - opCode = 0xD9C0 + static_cast(o0)->getRegIndex(); + opCode = 0xD9C0 + x86OpReg(o0); goto _EmitFpuOp; } if (code == kX86InstIdFst) { - opCode = 0xDDD0 + static_cast(o0)->getRegIndex(); + opCode = 0xDDD0 + x86OpReg(o0); goto _EmitFpuOp; } if (code == kX86InstIdFstp) { - opCode = 0xDDD8 + static_cast(o0)->getRegIndex(); + opCode = 0xDDD8 + x86OpReg(o0); goto _EmitFpuOp; } } break; - case kX86InstGroupFpuM: + case kX86InstEncodingIdFpuM: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); if (o0->getSize() == 2 && info.hasInstFlag(kX86InstFlagMem2)) { opCode += 4; @@ -2247,37 +2267,37 @@ _EmitFpArith_Mem: if (o0->getSize() == 8 && info.hasInstFlag(kX86InstFlagMem8)) { opCode = extendedInfo.getSecondaryOpCode(); - opReg = opCode >> kX86InstOpCode_O_Shift; + opReg = x86ExtractO(opCode); goto _EmitX86M; } } break; - case kX86InstGroupFpuRDef: + case kX86InstEncodingIdFpuRDef: if (encoded == ENC_OPS(None, None, None)) { opCode += 1; goto _EmitFpuOp; } // ... Fall through ... - case kX86InstGroupFpuR: + case kX86InstEncodingIdFpuR: if (encoded == ENC_OPS(Reg, None, None)) { - opCode += static_cast(o0)->getRegIndex(); + opCode += x86OpReg(o0); goto _EmitFpuOp; } break; - case kX86InstGroupFpuStsw: + case kX86InstEncodingIdFpuStsw: if (encoded == ENC_OPS(Reg, None, None)) { - if (static_cast(o0)->getRegIndex() != 0) + if (x86OpReg(o0) != 0) goto _IllegalInst; opCode = extendedInfo.getSecondaryOpCode(); - goto _EmitX86Op; + goto _EmitFpuOp; } if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; @@ -2286,7 +2306,7 @@ _EmitFpArith_Mem: // [Ext] // ------------------------------------------------------------------------ - case kX86InstGroupExtCrc: + case kX86InstEncodingIdExtCrc: ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); @@ -2295,8 +2315,8 @@ _EmitFpArith_Mem: static_cast(o0)->getRegType() == kX86RegTypeGpq); opCode += o0->getSize() != 1; - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } @@ -2305,21 +2325,21 @@ _EmitFpArith_Mem: static_cast(o0)->getRegType() == kX86RegTypeGpq); opCode += o0->getSize() != 1; - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupExtExtract: + case kX86InstEncodingIdExtExtract: if (encoded == ENC_OPS(Reg, Reg, Imm)) { ADD_66H_P(static_cast(o1)->isXmm()); imVal = static_cast(o2)->getInt64(); imLen = 1; - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitX86R; } @@ -2331,15 +2351,15 @@ _EmitFpArith_Mem: imVal = static_cast(o2)->getInt64(); imLen = 1; - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupExtFence: - if (Arch == kArchX64 && opX) { - EMIT_BYTE(0x40 | opX); + case kX86InstEncodingIdExtFence: + if (Arch == kArchX64 && (opCode & kX86InstOpCode_W_Mask)) { + EMIT_BYTE(kX86ByteRex | kX86ByteRexW); } EMIT_BYTE(0x0F); @@ -2347,8 +2367,8 @@ _EmitFpArith_Mem: EMIT_BYTE(0xC0 | (opReg << 3)); goto _EmitDone; - case kX86InstGroupExtMov: - case kX86InstGroupExtMovNoRexW: + case kX86InstEncodingIdExtMov: + case kX86InstEncodingIdExtMovNoRexW: ASMJIT_ASSERT(extendedInfo._opFlags[0] != 0); ASMJIT_ASSERT(extendedInfo._opFlags[1] != 0); @@ -2366,20 +2386,20 @@ _EmitFpArith_Mem: // Gp|Mm|Xmm <- Gp|Mm|Xmm if (encoded == ENC_OPS(Reg, Reg, None)) { - ADD_REX_W(static_cast(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); - ADD_REX_W(static_cast(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o0)->isGpq() && (info.getEncodingId() != kX86InstEncodingIdExtMovNoRexW)); + ADD_REX_W(static_cast(o1)->isGpq() && (info.getEncodingId() != kX86InstEncodingIdExtMovNoRexW)); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } // Gp|Mm|Xmm <- Mem if (encoded == ENC_OPS(Reg, Mem, None)) { - ADD_REX_W(static_cast(o0)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o0)->isGpq() && (info.getEncodingId() != kX86InstEncodingIdExtMovNoRexW)); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } @@ -2388,21 +2408,21 @@ _EmitFpArith_Mem: // X86Mem <- Gp|Mm|Xmm if (encoded == ENC_OPS(Mem, Reg, None)) { - ADD_REX_W(static_cast(o1)->isGpq() && (info.getInstGroup() != kX86InstGroupExtMovNoRexW)); + ADD_REX_W(static_cast(o1)->isGpq() && (info.getEncodingId() != kX86InstEncodingIdExtMovNoRexW)); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupExtMovBe: + case kX86InstEncodingIdExtMovBe: if (encoded == ENC_OPS(Reg, Mem, None)) { ADD_66H_P_BY_SIZE(o0->getSize()); ADD_REX_W_BY_SIZE(o0->getSize()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } @@ -2413,51 +2433,51 @@ _EmitFpArith_Mem: ADD_66H_P_BY_SIZE(o1->getSize()); ADD_REX_W_BY_SIZE(o1->getSize()); - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupExtMovD: + case kX86InstEncodingIdExtMovD: _EmitMmMovD: - opReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o0); ADD_66H_P(static_cast(o0)->isXmm()); // Mm/Xmm <- Gp if (encoded == ENC_OPS(Reg, Reg, None) && static_cast(o1)->isGp()) { - rmReg = static_cast(o1)->getRegIndex(); + rmReg = x86OpReg(o1); goto _EmitX86R; } // Mm/Xmm <- Mem if (encoded == ENC_OPS(Reg, Mem, None)) { - rmMem = static_cast(o1); + rmMem = x86OpMem(o1); goto _EmitX86M; } // The following instructions use the secondary opcode. opCode = extendedInfo.getSecondaryOpCode(); - opReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o1); ADD_66H_P(static_cast(o1)->isXmm()); // Gp <- Mm/Xmm if (encoded == ENC_OPS(Reg, Reg, None) && static_cast(o0)->isGp()) { - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } // X86Mem <- Mm/Xmm if (encoded == ENC_OPS(Mem, Reg, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupExtMovQ: + case kX86InstEncodingIdExtMovQ: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); // Mm <- Mm if (static_cast(o0)->isMm() && static_cast(o1)->isMm()) { @@ -2485,8 +2505,8 @@ _EmitMmMovD: } if (encoded == ENC_OPS(Reg, Mem, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); // Mm <- Mem if (static_cast(o0)->isMm()) { @@ -2502,8 +2522,8 @@ _EmitMmMovD: } if (encoded == ENC_OPS(Mem, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); // X86Mem <- Mm if (static_cast(o1)->isMm()) { @@ -2519,108 +2539,106 @@ _EmitMmMovD: } if (Arch == kArchX64) { - // Movq in other case is simply a promoted MOVD instruction to 64-bit. - ADD_REX_W(true); - - opCode = kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | 0x6E; + // Movq in other case is simply a MOVD instruction promoted to 64-bit. + opCode |= kX86InstOpCode_W; goto _EmitMmMovD; } break; - case kX86InstGroupExtPrefetch: + case kX86InstEncodingIdExtPrefetch: if (encoded == ENC_OPS(Mem, Imm, None)) { opReg = static_cast(o1)->getUInt32() & 0x3; - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitX86M; } break; - case kX86InstGroupExtRm_PQ: + case kX86InstEncodingIdExtRm_PQ: ADD_66H_P(o0->isRegType(kX86RegTypeXmm) || o1->isRegType(kX86RegTypeXmm)); // ... Fall through ... - case kX86InstGroupExtRm_Q: + case kX86InstEncodingIdExtRm_Q: ADD_REX_W(o0->isRegType(kX86RegTypeGpq) || o1->isRegType(kX86RegTypeGpq) || (o1->isMem() && o1->getSize() == 8)); // ... Fall through ... - case kX86InstGroupExtRm: + case kX86InstEncodingIdExtRm: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupExtRm_P: + case kX86InstEncodingIdExtRm_P: if (encoded == ENC_OPS(Reg, Reg, None)) { ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { ADD_66H_P(static_cast(o0)->isXmm()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupExtRmRi: + case kX86InstEncodingIdExtRmRi: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } // The following instruction uses the secondary opcode. opCode = extendedInfo.getSecondaryOpCode(); - opReg = opCode >> kX86InstOpCode_O_Shift; + opReg = x86ExtractO(opCode); if (encoded == ENC_OPS(Reg, Imm, None)) { imVal = static_cast(o1)->getInt64(); imLen = 1; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } break; - case kX86InstGroupExtRmRi_P: + case kX86InstEncodingIdExtRmRi_P: if (encoded == ENC_OPS(Reg, Reg, None)) { ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { ADD_66H_P(static_cast(o0)->isXmm()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } // The following instruction uses the secondary opcode. opCode = extendedInfo.getSecondaryOpCode(); - opReg = opCode >> kX86InstOpCode_O_Shift; + opReg = x86ExtractO(opCode); if (encoded == ENC_OPS(Reg, Imm, None)) { ADD_66H_P(static_cast(o0)->isXmm()); @@ -2628,69 +2646,112 @@ _EmitMmMovD: imVal = static_cast(o1)->getInt64(); imLen = 1; - rmReg = static_cast(o0)->getRegIndex(); + rmReg = x86OpReg(o0); goto _EmitX86R; } break; - case kX86InstGroupExtRmi: + case kX86InstEncodingIdExtRmi: imVal = static_cast(o2)->getInt64(); imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; - case kX86InstGroupExtRmi_P: + case kX86InstEncodingIdExtRmi_P: imVal = static_cast(o2)->getInt64(); imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { ADD_66H_P(static_cast(o0)->isXmm() | static_cast(o1)->isXmm()); - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { ADD_66H_P(static_cast(o0)->isXmm()); - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; + // ------------------------------------------------------------------------ + // [Group - Extrq / Insertq (SSE4a)] + // ------------------------------------------------------------------------ + + case kX86InstEncodingIdExtExtrq: + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); + + if (encoded == ENC_OPS(Reg, Reg, None)) + goto _EmitX86R; + + // The following instruction uses the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Reg, Imm, Imm)) { + imVal = (static_cast(o1)->getUInt32() ) + + (static_cast(o2)->getUInt32() << 8) ; + imLen = 2; + + rmReg = opReg; + opReg = x86ExtractO(opCode); + goto _EmitX86R; + } + break; + + case kX86InstEncodingIdExtInsertq: + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); + + if (encoded == ENC_OPS(Reg, Reg, None)) + goto _EmitX86R; + + // The following instruction uses the secondary opcode. + opCode = extendedInfo.getSecondaryOpCode(); + + if (encoded == ENC_OPS(Reg, Reg, Imm) && o3->isImm()) { + imVal = (static_cast(o2)->getUInt32() ) + + (static_cast(o3)->getUInt32() << 8) ; + imLen = 2; + goto _EmitX86R; + } + break; + // ------------------------------------------------------------------------ // [Group - 3dNow] // ------------------------------------------------------------------------ - case kX86InstGroup3dNow: + case kX86InstEncodingId3dNow: // Every 3dNow instruction starts with 0x0F0F and the actual opcode is // stored as 8-bit immediate. imVal = opCode & 0xFF; imLen = 1; opCode = kX86InstOpCode_MM_0F | 0x0F; - opReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o0); if (encoded == ENC_OPS(Reg, Reg, None)) { - rmReg = static_cast(o1)->getRegIndex(); + rmReg = x86OpReg(o1); goto _EmitX86R; } if (encoded == ENC_OPS(Reg, Mem, None)) { - rmMem = static_cast(o1); + rmMem = x86OpMem(o1); goto _EmitX86M; } break; @@ -2699,146 +2760,142 @@ _EmitMmMovD: // [Avx] // ------------------------------------------------------------------------ - case kX86InstGroupAvxOp: + case kX86InstEncodingIdAvxOp: goto _EmitAvxOp; - case kX86InstGroupAvxM: + case kX86InstEncodingIdAvxM: if (encoded == ENC_OPS(Mem, None, None)) { - rmMem = static_cast(o0); + rmMem = x86OpMem(o0); goto _EmitAvxM; } break; - case kX86InstGroupAvxMr_P: + case kX86InstEncodingIdAvxMr_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxMr: + case kX86InstEncodingIdAvxMr: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitAvxR; } if (encoded == ENC_OPS(Mem, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitAvxM; } break; - case kX86InstGroupAvxMri_P: + case kX86InstEncodingIdAvxMri_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxMri: + case kX86InstEncodingIdAvxMri: imVal = static_cast(o2)->getInt64(); imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitAvxR; } if (encoded == ENC_OPS(Mem, Reg, Imm)) { - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitAvxM; } break; - case kX86InstGroupAvxRm_P: + case kX86InstEncodingIdAvxRm_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRm: + case kX86InstEncodingIdAvxRm: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxRmi_P: + case kX86InstEncodingIdAvxRmi_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRmi: + case kX86InstEncodingIdAvxRmi: imVal = static_cast(o2)->getInt64(); imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvm_P: + case kX86InstEncodingIdAvxRvm_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRvm: + case kX86InstEncodingIdAvxRvm: if (encoded == ENC_OPS(Reg, Reg, Reg)) { _EmitAvxRvm: - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvmr_P: + case kX86InstEncodingIdAvxRvmr_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRvmr: + case kX86InstEncodingIdAvxRvmr: if (!o3->isReg()) goto _IllegalInst; - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvmi_P: + case kX86InstEncodingIdAvxRvmi_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRvmi: + case kX86InstEncodingIdAvxRvmi: if (!o3->isImm()) goto _IllegalInst; @@ -2846,37 +2903,33 @@ _EmitAvxRvm: imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } break; - case kX86InstGroupAvxRmv: + case kX86InstEncodingIdAvxRmv: if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxRmvi: + case kX86InstEncodingIdAvxRmvi: if (!o3->isImm()) goto _IllegalInst; @@ -2884,63 +2937,60 @@ _EmitAvxRvm: imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxRmMr_P: + case kX86InstEncodingIdAvxRmMr_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRmMr: + case kX86InstEncodingIdAvxRmMr: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitAvxM; } // The following instruction uses the secondary opcode. - opCode = extendedInfo.getSecondaryOpCode(); + opCode &= kX86InstOpCode_L_Mask; + opCode |= extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Mem, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvmRmi_P: + case kX86InstEncodingIdAvxRvmRmi_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRvmRmi: + case kX86InstEncodingIdAvxRvmRmi: if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } @@ -2952,30 +3002,28 @@ _EmitAvxRvm: imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvmMr: + case kX86InstEncodingIdAvxRvmMr: if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } @@ -2983,34 +3031,32 @@ _EmitAvxRvm: opCode = extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmReg = static_cast(o0)->getRegIndex(); + opReg = x86OpReg(o1); + rmReg = x86OpReg(o0); goto _EmitAvxR; } if (encoded == ENC_OPS(Mem, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvmMvr_P: + case kX86InstEncodingIdAvxRvmMvr_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRvmMvr: + case kX86InstEncodingIdAvxRvmMvr: if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } @@ -3019,151 +3065,144 @@ _EmitAvxRvm: opCode |= extendedInfo.getSecondaryOpCode(); if (encoded == ENC_OPS(Mem, Reg, Reg)) { - opReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o0); + opReg = x86RegAndVvvv(x86OpReg(o2), x86OpReg(o1)); + rmMem = x86OpMem(o0); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvmVmi_P: + case kX86InstEncodingIdAvxRvmVmi_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRvmVmi: + case kX86InstEncodingIdAvxRvmVmi: if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } // The following instruction uses the secondary opcode. opCode &= kX86InstOpCode_L_Mask; opCode |= extendedInfo.getSecondaryOpCode(); - opReg = opCode >> kX86InstOpCode_O_Shift; + opReg = x86ExtractO(opCode); imVal = static_cast(o2)->getInt64(); imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86RegAndVvvv(opReg, x86OpReg(o0)); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { - opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(opReg, x86OpReg(o0)); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxVm: + case kX86InstEncodingIdAvxVm: if (encoded == ENC_OPS(Reg, Reg, None)) { - opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86RegAndVvvv(opReg, x86OpReg(o0)); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(opReg, x86OpReg(o0)); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxVmi_P: + case kX86InstEncodingIdAvxVmi_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxVmi: + case kX86InstEncodingIdAvxVmi: imVal = static_cast(o3)->getInt64(); imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86RegAndVvvv(opReg, x86OpReg(o0)); + rmReg = x86OpReg(o1); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { - opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(opReg, x86OpReg(o0)); + rmMem = x86OpMem(o1); goto _EmitAvxM; } break; - case kX86InstGroupAvxRvrmRvmr_P: + case kX86InstEncodingIdAvxRvrmRvmr_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupAvxRvrmRvmr: + case kX86InstEncodingIdAvxRvrmRvmr: if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o2)->getRegIndex(); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) { - imVal = static_cast(o2)->getRegIndex() << 4; + imVal = x86OpReg(o2) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o3); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o3); ADD_VEX_W(true); goto _EmitAvxM; } if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) { - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } break; - case kX86InstGroupAvxMovSsSd: + case kX86InstEncodingIdAvxMovSsSd: if (encoded == ENC_OPS(Reg, Reg, Reg)) { goto _EmitAvxRvm; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opX |= static_cast(o0)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(opReg, x86OpReg(o0)); + rmMem = x86OpMem(o1); goto _EmitAvxM; } if (encoded == ENC_OPS(Mem, Reg, None)) { - opReg = static_cast(o1)->getRegIndex(); - rmMem = static_cast(o0); + opReg = x86OpReg(o1); + rmMem = x86OpMem(o0); goto _EmitAvxM; } break; - case kX86InstGroupAvxGatherEx: + case kX86InstEncodingIdAvxGatherEx: if (encoded == ENC_OPS(Reg, Mem, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmMem = x86OpMem(o1); uint32_t vSib = rmMem->getVSib(); if (vSib == kX86MemVSibGpz) @@ -3174,11 +3213,10 @@ _EmitAvxRvm: } break; - case kX86InstGroupAvxGather: + case kX86InstEncodingIdAvxGather: if (encoded == ENC_OPS(Reg, Mem, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmMem = x86OpMem(o1); uint32_t vSib = rmMem->getVSib(); if (vSib == kX86MemVSibGpz) @@ -3193,42 +3231,39 @@ _EmitAvxRvm: // [FMA4] // ------------------------------------------------------------------------ - case kX86InstGroupFma4_P: + case kX86InstEncodingIdFma4_P: // It's fine to just check the first operand, second is just for sanity. ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupFma4: + case kX86InstEncodingIdFma4: if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o2)->getRegIndex(); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitAvxR; } if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) { - imVal = static_cast(o2)->getRegIndex() << 4; + imVal = x86OpReg(o2) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o3); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o3); ADD_VEX_W(true); goto _EmitAvxM; } if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) { - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitAvxM; } @@ -3238,45 +3273,42 @@ _EmitAvxRvm: // [XOP] // ------------------------------------------------------------------------ - case kX86InstGroupXopRm_P: + case kX86InstEncodingIdXopRm_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupXopRm: + case kX86InstEncodingIdXopRm: if (encoded == ENC_OPS(Reg, Reg, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitXopR; } if (encoded == ENC_OPS(Reg, Mem, None)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitXopM; } break; - case kX86InstGroupXopRvmRmv: + case kX86InstEncodingIdXopRvmRmv: if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmReg = x86OpReg(o1); goto _EmitXopR; } if (encoded == ENC_OPS(Reg, Mem, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmMem = x86OpMem(o1); goto _EmitXopM; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); ADD_VEX_W(true); goto _EmitXopM; @@ -3284,26 +3316,23 @@ _EmitAvxRvm: break; - case kX86InstGroupXopRvmRmi: + case kX86InstEncodingIdXopRvmRmi: if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmReg = x86OpReg(o1); goto _EmitXopR; } if (encoded == ENC_OPS(Reg, Mem, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o2)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o1); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o2)); + rmMem = x86OpMem(o1); goto _EmitXopM; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); ADD_VEX_W(true); goto _EmitXopM; @@ -3316,49 +3345,47 @@ _EmitAvxRvm: imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o1)->getRegIndex(); + opReg = x86OpReg(o0); + rmReg = x86OpReg(o1); goto _EmitXopR; } if (encoded == ENC_OPS(Reg, Mem, Imm)) { - opReg = static_cast(o0)->getRegIndex(); - rmMem = static_cast(o1); + opReg = x86OpReg(o0); + rmMem = x86OpMem(o1); goto _EmitXopM; } break; - case kX86InstGroupXopRvmr_P: + case kX86InstEncodingIdXopRvmr_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupXopRvmr: + case kX86InstEncodingIdXopRvmr: if (!o3->isReg()) goto _IllegalInst; - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitXopR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitXopM; } break; - case kX86InstGroupXopRvmi_P: + case kX86InstEncodingIdXopRvmi_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupXopRvmi: + case kX86InstEncodingIdXopRvmi: if (!o3->isImm()) goto _IllegalInst; @@ -3366,55 +3393,50 @@ _EmitAvxRvm: imLen = 1; if (encoded == ENC_OPS(Reg, Reg, Reg)) { - opReg = static_cast(o0)->getRegIndex(); - rmReg = static_cast(o2)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitXopR; } if (encoded == ENC_OPS(Reg, Reg, Mem)) { - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitXopM; } break; - case kX86InstGroupXopRvrmRvmr_P: + case kX86InstEncodingIdXopRvrmRvmr_P: ADD_VEX_L(static_cast(o0)->isYmm() | static_cast(o1)->isYmm()); // ... Fall through ... - case kX86InstGroupXopRvrmRvmr: + case kX86InstEncodingIdXopRvrmRvmr: if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isReg()) { - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmReg = static_cast(o2)->getRegIndex(); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmReg = x86OpReg(o2); goto _EmitXopR; } if (encoded == ENC_OPS(Reg, Reg, Reg) && o3->isMem()) { - imVal = static_cast(o2)->getRegIndex() << 4; + imVal = x86OpReg(o2) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o3); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o3); ADD_VEX_W(true); goto _EmitXopM; } if (encoded == ENC_OPS(Reg, Reg, Mem) && o3->isReg()) { - imVal = static_cast(o3)->getRegIndex() << 4; + imVal = x86OpReg(o3) << 4; imLen = 1; - opReg = static_cast(o0)->getRegIndex(); - opX |= static_cast(o1)->getRegIndex() << kVexVVVVShift; - rmMem = static_cast(o2); + opReg = x86RegAndVvvv(x86OpReg(o0), x86OpReg(o1)); + rmMem = x86OpMem(o2); goto _EmitXopM; } @@ -3455,34 +3477,56 @@ _EmitX86Op: EMIT_PP(opCode); // Rex prefix (64-bit only). - if (Arch == kArchX64 && opX) { - opX |= 0x40; - EMIT_BYTE(opX); - if (opX >= kRexForbidden) - goto _IllegalInst; + if (Arch == kArchX64) { + uint32_t rex = x86RexFromOpCodeAndOptions(opCode, options); + + if (rex & ~static_cast(_kX86InstOptionNoRex)) { + rex |= kX86ByteRex; + EMIT_BYTE(rex); + + if (x86RexIsInvalid(rex)) + goto _IllegalInst; + } } // Instruction opcodes. EMIT_MM(opCode); EMIT_OP(opCode); - goto _EmitDone; -_EmitX86OpI: + if (imLen != 0) + goto _EmitImm; + else + goto _EmitDone; + +_EmitX86OpWithOpReg: // Mandatory instruction prefix. EMIT_PP(opCode); // Rex prefix (64-bit only). - if (Arch == kArchX64 && opX) { - opX |= 0x40; - EMIT_BYTE(opX); - if (opX >= kRexForbidden) - goto _IllegalInst; + if (Arch == kArchX64) { + uint32_t rex = x86RexFromOpCodeAndOptions(opCode, options); + + rex += (opReg >> 3); // Rex.B (0x01). + + if (rex & ~static_cast(_kX86InstOptionNoRex)) { + rex |= kX86ByteRex; + opReg &= 0x7; + EMIT_BYTE(rex); + + if (x86RexIsInvalid(rex)) + goto _IllegalInst; + } } // Instruction opcodes. + opCode += opReg; EMIT_MM(opCode); EMIT_OP(opCode); - goto _EmitImm; + + if (imLen != 0) + goto _EmitImm; + else + goto _EmitDone; _EmitX86R: // Mandatory instruction prefix. @@ -3490,18 +3534,19 @@ _EmitX86R: // Rex prefix (64-bit only). if (Arch == kArchX64) { - opX += static_cast(opReg & 0x08) >> 1; // Rex.R (0x04). - opX += static_cast(rmReg) >> 3; // Rex.B (0x01). + uint32_t rex = x86RexFromOpCodeAndOptions(opCode, options); - if (opX) { - opX |= 0x40; - EMIT_BYTE(opX); - - if (opX >= kRexForbidden) - goto _IllegalInst; + rex += static_cast(opReg & 0x08) >> 1; // Rex.R (0x04). + rex += static_cast(rmReg) >> 3; // Rex.B (0x01). + if (rex & ~static_cast(_kX86InstOptionNoRex)) { + rex |= kX86ByteRex; opReg &= 0x7; rmReg &= 0x7; + EMIT_BYTE(rex); + + if (x86RexIsInvalid(rex)) + goto _IllegalInst; } } @@ -3546,18 +3591,19 @@ _EmitX86M: // Rex prefix (64-bit only). if (Arch == kArchX64) { - opX += static_cast(opReg & 8) >> 1; // Rex.R (0x04). - opX += static_cast(mIndex - 8 < 8) << 1; // Rex.X (0x02). - opX += static_cast(mBase - 8 < 8); // Rex.B (0x01). + uint32_t rex = x86RexFromOpCodeAndOptions(opCode, options); - if (opX) { - opX |= 0x40; - EMIT_BYTE(opX); - - if (opX >= kRexForbidden) - goto _IllegalInst; + rex += static_cast(opReg & 8) >> 1; // Rex.R (0x04). + rex += static_cast(mIndex - 8 < 8) << 1; // Rex.X (0x02). + rex += static_cast(mBase - 8 < 8); // Rex.B (0x01). + if (rex & ~static_cast(_kX86InstOptionNoRex)) { + rex |= kX86ByteRex; opReg &= 0x7; + EMIT_BYTE(rex); + + if (x86RexIsInvalid(rex)) + goto _IllegalInst; } mBase &= 0x7; @@ -3655,18 +3701,20 @@ _EmitSib: label = self->getLabelData(rmMem->_vmem.base); relocId = self->_relocList.getLength(); - RelocData reloc; - reloc.type = kRelocRelToAbs; - reloc.size = 4; - reloc.from = static_cast((uintptr_t)(cursor - self->_buffer)); - reloc.data = static_cast(dispOffset); + { + RelocData rd; + rd.type = kRelocRelToAbs; + rd.size = 4; + rd.from = static_cast((uintptr_t)(cursor - self->_buffer)); + rd.data = static_cast(dispOffset); - if (self->_relocList.append(reloc) != kErrorOk) - return self->setError(kErrorNoHeapMemory); + if (self->_relocList.append(rd) != kErrorOk) + return self->setError(kErrorNoHeapMemory); + } if (label->offset != -1) { // Bound label. - reloc.data += static_cast(label->offset); + self->_relocList[relocId].data += static_cast(label->offset); EMIT_DWORD(0); } else { @@ -3775,21 +3823,21 @@ _EmitFpuOp: uint32_t vex_XvvvvLpp; \ uint32_t vex_rxbmmmmm; \ \ - vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ - vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \ - vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \ - vex_XvvvvLpp += (opX << 4) & 0x80; \ + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_W_Shift - 7)) & 0x80; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift )) & 0x03; \ + vex_XvvvvLpp += (opReg >> (kVexVVVVShift - 3)); \ \ - vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \ - vex_rxbmmmmm += static_cast(mBase - 8 < 8) << 5; \ - vex_rxbmmmmm += static_cast(mIndex - 8 < 8) << 6; \ + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x0F; \ + vex_rxbmmmmm |= static_cast(mBase - 8 < 8) << 5; \ + vex_rxbmmmmm |= static_cast(mIndex - 8 < 8) << 6; \ \ if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) { \ vex_rxbmmmmm |= static_cast(opReg << 4) & 0x80; \ vex_rxbmmmmm ^= 0xE0; \ vex_XvvvvLpp ^= 0x78; \ \ - EMIT_BYTE(kVex3Byte); \ + EMIT_BYTE(kX86ByteVex3); \ EMIT_BYTE(vex_rxbmmmmm); \ EMIT_BYTE(vex_XvvvvLpp); \ EMIT_OP(opCode); \ @@ -3798,7 +3846,7 @@ _EmitFpuOp: vex_XvvvvLpp |= static_cast(opReg << 4) & 0x80; \ vex_XvvvvLpp ^= 0xF8; \ \ - EMIT_BYTE(kVex2Byte); \ + EMIT_BYTE(kX86ByteVex2); \ EMIT_BYTE(vex_XvvvvLpp); \ EMIT_OP(opCode); \ } \ @@ -3819,13 +3867,13 @@ _EmitAvxOp: if ((options & kX86InstOptionVex3) != 0) { uint32_t vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) | 0xE0; - EMIT_BYTE(kVex3Byte); + EMIT_BYTE(kX86ByteVex3); EMIT_OP(vex_rxbmmmmm); EMIT_OP(vex_XvvvvLpp); EMIT_OP(opCode); } else { - EMIT_BYTE(kVex2Byte); + EMIT_BYTE(kX86ByteVex2); EMIT_OP(vex_XvvvvLpp); EMIT_OP(opCode); } @@ -3837,12 +3885,12 @@ _EmitAvxR: uint32_t vex_XvvvvLpp; uint32_t vex_rxbmmmmm; - vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; - vex_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); - vex_XvvvvLpp |= (opX >> (kVexVVVVShift - 3)); - vex_XvvvvLpp |= (opX << 4) & 0x80; + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_W_Shift - 7)) & 0x80; + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift )) & 0x03; + vex_XvvvvLpp += (opReg >> (kVexVVVVShift - 3)); - vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x0F; vex_rxbmmmmm |= (rmReg << 2) & 0x20; if (vex_rxbmmmmm != 0x01 || vex_XvvvvLpp >= 0x80 || (options & kX86InstOptionVex3) != 0) { @@ -3850,7 +3898,7 @@ _EmitAvxR: vex_rxbmmmmm ^= 0xE0; vex_XvvvvLpp ^= 0x78; - EMIT_BYTE(kVex3Byte); + EMIT_BYTE(kX86ByteVex3); EMIT_OP(vex_rxbmmmmm); EMIT_OP(vex_XvvvvLpp); EMIT_OP(opCode); @@ -3861,7 +3909,7 @@ _EmitAvxR: vex_XvvvvLpp += static_cast(opReg & 0x08) << 4; vex_XvvvvLpp ^= 0xF8; - EMIT_BYTE(kVex2Byte); + EMIT_BYTE(kX86ByteVex2); EMIT_OP(vex_XvvvvLpp); EMIT_OP(opCode); } @@ -3925,18 +3973,20 @@ _EmitAvxV: label = self->getLabelData(rmMem->_vmem.base); relocId = self->_relocList.getLength(); - RelocData reloc; - reloc.type = kRelocRelToAbs; - reloc.size = 4; - reloc.from = static_cast((uintptr_t)(cursor - self->_buffer)); - reloc.data = static_cast(dispOffset); + { + RelocData rd; + rd.type = kRelocRelToAbs; + rd.size = 4; + rd.from = static_cast((uintptr_t)(cursor - self->_buffer)); + rd.data = static_cast(dispOffset); - if (self->_relocList.append(reloc) != kErrorOk) - return self->setError(kErrorNoHeapMemory); + if (self->_relocList.append(rd) != kErrorOk) + return self->setError(kErrorNoHeapMemory); + } if (label->offset != -1) { // Bound label. - reloc.data += static_cast(label->offset); + self->_relocList[relocId].data += static_cast(label->offset); EMIT_DWORD(0); } else { @@ -3972,12 +4022,12 @@ _EmitAvxV: uint32_t vex_XvvvvLpp; \ uint32_t vex_rxbmmmmm; \ \ - vex_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ - vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift)) & 0x03; \ - vex_XvvvvLpp += (opX >> (kVexVVVVShift - 3)); \ - vex_XvvvvLpp += (opX << 4) & 0x80; \ + vex_XvvvvLpp = (opCode >> (kX86InstOpCode_W_Shift - 7)) & 0x80; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; \ + vex_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift )) & 0x03; \ + vex_XvvvvLpp += (opReg >> (kVexVVVVShift - 3)); \ \ - vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; \ + vex_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x0F; \ vex_rxbmmmmm += static_cast(mBase - 8 < 8) << 5; \ vex_rxbmmmmm += static_cast(mIndex - 8 < 8) << 6; \ \ @@ -3985,7 +4035,7 @@ _EmitAvxV: vex_rxbmmmmm ^= 0xE0; \ vex_XvvvvLpp ^= 0x78; \ \ - EMIT_BYTE(kXopByte); \ + EMIT_BYTE(kX86ByteXop3); \ EMIT_BYTE(vex_rxbmmmmm); \ EMIT_BYTE(vex_XvvvvLpp); \ EMIT_OP(opCode); \ @@ -3999,19 +4049,19 @@ _EmitXopR: uint32_t xop_XvvvvLpp; uint32_t xop_rxbmmmmm; - xop_XvvvvLpp = (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; - xop_XvvvvLpp |= (opCode >> (kX86InstOpCode_PP_Shift)); - xop_XvvvvLpp |= (opX >> (kVexVVVVShift - 3)); - xop_XvvvvLpp |= (opX << 4) & 0x80; + xop_XvvvvLpp = (opCode >> (kX86InstOpCode_W_Shift - 7)) & 0x80; + xop_XvvvvLpp += (opCode >> (kX86InstOpCode_L_Shift - 2)) & 0x04; + xop_XvvvvLpp += (opCode >> (kX86InstOpCode_PP_Shift )) & 0x03; + xop_XvvvvLpp += (opReg >> (kVexVVVVShift - 3)); - xop_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x1F; + xop_rxbmmmmm = (opCode >> kX86InstOpCode_MM_Shift) & 0x0F; xop_rxbmmmmm |= (rmReg << 2) & 0x20; xop_rxbmmmmm |= static_cast(opReg & 0x08) << 4; xop_rxbmmmmm ^= 0xE0; xop_XvvvvLpp ^= 0x78; - EMIT_BYTE(kXopByte); + EMIT_BYTE(kX86ByteXop3); EMIT_OP(xop_rxbmmmmm); EMIT_OP(xop_XvvvvLpp); EMIT_OP(opCode); @@ -4058,7 +4108,6 @@ _EmitJmpOrCallAbs: if (Arch == kArchX64) { Ptr baseAddress = self->getBaseAddress(); - Ptr diff = rd.data - (baseAddress + rd.from + 4); // If the base address of the output is known, it's possible to determine // the need for a trampoline here. This saves possible REX prefix in @@ -4070,7 +4119,7 @@ _EmitJmpOrCallAbs: rd.type = kRelocTrampoline; rd.from++; - EMIT_OP(0x40); + EMIT_BYTE(kX86ByteRex); trampolineSize = 8; } } @@ -4110,6 +4159,9 @@ _EmitDisplacement: EMIT_BYTE(0x01); else // if (dispSize == 4) EMIT_DWORD(0x04040404); + + if (imLen != 0) + goto _EmitImm; } // -------------------------------------------------------------------------- @@ -4134,9 +4186,9 @@ _EmitDone: X86Assembler_dumpInstruction(sb, Arch, code, options, o0, o1, o2, o3, loggerOptions); if ((loggerOptions & (1 << kLoggerOptionBinaryForm)) != 0) - X86Assembler_dumpComment(sb, sb.getLength(), self->_cursor, (intptr_t)(cursor - self->_cursor), dispSize, self->_comment); + X86Assembler_dumpComment(sb, sb.getLength(), self->_cursor, (intptr_t)(cursor - self->_cursor), dispSize, imLen, self->_comment); else - X86Assembler_dumpComment(sb, sb.getLength(), NULL, 0, 0, self->_comment); + X86Assembler_dumpComment(sb, sb.getLength(), NULL, 0, 0, 0, self->_comment); # if defined(ASMJIT_DEBUG) if (self->_logger) diff --git a/libraries/asmjit/x86/x86assembler.h b/libraries/asmjit/x86/x86assembler.h index 223ae4aa0..32f0bd50d 100644 --- a/libraries/asmjit/x86/x86assembler.h +++ b/libraries/asmjit/x86/x86assembler.h @@ -57,16 +57,64 @@ namespace asmjit { return *this; \ } \ \ - /*! Force REX prefix. */ \ + /*! Force REX prefix (X64). */ \ ASMJIT_INLINE _Class_& rex() { \ _instOptions |= kX86InstOptionRex; \ return *this; \ } \ \ - /*! Force 3-byte VEX prefix. */ \ + /*! Force 3-byte VEX prefix (AVX+). */ \ ASMJIT_INLINE _Class_& vex3() { \ _instOptions |= kX86InstOptionVex3; \ return *this; \ + } \ + \ + /*! Force 4-byte EVEX prefix (AVX512+). */ \ + ASMJIT_INLINE _Class_& evex() { \ + _instOptions |= kX86InstOptionEvex; \ + return *this; \ + } \ + \ + /*! Use zeroing instead of merging (AVX512+). */ \ + ASMJIT_INLINE _Class_& z() { \ + _instOptions |= kX86InstOptionEvexZero; \ + return *this; \ + } \ + \ + /*! Broadcast one element to all other elements (AVX512+). */ \ + ASMJIT_INLINE _Class_& _1ToN() { \ + _instOptions |= kX86InstOptionEvexOneN; \ + return *this; \ + } \ + \ + /*! Suppress all exceptions (AVX512+). */ \ + ASMJIT_INLINE _Class_& sae() { \ + _instOptions |= kX86InstOptionEvexSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-to-nearest` (even) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& rn_sae() { \ + _instOptions |= kX86InstOptionEvexRnSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-down` (toward -inf) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& rd_sae() { \ + _instOptions |= kX86InstOptionEvexRdSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-up` (toward +inf) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& ru_sae() { \ + _instOptions |= kX86InstOptionEvexRuSae; \ + return *this; \ + } \ + \ + /*! Static rounding mode `round-toward-zero` (truncate) and `SAE` (AVX512+). */ \ + ASMJIT_INLINE _Class_& rz_sae() { \ + _instOptions |= kX86InstOptionEvexRzSae; \ + return *this; \ } //! X86/X64 assembler. @@ -94,10 +142,10 @@ namespace asmjit { //! ~~~ //! // Use asmjit namespace. //! using namespace asmjit; -//! using namespace asmjit::host; +//! using namespace asmjit::x86; //! -//! // Create Assembler instance. -//! Assembler a; +//! // Create X86Assembler instance. +//! X86Assembler a; //! //! // Prolog. //! a.push(ebp); @@ -115,10 +163,10 @@ namespace asmjit { //! ~~~ //! //! You can see that syntax is very close to Intel one. Only difference is that -//! you are calling functions that emits the binary code for you. All registers -//! are in `asmjit` namespace, so it's very comfortable to use it (look at -//! first line). There is also used method `imm()` to create an immediate value. -//! Use `imm_u()` to create unsigned immediate value. +//! you are calling functions that emit binary code for you. All registers are +//! in `asmjit::x86` namespace, so it's very comfortable to use it (look at the +//! `use namespace` section). Without importing `asmjit::x86` registers would +//! have to be written as `x86::eax`, `x86::esp`, and so on. //! //! There is also possibility to use memory addresses and immediates. Use //! `ptr()`, `byte_ptr()`, `word_ptr()`, `dword_ptr()` and similar functions to @@ -126,14 +174,14 @@ namespace asmjit { //! information related to the operand size is needed only in rare cases, that //! is an instruction without having any register operands, such as `inc [mem]`. //! -//! for example, `a` is `x86::Assembler` instance: +//! for example, `a` is an `X86Assembler` instance: //! //! ~~~ //! a.mov(ptr(eax), 0); // mov ptr [eax], 0 //! a.mov(ptr(eax), edx); // mov ptr [eax], edx //! ~~~ //! -//! But it's also possible to create complex addresses: +//! But it's also possible to create complex addresses offered by x86 architecture: //! //! ~~~ //! // eax + ecx*x addresses @@ -148,10 +196,12 @@ namespace asmjit { //! a.mov(ptr(eax, ecx, 3, 16), 0); // mov ptr [eax + ecx * 8 + 16], 0 //! ~~~ //! -//! All addresses shown are using `ptr()` to make memory operand. Some assembler -//! instructions (single operand ones) needs to have specified memory operand -//! size. For example `a.inc(ptr(eax))` can't be called, because the meaning is -//! ambiguous, see the code below. +//! All addresses shown are using `x86::ptr()` to make memory operand. Some +//! assembler instructions using a single operand need to know the size of +//! the operand to avoid ambiguity. For example `a.inc(ptr(eax))` is ambiguous +//! and would cause a runtime error. This problem can be fixed by using memory +//! operand with size specified - `byte_ptr`, `word_ptr`, `dword_ptr`, see the +//! code below: //! //! ~~~ //! // [byte] address. @@ -163,30 +213,34 @@ namespace asmjit { //! // [dword] address. //! a.inc(dword_ptr(eax)); // Inc dword ptr [eax]. //! a.dec(dword_ptr(eax)); // Dec dword ptr [eax]. +//! // [dword] address. +//! a.inc(dword_ptr(rax)); // Inc qword ptr [rax]. +//! a.dec(dword_ptr(rax)); // Dec qword ptr [rax]. //! ~~~ //! //! Calling JIT Code //! ---------------- //! -//! While you are over from emitting instructions, you can make your function -//! by using `Assembler::make()` method. This method will use memory -//! manager to allocate virtual memory and relocates generated code to it. For -//! memory allocation is used global memory manager by default and memory is -//! freeable, but of course this default behavior can be overridden specifying -//! your memory manager and allocation type. If you want to do with code -//! something else you can always override make() method and do what you want. +//! After you are finished with emitting instructions, you can make your function +//! callable by using `Assembler::make()` method. This method will use memory +//! manager to allocate virtual memory and relocates generated code to it. The +//! memory is allocated through `Runtime` instance provided to `X86Assembler` +//! constructor. //! -//! You can get size of generated code by `getCodeSize()` or `getOffset()` -//! methods. These methods returns you code size or more precisely the current -//! code offset in bytes. The `takeCode()` function can be used to take the -//! internal buffer and reset the code generator, but the buffer taken has to -//! be freed manually in such case. +//! The size of the code generated can be retrieved by `getCodeSize()` and +//! `getOffset()` methods. The `getOffset()` method returns the current offset +//! (that is mostly equal to the final code size, if called after the code +//! generation) and `getCodeSize()` returns the final code size with possible +//! trampolines. The `takeCode()` method can be used to take the internal buffer +//! and reset the code generator, but the buffer returned has to be freed manually +//! in such case. //! //! Machine code can be executed only in memory that is marked executable. This -//! mark is usually not set for memory returned by a C/C++ `malloc` function. -//! The `VMem::alloc()` function can be used allocate a memory where the code can -//! be executed or more preferably `VMemMgr` which has interface -//! similar to `malloc/free` and can allocate chunks of various sizes. +//! mark is usually not set for memory returned by a C/C++ `malloc()` function. +//! The `VMemUtil::alloc()` function can be used allocate a memory where the code +//! can be executed. Please note that `VMemUtil` is a low-level class that works +//! at memory page level. High level interface that is similar to malloc/free is +//! provided by `VMemMgr` class. //! //! The next example shows how to allocate memory where the code can be executed: //! @@ -194,27 +248,28 @@ namespace asmjit { //! using namespace asmjit; //! //! JitRuntime runtime; -//! Assembler a(&runtime); +//! X86Assembler a(&runtime); //! -//! // ... Your code generation ... +//! ... Code generation ... //! -//! // The function prototype +//! // The function prototype. //! typedef void (*MyFunc)(); //! -//! // make your function +//! // Make the function. //! MyFunc func = asmjit_cast(a.make()); //! -//! // call your function +//! // Call the function. //! func(); //! -//! // If you don't need your function again, free it. +//! // Release the function if not needed anymore. //! runtime.release(func); //! ~~~ //! -//! This was a very primitive showing how the generated code can be executed. -//! In production noone will probably generate a function that is only called -//! once and nobody will probably free the function right after it was executed. -//! The code just shows the proper way of code generation and cleanup. +//! This was a very primitive example showing how the generated code can be. +//! executed by using the foundation of classes AsmJit offers. In production +//! nobody is likely to generate a function that is only called once and freed +//! immediately after it's been called, however, the concept of releasing code +//! that is not needed anymore should be clear. //! //! Labels //! ------ @@ -278,7 +333,7 @@ namespace asmjit { //! a.mov(esp, ebp); //! a.pop(ebp); //! -//! // Return: STDCALL convention is to pop stack in called function. +//! // Return: Pop the stack by `arg_size` as defined by `STDCALL` convention. //! a.ret(arg_size); //! ~~~ //! @@ -315,13 +370,13 @@ namespace asmjit { //! Next, more advanced, but often needed technique is that you can build your //! own registers allocator. X86 architecture contains 8 general purpose //! registers, 8 Mm registers and 8 Xmm/Ymm/Zmm registers. X64 architecture -//! extends the count of Gp registers and Xmm/Ymm/Zmm registers to 16 or 32 -//! when AVX512 is available. +//! extends the count of Gp registers and Xmm/Ymm/Zmm registers to 16. AVX-512 +//! architecture extends Xmm/Ymm/Zmm SIMD registers to 32. //! //! To create a general purpose register operand from register index use //! `gpb_lo()`, `gpb_hi()`, `gpw()`, `gpd()`, `gpq()`. To create registers of -//! other types there are functions `fp()`, `mm()`, `xmm()`, `ymm()` and `zmm()` -//! available. +//! other types there `fp()`, `mm()`, `k()`, `xmm()`, `ymm()` and `zmm()` +//! functions available that return a new register operand. //! //! \sa X86Compiler. struct ASMJIT_VCLASS X86Assembler : public Assembler { @@ -330,9 +385,9 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { // -------------------------------------------------------------------------- ASMJIT_API X86Assembler(Runtime* runtime, uint32_t arch -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) = kArchHost -#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 +#endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64 ); ASMJIT_API virtual ~X86Assembler(); @@ -340,7 +395,7 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { // [Arch] // -------------------------------------------------------------------------- - //! Get count of registers of the current architecture. + //! Get count of registers of the current architecture and mode. ASMJIT_INLINE const X86RegCount& getRegCount() const { return _regCount; } @@ -457,28 +512,28 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { // [Members] // -------------------------------------------------------------------------- - //! Count of registers depending on the current architecture. + //! Count of registers depending on the architecture selected. X86RegCount _regCount; - //! EAX or RAX register depending on the current architecture. + //! EAX or RAX register depending on the architecture selected. X86GpReg zax; - //! ECX or RCX register depending on the current architecture. + //! ECX or RCX register depending on the architecture selected. X86GpReg zcx; - //! EDX or RDX register depending on the current architecture. + //! EDX or RDX register depending on the architecture selected. X86GpReg zdx; - //! EBX or RBX register depending on the current architecture. + //! EBX or RBX register depending on the architecture selected. X86GpReg zbx; - //! ESP or RSP register depending on the current architecture. + //! ESP or RSP register depending on the architecture selected. X86GpReg zsp; - //! EBP or RBP register depending on the current architecture. + //! EBP or RBP register depending on the architecture selected. X86GpReg zbp; - //! ESI or RSI register depending on the current architecture. + //! ESI or RSI register depending on the architecture selected. X86GpReg zsi; - //! EDI or RDI register depending on the current architecture. + //! EDI or RDI register depending on the architecture selected. X86GpReg zdi; // -------------------------------------------------------------------------- - // [Base Instructions] + // [Emit] // -------------------------------------------------------------------------- #define INST_0x(_Inst_, _Code_) \ @@ -498,25 +553,15 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { } #define INST_1i(_Inst_, _Code_, _Op0_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { \ - return emit(_Code_, o0); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0) { return emit(_Code_, o0); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(int o0) { \ - return emit(_Code_, o0); \ - } \ + ASMJIT_INLINE Error _Inst_(int o0) { return emit(_Code_, asInt(o0)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(unsigned int o0) { \ - return emit(_Code_, static_cast(o0)); \ - } \ + ASMJIT_INLINE Error _Inst_(unsigned int o0) { return emit(_Code_, asInt(o0)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(int64_t o0) { \ - return emit(_Code_, static_cast(o0)); \ - } \ + ASMJIT_INLINE Error _Inst_(int64_t o0) { return emit(_Code_, asInt(o0)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(uint64_t o0) { \ - return emit(_Code_, o0); \ - } + ASMJIT_INLINE Error _Inst_(uint64_t o0) { return emit(_Code_, asInt(o0)); } #define INST_1cc(_Inst_, _Code_, _Translate_, _Op0_) \ ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0) { \ @@ -566,25 +611,15 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { } #define INST_2i(_Inst_, _Code_, _Op0_, _Op1_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { \ - return emit(_Code_, o0, o1); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_, o0, o1); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int o1) { \ - return emit(_Code_, o0, o1); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int o1) { return emit(_Code_, o0, asInt(o1)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, unsigned int o1) { \ - return emit(_Code_, o0, static_cast(o1)); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, unsigned int o1) { return emit(_Code_, o0, asInt(o1)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int64_t o1) { \ - return emit(_Code_, o0, static_cast(o1)); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int64_t o1) { return emit(_Code_, o0, asInt(o1)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, uint64_t o1) { \ - return emit(_Code_, o0, o1); \ - } + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, uint64_t o1) { return emit(_Code_, o0, asInt(o1)); } #define INST_2cc(_Inst_, _Code_, _Translate_, _Op0_, _Op1_) \ ASMJIT_INLINE Error _Inst_(uint32_t cc, const _Op0_& o0, const _Op1_& o1) { \ @@ -623,68 +658,58 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { ASMJIT_INLINE Error _Inst_##z(const _Op0_& o0, const _Op1_& o1) { return emit(_Code_##z, o0, o1); } #define INST_3x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ - return emit(_Code_, o0, o1, o2); \ - } - -#define INST_3x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Cond_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ - ASMJIT_ASSERT(_Cond_); \ - return emit(_Code_, o0, o1, o2); \ - } + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { return emit(_Code_, o0, o1, o2); } #define INST_3i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ - return emit(_Code_, o0, o1, o2); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { return emit(_Code_, o0, o1, o2); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { \ - return emit(_Code_, o0, o1, o2); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int o2) { return emit(_Code_, o0, o1, asInt(o2)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { \ - return emit(_Code_, o0, o1, static_cast(o2)); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2) { return emit(_Code_, o0, o1, asInt(o2)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { \ - return emit(_Code_, o0, o1, static_cast(o2)); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2) { return emit(_Code_, o0, o1, asInt(o2)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { \ - return emit(_Code_, o0, o1, o2); \ - } + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2) { return emit(_Code_, o0, o1, asInt(o2)); } -#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ - return emit(_Code_, o0, o1, o2, o3); \ - } +#define INST_3ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { return emit(_Code_, o0, o1, o2); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int o1, int o2) { return emit(_Code_, o0, Imm(o1), asInt(o2)); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, unsigned int o1, unsigned int o2) { return emit(_Code_, o0, Imm(o1), asInt(o2)); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, int64_t o1, int64_t o2) { return emit(_Code_, o0, Imm(o1), asInt(o2)); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, uint64_t o1, uint64_t o2) { return emit(_Code_, o0, Imm(o1), asInt(o2)); } -#define INST_4x_(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_, _Cond_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ - ASMJIT_ASSERT(_Cond_); \ - return emit(_Code_, o0, o1, o2, o3); \ - } +#define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { return emit(_Code_, o0, o1, o2, o3); } #define INST_4i(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ - return emit(_Code_, o0, o1, o2, o3); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { return emit(_Code_, o0, o1, o2, o3); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { \ - return emit(_Code_, o0, o1, o2, o3); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int o3) { return emit(_Code_, o0, o1, o2, asInt(o3)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { \ - return emit(_Code_, o0, o1, o2, static_cast(o3)); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, unsigned int o3) { return emit(_Code_, o0, o1, o2, asInt(o3)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { \ - return emit(_Code_, o0, o1, o2, static_cast(o3)); \ - } \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, int64_t o3) { return emit(_Code_, o0, o1, o2, asInt(o3)); } \ /*! \overload */ \ - ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { \ - return emit(_Code_, o0, o1, o2, o3); \ - } + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, uint64_t o3) { return emit(_Code_, o0, o1, o2, asInt(o3)); } + +#define INST_4ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { return emit(_Code_, o0, o1, o2, o3); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int o2, int o3) { return emit(_Code_, o0, o1, Imm(o2), asInt(o3)); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2, unsigned int o3) { return emit(_Code_, o0, o1, Imm(o2), asInt(o3)); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2, int64_t o3) { return emit(_Code_, o0, o1, Imm(o2), asInt(o3)); } \ + /*! \overload */ \ + ASMJIT_INLINE Error _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2, uint64_t o3) { return emit(_Code_, o0, o1, Imm(o2), asInt(o3)); } + + // -------------------------------------------------------------------------- + // [X86/X64] + // -------------------------------------------------------------------------- //! Add with Carry. INST_2x(adc, kX86InstIdAdc, X86GpReg, X86GpReg) @@ -837,11 +862,6 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! CPU identification (i486). INST_0x(cpuid, kX86InstIdCpuid) - //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). - INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86GpReg, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) - //! \overload - INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) - //! Decimal adjust AL after addition (X86 Only). INST_0x(daa, kX86InstIdDaa) //! Decimal adjust AL after subtraction (X86 Only). @@ -1037,11 +1057,6 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! Pop stack into EFLAGS register (32-bit or 64-bit). INST_0x(popf, kX86InstIdPopf) - //! Return the count of number of bits set to 1 (SSE4.2). - INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86GpReg, !o0.isGpb() && o0.getRegType() == o1.getRegType()) - //! \overload - INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86Mem, !o0.isGpb()) - //! Push WORD or DWORD/QWORD on the stack. INST_1x_(push, kX86InstIdPush, X86GpReg, o0.getSize() == 2 || o0.getSize() == _regSize) //! Push WORD or DWORD/QWORD on the stack. @@ -1329,273 +1344,277 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) // -------------------------------------------------------------------------- - // [Fpu] + // [FPU] // -------------------------------------------------------------------------- - //! Compute 2^x - 1 (FPU). + //! Compute `2^x - 1` - `fp0 = POW(2, fp0) - 1` (FPU). INST_0x(f2xm1, kX86InstIdF2xm1) - //! Absolute value of fp0 (FPU). + //! Abs `fp0 = ABS(fp0)` (FPU). INST_0x(fabs, kX86InstIdFabs) - //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU). + //! Add `o0 = o0 + o1` (one operand has to be `fp0`) (FPU). INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU). + //! Add `fp0 = fp0 + float_or_double[o0]` (FPU). INST_1x(fadd, kX86InstIdFadd, X86Mem) - //! Add fp0 to `o0` and pop the FPU stack (FPU). + //! Add `o0 = o0 + fp0` and POP (FPU). INST_1x(faddp, kX86InstIdFaddp, X86FpReg) - //! \overload + //! Add `fp1 = fp1 + fp0` and POP (FPU). INST_0x(faddp, kX86InstIdFaddp) - //! Load binary coded decimal (FPU). + //! Load BCD from `[o0]` and PUSH (FPU). INST_1x(fbld, kX86InstIdFbld, X86Mem) - //! Store BCD integer and Pop (FPU). + //! Store BCD-Integer to `[o0]` and POP (FPU). INST_1x(fbstp, kX86InstIdFbstp, X86Mem) - //! Change fp0 sign (FPU). + + //! Complement Sign `fp0 = -fp0` (FPU). INST_0x(fchs, kX86InstIdFchs) + //! Clear exceptions (FPU). INST_0x(fclex, kX86InstIdFclex) - //! Conditional move (FPU). + //! Conditional move `if (CF=1) fp0 = o0` (FPU). INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (CF|ZF=1) fp0 = o0` (FPU). INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (ZF=1) fp0 = o0` (FPU). INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (CF=0) fp0 = o0` (FPU). INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (CF|ZF=0) fp0 = o0` (FPU). INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (ZF=0) fp0 = o0` (FPU). INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (PF=0) fp0 = o0` (FPU). INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (PF=1) fp0 = o0` (FPU). INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg) - //! Compare fp0 with `o0` (FPU). + //! Compare `fp0` with `o0` (FPU). INST_1x(fcom, kX86InstIdFcom, X86FpReg) - //! Compare fp0 with fp1 (FPU). + //! Compare `fp0` with `fp1` (FPU). INST_0x(fcom, kX86InstIdFcom) - //! Compare fp0 with 4-byte or 8-byte FP at `src` (FPU). + //! Compare `fp0` with `float_or_double[o0]` (FPU). INST_1x(fcom, kX86InstIdFcom, X86Mem) - //! Compare fp0 with `o0` and pop the FPU stack (FPU). + //! Compare `fp0` with `o0` and POP (FPU). INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) - //! Compare fp0 with fp1 and pop the FPU stack (FPU). + //! Compare `fp0` with `fp1` and POP (FPU). INST_0x(fcomp, kX86InstIdFcomp) - //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU). + //! Compare `fp0` with `float_or_double[o0]` and POP (FPU). INST_1x(fcomp, kX86InstIdFcomp, X86Mem) - //! Compare fp0 with fp1 and pop the FPU stack twice (FPU). + //! Compare `fp0` with `fp1` and POP twice (FPU). INST_0x(fcompp, kX86InstIdFcompp) - //! Compare fp0 and `o0` and Set EFLAGS (FPU). + //! Compare `fp0` with `o0` and set EFLAGS (FPU). INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) - //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU). + //! Compare `fp0` with `o0` and set EFLAGS and POP (FPU). INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) - //! Calculate cosine of fp0 and store result in fp0 (FPU). + //! Cos `fp0 = cos(fp0)` (FPU). INST_0x(fcos, kX86InstIdFcos) - //! Decrement FPU stack-top pointer (FPU). + + //! Decrement FPU stack pointer (FPU). INST_0x(fdecstp, kX86InstIdFdecstp) - //! Divide `o0` by `o1` (one has to be `fp0`) (FPU). + //! Divide `o0 = o0 / o1` (one has to be `fp0`) (FPU). INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Divide fp0 by 32-bit or 64-bit FP value (FPU). + //! Divide `fp0 = fp0 / float_or_double[o0]` (FPU). INST_1x(fdiv, kX86InstIdFdiv, X86Mem) - //! Divide `o0` by fp0 (FPU). + //! Divide `o0 = o0 / fp0` and POP (FPU). INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) - //! \overload + //! Divide `fp1 = fp1 / fp0` and POP (FPU). INST_0x(fdivp, kX86InstIdFdivp) - //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU). + //! Reverse divide `o0 = o1 / o0` (one has to be `fp0`) (FPU). INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU). + //! Reverse divide `fp0 = float_or_double[o0] / fp0` (FPU). INST_1x(fdivr, kX86InstIdFdivr, X86Mem) - //! Reverse divide `o0` by fp0 (FPU). + //! Reverse divide `o0 = fp0 / o0` and POP (FPU). INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) - //! \overload + //! Reverse divide `fp1 = fp0 / fp1` and POP (FPU). INST_0x(fdivrp, kX86InstIdFdivrp) //! Free FP register (FPU). INST_1x(ffree, kX86InstIdFfree, X86FpReg) - //! Add 16-bit or 32-bit integer to fp0 (FPU). + //! Add `fp0 = fp0 + short_or_int[o0]` (FPU). INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Compare fp0 with 16-bit or 32-bit Integer (FPU). + //! Compare `fp0` with `short_or_int[o0]` (FPU). INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU). + //! Compare `fp0` with `short_or_int[o0]` and POP (FPU). INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + //! Divide `fp0 = fp0 / short_or_int[o0]` (FPU). INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + //! Reverse divide `fp0 = short_or_int[o0] / fp0` (FPU). INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU). + //! Load `short_or_int_or_long[o0]` and PUSH (FPU). INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) - //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU). + //! Multiply `fp0 *= short_or_int[o0]` (FPU). INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Increment FPU stack-top pointer (FPU). + //! Increment FPU stack pointer (FPU). INST_0x(fincstp, kX86InstIdFincstp) //! Initialize FPU (FPU). INST_0x(finit, kX86InstIdFinit) - //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + //! Subtract `fp0 = fp0 - short_or_int[o0]` (FPU). INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + //! Reverse subtract `fp0 = short_or_int[o0] - fp0` (FPU). INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) //! Initialize FPU without checking for pending unmasked exceptions (FPU). INST_0x(fninit, kX86InstIdFninit) - //! Store fp0 as 16-bit or 32-bit Integer to `o0` (FPU). + //! Store `fp0` as `short_or_int[o0]` (FPU). INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU). + //! Store `fp0` as `short_or_int_or_long[o0]` and POP (FPU). INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) - //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU). + + //! Load `float_or_double_or_extended[o0]` and PUSH (FPU). INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) - //! Push `o0` on the FPU stack (FPU). + //! PUSH `o0` (FPU). INST_1x(fld, kX86InstIdFld, X86FpReg) - //! Push +1.0 on the FPU stack (FPU). + //! PUSH `1.0` (FPU). INST_0x(fld1, kX86InstIdFld1) - //! Push log2(10) on the FPU stack (FPU). + //! PUSH `log2(10)` (FPU). INST_0x(fldl2t, kX86InstIdFldl2t) - //! Push log2(e) on the FPU stack (FPU). + //! PUSH `log2(e)` (FPU). INST_0x(fldl2e, kX86InstIdFldl2e) - //! Push pi on the FPU stack (FPU). + //! PUSH `pi` (FPU). INST_0x(fldpi, kX86InstIdFldpi) - //! Push log10(2) on the FPU stack (FPU). + //! PUSH `log10(2)` (FPU). INST_0x(fldlg2, kX86InstIdFldlg2) - //! Push ln(2) on the FPU stack (FPU). + //! PUSH `ln(2)` (FPU). INST_0x(fldln2, kX86InstIdFldln2) - //! Push +0.0 on the FPU stack (FPU). + //! PUSH `+0.0` (FPU). INST_0x(fldz, kX86InstIdFldz) - //! Load x87 FPU control word (2 bytes) (FPU). + //! Load x87 FPU control word from `word_ptr[o0]` (FPU). INST_1x(fldcw, kX86InstIdFldcw, X86Mem) - //! Load x87 FPU environment (14 or 28 bytes) (FPU). + //! Load x87 FPU environment (14 or 28 bytes) from `[o0]` (FPU). INST_1x(fldenv, kX86InstIdFldenv, X86Mem) - //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU). + //! Multiply `o0 = o0 * o1` (one has to be `fp0`) (FPU). INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU). + //! Multiply `fp0 = fp0 * float_or_double[o0]` (FPU). INST_1x(fmul, kX86InstIdFmul, X86Mem) - //! Multiply fp0 by `o0` and pop the FPU stack (FPU). + //! Multiply `o0 = o0 * fp0` and POP (FPU). INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) - //! \overload + //! Multiply `fp1 = fp1 * fp0` and POP (FPU). INST_0x(fmulp, kX86InstIdFmulp) //! Clear exceptions (FPU). INST_0x(fnclex, kX86InstIdFnclex) //! No operation (FPU). INST_0x(fnop, kX86InstIdFnop) - //! Save FPU state (FPU). + //! Save FPU state to `[o0]` (FPU). INST_1x(fnsave, kX86InstIdFnsave, X86Mem) - //! Store x87 FPU environment (FPU). + //! Store x87 FPU environment to `[o0]` (FPU). INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) - //! Store x87 FPU control word (FPU). + //! Store x87 FPU control word to `[o0]` (FPU). INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem) //! Store x87 FPU status word to `o0` (AX) (FPU). INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx)) - //! Store x87 FPU status word to `o0` (2 bytes) (FPU). + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) - //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU). + //! Partial Arctan `fp1 = atan2(fp1, fp0)` and POP (FPU). INST_0x(fpatan, kX86InstIdFpatan) - //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + //! Partial Remainder[Trunc] `fp1 = fp0 % fp1` and POP (FPU). INST_0x(fprem, kX86InstIdFprem) - //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + //! Partial Remainder[Round] `fp1 = fp0 % fp1` and POP (FPU). INST_0x(fprem1, kX86InstIdFprem1) - //! Arctan(`fp0`) and pop the FPU stack (FPU). + //! Partial Tan `fp0 = tan(fp0)` and PUSH `1.0` (FPU). INST_0x(fptan, kX86InstIdFptan) - //! Round `fp0` to Integer (FPU). + //! Round `fp0 = round(fp0)` (FPU). INST_0x(frndint, kX86InstIdFrndint) - //! Restore FPU state from `o0` (94 or 108 bytes) (FPU). + //! Restore FPU state from `[o0]` (94 or 108 bytes) (FPU). INST_1x(frstor, kX86InstIdFrstor, X86Mem) - //! Save FPU state to `o0` (94 or 108 bytes) (FPU). + //! Save FPU state to `[o0]` (94 or 108 bytes) (FPU). INST_1x(fsave, kX86InstIdFsave, X86Mem) - //! Scale `fp0` by `fp1` (FPU). + //! Scale `fp0 = fp0 * pow(2, RoundTowardsZero(fp1))` (FPU). INST_0x(fscale, kX86InstIdFscale) - //! Sine of `fp0` and store result in `fp0` (FPU). + //! Sin `fp0 = sin(fp0)` (FPU). INST_0x(fsin, kX86InstIdFsin) - //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU). + //! Sincos `fp0 = sin(fp0)` and PUSH `cos(fp0)` (FPU). INST_0x(fsincos, kX86InstIdFsincos) - //! Square root of `fp0` and store it in `fp0` (FPU). + //! Square root `fp0 = sqrt(fp0)` (FPU). INST_0x(fsqrt, kX86InstIdFsqrt) - //! Store floating point value to 32-bit or 64-bit memory location (FPU). + //! Store floating point value to `float_or_double[o0]` (FPU). INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Store floating point value to `o0` (FPU). + //! Copy `o0 = fp0` (FPU). INST_1x(fst, kX86InstIdFst, X86FpReg) - //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU). + //! Store floating point value to `float_or_double_or_extended[o0]` and POP (FPU). INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) - //! Store floating point value to `o0` and pop the FPU stack (FPU). + //! Copy `o0 = fp0` and POP (FPU). INST_1x(fstp, kX86InstIdFstp, X86FpReg) - //! Store x87 FPU control word to `o0` (2 bytes) (FPU). + //! Store x87 FPU control word to `word_ptr[o0]` (FPU). INST_1x(fstcw, kX86InstIdFstcw, X86Mem) - //! Store x87 FPU environment to `o0` (14 or 28 bytes) (FPU). + //! Store x87 FPU environment to `[o0]` (14 or 28 bytes) (FPU). INST_1x(fstenv, kX86InstIdFstenv, X86Mem) - //! Store x87 FPU status word to AX (FPU). + //! Store x87 FPU status word to `o0` (AX) (FPU). INST_1x_(fstsw, kX86InstIdFstsw, X86GpReg, o0.getRegIndex() == kX86RegIndexAx) - //! Store x87 FPU status word (2 bytes) (FPU). + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). INST_1x(fstsw, kX86InstIdFstsw, X86Mem) - //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + //! Subtract `o0 = o0 - o1` (one has to be `fp0`) (FPU). INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU). + //! Subtract `fp0 = fp0 - float_or_double[o0]` (FPU). INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Subtract fp0 from `o0` and pop FPU stack (FPU). + //! Subtract `o0 = o0 - fp0` and POP (FPU). INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) - //! \overload + //! Subtract `fp1 = fp1 - fp0` and POP (FPU). INST_0x(fsubp, kX86InstIdFsubp) - //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + //! Reverse subtract `o0 = o1 - o0` (one has to be `fp0`) (FPU). INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU). + //! Reverse subtract `fp0 = fp0 - float_or_double[o0]` (FPU). INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU). + //! Reverse subtract `o0 = o0 - fp0` and POP (FPU). INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) - //! \overload + //! Reverse subtract `fp1 = fp1 - fp0` and POP (FPU). INST_0x(fsubrp, kX86InstIdFsubrp) - //! Floating point test - Compare `fp0` with 0.0. (FPU). + //! Compare `fp0` with `0.0` (FPU). INST_0x(ftst, kX86InstIdFtst) //! Unordered compare `fp0` with `o0` (FPU). INST_1x(fucom, kX86InstIdFucom, X86FpReg) //! Unordered compare `fp0` with `fp1` (FPU). INST_0x(fucom, kX86InstIdFucom) - //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS (FPU). + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS (FPU). INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) - //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU). + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS and POP (FPU). INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) - //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU). + //! Unordered compare `fp0` with `o0` and POP (FPU). INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) - //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU). + //! Unordered compare `fp0` with `fp1` and POP (FPU). INST_0x(fucomp, kX86InstIdFucomp) - //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU). + //! Unordered compare `fp0` with `fp1` and POP twice (FPU). INST_0x(fucompp, kX86InstIdFucompp) INST_0x(fwait, kX86InstIdFwait) //! Examine fp0 (FPU). INST_0x(fxam, kX86InstIdFxam) - //! Exchange content of fp0 with `o0` (FPU). + //! Exchange `fp0` with `o0` (FPU). INST_1x(fxch, kX86InstIdFxch, X86FpReg) //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem) //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). INST_1x(fxsave, kX86InstIdFxsave, X86Mem) - //! Extract exponent and store to `fp0` and push significand on the FPU stack (FPU). + //! Extract `fp0 = exponent(fp0)` and PUSH `significant(fp0)` (FPU). INST_0x(fxtract, kX86InstIdFxtract) - //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU). + //! Compute `fp1 = fp1 * log2(fp0)` and POP (FPU). INST_0x(fyl2x, kX86InstIdFyl2x) - //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU). + //! Compute `fp1 = fp1 * log2(fp0 + 1)` and POP (FPU). INST_0x(fyl2xp1, kX86InstIdFyl2xp1) // -------------------------------------------------------------------------- @@ -2356,12 +2375,12 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(cvtdq2ps, kX86InstIdCvtdq2ps, X86XmmReg, X86Mem) - //! Convert packed DP-FP to packed QWORDs (SSE2). + //! Convert packed DP-FP to packed DWORDs (SSE2). INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(cvtpd2dq, kX86InstIdCvtpd2dq, X86XmmReg, X86Mem) - //! Convert packed DP-FP to packed QRODSs (SSE2). + //! Convert packed DP-FP to packed DWORDs (SSE2). INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86XmmReg) //! \overload INST_2x(cvtpd2pi, kX86InstIdCvtpd2pi, X86MmReg, X86Mem) @@ -2376,7 +2395,7 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(cvtpi2pd, kX86InstIdCvtpi2pd, X86XmmReg, X86Mem) - //! Convert packed SP-FP to packed QWORDs (SSE2). + //! Convert packed SP-FP to packed DWORDs (SSE2). INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(cvtps2dq, kX86InstIdCvtps2dq, X86XmmReg, X86Mem) @@ -2411,12 +2430,12 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(cvttpd2pi, kX86InstIdCvttpd2pi, X86MmReg, X86Mem) - //! Convert with truncation packed DP-FP to packed QWORDs (SSE2). + //! Convert with truncation packed DP-FP to packed DWORDs (SSE2). INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(cvttpd2dq, kX86InstIdCvttpd2dq, X86XmmReg, X86Mem) - //! Convert with truncation packed SP-FP to packed QWORDs (SSE2). + //! Convert with truncation packed SP-FP to packed DWORDs (SSE2). INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(cvttps2dq, kX86InstIdCvttps2dq, X86XmmReg, X86Mem) @@ -2951,8 +2970,7 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(addsubps, kX86InstIdAddsubps, X86XmmReg, X86Mem) - //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop - //! the FPU stack (FPU / SSE3). + //! Store truncated `fp0` to `short_or_int_or_long[o0]` and POP (FPU & SSE3). INST_1x(fisttp, kX86InstIdFisttp, X86Mem) //! Packed DP-FP horizontal add (SSE3). @@ -3412,6 +3430,11 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { // [SSE4.2] // -------------------------------------------------------------------------- + //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86GpReg, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! \overload + INST_2x_(crc32, kX86InstIdCrc32, X86GpReg, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! Packed compare explicit length strings, return index (SSE4.2). INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmReg, X86XmmReg, Imm) //! \overload @@ -3437,6 +3460,43 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmReg, X86Mem) + // -------------------------------------------------------------------------- + // [SSE4a] + // -------------------------------------------------------------------------- + + //! Extract Field (SSE4a). + INST_2x(extrq, kX86InstIdExtrq, X86XmmReg, X86XmmReg) + //! Extract Field (SSE4a). + INST_3ii(extrq, kX86InstIdExtrq, X86XmmReg, Imm, Imm) + + //! Insert Field (SSE4a). + INST_2x(insertq, kX86InstIdInsertq, X86XmmReg, X86XmmReg) + //! Insert Field (SSE4a). + INST_4ii(insertq, kX86InstIdInsertq, X86XmmReg, X86XmmReg, Imm, Imm) + + //! Move Non-Temporal Scalar DP-FP (SSE4a). + INST_2x(movntsd, kX86InstIdMovntsd, X86Mem, X86XmmReg) + //! Move Non-Temporal Scalar SP-FP (SSE4a). + INST_2x(movntss, kX86InstIdMovntss, X86Mem, X86XmmReg) + + // -------------------------------------------------------------------------- + // [POPCNT] + // -------------------------------------------------------------------------- + + //! Return the count of number of bits set to 1 (POPCNT). + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86GpReg, !o0.isGpb() && o0.getRegType() == o1.getRegType()) + //! \overload + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpReg, X86Mem, !o0.isGpb()) + + // -------------------------------------------------------------------------- + // [LZCNT] + // -------------------------------------------------------------------------- + + //! Count the number of leading zero bits (LZCNT). + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86GpReg) + //! \overload + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86Mem) + // -------------------------------------------------------------------------- // [AESNI] // -------------------------------------------------------------------------- @@ -3480,6 +3540,30 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmReg, X86Mem, Imm) + // -------------------------------------------------------------------------- + // [XSAVE] + // -------------------------------------------------------------------------- + + //! Restore Processor Extended States specified by `EDX:EAX` (XSAVE). + INST_1x(xrstor, kX86InstIdXrstor, X86Mem) + //! Restore Processor Extended States specified by `EDX:EAX` (XSAVE&X64). + INST_1x(xrstor64, kX86InstIdXrstor64, X86Mem) + + //! Save Processor Extended States specified by `EDX:EAX` (XSAVE). + INST_1x(xsave, kX86InstIdXsave, X86Mem) + //! Save Processor Extended States specified by `EDX:EAX` (XSAVE&X64). + INST_1x(xsave64, kX86InstIdXsave64, X86Mem) + + //! Save Processor Extended States specified by `EDX:EAX` (Optimized) (XSAVEOPT). + INST_1x(xsaveopt, kX86InstIdXsave, X86Mem) + //! Save Processor Extended States specified by `EDX:EAX` (Optimized) (XSAVEOPT&X64). + INST_1x(xsaveopt64, kX86InstIdXsave64, X86Mem) + + //! Get XCR - `EDX:EAX <- XCR[ECX]` (XSAVE). + INST_0x(xgetbv, kX86InstIdXgetbv) + //! Set XCR - `XCR[ECX] <- EDX:EAX` (XSAVE). + INST_0x(xsetbv, kX86InstIdXsetbv) + // -------------------------------------------------------------------------- // [AVX] // -------------------------------------------------------------------------- @@ -3667,7 +3751,7 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(vcvtdq2ps, kX86InstIdVcvtdq2ps, X86YmmReg, X86Mem) - //! Convert packed DP-FP to packed QWORDs (AVX). + //! Convert packed DP-FP to packed DWORDs (AVX). INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(vcvtpd2dq, kX86InstIdVcvtpd2dq, X86XmmReg, X86YmmReg) @@ -3681,7 +3765,7 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(vcvtpd2ps, kX86InstIdVcvtpd2ps, X86XmmReg, X86Mem) - //! Convert packed SP-FP to packed QWORDs (AVX). + //! Convert packed SP-FP to packed DWORDs (AVX). INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(vcvtps2dq, kX86InstIdVcvtps2dq, X86XmmReg, X86Mem) @@ -3729,14 +3813,14 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(vcvtss2si, kX86InstIdVcvtss2si, X86GpReg, X86Mem) - //! Convert with truncation packed DP-FP to packed QWORDs (AVX). + //! Convert with truncation packed DP-FP to packed DWORDs (AVX). INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86YmmReg) //! \overload INST_2x(vcvttpd2dq, kX86InstIdVcvttpd2dq, X86XmmReg, X86Mem) - //! Convert with truncation packed SP-FP to packed QWORDs (AVX). + //! Convert with truncation packed SP-FP to packed DWORDs (AVX). INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86XmmReg) //! \overload INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86XmmReg, X86Mem) @@ -3745,7 +3829,7 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(vcvttps2dq, kX86InstIdVcvttps2dq, X86YmmReg, X86Mem) - //! Convert with truncation scalar DP-FP to DWORD (AVX). + //! Convert with truncation scalar DP-FP to INT32 (AVX). INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86XmmReg) //! \overload INST_2x(vcvttsd2si, kX86InstIdVcvttsd2si, X86GpReg, X86Mem) @@ -6393,15 +6477,6 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { //! \overload INST_2x(tzcnt, kX86InstIdTzcnt, X86GpReg, X86Mem) - // -------------------------------------------------------------------------- - // [LZCNT] - // -------------------------------------------------------------------------- - - //! Count the number of leading zero bits (LZCNT). - INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86GpReg) - //! \overload - INST_2x(lzcnt, kX86InstIdLzcnt, X86GpReg, X86Mem) - // -------------------------------------------------------------------------- // [BMI2] // -------------------------------------------------------------------------- @@ -6450,11 +6525,11 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { // [RDRAND] // -------------------------------------------------------------------------- - //! Store a random number in destination register. + //! Store a random number in destination register (RDRAND). //! //! Please do not use this instruction in cryptographic software. The result - //! doesn't necessarily have to be random which may cause a major security - //! issue in the software that relies on it. + //! doesn't necessarily have to be random, which may cause a major security + //! hole in the software. INST_1x(rdrand, kX86InstIdRdrand, X86GpReg) // -------------------------------------------------------------------------- @@ -6501,12 +6576,12 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler { #undef INST_2cc #undef INST_3x -#undef INST_3x_ #undef INST_3i +#undef INST_3ii #undef INST_4x -#undef INST_4x_ #undef INST_4i +#undef INST_4ii }; //! \} diff --git a/libraries/asmjit/x86/x86compiler.cpp b/libraries/asmjit/x86/x86compiler.cpp index d82efda04..424188aa8 100644 --- a/libraries/asmjit/x86/x86compiler.cpp +++ b/libraries/asmjit/x86/x86compiler.cpp @@ -60,14 +60,18 @@ const X86VarInfo _x86VarInfo[] = { /* 10: kVarTypeFp32 */ { kX86RegTypeFp , 4 , C(Fp) , D(Sp) , "fp" }, /* 11: kVarTypeFp64 */ { kX86RegTypeFp , 8 , C(Fp) , D(Dp) , "fp" }, /* 12: kX86VarTypeMm */ { kX86RegTypeMm , 8 , C(Mm) , 0 , "mm" }, - /* 13: kX86VarTypeXmm */ { kX86RegTypeXmm , 16, C(Xyz), 0 , "xmm" }, - /* 14: kX86VarTypeXmmSs */ { kX86RegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" }, - /* 15: kX86VarTypeXmmPs */ { kX86RegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" }, - /* 16: kX86VarTypeXmmSd */ { kX86RegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" }, - /* 17: kX86VarTypeXmmPd */ { kX86RegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" }, - /* 18: kX86VarTypeYmm */ { kX86RegTypeYmm , 32, C(Xyz), 0 , "ymm" }, - /* 19: kX86VarTypeYmmPs */ { kX86RegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" }, - /* 20: kX86VarTypeYmmPd */ { kX86RegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" } + /* 13: kX86VarTypeK */ { kX86RegTypeK , 8 , C(K) , 0 , "k" }, + /* 14: kX86VarTypeXmm */ { kX86RegTypeXmm , 16, C(Xyz), 0 , "xmm" }, + /* 15: kX86VarTypeXmmSs */ { kX86RegTypeXmm , 4 , C(Xyz), D(Sp) , "xmm" }, + /* 16: kX86VarTypeXmmPs */ { kX86RegTypeXmm , 16, C(Xyz), D(Sp) | D(Packed), "xmm" }, + /* 17: kX86VarTypeXmmSd */ { kX86RegTypeXmm , 8 , C(Xyz), D(Dp) , "xmm" }, + /* 18: kX86VarTypeXmmPd */ { kX86RegTypeXmm , 16, C(Xyz), D(Dp) | D(Packed), "xmm" }, + /* 19: kX86VarTypeYmm */ { kX86RegTypeYmm , 32, C(Xyz), 0 , "ymm" }, + /* 20: kX86VarTypeYmmPs */ { kX86RegTypeYmm , 32, C(Xyz), D(Sp) | D(Packed), "ymm" }, + /* 21: kX86VarTypeYmmPd */ { kX86RegTypeYmm , 32, C(Xyz), D(Dp) | D(Packed), "ymm" }, + /* 22: kX86VarTypeZmm */ { kX86RegTypeZmm , 64, C(Xyz), 0 , "zmm" }, + /* 23: kX86VarTypeZmmPs */ { kX86RegTypeZmm , 64, C(Xyz), D(Sp) | D(Packed), "zmm" }, + /* 24: kX86VarTypeZmmPd */ { kX86RegTypeZmm , 64, C(Xyz), D(Dp) | D(Packed), "zmm" } }; #undef D @@ -88,14 +92,18 @@ const uint8_t _x86VarMapping[kX86VarTypeCount] = { /* 10: kVarTypeFp32 */ kVarTypeFp32, /* 11: kVarTypeFp64 */ kVarTypeFp64, /* 12: kX86VarTypeMm */ kX86VarTypeMm, - /* 13: kX86VarTypeXmm */ kX86VarTypeXmm, - /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, - /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, - /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, - /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, - /* 18: kX86VarTypeYmm */ kX86VarTypeYmm, - /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, - /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd + /* 13: kX86VarTypeK */ kX86VarTypeK, + /* 14: kX86VarTypeXmm */ kX86VarTypeXmm, + /* 15: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, + /* 16: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, + /* 17: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, + /* 18: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, + /* 19: kX86VarTypeYmm */ kX86VarTypeYmm, + /* 20: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, + /* 21: kX86VarTypeYmmPd */ kX86VarTypeYmmPd, + /* 22: kX86VarTypeZmm */ kX86VarTypeZmm, + /* 23: kX86VarTypeZmmPs */ kX86VarTypeZmmPs, + /* 24: kX86VarTypeZmmPd */ kX86VarTypeZmmPd }; #endif // ASMJIT_BUILD_X86 @@ -114,14 +122,18 @@ const uint8_t _x64VarMapping[kX86VarTypeCount] = { /* 10: kVarTypeFp32 */ kVarTypeFp32, /* 11: kVarTypeFp64 */ kVarTypeFp64, /* 12: kX86VarTypeMm */ kX86VarTypeMm, - /* 13: kX86VarTypeXmm */ kX86VarTypeXmm, - /* 14: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, - /* 15: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, - /* 16: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, - /* 17: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, - /* 18: kX86VarTypeYmm */ kX86VarTypeYmm, - /* 19: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, - /* 20: kX86VarTypeYmmPd */ kX86VarTypeYmmPd + /* 13: kX86VarTypeK */ kX86VarTypeK, + /* 14: kX86VarTypeXmm */ kX86VarTypeXmm, + /* 15: kX86VarTypeXmmSs */ kX86VarTypeXmmSs, + /* 16: kX86VarTypeXmmPs */ kX86VarTypeXmmPs, + /* 17: kX86VarTypeXmmSd */ kX86VarTypeXmmSd, + /* 18: kX86VarTypeXmmPd */ kX86VarTypeXmmPd, + /* 19: kX86VarTypeYmm */ kX86VarTypeYmm, + /* 20: kX86VarTypeYmmPs */ kX86VarTypeYmmPs, + /* 21: kX86VarTypeYmmPd */ kX86VarTypeYmmPd, + /* 22: kX86VarTypeZmm */ kX86VarTypeZmm, + /* 23: kX86VarTypeZmmPs */ kX86VarTypeZmmPs, + /* 24: kX86VarTypeZmmPd */ kX86VarTypeZmmPd }; #endif // ASMJIT_BUILD_X64 @@ -436,7 +448,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, continue; arg._regIndex = self->_passedOrderGp[gpPos++]; - self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + self->_used.or_(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); } // Stack arguments. @@ -482,14 +494,14 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, if (x86ArgIsInt(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderGp)) { arg._regIndex = self->_passedOrderGp[i]; - self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + self->_used.or_(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); continue; } if (x86ArgIsFp(varType) && i < ASMJIT_ARRAY_SIZE(self->_passedOrderXmm)) { arg._varType = static_cast(x86ArgTypeToXmmType(varType)); arg._regIndex = self->_passedOrderXmm[i]; - self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); + self->_used.or_(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); } } @@ -527,7 +539,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, continue; arg._regIndex = self->_passedOrderGp[gpPos++]; - self->_used.add(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); + self->_used.or_(kX86RegClassGp, IntUtil::mask(arg.getRegIndex())); } // Register arguments (Xmm), always left-to-right. @@ -538,7 +550,7 @@ static Error X86FuncDecl_initFunc(X86FuncDecl* self, uint32_t arch, if (x86ArgIsFp(varType)) { arg._varType = static_cast(x86ArgTypeToXmmType(varType)); arg._regIndex = self->_passedOrderXmm[xmmPos++]; - self->_used.add(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); + self->_used.or_(kX86RegClassXyz, IntUtil::mask(arg.getRegIndex())); } } @@ -721,10 +733,10 @@ Error X86Compiler::setArch(uint32_t arch) { _regSize = 4; _regCount.reset(); - _regCount._gp = 8; - _regCount._fp = 8; - _regCount._mm = 8; - _regCount._xy = 8; + _regCount._gp = 8; + _regCount._mm = 8; + _regCount._k = 8; + _regCount._xyz = 8; zax = x86::eax; zcx = x86::ecx; @@ -746,10 +758,10 @@ Error X86Compiler::setArch(uint32_t arch) { _regSize = 8; _regCount.reset(); - _regCount._gp = 16; - _regCount._fp = 8; - _regCount._mm = 8; - _regCount._xy = 16; + _regCount._gp = 16; + _regCount._mm = 8; + _regCount._k = 8; + _regCount._xyz = 16; zax = x86::rax; zcx = x86::rcx; @@ -783,7 +795,7 @@ static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code, JumpNode* node = new(p) JumpNode(self, code, options, opList, opCount); TargetNode* jTarget = self->getTargetById(opList[0].getId()); - node->addFlags(code == kX86InstIdJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc); + node->orFlags(code == kX86InstIdJmp ? kNodeFlagIsJmp | kNodeFlagIsTaken : kNodeFlagIsJcc); node->_target = jTarget; node->_jumpNext = static_cast(jTarget->_from); @@ -792,9 +804,9 @@ static InstNode* X86Compiler_newInst(X86Compiler* self, void* p, uint32_t code, // The 'jmp' is always taken, conditional jump can contain hint, we detect it. if (code == kX86InstIdJmp) - node->addFlags(kNodeFlagIsTaken); + node->orFlags(kNodeFlagIsTaken); else if (options & kInstOptionTaken) - node->addFlags(kNodeFlagIsTaken); + node->orFlags(kNodeFlagIsTaken); node->addOptions(options); return node; @@ -1025,6 +1037,22 @@ InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, return static_cast(addNode(node)); } +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3_) { + Imm o3(o3_); + InstNode* node = newInst(code, o0, o1, o2, o3); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + +InstNode* X86Compiler::emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3_) { + Imm o3(o3_); + InstNode* node = newInst(code, o0, o1, o2, o3); + if (node == NULL) + return NULL; + return static_cast(addNode(node)); +} + // ============================================================================ // [asmjit::X86Compiler - Func] // ============================================================================ diff --git a/libraries/asmjit/x86/x86compiler.h b/libraries/asmjit/x86/x86compiler.h index 2a71bcd31..76b4193dd 100644 --- a/libraries/asmjit/x86/x86compiler.h +++ b/libraries/asmjit/x86/x86compiler.h @@ -37,7 +37,7 @@ struct X86VarState; // ============================================================================ //! X86/X64 variable type. -ASMJIT_ENUM(kX86VarType) { +ASMJIT_ENUM(X86VarType) { //! Variable is SP-FP (x87). kX86VarTypeFp32 = kVarTypeFp32, //! Variable is DP-FP (x87). @@ -46,24 +46,34 @@ ASMJIT_ENUM(kX86VarType) { //! Variable is Mm (MMX). kX86VarTypeMm = 12, + //! Variable is K (AVX512+) + kX86VarTypeK, + //! Variable is Xmm (SSE+). kX86VarTypeXmm, - //! Variable is scalar Xmm SP-FP number. + //! Variable is a scalar Xmm SP-FP number. kX86VarTypeXmmSs, - //! Variable is packed Xmm SP-FP number (4 floats). + //! Variable is a packed Xmm SP-FP number (4 floats). kX86VarTypeXmmPs, - //! Variable is scalar Xmm DP-FP number. + //! Variable is a scalar Xmm DP-FP number. kX86VarTypeXmmSd, - //! Variable is packed Xmm DP-FP number (2 doubles). + //! Variable is a packed Xmm DP-FP number (2 doubles). kX86VarTypeXmmPd, //! Variable is Ymm (AVX+). kX86VarTypeYmm, - //! Variable is packed Ymm SP-FP number (8 floats). + //! Variable is a packed Ymm SP-FP number (8 floats). kX86VarTypeYmmPs, - //! Variable is packed Ymm DP-FP number (4 doubles). + //! Variable is a packed Ymm DP-FP number (4 doubles). kX86VarTypeYmmPd, + //! Variable is Zmm (AVX512+). + kX86VarTypeZmm, + //! Variable is a packed Zmm SP-FP number (16 floats). + kX86VarTypeZmmPs, + //! Variable is a packed Zmm DP-FP number (8 doubles). + kX86VarTypeZmmPd, + //! Count of variable types. kX86VarTypeCount, @@ -76,22 +86,27 @@ ASMJIT_ENUM(kX86VarType) { _kX86VarTypeXmmEnd = kX86VarTypeXmmPd, _kX86VarTypeYmmStart = kX86VarTypeYmm, - _kX86VarTypeYmmEnd = kX86VarTypeYmmPd + _kX86VarTypeYmmEnd = kX86VarTypeYmmPd, + + _kX86VarTypeZmmStart = kX86VarTypeZmm, + _kX86VarTypeZmmEnd = kX86VarTypeZmmPd //! \} }; // ============================================================================ -// [asmjit::kX86VarAttr] +// [asmjit::X86VarAttr] // ============================================================================ //! X86/X64 VarAttr flags. -ASMJIT_ENUM(kX86VarAttr) { +ASMJIT_ENUM(X86VarAttr) { kX86VarAttrGpbLo = 0x10000000, - kX86VarAttrGpbHi = 0x20000000 + kX86VarAttrGpbHi = 0x20000000, + kX86VarAttrFld4 = 0x40000000, + kX86VarAttrFld8 = 0x80000000 }; // ============================================================================ -// [asmjit::kX86FuncConv] +// [asmjit::X86FuncConv] // ============================================================================ //! X86 function calling conventions. @@ -122,7 +137,7 @@ ASMJIT_ENUM(kX86VarAttr) { //! convention. //! //! These types are used together with `Compiler::addFunc()` method. -ASMJIT_ENUM(kX86FuncConv) { +ASMJIT_ENUM(X86FuncConv) { // -------------------------------------------------------------------------- // [X64] // -------------------------------------------------------------------------- @@ -349,7 +364,7 @@ ASMJIT_ENUM(kX86FuncConv) { #if !defined(ASMJIT_DOCGEN) // X86/X64 Host Support - documented in base/compiler.h. -#if defined(ASMJIT_HOST_X86) +#if defined(ASMJIT_ARCH_X86) enum { // X86. kFuncConvHost = kX86FuncConvCDecl, @@ -362,12 +377,12 @@ enum { #elif defined(__BORLANDC__) kFuncConvHostFastCall = kX86FuncConvBorlandFastCall #else -#error "kFuncConvHostFastCall not determined." +#error "AsmJit - kFuncConvHostFastCall not determined." #endif }; -#endif // ASMJIT_HOST_X86 +#endif // ASMJIT_ARCH_X86 -#if defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X64) enum { #if defined(ASMJIT_OS_WINDOWS) kFuncConvHost = kX86FuncConvW64, @@ -378,15 +393,15 @@ enum { kFuncConvHostStdCall = kFuncConvHost, kFuncConvHostFastCall = kFuncConvHost }; -#endif // ASMJIT_HOST_X64 +#endif // ASMJIT_ARCH_X64 #endif // !ASMJIT_DOCGEN // ============================================================================ -// [asmjit::kX86FuncHint] +// [asmjit::X86FuncHint] // ============================================================================ //! X86 function hints. -ASMJIT_ENUM(kX86FuncHint) { +ASMJIT_ENUM(X86FuncHint) { //! Use push/pop sequences instead of mov sequences in function prolog //! and epilog. kX86FuncHintPushPop = 16, @@ -399,11 +414,11 @@ ASMJIT_ENUM(kX86FuncHint) { }; // ============================================================================ -// [asmjit::kX86FuncFlags] +// [asmjit::X86FuncFlags] // ============================================================================ //! X86 function flags. -ASMJIT_ENUM(kX86FuncFlags) { +ASMJIT_ENUM(X86FuncFlags) { //! Whether to emit register load/save sequence using push/pop pairs. kX86FuncFlagPushPop = 0x00010000, @@ -445,13 +460,13 @@ struct X86VarInfo { // [Accessors] // -------------------------------------------------------------------------- - //! Get register type, see `kX86RegType`. + //! Get register type, see `X86RegType`. ASMJIT_INLINE uint32_t getReg() const { return _reg; } //! Get register size in bytes. ASMJIT_INLINE uint32_t getSize() const { return _size; } - //! Get variable class, see `kRegClass`. + //! Get variable class, see `RegClass`. ASMJIT_INLINE uint32_t getClass() const { return _class; } - //! Get variable description, see `kVarFlag`. + //! Get variable description, see `VarFlag`. ASMJIT_INLINE uint32_t getDesc() const { return _desc; } //! Get variable type name. ASMJIT_INLINE const char* getName() const { return _name; } @@ -460,13 +475,13 @@ struct X86VarInfo { // [Members] // -------------------------------------------------------------------------- - //! Register type, see `kX86RegType`. + //! Register type, see `X86RegType`. uint8_t _reg; //! Register size in bytes. uint8_t _size; - //! Register class, see `kRegClass`. + //! Register class, see `RegClass`. uint8_t _class; - //! Variable flags, see `kVarFlag`. + //! Variable flags, see `VarFlag`. uint8_t _desc; //! Variable type name. char _name[4]; @@ -526,12 +541,6 @@ struct X86Var : public Var { return X86Var(*this); } - //! Reset X86Var operand. - ASMJIT_INLINE void reset() { - _init_packed_op_sz_b0_b1_id(kOperandTypeVar, 0, kInvalidReg, kInvalidReg, kInvalidValue); - _init_packed_d2_d3(kInvalidValue, kInvalidValue); - } - // -------------------------------------------------------------------------- // [Type] // -------------------------------------------------------------------------- @@ -558,6 +567,9 @@ struct X86Var : public Var { //! Get whether the variable is Mm (64-bit) register. ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; } + //! Get whether the variable is K (64-bit) register. + ASMJIT_INLINE bool isK() const { return _vreg.type == kX86RegTypeK; } + //! Get whether the variable is Xmm (128-bit) register. ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; } //! Get whether the variable is Ymm (256-bit) register. @@ -700,6 +712,10 @@ struct X86GpVar : public X86Var { // [Construction / Destruction] // -------------------------------------------------------------------------- +protected: + ASMJIT_INLINE X86GpVar(const X86GpVar& other, uint32_t reg, uint32_t size) : X86Var(other, reg, size) {} + +public: //! Create a new uninitialized `X86GpVar` instance. ASMJIT_INLINE X86GpVar() : X86Var() {} @@ -732,18 +748,18 @@ struct X86GpVar : public X86Var { // [X86GpVar Cast] // -------------------------------------------------------------------------- - //! Cast this variable to 8-bit (LO) part of variable + //! Cast this variable to 8-bit (LO) part of variable. ASMJIT_INLINE X86GpVar r8() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); } - //! Cast this variable to 8-bit (LO) part of variable + //! Cast this variable to 8-bit (LO) part of variable. ASMJIT_INLINE X86GpVar r8Lo() const { return X86GpVar(*this, kX86RegTypeGpbLo, 1); } - //! Cast this variable to 8-bit (HI) part of variable + //! Cast this variable to 8-bit (HI) part of variable. ASMJIT_INLINE X86GpVar r8Hi() const { return X86GpVar(*this, kX86RegTypeGpbHi, 1); } - //! Cast this variable to 16-bit part of variable + //! Cast this variable to 16-bit part of variable. ASMJIT_INLINE X86GpVar r16() const { return X86GpVar(*this, kX86RegTypeGpw, 2); } - //! Cast this variable to 32-bit part of variable + //! Cast this variable to 32-bit part of variable. ASMJIT_INLINE X86GpVar r32() const { return X86GpVar(*this, kX86RegTypeGpd, 4); } - //! Cast this variable to 64-bit part of variable + //! Cast this variable to 64-bit part of variable. ASMJIT_INLINE X86GpVar r64() const { return X86GpVar(*this, kX86RegTypeGpq, 8); } // -------------------------------------------------------------------------- @@ -754,13 +770,6 @@ struct X86GpVar : public X86Var { ASMJIT_INLINE bool operator==(const X86GpVar& other) const { return X86Var::operator==(other); } ASMJIT_INLINE bool operator!=(const X86GpVar& other) const { return X86Var::operator!=(other); } - - // -------------------------------------------------------------------------- - // [Private] - // -------------------------------------------------------------------------- - -protected: - ASMJIT_INLINE X86GpVar(const X86GpVar& other, uint32_t reg, uint32_t size) : X86Var(other, reg, size) {} }; // ============================================================================ @@ -847,6 +856,12 @@ struct X86XmmVar : public X86Var { X86Var::reset(); } + // -------------------------------------------------------------------------- + // [X86XmmVar Cast] + // -------------------------------------------------------------------------- + + // TODO: + // -------------------------------------------------------------------------- // [Operator Overload] // -------------------------------------------------------------------------- @@ -894,6 +909,12 @@ struct X86YmmVar : public X86Var { X86Var::reset(); } + // -------------------------------------------------------------------------- + // [X86YmmVar Cast] + // -------------------------------------------------------------------------- + + // TODO: + // -------------------------------------------------------------------------- // [Operator Overload] // -------------------------------------------------------------------------- @@ -1417,7 +1438,7 @@ struct X86CallNode : public CallNode { }; // ============================================================================ -// [asmjit::X86TypeId / VarMapping] +// [asmjit::X86VarId / VarMapping] // ============================================================================ #if !defined(ASMJIT_DOCGEN) @@ -1678,14 +1699,14 @@ ASMJIT_TYPE_ID(X86YmmVar, kX86VarTypeYmm); //! //! Variable states: //! -//! - `kVarStateUnused - State that is assigned to newly created variables or +//! - `kVarStateNone - State that is assigned to newly created variables or //! to not used variables (dereferenced to zero). //! - `kVarStateReg - State that means that variable is currently allocated in //! register. //! - `kVarStateMem - State that means that variable is currently only in //! memory location. //! -//! When you create new variable, initial state is always `kVarStateUnused`, +//! When you create new variable, initial state is always `kVarStateNone`, //! allocating it to register or spilling to memory changes this state to //! `kVarStateReg` or `kVarStateMem`, respectively. During variable lifetime //! it's usual that its state is changed multiple times. To generate better @@ -2018,10 +2039,11 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { //! Create a `X86Compiler` instance. ASMJIT_API X86Compiler(Runtime* runtime, uint32_t arch -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) = kArchHost -#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 +#endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64 ); + //! Destroy the `X86Compiler` instance. ASMJIT_API ~X86Compiler(); @@ -2029,7 +2051,12 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { // [Arch] // -------------------------------------------------------------------------- - //! Get count of registers of the current architecture. + //! \internal + //! + //! Set the architecture to `arch`. + ASMJIT_API Error setArch(uint32_t arch); + + //! Get count of registers of the current architecture and mode. ASMJIT_INLINE const X86RegCount& getRegCount() const { return _regCount; } @@ -2081,8 +2108,6 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { return x86::ptr_abs(pAbs, index, shift, disp, _regSize); } - ASMJIT_API Error setArch(uint32_t arch); - // -------------------------------------------------------------------------- // [Inst / Emit] // -------------------------------------------------------------------------- @@ -2125,6 +2150,10 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, int o2); //! \overload ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, uint64_t o2); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, int o3); + //! \overload + ASMJIT_API InstNode* emit(uint32_t code, const Operand& o0, const Operand& o1, const Operand& o2, uint64_t o3); // -------------------------------------------------------------------------- // [Func] @@ -2135,7 +2164,7 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { //! Add a new function. //! - //! \param conv Calling convention to use (see \ref kFuncConv enum) + //! \param conv Calling convention to use (see \ref FuncConv) //! \param params Function arguments prototype. //! //! This method is usually used as a first step when generating functions @@ -2444,7 +2473,7 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { X86GpReg zdi; // -------------------------------------------------------------------------- - // [X86 Instructions] + // [Emit] // -------------------------------------------------------------------------- #define INST_0x(_Inst_, _Code_) \ @@ -2620,6 +2649,31 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { return emit(_Code_, o0, o1, o2); \ } +#define INST_3ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2) { \ + return emit(_Code_, o0, o1, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int o1, int o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, o2); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, unsigned int o1, unsigned int o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, int64_t o1, int64_t o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, static_cast(o2)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, uint64_t o1, uint64_t o2) { \ + Imm o1Imm(o1); \ + return emit(_Code_, o0, o1Imm, o2); \ + } + #define INST_4x(_Inst_, _Code_, _Op0_, _Op1_, _Op2_) \ ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ return emit(_Code_, o0, o1, o2, o3); \ @@ -2652,6 +2706,35 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { return emit(_Code_, o0, o1, o2, o3); \ } +#define INST_4ii(_Inst_, _Code_, _Op0_, _Op1_, _Op2_, _Op3_) \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, const _Op2_& o2, const _Op3_& o3) { \ + return emit(_Code_, o0, o1, o2, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int o2, int o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, o3); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, unsigned int o2, unsigned int o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, int64_t o2, int64_t o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, static_cast(o3)); \ + } \ + /*! \overload */ \ + ASMJIT_INLINE InstNode* _Inst_(const _Op0_& o0, const _Op1_& o1, uint64_t o2, uint64_t o3) { \ + Imm o2Imm(o2); \ + return emit(_Code_, o0, o1, o2Imm, o3); \ + } + + // -------------------------------------------------------------------------- + // [X86/X64] + // -------------------------------------------------------------------------- + //! Add with carry. INST_2x(adc, kX86InstIdAdc, X86GpVar, X86GpVar) //! \overload @@ -2838,11 +2921,6 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { return emit(kX86InstIdCpuid, x_eax, w_ebx, x_ecx, w_edx); } - //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). - INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86GpVar, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) - //! \overload - INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) - //! Decimal adjust AL after addition (X86 Only). INST_1x(daa, kX86InstIdDaa, X86GpVar) //! Decimal adjust AL after subtraction (X86 Only). @@ -3030,11 +3108,6 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { //! Pop stack into EFLAGS Register (32-bit or 64-bit). INST_0x(popf, kX86InstIdPopf) - //! Return the count of number of bits set to 1 (SSE4.2). - INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86GpVar, !o0.isGpb() && o0.getSize() == o1.getSize()) - //! \overload - INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86Mem, !o0.isGpb()) - //! Push WORD or DWORD/QWORD on the stack. INST_1x_(push, kX86InstIdPush, X86GpVar, o0.getSize() == 2 || o0.getSize() == _regSize) //! Push WORD or DWORD/QWORD on the stack. @@ -3305,273 +3378,277 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { INST_2i(xor_, kX86InstIdXor, X86Mem, Imm) // -------------------------------------------------------------------------- - // [Fpu] + // [FPU] // -------------------------------------------------------------------------- - //! Compute 2^x - 1 (FPU). + //! Compute `2^x - 1` - `fp0 = POW(2, fp0) - 1` (FPU). INST_0x(f2xm1, kX86InstIdF2xm1) - //! Absolute value of fp0 (FPU). + //! Abs `fp0 = ABS(fp0)` (FPU). INST_0x(fabs, kX86InstIdFabs) - //! Add `o1` to `o0` (one has to be `fp0`) and store result in `o0` (FPU). + //! Add `o0 = o0 + o1` (one operand has to be `fp0`) (FPU). INST_2x_(fadd, kX86InstIdFadd, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Add 4-byte or 8-byte FP `o0` to fp0 and store result in fp0 (FPU). + //! Add `fp0 = fp0 + float_or_double[o0]` (FPU). INST_1x(fadd, kX86InstIdFadd, X86Mem) - //! Add fp0 to `o0` and pop the FPU stack (FPU). + //! Add `o0 = o0 + fp0` and POP (FPU). INST_1x(faddp, kX86InstIdFaddp, X86FpReg) - //! \overload + //! Add `fp1 = fp1 + fp0` and POP (FPU). INST_0x(faddp, kX86InstIdFaddp) - //! Load binary coded decimal (FPU). + //! Load BCD from `[o0]` and PUSH (FPU). INST_1x(fbld, kX86InstIdFbld, X86Mem) - //! Store BCD integer and Pop (FPU). + //! Store BCD-Integer to `[o0]` and POP (FPU). INST_1x(fbstp, kX86InstIdFbstp, X86Mem) - //! Change fp0 sign (FPU). + + //! Complement Sign `fp0 = -fp0` (FPU). INST_0x(fchs, kX86InstIdFchs) + //! Clear exceptions (FPU). INST_0x(fclex, kX86InstIdFclex) - //! Conditional move (FPU). + //! Conditional move `if (CF=1) fp0 = o0` (FPU). INST_1x(fcmovb, kX86InstIdFcmovb, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (CF|ZF=1) fp0 = o0` (FPU). INST_1x(fcmovbe, kX86InstIdFcmovbe, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (ZF=1) fp0 = o0` (FPU). INST_1x(fcmove, kX86InstIdFcmove, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (CF=0) fp0 = o0` (FPU). INST_1x(fcmovnb, kX86InstIdFcmovnb, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (CF|ZF=0) fp0 = o0` (FPU). INST_1x(fcmovnbe, kX86InstIdFcmovnbe, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (ZF=0) fp0 = o0` (FPU). INST_1x(fcmovne, kX86InstIdFcmovne, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (PF=0) fp0 = o0` (FPU). INST_1x(fcmovnu, kX86InstIdFcmovnu, X86FpReg) - //! Conditional move (FPU). + //! Conditional move `if (PF=1) fp0 = o0` (FPU). INST_1x(fcmovu, kX86InstIdFcmovu, X86FpReg) - //! Compare fp0 with `o0` (FPU). + //! Compare `fp0` with `o0` (FPU). INST_1x(fcom, kX86InstIdFcom, X86FpReg) - //! Compare fp0 with fp1 (FPU). + //! Compare `fp0` with `fp1` (FPU). INST_0x(fcom, kX86InstIdFcom) - //! Compare fp0 with 4-byte or 8-byte FP at `src` (FPU). + //! Compare `fp0` with `float_or_double[o0]` (FPU). INST_1x(fcom, kX86InstIdFcom, X86Mem) - //! Compare fp0 with `o0` and pop the FPU stack (FPU). + //! Compare `fp0` with `o0` and POP (FPU). INST_1x(fcomp, kX86InstIdFcomp, X86FpReg) - //! Compare fp0 with fp1 and pop the FPU stack (FPU). + //! Compare `fp0` with `fp1` and POP (FPU). INST_0x(fcomp, kX86InstIdFcomp) - //! Compare fp0 with 4-byte or 8-byte FP at `adr` and pop the FPU stack (FPU). + //! Compare `fp0` with `float_or_double[o0]` and POP (FPU). INST_1x(fcomp, kX86InstIdFcomp, X86Mem) - //! Compare fp0 with fp1 and pop the FPU stack twice (FPU). + //! Compare `fp0` with `fp1` and POP twice (FPU). INST_0x(fcompp, kX86InstIdFcompp) - //! Compare fp0 and `o0` and Set EFLAGS (FPU). + //! Compare `fp0` with `o0` and set EFLAGS (FPU). INST_1x(fcomi, kX86InstIdFcomi, X86FpReg) - //! Compare fp0 and `o0` and Set EFLAGS and pop the FPU stack (FPU). + //! Compare `fp0` with `o0` and set EFLAGS and POP (FPU). INST_1x(fcomip, kX86InstIdFcomip, X86FpReg) - //! Calculate cosine of fp0 and store result in fp0 (FPU). + //! Cos `fp0 = cos(fp0)` (FPU). INST_0x(fcos, kX86InstIdFcos) - //! Decrement FPU stack-top pointer (FPU). + + //! Decrement FPU stack pointer (FPU). INST_0x(fdecstp, kX86InstIdFdecstp) - //! Divide `o0` by `o1` (one has to be `fp0`) (FPU). + //! Divide `o0 = o0 / o1` (one has to be `fp0`) (FPU). INST_2x_(fdiv, kX86InstIdFdiv, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Divide fp0 by 32-bit or 64-bit FP value (FPU). + //! Divide `fp0 = fp0 / float_or_double[o0]` (FPU). INST_1x(fdiv, kX86InstIdFdiv, X86Mem) - //! Divide `o0` by fp0 (FPU). + //! Divide `o0 = o0 / fp0` and POP (FPU). INST_1x(fdivp, kX86InstIdFdivp, X86FpReg) - //! \overload + //! Divide `fp1 = fp1 / fp0` and POP (FPU). INST_0x(fdivp, kX86InstIdFdivp) - //! Reverse divide `o0` by `o1` (one has to be `fp0`) (FPU). + //! Reverse divide `o0 = o1 / o0` (one has to be `fp0`) (FPU). INST_2x_(fdivr, kX86InstIdFdivr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Reverse divide fp0 by 32-bit or 64-bit FP value (FPU). + //! Reverse divide `fp0 = float_or_double[o0] / fp0` (FPU). INST_1x(fdivr, kX86InstIdFdivr, X86Mem) - //! Reverse divide `o0` by fp0 (FPU). + //! Reverse divide `o0 = fp0 / o0` and POP (FPU). INST_1x(fdivrp, kX86InstIdFdivrp, X86FpReg) - //! \overload + //! Reverse divide `fp1 = fp0 / fp1` and POP (FPU). INST_0x(fdivrp, kX86InstIdFdivrp) //! Free FP register (FPU). INST_1x(ffree, kX86InstIdFfree, X86FpReg) - //! Add 16-bit or 32-bit integer to fp0 (FPU). + //! Add `fp0 = fp0 + short_or_int[o0]` (FPU). INST_1x_(fiadd, kX86InstIdFiadd, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Compare fp0 with 16-bit or 32-bit Integer (FPU). + //! Compare `fp0` with `short_or_int[o0]` (FPU). INST_1x_(ficom, kX86InstIdFicom, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Compare fp0 with 16-bit or 32-bit Integer and pop the FPU stack (FPU). + //! Compare `fp0` with `short_or_int[o0]` and POP (FPU). INST_1x_(ficomp, kX86InstIdFicomp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + //! Divide `fp0 = fp0 / short_or_int[o0]` (FPU). INST_1x_(fidiv, kX86InstIdFidiv, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Reverse divide fp0 by 32-bit or 16-bit integer (`src`) (FPU). + //! Reverse divide `fp0 = short_or_int[o0] / fp0` (FPU). INST_1x_(fidivr, kX86InstIdFidivr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Load 16-bit, 32-bit or 64-bit Integer and push it to the FPU stack (FPU). + //! Load `short_or_int_or_long[o0]` and PUSH (FPU). INST_1x_(fild, kX86InstIdFild, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) - //! Multiply fp0 by 16-bit or 32-bit integer and store it to fp0 (FPU). + //! Multiply `fp0 *= short_or_int[o0]` (FPU). INST_1x_(fimul, kX86InstIdFimul, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Increment FPU stack-top pointer (FPU). + //! Increment FPU stack pointer (FPU). INST_0x(fincstp, kX86InstIdFincstp) //! Initialize FPU (FPU). INST_0x(finit, kX86InstIdFinit) - //! Subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + //! Subtract `fp0 = fp0 - short_or_int[o0]` (FPU). INST_1x_(fisub, kX86InstIdFisub, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Reverse subtract 16-bit or 32-bit integer from fp0 and store result to fp0 (FPU). + //! Reverse subtract `fp0 = short_or_int[o0] - fp0` (FPU). INST_1x_(fisubr, kX86InstIdFisubr, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) //! Initialize FPU without checking for pending unmasked exceptions (FPU). INST_0x(fninit, kX86InstIdFninit) - //! Store fp0 as 16-bit or 32-bit Integer to `o0` (FPU). + //! Store `fp0` as `short_or_int[o0]` (FPU). INST_1x_(fist, kX86InstIdFist, X86Mem, o0.getSize() == 2 || o0.getSize() == 4) - //! Store fp0 as 16-bit, 32-bit or 64-bit Integer to `o0` and pop the FPU stack (FPU). + //! Store `fp0` as `short_or_int_or_long[o0]` and POP (FPU). INST_1x_(fistp, kX86InstIdFistp, X86Mem, o0.getSize() == 2 || o0.getSize() == 4 || o0.getSize() == 8) - //! Push 32-bit, 64-bit or 80-bit floating point value on the FPU stack (FPU). + + //! Load `float_or_double_or_extended[o0]` and PUSH (FPU). INST_1x_(fld, kX86InstIdFld, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) - //! Push `o0` on the FPU stack (FPU). + //! PUSH `o0` (FPU). INST_1x(fld, kX86InstIdFld, X86FpReg) - //! Push +1.0 on the FPU stack (FPU). + //! PUSH `1.0` (FPU). INST_0x(fld1, kX86InstIdFld1) - //! Push log2(10) on the FPU stack (FPU). + //! PUSH `log2(10)` (FPU). INST_0x(fldl2t, kX86InstIdFldl2t) - //! Push log2(e) on the FPU stack (FPU). + //! PUSH `log2(e)` (FPU). INST_0x(fldl2e, kX86InstIdFldl2e) - //! Push pi on the FPU stack (FPU). + //! PUSH `pi` (FPU). INST_0x(fldpi, kX86InstIdFldpi) - //! Push log10(2) on the FPU stack (FPU). + //! PUSH `log10(2)` (FPU). INST_0x(fldlg2, kX86InstIdFldlg2) - //! Push ln(2) on the FPU stack (FPU). + //! PUSH `ln(2)` (FPU). INST_0x(fldln2, kX86InstIdFldln2) - //! Push +0.0 on the FPU stack (FPU). + //! PUSH `+0.0` (FPU). INST_0x(fldz, kX86InstIdFldz) - //! Load x87 FPU control word (2 bytes) (FPU). + //! Load x87 FPU control word from `word_ptr[o0]` (FPU). INST_1x(fldcw, kX86InstIdFldcw, X86Mem) - //! Load x87 FPU environment (14 or 28 bytes) (FPU). + //! Load x87 FPU environment (14 or 28 bytes) from `[o0]` (FPU). INST_1x(fldenv, kX86InstIdFldenv, X86Mem) - //! Multiply `o0` by `o1` (one has to be `fp0`) and store result in `o0` (FPU). + //! Multiply `o0 = o0 * o1` (one has to be `fp0`) (FPU). INST_2x_(fmul, kX86InstIdFmul, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Multiply fp0 by 32-bit or 64-bit `o0` and store result in fp0 (FPU). + //! Multiply `fp0 = fp0 * float_or_double[o0]` (FPU). INST_1x(fmul, kX86InstIdFmul, X86Mem) - //! Multiply fp0 by `o0` and pop the FPU stack (FPU). + //! Multiply `o0 = o0 * fp0` and POP (FPU). INST_1x(fmulp, kX86InstIdFmulp, X86FpReg) - //! \overload + //! Multiply `fp1 = fp1 * fp0` and POP (FPU). INST_0x(fmulp, kX86InstIdFmulp) //! Clear exceptions (FPU). INST_0x(fnclex, kX86InstIdFnclex) //! No operation (FPU). INST_0x(fnop, kX86InstIdFnop) - //! Save FPU state (FPU). + //! Save FPU state to `[o0]` (FPU). INST_1x(fnsave, kX86InstIdFnsave, X86Mem) - //! Store x87 FPU environment (FPU). + //! Store x87 FPU environment to `[o0]` (FPU). INST_1x(fnstenv, kX86InstIdFnstenv, X86Mem) - //! Store x87 FPU control word (FPU). + //! Store x87 FPU control word to `[o0]` (FPU). INST_1x(fnstcw, kX86InstIdFnstcw, X86Mem) //! Store x87 FPU status word to `o0` (AX) (FPU). - INST_1x_(fnstsw, kX86InstIdFnstsw, X86GpReg, o0.isRegCode(kX86RegTypeGpw, kX86RegIndexAx)) - //! Store x87 FPU status word to `o0` (2 bytes) (FPU). + INST_1x(fnstsw, kX86InstIdFnstsw, X86GpVar) + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). INST_1x(fnstsw, kX86InstIdFnstsw, X86Mem) - //! Arctan(`fp1` / `fp0`) and pop the FPU stack (FPU). + //! Partial Arctan `fp1 = atan2(fp1, fp0)` and POP (FPU). INST_0x(fpatan, kX86InstIdFpatan) - //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + //! Partial Remainder[Trunc] `fp1 = fp0 % fp1` and POP (FPU). INST_0x(fprem, kX86InstIdFprem) - //! Fprem(`fp0`, `fp1`) and pop the FPU stack (FPU). + //! Partial Remainder[Round] `fp1 = fp0 % fp1` and POP (FPU). INST_0x(fprem1, kX86InstIdFprem1) - //! Arctan(`fp0`) and pop the FPU stack (FPU). + //! Partial Tan `fp0 = tan(fp0)` and PUSH `1.0` (FPU). INST_0x(fptan, kX86InstIdFptan) - //! Round `fp0` to Integer (FPU). + //! Round `fp0 = round(fp0)` (FPU). INST_0x(frndint, kX86InstIdFrndint) - //! Restore FPU state from `o0` (94 or 108 bytes) (FPU). + //! Restore FPU state from `[o0]` (94 or 108 bytes) (FPU). INST_1x(frstor, kX86InstIdFrstor, X86Mem) - //! Save FPU state to `o0` (94 or 108 bytes) (FPU). + //! Save FPU state to `[o0]` (94 or 108 bytes) (FPU). INST_1x(fsave, kX86InstIdFsave, X86Mem) - //! Scale `fp0` by `fp1` (FPU). + //! Scale `fp0 = fp0 * pow(2, RoundTowardsZero(fp1))` (FPU). INST_0x(fscale, kX86InstIdFscale) - //! Sine of `fp0` and store result in `fp0` (FPU). + //! Sin `fp0 = sin(fp0)` (FPU). INST_0x(fsin, kX86InstIdFsin) - //! Sine and cosine of `fp0`, store sine in `fp0` and push cosine on the FPU stack (FPU). + //! Sincos `fp0 = sin(fp0)` and PUSH `cos(fp0)` (FPU). INST_0x(fsincos, kX86InstIdFsincos) - //! Square root of `fp0` and store it in `fp0` (FPU). + //! Square root `fp0 = sqrt(fp0)` (FPU). INST_0x(fsqrt, kX86InstIdFsqrt) - //! Store floating point value to 32-bit or 64-bit memory location (FPU). + //! Store floating point value to `float_or_double[o0]` (FPU). INST_1x_(fst, kX86InstIdFst, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Store floating point value to `o0` (FPU). + //! Copy `o0 = fp0` (FPU). INST_1x(fst, kX86InstIdFst, X86FpReg) - //! Store floating point value to 32-bit or 64-bit memory location and pop the FPU stack (FPU). + //! Store floating point value to `float_or_double_or_extended[o0]` and POP (FPU). INST_1x_(fstp, kX86InstIdFstp, X86Mem, o0.getSize() == 4 || o0.getSize() == 8 || o0.getSize() == 10) - //! Store floating point value to `o0` and pop the FPU stack (FPU). + //! Copy `o0 = fp0` and POP (FPU). INST_1x(fstp, kX86InstIdFstp, X86FpReg) - //! Store x87 FPU control word to `o0` (2 bytes) (FPU). + //! Store x87 FPU control word to `word_ptr[o0]` (FPU). INST_1x(fstcw, kX86InstIdFstcw, X86Mem) - //! Store x87 FPU environment to `o0` (14 or 28 bytes) (FPU). + //! Store x87 FPU environment to `[o0]` (14 or 28 bytes) (FPU). INST_1x(fstenv, kX86InstIdFstenv, X86Mem) - //! Store x87 FPU status word to `o0` (allocated in AX) (FPU). + //! Store x87 FPU status word to `o0` (AX) (FPU). INST_1x(fstsw, kX86InstIdFstsw, X86GpVar) - //! Store x87 FPU status word (2 bytes) (FPU). + //! Store x87 FPU status word to `word_ptr[o0]` (FPU). INST_1x(fstsw, kX86InstIdFstsw, X86Mem) - //! Subtract `o0` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + //! Subtract `o0 = o0 - o1` (one has to be `fp0`) (FPU). INST_2x_(fsub, kX86InstIdFsub, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Subtract 32-bit or 64-bit `o0` from fp0 and store result in fp0 (FPU). + //! Subtract `fp0 = fp0 - float_or_double[o0]` (FPU). INST_1x_(fsub, kX86InstIdFsub, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Subtract fp0 from `o0` and pop FPU stack (FPU). + //! Subtract `o0 = o0 - fp0` and POP (FPU). INST_1x(fsubp, kX86InstIdFsubp, X86FpReg) - //! \overload + //! Subtract `fp1 = fp1 - fp0` and POP (FPU). INST_0x(fsubp, kX86InstIdFsubp) - //! Reverse subtract `o1` from `o0` (one has to be `fp0`) and store result in `o0` (FPU). + //! Reverse subtract `o0 = o1 - o0` (one has to be `fp0`) (FPU). INST_2x_(fsubr, kX86InstIdFsubr, X86FpReg, X86FpReg, o0.getRegIndex() == 0 || o1.getRegIndex() == 0) - //! Reverse subtract 32-bit or 64-bit `o0` from `fp0` and store result in `fp0` (FPU). + //! Reverse subtract `fp0 = fp0 - float_or_double[o0]` (FPU). INST_1x_(fsubr, kX86InstIdFsubr, X86Mem, o0.getSize() == 4 || o0.getSize() == 8) - //! Reverse subtract `fp0` from `o0` and pop FPU stack (FPU). + //! Reverse subtract `o0 = o0 - fp0` and POP (FPU). INST_1x(fsubrp, kX86InstIdFsubrp, X86FpReg) - //! \overload + //! Reverse subtract `fp1 = fp1 - fp0` and POP (FPU). INST_0x(fsubrp, kX86InstIdFsubrp) - //! Floating point test - Compare `fp0` with 0.0. (FPU). + //! Compare `fp0` with `0.0` (FPU). INST_0x(ftst, kX86InstIdFtst) //! Unordered compare `fp0` with `o0` (FPU). INST_1x(fucom, kX86InstIdFucom, X86FpReg) //! Unordered compare `fp0` with `fp1` (FPU). INST_0x(fucom, kX86InstIdFucom) - //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS (FPU). + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS (FPU). INST_1x(fucomi, kX86InstIdFucomi, X86FpReg) - //! Unordered compare `fp0` and `o0`, check for ordered values and set EFLAGS and pop the FPU stack (FPU). + //! Unordered compare `fp0` with `o0`, check for ordered values and set EFLAGS and POP (FPU). INST_1x(fucomip, kX86InstIdFucomip, X86FpReg) - //! Unordered compare `fp0` with `o0` and pop the FPU stack (FPU). + //! Unordered compare `fp0` with `o0` and POP (FPU). INST_1x(fucomp, kX86InstIdFucomp, X86FpReg) - //! Unordered compare `fp0` with `fp1` and pop the FPU stack (FPU). + //! Unordered compare `fp0` with `fp1` and POP (FPU). INST_0x(fucomp, kX86InstIdFucomp) - //! Unordered compare `fp0` with `fp1` and pop the FPU stack twice (FPU). + //! Unordered compare `fp0` with `fp1` and POP twice (FPU). INST_0x(fucompp, kX86InstIdFucompp) INST_0x(fwait, kX86InstIdFwait) //! Examine fp0 (FPU). INST_0x(fxam, kX86InstIdFxam) - //! Exchange content of fp0 with `o0` (FPU). + //! Exchange `fp0` with `o0` (FPU). INST_1x(fxch, kX86InstIdFxch, X86FpReg) //! Restore FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). INST_1x(fxrstor, kX86InstIdFxrstor, X86Mem) //! Store FP/MMX/SIMD extension states to `o0` (512 bytes) (FPU, MMX, SSE). INST_1x(fxsave, kX86InstIdFxsave, X86Mem) - //! Extract exponent and store to `fp0` and push significand on the FPU stack (FPU). + //! Extract `fp0 = exponent(fp0)` and PUSH `significant(fp0)` (FPU). INST_0x(fxtract, kX86InstIdFxtract) - //! Compute `fp1 * log2(fp0)`, pop the FPU stack and store result in `fp0` (FPU). + //! Compute `fp1 = fp1 * log2(fp0)` and POP (FPU). INST_0x(fyl2x, kX86InstIdFyl2x) - //! Compute `fp1 * log2(fp0 + 1)`, pop the FPU stack and store result in `fp0` (FPU). + //! Compute `fp1 = fp1 * log2(fp0 + 1)` and POP (FPU). INST_0x(fyl2xp1, kX86InstIdFyl2xp1) // -------------------------------------------------------------------------- @@ -3839,7 +3916,7 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { INST_0x(emms, kX86InstIdEmms) // -------------------------------------------------------------------------- - // [3dNow] + // [3DNOW] // -------------------------------------------------------------------------- //! Packed SP-FP to DWORD convert (3dNow!). @@ -4927,8 +5004,7 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { //! \overload INST_2x(addsubps, kX86InstIdAddsubps, X86XmmVar, X86Mem) - //! Store truncated `fp0` as 16-bit, 32-bit or 64-bit integer to `o0` and pop - //! the FPU stack (FPU / SSE3). + //! Store truncated `fp0` to `short_or_int_or_long[o0]` and POP (FPU & SSE3). INST_1x(fisttp, kX86InstIdFisttp, X86Mem) //! Packed DP-FP horizontal add (SSE3). @@ -5388,6 +5464,11 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { // [SSE4.2] // -------------------------------------------------------------------------- + //! Accumulate crc32 value (polynomial 0x11EDC6F41) (SSE4.2). + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86GpVar, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! \overload + INST_2x_(crc32, kX86InstIdCrc32, X86GpVar, X86Mem, o0.isRegType(kX86RegTypeGpd) || o0.isRegType(kX86RegTypeGpq)) + //! Packed compare explicit length strings, return index (SSE4.2). INST_3i(pcmpestri, kX86InstIdPcmpestri, X86XmmVar, X86XmmVar, Imm) //! \overload @@ -5413,6 +5494,43 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { //! \overload INST_2x(pcmpgtq, kX86InstIdPcmpgtq, X86XmmVar, X86Mem) + // -------------------------------------------------------------------------- + // [SSE4a] + // -------------------------------------------------------------------------- + + //! Extract Field (SSE4a). + INST_2x(extrq, kX86InstIdExtrq, X86XmmVar, X86XmmVar) + //! Extract Field (SSE4a). + INST_3ii(extrq, kX86InstIdExtrq, X86XmmVar, Imm, Imm) + + //! Insert Field (SSE4a). + INST_2x(insertq, kX86InstIdInsertq, X86XmmVar, X86XmmVar) + //! Insert Field (SSE4a). + INST_4ii(insertq, kX86InstIdInsertq, X86XmmVar, X86XmmVar, Imm, Imm) + + //! Move Non-Temporal Scalar DP-FP (SSE4a). + INST_2x(movntsd, kX86InstIdMovntsd, X86Mem, X86XmmVar) + //! Move Non-Temporal Scalar SP-FP (SSE4a). + INST_2x(movntss, kX86InstIdMovntss, X86Mem, X86XmmVar) + + // -------------------------------------------------------------------------- + // [POPCNT] + // -------------------------------------------------------------------------- + + //! Return the count of number of bits set to 1 (POPCNT). + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86GpVar, !o0.isGpb() && o0.getSize() == o1.getSize()) + //! \overload + INST_2x_(popcnt, kX86InstIdPopcnt, X86GpVar, X86Mem, !o0.isGpb()) + + // -------------------------------------------------------------------------- + // [LZCNT] + // -------------------------------------------------------------------------- + + //! Count the number of leading zero bits (LZCNT). + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpVar, X86GpVar) + //! \overload + INST_2x(lzcnt, kX86InstIdLzcnt, X86GpVar, X86Mem) + // -------------------------------------------------------------------------- // [AESNI] // -------------------------------------------------------------------------- @@ -5456,6 +5574,34 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { //! \overload INST_3i(pclmulqdq, kX86InstIdPclmulqdq, X86XmmVar, X86Mem, Imm); + // -------------------------------------------------------------------------- + // [XSAVE] + // -------------------------------------------------------------------------- + + //! Restore Processor Extended States specified by `o1:o2` (XSAVE). + INST_3x(xrstor, kX86InstIdXrstor, X86Mem, X86GpVar, X86GpVar) + //! Restore Processor Extended States specified by `o1:o2` (XSAVE&X64). + INST_3x(xrstor64, kX86InstIdXrstor64, X86Mem, X86GpVar, X86GpVar) + + //! Save Processor Extended States specified by `o1:o2` (XSAVE). + INST_3x(xsave, kX86InstIdXsave, X86Mem, X86GpVar, X86GpVar) + //! Save Processor Extended States specified by `o1:o2` (XSAVE&X64). + INST_3x(xsave64, kX86InstIdXsave64, X86Mem, X86GpVar, X86GpVar) + + //! Save Processor Extended States specified by `o1:o2` (Optimized) (XSAVEOPT). + INST_3x(xsaveopt, kX86InstIdXsave, X86Mem, X86GpVar, X86GpVar) + //! Save Processor Extended States specified by `o1:o2` (Optimized) (XSAVEOPT&X64). + INST_3x(xsaveopt64, kX86InstIdXsave64, X86Mem, X86GpVar, X86GpVar) + + //! Get XCR - `o1:o2 <- XCR[o0]` (`EDX:EAX <- XCR[ECX]`) (XSAVE). + INST_3x(xgetbv, kX86InstIdXgetbv, X86GpVar, X86GpVar, X86GpVar) + //! Set XCR - `XCR[o0] <- o1:o2` (`XCR[ECX] <- EDX:EAX`) (XSAVE). + INST_3x(xsetbv, kX86InstIdXsetbv, X86GpVar, X86GpVar, X86GpVar) + + // -------------------------------------------------------------------------- + // [Cleanup] + // -------------------------------------------------------------------------- + #undef INST_0x #undef INST_1x @@ -5471,10 +5617,12 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler { #undef INST_3x #undef INST_3x_ #undef INST_3i +#undef INST_3ii #undef INST_4x #undef INST_4x_ #undef INST_4i +#undef INST_4ii }; //! \} diff --git a/libraries/asmjit/x86/x86context.cpp b/libraries/asmjit/x86/x86context.cpp index 6dabc0f30..9e5cfdde0 100644 --- a/libraries/asmjit/x86/x86context.cpp +++ b/libraries/asmjit/x86/x86context.cpp @@ -143,9 +143,9 @@ static void X86Context_annotateOperand(X86Context* self, } static bool X86Context_annotateInstruction(X86Context* self, - StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) { + StringBuilder& sb, uint32_t instId, const Operand* opList, uint32_t opCount) { - sb.appendString(_x86InstInfo[code].getInstName()); + sb.appendString(_x86InstInfo[instId].getInstName()); for (uint32_t i = 0; i < opCount; i++) { if (i == 0) sb.appendChar(' '); @@ -207,7 +207,7 @@ static void X86Context_traceNode(X86Context* self, Node* node_) { case kNodeTypeInst: { InstNode* node = static_cast(node_); X86Context_annotateInstruction(self, sb, - node->getCode(), node->getOpList(), node->getOpCount()); + node->getInstId(), node->getOpList(), node->getOpCount()); break; } @@ -279,16 +279,16 @@ X86Context::~X86Context() {} // [asmjit::X86Context - Reset] // ============================================================================ -void X86Context::reset() { - Context::reset(); +void X86Context::reset(bool releaseMemory) { + Context::reset(releaseMemory); _x86State.reset(0); _clobberedRegs.reset(); _stackFrameCell = NULL; _gaRegs[kX86RegClassGp ] = IntUtil::bits(_regCount.getGp()) & ~IntUtil::mask(kX86RegIndexSp); - _gaRegs[kX86RegClassFp ] = IntUtil::bits(_regCount.getFp()); _gaRegs[kX86RegClassMm ] = IntUtil::bits(_regCount.getMm()); + _gaRegs[kX86RegClassK ] = IntUtil::bits(_regCount.getK()); _gaRegs[kX86RegClassXyz] = IntUtil::bits(_regCount.getXyz()); _argBaseReg = kInvalidReg; // Used by patcher. @@ -426,8 +426,26 @@ static const X86SpecialInst x86SpecialInstBlend[] = { { 0 , kInvalidReg , kVarAttrInReg } }; -static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t code, const Operand* opList, uint32_t opCount) { - switch (code) { +static const X86SpecialInst x86SpecialInstXsaveXrstor[] = { + { kInvalidReg , kInvalidReg , 0 }, + { kX86RegIndexDx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } +}; + +static const X86SpecialInst x86SpecialInstXgetbv[] = { + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg }, + { kInvalidReg , kX86RegIndexDx, kVarAttrOutReg }, + { kInvalidReg , kX86RegIndexAx, kVarAttrOutReg } +}; + +static const X86SpecialInst x86SpecialInstXsetbv[] = { + { kX86RegIndexCx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexDx, kInvalidReg , kVarAttrInReg }, + { kX86RegIndexAx, kInvalidReg , kVarAttrInReg } +}; + +static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t instId, const Operand* opList, uint32_t opCount) { + switch (instId) { case kX86InstIdCpuid: return x86SpecialInstCpuid; @@ -600,6 +618,20 @@ static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t code, con case kX86InstIdPblendvb: return x86SpecialInstBlend; + case kX86InstIdXrstor: + case kX86InstIdXrstor64: + case kX86InstIdXsave: + case kX86InstIdXsave64: + case kX86InstIdXsaveopt: + case kX86InstIdXsaveopt64: + return x86SpecialInstXsaveXrstor; + + case kX86InstIdXgetbv: + return x86SpecialInstXgetbv; + + case kX86InstIdXsetbv: + return x86SpecialInstXsetbv; + default: return NULL; } @@ -976,7 +1008,7 @@ void X86Context::emitMoveVarOnStack( X86Reg r0, r1; uint32_t regSize = compiler->getRegSize(); - uint32_t instCode; + uint32_t instId; switch (dstType) { case kVarTypeInt8: @@ -1002,7 +1034,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(1); r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = (dstType == kVarTypeInt16 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; + instId = (dstType == kVarTypeInt16 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpD; } @@ -1027,7 +1059,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(1); r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; + instId = (dstType == kVarTypeInt32 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpD; } @@ -1036,7 +1068,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(2); r1.setCode(kX86RegTypeGpw, srcIndex); - instCode = (dstType == kVarTypeInt32 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; + instId = (dstType == kVarTypeInt32 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpD; } @@ -1060,7 +1092,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(1); r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; + instId = (dstType == kVarTypeInt64 && srcType == kVarTypeInt8) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpXQ; } @@ -1069,7 +1101,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(2); r1.setCode(kX86RegTypeGpw, srcIndex); - instCode = (dstType == kVarTypeInt64 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; + instId = (dstType == kVarTypeInt64 && srcType == kVarTypeInt16) ? kX86InstIdMovsx : kX86InstIdMovzx; goto _ExtendMovGpXQ; } @@ -1078,7 +1110,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(4); r1.setCode(kX86RegTypeGpd, srcIndex); - instCode = kX86InstIdMovsxd; + instId = kX86InstIdMovsxd; if (dstType == kVarTypeInt64 && srcType == kVarTypeInt32) goto _ExtendMovGpXQ; else @@ -1104,7 +1136,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(1); r1.setCode(kX86RegTypeGpbLo, srcIndex); - instCode = kX86InstIdMovzx; + instId = kX86InstIdMovzx; goto _ExtendMovGpXQ; } @@ -1113,7 +1145,7 @@ void X86Context::emitMoveVarOnStack( r1.setSize(2); r1.setCode(kX86RegTypeGpw, srcIndex); - instCode = kX86InstIdMovzx; + instId = kX86InstIdMovzx; goto _ExtendMovGpXQ; } @@ -1175,7 +1207,7 @@ _ExtendMovGpD: r0.setSize(4); r0.setCode(kX86RegTypeGpd, srcIndex); - compiler->emit(instCode, r0, r1); + compiler->emit(instId, r0, r1); compiler->emit(kX86InstIdMov, m0, r0); return; @@ -1185,7 +1217,7 @@ _ExtendMovGpXQ: r0.setSize(8); r0.setCode(kX86RegTypeGpq, srcIndex); - compiler->emit(instCode, r0, r1); + compiler->emit(instId, r0, r1); compiler->emit(kX86InstIdMov, m0, r0); } else { @@ -1193,7 +1225,7 @@ _ExtendMovGpXQ: r0.setSize(4); r0.setCode(kX86RegTypeGpd, srcIndex); - compiler->emit(instCode, r0, r1); + compiler->emit(instId, r0, r1); _ExtendMovGpDQ: compiler->emit(kX86InstIdMov, m0, r0); @@ -1749,8 +1781,8 @@ static ASMJIT_INLINE Node* X86Context_getOppositeJccFlow(JumpNode* jNode) { // ============================================================================ //! \internal -static void X86Context_prepareSingleVarInst(uint32_t code, VarAttr* va) { - switch (code) { +static void X86Context_prepareSingleVarInst(uint32_t instId, VarAttr* va) { + switch (instId) { // - andn reg, reg ; Set all bits in reg to 0. // - xor/pxor reg, reg ; Set all bits in reg to 0. // - sub/psub reg, reg ; Set all bits in reg to 0. @@ -1763,7 +1795,7 @@ static void X86Context_prepareSingleVarInst(uint32_t code, VarAttr* va) { case kX86InstIdPsubsb : case kX86InstIdPsubsw : case kX86InstIdPsubusb : case kX86InstIdPsubusw : case kX86InstIdPcmpeqb : case kX86InstIdPcmpeqw : case kX86InstIdPcmpeqd : case kX86InstIdPcmpeqq : case kX86InstIdPcmpgtb : case kX86InstIdPcmpgtw : case kX86InstIdPcmpgtd : case kX86InstIdPcmpgtq : - va->delFlags(kVarAttrInReg); + va->andNotFlags(kVarAttrInReg); break; // - and reg, reg ; Nop. @@ -1772,7 +1804,7 @@ static void X86Context_prepareSingleVarInst(uint32_t code, VarAttr* va) { case kX86InstIdAnd : case kX86InstIdAndpd : case kX86InstIdAndps : case kX86InstIdPand : case kX86InstIdOr : case kX86InstIdOrpd : case kX86InstIdOrps : case kX86InstIdPor : case kX86InstIdXchg : - va->delFlags(kVarAttrOutReg); + va->andNotFlags(kVarAttrOutReg); break; } } @@ -1824,7 +1856,7 @@ static ASMJIT_INLINE X86RegMask X86Context_getUsedArgs(X86Context* self, X86Call const FuncInOut& arg = decl->getArg(i); if (!arg.hasRegIndex()) continue; - regs.add(x86VarTypeToClass(arg.getVarType()), IntUtil::mask(arg.getRegIndex())); + regs.or_(x86VarTypeToClass(arg.getVarType()), IntUtil::mask(arg.getRegIndex())); } return regs; @@ -2058,7 +2090,6 @@ Error X86Context::fetch() { Node* next = NULL; Node* stop = getStop(); - uint32_t groupId = 1; uint32_t flowId = 0; VarAttr vaTmpList[80]; @@ -2117,7 +2148,7 @@ Error X86Context::fetch() { goto _NoMemory; \ \ X86RegCount vaIndex; \ - vaIndex.makeIndex(regCount); \ + vaIndex.indexFromRegCount(regCount); \ \ map->_vaCount = vaCount; \ map->_count = regCount; \ @@ -2181,7 +2212,7 @@ Error X86Context::fetch() { regCount.add(_Vd_->getClass()); \ } \ \ - _Va_->addFlags(_Flags_); \ + _Va_->orFlags(_Flags_); \ _Va_->addVarCount(1); \ } while (0) @@ -2230,18 +2261,13 @@ _NextGroup: VI_BEGIN(); if (node->getHint() == kVarHintAlloc) { - uint32_t remain[kX86RegClassCount]; + uint32_t remain[_kX86RegClassManagedCount]; HintNode* cur = node; remain[kX86RegClassGp ] = _regCount.getGp() - 1 - func->hasFuncFlag(kFuncFlagIsNaked); - remain[kX86RegClassFp ] = _regCount.getFp(); remain[kX86RegClassMm ] = _regCount.getMm(); - - // Correct. Instead of using `getXyz()` which may be 32 in 64-bit - // mode we use `getGp()`. The reason is that not all registers are - // accessible by all instructions when using AVX512, this makes the - // algorithm safe. - remain[kX86RegClassXyz] = _regCount.getGp(); + remain[kX86RegClassK ] = _regCount.getK(); + remain[kX86RegClassXyz] = _regCount.getXyz(); // Merge as many alloc-hints as possible. for (;;) { @@ -2333,14 +2359,14 @@ _NextGroup: case kNodeTypeInst: { InstNode* node = static_cast(node_); - uint32_t code = node->getCode(); + uint32_t instId = node->getInstId(); uint32_t flags = node->getFlags(); Operand* opList = node->getOpList(); uint32_t opCount = node->getOpCount(); if (opCount) { - const X86InstExtendedInfo& extendedInfo = _x86InstInfo[code].getExtendedInfo(); + const X86InstExtendedInfo& extendedInfo = _x86InstInfo[instId].getExtendedInfo(); const X86SpecialInst* special = NULL; VI_BEGIN(); @@ -2348,7 +2374,7 @@ _NextGroup: if (extendedInfo.isFp()) flags |= kNodeFlagIsFp; - if (extendedInfo.isSpecial() && (special = X86SpecialInst_get(code, opList, opCount)) != NULL) + if (extendedInfo.isSpecial() && (special = X86SpecialInst_get(instId, opList, opCount)) != NULL) flags |= kNodeFlagIsSpecial; uint32_t gpAllowedMask = 0xFFFFFFFF; @@ -2363,7 +2389,7 @@ _NextGroup: VI_MERGE_VAR(vd, va, 0, gaRegs[vd->getClass()] & gpAllowedMask); if (static_cast(op)->isGpb()) { - va->addFlags(static_cast(op)->isGpbLo() ? kX86VarAttrGpbLo : kX86VarAttrGpbHi); + va->orFlags(static_cast(op)->isGpbLo() ? kX86VarAttrGpbLo : kX86VarAttrGpbHi); if (arch == kArchX86) { // If a byte register is accessed in 32-bit mode we have to limit // all allocable registers for that variable to eax/ebx/ecx/edx. @@ -2401,17 +2427,17 @@ _NextGroup: if (inReg != kInvalidReg) { uint32_t mask = IntUtil::mask(inReg); - inRegs.add(c, mask); + inRegs.or_(c, mask); va->addInRegs(mask); } if (outReg != kInvalidReg) { uint32_t mask = IntUtil::mask(outReg); - outRegs.add(c, mask); + outRegs.or_(c, mask); va->setOutRegIndex(outReg); } - va->addFlags(special[i].flags); + va->orFlags(special[i].flags); } else { uint32_t inFlags = kVarAttrInReg; @@ -2426,7 +2452,7 @@ _NextGroup: // but there are some exceptions based on the operands' size // and type. if (extendedInfo.isMove()) { - uint32_t movSize = extendedInfo.getMoveSize(); + uint32_t movSize = extendedInfo.getWriteSize(); uint32_t varSize = vd->getSize(); // Exception - If the source operand is a memory location @@ -2461,7 +2487,7 @@ _NextGroup: combinedFlags = inFlags; } // Imul. - else if (code == kX86InstIdImul && opCount == 3) { + else if (instId == kX86InstIdImul && opCount == 3) { combinedFlags = outFlags; } } @@ -2470,13 +2496,13 @@ _NextGroup: combinedFlags = inFlags; // Idiv is a special instruction, never handled here. - ASMJIT_ASSERT(code != kX86InstIdIdiv); + ASMJIT_ASSERT(instId != kX86InstIdIdiv); // Xchg/Xadd/Imul. - if (extendedInfo.isXchg() || (code == kX86InstIdImul && opCount == 3 && i == 1)) + if (extendedInfo.isXchg() || (instId == kX86InstIdImul && opCount == 3 && i == 1)) combinedFlags = inFlags | outFlags; } - va->addFlags(combinedFlags); + va->orFlags(combinedFlags); } } else if (op->isMem()) { @@ -2488,7 +2514,7 @@ _NextGroup: if (!vd->isStack()) { VI_MERGE_VAR(vd, va, 0, gaRegs[vd->getClass()] & gpAllowedMask); if (m->getMemType() == kMemTypeBaseIndex) { - va->addFlags(kVarAttrInReg); + va->orFlags(kVarAttrInReg); } else { uint32_t inFlags = kVarAttrInMem; @@ -2503,7 +2529,7 @@ _NextGroup: // as if it's just move to the register. It's just a bit // simpler as there are no special cases. if (extendedInfo.isMove()) { - uint32_t movSize = IntUtil::iMax(extendedInfo.getMoveSize(), m->getSize()); + uint32_t movSize = IntUtil::iMax(extendedInfo.getWriteSize(), m->getSize()); uint32_t varSize = vd->getSize(); if (movSize >= varSize) @@ -2523,7 +2549,7 @@ _NextGroup: combinedFlags = inFlags | outFlags; } - va->addFlags(combinedFlags); + va->orFlags(combinedFlags); } } } @@ -2533,7 +2559,7 @@ _NextGroup: vd = compiler->getVdById(m->getIndex()); VI_MERGE_VAR(vd, va, 0, gaRegs[kX86RegClassGp] & gpAllowedMask); va->andAllocableRegs(indexMask); - va->addFlags(kVarAttrInReg); + va->orFlags(kVarAttrInReg); } } } @@ -2543,7 +2569,7 @@ _NextGroup: // Handle instructions which result in zeros/ones or nop if used with the // same destination and source operand. if (vaCount == 1 && opCount >= 2 && opList[0].isVar() && opList[1].isVar() && !node->hasMemOp()) - X86Context_prepareSingleVarInst(code, &vaTmpList[0]); + X86Context_prepareSingleVarInst(instId, &vaTmpList[0]); } VI_END(node_); @@ -2577,7 +2603,7 @@ _NextGroup: // backward jump. This behavior can be overridden by using // `kInstOptionTaken` when the instruction is created. if (!jNode->isTaken() && opCount == 1 && jTargetFlowId <= flowId) { - jNode->addFlags(kNodeFlagIsTaken); + jNode->orFlags(kNodeFlagIsTaken); } } else if (jNext->isFetched()) { @@ -2623,18 +2649,18 @@ _NextGroup: if (arg.hasRegIndex()) { if (x86VarTypeToClass(aType) == vd->getClass()) { - va->addFlags(kVarAttrOutReg); + va->orFlags(kVarAttrOutReg); va->setOutRegIndex(arg.getRegIndex()); } else { - va->addFlags(kVarAttrOutConv); + va->orFlags(kVarAttrOutConv); } } else { if ((x86VarTypeToClass(aType) == vd->getClass()) || (vType == kX86VarTypeXmmSs && aType == kVarTypeFp32) || (vType == kX86VarTypeXmmSd && aType == kVarTypeFp64)) { - va->addFlags(kVarAttrOutMem); + va->orFlags(kVarAttrOutMem); } else { // TODO: [COMPILER] Not implemented. @@ -2674,12 +2700,21 @@ _NextGroup: VarData* vd = compiler->getVdById(op->getId()); VarAttr* va; - if (vd->getClass() == retClass) { + VI_MERGE_VAR(vd, va, 0, 0); + + if (retClass == vd->getClass()) { // TODO: [COMPILER] Fix RetNode fetch. - VI_MERGE_VAR(vd, va, 0, 0); + va->orFlags(kVarAttrInReg); va->setInRegs(i == 0 ? IntUtil::mask(kX86RegIndexAx) : IntUtil::mask(kX86RegIndexDx)); - va->addFlags(kVarAttrInReg); - inRegs.add(retClass, va->getInRegs()); + inRegs.or_(retClass, va->getInRegs()); + } + else if (retClass == kX86RegClassFp) { + uint32_t fldFlag = ret.getVarType() == kVarTypeFp32 ? kX86VarAttrFld4 : kX86VarAttrFld8; + va->orFlags(kVarAttrInMem | fldFlag); + } + else { + // TODO: Fix possible other return type conversions. + ASMJIT_ASSERT(!"Reached"); } } } @@ -2719,7 +2754,7 @@ _NextGroup: vd = compiler->getVdById(target->getId()); VI_MERGE_VAR(vd, va, 0, 0); - va->addFlags(kVarAttrInReg | kVarAttrInCall); + va->orFlags(kVarAttrInReg | kVarAttrInCall); if (va->getInRegs() == 0) va->addAllocableRegs(gpAllocableMask); } @@ -2731,12 +2766,12 @@ _NextGroup: if (!vd->isStack()) { VI_MERGE_VAR(vd, va, 0, 0); if (m->getMemType() == kMemTypeBaseIndex) { - va->addFlags(kVarAttrInReg | kVarAttrInCall); + va->orFlags(kVarAttrInReg | kVarAttrInCall); if (va->getInRegs() == 0) va->addAllocableRegs(gpAllocableMask); } else { - va->addFlags(kVarAttrInMem | kVarAttrInCall); + va->orFlags(kVarAttrInMem | kVarAttrInCall); } } } @@ -2746,7 +2781,7 @@ _NextGroup: vd = compiler->getVdById(m->getIndex()); VI_MERGE_VAR(vd, va, 0, 0); - va->addFlags(kVarAttrInReg | kVarAttrInCall); + va->orFlags(kVarAttrInReg | kVarAttrInCall); if ((va->getInRegs() & ~indexMask) == 0) va->andAllocableRegs(gpAllocableMask & indexMask); } @@ -2769,10 +2804,10 @@ _NextGroup: if (vd->getClass() == argClass) { va->addInRegs(IntUtil::mask(arg.getRegIndex())); - va->addFlags(kVarAttrInReg | kVarAttrInArg); + va->orFlags(kVarAttrInReg | kVarAttrInArg); } else { - va->addFlags(kVarAttrInConv | kVarAttrInArg); + va->orFlags(kVarAttrInConv | kVarAttrInArg); } } // If this is a stack-based argument we insert SArgNode instead of @@ -2803,18 +2838,18 @@ _NextGroup: if (vd->getClass() == retClass) { va->setOutRegIndex(ret.getRegIndex()); - va->addFlags(kVarAttrOutReg | kVarAttrOutRet); + va->orFlags(kVarAttrOutReg | kVarAttrOutRet); } else { - va->addFlags(kVarAttrOutConv | kVarAttrOutRet); + va->orFlags(kVarAttrOutConv | kVarAttrOutRet); } } } // Init clobbered. - clobberedRegs.set(kX86RegClassGp , IntUtil::bits(_regCount.getGp()) & (~decl->getPreserved(kX86RegClassGp))); - clobberedRegs.set(kX86RegClassFp , IntUtil::bits(_regCount.getFp())); - clobberedRegs.set(kX86RegClassMm , IntUtil::bits(_regCount.getMm()) & (~decl->getPreserved(kX86RegClassMm))); + clobberedRegs.set(kX86RegClassGp , IntUtil::bits(_regCount.getGp()) & (~decl->getPreserved(kX86RegClassGp ))); + clobberedRegs.set(kX86RegClassMm , IntUtil::bits(_regCount.getMm()) & (~decl->getPreserved(kX86RegClassMm ))); + clobberedRegs.set(kX86RegClassK , IntUtil::bits(_regCount.getK()) & (~decl->getPreserved(kX86RegClassK ))); clobberedRegs.set(kX86RegClassXyz, IntUtil::bits(_regCount.getXyz()) & (~decl->getPreserved(kX86RegClassXyz))); VI_END(node_); @@ -2860,7 +2895,7 @@ Error X86Context::annotate() { if (node_->getComment() == NULL) { if (node_->getType() == kNodeTypeInst) { InstNode* node = static_cast(node_); - X86Context_annotateInstruction(this, sb, node->getCode(), node->getOpList(), node->getOpCount()); + X86Context_annotateInstruction(this, sb, node->getInstId(), node->getOpList(), node->getOpCount()); node_->setComment(static_cast(sa.dup(sb.getData(), sb.getLength() + 1))); maxLen = IntUtil::iMax(maxLen, static_cast(sb.getLength())); @@ -2962,7 +2997,7 @@ protected: //! Variable map. X86VarMap* _map; //! VarAttr list (per register class). - VarAttr* _vaList[4]; + VarAttr* _vaList[_kX86RegClassManagedCount]; //! Count of all VarAttr's. uint32_t _vaCount; @@ -2990,8 +3025,8 @@ ASMJIT_INLINE void X86BaseAlloc::init(Node* node, X86VarMap* map) { { VarAttr* va = map->getVaList(); _vaList[kX86RegClassGp ] = va; - _vaList[kX86RegClassFp ] = va + map->getVaStart(kX86RegClassFp ); _vaList[kX86RegClassMm ] = va + map->getVaStart(kX86RegClassMm ); + _vaList[kX86RegClassK ] = va + map->getVaStart(kX86RegClassK ); _vaList[kX86RegClassXyz] = va + map->getVaStart(kX86RegClassXyz); } @@ -3223,8 +3258,8 @@ ASMJIT_INLINE Error X86VarAlloc::run(Node* node_) { cleanup(); // Update clobbered mask. - _context->_clobberedRegs.add(_willAlloc); - _context->_clobberedRegs.add(map->_clobberedRegs); + _context->_clobberedRegs.or_(_willAlloc); + _context->_clobberedRegs.or_(map->_clobberedRegs); // Unuse. unuseAfter(); @@ -3245,7 +3280,7 @@ ASMJIT_INLINE void X86VarAlloc::init(Node* node, X86VarMap* map) { // add more registers when assigning registers to variables that don't need // any specific register. _willAlloc = map->_inRegs; - _willAlloc.add(map->_outRegs); + _willAlloc.or_(map->_outRegs); _willSpill.reset(); } @@ -3308,7 +3343,7 @@ ASMJIT_INLINE void X86VarAlloc::plan() { if ((mandatoryRegs | allocableRegs) & regMask) { va->setOutRegIndex(regIndex); - va->addFlags(kVarAttrAllocOutDone); + va->orFlags(kVarAttrAllocOutDone); if (mandatoryRegs & regMask) { // Case 'a' - 'willAlloc' contains initially all inRegs from all VarAttr's. @@ -3329,7 +3364,7 @@ ASMJIT_INLINE void X86VarAlloc::plan() { else { if ((mandatoryRegs | allocableRegs) & regMask) { va->setInRegIndex(regIndex); - va->addFlags(kVarAttrAllocInDone); + va->orFlags(kVarAttrAllocInDone); if (mandatoryRegs & regMask) { // Case 'a' - 'willAlloc' contains initially all inRegs from all VarAttr's. @@ -3377,7 +3412,7 @@ ASMJIT_INLINE void X86VarAlloc::plan() { } else { ASMJIT_TLOG("[RA-PLAN ] Done\n"); - va->addFlags(kVarAttrAllocInDone); + va->orFlags(kVarAttrAllocInDone); addVaDone(C); continue; } @@ -3563,12 +3598,12 @@ ASMJIT_INLINE void X86VarAlloc::alloc() { VarAttr* bVa = bVd->getVa(); _context->swapGp(aVd, bVd); - aVa->addFlags(kVarAttrAllocInDone); + aVa->orFlags(kVarAttrAllocInDone); addVaDone(C); // Doublehit, two registers allocated by a single swap. if (bVa != NULL && bVa->getInRegIndex() == aIndex) { - bVa->addFlags(kVarAttrAllocInDone); + bVa->orFlags(kVarAttrAllocInDone); addVaDone(C); } @@ -3579,7 +3614,7 @@ ASMJIT_INLINE void X86VarAlloc::alloc() { else if (aIndex != kInvalidReg) { _context->move(aVd, bIndex); - aVa->addFlags(kVarAttrAllocInDone); + aVa->orFlags(kVarAttrAllocInDone); addVaDone(C); didWork = true; @@ -3588,7 +3623,7 @@ ASMJIT_INLINE void X86VarAlloc::alloc() { else { _context->alloc(aVd, bIndex); - aVa->addFlags(kVarAttrAllocInDone); + aVa->orFlags(kVarAttrAllocInDone); addVaDone(C); didWork = true; @@ -3613,7 +3648,7 @@ ASMJIT_INLINE void X86VarAlloc::alloc() { _context->attach(vd, regIndex, false); } - va->addFlags(kVarAttrAllocOutDone); + va->orFlags(kVarAttrAllocOutDone); addVaDone(C); } } @@ -3730,7 +3765,7 @@ ASMJIT_INLINE void X86VarAlloc::modified() { uint32_t regMask = IntUtil::mask(regIndex); vd->setModified(true); - _context->_x86State._modified.add(C, regMask); + _context->_x86State._modified.or_(C, regMask); } } } @@ -3972,7 +4007,7 @@ ASMJIT_INLINE void X86CallAlloc::plan() { // is not clobbered (i.e. it will survive function call). if ((regMask & inRegs) != 0 || ((regMask & ~clobbered) != 0 && (vaFlags & kVarAttrUnuse) == 0)) { va->setInRegIndex(regIndex); - va->addFlags(kVarAttrAllocInDone); + va->orFlags(kVarAttrAllocInDone); addVaDone(C); } else { @@ -3985,7 +4020,7 @@ ASMJIT_INLINE void X86CallAlloc::plan() { willFree |= regMask; } else { - va->addFlags(kVarAttrAllocInDone); + va->orFlags(kVarAttrAllocInDone); addVaDone(C); } } @@ -4131,12 +4166,12 @@ ASMJIT_INLINE void X86CallAlloc::alloc() { if (C == kX86RegClassGp) { _context->swapGp(aVd, bVd); - aVa->addFlags(kVarAttrAllocInDone); + aVa->orFlags(kVarAttrAllocInDone); addVaDone(C); // Doublehit, two registers allocated by a single swap. if (bVa != NULL && bVa->getInRegIndex() == aIndex) { - bVa->addFlags(kVarAttrAllocInDone); + bVa->orFlags(kVarAttrAllocInDone); addVaDone(C); } @@ -4147,7 +4182,7 @@ ASMJIT_INLINE void X86CallAlloc::alloc() { else if (aIndex != kInvalidReg) { _context->move(aVd, bIndex); - aVa->addFlags(kVarAttrAllocInDone); + aVa->orFlags(kVarAttrAllocInDone); addVaDone(C); didWork = true; @@ -4156,7 +4191,7 @@ ASMJIT_INLINE void X86CallAlloc::alloc() { else { _context->alloc(aVd, bIndex); - aVa->addFlags(kVarAttrAllocInDone); + aVa->orFlags(kVarAttrAllocInDone); addVaDone(C); didWork = true; @@ -4227,7 +4262,7 @@ ASMJIT_INLINE void X86CallAlloc::duplicate() { for (uint32_t dupIndex = 0; inRegs != 0; dupIndex++, inRegs >>= 1) { if (inRegs & 0x1) { _context->emitMove(vd, dupIndex, regIndex, "Duplicate"); - _context->_clobberedRegs.add(C, IntUtil::mask(dupIndex)); + _context->_clobberedRegs.or_(C, IntUtil::mask(dupIndex)); } } } @@ -4346,7 +4381,7 @@ ASMJIT_INLINE void X86CallAlloc::clobber() { ASMJIT_ASSERT(vd != NULL); VarAttr* va = vd->getVa(); - uint32_t vdState = kVarStateUnused; + uint32_t vdState = kVarStateNone; if (!vd->isModified() || (va != NULL && (va->getFlags() & (kVarAttrOutAll | kVarAttrUnuse)) != 0)) { vdState = kVarStateMem; @@ -4376,23 +4411,49 @@ ASMJIT_INLINE void X86CallAlloc::ret() { continue; VarData* vd = _compiler->getVdById(op->getId()); + uint32_t vf = _x86VarInfo[vd->getType()].getDesc(); uint32_t regIndex = ret.getRegIndex(); + // TODO: Is it necessary to check for kInvalidReg when unusing if it's + // checked by unuse<> as well? switch (vd->getClass()) { case kX86RegClassGp: + ASMJIT_ASSERT(x86VarTypeToClass(ret.getVarType()) == vd->getClass()); + if (vd->getRegIndex() != kInvalidReg) _context->unuse(vd); + _context->attach(vd, regIndex, true); break; + case kX86RegClassMm: + ASMJIT_ASSERT(x86VarTypeToClass(ret.getVarType()) == vd->getClass()); + if (vd->getRegIndex() != kInvalidReg) _context->unuse(vd); + _context->attach(vd, regIndex, true); break; + case kX86RegClassXyz: - if (vd->getRegIndex() != kInvalidReg) - _context->unuse(vd); - _context->attach(vd, regIndex, true); + if (ret.getVarType() == kVarTypeFp32 || ret.getVarType() == kVarTypeFp64) { + X86Mem m = _context->getVarMem(vd); + m.setSize( + (vf & kVarFlagSp) ? 4 : + (vf & kVarFlagDp) ? 8 : + (ret.getVarType() == kVarTypeFp32) ? 4 : 8); + + _context->unuse(vd, kVarStateMem); + _compiler->fstp(m); + } + else { + ASMJIT_ASSERT(x86VarTypeToClass(ret.getVarType()) == vd->getClass()); + + if (vd->getRegIndex() != kInvalidReg) + _context->unuse(vd); + + _context->attach(vd, regIndex, true); + } break; } } @@ -4405,8 +4466,6 @@ ASMJIT_INLINE void X86CallAlloc::ret() { //! \internal static Error X86Context_translateOperands(X86Context* self, Operand* opList, uint32_t opCount) { X86Compiler* compiler = self->getCompiler(); - const X86VarInfo* varInfo = _x86VarInfo; - uint32_t hasGpdBase = compiler->getRegSize() == 4; // Translate variables into registers. @@ -4467,8 +4526,8 @@ static Error X86Context_initFunc(X86Context* self, X86FuncNode* func) { // Setup "Save-Restore" registers. func->_saveRestoreRegs.set(kX86RegClassGp , clobberedRegs.get(kX86RegClassGp ) & decl->getPreserved(kX86RegClassGp )); - func->_saveRestoreRegs.set(kX86RegClassFp , 0); func->_saveRestoreRegs.set(kX86RegClassMm , clobberedRegs.get(kX86RegClassMm ) & decl->getPreserved(kX86RegClassMm )); + func->_saveRestoreRegs.set(kX86RegClassK , 0); func->_saveRestoreRegs.set(kX86RegClassXyz, clobberedRegs.get(kX86RegClassXyz) & decl->getPreserved(kX86RegClassXyz)); ASMJIT_ASSERT(!func->_saveRestoreRegs.has(kX86RegClassGp, IntUtil::mask(kX86RegIndexSp))); @@ -4503,7 +4562,7 @@ static Error X86Context_initFunc(X86Context* self, X86FuncNode* func) { // Get a memory cell where the original stack frame will be stored. MemCell* cell = self->_newStackCell(regSize, regSize); if (cell == NULL) - return self->getError(); + return self->getError(); // The error has already been set. func->addFuncFlags(kFuncFlagIsStackAdjusted); self->_stackFrameCell = cell; @@ -4540,7 +4599,7 @@ static Error X86Context_initFunc(X86Context* self, X86FuncNode* func) { // from '_saveRestoreRegs' in case that it is preserved. fRegMask = IntUtil::mask(fRegIndex); if ((fRegMask & decl->getPreserved(kX86RegClassGp)) != 0) { - func->_saveRestoreRegs.del(kX86RegClassGp, fRegMask); + func->_saveRestoreRegs.andNot(kX86RegClassGp, fRegMask); func->_isStackFrameRegPreserved = true; } @@ -4556,7 +4615,7 @@ static Error X86Context_initFunc(X86Context* self, X86FuncNode* func) { else stackFrameCopyRegs = IntUtil::keepNOnesFromRight(stackFrameCopyRegs, IntUtil::iMin(maxRegs, 2)); - func->_saveRestoreRegs.add(kX86RegClassGp, stackFrameCopyRegs & decl->getPreserved(kX86RegClassGp)); + func->_saveRestoreRegs.or_(kX86RegClassGp, stackFrameCopyRegs & decl->getPreserved(kX86RegClassGp)); IntUtil::indexNOnesFromRight(func->_stackFrameCopyGpIndex, stackFrameCopyRegs, maxRegs); } } @@ -4679,16 +4738,14 @@ static Error X86Context_patchFuncMem(X86Context* self, X86FuncNode* func, Node* if (vd->isMemArg()) { m->_vmem.base = self->_argBaseReg; - m->_vmem.displacement += vd->getMemOffset(); - m->_vmem.displacement += self->_argBaseOffset; + m->_vmem.displacement += self->_argBaseOffset + vd->getMemOffset(); } else { MemCell* cell = vd->getMemCell(); ASMJIT_ASSERT(cell != NULL); m->_vmem.base = self->_varBaseReg; - m->_vmem.displacement += cell->getOffset(); - m->_vmem.displacement += self->_varBaseOffset; + m->_vmem.displacement += self->_varBaseOffset + cell->getOffset(); } } } @@ -4753,7 +4810,7 @@ static Error X86Context_translatePrologEpilog(X86Context* self, X86FuncNode* fun if (func->isNaked()) { if (func->isStackMisaligned()) { fpReg.setIndex(func->getStackFrameRegIndex()); - fpOffset = x86::ptr(self->_zsp, static_cast(self->_stackFrameCell->getOffset())); + fpOffset = x86::ptr(self->_zsp, self->_varBaseOffset + static_cast(self->_stackFrameCell->getOffset())); earlyPushPop = func->hasFuncFlag(kX86FuncFlagPushPop); if (earlyPushPop) @@ -4992,8 +5049,34 @@ static void X86Context_translateJump(X86Context* self, JumpNode* jNode, TargetNo // ============================================================================ static Error X86Context_translateRet(X86Context* self, RetNode* rNode, TargetNode* exitTarget) { + X86Compiler* compiler = self->getCompiler(); Node* node = rNode->getNext(); + // 32-bit mode requires to push floating point return value(s), handle it + // here as it's a special case. + X86VarMap* map = rNode->getMap(); + if (map != NULL) { + VarAttr* vaList = map->getVaList(); + uint32_t vaCount = map->getVaCount(); + + for (uint32_t i = 0; i < vaCount; i++) { + VarAttr& va = vaList[i]; + if (va.hasFlag(kX86VarAttrFld4 | kX86VarAttrFld8)) { + VarData* vd = va.getVd(); + X86Mem m(self->getVarMem(vd)); + + uint32_t flags = _x86VarInfo[vd->getType()].getDesc(); + m.setSize( + (flags & kVarFlagSp) ? 4 : + (flags & kVarFlagDp) ? 8 : + va.hasFlag(kX86VarAttrFld4) ? 4 : 8); + + compiler->fld(m); + } + } + } + + // Decide whether to `jmp` or not in case we are next to the return label. while (node != NULL) { switch (node->getType()) { // If we have found an exit label we just return, there is no need to @@ -5029,8 +5112,6 @@ static Error X86Context_translateRet(X86Context* self, RetNode* rNode, TargetNod _EmitRet: { - X86Compiler* compiler = self->getCompiler(); - compiler->_setCursor(rNode); compiler->jmp(exitTarget->getLabel()); } @@ -5096,7 +5177,7 @@ _NextGroup: } next = node_->getNext(); - node_->addFlags(kNodeFlagIsTranslated); + node_->orFlags(kNodeFlagIsTranslated); ASMJIT_TSEC({ X86Context_traceNode(this, node_); @@ -5143,7 +5224,7 @@ _NextGroup: VarData* vd = va->getVd(); if (!liveness->getBit(vd->getContextId())) - va->addFlags(kVarAttrUnuse); + va->orFlags(kVarAttrUnuse); } } } @@ -5321,7 +5402,7 @@ _NextGroup: for (;;) { Node* next = node_->getNext(); - node_->addFlags(kNodeFlagIsScheduled); + node_->orFlags(kNodeFlagIsScheduled); // Shouldn't happen here, investigate if hit. ASMJIT_ASSERT(node_ != stop); @@ -5508,7 +5589,7 @@ static ASMJIT_INLINE Error X86Context_serialize(X86Context* self, X86Assembler* case kNodeTypeInst: { InstNode* node = static_cast(node_); - uint32_t code = node->getCode(); + uint32_t instId = node->getInstId(); uint32_t opCount = node->getOpCount(); const Operand* opList = node->getOpList(); @@ -5517,9 +5598,10 @@ static ASMJIT_INLINE Error X86Context_serialize(X86Context* self, X86Assembler* const Operand* o0 = &noOperand; const Operand* o1 = &noOperand; const Operand* o2 = &noOperand; + const Operand* o3 = &noOperand; if (node->isSpecial()) { - switch (code) { + switch (instId) { case kX86InstIdCpuid: break; @@ -5632,6 +5714,19 @@ static ASMJIT_INLINE Error X86Context_serialize(X86Context* self, X86Assembler* case kX86InstIdRepneScasB: case kX86InstIdRepneScasD: case kX86InstIdRepneScasQ: case kX86InstIdRepneScasW: break; + case kX86InstIdXrstor: + case kX86InstIdXrstor64: + case kX86InstIdXsave: + case kX86InstIdXsave64: + case kX86InstIdXsaveopt: + case kX86InstIdXsaveopt64: + o0 = &opList[0]; + break; + + case kX86InstIdXgetbv: + case kX86InstIdXsetbv: + break; + default: ASMJIT_ASSERT(!"Reached"); } @@ -5640,10 +5735,11 @@ static ASMJIT_INLINE Error X86Context_serialize(X86Context* self, X86Assembler* if (opCount > 0) o0 = &opList[0]; if (opCount > 1) o1 = &opList[1]; if (opCount > 2) o2 = &opList[2]; + if (opCount > 3) o3 = &opList[3]; } - // We use this form, because it is the main one. - assembler->emit(code, *o0, *o1, *o2); + // Should call _emit() directly as 4 operand form is the main form. + assembler->emit(instId, *o0, *o1, *o2, *o3); break; } diff --git a/libraries/asmjit/x86/x86context_p.h b/libraries/asmjit/x86/x86context_p.h index 64bfc11fa..1a818dc1b 100644 --- a/libraries/asmjit/x86/x86context_p.h +++ b/libraries/asmjit/x86/x86context_p.h @@ -59,7 +59,7 @@ struct X86Context : public Context { // [Reset] // -------------------------------------------------------------------------- - virtual void reset(); + virtual void reset(bool releaseMemory = false); // -------------------------------------------------------------------------- // [Arch] @@ -150,8 +150,8 @@ struct X86Context : public Context { vd->setModified(modified); _x86State.getListByClass(C)[regIndex] = vd; - _x86State._occupied.add(C, regMask); - _x86State._modified.add(C, static_cast(modified) << regIndex); + _x86State._occupied.or_(C, regMask); + _x86State._modified.or_(C, static_cast(modified) << regIndex); ASMJIT_X86_CHECK_STATE } @@ -174,8 +174,8 @@ struct X86Context : public Context { vd->setModified(false); _x86State.getListByClass(C)[regIndex] = NULL; - _x86State._occupied.del(C, regMask); - _x86State._modified.del(C, regMask); + _x86State._occupied.andNot(C, regMask); + _x86State._modified.andNot(C, regMask); ASMJIT_X86_CHECK_STATE } @@ -244,7 +244,7 @@ struct X86Context : public Context { emitSave(vd, regIndex, "Save"); vd->setModified(false); - _x86State._modified.del(C, regMask); + _x86State._modified.andNot(C, regMask); ASMJIT_X86_CHECK_STATE } @@ -381,7 +381,7 @@ struct X86Context : public Context { uint32_t regMask = IntUtil::mask(regIndex); vd->setModified(true); - _x86State._modified.add(C, regMask); + _x86State._modified.or_(C, regMask); ASMJIT_X86_CHECK_STATE } @@ -393,9 +393,9 @@ struct X86Context : public Context { //! Unuse. //! //! Unuse variable, it will be detached it if it's allocated then its state - //! will be changed to kVarStateUnused. + //! will be changed to kVarStateNone. template - ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateUnused) { + ASMJIT_INLINE void unuse(VarData* vd, uint32_t vState = kVarStateNone) { ASMJIT_ASSERT(vd->getClass() == C); ASMJIT_ASSERT(vState != kVarStateReg); diff --git a/libraries/asmjit/x86/x86cpuinfo.cpp b/libraries/asmjit/x86/x86cpuinfo.cpp index 75ed0b06f..bd36dde29 100644 --- a/libraries/asmjit/x86/x86cpuinfo.cpp +++ b/libraries/asmjit/x86/x86cpuinfo.cpp @@ -88,20 +88,33 @@ _Skip: // in 64-bit mode not allows to use inline assembler, so we need intrinsic and // we need also asm version. +union X86XCR { + uint64_t value; + + struct { + uint32_t eax; + uint32_t edx; + }; +}; + // callCpuId() and detectCpuInfo() for x86 and x64 platforms begins here. -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) -void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) { +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) +void X86CpuUtil::_docpuid(uint32_t inEcx, uint32_t inEax, X86CpuId* result) { #if defined(_MSC_VER) -// 2009-02-05: Thanks to Mike Tajmajer for supporting VC7.1 compiler. -// ASMJIT_HOST_X64 is here only for readibility, only VS2005 can compile 64-bit code. -# if _MSC_VER >= 1400 || defined(ASMJIT_HOST_X64) - // Done by intrinsics. - __cpuidex(reinterpret_cast(outResult->i), inEax, inEcx); -# else // _MSC_VER < 1400 +// __cpuidex was introduced by VS2008-SP1. +# if _MSC_FULL_VER >= 150030729 + __cpuidex(reinterpret_cast(result->i), inEax, inEcx); +# elif defined(ASMJIT_ARCH_X64) + // VS2008 or less, 64-bit mode - `__cpuidex` doesn't exist! However, 64-bit + // calling convention specifies parameter to be passed in ECX/RCX, so we may + // be lucky if compiler doesn't move the register, otherwise the result is + // undefined. + __cpuid(reinterpret_cast(result->i), inEax); +# else uint32_t cpuid_eax = inEax; - uint32_t cpuid_ecx = inCax; - uint32_t* cpuid_out = outResult->i; + uint32_t cpuid_ecx = inEcx; + uint32_t* cpuid_out = result->i; __asm { mov eax, cpuid_eax @@ -113,24 +126,59 @@ void X86CpuUtil::callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* outResult) mov dword ptr[edi + 8], ecx mov dword ptr[edi + 12], edx } -# endif // _MSC_VER < 1400 +# endif #elif defined(__GNUC__) // Note, patched to preserve ebx/rbx register which is used by GCC. -# if defined(ASMJIT_HOST_X86) +# if defined(ASMJIT_ARCH_X86) # define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \ - asm ("mov %%ebx, %%edi\n" \ - "cpuid\n" \ - "xchg %%edi, %%ebx\n" \ - : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx)) + __asm__ __volatile__( \ + "mov %%ebx, %%edi\n" \ + "cpuid\n" \ + "xchg %%edi, %%ebx\n" \ + : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) \ + : "a" (inEax), "c" (inEcx)) # else # define __myCpuId(inEax, inEcx, outEax, outEbx, outEcx, outEdx) \ - asm ("mov %%rbx, %%rdi\n" \ - "cpuid\n" \ - "xchg %%rdi, %%rbx\n" \ - : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) : "a" (inEax), "c" (inEcx)) + __asm__ __volatile__( \ + "mov %%rbx, %%rdi\n" \ + "cpuid\n" \ + "xchg %%rdi, %%rbx\n" \ + : "=a" (outEax), "=D" (outEbx), "=c" (outEcx), "=d" (outEdx) \ + : "a" (inEax), "c" (inEcx)) # endif - __myCpuId(inEax, inEcx, outResult->eax, outResult->ebx, outResult->ecx, outResult->edx); + __myCpuId(inEax, inEcx, result->eax, result->ebx, result->ecx, result->edx); + +#else +# error "asmjit::X86CpuUtil::_docpuid() unimplemented!" +#endif +} + +static void callXGetBV(X86XCR* result, uint32_t inEcx) { + +#if defined(_MSC_VER) + +# if (_MSC_FULL_VER >= 160040219) // 2010SP1+ + result->value = _xgetbv(inEcx); +# else + result->value = 0; +# endif + +#elif defined(__GNUC__) + + unsigned int eax, edx; +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) + __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(inEcx)); +# else + __asm__ __volatile__(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(inEcx)); +# endif + result->eax = eax; + result->edx = edx; + +#else + + result->value = 0; + #endif // COMPILER } @@ -138,7 +186,11 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { X86CpuId regs; uint32_t i; - uint32_t maxId; + uint32_t maxBaseId; + + bool maybeMPX = false; + X86XCR xcr0; + xcr0.value = 0; // Clear everything except the '_size' member. ::memset(reinterpret_cast(cpuInfo) + sizeof(uint32_t), @@ -148,14 +200,13 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { cpuInfo->_hwThreadsCount = CpuInfo::detectHwThreadsCount(); // -------------------------------------------------------------------------- - // [CPUID EAX=0x00000000] + // [CPUID EAX=0x0] // -------------------------------------------------------------------------- // Get vendor string/id. - callCpuId(0, 0, ®s); - - maxId = regs.eax; + callCpuId(®s, 0x0); + maxBaseId = regs.eax; ::memcpy(cpuInfo->_vendorString, ®s.ebx, 4); ::memcpy(cpuInfo->_vendorString + 4, ®s.edx, 4); ::memcpy(cpuInfo->_vendorString + 8, ®s.ecx, 4); @@ -168,79 +219,134 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { } // -------------------------------------------------------------------------- - // [CPUID EAX=0x00000001] + // [CPUID EAX=0x1] // -------------------------------------------------------------------------- - // Get feature flags in ecx/edx and family/model in eax. - callCpuId(1, 0, ®s); + if (maxBaseId >= 0x1) { + // Get feature flags in ECX/EDX and family/model in EAX. + callCpuId(®s, 0x1); - // Fill family and model fields. - cpuInfo->_family = (regs.eax >> 8) & 0x0F; - cpuInfo->_model = (regs.eax >> 4) & 0x0F; - cpuInfo->_stepping = (regs.eax ) & 0x0F; + // Fill family and model fields. + cpuInfo->_family = (regs.eax >> 8) & 0x0F; + cpuInfo->_model = (regs.eax >> 4) & 0x0F; + cpuInfo->_stepping = (regs.eax ) & 0x0F; - // Use extended family and model fields. - if (cpuInfo->_family == 0x0F) { - cpuInfo->_family += ((regs.eax >> 20) & 0xFF); - cpuInfo->_model += ((regs.eax >> 16) & 0x0F) << 4; - } + // Use extended family and model fields. + if (cpuInfo->_family == 0x0F) { + cpuInfo->_family += ((regs.eax >> 20) & 0xFF); + cpuInfo->_model += ((regs.eax >> 16) & 0x0F) << 4; + } - cpuInfo->_processorType = ((regs.eax >> 12) & 0x03); - cpuInfo->_brandIndex = ((regs.ebx ) & 0xFF); - cpuInfo->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8; - cpuInfo->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF); - - if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureSse3); - if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kX86CpuFeaturePclmulqdq); - if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureMonitorMWait); - if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureSsse3); - if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg16B); - if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureSse41); - if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureSse42); - if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMovbe); - if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeaturePopcnt); - if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureAesni); - if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureRdrand); - - if (regs.edx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureRdtsc); - if (regs.edx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureCmpXchg8B); - if (regs.edx & 0x00008000U) cpuInfo->addFeature(kX86CpuFeatureCmov); - if (regs.edx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureMmx); - if (regs.edx & 0x01000000U) cpuInfo->addFeature(kX86CpuFeatureFxsr); - if (regs.edx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureMmxExt); - if (regs.edx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureSse).addFeature(kX86CpuFeatureSse2); - if (regs.edx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureMultithreading); - - if (cpuInfo->_vendorId == kCpuVendorAmd && (regs.edx & 0x10000000U)) { - // AMD sets Multithreading to ON if it has more cores. - if (cpuInfo->_hwThreadsCount == 1) + cpuInfo->_processorType = ((regs.eax >> 12) & 0x03); + cpuInfo->_brandIndex = ((regs.ebx ) & 0xFF); + cpuInfo->_flushCacheLineSize = ((regs.ebx >> 8) & 0xFF) * 8; + cpuInfo->_maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF); + + if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureSSE3); + if (regs.ecx & 0x00000002U) cpuInfo->addFeature(kX86CpuFeaturePCLMULQDQ); + if (regs.ecx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureMONITOR); + if (regs.ecx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureSSSE3); + if (regs.ecx & 0x00002000U) cpuInfo->addFeature(kX86CpuFeatureCMPXCHG16B); + if (regs.ecx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureSSE4_1); + if (regs.ecx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureSSE4_2); + if (regs.ecx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMOVBE); + if (regs.ecx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeaturePOPCNT); + if (regs.ecx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureAESNI); + if (regs.ecx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureXSave); + if (regs.ecx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureXSaveOS); + if (regs.ecx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureRDRAND); + + if (regs.edx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureRDTSC); + if (regs.edx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureCMPXCHG8B); + if (regs.edx & 0x00008000U) cpuInfo->addFeature(kX86CpuFeatureCMOV); + if (regs.edx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureCLFLUSH); + if (regs.edx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureMMX); + if (regs.edx & 0x01000000U) cpuInfo->addFeature(kX86CpuFeatureFXSR); + if (regs.edx & 0x02000000U) cpuInfo->addFeature(kX86CpuFeatureSSE).addFeature(kX86CpuFeatureMMX2); + if (regs.edx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureSSE).addFeature(kX86CpuFeatureSSE2); + if (regs.edx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureMT); + + // AMD sets Multithreading to ON if it has two or more cores. + if (cpuInfo->_hwThreadsCount == 1 && cpuInfo->_vendorId == kCpuVendorAmd && (regs.edx & 0x10000000U)) { cpuInfo->_hwThreadsCount = 2; - } + } - // Detect AVX. - if (regs.ecx & 0x10000000U) { - cpuInfo->addFeature(kX86CpuFeatureAvx); + // Get the content of XCR0 if supported by CPU and enabled by OS. + if ((regs.ecx & 0x0C000000U) == 0x0C000000U) { + callXGetBV(&xcr0, 0); + } - if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureXop); - if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kX86CpuFeatureFma3); - if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kX86CpuFeatureFma4); - if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureF16C); + // Detect AVX+. + if (regs.ecx & 0x10000000U) { + // - XCR0[2:1] == 11b + // XMM & YMM states are enabled by OS. + if ((xcr0.eax & 0x00000006U) == 0x00000006U) { + cpuInfo->addFeature(kX86CpuFeatureAVX); + + if (regs.ecx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureXOP); + if (regs.ecx & 0x00004000U) cpuInfo->addFeature(kX86CpuFeatureFMA3); + if (regs.ecx & 0x00010000U) cpuInfo->addFeature(kX86CpuFeatureFMA4); + if (regs.ecx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureF16C); + } + } } + // -------------------------------------------------------------------------- + // [CPUID EAX=0x7 ECX=0x0] + // -------------------------------------------------------------------------- + // Detect new features if the processor supports CPUID-07. - if (maxId >= 7) { - callCpuId(7, 0, ®s); - - if (regs.ebx & 0x00000001) cpuInfo->addFeature(kX86CpuFeatureFsGsBase); - if (regs.ebx & 0x00000008) cpuInfo->addFeature(kX86CpuFeatureBmi); - if (regs.ebx & 0x00000010) cpuInfo->addFeature(kX86CpuFeatureHle); - if (regs.ebx & 0x00000100) cpuInfo->addFeature(kX86CpuFeatureBmi2); - if (regs.ebx & 0x00000200) cpuInfo->addFeature(kX86CpuFeatureRepMovsbStosbExt); - if (regs.ebx & 0x00000800) cpuInfo->addFeature(kX86CpuFeatureRtm); - - // AVX2 depends on AVX. - if (cpuInfo->hasFeature(kX86CpuFeatureAvx)) { - if (regs.ebx & 0x00000020) cpuInfo->addFeature(kX86CpuFeatureAvx2); + if (maxBaseId >= 0x7) { + callCpuId(®s, 0x7); + + if (regs.ebx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureFSGSBase); + if (regs.ebx & 0x00000008U) cpuInfo->addFeature(kX86CpuFeatureBMI); + if (regs.ebx & 0x00000010U) cpuInfo->addFeature(kX86CpuFeatureHLE); + if (regs.ebx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeatureBMI2); + if (regs.ebx & 0x00000200U) cpuInfo->addFeature(kX86CpuFeatureMOVSBSTOSBOpt); + if (regs.ebx & 0x00000800U) cpuInfo->addFeature(kX86CpuFeatureRTM); + if (regs.ebx & 0x00004000U) maybeMPX = true; + if (regs.ebx & 0x00040000U) cpuInfo->addFeature(kX86CpuFeatureRDSEED); + if (regs.ebx & 0x00080000U) cpuInfo->addFeature(kX86CpuFeatureADX); + if (regs.ebx & 0x00800000U) cpuInfo->addFeature(kX86CpuFeatureCLFLUSHOpt); + if (regs.ebx & 0x20000000U) cpuInfo->addFeature(kX86CpuFeatureSHA); + + if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeaturePREFETCHWT1); + + // Detect AVX2. + if (cpuInfo->hasFeature(kX86CpuFeatureAVX)) { + if (regs.ebx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureAVX2); + } + + // Detect AVX-512+. + if (regs.ebx & 0x00010000U) { + // - XCR0[2:1] == 11b + // XMM & YMM states are enabled by OS. + // - XCR0[7:5] == 111b + // Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 state are enabled by OS. + if ((xcr0.eax & 0x00000076U) == 0x00000076U) { + cpuInfo->addFeature(kX86CpuFeatureAVX512F); + + if (regs.ebx & 0x00020000U) cpuInfo->addFeature(kX86CpuFeatureAVX512DQ); + if (regs.ebx & 0x04000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512PF); + if (regs.ebx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512ER); + if (regs.ebx & 0x10000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512CD); + if (regs.ebx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512BW); + if (regs.ebx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeatureAVX512VL); + } + } + } + + // -------------------------------------------------------------------------- + // [CPUID EAX=0xD, ECX=0x0] + // -------------------------------------------------------------------------- + + if (maxBaseId >= 0xD && maybeMPX) { + callCpuId(®s, 0xD); + + // Both CPUID result and XCR0 has to be enabled to have support for MPX. + if (((regs.eax & xcr0.eax) & 0x00000018U) == 0x00000018U) { + cpuInfo->addFeature(kX86CpuFeatureMPX); } } @@ -250,28 +356,28 @@ void X86CpuUtil::detect(X86CpuInfo* cpuInfo) { // Calling cpuid with 0x80000000 as the in argument gets the number of valid // extended IDs. - callCpuId(0x80000000, 0, ®s); + callCpuId(®s, 0x80000000); uint32_t maxExtId = IntUtil::iMin(regs.eax, 0x80000004); uint32_t* brand = reinterpret_cast(cpuInfo->_brandString); for (i = 0x80000001; i <= maxExtId; i++) { - callCpuId(i, 0, ®s); + callCpuId(®s, i); switch (i) { case 0x80000001: if (regs.ecx & 0x00000001U) cpuInfo->addFeature(kX86CpuFeatureLahfSahf); - if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureLzcnt); - if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kX86CpuFeatureSse4A); - if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kX86CpuFeatureMsse); - if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeaturePrefetch); - - if (regs.edx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureExecuteDisableBit); - if (regs.edx & 0x00200000U) cpuInfo->addFeature(kX86CpuFeatureFfxsr); - if (regs.edx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMmxExt); - if (regs.edx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureRdtscp); - if (regs.edx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeature3dNowExt).addFeature(kX86CpuFeatureMmxExt); - if (regs.edx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeature3dNow); + if (regs.ecx & 0x00000020U) cpuInfo->addFeature(kX86CpuFeatureLZCNT); + if (regs.ecx & 0x00000040U) cpuInfo->addFeature(kX86CpuFeatureSSE4A); + if (regs.ecx & 0x00000080U) cpuInfo->addFeature(kX86CpuFeatureMSSE); + if (regs.ecx & 0x00000100U) cpuInfo->addFeature(kX86CpuFeaturePREFETCH); + + if (regs.edx & 0x00100000U) cpuInfo->addFeature(kX86CpuFeatureNX); + if (regs.edx & 0x00200000U) cpuInfo->addFeature(kX86CpuFeatureFXSROpt); + if (regs.edx & 0x00400000U) cpuInfo->addFeature(kX86CpuFeatureMMX2); + if (regs.edx & 0x08000000U) cpuInfo->addFeature(kX86CpuFeatureRDTSCP); + if (regs.edx & 0x40000000U) cpuInfo->addFeature(kX86CpuFeature3DNOW2).addFeature(kX86CpuFeatureMMX2); + if (regs.edx & 0x80000000U) cpuInfo->addFeature(kX86CpuFeature3DNOW); break; case 0x80000002: diff --git a/libraries/asmjit/x86/x86cpuinfo.h b/libraries/asmjit/x86/x86cpuinfo.h index 7e71f2c46..8268ef26f 100644 --- a/libraries/asmjit/x86/x86cpuinfo.h +++ b/libraries/asmjit/x86/x86cpuinfo.h @@ -26,97 +26,128 @@ struct X86CpuInfo; //! \{ // ============================================================================ -// [asmjit::kX86CpuFeature] +// [asmjit::X86CpuFeature] // ============================================================================ //! X86 CPU features. -ASMJIT_ENUM(kX86CpuFeature) { +ASMJIT_ENUM(X86CpuFeature) { + //! Cpu has Not-Execute-Bit. + kX86CpuFeatureNX = 0, //! Cpu has multithreading. - kX86CpuFeatureMultithreading = 1, - //! Cpu has execute disable bit. - kX86CpuFeatureExecuteDisableBit, + kX86CpuFeatureMT, //! Cpu has RDTSC. - kX86CpuFeatureRdtsc, + kX86CpuFeatureRDTSC, //! Cpu has RDTSCP. - kX86CpuFeatureRdtscp, + kX86CpuFeatureRDTSCP, //! Cpu has CMOV. - kX86CpuFeatureCmov, + kX86CpuFeatureCMOV, //! Cpu has CMPXCHG8B. - kX86CpuFeatureCmpXchg8B, - //! Cpu has CMPXCHG16B (x64). - kX86CpuFeatureCmpXchg16B, + kX86CpuFeatureCMPXCHG8B, + //! Cpu has CMPXCHG16B (X64). + kX86CpuFeatureCMPXCHG16B, //! Cpu has CLFUSH. - kX86CpuFeatureClflush, + kX86CpuFeatureCLFLUSH, + //! Cpu has CLFUSH (Optimized). + kX86CpuFeatureCLFLUSHOpt, //! Cpu has PREFETCH. - kX86CpuFeaturePrefetch, + kX86CpuFeaturePREFETCH, + //! Cpu has PREFETCHWT1. + kX86CpuFeaturePREFETCHWT1, //! Cpu has LAHF/SAHF. kX86CpuFeatureLahfSahf, //! Cpu has FXSAVE/FXRSTOR. - kX86CpuFeatureFxsr, - //! Cpu has FXSAVE/FXRSTOR optimizations. - kX86CpuFeatureFfxsr, + kX86CpuFeatureFXSR, + //! Cpu has FXSAVE/FXRSTOR (Optimized). + kX86CpuFeatureFXSROpt, //! Cpu has MMX. - kX86CpuFeatureMmx, + kX86CpuFeatureMMX, //! Cpu has extended MMX. - kX86CpuFeatureMmxExt, + kX86CpuFeatureMMX2, //! Cpu has 3dNow! - kX86CpuFeature3dNow, + kX86CpuFeature3DNOW, //! Cpu has enchanced 3dNow! - kX86CpuFeature3dNowExt, + kX86CpuFeature3DNOW2, //! Cpu has SSE. - kX86CpuFeatureSse, + kX86CpuFeatureSSE, //! Cpu has SSE2. - kX86CpuFeatureSse2, + kX86CpuFeatureSSE2, //! Cpu has SSE3. - kX86CpuFeatureSse3, - //! Cpu has Supplemental SSE3 (SSSE3). - kX86CpuFeatureSsse3, + kX86CpuFeatureSSE3, + //! Cpu has SSSE3. + kX86CpuFeatureSSSE3, //! Cpu has SSE4.A. - kX86CpuFeatureSse4A, + kX86CpuFeatureSSE4A, //! Cpu has SSE4.1. - kX86CpuFeatureSse41, + kX86CpuFeatureSSE4_1, //! Cpu has SSE4.2. - kX86CpuFeatureSse42, + kX86CpuFeatureSSE4_2, //! Cpu has Misaligned SSE (MSSE). - kX86CpuFeatureMsse, + kX86CpuFeatureMSSE, //! Cpu has MONITOR and MWAIT. - kX86CpuFeatureMonitorMWait, + kX86CpuFeatureMONITOR, //! Cpu has MOVBE. - kX86CpuFeatureMovbe, + kX86CpuFeatureMOVBE, //! Cpu has POPCNT. - kX86CpuFeaturePopcnt, + kX86CpuFeaturePOPCNT, //! Cpu has LZCNT. - kX86CpuFeatureLzcnt, + kX86CpuFeatureLZCNT, //! Cpu has AESNI. - kX86CpuFeatureAesni, + kX86CpuFeatureAESNI, //! Cpu has PCLMULQDQ. - kX86CpuFeaturePclmulqdq, + kX86CpuFeaturePCLMULQDQ, //! Cpu has RDRAND. - kX86CpuFeatureRdrand, + kX86CpuFeatureRDRAND, + //! Cpu has RDSEED. + kX86CpuFeatureRDSEED, + //! Cpu has SHA-1 and SHA-256. + kX86CpuFeatureSHA, + //! Cpu has XSAVE support - XSAVE/XRSTOR, XSETBV/XGETBV, and XCR0. + kX86CpuFeatureXSave, + //! OS has enabled XSAVE, you can call XGETBV to get value of XCR0. + kX86CpuFeatureXSaveOS, //! Cpu has AVX. - kX86CpuFeatureAvx, + kX86CpuFeatureAVX, //! Cpu has AVX2. - kX86CpuFeatureAvx2, + kX86CpuFeatureAVX2, //! Cpu has F16C. kX86CpuFeatureF16C, //! Cpu has FMA3. - kX86CpuFeatureFma3, + kX86CpuFeatureFMA3, //! Cpu has FMA4. - kX86CpuFeatureFma4, + kX86CpuFeatureFMA4, //! Cpu has XOP. - kX86CpuFeatureXop, + kX86CpuFeatureXOP, //! Cpu has BMI. - kX86CpuFeatureBmi, + kX86CpuFeatureBMI, //! Cpu has BMI2. - kX86CpuFeatureBmi2, + kX86CpuFeatureBMI2, //! Cpu has HLE. - kX86CpuFeatureHle, + kX86CpuFeatureHLE, //! Cpu has RTM. - kX86CpuFeatureRtm, + kX86CpuFeatureRTM, + //! Cpu has ADX. + kX86CpuFeatureADX, + //! Cpu has MPX (Memory Protection Extensions). + kX86CpuFeatureMPX, //! Cpu has FSGSBASE. - kX86CpuFeatureFsGsBase, - //! Cpu has enhanced REP MOVSB/STOSB. - kX86CpuFeatureRepMovsbStosbExt, + kX86CpuFeatureFSGSBase, + //! Cpu has optimized REP MOVSB/STOSB. + kX86CpuFeatureMOVSBSTOSBOpt, + + //! Cpu has AVX-512F (Foundation). + kX86CpuFeatureAVX512F, + //! Cpu has AVX-512CD (Conflict Detection). + kX86CpuFeatureAVX512CD, + //! Cpu has AVX-512PF (Prefetch Instructions). + kX86CpuFeatureAVX512PF, + //! Cpu has AVX-512ER (Exponential and Reciprocal Instructions). + kX86CpuFeatureAVX512ER, + //! Cpu has AVX-512DQ (DWord/QWord). + kX86CpuFeatureAVX512DQ, + //! Cpu has AVX-512BW (Byte/Word). + kX86CpuFeatureAVX512BW, + //! Cpu has AVX VL (Vector Length Excensions). + kX86CpuFeatureAVX512VL, //! Count of X86/X64 Cpu features. kX86CpuFeatureCount @@ -147,16 +178,24 @@ union X86CpuId { // [asmjit::X86CpuUtil] // ============================================================================ -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) //! CPU utilities available only if the host processor is X86/X64. struct X86CpuUtil { + //! \internal + //! + //! Designed to support VS2008 and less in 64-bit mode, even if this compiler + //! doesn't have `__cpuidex` intrinsic. + ASMJIT_API static void _docpuid(uint32_t inEcx, uint32_t inEax, X86CpuId* out); + //! Get the result of calling CPUID instruction to `out`. - ASMJIT_API static void callCpuId(uint32_t inEax, uint32_t inEcx, X86CpuId* out); + static ASMJIT_INLINE void callCpuId(X86CpuId* out, uint32_t inEax, uint32_t inEcx = 0) { + return _docpuid(inEcx, inEax, out); + } //! Detect the Host CPU. ASMJIT_API static void detect(X86CpuInfo* cpuInfo); }; -#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 +#endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64 // ============================================================================ // [asmjit::X86CpuInfo] @@ -169,8 +208,7 @@ struct X86CpuInfo : public CpuInfo { // [Construction / Destruction] // -------------------------------------------------------------------------- - ASMJIT_INLINE X86CpuInfo(uint32_t size = sizeof(X86CpuInfo)) : - CpuInfo(size) {} + ASMJIT_INLINE X86CpuInfo(); // -------------------------------------------------------------------------- // [Accessors] @@ -200,12 +238,12 @@ struct X86CpuInfo : public CpuInfo { // [Statics] // -------------------------------------------------------------------------- -#if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) +#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64) //! Get global instance of `X86CpuInfo`. static ASMJIT_INLINE const X86CpuInfo* getHost() { return static_cast(CpuInfo::getHost()); } -#endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 +#endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64 // -------------------------------------------------------------------------- // [Members] @@ -221,6 +259,9 @@ struct X86CpuInfo : public CpuInfo { uint32_t _maxLogicalProcessors; }; +ASMJIT_INLINE X86CpuInfo::X86CpuInfo() : + CpuInfo(sizeof(X86CpuInfo)) {} + //! \} } // asmjit namespace diff --git a/libraries/asmjit/x86/x86inst.cpp b/libraries/asmjit/x86/x86inst.cpp index 39beacc44..c7a51ba60 100644 --- a/libraries/asmjit/x86/x86inst.cpp +++ b/libraries/asmjit/x86/x86inst.cpp @@ -19,6 +19,79 @@ namespace asmjit { +// ============================================================================ +// [Enums (Internal)] +// ============================================================================ + +//! \internal +enum { + kX86InstTable_L__ = (0) << kX86InstOpCode_L_Shift, + kX86InstTable_L_I = (0) << kX86InstOpCode_L_Shift, + kX86InstTable_L_0 = (0) << kX86InstOpCode_L_Shift, + kX86InstTable_L_L = (1) << kX86InstOpCode_L_Shift, + + kX86InstTable_W__ = (0) << kX86InstOpCode_W_Shift, + kX86InstTable_W_I = (0) << kX86InstOpCode_W_Shift, + kX86InstTable_W_0 = (0) << kX86InstOpCode_W_Shift, + kX86InstTable_W_1 = (1) << kX86InstOpCode_W_Shift, + kX86InstTable_W_W = (1) << kX86InstOpCode_W_Shift, + + kX86InstTable_E__ = (0) << kX86InstOpCode_EW_Shift, + kX86InstTable_E_I = (0) << kX86InstOpCode_EW_Shift, + kX86InstTable_E_0 = (0) << kX86InstOpCode_EW_Shift, + kX86InstTable_E_1 = (1) << kX86InstOpCode_EW_Shift +}; + +//! \internal +//! +//! Combined flags. +enum X86InstOpInternal { + kX86InstOpI = kX86InstOpImm, + kX86InstOpL = kX86InstOpLabel, + kX86InstOpLbImm = kX86InstOpLabel | kX86InstOpImm, + + kX86InstOpGwb = kX86InstOpGw | kX86InstOpGb, + kX86InstOpGqd = kX86InstOpGq | kX86InstOpGd, + kX86InstOpGqdw = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw, + kX86InstOpGqdwb = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb, + + kX86InstOpGbMem = kX86InstOpGb | kX86InstOpMem, + kX86InstOpGwMem = kX86InstOpGw | kX86InstOpMem, + kX86InstOpGdMem = kX86InstOpGd | kX86InstOpMem, + kX86InstOpGqMem = kX86InstOpGq | kX86InstOpMem, + kX86InstOpGwbMem = kX86InstOpGwb | kX86InstOpMem, + kX86InstOpGqdMem = kX86InstOpGqd | kX86InstOpMem, + kX86InstOpGqdwMem = kX86InstOpGqdw | kX86InstOpMem, + kX86InstOpGqdwbMem = kX86InstOpGqdwb | kX86InstOpMem, + + kX86InstOpFpMem = kX86InstOpFp | kX86InstOpMem, + kX86InstOpMmMem = kX86InstOpMm | kX86InstOpMem, + kX86InstOpKMem = kX86InstOpK | kX86InstOpMem, + kX86InstOpXmmMem = kX86InstOpXmm | kX86InstOpMem, + kX86InstOpYmmMem = kX86InstOpYmm | kX86InstOpMem, + kX86InstOpZmmMem = kX86InstOpZmm | kX86InstOpMem, + + kX86InstOpMmXmm = kX86InstOpMm | kX86InstOpXmm, + kX86InstOpMmXmmMem = kX86InstOpMmXmm | kX86InstOpMem, + + kX86InstOpXy = kX86InstOpXmm | kX86InstOpYmm, + kX86InstOpXyMem = kX86InstOpXy | kX86InstOpMem, + + kX86InstOpXyz = kX86InstOpXy | kX86InstOpZmm, + kX86InstOpXyzMem = kX86InstOpXyz | kX86InstOpMem +}; + +//! \internal +//! +//! X86/X64 Instruction AVX-512 flags (combined). +ASMJIT_ENUM(X86InstFlagsInternal) { + // FPU. + kX86InstFlagMem2_4 = kX86InstFlagMem2 | kX86InstFlagMem4, + kX86InstFlagMem2_4_8 = kX86InstFlagMem2_4 | kX86InstFlagMem8, + kX86InstFlagMem4_8 = kX86InstFlagMem4 | kX86InstFlagMem8, + kX86InstFlagMem4_8_10 = kX86InstFlagMem4_8 | kX86InstFlagMem10 +}; + // ============================================================================ // [Macros] // ============================================================================ @@ -29,47 +102,54 @@ namespace asmjit { # define INST_NAME_INDEX(_Code_) 0 #endif -#define G(_Group_) kX86InstGroup##_Group_ -#define F(_Flags_) kX86InstFlag##_Flags_ -#define O(_Op_) kX86InstOp##_Op_ -#define E(_Flags_) 0 - +// Undefined. Used to distinguish between zero and field that is not used. #define U 0 -#define L kX86InstOpCode_L_True -#define O_000000(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_000F00(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_000F01(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F01 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_000F0F(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_000F38(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_000F3A(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_660000(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_660F00(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_660F38(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_660F3A(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_9B0000(_OpCode_, _R_) (kX86InstOpCode_PP_9B | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F20000(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F20F00(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F20F38(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F20F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F30000(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F30F00(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F30F38(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_F30F3A(_OpCode_, _R_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +// Instruction opcodes. +#define O_000000(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_000F00(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_000F01(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F01 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_000F0F(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_000F38(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_000F3A(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_660000(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_660F00(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_660F38(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_660F3A(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_9B0000(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_9B | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F20000(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F20F00(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F20F38(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F20F3A(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F2 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F30000(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_00 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F30F00(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F30F38(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F38 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_F30F3A(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_F3 | kX86InstOpCode_MM_0F3A | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) + +#define O_00_M08(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_00_M09(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) +#define O_66_M03(_OpCode_, _O_, _L_, _W_, _EVEX_W_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift) | kX86InstTable_L_##_L_ | kX86InstTable_W_##_W_ | kX86InstTable_E_##_EVEX_W_) + +#define O_00_X(_OpCode_, _O_) (kX86InstOpCode_PP_00 | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift)) +#define O_9B_X(_OpCode_, _O_) (kX86InstOpCode_PP_9B | (0x##_OpCode_) | ((_O_) << kX86InstOpCode_O_Shift)) + +// Instruction Encoding `Enc(...)`. +#define Enc(_Id_) kX86InstEncodingId##_Id_ + +// Instruction Flags `F(...)` and AVX-512 `AVX(...)`flags. +#define F(_Flags_) kX86InstFlag##_Flags_ -#define O_00_M03(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_00_M08(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_00_M09(_OpCode_, _R_) (kX86InstOpCode_PP_00 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +#define A(_Flags_) kX86InstFlagAvx512##_Flags_ -#define O_66_M03(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_00011| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_66_M08(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01000| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_66_M09(_OpCode_, _R_) (kX86InstOpCode_PP_66 | kX86InstOpCode_MM_01001| (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +// Instruction EFLAGS `E(OSZAPCDX)`. +#define EF(_Flags_) 0 -#define O_00_X(_OpCode_, _R_) (kX86InstOpCode_PP_00 | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) -#define O_9B_X(_OpCode_, _R_) (kX86InstOpCode_PP_9B | (0x##_OpCode_) | ((_R_) << kX86InstOpCode_O_Shift)) +// Instruction Operands' Flags `O(...)`. +#define O(_Op_) kX86InstOp##_Op_ -#define INST(_Code_, _Name_, _Group_, _Flags_, _MoveSize_, _OpFlags0_, _OpFlags1_, _OpFlags2_, _OpFlags3_, _EFlags_, _OpCode0_, _OpCode1_) \ - { INST_NAME_INDEX(_Code_), _Code_##_ExtendedIndex, _OpCode0_ } +// Defines an X86/X64 instruction. +#define INST(_Id_, _Name_, _OpCode0_, _OpCode1_, _Encoding_, _IFlags_, _EFlags_, _WriteIndex_, _WriteSize_, _Op0_, _Op_, _Op2_, _Op3_, _Op4_) \ + { INST_NAME_INDEX(_Id_), _Id_##_ExtendedIndex, _OpCode0_ } // ============================================================================ // [asmjit::X86Inst] @@ -208,6 +288,7 @@ const char _x86InstName[] = "emms\0" "enter\0" "extractps\0" + "extrq\0" "f2xm1\0" "fabs\0" "fadd\0" @@ -312,6 +393,7 @@ const char _x86InstName[] = "imul\0" "inc\0" "insertps\0" + "insertq\0" "int\0" "ja\0" "jae\0" @@ -392,6 +474,8 @@ const char _x86InstName[] = "movntpd\0" "movntps\0" "movntq\0" + "movntsd\0" + "movntss\0" "movq\0" "movq2dq\0" "movs_b\0" @@ -1126,12 +1210,20 @@ const char _x86InstName[] = "wrgsbase\0" "xadd\0" "xchg\0" + "xgetbv\0" "xor\0" "xorpd\0" - "xorps\0"; + "xorps\0" + "xrstor\0" + "xrstor64\0" + "xsave\0" + "xsave64\0" + "xsaveopt\0" + "xsaveopt64\0" + "xsetbv\0"; // Automatically generated, do not edit. -enum kX86InstAlphaIndex { +enum X86InstAlphaIndex { kX86InstAlphaIndexFirst = 'a', kX86InstAlphaIndexLast = 'z', kX86InstAlphaIndexInvalid = 0xFFFF @@ -1168,7 +1260,7 @@ static const uint16_t _x86InstAlphaIndex[26] = { }; // Automatically generated, do not edit. -enum kX86InstData_NameIndex { +enum X86InstData_NameIndex { kInstIdNone_NameIndex = 0, kX86InstIdAdc_NameIndex = 1, kX86InstIdAdd_NameIndex = 5, @@ -1298,1224 +1390,1230 @@ enum kX86InstData_NameIndex { kX86InstIdEmms_NameIndex = 856, kX86InstIdEnter_NameIndex = 861, kX86InstIdExtractps_NameIndex = 867, - kX86InstIdF2xm1_NameIndex = 877, - kX86InstIdFabs_NameIndex = 883, - kX86InstIdFadd_NameIndex = 888, - kX86InstIdFaddp_NameIndex = 893, - kX86InstIdFbld_NameIndex = 899, - kX86InstIdFbstp_NameIndex = 904, - kX86InstIdFchs_NameIndex = 910, - kX86InstIdFclex_NameIndex = 915, - kX86InstIdFcmovb_NameIndex = 921, - kX86InstIdFcmovbe_NameIndex = 928, - kX86InstIdFcmove_NameIndex = 936, - kX86InstIdFcmovnb_NameIndex = 943, - kX86InstIdFcmovnbe_NameIndex = 951, - kX86InstIdFcmovne_NameIndex = 960, - kX86InstIdFcmovnu_NameIndex = 968, - kX86InstIdFcmovu_NameIndex = 976, - kX86InstIdFcom_NameIndex = 983, - kX86InstIdFcomi_NameIndex = 988, - kX86InstIdFcomip_NameIndex = 994, - kX86InstIdFcomp_NameIndex = 1001, - kX86InstIdFcompp_NameIndex = 1007, - kX86InstIdFcos_NameIndex = 1014, - kX86InstIdFdecstp_NameIndex = 1019, - kX86InstIdFdiv_NameIndex = 1027, - kX86InstIdFdivp_NameIndex = 1032, - kX86InstIdFdivr_NameIndex = 1038, - kX86InstIdFdivrp_NameIndex = 1044, - kX86InstIdFemms_NameIndex = 1051, - kX86InstIdFfree_NameIndex = 1057, - kX86InstIdFiadd_NameIndex = 1063, - kX86InstIdFicom_NameIndex = 1069, - kX86InstIdFicomp_NameIndex = 1075, - kX86InstIdFidiv_NameIndex = 1082, - kX86InstIdFidivr_NameIndex = 1088, - kX86InstIdFild_NameIndex = 1095, - kX86InstIdFimul_NameIndex = 1100, - kX86InstIdFincstp_NameIndex = 1106, - kX86InstIdFinit_NameIndex = 1114, - kX86InstIdFist_NameIndex = 1120, - kX86InstIdFistp_NameIndex = 1125, - kX86InstIdFisttp_NameIndex = 1131, - kX86InstIdFisub_NameIndex = 1138, - kX86InstIdFisubr_NameIndex = 1144, - kX86InstIdFld_NameIndex = 1151, - kX86InstIdFld1_NameIndex = 1155, - kX86InstIdFldcw_NameIndex = 1160, - kX86InstIdFldenv_NameIndex = 1166, - kX86InstIdFldl2e_NameIndex = 1173, - kX86InstIdFldl2t_NameIndex = 1180, - kX86InstIdFldlg2_NameIndex = 1187, - kX86InstIdFldln2_NameIndex = 1194, - kX86InstIdFldpi_NameIndex = 1201, - kX86InstIdFldz_NameIndex = 1207, - kX86InstIdFmul_NameIndex = 1212, - kX86InstIdFmulp_NameIndex = 1217, - kX86InstIdFnclex_NameIndex = 1223, - kX86InstIdFninit_NameIndex = 1230, - kX86InstIdFnop_NameIndex = 1237, - kX86InstIdFnsave_NameIndex = 1242, - kX86InstIdFnstcw_NameIndex = 1249, - kX86InstIdFnstenv_NameIndex = 1256, - kX86InstIdFnstsw_NameIndex = 1264, - kX86InstIdFpatan_NameIndex = 1271, - kX86InstIdFprem_NameIndex = 1278, - kX86InstIdFprem1_NameIndex = 1284, - kX86InstIdFptan_NameIndex = 1291, - kX86InstIdFrndint_NameIndex = 1297, - kX86InstIdFrstor_NameIndex = 1305, - kX86InstIdFsave_NameIndex = 1312, - kX86InstIdFscale_NameIndex = 1318, - kX86InstIdFsin_NameIndex = 1325, - kX86InstIdFsincos_NameIndex = 1330, - kX86InstIdFsqrt_NameIndex = 1338, - kX86InstIdFst_NameIndex = 1344, - kX86InstIdFstcw_NameIndex = 1348, - kX86InstIdFstenv_NameIndex = 1354, - kX86InstIdFstp_NameIndex = 1361, - kX86InstIdFstsw_NameIndex = 1366, - kX86InstIdFsub_NameIndex = 1372, - kX86InstIdFsubp_NameIndex = 1377, - kX86InstIdFsubr_NameIndex = 1383, - kX86InstIdFsubrp_NameIndex = 1389, - kX86InstIdFtst_NameIndex = 1396, - kX86InstIdFucom_NameIndex = 1401, - kX86InstIdFucomi_NameIndex = 1407, - kX86InstIdFucomip_NameIndex = 1414, - kX86InstIdFucomp_NameIndex = 1422, - kX86InstIdFucompp_NameIndex = 1429, - kX86InstIdFwait_NameIndex = 1437, - kX86InstIdFxam_NameIndex = 1443, - kX86InstIdFxch_NameIndex = 1448, - kX86InstIdFxrstor_NameIndex = 1453, - kX86InstIdFxsave_NameIndex = 1461, - kX86InstIdFxtract_NameIndex = 1468, - kX86InstIdFyl2x_NameIndex = 1476, - kX86InstIdFyl2xp1_NameIndex = 1482, - kX86InstIdHaddpd_NameIndex = 1490, - kX86InstIdHaddps_NameIndex = 1497, - kX86InstIdHsubpd_NameIndex = 1504, - kX86InstIdHsubps_NameIndex = 1511, - kX86InstIdIdiv_NameIndex = 1518, - kX86InstIdImul_NameIndex = 1523, - kX86InstIdInc_NameIndex = 1528, - kX86InstIdInsertps_NameIndex = 1532, - kX86InstIdInt_NameIndex = 1541, - kX86InstIdJa_NameIndex = 1545, - kX86InstIdJae_NameIndex = 1548, - kX86InstIdJb_NameIndex = 1552, - kX86InstIdJbe_NameIndex = 1555, - kX86InstIdJc_NameIndex = 1559, - kX86InstIdJe_NameIndex = 1562, - kX86InstIdJg_NameIndex = 1565, - kX86InstIdJge_NameIndex = 1568, - kX86InstIdJl_NameIndex = 1572, - kX86InstIdJle_NameIndex = 1575, - kX86InstIdJna_NameIndex = 1579, - kX86InstIdJnae_NameIndex = 1583, - kX86InstIdJnb_NameIndex = 1588, - kX86InstIdJnbe_NameIndex = 1592, - kX86InstIdJnc_NameIndex = 1597, - kX86InstIdJne_NameIndex = 1601, - kX86InstIdJng_NameIndex = 1605, - kX86InstIdJnge_NameIndex = 1609, - kX86InstIdJnl_NameIndex = 1614, - kX86InstIdJnle_NameIndex = 1618, - kX86InstIdJno_NameIndex = 1623, - kX86InstIdJnp_NameIndex = 1627, - kX86InstIdJns_NameIndex = 1631, - kX86InstIdJnz_NameIndex = 1635, - kX86InstIdJo_NameIndex = 1639, - kX86InstIdJp_NameIndex = 1642, - kX86InstIdJpe_NameIndex = 1645, - kX86InstIdJpo_NameIndex = 1649, - kX86InstIdJs_NameIndex = 1653, - kX86InstIdJz_NameIndex = 1656, - kX86InstIdJecxz_NameIndex = 1659, - kX86InstIdJmp_NameIndex = 1665, - kX86InstIdLahf_NameIndex = 1669, - kX86InstIdLddqu_NameIndex = 1674, - kX86InstIdLdmxcsr_NameIndex = 1680, - kX86InstIdLea_NameIndex = 1688, - kX86InstIdLeave_NameIndex = 1692, - kX86InstIdLfence_NameIndex = 1698, - kX86InstIdLodsB_NameIndex = 1705, - kX86InstIdLodsD_NameIndex = 1712, - kX86InstIdLodsQ_NameIndex = 1719, - kX86InstIdLodsW_NameIndex = 1726, - kX86InstIdLzcnt_NameIndex = 1733, - kX86InstIdMaskmovdqu_NameIndex = 1739, - kX86InstIdMaskmovq_NameIndex = 1750, - kX86InstIdMaxpd_NameIndex = 1759, - kX86InstIdMaxps_NameIndex = 1765, - kX86InstIdMaxsd_NameIndex = 1771, - kX86InstIdMaxss_NameIndex = 1777, - kX86InstIdMfence_NameIndex = 1783, - kX86InstIdMinpd_NameIndex = 1790, - kX86InstIdMinps_NameIndex = 1796, - kX86InstIdMinsd_NameIndex = 1802, - kX86InstIdMinss_NameIndex = 1808, - kX86InstIdMonitor_NameIndex = 1814, - kX86InstIdMov_NameIndex = 1822, - kX86InstIdMovPtr_NameIndex = 1826, - kX86InstIdMovapd_NameIndex = 1834, - kX86InstIdMovaps_NameIndex = 1841, - kX86InstIdMovbe_NameIndex = 1848, - kX86InstIdMovd_NameIndex = 1854, - kX86InstIdMovddup_NameIndex = 1859, - kX86InstIdMovdq2q_NameIndex = 1867, - kX86InstIdMovdqa_NameIndex = 1875, - kX86InstIdMovdqu_NameIndex = 1882, - kX86InstIdMovhlps_NameIndex = 1889, - kX86InstIdMovhpd_NameIndex = 1897, - kX86InstIdMovhps_NameIndex = 1904, - kX86InstIdMovlhps_NameIndex = 1911, - kX86InstIdMovlpd_NameIndex = 1919, - kX86InstIdMovlps_NameIndex = 1926, - kX86InstIdMovmskpd_NameIndex = 1933, - kX86InstIdMovmskps_NameIndex = 1942, - kX86InstIdMovntdq_NameIndex = 1951, - kX86InstIdMovntdqa_NameIndex = 1959, - kX86InstIdMovnti_NameIndex = 1968, - kX86InstIdMovntpd_NameIndex = 1975, - kX86InstIdMovntps_NameIndex = 1983, - kX86InstIdMovntq_NameIndex = 1991, - kX86InstIdMovq_NameIndex = 1998, - kX86InstIdMovq2dq_NameIndex = 2003, - kX86InstIdMovsB_NameIndex = 2011, - kX86InstIdMovsD_NameIndex = 2018, - kX86InstIdMovsQ_NameIndex = 2025, - kX86InstIdMovsW_NameIndex = 2032, - kX86InstIdMovsd_NameIndex = 2039, - kX86InstIdMovshdup_NameIndex = 2045, - kX86InstIdMovsldup_NameIndex = 2054, - kX86InstIdMovss_NameIndex = 2063, - kX86InstIdMovsx_NameIndex = 2069, - kX86InstIdMovsxd_NameIndex = 2075, - kX86InstIdMovupd_NameIndex = 2082, - kX86InstIdMovups_NameIndex = 2089, - kX86InstIdMovzx_NameIndex = 2096, - kX86InstIdMpsadbw_NameIndex = 2102, - kX86InstIdMul_NameIndex = 2110, - kX86InstIdMulpd_NameIndex = 2114, - kX86InstIdMulps_NameIndex = 2120, - kX86InstIdMulsd_NameIndex = 2126, - kX86InstIdMulss_NameIndex = 2132, - kX86InstIdMulx_NameIndex = 2138, - kX86InstIdMwait_NameIndex = 2143, - kX86InstIdNeg_NameIndex = 2149, - kX86InstIdNop_NameIndex = 2153, - kX86InstIdNot_NameIndex = 2157, - kX86InstIdOr_NameIndex = 2161, - kX86InstIdOrpd_NameIndex = 2164, - kX86InstIdOrps_NameIndex = 2169, - kX86InstIdPabsb_NameIndex = 2174, - kX86InstIdPabsd_NameIndex = 2180, - kX86InstIdPabsw_NameIndex = 2186, - kX86InstIdPackssdw_NameIndex = 2192, - kX86InstIdPacksswb_NameIndex = 2201, - kX86InstIdPackusdw_NameIndex = 2210, - kX86InstIdPackuswb_NameIndex = 2219, - kX86InstIdPaddb_NameIndex = 2228, - kX86InstIdPaddd_NameIndex = 2234, - kX86InstIdPaddq_NameIndex = 2240, - kX86InstIdPaddsb_NameIndex = 2246, - kX86InstIdPaddsw_NameIndex = 2253, - kX86InstIdPaddusb_NameIndex = 2260, - kX86InstIdPaddusw_NameIndex = 2268, - kX86InstIdPaddw_NameIndex = 2276, - kX86InstIdPalignr_NameIndex = 2282, - kX86InstIdPand_NameIndex = 2290, - kX86InstIdPandn_NameIndex = 2295, - kX86InstIdPause_NameIndex = 2301, - kX86InstIdPavgb_NameIndex = 2307, - kX86InstIdPavgw_NameIndex = 2313, - kX86InstIdPblendvb_NameIndex = 2319, - kX86InstIdPblendw_NameIndex = 2328, - kX86InstIdPclmulqdq_NameIndex = 2336, - kX86InstIdPcmpeqb_NameIndex = 2346, - kX86InstIdPcmpeqd_NameIndex = 2354, - kX86InstIdPcmpeqq_NameIndex = 2362, - kX86InstIdPcmpeqw_NameIndex = 2370, - kX86InstIdPcmpestri_NameIndex = 2378, - kX86InstIdPcmpestrm_NameIndex = 2388, - kX86InstIdPcmpgtb_NameIndex = 2398, - kX86InstIdPcmpgtd_NameIndex = 2406, - kX86InstIdPcmpgtq_NameIndex = 2414, - kX86InstIdPcmpgtw_NameIndex = 2422, - kX86InstIdPcmpistri_NameIndex = 2430, - kX86InstIdPcmpistrm_NameIndex = 2440, - kX86InstIdPdep_NameIndex = 2450, - kX86InstIdPext_NameIndex = 2455, - kX86InstIdPextrb_NameIndex = 2460, - kX86InstIdPextrd_NameIndex = 2467, - kX86InstIdPextrq_NameIndex = 2474, - kX86InstIdPextrw_NameIndex = 2481, - kX86InstIdPf2id_NameIndex = 2488, - kX86InstIdPf2iw_NameIndex = 2494, - kX86InstIdPfacc_NameIndex = 2500, - kX86InstIdPfadd_NameIndex = 2506, - kX86InstIdPfcmpeq_NameIndex = 2512, - kX86InstIdPfcmpge_NameIndex = 2520, - kX86InstIdPfcmpgt_NameIndex = 2528, - kX86InstIdPfmax_NameIndex = 2536, - kX86InstIdPfmin_NameIndex = 2542, - kX86InstIdPfmul_NameIndex = 2548, - kX86InstIdPfnacc_NameIndex = 2554, - kX86InstIdPfpnacc_NameIndex = 2561, - kX86InstIdPfrcp_NameIndex = 2569, - kX86InstIdPfrcpit1_NameIndex = 2575, - kX86InstIdPfrcpit2_NameIndex = 2584, - kX86InstIdPfrsqit1_NameIndex = 2593, - kX86InstIdPfrsqrt_NameIndex = 2602, - kX86InstIdPfsub_NameIndex = 2610, - kX86InstIdPfsubr_NameIndex = 2616, - kX86InstIdPhaddd_NameIndex = 2623, - kX86InstIdPhaddsw_NameIndex = 2630, - kX86InstIdPhaddw_NameIndex = 2638, - kX86InstIdPhminposuw_NameIndex = 2645, - kX86InstIdPhsubd_NameIndex = 2656, - kX86InstIdPhsubsw_NameIndex = 2663, - kX86InstIdPhsubw_NameIndex = 2671, - kX86InstIdPi2fd_NameIndex = 2678, - kX86InstIdPi2fw_NameIndex = 2684, - kX86InstIdPinsrb_NameIndex = 2690, - kX86InstIdPinsrd_NameIndex = 2697, - kX86InstIdPinsrq_NameIndex = 2704, - kX86InstIdPinsrw_NameIndex = 2711, - kX86InstIdPmaddubsw_NameIndex = 2718, - kX86InstIdPmaddwd_NameIndex = 2728, - kX86InstIdPmaxsb_NameIndex = 2736, - kX86InstIdPmaxsd_NameIndex = 2743, - kX86InstIdPmaxsw_NameIndex = 2750, - kX86InstIdPmaxub_NameIndex = 2757, - kX86InstIdPmaxud_NameIndex = 2764, - kX86InstIdPmaxuw_NameIndex = 2771, - kX86InstIdPminsb_NameIndex = 2778, - kX86InstIdPminsd_NameIndex = 2785, - kX86InstIdPminsw_NameIndex = 2792, - kX86InstIdPminub_NameIndex = 2799, - kX86InstIdPminud_NameIndex = 2806, - kX86InstIdPminuw_NameIndex = 2813, - kX86InstIdPmovmskb_NameIndex = 2820, - kX86InstIdPmovsxbd_NameIndex = 2829, - kX86InstIdPmovsxbq_NameIndex = 2838, - kX86InstIdPmovsxbw_NameIndex = 2847, - kX86InstIdPmovsxdq_NameIndex = 2856, - kX86InstIdPmovsxwd_NameIndex = 2865, - kX86InstIdPmovsxwq_NameIndex = 2874, - kX86InstIdPmovzxbd_NameIndex = 2883, - kX86InstIdPmovzxbq_NameIndex = 2892, - kX86InstIdPmovzxbw_NameIndex = 2901, - kX86InstIdPmovzxdq_NameIndex = 2910, - kX86InstIdPmovzxwd_NameIndex = 2919, - kX86InstIdPmovzxwq_NameIndex = 2928, - kX86InstIdPmuldq_NameIndex = 2937, - kX86InstIdPmulhrsw_NameIndex = 2944, - kX86InstIdPmulhuw_NameIndex = 2953, - kX86InstIdPmulhw_NameIndex = 2961, - kX86InstIdPmulld_NameIndex = 2968, - kX86InstIdPmullw_NameIndex = 2975, - kX86InstIdPmuludq_NameIndex = 2982, - kX86InstIdPop_NameIndex = 2990, - kX86InstIdPopa_NameIndex = 2994, - kX86InstIdPopcnt_NameIndex = 2999, - kX86InstIdPopf_NameIndex = 3006, - kX86InstIdPor_NameIndex = 3011, - kX86InstIdPrefetch_NameIndex = 3015, - kX86InstIdPrefetch3dNow_NameIndex = 3024, - kX86InstIdPrefetchw3dNow_NameIndex = 3039, - kX86InstIdPsadbw_NameIndex = 3055, - kX86InstIdPshufb_NameIndex = 3062, - kX86InstIdPshufd_NameIndex = 3069, - kX86InstIdPshufhw_NameIndex = 3076, - kX86InstIdPshuflw_NameIndex = 3084, - kX86InstIdPshufw_NameIndex = 3092, - kX86InstIdPsignb_NameIndex = 3099, - kX86InstIdPsignd_NameIndex = 3106, - kX86InstIdPsignw_NameIndex = 3113, - kX86InstIdPslld_NameIndex = 3120, - kX86InstIdPslldq_NameIndex = 3126, - kX86InstIdPsllq_NameIndex = 3133, - kX86InstIdPsllw_NameIndex = 3139, - kX86InstIdPsrad_NameIndex = 3145, - kX86InstIdPsraw_NameIndex = 3151, - kX86InstIdPsrld_NameIndex = 3157, - kX86InstIdPsrldq_NameIndex = 3163, - kX86InstIdPsrlq_NameIndex = 3170, - kX86InstIdPsrlw_NameIndex = 3176, - kX86InstIdPsubb_NameIndex = 3182, - kX86InstIdPsubd_NameIndex = 3188, - kX86InstIdPsubq_NameIndex = 3194, - kX86InstIdPsubsb_NameIndex = 3200, - kX86InstIdPsubsw_NameIndex = 3207, - kX86InstIdPsubusb_NameIndex = 3214, - kX86InstIdPsubusw_NameIndex = 3222, - kX86InstIdPsubw_NameIndex = 3230, - kX86InstIdPswapd_NameIndex = 3236, - kX86InstIdPtest_NameIndex = 3243, - kX86InstIdPunpckhbw_NameIndex = 3249, - kX86InstIdPunpckhdq_NameIndex = 3259, - kX86InstIdPunpckhqdq_NameIndex = 3269, - kX86InstIdPunpckhwd_NameIndex = 3280, - kX86InstIdPunpcklbw_NameIndex = 3290, - kX86InstIdPunpckldq_NameIndex = 3300, - kX86InstIdPunpcklqdq_NameIndex = 3310, - kX86InstIdPunpcklwd_NameIndex = 3321, - kX86InstIdPush_NameIndex = 3331, - kX86InstIdPusha_NameIndex = 3336, - kX86InstIdPushf_NameIndex = 3342, - kX86InstIdPxor_NameIndex = 3348, - kX86InstIdRcl_NameIndex = 3353, - kX86InstIdRcpps_NameIndex = 3357, - kX86InstIdRcpss_NameIndex = 3363, - kX86InstIdRcr_NameIndex = 3369, - kX86InstIdRdfsbase_NameIndex = 3373, - kX86InstIdRdgsbase_NameIndex = 3382, - kX86InstIdRdrand_NameIndex = 3391, - kX86InstIdRdtsc_NameIndex = 3398, - kX86InstIdRdtscp_NameIndex = 3404, - kX86InstIdRepLodsB_NameIndex = 3411, - kX86InstIdRepLodsD_NameIndex = 3422, - kX86InstIdRepLodsQ_NameIndex = 3433, - kX86InstIdRepLodsW_NameIndex = 3444, - kX86InstIdRepMovsB_NameIndex = 3455, - kX86InstIdRepMovsD_NameIndex = 3466, - kX86InstIdRepMovsQ_NameIndex = 3477, - kX86InstIdRepMovsW_NameIndex = 3488, - kX86InstIdRepStosB_NameIndex = 3499, - kX86InstIdRepStosD_NameIndex = 3510, - kX86InstIdRepStosQ_NameIndex = 3521, - kX86InstIdRepStosW_NameIndex = 3532, - kX86InstIdRepeCmpsB_NameIndex = 3543, - kX86InstIdRepeCmpsD_NameIndex = 3555, - kX86InstIdRepeCmpsQ_NameIndex = 3567, - kX86InstIdRepeCmpsW_NameIndex = 3579, - kX86InstIdRepeScasB_NameIndex = 3591, - kX86InstIdRepeScasD_NameIndex = 3603, - kX86InstIdRepeScasQ_NameIndex = 3615, - kX86InstIdRepeScasW_NameIndex = 3627, - kX86InstIdRepneCmpsB_NameIndex = 3639, - kX86InstIdRepneCmpsD_NameIndex = 3652, - kX86InstIdRepneCmpsQ_NameIndex = 3665, - kX86InstIdRepneCmpsW_NameIndex = 3678, - kX86InstIdRepneScasB_NameIndex = 3691, - kX86InstIdRepneScasD_NameIndex = 3704, - kX86InstIdRepneScasQ_NameIndex = 3717, - kX86InstIdRepneScasW_NameIndex = 3730, - kX86InstIdRet_NameIndex = 3743, - kX86InstIdRol_NameIndex = 3747, - kX86InstIdRor_NameIndex = 3751, - kX86InstIdRorx_NameIndex = 3755, - kX86InstIdRoundpd_NameIndex = 3760, - kX86InstIdRoundps_NameIndex = 3768, - kX86InstIdRoundsd_NameIndex = 3776, - kX86InstIdRoundss_NameIndex = 3784, - kX86InstIdRsqrtps_NameIndex = 3792, - kX86InstIdRsqrtss_NameIndex = 3800, - kX86InstIdSahf_NameIndex = 3808, - kX86InstIdSal_NameIndex = 3813, - kX86InstIdSar_NameIndex = 3817, - kX86InstIdSarx_NameIndex = 3821, - kX86InstIdSbb_NameIndex = 3826, - kX86InstIdScasB_NameIndex = 3830, - kX86InstIdScasD_NameIndex = 3837, - kX86InstIdScasQ_NameIndex = 3844, - kX86InstIdScasW_NameIndex = 3851, - kX86InstIdSeta_NameIndex = 3858, - kX86InstIdSetae_NameIndex = 3863, - kX86InstIdSetb_NameIndex = 3869, - kX86InstIdSetbe_NameIndex = 3874, - kX86InstIdSetc_NameIndex = 3880, - kX86InstIdSete_NameIndex = 3885, - kX86InstIdSetg_NameIndex = 3890, - kX86InstIdSetge_NameIndex = 3895, - kX86InstIdSetl_NameIndex = 3901, - kX86InstIdSetle_NameIndex = 3906, - kX86InstIdSetna_NameIndex = 3912, - kX86InstIdSetnae_NameIndex = 3918, - kX86InstIdSetnb_NameIndex = 3925, - kX86InstIdSetnbe_NameIndex = 3931, - kX86InstIdSetnc_NameIndex = 3938, - kX86InstIdSetne_NameIndex = 3944, - kX86InstIdSetng_NameIndex = 3950, - kX86InstIdSetnge_NameIndex = 3956, - kX86InstIdSetnl_NameIndex = 3963, - kX86InstIdSetnle_NameIndex = 3969, - kX86InstIdSetno_NameIndex = 3976, - kX86InstIdSetnp_NameIndex = 3982, - kX86InstIdSetns_NameIndex = 3988, - kX86InstIdSetnz_NameIndex = 3994, - kX86InstIdSeto_NameIndex = 4000, - kX86InstIdSetp_NameIndex = 4005, - kX86InstIdSetpe_NameIndex = 4010, - kX86InstIdSetpo_NameIndex = 4016, - kX86InstIdSets_NameIndex = 4022, - kX86InstIdSetz_NameIndex = 4027, - kX86InstIdSfence_NameIndex = 4032, - kX86InstIdShl_NameIndex = 4039, - kX86InstIdShld_NameIndex = 4043, - kX86InstIdShlx_NameIndex = 4048, - kX86InstIdShr_NameIndex = 4053, - kX86InstIdShrd_NameIndex = 4057, - kX86InstIdShrx_NameIndex = 4062, - kX86InstIdShufpd_NameIndex = 4067, - kX86InstIdShufps_NameIndex = 4074, - kX86InstIdSqrtpd_NameIndex = 4081, - kX86InstIdSqrtps_NameIndex = 4088, - kX86InstIdSqrtsd_NameIndex = 4095, - kX86InstIdSqrtss_NameIndex = 4102, - kX86InstIdStc_NameIndex = 4109, - kX86InstIdStd_NameIndex = 4113, - kX86InstIdStmxcsr_NameIndex = 4117, - kX86InstIdStosB_NameIndex = 4125, - kX86InstIdStosD_NameIndex = 4132, - kX86InstIdStosQ_NameIndex = 4139, - kX86InstIdStosW_NameIndex = 4146, - kX86InstIdSub_NameIndex = 4153, - kX86InstIdSubpd_NameIndex = 4157, - kX86InstIdSubps_NameIndex = 4163, - kX86InstIdSubsd_NameIndex = 4169, - kX86InstIdSubss_NameIndex = 4175, - kX86InstIdTest_NameIndex = 4181, - kX86InstIdTzcnt_NameIndex = 4186, - kX86InstIdUcomisd_NameIndex = 4192, - kX86InstIdUcomiss_NameIndex = 4200, - kX86InstIdUd2_NameIndex = 4208, - kX86InstIdUnpckhpd_NameIndex = 4212, - kX86InstIdUnpckhps_NameIndex = 4221, - kX86InstIdUnpcklpd_NameIndex = 4230, - kX86InstIdUnpcklps_NameIndex = 4239, - kX86InstIdVaddpd_NameIndex = 4248, - kX86InstIdVaddps_NameIndex = 4255, - kX86InstIdVaddsd_NameIndex = 4262, - kX86InstIdVaddss_NameIndex = 4269, - kX86InstIdVaddsubpd_NameIndex = 4276, - kX86InstIdVaddsubps_NameIndex = 4286, - kX86InstIdVaesdec_NameIndex = 4296, - kX86InstIdVaesdeclast_NameIndex = 4304, - kX86InstIdVaesenc_NameIndex = 4316, - kX86InstIdVaesenclast_NameIndex = 4324, - kX86InstIdVaesimc_NameIndex = 4336, - kX86InstIdVaeskeygenassist_NameIndex = 4344, - kX86InstIdVandnpd_NameIndex = 4361, - kX86InstIdVandnps_NameIndex = 4369, - kX86InstIdVandpd_NameIndex = 4377, - kX86InstIdVandps_NameIndex = 4384, - kX86InstIdVblendpd_NameIndex = 4391, - kX86InstIdVblendps_NameIndex = 4400, - kX86InstIdVblendvpd_NameIndex = 4409, - kX86InstIdVblendvps_NameIndex = 4419, - kX86InstIdVbroadcastf128_NameIndex = 4429, - kX86InstIdVbroadcasti128_NameIndex = 4444, - kX86InstIdVbroadcastsd_NameIndex = 4459, - kX86InstIdVbroadcastss_NameIndex = 4472, - kX86InstIdVcmppd_NameIndex = 4485, - kX86InstIdVcmpps_NameIndex = 4492, - kX86InstIdVcmpsd_NameIndex = 4499, - kX86InstIdVcmpss_NameIndex = 4506, - kX86InstIdVcomisd_NameIndex = 4513, - kX86InstIdVcomiss_NameIndex = 4521, - kX86InstIdVcvtdq2pd_NameIndex = 4529, - kX86InstIdVcvtdq2ps_NameIndex = 4539, - kX86InstIdVcvtpd2dq_NameIndex = 4549, - kX86InstIdVcvtpd2ps_NameIndex = 4559, - kX86InstIdVcvtph2ps_NameIndex = 4569, - kX86InstIdVcvtps2dq_NameIndex = 4579, - kX86InstIdVcvtps2pd_NameIndex = 4589, - kX86InstIdVcvtps2ph_NameIndex = 4599, - kX86InstIdVcvtsd2si_NameIndex = 4609, - kX86InstIdVcvtsd2ss_NameIndex = 4619, - kX86InstIdVcvtsi2sd_NameIndex = 4629, - kX86InstIdVcvtsi2ss_NameIndex = 4639, - kX86InstIdVcvtss2sd_NameIndex = 4649, - kX86InstIdVcvtss2si_NameIndex = 4659, - kX86InstIdVcvttpd2dq_NameIndex = 4669, - kX86InstIdVcvttps2dq_NameIndex = 4680, - kX86InstIdVcvttsd2si_NameIndex = 4691, - kX86InstIdVcvttss2si_NameIndex = 4702, - kX86InstIdVdivpd_NameIndex = 4713, - kX86InstIdVdivps_NameIndex = 4720, - kX86InstIdVdivsd_NameIndex = 4727, - kX86InstIdVdivss_NameIndex = 4734, - kX86InstIdVdppd_NameIndex = 4741, - kX86InstIdVdpps_NameIndex = 4747, - kX86InstIdVextractf128_NameIndex = 4753, - kX86InstIdVextracti128_NameIndex = 4766, - kX86InstIdVextractps_NameIndex = 4779, - kX86InstIdVfmadd132pd_NameIndex = 4790, - kX86InstIdVfmadd132ps_NameIndex = 4802, - kX86InstIdVfmadd132sd_NameIndex = 4814, - kX86InstIdVfmadd132ss_NameIndex = 4826, - kX86InstIdVfmadd213pd_NameIndex = 4838, - kX86InstIdVfmadd213ps_NameIndex = 4850, - kX86InstIdVfmadd213sd_NameIndex = 4862, - kX86InstIdVfmadd213ss_NameIndex = 4874, - kX86InstIdVfmadd231pd_NameIndex = 4886, - kX86InstIdVfmadd231ps_NameIndex = 4898, - kX86InstIdVfmadd231sd_NameIndex = 4910, - kX86InstIdVfmadd231ss_NameIndex = 4922, - kX86InstIdVfmaddpd_NameIndex = 4934, - kX86InstIdVfmaddps_NameIndex = 4943, - kX86InstIdVfmaddsd_NameIndex = 4952, - kX86InstIdVfmaddss_NameIndex = 4961, - kX86InstIdVfmaddsub132pd_NameIndex = 4970, - kX86InstIdVfmaddsub132ps_NameIndex = 4985, - kX86InstIdVfmaddsub213pd_NameIndex = 5000, - kX86InstIdVfmaddsub213ps_NameIndex = 5015, - kX86InstIdVfmaddsub231pd_NameIndex = 5030, - kX86InstIdVfmaddsub231ps_NameIndex = 5045, - kX86InstIdVfmaddsubpd_NameIndex = 5060, - kX86InstIdVfmaddsubps_NameIndex = 5072, - kX86InstIdVfmsub132pd_NameIndex = 5084, - kX86InstIdVfmsub132ps_NameIndex = 5096, - kX86InstIdVfmsub132sd_NameIndex = 5108, - kX86InstIdVfmsub132ss_NameIndex = 5120, - kX86InstIdVfmsub213pd_NameIndex = 5132, - kX86InstIdVfmsub213ps_NameIndex = 5144, - kX86InstIdVfmsub213sd_NameIndex = 5156, - kX86InstIdVfmsub213ss_NameIndex = 5168, - kX86InstIdVfmsub231pd_NameIndex = 5180, - kX86InstIdVfmsub231ps_NameIndex = 5192, - kX86InstIdVfmsub231sd_NameIndex = 5204, - kX86InstIdVfmsub231ss_NameIndex = 5216, - kX86InstIdVfmsubadd132pd_NameIndex = 5228, - kX86InstIdVfmsubadd132ps_NameIndex = 5243, - kX86InstIdVfmsubadd213pd_NameIndex = 5258, - kX86InstIdVfmsubadd213ps_NameIndex = 5273, - kX86InstIdVfmsubadd231pd_NameIndex = 5288, - kX86InstIdVfmsubadd231ps_NameIndex = 5303, - kX86InstIdVfmsubaddpd_NameIndex = 5318, - kX86InstIdVfmsubaddps_NameIndex = 5330, - kX86InstIdVfmsubpd_NameIndex = 5342, - kX86InstIdVfmsubps_NameIndex = 5351, - kX86InstIdVfmsubsd_NameIndex = 5360, - kX86InstIdVfmsubss_NameIndex = 5369, - kX86InstIdVfnmadd132pd_NameIndex = 5378, - kX86InstIdVfnmadd132ps_NameIndex = 5391, - kX86InstIdVfnmadd132sd_NameIndex = 5404, - kX86InstIdVfnmadd132ss_NameIndex = 5417, - kX86InstIdVfnmadd213pd_NameIndex = 5430, - kX86InstIdVfnmadd213ps_NameIndex = 5443, - kX86InstIdVfnmadd213sd_NameIndex = 5456, - kX86InstIdVfnmadd213ss_NameIndex = 5469, - kX86InstIdVfnmadd231pd_NameIndex = 5482, - kX86InstIdVfnmadd231ps_NameIndex = 5495, - kX86InstIdVfnmadd231sd_NameIndex = 5508, - kX86InstIdVfnmadd231ss_NameIndex = 5521, - kX86InstIdVfnmaddpd_NameIndex = 5534, - kX86InstIdVfnmaddps_NameIndex = 5544, - kX86InstIdVfnmaddsd_NameIndex = 5554, - kX86InstIdVfnmaddss_NameIndex = 5564, - kX86InstIdVfnmsub132pd_NameIndex = 5574, - kX86InstIdVfnmsub132ps_NameIndex = 5587, - kX86InstIdVfnmsub132sd_NameIndex = 5600, - kX86InstIdVfnmsub132ss_NameIndex = 5613, - kX86InstIdVfnmsub213pd_NameIndex = 5626, - kX86InstIdVfnmsub213ps_NameIndex = 5639, - kX86InstIdVfnmsub213sd_NameIndex = 5652, - kX86InstIdVfnmsub213ss_NameIndex = 5665, - kX86InstIdVfnmsub231pd_NameIndex = 5678, - kX86InstIdVfnmsub231ps_NameIndex = 5691, - kX86InstIdVfnmsub231sd_NameIndex = 5704, - kX86InstIdVfnmsub231ss_NameIndex = 5717, - kX86InstIdVfnmsubpd_NameIndex = 5730, - kX86InstIdVfnmsubps_NameIndex = 5740, - kX86InstIdVfnmsubsd_NameIndex = 5750, - kX86InstIdVfnmsubss_NameIndex = 5760, - kX86InstIdVfrczpd_NameIndex = 5770, - kX86InstIdVfrczps_NameIndex = 5778, - kX86InstIdVfrczsd_NameIndex = 5786, - kX86InstIdVfrczss_NameIndex = 5794, - kX86InstIdVgatherdpd_NameIndex = 5802, - kX86InstIdVgatherdps_NameIndex = 5813, - kX86InstIdVgatherqpd_NameIndex = 5824, - kX86InstIdVgatherqps_NameIndex = 5835, - kX86InstIdVhaddpd_NameIndex = 5846, - kX86InstIdVhaddps_NameIndex = 5854, - kX86InstIdVhsubpd_NameIndex = 5862, - kX86InstIdVhsubps_NameIndex = 5870, - kX86InstIdVinsertf128_NameIndex = 5878, - kX86InstIdVinserti128_NameIndex = 5890, - kX86InstIdVinsertps_NameIndex = 5902, - kX86InstIdVlddqu_NameIndex = 5912, - kX86InstIdVldmxcsr_NameIndex = 5919, - kX86InstIdVmaskmovdqu_NameIndex = 5928, - kX86InstIdVmaskmovpd_NameIndex = 5940, - kX86InstIdVmaskmovps_NameIndex = 5951, - kX86InstIdVmaxpd_NameIndex = 5962, - kX86InstIdVmaxps_NameIndex = 5969, - kX86InstIdVmaxsd_NameIndex = 5976, - kX86InstIdVmaxss_NameIndex = 5983, - kX86InstIdVminpd_NameIndex = 5990, - kX86InstIdVminps_NameIndex = 5997, - kX86InstIdVminsd_NameIndex = 6004, - kX86InstIdVminss_NameIndex = 6011, - kX86InstIdVmovapd_NameIndex = 6018, - kX86InstIdVmovaps_NameIndex = 6026, - kX86InstIdVmovd_NameIndex = 6034, - kX86InstIdVmovddup_NameIndex = 6040, - kX86InstIdVmovdqa_NameIndex = 6049, - kX86InstIdVmovdqu_NameIndex = 6057, - kX86InstIdVmovhlps_NameIndex = 6065, - kX86InstIdVmovhpd_NameIndex = 6074, - kX86InstIdVmovhps_NameIndex = 6082, - kX86InstIdVmovlhps_NameIndex = 6090, - kX86InstIdVmovlpd_NameIndex = 6099, - kX86InstIdVmovlps_NameIndex = 6107, - kX86InstIdVmovmskpd_NameIndex = 6115, - kX86InstIdVmovmskps_NameIndex = 6125, - kX86InstIdVmovntdq_NameIndex = 6135, - kX86InstIdVmovntdqa_NameIndex = 6144, - kX86InstIdVmovntpd_NameIndex = 6154, - kX86InstIdVmovntps_NameIndex = 6163, - kX86InstIdVmovq_NameIndex = 6172, - kX86InstIdVmovsd_NameIndex = 6178, - kX86InstIdVmovshdup_NameIndex = 6185, - kX86InstIdVmovsldup_NameIndex = 6195, - kX86InstIdVmovss_NameIndex = 6205, - kX86InstIdVmovupd_NameIndex = 6212, - kX86InstIdVmovups_NameIndex = 6220, - kX86InstIdVmpsadbw_NameIndex = 6228, - kX86InstIdVmulpd_NameIndex = 6237, - kX86InstIdVmulps_NameIndex = 6244, - kX86InstIdVmulsd_NameIndex = 6251, - kX86InstIdVmulss_NameIndex = 6258, - kX86InstIdVorpd_NameIndex = 6265, - kX86InstIdVorps_NameIndex = 6271, - kX86InstIdVpabsb_NameIndex = 6277, - kX86InstIdVpabsd_NameIndex = 6284, - kX86InstIdVpabsw_NameIndex = 6291, - kX86InstIdVpackssdw_NameIndex = 6298, - kX86InstIdVpacksswb_NameIndex = 6308, - kX86InstIdVpackusdw_NameIndex = 6318, - kX86InstIdVpackuswb_NameIndex = 6328, - kX86InstIdVpaddb_NameIndex = 6338, - kX86InstIdVpaddd_NameIndex = 6345, - kX86InstIdVpaddq_NameIndex = 6352, - kX86InstIdVpaddsb_NameIndex = 6359, - kX86InstIdVpaddsw_NameIndex = 6367, - kX86InstIdVpaddusb_NameIndex = 6375, - kX86InstIdVpaddusw_NameIndex = 6384, - kX86InstIdVpaddw_NameIndex = 6393, - kX86InstIdVpalignr_NameIndex = 6400, - kX86InstIdVpand_NameIndex = 6409, - kX86InstIdVpandn_NameIndex = 6415, - kX86InstIdVpavgb_NameIndex = 6422, - kX86InstIdVpavgw_NameIndex = 6429, - kX86InstIdVpblendd_NameIndex = 6436, - kX86InstIdVpblendvb_NameIndex = 6445, - kX86InstIdVpblendw_NameIndex = 6455, - kX86InstIdVpbroadcastb_NameIndex = 6464, - kX86InstIdVpbroadcastd_NameIndex = 6477, - kX86InstIdVpbroadcastq_NameIndex = 6490, - kX86InstIdVpbroadcastw_NameIndex = 6503, - kX86InstIdVpclmulqdq_NameIndex = 6516, - kX86InstIdVpcmov_NameIndex = 6527, - kX86InstIdVpcmpeqb_NameIndex = 6534, - kX86InstIdVpcmpeqd_NameIndex = 6543, - kX86InstIdVpcmpeqq_NameIndex = 6552, - kX86InstIdVpcmpeqw_NameIndex = 6561, - kX86InstIdVpcmpestri_NameIndex = 6570, - kX86InstIdVpcmpestrm_NameIndex = 6581, - kX86InstIdVpcmpgtb_NameIndex = 6592, - kX86InstIdVpcmpgtd_NameIndex = 6601, - kX86InstIdVpcmpgtq_NameIndex = 6610, - kX86InstIdVpcmpgtw_NameIndex = 6619, - kX86InstIdVpcmpistri_NameIndex = 6628, - kX86InstIdVpcmpistrm_NameIndex = 6639, - kX86InstIdVpcomb_NameIndex = 6650, - kX86InstIdVpcomd_NameIndex = 6657, - kX86InstIdVpcomq_NameIndex = 6664, - kX86InstIdVpcomub_NameIndex = 6671, - kX86InstIdVpcomud_NameIndex = 6679, - kX86InstIdVpcomuq_NameIndex = 6687, - kX86InstIdVpcomuw_NameIndex = 6695, - kX86InstIdVpcomw_NameIndex = 6703, - kX86InstIdVperm2f128_NameIndex = 6710, - kX86InstIdVperm2i128_NameIndex = 6721, - kX86InstIdVpermd_NameIndex = 6732, - kX86InstIdVpermil2pd_NameIndex = 6739, - kX86InstIdVpermil2ps_NameIndex = 6750, - kX86InstIdVpermilpd_NameIndex = 6761, - kX86InstIdVpermilps_NameIndex = 6771, - kX86InstIdVpermpd_NameIndex = 6781, - kX86InstIdVpermps_NameIndex = 6789, - kX86InstIdVpermq_NameIndex = 6797, - kX86InstIdVpextrb_NameIndex = 6804, - kX86InstIdVpextrd_NameIndex = 6812, - kX86InstIdVpextrq_NameIndex = 6820, - kX86InstIdVpextrw_NameIndex = 6828, - kX86InstIdVpgatherdd_NameIndex = 6836, - kX86InstIdVpgatherdq_NameIndex = 6847, - kX86InstIdVpgatherqd_NameIndex = 6858, - kX86InstIdVpgatherqq_NameIndex = 6869, - kX86InstIdVphaddbd_NameIndex = 6880, - kX86InstIdVphaddbq_NameIndex = 6889, - kX86InstIdVphaddbw_NameIndex = 6898, - kX86InstIdVphaddd_NameIndex = 6907, - kX86InstIdVphadddq_NameIndex = 6915, - kX86InstIdVphaddsw_NameIndex = 6924, - kX86InstIdVphaddubd_NameIndex = 6933, - kX86InstIdVphaddubq_NameIndex = 6943, - kX86InstIdVphaddubw_NameIndex = 6953, - kX86InstIdVphaddudq_NameIndex = 6963, - kX86InstIdVphadduwd_NameIndex = 6973, - kX86InstIdVphadduwq_NameIndex = 6983, - kX86InstIdVphaddw_NameIndex = 6993, - kX86InstIdVphaddwd_NameIndex = 7001, - kX86InstIdVphaddwq_NameIndex = 7010, - kX86InstIdVphminposuw_NameIndex = 7019, - kX86InstIdVphsubbw_NameIndex = 7031, - kX86InstIdVphsubd_NameIndex = 7040, - kX86InstIdVphsubdq_NameIndex = 7048, - kX86InstIdVphsubsw_NameIndex = 7057, - kX86InstIdVphsubw_NameIndex = 7066, - kX86InstIdVphsubwd_NameIndex = 7074, - kX86InstIdVpinsrb_NameIndex = 7083, - kX86InstIdVpinsrd_NameIndex = 7091, - kX86InstIdVpinsrq_NameIndex = 7099, - kX86InstIdVpinsrw_NameIndex = 7107, - kX86InstIdVpmacsdd_NameIndex = 7115, - kX86InstIdVpmacsdqh_NameIndex = 7124, - kX86InstIdVpmacsdql_NameIndex = 7134, - kX86InstIdVpmacssdd_NameIndex = 7144, - kX86InstIdVpmacssdqh_NameIndex = 7154, - kX86InstIdVpmacssdql_NameIndex = 7165, - kX86InstIdVpmacsswd_NameIndex = 7176, - kX86InstIdVpmacssww_NameIndex = 7186, - kX86InstIdVpmacswd_NameIndex = 7196, - kX86InstIdVpmacsww_NameIndex = 7205, - kX86InstIdVpmadcsswd_NameIndex = 7214, - kX86InstIdVpmadcswd_NameIndex = 7225, - kX86InstIdVpmaddubsw_NameIndex = 7235, - kX86InstIdVpmaddwd_NameIndex = 7246, - kX86InstIdVpmaskmovd_NameIndex = 7255, - kX86InstIdVpmaskmovq_NameIndex = 7266, - kX86InstIdVpmaxsb_NameIndex = 7277, - kX86InstIdVpmaxsd_NameIndex = 7285, - kX86InstIdVpmaxsw_NameIndex = 7293, - kX86InstIdVpmaxub_NameIndex = 7301, - kX86InstIdVpmaxud_NameIndex = 7309, - kX86InstIdVpmaxuw_NameIndex = 7317, - kX86InstIdVpminsb_NameIndex = 7325, - kX86InstIdVpminsd_NameIndex = 7333, - kX86InstIdVpminsw_NameIndex = 7341, - kX86InstIdVpminub_NameIndex = 7349, - kX86InstIdVpminud_NameIndex = 7357, - kX86InstIdVpminuw_NameIndex = 7365, - kX86InstIdVpmovmskb_NameIndex = 7373, - kX86InstIdVpmovsxbd_NameIndex = 7383, - kX86InstIdVpmovsxbq_NameIndex = 7393, - kX86InstIdVpmovsxbw_NameIndex = 7403, - kX86InstIdVpmovsxdq_NameIndex = 7413, - kX86InstIdVpmovsxwd_NameIndex = 7423, - kX86InstIdVpmovsxwq_NameIndex = 7433, - kX86InstIdVpmovzxbd_NameIndex = 7443, - kX86InstIdVpmovzxbq_NameIndex = 7453, - kX86InstIdVpmovzxbw_NameIndex = 7463, - kX86InstIdVpmovzxdq_NameIndex = 7473, - kX86InstIdVpmovzxwd_NameIndex = 7483, - kX86InstIdVpmovzxwq_NameIndex = 7493, - kX86InstIdVpmuldq_NameIndex = 7503, - kX86InstIdVpmulhrsw_NameIndex = 7511, - kX86InstIdVpmulhuw_NameIndex = 7521, - kX86InstIdVpmulhw_NameIndex = 7530, - kX86InstIdVpmulld_NameIndex = 7538, - kX86InstIdVpmullw_NameIndex = 7546, - kX86InstIdVpmuludq_NameIndex = 7554, - kX86InstIdVpor_NameIndex = 7563, - kX86InstIdVpperm_NameIndex = 7568, - kX86InstIdVprotb_NameIndex = 7575, - kX86InstIdVprotd_NameIndex = 7582, - kX86InstIdVprotq_NameIndex = 7589, - kX86InstIdVprotw_NameIndex = 7596, - kX86InstIdVpsadbw_NameIndex = 7603, - kX86InstIdVpshab_NameIndex = 7611, - kX86InstIdVpshad_NameIndex = 7618, - kX86InstIdVpshaq_NameIndex = 7625, - kX86InstIdVpshaw_NameIndex = 7632, - kX86InstIdVpshlb_NameIndex = 7639, - kX86InstIdVpshld_NameIndex = 7646, - kX86InstIdVpshlq_NameIndex = 7653, - kX86InstIdVpshlw_NameIndex = 7660, - kX86InstIdVpshufb_NameIndex = 7667, - kX86InstIdVpshufd_NameIndex = 7675, - kX86InstIdVpshufhw_NameIndex = 7683, - kX86InstIdVpshuflw_NameIndex = 7692, - kX86InstIdVpsignb_NameIndex = 7701, - kX86InstIdVpsignd_NameIndex = 7709, - kX86InstIdVpsignw_NameIndex = 7717, - kX86InstIdVpslld_NameIndex = 7725, - kX86InstIdVpslldq_NameIndex = 7732, - kX86InstIdVpsllq_NameIndex = 7740, - kX86InstIdVpsllvd_NameIndex = 7747, - kX86InstIdVpsllvq_NameIndex = 7755, - kX86InstIdVpsllw_NameIndex = 7763, - kX86InstIdVpsrad_NameIndex = 7770, - kX86InstIdVpsravd_NameIndex = 7777, - kX86InstIdVpsraw_NameIndex = 7785, - kX86InstIdVpsrld_NameIndex = 7792, - kX86InstIdVpsrldq_NameIndex = 7799, - kX86InstIdVpsrlq_NameIndex = 7807, - kX86InstIdVpsrlvd_NameIndex = 7814, - kX86InstIdVpsrlvq_NameIndex = 7822, - kX86InstIdVpsrlw_NameIndex = 7830, - kX86InstIdVpsubb_NameIndex = 7837, - kX86InstIdVpsubd_NameIndex = 7844, - kX86InstIdVpsubq_NameIndex = 7851, - kX86InstIdVpsubsb_NameIndex = 7858, - kX86InstIdVpsubsw_NameIndex = 7866, - kX86InstIdVpsubusb_NameIndex = 7874, - kX86InstIdVpsubusw_NameIndex = 7883, - kX86InstIdVpsubw_NameIndex = 7892, - kX86InstIdVptest_NameIndex = 7899, - kX86InstIdVpunpckhbw_NameIndex = 7906, - kX86InstIdVpunpckhdq_NameIndex = 7917, - kX86InstIdVpunpckhqdq_NameIndex = 7928, - kX86InstIdVpunpckhwd_NameIndex = 7940, - kX86InstIdVpunpcklbw_NameIndex = 7951, - kX86InstIdVpunpckldq_NameIndex = 7962, - kX86InstIdVpunpcklqdq_NameIndex = 7973, - kX86InstIdVpunpcklwd_NameIndex = 7985, - kX86InstIdVpxor_NameIndex = 7996, - kX86InstIdVrcpps_NameIndex = 8002, - kX86InstIdVrcpss_NameIndex = 8009, - kX86InstIdVroundpd_NameIndex = 8016, - kX86InstIdVroundps_NameIndex = 8025, - kX86InstIdVroundsd_NameIndex = 8034, - kX86InstIdVroundss_NameIndex = 8043, - kX86InstIdVrsqrtps_NameIndex = 8052, - kX86InstIdVrsqrtss_NameIndex = 8061, - kX86InstIdVshufpd_NameIndex = 8070, - kX86InstIdVshufps_NameIndex = 8078, - kX86InstIdVsqrtpd_NameIndex = 8086, - kX86InstIdVsqrtps_NameIndex = 8094, - kX86InstIdVsqrtsd_NameIndex = 8102, - kX86InstIdVsqrtss_NameIndex = 8110, - kX86InstIdVstmxcsr_NameIndex = 8118, - kX86InstIdVsubpd_NameIndex = 8127, - kX86InstIdVsubps_NameIndex = 8134, - kX86InstIdVsubsd_NameIndex = 8141, - kX86InstIdVsubss_NameIndex = 8148, - kX86InstIdVtestpd_NameIndex = 8155, - kX86InstIdVtestps_NameIndex = 8163, - kX86InstIdVucomisd_NameIndex = 8171, - kX86InstIdVucomiss_NameIndex = 8180, - kX86InstIdVunpckhpd_NameIndex = 8189, - kX86InstIdVunpckhps_NameIndex = 8199, - kX86InstIdVunpcklpd_NameIndex = 8209, - kX86InstIdVunpcklps_NameIndex = 8219, - kX86InstIdVxorpd_NameIndex = 8229, - kX86InstIdVxorps_NameIndex = 8236, - kX86InstIdVzeroall_NameIndex = 8243, - kX86InstIdVzeroupper_NameIndex = 8252, - kX86InstIdWrfsbase_NameIndex = 8263, - kX86InstIdWrgsbase_NameIndex = 8272, - kX86InstIdXadd_NameIndex = 8281, - kX86InstIdXchg_NameIndex = 8286, - kX86InstIdXor_NameIndex = 8291, - kX86InstIdXorpd_NameIndex = 8295, - kX86InstIdXorps_NameIndex = 8301 + kX86InstIdExtrq_NameIndex = 877, + kX86InstIdF2xm1_NameIndex = 883, + kX86InstIdFabs_NameIndex = 889, + kX86InstIdFadd_NameIndex = 894, + kX86InstIdFaddp_NameIndex = 899, + kX86InstIdFbld_NameIndex = 905, + kX86InstIdFbstp_NameIndex = 910, + kX86InstIdFchs_NameIndex = 916, + kX86InstIdFclex_NameIndex = 921, + kX86InstIdFcmovb_NameIndex = 927, + kX86InstIdFcmovbe_NameIndex = 934, + kX86InstIdFcmove_NameIndex = 942, + kX86InstIdFcmovnb_NameIndex = 949, + kX86InstIdFcmovnbe_NameIndex = 957, + kX86InstIdFcmovne_NameIndex = 966, + kX86InstIdFcmovnu_NameIndex = 974, + kX86InstIdFcmovu_NameIndex = 982, + kX86InstIdFcom_NameIndex = 989, + kX86InstIdFcomi_NameIndex = 994, + kX86InstIdFcomip_NameIndex = 1000, + kX86InstIdFcomp_NameIndex = 1007, + kX86InstIdFcompp_NameIndex = 1013, + kX86InstIdFcos_NameIndex = 1020, + kX86InstIdFdecstp_NameIndex = 1025, + kX86InstIdFdiv_NameIndex = 1033, + kX86InstIdFdivp_NameIndex = 1038, + kX86InstIdFdivr_NameIndex = 1044, + kX86InstIdFdivrp_NameIndex = 1050, + kX86InstIdFemms_NameIndex = 1057, + kX86InstIdFfree_NameIndex = 1063, + kX86InstIdFiadd_NameIndex = 1069, + kX86InstIdFicom_NameIndex = 1075, + kX86InstIdFicomp_NameIndex = 1081, + kX86InstIdFidiv_NameIndex = 1088, + kX86InstIdFidivr_NameIndex = 1094, + kX86InstIdFild_NameIndex = 1101, + kX86InstIdFimul_NameIndex = 1106, + kX86InstIdFincstp_NameIndex = 1112, + kX86InstIdFinit_NameIndex = 1120, + kX86InstIdFist_NameIndex = 1126, + kX86InstIdFistp_NameIndex = 1131, + kX86InstIdFisttp_NameIndex = 1137, + kX86InstIdFisub_NameIndex = 1144, + kX86InstIdFisubr_NameIndex = 1150, + kX86InstIdFld_NameIndex = 1157, + kX86InstIdFld1_NameIndex = 1161, + kX86InstIdFldcw_NameIndex = 1166, + kX86InstIdFldenv_NameIndex = 1172, + kX86InstIdFldl2e_NameIndex = 1179, + kX86InstIdFldl2t_NameIndex = 1186, + kX86InstIdFldlg2_NameIndex = 1193, + kX86InstIdFldln2_NameIndex = 1200, + kX86InstIdFldpi_NameIndex = 1207, + kX86InstIdFldz_NameIndex = 1213, + kX86InstIdFmul_NameIndex = 1218, + kX86InstIdFmulp_NameIndex = 1223, + kX86InstIdFnclex_NameIndex = 1229, + kX86InstIdFninit_NameIndex = 1236, + kX86InstIdFnop_NameIndex = 1243, + kX86InstIdFnsave_NameIndex = 1248, + kX86InstIdFnstcw_NameIndex = 1255, + kX86InstIdFnstenv_NameIndex = 1262, + kX86InstIdFnstsw_NameIndex = 1270, + kX86InstIdFpatan_NameIndex = 1277, + kX86InstIdFprem_NameIndex = 1284, + kX86InstIdFprem1_NameIndex = 1290, + kX86InstIdFptan_NameIndex = 1297, + kX86InstIdFrndint_NameIndex = 1303, + kX86InstIdFrstor_NameIndex = 1311, + kX86InstIdFsave_NameIndex = 1318, + kX86InstIdFscale_NameIndex = 1324, + kX86InstIdFsin_NameIndex = 1331, + kX86InstIdFsincos_NameIndex = 1336, + kX86InstIdFsqrt_NameIndex = 1344, + kX86InstIdFst_NameIndex = 1350, + kX86InstIdFstcw_NameIndex = 1354, + kX86InstIdFstenv_NameIndex = 1360, + kX86InstIdFstp_NameIndex = 1367, + kX86InstIdFstsw_NameIndex = 1372, + kX86InstIdFsub_NameIndex = 1378, + kX86InstIdFsubp_NameIndex = 1383, + kX86InstIdFsubr_NameIndex = 1389, + kX86InstIdFsubrp_NameIndex = 1395, + kX86InstIdFtst_NameIndex = 1402, + kX86InstIdFucom_NameIndex = 1407, + kX86InstIdFucomi_NameIndex = 1413, + kX86InstIdFucomip_NameIndex = 1420, + kX86InstIdFucomp_NameIndex = 1428, + kX86InstIdFucompp_NameIndex = 1435, + kX86InstIdFwait_NameIndex = 1443, + kX86InstIdFxam_NameIndex = 1449, + kX86InstIdFxch_NameIndex = 1454, + kX86InstIdFxrstor_NameIndex = 1459, + kX86InstIdFxsave_NameIndex = 1467, + kX86InstIdFxtract_NameIndex = 1474, + kX86InstIdFyl2x_NameIndex = 1482, + kX86InstIdFyl2xp1_NameIndex = 1488, + kX86InstIdHaddpd_NameIndex = 1496, + kX86InstIdHaddps_NameIndex = 1503, + kX86InstIdHsubpd_NameIndex = 1510, + kX86InstIdHsubps_NameIndex = 1517, + kX86InstIdIdiv_NameIndex = 1524, + kX86InstIdImul_NameIndex = 1529, + kX86InstIdInc_NameIndex = 1534, + kX86InstIdInsertps_NameIndex = 1538, + kX86InstIdInsertq_NameIndex = 1547, + kX86InstIdInt_NameIndex = 1555, + kX86InstIdJa_NameIndex = 1559, + kX86InstIdJae_NameIndex = 1562, + kX86InstIdJb_NameIndex = 1566, + kX86InstIdJbe_NameIndex = 1569, + kX86InstIdJc_NameIndex = 1573, + kX86InstIdJe_NameIndex = 1576, + kX86InstIdJg_NameIndex = 1579, + kX86InstIdJge_NameIndex = 1582, + kX86InstIdJl_NameIndex = 1586, + kX86InstIdJle_NameIndex = 1589, + kX86InstIdJna_NameIndex = 1593, + kX86InstIdJnae_NameIndex = 1597, + kX86InstIdJnb_NameIndex = 1602, + kX86InstIdJnbe_NameIndex = 1606, + kX86InstIdJnc_NameIndex = 1611, + kX86InstIdJne_NameIndex = 1615, + kX86InstIdJng_NameIndex = 1619, + kX86InstIdJnge_NameIndex = 1623, + kX86InstIdJnl_NameIndex = 1628, + kX86InstIdJnle_NameIndex = 1632, + kX86InstIdJno_NameIndex = 1637, + kX86InstIdJnp_NameIndex = 1641, + kX86InstIdJns_NameIndex = 1645, + kX86InstIdJnz_NameIndex = 1649, + kX86InstIdJo_NameIndex = 1653, + kX86InstIdJp_NameIndex = 1656, + kX86InstIdJpe_NameIndex = 1659, + kX86InstIdJpo_NameIndex = 1663, + kX86InstIdJs_NameIndex = 1667, + kX86InstIdJz_NameIndex = 1670, + kX86InstIdJecxz_NameIndex = 1673, + kX86InstIdJmp_NameIndex = 1679, + kX86InstIdLahf_NameIndex = 1683, + kX86InstIdLddqu_NameIndex = 1688, + kX86InstIdLdmxcsr_NameIndex = 1694, + kX86InstIdLea_NameIndex = 1702, + kX86InstIdLeave_NameIndex = 1706, + kX86InstIdLfence_NameIndex = 1712, + kX86InstIdLodsB_NameIndex = 1719, + kX86InstIdLodsD_NameIndex = 1726, + kX86InstIdLodsQ_NameIndex = 1733, + kX86InstIdLodsW_NameIndex = 1740, + kX86InstIdLzcnt_NameIndex = 1747, + kX86InstIdMaskmovdqu_NameIndex = 1753, + kX86InstIdMaskmovq_NameIndex = 1764, + kX86InstIdMaxpd_NameIndex = 1773, + kX86InstIdMaxps_NameIndex = 1779, + kX86InstIdMaxsd_NameIndex = 1785, + kX86InstIdMaxss_NameIndex = 1791, + kX86InstIdMfence_NameIndex = 1797, + kX86InstIdMinpd_NameIndex = 1804, + kX86InstIdMinps_NameIndex = 1810, + kX86InstIdMinsd_NameIndex = 1816, + kX86InstIdMinss_NameIndex = 1822, + kX86InstIdMonitor_NameIndex = 1828, + kX86InstIdMov_NameIndex = 1836, + kX86InstIdMovPtr_NameIndex = 1840, + kX86InstIdMovapd_NameIndex = 1848, + kX86InstIdMovaps_NameIndex = 1855, + kX86InstIdMovbe_NameIndex = 1862, + kX86InstIdMovd_NameIndex = 1868, + kX86InstIdMovddup_NameIndex = 1873, + kX86InstIdMovdq2q_NameIndex = 1881, + kX86InstIdMovdqa_NameIndex = 1889, + kX86InstIdMovdqu_NameIndex = 1896, + kX86InstIdMovhlps_NameIndex = 1903, + kX86InstIdMovhpd_NameIndex = 1911, + kX86InstIdMovhps_NameIndex = 1918, + kX86InstIdMovlhps_NameIndex = 1925, + kX86InstIdMovlpd_NameIndex = 1933, + kX86InstIdMovlps_NameIndex = 1940, + kX86InstIdMovmskpd_NameIndex = 1947, + kX86InstIdMovmskps_NameIndex = 1956, + kX86InstIdMovntdq_NameIndex = 1965, + kX86InstIdMovntdqa_NameIndex = 1973, + kX86InstIdMovnti_NameIndex = 1982, + kX86InstIdMovntpd_NameIndex = 1989, + kX86InstIdMovntps_NameIndex = 1997, + kX86InstIdMovntq_NameIndex = 2005, + kX86InstIdMovntsd_NameIndex = 2012, + kX86InstIdMovntss_NameIndex = 2020, + kX86InstIdMovq_NameIndex = 2028, + kX86InstIdMovq2dq_NameIndex = 2033, + kX86InstIdMovsB_NameIndex = 2041, + kX86InstIdMovsD_NameIndex = 2048, + kX86InstIdMovsQ_NameIndex = 2055, + kX86InstIdMovsW_NameIndex = 2062, + kX86InstIdMovsd_NameIndex = 2069, + kX86InstIdMovshdup_NameIndex = 2075, + kX86InstIdMovsldup_NameIndex = 2084, + kX86InstIdMovss_NameIndex = 2093, + kX86InstIdMovsx_NameIndex = 2099, + kX86InstIdMovsxd_NameIndex = 2105, + kX86InstIdMovupd_NameIndex = 2112, + kX86InstIdMovups_NameIndex = 2119, + kX86InstIdMovzx_NameIndex = 2126, + kX86InstIdMpsadbw_NameIndex = 2132, + kX86InstIdMul_NameIndex = 2140, + kX86InstIdMulpd_NameIndex = 2144, + kX86InstIdMulps_NameIndex = 2150, + kX86InstIdMulsd_NameIndex = 2156, + kX86InstIdMulss_NameIndex = 2162, + kX86InstIdMulx_NameIndex = 2168, + kX86InstIdMwait_NameIndex = 2173, + kX86InstIdNeg_NameIndex = 2179, + kX86InstIdNop_NameIndex = 2183, + kX86InstIdNot_NameIndex = 2187, + kX86InstIdOr_NameIndex = 2191, + kX86InstIdOrpd_NameIndex = 2194, + kX86InstIdOrps_NameIndex = 2199, + kX86InstIdPabsb_NameIndex = 2204, + kX86InstIdPabsd_NameIndex = 2210, + kX86InstIdPabsw_NameIndex = 2216, + kX86InstIdPackssdw_NameIndex = 2222, + kX86InstIdPacksswb_NameIndex = 2231, + kX86InstIdPackusdw_NameIndex = 2240, + kX86InstIdPackuswb_NameIndex = 2249, + kX86InstIdPaddb_NameIndex = 2258, + kX86InstIdPaddd_NameIndex = 2264, + kX86InstIdPaddq_NameIndex = 2270, + kX86InstIdPaddsb_NameIndex = 2276, + kX86InstIdPaddsw_NameIndex = 2283, + kX86InstIdPaddusb_NameIndex = 2290, + kX86InstIdPaddusw_NameIndex = 2298, + kX86InstIdPaddw_NameIndex = 2306, + kX86InstIdPalignr_NameIndex = 2312, + kX86InstIdPand_NameIndex = 2320, + kX86InstIdPandn_NameIndex = 2325, + kX86InstIdPause_NameIndex = 2331, + kX86InstIdPavgb_NameIndex = 2337, + kX86InstIdPavgw_NameIndex = 2343, + kX86InstIdPblendvb_NameIndex = 2349, + kX86InstIdPblendw_NameIndex = 2358, + kX86InstIdPclmulqdq_NameIndex = 2366, + kX86InstIdPcmpeqb_NameIndex = 2376, + kX86InstIdPcmpeqd_NameIndex = 2384, + kX86InstIdPcmpeqq_NameIndex = 2392, + kX86InstIdPcmpeqw_NameIndex = 2400, + kX86InstIdPcmpestri_NameIndex = 2408, + kX86InstIdPcmpestrm_NameIndex = 2418, + kX86InstIdPcmpgtb_NameIndex = 2428, + kX86InstIdPcmpgtd_NameIndex = 2436, + kX86InstIdPcmpgtq_NameIndex = 2444, + kX86InstIdPcmpgtw_NameIndex = 2452, + kX86InstIdPcmpistri_NameIndex = 2460, + kX86InstIdPcmpistrm_NameIndex = 2470, + kX86InstIdPdep_NameIndex = 2480, + kX86InstIdPext_NameIndex = 2485, + kX86InstIdPextrb_NameIndex = 2490, + kX86InstIdPextrd_NameIndex = 2497, + kX86InstIdPextrq_NameIndex = 2504, + kX86InstIdPextrw_NameIndex = 2511, + kX86InstIdPf2id_NameIndex = 2518, + kX86InstIdPf2iw_NameIndex = 2524, + kX86InstIdPfacc_NameIndex = 2530, + kX86InstIdPfadd_NameIndex = 2536, + kX86InstIdPfcmpeq_NameIndex = 2542, + kX86InstIdPfcmpge_NameIndex = 2550, + kX86InstIdPfcmpgt_NameIndex = 2558, + kX86InstIdPfmax_NameIndex = 2566, + kX86InstIdPfmin_NameIndex = 2572, + kX86InstIdPfmul_NameIndex = 2578, + kX86InstIdPfnacc_NameIndex = 2584, + kX86InstIdPfpnacc_NameIndex = 2591, + kX86InstIdPfrcp_NameIndex = 2599, + kX86InstIdPfrcpit1_NameIndex = 2605, + kX86InstIdPfrcpit2_NameIndex = 2614, + kX86InstIdPfrsqit1_NameIndex = 2623, + kX86InstIdPfrsqrt_NameIndex = 2632, + kX86InstIdPfsub_NameIndex = 2640, + kX86InstIdPfsubr_NameIndex = 2646, + kX86InstIdPhaddd_NameIndex = 2653, + kX86InstIdPhaddsw_NameIndex = 2660, + kX86InstIdPhaddw_NameIndex = 2668, + kX86InstIdPhminposuw_NameIndex = 2675, + kX86InstIdPhsubd_NameIndex = 2686, + kX86InstIdPhsubsw_NameIndex = 2693, + kX86InstIdPhsubw_NameIndex = 2701, + kX86InstIdPi2fd_NameIndex = 2708, + kX86InstIdPi2fw_NameIndex = 2714, + kX86InstIdPinsrb_NameIndex = 2720, + kX86InstIdPinsrd_NameIndex = 2727, + kX86InstIdPinsrq_NameIndex = 2734, + kX86InstIdPinsrw_NameIndex = 2741, + kX86InstIdPmaddubsw_NameIndex = 2748, + kX86InstIdPmaddwd_NameIndex = 2758, + kX86InstIdPmaxsb_NameIndex = 2766, + kX86InstIdPmaxsd_NameIndex = 2773, + kX86InstIdPmaxsw_NameIndex = 2780, + kX86InstIdPmaxub_NameIndex = 2787, + kX86InstIdPmaxud_NameIndex = 2794, + kX86InstIdPmaxuw_NameIndex = 2801, + kX86InstIdPminsb_NameIndex = 2808, + kX86InstIdPminsd_NameIndex = 2815, + kX86InstIdPminsw_NameIndex = 2822, + kX86InstIdPminub_NameIndex = 2829, + kX86InstIdPminud_NameIndex = 2836, + kX86InstIdPminuw_NameIndex = 2843, + kX86InstIdPmovmskb_NameIndex = 2850, + kX86InstIdPmovsxbd_NameIndex = 2859, + kX86InstIdPmovsxbq_NameIndex = 2868, + kX86InstIdPmovsxbw_NameIndex = 2877, + kX86InstIdPmovsxdq_NameIndex = 2886, + kX86InstIdPmovsxwd_NameIndex = 2895, + kX86InstIdPmovsxwq_NameIndex = 2904, + kX86InstIdPmovzxbd_NameIndex = 2913, + kX86InstIdPmovzxbq_NameIndex = 2922, + kX86InstIdPmovzxbw_NameIndex = 2931, + kX86InstIdPmovzxdq_NameIndex = 2940, + kX86InstIdPmovzxwd_NameIndex = 2949, + kX86InstIdPmovzxwq_NameIndex = 2958, + kX86InstIdPmuldq_NameIndex = 2967, + kX86InstIdPmulhrsw_NameIndex = 2974, + kX86InstIdPmulhuw_NameIndex = 2983, + kX86InstIdPmulhw_NameIndex = 2991, + kX86InstIdPmulld_NameIndex = 2998, + kX86InstIdPmullw_NameIndex = 3005, + kX86InstIdPmuludq_NameIndex = 3012, + kX86InstIdPop_NameIndex = 3020, + kX86InstIdPopa_NameIndex = 3024, + kX86InstIdPopcnt_NameIndex = 3029, + kX86InstIdPopf_NameIndex = 3036, + kX86InstIdPor_NameIndex = 3041, + kX86InstIdPrefetch_NameIndex = 3045, + kX86InstIdPrefetch3dNow_NameIndex = 3054, + kX86InstIdPrefetchw3dNow_NameIndex = 3069, + kX86InstIdPsadbw_NameIndex = 3085, + kX86InstIdPshufb_NameIndex = 3092, + kX86InstIdPshufd_NameIndex = 3099, + kX86InstIdPshufhw_NameIndex = 3106, + kX86InstIdPshuflw_NameIndex = 3114, + kX86InstIdPshufw_NameIndex = 3122, + kX86InstIdPsignb_NameIndex = 3129, + kX86InstIdPsignd_NameIndex = 3136, + kX86InstIdPsignw_NameIndex = 3143, + kX86InstIdPslld_NameIndex = 3150, + kX86InstIdPslldq_NameIndex = 3156, + kX86InstIdPsllq_NameIndex = 3163, + kX86InstIdPsllw_NameIndex = 3169, + kX86InstIdPsrad_NameIndex = 3175, + kX86InstIdPsraw_NameIndex = 3181, + kX86InstIdPsrld_NameIndex = 3187, + kX86InstIdPsrldq_NameIndex = 3193, + kX86InstIdPsrlq_NameIndex = 3200, + kX86InstIdPsrlw_NameIndex = 3206, + kX86InstIdPsubb_NameIndex = 3212, + kX86InstIdPsubd_NameIndex = 3218, + kX86InstIdPsubq_NameIndex = 3224, + kX86InstIdPsubsb_NameIndex = 3230, + kX86InstIdPsubsw_NameIndex = 3237, + kX86InstIdPsubusb_NameIndex = 3244, + kX86InstIdPsubusw_NameIndex = 3252, + kX86InstIdPsubw_NameIndex = 3260, + kX86InstIdPswapd_NameIndex = 3266, + kX86InstIdPtest_NameIndex = 3273, + kX86InstIdPunpckhbw_NameIndex = 3279, + kX86InstIdPunpckhdq_NameIndex = 3289, + kX86InstIdPunpckhqdq_NameIndex = 3299, + kX86InstIdPunpckhwd_NameIndex = 3310, + kX86InstIdPunpcklbw_NameIndex = 3320, + kX86InstIdPunpckldq_NameIndex = 3330, + kX86InstIdPunpcklqdq_NameIndex = 3340, + kX86InstIdPunpcklwd_NameIndex = 3351, + kX86InstIdPush_NameIndex = 3361, + kX86InstIdPusha_NameIndex = 3366, + kX86InstIdPushf_NameIndex = 3372, + kX86InstIdPxor_NameIndex = 3378, + kX86InstIdRcl_NameIndex = 3383, + kX86InstIdRcpps_NameIndex = 3387, + kX86InstIdRcpss_NameIndex = 3393, + kX86InstIdRcr_NameIndex = 3399, + kX86InstIdRdfsbase_NameIndex = 3403, + kX86InstIdRdgsbase_NameIndex = 3412, + kX86InstIdRdrand_NameIndex = 3421, + kX86InstIdRdtsc_NameIndex = 3428, + kX86InstIdRdtscp_NameIndex = 3434, + kX86InstIdRepLodsB_NameIndex = 3441, + kX86InstIdRepLodsD_NameIndex = 3452, + kX86InstIdRepLodsQ_NameIndex = 3463, + kX86InstIdRepLodsW_NameIndex = 3474, + kX86InstIdRepMovsB_NameIndex = 3485, + kX86InstIdRepMovsD_NameIndex = 3496, + kX86InstIdRepMovsQ_NameIndex = 3507, + kX86InstIdRepMovsW_NameIndex = 3518, + kX86InstIdRepStosB_NameIndex = 3529, + kX86InstIdRepStosD_NameIndex = 3540, + kX86InstIdRepStosQ_NameIndex = 3551, + kX86InstIdRepStosW_NameIndex = 3562, + kX86InstIdRepeCmpsB_NameIndex = 3573, + kX86InstIdRepeCmpsD_NameIndex = 3585, + kX86InstIdRepeCmpsQ_NameIndex = 3597, + kX86InstIdRepeCmpsW_NameIndex = 3609, + kX86InstIdRepeScasB_NameIndex = 3621, + kX86InstIdRepeScasD_NameIndex = 3633, + kX86InstIdRepeScasQ_NameIndex = 3645, + kX86InstIdRepeScasW_NameIndex = 3657, + kX86InstIdRepneCmpsB_NameIndex = 3669, + kX86InstIdRepneCmpsD_NameIndex = 3682, + kX86InstIdRepneCmpsQ_NameIndex = 3695, + kX86InstIdRepneCmpsW_NameIndex = 3708, + kX86InstIdRepneScasB_NameIndex = 3721, + kX86InstIdRepneScasD_NameIndex = 3734, + kX86InstIdRepneScasQ_NameIndex = 3747, + kX86InstIdRepneScasW_NameIndex = 3760, + kX86InstIdRet_NameIndex = 3773, + kX86InstIdRol_NameIndex = 3777, + kX86InstIdRor_NameIndex = 3781, + kX86InstIdRorx_NameIndex = 3785, + kX86InstIdRoundpd_NameIndex = 3790, + kX86InstIdRoundps_NameIndex = 3798, + kX86InstIdRoundsd_NameIndex = 3806, + kX86InstIdRoundss_NameIndex = 3814, + kX86InstIdRsqrtps_NameIndex = 3822, + kX86InstIdRsqrtss_NameIndex = 3830, + kX86InstIdSahf_NameIndex = 3838, + kX86InstIdSal_NameIndex = 3843, + kX86InstIdSar_NameIndex = 3847, + kX86InstIdSarx_NameIndex = 3851, + kX86InstIdSbb_NameIndex = 3856, + kX86InstIdScasB_NameIndex = 3860, + kX86InstIdScasD_NameIndex = 3867, + kX86InstIdScasQ_NameIndex = 3874, + kX86InstIdScasW_NameIndex = 3881, + kX86InstIdSeta_NameIndex = 3888, + kX86InstIdSetae_NameIndex = 3893, + kX86InstIdSetb_NameIndex = 3899, + kX86InstIdSetbe_NameIndex = 3904, + kX86InstIdSetc_NameIndex = 3910, + kX86InstIdSete_NameIndex = 3915, + kX86InstIdSetg_NameIndex = 3920, + kX86InstIdSetge_NameIndex = 3925, + kX86InstIdSetl_NameIndex = 3931, + kX86InstIdSetle_NameIndex = 3936, + kX86InstIdSetna_NameIndex = 3942, + kX86InstIdSetnae_NameIndex = 3948, + kX86InstIdSetnb_NameIndex = 3955, + kX86InstIdSetnbe_NameIndex = 3961, + kX86InstIdSetnc_NameIndex = 3968, + kX86InstIdSetne_NameIndex = 3974, + kX86InstIdSetng_NameIndex = 3980, + kX86InstIdSetnge_NameIndex = 3986, + kX86InstIdSetnl_NameIndex = 3993, + kX86InstIdSetnle_NameIndex = 3999, + kX86InstIdSetno_NameIndex = 4006, + kX86InstIdSetnp_NameIndex = 4012, + kX86InstIdSetns_NameIndex = 4018, + kX86InstIdSetnz_NameIndex = 4024, + kX86InstIdSeto_NameIndex = 4030, + kX86InstIdSetp_NameIndex = 4035, + kX86InstIdSetpe_NameIndex = 4040, + kX86InstIdSetpo_NameIndex = 4046, + kX86InstIdSets_NameIndex = 4052, + kX86InstIdSetz_NameIndex = 4057, + kX86InstIdSfence_NameIndex = 4062, + kX86InstIdShl_NameIndex = 4069, + kX86InstIdShld_NameIndex = 4073, + kX86InstIdShlx_NameIndex = 4078, + kX86InstIdShr_NameIndex = 4083, + kX86InstIdShrd_NameIndex = 4087, + kX86InstIdShrx_NameIndex = 4092, + kX86InstIdShufpd_NameIndex = 4097, + kX86InstIdShufps_NameIndex = 4104, + kX86InstIdSqrtpd_NameIndex = 4111, + kX86InstIdSqrtps_NameIndex = 4118, + kX86InstIdSqrtsd_NameIndex = 4125, + kX86InstIdSqrtss_NameIndex = 4132, + kX86InstIdStc_NameIndex = 4139, + kX86InstIdStd_NameIndex = 4143, + kX86InstIdStmxcsr_NameIndex = 4147, + kX86InstIdStosB_NameIndex = 4155, + kX86InstIdStosD_NameIndex = 4162, + kX86InstIdStosQ_NameIndex = 4169, + kX86InstIdStosW_NameIndex = 4176, + kX86InstIdSub_NameIndex = 4183, + kX86InstIdSubpd_NameIndex = 4187, + kX86InstIdSubps_NameIndex = 4193, + kX86InstIdSubsd_NameIndex = 4199, + kX86InstIdSubss_NameIndex = 4205, + kX86InstIdTest_NameIndex = 4211, + kX86InstIdTzcnt_NameIndex = 4216, + kX86InstIdUcomisd_NameIndex = 4222, + kX86InstIdUcomiss_NameIndex = 4230, + kX86InstIdUd2_NameIndex = 4238, + kX86InstIdUnpckhpd_NameIndex = 4242, + kX86InstIdUnpckhps_NameIndex = 4251, + kX86InstIdUnpcklpd_NameIndex = 4260, + kX86InstIdUnpcklps_NameIndex = 4269, + kX86InstIdVaddpd_NameIndex = 4278, + kX86InstIdVaddps_NameIndex = 4285, + kX86InstIdVaddsd_NameIndex = 4292, + kX86InstIdVaddss_NameIndex = 4299, + kX86InstIdVaddsubpd_NameIndex = 4306, + kX86InstIdVaddsubps_NameIndex = 4316, + kX86InstIdVaesdec_NameIndex = 4326, + kX86InstIdVaesdeclast_NameIndex = 4334, + kX86InstIdVaesenc_NameIndex = 4346, + kX86InstIdVaesenclast_NameIndex = 4354, + kX86InstIdVaesimc_NameIndex = 4366, + kX86InstIdVaeskeygenassist_NameIndex = 4374, + kX86InstIdVandnpd_NameIndex = 4391, + kX86InstIdVandnps_NameIndex = 4399, + kX86InstIdVandpd_NameIndex = 4407, + kX86InstIdVandps_NameIndex = 4414, + kX86InstIdVblendpd_NameIndex = 4421, + kX86InstIdVblendps_NameIndex = 4430, + kX86InstIdVblendvpd_NameIndex = 4439, + kX86InstIdVblendvps_NameIndex = 4449, + kX86InstIdVbroadcastf128_NameIndex = 4459, + kX86InstIdVbroadcasti128_NameIndex = 4474, + kX86InstIdVbroadcastsd_NameIndex = 4489, + kX86InstIdVbroadcastss_NameIndex = 4502, + kX86InstIdVcmppd_NameIndex = 4515, + kX86InstIdVcmpps_NameIndex = 4522, + kX86InstIdVcmpsd_NameIndex = 4529, + kX86InstIdVcmpss_NameIndex = 4536, + kX86InstIdVcomisd_NameIndex = 4543, + kX86InstIdVcomiss_NameIndex = 4551, + kX86InstIdVcvtdq2pd_NameIndex = 4559, + kX86InstIdVcvtdq2ps_NameIndex = 4569, + kX86InstIdVcvtpd2dq_NameIndex = 4579, + kX86InstIdVcvtpd2ps_NameIndex = 4589, + kX86InstIdVcvtph2ps_NameIndex = 4599, + kX86InstIdVcvtps2dq_NameIndex = 4609, + kX86InstIdVcvtps2pd_NameIndex = 4619, + kX86InstIdVcvtps2ph_NameIndex = 4629, + kX86InstIdVcvtsd2si_NameIndex = 4639, + kX86InstIdVcvtsd2ss_NameIndex = 4649, + kX86InstIdVcvtsi2sd_NameIndex = 4659, + kX86InstIdVcvtsi2ss_NameIndex = 4669, + kX86InstIdVcvtss2sd_NameIndex = 4679, + kX86InstIdVcvtss2si_NameIndex = 4689, + kX86InstIdVcvttpd2dq_NameIndex = 4699, + kX86InstIdVcvttps2dq_NameIndex = 4710, + kX86InstIdVcvttsd2si_NameIndex = 4721, + kX86InstIdVcvttss2si_NameIndex = 4732, + kX86InstIdVdivpd_NameIndex = 4743, + kX86InstIdVdivps_NameIndex = 4750, + kX86InstIdVdivsd_NameIndex = 4757, + kX86InstIdVdivss_NameIndex = 4764, + kX86InstIdVdppd_NameIndex = 4771, + kX86InstIdVdpps_NameIndex = 4777, + kX86InstIdVextractf128_NameIndex = 4783, + kX86InstIdVextracti128_NameIndex = 4796, + kX86InstIdVextractps_NameIndex = 4809, + kX86InstIdVfmadd132pd_NameIndex = 4820, + kX86InstIdVfmadd132ps_NameIndex = 4832, + kX86InstIdVfmadd132sd_NameIndex = 4844, + kX86InstIdVfmadd132ss_NameIndex = 4856, + kX86InstIdVfmadd213pd_NameIndex = 4868, + kX86InstIdVfmadd213ps_NameIndex = 4880, + kX86InstIdVfmadd213sd_NameIndex = 4892, + kX86InstIdVfmadd213ss_NameIndex = 4904, + kX86InstIdVfmadd231pd_NameIndex = 4916, + kX86InstIdVfmadd231ps_NameIndex = 4928, + kX86InstIdVfmadd231sd_NameIndex = 4940, + kX86InstIdVfmadd231ss_NameIndex = 4952, + kX86InstIdVfmaddpd_NameIndex = 4964, + kX86InstIdVfmaddps_NameIndex = 4973, + kX86InstIdVfmaddsd_NameIndex = 4982, + kX86InstIdVfmaddss_NameIndex = 4991, + kX86InstIdVfmaddsub132pd_NameIndex = 5000, + kX86InstIdVfmaddsub132ps_NameIndex = 5015, + kX86InstIdVfmaddsub213pd_NameIndex = 5030, + kX86InstIdVfmaddsub213ps_NameIndex = 5045, + kX86InstIdVfmaddsub231pd_NameIndex = 5060, + kX86InstIdVfmaddsub231ps_NameIndex = 5075, + kX86InstIdVfmaddsubpd_NameIndex = 5090, + kX86InstIdVfmaddsubps_NameIndex = 5102, + kX86InstIdVfmsub132pd_NameIndex = 5114, + kX86InstIdVfmsub132ps_NameIndex = 5126, + kX86InstIdVfmsub132sd_NameIndex = 5138, + kX86InstIdVfmsub132ss_NameIndex = 5150, + kX86InstIdVfmsub213pd_NameIndex = 5162, + kX86InstIdVfmsub213ps_NameIndex = 5174, + kX86InstIdVfmsub213sd_NameIndex = 5186, + kX86InstIdVfmsub213ss_NameIndex = 5198, + kX86InstIdVfmsub231pd_NameIndex = 5210, + kX86InstIdVfmsub231ps_NameIndex = 5222, + kX86InstIdVfmsub231sd_NameIndex = 5234, + kX86InstIdVfmsub231ss_NameIndex = 5246, + kX86InstIdVfmsubadd132pd_NameIndex = 5258, + kX86InstIdVfmsubadd132ps_NameIndex = 5273, + kX86InstIdVfmsubadd213pd_NameIndex = 5288, + kX86InstIdVfmsubadd213ps_NameIndex = 5303, + kX86InstIdVfmsubadd231pd_NameIndex = 5318, + kX86InstIdVfmsubadd231ps_NameIndex = 5333, + kX86InstIdVfmsubaddpd_NameIndex = 5348, + kX86InstIdVfmsubaddps_NameIndex = 5360, + kX86InstIdVfmsubpd_NameIndex = 5372, + kX86InstIdVfmsubps_NameIndex = 5381, + kX86InstIdVfmsubsd_NameIndex = 5390, + kX86InstIdVfmsubss_NameIndex = 5399, + kX86InstIdVfnmadd132pd_NameIndex = 5408, + kX86InstIdVfnmadd132ps_NameIndex = 5421, + kX86InstIdVfnmadd132sd_NameIndex = 5434, + kX86InstIdVfnmadd132ss_NameIndex = 5447, + kX86InstIdVfnmadd213pd_NameIndex = 5460, + kX86InstIdVfnmadd213ps_NameIndex = 5473, + kX86InstIdVfnmadd213sd_NameIndex = 5486, + kX86InstIdVfnmadd213ss_NameIndex = 5499, + kX86InstIdVfnmadd231pd_NameIndex = 5512, + kX86InstIdVfnmadd231ps_NameIndex = 5525, + kX86InstIdVfnmadd231sd_NameIndex = 5538, + kX86InstIdVfnmadd231ss_NameIndex = 5551, + kX86InstIdVfnmaddpd_NameIndex = 5564, + kX86InstIdVfnmaddps_NameIndex = 5574, + kX86InstIdVfnmaddsd_NameIndex = 5584, + kX86InstIdVfnmaddss_NameIndex = 5594, + kX86InstIdVfnmsub132pd_NameIndex = 5604, + kX86InstIdVfnmsub132ps_NameIndex = 5617, + kX86InstIdVfnmsub132sd_NameIndex = 5630, + kX86InstIdVfnmsub132ss_NameIndex = 5643, + kX86InstIdVfnmsub213pd_NameIndex = 5656, + kX86InstIdVfnmsub213ps_NameIndex = 5669, + kX86InstIdVfnmsub213sd_NameIndex = 5682, + kX86InstIdVfnmsub213ss_NameIndex = 5695, + kX86InstIdVfnmsub231pd_NameIndex = 5708, + kX86InstIdVfnmsub231ps_NameIndex = 5721, + kX86InstIdVfnmsub231sd_NameIndex = 5734, + kX86InstIdVfnmsub231ss_NameIndex = 5747, + kX86InstIdVfnmsubpd_NameIndex = 5760, + kX86InstIdVfnmsubps_NameIndex = 5770, + kX86InstIdVfnmsubsd_NameIndex = 5780, + kX86InstIdVfnmsubss_NameIndex = 5790, + kX86InstIdVfrczpd_NameIndex = 5800, + kX86InstIdVfrczps_NameIndex = 5808, + kX86InstIdVfrczsd_NameIndex = 5816, + kX86InstIdVfrczss_NameIndex = 5824, + kX86InstIdVgatherdpd_NameIndex = 5832, + kX86InstIdVgatherdps_NameIndex = 5843, + kX86InstIdVgatherqpd_NameIndex = 5854, + kX86InstIdVgatherqps_NameIndex = 5865, + kX86InstIdVhaddpd_NameIndex = 5876, + kX86InstIdVhaddps_NameIndex = 5884, + kX86InstIdVhsubpd_NameIndex = 5892, + kX86InstIdVhsubps_NameIndex = 5900, + kX86InstIdVinsertf128_NameIndex = 5908, + kX86InstIdVinserti128_NameIndex = 5920, + kX86InstIdVinsertps_NameIndex = 5932, + kX86InstIdVlddqu_NameIndex = 5942, + kX86InstIdVldmxcsr_NameIndex = 5949, + kX86InstIdVmaskmovdqu_NameIndex = 5958, + kX86InstIdVmaskmovpd_NameIndex = 5970, + kX86InstIdVmaskmovps_NameIndex = 5981, + kX86InstIdVmaxpd_NameIndex = 5992, + kX86InstIdVmaxps_NameIndex = 5999, + kX86InstIdVmaxsd_NameIndex = 6006, + kX86InstIdVmaxss_NameIndex = 6013, + kX86InstIdVminpd_NameIndex = 6020, + kX86InstIdVminps_NameIndex = 6027, + kX86InstIdVminsd_NameIndex = 6034, + kX86InstIdVminss_NameIndex = 6041, + kX86InstIdVmovapd_NameIndex = 6048, + kX86InstIdVmovaps_NameIndex = 6056, + kX86InstIdVmovd_NameIndex = 6064, + kX86InstIdVmovddup_NameIndex = 6070, + kX86InstIdVmovdqa_NameIndex = 6079, + kX86InstIdVmovdqu_NameIndex = 6087, + kX86InstIdVmovhlps_NameIndex = 6095, + kX86InstIdVmovhpd_NameIndex = 6104, + kX86InstIdVmovhps_NameIndex = 6112, + kX86InstIdVmovlhps_NameIndex = 6120, + kX86InstIdVmovlpd_NameIndex = 6129, + kX86InstIdVmovlps_NameIndex = 6137, + kX86InstIdVmovmskpd_NameIndex = 6145, + kX86InstIdVmovmskps_NameIndex = 6155, + kX86InstIdVmovntdq_NameIndex = 6165, + kX86InstIdVmovntdqa_NameIndex = 6174, + kX86InstIdVmovntpd_NameIndex = 6184, + kX86InstIdVmovntps_NameIndex = 6193, + kX86InstIdVmovq_NameIndex = 6202, + kX86InstIdVmovsd_NameIndex = 6208, + kX86InstIdVmovshdup_NameIndex = 6215, + kX86InstIdVmovsldup_NameIndex = 6225, + kX86InstIdVmovss_NameIndex = 6235, + kX86InstIdVmovupd_NameIndex = 6242, + kX86InstIdVmovups_NameIndex = 6250, + kX86InstIdVmpsadbw_NameIndex = 6258, + kX86InstIdVmulpd_NameIndex = 6267, + kX86InstIdVmulps_NameIndex = 6274, + kX86InstIdVmulsd_NameIndex = 6281, + kX86InstIdVmulss_NameIndex = 6288, + kX86InstIdVorpd_NameIndex = 6295, + kX86InstIdVorps_NameIndex = 6301, + kX86InstIdVpabsb_NameIndex = 6307, + kX86InstIdVpabsd_NameIndex = 6314, + kX86InstIdVpabsw_NameIndex = 6321, + kX86InstIdVpackssdw_NameIndex = 6328, + kX86InstIdVpacksswb_NameIndex = 6338, + kX86InstIdVpackusdw_NameIndex = 6348, + kX86InstIdVpackuswb_NameIndex = 6358, + kX86InstIdVpaddb_NameIndex = 6368, + kX86InstIdVpaddd_NameIndex = 6375, + kX86InstIdVpaddq_NameIndex = 6382, + kX86InstIdVpaddsb_NameIndex = 6389, + kX86InstIdVpaddsw_NameIndex = 6397, + kX86InstIdVpaddusb_NameIndex = 6405, + kX86InstIdVpaddusw_NameIndex = 6414, + kX86InstIdVpaddw_NameIndex = 6423, + kX86InstIdVpalignr_NameIndex = 6430, + kX86InstIdVpand_NameIndex = 6439, + kX86InstIdVpandn_NameIndex = 6445, + kX86InstIdVpavgb_NameIndex = 6452, + kX86InstIdVpavgw_NameIndex = 6459, + kX86InstIdVpblendd_NameIndex = 6466, + kX86InstIdVpblendvb_NameIndex = 6475, + kX86InstIdVpblendw_NameIndex = 6485, + kX86InstIdVpbroadcastb_NameIndex = 6494, + kX86InstIdVpbroadcastd_NameIndex = 6507, + kX86InstIdVpbroadcastq_NameIndex = 6520, + kX86InstIdVpbroadcastw_NameIndex = 6533, + kX86InstIdVpclmulqdq_NameIndex = 6546, + kX86InstIdVpcmov_NameIndex = 6557, + kX86InstIdVpcmpeqb_NameIndex = 6564, + kX86InstIdVpcmpeqd_NameIndex = 6573, + kX86InstIdVpcmpeqq_NameIndex = 6582, + kX86InstIdVpcmpeqw_NameIndex = 6591, + kX86InstIdVpcmpestri_NameIndex = 6600, + kX86InstIdVpcmpestrm_NameIndex = 6611, + kX86InstIdVpcmpgtb_NameIndex = 6622, + kX86InstIdVpcmpgtd_NameIndex = 6631, + kX86InstIdVpcmpgtq_NameIndex = 6640, + kX86InstIdVpcmpgtw_NameIndex = 6649, + kX86InstIdVpcmpistri_NameIndex = 6658, + kX86InstIdVpcmpistrm_NameIndex = 6669, + kX86InstIdVpcomb_NameIndex = 6680, + kX86InstIdVpcomd_NameIndex = 6687, + kX86InstIdVpcomq_NameIndex = 6694, + kX86InstIdVpcomub_NameIndex = 6701, + kX86InstIdVpcomud_NameIndex = 6709, + kX86InstIdVpcomuq_NameIndex = 6717, + kX86InstIdVpcomuw_NameIndex = 6725, + kX86InstIdVpcomw_NameIndex = 6733, + kX86InstIdVperm2f128_NameIndex = 6740, + kX86InstIdVperm2i128_NameIndex = 6751, + kX86InstIdVpermd_NameIndex = 6762, + kX86InstIdVpermil2pd_NameIndex = 6769, + kX86InstIdVpermil2ps_NameIndex = 6780, + kX86InstIdVpermilpd_NameIndex = 6791, + kX86InstIdVpermilps_NameIndex = 6801, + kX86InstIdVpermpd_NameIndex = 6811, + kX86InstIdVpermps_NameIndex = 6819, + kX86InstIdVpermq_NameIndex = 6827, + kX86InstIdVpextrb_NameIndex = 6834, + kX86InstIdVpextrd_NameIndex = 6842, + kX86InstIdVpextrq_NameIndex = 6850, + kX86InstIdVpextrw_NameIndex = 6858, + kX86InstIdVpgatherdd_NameIndex = 6866, + kX86InstIdVpgatherdq_NameIndex = 6877, + kX86InstIdVpgatherqd_NameIndex = 6888, + kX86InstIdVpgatherqq_NameIndex = 6899, + kX86InstIdVphaddbd_NameIndex = 6910, + kX86InstIdVphaddbq_NameIndex = 6919, + kX86InstIdVphaddbw_NameIndex = 6928, + kX86InstIdVphaddd_NameIndex = 6937, + kX86InstIdVphadddq_NameIndex = 6945, + kX86InstIdVphaddsw_NameIndex = 6954, + kX86InstIdVphaddubd_NameIndex = 6963, + kX86InstIdVphaddubq_NameIndex = 6973, + kX86InstIdVphaddubw_NameIndex = 6983, + kX86InstIdVphaddudq_NameIndex = 6993, + kX86InstIdVphadduwd_NameIndex = 7003, + kX86InstIdVphadduwq_NameIndex = 7013, + kX86InstIdVphaddw_NameIndex = 7023, + kX86InstIdVphaddwd_NameIndex = 7031, + kX86InstIdVphaddwq_NameIndex = 7040, + kX86InstIdVphminposuw_NameIndex = 7049, + kX86InstIdVphsubbw_NameIndex = 7061, + kX86InstIdVphsubd_NameIndex = 7070, + kX86InstIdVphsubdq_NameIndex = 7078, + kX86InstIdVphsubsw_NameIndex = 7087, + kX86InstIdVphsubw_NameIndex = 7096, + kX86InstIdVphsubwd_NameIndex = 7104, + kX86InstIdVpinsrb_NameIndex = 7113, + kX86InstIdVpinsrd_NameIndex = 7121, + kX86InstIdVpinsrq_NameIndex = 7129, + kX86InstIdVpinsrw_NameIndex = 7137, + kX86InstIdVpmacsdd_NameIndex = 7145, + kX86InstIdVpmacsdqh_NameIndex = 7154, + kX86InstIdVpmacsdql_NameIndex = 7164, + kX86InstIdVpmacssdd_NameIndex = 7174, + kX86InstIdVpmacssdqh_NameIndex = 7184, + kX86InstIdVpmacssdql_NameIndex = 7195, + kX86InstIdVpmacsswd_NameIndex = 7206, + kX86InstIdVpmacssww_NameIndex = 7216, + kX86InstIdVpmacswd_NameIndex = 7226, + kX86InstIdVpmacsww_NameIndex = 7235, + kX86InstIdVpmadcsswd_NameIndex = 7244, + kX86InstIdVpmadcswd_NameIndex = 7255, + kX86InstIdVpmaddubsw_NameIndex = 7265, + kX86InstIdVpmaddwd_NameIndex = 7276, + kX86InstIdVpmaskmovd_NameIndex = 7285, + kX86InstIdVpmaskmovq_NameIndex = 7296, + kX86InstIdVpmaxsb_NameIndex = 7307, + kX86InstIdVpmaxsd_NameIndex = 7315, + kX86InstIdVpmaxsw_NameIndex = 7323, + kX86InstIdVpmaxub_NameIndex = 7331, + kX86InstIdVpmaxud_NameIndex = 7339, + kX86InstIdVpmaxuw_NameIndex = 7347, + kX86InstIdVpminsb_NameIndex = 7355, + kX86InstIdVpminsd_NameIndex = 7363, + kX86InstIdVpminsw_NameIndex = 7371, + kX86InstIdVpminub_NameIndex = 7379, + kX86InstIdVpminud_NameIndex = 7387, + kX86InstIdVpminuw_NameIndex = 7395, + kX86InstIdVpmovmskb_NameIndex = 7403, + kX86InstIdVpmovsxbd_NameIndex = 7413, + kX86InstIdVpmovsxbq_NameIndex = 7423, + kX86InstIdVpmovsxbw_NameIndex = 7433, + kX86InstIdVpmovsxdq_NameIndex = 7443, + kX86InstIdVpmovsxwd_NameIndex = 7453, + kX86InstIdVpmovsxwq_NameIndex = 7463, + kX86InstIdVpmovzxbd_NameIndex = 7473, + kX86InstIdVpmovzxbq_NameIndex = 7483, + kX86InstIdVpmovzxbw_NameIndex = 7493, + kX86InstIdVpmovzxdq_NameIndex = 7503, + kX86InstIdVpmovzxwd_NameIndex = 7513, + kX86InstIdVpmovzxwq_NameIndex = 7523, + kX86InstIdVpmuldq_NameIndex = 7533, + kX86InstIdVpmulhrsw_NameIndex = 7541, + kX86InstIdVpmulhuw_NameIndex = 7551, + kX86InstIdVpmulhw_NameIndex = 7560, + kX86InstIdVpmulld_NameIndex = 7568, + kX86InstIdVpmullw_NameIndex = 7576, + kX86InstIdVpmuludq_NameIndex = 7584, + kX86InstIdVpor_NameIndex = 7593, + kX86InstIdVpperm_NameIndex = 7598, + kX86InstIdVprotb_NameIndex = 7605, + kX86InstIdVprotd_NameIndex = 7612, + kX86InstIdVprotq_NameIndex = 7619, + kX86InstIdVprotw_NameIndex = 7626, + kX86InstIdVpsadbw_NameIndex = 7633, + kX86InstIdVpshab_NameIndex = 7641, + kX86InstIdVpshad_NameIndex = 7648, + kX86InstIdVpshaq_NameIndex = 7655, + kX86InstIdVpshaw_NameIndex = 7662, + kX86InstIdVpshlb_NameIndex = 7669, + kX86InstIdVpshld_NameIndex = 7676, + kX86InstIdVpshlq_NameIndex = 7683, + kX86InstIdVpshlw_NameIndex = 7690, + kX86InstIdVpshufb_NameIndex = 7697, + kX86InstIdVpshufd_NameIndex = 7705, + kX86InstIdVpshufhw_NameIndex = 7713, + kX86InstIdVpshuflw_NameIndex = 7722, + kX86InstIdVpsignb_NameIndex = 7731, + kX86InstIdVpsignd_NameIndex = 7739, + kX86InstIdVpsignw_NameIndex = 7747, + kX86InstIdVpslld_NameIndex = 7755, + kX86InstIdVpslldq_NameIndex = 7762, + kX86InstIdVpsllq_NameIndex = 7770, + kX86InstIdVpsllvd_NameIndex = 7777, + kX86InstIdVpsllvq_NameIndex = 7785, + kX86InstIdVpsllw_NameIndex = 7793, + kX86InstIdVpsrad_NameIndex = 7800, + kX86InstIdVpsravd_NameIndex = 7807, + kX86InstIdVpsraw_NameIndex = 7815, + kX86InstIdVpsrld_NameIndex = 7822, + kX86InstIdVpsrldq_NameIndex = 7829, + kX86InstIdVpsrlq_NameIndex = 7837, + kX86InstIdVpsrlvd_NameIndex = 7844, + kX86InstIdVpsrlvq_NameIndex = 7852, + kX86InstIdVpsrlw_NameIndex = 7860, + kX86InstIdVpsubb_NameIndex = 7867, + kX86InstIdVpsubd_NameIndex = 7874, + kX86InstIdVpsubq_NameIndex = 7881, + kX86InstIdVpsubsb_NameIndex = 7888, + kX86InstIdVpsubsw_NameIndex = 7896, + kX86InstIdVpsubusb_NameIndex = 7904, + kX86InstIdVpsubusw_NameIndex = 7913, + kX86InstIdVpsubw_NameIndex = 7922, + kX86InstIdVptest_NameIndex = 7929, + kX86InstIdVpunpckhbw_NameIndex = 7936, + kX86InstIdVpunpckhdq_NameIndex = 7947, + kX86InstIdVpunpckhqdq_NameIndex = 7958, + kX86InstIdVpunpckhwd_NameIndex = 7970, + kX86InstIdVpunpcklbw_NameIndex = 7981, + kX86InstIdVpunpckldq_NameIndex = 7992, + kX86InstIdVpunpcklqdq_NameIndex = 8003, + kX86InstIdVpunpcklwd_NameIndex = 8015, + kX86InstIdVpxor_NameIndex = 8026, + kX86InstIdVrcpps_NameIndex = 8032, + kX86InstIdVrcpss_NameIndex = 8039, + kX86InstIdVroundpd_NameIndex = 8046, + kX86InstIdVroundps_NameIndex = 8055, + kX86InstIdVroundsd_NameIndex = 8064, + kX86InstIdVroundss_NameIndex = 8073, + kX86InstIdVrsqrtps_NameIndex = 8082, + kX86InstIdVrsqrtss_NameIndex = 8091, + kX86InstIdVshufpd_NameIndex = 8100, + kX86InstIdVshufps_NameIndex = 8108, + kX86InstIdVsqrtpd_NameIndex = 8116, + kX86InstIdVsqrtps_NameIndex = 8124, + kX86InstIdVsqrtsd_NameIndex = 8132, + kX86InstIdVsqrtss_NameIndex = 8140, + kX86InstIdVstmxcsr_NameIndex = 8148, + kX86InstIdVsubpd_NameIndex = 8157, + kX86InstIdVsubps_NameIndex = 8164, + kX86InstIdVsubsd_NameIndex = 8171, + kX86InstIdVsubss_NameIndex = 8178, + kX86InstIdVtestpd_NameIndex = 8185, + kX86InstIdVtestps_NameIndex = 8193, + kX86InstIdVucomisd_NameIndex = 8201, + kX86InstIdVucomiss_NameIndex = 8210, + kX86InstIdVunpckhpd_NameIndex = 8219, + kX86InstIdVunpckhps_NameIndex = 8229, + kX86InstIdVunpcklpd_NameIndex = 8239, + kX86InstIdVunpcklps_NameIndex = 8249, + kX86InstIdVxorpd_NameIndex = 8259, + kX86InstIdVxorps_NameIndex = 8266, + kX86InstIdVzeroall_NameIndex = 8273, + kX86InstIdVzeroupper_NameIndex = 8282, + kX86InstIdWrfsbase_NameIndex = 8293, + kX86InstIdWrgsbase_NameIndex = 8302, + kX86InstIdXadd_NameIndex = 8311, + kX86InstIdXchg_NameIndex = 8316, + kX86InstIdXgetbv_NameIndex = 8321, + kX86InstIdXor_NameIndex = 8328, + kX86InstIdXorpd_NameIndex = 8332, + kX86InstIdXorps_NameIndex = 8338, + kX86InstIdXrstor_NameIndex = 8344, + kX86InstIdXrstor64_NameIndex = 8351, + kX86InstIdXsave_NameIndex = 8360, + kX86InstIdXsave64_NameIndex = 8366, + kX86InstIdXsaveopt_NameIndex = 8374, + kX86InstIdXsaveopt64_NameIndex = 8383, + kX86InstIdXsetbv_NameIndex = 8394 }; #endif // !ASMJIT_DISABLE_NAMES // Automatically generated, do not edit. const X86InstExtendedInfo _x86InstExtendedInfo[] = { - { G(None) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, - { G(X86Arith) , 0 , 0x20, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, - { G(X86Arith) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, - { G(ExtRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, - { G(AvxRvm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U }, - { G(AvxRmv) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U }, - { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(AvxVm) , 0 , 0x00, 0x3F, F(None) , { O(Gqd) , O(GqdMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x00, 0x3F, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86BSwap) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U }, - { G(X86BTest) , 0 , 0x00, 0x3B, F(Test) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,4) }, - { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,7) }, - { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,6) }, - { G(X86BTest) , 0 , 0x00, 0x3B, F(Lock) , { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, O_000F00(BA,5) }, - { G(X86Call) , 0 , 0x00, 0x00, F(Flow) , { O(GqdMem)|O(Imm)|O(Label), U , U , U , U }, O_000000(E8,U) }, - { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x00, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x00, 0x20, F(None) , { U , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x00, 0x40, F(None) , { U , U , U , U , U }, U }, - { G(X86M) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x20, 0x20, F(None) , { U , U , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x24, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x20, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x04, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x07, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x03, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x01, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x10, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86RegRm) , 0 , 0x02, 0x00, F(None) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(X86Arith) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, - { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, - { G(X86Op_66H) , 0 , 0x40, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86RmReg) , 0 , 0x00, 0x3F, F(Lock)|F(Special) , { U , U , U , U , U }, U }, - { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U }, - { G(X86M) , 0 , 0x00, 0x04, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U }, - { G(ExtRm) , 0 , 0x00, 0x3F, F(Test) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(ExtCrc) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdwbMem) , U , U , U }, U }, - { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(XmmMem) , U , U , U }, U }, - { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U }, - { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(MmMem) , U , U , U }, U }, - { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(XmmMem) , U , U , U }, U }, - { G(ExtRm) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(ExtRm_Q) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U }, - { G(ExtRm_Q) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(GqdMem) , U , U , U }, U }, - { G(ExtRm) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(X86Op) , 0 , 0x28, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(48,U) }, - { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, - { G(X86Enter) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GqdMem) , O(Xmm) , U , U , U }, O_660F3A(17,U) }, - { G(FpuOp) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U }, - { G(FpuArith) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(FpMem) , O(Fp) , U , U , U }, U }, - { G(FpuRDef) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, - { G(X86M) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, U }, - { G(FpuR) , 0 , 0x20, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, - { G(FpuR) , 0 , 0x24, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, - { G(FpuR) , 0 , 0x04, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, - { G(FpuR) , 0 , 0x10, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, - { G(FpuCom) , 0 , 0x00, 0x00, F(Fp) , { O(Fp)|O(Mem) , O(Fp) , U , U , U }, U }, - { G(FpuR) , 0 , 0x00, 0x3F, F(Fp) , { O(Fp) , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x00, 0x00, F(Fp) , { U , U , U , U , U }, U }, - { G(FpuR) , 0 , 0x00, 0x00, F(Fp) , { O(Fp) , U , U , U , U }, U }, - { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4) , { O(Mem) , U , U , U , U }, U }, - { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,5) }, - { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DF,7) }, - { G(FpuM) , 0 , 0x00, 0x00, F(Fp)|F(Mem2_4_8) , { O(Mem) , U , U , U , U }, O_000000(DD,1) }, - { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,5) }, - { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_00_X(DFE0,U) }, - { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8) , { O(Mem) , U , U , U , U }, U }, - { G(FpuFldFst) , 0 , 0x00, 0x00, F(Fp)|F(Mem4_8_10) , { O(Mem) , U , U , U , U }, O_000000(DB,7) }, - { G(FpuStsw) , 0 , 0x00, 0x00, F(Fp) , { O(Mem) , U , U , U , U }, O_9B_X(DFE0,U) }, - { G(X86Rm_B) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U }, - { G(X86Imul) , 0 , 0x00, 0x3F, F(None)|F(Special) , { 0 , 0 , U , U , U }, U }, - { G(X86IncDec) , 0 , 0x00, 0x1F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, O_000000(40,U) }, - { G(X86Int) , 0 , 0x00, 0x80, F(None) , { U , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x24, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x20, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x04, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x07, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x03, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x01, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x10, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jcc) , 0 , 0x02, 0x00, F(Flow) , { O(Label) , U , U , U , U }, U }, - { G(X86Jecxz) , 0 , 0x00, 0x00, F(Flow)|F(Special) , { O(Gqdw) , O(Label) , U , U , U }, U }, - { G(X86Jmp) , 0 , 0x00, 0x00, F(Flow) , { O(Imm)|O(Label) , U , U , U , U }, O_000000(E9,U) }, - { G(X86Op) , 0 , 0x3E, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U }, - { G(X86Lea) , 0 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Mem) , U , U , U }, U }, - { G(ExtFence) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, - { G(X86Op) , 1 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Op) , 4 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Op) , 8 , 0x40, 0x00, F(Move)|F(Special)|F(W), { U , U , U , U , U }, U }, - { G(X86Op_66H) , 2 , 0x40, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, - { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Xmm) , O(Xmm) , U , U , U }, U }, - { G(ExtRm) , 0 , 0x00, 0x00, F(None)|F(Special) , { O(Mm) , O(Mm) , U , U , U }, U }, - { G(X86Mov) , 0 , 0x00, 0x00, F(Move) , { O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U }, U }, - { G(X86MovPtr) , 0 , 0x00, 0x00, F(Move)|F(Special) , { O(Gqdwb) , O(Imm) , U , U , U }, O_000000(A2,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(29,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(29,U) }, - { G(ExtMovBe) , 0 , 0x00, 0x00, F(Move) , { O(GqdwMem) , O(GqdwMem) , U , U , U }, O_000F38(F1,U) }, - { G(ExtMovD) , 16, 0x00, 0x00, F(Move) , { O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , U }, O_000F00(7E,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(Xmm) , U , U , U }, U }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7F,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(7F,U) }, - { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(Xmm) , U , U , U }, U }, - { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(17,U) }, - { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(17,U) }, - { G(ExtMov) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U }, - { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(13,U) }, - { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(13,U) }, - { G(ExtMovNoRexW) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(Xmm) , U , U , U }, U }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(E7,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mem) , U , U , U }, U }, - { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Gqd) , U , U , U }, O_000F00(C3,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_660F00(2B,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(Mem) , O(Xmm) , U , U , U }, O_000F00(2B,U) }, - { G(ExtMov) , 8 , 0x00, 0x00, F(Move) , { O(Mem) , O(Mm) , U , U , U }, O_000F00(E7,U) }, - { G(ExtMovQ) , 16, 0x00, 0x00, F(Move) , { O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U }, U }, - { G(ExtRm) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(Mm) , U , U , U }, U }, - { G(X86Op) , 0 , 0x00, 0x00, F(Move)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Op_66H) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(ExtMov) , 8 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F20F00(11,U) }, - { G(ExtMov) , 4 , 0x00, 0x00, F(Move) |F(Z), { O(XmmMem) , O(XmmMem) , U , U , U }, O_F30F00(11,U) }, - { G(X86MovSxZx) , 0 , 0x00, 0x00, F(Move) , { O(Gqdw) , O(GwbMem) , U , U , U }, U }, - { G(X86MovSxd) , 0 , 0x00, 0x00, F(Move) , { O(Gq) , O(GdMem) , U , U , U }, U }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(11,U) }, - { G(ExtMov) , 16, 0x00, 0x00, F(Move) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_000F00(11,U) }, - { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, U }, - { G(X86Rm_B) , 0 , 0x00, 0x3F, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U }, - { G(X86Rm_B) , 0 , 0x00, 0x00, F(Lock) , { O(GqdwbMem) , U , U , U , U }, U }, - { G(ExtRm_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , U , U , U }, U }, - { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem) , O(Imm) , U , U }, U }, - { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , U }, O_000F3A(14,U) }, - { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) }, - { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) |F(W), { O(GqdMem) , O(Xmm) , U , U , U }, O_000F3A(16,U) }, - { G(ExtExtract) , 8 , 0x00, 0x00, F(Move) , { O(GdMem) , O(MmXmm) , U , U , U }, O_000F3A(15,U) }, - { G(3dNow) , 0 , 0x00, 0x00, F(None) , { O(Mm) , O(MmMem) , U , U , U }, U }, - { G(ExtRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(GdMem) , O(Imm) , U , U }, U }, - { G(ExtRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(GqMem) , O(Imm) , U , U }, U }, - { G(ExtRmi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(GdMem) , O(Imm) , U , U }, U }, - { G(ExtRm_PQ) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , O(MmXmm) , U , U , U }, U }, - { G(X86Pop) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(58,U) }, - { G(X86Op) , 0 , 0x00, 0xFF, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(ExtPrefetch) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(Imm) , U , U , U }, U }, - { G(ExtRmi) , 16, 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, - { G(ExtRmi_P) , 8 , 0x00, 0x00, F(Move) , { O(Mm) , O(MmMem) , O(Imm) , U , U }, U }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,6) }, - { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,7) }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,6) }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,6) }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,4) }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,4) }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(72,2) }, - { G(ExtRmRi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Imm) , U , U , U }, O_660F00(73,3) }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(73,2) }, - { G(ExtRmRi_P) , 0 , 0x00, 0x00, F(None) , { O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , U }, O_000F00(71,2) }, - { G(X86Push) , 0 , 0x00, 0x00, F(None)|F(Special) , { 0 , U , U , U , U }, O_000000(50,U) }, - { G(X86Op) , 0 , 0xFF, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Rot) , 0 , 0x20, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, - { G(X86Rm) , 8 , 0x00, 0x00, F(Move) , { O(Gqd) , U , U , U , U }, U }, - { G(X86Rm) , 8 , 0x00, 0x3F, F(Move) , { O(Gqdw) , U , U , U , U }, U }, - { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , U , U , U , U }, U }, - { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , U , U , U , U }, U }, - { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U }, - { G(X86Rep) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U }, - { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special) , { O(Mem) , O(Mem) , U , U , U }, U }, - { G(X86Rep) , 0 , 0x40, 0x3F, F(None)|F(Special)|F(W), { O(Mem) , O(Mem) , U , U , U }, U }, - { G(X86Ret) , 0 , 0x00, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Rot) , 0 , 0x00, 0x21, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, - { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Imm) , U , U }, U }, - { G(ExtRmi) , 8 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, - { G(ExtRmi) , 4 , 0x00, 0x00, F(Move) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, - { G(X86Op) , 0 , 0x00, 0x3E, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Rot) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, U }, - { G(AvxRmv) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, U }, - { G(X86Set) , 1 , 0x24, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Set) , 1 , 0x20, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Set) , 1 , 0x04, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Set) , 1 , 0x07, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Set) , 1 , 0x03, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Set) , 1 , 0x01, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Set) , 1 , 0x10, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Set) , 1 , 0x02, 0x00, F(Move) , { O(GbMem) , U , U , U , U }, U }, - { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gb) , U , U , U }, U }, - { G(X86Shlrd) , 0 , 0x00, 0x3F, F(None)|F(Special) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U }, - { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Op) , 0 , 0x40, 0x00, F(None)|F(Special)|F(W), { U , U , U , U , U }, U }, - { G(X86Op_66H) , 0 , 0x40, 0x00, F(None)|F(Special) , { U , U , U , U , U }, U }, - { G(X86Test) , 0 , 0x00, 0x3F, F(Test) , { O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , U }, O_000000(F6,U) }, - { G(X86RegRm) , 0 , 0x00, 0x3F, F(Move) , { O(Gqdw) , O(GqdwMem) , U , U , U }, U }, - { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U }, - { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U }, - { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(AvxRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, U }, - { G(AvxRvmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U }, U }, - { G(AvxRvmr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U }, - { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Mem) , U , U , U }, U }, - { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(XmmMem) , U , U , U }, U }, - { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U }, - { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmMem) , U , U , U }, U }, - { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, - { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U }, - { G(AvxMri_P) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmYmm) , O(Imm) , U , U }, U }, - { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmMem) , U , U , U }, U }, - { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , U , U }, U }, - { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmYmmMem) , U , U , U }, U }, - { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Ymm) , O(Imm) , U , U }, U }, - { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdMem) , O(Xmm) , O(Imm) , U , U }, U }, - { G(AvxRvm_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , U }, U }, - { G(AvxRvm) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, U }, - { G(Fma4_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, - { G(Fma4) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U }, - { G(XopRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, - { G(XopRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(AvxGather) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U }, - { G(AvxGather) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , O(XmmYmm) , U , U }, U }, - { G(AvxGatherEx) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Mem) , O(Xmm) , U , U }, U }, - { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , U }, U }, - { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(Mem) , U , U , U }, U }, - { G(AvxM) , 0 , 0x00, 0x00, F(None) , { O(Mem) , U , U , U , U }, U }, - { G(AvxRm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , U , U , U }, U }, - { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2F,U) }, - { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(2E,U) }, - { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(29,U) }, - { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(29,U) }, - { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) }, - { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(7F,U) }, - { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_F30F00(7F,U) }, - { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(Xmm) , U , U }, U }, - { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(17,U) }, - { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(17,U) }, - { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_660F00(13,U) }, - { G(AvxRvmMr) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, O_000F00(13,U) }, - { G(AvxRm_P) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , O(XmmYmm) , U , U , U }, U }, - { G(AvxMr) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U }, - { G(AvxMr_P) , 0 , 0x00, 0x00, F(None) , { O(Mem) , O(XmmYmm) , U , U , U }, U }, - { G(AvxRmMr) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmMem) , O(XmmMem) , U , U , U }, O_660F00(7E,U) }, - { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(XmmMem) , O(Xmm) , U , U }, O_F20F00(11,U) }, - { G(AvxMovSsSd) , 0 , 0x00, 0x00, F(None) , { O(XmmMem) , O(Xmm) , O(Xmm) , U , U }, O_F30F00(11,U) }, - { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_660F00(11,U) }, - { G(AvxRmMr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmmMem) , U , U , U }, O_000F00(11,U) }, - { G(AvxRvmr) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , U }, U }, - { G(XopRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, - { G(XopRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, U }, - { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , U }, U }, - { G(AvxRvm) , 0 , 0x00, 0x00, F(None) , { O(Ymm) , O(Ymm) , O(YmmMem) , U , U }, U }, - { G(AvxRvrmRvmr_P), 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , U }, U }, - { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(05,U) }, - { G(AvxRvmRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F3A(04,U) }, - { G(AvxRmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Ymm) , O(YmmMem) , O(Imm) , U , U }, U }, - { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwbMem) , O(Xmm) , O(Imm) , U , U }, U }, - { G(AvxMri) , 0 , 0x00, 0x00, F(None) |F(W), { O(GqMem) , O(Xmm) , O(Imm) , U , U }, U }, - { G(AvxMri) , 0 , 0x00, 0x00, F(None) , { O(GqdwMem) , O(Xmm) , O(Imm) , U , U }, U }, - { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , U }, U }, - { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , U }, U }, - { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) |F(W), { O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , U }, U }, - { G(AvxRvmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , U }, U }, - { G(XopRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U }, U }, - { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) }, - { G(AvxRvmMvr_P) , 0 , 0x00, 0x00, F(None) |F(W), { O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , U }, O_660F38(8E,U) }, - { G(XopRvrmRvmr) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, U }, - { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C0,U) }, - { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C2,U) }, - { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C3,U) }, - { G(XopRvmRmi) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, O_00_M08(C1,U) }, - { G(XopRvmRmv) , 0 , 0x00, 0x00, F(None) , { O(Xmm) , O(XmmMem) , O(XmmMem) , U , U }, U }, - { G(AvxRmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,6) }, - { G(AvxVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , U }, U }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,6) }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,6) }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,4) }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,4) }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(72,2) }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(73,2) }, - { G(AvxRvmVmi_P) , 0 , 0x00, 0x00, F(None) , { O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , U }, O_660F00(71,2) }, - { G(AvxRm_P) , 0 , 0x00, 0x3F, F(None) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, - { G(AvxRm_P) , 0 , 0x00, 0x3F, F(Test) , { O(XmmYmm) , O(XmmYmmMem) , U , U , U }, U }, - { G(AvxRm) , 0 , 0x00, 0x3F, F(None) , { O(Xmm) , O(XmmMem) , U , U , U }, U }, - { G(AvxOp) , 0 , 0x00, 0x00, F(None) , { U , U , U , U , U }, U }, - { G(X86Rm) , 0 , 0x00, 0x00, F(None) , { O(Gqd) , U , U , U , U }, U }, - { G(X86Xadd) , 0 , 0x00, 0x3F, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U }, - { G(X86Xchg) , 0 , 0x00, 0x00, F(Xchg)|F(Lock) , { O(GqdwbMem) , O(Gqdwb) , U , U , U }, U } + { Enc(None) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(None) , U }, + { Enc(X86Arith) , 0 , 0 , 0x20, 0x3F, 0, { O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U }, F(Lock) , U }, + { Enc(X86Arith) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U }, F(Lock) , U }, + { Enc(ExtRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(None) , U }, + { Enc(ExtRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, F(None) , U }, + { Enc(AvxRvm) , 0 , 0 , 0x00, 0x3F, 0, { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, F(None) , U }, + { Enc(AvxRmv) , 0 , 0 , 0x00, 0x3F, 0, { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, F(None) , U }, + { Enc(ExtRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(None)|F(Special) , U }, + { Enc(AvxVm) , 0 , 0 , 0x00, 0x3F, 0, { O(Gqd) , O(GqdMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x00, 0x3F, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86BSwap) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , U , U , U , U }, F(None) , U }, + { Enc(X86BTest) , 0 , 0 , 0x00, 0x3B, 0, { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, F(Test) , O_000F00(BA,4,_,_,_) }, + { Enc(X86BTest) , 0 , 0 , 0x00, 0x3B, 0, { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, F(Lock) , O_000F00(BA,7,_,_,_) }, + { Enc(X86BTest) , 0 , 0 , 0x00, 0x3B, 0, { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, F(Lock) , O_000F00(BA,6,_,_,_) }, + { Enc(X86BTest) , 0 , 0 , 0x00, 0x3B, 0, { O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U }, F(Lock) , O_000F00(BA,5,_,_,_) }, + { Enc(X86Call) , 0 , 0 , 0x00, 0x00, 0, { O(GqdMem)|O(LbImm), U , U , U , U }, F(Flow) , O_000000(E8,U,_,_,_) }, + { Enc(X86Op) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Op) , 0 , 0 , 0x00, 0x20, 0, { U , U , U , U , U }, F(None) , U }, + { Enc(X86Op) , 0 , 0 , 0x00, 0x40, 0, { U , U , U , U , U }, F(None) , U }, + { Enc(X86M) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(None) , U }, + { Enc(X86Op) , 0 , 0 , 0x20, 0x20, 0, { U , U , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x24, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x20, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x04, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x07, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x03, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x01, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x10, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86RegRm) , 0 , 0 , 0x02, 0x00, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(None) , U }, + { Enc(X86Arith) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U }, F(Test) , U }, + { Enc(X86Op) , 0 , 0 , 0x40, 0x3F, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Op_66H) , 0 , 0 , 0x40, 0x3F, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86RmReg) , 0 , 0 , 0x00, 0x3F, 0, { U , U , U , U , U }, F(Lock)|F(Special) , U }, + { Enc(X86M) , 0 , 0 , 0x00, 0x04, 0, { O(Mem) , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(ExtRm) , 0 , 0 , 0x00, 0x3F, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Test) , U }, + { Enc(ExtCrc) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , O(GqdwbMem) , U , U , U }, F(None) , U }, + { Enc(ExtRm) , 0 , 16, 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm) , 0 , 8 , 0x00, 0x00, 0, { O(Mm) , O(XmmMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm) , 0 , 16, 0x00, 0x00, 0, { O(Xmm) , O(MmMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm) , 0 , 8 , 0x00, 0x00, 0, { O(Xmm) , O(MmMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm_Q) , 0 , 8 , 0x00, 0x00, 0, { O(Gqd) , O(XmmMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm) , 0 , 4 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm_Q) , 0 , 8 , 0x00, 0x00, 0, { O(Xmm) , O(GqdMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm_Q) , 0 , 4 , 0x00, 0x00, 0, { O(Xmm) , O(GqdMem) , U , U , U }, F(Move) , U }, + { Enc(ExtRm) , 0 , 8 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Move) , U }, + { Enc(X86Op) , 0 , 0 , 0x28, 0x3F, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86IncDec) , 0 , 0 , 0x00, 0x1F, 0, { O(GqdwbMem) , U , U , U , U }, F(Lock) , O_000000(48,U,_,_,_) }, + { Enc(X86Rm_B) , 0 , 0 , 0x00, 0x3F, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Op) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(None) , U }, + { Enc(X86Enter) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(ExtExtract) , 0 , 8 , 0x00, 0x00, 0, { O(GqdMem) , O(Xmm) , U , U , U }, F(Move) , O_660F3A(17,U,_,_,_) }, + { Enc(ExtExtrq) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm)|O(Imm) , O(None)|O(Imm) , U , U }, F(None) , O_660F00(78,0,_,_,_) }, + { Enc(FpuOp) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(Fp) , U }, + { Enc(FpuArith) , 0 , 0 , 0x00, 0x00, 0, { O(FpMem) , O(Fp) , U , U , U }, F(Fp)|F(Mem4_8) , U }, + { Enc(FpuRDef) , 0 , 0 , 0x00, 0x00, 0, { O(Fp) , U , U , U , U }, F(Fp) , U }, + { Enc(X86M) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp) , U }, + { Enc(FpuR) , 0 , 0 , 0x20, 0x00, 0, { O(Fp) , U , U , U , U }, F(Fp) , U }, + { Enc(FpuR) , 0 , 0 , 0x24, 0x00, 0, { O(Fp) , U , U , U , U }, F(Fp) , U }, + { Enc(FpuR) , 0 , 0 , 0x04, 0x00, 0, { O(Fp) , U , U , U , U }, F(Fp) , U }, + { Enc(FpuR) , 0 , 0 , 0x10, 0x00, 0, { O(Fp) , U , U , U , U }, F(Fp) , U }, + { Enc(FpuCom) , 0 , 0 , 0x00, 0x00, 0, { O(Fp)|O(Mem) , O(Fp) , U , U , U }, F(Fp) , U }, + { Enc(FpuR) , 0 , 0 , 0x00, 0x3F, 0, { O(Fp) , U , U , U , U }, F(Fp) , U }, + { Enc(X86Op) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(Fp) , U }, + { Enc(FpuR) , 0 , 0 , 0x00, 0x00, 0, { O(Fp) , U , U , U , U }, F(Fp) , U }, + { Enc(FpuM) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp)|F(Mem2_4) , U }, + { Enc(FpuM) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp)|F(Mem2_4_8) , O_000000(DF,5,_,_,_) }, + { Enc(FpuM) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp)|F(Mem2_4_8) , O_000000(DF,7,_,_,_) }, + { Enc(FpuM) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp)|F(Mem2_4_8) , O_000000(DD,1,_,_,_) }, + { Enc(FpuFldFst) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp)|F(Mem4_8_10) , O_000000(DB,5,_,_,_) }, + { Enc(FpuStsw) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp) , O_00_X(DFE0,U) }, + { Enc(FpuFldFst) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp)|F(Mem4_8) , U }, + { Enc(FpuFldFst) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp)|F(Mem4_8_10) , O_000000(DB,7,_,_,_) }, + { Enc(FpuStsw) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Fp) , O_9B_X(DFE0,U) }, + { Enc(X86Rm_B) , 0 , 0 , 0x00, 0x3F, 0, { 0 , 0 , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Imul) , 0 , 0 , 0x00, 0x3F, 0, { 0 , 0 , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86IncDec) , 0 , 0 , 0x00, 0x1F, 0, { O(GqdwbMem) , U , U , U , U }, F(Lock) , O_000000(40,U,_,_,_) }, + { Enc(ExtInsertq) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(None)|O(Imm) , O(None)|O(Imm) , U }, F(None) , O_F20F00(78,U,_,_,_) }, + { Enc(X86Int) , 0 , 0 , 0x00, 0x80, 0, { U , U , U , U , U }, F(None) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x24, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x20, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x04, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x07, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x03, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x01, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x10, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jcc) , 0 , 0 , 0x02, 0x00, 0, { O(Label) , U , U , U , U }, F(Flow) , U }, + { Enc(X86Jecxz) , 0 , 0 , 0x00, 0x00, 0, { O(Gqdw) , O(Label) , U , U , U }, F(Flow)|F(Special) , U }, + { Enc(X86Jmp) , 0 , 0 , 0x00, 0x00, 0, { O(Label)|O(Imm) , U , U , U , U }, F(Flow) , O_000000(E9,U,_,_,_) }, + { Enc(X86Op) , 0 , 0 , 0x3E, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(ExtRm) , 0 , 16, 0x00, 0x00, 0, { O(Xmm) , O(Mem) , U , U , U }, F(Move) , U }, + { Enc(X86Lea) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , O(Mem) , U , U , U }, F(Move) , U }, + { Enc(ExtFence) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(None) , U }, + { Enc(X86Op) , 0 , 1 , 0x40, 0x00, 0, { U , U , U , U , U }, F(Move)|F(Special) , U }, + { Enc(X86Op) , 0 , 4 , 0x40, 0x00, 0, { U , U , U , U , U }, F(Move)|F(Special) , U }, + { Enc(X86Op) , 0 , 8 , 0x40, 0x00, 0, { U , U , U , U , U }, F(Move)|F(Special) , U }, + { Enc(X86Op_66H) , 0 , 2 , 0x40, 0x00, 0, { U , U , U , U , U }, F(Move)|F(Special) , U }, + { Enc(ExtRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , U , U , U }, F(None)|F(Special) , U }, + { Enc(ExtRm) , 0 , 0 , 0x00, 0x00, 0, { O(Mm) , O(Mm) , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Mov) , 0 , 0 , 0x00, 0x00, 0, { O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U }, F(Move) , U }, + { Enc(X86MovPtr) , 0 , 0 , 0x00, 0x00, 0, { O(Gqdwb) , O(Imm) , U , U , U }, F(Move)|F(Special) , O_000000(A2,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_660F00(29,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_000F00(29,U,_,_,_) }, + { Enc(ExtMovBe) , 0 , 0 , 0x00, 0x00, 0, { O(GqdwMem) , O(GqdwMem) , U , U , U }, F(Move) , O_000F38(F1,U,_,_,_) }, + { Enc(ExtMovD) , 0 , 16, 0x00, 0x00, 0, { O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , U }, F(Move) , O_000F00(7E,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Move) , U }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(Mm) , O(Xmm) , U , U , U }, F(Move) , U }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_660F00(7F,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_F30F00(7F,U,_,_,_) }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , U , U , U }, F(Move) , U }, + { Enc(ExtMov) , 8 , 8 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(None) , O_660F00(17,U,_,_,_) }, + { Enc(ExtMov) , 8 , 8 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(None) , O_000F00(17,U,_,_,_) }, + { Enc(ExtMov) , 8 , 8 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , U , U , U }, F(None) , U }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_660F00(13,U,_,_,_) }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_000F00(13,U,_,_,_) }, + { Enc(ExtMovNoRexW) , 0 , 8 , 0x00, 0x00, 0, { O(Gqd) , O(Xmm) , U , U , U }, F(Move) , U }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(Mem) , O(Xmm) , U , U , U }, F(Move) , O_660F00(E7,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(Xmm) , O(Mem) , U , U , U }, F(Move) , U }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(Mem) , O(Gqd) , U , U , U }, F(Move) , O_000F00(C3,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(Mem) , O(Xmm) , U , U , U }, F(Move) , O_660F00(2B,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(Mem) , O(Xmm) , U , U , U }, F(Move) , O_000F00(2B,U,_,_,_) }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(Mem) , O(Mm) , U , U , U }, F(Move) , O_000F00(E7,U,_,_,_) }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(Mem) , O(Xmm) , U , U , U }, F(Move) , O_F20F00(2B,U,_,_,_) }, + { Enc(ExtMov) , 0 , 4 , 0x00, 0x00, 0, { O(Mem) , O(Xmm) , U , U , U }, F(Move) , O_F30F00(2B,U,_,_,_) }, + { Enc(ExtMovQ) , 0 , 16, 0x00, 0x00, 0, { O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U }, F(Move) , O_000F00(7E,U,_,W,_) }, + { Enc(ExtRm) , 0 , 16, 0x00, 0x00, 0, { O(Xmm) , O(Mm) , U , U , U }, F(Move) , U }, + { Enc(X86Op) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(Move)|F(Special) , U }, + { Enc(X86Op_66H) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(ExtMov) , 0 , 8 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) |F(Z) , O_F20F00(11,U,_,_,_) }, + { Enc(ExtMov) , 0 , 4 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) |F(Z) , O_F30F00(11,U,_,_,_) }, + { Enc(X86MovSxZx) , 0 , 0 , 0x00, 0x00, 0, { O(Gqdw) , O(GwbMem) , U , U , U }, F(Move) , U }, + { Enc(X86MovSxd) , 0 , 0 , 0x00, 0x00, 0, { O(Gq) , O(GdMem) , U , U , U }, F(Move) , U }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_660F00(11,U,_,_,_) }, + { Enc(ExtMov) , 0 , 16, 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Move) , O_000F00(11,U,_,_,_) }, + { Enc(AvxRvm) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , O(Gqd) , O(GqdMem) , U , U }, F(None) , U }, + { Enc(X86Rm_B) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , U , U , U , U }, F(Lock) , U }, + { Enc(X86Rm_B) , 0 , 0 , 0x00, 0x00, 0, { O(GqdwbMem) , U , U , U , U }, F(Lock) , U }, + { Enc(ExtRm_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem) , U , U , U }, F(None) , U }, + { Enc(ExtRmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem) , O(Imm) , U , U }, F(None) , U }, + { Enc(ExtExtract) , 0 , 8 , 0x00, 0x00, 0, { O(Gd)|O(Gb)|O(Mem), O(Xmm) , U , U , U }, F(Move) , O_000F3A(14,U,_,_,_) }, + { Enc(ExtExtract) , 0 , 8 , 0x00, 0x00, 0, { O(GdMem) , O(Xmm) , U , U , U }, F(Move) , O_000F3A(16,U,_,_,_) }, + { Enc(ExtExtract) , 0 , 8 , 0x00, 0x00, 0, { O(GqdMem) , O(Xmm) , U , U , U }, F(Move) , O_000F3A(16,U,_,W,_) }, + { Enc(ExtExtract) , 0 , 8 , 0x00, 0x00, 0, { O(GdMem) , O(MmXmm) , U , U , U }, F(Move) , O_000F3A(15,U,_,_,_) }, + { Enc(3dNow) , 0 , 0 , 0x00, 0x00, 0, { O(Mm) , O(MmMem) , U , U , U }, F(None) , U }, + { Enc(ExtRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(GdMem) , O(Imm) , U , U }, F(None) , U }, + { Enc(ExtRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(GqMem) , O(Imm) , U , U }, F(None) , U }, + { Enc(ExtRmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(GdMem) , O(Imm) , U , U }, F(None) , U }, + { Enc(ExtRm_PQ) , 0 , 8 , 0x00, 0x00, 0, { O(Gqd) , O(MmXmm) , U , U , U }, F(Move) , U }, + { Enc(X86Pop) , 0 , 0 , 0x00, 0x00, 0, { 0 , U , U , U , U }, F(None)|F(Special) , O_000000(58,U,_,_,_) }, + { Enc(X86Op) , 0 , 0 , 0x00, 0xFF, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(ExtPrefetch) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , O(Imm) , U , U , U }, F(None) , U }, + { Enc(ExtRmi) , 0 , 16, 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, F(Move) , U }, + { Enc(ExtRmi_P) , 0 , 8 , 0x00, 0x00, 0, { O(Mm) , O(MmMem) , O(Imm) , U , U }, F(Move) , U }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(72,6,_,_,_) }, + { Enc(ExtRmRi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Imm) , U , U , U }, F(None) , O_660F00(73,7,_,_,_) }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(73,6,_,_,_) }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(71,6,_,_,_) }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(72,4,_,_,_) }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(71,4,_,_,_) }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(72,2,_,_,_) }, + { Enc(ExtRmRi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Imm) , U , U , U }, F(None) , O_660F00(73,3,_,_,_) }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(73,2,_,_,_) }, + { Enc(ExtRmRi_P) , 0 , 0 , 0x00, 0x00, 0, { O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U }, F(None) , O_000F00(71,2,_,_,_) }, + { Enc(X86Push) , 0 , 0 , 0x00, 0x00, 0, { 0 , U , U , U , U }, F(None)|F(Special) , O_000000(50,U,_,_,_) }, + { Enc(X86Op) , 0 , 0 , 0xFF, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Rot) , 0 , 0 , 0x20, 0x21, 0, { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Rm) , 0 , 8 , 0x00, 0x00, 0, { O(Gqd) , U , U , U , U }, F(Move) , U }, + { Enc(X86Rm) , 0 , 8 , 0x00, 0x3F, 0, { O(Gqdw) , U , U , U , U }, F(Move) , U }, + { Enc(X86Rep) , 0 , 0 , 0x40, 0x00, 0, { O(Mem) , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Rep) , 0 , 0 , 0x40, 0x00, 0, { O(Mem) , O(Mem) , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Rep) , 0 , 0 , 0x40, 0x3F, 0, { O(Mem) , O(Mem) , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Ret) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Rot) , 0 , 0 , 0x00, 0x21, 0, { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, F(None)|F(Special) , U }, + { Enc(AvxRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , O(GqdMem) , O(Imm) , U , U }, F(None) , U }, + { Enc(ExtRmi) , 0 , 8 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, F(Move) , U }, + { Enc(ExtRmi) , 0 , 4 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, F(Move) , U }, + { Enc(X86Op) , 0 , 0 , 0x00, 0x3E, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Rot) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U }, F(None)|F(Special) , U }, + { Enc(AvxRmv) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , O(GqdMem) , O(Gqd) , U , U }, F(None) , U }, + { Enc(X86Set) , 0 , 1 , 0x24, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Set) , 0 , 1 , 0x20, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Set) , 0 , 1 , 0x04, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Set) , 0 , 1 , 0x07, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Set) , 0 , 1 , 0x03, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Set) , 0 , 1 , 0x01, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Set) , 0 , 1 , 0x10, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Set) , 0 , 1 , 0x02, 0x00, 0, { O(GbMem) , U , U , U , U }, F(Move) , U }, + { Enc(X86Shlrd) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , O(Gb) , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Shlrd) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , O(Gqdwb) , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Op) , 0 , 0 , 0x40, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Op_66H) , 0 , 0 , 0x40, 0x00, 0, { U , U , U , U , U }, F(None)|F(Special) , U }, + { Enc(X86Test) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , U }, F(Test) , O_000000(F6,U,_,_,_) }, + { Enc(X86RegRm) , 0 , 0 , 0x00, 0x3F, 0, { O(Gqdw) , O(GqdwMem) , U , U , U }, F(Move) , U }, + { Enc(AvxRvm_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Xy) , O(XyMem) , U , U }, F(Avx) , U }, + { Enc(AvxRvm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(XmmMem) , U , U }, F(Avx) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxRvmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRvmr_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Xy) , O(XyMem) , O(Xy) , U }, F(Avx) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x00, 0, { O(Ymm) , O(Mem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x00, 0, { O(Ymm) , O(XmmMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XmmMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRm_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XmmMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRm_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XyMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxMri_P) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(Xy) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , O(XmmMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRvm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(GqdMem) , U , U }, F(Avx) , U }, + { Enc(AvxRm_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XyMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxMri) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(Ymm) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxMri) , 0 , 0 , 0x00, 0x00, 0, { O(GqdMem) , O(Xmm) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(Fma4_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U }, F(Avx) , U }, + { Enc(Fma4) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, F(Avx) , U }, + { Enc(XopRm_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , U , U , U }, F(Avx) , U }, + { Enc(XopRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxGather) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Mem) , O(Xy) , U , U }, F(Avx) , U }, + { Enc(AvxGatherEx) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Mem) , O(Xmm) , U , U }, F(Avx) , U }, + { Enc(AvxRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRm_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Mem) , U , U , U }, F(Avx) , U }, + { Enc(AvxM) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(Avx) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , U , U , U }, F(Avx) , U }, + { Enc(AvxRvmMvr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(Xy) , O(XyMem) , U , U }, F(Avx) , O_660F38(2F,U,_,_,_) }, + { Enc(AvxRvmMvr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(Xy) , O(XyMem) , U , U }, F(Avx) , O_660F38(2E,U,_,_,_) }, + { Enc(AvxRmMr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(XyMem) , U , U , U }, F(Avx) , O_660F00(29,U,_,_,_) }, + { Enc(AvxRmMr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(XyMem) , U , U , U }, F(Avx) , O_000F00(29,U,_,_,_) }, + { Enc(AvxRmMr) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , U , U , U }, F(Avx) , O_660F00(7E,U,_,_,_) }, + { Enc(AvxRmMr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(XyMem) , U , U , U }, F(Avx) , O_660F00(7F,U,_,_,_) }, + { Enc(AvxRmMr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(XyMem) , U , U , U }, F(Avx) , O_F30F00(7F,U,_,_,_) }, + { Enc(AvxRvm) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(Xmm) , U , U }, F(Avx) , U }, + { Enc(AvxRvmMr) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, F(Avx) , O_660F00(17,U,_,_,_) }, + { Enc(AvxRvmMr) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, F(Avx) , O_000F00(17,U,_,_,_) }, + { Enc(AvxRvmMr) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, F(Avx) , O_660F00(13,U,_,_,_) }, + { Enc(AvxRvmMr) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(Xmm) , O(Mem) , U , U }, F(Avx) , O_000F00(13,U,_,_,_) }, + { Enc(AvxRm_P) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , O(Xy) , U , U , U }, F(Avx) , U }, + { Enc(AvxMr) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , O(Xy) , U , U , U }, F(Avx) , U }, + { Enc(AvxMr_P) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , O(Xy) , U , U , U }, F(Avx) , U }, + { Enc(AvxMovSsSd) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(XmmMem) , O(Xmm) , U , U }, F(Avx) , O_F20F00(11,U,_,_,_) }, + { Enc(AvxMovSsSd) , 0 , 0 , 0x00, 0x00, 0, { O(XmmMem) , O(Xmm) , O(Xmm) , U , U }, F(Avx) , O_F30F00(11,U,_,_,_) }, + { Enc(AvxRmMr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(XyMem) , U , U , U }, F(Avx) , O_660F00(11,U,_,_,_) }, + { Enc(AvxRmMr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(XyMem) , U , U , U }, F(Avx) , O_000F00(11,U,_,_,_) }, + { Enc(AvxRvmr) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Xy) , O(XyMem) , O(Xy) , U }, F(Avx) , U }, + { Enc(XopRvrmRvmr_P), 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U }, F(Avx) , U }, + { Enc(XopRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRvm) , 0 , 0 , 0x00, 0x00, 0, { O(Ymm) , O(Ymm) , O(YmmMem) , U , U }, F(Avx) , U }, + { Enc(AvxRvrmRvmr_P), 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U }, F(Avx) , U }, + { Enc(AvxRvmRmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F3A(05,U,_,_,_) }, + { Enc(AvxRvmRmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F3A(04,U,_,_,_) }, + { Enc(AvxRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Ymm) , O(YmmMem) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxMri) , 0 , 0 , 0x00, 0x00, 0, { O(GqdwbMem) , O(Xmm) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxMri) , 0 , 0 , 0x00, 0x00, 0, { O(GqMem) , O(Xmm) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxMri) , 0 , 0 , 0x00, 0x00, 0, { O(GqdwMem) , O(Xmm) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(AvxRvmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , U }, F(Avx) , U }, + { Enc(XopRvmr) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U }, F(Avx) , U }, + { Enc(AvxRvmMvr_P) , 0 , 0 , 0x00, 0x00, 0, { O(XyMem) , O(Xy) , O(XyMem) , U , U }, F(Avx) , O_660F38(8E,U,_,_,_) }, + { Enc(XopRvrmRvmr) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U }, F(Avx) , U }, + { Enc(XopRvmRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, F(Avx) , O_00_M08(C0,U,_,_,_) }, + { Enc(XopRvmRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, F(Avx) , O_00_M08(C2,U,_,_,_) }, + { Enc(XopRvmRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, F(Avx) , O_00_M08(C3,U,_,_,_) }, + { Enc(XopRvmRmi) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U }, F(Avx) , O_00_M08(C1,U,_,_,_) }, + { Enc(XopRvmRmv) , 0 , 0 , 0x00, 0x00, 0, { O(Xmm) , O(XmmMem) , O(XmmMem) , U , U }, F(Avx) , U }, + { Enc(AvxRmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(72,6,_,_,_) }, + { Enc(AvxVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(Imm) , U , U }, F(Avx) , U }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(73,6,_,_,_) }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(71,6,_,_,_) }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(72,4,_,_,_) }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(71,4,_,_,_) }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(72,2,_,_,_) }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(73,2,_,_,_) }, + { Enc(AvxRvmVmi_P) , 0 , 0 , 0x00, 0x00, 0, { O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U }, F(Avx) , O_660F00(71,2,_,_,_) }, + { Enc(AvxRm_P) , 0 , 0 , 0x00, 0x3F, 0, { O(Xy) , O(XyMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxRm_P) , 0 , 0 , 0x00, 0x3F, 0, { O(Xy) , O(XyMem) , U , U , U }, F(Test) , U }, + { Enc(AvxRm) , 0 , 0 , 0x00, 0x3F, 0, { O(Xmm) , O(XmmMem) , U , U , U }, F(Avx) , U }, + { Enc(AvxOp) , 0 , 0 , 0x00, 0x00, 0, { U , U , U , U , U }, F(Avx) , U }, + { Enc(X86Rm) , 0 , 0 , 0x00, 0x00, 0, { O(Gqd) , U , U , U , U }, F(None) , U }, + { Enc(X86Xadd) , 0 , 0 , 0x00, 0x3F, 0, { O(GqdwbMem) , O(Gqdwb) , U , U , U }, F(Xchg)|F(Lock) , U }, + { Enc(X86Xchg) , 0 , 0 , 0x00, 0x00, 0, { O(GqdwbMem) , O(Gqdwb) , U , U , U }, F(Xchg)|F(Lock) , U }, + { Enc(X86M) , 0 , 0 , 0x00, 0x00, 0, { O(Mem) , U , U , U , U }, F(None)|F(Special) , U } }; // Automatically generated, do not edit. -enum kX86InstData_ExtendedIndex { +enum X86InstData_ExtendedIndex { kInstIdNone_ExtendedIndex = 0, kX86InstIdAdc_ExtendedIndex = 1, kX86InstIdAdd_ExtendedIndex = 2, @@ -2556,2075 +2654,2100 @@ enum kX86InstData_ExtendedIndex { kX86InstIdCall_ExtendedIndex = 15, kX86InstIdCbw_ExtendedIndex = 16, kX86InstIdCdq_ExtendedIndex = 16, - kX86InstIdCdqe_ExtendedIndex = 17, - kX86InstIdClc_ExtendedIndex = 18, - kX86InstIdCld_ExtendedIndex = 19, - kX86InstIdClflush_ExtendedIndex = 20, - kX86InstIdCmc_ExtendedIndex = 21, - kX86InstIdCmova_ExtendedIndex = 22, - kX86InstIdCmovae_ExtendedIndex = 23, - kX86InstIdCmovb_ExtendedIndex = 23, - kX86InstIdCmovbe_ExtendedIndex = 22, - kX86InstIdCmovc_ExtendedIndex = 23, - kX86InstIdCmove_ExtendedIndex = 24, - kX86InstIdCmovg_ExtendedIndex = 25, - kX86InstIdCmovge_ExtendedIndex = 26, - kX86InstIdCmovl_ExtendedIndex = 26, - kX86InstIdCmovle_ExtendedIndex = 25, - kX86InstIdCmovna_ExtendedIndex = 22, - kX86InstIdCmovnae_ExtendedIndex = 23, - kX86InstIdCmovnb_ExtendedIndex = 23, - kX86InstIdCmovnbe_ExtendedIndex = 22, - kX86InstIdCmovnc_ExtendedIndex = 23, - kX86InstIdCmovne_ExtendedIndex = 24, - kX86InstIdCmovng_ExtendedIndex = 25, - kX86InstIdCmovnge_ExtendedIndex = 26, - kX86InstIdCmovnl_ExtendedIndex = 26, - kX86InstIdCmovnle_ExtendedIndex = 25, - kX86InstIdCmovno_ExtendedIndex = 27, - kX86InstIdCmovnp_ExtendedIndex = 28, - kX86InstIdCmovns_ExtendedIndex = 29, - kX86InstIdCmovnz_ExtendedIndex = 24, - kX86InstIdCmovo_ExtendedIndex = 27, - kX86InstIdCmovp_ExtendedIndex = 28, - kX86InstIdCmovpe_ExtendedIndex = 28, - kX86InstIdCmovpo_ExtendedIndex = 28, - kX86InstIdCmovs_ExtendedIndex = 29, - kX86InstIdCmovz_ExtendedIndex = 24, - kX86InstIdCmp_ExtendedIndex = 30, + kX86InstIdCdqe_ExtendedIndex = 16, + kX86InstIdClc_ExtendedIndex = 17, + kX86InstIdCld_ExtendedIndex = 18, + kX86InstIdClflush_ExtendedIndex = 19, + kX86InstIdCmc_ExtendedIndex = 20, + kX86InstIdCmova_ExtendedIndex = 21, + kX86InstIdCmovae_ExtendedIndex = 22, + kX86InstIdCmovb_ExtendedIndex = 22, + kX86InstIdCmovbe_ExtendedIndex = 21, + kX86InstIdCmovc_ExtendedIndex = 22, + kX86InstIdCmove_ExtendedIndex = 23, + kX86InstIdCmovg_ExtendedIndex = 24, + kX86InstIdCmovge_ExtendedIndex = 25, + kX86InstIdCmovl_ExtendedIndex = 25, + kX86InstIdCmovle_ExtendedIndex = 24, + kX86InstIdCmovna_ExtendedIndex = 21, + kX86InstIdCmovnae_ExtendedIndex = 22, + kX86InstIdCmovnb_ExtendedIndex = 22, + kX86InstIdCmovnbe_ExtendedIndex = 21, + kX86InstIdCmovnc_ExtendedIndex = 22, + kX86InstIdCmovne_ExtendedIndex = 23, + kX86InstIdCmovng_ExtendedIndex = 24, + kX86InstIdCmovnge_ExtendedIndex = 25, + kX86InstIdCmovnl_ExtendedIndex = 25, + kX86InstIdCmovnle_ExtendedIndex = 24, + kX86InstIdCmovno_ExtendedIndex = 26, + kX86InstIdCmovnp_ExtendedIndex = 27, + kX86InstIdCmovns_ExtendedIndex = 28, + kX86InstIdCmovnz_ExtendedIndex = 23, + kX86InstIdCmovo_ExtendedIndex = 26, + kX86InstIdCmovp_ExtendedIndex = 27, + kX86InstIdCmovpe_ExtendedIndex = 27, + kX86InstIdCmovpo_ExtendedIndex = 27, + kX86InstIdCmovs_ExtendedIndex = 28, + kX86InstIdCmovz_ExtendedIndex = 23, + kX86InstIdCmp_ExtendedIndex = 29, kX86InstIdCmppd_ExtendedIndex = 4, kX86InstIdCmpps_ExtendedIndex = 4, - kX86InstIdCmpsB_ExtendedIndex = 31, - kX86InstIdCmpsD_ExtendedIndex = 31, - kX86InstIdCmpsQ_ExtendedIndex = 32, - kX86InstIdCmpsW_ExtendedIndex = 33, + kX86InstIdCmpsB_ExtendedIndex = 30, + kX86InstIdCmpsD_ExtendedIndex = 30, + kX86InstIdCmpsQ_ExtendedIndex = 30, + kX86InstIdCmpsW_ExtendedIndex = 31, kX86InstIdCmpsd_ExtendedIndex = 4, kX86InstIdCmpss_ExtendedIndex = 4, - kX86InstIdCmpxchg_ExtendedIndex = 34, - kX86InstIdCmpxchg16b_ExtendedIndex = 35, - kX86InstIdCmpxchg8b_ExtendedIndex = 36, - kX86InstIdComisd_ExtendedIndex = 37, - kX86InstIdComiss_ExtendedIndex = 37, + kX86InstIdCmpxchg_ExtendedIndex = 32, + kX86InstIdCmpxchg16b_ExtendedIndex = 33, + kX86InstIdCmpxchg8b_ExtendedIndex = 33, + kX86InstIdComisd_ExtendedIndex = 34, + kX86InstIdComiss_ExtendedIndex = 34, kX86InstIdCpuid_ExtendedIndex = 16, - kX86InstIdCqo_ExtendedIndex = 17, - kX86InstIdCrc32_ExtendedIndex = 38, - kX86InstIdCvtdq2pd_ExtendedIndex = 39, - kX86InstIdCvtdq2ps_ExtendedIndex = 39, - kX86InstIdCvtpd2dq_ExtendedIndex = 39, - kX86InstIdCvtpd2pi_ExtendedIndex = 40, - kX86InstIdCvtpd2ps_ExtendedIndex = 39, - kX86InstIdCvtpi2pd_ExtendedIndex = 41, - kX86InstIdCvtpi2ps_ExtendedIndex = 42, - kX86InstIdCvtps2dq_ExtendedIndex = 39, - kX86InstIdCvtps2pd_ExtendedIndex = 39, - kX86InstIdCvtps2pi_ExtendedIndex = 40, - kX86InstIdCvtsd2si_ExtendedIndex = 43, - kX86InstIdCvtsd2ss_ExtendedIndex = 44, - kX86InstIdCvtsi2sd_ExtendedIndex = 45, - kX86InstIdCvtsi2ss_ExtendedIndex = 46, - kX86InstIdCvtss2sd_ExtendedIndex = 47, - kX86InstIdCvtss2si_ExtendedIndex = 43, - kX86InstIdCvttpd2dq_ExtendedIndex = 39, - kX86InstIdCvttpd2pi_ExtendedIndex = 40, - kX86InstIdCvttps2dq_ExtendedIndex = 39, - kX86InstIdCvttps2pi_ExtendedIndex = 40, - kX86InstIdCvttsd2si_ExtendedIndex = 43, - kX86InstIdCvttss2si_ExtendedIndex = 43, + kX86InstIdCqo_ExtendedIndex = 16, + kX86InstIdCrc32_ExtendedIndex = 35, + kX86InstIdCvtdq2pd_ExtendedIndex = 36, + kX86InstIdCvtdq2ps_ExtendedIndex = 36, + kX86InstIdCvtpd2dq_ExtendedIndex = 36, + kX86InstIdCvtpd2pi_ExtendedIndex = 37, + kX86InstIdCvtpd2ps_ExtendedIndex = 36, + kX86InstIdCvtpi2pd_ExtendedIndex = 38, + kX86InstIdCvtpi2ps_ExtendedIndex = 39, + kX86InstIdCvtps2dq_ExtendedIndex = 36, + kX86InstIdCvtps2pd_ExtendedIndex = 36, + kX86InstIdCvtps2pi_ExtendedIndex = 37, + kX86InstIdCvtsd2si_ExtendedIndex = 40, + kX86InstIdCvtsd2ss_ExtendedIndex = 41, + kX86InstIdCvtsi2sd_ExtendedIndex = 42, + kX86InstIdCvtsi2ss_ExtendedIndex = 43, + kX86InstIdCvtss2sd_ExtendedIndex = 44, + kX86InstIdCvtss2si_ExtendedIndex = 40, + kX86InstIdCvttpd2dq_ExtendedIndex = 36, + kX86InstIdCvttpd2pi_ExtendedIndex = 37, + kX86InstIdCvttps2dq_ExtendedIndex = 36, + kX86InstIdCvttps2pi_ExtendedIndex = 37, + kX86InstIdCvttsd2si_ExtendedIndex = 40, + kX86InstIdCvttss2si_ExtendedIndex = 40, kX86InstIdCwd_ExtendedIndex = 16, kX86InstIdCwde_ExtendedIndex = 16, - kX86InstIdDaa_ExtendedIndex = 48, - kX86InstIdDas_ExtendedIndex = 48, - kX86InstIdDec_ExtendedIndex = 49, - kX86InstIdDiv_ExtendedIndex = 50, + kX86InstIdDaa_ExtendedIndex = 45, + kX86InstIdDas_ExtendedIndex = 45, + kX86InstIdDec_ExtendedIndex = 46, + kX86InstIdDiv_ExtendedIndex = 47, kX86InstIdDivpd_ExtendedIndex = 3, kX86InstIdDivps_ExtendedIndex = 3, kX86InstIdDivsd_ExtendedIndex = 3, kX86InstIdDivss_ExtendedIndex = 3, kX86InstIdDppd_ExtendedIndex = 4, kX86InstIdDpps_ExtendedIndex = 4, - kX86InstIdEmms_ExtendedIndex = 51, - kX86InstIdEnter_ExtendedIndex = 52, - kX86InstIdExtractps_ExtendedIndex = 53, - kX86InstIdF2xm1_ExtendedIndex = 54, - kX86InstIdFabs_ExtendedIndex = 54, - kX86InstIdFadd_ExtendedIndex = 55, - kX86InstIdFaddp_ExtendedIndex = 56, - kX86InstIdFbld_ExtendedIndex = 57, - kX86InstIdFbstp_ExtendedIndex = 57, - kX86InstIdFchs_ExtendedIndex = 54, - kX86InstIdFclex_ExtendedIndex = 54, - kX86InstIdFcmovb_ExtendedIndex = 58, - kX86InstIdFcmovbe_ExtendedIndex = 59, - kX86InstIdFcmove_ExtendedIndex = 60, - kX86InstIdFcmovnb_ExtendedIndex = 58, - kX86InstIdFcmovnbe_ExtendedIndex = 59, - kX86InstIdFcmovne_ExtendedIndex = 60, - kX86InstIdFcmovnu_ExtendedIndex = 61, - kX86InstIdFcmovu_ExtendedIndex = 61, - kX86InstIdFcom_ExtendedIndex = 62, - kX86InstIdFcomi_ExtendedIndex = 63, - kX86InstIdFcomip_ExtendedIndex = 63, - kX86InstIdFcomp_ExtendedIndex = 62, - kX86InstIdFcompp_ExtendedIndex = 54, - kX86InstIdFcos_ExtendedIndex = 54, - kX86InstIdFdecstp_ExtendedIndex = 54, - kX86InstIdFdiv_ExtendedIndex = 55, - kX86InstIdFdivp_ExtendedIndex = 56, - kX86InstIdFdivr_ExtendedIndex = 55, - kX86InstIdFdivrp_ExtendedIndex = 56, - kX86InstIdFemms_ExtendedIndex = 64, - kX86InstIdFfree_ExtendedIndex = 65, - kX86InstIdFiadd_ExtendedIndex = 66, - kX86InstIdFicom_ExtendedIndex = 66, - kX86InstIdFicomp_ExtendedIndex = 66, - kX86InstIdFidiv_ExtendedIndex = 66, - kX86InstIdFidivr_ExtendedIndex = 66, - kX86InstIdFild_ExtendedIndex = 67, - kX86InstIdFimul_ExtendedIndex = 66, - kX86InstIdFincstp_ExtendedIndex = 54, - kX86InstIdFinit_ExtendedIndex = 54, - kX86InstIdFist_ExtendedIndex = 66, - kX86InstIdFistp_ExtendedIndex = 68, - kX86InstIdFisttp_ExtendedIndex = 69, - kX86InstIdFisub_ExtendedIndex = 66, - kX86InstIdFisubr_ExtendedIndex = 66, - kX86InstIdFld_ExtendedIndex = 70, - kX86InstIdFld1_ExtendedIndex = 54, - kX86InstIdFldcw_ExtendedIndex = 57, - kX86InstIdFldenv_ExtendedIndex = 57, - kX86InstIdFldl2e_ExtendedIndex = 54, - kX86InstIdFldl2t_ExtendedIndex = 54, - kX86InstIdFldlg2_ExtendedIndex = 54, - kX86InstIdFldln2_ExtendedIndex = 54, - kX86InstIdFldpi_ExtendedIndex = 54, - kX86InstIdFldz_ExtendedIndex = 54, - kX86InstIdFmul_ExtendedIndex = 55, - kX86InstIdFmulp_ExtendedIndex = 56, - kX86InstIdFnclex_ExtendedIndex = 54, - kX86InstIdFninit_ExtendedIndex = 54, - kX86InstIdFnop_ExtendedIndex = 54, - kX86InstIdFnsave_ExtendedIndex = 57, - kX86InstIdFnstcw_ExtendedIndex = 57, - kX86InstIdFnstenv_ExtendedIndex = 57, - kX86InstIdFnstsw_ExtendedIndex = 71, - kX86InstIdFpatan_ExtendedIndex = 54, - kX86InstIdFprem_ExtendedIndex = 54, - kX86InstIdFprem1_ExtendedIndex = 54, - kX86InstIdFptan_ExtendedIndex = 54, - kX86InstIdFrndint_ExtendedIndex = 54, - kX86InstIdFrstor_ExtendedIndex = 57, - kX86InstIdFsave_ExtendedIndex = 57, - kX86InstIdFscale_ExtendedIndex = 54, - kX86InstIdFsin_ExtendedIndex = 54, - kX86InstIdFsincos_ExtendedIndex = 54, - kX86InstIdFsqrt_ExtendedIndex = 54, - kX86InstIdFst_ExtendedIndex = 72, - kX86InstIdFstcw_ExtendedIndex = 57, - kX86InstIdFstenv_ExtendedIndex = 57, - kX86InstIdFstp_ExtendedIndex = 73, - kX86InstIdFstsw_ExtendedIndex = 74, - kX86InstIdFsub_ExtendedIndex = 55, - kX86InstIdFsubp_ExtendedIndex = 56, - kX86InstIdFsubr_ExtendedIndex = 55, - kX86InstIdFsubrp_ExtendedIndex = 56, - kX86InstIdFtst_ExtendedIndex = 54, - kX86InstIdFucom_ExtendedIndex = 56, - kX86InstIdFucomi_ExtendedIndex = 63, - kX86InstIdFucomip_ExtendedIndex = 63, - kX86InstIdFucomp_ExtendedIndex = 56, - kX86InstIdFucompp_ExtendedIndex = 54, - kX86InstIdFwait_ExtendedIndex = 64, - kX86InstIdFxam_ExtendedIndex = 54, - kX86InstIdFxch_ExtendedIndex = 65, - kX86InstIdFxrstor_ExtendedIndex = 57, - kX86InstIdFxsave_ExtendedIndex = 57, - kX86InstIdFxtract_ExtendedIndex = 54, - kX86InstIdFyl2x_ExtendedIndex = 54, - kX86InstIdFyl2xp1_ExtendedIndex = 54, + kX86InstIdEmms_ExtendedIndex = 48, + kX86InstIdEnter_ExtendedIndex = 49, + kX86InstIdExtractps_ExtendedIndex = 50, + kX86InstIdExtrq_ExtendedIndex = 51, + kX86InstIdF2xm1_ExtendedIndex = 52, + kX86InstIdFabs_ExtendedIndex = 52, + kX86InstIdFadd_ExtendedIndex = 53, + kX86InstIdFaddp_ExtendedIndex = 54, + kX86InstIdFbld_ExtendedIndex = 55, + kX86InstIdFbstp_ExtendedIndex = 55, + kX86InstIdFchs_ExtendedIndex = 52, + kX86InstIdFclex_ExtendedIndex = 52, + kX86InstIdFcmovb_ExtendedIndex = 56, + kX86InstIdFcmovbe_ExtendedIndex = 57, + kX86InstIdFcmove_ExtendedIndex = 58, + kX86InstIdFcmovnb_ExtendedIndex = 56, + kX86InstIdFcmovnbe_ExtendedIndex = 57, + kX86InstIdFcmovne_ExtendedIndex = 58, + kX86InstIdFcmovnu_ExtendedIndex = 59, + kX86InstIdFcmovu_ExtendedIndex = 59, + kX86InstIdFcom_ExtendedIndex = 60, + kX86InstIdFcomi_ExtendedIndex = 61, + kX86InstIdFcomip_ExtendedIndex = 61, + kX86InstIdFcomp_ExtendedIndex = 60, + kX86InstIdFcompp_ExtendedIndex = 52, + kX86InstIdFcos_ExtendedIndex = 52, + kX86InstIdFdecstp_ExtendedIndex = 52, + kX86InstIdFdiv_ExtendedIndex = 53, + kX86InstIdFdivp_ExtendedIndex = 54, + kX86InstIdFdivr_ExtendedIndex = 53, + kX86InstIdFdivrp_ExtendedIndex = 54, + kX86InstIdFemms_ExtendedIndex = 62, + kX86InstIdFfree_ExtendedIndex = 63, + kX86InstIdFiadd_ExtendedIndex = 64, + kX86InstIdFicom_ExtendedIndex = 64, + kX86InstIdFicomp_ExtendedIndex = 64, + kX86InstIdFidiv_ExtendedIndex = 64, + kX86InstIdFidivr_ExtendedIndex = 64, + kX86InstIdFild_ExtendedIndex = 65, + kX86InstIdFimul_ExtendedIndex = 64, + kX86InstIdFincstp_ExtendedIndex = 52, + kX86InstIdFinit_ExtendedIndex = 52, + kX86InstIdFist_ExtendedIndex = 64, + kX86InstIdFistp_ExtendedIndex = 66, + kX86InstIdFisttp_ExtendedIndex = 67, + kX86InstIdFisub_ExtendedIndex = 64, + kX86InstIdFisubr_ExtendedIndex = 64, + kX86InstIdFld_ExtendedIndex = 68, + kX86InstIdFld1_ExtendedIndex = 52, + kX86InstIdFldcw_ExtendedIndex = 55, + kX86InstIdFldenv_ExtendedIndex = 55, + kX86InstIdFldl2e_ExtendedIndex = 52, + kX86InstIdFldl2t_ExtendedIndex = 52, + kX86InstIdFldlg2_ExtendedIndex = 52, + kX86InstIdFldln2_ExtendedIndex = 52, + kX86InstIdFldpi_ExtendedIndex = 52, + kX86InstIdFldz_ExtendedIndex = 52, + kX86InstIdFmul_ExtendedIndex = 53, + kX86InstIdFmulp_ExtendedIndex = 54, + kX86InstIdFnclex_ExtendedIndex = 52, + kX86InstIdFninit_ExtendedIndex = 52, + kX86InstIdFnop_ExtendedIndex = 52, + kX86InstIdFnsave_ExtendedIndex = 55, + kX86InstIdFnstcw_ExtendedIndex = 55, + kX86InstIdFnstenv_ExtendedIndex = 55, + kX86InstIdFnstsw_ExtendedIndex = 69, + kX86InstIdFpatan_ExtendedIndex = 52, + kX86InstIdFprem_ExtendedIndex = 52, + kX86InstIdFprem1_ExtendedIndex = 52, + kX86InstIdFptan_ExtendedIndex = 52, + kX86InstIdFrndint_ExtendedIndex = 52, + kX86InstIdFrstor_ExtendedIndex = 55, + kX86InstIdFsave_ExtendedIndex = 55, + kX86InstIdFscale_ExtendedIndex = 52, + kX86InstIdFsin_ExtendedIndex = 52, + kX86InstIdFsincos_ExtendedIndex = 52, + kX86InstIdFsqrt_ExtendedIndex = 52, + kX86InstIdFst_ExtendedIndex = 70, + kX86InstIdFstcw_ExtendedIndex = 55, + kX86InstIdFstenv_ExtendedIndex = 55, + kX86InstIdFstp_ExtendedIndex = 71, + kX86InstIdFstsw_ExtendedIndex = 72, + kX86InstIdFsub_ExtendedIndex = 53, + kX86InstIdFsubp_ExtendedIndex = 54, + kX86InstIdFsubr_ExtendedIndex = 53, + kX86InstIdFsubrp_ExtendedIndex = 54, + kX86InstIdFtst_ExtendedIndex = 52, + kX86InstIdFucom_ExtendedIndex = 54, + kX86InstIdFucomi_ExtendedIndex = 61, + kX86InstIdFucomip_ExtendedIndex = 61, + kX86InstIdFucomp_ExtendedIndex = 54, + kX86InstIdFucompp_ExtendedIndex = 52, + kX86InstIdFwait_ExtendedIndex = 62, + kX86InstIdFxam_ExtendedIndex = 52, + kX86InstIdFxch_ExtendedIndex = 63, + kX86InstIdFxrstor_ExtendedIndex = 55, + kX86InstIdFxsave_ExtendedIndex = 55, + kX86InstIdFxtract_ExtendedIndex = 52, + kX86InstIdFyl2x_ExtendedIndex = 52, + kX86InstIdFyl2xp1_ExtendedIndex = 52, kX86InstIdHaddpd_ExtendedIndex = 3, kX86InstIdHaddps_ExtendedIndex = 3, kX86InstIdHsubpd_ExtendedIndex = 3, kX86InstIdHsubps_ExtendedIndex = 3, - kX86InstIdIdiv_ExtendedIndex = 75, - kX86InstIdImul_ExtendedIndex = 76, - kX86InstIdInc_ExtendedIndex = 77, + kX86InstIdIdiv_ExtendedIndex = 73, + kX86InstIdImul_ExtendedIndex = 74, + kX86InstIdInc_ExtendedIndex = 75, kX86InstIdInsertps_ExtendedIndex = 4, - kX86InstIdInt_ExtendedIndex = 78, - kX86InstIdJa_ExtendedIndex = 79, - kX86InstIdJae_ExtendedIndex = 80, - kX86InstIdJb_ExtendedIndex = 80, - kX86InstIdJbe_ExtendedIndex = 79, - kX86InstIdJc_ExtendedIndex = 80, - kX86InstIdJe_ExtendedIndex = 81, - kX86InstIdJg_ExtendedIndex = 82, - kX86InstIdJge_ExtendedIndex = 83, - kX86InstIdJl_ExtendedIndex = 83, - kX86InstIdJle_ExtendedIndex = 82, - kX86InstIdJna_ExtendedIndex = 79, - kX86InstIdJnae_ExtendedIndex = 80, - kX86InstIdJnb_ExtendedIndex = 80, - kX86InstIdJnbe_ExtendedIndex = 79, - kX86InstIdJnc_ExtendedIndex = 80, - kX86InstIdJne_ExtendedIndex = 81, - kX86InstIdJng_ExtendedIndex = 82, - kX86InstIdJnge_ExtendedIndex = 83, - kX86InstIdJnl_ExtendedIndex = 83, - kX86InstIdJnle_ExtendedIndex = 82, - kX86InstIdJno_ExtendedIndex = 84, - kX86InstIdJnp_ExtendedIndex = 85, - kX86InstIdJns_ExtendedIndex = 86, - kX86InstIdJnz_ExtendedIndex = 81, - kX86InstIdJo_ExtendedIndex = 84, - kX86InstIdJp_ExtendedIndex = 85, - kX86InstIdJpe_ExtendedIndex = 85, - kX86InstIdJpo_ExtendedIndex = 85, - kX86InstIdJs_ExtendedIndex = 86, - kX86InstIdJz_ExtendedIndex = 81, - kX86InstIdJecxz_ExtendedIndex = 87, - kX86InstIdJmp_ExtendedIndex = 88, - kX86InstIdLahf_ExtendedIndex = 89, - kX86InstIdLddqu_ExtendedIndex = 90, - kX86InstIdLdmxcsr_ExtendedIndex = 20, - kX86InstIdLea_ExtendedIndex = 91, + kX86InstIdInsertq_ExtendedIndex = 76, + kX86InstIdInt_ExtendedIndex = 77, + kX86InstIdJa_ExtendedIndex = 78, + kX86InstIdJae_ExtendedIndex = 79, + kX86InstIdJb_ExtendedIndex = 79, + kX86InstIdJbe_ExtendedIndex = 78, + kX86InstIdJc_ExtendedIndex = 79, + kX86InstIdJe_ExtendedIndex = 80, + kX86InstIdJg_ExtendedIndex = 81, + kX86InstIdJge_ExtendedIndex = 82, + kX86InstIdJl_ExtendedIndex = 82, + kX86InstIdJle_ExtendedIndex = 81, + kX86InstIdJna_ExtendedIndex = 78, + kX86InstIdJnae_ExtendedIndex = 79, + kX86InstIdJnb_ExtendedIndex = 79, + kX86InstIdJnbe_ExtendedIndex = 78, + kX86InstIdJnc_ExtendedIndex = 79, + kX86InstIdJne_ExtendedIndex = 80, + kX86InstIdJng_ExtendedIndex = 81, + kX86InstIdJnge_ExtendedIndex = 82, + kX86InstIdJnl_ExtendedIndex = 82, + kX86InstIdJnle_ExtendedIndex = 81, + kX86InstIdJno_ExtendedIndex = 83, + kX86InstIdJnp_ExtendedIndex = 84, + kX86InstIdJns_ExtendedIndex = 85, + kX86InstIdJnz_ExtendedIndex = 80, + kX86InstIdJo_ExtendedIndex = 83, + kX86InstIdJp_ExtendedIndex = 84, + kX86InstIdJpe_ExtendedIndex = 84, + kX86InstIdJpo_ExtendedIndex = 84, + kX86InstIdJs_ExtendedIndex = 85, + kX86InstIdJz_ExtendedIndex = 80, + kX86InstIdJecxz_ExtendedIndex = 86, + kX86InstIdJmp_ExtendedIndex = 87, + kX86InstIdLahf_ExtendedIndex = 88, + kX86InstIdLddqu_ExtendedIndex = 89, + kX86InstIdLdmxcsr_ExtendedIndex = 19, + kX86InstIdLea_ExtendedIndex = 90, kX86InstIdLeave_ExtendedIndex = 16, - kX86InstIdLfence_ExtendedIndex = 92, - kX86InstIdLodsB_ExtendedIndex = 93, - kX86InstIdLodsD_ExtendedIndex = 94, - kX86InstIdLodsQ_ExtendedIndex = 95, - kX86InstIdLodsW_ExtendedIndex = 96, + kX86InstIdLfence_ExtendedIndex = 91, + kX86InstIdLodsB_ExtendedIndex = 92, + kX86InstIdLodsD_ExtendedIndex = 93, + kX86InstIdLodsQ_ExtendedIndex = 94, + kX86InstIdLodsW_ExtendedIndex = 95, kX86InstIdLzcnt_ExtendedIndex = 9, - kX86InstIdMaskmovdqu_ExtendedIndex = 97, - kX86InstIdMaskmovq_ExtendedIndex = 98, + kX86InstIdMaskmovdqu_ExtendedIndex = 96, + kX86InstIdMaskmovq_ExtendedIndex = 97, kX86InstIdMaxpd_ExtendedIndex = 3, kX86InstIdMaxps_ExtendedIndex = 3, kX86InstIdMaxsd_ExtendedIndex = 3, kX86InstIdMaxss_ExtendedIndex = 3, - kX86InstIdMfence_ExtendedIndex = 92, + kX86InstIdMfence_ExtendedIndex = 91, kX86InstIdMinpd_ExtendedIndex = 3, kX86InstIdMinps_ExtendedIndex = 3, kX86InstIdMinsd_ExtendedIndex = 3, kX86InstIdMinss_ExtendedIndex = 3, kX86InstIdMonitor_ExtendedIndex = 16, - kX86InstIdMov_ExtendedIndex = 99, - kX86InstIdMovPtr_ExtendedIndex = 100, - kX86InstIdMovapd_ExtendedIndex = 101, - kX86InstIdMovaps_ExtendedIndex = 102, - kX86InstIdMovbe_ExtendedIndex = 103, - kX86InstIdMovd_ExtendedIndex = 104, - kX86InstIdMovddup_ExtendedIndex = 105, - kX86InstIdMovdq2q_ExtendedIndex = 106, - kX86InstIdMovdqa_ExtendedIndex = 107, - kX86InstIdMovdqu_ExtendedIndex = 108, - kX86InstIdMovhlps_ExtendedIndex = 109, - kX86InstIdMovhpd_ExtendedIndex = 110, - kX86InstIdMovhps_ExtendedIndex = 111, - kX86InstIdMovlhps_ExtendedIndex = 112, - kX86InstIdMovlpd_ExtendedIndex = 113, - kX86InstIdMovlps_ExtendedIndex = 114, - kX86InstIdMovmskpd_ExtendedIndex = 115, - kX86InstIdMovmskps_ExtendedIndex = 115, - kX86InstIdMovntdq_ExtendedIndex = 116, - kX86InstIdMovntdqa_ExtendedIndex = 117, - kX86InstIdMovnti_ExtendedIndex = 118, - kX86InstIdMovntpd_ExtendedIndex = 119, - kX86InstIdMovntps_ExtendedIndex = 120, - kX86InstIdMovntq_ExtendedIndex = 121, - kX86InstIdMovq_ExtendedIndex = 122, - kX86InstIdMovq2dq_ExtendedIndex = 123, + kX86InstIdMov_ExtendedIndex = 98, + kX86InstIdMovPtr_ExtendedIndex = 99, + kX86InstIdMovapd_ExtendedIndex = 100, + kX86InstIdMovaps_ExtendedIndex = 101, + kX86InstIdMovbe_ExtendedIndex = 102, + kX86InstIdMovd_ExtendedIndex = 103, + kX86InstIdMovddup_ExtendedIndex = 104, + kX86InstIdMovdq2q_ExtendedIndex = 105, + kX86InstIdMovdqa_ExtendedIndex = 106, + kX86InstIdMovdqu_ExtendedIndex = 107, + kX86InstIdMovhlps_ExtendedIndex = 108, + kX86InstIdMovhpd_ExtendedIndex = 109, + kX86InstIdMovhps_ExtendedIndex = 110, + kX86InstIdMovlhps_ExtendedIndex = 111, + kX86InstIdMovlpd_ExtendedIndex = 112, + kX86InstIdMovlps_ExtendedIndex = 113, + kX86InstIdMovmskpd_ExtendedIndex = 114, + kX86InstIdMovmskps_ExtendedIndex = 114, + kX86InstIdMovntdq_ExtendedIndex = 115, + kX86InstIdMovntdqa_ExtendedIndex = 116, + kX86InstIdMovnti_ExtendedIndex = 117, + kX86InstIdMovntpd_ExtendedIndex = 118, + kX86InstIdMovntps_ExtendedIndex = 119, + kX86InstIdMovntq_ExtendedIndex = 120, + kX86InstIdMovntsd_ExtendedIndex = 121, + kX86InstIdMovntss_ExtendedIndex = 122, + kX86InstIdMovq_ExtendedIndex = 123, + kX86InstIdMovq2dq_ExtendedIndex = 124, kX86InstIdMovsB_ExtendedIndex = 16, - kX86InstIdMovsD_ExtendedIndex = 124, - kX86InstIdMovsQ_ExtendedIndex = 17, - kX86InstIdMovsW_ExtendedIndex = 125, - kX86InstIdMovsd_ExtendedIndex = 126, - kX86InstIdMovshdup_ExtendedIndex = 39, - kX86InstIdMovsldup_ExtendedIndex = 39, - kX86InstIdMovss_ExtendedIndex = 127, - kX86InstIdMovsx_ExtendedIndex = 128, - kX86InstIdMovsxd_ExtendedIndex = 129, - kX86InstIdMovupd_ExtendedIndex = 130, - kX86InstIdMovups_ExtendedIndex = 131, - kX86InstIdMovzx_ExtendedIndex = 128, + kX86InstIdMovsD_ExtendedIndex = 125, + kX86InstIdMovsQ_ExtendedIndex = 16, + kX86InstIdMovsW_ExtendedIndex = 126, + kX86InstIdMovsd_ExtendedIndex = 127, + kX86InstIdMovshdup_ExtendedIndex = 36, + kX86InstIdMovsldup_ExtendedIndex = 36, + kX86InstIdMovss_ExtendedIndex = 128, + kX86InstIdMovsx_ExtendedIndex = 129, + kX86InstIdMovsxd_ExtendedIndex = 130, + kX86InstIdMovupd_ExtendedIndex = 131, + kX86InstIdMovups_ExtendedIndex = 132, + kX86InstIdMovzx_ExtendedIndex = 129, kX86InstIdMpsadbw_ExtendedIndex = 4, - kX86InstIdMul_ExtendedIndex = 75, + kX86InstIdMul_ExtendedIndex = 73, kX86InstIdMulpd_ExtendedIndex = 3, kX86InstIdMulps_ExtendedIndex = 3, kX86InstIdMulsd_ExtendedIndex = 3, kX86InstIdMulss_ExtendedIndex = 3, - kX86InstIdMulx_ExtendedIndex = 132, + kX86InstIdMulx_ExtendedIndex = 133, kX86InstIdMwait_ExtendedIndex = 16, - kX86InstIdNeg_ExtendedIndex = 133, - kX86InstIdNop_ExtendedIndex = 51, - kX86InstIdNot_ExtendedIndex = 134, + kX86InstIdNeg_ExtendedIndex = 134, + kX86InstIdNop_ExtendedIndex = 48, + kX86InstIdNot_ExtendedIndex = 135, kX86InstIdOr_ExtendedIndex = 2, kX86InstIdOrpd_ExtendedIndex = 3, kX86InstIdOrps_ExtendedIndex = 3, - kX86InstIdPabsb_ExtendedIndex = 135, - kX86InstIdPabsd_ExtendedIndex = 135, - kX86InstIdPabsw_ExtendedIndex = 135, - kX86InstIdPackssdw_ExtendedIndex = 135, - kX86InstIdPacksswb_ExtendedIndex = 135, + kX86InstIdPabsb_ExtendedIndex = 136, + kX86InstIdPabsd_ExtendedIndex = 136, + kX86InstIdPabsw_ExtendedIndex = 136, + kX86InstIdPackssdw_ExtendedIndex = 136, + kX86InstIdPacksswb_ExtendedIndex = 136, kX86InstIdPackusdw_ExtendedIndex = 3, - kX86InstIdPackuswb_ExtendedIndex = 135, - kX86InstIdPaddb_ExtendedIndex = 135, - kX86InstIdPaddd_ExtendedIndex = 135, - kX86InstIdPaddq_ExtendedIndex = 135, - kX86InstIdPaddsb_ExtendedIndex = 135, - kX86InstIdPaddsw_ExtendedIndex = 135, - kX86InstIdPaddusb_ExtendedIndex = 135, - kX86InstIdPaddusw_ExtendedIndex = 135, - kX86InstIdPaddw_ExtendedIndex = 135, - kX86InstIdPalignr_ExtendedIndex = 136, - kX86InstIdPand_ExtendedIndex = 135, - kX86InstIdPandn_ExtendedIndex = 135, - kX86InstIdPause_ExtendedIndex = 51, - kX86InstIdPavgb_ExtendedIndex = 135, - kX86InstIdPavgw_ExtendedIndex = 135, + kX86InstIdPackuswb_ExtendedIndex = 136, + kX86InstIdPaddb_ExtendedIndex = 136, + kX86InstIdPaddd_ExtendedIndex = 136, + kX86InstIdPaddq_ExtendedIndex = 136, + kX86InstIdPaddsb_ExtendedIndex = 136, + kX86InstIdPaddsw_ExtendedIndex = 136, + kX86InstIdPaddusb_ExtendedIndex = 136, + kX86InstIdPaddusw_ExtendedIndex = 136, + kX86InstIdPaddw_ExtendedIndex = 136, + kX86InstIdPalignr_ExtendedIndex = 137, + kX86InstIdPand_ExtendedIndex = 136, + kX86InstIdPandn_ExtendedIndex = 136, + kX86InstIdPause_ExtendedIndex = 48, + kX86InstIdPavgb_ExtendedIndex = 136, + kX86InstIdPavgw_ExtendedIndex = 136, kX86InstIdPblendvb_ExtendedIndex = 7, kX86InstIdPblendw_ExtendedIndex = 4, kX86InstIdPclmulqdq_ExtendedIndex = 4, - kX86InstIdPcmpeqb_ExtendedIndex = 135, - kX86InstIdPcmpeqd_ExtendedIndex = 135, + kX86InstIdPcmpeqb_ExtendedIndex = 136, + kX86InstIdPcmpeqd_ExtendedIndex = 136, kX86InstIdPcmpeqq_ExtendedIndex = 3, - kX86InstIdPcmpeqw_ExtendedIndex = 135, + kX86InstIdPcmpeqw_ExtendedIndex = 136, kX86InstIdPcmpestri_ExtendedIndex = 4, kX86InstIdPcmpestrm_ExtendedIndex = 4, - kX86InstIdPcmpgtb_ExtendedIndex = 135, - kX86InstIdPcmpgtd_ExtendedIndex = 135, + kX86InstIdPcmpgtb_ExtendedIndex = 136, + kX86InstIdPcmpgtd_ExtendedIndex = 136, kX86InstIdPcmpgtq_ExtendedIndex = 3, - kX86InstIdPcmpgtw_ExtendedIndex = 135, + kX86InstIdPcmpgtw_ExtendedIndex = 136, kX86InstIdPcmpistri_ExtendedIndex = 4, kX86InstIdPcmpistrm_ExtendedIndex = 4, - kX86InstIdPdep_ExtendedIndex = 132, - kX86InstIdPext_ExtendedIndex = 132, - kX86InstIdPextrb_ExtendedIndex = 137, - kX86InstIdPextrd_ExtendedIndex = 138, - kX86InstIdPextrq_ExtendedIndex = 139, - kX86InstIdPextrw_ExtendedIndex = 140, - kX86InstIdPf2id_ExtendedIndex = 141, - kX86InstIdPf2iw_ExtendedIndex = 141, - kX86InstIdPfacc_ExtendedIndex = 141, - kX86InstIdPfadd_ExtendedIndex = 141, - kX86InstIdPfcmpeq_ExtendedIndex = 141, - kX86InstIdPfcmpge_ExtendedIndex = 141, - kX86InstIdPfcmpgt_ExtendedIndex = 141, - kX86InstIdPfmax_ExtendedIndex = 141, - kX86InstIdPfmin_ExtendedIndex = 141, - kX86InstIdPfmul_ExtendedIndex = 141, - kX86InstIdPfnacc_ExtendedIndex = 141, - kX86InstIdPfpnacc_ExtendedIndex = 141, - kX86InstIdPfrcp_ExtendedIndex = 141, - kX86InstIdPfrcpit1_ExtendedIndex = 141, - kX86InstIdPfrcpit2_ExtendedIndex = 141, - kX86InstIdPfrsqit1_ExtendedIndex = 141, - kX86InstIdPfrsqrt_ExtendedIndex = 141, - kX86InstIdPfsub_ExtendedIndex = 141, - kX86InstIdPfsubr_ExtendedIndex = 141, - kX86InstIdPhaddd_ExtendedIndex = 135, - kX86InstIdPhaddsw_ExtendedIndex = 135, - kX86InstIdPhaddw_ExtendedIndex = 135, + kX86InstIdPdep_ExtendedIndex = 133, + kX86InstIdPext_ExtendedIndex = 133, + kX86InstIdPextrb_ExtendedIndex = 138, + kX86InstIdPextrd_ExtendedIndex = 139, + kX86InstIdPextrq_ExtendedIndex = 140, + kX86InstIdPextrw_ExtendedIndex = 141, + kX86InstIdPf2id_ExtendedIndex = 142, + kX86InstIdPf2iw_ExtendedIndex = 142, + kX86InstIdPfacc_ExtendedIndex = 142, + kX86InstIdPfadd_ExtendedIndex = 142, + kX86InstIdPfcmpeq_ExtendedIndex = 142, + kX86InstIdPfcmpge_ExtendedIndex = 142, + kX86InstIdPfcmpgt_ExtendedIndex = 142, + kX86InstIdPfmax_ExtendedIndex = 142, + kX86InstIdPfmin_ExtendedIndex = 142, + kX86InstIdPfmul_ExtendedIndex = 142, + kX86InstIdPfnacc_ExtendedIndex = 142, + kX86InstIdPfpnacc_ExtendedIndex = 142, + kX86InstIdPfrcp_ExtendedIndex = 142, + kX86InstIdPfrcpit1_ExtendedIndex = 142, + kX86InstIdPfrcpit2_ExtendedIndex = 142, + kX86InstIdPfrsqit1_ExtendedIndex = 142, + kX86InstIdPfrsqrt_ExtendedIndex = 142, + kX86InstIdPfsub_ExtendedIndex = 142, + kX86InstIdPfsubr_ExtendedIndex = 142, + kX86InstIdPhaddd_ExtendedIndex = 136, + kX86InstIdPhaddsw_ExtendedIndex = 136, + kX86InstIdPhaddw_ExtendedIndex = 136, kX86InstIdPhminposuw_ExtendedIndex = 3, - kX86InstIdPhsubd_ExtendedIndex = 135, - kX86InstIdPhsubsw_ExtendedIndex = 135, - kX86InstIdPhsubw_ExtendedIndex = 135, - kX86InstIdPi2fd_ExtendedIndex = 141, - kX86InstIdPi2fw_ExtendedIndex = 141, - kX86InstIdPinsrb_ExtendedIndex = 142, - kX86InstIdPinsrd_ExtendedIndex = 142, - kX86InstIdPinsrq_ExtendedIndex = 143, - kX86InstIdPinsrw_ExtendedIndex = 144, - kX86InstIdPmaddubsw_ExtendedIndex = 135, - kX86InstIdPmaddwd_ExtendedIndex = 135, + kX86InstIdPhsubd_ExtendedIndex = 136, + kX86InstIdPhsubsw_ExtendedIndex = 136, + kX86InstIdPhsubw_ExtendedIndex = 136, + kX86InstIdPi2fd_ExtendedIndex = 142, + kX86InstIdPi2fw_ExtendedIndex = 142, + kX86InstIdPinsrb_ExtendedIndex = 143, + kX86InstIdPinsrd_ExtendedIndex = 143, + kX86InstIdPinsrq_ExtendedIndex = 144, + kX86InstIdPinsrw_ExtendedIndex = 145, + kX86InstIdPmaddubsw_ExtendedIndex = 136, + kX86InstIdPmaddwd_ExtendedIndex = 136, kX86InstIdPmaxsb_ExtendedIndex = 3, kX86InstIdPmaxsd_ExtendedIndex = 3, - kX86InstIdPmaxsw_ExtendedIndex = 135, - kX86InstIdPmaxub_ExtendedIndex = 135, + kX86InstIdPmaxsw_ExtendedIndex = 136, + kX86InstIdPmaxub_ExtendedIndex = 136, kX86InstIdPmaxud_ExtendedIndex = 3, kX86InstIdPmaxuw_ExtendedIndex = 3, kX86InstIdPminsb_ExtendedIndex = 3, kX86InstIdPminsd_ExtendedIndex = 3, - kX86InstIdPminsw_ExtendedIndex = 135, - kX86InstIdPminub_ExtendedIndex = 135, + kX86InstIdPminsw_ExtendedIndex = 136, + kX86InstIdPminub_ExtendedIndex = 136, kX86InstIdPminud_ExtendedIndex = 3, kX86InstIdPminuw_ExtendedIndex = 3, - kX86InstIdPmovmskb_ExtendedIndex = 145, - kX86InstIdPmovsxbd_ExtendedIndex = 39, - kX86InstIdPmovsxbq_ExtendedIndex = 39, - kX86InstIdPmovsxbw_ExtendedIndex = 39, - kX86InstIdPmovsxdq_ExtendedIndex = 39, - kX86InstIdPmovsxwd_ExtendedIndex = 39, - kX86InstIdPmovsxwq_ExtendedIndex = 39, - kX86InstIdPmovzxbd_ExtendedIndex = 39, - kX86InstIdPmovzxbq_ExtendedIndex = 39, - kX86InstIdPmovzxbw_ExtendedIndex = 39, - kX86InstIdPmovzxdq_ExtendedIndex = 39, - kX86InstIdPmovzxwd_ExtendedIndex = 39, - kX86InstIdPmovzxwq_ExtendedIndex = 39, + kX86InstIdPmovmskb_ExtendedIndex = 146, + kX86InstIdPmovsxbd_ExtendedIndex = 36, + kX86InstIdPmovsxbq_ExtendedIndex = 36, + kX86InstIdPmovsxbw_ExtendedIndex = 36, + kX86InstIdPmovsxdq_ExtendedIndex = 36, + kX86InstIdPmovsxwd_ExtendedIndex = 36, + kX86InstIdPmovsxwq_ExtendedIndex = 36, + kX86InstIdPmovzxbd_ExtendedIndex = 36, + kX86InstIdPmovzxbq_ExtendedIndex = 36, + kX86InstIdPmovzxbw_ExtendedIndex = 36, + kX86InstIdPmovzxdq_ExtendedIndex = 36, + kX86InstIdPmovzxwd_ExtendedIndex = 36, + kX86InstIdPmovzxwq_ExtendedIndex = 36, kX86InstIdPmuldq_ExtendedIndex = 3, - kX86InstIdPmulhrsw_ExtendedIndex = 135, - kX86InstIdPmulhuw_ExtendedIndex = 135, - kX86InstIdPmulhw_ExtendedIndex = 135, + kX86InstIdPmulhrsw_ExtendedIndex = 136, + kX86InstIdPmulhuw_ExtendedIndex = 136, + kX86InstIdPmulhw_ExtendedIndex = 136, kX86InstIdPmulld_ExtendedIndex = 3, - kX86InstIdPmullw_ExtendedIndex = 135, - kX86InstIdPmuludq_ExtendedIndex = 135, - kX86InstIdPop_ExtendedIndex = 146, + kX86InstIdPmullw_ExtendedIndex = 136, + kX86InstIdPmuludq_ExtendedIndex = 136, + kX86InstIdPop_ExtendedIndex = 147, kX86InstIdPopa_ExtendedIndex = 16, kX86InstIdPopcnt_ExtendedIndex = 9, - kX86InstIdPopf_ExtendedIndex = 147, - kX86InstIdPor_ExtendedIndex = 135, - kX86InstIdPrefetch_ExtendedIndex = 148, - kX86InstIdPrefetch3dNow_ExtendedIndex = 20, - kX86InstIdPrefetchw3dNow_ExtendedIndex = 20, - kX86InstIdPsadbw_ExtendedIndex = 135, - kX86InstIdPshufb_ExtendedIndex = 135, - kX86InstIdPshufd_ExtendedIndex = 149, - kX86InstIdPshufhw_ExtendedIndex = 149, - kX86InstIdPshuflw_ExtendedIndex = 149, - kX86InstIdPshufw_ExtendedIndex = 150, - kX86InstIdPsignb_ExtendedIndex = 135, - kX86InstIdPsignd_ExtendedIndex = 135, - kX86InstIdPsignw_ExtendedIndex = 135, - kX86InstIdPslld_ExtendedIndex = 151, - kX86InstIdPslldq_ExtendedIndex = 152, - kX86InstIdPsllq_ExtendedIndex = 153, - kX86InstIdPsllw_ExtendedIndex = 154, - kX86InstIdPsrad_ExtendedIndex = 155, - kX86InstIdPsraw_ExtendedIndex = 156, - kX86InstIdPsrld_ExtendedIndex = 157, - kX86InstIdPsrldq_ExtendedIndex = 158, - kX86InstIdPsrlq_ExtendedIndex = 159, - kX86InstIdPsrlw_ExtendedIndex = 160, - kX86InstIdPsubb_ExtendedIndex = 135, - kX86InstIdPsubd_ExtendedIndex = 135, - kX86InstIdPsubq_ExtendedIndex = 135, - kX86InstIdPsubsb_ExtendedIndex = 135, - kX86InstIdPsubsw_ExtendedIndex = 135, - kX86InstIdPsubusb_ExtendedIndex = 135, - kX86InstIdPsubusw_ExtendedIndex = 135, - kX86InstIdPsubw_ExtendedIndex = 135, - kX86InstIdPswapd_ExtendedIndex = 141, - kX86InstIdPtest_ExtendedIndex = 37, - kX86InstIdPunpckhbw_ExtendedIndex = 135, - kX86InstIdPunpckhdq_ExtendedIndex = 135, + kX86InstIdPopf_ExtendedIndex = 148, + kX86InstIdPor_ExtendedIndex = 136, + kX86InstIdPrefetch_ExtendedIndex = 149, + kX86InstIdPrefetch3dNow_ExtendedIndex = 19, + kX86InstIdPrefetchw3dNow_ExtendedIndex = 19, + kX86InstIdPsadbw_ExtendedIndex = 136, + kX86InstIdPshufb_ExtendedIndex = 136, + kX86InstIdPshufd_ExtendedIndex = 150, + kX86InstIdPshufhw_ExtendedIndex = 150, + kX86InstIdPshuflw_ExtendedIndex = 150, + kX86InstIdPshufw_ExtendedIndex = 151, + kX86InstIdPsignb_ExtendedIndex = 136, + kX86InstIdPsignd_ExtendedIndex = 136, + kX86InstIdPsignw_ExtendedIndex = 136, + kX86InstIdPslld_ExtendedIndex = 152, + kX86InstIdPslldq_ExtendedIndex = 153, + kX86InstIdPsllq_ExtendedIndex = 154, + kX86InstIdPsllw_ExtendedIndex = 155, + kX86InstIdPsrad_ExtendedIndex = 156, + kX86InstIdPsraw_ExtendedIndex = 157, + kX86InstIdPsrld_ExtendedIndex = 158, + kX86InstIdPsrldq_ExtendedIndex = 159, + kX86InstIdPsrlq_ExtendedIndex = 160, + kX86InstIdPsrlw_ExtendedIndex = 161, + kX86InstIdPsubb_ExtendedIndex = 136, + kX86InstIdPsubd_ExtendedIndex = 136, + kX86InstIdPsubq_ExtendedIndex = 136, + kX86InstIdPsubsb_ExtendedIndex = 136, + kX86InstIdPsubsw_ExtendedIndex = 136, + kX86InstIdPsubusb_ExtendedIndex = 136, + kX86InstIdPsubusw_ExtendedIndex = 136, + kX86InstIdPsubw_ExtendedIndex = 136, + kX86InstIdPswapd_ExtendedIndex = 142, + kX86InstIdPtest_ExtendedIndex = 34, + kX86InstIdPunpckhbw_ExtendedIndex = 136, + kX86InstIdPunpckhdq_ExtendedIndex = 136, kX86InstIdPunpckhqdq_ExtendedIndex = 3, - kX86InstIdPunpckhwd_ExtendedIndex = 135, - kX86InstIdPunpcklbw_ExtendedIndex = 135, - kX86InstIdPunpckldq_ExtendedIndex = 135, + kX86InstIdPunpckhwd_ExtendedIndex = 136, + kX86InstIdPunpcklbw_ExtendedIndex = 136, + kX86InstIdPunpckldq_ExtendedIndex = 136, kX86InstIdPunpcklqdq_ExtendedIndex = 3, - kX86InstIdPunpcklwd_ExtendedIndex = 135, - kX86InstIdPush_ExtendedIndex = 161, + kX86InstIdPunpcklwd_ExtendedIndex = 136, + kX86InstIdPush_ExtendedIndex = 162, kX86InstIdPusha_ExtendedIndex = 16, - kX86InstIdPushf_ExtendedIndex = 162, - kX86InstIdPxor_ExtendedIndex = 135, - kX86InstIdRcl_ExtendedIndex = 163, - kX86InstIdRcpps_ExtendedIndex = 39, - kX86InstIdRcpss_ExtendedIndex = 44, - kX86InstIdRcr_ExtendedIndex = 163, - kX86InstIdRdfsbase_ExtendedIndex = 164, - kX86InstIdRdgsbase_ExtendedIndex = 164, - kX86InstIdRdrand_ExtendedIndex = 165, + kX86InstIdPushf_ExtendedIndex = 163, + kX86InstIdPxor_ExtendedIndex = 136, + kX86InstIdRcl_ExtendedIndex = 164, + kX86InstIdRcpps_ExtendedIndex = 36, + kX86InstIdRcpss_ExtendedIndex = 41, + kX86InstIdRcr_ExtendedIndex = 164, + kX86InstIdRdfsbase_ExtendedIndex = 165, + kX86InstIdRdgsbase_ExtendedIndex = 165, + kX86InstIdRdrand_ExtendedIndex = 166, kX86InstIdRdtsc_ExtendedIndex = 16, kX86InstIdRdtscp_ExtendedIndex = 16, - kX86InstIdRepLodsB_ExtendedIndex = 166, - kX86InstIdRepLodsD_ExtendedIndex = 166, + kX86InstIdRepLodsB_ExtendedIndex = 167, + kX86InstIdRepLodsD_ExtendedIndex = 167, kX86InstIdRepLodsQ_ExtendedIndex = 167, - kX86InstIdRepLodsW_ExtendedIndex = 166, + kX86InstIdRepLodsW_ExtendedIndex = 167, kX86InstIdRepMovsB_ExtendedIndex = 168, kX86InstIdRepMovsD_ExtendedIndex = 168, - kX86InstIdRepMovsQ_ExtendedIndex = 169, + kX86InstIdRepMovsQ_ExtendedIndex = 168, kX86InstIdRepMovsW_ExtendedIndex = 168, - kX86InstIdRepStosB_ExtendedIndex = 166, - kX86InstIdRepStosD_ExtendedIndex = 166, + kX86InstIdRepStosB_ExtendedIndex = 167, + kX86InstIdRepStosD_ExtendedIndex = 167, kX86InstIdRepStosQ_ExtendedIndex = 167, - kX86InstIdRepStosW_ExtendedIndex = 166, - kX86InstIdRepeCmpsB_ExtendedIndex = 170, - kX86InstIdRepeCmpsD_ExtendedIndex = 170, - kX86InstIdRepeCmpsQ_ExtendedIndex = 171, - kX86InstIdRepeCmpsW_ExtendedIndex = 170, - kX86InstIdRepeScasB_ExtendedIndex = 170, - kX86InstIdRepeScasD_ExtendedIndex = 170, - kX86InstIdRepeScasQ_ExtendedIndex = 171, - kX86InstIdRepeScasW_ExtendedIndex = 170, - kX86InstIdRepneCmpsB_ExtendedIndex = 170, - kX86InstIdRepneCmpsD_ExtendedIndex = 170, - kX86InstIdRepneCmpsQ_ExtendedIndex = 171, - kX86InstIdRepneCmpsW_ExtendedIndex = 170, - kX86InstIdRepneScasB_ExtendedIndex = 170, - kX86InstIdRepneScasD_ExtendedIndex = 170, - kX86InstIdRepneScasQ_ExtendedIndex = 171, - kX86InstIdRepneScasW_ExtendedIndex = 170, - kX86InstIdRet_ExtendedIndex = 172, - kX86InstIdRol_ExtendedIndex = 173, - kX86InstIdRor_ExtendedIndex = 173, - kX86InstIdRorx_ExtendedIndex = 174, - kX86InstIdRoundpd_ExtendedIndex = 149, - kX86InstIdRoundps_ExtendedIndex = 149, - kX86InstIdRoundsd_ExtendedIndex = 175, - kX86InstIdRoundss_ExtendedIndex = 176, - kX86InstIdRsqrtps_ExtendedIndex = 39, - kX86InstIdRsqrtss_ExtendedIndex = 44, - kX86InstIdSahf_ExtendedIndex = 177, - kX86InstIdSal_ExtendedIndex = 178, - kX86InstIdSar_ExtendedIndex = 178, - kX86InstIdSarx_ExtendedIndex = 179, + kX86InstIdRepStosW_ExtendedIndex = 167, + kX86InstIdRepeCmpsB_ExtendedIndex = 169, + kX86InstIdRepeCmpsD_ExtendedIndex = 169, + kX86InstIdRepeCmpsQ_ExtendedIndex = 169, + kX86InstIdRepeCmpsW_ExtendedIndex = 169, + kX86InstIdRepeScasB_ExtendedIndex = 169, + kX86InstIdRepeScasD_ExtendedIndex = 169, + kX86InstIdRepeScasQ_ExtendedIndex = 169, + kX86InstIdRepeScasW_ExtendedIndex = 169, + kX86InstIdRepneCmpsB_ExtendedIndex = 169, + kX86InstIdRepneCmpsD_ExtendedIndex = 169, + kX86InstIdRepneCmpsQ_ExtendedIndex = 169, + kX86InstIdRepneCmpsW_ExtendedIndex = 169, + kX86InstIdRepneScasB_ExtendedIndex = 169, + kX86InstIdRepneScasD_ExtendedIndex = 169, + kX86InstIdRepneScasQ_ExtendedIndex = 169, + kX86InstIdRepneScasW_ExtendedIndex = 169, + kX86InstIdRet_ExtendedIndex = 170, + kX86InstIdRol_ExtendedIndex = 171, + kX86InstIdRor_ExtendedIndex = 171, + kX86InstIdRorx_ExtendedIndex = 172, + kX86InstIdRoundpd_ExtendedIndex = 150, + kX86InstIdRoundps_ExtendedIndex = 150, + kX86InstIdRoundsd_ExtendedIndex = 173, + kX86InstIdRoundss_ExtendedIndex = 174, + kX86InstIdRsqrtps_ExtendedIndex = 36, + kX86InstIdRsqrtss_ExtendedIndex = 41, + kX86InstIdSahf_ExtendedIndex = 175, + kX86InstIdSal_ExtendedIndex = 176, + kX86InstIdSar_ExtendedIndex = 176, + kX86InstIdSarx_ExtendedIndex = 177, kX86InstIdSbb_ExtendedIndex = 1, - kX86InstIdScasB_ExtendedIndex = 31, - kX86InstIdScasD_ExtendedIndex = 31, - kX86InstIdScasQ_ExtendedIndex = 32, - kX86InstIdScasW_ExtendedIndex = 33, - kX86InstIdSeta_ExtendedIndex = 180, - kX86InstIdSetae_ExtendedIndex = 181, - kX86InstIdSetb_ExtendedIndex = 181, - kX86InstIdSetbe_ExtendedIndex = 180, - kX86InstIdSetc_ExtendedIndex = 181, - kX86InstIdSete_ExtendedIndex = 182, - kX86InstIdSetg_ExtendedIndex = 183, - kX86InstIdSetge_ExtendedIndex = 184, - kX86InstIdSetl_ExtendedIndex = 184, - kX86InstIdSetle_ExtendedIndex = 183, - kX86InstIdSetna_ExtendedIndex = 180, - kX86InstIdSetnae_ExtendedIndex = 181, - kX86InstIdSetnb_ExtendedIndex = 181, - kX86InstIdSetnbe_ExtendedIndex = 180, - kX86InstIdSetnc_ExtendedIndex = 181, - kX86InstIdSetne_ExtendedIndex = 182, - kX86InstIdSetng_ExtendedIndex = 183, - kX86InstIdSetnge_ExtendedIndex = 184, - kX86InstIdSetnl_ExtendedIndex = 184, - kX86InstIdSetnle_ExtendedIndex = 183, - kX86InstIdSetno_ExtendedIndex = 185, - kX86InstIdSetnp_ExtendedIndex = 186, - kX86InstIdSetns_ExtendedIndex = 187, - kX86InstIdSetnz_ExtendedIndex = 182, - kX86InstIdSeto_ExtendedIndex = 185, - kX86InstIdSetp_ExtendedIndex = 186, - kX86InstIdSetpe_ExtendedIndex = 186, - kX86InstIdSetpo_ExtendedIndex = 186, - kX86InstIdSets_ExtendedIndex = 187, - kX86InstIdSetz_ExtendedIndex = 182, - kX86InstIdSfence_ExtendedIndex = 92, - kX86InstIdShl_ExtendedIndex = 178, - kX86InstIdShld_ExtendedIndex = 188, - kX86InstIdShlx_ExtendedIndex = 179, - kX86InstIdShr_ExtendedIndex = 178, - kX86InstIdShrd_ExtendedIndex = 189, - kX86InstIdShrx_ExtendedIndex = 179, + kX86InstIdScasB_ExtendedIndex = 30, + kX86InstIdScasD_ExtendedIndex = 30, + kX86InstIdScasQ_ExtendedIndex = 30, + kX86InstIdScasW_ExtendedIndex = 31, + kX86InstIdSeta_ExtendedIndex = 178, + kX86InstIdSetae_ExtendedIndex = 179, + kX86InstIdSetb_ExtendedIndex = 179, + kX86InstIdSetbe_ExtendedIndex = 178, + kX86InstIdSetc_ExtendedIndex = 179, + kX86InstIdSete_ExtendedIndex = 180, + kX86InstIdSetg_ExtendedIndex = 181, + kX86InstIdSetge_ExtendedIndex = 182, + kX86InstIdSetl_ExtendedIndex = 182, + kX86InstIdSetle_ExtendedIndex = 181, + kX86InstIdSetna_ExtendedIndex = 178, + kX86InstIdSetnae_ExtendedIndex = 179, + kX86InstIdSetnb_ExtendedIndex = 179, + kX86InstIdSetnbe_ExtendedIndex = 178, + kX86InstIdSetnc_ExtendedIndex = 179, + kX86InstIdSetne_ExtendedIndex = 180, + kX86InstIdSetng_ExtendedIndex = 181, + kX86InstIdSetnge_ExtendedIndex = 182, + kX86InstIdSetnl_ExtendedIndex = 182, + kX86InstIdSetnle_ExtendedIndex = 181, + kX86InstIdSetno_ExtendedIndex = 183, + kX86InstIdSetnp_ExtendedIndex = 184, + kX86InstIdSetns_ExtendedIndex = 185, + kX86InstIdSetnz_ExtendedIndex = 180, + kX86InstIdSeto_ExtendedIndex = 183, + kX86InstIdSetp_ExtendedIndex = 184, + kX86InstIdSetpe_ExtendedIndex = 184, + kX86InstIdSetpo_ExtendedIndex = 184, + kX86InstIdSets_ExtendedIndex = 185, + kX86InstIdSetz_ExtendedIndex = 180, + kX86InstIdSfence_ExtendedIndex = 91, + kX86InstIdShl_ExtendedIndex = 176, + kX86InstIdShld_ExtendedIndex = 186, + kX86InstIdShlx_ExtendedIndex = 177, + kX86InstIdShr_ExtendedIndex = 176, + kX86InstIdShrd_ExtendedIndex = 187, + kX86InstIdShrx_ExtendedIndex = 177, kX86InstIdShufpd_ExtendedIndex = 4, kX86InstIdShufps_ExtendedIndex = 4, - kX86InstIdSqrtpd_ExtendedIndex = 39, - kX86InstIdSqrtps_ExtendedIndex = 39, - kX86InstIdSqrtsd_ExtendedIndex = 47, - kX86InstIdSqrtss_ExtendedIndex = 44, - kX86InstIdStc_ExtendedIndex = 18, - kX86InstIdStd_ExtendedIndex = 19, - kX86InstIdStmxcsr_ExtendedIndex = 20, - kX86InstIdStosB_ExtendedIndex = 190, - kX86InstIdStosD_ExtendedIndex = 190, - kX86InstIdStosQ_ExtendedIndex = 191, - kX86InstIdStosW_ExtendedIndex = 192, + kX86InstIdSqrtpd_ExtendedIndex = 36, + kX86InstIdSqrtps_ExtendedIndex = 36, + kX86InstIdSqrtsd_ExtendedIndex = 44, + kX86InstIdSqrtss_ExtendedIndex = 41, + kX86InstIdStc_ExtendedIndex = 17, + kX86InstIdStd_ExtendedIndex = 18, + kX86InstIdStmxcsr_ExtendedIndex = 19, + kX86InstIdStosB_ExtendedIndex = 188, + kX86InstIdStosD_ExtendedIndex = 188, + kX86InstIdStosQ_ExtendedIndex = 188, + kX86InstIdStosW_ExtendedIndex = 189, kX86InstIdSub_ExtendedIndex = 2, kX86InstIdSubpd_ExtendedIndex = 3, kX86InstIdSubps_ExtendedIndex = 3, kX86InstIdSubsd_ExtendedIndex = 3, kX86InstIdSubss_ExtendedIndex = 3, - kX86InstIdTest_ExtendedIndex = 193, - kX86InstIdTzcnt_ExtendedIndex = 194, - kX86InstIdUcomisd_ExtendedIndex = 37, - kX86InstIdUcomiss_ExtendedIndex = 37, - kX86InstIdUd2_ExtendedIndex = 51, + kX86InstIdTest_ExtendedIndex = 190, + kX86InstIdTzcnt_ExtendedIndex = 191, + kX86InstIdUcomisd_ExtendedIndex = 34, + kX86InstIdUcomiss_ExtendedIndex = 34, + kX86InstIdUd2_ExtendedIndex = 48, kX86InstIdUnpckhpd_ExtendedIndex = 3, kX86InstIdUnpckhps_ExtendedIndex = 3, kX86InstIdUnpcklpd_ExtendedIndex = 3, kX86InstIdUnpcklps_ExtendedIndex = 3, - kX86InstIdVaddpd_ExtendedIndex = 195, - kX86InstIdVaddps_ExtendedIndex = 195, - kX86InstIdVaddsd_ExtendedIndex = 195, - kX86InstIdVaddss_ExtendedIndex = 195, - kX86InstIdVaddsubpd_ExtendedIndex = 195, - kX86InstIdVaddsubps_ExtendedIndex = 195, - kX86InstIdVaesdec_ExtendedIndex = 196, - kX86InstIdVaesdeclast_ExtendedIndex = 196, - kX86InstIdVaesenc_ExtendedIndex = 196, - kX86InstIdVaesenclast_ExtendedIndex = 196, - kX86InstIdVaesimc_ExtendedIndex = 197, - kX86InstIdVaeskeygenassist_ExtendedIndex = 198, - kX86InstIdVandnpd_ExtendedIndex = 195, - kX86InstIdVandnps_ExtendedIndex = 195, - kX86InstIdVandpd_ExtendedIndex = 195, - kX86InstIdVandps_ExtendedIndex = 195, - kX86InstIdVblendpd_ExtendedIndex = 199, - kX86InstIdVblendps_ExtendedIndex = 199, - kX86InstIdVblendvpd_ExtendedIndex = 200, - kX86InstIdVblendvps_ExtendedIndex = 200, - kX86InstIdVbroadcastf128_ExtendedIndex = 201, - kX86InstIdVbroadcasti128_ExtendedIndex = 201, - kX86InstIdVbroadcastsd_ExtendedIndex = 202, - kX86InstIdVbroadcastss_ExtendedIndex = 202, - kX86InstIdVcmppd_ExtendedIndex = 199, - kX86InstIdVcmpps_ExtendedIndex = 199, - kX86InstIdVcmpsd_ExtendedIndex = 203, - kX86InstIdVcmpss_ExtendedIndex = 203, - kX86InstIdVcomisd_ExtendedIndex = 197, - kX86InstIdVcomiss_ExtendedIndex = 197, - kX86InstIdVcvtdq2pd_ExtendedIndex = 204, - kX86InstIdVcvtdq2ps_ExtendedIndex = 205, - kX86InstIdVcvtpd2dq_ExtendedIndex = 206, - kX86InstIdVcvtpd2ps_ExtendedIndex = 206, - kX86InstIdVcvtph2ps_ExtendedIndex = 204, - kX86InstIdVcvtps2dq_ExtendedIndex = 205, - kX86InstIdVcvtps2pd_ExtendedIndex = 204, - kX86InstIdVcvtps2ph_ExtendedIndex = 207, - kX86InstIdVcvtsd2si_ExtendedIndex = 208, - kX86InstIdVcvtsd2ss_ExtendedIndex = 196, - kX86InstIdVcvtsi2sd_ExtendedIndex = 209, - kX86InstIdVcvtsi2ss_ExtendedIndex = 209, - kX86InstIdVcvtss2sd_ExtendedIndex = 196, - kX86InstIdVcvtss2si_ExtendedIndex = 208, - kX86InstIdVcvttpd2dq_ExtendedIndex = 210, - kX86InstIdVcvttps2dq_ExtendedIndex = 205, - kX86InstIdVcvttsd2si_ExtendedIndex = 208, - kX86InstIdVcvttss2si_ExtendedIndex = 208, - kX86InstIdVdivpd_ExtendedIndex = 195, - kX86InstIdVdivps_ExtendedIndex = 195, - kX86InstIdVdivsd_ExtendedIndex = 196, - kX86InstIdVdivss_ExtendedIndex = 196, - kX86InstIdVdppd_ExtendedIndex = 203, - kX86InstIdVdpps_ExtendedIndex = 199, - kX86InstIdVextractf128_ExtendedIndex = 211, - kX86InstIdVextracti128_ExtendedIndex = 211, - kX86InstIdVextractps_ExtendedIndex = 212, - kX86InstIdVfmadd132pd_ExtendedIndex = 213, - kX86InstIdVfmadd132ps_ExtendedIndex = 195, - kX86InstIdVfmadd132sd_ExtendedIndex = 214, - kX86InstIdVfmadd132ss_ExtendedIndex = 196, - kX86InstIdVfmadd213pd_ExtendedIndex = 213, - kX86InstIdVfmadd213ps_ExtendedIndex = 195, - kX86InstIdVfmadd213sd_ExtendedIndex = 214, - kX86InstIdVfmadd213ss_ExtendedIndex = 196, - kX86InstIdVfmadd231pd_ExtendedIndex = 213, - kX86InstIdVfmadd231ps_ExtendedIndex = 195, - kX86InstIdVfmadd231sd_ExtendedIndex = 214, - kX86InstIdVfmadd231ss_ExtendedIndex = 196, - kX86InstIdVfmaddpd_ExtendedIndex = 215, - kX86InstIdVfmaddps_ExtendedIndex = 215, - kX86InstIdVfmaddsd_ExtendedIndex = 216, - kX86InstIdVfmaddss_ExtendedIndex = 216, - kX86InstIdVfmaddsub132pd_ExtendedIndex = 213, - kX86InstIdVfmaddsub132ps_ExtendedIndex = 195, - kX86InstIdVfmaddsub213pd_ExtendedIndex = 213, - kX86InstIdVfmaddsub213ps_ExtendedIndex = 195, - kX86InstIdVfmaddsub231pd_ExtendedIndex = 213, - kX86InstIdVfmaddsub231ps_ExtendedIndex = 195, - kX86InstIdVfmaddsubpd_ExtendedIndex = 215, - kX86InstIdVfmaddsubps_ExtendedIndex = 215, - kX86InstIdVfmsub132pd_ExtendedIndex = 213, - kX86InstIdVfmsub132ps_ExtendedIndex = 195, - kX86InstIdVfmsub132sd_ExtendedIndex = 214, - kX86InstIdVfmsub132ss_ExtendedIndex = 196, - kX86InstIdVfmsub213pd_ExtendedIndex = 213, - kX86InstIdVfmsub213ps_ExtendedIndex = 195, - kX86InstIdVfmsub213sd_ExtendedIndex = 214, - kX86InstIdVfmsub213ss_ExtendedIndex = 196, - kX86InstIdVfmsub231pd_ExtendedIndex = 213, - kX86InstIdVfmsub231ps_ExtendedIndex = 195, - kX86InstIdVfmsub231sd_ExtendedIndex = 214, - kX86InstIdVfmsub231ss_ExtendedIndex = 196, - kX86InstIdVfmsubadd132pd_ExtendedIndex = 213, - kX86InstIdVfmsubadd132ps_ExtendedIndex = 195, - kX86InstIdVfmsubadd213pd_ExtendedIndex = 213, - kX86InstIdVfmsubadd213ps_ExtendedIndex = 195, - kX86InstIdVfmsubadd231pd_ExtendedIndex = 213, - kX86InstIdVfmsubadd231ps_ExtendedIndex = 195, - kX86InstIdVfmsubaddpd_ExtendedIndex = 215, - kX86InstIdVfmsubaddps_ExtendedIndex = 215, - kX86InstIdVfmsubpd_ExtendedIndex = 215, - kX86InstIdVfmsubps_ExtendedIndex = 215, - kX86InstIdVfmsubsd_ExtendedIndex = 216, - kX86InstIdVfmsubss_ExtendedIndex = 216, - kX86InstIdVfnmadd132pd_ExtendedIndex = 213, - kX86InstIdVfnmadd132ps_ExtendedIndex = 195, - kX86InstIdVfnmadd132sd_ExtendedIndex = 214, - kX86InstIdVfnmadd132ss_ExtendedIndex = 196, - kX86InstIdVfnmadd213pd_ExtendedIndex = 213, - kX86InstIdVfnmadd213ps_ExtendedIndex = 195, - kX86InstIdVfnmadd213sd_ExtendedIndex = 214, - kX86InstIdVfnmadd213ss_ExtendedIndex = 196, - kX86InstIdVfnmadd231pd_ExtendedIndex = 213, - kX86InstIdVfnmadd231ps_ExtendedIndex = 195, - kX86InstIdVfnmadd231sd_ExtendedIndex = 214, - kX86InstIdVfnmadd231ss_ExtendedIndex = 196, - kX86InstIdVfnmaddpd_ExtendedIndex = 215, - kX86InstIdVfnmaddps_ExtendedIndex = 215, - kX86InstIdVfnmaddsd_ExtendedIndex = 216, - kX86InstIdVfnmaddss_ExtendedIndex = 216, - kX86InstIdVfnmsub132pd_ExtendedIndex = 213, - kX86InstIdVfnmsub132ps_ExtendedIndex = 195, - kX86InstIdVfnmsub132sd_ExtendedIndex = 214, - kX86InstIdVfnmsub132ss_ExtendedIndex = 196, - kX86InstIdVfnmsub213pd_ExtendedIndex = 213, - kX86InstIdVfnmsub213ps_ExtendedIndex = 195, - kX86InstIdVfnmsub213sd_ExtendedIndex = 214, - kX86InstIdVfnmsub213ss_ExtendedIndex = 196, - kX86InstIdVfnmsub231pd_ExtendedIndex = 213, - kX86InstIdVfnmsub231ps_ExtendedIndex = 195, - kX86InstIdVfnmsub231sd_ExtendedIndex = 214, - kX86InstIdVfnmsub231ss_ExtendedIndex = 196, - kX86InstIdVfnmsubpd_ExtendedIndex = 215, - kX86InstIdVfnmsubps_ExtendedIndex = 215, - kX86InstIdVfnmsubsd_ExtendedIndex = 216, - kX86InstIdVfnmsubss_ExtendedIndex = 216, - kX86InstIdVfrczpd_ExtendedIndex = 217, - kX86InstIdVfrczps_ExtendedIndex = 217, - kX86InstIdVfrczsd_ExtendedIndex = 218, - kX86InstIdVfrczss_ExtendedIndex = 218, - kX86InstIdVgatherdpd_ExtendedIndex = 219, - kX86InstIdVgatherdps_ExtendedIndex = 220, - kX86InstIdVgatherqpd_ExtendedIndex = 219, - kX86InstIdVgatherqps_ExtendedIndex = 221, - kX86InstIdVhaddpd_ExtendedIndex = 195, - kX86InstIdVhaddps_ExtendedIndex = 195, - kX86InstIdVhsubpd_ExtendedIndex = 195, - kX86InstIdVhsubps_ExtendedIndex = 195, - kX86InstIdVinsertf128_ExtendedIndex = 222, - kX86InstIdVinserti128_ExtendedIndex = 222, - kX86InstIdVinsertps_ExtendedIndex = 203, - kX86InstIdVlddqu_ExtendedIndex = 223, - kX86InstIdVldmxcsr_ExtendedIndex = 224, - kX86InstIdVmaskmovdqu_ExtendedIndex = 225, - kX86InstIdVmaskmovpd_ExtendedIndex = 226, - kX86InstIdVmaskmovps_ExtendedIndex = 227, - kX86InstIdVmaxpd_ExtendedIndex = 195, - kX86InstIdVmaxps_ExtendedIndex = 195, - kX86InstIdVmaxsd_ExtendedIndex = 195, - kX86InstIdVmaxss_ExtendedIndex = 195, - kX86InstIdVminpd_ExtendedIndex = 195, - kX86InstIdVminps_ExtendedIndex = 195, - kX86InstIdVminsd_ExtendedIndex = 195, - kX86InstIdVminss_ExtendedIndex = 195, - kX86InstIdVmovapd_ExtendedIndex = 228, - kX86InstIdVmovaps_ExtendedIndex = 229, - kX86InstIdVmovd_ExtendedIndex = 230, - kX86InstIdVmovddup_ExtendedIndex = 205, - kX86InstIdVmovdqa_ExtendedIndex = 231, - kX86InstIdVmovdqu_ExtendedIndex = 232, - kX86InstIdVmovhlps_ExtendedIndex = 233, - kX86InstIdVmovhpd_ExtendedIndex = 234, - kX86InstIdVmovhps_ExtendedIndex = 235, - kX86InstIdVmovlhps_ExtendedIndex = 233, - kX86InstIdVmovlpd_ExtendedIndex = 236, - kX86InstIdVmovlps_ExtendedIndex = 237, - kX86InstIdVmovmskpd_ExtendedIndex = 238, - kX86InstIdVmovmskps_ExtendedIndex = 238, - kX86InstIdVmovntdq_ExtendedIndex = 239, - kX86InstIdVmovntdqa_ExtendedIndex = 223, - kX86InstIdVmovntpd_ExtendedIndex = 240, - kX86InstIdVmovntps_ExtendedIndex = 240, - kX86InstIdVmovq_ExtendedIndex = 241, - kX86InstIdVmovsd_ExtendedIndex = 242, - kX86InstIdVmovshdup_ExtendedIndex = 205, - kX86InstIdVmovsldup_ExtendedIndex = 205, - kX86InstIdVmovss_ExtendedIndex = 243, - kX86InstIdVmovupd_ExtendedIndex = 244, - kX86InstIdVmovups_ExtendedIndex = 245, - kX86InstIdVmpsadbw_ExtendedIndex = 199, - kX86InstIdVmulpd_ExtendedIndex = 195, - kX86InstIdVmulps_ExtendedIndex = 195, - kX86InstIdVmulsd_ExtendedIndex = 195, - kX86InstIdVmulss_ExtendedIndex = 195, - kX86InstIdVorpd_ExtendedIndex = 195, - kX86InstIdVorps_ExtendedIndex = 195, - kX86InstIdVpabsb_ExtendedIndex = 205, - kX86InstIdVpabsd_ExtendedIndex = 205, - kX86InstIdVpabsw_ExtendedIndex = 205, - kX86InstIdVpackssdw_ExtendedIndex = 195, - kX86InstIdVpacksswb_ExtendedIndex = 195, - kX86InstIdVpackusdw_ExtendedIndex = 195, - kX86InstIdVpackuswb_ExtendedIndex = 195, - kX86InstIdVpaddb_ExtendedIndex = 195, - kX86InstIdVpaddd_ExtendedIndex = 195, - kX86InstIdVpaddq_ExtendedIndex = 195, - kX86InstIdVpaddsb_ExtendedIndex = 195, - kX86InstIdVpaddsw_ExtendedIndex = 195, - kX86InstIdVpaddusb_ExtendedIndex = 195, - kX86InstIdVpaddusw_ExtendedIndex = 195, - kX86InstIdVpaddw_ExtendedIndex = 195, - kX86InstIdVpalignr_ExtendedIndex = 199, - kX86InstIdVpand_ExtendedIndex = 195, - kX86InstIdVpandn_ExtendedIndex = 195, - kX86InstIdVpavgb_ExtendedIndex = 195, - kX86InstIdVpavgw_ExtendedIndex = 195, - kX86InstIdVpblendd_ExtendedIndex = 199, - kX86InstIdVpblendvb_ExtendedIndex = 246, - kX86InstIdVpblendw_ExtendedIndex = 199, - kX86InstIdVpbroadcastb_ExtendedIndex = 204, - kX86InstIdVpbroadcastd_ExtendedIndex = 204, - kX86InstIdVpbroadcastq_ExtendedIndex = 204, - kX86InstIdVpbroadcastw_ExtendedIndex = 204, - kX86InstIdVpclmulqdq_ExtendedIndex = 203, - kX86InstIdVpcmov_ExtendedIndex = 247, - kX86InstIdVpcmpeqb_ExtendedIndex = 195, - kX86InstIdVpcmpeqd_ExtendedIndex = 195, - kX86InstIdVpcmpeqq_ExtendedIndex = 195, - kX86InstIdVpcmpeqw_ExtendedIndex = 195, - kX86InstIdVpcmpestri_ExtendedIndex = 198, - kX86InstIdVpcmpestrm_ExtendedIndex = 198, - kX86InstIdVpcmpgtb_ExtendedIndex = 195, - kX86InstIdVpcmpgtd_ExtendedIndex = 195, - kX86InstIdVpcmpgtq_ExtendedIndex = 195, - kX86InstIdVpcmpgtw_ExtendedIndex = 195, - kX86InstIdVpcmpistri_ExtendedIndex = 198, - kX86InstIdVpcmpistrm_ExtendedIndex = 198, - kX86InstIdVpcomb_ExtendedIndex = 248, - kX86InstIdVpcomd_ExtendedIndex = 248, - kX86InstIdVpcomq_ExtendedIndex = 248, - kX86InstIdVpcomub_ExtendedIndex = 248, - kX86InstIdVpcomud_ExtendedIndex = 248, - kX86InstIdVpcomuq_ExtendedIndex = 248, - kX86InstIdVpcomuw_ExtendedIndex = 248, - kX86InstIdVpcomw_ExtendedIndex = 248, - kX86InstIdVperm2f128_ExtendedIndex = 249, - kX86InstIdVperm2i128_ExtendedIndex = 249, - kX86InstIdVpermd_ExtendedIndex = 250, - kX86InstIdVpermil2pd_ExtendedIndex = 251, - kX86InstIdVpermil2ps_ExtendedIndex = 251, - kX86InstIdVpermilpd_ExtendedIndex = 252, - kX86InstIdVpermilps_ExtendedIndex = 253, - kX86InstIdVpermpd_ExtendedIndex = 254, - kX86InstIdVpermps_ExtendedIndex = 250, - kX86InstIdVpermq_ExtendedIndex = 254, - kX86InstIdVpextrb_ExtendedIndex = 255, - kX86InstIdVpextrd_ExtendedIndex = 212, - kX86InstIdVpextrq_ExtendedIndex = 256, - kX86InstIdVpextrw_ExtendedIndex = 257, - kX86InstIdVpgatherdd_ExtendedIndex = 220, - kX86InstIdVpgatherdq_ExtendedIndex = 219, - kX86InstIdVpgatherqd_ExtendedIndex = 221, - kX86InstIdVpgatherqq_ExtendedIndex = 219, - kX86InstIdVphaddbd_ExtendedIndex = 218, - kX86InstIdVphaddbq_ExtendedIndex = 218, - kX86InstIdVphaddbw_ExtendedIndex = 218, - kX86InstIdVphaddd_ExtendedIndex = 195, - kX86InstIdVphadddq_ExtendedIndex = 218, - kX86InstIdVphaddsw_ExtendedIndex = 195, - kX86InstIdVphaddubd_ExtendedIndex = 218, - kX86InstIdVphaddubq_ExtendedIndex = 218, - kX86InstIdVphaddubw_ExtendedIndex = 218, - kX86InstIdVphaddudq_ExtendedIndex = 218, - kX86InstIdVphadduwd_ExtendedIndex = 218, - kX86InstIdVphadduwq_ExtendedIndex = 218, - kX86InstIdVphaddw_ExtendedIndex = 195, - kX86InstIdVphaddwd_ExtendedIndex = 218, - kX86InstIdVphaddwq_ExtendedIndex = 218, - kX86InstIdVphminposuw_ExtendedIndex = 197, - kX86InstIdVphsubbw_ExtendedIndex = 218, - kX86InstIdVphsubd_ExtendedIndex = 195, - kX86InstIdVphsubdq_ExtendedIndex = 218, - kX86InstIdVphsubsw_ExtendedIndex = 195, - kX86InstIdVphsubw_ExtendedIndex = 195, - kX86InstIdVphsubwd_ExtendedIndex = 218, - kX86InstIdVpinsrb_ExtendedIndex = 258, - kX86InstIdVpinsrd_ExtendedIndex = 259, - kX86InstIdVpinsrq_ExtendedIndex = 260, - kX86InstIdVpinsrw_ExtendedIndex = 261, - kX86InstIdVpmacsdd_ExtendedIndex = 262, - kX86InstIdVpmacsdqh_ExtendedIndex = 262, - kX86InstIdVpmacsdql_ExtendedIndex = 262, - kX86InstIdVpmacssdd_ExtendedIndex = 262, - kX86InstIdVpmacssdqh_ExtendedIndex = 262, - kX86InstIdVpmacssdql_ExtendedIndex = 262, - kX86InstIdVpmacsswd_ExtendedIndex = 262, - kX86InstIdVpmacssww_ExtendedIndex = 262, - kX86InstIdVpmacswd_ExtendedIndex = 262, - kX86InstIdVpmacsww_ExtendedIndex = 262, - kX86InstIdVpmadcsswd_ExtendedIndex = 262, - kX86InstIdVpmadcswd_ExtendedIndex = 262, - kX86InstIdVpmaddubsw_ExtendedIndex = 195, - kX86InstIdVpmaddwd_ExtendedIndex = 195, - kX86InstIdVpmaskmovd_ExtendedIndex = 263, - kX86InstIdVpmaskmovq_ExtendedIndex = 264, - kX86InstIdVpmaxsb_ExtendedIndex = 195, - kX86InstIdVpmaxsd_ExtendedIndex = 195, - kX86InstIdVpmaxsw_ExtendedIndex = 195, - kX86InstIdVpmaxub_ExtendedIndex = 195, - kX86InstIdVpmaxud_ExtendedIndex = 195, - kX86InstIdVpmaxuw_ExtendedIndex = 195, - kX86InstIdVpminsb_ExtendedIndex = 195, - kX86InstIdVpminsd_ExtendedIndex = 195, - kX86InstIdVpminsw_ExtendedIndex = 195, - kX86InstIdVpminub_ExtendedIndex = 195, - kX86InstIdVpminud_ExtendedIndex = 195, - kX86InstIdVpminuw_ExtendedIndex = 195, - kX86InstIdVpmovmskb_ExtendedIndex = 238, - kX86InstIdVpmovsxbd_ExtendedIndex = 205, - kX86InstIdVpmovsxbq_ExtendedIndex = 205, - kX86InstIdVpmovsxbw_ExtendedIndex = 205, - kX86InstIdVpmovsxdq_ExtendedIndex = 205, - kX86InstIdVpmovsxwd_ExtendedIndex = 205, - kX86InstIdVpmovsxwq_ExtendedIndex = 205, - kX86InstIdVpmovzxbd_ExtendedIndex = 205, - kX86InstIdVpmovzxbq_ExtendedIndex = 205, - kX86InstIdVpmovzxbw_ExtendedIndex = 205, - kX86InstIdVpmovzxdq_ExtendedIndex = 205, - kX86InstIdVpmovzxwd_ExtendedIndex = 205, - kX86InstIdVpmovzxwq_ExtendedIndex = 205, - kX86InstIdVpmuldq_ExtendedIndex = 195, - kX86InstIdVpmulhrsw_ExtendedIndex = 195, - kX86InstIdVpmulhuw_ExtendedIndex = 195, - kX86InstIdVpmulhw_ExtendedIndex = 195, - kX86InstIdVpmulld_ExtendedIndex = 195, - kX86InstIdVpmullw_ExtendedIndex = 195, - kX86InstIdVpmuludq_ExtendedIndex = 195, - kX86InstIdVpor_ExtendedIndex = 195, - kX86InstIdVpperm_ExtendedIndex = 265, - kX86InstIdVprotb_ExtendedIndex = 266, - kX86InstIdVprotd_ExtendedIndex = 267, - kX86InstIdVprotq_ExtendedIndex = 268, - kX86InstIdVprotw_ExtendedIndex = 269, - kX86InstIdVpsadbw_ExtendedIndex = 195, - kX86InstIdVpshab_ExtendedIndex = 270, - kX86InstIdVpshad_ExtendedIndex = 270, - kX86InstIdVpshaq_ExtendedIndex = 270, - kX86InstIdVpshaw_ExtendedIndex = 270, - kX86InstIdVpshlb_ExtendedIndex = 270, - kX86InstIdVpshld_ExtendedIndex = 270, - kX86InstIdVpshlq_ExtendedIndex = 270, - kX86InstIdVpshlw_ExtendedIndex = 270, - kX86InstIdVpshufb_ExtendedIndex = 195, - kX86InstIdVpshufd_ExtendedIndex = 271, - kX86InstIdVpshufhw_ExtendedIndex = 271, - kX86InstIdVpshuflw_ExtendedIndex = 271, - kX86InstIdVpsignb_ExtendedIndex = 195, - kX86InstIdVpsignd_ExtendedIndex = 195, - kX86InstIdVpsignw_ExtendedIndex = 195, - kX86InstIdVpslld_ExtendedIndex = 272, - kX86InstIdVpslldq_ExtendedIndex = 273, - kX86InstIdVpsllq_ExtendedIndex = 274, - kX86InstIdVpsllvd_ExtendedIndex = 195, - kX86InstIdVpsllvq_ExtendedIndex = 213, - kX86InstIdVpsllw_ExtendedIndex = 275, - kX86InstIdVpsrad_ExtendedIndex = 276, - kX86InstIdVpsravd_ExtendedIndex = 195, - kX86InstIdVpsraw_ExtendedIndex = 277, - kX86InstIdVpsrld_ExtendedIndex = 278, - kX86InstIdVpsrldq_ExtendedIndex = 273, - kX86InstIdVpsrlq_ExtendedIndex = 279, - kX86InstIdVpsrlvd_ExtendedIndex = 195, - kX86InstIdVpsrlvq_ExtendedIndex = 213, - kX86InstIdVpsrlw_ExtendedIndex = 280, - kX86InstIdVpsubb_ExtendedIndex = 195, - kX86InstIdVpsubd_ExtendedIndex = 195, - kX86InstIdVpsubq_ExtendedIndex = 195, - kX86InstIdVpsubsb_ExtendedIndex = 195, - kX86InstIdVpsubsw_ExtendedIndex = 195, - kX86InstIdVpsubusb_ExtendedIndex = 195, - kX86InstIdVpsubusw_ExtendedIndex = 195, - kX86InstIdVpsubw_ExtendedIndex = 195, - kX86InstIdVptest_ExtendedIndex = 281, - kX86InstIdVpunpckhbw_ExtendedIndex = 195, - kX86InstIdVpunpckhdq_ExtendedIndex = 195, - kX86InstIdVpunpckhqdq_ExtendedIndex = 195, - kX86InstIdVpunpckhwd_ExtendedIndex = 195, - kX86InstIdVpunpcklbw_ExtendedIndex = 195, - kX86InstIdVpunpckldq_ExtendedIndex = 195, - kX86InstIdVpunpcklqdq_ExtendedIndex = 195, - kX86InstIdVpunpcklwd_ExtendedIndex = 195, - kX86InstIdVpxor_ExtendedIndex = 195, - kX86InstIdVrcpps_ExtendedIndex = 205, - kX86InstIdVrcpss_ExtendedIndex = 196, - kX86InstIdVroundpd_ExtendedIndex = 271, - kX86InstIdVroundps_ExtendedIndex = 271, - kX86InstIdVroundsd_ExtendedIndex = 203, - kX86InstIdVroundss_ExtendedIndex = 203, - kX86InstIdVrsqrtps_ExtendedIndex = 205, - kX86InstIdVrsqrtss_ExtendedIndex = 196, - kX86InstIdVshufpd_ExtendedIndex = 199, - kX86InstIdVshufps_ExtendedIndex = 199, - kX86InstIdVsqrtpd_ExtendedIndex = 205, - kX86InstIdVsqrtps_ExtendedIndex = 205, - kX86InstIdVsqrtsd_ExtendedIndex = 196, - kX86InstIdVsqrtss_ExtendedIndex = 196, - kX86InstIdVstmxcsr_ExtendedIndex = 224, - kX86InstIdVsubpd_ExtendedIndex = 195, - kX86InstIdVsubps_ExtendedIndex = 195, - kX86InstIdVsubsd_ExtendedIndex = 196, - kX86InstIdVsubss_ExtendedIndex = 196, - kX86InstIdVtestpd_ExtendedIndex = 282, - kX86InstIdVtestps_ExtendedIndex = 282, - kX86InstIdVucomisd_ExtendedIndex = 283, - kX86InstIdVucomiss_ExtendedIndex = 283, - kX86InstIdVunpckhpd_ExtendedIndex = 195, - kX86InstIdVunpckhps_ExtendedIndex = 195, - kX86InstIdVunpcklpd_ExtendedIndex = 195, - kX86InstIdVunpcklps_ExtendedIndex = 195, - kX86InstIdVxorpd_ExtendedIndex = 195, - kX86InstIdVxorps_ExtendedIndex = 195, - kX86InstIdVzeroall_ExtendedIndex = 284, - kX86InstIdVzeroupper_ExtendedIndex = 284, - kX86InstIdWrfsbase_ExtendedIndex = 285, - kX86InstIdWrgsbase_ExtendedIndex = 285, - kX86InstIdXadd_ExtendedIndex = 286, - kX86InstIdXchg_ExtendedIndex = 287, + kX86InstIdVaddpd_ExtendedIndex = 192, + kX86InstIdVaddps_ExtendedIndex = 192, + kX86InstIdVaddsd_ExtendedIndex = 193, + kX86InstIdVaddss_ExtendedIndex = 193, + kX86InstIdVaddsubpd_ExtendedIndex = 192, + kX86InstIdVaddsubps_ExtendedIndex = 192, + kX86InstIdVaesdec_ExtendedIndex = 193, + kX86InstIdVaesdeclast_ExtendedIndex = 193, + kX86InstIdVaesenc_ExtendedIndex = 193, + kX86InstIdVaesenclast_ExtendedIndex = 193, + kX86InstIdVaesimc_ExtendedIndex = 194, + kX86InstIdVaeskeygenassist_ExtendedIndex = 195, + kX86InstIdVandnpd_ExtendedIndex = 192, + kX86InstIdVandnps_ExtendedIndex = 192, + kX86InstIdVandpd_ExtendedIndex = 192, + kX86InstIdVandps_ExtendedIndex = 192, + kX86InstIdVblendpd_ExtendedIndex = 196, + kX86InstIdVblendps_ExtendedIndex = 196, + kX86InstIdVblendvpd_ExtendedIndex = 197, + kX86InstIdVblendvps_ExtendedIndex = 197, + kX86InstIdVbroadcastf128_ExtendedIndex = 198, + kX86InstIdVbroadcasti128_ExtendedIndex = 198, + kX86InstIdVbroadcastsd_ExtendedIndex = 199, + kX86InstIdVbroadcastss_ExtendedIndex = 200, + kX86InstIdVcmppd_ExtendedIndex = 196, + kX86InstIdVcmpps_ExtendedIndex = 196, + kX86InstIdVcmpsd_ExtendedIndex = 201, + kX86InstIdVcmpss_ExtendedIndex = 201, + kX86InstIdVcomisd_ExtendedIndex = 194, + kX86InstIdVcomiss_ExtendedIndex = 194, + kX86InstIdVcvtdq2pd_ExtendedIndex = 202, + kX86InstIdVcvtdq2ps_ExtendedIndex = 203, + kX86InstIdVcvtpd2dq_ExtendedIndex = 204, + kX86InstIdVcvtpd2ps_ExtendedIndex = 204, + kX86InstIdVcvtph2ps_ExtendedIndex = 202, + kX86InstIdVcvtps2dq_ExtendedIndex = 203, + kX86InstIdVcvtps2pd_ExtendedIndex = 202, + kX86InstIdVcvtps2ph_ExtendedIndex = 205, + kX86InstIdVcvtsd2si_ExtendedIndex = 206, + kX86InstIdVcvtsd2ss_ExtendedIndex = 193, + kX86InstIdVcvtsi2sd_ExtendedIndex = 207, + kX86InstIdVcvtsi2ss_ExtendedIndex = 207, + kX86InstIdVcvtss2sd_ExtendedIndex = 193, + kX86InstIdVcvtss2si_ExtendedIndex = 206, + kX86InstIdVcvttpd2dq_ExtendedIndex = 208, + kX86InstIdVcvttps2dq_ExtendedIndex = 203, + kX86InstIdVcvttsd2si_ExtendedIndex = 206, + kX86InstIdVcvttss2si_ExtendedIndex = 206, + kX86InstIdVdivpd_ExtendedIndex = 192, + kX86InstIdVdivps_ExtendedIndex = 192, + kX86InstIdVdivsd_ExtendedIndex = 193, + kX86InstIdVdivss_ExtendedIndex = 193, + kX86InstIdVdppd_ExtendedIndex = 201, + kX86InstIdVdpps_ExtendedIndex = 196, + kX86InstIdVextractf128_ExtendedIndex = 209, + kX86InstIdVextracti128_ExtendedIndex = 209, + kX86InstIdVextractps_ExtendedIndex = 210, + kX86InstIdVfmadd132pd_ExtendedIndex = 192, + kX86InstIdVfmadd132ps_ExtendedIndex = 192, + kX86InstIdVfmadd132sd_ExtendedIndex = 193, + kX86InstIdVfmadd132ss_ExtendedIndex = 193, + kX86InstIdVfmadd213pd_ExtendedIndex = 192, + kX86InstIdVfmadd213ps_ExtendedIndex = 192, + kX86InstIdVfmadd213sd_ExtendedIndex = 193, + kX86InstIdVfmadd213ss_ExtendedIndex = 193, + kX86InstIdVfmadd231pd_ExtendedIndex = 192, + kX86InstIdVfmadd231ps_ExtendedIndex = 192, + kX86InstIdVfmadd231sd_ExtendedIndex = 193, + kX86InstIdVfmadd231ss_ExtendedIndex = 193, + kX86InstIdVfmaddpd_ExtendedIndex = 211, + kX86InstIdVfmaddps_ExtendedIndex = 211, + kX86InstIdVfmaddsd_ExtendedIndex = 212, + kX86InstIdVfmaddss_ExtendedIndex = 212, + kX86InstIdVfmaddsub132pd_ExtendedIndex = 192, + kX86InstIdVfmaddsub132ps_ExtendedIndex = 192, + kX86InstIdVfmaddsub213pd_ExtendedIndex = 192, + kX86InstIdVfmaddsub213ps_ExtendedIndex = 192, + kX86InstIdVfmaddsub231pd_ExtendedIndex = 192, + kX86InstIdVfmaddsub231ps_ExtendedIndex = 192, + kX86InstIdVfmaddsubpd_ExtendedIndex = 211, + kX86InstIdVfmaddsubps_ExtendedIndex = 211, + kX86InstIdVfmsub132pd_ExtendedIndex = 192, + kX86InstIdVfmsub132ps_ExtendedIndex = 192, + kX86InstIdVfmsub132sd_ExtendedIndex = 193, + kX86InstIdVfmsub132ss_ExtendedIndex = 193, + kX86InstIdVfmsub213pd_ExtendedIndex = 192, + kX86InstIdVfmsub213ps_ExtendedIndex = 192, + kX86InstIdVfmsub213sd_ExtendedIndex = 193, + kX86InstIdVfmsub213ss_ExtendedIndex = 193, + kX86InstIdVfmsub231pd_ExtendedIndex = 192, + kX86InstIdVfmsub231ps_ExtendedIndex = 192, + kX86InstIdVfmsub231sd_ExtendedIndex = 193, + kX86InstIdVfmsub231ss_ExtendedIndex = 193, + kX86InstIdVfmsubadd132pd_ExtendedIndex = 192, + kX86InstIdVfmsubadd132ps_ExtendedIndex = 192, + kX86InstIdVfmsubadd213pd_ExtendedIndex = 192, + kX86InstIdVfmsubadd213ps_ExtendedIndex = 192, + kX86InstIdVfmsubadd231pd_ExtendedIndex = 192, + kX86InstIdVfmsubadd231ps_ExtendedIndex = 192, + kX86InstIdVfmsubaddpd_ExtendedIndex = 211, + kX86InstIdVfmsubaddps_ExtendedIndex = 211, + kX86InstIdVfmsubpd_ExtendedIndex = 211, + kX86InstIdVfmsubps_ExtendedIndex = 211, + kX86InstIdVfmsubsd_ExtendedIndex = 212, + kX86InstIdVfmsubss_ExtendedIndex = 212, + kX86InstIdVfnmadd132pd_ExtendedIndex = 192, + kX86InstIdVfnmadd132ps_ExtendedIndex = 192, + kX86InstIdVfnmadd132sd_ExtendedIndex = 193, + kX86InstIdVfnmadd132ss_ExtendedIndex = 193, + kX86InstIdVfnmadd213pd_ExtendedIndex = 192, + kX86InstIdVfnmadd213ps_ExtendedIndex = 192, + kX86InstIdVfnmadd213sd_ExtendedIndex = 193, + kX86InstIdVfnmadd213ss_ExtendedIndex = 193, + kX86InstIdVfnmadd231pd_ExtendedIndex = 192, + kX86InstIdVfnmadd231ps_ExtendedIndex = 192, + kX86InstIdVfnmadd231sd_ExtendedIndex = 193, + kX86InstIdVfnmadd231ss_ExtendedIndex = 193, + kX86InstIdVfnmaddpd_ExtendedIndex = 211, + kX86InstIdVfnmaddps_ExtendedIndex = 211, + kX86InstIdVfnmaddsd_ExtendedIndex = 212, + kX86InstIdVfnmaddss_ExtendedIndex = 212, + kX86InstIdVfnmsub132pd_ExtendedIndex = 192, + kX86InstIdVfnmsub132ps_ExtendedIndex = 192, + kX86InstIdVfnmsub132sd_ExtendedIndex = 193, + kX86InstIdVfnmsub132ss_ExtendedIndex = 193, + kX86InstIdVfnmsub213pd_ExtendedIndex = 192, + kX86InstIdVfnmsub213ps_ExtendedIndex = 192, + kX86InstIdVfnmsub213sd_ExtendedIndex = 193, + kX86InstIdVfnmsub213ss_ExtendedIndex = 193, + kX86InstIdVfnmsub231pd_ExtendedIndex = 192, + kX86InstIdVfnmsub231ps_ExtendedIndex = 192, + kX86InstIdVfnmsub231sd_ExtendedIndex = 193, + kX86InstIdVfnmsub231ss_ExtendedIndex = 193, + kX86InstIdVfnmsubpd_ExtendedIndex = 211, + kX86InstIdVfnmsubps_ExtendedIndex = 211, + kX86InstIdVfnmsubsd_ExtendedIndex = 212, + kX86InstIdVfnmsubss_ExtendedIndex = 212, + kX86InstIdVfrczpd_ExtendedIndex = 213, + kX86InstIdVfrczps_ExtendedIndex = 213, + kX86InstIdVfrczsd_ExtendedIndex = 214, + kX86InstIdVfrczss_ExtendedIndex = 214, + kX86InstIdVgatherdpd_ExtendedIndex = 215, + kX86InstIdVgatherdps_ExtendedIndex = 215, + kX86InstIdVgatherqpd_ExtendedIndex = 215, + kX86InstIdVgatherqps_ExtendedIndex = 216, + kX86InstIdVhaddpd_ExtendedIndex = 192, + kX86InstIdVhaddps_ExtendedIndex = 192, + kX86InstIdVhsubpd_ExtendedIndex = 192, + kX86InstIdVhsubps_ExtendedIndex = 192, + kX86InstIdVinsertf128_ExtendedIndex = 217, + kX86InstIdVinserti128_ExtendedIndex = 217, + kX86InstIdVinsertps_ExtendedIndex = 201, + kX86InstIdVlddqu_ExtendedIndex = 218, + kX86InstIdVldmxcsr_ExtendedIndex = 219, + kX86InstIdVmaskmovdqu_ExtendedIndex = 220, + kX86InstIdVmaskmovpd_ExtendedIndex = 221, + kX86InstIdVmaskmovps_ExtendedIndex = 222, + kX86InstIdVmaxpd_ExtendedIndex = 192, + kX86InstIdVmaxps_ExtendedIndex = 192, + kX86InstIdVmaxsd_ExtendedIndex = 192, + kX86InstIdVmaxss_ExtendedIndex = 192, + kX86InstIdVminpd_ExtendedIndex = 192, + kX86InstIdVminps_ExtendedIndex = 192, + kX86InstIdVminsd_ExtendedIndex = 192, + kX86InstIdVminss_ExtendedIndex = 192, + kX86InstIdVmovapd_ExtendedIndex = 223, + kX86InstIdVmovaps_ExtendedIndex = 224, + kX86InstIdVmovd_ExtendedIndex = 225, + kX86InstIdVmovddup_ExtendedIndex = 203, + kX86InstIdVmovdqa_ExtendedIndex = 226, + kX86InstIdVmovdqu_ExtendedIndex = 227, + kX86InstIdVmovhlps_ExtendedIndex = 228, + kX86InstIdVmovhpd_ExtendedIndex = 229, + kX86InstIdVmovhps_ExtendedIndex = 230, + kX86InstIdVmovlhps_ExtendedIndex = 228, + kX86InstIdVmovlpd_ExtendedIndex = 231, + kX86InstIdVmovlps_ExtendedIndex = 232, + kX86InstIdVmovmskpd_ExtendedIndex = 233, + kX86InstIdVmovmskps_ExtendedIndex = 233, + kX86InstIdVmovntdq_ExtendedIndex = 234, + kX86InstIdVmovntdqa_ExtendedIndex = 218, + kX86InstIdVmovntpd_ExtendedIndex = 235, + kX86InstIdVmovntps_ExtendedIndex = 235, + kX86InstIdVmovq_ExtendedIndex = 225, + kX86InstIdVmovsd_ExtendedIndex = 236, + kX86InstIdVmovshdup_ExtendedIndex = 203, + kX86InstIdVmovsldup_ExtendedIndex = 203, + kX86InstIdVmovss_ExtendedIndex = 237, + kX86InstIdVmovupd_ExtendedIndex = 238, + kX86InstIdVmovups_ExtendedIndex = 239, + kX86InstIdVmpsadbw_ExtendedIndex = 196, + kX86InstIdVmulpd_ExtendedIndex = 192, + kX86InstIdVmulps_ExtendedIndex = 192, + kX86InstIdVmulsd_ExtendedIndex = 192, + kX86InstIdVmulss_ExtendedIndex = 192, + kX86InstIdVorpd_ExtendedIndex = 192, + kX86InstIdVorps_ExtendedIndex = 192, + kX86InstIdVpabsb_ExtendedIndex = 203, + kX86InstIdVpabsd_ExtendedIndex = 203, + kX86InstIdVpabsw_ExtendedIndex = 203, + kX86InstIdVpackssdw_ExtendedIndex = 192, + kX86InstIdVpacksswb_ExtendedIndex = 192, + kX86InstIdVpackusdw_ExtendedIndex = 192, + kX86InstIdVpackuswb_ExtendedIndex = 192, + kX86InstIdVpaddb_ExtendedIndex = 192, + kX86InstIdVpaddd_ExtendedIndex = 192, + kX86InstIdVpaddq_ExtendedIndex = 192, + kX86InstIdVpaddsb_ExtendedIndex = 192, + kX86InstIdVpaddsw_ExtendedIndex = 192, + kX86InstIdVpaddusb_ExtendedIndex = 192, + kX86InstIdVpaddusw_ExtendedIndex = 192, + kX86InstIdVpaddw_ExtendedIndex = 192, + kX86InstIdVpalignr_ExtendedIndex = 196, + kX86InstIdVpand_ExtendedIndex = 192, + kX86InstIdVpandn_ExtendedIndex = 192, + kX86InstIdVpavgb_ExtendedIndex = 192, + kX86InstIdVpavgw_ExtendedIndex = 192, + kX86InstIdVpblendd_ExtendedIndex = 196, + kX86InstIdVpblendvb_ExtendedIndex = 240, + kX86InstIdVpblendw_ExtendedIndex = 196, + kX86InstIdVpbroadcastb_ExtendedIndex = 202, + kX86InstIdVpbroadcastd_ExtendedIndex = 202, + kX86InstIdVpbroadcastq_ExtendedIndex = 202, + kX86InstIdVpbroadcastw_ExtendedIndex = 202, + kX86InstIdVpclmulqdq_ExtendedIndex = 201, + kX86InstIdVpcmov_ExtendedIndex = 241, + kX86InstIdVpcmpeqb_ExtendedIndex = 192, + kX86InstIdVpcmpeqd_ExtendedIndex = 192, + kX86InstIdVpcmpeqq_ExtendedIndex = 192, + kX86InstIdVpcmpeqw_ExtendedIndex = 192, + kX86InstIdVpcmpestri_ExtendedIndex = 195, + kX86InstIdVpcmpestrm_ExtendedIndex = 195, + kX86InstIdVpcmpgtb_ExtendedIndex = 192, + kX86InstIdVpcmpgtd_ExtendedIndex = 192, + kX86InstIdVpcmpgtq_ExtendedIndex = 192, + kX86InstIdVpcmpgtw_ExtendedIndex = 192, + kX86InstIdVpcmpistri_ExtendedIndex = 195, + kX86InstIdVpcmpistrm_ExtendedIndex = 195, + kX86InstIdVpcomb_ExtendedIndex = 242, + kX86InstIdVpcomd_ExtendedIndex = 242, + kX86InstIdVpcomq_ExtendedIndex = 242, + kX86InstIdVpcomub_ExtendedIndex = 242, + kX86InstIdVpcomud_ExtendedIndex = 242, + kX86InstIdVpcomuq_ExtendedIndex = 242, + kX86InstIdVpcomuw_ExtendedIndex = 242, + kX86InstIdVpcomw_ExtendedIndex = 242, + kX86InstIdVperm2f128_ExtendedIndex = 243, + kX86InstIdVperm2i128_ExtendedIndex = 243, + kX86InstIdVpermd_ExtendedIndex = 244, + kX86InstIdVpermil2pd_ExtendedIndex = 245, + kX86InstIdVpermil2ps_ExtendedIndex = 245, + kX86InstIdVpermilpd_ExtendedIndex = 246, + kX86InstIdVpermilps_ExtendedIndex = 247, + kX86InstIdVpermpd_ExtendedIndex = 248, + kX86InstIdVpermps_ExtendedIndex = 244, + kX86InstIdVpermq_ExtendedIndex = 248, + kX86InstIdVpextrb_ExtendedIndex = 249, + kX86InstIdVpextrd_ExtendedIndex = 210, + kX86InstIdVpextrq_ExtendedIndex = 250, + kX86InstIdVpextrw_ExtendedIndex = 251, + kX86InstIdVpgatherdd_ExtendedIndex = 215, + kX86InstIdVpgatherdq_ExtendedIndex = 215, + kX86InstIdVpgatherqd_ExtendedIndex = 216, + kX86InstIdVpgatherqq_ExtendedIndex = 215, + kX86InstIdVphaddbd_ExtendedIndex = 214, + kX86InstIdVphaddbq_ExtendedIndex = 214, + kX86InstIdVphaddbw_ExtendedIndex = 214, + kX86InstIdVphaddd_ExtendedIndex = 192, + kX86InstIdVphadddq_ExtendedIndex = 214, + kX86InstIdVphaddsw_ExtendedIndex = 192, + kX86InstIdVphaddubd_ExtendedIndex = 214, + kX86InstIdVphaddubq_ExtendedIndex = 214, + kX86InstIdVphaddubw_ExtendedIndex = 214, + kX86InstIdVphaddudq_ExtendedIndex = 214, + kX86InstIdVphadduwd_ExtendedIndex = 214, + kX86InstIdVphadduwq_ExtendedIndex = 214, + kX86InstIdVphaddw_ExtendedIndex = 192, + kX86InstIdVphaddwd_ExtendedIndex = 214, + kX86InstIdVphaddwq_ExtendedIndex = 214, + kX86InstIdVphminposuw_ExtendedIndex = 194, + kX86InstIdVphsubbw_ExtendedIndex = 214, + kX86InstIdVphsubd_ExtendedIndex = 192, + kX86InstIdVphsubdq_ExtendedIndex = 214, + kX86InstIdVphsubsw_ExtendedIndex = 192, + kX86InstIdVphsubw_ExtendedIndex = 192, + kX86InstIdVphsubwd_ExtendedIndex = 214, + kX86InstIdVpinsrb_ExtendedIndex = 252, + kX86InstIdVpinsrd_ExtendedIndex = 253, + kX86InstIdVpinsrq_ExtendedIndex = 254, + kX86InstIdVpinsrw_ExtendedIndex = 255, + kX86InstIdVpmacsdd_ExtendedIndex = 256, + kX86InstIdVpmacsdqh_ExtendedIndex = 256, + kX86InstIdVpmacsdql_ExtendedIndex = 256, + kX86InstIdVpmacssdd_ExtendedIndex = 256, + kX86InstIdVpmacssdqh_ExtendedIndex = 256, + kX86InstIdVpmacssdql_ExtendedIndex = 256, + kX86InstIdVpmacsswd_ExtendedIndex = 256, + kX86InstIdVpmacssww_ExtendedIndex = 256, + kX86InstIdVpmacswd_ExtendedIndex = 256, + kX86InstIdVpmacsww_ExtendedIndex = 256, + kX86InstIdVpmadcsswd_ExtendedIndex = 256, + kX86InstIdVpmadcswd_ExtendedIndex = 256, + kX86InstIdVpmaddubsw_ExtendedIndex = 192, + kX86InstIdVpmaddwd_ExtendedIndex = 192, + kX86InstIdVpmaskmovd_ExtendedIndex = 257, + kX86InstIdVpmaskmovq_ExtendedIndex = 257, + kX86InstIdVpmaxsb_ExtendedIndex = 192, + kX86InstIdVpmaxsd_ExtendedIndex = 192, + kX86InstIdVpmaxsw_ExtendedIndex = 192, + kX86InstIdVpmaxub_ExtendedIndex = 192, + kX86InstIdVpmaxud_ExtendedIndex = 192, + kX86InstIdVpmaxuw_ExtendedIndex = 192, + kX86InstIdVpminsb_ExtendedIndex = 192, + kX86InstIdVpminsd_ExtendedIndex = 192, + kX86InstIdVpminsw_ExtendedIndex = 192, + kX86InstIdVpminub_ExtendedIndex = 192, + kX86InstIdVpminud_ExtendedIndex = 192, + kX86InstIdVpminuw_ExtendedIndex = 192, + kX86InstIdVpmovmskb_ExtendedIndex = 233, + kX86InstIdVpmovsxbd_ExtendedIndex = 203, + kX86InstIdVpmovsxbq_ExtendedIndex = 203, + kX86InstIdVpmovsxbw_ExtendedIndex = 203, + kX86InstIdVpmovsxdq_ExtendedIndex = 203, + kX86InstIdVpmovsxwd_ExtendedIndex = 203, + kX86InstIdVpmovsxwq_ExtendedIndex = 203, + kX86InstIdVpmovzxbd_ExtendedIndex = 203, + kX86InstIdVpmovzxbq_ExtendedIndex = 203, + kX86InstIdVpmovzxbw_ExtendedIndex = 203, + kX86InstIdVpmovzxdq_ExtendedIndex = 203, + kX86InstIdVpmovzxwd_ExtendedIndex = 203, + kX86InstIdVpmovzxwq_ExtendedIndex = 203, + kX86InstIdVpmuldq_ExtendedIndex = 192, + kX86InstIdVpmulhrsw_ExtendedIndex = 192, + kX86InstIdVpmulhuw_ExtendedIndex = 192, + kX86InstIdVpmulhw_ExtendedIndex = 192, + kX86InstIdVpmulld_ExtendedIndex = 192, + kX86InstIdVpmullw_ExtendedIndex = 192, + kX86InstIdVpmuludq_ExtendedIndex = 192, + kX86InstIdVpor_ExtendedIndex = 192, + kX86InstIdVpperm_ExtendedIndex = 258, + kX86InstIdVprotb_ExtendedIndex = 259, + kX86InstIdVprotd_ExtendedIndex = 260, + kX86InstIdVprotq_ExtendedIndex = 261, + kX86InstIdVprotw_ExtendedIndex = 262, + kX86InstIdVpsadbw_ExtendedIndex = 192, + kX86InstIdVpshab_ExtendedIndex = 263, + kX86InstIdVpshad_ExtendedIndex = 263, + kX86InstIdVpshaq_ExtendedIndex = 263, + kX86InstIdVpshaw_ExtendedIndex = 263, + kX86InstIdVpshlb_ExtendedIndex = 263, + kX86InstIdVpshld_ExtendedIndex = 263, + kX86InstIdVpshlq_ExtendedIndex = 263, + kX86InstIdVpshlw_ExtendedIndex = 263, + kX86InstIdVpshufb_ExtendedIndex = 192, + kX86InstIdVpshufd_ExtendedIndex = 264, + kX86InstIdVpshufhw_ExtendedIndex = 264, + kX86InstIdVpshuflw_ExtendedIndex = 264, + kX86InstIdVpsignb_ExtendedIndex = 192, + kX86InstIdVpsignd_ExtendedIndex = 192, + kX86InstIdVpsignw_ExtendedIndex = 192, + kX86InstIdVpslld_ExtendedIndex = 265, + kX86InstIdVpslldq_ExtendedIndex = 266, + kX86InstIdVpsllq_ExtendedIndex = 267, + kX86InstIdVpsllvd_ExtendedIndex = 192, + kX86InstIdVpsllvq_ExtendedIndex = 192, + kX86InstIdVpsllw_ExtendedIndex = 268, + kX86InstIdVpsrad_ExtendedIndex = 269, + kX86InstIdVpsravd_ExtendedIndex = 192, + kX86InstIdVpsraw_ExtendedIndex = 270, + kX86InstIdVpsrld_ExtendedIndex = 271, + kX86InstIdVpsrldq_ExtendedIndex = 266, + kX86InstIdVpsrlq_ExtendedIndex = 272, + kX86InstIdVpsrlvd_ExtendedIndex = 192, + kX86InstIdVpsrlvq_ExtendedIndex = 192, + kX86InstIdVpsrlw_ExtendedIndex = 273, + kX86InstIdVpsubb_ExtendedIndex = 192, + kX86InstIdVpsubd_ExtendedIndex = 192, + kX86InstIdVpsubq_ExtendedIndex = 192, + kX86InstIdVpsubsb_ExtendedIndex = 192, + kX86InstIdVpsubsw_ExtendedIndex = 192, + kX86InstIdVpsubusb_ExtendedIndex = 192, + kX86InstIdVpsubusw_ExtendedIndex = 192, + kX86InstIdVpsubw_ExtendedIndex = 192, + kX86InstIdVptest_ExtendedIndex = 274, + kX86InstIdVpunpckhbw_ExtendedIndex = 192, + kX86InstIdVpunpckhdq_ExtendedIndex = 192, + kX86InstIdVpunpckhqdq_ExtendedIndex = 192, + kX86InstIdVpunpckhwd_ExtendedIndex = 192, + kX86InstIdVpunpcklbw_ExtendedIndex = 192, + kX86InstIdVpunpckldq_ExtendedIndex = 192, + kX86InstIdVpunpcklqdq_ExtendedIndex = 192, + kX86InstIdVpunpcklwd_ExtendedIndex = 192, + kX86InstIdVpxor_ExtendedIndex = 192, + kX86InstIdVrcpps_ExtendedIndex = 203, + kX86InstIdVrcpss_ExtendedIndex = 193, + kX86InstIdVroundpd_ExtendedIndex = 264, + kX86InstIdVroundps_ExtendedIndex = 264, + kX86InstIdVroundsd_ExtendedIndex = 201, + kX86InstIdVroundss_ExtendedIndex = 201, + kX86InstIdVrsqrtps_ExtendedIndex = 203, + kX86InstIdVrsqrtss_ExtendedIndex = 193, + kX86InstIdVshufpd_ExtendedIndex = 196, + kX86InstIdVshufps_ExtendedIndex = 196, + kX86InstIdVsqrtpd_ExtendedIndex = 203, + kX86InstIdVsqrtps_ExtendedIndex = 203, + kX86InstIdVsqrtsd_ExtendedIndex = 193, + kX86InstIdVsqrtss_ExtendedIndex = 193, + kX86InstIdVstmxcsr_ExtendedIndex = 219, + kX86InstIdVsubpd_ExtendedIndex = 192, + kX86InstIdVsubps_ExtendedIndex = 192, + kX86InstIdVsubsd_ExtendedIndex = 193, + kX86InstIdVsubss_ExtendedIndex = 193, + kX86InstIdVtestpd_ExtendedIndex = 275, + kX86InstIdVtestps_ExtendedIndex = 275, + kX86InstIdVucomisd_ExtendedIndex = 276, + kX86InstIdVucomiss_ExtendedIndex = 276, + kX86InstIdVunpckhpd_ExtendedIndex = 192, + kX86InstIdVunpckhps_ExtendedIndex = 192, + kX86InstIdVunpcklpd_ExtendedIndex = 192, + kX86InstIdVunpcklps_ExtendedIndex = 192, + kX86InstIdVxorpd_ExtendedIndex = 192, + kX86InstIdVxorps_ExtendedIndex = 192, + kX86InstIdVzeroall_ExtendedIndex = 277, + kX86InstIdVzeroupper_ExtendedIndex = 277, + kX86InstIdWrfsbase_ExtendedIndex = 278, + kX86InstIdWrgsbase_ExtendedIndex = 278, + kX86InstIdXadd_ExtendedIndex = 279, + kX86InstIdXchg_ExtendedIndex = 280, + kX86InstIdXgetbv_ExtendedIndex = 16, kX86InstIdXor_ExtendedIndex = 2, kX86InstIdXorpd_ExtendedIndex = 3, - kX86InstIdXorps_ExtendedIndex = 3 + kX86InstIdXorps_ExtendedIndex = 3, + kX86InstIdXrstor_ExtendedIndex = 281, + kX86InstIdXrstor64_ExtendedIndex = 281, + kX86InstIdXsave_ExtendedIndex = 281, + kX86InstIdXsave64_ExtendedIndex = 281, + kX86InstIdXsaveopt_ExtendedIndex = 281, + kX86InstIdXsaveopt64_ExtendedIndex = 281, + kX86InstIdXsetbv_ExtendedIndex = 16 }; // ${X86InstData:End} -// Instruction data. -// -// Please rerun tools/src-gendefs.js (by using node.js) to regenerate instruction -// names and extended info tables. +// Please run tools/src-gendefs.js (by using just node.js, without any dependencies) to regenerate the code above. const X86InstInfo _x86InstInfo[] = { - // Inst-Code | Inst-Name | Inst-Group | Inst-Flags | M | Op-Flags[0] | Op-Flags[1] | Op-Flags[2] | Op-Flags[2] | E-OSZAPCDX | OpCode[0] | OpCode[1] | - INST(kInstIdNone , "" , G(None) , F(None) , 0 , U , U , U , U , E(________) , U , U ), - INST(kX86InstIdAdc , "adc" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(10,2) , U ), - INST(kX86InstIdAdd , "add" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(00,0) , U ), - INST(kX86InstIdAddpd , "addpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(58,U) , U ), - INST(kX86InstIdAddps , "addps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(58,U) , U ), - INST(kX86InstIdAddsd , "addsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(58,U) , U ), - INST(kX86InstIdAddss , "addss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(58,U) , U ), - INST(kX86InstIdAddsubpd , "addsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(D0,U) , U ), - INST(kX86InstIdAddsubps , "addsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(D0,U) , U ), - INST(kX86InstIdAesdec , "aesdec" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DE,U) , U ), - INST(kX86InstIdAesdeclast , "aesdeclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DF,U) , U ), - INST(kX86InstIdAesenc , "aesenc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DC,U) , U ), - INST(kX86InstIdAesenclast , "aesenclast" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DD,U) , U ), - INST(kX86InstIdAesimc , "aesimc" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ), - INST(kX86InstIdAeskeygenassist , "aeskeygenassist" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ), - INST(kX86InstIdAnd , "and" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(20,4) , U ), - INST(kX86InstIdAndn , "andn" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(WWWUUW__) , O_000F38(F2,U) , U ), - INST(kX86InstIdAndnpd , "andnpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(55,U) , U ), - INST(kX86InstIdAndnps , "andnps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(55,U) , U ), - INST(kX86InstIdAndpd , "andpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(54,U) , U ), - INST(kX86InstIdAndps , "andps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(54,U) , U ), - INST(kX86InstIdBextr , "bextr" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WUWUUW__) , O_000F38(F7,U) , U ), - INST(kX86InstIdBlendpd , "blendpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0D,U) , U ), - INST(kX86InstIdBlendps , "blendps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0C,U) , U ), - INST(kX86InstIdBlendvpd , "blendvpd" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(15,U) , U ), - INST(kX86InstIdBlendvps , "blendvps" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(14,U) , U ), - INST(kX86InstIdBlsi , "blsi" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,3) , U ), - INST(kX86InstIdBlsmsk , "blsmsk" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,2) , U ), - INST(kX86InstIdBlsr , "blsr" , G(AvxVm) , F(None) , 0 , O(Gqd) , O(GqdMem) , U , U , E(WWWUUW__) , O_000F38(F3,1) , U ), - INST(kX86InstIdBsf , "bsf" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BC,U) , U ), - INST(kX86InstIdBsr , "bsr" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUU__) , O_000F00(BD,U) , U ), - INST(kX86InstIdBswap , "bswap" , G(X86BSwap) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_000F00(C8,U) , U ), - INST(kX86InstIdBt , "bt" , G(X86BTest) , F(Test) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(A3,U) , O_000F00(BA,4) ), - INST(kX86InstIdBtc , "btc" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(BB,U) , O_000F00(BA,7) ), - INST(kX86InstIdBtr , "btr" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(B3,U) , O_000F00(BA,6) ), - INST(kX86InstIdBts , "bts" , G(X86BTest) , F(Lock) , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , E(UU_UUW__) , O_000F00(AB,U) , O_000F00(BA,5) ), - INST(kX86InstIdBzhi , "bzhi" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(WWWUUW__) , O_000F38(F5,U) , U ), - INST(kX86InstIdCall , "call" , G(X86Call) , F(Flow) , 0 , O(GqdMem)|O(Imm)|O(Label), U , U , U , E(________) , O_000000(FF,2) , O_000000(E8,U) ), - INST(kX86InstIdCbw , "cbw" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(98,U) , U ), - INST(kX86InstIdCdq , "cdq" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(99,U) , U ), - INST(kX86InstIdCdqe , "cdqe" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(98,U) , U ), - INST(kX86InstIdClc , "clc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F8,U) , U ), - INST(kX86InstIdCld , "cld" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FC,U) , U ), - INST(kX86InstIdClflush , "clflush" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,7) , U ), - INST(kX86InstIdCmc , "cmc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____X__) , O_000000(F5,U) , U ), - INST(kX86InstIdCmova , "cmova" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ), - INST(kX86InstIdCmovae , "cmovae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), - INST(kX86InstIdCmovb , "cmovb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), - INST(kX86InstIdCmovbe , "cmovbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ), - INST(kX86InstIdCmovc , "cmovc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), - INST(kX86InstIdCmove , "cmove" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ), - INST(kX86InstIdCmovg , "cmovg" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ), - INST(kX86InstIdCmovge , "cmovge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ), - INST(kX86InstIdCmovl , "cmovl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ), - INST(kX86InstIdCmovle , "cmovle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ), - INST(kX86InstIdCmovna , "cmovna" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(46,U) , U ), - INST(kX86InstIdCmovnae , "cmovnae" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(42,U) , U ), - INST(kX86InstIdCmovnb , "cmovnb" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), - INST(kX86InstIdCmovnbe , "cmovnbe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R__R__) , O_000F00(47,U) , U ), - INST(kX86InstIdCmovnc , "cmovnc" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_____R__) , O_000F00(43,U) , U ), - INST(kX86InstIdCmovne , "cmovne" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ), - INST(kX86InstIdCmovng , "cmovng" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4E,U) , U ), - INST(kX86InstIdCmovnge , "cmovnge" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4C,U) , U ), - INST(kX86InstIdCmovnl , "cmovnl" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RR______) , O_000F00(4D,U) , U ), - INST(kX86InstIdCmovnle , "cmovnle" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(RRR_____) , O_000F00(4F,U) , U ), - INST(kX86InstIdCmovno , "cmovno" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(41,U) , U ), - INST(kX86InstIdCmovnp , "cmovnp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ), - INST(kX86InstIdCmovns , "cmovns" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(49,U) , U ), - INST(kX86InstIdCmovnz , "cmovnz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(45,U) , U ), - INST(kX86InstIdCmovo , "cmovo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(R_______) , O_000F00(40,U) , U ), - INST(kX86InstIdCmovp , "cmovp" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ), - INST(kX86InstIdCmovpe , "cmovpe" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4A,U) , U ), - INST(kX86InstIdCmovpo , "cmovpo" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(____R___) , O_000F00(4B,U) , U ), - INST(kX86InstIdCmovs , "cmovs" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(_R______) , O_000F00(48,U) , U ), - INST(kX86InstIdCmovz , "cmovz" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(__R_____) , O_000F00(44,U) , U ), - INST(kX86InstIdCmp , "cmp" , G(X86Arith) , F(Test) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(38,7) , U ), - INST(kX86InstIdCmppd , "cmppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C2,U) , U ), - INST(kX86InstIdCmpps , "cmpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C2,U) , U ), - INST(kX86InstIdCmpsB , "cmps_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A6,U) , U ), - INST(kX86InstIdCmpsD , "cmps_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), - INST(kX86InstIdCmpsQ , "cmps_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), - INST(kX86InstIdCmpsW , "cmps_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(A7,U) , U ), - INST(kX86InstIdCmpsd , "cmpsd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(C2,U) , U ), - INST(kX86InstIdCmpss , "cmpss" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(C2,U) , U ), - INST(kX86InstIdCmpxchg , "cmpxchg" , G(X86RmReg) , F(Lock)|F(Special) , 0 , U , U , U , U , E(WWWWWW__) , O_000F00(B0,U) , U ), - INST(kX86InstIdCmpxchg16b , "cmpxchg16b" , G(X86M) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ), - INST(kX86InstIdCmpxchg8b , "cmpxchg8b" , G(X86M) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(__W_____) , O_000F00(C7,1) , U ), - INST(kX86InstIdComisd , "comisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2F,U) , U ), - INST(kX86InstIdComiss , "comiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2F,U) , U ), - INST(kX86InstIdCpuid , "cpuid" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(A2,U) , U ), - INST(kX86InstIdCqo , "cqo" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(99,U) , U ), - INST(kX86InstIdCrc32 , "crc32" , G(ExtCrc) , F(None) , 0 , O(Gqd) , O(GqdwbMem) , U , U , E(________) , O_F20F38(F0,U) , U ), - INST(kX86InstIdCvtdq2pd , "cvtdq2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ), - INST(kX86InstIdCvtdq2ps , "cvtdq2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5B,U) , U ), - INST(kX86InstIdCvtpd2dq , "cvtpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ), - INST(kX86InstIdCvtpd2pi , "cvtpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2D,U) , U ), - INST(kX86InstIdCvtpd2ps , "cvtpd2ps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5A,U) , U ), - INST(kX86InstIdCvtpi2pd , "cvtpi2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(MmMem) , U , U , E(________) , O_660F00(2A,U) , U ), - INST(kX86InstIdCvtpi2ps , "cvtpi2ps" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(MmMem) , U , U , E(________) , O_000F00(2A,U) , U ), - INST(kX86InstIdCvtps2dq , "cvtps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5B,U) , U ), - INST(kX86InstIdCvtps2pd , "cvtps2pd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ), - INST(kX86InstIdCvtps2pi , "cvtps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2D,U) , U ), - INST(kX86InstIdCvtsd2si , "cvtsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), - INST(kX86InstIdCvtsd2ss , "cvtsd2ss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5A,U) , U ), - INST(kX86InstIdCvtsi2sd , "cvtsi2sd" , G(ExtRm_Q) , F(Move) , 8 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F20F00(2A,U) , U ), - INST(kX86InstIdCvtsi2ss , "cvtsi2ss" , G(ExtRm_Q) , F(Move) , 4 , O(Xmm) , O(GqdMem) , U , U , E(________) , O_F30F00(2A,U) , U ), - INST(kX86InstIdCvtss2sd , "cvtss2sd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5A,U) , U ), - INST(kX86InstIdCvtss2si , "cvtss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2D,U) , U ), - INST(kX86InstIdCvttpd2dq , "cvttpd2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(E6,U) , U ), - INST(kX86InstIdCvttpd2pi , "cvttpd2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_660F00(2C,U) , U ), - INST(kX86InstIdCvttps2dq , "cvttps2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ), - INST(kX86InstIdCvttps2pi , "cvttps2pi" , G(ExtRm) , F(Move) , 8 , O(Mm) , O(XmmMem) , U , U , E(________) , O_000F00(2C,U) , U ), - INST(kX86InstIdCvttsd2si , "cvttsd2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ), - INST(kX86InstIdCvttss2si , "cvttss2si" , G(ExtRm_Q) , F(Move) , 8 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ), - INST(kX86InstIdCwd , "cwd" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_660000(99,U) , U ), - INST(kX86InstIdCwde , "cwde" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(98,U) , U ), - INST(kX86InstIdDaa , "daa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(27,U) , U ), - INST(kX86InstIdDas , "das" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(UWWXWX__) , O_000000(2F,U) , U ), - INST(kX86InstIdDec , "dec" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,1) , O_000000(48,U) ), - INST(kX86InstIdDiv , "div" , G(X86Rm_B) , F(None)|F(Special) , 0 , U , U , U , U , E(UUUUUU__) , O_000000(F6,6) , U ), - INST(kX86InstIdDivpd , "divpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5E,U) , U ), - INST(kX86InstIdDivps , "divps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5E,U) , U ), - INST(kX86InstIdDivsd , "divsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5E,U) , U ), - INST(kX86InstIdDivss , "divss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5E,U) , U ), - INST(kX86InstIdDppd , "dppd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(41,U) , U ), - INST(kX86InstIdDpps , "dpps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(40,U) , U ), - INST(kX86InstIdEmms , "emms" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ), - INST(kX86InstIdEnter , "enter" , G(X86Enter) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C8,U) , U ), - INST(kX86InstIdExtractps , "extractps" , G(ExtExtract) , F(Move) , 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_660F3A(17,U) , O_660F3A(17,U) ), - INST(kX86InstIdF2xm1 , "f2xm1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F0,U) , U ), - INST(kX86InstIdFabs , "fabs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E1,U) , U ), - INST(kX86InstIdFadd , "fadd" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C0C0,0) , U ), - INST(kX86InstIdFaddp , "faddp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC0,U) , U ), - INST(kX86InstIdFbld , "fbld" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,4) , U ), - INST(kX86InstIdFbstp , "fbstp" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DF,6) , U ), - INST(kX86InstIdFchs , "fchs" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E0,U) , U ), - INST(kX86InstIdFclex , "fclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE2,U) , U ), - INST(kX86InstIdFcmovb , "fcmovb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DAC0,U) , U ), - INST(kX86InstIdFcmovbe , "fcmovbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DAD0,U) , U ), - INST(kX86InstIdFcmove , "fcmove" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DAC8,U) , U ), - INST(kX86InstIdFcmovnb , "fcmovnb" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(_____R__) , O_00_X(DBC0,U) , U ), - INST(kX86InstIdFcmovnbe , "fcmovnbe" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R__R__) , O_00_X(DBD0,U) , U ), - INST(kX86InstIdFcmovne , "fcmovne" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(__R_____) , O_00_X(DBC8,U) , U ), - INST(kX86InstIdFcmovnu , "fcmovnu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DBD8,U) , U ), - INST(kX86InstIdFcmovu , "fcmovu" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(____R___) , O_00_X(DAD8,U) , U ), - INST(kX86InstIdFcom , "fcom" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D0D0,2) , U ), - INST(kX86InstIdFcomi , "fcomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBF0,U) , U ), - INST(kX86InstIdFcomip , "fcomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFF0,U) , U ), - INST(kX86InstIdFcomp , "fcomp" , G(FpuCom) , F(Fp) , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , E(________) , O_00_X(D8D8,3) , U ), - INST(kX86InstIdFcompp , "fcompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DED9,U) , U ), - INST(kX86InstIdFcos , "fcos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FF,U) , U ), - INST(kX86InstIdFdecstp , "fdecstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F6,U) , U ), - INST(kX86InstIdFdiv , "fdiv" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F0F8,6) , U ), - INST(kX86InstIdFdivp , "fdivp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF8,U) , U ), - INST(kX86InstIdFdivr , "fdivr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(F8F0,7) , U ), - INST(kX86InstIdFdivrp , "fdivrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEF0,U) , U ), - INST(kX86InstIdFemms , "femms" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000F00(0E,U) , U ), - INST(kX86InstIdFfree , "ffree" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDC0,U) , U ), - INST(kX86InstIdFiadd , "fiadd" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,0) , U ), - INST(kX86InstIdFicom , "ficom" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,2) , U ), - INST(kX86InstIdFicomp , "ficomp" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,3) , U ), - INST(kX86InstIdFidiv , "fidiv" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,6) , U ), - INST(kX86InstIdFidivr , "fidivr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,7) , U ), - INST(kX86InstIdFild , "fild" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,0) , O_000000(DF,5) ), - INST(kX86InstIdFimul , "fimul" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,1) , U ), - INST(kX86InstIdFincstp , "fincstp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F7,U) , U ), - INST(kX86InstIdFinit , "finit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_9B_X(DBE3,U) , U ), - INST(kX86InstIdFist , "fist" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,2) , U ), - INST(kX86InstIdFistp , "fistp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,3) , O_000000(DF,7) ), - INST(kX86InstIdFisttp , "fisttp" , G(FpuM) , F(Fp)|F(Mem2_4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DB,1) , O_000000(DD,1) ), - INST(kX86InstIdFisub , "fisub" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,4) , U ), - INST(kX86InstIdFisubr , "fisubr" , G(FpuM) , F(Fp)|F(Mem2_4) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DA,5) , U ), - INST(kX86InstIdFld , "fld" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,0) , O_000000(DB,5) ), - INST(kX86InstIdFld1 , "fld1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E8,U) , U ), - INST(kX86InstIdFldcw , "fldcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,5) , U ), - INST(kX86InstIdFldenv , "fldenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,4) , U ), - INST(kX86InstIdFldl2e , "fldl2e" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EA,U) , U ), - INST(kX86InstIdFldl2t , "fldl2t" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E9,U) , U ), - INST(kX86InstIdFldlg2 , "fldlg2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EC,U) , U ), - INST(kX86InstIdFldln2 , "fldln2" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9ED,U) , U ), - INST(kX86InstIdFldpi , "fldpi" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EB,U) , U ), - INST(kX86InstIdFldz , "fldz" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9EE,U) , U ), - INST(kX86InstIdFmul , "fmul" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(C8C8,1) , U ), - INST(kX86InstIdFmulp , "fmulp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEC8,U) , U ), - INST(kX86InstIdFnclex , "fnclex" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE2,U) , U ), - INST(kX86InstIdFninit , "fninit" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DBE3,U) , U ), - INST(kX86InstIdFnop , "fnop" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9D0,U) , U ), - INST(kX86InstIdFnsave , "fnsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,6) , U ), - INST(kX86InstIdFnstcw , "fnstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,7) , U ), - INST(kX86InstIdFnstenv , "fnstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,6) , U ), - INST(kX86InstIdFnstsw , "fnstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,7) , O_00_X(DFE0,U) ), - INST(kX86InstIdFpatan , "fpatan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F3,U) , U ), - INST(kX86InstIdFprem , "fprem" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F8,U) , U ), - INST(kX86InstIdFprem1 , "fprem1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F5,U) , U ), - INST(kX86InstIdFptan , "fptan" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F2,U) , U ), - INST(kX86InstIdFrndint , "frndint" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FC,U) , U ), - INST(kX86InstIdFrstor , "frstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000000(DD,4) , U ), - INST(kX86InstIdFsave , "fsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,6) , U ), - INST(kX86InstIdFscale , "fscale" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FD,U) , U ), - INST(kX86InstIdFsin , "fsin" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FE,U) , U ), - INST(kX86InstIdFsincos , "fsincos" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FB,U) , U ), - INST(kX86InstIdFsqrt , "fsqrt" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9FA,U) , U ), - INST(kX86InstIdFst , "fst" , G(FpuFldFst) , F(Fp)|F(Mem4_8) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,2) , U ), - INST(kX86InstIdFstcw , "fstcw" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,7) , U ), - INST(kX86InstIdFstenv , "fstenv" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(D9,6) , U ), - INST(kX86InstIdFstp , "fstp" , G(FpuFldFst) , F(Fp)|F(Mem4_8_10) , 0 , O(Mem) , U , U , U , E(________) , O_000000(D9,3) , O_000000(DB,7) ), - INST(kX86InstIdFstsw , "fstsw" , G(FpuStsw) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_9B0000(DD,7) , O_9B_X(DFE0,U) ), - INST(kX86InstIdFsub , "fsub" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E0E8,4) , U ), - INST(kX86InstIdFsubp , "fsubp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE8,U) , U ), - INST(kX86InstIdFsubr , "fsubr" , G(FpuArith) , F(Fp)|F(Mem4_8) , 0 , O(FpMem) , O(Fp) , U , U , E(________) , O_00_X(E8E0,5) , U ), - INST(kX86InstIdFsubrp , "fsubrp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DEE0,U) , U ), - INST(kX86InstIdFtst , "ftst" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E4,U) , U ), - INST(kX86InstIdFucom , "fucom" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE0,U) , U ), - INST(kX86InstIdFucomi , "fucomi" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DBE8,U) , U ), - INST(kX86InstIdFucomip , "fucomip" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(WWWWWW__) , O_00_X(DFE8,U) , U ), - INST(kX86InstIdFucomp , "fucomp" , G(FpuRDef) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(DDE8,U) , U ), - INST(kX86InstIdFucompp , "fucompp" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(DAE9,U) , U ), - INST(kX86InstIdFwait , "fwait" , G(X86Op) , F(Fp) , 0 , U , U , U , U , E(________) , O_000000(DB,U) , U ), - INST(kX86InstIdFxam , "fxam" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9E5,U) , U ), - INST(kX86InstIdFxch , "fxch" , G(FpuR) , F(Fp) , 0 , O(Fp) , U , U , U , E(________) , O_00_X(D9C8,U) , U ), - INST(kX86InstIdFxrstor , "fxrstor" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,1) , U ), - INST(kX86InstIdFxsave , "fxsave" , G(X86M) , F(Fp) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,0) , U ), - INST(kX86InstIdFxtract , "fxtract" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F4,U) , U ), - INST(kX86InstIdFyl2x , "fyl2x" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F1,U) , U ), - INST(kX86InstIdFyl2xp1 , "fyl2xp1" , G(FpuOp) , F(Fp) , 0 , U , U , U , U , E(________) , O_00_X(D9F9,U) , U ), - INST(kX86InstIdHaddpd , "haddpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7C,U) , U ), - INST(kX86InstIdHaddps , "haddps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7C,U) , U ), - INST(kX86InstIdHsubpd , "hsubpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(7D,U) , U ), - INST(kX86InstIdHsubps , "hsubps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(7D,U) , U ), - INST(kX86InstIdIdiv , "idiv" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(UUUUUU__) , O_000000(F6,7) , U ), - INST(kX86InstIdImul , "imul" , G(X86Imul) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , U , U ), - INST(kX86InstIdInc , "inc" , G(X86IncDec) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWW___) , O_000000(FE,0) , O_000000(40,U) ), - INST(kX86InstIdInsertps , "insertps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(21,U) , U ), - INST(kX86InstIdInt , "int" , G(X86Int) , F(None) , 0 , U , U , U , U , E(_______W) , O_000000(CC,U) , U ), - INST(kX86InstIdJa , "ja" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ), - INST(kX86InstIdJae , "jae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), - INST(kX86InstIdJb , "jb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), - INST(kX86InstIdJbe , "jbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ), - INST(kX86InstIdJc , "jc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), - INST(kX86InstIdJe , "je" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ), - INST(kX86InstIdJg , "jg" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ), - INST(kX86InstIdJge , "jge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ), - INST(kX86InstIdJl , "jl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ), - INST(kX86InstIdJle , "jle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ), - INST(kX86InstIdJna , "jna" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(76,U) , U ), - INST(kX86InstIdJnae , "jnae" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(72,U) , U ), - INST(kX86InstIdJnb , "jnb" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), - INST(kX86InstIdJnbe , "jnbe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R__R__) , O_000000(77,U) , U ), - INST(kX86InstIdJnc , "jnc" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_____R__) , O_000000(73,U) , U ), - INST(kX86InstIdJne , "jne" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ), - INST(kX86InstIdJng , "jng" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7E,U) , U ), - INST(kX86InstIdJnge , "jnge" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7C,U) , U ), - INST(kX86InstIdJnl , "jnl" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RR______) , O_000000(7D,U) , U ), - INST(kX86InstIdJnle , "jnle" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(RRR_____) , O_000000(7F,U) , U ), - INST(kX86InstIdJno , "jno" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(71,U) , U ), - INST(kX86InstIdJnp , "jnp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ), - INST(kX86InstIdJns , "jns" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(79,U) , U ), - INST(kX86InstIdJnz , "jnz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(75,U) , U ), - INST(kX86InstIdJo , "jo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(R_______) , O_000000(70,U) , U ), - INST(kX86InstIdJp , "jp" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ), - INST(kX86InstIdJpe , "jpe" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7A,U) , U ), - INST(kX86InstIdJpo , "jpo" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(____R___) , O_000000(7B,U) , U ), - INST(kX86InstIdJs , "js" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(_R______) , O_000000(78,U) , U ), - INST(kX86InstIdJz , "jz" , G(X86Jcc) , F(Flow) , 0 , O(Label) , U , U , U , E(__R_____) , O_000000(74,U) , U ), - INST(kX86InstIdJecxz , "jecxz" , G(X86Jecxz) , F(Flow)|F(Special) , 0 , O(Gqdw) , O(Label) , U , U , E(________) , O_000000(E3,U) , U ), - INST(kX86InstIdJmp , "jmp" , G(X86Jmp) , F(Flow) , 0 , O(Imm)|O(Label) , U , U , U , E(________) , O_000000(FF,4) , O_000000(E9,U) ), - INST(kX86InstIdLahf , "lahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_RRRRR__) , O_000000(9F,U) , U ), - INST(kX86InstIdLddqu , "lddqu" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ), - INST(kX86InstIdLdmxcsr , "ldmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ), - INST(kX86InstIdLea , "lea" , G(X86Lea) , F(Move) , 0 , O(Gqd) , O(Mem) , U , U , E(________) , O_000000(8D,U) , U ), - INST(kX86InstIdLeave , "leave" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C9,U) , U ), - INST(kX86InstIdLfence , "lfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,5) , U ), - INST(kX86InstIdLodsB , "lods_b" , G(X86Op) , F(Move)|F(Special) , 1 , U , U , U , U , E(______R_) , O_000000(AC,U) , U ), - INST(kX86InstIdLodsD , "lods_d" , G(X86Op) , F(Move)|F(Special) , 4 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), - INST(kX86InstIdLodsQ , "lods_q" , G(X86Op) , F(Move)|F(Special)|F(W), 8 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), - INST(kX86InstIdLodsW , "lods_w" , G(X86Op_66H) , F(Move)|F(Special) , 2 , U , U , U , U , E(______R_) , O_000000(AD,U) , U ), - INST(kX86InstIdLzcnt , "lzcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BD,U) , U ), - INST(kX86InstIdMaskmovdqu , "maskmovdqu" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(57,U) , U ), - INST(kX86InstIdMaskmovq , "maskmovq" , G(ExtRm) , F(None)|F(Special) , 0 , O(Mm) , O(Mm) , U , U , E(________) , O_000F00(F7,U) , U ), - INST(kX86InstIdMaxpd , "maxpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5F,U) , U ), - INST(kX86InstIdMaxps , "maxps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5F,U) , U ), - INST(kX86InstIdMaxsd , "maxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5F,U) , U ), - INST(kX86InstIdMaxss , "maxss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5F,U) , U ), - INST(kX86InstIdMfence , "mfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,6) , U ), - INST(kX86InstIdMinpd , "minpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5D,U) , U ), - INST(kX86InstIdMinps , "minps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5D,U) , U ), - INST(kX86InstIdMinsd , "minsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5D,U) , U ), - INST(kX86InstIdMinss , "minss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5D,U) , U ), - INST(kX86InstIdMonitor , "monitor" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C8,U) , U ), - INST(kX86InstIdMov , "mov" , G(X86Mov) , F(Move) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(________) , U , U ), - INST(kX86InstIdMovPtr , "mov_ptr" , G(X86MovPtr) , F(Move)|F(Special) , 0 , O(Gqdwb) , O(Imm) , U , U , E(________) , O_000000(A0,U) , O_000000(A2,U) ), - INST(kX86InstIdMovapd , "movapd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ), - INST(kX86InstIdMovaps , "movaps" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ), - INST(kX86InstIdMovbe , "movbe" , G(ExtMovBe) , F(Move) , 0 , O(GqdwMem) , O(GqdwMem) , U , U , E(________) , O_000F38(F0,U) , O_000F38(F1,U) ), - INST(kX86InstIdMovd , "movd" , G(ExtMovD) , F(Move) , 16, O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , E(________) , O_000F00(6E,U) , O_000F00(7E,U) ), - INST(kX86InstIdMovddup , "movddup" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(12,U) , U ), - INST(kX86InstIdMovdq2q , "movdq2q" , G(ExtMov) , F(Move) , 8 , O(Mm) , O(Xmm) , U , U , E(________) , O_F20F00(D6,U) , U ), - INST(kX86InstIdMovdqa , "movdqa" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ), - INST(kX86InstIdMovdqu , "movdqu" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ), - INST(kX86InstIdMovhlps , "movhlps" , G(ExtMov) , F(Move) , 8 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(12,U) , U ), - INST(kX86InstIdMovhpd , "movhpd" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ), - INST(kX86InstIdMovhps , "movhps" , G(ExtMov) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ), - INST(kX86InstIdMovlhps , "movlhps" , G(ExtMov) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_000F00(16,U) , U ), - INST(kX86InstIdMovlpd , "movlpd" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ), - INST(kX86InstIdMovlps , "movlps" , G(ExtMov) , F(Move) , 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ), - INST(kX86InstIdMovmskpd , "movmskpd" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_660F00(50,U) , U ), - INST(kX86InstIdMovmskps , "movmskps" , G(ExtMovNoRexW) , F(Move) , 8 , O(Gqd) , O(Xmm) , U , U , E(________) , O_000F00(50,U) , U ), - INST(kX86InstIdMovntdq , "movntdq" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(E7,U) ), - INST(kX86InstIdMovntdqa , "movntdqa" , G(ExtMov) , F(Move) , 16, O(Xmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ), - INST(kX86InstIdMovnti , "movnti" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Gqd) , U , U , E(________) , U , O_000F00(C3,U) ), - INST(kX86InstIdMovntpd , "movntpd" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_660F00(2B,U) ), - INST(kX86InstIdMovntps , "movntps" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , E(________) , U , O_000F00(2B,U) ), - INST(kX86InstIdMovntq , "movntq" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Mm) , U , U , E(________) , U , O_000F00(E7,U) ), - INST(kX86InstIdMovq , "movq" , G(ExtMovQ) , F(Move) , 16, O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , E(________) , U , U ), - INST(kX86InstIdMovq2dq , "movq2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mm) , U , U , E(________) , O_F30F00(D6,U) , U ), - INST(kX86InstIdMovsB , "movs_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A4,U) , U ), - INST(kX86InstIdMovsD , "movs_d" , G(X86Op) , F(Move)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), - INST(kX86InstIdMovsQ , "movs_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), - INST(kX86InstIdMovsW , "movs_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(A5,U) , U ), - INST(kX86InstIdMovsd , "movsd" , G(ExtMov) , F(Move) |F(Z), 8 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ), - INST(kX86InstIdMovshdup , "movshdup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(16,U) , U ), - INST(kX86InstIdMovsldup , "movsldup" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(12,U) , U ), - INST(kX86InstIdMovss , "movss" , G(ExtMov) , F(Move) |F(Z), 4 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ), - INST(kX86InstIdMovsx , "movsx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(BE,U) , U ), - INST(kX86InstIdMovsxd , "movsxd" , G(X86MovSxd) , F(Move) , 0 , O(Gq) , O(GdMem) , U , U , E(________) , O_000000(63,U) , U ), - INST(kX86InstIdMovupd , "movupd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ), - INST(kX86InstIdMovups , "movups" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ), - INST(kX86InstIdMovzx , "movzx" , G(X86MovSxZx) , F(Move) , 0 , O(Gqdw) , O(GwbMem) , U , U , E(________) , O_000F00(B6,U) , U ), - INST(kX86InstIdMpsadbw , "mpsadbw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(42,U) , U ), - INST(kX86InstIdMul , "mul" , G(X86Rm_B) , F(None)|F(Special) , 0 , 0 , 0 , U , U , E(WUUUUW__) , O_000000(F6,4) , U ), - INST(kX86InstIdMulpd , "mulpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(59,U) , U ), - INST(kX86InstIdMulps , "mulps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(59,U) , U ), - INST(kX86InstIdMulsd , "mulsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(59,U) , U ), - INST(kX86InstIdMulss , "mulss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(59,U) , U ), - INST(kX86InstIdMulx , "mulx" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F6,U) , U ), - INST(kX86InstIdMwait , "mwait" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(C9,U) , U ), - INST(kX86InstIdNeg , "neg" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(WWWWWW__) , O_000000(F6,3) , U ), - INST(kX86InstIdNop , "nop" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000000(90,U) , U ), - INST(kX86InstIdNot , "not" , G(X86Rm_B) , F(Lock) , 0 , O(GqdwbMem) , U , U , U , E(________) , O_000000(F6,2) , U ), - INST(kX86InstIdOr , "or" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(08,1) , U ), - INST(kX86InstIdOrpd , "orpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(56,U) , U ), - INST(kX86InstIdOrps , "orps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(56,U) , U ), - INST(kX86InstIdPabsb , "pabsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1C,U) , U ), - INST(kX86InstIdPabsd , "pabsd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1E,U) , U ), - INST(kX86InstIdPabsw , "pabsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(1D,U) , U ), - INST(kX86InstIdPackssdw , "packssdw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6B,U) , U ), - INST(kX86InstIdPacksswb , "packsswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(63,U) , U ), - INST(kX86InstIdPackusdw , "packusdw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(2B,U) , U ), - INST(kX86InstIdPackuswb , "packuswb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(67,U) , U ), - INST(kX86InstIdPaddb , "paddb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FC,U) , U ), - INST(kX86InstIdPaddd , "paddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FE,U) , U ), - INST(kX86InstIdPaddq , "paddq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D4,U) , U ), - INST(kX86InstIdPaddsb , "paddsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EC,U) , U ), - INST(kX86InstIdPaddsw , "paddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(ED,U) , U ), - INST(kX86InstIdPaddusb , "paddusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DC,U) , U ), - INST(kX86InstIdPaddusw , "paddusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DD,U) , U ), - INST(kX86InstIdPaddw , "paddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FD,U) , U ), - INST(kX86InstIdPalignr , "palignr" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , O(Imm) , U , E(________) , O_000F3A(0F,U) , U ), - INST(kX86InstIdPand , "pand" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DB,U) , U ), - INST(kX86InstIdPandn , "pandn" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DF,U) , U ), - INST(kX86InstIdPause , "pause" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_F30000(90,U) , U ), - INST(kX86InstIdPavgb , "pavgb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E0,U) , U ), - INST(kX86InstIdPavgw , "pavgw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E3,U) , U ), - INST(kX86InstIdPblendvb , "pblendvb" , G(ExtRm) , F(None)|F(Special) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(10,U) , U ), - INST(kX86InstIdPblendw , "pblendw" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0E,U) , U ), - INST(kX86InstIdPclmulqdq , "pclmulqdq" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(44,U) , U ), - INST(kX86InstIdPcmpeqb , "pcmpeqb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(74,U) , U ), - INST(kX86InstIdPcmpeqd , "pcmpeqd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(76,U) , U ), - INST(kX86InstIdPcmpeqq , "pcmpeqq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(29,U) , U ), - INST(kX86InstIdPcmpeqw , "pcmpeqw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(75,U) , U ), - INST(kX86InstIdPcmpestri , "pcmpestri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ), - INST(kX86InstIdPcmpestrm , "pcmpestrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ), - INST(kX86InstIdPcmpgtb , "pcmpgtb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(64,U) , U ), - INST(kX86InstIdPcmpgtd , "pcmpgtd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(66,U) , U ), - INST(kX86InstIdPcmpgtq , "pcmpgtq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(37,U) , U ), - INST(kX86InstIdPcmpgtw , "pcmpgtw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(65,U) , U ), - INST(kX86InstIdPcmpistri , "pcmpistri" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ), - INST(kX86InstIdPcmpistrm , "pcmpistrm" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ), - INST(kX86InstIdPdep , "pdep" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F20F38(F5,U) , U ), - INST(kX86InstIdPext , "pext" , G(AvxRvm) , F(None) , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , E(________) , O_F30F38(F5,U) , U ), - INST(kX86InstIdPextrb , "pextrb" , G(ExtExtract) , F(Move) , 8 , O(Gd)|O(Gb)|O(Mem) , O(Xmm) , U , U , E(________) , O_000F3A(14,U) , O_000F3A(14,U) ), - INST(kX86InstIdPextrd , "pextrd" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ), - INST(kX86InstIdPextrq , "pextrq" , G(ExtExtract) , F(Move) |F(W), 8 , O(GqdMem) , O(Xmm) , U , U , E(________) , O_000F3A(16,U) , O_000F3A(16,U) ), - INST(kX86InstIdPextrw , "pextrw" , G(ExtExtract) , F(Move) , 8 , O(GdMem) , O(MmXmm) , U , U , E(________) , O_000F00(C5,U) , O_000F3A(15,U) ), - INST(kX86InstIdPf2id , "pf2id" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1D,U) , U ), - INST(kX86InstIdPf2iw , "pf2iw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(1C,U) , U ), - INST(kX86InstIdPfacc , "pfacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AE,U) , U ), - INST(kX86InstIdPfadd , "pfadd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9E,U) , U ), - INST(kX86InstIdPfcmpeq , "pfcmpeq" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B0,U) , U ), - INST(kX86InstIdPfcmpge , "pfcmpge" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(90,U) , U ), - INST(kX86InstIdPfcmpgt , "pfcmpgt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A0,U) , U ), - INST(kX86InstIdPfmax , "pfmax" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A4,U) , U ), - INST(kX86InstIdPfmin , "pfmin" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(94,U) , U ), - INST(kX86InstIdPfmul , "pfmul" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B4,U) , U ), - INST(kX86InstIdPfnacc , "pfnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8A,U) , U ), - INST(kX86InstIdPfpnacc , "pfpnacc" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(8E,U) , U ), - INST(kX86InstIdPfrcp , "pfrcp" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(96,U) , U ), - INST(kX86InstIdPfrcpit1 , "pfrcpit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A6,U) , U ), - INST(kX86InstIdPfrcpit2 , "pfrcpit2" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(B6,U) , U ), - INST(kX86InstIdPfrsqit1 , "pfrsqit1" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(A7,U) , U ), - INST(kX86InstIdPfrsqrt , "pfrsqrt" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(97,U) , U ), - INST(kX86InstIdPfsub , "pfsub" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(9A,U) , U ), - INST(kX86InstIdPfsubr , "pfsubr" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(AA,U) , U ), - INST(kX86InstIdPhaddd , "phaddd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(02,U) , U ), - INST(kX86InstIdPhaddsw , "phaddsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(03,U) , U ), - INST(kX86InstIdPhaddw , "phaddw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(01,U) , U ), - INST(kX86InstIdPhminposuw , "phminposuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ), - INST(kX86InstIdPhsubd , "phsubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(06,U) , U ), - INST(kX86InstIdPhsubsw , "phsubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(07,U) , U ), - INST(kX86InstIdPhsubw , "phsubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(05,U) , U ), - INST(kX86InstIdPi2fd , "pi2fd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0D,U) , U ), - INST(kX86InstIdPi2fw , "pi2fw" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(0C,U) , U ), - INST(kX86InstIdPinsrb , "pinsrb" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(20,U) , U ), - INST(kX86InstIdPinsrd , "pinsrd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ), - INST(kX86InstIdPinsrq , "pinsrq" , G(ExtRmi) , F(None) |F(W), 0 , O(Xmm) , O(GqMem) , O(Imm) , U , E(________) , O_660F3A(22,U) , U ), - INST(kX86InstIdPinsrw , "pinsrw" , G(ExtRmi_P) , F(None) , 0 , O(MmXmm) , O(GdMem) , O(Imm) , U , E(________) , O_000F00(C4,U) , U ), - INST(kX86InstIdPmaddubsw , "pmaddubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(04,U) , U ), - INST(kX86InstIdPmaddwd , "pmaddwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F5,U) , U ), - INST(kX86InstIdPmaxsb , "pmaxsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3C,U) , U ), - INST(kX86InstIdPmaxsd , "pmaxsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3D,U) , U ), - INST(kX86InstIdPmaxsw , "pmaxsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EE,U) , U ), - INST(kX86InstIdPmaxub , "pmaxub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DE,U) , U ), - INST(kX86InstIdPmaxud , "pmaxud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3F,U) , U ), - INST(kX86InstIdPmaxuw , "pmaxuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3E,U) , U ), - INST(kX86InstIdPminsb , "pminsb" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(38,U) , U ), - INST(kX86InstIdPminsd , "pminsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(39,U) , U ), - INST(kX86InstIdPminsw , "pminsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EA,U) , U ), - INST(kX86InstIdPminub , "pminub" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(DA,U) , U ), - INST(kX86InstIdPminud , "pminud" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3B,U) , U ), - INST(kX86InstIdPminuw , "pminuw" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(3A,U) , U ), - INST(kX86InstIdPmovmskb , "pmovmskb" , G(ExtRm_PQ) , F(Move) , 8 , O(Gqd) , O(MmXmm) , U , U , E(________) , O_000F00(D7,U) , U ), - INST(kX86InstIdPmovsxbd , "pmovsxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(21,U) , U ), - INST(kX86InstIdPmovsxbq , "pmovsxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(22,U) , U ), - INST(kX86InstIdPmovsxbw , "pmovsxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(20,U) , U ), - INST(kX86InstIdPmovsxdq , "pmovsxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(25,U) , U ), - INST(kX86InstIdPmovsxwd , "pmovsxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(23,U) , U ), - INST(kX86InstIdPmovsxwq , "pmovsxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(24,U) , U ), - INST(kX86InstIdPmovzxbd , "pmovzxbd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(31,U) , U ), - INST(kX86InstIdPmovzxbq , "pmovzxbq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(32,U) , U ), - INST(kX86InstIdPmovzxbw , "pmovzxbw" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(30,U) , U ), - INST(kX86InstIdPmovzxdq , "pmovzxdq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(35,U) , U ), - INST(kX86InstIdPmovzxwd , "pmovzxwd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(33,U) , U ), - INST(kX86InstIdPmovzxwq , "pmovzxwq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(34,U) , U ), - INST(kX86InstIdPmuldq , "pmuldq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(28,U) , U ), - INST(kX86InstIdPmulhrsw , "pmulhrsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0B,U) , U ), - INST(kX86InstIdPmulhuw , "pmulhuw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E4,U) , U ), - INST(kX86InstIdPmulhw , "pmulhw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E5,U) , U ), - INST(kX86InstIdPmulld , "pmulld" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(40,U) , U ), - INST(kX86InstIdPmullw , "pmullw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D5,U) , U ), - INST(kX86InstIdPmuludq , "pmuludq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F4,U) , U ), - INST(kX86InstIdPop , "pop" , G(X86Pop) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(8F,0) , O_000000(58,U) ), - INST(kX86InstIdPopa , "popa" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(61,U) , U ), - INST(kX86InstIdPopcnt , "popcnt" , G(X86RegRm) , F(None) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(WWWWWW__) , O_F30F00(B8,U) , U ), - INST(kX86InstIdPopf , "popf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWWW) , O_000000(9D,U) , U ), - INST(kX86InstIdPor , "por" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EB,U) , U ), - INST(kX86InstIdPrefetch , "prefetch" , G(ExtPrefetch) , F(None) , 0 , O(Mem) , O(Imm) , U , U , E(________) , O_000F00(18,U) , U ), - INST(kX86InstIdPrefetch3dNow , "prefetch_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,0) , U ), - INST(kX86InstIdPrefetchw3dNow , "prefetchw_3dnow" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(0D,1) , U ), - INST(kX86InstIdPsadbw , "psadbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F6,U) , U ), - INST(kX86InstIdPshufb , "pshufb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(00,U) , U ), - INST(kX86InstIdPshufd , "pshufd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ), - INST(kX86InstIdPshufhw , "pshufhw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ), - INST(kX86InstIdPshuflw , "pshuflw" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ), - INST(kX86InstIdPshufw , "pshufw" , G(ExtRmi_P) , F(Move) , 8 , O(Mm) , O(MmMem) , O(Imm) , U , E(________) , O_000F00(70,U) , U ), - INST(kX86InstIdPsignb , "psignb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(08,U) , U ), - INST(kX86InstIdPsignd , "psignd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(0A,U) , U ), - INST(kX86InstIdPsignw , "psignw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F38(09,U) , U ), - INST(kX86InstIdPslld , "pslld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F2,U) , O_000F00(72,6) ), - INST(kX86InstIdPslldq , "pslldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,7) ), - INST(kX86InstIdPsllq , "psllq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F3,U) , O_000F00(73,6) ), - INST(kX86InstIdPsllw , "psllw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(F1,U) , O_000F00(71,6) ), - INST(kX86InstIdPsrad , "psrad" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E2,U) , O_000F00(72,4) ), - INST(kX86InstIdPsraw , "psraw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(E1,U) , O_000F00(71,4) ), - INST(kX86InstIdPsrld , "psrld" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D2,U) , O_000F00(72,2) ), - INST(kX86InstIdPsrldq , "psrldq" , G(ExtRmRi) , F(None) , 0 , O(Xmm) , O(Imm) , U , U , E(________) , U , O_660F00(73,3) ), - INST(kX86InstIdPsrlq , "psrlq" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D3,U) , O_000F00(73,2) ), - INST(kX86InstIdPsrlw , "psrlw" , G(ExtRmRi_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm) , U , U , E(________) , O_000F00(D1,U) , O_000F00(71,2) ), - INST(kX86InstIdPsubb , "psubb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F8,U) , U ), - INST(kX86InstIdPsubd , "psubd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FA,U) , U ), - INST(kX86InstIdPsubq , "psubq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(FB,U) , U ), - INST(kX86InstIdPsubsb , "psubsb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E8,U) , U ), - INST(kX86InstIdPsubsw , "psubsw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(E9,U) , U ), - INST(kX86InstIdPsubusb , "psubusb" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D8,U) , U ), - INST(kX86InstIdPsubusw , "psubusw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(D9,U) , U ), - INST(kX86InstIdPsubw , "psubw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(F9,U) , U ), - INST(kX86InstIdPswapd , "pswapd" , G(3dNow) , F(None) , 0 , O(Mm) , O(MmMem) , U , U , E(________) , O_000F0F(BB,U) , U ), - INST(kX86InstIdPtest , "ptest" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ), - INST(kX86InstIdPunpckhbw , "punpckhbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(68,U) , U ), - INST(kX86InstIdPunpckhdq , "punpckhdq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(6A,U) , U ), - INST(kX86InstIdPunpckhqdq , "punpckhqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6D,U) , U ), - INST(kX86InstIdPunpckhwd , "punpckhwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(69,U) , U ), - INST(kX86InstIdPunpcklbw , "punpcklbw" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(60,U) , U ), - INST(kX86InstIdPunpckldq , "punpckldq" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(62,U) , U ), - INST(kX86InstIdPunpcklqdq , "punpcklqdq" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(6C,U) , U ), - INST(kX86InstIdPunpcklwd , "punpcklwd" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(61,U) , U ), - INST(kX86InstIdPush , "push" , G(X86Push) , F(None)|F(Special) , 0 , 0 , U , U , U , E(________) , O_000000(FF,6) , O_000000(50,U) ), - INST(kX86InstIdPusha , "pusha" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(60,U) , U ), - INST(kX86InstIdPushf , "pushf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(RRRRRRRR) , O_000000(9C,U) , U ), - INST(kX86InstIdPxor , "pxor" , G(ExtRm_P) , F(None) , 0 , O(MmXmm) , O(MmXmmMem) , U , U , E(________) , O_000F00(EF,U) , U ), - INST(kX86InstIdRcl , "rcl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,2) , U ), - INST(kX86InstIdRcpps , "rcpps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(53,U) , U ), - INST(kX86InstIdRcpss , "rcpss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(53,U) , U ), - INST(kX86InstIdRcr , "rcr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____X__) , O_000000(D0,3) , U ), - INST(kX86InstIdRdfsbase , "rdfsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,0) , U ), - INST(kX86InstIdRdgsbase , "rdgsbase" , G(X86Rm) , F(Move) , 8 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,1) , U ), - INST(kX86InstIdRdrand , "rdrand" , G(X86Rm) , F(Move) , 8 , O(Gqdw) , U , U , U , E(WWWWWW__) , O_000F00(C7,6) , U ), - INST(kX86InstIdRdtsc , "rdtsc" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F00(31,U) , U ), - INST(kX86InstIdRdtscp , "rdtscp" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000F01(F9,U) , U ), - INST(kX86InstIdRepLodsB , "rep lods_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AC,1) , U ), - INST(kX86InstIdRepLodsD , "rep lods_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ), - INST(kX86InstIdRepLodsQ , "rep lods_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AD,1) , U ), - INST(kX86InstIdRepLodsW , "rep lods_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AD,1) , U ), - INST(kX86InstIdRepMovsB , "rep movs_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A4,1) , U ), - INST(kX86InstIdRepMovsD , "rep movs_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ), - INST(kX86InstIdRepMovsQ , "rep movs_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_000000(A5,1) , U ), - INST(kX86InstIdRepMovsW , "rep movs_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(______R_) , O_660000(A5,1) , U ), - INST(kX86InstIdRepStosB , "rep stos_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AA,1) , U ), - INST(kX86InstIdRepStosD , "rep stos_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ), - INST(kX86InstIdRepStosQ , "rep stos_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , U , U , U , E(______R_) , O_000000(AB,1) , U ), - INST(kX86InstIdRepStosW , "rep stos_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , U , U , U , E(______R_) , O_660000(AB,1) , U ), - INST(kX86InstIdRepeCmpsB , "repe cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,1) , U ), - INST(kX86InstIdRepeCmpsD , "repe cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ), - INST(kX86InstIdRepeCmpsQ , "repe cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,1) , U ), - INST(kX86InstIdRepeCmpsW , "repe cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,1) , U ), - INST(kX86InstIdRepeScasB , "repe scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,1) , U ), - INST(kX86InstIdRepeScasD , "repe scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ), - INST(kX86InstIdRepeScasQ , "repe scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,1) , U ), - INST(kX86InstIdRepeScasW , "repe scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,1) , U ), - INST(kX86InstIdRepneCmpsB , "repne cmps_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A6,0) , U ), - INST(kX86InstIdRepneCmpsD , "repne cmps_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ), - INST(kX86InstIdRepneCmpsQ , "repne cmps_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(A7,0) , U ), - INST(kX86InstIdRepneCmpsW , "repne cmps_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(A7,0) , U ), - INST(kX86InstIdRepneScasB , "repne scas_b" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AE,0) , U ), - INST(kX86InstIdRepneScasD , "repne scas_d" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ), - INST(kX86InstIdRepneScasQ , "repne scas_q" , G(X86Rep) , F(None)|F(Special)|F(W), 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_000000(AF,0) , U ), - INST(kX86InstIdRepneScasW , "repne scas_w" , G(X86Rep) , F(None)|F(Special) , 0 , O(Mem) , O(Mem) , U , U , E(WWWWWWR_) , O_660000(AF,0) , U ), - INST(kX86InstIdRet , "ret" , G(X86Ret) , F(None)|F(Special) , 0 , U , U , U , U , E(________) , O_000000(C2,U) , U ), - INST(kX86InstIdRol , "rol" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,0) , U ), - INST(kX86InstIdRor , "ror" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(W____W__) , O_000000(D0,1) , U ), - INST(kX86InstIdRorx , "rorx" , G(AvxRmi) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Imm) , U , E(________) , O_F20F3A(F0,U) , U ), - INST(kX86InstIdRoundpd , "roundpd" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ), - INST(kX86InstIdRoundps , "roundps" , G(ExtRmi) , F(Move) , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ), - INST(kX86InstIdRoundsd , "roundsd" , G(ExtRmi) , F(Move) , 8 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0B,U) , U ), - INST(kX86InstIdRoundss , "roundss" , G(ExtRmi) , F(Move) , 4 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(0A,U) , U ), - INST(kX86InstIdRsqrtps , "rsqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(52,U) , U ), - INST(kX86InstIdRsqrtss , "rsqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(52,U) , U ), - INST(kX86InstIdSahf , "sahf" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(_WWWWW__) , O_000000(9E,U) , U ), - INST(kX86InstIdSal , "sal" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ), - INST(kX86InstIdSar , "sar" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,7) , U ), - INST(kX86InstIdSarx , "sarx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F30F38(F7,U) , U ), - INST(kX86InstIdSbb , "sbb" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWX__) , O_000000(18,3) , U ), - INST(kX86InstIdScasB , "scas_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AE,U) , U ), - INST(kX86InstIdScasD , "scas_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), - INST(kX86InstIdScasQ , "scas_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), - INST(kX86InstIdScasW , "scas_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(WWWWWWR_) , O_000000(AF,U) , U ), - INST(kX86InstIdSeta , "seta" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ), - INST(kX86InstIdSetae , "setae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), - INST(kX86InstIdSetb , "setb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), - INST(kX86InstIdSetbe , "setbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ), - INST(kX86InstIdSetc , "setc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), - INST(kX86InstIdSete , "sete" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ), - INST(kX86InstIdSetg , "setg" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ), - INST(kX86InstIdSetge , "setge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ), - INST(kX86InstIdSetl , "setl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ), - INST(kX86InstIdSetle , "setle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ), - INST(kX86InstIdSetna , "setna" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(96,U) , U ), - INST(kX86InstIdSetnae , "setnae" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(92,U) , U ), - INST(kX86InstIdSetnb , "setnb" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), - INST(kX86InstIdSetnbe , "setnbe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R__R__) , O_000F00(97,U) , U ), - INST(kX86InstIdSetnc , "setnc" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_____R__) , O_000F00(93,U) , U ), - INST(kX86InstIdSetne , "setne" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ), - INST(kX86InstIdSetng , "setng" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9E,U) , U ), - INST(kX86InstIdSetnge , "setnge" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9C,U) , U ), - INST(kX86InstIdSetnl , "setnl" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RR______) , O_000F00(9D,U) , U ), - INST(kX86InstIdSetnle , "setnle" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(RRR_____) , O_000F00(9F,U) , U ), - INST(kX86InstIdSetno , "setno" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(91,U) , U ), - INST(kX86InstIdSetnp , "setnp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ), - INST(kX86InstIdSetns , "setns" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(99,U) , U ), - INST(kX86InstIdSetnz , "setnz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(95,U) , U ), - INST(kX86InstIdSeto , "seto" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(R_______) , O_000F00(90,U) , U ), - INST(kX86InstIdSetp , "setp" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ), - INST(kX86InstIdSetpe , "setpe" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9A,U) , U ), - INST(kX86InstIdSetpo , "setpo" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(____R___) , O_000F00(9B,U) , U ), - INST(kX86InstIdSets , "sets" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(_R______) , O_000F00(98,U) , U ), - INST(kX86InstIdSetz , "setz" , G(X86Set) , F(Move) , 1 , O(GbMem) , U , U , U , E(__R_____) , O_000F00(94,U) , U ), - INST(kX86InstIdSfence , "sfence" , G(ExtFence) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(AE,7) , U ), - INST(kX86InstIdShl , "shl" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,4) , U ), - INST(kX86InstIdShld , "shld" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb) , U , U , E(UWWUWW__) , O_000F00(A4,U) , U ), - INST(kX86InstIdShlx , "shlx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_660F38(F7,U) , U ), - INST(kX86InstIdShr , "shr" , G(X86Rot) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(D0,5) , U ), - INST(kX86InstIdShrd , "shrd" , G(X86Shlrd) , F(None)|F(Special) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(UWWUWW__) , O_000F00(AC,U) , U ), - INST(kX86InstIdShrx , "shrx" , G(AvxRmv) , F(None) , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , E(________) , O_F20F38(F7,U) , U ), - INST(kX86InstIdShufpd , "shufpd" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F00(C6,U) , U ), - INST(kX86InstIdShufps , "shufps" , G(ExtRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_000F00(C6,U) , U ), - INST(kX86InstIdSqrtpd , "sqrtpd" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(51,U) , U ), - INST(kX86InstIdSqrtps , "sqrtps" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(51,U) , U ), - INST(kX86InstIdSqrtsd , "sqrtsd" , G(ExtRm) , F(Move) , 8 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(51,U) , U ), - INST(kX86InstIdSqrtss , "sqrtss" , G(ExtRm) , F(Move) , 4 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(51,U) , U ), - INST(kX86InstIdStc , "stc" , G(X86Op) , F(None) , 0 , U , U , U , U , E(_____W__) , O_000000(F9,U) , U ), - INST(kX86InstIdStd , "std" , G(X86Op) , F(None) , 0 , U , U , U , U , E(______W_) , O_000000(FD,U) , U ), - INST(kX86InstIdStmxcsr , "stmxcsr" , G(X86M) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ), - INST(kX86InstIdStosB , "stos_b" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AA,U) , U ), - INST(kX86InstIdStosD , "stos_d" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), - INST(kX86InstIdStosQ , "stos_q" , G(X86Op) , F(None)|F(Special)|F(W), 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), - INST(kX86InstIdStosW , "stos_w" , G(X86Op_66H) , F(None)|F(Special) , 0 , U , U , U , U , E(______R_) , O_000000(AB,U) , U ), - INST(kX86InstIdSub , "sub" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWWWW__) , O_000000(28,5) , U ), - INST(kX86InstIdSubpd , "subpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(5C,U) , U ), - INST(kX86InstIdSubps , "subps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(5C,U) , U ), - INST(kX86InstIdSubsd , "subsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F20F00(5C,U) , U ), - INST(kX86InstIdSubss , "subss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_F30F00(5C,U) , U ), - INST(kX86InstIdTest , "test" , G(X86Test) , F(Test) , 0 , O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , E(WWWUWW__) , O_000000(84,U) , O_000000(F6,U) ), - INST(kX86InstIdTzcnt , "tzcnt" , G(X86RegRm) , F(Move) , 0 , O(Gqdw) , O(GqdwMem) , U , U , E(UUWUUW__) , O_F30F00(BC,U) , U ), - INST(kX86InstIdUcomisd , "ucomisd" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ), - INST(kX86InstIdUcomiss , "ucomiss" , G(ExtRm) , F(Test) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ), - INST(kX86InstIdUd2 , "ud2" , G(X86Op) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(0B,U) , U ), - INST(kX86InstIdUnpckhpd , "unpckhpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(15,U) , U ), - INST(kX86InstIdUnpckhps , "unpckhps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(15,U) , U ), - INST(kX86InstIdUnpcklpd , "unpcklpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(14,U) , U ), - INST(kX86InstIdUnpcklps , "unpcklps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(14,U) , U ), - INST(kX86InstIdVaddpd , "vaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(58,U) , U ), - INST(kX86InstIdVaddps , "vaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(58,U) , U ), - INST(kX86InstIdVaddsd , "vaddsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(58,U) , U ), - INST(kX86InstIdVaddss , "vaddss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(58,U) , U ), - INST(kX86InstIdVaddsubpd , "vaddsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D0,U) , U ), - INST(kX86InstIdVaddsubps , "vaddsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(D0,U) , U ), - INST(kX86InstIdVaesdec , "vaesdec" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DE,U) , U ), - INST(kX86InstIdVaesdeclast , "vaesdeclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DF,U) , U ), - INST(kX86InstIdVaesenc , "vaesenc" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DC,U) , U ), - INST(kX86InstIdVaesenclast , "vaesenclast" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(DD,U) , U ), - INST(kX86InstIdVaesimc , "vaesimc" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(DB,U) , U ), - INST(kX86InstIdVaeskeygenassist , "vaeskeygenassist" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(DF,U) , U ), - INST(kX86InstIdVandnpd , "vandnpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(55,U) , U ), - INST(kX86InstIdVandnps , "vandnps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(55,U) , U ), - INST(kX86InstIdVandpd , "vandpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(54,U) , U ), - INST(kX86InstIdVandps , "vandps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(54,U) , U ), - INST(kX86InstIdVblendpd , "vblendpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0D,U) , U ), - INST(kX86InstIdVblendps , "vblendps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0C,U) , U ), - INST(kX86InstIdVblendvpd , "vblendvpd" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4B,U) , U ), - INST(kX86InstIdVblendvps , "vblendvps" , G(AvxRvmr_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4A,U) , U ), - INST(kX86InstIdVbroadcastf128 , "vbroadcastf128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(1A,U)|L, U ), - INST(kX86InstIdVbroadcasti128 , "vbroadcasti128" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(Mem) , U , U , E(________) , O_660F38(5A,U)|L, U ), - INST(kX86InstIdVbroadcastsd , "vbroadcastsd" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(19,U)|L, U ), - INST(kX86InstIdVbroadcastss , "vbroadcastss" , G(AvxRm) , F(None) , 0 , O(Ymm) , O(XmmMem) , U , U , E(________) , O_660F38(18,U) , U ), - INST(kX86InstIdVcmppd , "vcmppd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C2,U) , U ), - INST(kX86InstIdVcmpps , "vcmpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C2,U) , U ), - INST(kX86InstIdVcmpsd , "vcmpsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F20F00(C2,U) , U ), - INST(kX86InstIdVcmpss , "vcmpss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_F30F00(C2,U) , U ), - INST(kX86InstIdVcomisd , "vcomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(2F,U) , U ), - INST(kX86InstIdVcomiss , "vcomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(2F,U) , U ), - INST(kX86InstIdVcvtdq2pd , "vcvtdq2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_F30F00(E6,U) , U ), - INST(kX86InstIdVcvtdq2ps , "vcvtdq2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(5B,U) , U ), - INST(kX86InstIdVcvtpd2dq , "vcvtpd2dq" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(E6,U) , U ), - INST(kX86InstIdVcvtpd2ps , "vcvtpd2ps" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5A,U) , U ), - INST(kX86InstIdVcvtph2ps , "vcvtph2ps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(13,U) , U ), - INST(kX86InstIdVcvtps2dq , "vcvtps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(5B,U) , U ), - INST(kX86InstIdVcvtps2pd , "vcvtps2pd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_000F00(5A,U) , U ), - INST(kX86InstIdVcvtps2ph , "vcvtps2ph" , G(AvxMri_P) , F(None) , 0 , O(XmmMem) , O(XmmYmm) , O(Imm) , U , E(________) , O_660F3A(1D,U) , U ), - INST(kX86InstIdVcvtsd2si , "vcvtsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), - INST(kX86InstIdVcvtsd2ss , "vcvtsd2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5A,U) , U ), - INST(kX86InstIdVcvtsi2sd , "vcvtsi2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F20F00(2A,U) , U ), - INST(kX86InstIdVcvtsi2ss , "vcvtsi2ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , E(________) , O_F30F00(2A,U) , U ), - INST(kX86InstIdVcvtss2sd , "vcvtss2sd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5A,U) , U ), - INST(kX86InstIdVcvtss2si , "vcvtss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2D,U) , U ), - INST(kX86InstIdVcvttpd2dq , "vcvttpd2dq" , G(AvxRm_P) , F(None) , 0 , O(Xmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(E6,U) , U ), - INST(kX86InstIdVcvttps2dq , "vcvttps2dq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(5B,U) , U ), - INST(kX86InstIdVcvttsd2si , "vcvttsd2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F20F00(2C,U) , U ), - INST(kX86InstIdVcvttss2si , "vcvttss2si" , G(AvxRm) , F(None) , 0 , O(Gqd) , O(XmmMem) , U , U , E(________) , O_F30F00(2C,U) , U ), - INST(kX86InstIdVdivpd , "vdivpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5E,U) , U ), - INST(kX86InstIdVdivps , "vdivps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5E,U) , U ), - INST(kX86InstIdVdivsd , "vdivsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5E,U) , U ), - INST(kX86InstIdVdivss , "vdivss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5E,U) , U ), - INST(kX86InstIdVdppd , "vdppd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(41,U) , U ), - INST(kX86InstIdVdpps , "vdpps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(40,U) , U ), - INST(kX86InstIdVextractf128 , "vextractf128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(19,U)|L, U ), - INST(kX86InstIdVextracti128 , "vextracti128" , G(AvxMri) , F(None) , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , E(________) , O_660F3A(39,U)|L, U ), - INST(kX86InstIdVextractps , "vextractps" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(17,U) , U ), - INST(kX86InstIdVfmadd132pd , "vfmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ), - INST(kX86InstIdVfmadd132ps , "vfmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(98,U) , U ), - INST(kX86InstIdVfmadd132sd , "vfmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ), - INST(kX86InstIdVfmadd132ss , "vfmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(99,U) , U ), - INST(kX86InstIdVfmadd213pd , "vfmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ), - INST(kX86InstIdVfmadd213ps , "vfmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A8,U) , U ), - INST(kX86InstIdVfmadd213sd , "vfmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ), - INST(kX86InstIdVfmadd213ss , "vfmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(A9,U) , U ), - INST(kX86InstIdVfmadd231pd , "vfmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ), - INST(kX86InstIdVfmadd231ps , "vfmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B8,U) , U ), - INST(kX86InstIdVfmadd231sd , "vfmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ), - INST(kX86InstIdVfmadd231ss , "vfmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(B9,U) , U ), - INST(kX86InstIdVfmaddpd , "vfmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(69,U) , U ), - INST(kX86InstIdVfmaddps , "vfmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(68,U) , U ), - INST(kX86InstIdVfmaddsd , "vfmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6B,U) , U ), - INST(kX86InstIdVfmaddss , "vfmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6A,U) , U ), - INST(kX86InstIdVfmaddsub132pd , "vfmaddsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ), - INST(kX86InstIdVfmaddsub132ps , "vfmaddsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(96,U) , U ), - INST(kX86InstIdVfmaddsub213pd , "vfmaddsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ), - INST(kX86InstIdVfmaddsub213ps , "vfmaddsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A6,U) , U ), - INST(kX86InstIdVfmaddsub231pd , "vfmaddsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ), - INST(kX86InstIdVfmaddsub231ps , "vfmaddsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B6,U) , U ), - INST(kX86InstIdVfmaddsubpd , "vfmaddsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5D,U) , U ), - INST(kX86InstIdVfmaddsubps , "vfmaddsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5C,U) , U ), - INST(kX86InstIdVfmsub132pd , "vfmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ), - INST(kX86InstIdVfmsub132ps , "vfmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9A,U) , U ), - INST(kX86InstIdVfmsub132sd , "vfmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ), - INST(kX86InstIdVfmsub132ss , "vfmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9B,U) , U ), - INST(kX86InstIdVfmsub213pd , "vfmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ), - INST(kX86InstIdVfmsub213ps , "vfmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AA,U) , U ), - INST(kX86InstIdVfmsub213sd , "vfmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ), - INST(kX86InstIdVfmsub213ss , "vfmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AB,U) , U ), - INST(kX86InstIdVfmsub231pd , "vfmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ), - INST(kX86InstIdVfmsub231ps , "vfmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BA,U) , U ), - INST(kX86InstIdVfmsub231sd , "vfmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ), - INST(kX86InstIdVfmsub231ss , "vfmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BB,U) , U ), - INST(kX86InstIdVfmsubadd132pd , "vfmsubadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ), - INST(kX86InstIdVfmsubadd132ps , "vfmsubadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(97,U) , U ), - INST(kX86InstIdVfmsubadd213pd , "vfmsubadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ), - INST(kX86InstIdVfmsubadd213ps , "vfmsubadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(A7,U) , U ), - INST(kX86InstIdVfmsubadd231pd , "vfmsubadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ), - INST(kX86InstIdVfmsubadd231ps , "vfmsubadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(B7,U) , U ), - INST(kX86InstIdVfmsubaddpd , "vfmsubaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5F,U) , U ), - INST(kX86InstIdVfmsubaddps , "vfmsubaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(5E,U) , U ), - INST(kX86InstIdVfmsubpd , "vfmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6D,U) , U ), - INST(kX86InstIdVfmsubps , "vfmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(6C,U) , U ), - INST(kX86InstIdVfmsubsd , "vfmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6F,U) , U ), - INST(kX86InstIdVfmsubss , "vfmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(6E,U) , U ), - INST(kX86InstIdVfnmadd132pd , "vfnmadd132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ), - INST(kX86InstIdVfnmadd132ps , "vfnmadd132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9C,U) , U ), - INST(kX86InstIdVfnmadd132sd , "vfnmadd132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ), - INST(kX86InstIdVfnmadd132ss , "vfnmadd132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9D,U) , U ), - INST(kX86InstIdVfnmadd213pd , "vfnmadd213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ), - INST(kX86InstIdVfnmadd213ps , "vfnmadd213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AC,U) , U ), - INST(kX86InstIdVfnmadd213sd , "vfnmadd213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ), - INST(kX86InstIdVfnmadd213ss , "vfnmadd213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AD,U) , U ), - INST(kX86InstIdVfnmadd231pd , "vfnmadd231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ), - INST(kX86InstIdVfnmadd231ps , "vfnmadd231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BC,U) , U ), - INST(kX86InstIdVfnmadd231sd , "vfnmadd231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ), - INST(kX86InstIdVfnmadd231ss , "vfnmadd231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BC,U) , U ), - INST(kX86InstIdVfnmaddpd , "vfnmaddpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(79,U) , U ), - INST(kX86InstIdVfnmaddps , "vfnmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(78,U) , U ), - INST(kX86InstIdVfnmaddsd , "vfnmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7B,U) , U ), - INST(kX86InstIdVfnmaddss , "vfnmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7A,U) , U ), - INST(kX86InstIdVfnmsub132pd , "vfnmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ), - INST(kX86InstIdVfnmsub132ps , "vfnmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(9E,U) , U ), - INST(kX86InstIdVfnmsub132sd , "vfnmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ), - INST(kX86InstIdVfnmsub132ss , "vfnmsub132ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(9F,U) , U ), - INST(kX86InstIdVfnmsub213pd , "vfnmsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ), - INST(kX86InstIdVfnmsub213ps , "vfnmsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(AE,U) , U ), - INST(kX86InstIdVfnmsub213sd , "vfnmsub213sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ), - INST(kX86InstIdVfnmsub213ss , "vfnmsub213ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(AF,U) , U ), - INST(kX86InstIdVfnmsub231pd , "vfnmsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ), - INST(kX86InstIdVfnmsub231ps , "vfnmsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(BE,U) , U ), - INST(kX86InstIdVfnmsub231sd , "vfnmsub231sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ), - INST(kX86InstIdVfnmsub231ss , "vfnmsub231ss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_660F38(BF,U) , U ), - INST(kX86InstIdVfnmsubpd , "vfnmsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7D,U) , U ), - INST(kX86InstIdVfnmsubps , "vfnmsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_660F3A(7C,U) , U ), - INST(kX86InstIdVfnmsubsd , "vfnmsubsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7F,U) , U ), - INST(kX86InstIdVfnmsubss , "vfnmsubss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_660F3A(7E,U) , U ), - INST(kX86InstIdVfrczpd , "vfrczpd" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(81,U) , U ), - INST(kX86InstIdVfrczps , "vfrczps" , G(XopRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_00_M09(80,U) , U ), - INST(kX86InstIdVfrczsd , "vfrczsd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(83,U) , U ), - INST(kX86InstIdVfrczss , "vfrczss" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(82,U) , U ), - INST(kX86InstIdVgatherdpd , "vgatherdpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ), - INST(kX86InstIdVgatherdps , "vgatherdps" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(92,U) , U ), - INST(kX86InstIdVgatherqpd , "vgatherqpd" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(93,U) , U ), - INST(kX86InstIdVgatherqps , "vgatherqps" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(93,U) , U ), - INST(kX86InstIdVhaddpd , "vhaddpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7C,U) , U ), - INST(kX86InstIdVhaddps , "vhaddps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7C,U) , U ), - INST(kX86InstIdVhsubpd , "vhsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(7D,U) , U ), - INST(kX86InstIdVhsubps , "vhsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(7D,U) , U ), - INST(kX86InstIdVinsertf128 , "vinsertf128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(18,U)|L, U ), - INST(kX86InstIdVinserti128 , "vinserti128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(38,U)|L, U ), - INST(kX86InstIdVinsertps , "vinsertps" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(21,U) , U ), - INST(kX86InstIdVlddqu , "vlddqu" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_F20F00(F0,U) , U ), - INST(kX86InstIdVldmxcsr , "vldmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,2) , U ), - INST(kX86InstIdVmaskmovdqu , "vmaskmovdqu" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(Xmm) , U , U , E(________) , O_660F00(F7,U) , U ), - INST(kX86InstIdVmaskmovpd , "vmaskmovpd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2D,U) , O_660F38(2F,U) ), - INST(kX86InstIdVmaskmovps , "vmaskmovps" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2C,U) , O_660F38(2E,U) ), - INST(kX86InstIdVmaxpd , "vmaxpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5F,U) , U ), - INST(kX86InstIdVmaxps , "vmaxps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5F,U) , U ), - INST(kX86InstIdVmaxsd , "vmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5F,U) , U ), - INST(kX86InstIdVmaxss , "vmaxss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5F,U) , U ), - INST(kX86InstIdVminpd , "vminpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5D,U) , U ), - INST(kX86InstIdVminps , "vminps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5D,U) , U ), - INST(kX86InstIdVminsd , "vminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(5D,U) , U ), - INST(kX86InstIdVminss , "vminss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(5D,U) , U ), - INST(kX86InstIdVmovapd , "vmovapd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(28,U) , O_660F00(29,U) ), - INST(kX86InstIdVmovaps , "vmovaps" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(28,U) , O_000F00(29,U) ), - INST(kX86InstIdVmovd , "vmovd" , G(AvxRmMr) , F(None) , 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ), - INST(kX86InstIdVmovddup , "vmovddup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F20F00(12,U) , U ), - INST(kX86InstIdVmovdqa , "vmovdqa" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(6F,U) , O_660F00(7F,U) ), - INST(kX86InstIdVmovdqu , "vmovdqu" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(6F,U) , O_F30F00(7F,U) ), - INST(kX86InstIdVmovhlps , "vmovhlps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(12,U) , U ), - INST(kX86InstIdVmovhpd , "vmovhpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(16,U) , O_660F00(17,U) ), - INST(kX86InstIdVmovhps , "vmovhps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(16,U) , O_000F00(17,U) ), - INST(kX86InstIdVmovlhps , "vmovlhps" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , E(________) , O_000F00(16,U) , U ), - INST(kX86InstIdVmovlpd , "vmovlpd" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_660F00(12,U) , O_660F00(13,U) ), - INST(kX86InstIdVmovlps , "vmovlps" , G(AvxRvmMr) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , E(________) , O_000F00(12,U) , O_000F00(13,U) ), - INST(kX86InstIdVmovmskpd , "vmovmskpd" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(50,U) , U ), - INST(kX86InstIdVmovmskps , "vmovmskps" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_000F00(50,U) , U ), - INST(kX86InstIdVmovntdq , "vmovntdq" , G(AvxMr) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(E7,U) , U ), - INST(kX86InstIdVmovntdqa , "vmovntdqa" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(Mem) , U , U , E(________) , O_660F38(2A,U) , U ), - INST(kX86InstIdVmovntpd , "vmovntpd" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_660F00(2B,U) , U ), - INST(kX86InstIdVmovntps , "vmovntps" , G(AvxMr_P) , F(None) , 0 , O(Mem) , O(XmmYmm) , U , U , E(________) , O_000F00(2B,U) , U ), - INST(kX86InstIdVmovq , "vmovq" , G(AvxRmMr) , F(None) |F(W), 0 , O(XmmMem) , O(XmmMem) , U , U , E(________) , O_660F00(6E,U) , O_660F00(7E,U) ), - INST(kX86InstIdVmovsd , "vmovsd" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(XmmMem) , O(Xmm) , U , E(________) , O_F20F00(10,U) , O_F20F00(11,U) ), - INST(kX86InstIdVmovshdup , "vmovshdup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(16,U) , U ), - INST(kX86InstIdVmovsldup , "vmovsldup" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_F30F00(12,U) , U ), - INST(kX86InstIdVmovss , "vmovss" , G(AvxMovSsSd) , F(None) , 0 , O(XmmMem) , O(Xmm) , O(Xmm) , U , E(________) , O_F30F00(10,U) , O_F30F00(11,U) ), - INST(kX86InstIdVmovupd , "vmovupd" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_660F00(10,U) , O_660F00(11,U) ), - INST(kX86InstIdVmovups , "vmovups" , G(AvxRmMr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmmMem) , U , U , E(________) , O_000F00(10,U) , O_000F00(11,U) ), - INST(kX86InstIdVmpsadbw , "vmpsadbw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(42,U) , U ), - INST(kX86InstIdVmulpd , "vmulpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(59,U) , U ), - INST(kX86InstIdVmulps , "vmulps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(59,U) , U ), - INST(kX86InstIdVmulsd , "vmulsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F20F00(59,U) , U ), - INST(kX86InstIdVmulss , "vmulss" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_F30F00(59,U) , U ), - INST(kX86InstIdVorpd , "vorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(56,U) , U ), - INST(kX86InstIdVorps , "vorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(56,U) , U ), - INST(kX86InstIdVpabsb , "vpabsb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1C,U) , U ), - INST(kX86InstIdVpabsd , "vpabsd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1E,U) , U ), - INST(kX86InstIdVpabsw , "vpabsw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(1D,U) , U ), - INST(kX86InstIdVpackssdw , "vpackssdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6B,U) , U ), - INST(kX86InstIdVpacksswb , "vpacksswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(63,U) , U ), - INST(kX86InstIdVpackusdw , "vpackusdw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(2B,U) , U ), - INST(kX86InstIdVpackuswb , "vpackuswb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(67,U) , U ), - INST(kX86InstIdVpaddb , "vpaddb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FC,U) , U ), - INST(kX86InstIdVpaddd , "vpaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FE,U) , U ), - INST(kX86InstIdVpaddq , "vpaddq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D4,U) , U ), - INST(kX86InstIdVpaddsb , "vpaddsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EC,U) , U ), - INST(kX86InstIdVpaddsw , "vpaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(ED,U) , U ), - INST(kX86InstIdVpaddusb , "vpaddusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DC,U) , U ), - INST(kX86InstIdVpaddusw , "vpaddusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DD,U) , U ), - INST(kX86InstIdVpaddw , "vpaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FD,U) , U ), - INST(kX86InstIdVpalignr , "vpalignr" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0F,U) , U ), - INST(kX86InstIdVpand , "vpand" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DB,U) , U ), - INST(kX86InstIdVpandn , "vpandn" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DF,U) , U ), - INST(kX86InstIdVpavgb , "vpavgb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E0,U) , U ), - INST(kX86InstIdVpavgw , "vpavgw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E3,U) , U ), - INST(kX86InstIdVpblendd , "vpblendd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(02,U) , U ), - INST(kX86InstIdVpblendvb , "vpblendvb" , G(AvxRvmr) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmm) , E(________) , O_660F3A(4C,U) , U ), - INST(kX86InstIdVpblendw , "vpblendw" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F3A(0E,U) , U ), - INST(kX86InstIdVpbroadcastb , "vpbroadcastb" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(78,U) , U ), - INST(kX86InstIdVpbroadcastd , "vpbroadcastd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(58,U) , U ), - INST(kX86InstIdVpbroadcastq , "vpbroadcastq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(59,U) , U ), - INST(kX86InstIdVpbroadcastw , "vpbroadcastw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmMem) , U , U , E(________) , O_660F38(79,U) , U ), - INST(kX86InstIdVpclmulqdq , "vpclmulqdq" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(44,U) , U ), - INST(kX86InstIdVpcmov , "vpcmov" , G(XopRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_00_M08(A2,U) , U ), - INST(kX86InstIdVpcmpeqb , "vpcmpeqb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(74,U) , U ), - INST(kX86InstIdVpcmpeqd , "vpcmpeqd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(76,U) , U ), - INST(kX86InstIdVpcmpeqq , "vpcmpeqq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(29,U) , U ), - INST(kX86InstIdVpcmpeqw , "vpcmpeqw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(75,U) , U ), - INST(kX86InstIdVpcmpestri , "vpcmpestri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(61,U) , U ), - INST(kX86InstIdVpcmpestrm , "vpcmpestrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(60,U) , U ), - INST(kX86InstIdVpcmpgtb , "vpcmpgtb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(64,U) , U ), - INST(kX86InstIdVpcmpgtd , "vpcmpgtd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(66,U) , U ), - INST(kX86InstIdVpcmpgtq , "vpcmpgtq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(37,U) , U ), - INST(kX86InstIdVpcmpgtw , "vpcmpgtw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(65,U) , U ), - INST(kX86InstIdVpcmpistri , "vpcmpistri" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(63,U) , U ), - INST(kX86InstIdVpcmpistrm , "vpcmpistrm" , G(AvxRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , E(________) , O_660F3A(62,U) , U ), - INST(kX86InstIdVpcomb , "vpcomb" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CC,U) , U ), - INST(kX86InstIdVpcomd , "vpcomd" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CE,U) , U ), - INST(kX86InstIdVpcomq , "vpcomq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CF,U) , U ), - INST(kX86InstIdVpcomub , "vpcomub" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EC,U) , U ), - INST(kX86InstIdVpcomud , "vpcomud" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EE,U) , U ), - INST(kX86InstIdVpcomuq , "vpcomuq" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(EF,U) , U ), - INST(kX86InstIdVpcomuw , "vpcomuw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(ED,U) , U ), - INST(kX86InstIdVpcomw , "vpcomw" , G(XopRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_00_M08(CD,U) , U ), - INST(kX86InstIdVperm2f128 , "vperm2f128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(06,U)|L, U ), - INST(kX86InstIdVperm2i128 , "vperm2i128" , G(AvxRvmi) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , E(________) , O_660F3A(46,U)|L, U ), - INST(kX86InstIdVpermd , "vpermd" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(36,U)|L, U ), - INST(kX86InstIdVpermil2pd , "vpermil2pd" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(49,U) , U ), - INST(kX86InstIdVpermil2ps , "vpermil2ps" , G(AvxRvrmRvmr_P), F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , E(________) , O_66_M03(48,U) , U ), - INST(kX86InstIdVpermilpd , "vpermilpd" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0D,U) , O_660F3A(05,U) ), - INST(kX86InstIdVpermilps , "vpermilps" , G(AvxRvmRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F38(0C,U) , O_660F3A(04,U) ), - INST(kX86InstIdVpermpd , "vpermpd" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(01,U)|L, U ), - INST(kX86InstIdVpermps , "vpermps" , G(AvxRvm) , F(None) , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , E(________) , O_660F38(16,U)|L, U ), - INST(kX86InstIdVpermq , "vpermq" , G(AvxRmi) , F(None) |F(W), 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , E(________) , O_660F3A(00,U)|L, U ), - INST(kX86InstIdVpextrb , "vpextrb" , G(AvxMri) , F(None) , 0 , O(GqdwbMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(14,U) , U ), - INST(kX86InstIdVpextrd , "vpextrd" , G(AvxMri) , F(None) , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ), - INST(kX86InstIdVpextrq , "vpextrq" , G(AvxMri) , F(None) |F(W), 0 , O(GqMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(16,U) , U ), - INST(kX86InstIdVpextrw , "vpextrw" , G(AvxMri) , F(None) , 0 , O(GqdwMem) , O(Xmm) , O(Imm) , U , E(________) , O_660F3A(15,U) , U ), - INST(kX86InstIdVpgatherdd , "vpgatherdd" , G(AvxGather) , F(None) , 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ), - INST(kX86InstIdVpgatherdq , "vpgatherdq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(90,U) , U ), - INST(kX86InstIdVpgatherqd , "vpgatherqd" , G(AvxGatherEx) , F(None) , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , E(________) , O_660F38(91,U) , U ), - INST(kX86InstIdVpgatherqq , "vpgatherqq" , G(AvxGather) , F(None) |F(W), 0 , O(XmmYmm) , O(Mem) , O(XmmYmm) , U , E(________) , O_660F38(91,U) , U ), - INST(kX86InstIdVphaddbd , "vphaddbd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C2,U) , U ), - INST(kX86InstIdVphaddbq , "vphaddbq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C3,U) , U ), - INST(kX86InstIdVphaddbw , "vphaddbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C1,U) , U ), - INST(kX86InstIdVphaddd , "vphaddd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(02,U) , U ), - INST(kX86InstIdVphadddq , "vphadddq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(CB,U) , U ), - INST(kX86InstIdVphaddsw , "vphaddsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(03,U) , U ), - INST(kX86InstIdVphaddubd , "vphaddubd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D2,U) , U ), - INST(kX86InstIdVphaddubq , "vphaddubq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D3,U) , U ), - INST(kX86InstIdVphaddubw , "vphaddubw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D1,U) , U ), - INST(kX86InstIdVphaddudq , "vphaddudq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(DB,U) , U ), - INST(kX86InstIdVphadduwd , "vphadduwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D6,U) , U ), - INST(kX86InstIdVphadduwq , "vphadduwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(D7,U) , U ), - INST(kX86InstIdVphaddw , "vphaddw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(01,U) , U ), - INST(kX86InstIdVphaddwd , "vphaddwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C6,U) , U ), - INST(kX86InstIdVphaddwq , "vphaddwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(C7,U) , U ), - INST(kX86InstIdVphminposuw , "vphminposuw" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F38(41,U) , U ), - INST(kX86InstIdVphsubbw , "vphsubbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E1,U) , U ), - INST(kX86InstIdVphsubd , "vphsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(06,U) , U ), - INST(kX86InstIdVphsubdq , "vphsubdq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E3,U) , U ), - INST(kX86InstIdVphsubsw , "vphsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(07,U) , U ), - INST(kX86InstIdVphsubw , "vphsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(05,U) , U ), - INST(kX86InstIdVphsubwd , "vphsubwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_00_M09(E2,U) , U ), - INST(kX86InstIdVpinsrb , "vpinsrb" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , E(________) , O_660F3A(20,U) , U ), - INST(kX86InstIdVpinsrd , "vpinsrd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ), - INST(kX86InstIdVpinsrq , "vpinsrq" , G(AvxRvmi) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , E(________) , O_660F3A(22,U) , U ), - INST(kX86InstIdVpinsrw , "vpinsrw" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , E(________) , O_660F00(C4,U) , U ), - INST(kX86InstIdVpmacsdd , "vpmacsdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9E,U) , U ), - INST(kX86InstIdVpmacsdqh , "vpmacsdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(9F,U) , U ), - INST(kX86InstIdVpmacsdql , "vpmacsdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(97,U) , U ), - INST(kX86InstIdVpmacssdd , "vpmacssdd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8E,U) , U ), - INST(kX86InstIdVpmacssdqh , "vpmacssdqh" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(8F,U) , U ), - INST(kX86InstIdVpmacssdql , "vpmacssdql" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(87,U) , U ), - INST(kX86InstIdVpmacsswd , "vpmacsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(86,U) , U ), - INST(kX86InstIdVpmacssww , "vpmacssww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(85,U) , U ), - INST(kX86InstIdVpmacswd , "vpmacswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(96,U) , U ), - INST(kX86InstIdVpmacsww , "vpmacsww" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(95,U) , U ), - INST(kX86InstIdVpmadcsswd , "vpmadcsswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(A6,U) , U ), - INST(kX86InstIdVpmadcswd , "vpmadcswd" , G(XopRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , E(________) , O_00_M08(B6,U) , U ), - INST(kX86InstIdVpmaddubsw , "vpmaddubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(04,U) , U ), - INST(kX86InstIdVpmaddwd , "vpmaddwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F5,U) , U ), - INST(kX86InstIdVpmaskmovd , "vpmaskmovd" , G(AvxRvmMvr_P) , F(None) , 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ), - INST(kX86InstIdVpmaskmovq , "vpmaskmovq" , G(AvxRvmMvr_P) , F(None) |F(W), 0 , O(XmmYmmMem) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(8C,U) , O_660F38(8E,U) ), - INST(kX86InstIdVpmaxsb , "vpmaxsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3C,U) , U ), - INST(kX86InstIdVpmaxsd , "vpmaxsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3D,U) , U ), - INST(kX86InstIdVpmaxsw , "vpmaxsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EE,U) , U ), - INST(kX86InstIdVpmaxub , "vpmaxub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DE,U) , U ), - INST(kX86InstIdVpmaxud , "vpmaxud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3F,U) , U ), - INST(kX86InstIdVpmaxuw , "vpmaxuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3E,U) , U ), - INST(kX86InstIdVpminsb , "vpminsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(38,U) , U ), - INST(kX86InstIdVpminsd , "vpminsd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(39,U) , U ), - INST(kX86InstIdVpminsw , "vpminsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EA,U) , U ), - INST(kX86InstIdVpminub , "vpminub" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(DA,U) , U ), - INST(kX86InstIdVpminud , "vpminud" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3B,U) , U ), - INST(kX86InstIdVpminuw , "vpminuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(3A,U) , U ), - INST(kX86InstIdVpmovmskb , "vpmovmskb" , G(AvxRm_P) , F(None) , 0 , O(Gqd) , O(XmmYmm) , U , U , E(________) , O_660F00(D7,U) , U ), - INST(kX86InstIdVpmovsxbd , "vpmovsxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(21,U) , U ), - INST(kX86InstIdVpmovsxbq , "vpmovsxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(22,U) , U ), - INST(kX86InstIdVpmovsxbw , "vpmovsxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(20,U) , U ), - INST(kX86InstIdVpmovsxdq , "vpmovsxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(25,U) , U ), - INST(kX86InstIdVpmovsxwd , "vpmovsxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(23,U) , U ), - INST(kX86InstIdVpmovsxwq , "vpmovsxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(24,U) , U ), - INST(kX86InstIdVpmovzxbd , "vpmovzxbd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(31,U) , U ), - INST(kX86InstIdVpmovzxbq , "vpmovzxbq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(32,U) , U ), - INST(kX86InstIdVpmovzxbw , "vpmovzxbw" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(30,U) , U ), - INST(kX86InstIdVpmovzxdq , "vpmovzxdq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(35,U) , U ), - INST(kX86InstIdVpmovzxwd , "vpmovzxwd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(33,U) , U ), - INST(kX86InstIdVpmovzxwq , "vpmovzxwq" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F38(34,U) , U ), - INST(kX86InstIdVpmuldq , "vpmuldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(28,U) , U ), - INST(kX86InstIdVpmulhrsw , "vpmulhrsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0B,U) , U ), - INST(kX86InstIdVpmulhuw , "vpmulhuw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E4,U) , U ), - INST(kX86InstIdVpmulhw , "vpmulhw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E5,U) , U ), - INST(kX86InstIdVpmulld , "vpmulld" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(40,U) , U ), - INST(kX86InstIdVpmullw , "vpmullw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D5,U) , U ), - INST(kX86InstIdVpmuludq , "vpmuludq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F4,U) , U ), - INST(kX86InstIdVpor , "vpor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EB,U) , U ), - INST(kX86InstIdVpperm , "vpperm" , G(XopRvrmRvmr) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , E(________) , O_00_M08(A3,U) , U ), - INST(kX86InstIdVprotb , "vprotb" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(90,U) , O_00_M08(C0,U) ), - INST(kX86InstIdVprotd , "vprotd" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(92,U) , O_00_M08(C2,U) ), - INST(kX86InstIdVprotq , "vprotq" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(93,U) , O_00_M08(C3,U) ), - INST(kX86InstIdVprotw , "vprotw" , G(XopRvmRmi) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , E(________) , O_00_M09(91,U) , O_00_M08(C1,U) ), - INST(kX86InstIdVpsadbw , "vpsadbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F6,U) , U ), - INST(kX86InstIdVpshab , "vpshab" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(98,U) , U ), - INST(kX86InstIdVpshad , "vpshad" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9A,U) , U ), - INST(kX86InstIdVpshaq , "vpshaq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(9B,U) , U ), - INST(kX86InstIdVpshaw , "vpshaw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(99,U) , U ), - INST(kX86InstIdVpshlb , "vpshlb" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(94,U) , U ), - INST(kX86InstIdVpshld , "vpshld" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(96,U) , U ), - INST(kX86InstIdVpshlq , "vpshlq" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(97,U) , U ), - INST(kX86InstIdVpshlw , "vpshlw" , G(XopRvmRmv) , F(None) , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , E(________) , O_00_M09(95,U) , U ), - INST(kX86InstIdVpshufb , "vpshufb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(00,U) , U ), - INST(kX86InstIdVpshufd , "vpshufd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(70,U) , U ), - INST(kX86InstIdVpshufhw , "vpshufhw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F30F00(70,U) , U ), - INST(kX86InstIdVpshuflw , "vpshuflw" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_F20F00(70,U) , U ), - INST(kX86InstIdVpsignb , "vpsignb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(08,U) , U ), - INST(kX86InstIdVpsignd , "vpsignd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(0A,U) , U ), - INST(kX86InstIdVpsignw , "vpsignw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(09,U) , U ), - INST(kX86InstIdVpslld , "vpslld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F2,U) , O_660F00(72,6) ), - INST(kX86InstIdVpslldq , "vpslldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,7) , U ), - INST(kX86InstIdVpsllq , "vpsllq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F3,U) , O_660F00(73,6) ), - INST(kX86InstIdVpsllvd , "vpsllvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ), - INST(kX86InstIdVpsllvq , "vpsllvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(47,U) , U ), - INST(kX86InstIdVpsllw , "vpsllw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(F1,U) , O_660F00(71,6) ), - INST(kX86InstIdVpsrad , "vpsrad" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E2,U) , O_660F00(72,4) ), - INST(kX86InstIdVpsravd , "vpsravd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(46,U) , U ), - INST(kX86InstIdVpsraw , "vpsraw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(E1,U) , O_660F00(71,4) ), - INST(kX86InstIdVpsrld , "vpsrld" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D2,U) , O_660F00(72,2) ), - INST(kX86InstIdVpsrldq , "vpsrldq" , G(AvxVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F00(73,3) , U ), - INST(kX86InstIdVpsrlq , "vpsrlq" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D3,U) , O_660F00(73,2) ), - INST(kX86InstIdVpsrlvd , "vpsrlvd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ), - INST(kX86InstIdVpsrlvq , "vpsrlvq" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F38(45,U) , U ), - INST(kX86InstIdVpsrlw , "vpsrlw" , G(AvxRvmVmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem)|O(Imm) , U , E(________) , O_660F00(D1,U) , O_660F00(71,2) ), - INST(kX86InstIdVpsubb , "vpsubb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F8,U) , U ), - INST(kX86InstIdVpsubd , "vpsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FA,U) , U ), - INST(kX86InstIdVpsubq , "vpsubq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(FB,U) , U ), - INST(kX86InstIdVpsubsb , "vpsubsb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E8,U) , U ), - INST(kX86InstIdVpsubsw , "vpsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(E9,U) , U ), - INST(kX86InstIdVpsubusb , "vpsubusb" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D8,U) , U ), - INST(kX86InstIdVpsubusw , "vpsubusw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(D9,U) , U ), - INST(kX86InstIdVpsubw , "vpsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(F9,U) , U ), - INST(kX86InstIdVptest , "vptest" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(17,U) , U ), - INST(kX86InstIdVpunpckhbw , "vpunpckhbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(68,U) , U ), - INST(kX86InstIdVpunpckhdq , "vpunpckhdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6A,U) , U ), - INST(kX86InstIdVpunpckhqdq , "vpunpckhqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6D,U) , U ), - INST(kX86InstIdVpunpckhwd , "vpunpckhwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(69,U) , U ), - INST(kX86InstIdVpunpcklbw , "vpunpcklbw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(60,U) , U ), - INST(kX86InstIdVpunpckldq , "vpunpckldq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(62,U) , U ), - INST(kX86InstIdVpunpcklqdq , "vpunpcklqdq" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(6C,U) , U ), - INST(kX86InstIdVpunpcklwd , "vpunpcklwd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(61,U) , U ), - INST(kX86InstIdVpxor , "vpxor" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(EF,U) , U ), - INST(kX86InstIdVrcpps , "vrcpps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(53,U) , U ), - INST(kX86InstIdVrcpss , "vrcpss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(53,U) , U ), - INST(kX86InstIdVroundpd , "vroundpd" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(09,U) , U ), - INST(kX86InstIdVroundps , "vroundps" , G(AvxRmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , U , E(________) , O_660F3A(08,U) , U ), - INST(kX86InstIdVroundsd , "vroundsd" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0B,U) , U ), - INST(kX86InstIdVroundss , "vroundss" , G(AvxRvmi) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , E(________) , O_660F3A(0A,U) , U ), - INST(kX86InstIdVrsqrtps , "vrsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(52,U) , U ), - INST(kX86InstIdVrsqrtss , "vrsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(52,U) , U ), - INST(kX86InstIdVshufpd , "vshufpd" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_660F00(C6,U) , U ), - INST(kX86InstIdVshufps , "vshufps" , G(AvxRvmi_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(Imm) , E(________) , O_000F00(C6,U) , U ), - INST(kX86InstIdVsqrtpd , "vsqrtpd" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_660F00(51,U) , U ), - INST(kX86InstIdVsqrtps , "vsqrtps" , G(AvxRm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(________) , O_000F00(51,U) , U ), - INST(kX86InstIdVsqrtsd , "vsqrtsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(51,U) , U ), - INST(kX86InstIdVsqrtss , "vsqrtss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(51,U) , U ), - INST(kX86InstIdVstmxcsr , "vstmxcsr" , G(AvxM) , F(None) , 0 , O(Mem) , U , U , U , E(________) , O_000F00(AE,3) , U ), - INST(kX86InstIdVsubpd , "vsubpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(5C,U) , U ), - INST(kX86InstIdVsubps , "vsubps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(5C,U) , U ), - INST(kX86InstIdVsubsd , "vsubsd" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F20F00(5C,U) , U ), - INST(kX86InstIdVsubss , "vsubss" , G(AvxRvm) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , E(________) , O_F30F00(5C,U) , U ), - INST(kX86InstIdVtestpd , "vtestpd" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0F,U) , U ), - INST(kX86InstIdVtestps , "vtestps" , G(AvxRm_P) , F(Test) , 0 , O(XmmYmm) , O(XmmYmmMem) , U , U , E(WWWWWW__) , O_660F38(0E,U) , U ), - INST(kX86InstIdVucomisd , "vucomisd" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_660F00(2E,U) , U ), - INST(kX86InstIdVucomiss , "vucomiss" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(WWWWWW__) , O_000F00(2E,U) , U ), - INST(kX86InstIdVunpckhpd , "vunpckhpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(15,U) , U ), - INST(kX86InstIdVunpckhps , "vunpckhps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(15,U) , U ), - INST(kX86InstIdVunpcklpd , "vunpcklpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(14,U) , U ), - INST(kX86InstIdVunpcklps , "vunpcklps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(14,U) , U ), - INST(kX86InstIdVxorpd , "vxorpd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_660F00(57,U) , U ), - INST(kX86InstIdVxorps , "vxorps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , E(________) , O_000F00(57,U) , U ), - INST(kX86InstIdVzeroall , "vzeroall" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U)|L, U ), - INST(kX86InstIdVzeroupper , "vzeroupper" , G(AvxOp) , F(None) , 0 , U , U , U , U , E(________) , O_000F00(77,U) , U ), - INST(kX86InstIdWrfsbase , "wrfsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,2) , U ), - INST(kX86InstIdWrgsbase , "wrgsbase" , G(X86Rm) , F(None) , 0 , O(Gqd) , U , U , U , E(________) , O_F30F00(AE,3) , U ), - INST(kX86InstIdXadd , "xadd" , G(X86Xadd) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(WWWWWW__) , O_000F00(C0,U) , U ), - INST(kX86InstIdXchg , "xchg" , G(X86Xchg) , F(Xchg)|F(Lock) , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , E(________) , O_000000(86,U) , U ), - INST(kX86InstIdXor , "xor" , G(X86Arith) , F(Lock) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , E(WWWUWW__) , O_000000(30,6) , U ), - INST(kX86InstIdXorpd , "xorpd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_660F00(57,U) , U ), - INST(kX86InstIdXorps , "xorps" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , E(________) , O_000F00(57,U) , U ) + // <----------------------------+--------------------+-------------------------------------------+-------------------+------------------------------------+-------------+-------+---------------------------------------------------------------------------------------------------+ + // | | Instruction Opcodes | | Instruction Flags | E-FLAGS | Write | Operands (Gp/Fp/Mm/K/Xmm/Ymm/Zmm Regs, Mem, Imm, Label, None/Undefined) | + // Instruction Id | Instruction Name +---------------------+---------------------+ Instruction Enc. +---------------+--------------------+-------------+---+---+-------------------+-------------------+-------------------+-------------------+-------------------+ + // | | 0:PP-MMM OP/O L/W/EW| 1:PP-MMM OP/O L/W/EW| | Global Flags |A512(ID|VL|kz|rnd|b)| EF:OSZAPCDX |Idx| Sz| [0] 1st Operand | [1] 2nd Operand | [2] 3rd Operand | [3] 4th Operand | [4] 5th Operand | + // <----------------------------+--------------------+---------------------+---------------------+-------------------+---------------+--------------------+-------------+---+---+-------------------+-------------------+-------------------+-------------------+-------------------+ + INST(kInstIdNone , "" , U , U , Enc(None) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdAdc , "adc" , O_000000(10,2,_,_,_), U , Enc(X86Arith) , F(Lock) , EF(WWWWWX__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdAdd , "add" , O_000000(00,0,_,_,_), U , Enc(X86Arith) , F(Lock) , EF(WWWWWW__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdAddpd , "addpd" , O_660F00(58,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAddps , "addps" , O_000F00(58,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAddsd , "addsd" , O_F20F00(58,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAddss , "addss" , O_F30F00(58,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAddsubpd , "addsubpd" , O_660F00(D0,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAddsubps , "addsubps" , O_F20F00(D0,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAesdec , "aesdec" , O_660F38(DE,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAesdeclast , "aesdeclast" , O_660F38(DF,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAesenc , "aesenc" , O_660F38(DC,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAesenclast , "aesenclast" , O_660F38(DD,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAesimc , "aesimc" , O_660F38(DB,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAeskeygenassist , "aeskeygenassist" , O_660F3A(DF,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdAnd , "and" , O_000000(20,4,_,_,_), U , Enc(X86Arith) , F(Lock) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdAndn , "andn" , O_000F38(F2,U,_,_,_), U , Enc(AvxRvm) , F(None) , EF(WWWUUW__), 0 , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , U ), + INST(kX86InstIdAndnpd , "andnpd" , O_660F00(55,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAndnps , "andnps" , O_000F00(55,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAndpd , "andpd" , O_660F00(54,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdAndps , "andps" , O_000F00(54,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdBextr , "bextr" , O_000F38(F7,U,_,_,_), U , Enc(AvxRmv) , F(None) , EF(WUWUUW__), 0 , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , U ), + INST(kX86InstIdBlendpd , "blendpd" , O_660F3A(0D,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdBlendps , "blendps" , O_660F3A(0C,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdBlendvpd , "blendvpd" , O_660F38(15,U,_,_,_), U , Enc(ExtRm) , F(None)|F(Special) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdBlendvps , "blendvps" , O_660F38(14,U,_,_,_), U , Enc(ExtRm) , F(None)|F(Special) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdBlsi , "blsi" , O_000F38(F3,3,_,_,_), U , Enc(AvxVm) , F(None) , EF(WWWUUW__), 0 , 0 , O(Gqd) , O(GqdMem) , U , U , U ), + INST(kX86InstIdBlsmsk , "blsmsk" , O_000F38(F3,2,_,_,_), U , Enc(AvxVm) , F(None) , EF(WWWUUW__), 0 , 0 , O(Gqd) , O(GqdMem) , U , U , U ), + INST(kX86InstIdBlsr , "blsr" , O_000F38(F3,1,_,_,_), U , Enc(AvxVm) , F(None) , EF(WWWUUW__), 0 , 0 , O(Gqd) , O(GqdMem) , U , U , U ), + INST(kX86InstIdBsf , "bsf" , O_000F00(BC,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(UUWUUU__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdBsr , "bsr" , O_000F00(BD,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(UUWUUU__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdBswap , "bswap" , O_000F00(C8,U,_,_,_), U , Enc(X86BSwap) , F(None) , EF(________), 0 , 0 , O(Gqd) , U , U , U , U ), + INST(kX86InstIdBt , "bt" , O_000F00(A3,U,_,_,_), O_000F00(BA,4,_,_,_), Enc(X86BTest) , F(Test) , EF(UU_UUW__), 0 , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U ), + INST(kX86InstIdBtc , "btc" , O_000F00(BB,U,_,_,_), O_000F00(BA,7,_,_,_), Enc(X86BTest) , F(Lock) , EF(UU_UUW__), 0 , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U ), + INST(kX86InstIdBtr , "btr" , O_000F00(B3,U,_,_,_), O_000F00(BA,6,_,_,_), Enc(X86BTest) , F(Lock) , EF(UU_UUW__), 0 , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U ), + INST(kX86InstIdBts , "bts" , O_000F00(AB,U,_,_,_), O_000F00(BA,5,_,_,_), Enc(X86BTest) , F(Lock) , EF(UU_UUW__), 0 , 0 , O(GqdwMem) , O(Gqdw)|O(Imm) , U , U , U ), + INST(kX86InstIdBzhi , "bzhi" , O_000F38(F5,U,_,_,_), U , Enc(AvxRmv) , F(None) , EF(WWWUUW__), 0 , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , U ), + INST(kX86InstIdCall , "call" , O_000000(FF,2,_,_,_), O_000000(E8,U,_,_,_), Enc(X86Call) , F(Flow) , EF(________), 0 , 0 , O(GqdMem)|O(LbImm), U , U , U , U ), + INST(kX86InstIdCbw , "cbw" , O_660000(98,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCdq , "cdq" , O_000000(99,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCdqe , "cdqe" , O_000000(98,U,_,W,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdClc , "clc" , O_000000(F8,U,_,_,_), U , Enc(X86Op) , F(None) , EF(_____W__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCld , "cld" , O_000000(FC,U,_,_,_), U , Enc(X86Op) , F(None) , EF(______W_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdClflush , "clflush" , O_000F00(AE,7,_,_,_), U , Enc(X86M) , F(None) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdCmc , "cmc" , O_000000(F5,U,_,_,_), U , Enc(X86Op) , F(None) , EF(_____X__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCmova , "cmova" , O_000F00(47,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R__R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovae , "cmovae" , O_000F00(43,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_____R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovb , "cmovb" , O_000F00(42,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_____R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovbe , "cmovbe" , O_000F00(46,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R__R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovc , "cmovc" , O_000F00(42,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_____R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmove , "cmove" , O_000F00(44,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovg , "cmovg" , O_000F00(4F,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RRR_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovge , "cmovge" , O_000F00(4D,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RR______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovl , "cmovl" , O_000F00(4C,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RR______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovle , "cmovle" , O_000F00(4E,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RRR_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovna , "cmovna" , O_000F00(46,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R__R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnae , "cmovnae" , O_000F00(42,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_____R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnb , "cmovnb" , O_000F00(43,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_____R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnbe , "cmovnbe" , O_000F00(47,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R__R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnc , "cmovnc" , O_000F00(43,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_____R__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovne , "cmovne" , O_000F00(45,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovng , "cmovng" , O_000F00(4E,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RRR_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnge , "cmovnge" , O_000F00(4C,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RR______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnl , "cmovnl" , O_000F00(4D,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RR______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnle , "cmovnle" , O_000F00(4F,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(RRR_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovno , "cmovno" , O_000F00(41,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(R_______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnp , "cmovnp" , O_000F00(4B,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(____R___), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovns , "cmovns" , O_000F00(49,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_R______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovnz , "cmovnz" , O_000F00(45,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovo , "cmovo" , O_000F00(40,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(R_______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovp , "cmovp" , O_000F00(4A,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(____R___), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovpe , "cmovpe" , O_000F00(4A,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(____R___), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovpo , "cmovpo" , O_000F00(4B,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(____R___), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovs , "cmovs" , O_000F00(48,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(_R______), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmovz , "cmovz" , O_000F00(44,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(__R_____), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdCmp , "cmp" , O_000000(38,7,_,_,_), U , Enc(X86Arith) , F(Test) , EF(WWWWWW__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdCmppd , "cmppd" , O_660F00(C2,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdCmpps , "cmpps" , O_000F00(C2,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdCmpsB , "cmps_b" , O_000000(A6,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCmpsD , "cmps_d" , O_000000(A7,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCmpsQ , "cmps_q" , O_000000(A7,U,_,W,_), U , Enc(X86Op) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCmpsW , "cmps_w" , O_000000(A7,U,_,_,_), U , Enc(X86Op_66H) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCmpsd , "cmpsd" , O_F20F00(C2,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdCmpss , "cmpss" , O_F30F00(C2,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdCmpxchg , "cmpxchg" , O_000F00(B0,U,_,_,_), U , Enc(X86RmReg) , F(Lock)|F(Special) , EF(WWWWWW__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCmpxchg16b , "cmpxchg16b" , O_000F00(C7,1,_,W,_), U , Enc(X86M) , F(None)|F(Special) , EF(__W_____), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdCmpxchg8b , "cmpxchg8b" , O_000F00(C7,1,_,_,_), U , Enc(X86M) , F(None)|F(Special) , EF(__W_____), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdComisd , "comisd" , O_660F00(2F,U,_,_,_), U , Enc(ExtRm) , F(Test) , EF(WWWWWW__), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdComiss , "comiss" , O_000F00(2F,U,_,_,_), U , Enc(ExtRm) , F(Test) , EF(WWWWWW__), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCpuid , "cpuid" , O_000F00(A2,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCqo , "cqo" , O_000000(99,U,_,W,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCrc32 , "crc32" , O_F20F38(F0,U,_,_,_), U , Enc(ExtCrc) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(GqdwbMem) , U , U , U ), + INST(kX86InstIdCvtdq2pd , "cvtdq2pd" , O_F30F00(E6,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtdq2ps , "cvtdq2ps" , O_000F00(5B,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtpd2dq , "cvtpd2dq" , O_F20F00(E6,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtpd2pi , "cvtpd2pi" , O_660F00(2D,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 8 , O(Mm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtpd2ps , "cvtpd2ps" , O_660F00(5A,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtpi2pd , "cvtpi2pd" , O_660F00(2A,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(MmMem) , U , U , U ), + INST(kX86InstIdCvtpi2ps , "cvtpi2ps" , O_000F00(2A,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 8 , O(Xmm) , O(MmMem) , U , U , U ), + INST(kX86InstIdCvtps2dq , "cvtps2dq" , O_660F00(5B,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtps2pd , "cvtps2pd" , O_000F00(5A,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtps2pi , "cvtps2pi" , O_000F00(2D,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 8 , O(Mm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtsd2si , "cvtsd2si" , O_F20F00(2D,U,_,_,_), U , Enc(ExtRm_Q) , F(Move) , EF(________), 0 , 8 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtsd2ss , "cvtsd2ss" , O_F20F00(5A,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 4 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtsi2sd , "cvtsi2sd" , O_F20F00(2A,U,_,_,_), U , Enc(ExtRm_Q) , F(Move) , EF(________), 0 , 8 , O(Xmm) , O(GqdMem) , U , U , U ), + INST(kX86InstIdCvtsi2ss , "cvtsi2ss" , O_F30F00(2A,U,_,_,_), U , Enc(ExtRm_Q) , F(Move) , EF(________), 0 , 4 , O(Xmm) , O(GqdMem) , U , U , U ), + INST(kX86InstIdCvtss2sd , "cvtss2sd" , O_F30F00(5A,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 8 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvtss2si , "cvtss2si" , O_F30F00(2D,U,_,_,_), U , Enc(ExtRm_Q) , F(Move) , EF(________), 0 , 8 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvttpd2dq , "cvttpd2dq" , O_660F00(E6,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvttpd2pi , "cvttpd2pi" , O_660F00(2C,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 8 , O(Mm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvttps2dq , "cvttps2dq" , O_F30F00(5B,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvttps2pi , "cvttps2pi" , O_000F00(2C,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 8 , O(Mm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvttsd2si , "cvttsd2si" , O_F20F00(2C,U,_,_,_), U , Enc(ExtRm_Q) , F(Move) , EF(________), 0 , 8 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCvttss2si , "cvttss2si" , O_F30F00(2C,U,_,_,_), U , Enc(ExtRm_Q) , F(Move) , EF(________), 0 , 8 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdCwd , "cwd" , O_660000(99,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdCwde , "cwde" , O_000000(98,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdDaa , "daa" , O_000000(27,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(UWWXWX__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdDas , "das" , O_000000(2F,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(UWWXWX__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdDec , "dec" , O_000000(FE,1,_,_,_), O_000000(48,U,_,_,_), Enc(X86IncDec) , F(Lock) , EF(WWWWW___), 0 , 0 , O(GqdwbMem) , U , U , U , U ), + INST(kX86InstIdDiv , "div" , O_000000(F6,6,_,_,_), U , Enc(X86Rm_B) , F(None)|F(Special) , EF(UUUUUU__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdDivpd , "divpd" , O_660F00(5E,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdDivps , "divps" , O_000F00(5E,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdDivsd , "divsd" , O_F20F00(5E,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdDivss , "divss" , O_F30F00(5E,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdDppd , "dppd" , O_660F3A(41,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdDpps , "dpps" , O_660F3A(40,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdEmms , "emms" , O_000F00(77,U,_,_,_), U , Enc(X86Op) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdEnter , "enter" , O_000000(C8,U,_,_,_), U , Enc(X86Enter) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdExtractps , "extractps" , O_660F3A(17,U,_,_,_), O_660F3A(17,U,_,_,_), Enc(ExtExtract) , F(Move) , EF(________), 0 , 8 , O(GqdMem) , O(Xmm) , U , U , U ), + INST(kX86InstIdExtrq , "extrq" , O_660F00(79,U,_,_,_), O_660F00(78,0,_,_,_), Enc(ExtExtrq) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(Xmm)|O(Imm) , O(None)|O(Imm) , U , U ), + INST(kX86InstIdF2xm1 , "f2xm1" , O_00_X(D9F0,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFabs , "fabs" , O_00_X(D9E1,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFadd , "fadd" , O_00_X(C0C0,0) , U , Enc(FpuArith) , F(Fp)|F(Mem4_8) , EF(________), 0 , 0 , O(FpMem) , O(Fp) , U , U , U ), + INST(kX86InstIdFaddp , "faddp" , O_00_X(DEC0,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFbld , "fbld" , O_000000(DF,4,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFbstp , "fbstp" , O_000000(DF,6,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFchs , "fchs" , O_00_X(D9E0,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFclex , "fclex" , O_9B_X(DBE2,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFcmovb , "fcmovb" , O_00_X(DAC0,U) , U , Enc(FpuR) , F(Fp) , EF(_____R__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcmovbe , "fcmovbe" , O_00_X(DAD0,U) , U , Enc(FpuR) , F(Fp) , EF(__R__R__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcmove , "fcmove" , O_00_X(DAC8,U) , U , Enc(FpuR) , F(Fp) , EF(__R_____), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcmovnb , "fcmovnb" , O_00_X(DBC0,U) , U , Enc(FpuR) , F(Fp) , EF(_____R__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcmovnbe , "fcmovnbe" , O_00_X(DBD0,U) , U , Enc(FpuR) , F(Fp) , EF(__R__R__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcmovne , "fcmovne" , O_00_X(DBC8,U) , U , Enc(FpuR) , F(Fp) , EF(__R_____), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcmovnu , "fcmovnu" , O_00_X(DBD8,U) , U , Enc(FpuR) , F(Fp) , EF(____R___), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcmovu , "fcmovu" , O_00_X(DAD8,U) , U , Enc(FpuR) , F(Fp) , EF(____R___), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcom , "fcom" , O_00_X(D0D0,2) , U , Enc(FpuCom) , F(Fp) , EF(________), 0 , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , U ), + INST(kX86InstIdFcomi , "fcomi" , O_00_X(DBF0,U) , U , Enc(FpuR) , F(Fp) , EF(WWWWWW__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcomip , "fcomip" , O_00_X(DFF0,U) , U , Enc(FpuR) , F(Fp) , EF(WWWWWW__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFcomp , "fcomp" , O_00_X(D8D8,3) , U , Enc(FpuCom) , F(Fp) , EF(________), 0 , 0 , O(Fp)|O(Mem) , O(Fp) , U , U , U ), + INST(kX86InstIdFcompp , "fcompp" , O_00_X(DED9,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFcos , "fcos" , O_00_X(D9FF,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFdecstp , "fdecstp" , O_00_X(D9F6,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFdiv , "fdiv" , O_00_X(F0F8,6) , U , Enc(FpuArith) , F(Fp)|F(Mem4_8) , EF(________), 0 , 0 , O(FpMem) , O(Fp) , U , U , U ), + INST(kX86InstIdFdivp , "fdivp" , O_00_X(DEF8,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFdivr , "fdivr" , O_00_X(F8F0,7) , U , Enc(FpuArith) , F(Fp)|F(Mem4_8) , EF(________), 0 , 0 , O(FpMem) , O(Fp) , U , U , U ), + INST(kX86InstIdFdivrp , "fdivrp" , O_00_X(DEF0,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFemms , "femms" , O_000F00(0E,U,_,_,_), U , Enc(X86Op) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFfree , "ffree" , O_00_X(DDC0,U) , U , Enc(FpuR) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFiadd , "fiadd" , O_000000(DA,0,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFicom , "ficom" , O_000000(DA,2,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFicomp , "ficomp" , O_000000(DA,3,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFidiv , "fidiv" , O_000000(DA,6,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFidivr , "fidivr" , O_000000(DA,7,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFild , "fild" , O_000000(DB,0,_,_,_), O_000000(DF,5,_,_,_), Enc(FpuM) , F(Fp)|F(Mem2_4_8) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFimul , "fimul" , O_000000(DA,1,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFincstp , "fincstp" , O_00_X(D9F7,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFinit , "finit" , O_9B_X(DBE3,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFist , "fist" , O_000000(DB,2,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFistp , "fistp" , O_000000(DB,3,_,_,_), O_000000(DF,7,_,_,_), Enc(FpuM) , F(Fp)|F(Mem2_4_8) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFisttp , "fisttp" , O_000000(DB,1,_,_,_), O_000000(DD,1,_,_,_), Enc(FpuM) , F(Fp)|F(Mem2_4_8) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFisub , "fisub" , O_000000(DA,4,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFisubr , "fisubr" , O_000000(DA,5,_,_,_), U , Enc(FpuM) , F(Fp)|F(Mem2_4) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFld , "fld" , O_000000(D9,0,_,_,_), O_000000(DB,5,_,_,_), Enc(FpuFldFst) , F(Fp)|F(Mem4_8_10) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFld1 , "fld1" , O_00_X(D9E8,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFldcw , "fldcw" , O_000000(D9,5,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFldenv , "fldenv" , O_000000(D9,4,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFldl2e , "fldl2e" , O_00_X(D9EA,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFldl2t , "fldl2t" , O_00_X(D9E9,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFldlg2 , "fldlg2" , O_00_X(D9EC,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFldln2 , "fldln2" , O_00_X(D9ED,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFldpi , "fldpi" , O_00_X(D9EB,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFldz , "fldz" , O_00_X(D9EE,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFmul , "fmul" , O_00_X(C8C8,1) , U , Enc(FpuArith) , F(Fp)|F(Mem4_8) , EF(________), 0 , 0 , O(FpMem) , O(Fp) , U , U , U ), + INST(kX86InstIdFmulp , "fmulp" , O_00_X(DEC8,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFnclex , "fnclex" , O_00_X(DBE2,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFninit , "fninit" , O_00_X(DBE3,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFnop , "fnop" , O_00_X(D9D0,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFnsave , "fnsave" , O_000000(DD,6,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFnstcw , "fnstcw" , O_000000(D9,7,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFnstenv , "fnstenv" , O_000000(D9,6,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFnstsw , "fnstsw" , O_000000(DD,7,_,_,_), O_00_X(DFE0,U) , Enc(FpuStsw) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFpatan , "fpatan" , O_00_X(D9F3,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFprem , "fprem" , O_00_X(D9F8,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFprem1 , "fprem1" , O_00_X(D9F5,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFptan , "fptan" , O_00_X(D9F2,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFrndint , "frndint" , O_00_X(D9FC,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFrstor , "frstor" , O_000000(DD,4,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFsave , "fsave" , O_9B0000(DD,6,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFscale , "fscale" , O_00_X(D9FD,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFsin , "fsin" , O_00_X(D9FE,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFsincos , "fsincos" , O_00_X(D9FB,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFsqrt , "fsqrt" , O_00_X(D9FA,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFst , "fst" , O_000000(D9,2,_,_,_), U , Enc(FpuFldFst) , F(Fp)|F(Mem4_8) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFstcw , "fstcw" , O_9B0000(D9,7,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFstenv , "fstenv" , O_9B0000(D9,6,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFstp , "fstp" , O_000000(D9,3,_,_,_), O_000000(DB,7,_,_,_), Enc(FpuFldFst) , F(Fp)|F(Mem4_8_10) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFstsw , "fstsw" , O_9B0000(DD,7,_,_,_), O_9B_X(DFE0,U) , Enc(FpuStsw) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFsub , "fsub" , O_00_X(E0E8,4) , U , Enc(FpuArith) , F(Fp)|F(Mem4_8) , EF(________), 0 , 0 , O(FpMem) , O(Fp) , U , U , U ), + INST(kX86InstIdFsubp , "fsubp" , O_00_X(DEE8,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFsubr , "fsubr" , O_00_X(E8E0,5) , U , Enc(FpuArith) , F(Fp)|F(Mem4_8) , EF(________), 0 , 0 , O(FpMem) , O(Fp) , U , U , U ), + INST(kX86InstIdFsubrp , "fsubrp" , O_00_X(DEE0,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFtst , "ftst" , O_00_X(D9E4,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFucom , "fucom" , O_00_X(DDE0,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFucomi , "fucomi" , O_00_X(DBE8,U) , U , Enc(FpuR) , F(Fp) , EF(WWWWWW__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFucomip , "fucomip" , O_00_X(DFE8,U) , U , Enc(FpuR) , F(Fp) , EF(WWWWWW__), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFucomp , "fucomp" , O_00_X(DDE8,U) , U , Enc(FpuRDef) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFucompp , "fucompp" , O_00_X(DAE9,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFwait , "fwait" , O_000000(DB,U,_,_,_), U , Enc(X86Op) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFxam , "fxam" , O_00_X(D9E5,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFxch , "fxch" , O_00_X(D9C8,U) , U , Enc(FpuR) , F(Fp) , EF(________), 0 , 0 , O(Fp) , U , U , U , U ), + INST(kX86InstIdFxrstor , "fxrstor" , O_000F00(AE,1,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFxsave , "fxsave" , O_000F00(AE,0,_,_,_), U , Enc(X86M) , F(Fp) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdFxtract , "fxtract" , O_00_X(D9F4,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFyl2x , "fyl2x" , O_00_X(D9F1,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdFyl2xp1 , "fyl2xp1" , O_00_X(D9F9,U) , U , Enc(FpuOp) , F(Fp) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdHaddpd , "haddpd" , O_660F00(7C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdHaddps , "haddps" , O_F20F00(7C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdHsubpd , "hsubpd" , O_660F00(7D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdHsubps , "hsubps" , O_F20F00(7D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdIdiv , "idiv" , O_000000(F6,7,_,_,_), U , Enc(X86Rm_B) , F(None)|F(Special) , EF(UUUUUU__), 0 , 0 , 0 , 0 , U , U , U ), + INST(kX86InstIdImul , "imul" , U , U , Enc(X86Imul) , F(None)|F(Special) , EF(WUUUUW__), 0 , 0 , 0 , 0 , U , U , U ), + INST(kX86InstIdInc , "inc" , O_000000(FE,0,_,_,_), O_000000(40,U,_,_,_), Enc(X86IncDec) , F(Lock) , EF(WWWWW___), 0 , 0 , O(GqdwbMem) , U , U , U , U ), + INST(kX86InstIdInsertps , "insertps" , O_660F3A(21,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdInsertq , "insertq" , O_F20F00(79,U,_,_,_), O_F20F00(78,U,_,_,_), Enc(ExtInsertq) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(None)|O(Imm) , O(None)|O(Imm) , U ), + INST(kX86InstIdInt , "int" , O_000000(CC,U,_,_,_), U , Enc(X86Int) , F(None) , EF(_______W), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdJa , "ja" , O_000000(77,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R__R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJae , "jae" , O_000000(73,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_____R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJb , "jb" , O_000000(72,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_____R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJbe , "jbe" , O_000000(76,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R__R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJc , "jc" , O_000000(72,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_____R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJe , "je" , O_000000(74,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJg , "jg" , O_000000(7F,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RRR_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJge , "jge" , O_000000(7D,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RR______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJl , "jl" , O_000000(7C,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RR______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJle , "jle" , O_000000(7E,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RRR_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJna , "jna" , O_000000(76,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R__R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnae , "jnae" , O_000000(72,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_____R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnb , "jnb" , O_000000(73,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_____R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnbe , "jnbe" , O_000000(77,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R__R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnc , "jnc" , O_000000(73,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_____R__), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJne , "jne" , O_000000(75,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJng , "jng" , O_000000(7E,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RRR_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnge , "jnge" , O_000000(7C,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RR______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnl , "jnl" , O_000000(7D,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RR______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnle , "jnle" , O_000000(7F,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(RRR_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJno , "jno" , O_000000(71,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(R_______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnp , "jnp" , O_000000(7B,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(____R___), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJns , "jns" , O_000000(79,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_R______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJnz , "jnz" , O_000000(75,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJo , "jo" , O_000000(70,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(R_______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJp , "jp" , O_000000(7A,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(____R___), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJpe , "jpe" , O_000000(7A,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(____R___), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJpo , "jpo" , O_000000(7B,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(____R___), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJs , "js" , O_000000(78,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(_R______), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJz , "jz" , O_000000(74,U,_,_,_), U , Enc(X86Jcc) , F(Flow) , EF(__R_____), 0 , 0 , O(Label) , U , U , U , U ), + INST(kX86InstIdJecxz , "jecxz" , O_000000(E3,U,_,_,_), U , Enc(X86Jecxz) , F(Flow)|F(Special) , EF(________), 0 , 0 , O(Gqdw) , O(Label) , U , U , U ), + INST(kX86InstIdJmp , "jmp" , O_000000(FF,4,_,_,_), O_000000(E9,U,_,_,_), Enc(X86Jmp) , F(Flow) , EF(________), 0 , 0 , O(Label)|O(Imm) , U , U , U , U ), + INST(kX86InstIdLahf , "lahf" , O_000000(9F,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(_RRRRR__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdLddqu , "lddqu" , O_F20F00(F0,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(Mem) , U , U , U ), + INST(kX86InstIdLdmxcsr , "ldmxcsr" , O_000F00(AE,2,_,_,_), U , Enc(X86M) , F(None) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdLea , "lea" , O_000000(8D,U,_,_,_), U , Enc(X86Lea) , F(Move) , EF(________), 0 , 0 , O(Gqd) , O(Mem) , U , U , U ), + INST(kX86InstIdLeave , "leave" , O_000000(C9,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdLfence , "lfence" , O_000F00(AE,5,_,_,_), U , Enc(ExtFence) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdLodsB , "lods_b" , O_000000(AC,U,_,_,_), U , Enc(X86Op) , F(Move)|F(Special) , EF(______R_), 0 , 1 , U , U , U , U , U ), + INST(kX86InstIdLodsD , "lods_d" , O_000000(AD,U,_,_,_), U , Enc(X86Op) , F(Move)|F(Special) , EF(______R_), 0 , 4 , U , U , U , U , U ), + INST(kX86InstIdLodsQ , "lods_q" , O_000000(AD,U,_,W,_), U , Enc(X86Op) , F(Move)|F(Special) , EF(______R_), 0 , 8 , U , U , U , U , U ), + INST(kX86InstIdLodsW , "lods_w" , O_000000(AD,U,_,_,_), U , Enc(X86Op_66H) , F(Move)|F(Special) , EF(______R_), 0 , 2 , U , U , U , U , U ), + INST(kX86InstIdLzcnt , "lzcnt" , O_F30F00(BD,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(UUWUUW__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdMaskmovdqu , "maskmovdqu" , O_660F00(57,U,_,_,_), U , Enc(ExtRm) , F(None)|F(Special) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , U , U , U ), + INST(kX86InstIdMaskmovq , "maskmovq" , O_000F00(F7,U,_,_,_), U , Enc(ExtRm) , F(None)|F(Special) , EF(________), 0 , 0 , O(Mm) , O(Mm) , U , U , U ), + INST(kX86InstIdMaxpd , "maxpd" , O_660F00(5F,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMaxps , "maxps" , O_000F00(5F,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMaxsd , "maxsd" , O_F20F00(5F,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMaxss , "maxss" , O_F30F00(5F,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMfence , "mfence" , O_000F00(AE,6,_,_,_), U , Enc(ExtFence) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdMinpd , "minpd" , O_660F00(5D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMinps , "minps" , O_000F00(5D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMinsd , "minsd" , O_F20F00(5D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMinss , "minss" , O_F30F00(5D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMonitor , "monitor" , O_000F01(C8,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdMov , "mov" , U , U , Enc(X86Mov) , F(Move) , EF(________), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdMovPtr , "mov_ptr" , O_000000(A0,U,_,_,_), O_000000(A2,U,_,_,_), Enc(X86MovPtr) , F(Move)|F(Special) , EF(________), 0 , 0 , O(Gqdwb) , O(Imm) , U , U , U ), + INST(kX86InstIdMovapd , "movapd" , O_660F00(28,U,_,_,_), O_660F00(29,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovaps , "movaps" , O_000F00(28,U,_,_,_), O_000F00(29,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovbe , "movbe" , O_000F38(F0,U,_,_,_), O_000F38(F1,U,_,_,_), Enc(ExtMovBe) , F(Move) , EF(________), 0 , 0 , O(GqdwMem) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdMovd , "movd" , O_000F00(6E,U,_,_,_), O_000F00(7E,U,_,_,_), Enc(ExtMovD) , F(Move) , EF(________), 0 , 16, O(Gd)|O(MmXmmMem) , O(Gd)|O(MmXmmMem) , U , U , U ), + INST(kX86InstIdMovddup , "movddup" , O_F20F00(12,U,_,_,_), U , Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovdq2q , "movdq2q" , O_F20F00(D6,U,_,_,_), U , Enc(ExtMov) , F(Move) , EF(________), 0 , 8 , O(Mm) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovdqa , "movdqa" , O_660F00(6F,U,_,_,_), O_660F00(7F,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovdqu , "movdqu" , O_F30F00(6F,U,_,_,_), O_F30F00(7F,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovhlps , "movhlps" , O_000F00(12,U,_,_,_), U , Enc(ExtMov) , F(Move) , EF(________), 0 , 8 , O(Xmm) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovhpd , "movhpd" , O_660F00(16,U,_,_,_), O_660F00(17,U,_,_,_), Enc(ExtMov) , F(None) , EF(________), 8 , 8 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovhps , "movhps" , O_000F00(16,U,_,_,_), O_000F00(17,U,_,_,_), Enc(ExtMov) , F(None) , EF(________), 8 , 8 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovlhps , "movlhps" , O_000F00(16,U,_,_,_), U , Enc(ExtMov) , F(None) , EF(________), 8 , 8 , O(Xmm) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovlpd , "movlpd" , O_660F00(12,U,_,_,_), O_660F00(13,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 8 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovlps , "movlps" , O_000F00(12,U,_,_,_), O_000F00(13,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 8 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovmskpd , "movmskpd" , O_660F00(50,U,_,_,_), U , Enc(ExtMovNoRexW) , F(Move) , EF(________), 0 , 8 , O(Gqd) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovmskps , "movmskps" , O_000F00(50,U,_,_,_), U , Enc(ExtMovNoRexW) , F(Move) , EF(________), 0 , 8 , O(Gqd) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovntdq , "movntdq" , U , O_660F00(E7,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(Mem) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovntdqa , "movntdqa" , O_660F38(2A,U,_,_,_), U , Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(Mem) , U , U , U ), + INST(kX86InstIdMovnti , "movnti" , U , O_000F00(C3,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 8 , O(Mem) , O(Gqd) , U , U , U ), + INST(kX86InstIdMovntpd , "movntpd" , U , O_660F00(2B,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(Mem) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovntps , "movntps" , U , O_000F00(2B,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(Mem) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovntq , "movntq" , U , O_000F00(E7,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 8 , O(Mem) , O(Mm) , U , U , U ), + INST(kX86InstIdMovntsd , "movntsd" , U , O_F20F00(2B,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 8 , O(Mem) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovntss , "movntss" , U , O_F30F00(2B,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 4 , O(Mem) , O(Xmm) , U , U , U ), + INST(kX86InstIdMovq , "movq" , O_000F00(6E,U,_,W,_), O_000F00(7E,U,_,W,_), Enc(ExtMovQ) , F(Move) , EF(________), 0 , 16, O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U ), + INST(kX86InstIdMovq2dq , "movq2dq" , O_F30F00(D6,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(Mm) , U , U , U ), + INST(kX86InstIdMovsB , "movs_b" , O_000000(A4,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdMovsD , "movs_d" , O_000000(A5,U,_,_,_), U , Enc(X86Op) , F(Move)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdMovsQ , "movs_q" , O_000000(A5,U,_,W,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdMovsW , "movs_w" , O_000000(A5,U,_,_,_), U , Enc(X86Op_66H) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdMovsd , "movsd" , O_F20F00(10,U,_,_,_), O_F20F00(11,U,_,_,_), Enc(ExtMov) , F(Move) |F(Z) , EF(________), 0 , 8 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovshdup , "movshdup" , O_F30F00(16,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovsldup , "movsldup" , O_F30F00(12,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovss , "movss" , O_F30F00(10,U,_,_,_), O_F30F00(11,U,_,_,_), Enc(ExtMov) , F(Move) |F(Z) , EF(________), 0 , 4 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovsx , "movsx" , O_000F00(BE,U,_,_,_), U , Enc(X86MovSxZx) , F(Move) , EF(________), 0 , 0 , O(Gqdw) , O(GwbMem) , U , U , U ), + INST(kX86InstIdMovsxd , "movsxd" , O_000000(63,U,_,_,_), U , Enc(X86MovSxd) , F(Move) , EF(________), 0 , 0 , O(Gq) , O(GdMem) , U , U , U ), + INST(kX86InstIdMovupd , "movupd" , O_660F00(10,U,_,_,_), O_660F00(11,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovups , "movups" , O_000F00(10,U,_,_,_), O_000F00(11,U,_,_,_), Enc(ExtMov) , F(Move) , EF(________), 0 , 16, O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMovzx , "movzx" , O_000F00(B6,U,_,_,_), U , Enc(X86MovSxZx) , F(Move) , EF(________), 0 , 0 , O(Gqdw) , O(GwbMem) , U , U , U ), + INST(kX86InstIdMpsadbw , "mpsadbw" , O_660F3A(42,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdMul , "mul" , O_000000(F6,4,_,_,_), U , Enc(X86Rm_B) , F(None)|F(Special) , EF(WUUUUW__), 0 , 0 , 0 , 0 , U , U , U ), + INST(kX86InstIdMulpd , "mulpd" , O_660F00(59,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMulps , "mulps" , O_000F00(59,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMulsd , "mulsd" , O_F20F00(59,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMulss , "mulss" , O_F30F00(59,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdMulx , "mulx" , O_F20F38(F6,U,_,_,_), U , Enc(AvxRvm) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , U ), + INST(kX86InstIdMwait , "mwait" , O_000F01(C9,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdNeg , "neg" , O_000000(F6,3,_,_,_), U , Enc(X86Rm_B) , F(Lock) , EF(WWWWWW__), 0 , 0 , O(GqdwbMem) , U , U , U , U ), + INST(kX86InstIdNop , "nop" , O_000000(90,U,_,_,_), U , Enc(X86Op) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdNot , "not" , O_000000(F6,2,_,_,_), U , Enc(X86Rm_B) , F(Lock) , EF(________), 0 , 0 , O(GqdwbMem) , U , U , U , U ), + INST(kX86InstIdOr , "or" , O_000000(08,1,_,_,_), U , Enc(X86Arith) , F(Lock) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdOrpd , "orpd" , O_660F00(56,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdOrps , "orps" , O_000F00(56,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPabsb , "pabsb" , O_000F38(1C,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPabsd , "pabsd" , O_000F38(1E,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPabsw , "pabsw" , O_000F38(1D,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPackssdw , "packssdw" , O_000F00(6B,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPacksswb , "packsswb" , O_000F00(63,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPackusdw , "packusdw" , O_660F38(2B,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPackuswb , "packuswb" , O_000F00(67,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddb , "paddb" , O_000F00(FC,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddd , "paddd" , O_000F00(FE,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddq , "paddq" , O_000F00(D4,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddsb , "paddsb" , O_000F00(EC,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddsw , "paddsw" , O_000F00(ED,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddusb , "paddusb" , O_000F00(DC,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddusw , "paddusw" , O_000F00(DD,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPaddw , "paddw" , O_000F00(FD,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPalignr , "palignr" , O_000F3A(0F,U,_,_,_), U , Enc(ExtRmi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPand , "pand" , O_000F00(DB,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPandn , "pandn" , O_000F00(DF,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPause , "pause" , O_F30000(90,U,_,_,_), U , Enc(X86Op) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdPavgb , "pavgb" , O_000F00(E0,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPavgw , "pavgw" , O_000F00(E3,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPblendvb , "pblendvb" , O_660F38(10,U,_,_,_), U , Enc(ExtRm) , F(None)|F(Special) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPblendw , "pblendw" , O_660F3A(0E,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPclmulqdq , "pclmulqdq" , O_660F3A(44,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPcmpeqb , "pcmpeqb" , O_000F00(74,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPcmpeqd , "pcmpeqd" , O_000F00(76,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPcmpeqq , "pcmpeqq" , O_660F38(29,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPcmpeqw , "pcmpeqw" , O_000F00(75,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPcmpestri , "pcmpestri" , O_660F3A(61,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPcmpestrm , "pcmpestrm" , O_660F3A(60,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPcmpgtb , "pcmpgtb" , O_000F00(64,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPcmpgtd , "pcmpgtd" , O_000F00(66,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPcmpgtq , "pcmpgtq" , O_660F38(37,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPcmpgtw , "pcmpgtw" , O_000F00(65,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPcmpistri , "pcmpistri" , O_660F3A(63,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPcmpistrm , "pcmpistrm" , O_660F3A(62,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPdep , "pdep" , O_F20F38(F5,U,_,_,_), U , Enc(AvxRvm) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , U ), + INST(kX86InstIdPext , "pext" , O_F30F38(F5,U,_,_,_), U , Enc(AvxRvm) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(Gqd) , O(GqdMem) , U , U ), + INST(kX86InstIdPextrb , "pextrb" , O_000F3A(14,U,_,_,_), O_000F3A(14,U,_,_,_), Enc(ExtExtract) , F(Move) , EF(________), 0 , 8 , O(Gd)|O(Gb)|O(Mem), O(Xmm) , U , U , U ), + INST(kX86InstIdPextrd , "pextrd" , O_000F3A(16,U,_,_,_), O_000F3A(16,U,_,_,_), Enc(ExtExtract) , F(Move) , EF(________), 0 , 8 , O(GdMem) , O(Xmm) , U , U , U ), + INST(kX86InstIdPextrq , "pextrq" , O_000F3A(16,U,_,W,_), O_000F3A(16,U,_,W,_), Enc(ExtExtract) , F(Move) , EF(________), 0 , 8 , O(GqdMem) , O(Xmm) , U , U , U ), + INST(kX86InstIdPextrw , "pextrw" , O_000F00(C5,U,_,_,_), O_000F3A(15,U,_,_,_), Enc(ExtExtract) , F(Move) , EF(________), 0 , 8 , O(GdMem) , O(MmXmm) , U , U , U ), + INST(kX86InstIdPf2id , "pf2id" , O_000F0F(1D,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPf2iw , "pf2iw" , O_000F0F(1C,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfacc , "pfacc" , O_000F0F(AE,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfadd , "pfadd" , O_000F0F(9E,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfcmpeq , "pfcmpeq" , O_000F0F(B0,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfcmpge , "pfcmpge" , O_000F0F(90,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfcmpgt , "pfcmpgt" , O_000F0F(A0,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfmax , "pfmax" , O_000F0F(A4,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfmin , "pfmin" , O_000F0F(94,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfmul , "pfmul" , O_000F0F(B4,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfnacc , "pfnacc" , O_000F0F(8A,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfpnacc , "pfpnacc" , O_000F0F(8E,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfrcp , "pfrcp" , O_000F0F(96,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfrcpit1 , "pfrcpit1" , O_000F0F(A6,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfrcpit2 , "pfrcpit2" , O_000F0F(B6,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfrsqit1 , "pfrsqit1" , O_000F0F(A7,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfrsqrt , "pfrsqrt" , O_000F0F(97,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfsub , "pfsub" , O_000F0F(9A,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPfsubr , "pfsubr" , O_000F0F(AA,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPhaddd , "phaddd" , O_000F38(02,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPhaddsw , "phaddsw" , O_000F38(03,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPhaddw , "phaddw" , O_000F38(01,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPhminposuw , "phminposuw" , O_660F38(41,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPhsubd , "phsubd" , O_000F38(06,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPhsubsw , "phsubsw" , O_000F38(07,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPhsubw , "phsubw" , O_000F38(05,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPi2fd , "pi2fd" , O_000F0F(0D,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPi2fw , "pi2fw" , O_000F0F(0C,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPinsrb , "pinsrb" , O_660F3A(20,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , U ), + INST(kX86InstIdPinsrd , "pinsrd" , O_660F3A(22,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(GdMem) , O(Imm) , U , U ), + INST(kX86InstIdPinsrq , "pinsrq" , O_660F3A(22,U,_,W,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(GqMem) , O(Imm) , U , U ), + INST(kX86InstIdPinsrw , "pinsrw" , O_000F00(C4,U,_,_,_), U , Enc(ExtRmi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(GdMem) , O(Imm) , U , U ), + INST(kX86InstIdPmaddubsw , "pmaddubsw" , O_000F38(04,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmaddwd , "pmaddwd" , O_000F00(F5,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmaxsb , "pmaxsb" , O_660F38(3C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmaxsd , "pmaxsd" , O_660F38(3D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmaxsw , "pmaxsw" , O_000F00(EE,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmaxub , "pmaxub" , O_000F00(DE,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmaxud , "pmaxud" , O_660F38(3F,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmaxuw , "pmaxuw" , O_660F38(3E,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPminsb , "pminsb" , O_660F38(38,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPminsd , "pminsd" , O_660F38(39,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPminsw , "pminsw" , O_000F00(EA,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPminub , "pminub" , O_000F00(DA,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPminud , "pminud" , O_660F38(3B,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPminuw , "pminuw" , O_660F38(3A,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovmskb , "pmovmskb" , O_000F00(D7,U,_,_,_), U , Enc(ExtRm_PQ) , F(Move) , EF(________), 0 , 8 , O(Gqd) , O(MmXmm) , U , U , U ), + INST(kX86InstIdPmovsxbd , "pmovsxbd" , O_660F38(21,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovsxbq , "pmovsxbq" , O_660F38(22,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovsxbw , "pmovsxbw" , O_660F38(20,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovsxdq , "pmovsxdq" , O_660F38(25,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovsxwd , "pmovsxwd" , O_660F38(23,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovsxwq , "pmovsxwq" , O_660F38(24,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovzxbd , "pmovzxbd" , O_660F38(31,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovzxbq , "pmovzxbq" , O_660F38(32,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovzxbw , "pmovzxbw" , O_660F38(30,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovzxdq , "pmovzxdq" , O_660F38(35,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovzxwd , "pmovzxwd" , O_660F38(33,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmovzxwq , "pmovzxwq" , O_660F38(34,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmuldq , "pmuldq" , O_660F38(28,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmulhrsw , "pmulhrsw" , O_000F38(0B,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmulhuw , "pmulhuw" , O_000F00(E4,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmulhw , "pmulhw" , O_000F00(E5,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmulld , "pmulld" , O_660F38(40,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPmullw , "pmullw" , O_000F00(D5,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPmuludq , "pmuludq" , O_000F00(F4,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPop , "pop" , O_000000(8F,0,_,_,_), O_000000(58,U,_,_,_), Enc(X86Pop) , F(None)|F(Special) , EF(________), 0 , 0 , 0 , U , U , U , U ), + INST(kX86InstIdPopa , "popa" , O_000000(61,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdPopcnt , "popcnt" , O_F30F00(B8,U,_,_,_), U , Enc(X86RegRm) , F(None) , EF(WWWWWW__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdPopf , "popf" , O_000000(9D,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(WWWWWWWW), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdPor , "por" , O_000F00(EB,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPrefetch , "prefetch" , O_000F00(18,U,_,_,_), U , Enc(ExtPrefetch) , F(None) , EF(________), 0 , 0 , O(Mem) , O(Imm) , U , U , U ), + INST(kX86InstIdPrefetch3dNow , "prefetch_3dnow" , O_000F00(0D,0,_,_,_), U , Enc(X86M) , F(None) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdPrefetchw3dNow , "prefetchw_3dnow" , O_000F00(0D,1,_,_,_), U , Enc(X86M) , F(None) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdPsadbw , "psadbw" , O_000F00(F6,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPshufb , "pshufb" , O_000F38(00,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPshufd , "pshufd" , O_660F00(70,U,_,_,_), U , Enc(ExtRmi) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPshufhw , "pshufhw" , O_F30F00(70,U,_,_,_), U , Enc(ExtRmi) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPshuflw , "pshuflw" , O_F20F00(70,U,_,_,_), U , Enc(ExtRmi) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdPshufw , "pshufw" , O_000F00(70,U,_,_,_), U , Enc(ExtRmi_P) , F(Move) , EF(________), 0 , 8 , O(Mm) , O(MmMem) , O(Imm) , U , U ), + INST(kX86InstIdPsignb , "psignb" , O_000F38(08,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsignd , "psignd" , O_000F38(0A,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsignw , "psignw" , O_000F38(09,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPslld , "pslld" , O_000F00(F2,U,_,_,_), O_000F00(72,6,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPslldq , "pslldq" , U , O_660F00(73,7,_,_,_), Enc(ExtRmRi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(Imm) , U , U , U ), + INST(kX86InstIdPsllq , "psllq" , O_000F00(F3,U,_,_,_), O_000F00(73,6,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPsllw , "psllw" , O_000F00(F1,U,_,_,_), O_000F00(71,6,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPsrad , "psrad" , O_000F00(E2,U,_,_,_), O_000F00(72,4,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPsraw , "psraw" , O_000F00(E1,U,_,_,_), O_000F00(71,4,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPsrld , "psrld" , O_000F00(D2,U,_,_,_), O_000F00(72,2,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPsrldq , "psrldq" , U , O_660F00(73,3,_,_,_), Enc(ExtRmRi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(Imm) , U , U , U ), + INST(kX86InstIdPsrlq , "psrlq" , O_000F00(D3,U,_,_,_), O_000F00(73,2,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPsrlw , "psrlw" , O_000F00(D1,U,_,_,_), O_000F00(71,2,_,_,_), Enc(ExtRmRi_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem)|O(Imm), U , U , U ), + INST(kX86InstIdPsubb , "psubb" , O_000F00(F8,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsubd , "psubd" , O_000F00(FA,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsubq , "psubq" , O_000F00(FB,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsubsb , "psubsb" , O_000F00(E8,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsubsw , "psubsw" , O_000F00(E9,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsubusb , "psubusb" , O_000F00(D8,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsubusw , "psubusw" , O_000F00(D9,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPsubw , "psubw" , O_000F00(F9,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPswapd , "pswapd" , O_000F0F(BB,U,_,_,_), U , Enc(3dNow) , F(None) , EF(________), 0 , 0 , O(Mm) , O(MmMem) , U , U , U ), + INST(kX86InstIdPtest , "ptest" , O_660F38(17,U,_,_,_), U , Enc(ExtRm) , F(Test) , EF(WWWWWW__), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPunpckhbw , "punpckhbw" , O_000F00(68,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPunpckhdq , "punpckhdq" , O_000F00(6A,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPunpckhqdq , "punpckhqdq" , O_660F00(6D,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPunpckhwd , "punpckhwd" , O_000F00(69,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPunpcklbw , "punpcklbw" , O_000F00(60,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPunpckldq , "punpckldq" , O_000F00(62,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPunpcklqdq , "punpcklqdq" , O_660F00(6C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdPunpcklwd , "punpcklwd" , O_000F00(61,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdPush , "push" , O_000000(FF,6,_,_,_), O_000000(50,U,_,_,_), Enc(X86Push) , F(None)|F(Special) , EF(________), 0 , 0 , 0 , U , U , U , U ), + INST(kX86InstIdPusha , "pusha" , O_000000(60,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdPushf , "pushf" , O_000000(9C,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(RRRRRRRR), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdPxor , "pxor" , O_000F00(EF,U,_,_,_), U , Enc(ExtRm_P) , F(None) , EF(________), 0 , 0 , O(MmXmm) , O(MmXmmMem) , U , U , U ), + INST(kX86InstIdRcl , "rcl" , O_000000(D0,2,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(W____X__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdRcpps , "rcpps" , O_000F00(53,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdRcpss , "rcpss" , O_F30F00(53,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 4 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdRcr , "rcr" , O_000000(D0,3,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(W____X__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdRdfsbase , "rdfsbase" , O_F30F00(AE,0,_,_,_), U , Enc(X86Rm) , F(Move) , EF(________), 0 , 8 , O(Gqd) , U , U , U , U ), + INST(kX86InstIdRdgsbase , "rdgsbase" , O_F30F00(AE,1,_,_,_), U , Enc(X86Rm) , F(Move) , EF(________), 0 , 8 , O(Gqd) , U , U , U , U ), + INST(kX86InstIdRdrand , "rdrand" , O_000F00(C7,6,_,_,_), U , Enc(X86Rm) , F(Move) , EF(WWWWWW__), 0 , 8 , O(Gqdw) , U , U , U , U ), + INST(kX86InstIdRdtsc , "rdtsc" , O_000F00(31,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdRdtscp , "rdtscp" , O_000F01(F9,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdRepLodsB , "rep lods_b" , O_000000(AC,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepLodsD , "rep lods_d" , O_000000(AD,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepLodsQ , "rep lods_q" , O_000000(AD,1,_,W,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepLodsW , "rep lods_w" , O_660000(AD,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepMovsB , "rep movs_b" , O_000000(A4,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepMovsD , "rep movs_d" , O_000000(A5,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepMovsQ , "rep movs_q" , O_000000(A5,1,_,W,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepMovsW , "rep movs_w" , O_660000(A5,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepStosB , "rep stos_b" , O_000000(AA,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepStosD , "rep stos_d" , O_000000(AB,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepStosQ , "rep stos_q" , O_000000(AB,1,_,W,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepStosW , "rep stos_w" , O_660000(AB,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(______R_), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdRepeCmpsB , "repe cmps_b" , O_000000(A6,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepeCmpsD , "repe cmps_d" , O_000000(A7,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepeCmpsQ , "repe cmps_q" , O_000000(A7,1,_,W,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepeCmpsW , "repe cmps_w" , O_660000(A7,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepeScasB , "repe scas_b" , O_000000(AE,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepeScasD , "repe scas_d" , O_000000(AF,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepeScasQ , "repe scas_q" , O_000000(AF,1,_,W,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepeScasW , "repe scas_w" , O_660000(AF,1,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneCmpsB , "repne cmps_b" , O_000000(A6,0,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneCmpsD , "repne cmps_d" , O_000000(A7,0,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneCmpsQ , "repne cmps_q" , O_000000(A7,0,_,W,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneCmpsW , "repne cmps_w" , O_660000(A7,0,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneScasB , "repne scas_b" , O_000000(AE,0,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneScasD , "repne scas_d" , O_000000(AF,0,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneScasQ , "repne scas_q" , O_000000(AF,0,_,W,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRepneScasW , "repne scas_w" , O_660000(AF,0,_,_,_), U , Enc(X86Rep) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , O(Mem) , O(Mem) , U , U , U ), + INST(kX86InstIdRet , "ret" , O_000000(C2,U,_,_,_), U , Enc(X86Ret) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdRol , "rol" , O_000000(D0,0,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(W____W__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdRor , "ror" , O_000000(D0,1,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(W____W__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdRorx , "rorx" , O_F20F3A(F0,U,_,_,_), U , Enc(AvxRmi) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(GqdMem) , O(Imm) , U , U ), + INST(kX86InstIdRoundpd , "roundpd" , O_660F3A(09,U,_,_,_), U , Enc(ExtRmi) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdRoundps , "roundps" , O_660F3A(08,U,_,_,_), U , Enc(ExtRmi) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdRoundsd , "roundsd" , O_660F3A(0B,U,_,_,_), U , Enc(ExtRmi) , F(Move) , EF(________), 0 , 8 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdRoundss , "roundss" , O_660F3A(0A,U,_,_,_), U , Enc(ExtRmi) , F(Move) , EF(________), 0 , 4 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdRsqrtps , "rsqrtps" , O_000F00(52,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdRsqrtss , "rsqrtss" , O_F30F00(52,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 4 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdSahf , "sahf" , O_000000(9E,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(_WWWWW__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdSal , "sal" , O_000000(D0,4,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdSar , "sar" , O_000000(D0,7,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdSarx , "sarx" , O_F30F38(F7,U,_,_,_), U , Enc(AvxRmv) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , U ), + INST(kX86InstIdSbb , "sbb" , O_000000(18,3,_,_,_), U , Enc(X86Arith) , F(Lock) , EF(WWWWWX__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdScasB , "scas_b" , O_000000(AE,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdScasD , "scas_d" , O_000000(AF,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdScasQ , "scas_q" , O_000000(AF,U,_,W,_), U , Enc(X86Op) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdScasW , "scas_w" , O_000000(AF,U,_,_,_), U , Enc(X86Op_66H) , F(None)|F(Special) , EF(WWWWWWR_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdSeta , "seta" , O_000F00(97,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R__R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetae , "setae" , O_000F00(93,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_____R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetb , "setb" , O_000F00(92,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_____R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetbe , "setbe" , O_000F00(96,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R__R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetc , "setc" , O_000F00(92,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_____R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSete , "sete" , O_000F00(94,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetg , "setg" , O_000F00(9F,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RRR_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetge , "setge" , O_000F00(9D,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RR______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetl , "setl" , O_000F00(9C,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RR______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetle , "setle" , O_000F00(9E,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RRR_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetna , "setna" , O_000F00(96,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R__R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnae , "setnae" , O_000F00(92,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_____R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnb , "setnb" , O_000F00(93,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_____R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnbe , "setnbe" , O_000F00(97,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R__R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnc , "setnc" , O_000F00(93,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_____R__), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetne , "setne" , O_000F00(95,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetng , "setng" , O_000F00(9E,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RRR_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnge , "setnge" , O_000F00(9C,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RR______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnl , "setnl" , O_000F00(9D,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RR______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnle , "setnle" , O_000F00(9F,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(RRR_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetno , "setno" , O_000F00(91,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(R_______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnp , "setnp" , O_000F00(9B,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(____R___), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetns , "setns" , O_000F00(99,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_R______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetnz , "setnz" , O_000F00(95,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSeto , "seto" , O_000F00(90,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(R_______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetp , "setp" , O_000F00(9A,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(____R___), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetpe , "setpe" , O_000F00(9A,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(____R___), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetpo , "setpo" , O_000F00(9B,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(____R___), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSets , "sets" , O_000F00(98,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(_R______), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSetz , "setz" , O_000F00(94,U,_,_,_), U , Enc(X86Set) , F(Move) , EF(__R_____), 0 , 1 , O(GbMem) , U , U , U , U ), + INST(kX86InstIdSfence , "sfence" , O_000F00(AE,7,_,_,_), U , Enc(ExtFence) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdShl , "shl" , O_000000(D0,4,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdShld , "shld" , O_000F00(A4,U,_,_,_), U , Enc(X86Shlrd) , F(None)|F(Special) , EF(UWWUWW__), 0 , 0 , O(GqdwbMem) , O(Gb) , U , U , U ), + INST(kX86InstIdShlx , "shlx" , O_660F38(F7,U,_,_,_), U , Enc(AvxRmv) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , U ), + INST(kX86InstIdShr , "shr" , O_000000(D0,5,_,_,_), U , Enc(X86Rot) , F(None)|F(Special) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(Gb)|O(Imm) , U , U , U ), + INST(kX86InstIdShrd , "shrd" , O_000F00(AC,U,_,_,_), U , Enc(X86Shlrd) , F(None)|F(Special) , EF(UWWUWW__), 0 , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , U ), + INST(kX86InstIdShrx , "shrx" , O_F20F38(F7,U,_,_,_), U , Enc(AvxRmv) , F(None) , EF(________), 0 , 0 , O(Gqd) , O(GqdMem) , O(Gqd) , U , U ), + INST(kX86InstIdShufpd , "shufpd" , O_660F00(C6,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdShufps , "shufps" , O_000F00(C6,U,_,_,_), U , Enc(ExtRmi) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdSqrtpd , "sqrtpd" , O_660F00(51,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdSqrtps , "sqrtps" , O_000F00(51,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 16, O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdSqrtsd , "sqrtsd" , O_F20F00(51,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 8 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdSqrtss , "sqrtss" , O_F30F00(51,U,_,_,_), U , Enc(ExtRm) , F(Move) , EF(________), 0 , 4 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdStc , "stc" , O_000000(F9,U,_,_,_), U , Enc(X86Op) , F(None) , EF(_____W__), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdStd , "std" , O_000000(FD,U,_,_,_), U , Enc(X86Op) , F(None) , EF(______W_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdStmxcsr , "stmxcsr" , O_000F00(AE,3,_,_,_), U , Enc(X86M) , F(None) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdStosB , "stos_b" , O_000000(AA,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(______R_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdStosD , "stos_d" , O_000000(AB,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(______R_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdStosQ , "stos_q" , O_000000(AB,U,_,W,_), U , Enc(X86Op) , F(None)|F(Special) , EF(______R_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdStosW , "stos_w" , O_000000(AB,U,_,_,_), U , Enc(X86Op_66H) , F(None)|F(Special) , EF(______R_), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdSub , "sub" , O_000000(28,5,_,_,_), U , Enc(X86Arith) , F(Lock) , EF(WWWWWW__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdSubpd , "subpd" , O_660F00(5C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdSubps , "subps" , O_000F00(5C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdSubsd , "subsd" , O_F20F00(5C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdSubss , "subss" , O_F30F00(5C,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdTest , "test" , O_000000(84,U,_,_,_), O_000000(F6,U,_,_,_), Enc(X86Test) , F(Test) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(Gqdwb)|O(Imm) , U , U , U ), + INST(kX86InstIdTzcnt , "tzcnt" , O_F30F00(BC,U,_,_,_), U , Enc(X86RegRm) , F(Move) , EF(UUWUUW__), 0 , 0 , O(Gqdw) , O(GqdwMem) , U , U , U ), + INST(kX86InstIdUcomisd , "ucomisd" , O_660F00(2E,U,_,_,_), U , Enc(ExtRm) , F(Test) , EF(WWWWWW__), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdUcomiss , "ucomiss" , O_000F00(2E,U,_,_,_), U , Enc(ExtRm) , F(Test) , EF(WWWWWW__), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdUd2 , "ud2" , O_000F00(0B,U,_,_,_), U , Enc(X86Op) , F(None) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdUnpckhpd , "unpckhpd" , O_660F00(15,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdUnpckhps , "unpckhps" , O_000F00(15,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdUnpcklpd , "unpcklpd" , O_660F00(14,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdUnpcklps , "unpcklps" , O_000F00(14,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVaddpd , "vaddpd" , O_660F00(58,U,_,I,1), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVaddps , "vaddps" , O_000F00(58,U,_,I,0), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVaddsd , "vaddsd" , O_F20F00(58,U,0,I,1), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVaddss , "vaddss" , O_F30F00(58,U,0,I,0), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVaddsubpd , "vaddsubpd" , O_660F00(D0,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVaddsubps , "vaddsubps" , O_F20F00(D0,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVaesdec , "vaesdec" , O_660F38(DE,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVaesdeclast , "vaesdeclast" , O_660F38(DF,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVaesenc , "vaesenc" , O_660F38(DC,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVaesenclast , "vaesenclast" , O_660F38(DD,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVaesimc , "vaesimc" , O_660F38(DB,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVaeskeygenassist , "vaeskeygenassist" , O_660F3A(DF,U,_,_,_), U , Enc(AvxRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdVandnpd , "vandnpd" , O_660F00(55,U,_,_,1), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVandnps , "vandnps" , O_000F00(55,U,_,_,0), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVandpd , "vandpd" , O_660F00(54,U,_,_,1), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVandps , "vandps" , O_000F00(54,U,_,_,0), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVblendpd , "vblendpd" , O_660F3A(0D,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVblendps , "vblendps" , O_660F3A(0C,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVblendvpd , "vblendvpd" , O_660F3A(4B,U,_,_,_), U , Enc(AvxRvmr_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Xy) , U ), + INST(kX86InstIdVblendvps , "vblendvps" , O_660F3A(4A,U,_,_,_), U , Enc(AvxRvmr_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Xy) , U ), + INST(kX86InstIdVbroadcastf128 , "vbroadcastf128" , O_660F38(1A,U,L,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Mem) , U , U , U ), + INST(kX86InstIdVbroadcasti128 , "vbroadcasti128" , O_660F38(5A,U,L,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Mem) , U , U , U ), + INST(kX86InstIdVbroadcastsd , "vbroadcastsd" , O_660F38(19,U,L,0,1), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVbroadcastss , "vbroadcastss" , O_660F38(18,U,_,0,0), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcmppd , "vcmppd" , O_660F00(C2,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVcmpps , "vcmpps" , O_000F00(C2,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVcmpsd , "vcmpsd" , O_F20F00(C2,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVcmpss , "vcmpss" , O_F30F00(C2,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVcomisd , "vcomisd" , O_660F00(2F,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcomiss , "vcomiss" , O_000F00(2F,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcvtdq2pd , "vcvtdq2pd" , O_F30F00(E6,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcvtdq2ps , "vcvtdq2ps" , O_000F00(5B,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVcvtpd2dq , "vcvtpd2dq" , O_F20F00(E6,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XyMem) , U , U , U ), + INST(kX86InstIdVcvtpd2ps , "vcvtpd2ps" , O_660F00(5A,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XyMem) , U , U , U ), + INST(kX86InstIdVcvtph2ps , "vcvtph2ps" , O_660F38(13,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcvtps2dq , "vcvtps2dq" , O_660F00(5B,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVcvtps2pd , "vcvtps2pd" , O_000F00(5A,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcvtps2ph , "vcvtps2ph" , O_660F3A(1D,U,_,_,_), U , Enc(AvxMri_P) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Xy) , O(Imm) , U , U ), + INST(kX86InstIdVcvtsd2si , "vcvtsd2si" , O_F20F00(2D,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcvtsd2ss , "vcvtsd2ss" , O_F20F00(5A,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVcvtsi2sd , "vcvtsi2sd" , O_F20F00(2A,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , U ), + INST(kX86InstIdVcvtsi2ss , "vcvtsi2ss" , O_F30F00(2A,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , U , U ), + INST(kX86InstIdVcvtss2sd , "vcvtss2sd" , O_F30F00(5A,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVcvtss2si , "vcvtss2si" , O_F20F00(2D,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcvttpd2dq , "vcvttpd2dq" , O_660F00(E6,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XyMem) , U , U , U ), + INST(kX86InstIdVcvttps2dq , "vcvttps2dq" , O_F30F00(5B,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVcvttsd2si , "vcvttsd2si" , O_F20F00(2C,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVcvttss2si , "vcvttss2si" , O_F30F00(2C,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Gqd) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVdivpd , "vdivpd" , O_660F00(5E,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVdivps , "vdivps" , O_000F00(5E,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVdivsd , "vdivsd" , O_F20F00(5E,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVdivss , "vdivss" , O_F30F00(5E,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVdppd , "vdppd" , O_660F3A(41,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVdpps , "vdpps" , O_660F3A(40,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVextractf128 , "vextractf128" , O_660F3A(19,U,L,_,_), U , Enc(AvxMri) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , U ), + INST(kX86InstIdVextracti128 , "vextracti128" , O_660F3A(39,U,L,_,_), U , Enc(AvxMri) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Ymm) , O(Imm) , U , U ), + INST(kX86InstIdVextractps , "vextractps" , O_660F3A(17,U,_,_,_), U , Enc(AvxMri) , F(Avx) , EF(________), 0 , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , U ), + INST(kX86InstIdVfmadd132pd , "vfmadd132pd" , O_660F38(98,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmadd132ps , "vfmadd132ps" , O_660F38(98,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmadd132sd , "vfmadd132sd" , O_660F38(99,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmadd132ss , "vfmadd132ss" , O_660F38(99,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmadd213pd , "vfmadd213pd" , O_660F38(A8,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmadd213ps , "vfmadd213ps" , O_660F38(A8,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmadd213sd , "vfmadd213sd" , O_660F38(A9,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmadd213ss , "vfmadd213ss" , O_660F38(A9,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmadd231pd , "vfmadd231pd" , O_660F38(B8,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmadd231ps , "vfmadd231ps" , O_660F38(B8,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmadd231sd , "vfmadd231sd" , O_660F38(B9,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmadd231ss , "vfmadd231ss" , O_660F38(B9,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmaddpd , "vfmaddpd" , O_660F3A(69,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmaddps , "vfmaddps" , O_660F3A(68,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmaddsd , "vfmaddsd" , O_660F3A(6B,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfmaddss , "vfmaddss" , O_660F3A(6A,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfmaddsub132pd , "vfmaddsub132pd" , O_660F38(96,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmaddsub132ps , "vfmaddsub132ps" , O_660F38(96,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmaddsub213pd , "vfmaddsub213pd" , O_660F38(A6,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmaddsub213ps , "vfmaddsub213ps" , O_660F38(A6,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmaddsub231pd , "vfmaddsub231pd" , O_660F38(B6,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmaddsub231ps , "vfmaddsub231ps" , O_660F38(B6,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmaddsubpd , "vfmaddsubpd" , O_660F3A(5D,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmaddsubps , "vfmaddsubps" , O_660F3A(5C,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmsub132pd , "vfmsub132pd" , O_660F38(9A,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsub132ps , "vfmsub132ps" , O_660F38(9A,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsub132sd , "vfmsub132sd" , O_660F38(9B,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmsub132ss , "vfmsub132ss" , O_660F38(9B,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmsub213pd , "vfmsub213pd" , O_660F38(AA,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsub213ps , "vfmsub213ps" , O_660F38(AA,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsub213sd , "vfmsub213sd" , O_660F38(AB,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmsub213ss , "vfmsub213ss" , O_660F38(AB,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmsub231pd , "vfmsub231pd" , O_660F38(BA,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsub231ps , "vfmsub231ps" , O_660F38(BA,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsub231sd , "vfmsub231sd" , O_660F38(BB,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmsub231ss , "vfmsub231ss" , O_660F38(BB,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfmsubadd132pd , "vfmsubadd132pd" , O_660F38(97,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsubadd132ps , "vfmsubadd132ps" , O_660F38(97,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsubadd213pd , "vfmsubadd213pd" , O_660F38(A7,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsubadd213ps , "vfmsubadd213ps" , O_660F38(A7,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsubadd231pd , "vfmsubadd231pd" , O_660F38(B7,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsubadd231ps , "vfmsubadd231ps" , O_660F38(B7,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfmsubaddpd , "vfmsubaddpd" , O_660F3A(5F,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmsubaddps , "vfmsubaddps" , O_660F3A(5E,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmsubpd , "vfmsubpd" , O_660F3A(6D,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmsubps , "vfmsubps" , O_660F3A(6C,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfmsubsd , "vfmsubsd" , O_660F3A(6F,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfmsubss , "vfmsubss" , O_660F3A(6E,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfnmadd132pd , "vfnmadd132pd" , O_660F38(9C,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmadd132ps , "vfnmadd132ps" , O_660F38(9C,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmadd132sd , "vfnmadd132sd" , O_660F38(9D,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmadd132ss , "vfnmadd132ss" , O_660F38(9D,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmadd213pd , "vfnmadd213pd" , O_660F38(AC,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmadd213ps , "vfnmadd213ps" , O_660F38(AC,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmadd213sd , "vfnmadd213sd" , O_660F38(AD,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmadd213ss , "vfnmadd213ss" , O_660F38(AD,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmadd231pd , "vfnmadd231pd" , O_660F38(BC,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmadd231ps , "vfnmadd231ps" , O_660F38(BC,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmadd231sd , "vfnmadd231sd" , O_660F38(BC,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmadd231ss , "vfnmadd231ss" , O_660F38(BC,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmaddpd , "vfnmaddpd" , O_660F3A(79,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfnmaddps , "vfnmaddps" , O_660F3A(78,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfnmaddsd , "vfnmaddsd" , O_660F3A(7B,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfnmaddss , "vfnmaddss" , O_660F3A(7A,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfnmsub132pd , "vfnmsub132pd" , O_660F38(9E,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmsub132ps , "vfnmsub132ps" , O_660F38(9E,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmsub132sd , "vfnmsub132sd" , O_660F38(9F,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmsub132ss , "vfnmsub132ss" , O_660F38(9F,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmsub213pd , "vfnmsub213pd" , O_660F38(AE,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmsub213ps , "vfnmsub213ps" , O_660F38(AE,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmsub213sd , "vfnmsub213sd" , O_660F38(AF,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmsub213ss , "vfnmsub213ss" , O_660F38(AF,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmsub231pd , "vfnmsub231pd" , O_660F38(BE,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmsub231ps , "vfnmsub231ps" , O_660F38(BE,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVfnmsub231sd , "vfnmsub231sd" , O_660F38(BF,U,_,W,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmsub231ss , "vfnmsub231ss" , O_660F38(BF,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVfnmsubpd , "vfnmsubpd" , O_660F3A(7D,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfnmsubps , "vfnmsubps" , O_660F3A(7C,U,_,_,_), U , Enc(Fma4_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVfnmsubsd , "vfnmsubsd" , O_660F3A(7F,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfnmsubss , "vfnmsubss" , O_660F3A(7E,U,_,_,_), U , Enc(Fma4) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVfrczpd , "vfrczpd" , O_00_M09(81,U,_,_,_), U , Enc(XopRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVfrczps , "vfrczps" , O_00_M09(80,U,_,_,_), U , Enc(XopRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVfrczsd , "vfrczsd" , O_00_M09(83,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVfrczss , "vfrczss" , O_00_M09(82,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVgatherdpd , "vgatherdpd" , O_660F38(92,U,_,W,_), U , Enc(AvxGather) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , O(Xy) , U , U ), + INST(kX86InstIdVgatherdps , "vgatherdps" , O_660F38(92,U,_,_,_), U , Enc(AvxGather) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , O(Xy) , U , U ), + INST(kX86InstIdVgatherqpd , "vgatherqpd" , O_660F38(93,U,_,W,_), U , Enc(AvxGather) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , O(Xy) , U , U ), + INST(kX86InstIdVgatherqps , "vgatherqps" , O_660F38(93,U,_,_,_), U , Enc(AvxGatherEx) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , U ), + INST(kX86InstIdVhaddpd , "vhaddpd" , O_660F00(7C,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVhaddps , "vhaddps" , O_F20F00(7C,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVhsubpd , "vhsubpd" , O_660F00(7D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVhsubps , "vhsubps" , O_F20F00(7D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVinsertf128 , "vinsertf128" , O_660F3A(18,U,L,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVinserti128 , "vinserti128" , O_660F3A(38,U,L,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Ymm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVinsertps , "vinsertps" , O_660F3A(21,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVlddqu , "vlddqu" , O_F20F00(F0,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , U , U , U ), + INST(kX86InstIdVldmxcsr , "vldmxcsr" , O_000F00(AE,2,_,_,_), U , Enc(AvxM) , F(Avx) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdVmaskmovdqu , "vmaskmovdqu" , O_660F00(F7,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , U , U , U ), + INST(kX86InstIdVmaskmovpd , "vmaskmovpd" , O_660F38(2D,U,_,_,_), O_660F38(2F,U,_,_,_), Enc(AvxRvmMvr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmaskmovps , "vmaskmovps" , O_660F38(2C,U,_,_,_), O_660F38(2E,U,_,_,_), Enc(AvxRvmMvr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmaxpd , "vmaxpd" , O_660F00(5F,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmaxps , "vmaxps" , O_000F00(5F,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmaxsd , "vmaxsd" , O_F20F00(5F,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmaxss , "vmaxss" , O_F30F00(5F,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVminpd , "vminpd" , O_660F00(5D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVminps , "vminps" , O_000F00(5D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVminsd , "vminsd" , O_F20F00(5D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVminss , "vminss" , O_F30F00(5D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmovapd , "vmovapd" , O_660F00(28,U,_,_,_), O_660F00(29,U,_,_,_), Enc(AvxRmMr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovaps , "vmovaps" , O_000F00(28,U,_,_,_), O_000F00(29,U,_,_,_), Enc(AvxRmMr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovd , "vmovd" , O_660F00(6E,U,_,_,_), O_660F00(7E,U,_,_,_), Enc(AvxRmMr) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVmovddup , "vmovddup" , O_F20F00(12,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovdqa , "vmovdqa" , O_660F00(6F,U,_,_,_), O_660F00(7F,U,_,_,_), Enc(AvxRmMr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovdqu , "vmovdqu" , O_F30F00(6F,U,_,_,_), O_F30F00(7F,U,_,_,_), Enc(AvxRmMr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovhlps , "vmovhlps" , O_000F00(12,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , U ), + INST(kX86InstIdVmovhpd , "vmovhpd" , O_660F00(16,U,_,_,_), O_660F00(17,U,_,_,_), Enc(AvxRvmMr) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , U ), + INST(kX86InstIdVmovhps , "vmovhps" , O_000F00(16,U,_,_,_), O_000F00(17,U,_,_,_), Enc(AvxRvmMr) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , U ), + INST(kX86InstIdVmovlhps , "vmovlhps" , O_000F00(16,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(Xmm) , U , U ), + INST(kX86InstIdVmovlpd , "vmovlpd" , O_660F00(12,U,_,_,_), O_660F00(13,U,_,_,_), Enc(AvxRvmMr) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , U ), + INST(kX86InstIdVmovlps , "vmovlps" , O_000F00(12,U,_,_,_), O_000F00(13,U,_,_,_), Enc(AvxRvmMr) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Xmm) , O(Mem) , U , U ), + INST(kX86InstIdVmovmskpd , "vmovmskpd" , O_660F00(50,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Gqd) , O(Xy) , U , U , U ), + INST(kX86InstIdVmovmskps , "vmovmskps" , O_000F00(50,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Gqd) , O(Xy) , U , U , U ), + INST(kX86InstIdVmovntdq , "vmovntdq" , O_660F00(E7,U,_,_,_), U , Enc(AvxMr) , F(Avx) , EF(________), 0 , 0 , O(Mem) , O(Xy) , U , U , U ), + INST(kX86InstIdVmovntdqa , "vmovntdqa" , O_660F38(2A,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , U , U , U ), + INST(kX86InstIdVmovntpd , "vmovntpd" , O_660F00(2B,U,_,_,_), U , Enc(AvxMr_P) , F(Avx) , EF(________), 0 , 0 , O(Mem) , O(Xy) , U , U , U ), + INST(kX86InstIdVmovntps , "vmovntps" , O_000F00(2B,U,_,_,_), U , Enc(AvxMr_P) , F(Avx) , EF(________), 0 , 0 , O(Mem) , O(Xy) , U , U , U ), + INST(kX86InstIdVmovq , "vmovq" , O_660F00(6E,U,_,W,_), O_660F00(7E,U,_,_,_), Enc(AvxRmMr) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVmovsd , "vmovsd" , O_F20F00(10,U,_,_,_), O_F20F00(11,U,_,_,_), Enc(AvxMovSsSd) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(XmmMem) , O(Xmm) , U , U ), + INST(kX86InstIdVmovshdup , "vmovshdup" , O_F30F00(16,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovsldup , "vmovsldup" , O_F30F00(12,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovss , "vmovss" , O_F30F00(10,U,_,_,_), O_F30F00(11,U,_,_,_), Enc(AvxMovSsSd) , F(Avx) , EF(________), 0 , 0 , O(XmmMem) , O(Xmm) , O(Xmm) , U , U ), + INST(kX86InstIdVmovupd , "vmovupd" , O_660F00(10,U,_,_,_), O_660F00(11,U,_,_,_), Enc(AvxRmMr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmovups , "vmovups" , O_000F00(10,U,_,_,_), O_000F00(11,U,_,_,_), Enc(AvxRmMr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(XyMem) , U , U , U ), + INST(kX86InstIdVmpsadbw , "vmpsadbw" , O_660F3A(42,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVmulpd , "vmulpd" , O_660F00(59,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmulps , "vmulps" , O_000F00(59,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmulsd , "vmulsd" , O_F20F00(59,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVmulss , "vmulss" , O_F30F00(59,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVorpd , "vorpd" , O_660F00(56,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVorps , "vorps" , O_000F00(56,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpabsb , "vpabsb" , O_660F38(1C,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpabsd , "vpabsd" , O_660F38(1E,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpabsw , "vpabsw" , O_660F38(1D,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpackssdw , "vpackssdw" , O_660F00(6B,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpacksswb , "vpacksswb" , O_660F00(63,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpackusdw , "vpackusdw" , O_660F38(2B,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpackuswb , "vpackuswb" , O_660F00(67,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddb , "vpaddb" , O_660F00(FC,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddd , "vpaddd" , O_660F00(FE,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddq , "vpaddq" , O_660F00(D4,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddsb , "vpaddsb" , O_660F00(EC,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddsw , "vpaddsw" , O_660F00(ED,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddusb , "vpaddusb" , O_660F00(DC,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddusw , "vpaddusw" , O_660F00(DD,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpaddw , "vpaddw" , O_660F00(FD,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpalignr , "vpalignr" , O_660F3A(0F,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVpand , "vpand" , O_660F00(DB,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpandn , "vpandn" , O_660F00(DF,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpavgb , "vpavgb" , O_660F00(E0,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpavgw , "vpavgw" , O_660F00(E3,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpblendd , "vpblendd" , O_660F3A(02,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVpblendvb , "vpblendvb" , O_660F3A(4C,U,_,_,_), U , Enc(AvxRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Xy) , U ), + INST(kX86InstIdVpblendw , "vpblendw" , O_660F3A(0E,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVpbroadcastb , "vpbroadcastb" , O_660F38(78,U,_,_,0), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVpbroadcastd , "vpbroadcastd" , O_660F38(58,U,_,_,0), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVpbroadcastq , "vpbroadcastq" , O_660F38(59,U,_,_,1), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVpbroadcastw , "vpbroadcastw" , O_660F38(79,U,_,_,0), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVpclmulqdq , "vpclmulqdq" , O_660F3A(44,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcmov , "vpcmov" , O_00_M08(A2,U,_,_,_), U , Enc(XopRvrmRvmr_P), F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVpcmpeqb , "vpcmpeqb" , O_660F00(74,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpeqd , "vpcmpeqd" , O_660F00(76,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpeqq , "vpcmpeqq" , O_660F38(29,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpeqw , "vpcmpeqw" , O_660F00(75,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpestri , "vpcmpestri" , O_660F3A(61,U,_,_,_), U , Enc(AvxRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdVpcmpestrm , "vpcmpestrm" , O_660F3A(60,U,_,_,_), U , Enc(AvxRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdVpcmpgtb , "vpcmpgtb" , O_660F00(64,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpgtd , "vpcmpgtd" , O_660F00(66,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpgtq , "vpcmpgtq" , O_660F38(37,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpgtw , "vpcmpgtw" , O_660F00(65,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpcmpistri , "vpcmpistri" , O_660F3A(63,U,_,_,_), U , Enc(AvxRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdVpcmpistrm , "vpcmpistrm" , O_660F3A(62,U,_,_,_), U , Enc(AvxRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(Imm) , U , U ), + INST(kX86InstIdVpcomb , "vpcomb" , O_00_M08(CC,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcomd , "vpcomd" , O_00_M08(CE,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcomq , "vpcomq" , O_00_M08(CF,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcomub , "vpcomub" , O_00_M08(EC,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcomud , "vpcomud" , O_00_M08(EE,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcomuq , "vpcomuq" , O_00_M08(EF,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcomuw , "vpcomuw" , O_00_M08(ED,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVpcomw , "vpcomw" , O_00_M08(CD,U,_,_,_), U , Enc(XopRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVperm2f128 , "vperm2f128" , O_660F3A(06,U,L,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , U ), + INST(kX86InstIdVperm2i128 , "vperm2i128" , O_660F3A(46,U,L,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , O(Imm) , U ), + INST(kX86InstIdVpermd , "vpermd" , O_660F38(36,U,L,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , U ), + INST(kX86InstIdVpermil2pd , "vpermil2pd" , O_66_M03(49,U,_,_,_), U , Enc(AvxRvrmRvmr_P), F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVpermil2ps , "vpermil2ps" , O_66_M03(48,U,_,_,_), U , Enc(AvxRvrmRvmr_P), F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(XyMem) , U ), + INST(kX86InstIdVpermilpd , "vpermilpd" , O_660F38(0D,U,_,_,_), O_660F3A(05,U,_,_,_), Enc(AvxRvmRmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpermilps , "vpermilps" , O_660F38(0C,U,_,_,_), O_660F3A(04,U,_,_,_), Enc(AvxRvmRmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpermpd , "vpermpd" , O_660F3A(01,U,L,W,_), U , Enc(AvxRmi) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , U ), + INST(kX86InstIdVpermps , "vpermps" , O_660F38(16,U,L,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(Ymm) , O(YmmMem) , U , U ), + INST(kX86InstIdVpermq , "vpermq" , O_660F3A(00,U,L,W,_), U , Enc(AvxRmi) , F(Avx) , EF(________), 0 , 0 , O(Ymm) , O(YmmMem) , O(Imm) , U , U ), + INST(kX86InstIdVpextrb , "vpextrb" , O_660F3A(14,U,_,_,_), U , Enc(AvxMri) , F(Avx) , EF(________), 0 , 0 , O(GqdwbMem) , O(Xmm) , O(Imm) , U , U ), + INST(kX86InstIdVpextrd , "vpextrd" , O_660F3A(16,U,_,_,_), U , Enc(AvxMri) , F(Avx) , EF(________), 0 , 0 , O(GqdMem) , O(Xmm) , O(Imm) , U , U ), + INST(kX86InstIdVpextrq , "vpextrq" , O_660F3A(16,U,_,W,_), U , Enc(AvxMri) , F(Avx) , EF(________), 0 , 0 , O(GqMem) , O(Xmm) , O(Imm) , U , U ), + INST(kX86InstIdVpextrw , "vpextrw" , O_660F3A(15,U,_,_,_), U , Enc(AvxMri) , F(Avx) , EF(________), 0 , 0 , O(GqdwMem) , O(Xmm) , O(Imm) , U , U ), + INST(kX86InstIdVpgatherdd , "vpgatherdd" , O_660F38(90,U,_,_,_), U , Enc(AvxGather) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , O(Xy) , U , U ), + INST(kX86InstIdVpgatherdq , "vpgatherdq" , O_660F38(90,U,_,W,_), U , Enc(AvxGather) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , O(Xy) , U , U ), + INST(kX86InstIdVpgatherqd , "vpgatherqd" , O_660F38(91,U,_,_,_), U , Enc(AvxGatherEx) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Mem) , O(Xmm) , U , U ), + INST(kX86InstIdVpgatherqq , "vpgatherqq" , O_660F38(91,U,_,W,_), U , Enc(AvxGather) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Mem) , O(Xy) , U , U ), + INST(kX86InstIdVphaddbd , "vphaddbd" , O_00_M09(C2,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddbq , "vphaddbq" , O_00_M09(C3,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddbw , "vphaddbw" , O_00_M09(C1,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddd , "vphaddd" , O_660F38(02,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVphadddq , "vphadddq" , O_00_M09(CB,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddsw , "vphaddsw" , O_660F38(03,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVphaddubd , "vphaddubd" , O_00_M09(D2,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddubq , "vphaddubq" , O_00_M09(D3,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddubw , "vphaddubw" , O_00_M09(D1,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddudq , "vphaddudq" , O_00_M09(DB,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphadduwd , "vphadduwd" , O_00_M09(D6,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphadduwq , "vphadduwq" , O_00_M09(D7,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddw , "vphaddw" , O_660F38(01,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVphaddwd , "vphaddwd" , O_00_M09(C6,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphaddwq , "vphaddwq" , O_00_M09(C7,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphminposuw , "vphminposuw" , O_660F38(41,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphsubbw , "vphsubbw" , O_00_M09(E1,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphsubd , "vphsubd" , O_660F38(06,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVphsubdq , "vphsubdq" , O_00_M09(E3,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVphsubsw , "vphsubsw" , O_660F38(07,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVphsubw , "vphsubw" , O_660F38(05,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVphsubwd , "vphsubwd" , O_00_M09(E2,U,_,_,_), U , Enc(XopRm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVpinsrb , "vpinsrb" , O_660F3A(20,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(GqdwbMem) , O(Imm) , U ), + INST(kX86InstIdVpinsrd , "vpinsrd" , O_660F3A(22,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(GqdMem) , O(Imm) , U ), + INST(kX86InstIdVpinsrq , "vpinsrq" , O_660F3A(22,U,_,W,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(GqMem) , O(Imm) , U ), + INST(kX86InstIdVpinsrw , "vpinsrw" , O_660F00(C4,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(GqdwMem) , O(Imm) , U ), + INST(kX86InstIdVpmacsdd , "vpmacsdd" , O_00_M08(9E,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacsdqh , "vpmacsdqh" , O_00_M08(9F,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacsdql , "vpmacsdql" , O_00_M08(97,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacssdd , "vpmacssdd" , O_00_M08(8E,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacssdqh , "vpmacssdqh" , O_00_M08(8F,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacssdql , "vpmacssdql" , O_00_M08(87,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacsswd , "vpmacsswd" , O_00_M08(86,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacssww , "vpmacssww" , O_00_M08(85,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacswd , "vpmacswd" , O_00_M08(96,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmacsww , "vpmacsww" , O_00_M08(95,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmadcsswd , "vpmadcsswd" , O_00_M08(A6,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmadcswd , "vpmadcswd" , O_00_M08(B6,U,_,_,_), U , Enc(XopRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Xmm) , U ), + INST(kX86InstIdVpmaddubsw , "vpmaddubsw" , O_660F38(04,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaddwd , "vpmaddwd" , O_660F00(F5,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaskmovd , "vpmaskmovd" , O_660F38(8C,U,_,_,_), O_660F38(8E,U,_,_,_), Enc(AvxRvmMvr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaskmovq , "vpmaskmovq" , O_660F38(8C,U,_,W,_), O_660F38(8E,U,_,_,_), Enc(AvxRvmMvr_P) , F(Avx) , EF(________), 0 , 0 , O(XyMem) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaxsb , "vpmaxsb" , O_660F38(3C,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaxsd , "vpmaxsd" , O_660F38(3D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaxsw , "vpmaxsw" , O_660F00(EE,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaxub , "vpmaxub" , O_660F00(DE,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaxud , "vpmaxud" , O_660F38(3F,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmaxuw , "vpmaxuw" , O_660F38(3E,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpminsb , "vpminsb" , O_660F38(38,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpminsd , "vpminsd" , O_660F38(39,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpminsw , "vpminsw" , O_660F00(EA,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpminub , "vpminub" , O_660F00(DA,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpminud , "vpminud" , O_660F38(3B,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpminuw , "vpminuw" , O_660F38(3A,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmovmskb , "vpmovmskb" , O_660F00(D7,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Gqd) , O(Xy) , U , U , U ), + INST(kX86InstIdVpmovsxbd , "vpmovsxbd" , O_660F38(21,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovsxbq , "vpmovsxbq" , O_660F38(22,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovsxbw , "vpmovsxbw" , O_660F38(20,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovsxdq , "vpmovsxdq" , O_660F38(25,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovsxwd , "vpmovsxwd" , O_660F38(23,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovsxwq , "vpmovsxwq" , O_660F38(24,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovzxbd , "vpmovzxbd" , O_660F38(31,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovzxbq , "vpmovzxbq" , O_660F38(32,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovzxbw , "vpmovzxbw" , O_660F38(30,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovzxdq , "vpmovzxdq" , O_660F38(35,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovzxwd , "vpmovzxwd" , O_660F38(33,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmovzxwq , "vpmovzxwq" , O_660F38(34,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpmuldq , "vpmuldq" , O_660F38(28,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmulhrsw , "vpmulhrsw" , O_660F38(0B,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmulhuw , "vpmulhuw" , O_660F00(E4,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmulhw , "vpmulhw" , O_660F00(E5,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmulld , "vpmulld" , O_660F38(40,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmullw , "vpmullw" , O_660F00(D5,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpmuludq , "vpmuludq" , O_660F00(F4,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpor , "vpor" , O_660F00(EB,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpperm , "vpperm" , O_00_M08(A3,U,_,_,_), U , Enc(XopRvrmRvmr) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , U ), + INST(kX86InstIdVprotb , "vprotb" , O_00_M09(90,U,_,_,_), O_00_M08(C0,U,_,_,_), Enc(XopRvmRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U ), + INST(kX86InstIdVprotd , "vprotd" , O_00_M09(92,U,_,_,_), O_00_M08(C2,U,_,_,_), Enc(XopRvmRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U ), + INST(kX86InstIdVprotq , "vprotq" , O_00_M09(93,U,_,_,_), O_00_M08(C3,U,_,_,_), Enc(XopRvmRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U ), + INST(kX86InstIdVprotw , "vprotw" , O_00_M09(91,U,_,_,_), O_00_M08(C1,U,_,_,_), Enc(XopRvmRmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsadbw , "vpsadbw" , O_660F00(F6,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpshab , "vpshab" , O_00_M09(98,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshad , "vpshad" , O_00_M09(9A,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshaq , "vpshaq" , O_00_M09(9B,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshaw , "vpshaw" , O_00_M09(99,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshlb , "vpshlb" , O_00_M09(94,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshld , "vpshld" , O_00_M09(96,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshlq , "vpshlq" , O_00_M09(97,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshlw , "vpshlw" , O_00_M09(95,U,_,_,_), U , Enc(XopRvmRmv) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , O(XmmMem) , U , U ), + INST(kX86InstIdVpshufb , "vpshufb" , O_660F38(00,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpshufd , "vpshufd" , O_660F00(70,U,_,_,_), U , Enc(AvxRmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(Imm) , U , U ), + INST(kX86InstIdVpshufhw , "vpshufhw" , O_F30F00(70,U,_,_,_), U , Enc(AvxRmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(Imm) , U , U ), + INST(kX86InstIdVpshuflw , "vpshuflw" , O_F20F00(70,U,_,_,_), U , Enc(AvxRmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(Imm) , U , U ), + INST(kX86InstIdVpsignb , "vpsignb" , O_660F38(08,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsignd , "vpsignd" , O_660F38(0A,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsignw , "vpsignw" , O_660F38(09,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpslld , "vpslld" , O_660F00(F2,U,_,_,_), O_660F00(72,6,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpslldq , "vpslldq" , O_660F00(73,7,_,_,_), U , Enc(AvxVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(Imm) , U , U ), + INST(kX86InstIdVpsllq , "vpsllq" , O_660F00(F3,U,_,_,_), O_660F00(73,6,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsllvd , "vpsllvd" , O_660F38(47,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsllvq , "vpsllvq" , O_660F38(47,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsllw , "vpsllw" , O_660F00(F1,U,_,_,_), O_660F00(71,6,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsrad , "vpsrad" , O_660F00(E2,U,_,_,_), O_660F00(72,4,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsravd , "vpsravd" , O_660F38(46,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsraw , "vpsraw" , O_660F00(E1,U,_,_,_), O_660F00(71,4,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsrld , "vpsrld" , O_660F00(D2,U,_,_,_), O_660F00(72,2,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsrldq , "vpsrldq" , O_660F00(73,3,_,_,_), U , Enc(AvxVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(Imm) , U , U ), + INST(kX86InstIdVpsrlq , "vpsrlq" , O_660F00(D3,U,_,_,_), O_660F00(73,2,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsrlvd , "vpsrlvd" , O_660F38(45,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsrlvq , "vpsrlvq" , O_660F38(45,U,_,W,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsrlw , "vpsrlw" , O_660F00(D1,U,_,_,_), O_660F00(71,2,_,_,_), Enc(AvxRvmVmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(XyMem)|O(Imm) , U , U ), + INST(kX86InstIdVpsubb , "vpsubb" , O_660F00(F8,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsubd , "vpsubd" , O_660F00(FA,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsubq , "vpsubq" , O_660F00(FB,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsubsb , "vpsubsb" , O_660F00(E8,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsubsw , "vpsubsw" , O_660F00(E9,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsubusb , "vpsubusb" , O_660F00(D8,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsubusw , "vpsubusw" , O_660F00(D9,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpsubw , "vpsubw" , O_660F00(F9,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVptest , "vptest" , O_660F38(17,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(WWWWWW__), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVpunpckhbw , "vpunpckhbw" , O_660F00(68,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpunpckhdq , "vpunpckhdq" , O_660F00(6A,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpunpckhqdq , "vpunpckhqdq" , O_660F00(6D,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpunpckhwd , "vpunpckhwd" , O_660F00(69,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpunpcklbw , "vpunpcklbw" , O_660F00(60,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpunpckldq , "vpunpckldq" , O_660F00(62,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpunpcklqdq , "vpunpcklqdq" , O_660F00(6C,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpunpcklwd , "vpunpcklwd" , O_660F00(61,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVpxor , "vpxor" , O_660F00(EF,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVrcpps , "vrcpps" , O_000F00(53,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVrcpss , "vrcpss" , O_F30F00(53,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVroundpd , "vroundpd" , O_660F3A(09,U,_,_,_), U , Enc(AvxRmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(Imm) , U , U ), + INST(kX86InstIdVroundps , "vroundps" , O_660F3A(08,U,_,_,_), U , Enc(AvxRmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , O(Imm) , U , U ), + INST(kX86InstIdVroundsd , "vroundsd" , O_660F3A(0B,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVroundss , "vroundss" , O_660F3A(0A,U,_,_,_), U , Enc(AvxRvmi) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(Imm) , U ), + INST(kX86InstIdVrsqrtps , "vrsqrtps" , O_000F00(52,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVrsqrtss , "vrsqrtss" , O_F30F00(52,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVshufpd , "vshufpd" , O_660F00(C6,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVshufps , "vshufps" , O_000F00(C6,U,_,_,_), U , Enc(AvxRvmi_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , O(Imm) , U ), + INST(kX86InstIdVsqrtpd , "vsqrtpd" , O_660F00(51,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVsqrtps , "vsqrtps" , O_000F00(51,U,_,_,_), U , Enc(AvxRm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVsqrtsd , "vsqrtsd" , O_F20F00(51,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVsqrtss , "vsqrtss" , O_F30F00(51,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVstmxcsr , "vstmxcsr" , O_000F00(AE,3,_,_,_), U , Enc(AvxM) , F(Avx) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdVsubpd , "vsubpd" , O_660F00(5C,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVsubps , "vsubps" , O_000F00(5C,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVsubsd , "vsubsd" , O_F20F00(5C,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVsubss , "vsubss" , O_F30F00(5C,U,_,_,_), U , Enc(AvxRvm) , F(Avx) , EF(________), 0 , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , U ), + INST(kX86InstIdVtestpd , "vtestpd" , O_660F38(0F,U,_,_,_), U , Enc(AvxRm_P) , F(Test) , EF(WWWWWW__), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVtestps , "vtestps" , O_660F38(0E,U,_,_,_), U , Enc(AvxRm_P) , F(Test) , EF(WWWWWW__), 0 , 0 , O(Xy) , O(XyMem) , U , U , U ), + INST(kX86InstIdVucomisd , "vucomisd" , O_660F00(2E,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(WWWWWW__), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVucomiss , "vucomiss" , O_000F00(2E,U,_,_,_), U , Enc(AvxRm) , F(Avx) , EF(WWWWWW__), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdVunpckhpd , "vunpckhpd" , O_660F00(15,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVunpckhps , "vunpckhps" , O_000F00(15,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVunpcklpd , "vunpcklpd" , O_660F00(14,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVunpcklps , "vunpcklps" , O_000F00(14,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVxorpd , "vxorpd" , O_660F00(57,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVxorps , "vxorps" , O_000F00(57,U,_,_,_), U , Enc(AvxRvm_P) , F(Avx) , EF(________), 0 , 0 , O(Xy) , O(Xy) , O(XyMem) , U , U ), + INST(kX86InstIdVzeroall , "vzeroall" , O_000F00(77,U,L,_,_), U , Enc(AvxOp) , F(Avx) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdVzeroupper , "vzeroupper" , O_000F00(77,U,_,_,_), U , Enc(AvxOp) , F(Avx) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdWrfsbase , "wrfsbase" , O_F30F00(AE,2,_,_,_), U , Enc(X86Rm) , F(None) , EF(________), 0 , 0 , O(Gqd) , U , U , U , U ), + INST(kX86InstIdWrgsbase , "wrgsbase" , O_F30F00(AE,3,_,_,_), U , Enc(X86Rm) , F(None) , EF(________), 0 , 0 , O(Gqd) , U , U , U , U ), + INST(kX86InstIdXadd , "xadd" , O_000F00(C0,U,_,_,_), U , Enc(X86Xadd) , F(Xchg)|F(Lock) , EF(WWWWWW__), 0 , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , U ), + INST(kX86InstIdXchg , "xchg" , O_000000(86,U,_,_,_), U , Enc(X86Xchg) , F(Xchg)|F(Lock) , EF(________), 0 , 0 , O(GqdwbMem) , O(Gqdwb) , U , U , U ), + INST(kX86InstIdXgetbv , "xgetbv" , O_000F01(D0,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ), + INST(kX86InstIdXor , "xor" , O_000000(30,6,_,_,_), U , Enc(X86Arith) , F(Lock) , EF(WWWUWW__), 0 , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm), U , U , U ), + INST(kX86InstIdXorpd , "xorpd" , O_660F00(57,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdXorps , "xorps" , O_000F00(57,U,_,_,_), U , Enc(ExtRm) , F(None) , EF(________), 0 , 0 , O(Xmm) , O(XmmMem) , U , U , U ), + INST(kX86InstIdXrstor , "xrstor" , O_000F00(AE,5,_,_,_), U , Enc(X86M) , F(None)|F(Special) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdXrstor64 , "xrstor64" , O_000F00(AE,5,_,W,_), U , Enc(X86M) , F(None)|F(Special) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdXsave , "xsave" , O_000F00(AE,4,_,_,_), U , Enc(X86M) , F(None)|F(Special) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdXsave64 , "xsave64" , O_000F00(AE,4,_,W,_), U , Enc(X86M) , F(None)|F(Special) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdXsaveopt , "xsaveopt" , O_000F00(AE,6,_,_,_), U , Enc(X86M) , F(None)|F(Special) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdXsaveopt64 , "xsaveopt64" , O_000F00(AE,6,_,W,_), U , Enc(X86M) , F(None)|F(Special) , EF(________), 0 , 0 , O(Mem) , U , U , U , U ), + INST(kX86InstIdXsetbv , "xsetbv" , O_000F01(D1,U,_,_,_), U , Enc(X86Op) , F(None)|F(Special) , EF(________), 0 , 0 , U , U , U , U , U ) }; #undef INST @@ -4632,13 +4755,9 @@ const X86InstInfo _x86InstInfo[] = { #undef O_00_X #undef O_9B_X -#undef O_66_M09 -#undef O_66_M08 #undef O_66_M03 - #undef O_00_M09 #undef O_00_M08 -#undef O_00_M03 #undef O_F30F3A #undef O_F30F38 @@ -4660,13 +4779,13 @@ const X86InstInfo _x86InstInfo[] = { #undef O_000F00 #undef O_000000 -#undef L -#undef U - -#undef E #undef O +#undef EF +#undef A #undef F -#undef G +#undef Enc + +#undef U // ============================================================================ // [asmjit::X86Cond] @@ -4817,6 +4936,7 @@ uint32_t X86Util::getInstIdByName(const char* name, size_t len) { #if defined(ASMJIT_TEST) && !defined(ASMJIT_DISABLE_NAMES) UNIT(x86_inst_name) { // All known instructions should be matched. + INFO("Matching all X86/X64 instructions."); for (uint32_t a = 0; a < _kX86InstIdCount; a++) { uint32_t b = X86Util::getInstIdByName(_x86InstInfo[a].getInstName()); @@ -4827,6 +4947,7 @@ UNIT(x86_inst_name) { } // Everything else should return kInstIdNone + INFO("Trying to look-up instructions that don't exist."); EXPECT(X86Util::getInstIdByName(NULL) == kInstIdNone, "Should return kInstIdNone for NULL input."); diff --git a/libraries/asmjit/x86/x86inst.h b/libraries/asmjit/x86/x86inst.h index be6ceaa7f..fe625ec4e 100644 --- a/libraries/asmjit/x86/x86inst.h +++ b/libraries/asmjit/x86/x86inst.h @@ -73,14 +73,19 @@ ASMJIT_VAR const uint32_t _x86CondToJcc[20]; ASMJIT_VAR const uint32_t _x86CondToSetcc[20]; // ============================================================================ -// [asmjit::kX86InstId] +// [asmjit::X86InstId] // ============================================================================ -//! X86/X64 instruction codes. +//! X86/X64 instruction IDs. //! //! Note that these instruction codes are AsmJit specific. Each instruction has -//! a unique ID that is used as an index to AsmJit instruction table. -ASMJIT_ENUM(kX86InstId) { +//! a unique ID that is used as an index to AsmJit instruction table. The list +//! is sorted alphabetically except instructions starting with `j`, because the +//! `jcc` instruction is composition of an opcode and condition code. It means +//! that these instructions are sorted as `jcc`, `jecxz` and `jmp`. Please use +//! \ref X86Util::getInstIdByName() if you need instruction name to ID mapping +//! and are not aware on how to handle such case. +ASMJIT_ENUM(X86InstId) { kX86InstIdAdc = 1, // X86/X64 kX86InstIdAdd, // X86/X64 kX86InstIdAddpd, // SSE2 @@ -111,7 +116,7 @@ ASMJIT_ENUM(kX86InstId) { kX86InstIdBlsr, // BMI kX86InstIdBsf, // X86/X64 kX86InstIdBsr, // X86/X64 - kX86InstIdBswap, // X86/X64 (i486) + kX86InstIdBswap, // X86/X64 (i486+) kX86InstIdBt, // X86/X64 kX86InstIdBtc, // X86/X64 kX86InstIdBtr, // X86/X64 @@ -125,36 +130,36 @@ ASMJIT_ENUM(kX86InstId) { kX86InstIdCld, // X86/X64 kX86InstIdClflush, // SSE2 kX86InstIdCmc, // X86/X64 - kX86InstIdCmova, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovae, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovb, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovbe, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovc, // X86/X64 (cmovcc) (i586) - kX86InstIdCmove, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovg, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovge, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovl, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovle, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovna, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnae, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnb, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnbe, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnc, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovne, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovng, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnge, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnl, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnle, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovno, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnp, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovns, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovnz, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovo, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovp, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovpe, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovpo, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovs, // X86/X64 (cmovcc) (i586) - kX86InstIdCmovz, // X86/X64 (cmovcc) (i586) + kX86InstIdCmova, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovae, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovb, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovbe, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovc, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmove, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovg, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovge, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovl, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovle, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovna, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnae, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnb, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnbe, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnc, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovne, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovng, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnge, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnl, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnle, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovno, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnp, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovns, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovnz, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovo, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovp, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovpe, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovpo, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovs, // X86/X64 (cmovcc) (i586+) + kX86InstIdCmovz, // X86/X64 (cmovcc) (i586+) kX86InstIdCmp, // X86/X64 kX86InstIdCmppd, // SSE2 kX86InstIdCmpps, // SSE @@ -164,12 +169,12 @@ ASMJIT_ENUM(kX86InstId) { kX86InstIdCmpsW, // CMPS - X86/X64 kX86InstIdCmpsd, // SSE2 kX86InstIdCmpss, // SSE - kX86InstIdCmpxchg, // X86/X64 (i486) + kX86InstIdCmpxchg, // X86/X64 (i486+) kX86InstIdCmpxchg16b, // X64 only - kX86InstIdCmpxchg8b, // X86/X64 (i586) + kX86InstIdCmpxchg8b, // X86/X64 (i586+) kX86InstIdComisd, // SSE2 kX86InstIdComiss, // SSE - kX86InstIdCpuid, // X86/X64 (i486) + kX86InstIdCpuid, // X86/X64 (i486/i586+) kX86InstIdCqo, // X64 only kX86InstIdCrc32, // SSE4.2 kX86InstIdCvtdq2pd, // SSE2 @@ -209,6 +214,7 @@ ASMJIT_ENUM(kX86InstId) { kX86InstIdEmms, // MMX kX86InstIdEnter, // X86/X64 kX86InstIdExtractps, // SSE4.1 + kX86InstIdExtrq, // SSE4a kX86InstIdF2xm1, // FPU kX86InstIdFabs, // FPU kX86InstIdFadd, // FPU @@ -313,6 +319,7 @@ ASMJIT_ENUM(kX86InstId) { kX86InstIdImul, // X86/X64 kX86InstIdInc, // X86/X64 kX86InstIdInsertps, // SSE4.1 + kX86InstIdInsertq, // SSE4a kX86InstIdInt, // X86/X64 kX86InstIdJa, // X86/X64 (jcc) kX86InstIdJae, // X86/X64 (jcc) @@ -393,6 +400,8 @@ ASMJIT_ENUM(kX86InstId) { kX86InstIdMovntpd, // SSE2 kX86InstIdMovntps, // SSE kX86InstIdMovntq, // MMX-Ext + kX86InstIdMovntsd, // SSE4a + kX86InstIdMovntss, // SSE4a kX86InstIdMovq, // MMX/SSE/SSE2 kX86InstIdMovq2dq, // SSE2 kX86InstIdMovsB, // MOVS - X86/X64 @@ -1125,11 +1134,19 @@ ASMJIT_ENUM(kX86InstId) { kX86InstIdVzeroupper, // AVX kX86InstIdWrfsbase, // FSGSBASE (x64) kX86InstIdWrgsbase, // FSGSBASE (x64) - kX86InstIdXadd, // X86/X64 (i486) - kX86InstIdXchg, // X86/X64 (i386) + kX86InstIdXadd, // X86/X64 (i486+) + kX86InstIdXchg, // X86/X64 + kX86InstIdXgetbv, // XSAVE kX86InstIdXor, // X86/X64 kX86InstIdXorpd, // SSE2 kX86InstIdXorps, // SSE + kX86InstIdXrstor, // XSAVE + kX86InstIdXrstor64, // XSAVE + kX86InstIdXsave, // XSAVE + kX86InstIdXsave64, // XSAVE + kX86InstIdXsaveopt, // XSAVE + kX86InstIdXsaveopt64, // XSAVE + kX86InstIdXsetbv, // XSAVE _kX86InstIdCount, @@ -1142,34 +1159,59 @@ ASMJIT_ENUM(kX86InstId) { }; // ============================================================================ -// [asmjit::kX86InstOptions] +// [asmjit::X86InstOptions] // ============================================================================ //! X86/X64 instruction emit options, mainly for internal purposes. -ASMJIT_ENUM(kX86InstOptions) { +ASMJIT_ENUM(X86InstOptions) { //! Emit instruction with LOCK prefix. //! //! If this option is used and instruction doesn't support LOCK prefix an //! invalid instruction error is generated. - kX86InstOptionLock = 0x10, + kX86InstOptionLock = 0x00000010, - //! Force REX prefix to be emitted. + //! Force REX prefix (X64). //! - //! This option should be used carefully, because there are unencodable - //! combinations. If you want to access ah, bh, ch or dh registers the REX - //! prefix can't be emitted, otherwise illegal instruction error will be - //! returned. - kX86InstOptionRex = 0x40, - - //! Force three-byte VEX prefix to be emitted (instead of more compact - //! two-byte VEX prefix). + //! This option should be used carefully as there are combinations of + //! instructions and their operands that are not encodable. The REX prefix + //! can't be used together with AH, BH, CH, and DH registers. AsmJit reports + //! \ref kErrorIllegalInstruction in such case. + kX86InstOptionRex = 0x00000040, + + //! \internal //! - //! Ignored if the instruction doesn't use VEX prefix. - kX86InstOptionVex3 = 0x80 + //! Reserved by `X86Assembler`, do not use! + _kX86InstOptionNoRex = 0x00000080, + + //! Force 3-byte VEX prefix even if the instruction is encodable by 2-byte + //! VEX prefix (AVX). + //! + //! Ignored if the instruction is not AVX or `kX86InstOptionEVEX` is used. + kX86InstOptionVex3 = 0x00000100, + + //! Force 4-byte EVEX prefix even if the instruction is encodable by using + //! VEX prefix. Please note that all higher bits from `kX86InstOptionEvex` + //! are reserved for EVEX and forces EVEX encoding to be used implicitly. + kX86InstOptionEvex = 0x00010000, + //! Use zeroing instead of merging (AVX512+). + kX86InstOptionEvexZero = 0x00020000, + //! Broadcast one element to all other elements (AVX512+). + kX86InstOptionEvexOneN = 0x00040000, + //! Suppress all exceptions (AVX512+). + kX86InstOptionEvexSae = 0x00080000, + + //! Static rounding mode `round-to-nearest` (even) and `SAE` (AVX512+). + kX86InstOptionEvexRnSae = 0x00100000, + //! Static rounding mode `round-down` (toward -inf) and `SAE` (AVX512+). + kX86InstOptionEvexRdSae = 0x00200000, + //! Static rounding mode `round-up` (toward +inf) and `SAE` (AVX512+). + kX86InstOptionEvexRuSae = 0x00400000, + //! Static rounding mode `round-toward-zero` (truncate) and `SAE` (AVX512+). + kX86InstOptionEvexRzSae = 0x00800000 }; // ============================================================================ -// [asmjit::kX86InstGroup] +// [asmjit::X86InstEncodingId] // ============================================================================ //! \internal @@ -1177,294 +1219,373 @@ ASMJIT_ENUM(kX86InstOptions) { //! X86/X64 instruction groups. //! //! This group is specific to AsmJit and only used by `X86Assembler`. -ASMJIT_ENUM(kX86InstGroup) { +ASMJIT_ENUM(X86InstEncodingId) { //! Never used. - kX86InstGroupNone, - - kX86InstGroupX86Op, - kX86InstGroupX86Op_66H, - kX86InstGroupX86Rm, - kX86InstGroupX86Rm_B, - kX86InstGroupX86RmReg, - kX86InstGroupX86RegRm, - kX86InstGroupX86M, + kX86InstEncodingIdNone = 0, + + kX86InstEncodingIdX86Op, + kX86InstEncodingIdX86Op_66H, + kX86InstEncodingIdX86Rm, + kX86InstEncodingIdX86Rm_B, + kX86InstEncodingIdX86RmReg, + kX86InstEncodingIdX86RegRm, + kX86InstEncodingIdX86M, //! Adc/Add/And/Cmp/Or/Sbb/Sub/Xor. - kX86InstGroupX86Arith, + kX86InstEncodingIdX86Arith, //! Bswap. - kX86InstGroupX86BSwap, + kX86InstEncodingIdX86BSwap, //! Bt/Btc/Btr/Bts. - kX86InstGroupX86BTest, + kX86InstEncodingIdX86BTest, //! Call. - kX86InstGroupX86Call, + kX86InstEncodingIdX86Call, //! Enter. - kX86InstGroupX86Enter, + kX86InstEncodingIdX86Enter, //! Imul. - kX86InstGroupX86Imul, + kX86InstEncodingIdX86Imul, //! Inc/Dec. - kX86InstGroupX86IncDec, + kX86InstEncodingIdX86IncDec, //! Int. - kX86InstGroupX86Int, + kX86InstEncodingIdX86Int, //! Jcc. - kX86InstGroupX86Jcc, + kX86InstEncodingIdX86Jcc, //! Jcxz/Jecxz/Jrcxz. - kX86InstGroupX86Jecxz, + kX86InstEncodingIdX86Jecxz, //! Jmp. - kX86InstGroupX86Jmp, + kX86InstEncodingIdX86Jmp, //! Lea. - kX86InstGroupX86Lea, + kX86InstEncodingIdX86Lea, //! Mov. - kX86InstGroupX86Mov, + kX86InstEncodingIdX86Mov, //! Movsx/Movzx. - kX86InstGroupX86MovSxZx, + kX86InstEncodingIdX86MovSxZx, //! Movsxd. - kX86InstGroupX86MovSxd, + kX86InstEncodingIdX86MovSxd, //! Mov having absolute memory operand (x86/x64). - kX86InstGroupX86MovPtr, + kX86InstEncodingIdX86MovPtr, //! Push. - kX86InstGroupX86Push, + kX86InstEncodingIdX86Push, //! Pop. - kX86InstGroupX86Pop, + kX86InstEncodingIdX86Pop, //! Rep/Repe/Repne LodsX/MovsX/StosX/CmpsX/ScasX. - kX86InstGroupX86Rep, + kX86InstEncodingIdX86Rep, //! Ret. - kX86InstGroupX86Ret, + kX86InstEncodingIdX86Ret, //! Rcl/Rcr/Rol/Ror/Sal/Sar/Shl/Shr. - kX86InstGroupX86Rot, + kX86InstEncodingIdX86Rot, //! Setcc. - kX86InstGroupX86Set, + kX86InstEncodingIdX86Set, //! Shld/Rhrd. - kX86InstGroupX86Shlrd, + kX86InstEncodingIdX86Shlrd, //! Test. - kX86InstGroupX86Test, + kX86InstEncodingIdX86Test, //! Xadd. - kX86InstGroupX86Xadd, + kX86InstEncodingIdX86Xadd, //! Xchg. - kX86InstGroupX86Xchg, + kX86InstEncodingIdX86Xchg, //! Fincstp/Finit/FldX/Fnclex/Fninit/Fnop/Fpatan/Fprem/Fprem1/Fptan/Frndint/Fscale/Fsin/Fsincos/Fsqrt/Ftst/Fucompp/Fxam/Fxtract/Fyl2x/Fyl2xp1. - kX86InstGroupFpuOp, + kX86InstEncodingIdFpuOp, //! Fadd/Fdiv/Fdivr/Fmul/Fsub/Fsubr. - kX86InstGroupFpuArith, + kX86InstEncodingIdFpuArith, //! Fcom/Fcomp. - kX86InstGroupFpuCom, + kX86InstEncodingIdFpuCom, //! Fld/Fst/Fstp. - kX86InstGroupFpuFldFst, + kX86InstEncodingIdFpuFldFst, //! Fiadd/Ficom/Ficomp/Fidiv/Fidivr/Fild/Fimul/Fist/Fistp/Fisttp/Fisub/Fisubr. - kX86InstGroupFpuM, + kX86InstEncodingIdFpuM, //! Fcmov/Fcomi/Fcomip/Ffree/Fucom/Fucomi/Fucomip/Fucomp/Fxch. - kX86InstGroupFpuR, + kX86InstEncodingIdFpuR, //! Faddp/Fdivp/Fdivrp/Fmulp/Fsubp/Fsubrp. - kX86InstGroupFpuRDef, + kX86InstEncodingIdFpuRDef, //! Fnstsw/Fstsw. - kX86InstGroupFpuStsw, + kX86InstEncodingIdFpuStsw, //! Mm/Xmm instruction. - kX86InstGroupExtRm, + kX86InstEncodingIdExtRm, //! Mm/Xmm instruction (propagates 66H if the instruction uses Xmm register). - kX86InstGroupExtRm_P, + kX86InstEncodingIdExtRm_P, //! Mm/Xmm instruction (propagates REX.W if GPQ is used). - kX86InstGroupExtRm_Q, + kX86InstEncodingIdExtRm_Q, //! Mm/Xmm instruction (propagates 66H and REX.W). - kX86InstGroupExtRm_PQ, + kX86InstEncodingIdExtRm_PQ, //! Mm/Xmm instruction having Rm/Ri encodings. - kX86InstGroupExtRmRi, + kX86InstEncodingIdExtRmRi, //! Mm/Xmm instruction having Rm/Ri encodings (propagates 66H if the instruction uses Xmm register). - kX86InstGroupExtRmRi_P, + kX86InstEncodingIdExtRmRi_P, //! Mm/Xmm instruction having Rmi encoding. - kX86InstGroupExtRmi, + kX86InstEncodingIdExtRmi, //! Mm/Xmm instruction having Rmi encoding (propagates 66H if the instruction uses Xmm register). - kX86InstGroupExtRmi_P, + kX86InstEncodingIdExtRmi_P, //! Crc32. - kX86InstGroupExtCrc, + kX86InstEncodingIdExtCrc, //! Pextrb/Pextrw/Pextrd/Pextrq/Extractps. - kX86InstGroupExtExtract, + kX86InstEncodingIdExtExtract, //! Lfence/Mfence/Sfence. - kX86InstGroupExtFence, + kX86InstEncodingIdExtFence, //! Mov Mm/Xmm. //! //! 0x66 prefix must be set manually in opcodes. //! //! - Primary opcode is used for instructions in (X)Mm <- (X)Mm/X86Mem format, //! - Secondary opcode is used for instructions in (X)Mm/X86Mem <- (X)Mm format. - kX86InstGroupExtMov, + kX86InstEncodingIdExtMov, //! Mov Mm/Xmm. - kX86InstGroupExtMovNoRexW, + kX86InstEncodingIdExtMovNoRexW, //! Movbe. - kX86InstGroupExtMovBe, + kX86InstEncodingIdExtMovBe, //! Movd. - kX86InstGroupExtMovD, + kX86InstEncodingIdExtMovD, //! Movq. - kX86InstGroupExtMovQ, + kX86InstEncodingIdExtMovQ, //! Prefetch. - kX86InstGroupExtPrefetch, + kX86InstEncodingIdExtPrefetch, + + //! Extrq (SSE4a). + kX86InstEncodingIdExtExtrq, + //! Insrq (SSE4a). + kX86InstEncodingIdExtInsertq, //! 3dNow instruction. - kX86InstGroup3dNow, + kX86InstEncodingId3dNow, //! AVX instruction without operands. - kX86InstGroupAvxOp, + kX86InstEncodingIdAvxOp, //! AVX instruction encoded as 'M'. - kX86InstGroupAvxM, + kX86InstEncodingIdAvxM, //! AVX instruction encoded as 'MR'. - kX86InstGroupAvxMr, + kX86InstEncodingIdAvxMr, //! AVX instruction encoded as 'MR' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxMr_P, + kX86InstEncodingIdAvxMr_P, //! AVX instruction encoded as 'MRI'. - kX86InstGroupAvxMri, + kX86InstEncodingIdAvxMri, //! AVX instruction encoded as 'MRI' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxMri_P, + kX86InstEncodingIdAvxMri_P, //! AVX instruction encoded as 'RM'. - kX86InstGroupAvxRm, + kX86InstEncodingIdAvxRm, //! AVX instruction encoded as 'RM' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRm_P, + kX86InstEncodingIdAvxRm_P, //! AVX instruction encoded as 'RMI'. - kX86InstGroupAvxRmi, + kX86InstEncodingIdAvxRmi, //! AVX instruction encoded as 'RMI' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRmi_P, + kX86InstEncodingIdAvxRmi_P, //! AVX instruction encoded as 'RVM'. - kX86InstGroupAvxRvm, + kX86InstEncodingIdAvxRvm, //! AVX instruction encoded as 'RVM' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRvm_P, + kX86InstEncodingIdAvxRvm_P, //! AVX instruction encoded as 'RVMR'. - kX86InstGroupAvxRvmr, + kX86InstEncodingIdAvxRvmr, //! AVX instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRvmr_P, + kX86InstEncodingIdAvxRvmr_P, //! AVX instruction encoded as 'RVMI'. - kX86InstGroupAvxRvmi, + kX86InstEncodingIdAvxRvmi, //! AVX instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRvmi_P, + kX86InstEncodingIdAvxRvmi_P, //! AVX instruction encoded as 'RMV'. - kX86InstGroupAvxRmv, + kX86InstEncodingIdAvxRmv, //! AVX instruction encoded as 'RMVI'. - kX86InstGroupAvxRmvi, + kX86InstEncodingIdAvxRmvi, //! AVX instruction encoded as 'RM' or 'MR'. - kX86InstGroupAvxRmMr, + kX86InstEncodingIdAvxRmMr, //! AVX instruction encoded as 'RM' or 'MR' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRmMr_P, + kX86InstEncodingIdAvxRmMr_P, //! AVX instruction encoded as 'RVM' or 'RMI'. - kX86InstGroupAvxRvmRmi, + kX86InstEncodingIdAvxRvmRmi, //! AVX instruction encoded as 'RVM' or 'RMI' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRvmRmi_P, + kX86InstEncodingIdAvxRvmRmi_P, //! AVX instruction encoded as 'RVM' or 'MR'. - kX86InstGroupAvxRvmMr, + kX86InstEncodingIdAvxRvmMr, //! AVX instruction encoded as 'RVM' or 'MVR'. - kX86InstGroupAvxRvmMvr, + kX86InstEncodingIdAvxRvmMvr, //! AVX instruction encoded as 'RVM' or 'MVR' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRvmMvr_P, + kX86InstEncodingIdAvxRvmMvr_P, //! AVX instruction encoded as 'RVM' or 'VMI'. - kX86InstGroupAvxRvmVmi, + kX86InstEncodingIdAvxRvmVmi, //! AVX instruction encoded as 'RVM' or 'VMI' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRvmVmi_P, + kX86InstEncodingIdAvxRvmVmi_P, //! AVX instruction encoded as 'VM'. - kX86InstGroupAvxVm, + kX86InstEncodingIdAvxVm, //! AVX instruction encoded as 'VMI'. - kX86InstGroupAvxVmi, + kX86InstEncodingIdAvxVmi, //! AVX instruction encoded as 'VMI' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxVmi_P, + kX86InstEncodingIdAvxVmi_P, //! AVX instruction encoded as 'RVRM' or 'RVMR'. - kX86InstGroupAvxRvrmRvmr, + kX86InstEncodingIdAvxRvrmRvmr, //! AVX instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). - kX86InstGroupAvxRvrmRvmr_P, + kX86InstEncodingIdAvxRvrmRvmr_P, //! Vmovss/Vmovsd. - kX86InstGroupAvxMovSsSd, + kX86InstEncodingIdAvxMovSsSd, //! AVX2 gather family instructions (VSIB). - kX86InstGroupAvxGather, + kX86InstEncodingIdAvxGather, //! AVX2 gather family instructions (VSIB), differs only in mem operand. - kX86InstGroupAvxGatherEx, + kX86InstEncodingIdAvxGatherEx, //! FMA4 instruction in form [R, R, R/M, R/M]. - kX86InstGroupFma4, + kX86InstEncodingIdFma4, //! FMA4 instruction in form [R, R, R/M, R/M] (Propagates AVX.L if Ymm used). - kX86InstGroupFma4_P, + kX86InstEncodingIdFma4_P, //! XOP instruction encoded as 'RM'. - kX86InstGroupXopRm, + kX86InstEncodingIdXopRm, //! XOP instruction encoded as 'RM' (Propagates AVX.L if Ymm used). - kX86InstGroupXopRm_P, + kX86InstEncodingIdXopRm_P, //! XOP instruction encoded as 'RVM' or 'RMV'. - kX86InstGroupXopRvmRmv, + kX86InstEncodingIdXopRvmRmv, //! XOP instruction encoded as 'RVM' or 'RMI'. - kX86InstGroupXopRvmRmi, + kX86InstEncodingIdXopRvmRmi, //! XOP instruction encoded as 'RVMR'. - kX86InstGroupXopRvmr, + kX86InstEncodingIdXopRvmr, //! XOP instruction encoded as 'RVMR' (Propagates AVX.L if Ymm used). - kX86InstGroupXopRvmr_P, + kX86InstEncodingIdXopRvmr_P, //! XOP instruction encoded as 'RVMI'. - kX86InstGroupXopRvmi, + kX86InstEncodingIdXopRvmi, //! XOP instruction encoded as 'RVMI' (Propagates AVX.L if Ymm used). - kX86InstGroupXopRvmi_P, + kX86InstEncodingIdXopRvmi_P, //! XOP instruction encoded as 'RVRM' or 'RVMR'. - kX86InstGroupXopRvrmRvmr, + kX86InstEncodingIdXopRvrmRvmr, //! XOP instruction encoded as 'RVRM' or 'RVMR' (Propagates AVX.L if Ymm used). - kX86InstGroupXopRvrmRvmr_P, + kX86InstEncodingIdXopRvrmRvmr_P, //! Count of X86 instruction groups. - _kX86InstGroupCount + _kX86InstEncodingIdCount }; // ============================================================================ -// [asmjit::kX86InstOpCode] +// [asmjit::X86InstOpCodeFlags] // ============================================================================ //! \internal //! -//! Instruction OpCode encoding used by asmjit 'X86InstInfo' table. +//! X86/X64 Instruction opcode encoding used by asmjit 'X86InstInfo' table. +//! +//! This schema is AsmJit specific and has been designed to allow encoding of +//! all X86 instructions available. X86, MMX, and SSE+ instructions always use +//! `MMMMM` and `PP` fields, which are encoded to corresponding prefixes needed +//! by X86 or SIMD instructions. AVX+ instructions embed `MMMMM` and `PP` fields +//! in a VEX prefix. +//! +//! The instruction opcode definition uses 1 or 2 bytes as an opcode value. 1 +//! byte is needed by most of the instructions, 2 bytes are only used by legacy +//! X87-FPU instructions. This means that a second byte is free to by used by +//! AVX and AVX-512 instructions. +//! +//! The fields description: +//! +//! - `MMMMM` field is used to encode prefixes needed by the instruction or as +//! a part of VEX/EVEX prefix. //! -//! The schema was inspired by AVX/AVX2 features. -ASMJIT_ENUM(kX86InstOpCode) { - // 'MMMMM' field in AVX/XOP instruction. - // 'OpCode' leading bytes in legacy encoding. - kX86InstOpCode_MM_Shift = 16, - kX86InstOpCode_MM_Mask = 0x0FU << kX86InstOpCode_MM_Shift, - kX86InstOpCode_MM_00 = 0x00U << kX86InstOpCode_MM_Shift, - kX86InstOpCode_MM_0F = 0x01U << kX86InstOpCode_MM_Shift, - kX86InstOpCode_MM_0F38 = 0x02U << kX86InstOpCode_MM_Shift, - kX86InstOpCode_MM_0F3A = 0x03U << kX86InstOpCode_MM_Shift, - kX86InstOpCode_MM_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // Ext/Not part of AVX. - - kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift, - kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift, - kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift, - - // 'PP' field in AVX/XOP instruction. - // 'Mandatory Prefix' in legacy encoding. - kX86InstOpCode_PP_Shift = 21, - kX86InstOpCode_PP_Mask = 0x07U << kX86InstOpCode_PP_Shift, - kX86InstOpCode_PP_00 = 0x00U << kX86InstOpCode_PP_Shift, - kX86InstOpCode_PP_66 = 0x01U << kX86InstOpCode_PP_Shift, - kX86InstOpCode_PP_F3 = 0x02U << kX86InstOpCode_PP_Shift, - kX86InstOpCode_PP_F2 = 0x03U << kX86InstOpCode_PP_Shift, - kX86InstOpCode_PP_9B = 0x07U << kX86InstOpCode_PP_Shift, // Ext/Not part of AVX. - - // 'L' field in AVX/XOP instruction. - kX86InstOpCode_L_Shift = 24, - kX86InstOpCode_L_Mask = 0x01U << kX86InstOpCode_L_Shift, - kX86InstOpCode_L_False = 0x00U << kX86InstOpCode_L_Shift, - kX86InstOpCode_L_True = 0x01U << kX86InstOpCode_L_Shift, - - // 'O' field. - kX86InstOpCode_O_Shift = 29, - kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_Shift +//! - `PP` field is used to encode prefixes needed by the instruction or as a +//! part of VEX/EVEX prefix. +//! +//! - `L` field is used exclusively by AVX+ and AVX512+ instruction sets. It +//! describes vector size, which is 128-bit for Xmm register `L_128`, 256 +//! for Ymm register `L_256` and 512-bit for Zmm register `L_512`. The `L` +//! field is omitted in case that instruction supports multiple vector lengths, +//! however, if the instruction requires specific `L` value it's specified as +//! a part of the opcode. +//! +//! - `W` field is the most complicated. It was added by 64-bit architecture +//! to promote default operation width (instructions that perform 32-bit +//! operation by default require to override the width to 64-bit explicitly). +//! There is nothing wrong on this, however, some instructions introduced +//! implicit `W` override, for example a `cdqe` instruction is basically a +//! `cwde` instructiontion with overridden `W` (set to 1). There are some +//! others in the base X86 instruction set. More recent instruction sets +//! started using `W` field more often: +//! +//! - AVX instructions started using `W` field as an extended opcode for FMA, +//! GATHER, PERM, and other instructions. It also uses `W` field to override +//! the default operation width in instructions like `vmovq`. AVX `W` field +//! is +//! +//! - AVX-512 instructions started using `W` field as an extended opcode for +//! all new instructions. This wouldn't have been an issue if the `W` field +//! of AVX-512 have matched AVX, but this is not the case. +//! +//! - `O` field is an extended opcode field (3) bytes used by ModR/M BYTE. +ASMJIT_ENUM(X86InstOpCodeFlags) { + // `MMMMM` field in AVX/XOP/AVX-512 instruction (5 bits). + // + // `OpCode` leading bytes in legacy encoding. + // + // AVX reserves 5 bits for `MMMMM` field, however AVX instructions only use + // 2 bits and XOP 4 bits. AVX-512 shrinks `MMMMM` field into `MM` so it's + // safe to assume that `MM` field won't grow in the future as EVEX doesn't + // use more than 2 bits. There is always a way how a fifth bit can be stored + // if needed. + kX86InstOpCode_MM_Shift = 16, + kX86InstOpCode_MM_Mask = 0x0FU << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_00 = 0x00U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F = 0x01U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F38 = 0x02U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_0F3A = 0x03U << kX86InstOpCode_MM_Shift, + kX86InstOpCode_MM_00011 = 0x03U << kX86InstOpCode_MM_Shift, // XOP. + kX86InstOpCode_MM_01000 = 0x08U << kX86InstOpCode_MM_Shift, // XOP. + kX86InstOpCode_MM_01001 = 0x09U << kX86InstOpCode_MM_Shift, // XOP. + kX86InstOpCode_MM_0F01 = 0x0FU << kX86InstOpCode_MM_Shift, // AsmJit specific, not part of AVX. + + // `PP` field in AVX/XOP/AVX-512 instruction. + // + // `Mandatory Prefix` in legacy encoding. + // + // AVX reserves 2 bits for `PP` field, but AsmJit extends the storage by 1 + // more bit that is used to emit 9B prefix for some X87-FPU instructions. + kX86InstOpCode_PP_Shift = 20, + kX86InstOpCode_PP_Mask = 0x07U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_00 = 0x00U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_66 = 0x01U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_F3 = 0x02U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_F2 = 0x03U << kX86InstOpCode_PP_Shift, + kX86InstOpCode_PP_9B = 0x07U << kX86InstOpCode_PP_Shift, // AsmJit specific, not part of AVX. + + // `L` field in AVX/XOP/AVX-512 instruction. + // + // AVX/XOP can only use the first bit `L.128` or `L.256`. AVX-512 makes it + // possible to use also `L.512`. + // + // \note If the instruction set manual describes an instruction by using `LIG` + // it means that the `L` field is ignored. AsmJit emits `0` in such case. + kX86InstOpCode_L_Shift = 23, + kX86InstOpCode_L_Mask = 0x03U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_128 = 0x00U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_256 = 0x01U << kX86InstOpCode_L_Shift, + kX86InstOpCode_L_512 = 0x02U << kX86InstOpCode_L_Shift, + + // `O` field (ModR/M). + kX86InstOpCode_O_Shift = 25, + kX86InstOpCode_O_Mask = 0x07U << kX86InstOpCode_O_Shift, + + // `W` field used in EVEX instruction encoding. + kX86InstOpCode_EW_Shift = 30, + kX86InstOpCode_EW_Mask = 0x01U << kX86InstOpCode_EW_Shift, + kX86InstOpCode_EW = 0x01U << kX86InstOpCode_EW_Shift, + + // `W` field used in REX/VEX instruction encoding. + // + // \note If the instruction set manual describes an instruction by using `WIG` + // it means that the `W` field is ignored. AsmJit emits `0` in such case. + kX86InstOpCode_W_Shift = 31, + kX86InstOpCode_W_Mask = 0x01U << kX86InstOpCode_W_Shift, + kX86InstOpCode_W = 0x01U << kX86InstOpCode_W_Shift, }; // ============================================================================ -// [asmjit::kX86InstFlags] +// [asmjit::X86InstFlags] // ============================================================================ //! \internal //! -//! X86/X64 instruction type flags. -ASMJIT_ENUM(kX86InstFlags) { +//! X86/X64 instruction flags. +ASMJIT_ENUM(X86InstFlags) { //! No flags. - kX86InstFlagNone = 0x0000, + kX86InstFlagNone = 0x00000000, //! Instruction is a control-flow instruction. //! //! Control flow instructions are jmp, jcc, call and ret. - kX86InstFlagFlow = 0x0001, + kX86InstFlagFlow = 0x00000001, //! Instruction is a compare/test like instruction. - kX86InstFlagTest = 0x0002, + kX86InstFlagTest = 0x00000002, //! Instruction is a move like instruction. //! @@ -1479,76 +1600,84 @@ ASMJIT_ENUM(kX86InstFlags) { //! There are some MOV instructions that do only a partial move (for example //! 'cvtsi2ss'), register allocator has to know the variable size and use //! the flag accordingly to it. - kX86InstFlagMove = 0x0004, + kX86InstFlagMove = 0x00000004, //! Instruction is an exchange like instruction. //! //! Exchange instruction typically overwrite first and second operand. So //! far only the instructions 'xchg' and 'xadd' are considered. - kX86InstFlagXchg = 0x0008, + kX86InstFlagXchg = 0x00000008, //! Instruction accesses Fp register(s). - kX86InstFlagFp = 0x0010, + kX86InstFlagFp = 0x00000010, //! Instruction can be prefixed by using the LOCK prefix. - kX86InstFlagLock = 0x0020, + kX86InstFlagLock = 0x00000020, - //! Instruction is special, this is for `Compiler`. - kX86InstFlagSpecial = 0x0040, + //! Instruction requires special handling, used by \ref Compiler. + kX86InstFlagSpecial = 0x00000040, //! Instruction always performs memory access. //! - //! This flag is always combined with `kX86InstFlagSpecial` and signalizes + //! This flag is always combined with `kX86InstFlagSpecial` and describes //! that there is an implicit address which is accessed (usually EDI/RDI or //! ESI/EDI). - kX86InstFlagSpecialMem = 0x0080, + kX86InstFlagSpecialMem = 0x00000080, //! Instruction memory operand can refer to 16-bit address (used by FPU). - kX86InstFlagMem2 = 0x0100, + kX86InstFlagMem2 = 0x00000100, //! Instruction memory operand can refer to 32-bit address (used by FPU). - kX86InstFlagMem4 = 0x0200, + kX86InstFlagMem4 = 0x00000200, //! Instruction memory operand can refer to 64-bit address (used by FPU). - kX86InstFlagMem8 = 0x0400, + kX86InstFlagMem8 = 0x00000400, //! Instruction memory operand can refer to 80-bit address (used by FPU). - kX86InstFlagMem10 = 0x0800, - - //! \internal - //! - //! Combination of `kX86InstFlagMem2` and `kX86InstFlagMem4`. - kX86InstFlagMem2_4 = kX86InstFlagMem2 | kX86InstFlagMem4, - - //! \internal - //! - //! Combination of `kX86InstFlagMem2`, `kX86InstFlagMem4` and `kX86InstFlagMem8`. - kX86InstFlagMem2_4_8 = kX86InstFlagMem2_4 | kX86InstFlagMem8, - - //! \internal - //! - //! Combination of `kX86InstFlagMem4` and `kX86InstFlagMem8`. - kX86InstFlagMem4_8 = kX86InstFlagMem4 | kX86InstFlagMem8, - - //! \internal - //! - //! Combination of `kX86InstFlagMem4`, `kX86InstFlagMem8` and `kX86InstFlagMem10`. - kX86InstFlagMem4_8_10 = kX86InstFlagMem4_8 | kX86InstFlagMem10, + kX86InstFlagMem10 = 0x00000800, //! Zeroes the rest of the register if the source operand is memory. //! //! Special behavior related to some SIMD load instructions. - kX86InstFlagZ = 0x1000, - - //! REX.W/VEX.W by default. - kX86InstFlagW = 0x8000 + kX86InstFlagZ = 0x00001000, + + //! Instruction is supported by AVX. + kX86InstFlagAvx = 0x00010000, + //! Instruction is supported by XOP. + kX86InstFlagXop = 0x00020000, + + //! Instruction is supported by AVX-512 F (Zmm). + kX86InstFlagAvx512F = 0x00100000, + //! Instruction is supported by AVX-512 CD (Zmm). + kX86InstFlagAvx512CD = 0x00200000, + //! Instruction is supported by AVX-512 PF (Zmm). + kX86InstFlagAvx512PF = 0x00400000, + //! Instruction is supported by AVX-512 ER (Zmm). + kX86InstFlagAvx512ER = 0x00800000, + //! Instruction is supported by AVX-512 DQ (Zmm). + kX86InstFlagAvx512DQ = 0x01000000, + //! Instruction is supported by AVX-512 BW (Zmm). + kX86InstFlagAvx512BW = 0x02000000, + //! Instruction is supported by AVX-512 VL (Xmm/Ymm). + kX86InstFlagAvx512VL = 0x04000000, + + //! Instruction supports masking {k0..k7}. + kX86InstFlagAvx512KMask = 0x08000000, + //! Instruction supports zeroing of elements {k0z..k7z}. + kX86InstFlagAvx512KZero = 0x10000000, + //! Instruction supports broadcast {1toN}. + kX86InstFlagAvx512Broadcast = 0x20000000, + //! Instruction supports suppressing all exceptions {sae}. + kX86InstFlagAvx512Sae = 0x40000000, + //! Instruction supports static rounding control with SAE {rnd-sae}, + kX86InstFlagAvx512Rnd = 0x80000000 }; // ============================================================================ -// [asmjit::kX86InstOp] +// [asmjit::X86InstOp] // ============================================================================ //! \internal //! //! X86/X64 instruction operand flags. -ASMJIT_ENUM(kX86InstOp) { +ASMJIT_ENUM(X86InstOp) { //! Instruction operand can be 8-bit Gpb register. kX86InstOpGb = 0x0001, //! Instruction operand can be 16-bit Gpw register. @@ -1557,10 +1686,15 @@ ASMJIT_ENUM(kX86InstOp) { kX86InstOpGd = 0x0004, //! Instruction operand can be 64-bit Gpq register. kX86InstOpGq = 0x0008, + //! Instruction operand can be Fp register. kX86InstOpFp = 0x0010, - //! Instruction operand can be 64-bit Mmx register. + //! Instruction operand can be 64-bit Mm register. kX86InstOpMm = 0x0020, + + //! Instruction operand can be 64-bit K register. + kX86InstOpK = 0x0040, + //! Instruction operand can be 128-bit Xmm register. kX86InstOpXmm = 0x0100, //! Instruction operand can be 256-bit Ymm register. @@ -1569,52 +1703,27 @@ ASMJIT_ENUM(kX86InstOp) { kX86InstOpZmm = 0x0400, //! Instruction operand can be memory. - kX86InstOpMem = 0x2000, + kX86InstOpMem = 0x1000, //! Instruction operand can be immediate. - kX86InstOpImm = 0x4000, + kX86InstOpImm = 0x2000, //! Instruction operand can be label. - kX86InstOpLabel = 0x8000, - - //! \internal - //! - //! Combined flags. + kX86InstOpLabel = 0x4000, + //! Instruction operand doesn't have to be used. //! - //! \{ - - kX86InstOpGwb = kX86InstOpGw | kX86InstOpGb, - kX86InstOpGqd = kX86InstOpGq | kX86InstOpGd, - kX86InstOpGqdw = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw, - kX86InstOpGqdwb = kX86InstOpGq | kX86InstOpGd | kX86InstOpGw | kX86InstOpGb, - - kX86InstOpGbMem = kX86InstOpGb | kX86InstOpMem, - kX86InstOpGwMem = kX86InstOpGw | kX86InstOpMem, - kX86InstOpGdMem = kX86InstOpGd | kX86InstOpMem, - kX86InstOpGqMem = kX86InstOpGq | kX86InstOpMem, - kX86InstOpGwbMem = kX86InstOpGwb | kX86InstOpMem, - kX86InstOpGqdMem = kX86InstOpGqd | kX86InstOpMem, - kX86InstOpGqdwMem = kX86InstOpGqdw | kX86InstOpMem, - kX86InstOpGqdwbMem = kX86InstOpGqdwb | kX86InstOpMem, - - kX86InstOpFpMem = kX86InstOpFp | kX86InstOpMem, - kX86InstOpMmMem = kX86InstOpMm | kX86InstOpMem, - kX86InstOpXmmMem = kX86InstOpXmm | kX86InstOpMem, - kX86InstOpYmmMem = kX86InstOpYmm | kX86InstOpMem, - - kX86InstOpMmXmm = kX86InstOpMm | kX86InstOpXmm, - kX86InstOpMmXmmMem = kX86InstOpMmXmm | kX86InstOpMem, - - kX86InstOpXmmYmm = kX86InstOpXmm | kX86InstOpYmm, - kX86InstOpXmmYmmMem = kX86InstOpXmmYmm | kX86InstOpMem - - //! \} + //! \note If no operand is specified the meaning is clear (the operand at the + //! particular index doesn't exist), however, when one or more operand is + //! specified, it's not clear whether the operand can be omitted or not. When + //! `kX86InstOpNone` is used it means that the operand is not used in some + //! cases. + kX86InstOpNone = 0x8000 }; // ============================================================================ -// [asmjit::kX86Cond] +// [asmjit::X86Cond] // ============================================================================ //! X86/X64 Condition codes. -ASMJIT_ENUM(kX86Cond) { +ASMJIT_ENUM(X86Cond) { kX86CondA = 0x07, // CF==0 & ZF==0 (unsigned) kX86CondAE = 0x03, // CF==0 (unsigned) kX86CondB = 0x02, // CF==1 (unsigned) @@ -1647,28 +1756,31 @@ ASMJIT_ENUM(kX86Cond) { kX86CondZ = 0x04, // ZF==1 // Simplified condition codes. - kX86CondOverflow = 0x00, - kX86CondNotOverflow = 0x01, - kX86CondBelow = 0x02, //!< Unsigned comparison. - kX86CondAboveEqual = 0x03, //!< Unsigned comparison. - kX86CondEqual = 0x04, - kX86CondNotEqual = 0x05, - kX86CondBelowEqual = 0x06, //!< Unsigned comparison. - kX86CondAbove = 0x07, //!< Unsigned comparison. - kX86CondSign = 0x08, - kX86CondNotSign = 0x09, - kX86CondParityEven = 0x0A, - kX86CondParityOdd = 0x0B, - kX86CondLess = 0x0C, //!< Signed comparison. - kX86CondGreaterEqual = 0x0D, //!< Signed comparison. - kX86CondLessEqual = 0x0E, //!< Signed comparison. - kX86CondGreater = 0x0F, //!< Signed comparison. + kX86CondSign = kX86CondS , //!< Sign (S). + kX86CondNotSign = kX86CondNS, //!< Not Sign (NS). + + kX86CondOverflow = kX86CondO , //!< Signed Overflow (O) + kX86CondNotOverflow = kX86CondNO, //!< Not Signed Overflow (NO) + + kX86CondLess = kX86CondL , //!< Signed `a < b` (L or NGE). + kX86CondLessEqual = kX86CondLE, //!< Signed `a <= b` (LE or NG ). + kX86CondGreater = kX86CondG , //!< Signed `a > b` (G or NLE). + kX86CondGreaterEqual = kX86CondGE, //!< Signed `a >= b` (GE or NL ). + kX86CondBelow = kX86CondB , //!< Unsigned `a < b` (B or NAE). + kX86CondBelowEqual = kX86CondBE, //!< Unsigned `a <= b` (BE or NA ). + kX86CondAbove = kX86CondA , //!< Unsigned `a > b` (A or NBE). + kX86CondAboveEqual = kX86CondAE, //!< Unsigned `a >= b` (AE or NB ). + kX86CondEqual = kX86CondE , //!< Equal `a == b` (E or Z ). + kX86CondNotEqual = kX86CondNE, //!< Not Equal `a != b` (NE or NZ ). + + kX86CondParityEven = kX86CondP, + kX86CondParityOdd = kX86CondPO, // Aliases. - kX86CondZero = 0x04, - kX86CondNotZero = 0x05, - kX86CondNegative = 0x08, - kX86CondPositive = 0x09, + kX86CondZero = kX86CondZ, + kX86CondNotZero = kX86CondNZ, + kX86CondNegative = kX86CondS, + kX86CondPositive = kX86CondNS, // Fpu-only. kX86CondFpuUnordered = 0x10, @@ -1679,24 +1791,24 @@ ASMJIT_ENUM(kX86Cond) { }; // ============================================================================ -// [asmjit::kX86EFlags] +// [asmjit::X86EFlags] // ============================================================================ //! X86/X64 EFLAGs bits (AsmJit specific). //! //! Each instruction stored in AsmJit database contains flags that instruction //! uses (reads) and flags that instruction modifies (writes). This is used by -//! instruction reordering, but can be used by third parties as the API and -//! definitions are public. +//! instruction reordering, but can be used by third parties as it's part of +//! AsmJit API. //! -//! \note Flags defined here doesn't correspond to real flags used by X86/X64 -//! architecture defined in Intel's Manual Section `3.4.3 - EFLAGS Register`. +//! \note Flags defined here don't correspond to real flags used by X86/X64 +//! architecture, defined in Intel's Manual Section `3.4.3 - EFLAGS Register`. //! -//! \note Flags are designed to fit in 8-bit integer. -ASMJIT_ENUM(kX86EFlags) { +//! \note Flags are designed to fit in an 8-bit integer. +ASMJIT_ENUM(X86EFlags) { // -------------------------------------------------------------------------- - // src-gendefs.js relies on the values of these masks, to modify them the - // tool has to be changed as well. + // src-gendefs.js relies on the values of these masks, the tool has to be + // changed as you plan to modify `X86EFlags`. // -------------------------------------------------------------------------- //! Overflow flag (OF). @@ -1743,16 +1855,16 @@ ASMJIT_ENUM(kX86EFlags) { //! `lods` and `stos`. kX86EFlagD = 0x40, - //! Any other flag that AsmJit doesn't use to keep track of it. + //! Any other flag that AsmJit doesn't use to keep track of. kX86EFlagX = 0x80 }; // ============================================================================ -// [asmjit::kX86FpSw] +// [asmjit::X86FpSw] // ============================================================================ -//! X86/X64 FPU status Word. -ASMJIT_ENUM(kX86FpSw) { +//! X86/X64 FPU status word. +ASMJIT_ENUM(X86FpSw) { kX86FpSw_Invalid = 0x0001, kX86FpSw_Denormalized = 0x0002, kX86FpSw_DivByZero = 0x0004, @@ -1770,11 +1882,11 @@ ASMJIT_ENUM(kX86FpSw) { }; // ============================================================================ -// [asmjit::kX86FpCw] +// [asmjit::X86FpCw] // ============================================================================ -//! X86/X64 FPU control Word. -ASMJIT_ENUM(kX86FpCw) { +//! X86/X64 FPU control word. +ASMJIT_ENUM(X86FpCw) { kX86FpCw_EM_Mask = 0x003F, // Bits 0-5. kX86FpCw_EM_Invalid = 0x0001, kX86FpCw_EM_Denormal = 0x0002, @@ -1801,13 +1913,72 @@ ASMJIT_ENUM(kX86FpCw) { }; // ============================================================================ -// [asmjit::kX86Prefetch] +// [asmjit::X86Cmp] +// ============================================================================ + +//! X86/X64 Comparison predicate used by CMP[PD/PS/SD/SS] family instructions. +ASMJIT_ENUM(X86Cmp) { + kX86CmpEQ = 0x00, //!< Equal (Quite). + kX86CmpLT = 0x01, //!< Less (Signaling). + kX86CmpLE = 0x02, //!< Less/Equal (Signaling). + kX86CmpUNORD = 0x03, //!< Unordered (Quite). + kX86CmpNEQ = 0x04, //!< Not Equal (Quite). + kX86CmpNLT = 0x05, //!< Not Less (Signaling). + kX86CmpNLE = 0x06, //!< Not Less/Equal (Signaling). + kX86CmpORD = 0x07 //!< Ordered (Quite). +}; + +// ============================================================================ +// [asmjit::X86VCmp] +// ============================================================================ + +//! X86/X64 Comparison predicate used by VCMP[PD/PS/SD/SS] family instructions. +//! +//! The first 8 are compatible with \ref X86Cmp. +ASMJIT_ENUM(X86VCmp) { + kX86VCmpEQ_OQ = 0x00, //!< Equal (Quite, Ordered). + kX86VCmpLT_OS = 0x01, //!< Less (Signaling, Ordered). + kX86VCmpLE_OS = 0x02, //!< Less/Equal (Signaling, Ordered). + kX86VCmpUNORD_Q = 0x03, //!< Unordered (Quite). + kX86VCmpNEQ_UQ = 0x04, //!< Not Equal (Quite, Unordered). + kX86VCmpNLT_US = 0x05, //!< Not Less (Signaling, Unordered). + kX86VCmpNLE_US = 0x06, //!< Not Less/Equal (Signaling, Unordered). + kX86VCmpORD_Q = 0x07, //!< Ordered (Quite). + + kX86VCmpEQ_UQ = 0x08, //!< Equal (Quite, Unordered). + kX86VCmpNGE_US = 0x09, //!< Not Greater/Equal (Signaling, Unordered). + kX86VCmpNGT_US = 0x0A, //!< Not Greater (Signaling, Unordered). + kX86VCmpFALSE_OQ = 0x0B, //!< False (Quite, Ordered). + kX86VCmpNEQ_OQ = 0x0C, //!< Not Equal (Quite, Ordered). + kX86VCmpGE_OS = 0x0D, //!< Greater/Equal (Signaling, Ordered). + kX86VCmpGT_OS = 0x0E, //!< Greater (Signaling, Ordered). + kX86VCmpTRUE_UQ = 0x0F, //!< True (Quite, Unordered). + kX86VCmpEQ_OS = 0x10, //!< Equal (Signaling, Ordered). + kX86VCmpLT_OQ = 0x11, //!< Less (Quite, Ordered). + kX86VCmpLE_OQ = 0x12, //!< Less/Equal (Quite, Ordered). + kX86VCmpUNORD_S = 0x13, //!< Unordered (Signaling). + kX86VCmpNEQ_US = 0x14, //!< Not Equal (Signaling, Unordered). + kX86VCmpNLT_UQ = 0x15, //!< Not Less (Quite, Unordered). + kX86VCmpNLE_UQ = 0x16, //!< Not Less/Equal (Quite, Unordered). + kX86VCmpORD_S = 0x17, //!< Ordered (Signaling). + kX86VCmpEQ_US = 0x18, //!< Equal (Signaling, Unordered). + kX86VCmpNGE_UQ = 0x19, //!< Not Greater/Equal (Quite, Unordered). + kX86VCmpNGT_UQ = 0x1A, //!< Not Greater (Quite, Unordered). + kX86VCmpFALSE_OS = 0x1B, //!< False (Signaling, Ordered). + kX86VCmpNEQ_OS = 0x1C, //!< Not Equal (Signaling, Ordered). + kX86VCmpGE_OQ = 0x1D, //!< Greater/Equal (Quite, Ordered). + kX86VCmpGT_OQ = 0x1E, //!< Greater (Quite, Ordered). + kX86VCmpTRUE_US = 0x1F //!< True (Signaling, Unordered). +}; + +// ============================================================================ +// [asmjit::X86Prefetch] // ============================================================================ //! X86/X64 Prefetch hints. -ASMJIT_ENUM(kX86Prefetch) { +ASMJIT_ENUM(X86Prefetch) { //! Prefetch using NT hint. - kX86PrefetchNta = 0, + kX86PrefetchNTA = 0, //! Prefetch to L0 cache. kX86PrefetchT0 = 1, //! Prefetch to L1 cache. @@ -1828,32 +1999,32 @@ ASMJIT_ENUM(kX86Prefetch) { //! used by few instructions. struct X86InstExtendedInfo { // -------------------------------------------------------------------------- - // [Accessors - InstGroup] + // [Accessors - Instruction Encoding] // -------------------------------------------------------------------------- - //! Get instruction group, see \ref kX86InstGroup. - ASMJIT_INLINE uint32_t getInstGroup() const { - return _instGroup; + //! Get instruction encoding, see \ref kX86InstEncoding. + ASMJIT_INLINE uint32_t getEncodingId() const { + return _encodingId; } // -------------------------------------------------------------------------- - // [Accessors - InstFlags] + // [Accessors - Instruction Flags] // -------------------------------------------------------------------------- - //! Get whether the instruction has flag `flag`, see `kX86InstFlags`. + //! Get whether the instruction has a `flag`, see `X86InstFlags`. ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const { return (_instFlags & flag) != 0; } - //! Get instruction flags, see `kX86InstFlags`. + //! Get all instruction flags, see `X86InstFlags`. ASMJIT_INLINE uint32_t getInstFlags() const { return _instFlags; } //! Get whether the instruction is a control-flow intruction. //! - //! Control flow instruction is instruction that modifies instruction pointer, - //! typically jmp, jcc, call, or ret. + //! Control flow instruction is instruction that can perform a branch, + //! typically `jmp`, `jcc`, `call`, or `ret`. ASMJIT_INLINE bool isFlow() const { return (getInstFlags() & kX86InstFlagFlow) != 0; } @@ -1893,14 +2064,13 @@ struct X86InstExtendedInfo { return (getInstFlags() & kX86InstFlagLock) != 0; } - //! Get whether the instruction is special type (this is used by - //! `Compiler` to manage additional variables or functionality). + //! Get whether the instruction is special type (this is used by `Compiler` + //! to manage additional variables or functionality). ASMJIT_INLINE bool isSpecial() const { return (getInstFlags() & kX86InstFlagSpecial) != 0; } - //! Get whether the instruction is special type and it performs - //! memory access. + //! Get whether the instruction is special type and it performs memory access. ASMJIT_INLINE bool isSpecialMem() const { return (getInstFlags() & kX86InstFlagSpecialMem) != 0; } @@ -1917,25 +2087,28 @@ struct X86InstExtendedInfo { // [Accessors - EFlags] // -------------------------------------------------------------------------- - //! Get EFLAGS that the instruction reads. + //! Get EFLAGS that the instruction reads, see \ref X86EFlags. ASMJIT_INLINE uint32_t getEFlagsIn() const { return _eflagsIn; } - //! Get EFLAGS that the instruction writes. + //! Get EFLAGS that the instruction writes, see \ref X86EFlags. ASMJIT_INLINE uint32_t getEFlagsOut() const { return _eflagsOut; } // -------------------------------------------------------------------------- - // [Accessors - Move-Size] + // [Accessors - Write Index/Size] // -------------------------------------------------------------------------- - //! Get size of move instruction in bytes. - //! - //! See \ref X86InstInfo::getMoveSize() for more details. - ASMJIT_INLINE uint32_t getMoveSize() const { - return _moveSize; + //! Get the destination index of WRITE operation. + ASMJIT_INLINE uint32_t getWriteIndex() const { + return _writeIndex; + } + + //! Get the number of bytes that will be written by a WRITE operation. + ASMJIT_INLINE uint32_t getWriteSize() const { + return _writeSize; } // -------------------------------------------------------------------------- @@ -1954,7 +2127,7 @@ struct X86InstExtendedInfo { // [Accessors - OpCode] // -------------------------------------------------------------------------- - //! Get the secondary instruction opcode, see \ref kX86InstOpCode. + //! Get the secondary instruction opcode, see \ref X86InstOpCodeFlags. //! //! See \ref X86InstInfo::getSecondaryOpCode() for more details. ASMJIT_INLINE uint32_t getSecondaryOpCode() const { @@ -1965,26 +2138,39 @@ struct X86InstExtendedInfo { // [Members] // -------------------------------------------------------------------------- - //! Instruction group. - uint8_t _instGroup; + //! Instruction encoding ID. + uint8_t _encodingId; - //! Count of bytes overwritten by a move instruction. + //! Destination index of WRITE operation, default 0. + uint8_t _writeIndex; + + //! Count of bytes affected by a write operation, needed by analysis for all + //! instructions that do not read the register overwritten. Only used with + //! `kX86InstFlagMove` flag. If `_writeSize` is zero it is automatically + //! deduced from the size of the destination register. //! - //! Only used with `kX86InstFlagMove` flag. If this value is zero move depends - //! on size of the destination register. - uint8_t _moveSize; + //! In general most of SSE write-only instructions should use 16 bytes as + //! this is the size of the register (and of Ymm/Zmm registers). This means + //! that 16-bytes of the register are changed, the rest remains unchanged. + //! However, AVX instructions should use the size of Zmm register as every + //! AVX instruction zeroes the rest of the register (AVX/AVX2 instructions + //! zero the HI part of Zmm if available). + uint8_t _writeSize; //! EFlags read by the instruction. uint8_t _eflagsIn; - //! EFlags modified by the instruction. + //! EFlags written by the instruction. uint8_t _eflagsOut; - //! Instruction flags. - uint16_t _instFlags; + //! \internal + uint8_t _reserved; - //! Operands' flags. + //! Operands' flags, up to 5 operands. uint16_t _opFlags[5]; + //! Instruction flags. + uint32_t _instFlags; + //! Secondary opcode. uint32_t _secondaryOpCode; }; @@ -2026,41 +2212,54 @@ struct X86InstInfo { } // -------------------------------------------------------------------------- - // [Accessors - Group] + // [Accessors - Instruction Encoding] // -------------------------------------------------------------------------- - //! Get instruction group, see \ref kX86InstGroup. - ASMJIT_INLINE uint32_t getInstGroup() const { - return getExtendedInfo().getInstGroup(); + //! Get instruction group, see \ref X86InstEncodingId. + ASMJIT_INLINE uint32_t getEncodingId() const { + return getExtendedInfo().getEncodingId(); } // -------------------------------------------------------------------------- - // [Accessors - Flags] + // [Accessors - Instruction Flags] // -------------------------------------------------------------------------- - //! Get instruction flags, see `kX86InstFlags`. + //! Get instruction flags, see `X86InstFlags`. ASMJIT_INLINE uint32_t getInstFlags() const { return getExtendedInfo().getInstFlags(); } - //! Get whether the instruction has flag `flag`, see `kX86InstFlags`. + //! Get whether the instruction has flag `flag`, see `X86InstFlags`. ASMJIT_INLINE bool hasInstFlag(uint32_t flag) const { return (getInstFlags() & flag) != 0; } // -------------------------------------------------------------------------- - // [Accessors - Move-Size] + // [Accessors - EFlags] // -------------------------------------------------------------------------- - //! Get size of move instruction in bytes. - //! - //! If zero, the size of MOV instruction is determined by the size of the - //! destination register (applies mostly for x86 arithmetic). This value is - //! useful for register allocator when determining if a variable is going to - //! be overwritten or not. Basically if the move size is equal or greater - //! than a variable itself it is considered overwritten. - ASMJIT_INLINE uint32_t getMoveSize() const { - return getExtendedInfo().getMoveSize(); + //! Get EFLAGS that the instruction reads, see \ref X86EFlags. + ASMJIT_INLINE uint32_t getEFlagsIn() const { + return getExtendedInfo().getEFlagsIn(); + } + + //! Get EFLAGS that the instruction writes, see \ref X86EFlags. + ASMJIT_INLINE uint32_t getEFlagsOut() const { + return getExtendedInfo().getEFlagsOut(); + } + + // -------------------------------------------------------------------------- + // [Accessors - Write Index/Size] + // -------------------------------------------------------------------------- + + //! Get the destination index of WRITE operation. + ASMJIT_INLINE uint32_t getWriteIndex() const { + return getExtendedInfo().getWriteIndex(); + } + + //! Get the number of bytes that will be written by a WRITE operation. + ASMJIT_INLINE uint32_t getWriteSize() const { + return getExtendedInfo().getWriteSize(); } // -------------------------------------------------------------------------- @@ -2076,12 +2275,12 @@ struct X86InstInfo { // [Accessors - OpCode] // -------------------------------------------------------------------------- - //! Get the primary instruction opcode, see \ref kX86InstOpCode. + //! Get the primary instruction opcode, see \ref X86InstOpCodeFlags. ASMJIT_INLINE uint32_t getPrimaryOpCode() const { return _primaryOpCode; } - //! Get the secondary instruction opcode, see \ref kX86InstOpCode. + //! Get the secondary instruction opcode, see \ref X86InstOpCodeFlags. ASMJIT_INLINE uint32_t getSecondaryOpCode() const { return getExtendedInfo().getSecondaryOpCode(); } @@ -2141,25 +2340,25 @@ struct X86Util { //! Get the equivalent of negated condition code. static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) { ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_x86ReverseCond)); - return static_cast(cond ^ static_cast(cond < kX86CondNone)); + return cond ^ static_cast(cond < kX86CondNone); } //! Translate condition code `cc` to `cmovcc` instruction code. - //! \sa \ref kX86InstId, \ref _kX86InstIdCmovcc. + //! \sa \ref X86InstId, \ref _kX86InstIdCmovcc. static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) { ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToCmovcc)); return _x86CondToCmovcc[cond]; } //! Translate condition code `cc` to `jcc` instruction code. - //! \sa \ref kX86InstId, \ref _kX86InstIdJcc. + //! \sa \ref X86InstId, \ref _kX86InstIdJcc. static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) { ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToJcc)); return _x86CondToJcc[cond]; } //! Translate condition code `cc` to `setcc` instruction code. - //! \sa \ref kX86InstId, \ref _kX86InstIdSetcc. + //! \sa \ref X86InstId, \ref _kX86InstIdSetcc. static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) { ASMJIT_ASSERT(static_cast(cond) < ASMJIT_ARRAY_SIZE(_x86CondToSetcc)); return _x86CondToSetcc[cond]; @@ -2188,11 +2387,11 @@ struct X86Util { //! \param w Fourth component position, number at interval [0, 3] inclusive. //! //! Shuffle constants can be used to make immediate value for these intrinsics: - //! - `X86Assembler::pshufw()` and `X86Compiler::pshufw()` - //! - `X86Assembler::pshufd()` and `X86Compiler::pshufd()` + //! - `X86Assembler::pshufw()` and `X86Compiler::pshufw()` + //! - `X86Assembler::pshufd()` and `X86Compiler::pshufd()` //! - `X86Assembler::pshufhw()` and `X86Compiler::pshufhw()` //! - `X86Assembler::pshuflw()` and `X86Compiler::pshuflw()` - //! - `X86Assembler::shufps()` and `X86Compiler::shufps()` + //! - `X86Assembler::shufps()` and `X86Compiler::shufps()` static ASMJIT_INLINE int mmShuffle(uint32_t z, uint32_t y, uint32_t x, uint32_t w) { return static_cast((z << 6) | (y << 4) | (x << 2) | w); } diff --git a/libraries/asmjit/x86/x86operand.h b/libraries/asmjit/x86/x86operand.h index f40ab12fa..7d573fd5c 100644 --- a/libraries/asmjit/x86/x86operand.h +++ b/libraries/asmjit/x86/x86operand.h @@ -23,7 +23,7 @@ //! //! Internal macro to get an operand ID casting it to `Operand`. Basically //! allows to get an id of operand that has been just 'typedef'ed. -#define _OP_ID(_Op_) reinterpret_cast(_Op_).getId() +#define ASMJIT_OP_ID(_Op_) reinterpret_cast(_Op_).getId() namespace asmjit { @@ -32,49 +32,70 @@ namespace asmjit { // ============================================================================ struct X86Reg; +struct X86RipReg; +struct X86SegReg; struct X86GpReg; struct X86FpReg; struct X86MmReg; +struct X86KReg; struct X86XmmReg; struct X86YmmReg; -struct X86SegReg; +struct X86ZmmReg; #if !defined(ASMJIT_DISABLE_COMPILER) struct X86Var; struct X86GpVar; struct X86MmVar; +struct X86KVar; struct X86XmmVar; struct X86YmmVar; +struct X86ZmmVar; #endif // !ASMJIT_DISABLE_COMPILER //! \addtogroup asmjit_x86_general //! \{ // ============================================================================ -// [asmjit::kX86RegClass] +// [asmjit::X86RegClass] // ============================================================================ //! X86/X64 variable class. -ASMJIT_ENUM(kX86RegClass) { +ASMJIT_ENUM(X86RegClass) { + // -------------------------------------------------------------------------- + // [Regs & Vars] + // -------------------------------------------------------------------------- + //! X86/X64 Gp register class (compatible with universal \ref kRegClassGp). kX86RegClassGp = kRegClassGp, - //! X86/X64 Fp register class. - kX86RegClassFp = 1, //! X86/X64 Mm register class. - kX86RegClassMm = 2, + kX86RegClassMm = 1, + //! X86/X64 K register class. + kX86RegClassK = 2, //! X86/X64 Xmm/Ymm/Zmm register class. kX86RegClassXyz = 3, + //! \internal + //! + //! Last register class that is managed by `X86Compiler`, used by asserts. + _kX86RegClassManagedCount = 4, + + // -------------------------------------------------------------------------- + // [Regs Only] + // -------------------------------------------------------------------------- + + //! X86/X64 Fp register class. + kX86RegClassFp = 4, + //! Count of X86/X64 register classes. - kX86RegClassCount = 4 + kX86RegClassCount = 5 }; // ============================================================================ -// [asmjit::kX86RegType] +// [asmjit::X86RegType] // ============================================================================ //! X86/X64 register type. -ASMJIT_ENUM(kX86RegType) { +ASMJIT_ENUM(X86RegType) { //! Gpb-lo register (AL, BL, CL, DL, ...). kX86RegTypeGpbLo = 0x01, //! Gpb-hi register (AH, BH, CH, DH only). @@ -89,27 +110,32 @@ ASMJIT_ENUM(kX86RegType) { kX86RegTypeGpw = 0x10, //! Gpd register. kX86RegTypeGpd = 0x20, - //! Gpq register. + //! Gpq register (X64). kX86RegTypeGpq = 0x30, //! Fp register. - kX86RegTypeFp = 0x50, - //! Mm register. - kX86RegTypeMm = 0x60, + kX86RegTypeFp = 0x40, + //! Mm register (MMX+). + kX86RegTypeMm = 0x50, - //! Xmm register. + //! K register (AVX512+). + kX86RegTypeK = 0x60, + + //! Xmm register (SSE+). kX86RegTypeXmm = 0x70, - //! Ymm register. + //! Ymm register (AVX+). kX86RegTypeYmm = 0x80, - //! Zmm register. + //! Zmm register (AVX512+). kX86RegTypeZmm = 0x90, + //! Instruction pointer (RIP). + kX86RegTypeRip = 0xE0, //! Segment register. kX86RegTypeSeg = 0xF0 }; // ============================================================================ -// [asmjit::kX86RegIndex] +// [asmjit::X86RegIndex] // ============================================================================ //! X86/X64 register indexes. @@ -117,7 +143,7 @@ ASMJIT_ENUM(kX86RegType) { //! \note Register indexes have been reduced to only support general purpose //! registers. There is no need to have enumerations with number suffix that //! expands to the exactly same value as the suffix value itself. -ASMJIT_ENUM(kX86RegIndex) { +ASMJIT_ENUM(X86RegIndex) { //! Index of Al/Ah/Ax/Eax/Rax registers. kX86RegIndexAx = 0, //! Index of Cl/Ch/Cx/Ecx/Rcx registers. @@ -153,11 +179,11 @@ ASMJIT_ENUM(kX86RegIndex) { }; // ============================================================================ -// [asmjit::kX86Seg] +// [asmjit::X86Seg] // ============================================================================ //! X86/X64 segment codes. -ASMJIT_ENUM(kX86Seg) { +ASMJIT_ENUM(X86Seg) { //! No/Default segment. kX86SegDefault = 0, //! Es segment. @@ -184,27 +210,29 @@ ASMJIT_ENUM(kX86Seg) { }; // ============================================================================ -// [asmjit::kX86MemVSib] +// [asmjit::X86MemVSib] // ============================================================================ //! X86/X64 index register legacy and AVX2 (VSIB) support. -ASMJIT_ENUM(kX86MemVSib) { - //! Memory operand uses Gp or no index register. +ASMJIT_ENUM(X86MemVSib) { + //! Memory operand uses Gpd/Gpq index (or no index register). kX86MemVSibGpz = 0, - //! Memory operand uses Xmm or no index register. + //! Memory operand uses Xmm index (or no index register). kX86MemVSibXmm = 1, - //! Memory operand uses Ymm or no index register. - kX86MemVSibYmm = 2 + //! Memory operand uses Ymm index (or no index register). + kX86MemVSibYmm = 2, + //! Memory operand uses Zmm index (or no index register). + kX86MemVSibZmm = 3 }; // ============================================================================ -// [asmjit::kX86MemFlags] +// [asmjit::X86MemFlags] // ============================================================================ //! \internal //! //! X86/X64 specific memory flags. -ASMJIT_ENUM(kX86MemFlags) { +ASMJIT_ENUM(X86MemFlags) { kX86MemSegBits = 0x7, kX86MemSegIndex = 0, kX86MemSegMask = kX86MemSegBits << kX86MemSegIndex, @@ -223,7 +251,21 @@ ASMJIT_ENUM(kX86MemFlags) { }; // This is only defined by `x86operand_regs.cpp` when exporting registers. -#if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS) +#if defined(ASMJIT_EXPORTS_X86OPERAND_REGS) + +// Remap all classes to POD structs so they can be statically initialized +// without calling a constructor. Compiler will store these in .DATA section. +struct X86RipReg { Operand::VRegOp data; }; +struct X86SegReg { Operand::VRegOp data; }; +struct X86GpReg { Operand::VRegOp data; }; +struct X86FpReg { Operand::VRegOp data; }; +struct X86KReg { Operand::VRegOp data; }; +struct X86MmReg { Operand::VRegOp data; }; +struct X86XmmReg { Operand::VRegOp data; }; +struct X86YmmReg { Operand::VRegOp data; }; +struct X86ZmmReg { Operand::VRegOp data; }; + +#else // ============================================================================ // [asmjit::X86RegCount] @@ -231,12 +273,29 @@ ASMJIT_ENUM(kX86MemFlags) { //! \internal //! -//! X86/X64 registers count (Gp, Fp, Mm, Xmm). +//! X86/X64 registers count (Gp, Mm, K, Xmm/Ymm/Zmm). +//! +//! Since the number of registers changed across CPU generations `X86RegCount` +//! class is used by `X86Assembler` and `X86Compiler` to provide a way to get +//! number of available registers dynamically. 32-bit mode offers always only +//! 8 registers of all classes, however, 64-bit mode offers 16 Gp registers and +//! 16 Xmm/Ymm/Zmm registers. AVX512 instruction set doubles the number of SIMD +//! registers (Xmm/Ymm/Zmm) to 32, this mode has to be explicitly enabled to +//! take effect as it changes some assumptions. +//! +//! `X86RegCount` is also used extensively by `X86Compiler`'s register allocator +//! and data structures. Fp registers were omitted as they are never mapped to +//! variables, thus, not needed to be managed. +//! +//! \note At the moment `X86RegCount` can fit into 32-bits, having 8-bits for +//! all register classes (except Fp). This can change in the future after a +//! new instruction set is announced. struct X86RegCount { // -------------------------------------------------------------------------- // [Zero] // -------------------------------------------------------------------------- + //! Reset all counters to zero. ASMJIT_INLINE void reset() { _packed = 0; } @@ -245,61 +304,87 @@ struct X86RegCount { // [Get] // -------------------------------------------------------------------------- - ASMJIT_INLINE uint32_t get(uint32_t c) const { - ASMJIT_ASSERT(c < kX86RegClassCount); - return _regs[c]; + //! Get register count by `classId`. + ASMJIT_INLINE uint32_t get(uint32_t classId) const { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + return _regs[classId]; } + //! Get Gp register count. ASMJIT_INLINE uint32_t getGp() const { return _regs[kX86RegClassGp]; } - ASMJIT_INLINE uint32_t getFp() const { return _regs[kX86RegClassFp]; } + //! Get Mm register count. ASMJIT_INLINE uint32_t getMm() const { return _regs[kX86RegClassMm]; } + //! Get K register count. + ASMJIT_INLINE uint32_t getK() const { return _regs[kX86RegClassK]; } + //! Get Xmm/Ymm/Zmm register count. ASMJIT_INLINE uint32_t getXyz() const { return _regs[kX86RegClassXyz]; } // -------------------------------------------------------------------------- // [Set] // -------------------------------------------------------------------------- - ASMJIT_INLINE void set(uint32_t c, uint32_t n) { - ASMJIT_ASSERT(c < kX86RegClassCount); - ASMJIT_ASSERT(n < 0x100); + //! Set register count by `classId`. + ASMJIT_INLINE void set(uint32_t classId, uint32_t n) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + ASMJIT_ASSERT(n <= 0xFF); - _regs[c] = static_cast(n); + _regs[classId] = static_cast(n); } + //! Set Gp register count. ASMJIT_INLINE void setGp(uint32_t n) { set(kX86RegClassGp, n); } - ASMJIT_INLINE void setFp(uint32_t n) { set(kX86RegClassFp, n); } + //! Set Mm register count. ASMJIT_INLINE void setMm(uint32_t n) { set(kX86RegClassMm, n); } + //! Set K register count. + ASMJIT_INLINE void setK(uint32_t n) { set(kX86RegClassK, n); } + //! Set Xmm/Ymm/Zmm register count. ASMJIT_INLINE void setXyz(uint32_t n) { set(kX86RegClassXyz, n); } // -------------------------------------------------------------------------- // [Add] // -------------------------------------------------------------------------- - ASMJIT_INLINE void add(uint32_t c, uint32_t n = 1) { - ASMJIT_ASSERT(c < kX86RegClassCount); - ASMJIT_ASSERT(n < 0x100); + //! Add register count by `classId`. + ASMJIT_INLINE void add(uint32_t classId, uint32_t n = 1) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + ASMJIT_ASSERT(0xFF - static_cast(_regs[classId]) >= n); - _regs[c] += static_cast(n); + _regs[classId] += static_cast(n); } + //! Add Gp register count. ASMJIT_INLINE void addGp(uint32_t n) { add(kX86RegClassGp, n); } - ASMJIT_INLINE void addFp(uint32_t n) { add(kX86RegClassFp, n); } + //! Add Mm register count. ASMJIT_INLINE void addMm(uint32_t n) { add(kX86RegClassMm, n); } + //! Add K register count. + ASMJIT_INLINE void addK(uint32_t n) { add(kX86RegClassK, n); } + //! Add Xmm/Ymm/Zmm register count. ASMJIT_INLINE void addXyz(uint32_t n) { add(kX86RegClassXyz, n); } // -------------------------------------------------------------------------- // [Misc] // -------------------------------------------------------------------------- - ASMJIT_INLINE void makeIndex(const X86RegCount& count) { - uint8_t a = count._regs[0]; - uint8_t b = count._regs[1]; - uint8_t c = count._regs[2]; + //! Build a register indexes, based on register's `count`. + //! + //! Register index is used by \ref `X86Compiler` in per-instruction register + //! data. Indexes are sorted by register class in Gp, Mm, K, and Xmm/Ymm/Zmm + //! order. + ASMJIT_INLINE void indexFromRegCount(const X86RegCount& count) { + uint32_t x = count._regs[0]; + uint32_t y; + + _regs[0] = static_cast(0); + _regs[1] = static_cast(x); + + x = x + count._regs[1]; + y = x + count._regs[2]; - _regs[0] = 0; - _regs[1] = a; - _regs[2] = a + b; - _regs[3] = a + b + c; + ASMJIT_ASSERT(x <= 0xFF); + ASMJIT_ASSERT(y <= 0xFF); + + _regs[2] = static_cast(x); + _regs[3] = static_cast(y); } // -------------------------------------------------------------------------- @@ -308,10 +393,16 @@ struct X86RegCount { union { struct { + //! Count of Gp registers. uint8_t _gp; - uint8_t _fp; + //! Count of Mm registers. uint8_t _mm; - uint8_t _xy; + //! Count of K registers. + uint8_t _k; + //! Count of Xmm/Ymm/Zmm registers. + uint8_t _xyz; + //! \internal + uint8_t _reserved[3]; }; uint8_t _regs[4]; @@ -325,12 +416,13 @@ struct X86RegCount { //! \internal //! -//! X86/X64 registers mask (Gp, Fp, Mm, Xmm/Ymm/Zmm). +//! X86/X64 registers mask (Gp, Mm, K, Xmm/Ymm/Zmm). struct X86RegMask { // -------------------------------------------------------------------------- // [Reset] // -------------------------------------------------------------------------- + //! Reset all register masks to zero. ASMJIT_INLINE void reset() { _packed.reset(); } @@ -339,135 +431,189 @@ struct X86RegMask { // [IsEmpty / Has] // -------------------------------------------------------------------------- + //! Get whether all register masks are zero (empty). ASMJIT_INLINE bool isEmpty() const { return _packed.isZero(); } - ASMJIT_INLINE bool has(uint32_t c, uint32_t mask = 0xFFFFFFFF) const { - switch (c) { + ASMJIT_INLINE bool has(uint32_t classId, uint32_t mask = 0xFFFFFFFF) const { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { case kX86RegClassGp : return (static_cast(_gp ) & mask) != 0; - case kX86RegClassFp : return (static_cast(_fp ) & mask) != 0; case kX86RegClassMm : return (static_cast(_mm ) & mask) != 0; + case kX86RegClassK : return (static_cast(_k ) & mask) != 0; case kX86RegClassXyz: return (static_cast(_xyz) & mask) != 0; } - ASMJIT_ASSERT(!"Reached"); return false; } - // -------------------------------------------------------------------------- - // [Zero] - // -------------------------------------------------------------------------- - - ASMJIT_INLINE void zero(uint32_t c) { - switch (c) { - case kX86RegClassGp : _gp = 0; break; - case kX86RegClassFp : _fp = 0; break; - case kX86RegClassMm : _mm = 0; break; - case kX86RegClassXyz: _xyz = 0; break; - } - } + ASMJIT_INLINE bool hasGp(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassGp, mask); } + ASMJIT_INLINE bool hasMm(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassMm, mask); } + ASMJIT_INLINE bool hasK(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassK, mask); } + ASMJIT_INLINE bool hasXyz(uint32_t mask = 0xFFFFFFFF) const { return has(kX86RegClassXyz, mask); } // -------------------------------------------------------------------------- // [Get] // -------------------------------------------------------------------------- - ASMJIT_INLINE uint32_t get(uint32_t c) const { - switch (c) { + ASMJIT_INLINE uint32_t get(uint32_t classId) const { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { case kX86RegClassGp : return _gp; - case kX86RegClassFp : return _fp; case kX86RegClassMm : return _mm; + case kX86RegClassK : return _k; case kX86RegClassXyz: return _xyz; } - ASMJIT_ASSERT(!"Reached"); return 0; } + ASMJIT_INLINE uint32_t getGp() const { return get(kX86RegClassGp); } + ASMJIT_INLINE uint32_t getMm() const { return get(kX86RegClassMm); } + ASMJIT_INLINE uint32_t getK() const { return get(kX86RegClassK); } + ASMJIT_INLINE uint32_t getXyz() const { return get(kX86RegClassXyz); } + + // -------------------------------------------------------------------------- + // [Zero] + // -------------------------------------------------------------------------- + + ASMJIT_INLINE void zero(uint32_t classId) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : _gp = 0; break; + case kX86RegClassMm : _mm = 0; break; + case kX86RegClassK : _k = 0; break; + case kX86RegClassXyz: _xyz = 0; break; + } + } + + ASMJIT_INLINE void zeroGp() { zero(kX86RegClassGp); } + ASMJIT_INLINE void zeroMm() { zero(kX86RegClassMm); } + ASMJIT_INLINE void zeroK() { zero(kX86RegClassK); } + ASMJIT_INLINE void zeroXyz() { zero(kX86RegClassXyz); } + // -------------------------------------------------------------------------- // [Set] // -------------------------------------------------------------------------- - ASMJIT_INLINE void set(uint32_t c, uint32_t mask) { - switch (c) { + ASMJIT_INLINE void set(const X86RegMask& other) { + _packed = other._packed; + } + + ASMJIT_INLINE void set(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { case kX86RegClassGp : _gp = static_cast(mask); break; - case kX86RegClassFp : _fp = static_cast(mask); break; case kX86RegClassMm : _mm = static_cast(mask); break; + case kX86RegClassK : _k = static_cast(mask); break; case kX86RegClassXyz: _xyz = static_cast(mask); break; } } - ASMJIT_INLINE void set(const X86RegMask& other) { - _packed.setUInt64(other._packed); - } + ASMJIT_INLINE void setGp(uint32_t mask) { return set(kX86RegClassGp, mask); } + ASMJIT_INLINE void setMm(uint32_t mask) { return set(kX86RegClassMm, mask); } + ASMJIT_INLINE void setK(uint32_t mask) { return set(kX86RegClassK, mask); } + ASMJIT_INLINE void setXyz(uint32_t mask) { return set(kX86RegClassXyz, mask); } // -------------------------------------------------------------------------- - // [Add] + // [And] // -------------------------------------------------------------------------- - ASMJIT_INLINE void add(uint32_t c, uint32_t mask) { - switch (c) { - case kX86RegClassGp : _gp |= static_cast(mask); break; - case kX86RegClassFp : _fp |= static_cast(mask); break; - case kX86RegClassMm : _mm |= static_cast(mask); break; - case kX86RegClassXyz: _xyz |= static_cast(mask); break; - } + ASMJIT_INLINE void and_(const X86RegMask& other) { + _packed.and_(other._packed); } - ASMJIT_INLINE void add(const X86RegMask& other) { - _packed.or_(other._packed); + ASMJIT_INLINE void and_(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { + case kX86RegClassGp : _gp &= static_cast(mask); break; + case kX86RegClassMm : _mm &= static_cast(mask); break; + case kX86RegClassK : _k &= static_cast(mask); break; + case kX86RegClassXyz: _xyz &= static_cast(mask); break; + } } + ASMJIT_INLINE void andGp(uint32_t mask) { and_(kX86RegClassGp, mask); } + ASMJIT_INLINE void andMm(uint32_t mask) { and_(kX86RegClassMm, mask); } + ASMJIT_INLINE void andK(uint32_t mask) { and_(kX86RegClassK, mask); } + ASMJIT_INLINE void andXyz(uint32_t mask) { and_(kX86RegClassXyz, mask); } + // -------------------------------------------------------------------------- - // [Del] + // [AndNot] // -------------------------------------------------------------------------- - ASMJIT_INLINE void del(uint32_t c, uint32_t mask) { - switch (c) { + ASMJIT_INLINE void andNot(const X86RegMask& other) { + _packed.andNot(other._packed); + } + + ASMJIT_INLINE void andNot(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { case kX86RegClassGp : _gp &= ~static_cast(mask); break; - case kX86RegClassFp : _fp &= ~static_cast(mask); break; case kX86RegClassMm : _mm &= ~static_cast(mask); break; + case kX86RegClassK : _k &= ~static_cast(mask); break; case kX86RegClassXyz: _xyz &= ~static_cast(mask); break; } } - ASMJIT_INLINE void del(const X86RegMask& other) { - _packed.del(other._packed); - } + ASMJIT_INLINE void andNotGp(uint32_t mask) { andNot(kX86RegClassGp, mask); } + ASMJIT_INLINE void andNotMm(uint32_t mask) { andNot(kX86RegClassMm, mask); } + ASMJIT_INLINE void andNotK(uint32_t mask) { andNot(kX86RegClassK, mask); } + ASMJIT_INLINE void andNotXyz(uint32_t mask) { andNot(kX86RegClassXyz, mask); } // -------------------------------------------------------------------------- - // [And] + // [Or] // -------------------------------------------------------------------------- - ASMJIT_INLINE void and_(uint32_t c, uint32_t mask) { - switch (c) { - case kX86RegClassGp : _gp &= static_cast(mask); break; - case kX86RegClassFp : _fp &= static_cast(mask); break; - case kX86RegClassMm : _mm &= static_cast(mask); break; - case kX86RegClassXyz: _xyz &= static_cast(mask); break; - } + ASMJIT_INLINE void or_(const X86RegMask& other) { + _packed.or_(other._packed); } - ASMJIT_INLINE void and_(const X86RegMask& other) { - _packed.and_(other._packed); + ASMJIT_INLINE void or_(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + switch (classId) { + case kX86RegClassGp : _gp |= static_cast(mask); break; + case kX86RegClassMm : _mm |= static_cast(mask); break; + case kX86RegClassK : _k |= static_cast(mask); break; + case kX86RegClassXyz: _xyz |= static_cast(mask); break; + } } + ASMJIT_INLINE void orGp(uint32_t mask) { return or_(kX86RegClassGp, mask); } + ASMJIT_INLINE void orMm(uint32_t mask) { return or_(kX86RegClassMm, mask); } + ASMJIT_INLINE void orK(uint32_t mask) { return or_(kX86RegClassK, mask); } + ASMJIT_INLINE void orXyz(uint32_t mask) { return or_(kX86RegClassXyz, mask); } + // -------------------------------------------------------------------------- // [Xor] // -------------------------------------------------------------------------- - ASMJIT_INLINE void xor_(uint32_t c, uint32_t mask) { - switch (c) { + ASMJIT_INLINE void xor_(const X86RegMask& other) { + _packed.xor_(other._packed); + } + + ASMJIT_INLINE void xor_(uint32_t classId, uint32_t mask) { + ASMJIT_ASSERT(classId < _kX86RegClassManagedCount); + + switch (classId) { case kX86RegClassGp : _gp ^= static_cast(mask); break; - case kX86RegClassFp : _fp ^= static_cast(mask); break; case kX86RegClassMm : _mm ^= static_cast(mask); break; + case kX86RegClassK : _k ^= static_cast(mask); break; case kX86RegClassXyz: _xyz ^= static_cast(mask); break; } } - ASMJIT_INLINE void xor_(const X86RegMask& other) { - _packed.xor_(other._packed); - } + ASMJIT_INLINE void xorGp(uint32_t mask) { xor_(kX86RegClassGp, mask); } + ASMJIT_INLINE void xorMm(uint32_t mask) { xor_(kX86RegClassMm, mask); } + ASMJIT_INLINE void xorK(uint32_t mask) { xor_(kX86RegClassK, mask); } + ASMJIT_INLINE void xorXyz(uint32_t mask) { xor_(kX86RegClassXyz, mask); } // -------------------------------------------------------------------------- // [Members] @@ -475,17 +621,17 @@ struct X86RegMask { union { struct { - //! Gp mask (16-bit). + //! Gp registers mask (16 bits). uint16_t _gp; - //! Fp mask (8-bit). - uint8_t _fp; - //! Mm mask (8-bit). + //! Mm registers mask (8 bits). uint8_t _mm; - //! Xmm/Ymm/Zmm mask (32-bit). + //! K registers mask (8 bits). + uint8_t _k; + //! Xmm/Ymm/Zmm registers mask (32 bits). uint32_t _xyz; }; - //! All masks as 64-bit integer. + //! Packed masks. UInt64 _packed; }; }; @@ -494,7 +640,7 @@ struct X86RegMask { // [asmjit::X86Reg] // ============================================================================ -//! Base class for all X86 registers. +//! X86/X86 register base class. struct X86Reg : public Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] @@ -520,7 +666,7 @@ struct X86Reg : public Reg { //! Get whether the register is Gp register. ASMJIT_INLINE bool isGp() const { return _vreg.type <= kX86RegTypeGpq; } //! Get whether the register is Gp byte (8-bit) register. - ASMJIT_INLINE bool isGpb() const { return _vreg.type <= kX86RegTypeGpbHi; } + ASMJIT_INLINE bool isGpb() const { return _vreg.type <= _kX86RegTypePatchedGpbHi; } //! Get whether the register is Gp lo-byte (8-bit) register. ASMJIT_INLINE bool isGpbLo() const { return _vreg.type == kX86RegTypeGpbLo; } //! Get whether the register is Gp hi-byte (8-bit) register. @@ -536,6 +682,10 @@ struct X86Reg : public Reg { ASMJIT_INLINE bool isFp() const { return _vreg.type == kX86RegTypeFp; } //! Get whether the register is Mm (64-bit) register. ASMJIT_INLINE bool isMm() const { return _vreg.type == kX86RegTypeMm; } + + //! Get whether the register is K (64-bit) register. + ASMJIT_INLINE bool isK() const { return _vreg.type == kX86RegTypeK; } + //! Get whether the register is Xmm (128-bit) register. ASMJIT_INLINE bool isXmm() const { return _vreg.type == kX86RegTypeXmm; } //! Get whether the register is Ymm (256-bit) register. @@ -543,7 +693,9 @@ struct X86Reg : public Reg { //! Get whether the register is Zmm (512-bit) register. ASMJIT_INLINE bool isZmm() const { return _vreg.type == kX86RegTypeZmm; } - //! Get whether the register is a segment. + //! Get whether the register is RIP. + ASMJIT_INLINE bool isRip() const { return _vreg.type == kX86RegTypeRip; } + //! Get whether the register is Segment. ASMJIT_INLINE bool isSeg() const { return _vreg.type == kX86RegTypeSeg; } // -------------------------------------------------------------------------- @@ -559,6 +711,58 @@ struct X86Reg : public Reg { } }; +// ============================================================================ +// [asmjit::X86RipReg] +// ============================================================================ + +//! X86/X64 RIP register. +struct X86RipReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a RIP register. + ASMJIT_INLINE X86RipReg() : X86Reg(kX86RegTypeRip, 0, 0) {} + //! Create a reference to `other` RIP register. + ASMJIT_INLINE X86RipReg(const X86RipReg& other) : X86Reg(other) {} + //! Create non-initialized RIP register. + explicit ASMJIT_INLINE X86RipReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86RipReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86RipReg) +}; + +// ============================================================================ +// [asmjit::X86SegReg] +// ============================================================================ + +//! X86/X64 segment register. +struct X86SegReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy segment register. + ASMJIT_INLINE X86SegReg() : X86Reg() {} + //! Create a reference to `other` segment register. + ASMJIT_INLINE X86SegReg(const X86SegReg& other) : X86Reg(other) {} + //! Create a reference to `other` segment register and change the index to `index`. + ASMJIT_INLINE X86SegReg(const X86SegReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom segment register. + ASMJIT_INLINE X86SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized segment register. + explicit ASMJIT_INLINE X86SegReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86SegReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86SegReg) +}; + // ============================================================================ // [asmjit::X86GpReg] // ============================================================================ @@ -585,6 +789,24 @@ struct X86GpReg : public X86Reg { // -------------------------------------------------------------------------- ASMJIT_REG_OP(X86GpReg) + + // -------------------------------------------------------------------------- + // [X86GpReg Cast] + // -------------------------------------------------------------------------- + + //! Cast this register to 8-bit (LO) part. + ASMJIT_INLINE X86GpReg r8() const { return X86GpReg(kX86RegTypeGpbLo, getRegIndex(), 1); } + //! Cast this register to 8-bit (LO) part. + ASMJIT_INLINE X86GpReg r8Lo() const { return X86GpReg(kX86RegTypeGpbLo, getRegIndex(), 1); } + //! Cast this register to 8-bit (HI) part. + ASMJIT_INLINE X86GpReg r8Hi() const { return X86GpReg(kX86RegTypeGpbHi, getRegIndex(), 1); } + + //! Cast this register to 16-bit. + ASMJIT_INLINE X86GpReg r16() const { return X86GpReg(kX86RegTypeGpw, getRegIndex(), 2); } + //! Cast this register to 32-bit. + ASMJIT_INLINE X86GpReg r32() const { return X86GpReg(kX86RegTypeGpd, getRegIndex(), 4); } + //! Cast this register to 64-bit. + ASMJIT_INLINE X86GpReg r64() const { return X86GpReg(kX86RegTypeGpq, getRegIndex(), 8); } }; // ============================================================================ @@ -619,7 +841,32 @@ struct X86FpReg : public X86Reg { // [asmjit::X86MmReg] // ============================================================================ -//! X86/X64 64-bit Mm register. +//! X86/X64 64-bit Mm register (MMX+). +//! +//! Structure of MMX register and it's memory mapping: +//! +//! ~~~ +//! Memory Bytes +//! +--+--+--+--+--+--+--+--+ +//! |00|01|02|03|04|05|06|07| +//! +--+--+--+--+--+--+--+--+ +//! +//! MMX Register +//! +-----------------------+ +//! | QWord | +//! +-----------+-----------+ +//! | HI-DWord | LO-DWord | +//! +-----------+-----------+ +//! | W3 | W2 | W1 | W0 | +//! +--+--+--+--+--+--+--+--+ +//! |07|06|05|04|03|02|01|00| +//! +--+--+--+--+--+--+--+--+ +//! ~~~ +//! +//! Move instruction semantics: +//! +//! - `movd` - writes 4-bytes in `LO-DWord` and zeroes `HI-DWord`. +//! - `movq` - writes 8-bytes in `QWord`. struct X86MmReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] @@ -643,11 +890,92 @@ struct X86MmReg : public X86Reg { ASMJIT_REG_OP(X86MmReg) }; +// ============================================================================ +// [asmjit::X86KReg] +// ============================================================================ + +//! X86/X64 64-bit K register (AVX512+). +struct X86KReg : public X86Reg { + // -------------------------------------------------------------------------- + // [Construction / Destruction] + // -------------------------------------------------------------------------- + + //! Create a dummy K register. + ASMJIT_INLINE X86KReg() : X86Reg() {} + //! Create a reference to `other` K register. + ASMJIT_INLINE X86KReg(const X86KReg& other) : X86Reg(other) {} + //! Create a reference to `other` K register and change the index to `index`. + ASMJIT_INLINE X86KReg(const X86KReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom K register. + ASMJIT_INLINE X86KReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized K register. + explicit ASMJIT_INLINE X86KReg(const _NoInit&) : X86Reg(NoInit) {} + + // -------------------------------------------------------------------------- + // [X86KReg Specific] + // -------------------------------------------------------------------------- + + ASMJIT_REG_OP(X86KReg) +}; + // ============================================================================ // [asmjit::X86XmmReg] // ============================================================================ -//! X86/X64 128-bit Xmm register. +//! X86/X64 128-bit Xmm register (SSE+). +//! +//! Structure of XMM register and it's memory mapping: +//! +//! ~~~ +//! Memory Bytes +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! +//! XMM Register +//! +-----------------------------------------------+ +//! | OWord | +//! +-----------------------+-----------------------+ +//! | HI-QWord/PD | LO-QWord/SD | +//! +-----------+-----------+-----------+-----------+ +//! | D3/PS | D2/PS | D1/PS | D0/SS | +//! +-----------+-----------+-----------+-----------+ +//! | W7 | W6 | W5 | W4 | W3 | W2 | W1 | W0 | +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! ~~~ +//! +//! Move instruction semantics: +//! +//! - `movd` - writes 4-bytes in `D0` and zeroes the rest. +//! - `movq` - writes 8-bytes in `Lo-QWord` and zeroes the rest. +//! - `movq2dq` - writes 8 bytes in `Lo-QWord` and zeroes the rest. +//! +//! - `movss` - writes 4-bytes in `D0` +//! (the rest is zeroed only if the source operand is a memory location). +//! - `movsd` - writes 8-bytes in `Lo-QWord` +//! (the rest is zeroed only if the source operand is a memory location). +//! +//! - `movaps`, +//! `movups`, +//! `movapd`, +//! `movupd`, +//! `movdqu`, +//! `movdqa`, +//! `lddqu` - writes 16-bytes in `OWord`. +//! +//! - `movlps`, +//! `movlpd`, +//! `movhlps` - writes 8-bytes in `Lo-QWord` and keeps the rest untouched. +//! +//! - `movhps`, +//! `movhpd`, +//! `movlhps` - writes 8-bytes in `Hi-QWord` and keeps the rest untouched. +//! +//! - `movddup`, +//! - `movsldup`, +//! - `movshdup` - writes 16 bytes in `OWord`. struct X86XmmReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] @@ -669,13 +997,46 @@ struct X86XmmReg : public X86Reg { // -------------------------------------------------------------------------- ASMJIT_REG_OP(X86XmmReg) + + // -------------------------------------------------------------------------- + // [X86XmmReg Cast] + // -------------------------------------------------------------------------- + + //! Cast this register to Xmm (clone). + ASMJIT_INLINE X86XmmReg xmm() const { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); } + //! Cast this register to Ymm. + ASMJIT_INLINE X86YmmReg ymm() const; + //! Cast this register to Zmm. + ASMJIT_INLINE X86ZmmReg zmm() const; }; // ============================================================================ // [asmjit::X86YmmReg] // ============================================================================ -//! X86/X64 256-bit Ymm register. +//! X86/X64 256-bit Ymm register (AVX+). +//! +//! Structure of YMM register and it's memory mapping: +//! +//! ~~~ +//! Memory Bytes +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! +//! YMM Register +//! +-----------------------------------------------+-----------------------------------------------+ +//! | HI-DQWord | LO-DQWord | +//! +-----------------------+-----------------------+-----------------------+-----------------------+ +//! | Q3/PD | Q2/PD | Q1/PD | Q0/SD | +//! +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+ +//! | D7/PS | D6/PS | D5/PS | D4/PS | D3/PS | D2/PS | D1/PS | D0/SS | +//! +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+ +//! | W15 | W14 | W13 | W12 | W11 | W10 | W9 | W8 | W7 | W6 | W5 | W4 | W3 | W2 | W1 | W0 | +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| +//! +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +//! ~~~ struct X86YmmReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] @@ -683,7 +1044,7 @@ struct X86YmmReg : public X86Reg { //! Create a dummy Ymm register. ASMJIT_INLINE X86YmmReg() : X86Reg() {} - //! Create a reference to `other` Xmm register. + //! Create a reference to `other` Ymm register. ASMJIT_INLINE X86YmmReg(const X86YmmReg& other) : X86Reg(other) {} //! Create a reference to `other` Ymm register and change the index to `index`. ASMJIT_INLINE X86YmmReg(const X86YmmReg& other, uint32_t index) : X86Reg(other, index) {} @@ -697,36 +1058,63 @@ struct X86YmmReg : public X86Reg { // -------------------------------------------------------------------------- ASMJIT_REG_OP(X86YmmReg) + + // -------------------------------------------------------------------------- + // [X86YmmReg Cast] + // -------------------------------------------------------------------------- + + //! Cast this register to Xmm. + ASMJIT_INLINE X86XmmReg xmm() const { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); } + //! Cast this register to Ymm (clone). + ASMJIT_INLINE X86YmmReg ymm() const { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); } + //! Cast this register to Zmm. + ASMJIT_INLINE X86ZmmReg zmm() const; }; +ASMJIT_INLINE X86YmmReg X86XmmReg::ymm() const { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); } + // ============================================================================ -// [asmjit::X86SegReg] +// [asmjit::X86ZmmReg] // ============================================================================ -//! X86/X64 segment register. -struct X86SegReg : public X86Reg { +//! X86/X64 512-bit Zmm register (AVX512+). +struct X86ZmmReg : public X86Reg { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- - //! Create a dummy segment register. - ASMJIT_INLINE X86SegReg() : X86Reg() {} - //! Create a reference to `other` segment register. - ASMJIT_INLINE X86SegReg(const X86SegReg& other) : X86Reg(other) {} - //! Create a reference to `other` segment register and change the index to `index`. - ASMJIT_INLINE X86SegReg(const X86SegReg& other, uint32_t index) : X86Reg(other, index) {} - //! Create a custom segment register. - ASMJIT_INLINE X86SegReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} - //! Create non-initialized segment register. - explicit ASMJIT_INLINE X86SegReg(const _NoInit&) : X86Reg(NoInit) {} + //! Create a dummy Zmm register. + ASMJIT_INLINE X86ZmmReg() : X86Reg() {} + //! Create a reference to `other` Zmm register. + ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other) : X86Reg(other) {} + //! Create a reference to `other` Zmm register and change the index to `index`. + ASMJIT_INLINE X86ZmmReg(const X86ZmmReg& other, uint32_t index) : X86Reg(other, index) {} + //! Create a custom Zmm register. + ASMJIT_INLINE X86ZmmReg(uint32_t type, uint32_t index, uint32_t size) : X86Reg(type, index, size) {} + //! Create non-initialized Zmm register. + explicit ASMJIT_INLINE X86ZmmReg(const _NoInit&) : X86Reg(NoInit) {} // -------------------------------------------------------------------------- - // [X86SegReg Specific] + // [X86ZmmReg Specific] // -------------------------------------------------------------------------- - ASMJIT_REG_OP(X86SegReg) + ASMJIT_REG_OP(X86ZmmReg) + + // -------------------------------------------------------------------------- + // [X86ZmmReg Cast] + // -------------------------------------------------------------------------- + + //! Cast this register to Xmm. + ASMJIT_INLINE X86XmmReg xmm() const { return X86XmmReg(kX86RegTypeXmm, getRegIndex(), 16); } + //! Cast this register to Ymm. + ASMJIT_INLINE X86YmmReg ymm() const { return X86YmmReg(kX86RegTypeYmm, getRegIndex(), 32); } + //! Cast this register to Zmm (clone). + ASMJIT_INLINE X86ZmmReg zmm() const { return X86ZmmReg(kX86RegTypeZmm, getRegIndex(), 64); } }; +ASMJIT_INLINE X86ZmmReg X86XmmReg::zmm() const { return X86ZmmReg(kX86RegTypeZmm, getRegIndex(), 64); } +ASMJIT_INLINE X86ZmmReg X86YmmReg::zmm() const { return X86ZmmReg(kX86RegTypeZmm, getRegIndex(), 64); } + // ============================================================================ // [asmjit::X86Mem] // ============================================================================ @@ -807,7 +1195,7 @@ struct X86Mem : public BaseMem { (kX86MemVSibGpz << kX86MemVSibIndex) + (shift << kX86MemShiftIndex), label.getId()); - _vmem.index = _OP_ID(index); + _vmem.index = ASMJIT_OP_ID(index); _vmem.displacement = disp; } @@ -815,7 +1203,7 @@ struct X86Mem : public BaseMem { _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, _getGpdFlags(reinterpret_cast(base)) + (kX86MemVSibGpz << kX86MemVSibIndex), - _OP_ID(base)); + ASMJIT_OP_ID(base)); _init_packed_d2_d3(kInvalidValue, disp); } @@ -825,8 +1213,8 @@ struct X86Mem : public BaseMem { _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex, _getGpdFlags(reinterpret_cast(base)) + (shift << kX86MemShiftIndex), - _OP_ID(base)); - _vmem.index = _OP_ID(index); + ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); _vmem.displacement = disp; } @@ -837,8 +1225,8 @@ struct X86Mem : public BaseMem { _getGpdFlags(reinterpret_cast(base)) + (kX86MemVSibXmm << kX86MemVSibIndex) + (shift << kX86MemShiftIndex), - _OP_ID(base)); - _vmem.index = _OP_ID(index); + ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); _vmem.displacement = disp; } @@ -849,13 +1237,13 @@ struct X86Mem : public BaseMem { _getGpdFlags(reinterpret_cast(base)) + (kX86MemVSibYmm << kX86MemVSibIndex) + (shift << kX86MemShiftIndex), - _OP_ID(base)); - _vmem.index = _OP_ID(index); + ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); _vmem.displacement = disp; } ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, int32_t disp, uint32_t size) : BaseMem(NoInit) { - _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, _OP_ID(base)); + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, 0, ASMJIT_OP_ID(base)); _vmem.index = kInvalidValue; _vmem.displacement = disp; } @@ -863,8 +1251,8 @@ struct X86Mem : public BaseMem { ASMJIT_INLINE X86Mem(const _Init&, uint32_t memType, const X86Var& base, const X86GpVar& index, uint32_t shift, int32_t disp, uint32_t size) : BaseMem(NoInit) { ASMJIT_ASSERT(shift <= 3); - _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, shift << kX86MemShiftIndex, _OP_ID(base)); - _vmem.index = _OP_ID(index); + _init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, memType, shift << kX86MemShiftIndex, ASMJIT_OP_ID(base)); + _vmem.index = ASMJIT_OP_ID(index); _vmem.displacement = disp; } #endif // !ASMJIT_DISABLE_COMPILER @@ -903,19 +1291,19 @@ struct X86Mem : public BaseMem { return (_vmem.flags & kX86MemSegMask) != (kX86SegDefault << kX86MemSegIndex); } - //! Get memory operand segment, see `kX86Seg`. + //! Get memory operand segment, see `X86Seg`. ASMJIT_INLINE uint32_t getSegment() const { return (static_cast(_vmem.flags) >> kX86MemSegIndex) & kX86MemSegBits; } - //! Set memory operand segment, see `kX86Seg`. + //! Set memory operand segment, see `X86Seg`. ASMJIT_INLINE X86Mem& setSegment(uint32_t segIndex) { _vmem.flags = static_cast( (static_cast(_vmem.flags) & kX86MemSegMask) + (segIndex << kX86MemSegIndex)); return *this; } - //! Set memory operand segment, see `kX86Seg`. + //! Set memory operand segment, see `X86Seg`. ASMJIT_INLINE X86Mem& setSegment(const X86SegReg& seg) { return setSegment(seg.getRegIndex()); } @@ -946,12 +1334,12 @@ struct X86Mem : public BaseMem { // [VSib] // -------------------------------------------------------------------------- - //! Get SIB type. + //! Get V-SIB type. ASMJIT_INLINE uint32_t getVSib() const { return (static_cast(_vmem.flags) >> kX86MemVSibIndex) & kX86MemVSibBits; } - //! Set SIB type. + //! Set V-SIB type. ASMJIT_INLINE X86Mem& _setVSib(uint32_t vsib) { _packed[0].u32[0] &=~IntUtil::pack32_4x8(0x00, 0x00, 0x00, kX86MemVSibMask); _packed[0].u32[0] |= IntUtil::pack32_4x8(0x00, 0x00, 0x00, vsib << kX86MemVSibIndex); @@ -1047,38 +1435,38 @@ struct X86Mem : public BaseMem { #if !defined(ASMJIT_DISABLE_COMPILER) //! Set memory index. ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index) { - _vmem.index = _OP_ID(index); + _vmem.index = ASMJIT_OP_ID(index); return _setVSib(kX86MemVSibGpz); } //! Set memory index. ASMJIT_INLINE X86Mem& setIndex(const X86GpVar& index, uint32_t shift) { - _vmem.index = _OP_ID(index); + _vmem.index = ASMJIT_OP_ID(index); return _setVSib(kX86MemVSibGpz).setShift(shift); } //! Set memory index. ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index) { - _vmem.index = _OP_ID(index); + _vmem.index = ASMJIT_OP_ID(index); return _setVSib(kX86MemVSibXmm); } //! Set memory index. ASMJIT_INLINE X86Mem& setIndex(const X86XmmVar& index, uint32_t shift) { - _vmem.index = _OP_ID(index); + _vmem.index = ASMJIT_OP_ID(index); return _setVSib(kX86MemVSibXmm).setShift(shift); } //! Set memory index. ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index) { - _vmem.index = _OP_ID(index); + _vmem.index = ASMJIT_OP_ID(index); return _setVSib(kX86MemVSibYmm); } //! Set memory index. ASMJIT_INLINE X86Mem& setIndex(const X86YmmVar& index, uint32_t shift) { - _vmem.index = _OP_ID(index); + _vmem.index = ASMJIT_OP_ID(index); return _setVSib(kX86MemVSibYmm).setShift(shift); } #endif // !ASMJIT_DISABLE_COMPILER @@ -1183,7 +1571,35 @@ struct X86Mem : public BaseMem { return (base._vreg.size & 0x4) << (kX86MemGpdIndex - 2); } }; -#endif // !ASMJIT_EXPORTS_X86OPERAND_REGS +#endif // ASMJIT_EXPORTS_X86OPERAND_REGS + +// ============================================================================ +// [asmjit::X86RegData] +// ============================================================================ + +struct X86RegData { + X86RipReg rip; + X86GpReg noGp; + + X86SegReg seg[7]; + + X86GpReg gpbLo[16]; + X86GpReg gpbHi[4]; + + X86GpReg gpw[16]; + X86GpReg gpd[16]; + X86GpReg gpq[16]; + + X86FpReg fp[8]; + X86MmReg mm[8]; + X86KReg k[8]; + + X86XmmReg xmm[32]; + X86YmmReg ymm[32]; + X86ZmmReg zmm[32]; +}; + +ASMJIT_VAR const X86RegData x86RegData; // ============================================================================ // [asmjit::x86] @@ -1195,140 +1611,218 @@ namespace x86 { // [asmjit::x86 - Reg] // ============================================================================ -//! No Gp register, can be used only within `X86Mem` operand. -ASMJIT_VAR const X86GpReg noGpReg; - -ASMJIT_VAR const X86GpReg al; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const X86GpReg cl; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const X86GpReg dl; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const X86GpReg bl; //!< 8-bit Gpb-lo register. -ASMJIT_VAR const X86GpReg spl; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg bpl; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg sil; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg dil; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r8b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r9b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r10b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r11b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r12b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r13b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r14b; //!< 8-bit Gpb-lo register (X64). -ASMJIT_VAR const X86GpReg r15b; //!< 8-bit Gpb-lo register (X64). - -ASMJIT_VAR const X86GpReg ah; //!< 8-bit Gpb-hi register. -ASMJIT_VAR const X86GpReg ch; //!< 8-bit Gpb-hi register. -ASMJIT_VAR const X86GpReg dh; //!< 8-bit Gpb-hi register. -ASMJIT_VAR const X86GpReg bh; //!< 8-bit Gpb-hi register. - -ASMJIT_VAR const X86GpReg ax; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg cx; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg dx; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg bx; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg sp; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg bp; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg si; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg di; //!< 16-bit Gpw register. -ASMJIT_VAR const X86GpReg r8w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const X86GpReg r9w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const X86GpReg r10w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const X86GpReg r11w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const X86GpReg r12w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const X86GpReg r13w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const X86GpReg r14w; //!< 16-bit Gpw register (X64). -ASMJIT_VAR const X86GpReg r15w; //!< 16-bit Gpw register (X64). - -ASMJIT_VAR const X86GpReg eax; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg ecx; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg edx; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg ebx; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg esp; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg ebp; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg esi; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg edi; //!< 32-bit Gpd register. -ASMJIT_VAR const X86GpReg r8d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const X86GpReg r9d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const X86GpReg r10d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const X86GpReg r11d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const X86GpReg r12d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const X86GpReg r13d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const X86GpReg r14d; //!< 32-bit Gpd register (X64). -ASMJIT_VAR const X86GpReg r15d; //!< 32-bit Gpd register (X64). - -ASMJIT_VAR const X86GpReg rax; //!< 64-bit Gpq register (X64). -ASMJIT_VAR const X86GpReg rcx; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg rdx; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg rbx; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg rsp; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg rbp; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg rsi; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg rdi; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r8; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r9; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r10; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r11; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r12; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r13; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r14; //!< 64-bit Gpq register (X64) -ASMJIT_VAR const X86GpReg r15; //!< 64-bit Gpq register (X64) - -ASMJIT_VAR const X86FpReg fp0; //!< 80-bit Fp register. -ASMJIT_VAR const X86FpReg fp1; //!< 80-bit Fp register. -ASMJIT_VAR const X86FpReg fp2; //!< 80-bit Fp register. -ASMJIT_VAR const X86FpReg fp3; //!< 80-bit Fp register. -ASMJIT_VAR const X86FpReg fp4; //!< 80-bit Fp register. -ASMJIT_VAR const X86FpReg fp5; //!< 80-bit Fp register. -ASMJIT_VAR const X86FpReg fp6; //!< 80-bit Fp register. -ASMJIT_VAR const X86FpReg fp7; //!< 80-bit Fp register. - -ASMJIT_VAR const X86MmReg mm0; //!< 64-bit Mm register. -ASMJIT_VAR const X86MmReg mm1; //!< 64-bit Mm register. -ASMJIT_VAR const X86MmReg mm2; //!< 64-bit Mm register. -ASMJIT_VAR const X86MmReg mm3; //!< 64-bit Mm register. -ASMJIT_VAR const X86MmReg mm4; //!< 64-bit Mm register. -ASMJIT_VAR const X86MmReg mm5; //!< 64-bit Mm register. -ASMJIT_VAR const X86MmReg mm6; //!< 64-bit Mm register. -ASMJIT_VAR const X86MmReg mm7; //!< 64-bit Mm register. - -ASMJIT_VAR const X86XmmReg xmm0; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm1; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm2; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm3; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm4; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm5; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm6; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm7; //!< 128-bit Xmm register. -ASMJIT_VAR const X86XmmReg xmm8; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const X86XmmReg xmm9; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const X86XmmReg xmm10; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const X86XmmReg xmm11; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const X86XmmReg xmm12; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const X86XmmReg xmm13; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const X86XmmReg xmm14; //!< 128-bit Xmm register (X64). -ASMJIT_VAR const X86XmmReg xmm15; //!< 128-bit Xmm register (X64). - -ASMJIT_VAR const X86YmmReg ymm0; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm1; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm2; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm3; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm4; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm5; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm6; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm7; //!< 256-bit Ymm register. -ASMJIT_VAR const X86YmmReg ymm8; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const X86YmmReg ymm9; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const X86YmmReg ymm10; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const X86YmmReg ymm11; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const X86YmmReg ymm12; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const X86YmmReg ymm13; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const X86YmmReg ymm14; //!< 256-bit Ymm register (X64). -ASMJIT_VAR const X86YmmReg ymm15; //!< 256-bit Ymm register (X64). - -ASMJIT_VAR const X86SegReg cs; //!< Cs segment register. -ASMJIT_VAR const X86SegReg ss; //!< Ss segment register. -ASMJIT_VAR const X86SegReg ds; //!< Ds segment register. -ASMJIT_VAR const X86SegReg es; //!< Es segment register. -ASMJIT_VAR const X86SegReg fs; //!< Fs segment register. -ASMJIT_VAR const X86SegReg gs; //!< Gs segment register. +#define ASMJIT_DEF_REG(_Type_, _Name_, _Field_) \ + static const _Type_& _Name_ = x86RegData._Field_ + +ASMJIT_DEF_REG(X86RipReg, rip, rip); //!< RIP register. +ASMJIT_DEF_REG(X86GpReg , noGpReg, noGp); //!< No GP register (for `X86Mem` operand.). + +ASMJIT_DEF_REG(X86SegReg, es , seg[1]); //!< Cs segment register. +ASMJIT_DEF_REG(X86SegReg, cs , seg[2]); //!< Ss segment register. +ASMJIT_DEF_REG(X86SegReg, ss , seg[3]); //!< Ds segment register. +ASMJIT_DEF_REG(X86SegReg, ds , seg[4]); //!< Es segment register. +ASMJIT_DEF_REG(X86SegReg, fs , seg[5]); //!< Fs segment register. +ASMJIT_DEF_REG(X86SegReg, gs , seg[6]); //!< Gs segment register. + +ASMJIT_DEF_REG(X86GpReg , al , gpbLo[0]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , cl , gpbLo[1]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , dl , gpbLo[2]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , bl , gpbLo[3]); //!< 8-bit Gpb-lo register. +ASMJIT_DEF_REG(X86GpReg , spl , gpbLo[4]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , bpl , gpbLo[5]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , sil , gpbLo[6]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , dil , gpbLo[7]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r8b , gpbLo[8]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r9b , gpbLo[9]); //!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r10b , gpbLo[10]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r11b , gpbLo[11]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r12b , gpbLo[12]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r13b , gpbLo[13]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r14b , gpbLo[14]);//!< 8-bit Gpb-lo register (X64). +ASMJIT_DEF_REG(X86GpReg , r15b , gpbLo[15]);//!< 8-bit Gpb-lo register (X64). + +ASMJIT_DEF_REG(X86GpReg , ah , gpbHi[0]); //!< 8-bit Gpb-hi register. +ASMJIT_DEF_REG(X86GpReg , ch , gpbHi[1]); //!< 8-bit Gpb-hi register. +ASMJIT_DEF_REG(X86GpReg , dh , gpbHi[2]); //!< 8-bit Gpb-hi register. +ASMJIT_DEF_REG(X86GpReg , bh , gpbHi[3]); //!< 8-bit Gpb-hi register. + +ASMJIT_DEF_REG(X86GpReg , ax , gpw[0]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , cx , gpw[1]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , dx , gpw[2]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , bx , gpw[3]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , sp , gpw[4]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , bp , gpw[5]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , si , gpw[6]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , di , gpw[7]); //!< 16-bit Gpw register. +ASMJIT_DEF_REG(X86GpReg , r8w , gpw[8]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r9w , gpw[9]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r10w , gpw[10]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r11w , gpw[11]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r12w , gpw[12]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r13w , gpw[13]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r14w , gpw[14]); //!< 16-bit Gpw register (X64). +ASMJIT_DEF_REG(X86GpReg , r15w , gpw[15]); //!< 16-bit Gpw register (X64). + +ASMJIT_DEF_REG(X86GpReg , eax , gpd[0]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , ecx , gpd[1]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , edx , gpd[2]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , ebx , gpd[3]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , esp , gpd[4]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , ebp , gpd[5]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , esi , gpd[6]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , edi , gpd[7]); //!< 32-bit Gpd register. +ASMJIT_DEF_REG(X86GpReg , r8d , gpd[8]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r9d , gpd[9]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r10d , gpd[10]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r11d , gpd[11]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r12d , gpd[12]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r13d , gpd[13]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r14d , gpd[14]); //!< 32-bit Gpd register (X64). +ASMJIT_DEF_REG(X86GpReg , r15d , gpd[15]); //!< 32-bit Gpd register (X64). + +ASMJIT_DEF_REG(X86GpReg , rax , gpq[0]); //!< 64-bit Gpq register (X64). +ASMJIT_DEF_REG(X86GpReg , rcx , gpq[1]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rdx , gpq[2]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rbx , gpq[3]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rsp , gpq[4]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rbp , gpq[5]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rsi , gpq[6]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , rdi , gpq[7]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r8 , gpq[8]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r9 , gpq[9]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r10 , gpq[10]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r11 , gpq[11]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r12 , gpq[12]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r13 , gpq[13]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r14 , gpq[14]); //!< 64-bit Gpq register (X64) +ASMJIT_DEF_REG(X86GpReg , r15 , gpq[15]); //!< 64-bit Gpq register (X64) + +ASMJIT_DEF_REG(X86FpReg , fp0 , fp[0]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp1 , fp[1]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp2 , fp[2]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp3 , fp[3]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp4 , fp[4]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp5 , fp[5]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp6 , fp[6]); //!< 80-bit Fp register. +ASMJIT_DEF_REG(X86FpReg , fp7 , fp[7]); //!< 80-bit Fp register. + +ASMJIT_DEF_REG(X86MmReg , mm0 , mm[0]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm1 , mm[1]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm2 , mm[2]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm3 , mm[3]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm4 , mm[4]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm5 , mm[5]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm6 , mm[6]); //!< 64-bit Mm register. +ASMJIT_DEF_REG(X86MmReg , mm7 , mm[7]); //!< 64-bit Mm register. + +ASMJIT_DEF_REG(X86KReg , k0 , k[0]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k1 , k[1]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k2 , k[2]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k3 , k[3]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k4 , k[4]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k5 , k[5]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k6 , k[6]); //!< 64-bit K register. +ASMJIT_DEF_REG(X86KReg , k7 , k[7]); //!< 64-bit K register. + +ASMJIT_DEF_REG(X86XmmReg, xmm0 , xmm[0]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm1 , xmm[1]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm2 , xmm[2]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm3 , xmm[3]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm4 , xmm[4]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm5 , xmm[5]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm6 , xmm[6]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm7 , xmm[7]); //!< 128-bit Xmm register. +ASMJIT_DEF_REG(X86XmmReg, xmm8 , xmm[8]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm9 , xmm[9]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm10, xmm[10]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm11, xmm[11]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm12, xmm[12]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm13, xmm[13]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm14, xmm[14]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm15, xmm[15]); //!< 128-bit Xmm register (X64). +ASMJIT_DEF_REG(X86XmmReg, xmm16, xmm[16]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm17, xmm[17]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm18, xmm[18]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm19, xmm[19]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm20, xmm[20]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm21, xmm[21]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm22, xmm[22]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm23, xmm[23]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm24, xmm[24]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm25, xmm[25]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm26, xmm[26]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm27, xmm[27]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm28, xmm[28]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm29, xmm[29]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm30, xmm[30]); //!< 128-bit Xmm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86XmmReg, xmm31, xmm[31]); //!< 128-bit Xmm register (X64 & AVX512VL+). + +ASMJIT_DEF_REG(X86YmmReg, ymm0 , ymm[0]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm1 , ymm[1]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm2 , ymm[2]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm3 , ymm[3]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm4 , ymm[4]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm5 , ymm[5]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm6 , ymm[6]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm7 , ymm[7]); //!< 256-bit Ymm register. +ASMJIT_DEF_REG(X86YmmReg, ymm8 , ymm[8]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm9 , ymm[9]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm10, ymm[10]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm11, ymm[11]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm12, ymm[12]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm13, ymm[13]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm14, ymm[14]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm15, ymm[15]); //!< 256-bit Ymm register (X64). +ASMJIT_DEF_REG(X86YmmReg, ymm16, ymm[16]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm17, ymm[17]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm18, ymm[18]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm19, ymm[19]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm20, ymm[20]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm21, ymm[21]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm22, ymm[22]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm23, ymm[23]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm24, ymm[24]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm25, ymm[25]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm26, ymm[26]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm27, ymm[27]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm28, ymm[28]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm29, ymm[29]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm30, ymm[30]); //!< 256-bit Ymm register (X64 & AVX512VL+). +ASMJIT_DEF_REG(X86YmmReg, ymm31, ymm[31]); //!< 256-bit Ymm register (X64 & AVX512VL+). + +ASMJIT_DEF_REG(X86ZmmReg, zmm0 , zmm[0]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm1 , zmm[1]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm2 , zmm[2]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm3 , zmm[3]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm4 , zmm[4]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm5 , zmm[5]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm6 , zmm[6]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm7 , zmm[7]); //!< 512-bit Zmm register. +ASMJIT_DEF_REG(X86ZmmReg, zmm8 , zmm[8]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm9 , zmm[9]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm10, zmm[10]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm11, zmm[11]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm12, zmm[12]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm13, zmm[13]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm14, zmm[14]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm15, zmm[15]); //!< 512-bit Zmm register (X64). +ASMJIT_DEF_REG(X86ZmmReg, zmm16, zmm[16]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm17, zmm[17]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm18, zmm[18]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm19, zmm[19]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm20, zmm[20]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm21, zmm[21]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm22, zmm[22]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm23, zmm[23]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm24, zmm[24]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm25, zmm[25]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm26, zmm[26]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm27, zmm[27]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm28, zmm[28]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm29, zmm[29]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm30, zmm[30]); //!< 512-bit Zmm register (X64 & AVX512+). +ASMJIT_DEF_REG(X86ZmmReg, zmm31, zmm[31]); //!< 512-bit Zmm register (X64 & AVX512+). +#undef ASMJIT_DEF_REG // This is only defined by `x86operand_regs.cpp` when exporting registers. #if !defined(ASMJIT_EXPORTS_X86OPERAND_REGS) @@ -1347,10 +1841,14 @@ static ASMJIT_INLINE X86GpReg gpq(uint32_t index) { return X86GpReg(kX86RegTypeG static ASMJIT_INLINE X86FpReg fp(uint32_t index) { return X86FpReg(kX86RegTypeFp, index, 10); } //! Create 64-bit Mm register operand. static ASMJIT_INLINE X86MmReg mm(uint32_t index) { return X86MmReg(kX86RegTypeMm, index, 8); } +//! Create 64-bit K register operand. +static ASMJIT_INLINE X86KReg k(uint32_t index) { return X86KReg(kX86RegTypeK, index, 8); } //! Create 128-bit Xmm register operand. static ASMJIT_INLINE X86XmmReg xmm(uint32_t index) { return X86XmmReg(kX86RegTypeXmm, index, 16); } //! Create 256-bit Ymm register operand. static ASMJIT_INLINE X86YmmReg ymm(uint32_t index) { return X86YmmReg(kX86RegTypeYmm, index, 32); } +//! Create 512-bit Zmm register operand. +static ASMJIT_INLINE X86ZmmReg zmm(uint32_t index) { return X86ZmmReg(kX86RegTypeZmm, index, 64); } // ============================================================================ // [asmjit::x86 - Ptr (Reg)] @@ -1522,7 +2020,8 @@ ASMJIT_EXPAND_PTR_VAR(zword, 64) } // asmjit namespace -#undef _OP_ID +// [Cleanup] +#undef ASMJIT_OP_ID // [Api-End] #include "../apiend.h" diff --git a/libraries/asmjit/x86/x86operand_regs.cpp b/libraries/asmjit/x86/x86operand_regs.cpp index b215ae4ad..cc649e9c3 100644 --- a/libraries/asmjit/x86/x86operand_regs.cpp +++ b/libraries/asmjit/x86/x86operand_regs.cpp @@ -20,165 +20,262 @@ namespace asmjit { -// Prevent static initialization. -// -// Remap all classes to POD structs so they can be statically initialized -// without calling a constructor. Compiler will store these in data section. -struct X86GpReg { Operand::VRegOp data; }; -struct X86FpReg { Operand::VRegOp data; }; -struct X86MmReg { Operand::VRegOp data; }; -struct X86XmmReg { Operand::VRegOp data; }; -struct X86YmmReg { Operand::VRegOp data; }; -struct X86SegReg { Operand::VRegOp data; }; - -namespace x86 { - -// ============================================================================ -// [asmjit::x86::Registers] -// ============================================================================ - -#define REG(_Class_, _Name_, _Type_, _Index_, _Size_) \ - const _Class_ _Name_ = {{ \ - kOperandTypeReg, _Size_, { ((_Type_) << 8) + _Index_ }, kInvalidValue, {{ kInvalidVar, 0 }} \ - }} - -REG(X86GpReg, noGpReg, kInvalidReg, kInvalidReg, 0); - -REG(X86GpReg, al, kX86RegTypeGpbLo, kX86RegIndexAx, 1); -REG(X86GpReg, cl, kX86RegTypeGpbLo, kX86RegIndexCx, 1); -REG(X86GpReg, dl, kX86RegTypeGpbLo, kX86RegIndexDx, 1); -REG(X86GpReg, bl, kX86RegTypeGpbLo, kX86RegIndexBx, 1); -REG(X86GpReg, spl, kX86RegTypeGpbLo, kX86RegIndexSp, 1); -REG(X86GpReg, bpl, kX86RegTypeGpbLo, kX86RegIndexBp, 1); -REG(X86GpReg, sil, kX86RegTypeGpbLo, kX86RegIndexSi, 1); -REG(X86GpReg, dil, kX86RegTypeGpbLo, kX86RegIndexDi, 1); -REG(X86GpReg, r8b, kX86RegTypeGpbLo, 8, 1); -REG(X86GpReg, r9b, kX86RegTypeGpbLo, 9, 1); -REG(X86GpReg, r10b, kX86RegTypeGpbLo, 10, 1); -REG(X86GpReg, r11b, kX86RegTypeGpbLo, 11, 1); -REG(X86GpReg, r12b, kX86RegTypeGpbLo, 12, 1); -REG(X86GpReg, r13b, kX86RegTypeGpbLo, 13, 1); -REG(X86GpReg, r14b, kX86RegTypeGpbLo, 14, 1); -REG(X86GpReg, r15b, kX86RegTypeGpbLo, 15, 1); - -REG(X86GpReg, ah, kX86RegTypeGpbHi, kX86RegIndexAx, 1); -REG(X86GpReg, ch, kX86RegTypeGpbHi, kX86RegIndexCx, 1); -REG(X86GpReg, dh, kX86RegTypeGpbHi, kX86RegIndexDx, 1); -REG(X86GpReg, bh, kX86RegTypeGpbHi, kX86RegIndexBx, 1); - -REG(X86GpReg, ax, kX86RegTypeGpw, kX86RegIndexAx, 2); -REG(X86GpReg, cx, kX86RegTypeGpw, kX86RegIndexCx, 2); -REG(X86GpReg, dx, kX86RegTypeGpw, kX86RegIndexDx, 2); -REG(X86GpReg, bx, kX86RegTypeGpw, kX86RegIndexBx, 2); -REG(X86GpReg, sp, kX86RegTypeGpw, kX86RegIndexSp, 2); -REG(X86GpReg, bp, kX86RegTypeGpw, kX86RegIndexBp, 2); -REG(X86GpReg, si, kX86RegTypeGpw, kX86RegIndexSi, 2); -REG(X86GpReg, di, kX86RegTypeGpw, kX86RegIndexDi, 2); -REG(X86GpReg, r8w, kX86RegTypeGpw, 8, 2); -REG(X86GpReg, r9w, kX86RegTypeGpw, 9, 2); -REG(X86GpReg, r10w, kX86RegTypeGpw, 10, 2); -REG(X86GpReg, r11w, kX86RegTypeGpw, 11, 2); -REG(X86GpReg, r12w, kX86RegTypeGpw, 12, 2); -REG(X86GpReg, r13w, kX86RegTypeGpw, 13, 2); -REG(X86GpReg, r14w, kX86RegTypeGpw, 14, 2); -REG(X86GpReg, r15w, kX86RegTypeGpw, 15, 2); - -REG(X86GpReg, eax, kX86RegTypeGpd, kX86RegIndexAx, 4); -REG(X86GpReg, ecx, kX86RegTypeGpd, kX86RegIndexCx, 4); -REG(X86GpReg, edx, kX86RegTypeGpd, kX86RegIndexDx, 4); -REG(X86GpReg, ebx, kX86RegTypeGpd, kX86RegIndexBx, 4); -REG(X86GpReg, esp, kX86RegTypeGpd, kX86RegIndexSp, 4); -REG(X86GpReg, ebp, kX86RegTypeGpd, kX86RegIndexBp, 4); -REG(X86GpReg, esi, kX86RegTypeGpd, kX86RegIndexSi, 4); -REG(X86GpReg, edi, kX86RegTypeGpd, kX86RegIndexDi, 4); -REG(X86GpReg, r8d, kX86RegTypeGpd, 8, 4); -REG(X86GpReg, r9d, kX86RegTypeGpd, 9, 4); -REG(X86GpReg, r10d, kX86RegTypeGpd, 10, 4); -REG(X86GpReg, r11d, kX86RegTypeGpd, 11, 4); -REG(X86GpReg, r12d, kX86RegTypeGpd, 12, 4); -REG(X86GpReg, r13d, kX86RegTypeGpd, 13, 4); -REG(X86GpReg, r14d, kX86RegTypeGpd, 14, 4); -REG(X86GpReg, r15d, kX86RegTypeGpd, 15, 4); - -REG(X86GpReg, rax, kX86RegTypeGpq, kX86RegIndexAx, 8); -REG(X86GpReg, rcx, kX86RegTypeGpq, kX86RegIndexCx, 8); -REG(X86GpReg, rdx, kX86RegTypeGpq, kX86RegIndexDx, 8); -REG(X86GpReg, rbx, kX86RegTypeGpq, kX86RegIndexBx, 8); -REG(X86GpReg, rsp, kX86RegTypeGpq, kX86RegIndexSp, 8); -REG(X86GpReg, rbp, kX86RegTypeGpq, kX86RegIndexBp, 8); -REG(X86GpReg, rsi, kX86RegTypeGpq, kX86RegIndexSi, 8); -REG(X86GpReg, rdi, kX86RegTypeGpq, kX86RegIndexDi, 8); -REG(X86GpReg, r8, kX86RegTypeGpq, 8, 8); -REG(X86GpReg, r9, kX86RegTypeGpq, 9, 8); -REG(X86GpReg, r10, kX86RegTypeGpq, 10, 8); -REG(X86GpReg, r11, kX86RegTypeGpq, 11, 8); -REG(X86GpReg, r12, kX86RegTypeGpq, 12, 8); -REG(X86GpReg, r13, kX86RegTypeGpq, 13, 8); -REG(X86GpReg, r14, kX86RegTypeGpq, 14, 8); -REG(X86GpReg, r15, kX86RegTypeGpq, 15, 8); - -REG(X86FpReg, fp0, kX86RegTypeFp, 0, 10); -REG(X86FpReg, fp1, kX86RegTypeFp, 1, 10); -REG(X86FpReg, fp2, kX86RegTypeFp, 2, 10); -REG(X86FpReg, fp3, kX86RegTypeFp, 3, 10); -REG(X86FpReg, fp4, kX86RegTypeFp, 4, 10); -REG(X86FpReg, fp5, kX86RegTypeFp, 5, 10); -REG(X86FpReg, fp6, kX86RegTypeFp, 6, 10); -REG(X86FpReg, fp7, kX86RegTypeFp, 7, 10); - -REG(X86MmReg, mm0, kX86RegTypeMm, 0, 8); -REG(X86MmReg, mm1, kX86RegTypeMm, 1, 8); -REG(X86MmReg, mm2, kX86RegTypeMm, 2, 8); -REG(X86MmReg, mm3, kX86RegTypeMm, 3, 8); -REG(X86MmReg, mm4, kX86RegTypeMm, 4, 8); -REG(X86MmReg, mm5, kX86RegTypeMm, 5, 8); -REG(X86MmReg, mm6, kX86RegTypeMm, 6, 8); -REG(X86MmReg, mm7, kX86RegTypeMm, 7, 8); - -REG(X86XmmReg, xmm0, kX86RegTypeXmm, 0, 16); -REG(X86XmmReg, xmm1, kX86RegTypeXmm, 1, 16); -REG(X86XmmReg, xmm2, kX86RegTypeXmm, 2, 16); -REG(X86XmmReg, xmm3, kX86RegTypeXmm, 3, 16); -REG(X86XmmReg, xmm4, kX86RegTypeXmm, 4, 16); -REG(X86XmmReg, xmm5, kX86RegTypeXmm, 5, 16); -REG(X86XmmReg, xmm6, kX86RegTypeXmm, 6, 16); -REG(X86XmmReg, xmm7, kX86RegTypeXmm, 7, 16); -REG(X86XmmReg, xmm8, kX86RegTypeXmm, 8, 16); -REG(X86XmmReg, xmm9, kX86RegTypeXmm, 9, 16); -REG(X86XmmReg, xmm10, kX86RegTypeXmm, 10, 16); -REG(X86XmmReg, xmm11, kX86RegTypeXmm, 11, 16); -REG(X86XmmReg, xmm12, kX86RegTypeXmm, 12, 16); -REG(X86XmmReg, xmm13, kX86RegTypeXmm, 13, 16); -REG(X86XmmReg, xmm14, kX86RegTypeXmm, 14, 16); -REG(X86XmmReg, xmm15, kX86RegTypeXmm, 15, 16); - -REG(X86YmmReg, ymm0, kX86RegTypeYmm, 0, 32); -REG(X86YmmReg, ymm1, kX86RegTypeYmm, 1, 32); -REG(X86YmmReg, ymm2, kX86RegTypeYmm, 2, 32); -REG(X86YmmReg, ymm3, kX86RegTypeYmm, 3, 32); -REG(X86YmmReg, ymm4, kX86RegTypeYmm, 4, 32); -REG(X86YmmReg, ymm5, kX86RegTypeYmm, 5, 32); -REG(X86YmmReg, ymm6, kX86RegTypeYmm, 6, 32); -REG(X86YmmReg, ymm7, kX86RegTypeYmm, 7, 32); -REG(X86YmmReg, ymm8, kX86RegTypeYmm, 8, 32); -REG(X86YmmReg, ymm9, kX86RegTypeYmm, 9, 32); -REG(X86YmmReg, ymm10, kX86RegTypeYmm, 10, 32); -REG(X86YmmReg, ymm11, kX86RegTypeYmm, 11, 32); -REG(X86YmmReg, ymm12, kX86RegTypeYmm, 12, 32); -REG(X86YmmReg, ymm13, kX86RegTypeYmm, 13, 32); -REG(X86YmmReg, ymm14, kX86RegTypeYmm, 14, 32); -REG(X86YmmReg, ymm15, kX86RegTypeYmm, 15, 32); - -REG(X86SegReg, cs, kX86RegTypeSeg, kX86SegCs, 2); -REG(X86SegReg, ss, kX86RegTypeSeg, kX86SegSs, 2); -REG(X86SegReg, ds, kX86RegTypeSeg, kX86SegDs, 2); -REG(X86SegReg, es, kX86RegTypeSeg, kX86SegEs, 2); -REG(X86SegReg, fs, kX86RegTypeSeg, kX86SegFs, 2); -REG(X86SegReg, gs, kX86RegTypeSeg, kX86SegGs, 2); +#define REG(_Type_, _Index_, _Size_) {{ \ + kOperandTypeReg, _Size_, { ((_Type_) << 8) + _Index_ }, kInvalidValue, {{ kInvalidVar, 0 }} \ +}} + +const X86RegData x86RegData = { + // RIP. + REG(kX86RegTypeRip, 0, 0), + // NpGp. + REG(kInvalidReg, kInvalidReg, 0), + + // Segments. + { + REG(kX86RegTypeSeg, 0, 2), // Default. + REG(kX86RegTypeSeg, 1, 2), // ES. + REG(kX86RegTypeSeg, 2, 2), // CS. + REG(kX86RegTypeSeg, 3, 2), // SS. + REG(kX86RegTypeSeg, 4, 2), // DS. + REG(kX86RegTypeSeg, 5, 2), // FS. + REG(kX86RegTypeSeg, 6, 2) // GS. + }, + + // GpbLo. + { + REG(kX86RegTypeGpbLo, 0, 1), + REG(kX86RegTypeGpbLo, 1, 1), + REG(kX86RegTypeGpbLo, 2, 1), + REG(kX86RegTypeGpbLo, 3, 1), + REG(kX86RegTypeGpbLo, 4, 1), + REG(kX86RegTypeGpbLo, 5, 1), + REG(kX86RegTypeGpbLo, 6, 1), + REG(kX86RegTypeGpbLo, 7, 1), + REG(kX86RegTypeGpbLo, 8, 1), + REG(kX86RegTypeGpbLo, 9, 1), + REG(kX86RegTypeGpbLo, 10, 1), + REG(kX86RegTypeGpbLo, 11, 1), + REG(kX86RegTypeGpbLo, 12, 1), + REG(kX86RegTypeGpbLo, 13, 1), + REG(kX86RegTypeGpbLo, 14, 1), + REG(kX86RegTypeGpbLo, 15, 1) + }, + + // GpbHi. + { + REG(kX86RegTypeGpbHi, 0, 1), + REG(kX86RegTypeGpbHi, 1, 1), + REG(kX86RegTypeGpbHi, 2, 1), + REG(kX86RegTypeGpbHi, 3, 1) + }, + + // Gpw. + { + REG(kX86RegTypeGpw, 0, 2), + REG(kX86RegTypeGpw, 1, 2), + REG(kX86RegTypeGpw, 2, 2), + REG(kX86RegTypeGpw, 3, 2), + REG(kX86RegTypeGpw, 4, 2), + REG(kX86RegTypeGpw, 5, 2), + REG(kX86RegTypeGpw, 6, 2), + REG(kX86RegTypeGpw, 7, 2), + REG(kX86RegTypeGpw, 8, 2), + REG(kX86RegTypeGpw, 9, 2), + REG(kX86RegTypeGpw, 10, 2), + REG(kX86RegTypeGpw, 11, 2), + REG(kX86RegTypeGpw, 12, 2), + REG(kX86RegTypeGpw, 13, 2), + REG(kX86RegTypeGpw, 14, 2), + REG(kX86RegTypeGpw, 15, 2) + }, + + // Gpd. + { + REG(kX86RegTypeGpd, 0, 4), + REG(kX86RegTypeGpd, 1, 4), + REG(kX86RegTypeGpd, 2, 4), + REG(kX86RegTypeGpd, 3, 4), + REG(kX86RegTypeGpd, 4, 4), + REG(kX86RegTypeGpd, 5, 4), + REG(kX86RegTypeGpd, 6, 4), + REG(kX86RegTypeGpd, 7, 4), + REG(kX86RegTypeGpd, 8, 4), + REG(kX86RegTypeGpd, 9, 4), + REG(kX86RegTypeGpd, 10, 4), + REG(kX86RegTypeGpd, 11, 4), + REG(kX86RegTypeGpd, 12, 4), + REG(kX86RegTypeGpd, 13, 4), + REG(kX86RegTypeGpd, 14, 4), + REG(kX86RegTypeGpd, 15, 4) + }, + + // Gpq. + { + REG(kX86RegTypeGpq, 0, 8), + REG(kX86RegTypeGpq, 1, 8), + REG(kX86RegTypeGpq, 2, 8), + REG(kX86RegTypeGpq, 3, 8), + REG(kX86RegTypeGpq, 4, 8), + REG(kX86RegTypeGpq, 5, 8), + REG(kX86RegTypeGpq, 6, 8), + REG(kX86RegTypeGpq, 7, 8), + REG(kX86RegTypeGpq, 8, 8), + REG(kX86RegTypeGpq, 9, 8), + REG(kX86RegTypeGpq, 10, 8), + REG(kX86RegTypeGpq, 11, 8), + REG(kX86RegTypeGpq, 12, 8), + REG(kX86RegTypeGpq, 13, 8), + REG(kX86RegTypeGpq, 14, 8), + REG(kX86RegTypeGpq, 15, 8) + }, + + // Fp. + { + REG(kX86RegTypeFp, 0, 10), + REG(kX86RegTypeFp, 1, 10), + REG(kX86RegTypeFp, 2, 10), + REG(kX86RegTypeFp, 3, 10), + REG(kX86RegTypeFp, 4, 10), + REG(kX86RegTypeFp, 5, 10), + REG(kX86RegTypeFp, 6, 10), + REG(kX86RegTypeFp, 7, 10) + }, + + // Mm. + { + REG(kX86RegTypeMm, 0, 8), + REG(kX86RegTypeMm, 1, 8), + REG(kX86RegTypeMm, 2, 8), + REG(kX86RegTypeMm, 3, 8), + REG(kX86RegTypeMm, 4, 8), + REG(kX86RegTypeMm, 5, 8), + REG(kX86RegTypeMm, 6, 8), + REG(kX86RegTypeMm, 7, 8) + }, + + // K. + { + REG(kX86RegTypeK, 0, 8), + REG(kX86RegTypeK, 1, 8), + REG(kX86RegTypeK, 2, 8), + REG(kX86RegTypeK, 3, 8), + REG(kX86RegTypeK, 4, 8), + REG(kX86RegTypeK, 5, 8), + REG(kX86RegTypeK, 6, 8), + REG(kX86RegTypeK, 7, 8) + }, + + // Xmm. + { + REG(kX86RegTypeXmm, 0, 16), + REG(kX86RegTypeXmm, 1, 16), + REG(kX86RegTypeXmm, 2, 16), + REG(kX86RegTypeXmm, 3, 16), + REG(kX86RegTypeXmm, 4, 16), + REG(kX86RegTypeXmm, 5, 16), + REG(kX86RegTypeXmm, 6, 16), + REG(kX86RegTypeXmm, 7, 16), + REG(kX86RegTypeXmm, 8, 16), + REG(kX86RegTypeXmm, 9, 16), + REG(kX86RegTypeXmm, 10, 16), + REG(kX86RegTypeXmm, 11, 16), + REG(kX86RegTypeXmm, 12, 16), + REG(kX86RegTypeXmm, 13, 16), + REG(kX86RegTypeXmm, 14, 16), + REG(kX86RegTypeXmm, 15, 16), + REG(kX86RegTypeXmm, 16, 16), + REG(kX86RegTypeXmm, 17, 16), + REG(kX86RegTypeXmm, 18, 16), + REG(kX86RegTypeXmm, 19, 16), + REG(kX86RegTypeXmm, 20, 16), + REG(kX86RegTypeXmm, 21, 16), + REG(kX86RegTypeXmm, 22, 16), + REG(kX86RegTypeXmm, 23, 16), + REG(kX86RegTypeXmm, 24, 16), + REG(kX86RegTypeXmm, 25, 16), + REG(kX86RegTypeXmm, 26, 16), + REG(kX86RegTypeXmm, 27, 16), + REG(kX86RegTypeXmm, 28, 16), + REG(kX86RegTypeXmm, 29, 16), + REG(kX86RegTypeXmm, 30, 16), + REG(kX86RegTypeXmm, 31, 16) + }, + + // Ymm. + { + REG(kX86RegTypeYmm, 0, 32), + REG(kX86RegTypeYmm, 1, 32), + REG(kX86RegTypeYmm, 2, 32), + REG(kX86RegTypeYmm, 3, 32), + REG(kX86RegTypeYmm, 4, 32), + REG(kX86RegTypeYmm, 5, 32), + REG(kX86RegTypeYmm, 6, 32), + REG(kX86RegTypeYmm, 7, 32), + REG(kX86RegTypeYmm, 8, 32), + REG(kX86RegTypeYmm, 9, 32), + REG(kX86RegTypeYmm, 10, 32), + REG(kX86RegTypeYmm, 11, 32), + REG(kX86RegTypeYmm, 12, 32), + REG(kX86RegTypeYmm, 13, 32), + REG(kX86RegTypeYmm, 14, 32), + REG(kX86RegTypeYmm, 15, 32), + REG(kX86RegTypeYmm, 16, 32), + REG(kX86RegTypeYmm, 17, 32), + REG(kX86RegTypeYmm, 18, 32), + REG(kX86RegTypeYmm, 19, 32), + REG(kX86RegTypeYmm, 20, 32), + REG(kX86RegTypeYmm, 21, 32), + REG(kX86RegTypeYmm, 22, 32), + REG(kX86RegTypeYmm, 23, 32), + REG(kX86RegTypeYmm, 24, 32), + REG(kX86RegTypeYmm, 25, 32), + REG(kX86RegTypeYmm, 26, 32), + REG(kX86RegTypeYmm, 27, 32), + REG(kX86RegTypeYmm, 28, 32), + REG(kX86RegTypeYmm, 29, 32), + REG(kX86RegTypeYmm, 30, 32), + REG(kX86RegTypeYmm, 31, 32) + }, + + // Zmm. + { + REG(kX86RegTypeZmm, 0, 64), + REG(kX86RegTypeZmm, 1, 64), + REG(kX86RegTypeZmm, 2, 64), + REG(kX86RegTypeZmm, 3, 64), + REG(kX86RegTypeZmm, 4, 64), + REG(kX86RegTypeZmm, 5, 64), + REG(kX86RegTypeZmm, 6, 64), + REG(kX86RegTypeZmm, 7, 64), + REG(kX86RegTypeZmm, 8, 64), + REG(kX86RegTypeZmm, 9, 64), + REG(kX86RegTypeZmm, 10, 64), + REG(kX86RegTypeZmm, 11, 64), + REG(kX86RegTypeZmm, 12, 64), + REG(kX86RegTypeZmm, 13, 64), + REG(kX86RegTypeZmm, 14, 64), + REG(kX86RegTypeZmm, 15, 64), + REG(kX86RegTypeZmm, 16, 64), + REG(kX86RegTypeZmm, 17, 64), + REG(kX86RegTypeZmm, 18, 64), + REG(kX86RegTypeZmm, 19, 64), + REG(kX86RegTypeZmm, 20, 64), + REG(kX86RegTypeZmm, 21, 64), + REG(kX86RegTypeZmm, 22, 64), + REG(kX86RegTypeZmm, 23, 64), + REG(kX86RegTypeZmm, 24, 64), + REG(kX86RegTypeZmm, 25, 64), + REG(kX86RegTypeZmm, 26, 64), + REG(kX86RegTypeZmm, 27, 64), + REG(kX86RegTypeZmm, 28, 64), + REG(kX86RegTypeZmm, 29, 64), + REG(kX86RegTypeZmm, 30, 64), + REG(kX86RegTypeZmm, 31, 64) + } +}; #undef REG -} // x86 namespace } // asmjit namespace // [Api-End] diff --git a/libraries/asmjit/x86/x86scheduler.cpp b/libraries/asmjit/x86/x86scheduler.cpp index 33ddb6197..10a2332ac 100644 --- a/libraries/asmjit/x86/x86scheduler.cpp +++ b/libraries/asmjit/x86/x86scheduler.cpp @@ -76,7 +76,7 @@ Error X86Scheduler::run(Node* start, Node* stop) { Node* next = node_->getNext(); ASMJIT_ASSERT(node_->getType() == kNodeTypeInst); - printf(" %s\n", X86Util::getInstInfo(static_cast(node_)->getCode()).getInstName()); + printf(" %s\n", X86Util::getInstInfo(static_cast(node_)->getInstId()).getInstName()); node_ = next; } diff --git a/serialization/src/XmlSerializer.cpp b/serialization/src/XmlSerializer.cpp index debd09ac5..5e5adda5a 100644 --- a/serialization/src/XmlSerializer.cpp +++ b/serialization/src/XmlSerializer.cpp @@ -90,7 +90,7 @@ static void encodeString(const string& str, string* outString) { // Below 32 is symbolic. char buf[ 32 ]; - snprintf(buf, sizeof(buf), "&#x%02X;", (unsigned) (c & 0xff)); + sprintf(buf, "&#x%02X;", (unsigned) (c & 0xff)); //*ME: warning C4267: convert 'size_t' to 'int' //*ME: Int-Cast to make compiler happy ... -- GitLab From 7e29671a9d23600a7944f9cf50eb58c9dbd8a638 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Fri, 13 Feb 2015 10:32:10 -0800 Subject: [PATCH 258/338] Created plugin for CUDA runtime compiler --- platforms/cuda/include/CudaContext.h | 4 +- platforms/cuda/include/CudaKernels.h | 27 ++++- platforms/cuda/src/CudaContext.cpp | 55 +++++++-- plugins/cudacompiler/CMakeLists.txt | 109 ++++++++++++++++++ .../internal/windowsExportCudaCompiler.h | 41 +++++++ .../src/CudaCompilerKernelFactory.cpp | 62 ++++++++++ .../src/CudaCompilerKernelFactory.h | 50 ++++++++ .../cudacompiler/src/CudaCompilerKernels.cpp | 98 ++++++++++++++++ .../cudacompiler/src/CudaCompilerKernels.h | 61 ++++++++++ 9 files changed, 492 insertions(+), 15 deletions(-) create mode 100644 plugins/cudacompiler/CMakeLists.txt create mode 100644 plugins/cudacompiler/include/internal/windowsExportCudaCompiler.h create mode 100644 plugins/cudacompiler/src/CudaCompilerKernelFactory.cpp create mode 100644 plugins/cudacompiler/src/CudaCompilerKernelFactory.h create mode 100644 plugins/cudacompiler/src/CudaCompilerKernels.cpp create mode 100644 plugins/cudacompiler/src/CudaCompilerKernels.h diff --git a/platforms/cuda/include/CudaContext.h b/platforms/cuda/include/CudaContext.h index 18e4a8620..2793bc1d3 100644 --- a/platforms/cuda/include/CudaContext.h +++ b/platforms/cuda/include/CudaContext.h @@ -41,6 +41,7 @@ #include #include "windowsExportCuda.h" #include "CudaPlatform.h" +#include "openmm/Kernel.h" typedef unsigned int tileflags; @@ -565,7 +566,7 @@ private: int paddedNumAtoms; int numAtomBlocks; int numThreadBlocks; - bool useBlockingSync, useDoublePrecision, useMixedPrecision, contextIsValid, atomsWereReordered, boxIsTriclinic; + bool useBlockingSync, useDoublePrecision, useMixedPrecision, contextIsValid, atomsWereReordered, boxIsTriclinic, hasCompilerKernel; std::string compiler, tempDir, cacheDir, gpuArchitecture; float4 periodicBoxVecXFloat, periodicBoxVecYFloat, periodicBoxVecZFloat, periodicBoxSizeFloat, invPeriodicBoxSizeFloat; double4 periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ, periodicBoxSize, invPeriodicBoxSize; @@ -602,6 +603,7 @@ private: CudaBondedUtilities* bonded; CudaNonbondedUtilities* nonbonded; WorkThread* thread; + Kernel compilerKernel; }; struct CudaContext::Molecule { diff --git a/platforms/cuda/include/CudaKernels.h b/platforms/cuda/include/CudaKernels.h index b02a3a763..4650ae9ff 100644 --- a/platforms/cuda/include/CudaKernels.h +++ b/platforms/cuda/include/CudaKernels.h @@ -38,6 +38,27 @@ namespace OpenMM { +/** + * This abstract class defines an interface for code that can compile CUDA kernels. This allows a plugin to take advantage of runtime compilation + * when running on recent versions of CUDA. + */ +class CudaCompilerKernel : public KernelImpl { +public: + static std::string Name() { + return "CudaCompilerKernel"; + } + CudaCompilerKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) { + } + /** + * Compile a kernel to PTX. + * + * @param source the source code for the kernel + * @param options the flags to be passed to the compiler + * @param cu the CudaContext for which the kernel is being compiled + */ + virtual std::string createModule(const std::string& source, const std::string& flags, CudaContext& cu) = 0; +}; + /** * This kernel is invoked at the beginning and end of force and energy computations. It gives the * Platform a chance to clear buffers and do other initialization at the beginning, and to do any @@ -591,9 +612,9 @@ private: int getKeySize() const {return 4;} const char* getDataType() const {return "int2";} const char* getKeyType() const {return "int";} - const char* getMinKey() const {return "INT_MIN";} - const char* getMaxKey() const {return "INT_MAX";} - const char* getMaxValue() const {return "make_int2(INT_MAX, INT_MAX)";} + const char* getMinKey() const {return "(-2147483647-1)";} + const char* getMaxKey() const {return "2147483647";} + const char* getMaxValue() const {return "make_int2(2147483647, 2147483647)";} const char* getSortKey() const {return "value.y";} }; class PmeIO; diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 8cb097c33..2b53773de 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -33,6 +33,7 @@ #include "CudaBondedUtilities.h" #include "CudaForceInfo.h" #include "CudaIntegrationUtilities.h" +#include "CudaKernels.h" #include "CudaKernelSources.h" #include "CudaNonbondedUtilities.h" #include "SHA1.h" @@ -73,9 +74,16 @@ bool CudaContext::hasInitializedCuda = false; CudaContext::CudaContext(const System& system, int deviceIndex, bool useBlockingSync, const string& precision, const string& compiler, const string& tempDir, const std::string& hostCompiler, CudaPlatform::PlatformData& platformData) : system(system), currentStream(0), - time(0.0), platformData(platformData), stepCount(0), computeForceCount(0), stepsSinceReorder(99999), contextIsValid(false), atomsWereReordered(false), pinnedBuffer(NULL), posq(NULL), - posqCorrection(NULL), velm(NULL), force(NULL), energyBuffer(NULL), integration(NULL), expression(NULL), bonded(NULL), nonbonded(NULL), thread(NULL) { + time(0.0), platformData(platformData), stepCount(0), computeForceCount(0), stepsSinceReorder(99999), contextIsValid(false), atomsWereReordered(false), hasCompilerKernel(false), + pinnedBuffer(NULL), posq(NULL), posqCorrection(NULL), velm(NULL), force(NULL), energyBuffer(NULL), integration(NULL), expression(NULL), bonded(NULL), nonbonded(NULL), thread(NULL) { this->compiler = "\""+compiler+"\""; + try { + compilerKernel = platformData.context->getPlatform().createKernel(CudaCompilerKernel::Name(), *platformData.context); + hasCompilerKernel = true; + } + catch (...) { + // The runtime compiler plugin isn't available. + } if (hostCompiler.size() > 0) this->compiler = compiler+" --compiler-bindir "+hostCompiler; if (!hasInitializedCuda) { @@ -508,7 +516,7 @@ CUmodule CudaContext::createModule(const string source, const map().createModule(src.str(), "-arch=compute_"+gpuArchitecture+" "+options, *this); + + // If possible, write the PTX out to a temporary file so we can cache it for later use. + + try { + ofstream out(outputFile.c_str()); + out << ptx; + out.close(); + } + catch (...) { + // An error occurred. Possibly we don't have permission to write to the tmep directory. Just try to load the module directly. + + CHECK_RESULT2(cuModuleLoadDataEx(&module, &ptx[0], 0, NULL, NULL), "Error loading CUDA module"); + return module; + } + } + else { + // Write out the source to a temporary file. + + ofstream out(inputFile.c_str()); + out << src.str(); + out.close(); #ifdef WIN32 #ifdef _DEBUG - string command = compiler+" --ptx -G -g --machine "+bits+" -arch=sm_"+gpuArchitecture+" -o "+outputFile+" "+options+" "+inputFile+" 2> "+logFile; + string command = compiler+" --ptx -G -g --machine "+bits+" -arch=sm_"+gpuArchitecture+" -o "+outputFile+" "+options+" "+inputFile+" 2> "+logFile; #else - string command = compiler+" --ptx -lineinfo --machine "+bits+" -arch=sm_"+gpuArchitecture+" -o "+outputFile+" "+options+" "+inputFile+" 2> "+logFile; + string command = compiler+" --ptx -lineinfo --machine "+bits+" -arch=sm_"+gpuArchitecture+" -o "+outputFile+" "+options+" "+inputFile+" 2> "+logFile; #endif - int res = compileInWindows(command); + int res = compileInWindows(command); #else - string command = compiler+" --ptx --machine "+bits+" -arch=sm_"+gpuArchitecture+" -o \""+outputFile+"\" "+options+" \""+inputFile+"\" 2> \""+logFile+"\""; - int res = std::system(command.c_str()); + string command = compiler+" --ptx --machine "+bits+" -arch=sm_"+gpuArchitecture+" -o \""+outputFile+"\" "+options+" \""+inputFile+"\" 2> \""+logFile+"\""; + res = std::system(command.c_str()); #endif + } try { if (res != 0) { // Load the error log. diff --git a/plugins/cudacompiler/CMakeLists.txt b/plugins/cudacompiler/CMakeLists.txt new file mode 100644 index 000000000..a880ff61a --- /dev/null +++ b/plugins/cudacompiler/CMakeLists.txt @@ -0,0 +1,109 @@ +#--------------------------------------------------- +# OpenMM CUDA RPMD Integrator +# +# Creates OpenMMCudaCompiler library,. +# +# Windows: +# OpenMMCudaCompiler.dll +# OpenMMCudaCompiler.lib +# Unix: +# libOpenMMCudaCompiler.so +#---------------------------------------------------- + +# 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(OPENMMCUDACOMPILER_LIBRARY_NAME OpenMMCudaCompiler) + +SET(SHARED_TARGET ${OPENMMCUDACOMPILER_LIBRARY_NAME}) + +# 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) + +# collect up source files +SET(SOURCE_FILES) # empty +SET(SOURCE_INCLUDE_FILES) + +FOREACH(subdir ${OPENMM_SOURCE_SUBDIRS}) + FILE(GLOB_RECURSE src_files ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/src/*.c) + 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) +INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/platforms/cuda/include) +INCLUDE_DIRECTORIES(${CUDA_TOOLKIT_INCLUDE}) +GET_FILENAME_COMPONENT(CUDA_LIB_DIR "${CUDA_cufft_LIBRARY}" PATH) +FIND_LIBRARY(CUDA_nvrtc_LIBRARY nvrtc "${CUDA_LIB_DIR}") + +# Build the shared plugin library. + +IF (OPENMM_BUILD_SHARED_LIB) + ADD_LIBRARY(${SHARED_TARGET} SHARED ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_INCLUDE_FILES}) + + TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME} ${CUDA_nvrtc_LIBRARY}) + TARGET_LINK_LIBRARIES(${SHARED_TARGET} ${OPENMM_LIBRARY_NAME}CUDA) + SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_CUDACOMPILER_BUILDING_SHARED_LIBRARY") + IF (APPLE) + SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS} -F/Library/Frameworks -framework CUDA") + ELSE (APPLE) + SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}") + ENDIF (APPLE) + + INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${SHARED_TARGET}) +ENDIF (OPENMM_BUILD_SHARED_LIB) + +# Build the static plugin library. + +IF(OPENMM_BUILD_STATIC_LIB) + ADD_LIBRARY(${STATIC_TARGET} STATIC ${SOURCE_FILES} ${SOURCE_INCLUDE_FILES} ${API_INCLUDE_FILES}) + + TARGET_LINK_LIBRARIES(${STATIC_TARGET} ${OPENMM_LIBRARY_NAME}_static ${CUDA_nvrtc_LIBRARY}) + TARGET_LINK_LIBRARIES(${STATIC_TARGET} ${OPENMM_LIBRARY_NAME}CUDA) + SET_TARGET_PROPERTIES(${STATIC_TARGET} PROPERTIES COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DOPENMM_CUDACOMPILER_BUILDING_STATIC_LIBRARY") + IF (APPLE) + SET_TARGET_PROPERTIES(${STATIC_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS} -F/Library/Frameworks -framework CUDA") + ELSE (APPLE) + SET_TARGET_PROPERTIES(${STATIC_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}") + ENDIF (APPLE) + + INSTALL_TARGETS(/lib/plugins RUNTIME_DIRECTORY /lib/plugins ${STATIC_TARGET}) +ENDIF(OPENMM_BUILD_STATIC_LIB) + +INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) +# Ensure that links to the main CUDA library will be resolved. +IF (APPLE) + ENDIF (OPENMM_BUILD_SHARED_LIB) + SET(CUDA_LIBRARY libOpenMMCUDA.dylib) + INSTALL(CODE "EXECUTE_PROCESS(COMMAND install_name_tool -change ${CUDA_LIBRARY} @loader_path/${CUDA_LIBRARY} ${CMAKE_INSTALL_PREFIX}/lib/plugins/lib${SHARED_TARGET}.dylib)") + ENDIF (OPENMM_BUILD_SHARED_LIB) +ENDIF (APPLE) diff --git a/plugins/cudacompiler/include/internal/windowsExportCudaCompiler.h b/plugins/cudacompiler/include/internal/windowsExportCudaCompiler.h new file mode 100644 index 000000000..224662a6f --- /dev/null +++ b/plugins/cudacompiler/include/internal/windowsExportCudaCompiler.h @@ -0,0 +1,41 @@ +#ifndef OPENMM_WINDOWSEXPORTCUDACOMPILER_H_ +#define OPENMM_WINDOWSEXPORTCUDACOMPILER_H_ + +/* + * Shared libraries are messy in Visual Studio. We have to distinguish three + * cases: + * (1) this header is being used to build the OpenMM shared library + * (dllexport) + * (2) this header is being used by a *client* of the OpenMM shared + * library (dllimport) + * (3) we are building the OpenMM static library, or the client is + * being compiled with the expectation of linking with the + * OpenMM static library (nothing special needed) + * In the CMake script for building this library, we define one of the symbols + * OPENMM_CUDACOMPILER_BUILDING_{SHARED|STATIC}_LIBRARY + * Client code normally has no special symbol defined, in which case we'll + * assume it wants to use the shared library. However, if the client defines + * the symbol OPENMM_USE_STATIC_LIBRARIES we'll suppress the dllimport so + * that the client code can be linked with static libraries. Note that + * the client symbol is not library dependent, while the library symbols + * affect only the OpenMM library, meaning that other libraries can + * be clients of this one. However, we are assuming all-static or all-shared. + */ + +#ifdef _MSC_VER + // We don't want to hear about how sprintf is "unsafe". + #pragma warning(disable:4996) + // Keep MS VC++ quiet about lack of dll export of private members. + #pragma warning(disable:4251) + #if defined(OPENMM_CUDACOMPILER_BUILDING_SHARED_LIBRARY) + #define OPENMM_EXPORT_CUDACOMPILER __declspec(dllexport) + #elif defined(OPENMM_CUDACOMPILER_BUILDING_STATIC_LIBRARY) || defined(OPENMM_CUDACOMPILER_USE_STATIC_LIBRARIES) + #define OPENMM_EXPORT_CUDACOMPILER + #else + #define OPENMM_EXPORT_CUDACOMPILER __declspec(dllimport) // i.e., a client of a shared library + #endif +#else + #define OPENMM_EXPORT_CUDACOMPILER // Linux, Mac +#endif + +#endif // OPENMM_WINDOWSEXPORTCUDACOMPILER_H_ diff --git a/plugins/cudacompiler/src/CudaCompilerKernelFactory.cpp b/plugins/cudacompiler/src/CudaCompilerKernelFactory.cpp new file mode 100644 index 000000000..735729ebc --- /dev/null +++ b/plugins/cudacompiler/src/CudaCompilerKernelFactory.cpp @@ -0,0 +1,62 @@ +/* -------------------------------------------------------------------------- * + * OpenMMCudaCompiler * + * -------------------------------------------------------------------------- * + * 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) 2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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 . * + * -------------------------------------------------------------------------- */ + +#include "CudaCompilerKernelFactory.h" +#include "CudaCompilerKernels.h" +#include "internal/windowsExportCudaCompiler.h" +#include "openmm/internal/ContextImpl.h" +#include "openmm/OpenMMException.h" +#include +using namespace OpenMM; + +extern "C" OPENMM_EXPORT_CUDACOMPILER void registerKernelFactories() { + try { + Platform& platform = Platform::getPlatformByName("CUDA"); + CudaCompilerKernelFactory* factory = new CudaCompilerKernelFactory(); + platform.registerKernelFactory(CudaCompilerKernel::Name(), factory); + } + catch (std::exception ex) { + // Ignore + } +} + +#ifdef OPENMM_CUDACOMPILER_BUILDING_STATIC_LIBRARY +extern "C" void registerCudaCompilerKernelFactories() { + registerKernelFactories(); +} +#else +extern "C" OPENMM_EXPORT_CUDACOMPILER void registerCudaCompilerKernelFactories() { + registerKernelFactories(); +} +extern "C" OPENMM_EXPORT_CUDACOMPILER void registerPlatforms() { +} +#endif + +KernelImpl* CudaCompilerKernelFactory::createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const { + if (name == CudaCompilerKernel::Name()) + return new CudaRuntimeCompilerKernel(name, platform); + throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str()); +} diff --git a/plugins/cudacompiler/src/CudaCompilerKernelFactory.h b/plugins/cudacompiler/src/CudaCompilerKernelFactory.h new file mode 100644 index 000000000..1a691de51 --- /dev/null +++ b/plugins/cudacompiler/src/CudaCompilerKernelFactory.h @@ -0,0 +1,50 @@ +#ifndef OPENMM_CPUCUDACOMPILERKERNELFACTORY_H_ +#define OPENMM_CPUCUDACOMPILERKERNELFACTORY_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) 2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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 kernels for the CUDA runtime compiler. + */ + +class CudaCompilerKernelFactory : public KernelFactory { +public: + KernelImpl* createKernelImpl(std::string name, const Platform& platform, ContextImpl& context) const; +}; + +} // namespace OpenMM + +#endif /*OPENMM_CPUCUDACOMPILERKERNELFACTORY_H_*/ diff --git a/plugins/cudacompiler/src/CudaCompilerKernels.cpp b/plugins/cudacompiler/src/CudaCompilerKernels.cpp new file mode 100644 index 000000000..ac47911a9 --- /dev/null +++ b/plugins/cudacompiler/src/CudaCompilerKernels.cpp @@ -0,0 +1,98 @@ +/* -------------------------------------------------------------------------- * + * 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) 2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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 "CudaCompilerKernels.h" +#include "openmm/OpenMMException.h" +#include +#include + +using namespace OpenMM; +using namespace std; + +#define CHECK_RESULT(result, prefix) \ + if (result != NVRTC_SUCCESS) { \ + stringstream m; \ + m< splitFlags; + while (flagsStream >> flag) + splitFlags.push_back(flag); + int numOptions = splitFlags.size(); + vector options(numOptions); + for (int i = 0; i < numOptions; i++) + options[i] = &splitFlags[i][0]; + + // Compile the program to PTX. + + nvrtcProgram program; + CHECK_RESULT(nvrtcCreateProgram(&program, source.c_str(), "", 0, NULL, NULL), "Error creating program"); + try { + nvrtcResult result = nvrtcCompileProgram(program, options.size(), &options[0]); + if (result != NVRTC_SUCCESS) { + size_t logSize; + nvrtcGetProgramLogSize(program, &logSize); + vector log(logSize); + nvrtcGetProgramLog(program, &log[0]); + throw OpenMMException("Error compiling program: "+string(&log[0])); + } + size_t ptxSize; + nvrtcGetPTXSize(program, &ptxSize); + vector ptx(ptxSize); + nvrtcGetPTX(program, &ptx[0]); + nvrtcDestroyProgram(&program); + return string(&ptx[0]); + } + catch (...) { + nvrtcDestroyProgram(&program); + throw; + } +} diff --git a/plugins/cudacompiler/src/CudaCompilerKernels.h b/plugins/cudacompiler/src/CudaCompilerKernels.h new file mode 100644 index 000000000..de50c8fca --- /dev/null +++ b/plugins/cudacompiler/src/CudaCompilerKernels.h @@ -0,0 +1,61 @@ +#ifndef OPENMM_CUDACOMPILER_KERNELS_H_ +#define OPENMM_CUDACOMPILER_KERNELS_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) 2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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 "internal/windowsExportCudaCompiler.h" +#include "CudaKernels.h" +#include + +namespace OpenMM { + +/** + * This kernel is a compiler for CUDA kernels based on the runtime compilation feature + * introduced in CUDA 7. + */ +class OPENMM_EXPORT_CUDACOMPILER CudaRuntimeCompilerKernel : public CudaCompilerKernel { +public: + CudaRuntimeCompilerKernel(std::string name, const Platform& platform) : CudaCompilerKernel(name, platform) { + } + /** + * Compile a kernel to PTX. + * + * @param source the source code for the kernel + * @param options the flags to be passed to the compiler + * @param cu the CudaContext for which the kernel is being compiled + */ + std::string createModule(const std::string& source, const std::string& flags, CudaContext& cu); +}; + +} // namespace OpenMM + +#endif /*OPENMM_CUDACOMPILER_KERNELS_H_*/ -- GitLab From 8fa08870b21869d0677b7ec329ea304a8b3c5e7a Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Fri, 13 Feb 2015 11:08:34 -0800 Subject: [PATCH 259/338] Cleanup to CUDA compiler plugin --- CMakeLists.txt | 15 +++ platforms/cuda/src/CudaContext.cpp | 8 +- plugins/cudacompiler/CMakeLists.txt | 12 ++- .../src/CudaCompilerKernelFactory.cpp | 14 ++- plugins/cudacompiler/tests/CMakeLists.txt | 24 +++++ .../cudacompiler/tests/TestCudaCompiler.cpp | 100 ++++++++++++++++++ 6 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 plugins/cudacompiler/tests/CMakeLists.txt create mode 100644 plugins/cudacompiler/tests/TestCudaCompiler.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cc7f83c8..d816fff99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -462,6 +462,21 @@ IF(OPENMM_BUILD_PME_PLUGIN) ADD_SUBDIRECTORY(plugins/cpupme) ENDIF(OPENMM_BUILD_PME_PLUGIN) +# CUDA compiler plugin + +GET_FILENAME_COMPONENT(CUDA_LIB_DIR "${CUDA_cufft_LIBRARY}" PATH) +FIND_LIBRARY(CUDA_nvrtc_LIBRARY nvrtc "${CUDA_LIB_DIR}") +IF(CUDA_nvrtc_LIBRARY) + SET(OPENMM_BUILD_CUDA_COMPILER_PLUGIN ON CACHE BOOL "Build CUDA runtime compiler plugin") +ELSE(CUDA_nvrtc_LIBRARY) + SET(OPENMM_BUILD_CUDA_COMPILER_PLUGIN OFF CACHE BOOL "Build CUDA runtime compiler plugin") +ENDIF(CUDA_nvrtc_LIBRARY) +SET(OPENMM_BUILD_CUDACOMPILER_PATH) +IF(OPENMM_BUILD_CUDA_COMPILER_PLUGIN) + SET(OPENMM_BUILD_CUDACOMPILER_PATH ${CMAKE_CURRENT_SOURCE_DIR}/plugins/cudacompiler) + ADD_SUBDIRECTORY(plugins/cudacompiler) +ENDIF(OPENMM_BUILD_CUDA_COMPILER_PLUGIN) + IF(OPENMM_BUILD_SHARED_LIB) INSTALL_TARGETS(/lib RUNTIME_DIRECTORY /lib ${SHARED_TARGET}) ENDIF(OPENMM_BUILD_SHARED_LIB) diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index 2b53773de..febdaff34 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -537,13 +537,19 @@ CUmodule CudaContext::createModule(const string source, const map + using namespace OpenMM; extern "C" OPENMM_EXPORT_CUDACOMPILER void registerKernelFactories() { try { - Platform& platform = Platform::getPlatformByName("CUDA"); - CudaCompilerKernelFactory* factory = new CudaCompilerKernelFactory(); - platform.registerKernelFactory(CudaCompilerKernel::Name(), factory); + // Make sure this is at least CUDA 7.0. + + int driverVersion; + cuDriverGetVersion(&driverVersion); + if (driverVersion >= 7000) { + Platform& platform = Platform::getPlatformByName("CUDA"); + CudaCompilerKernelFactory* factory = new CudaCompilerKernelFactory(); + platform.registerKernelFactory(CudaCompilerKernel::Name(), factory); + } } catch (std::exception ex) { // Ignore diff --git a/plugins/cudacompiler/tests/CMakeLists.txt b/plugins/cudacompiler/tests/CMakeLists.txt new file mode 100644 index 000000000..21218da3f --- /dev/null +++ b/plugins/cudacompiler/tests/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# Testing +# + +ENABLE_TESTING() + +INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIR}) + +# Automatically create tests using files named "Test*.cpp" +FILE(GLOB TEST_PROGS "*Test*.cpp") +FOREACH(TEST_PROG ${TEST_PROGS}) + GET_FILENAME_COMPONENT(TEST_ROOT ${TEST_PROG} NAME_WE) + + # Link with shared library + ADD_EXECUTABLE(${TEST_ROOT} ${TEST_PROG}) + TARGET_LINK_LIBRARIES(${TEST_ROOT} ${SHARED_TARGET}) + IF (APPLE) + SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS} -F/Library/Frameworks -framework CUDA" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}") + ELSE (APPLE) + SET_TARGET_PROPERTIES(${TEST_ROOT} PROPERTIES LINK_FLAGS "${EXTRA_COMPILE_FLAGS}" COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}") + ENDIF (APPLE) + ADD_TEST(${TEST_ROOT} ${EXECUTABLE_OUTPUT_PATH}/${TEST_ROOT}) + +ENDFOREACH(TEST_PROG ${TEST_PROGS}) diff --git a/plugins/cudacompiler/tests/TestCudaCompiler.cpp b/plugins/cudacompiler/tests/TestCudaCompiler.cpp new file mode 100644 index 000000000..9d91005d9 --- /dev/null +++ b/plugins/cudacompiler/tests/TestCudaCompiler.cpp @@ -0,0 +1,100 @@ +/* -------------------------------------------------------------------------- * + * 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-2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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. * + * -------------------------------------------------------------------------- */ + +/** + * This tests using the CUDA runtime compiler plugin to compile kernels. + */ + +#include "openmm/internal/AssertionUtilities.h" +#include "openmm/Context.h" +#include "CudaPlatform.h" +#include "ReferencePlatform.h" +#include "openmm/HarmonicBondForce.h" +#include "openmm/NonbondedForce.h" +#include "openmm/System.h" +#include "openmm/LangevinIntegrator.h" +#include "openmm/VerletIntegrator.h" +#include "openmm/internal/ContextImpl.h" +#include "CudaArray.h" +#include "CudaNonbondedUtilities.h" +#include "SimTKOpenMMRealType.h" +#include "sfmt/SFMT.h" +#include +#include + +using namespace OpenMM; +using namespace std; + +CudaPlatform platform; + +extern "C" void registerCudaCompilerKernelFactories(); + +/** + * A simple test taken from the NonbondedForce test suite. Make sure it works as + * expected when using the runtime compiler. + */ +void testCoulomb() { + System system; + system.addParticle(1.0); + system.addParticle(1.0); + VerletIntegrator integrator(0.01); + NonbondedForce* forceField = new NonbondedForce(); + forceField->addParticle(0.5, 1, 0); + forceField->addParticle(-1.5, 1, 0); + system.addForce(forceField); + Context context(system, integrator, platform); + vector positions(2); + positions[0] = Vec3(0, 0, 0); + positions[1] = Vec3(2, 0, 0); + context.setPositions(positions); + State state = context.getState(State::Forces | State::Energy); + const vector& forces = state.getForces(); + double force = ONE_4PI_EPS0*(-0.75)/4.0; + ASSERT_EQUAL_VEC(Vec3(-force, 0, 0), forces[0], 1e-5); + ASSERT_EQUAL_VEC(Vec3(force, 0, 0), forces[1], 1e-5); + ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(-0.75)/2.0, state.getPotentialEnergy(), 1e-5); +} + +int main(int argc, char* argv[]) { + try { + Platform::registerPlatform(&platform); + registerCudaCompilerKernelFactories(); + // Ensure that we won't use cached kernels. + platform.setPropertyDefaultValue(CudaPlatform::CudaTempDirectory(), "this does not exist"); + testCoulomb(); + } + catch(const exception& e) { + cout << "exception: " << e.what() << endl; + return 1; + } + cout << "Done" << endl; + return 0; +} -- GitLab From 418ceabd019411e9a347e839341dfdf0ee21cc19 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 13 Feb 2015 11:51:54 -0800 Subject: [PATCH 260/338] Lepton exceptions have more informative messages --- libraries/lepton/src/ExpressionTreeNode.cpp | 10 +-- libraries/lepton/src/Parser.cpp | 87 +++++++++++---------- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/libraries/lepton/src/ExpressionTreeNode.cpp b/libraries/lepton/src/ExpressionTreeNode.cpp index dcb99c068..161665250 100644 --- a/libraries/lepton/src/ExpressionTreeNode.cpp +++ b/libraries/lepton/src/ExpressionTreeNode.cpp @@ -6,7 +6,7 @@ * 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. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -38,25 +38,25 @@ using namespace std; ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const vector& children) : operation(operation), children(children) { if (operation->getNumArguments() != children.size()) - throw Exception("Parse error: wrong number of arguments to function: "+operation->getName()); + throw Exception("wrong number of arguments to function: "+operation->getName()); } ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child1, const ExpressionTreeNode& child2) : operation(operation) { children.push_back(child1); children.push_back(child2); if (operation->getNumArguments() != children.size()) - throw Exception("Parse error: wrong number of arguments to function: "+operation->getName()); + throw Exception("wrong number of arguments to function: "+operation->getName()); } ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child) : operation(operation) { children.push_back(child); if (operation->getNumArguments() != children.size()) - throw Exception("Parse error: wrong number of arguments to function: "+operation->getName()); + throw Exception("wrong number of arguments to function: "+operation->getName()); } ExpressionTreeNode::ExpressionTreeNode(Operation* operation) : operation(operation) { if (operation->getNumArguments() != children.size()) - throw Exception("Parse error: wrong number of arguments to function: "+operation->getName()); + throw Exception("wrong number of arguments to function: "+operation->getName()); } ExpressionTreeNode::ExpressionTreeNode(const ExpressionTreeNode& node) : operation(&node.getOperation() == NULL ? NULL : node.getOperation().clone()), children(node.getChildren()) { diff --git a/libraries/lepton/src/Parser.cpp b/libraries/lepton/src/Parser.cpp index efae69046..7729625a1 100644 --- a/libraries/lepton/src/Parser.cpp +++ b/libraries/lepton/src/Parser.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2013 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -150,51 +150,56 @@ ParsedExpression Parser::parse(const string& expression) { } ParsedExpression Parser::parse(const string& expression, const map& customFunctions) { - // First split the expression into subexpressions. + try { + // First split the expression into subexpressions. - string primaryExpression = expression; - vector subexpressions; - while (true) { - string::size_type pos = primaryExpression.find_last_of(';'); - if (pos == string::npos) - break; - string sub = trim(primaryExpression.substr(pos+1)); - if (sub.size() > 0) - subexpressions.push_back(sub); - primaryExpression = primaryExpression.substr(0, pos); - } + string primaryExpression = expression; + vector subexpressions; + while (true) { + string::size_type pos = primaryExpression.find_last_of(';'); + if (pos == string::npos) + break; + string sub = trim(primaryExpression.substr(pos+1)); + if (sub.size() > 0) + subexpressions.push_back(sub); + primaryExpression = primaryExpression.substr(0, pos); + } + + // Parse the subexpressions. + + map subexpDefs; + for (int i = 0; i < (int) subexpressions.size(); i++) { + string::size_type equalsPos = subexpressions[i].find('='); + if (equalsPos == string::npos) + throw Exception("subexpression does not specify a name"); + string name = trim(subexpressions[i].substr(0, equalsPos)); + if (name.size() == 0) + throw Exception("subexpression does not specify a name"); + vector tokens = tokenize(subexpressions[i].substr(equalsPos+1)); + int pos = 0; + subexpDefs[name] = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0); + if (pos != tokens.size()) + throw Exception("unexpected text at end of subexpression: "+tokens[pos].getText()); + } - // Parse the subexpressions. + // Now parse the primary expression. - map subexpDefs; - for (int i = 0; i < (int) subexpressions.size(); i++) { - string::size_type equalsPos = subexpressions[i].find('='); - if (equalsPos == string::npos) - throw Exception("Parse error: subexpression does not specify a name"); - string name = trim(subexpressions[i].substr(0, equalsPos)); - if (name.size() == 0) - throw Exception("Parse error: subexpression does not specify a name"); - vector tokens = tokenize(subexpressions[i].substr(equalsPos+1)); + vector tokens = tokenize(primaryExpression); int pos = 0; - subexpDefs[name] = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0); + ExpressionTreeNode result = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0); if (pos != tokens.size()) - throw Exception("Parse error: unexpected text at end of subexpression: "+tokens[pos].getText()); + throw Exception("unexpected text at end of expression: "+tokens[pos].getText()); + return ParsedExpression(result); + } + catch (Exception& ex) { + throw Exception("Parse error in expression \""+expression+"\": "+ex.what()); } - - // Now parse the primary expression. - - vector tokens = tokenize(primaryExpression); - int pos = 0; - ExpressionTreeNode result = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0); - if (pos != tokens.size()) - throw Exception("Parse error: unexpected text at end of expression: "+tokens[pos].getText()); - return ParsedExpression(result); } ExpressionTreeNode Parser::parsePrecedence(const vector& tokens, int& pos, const map& customFunctions, const map& subexpressionDefs, int precedence) { if (pos == tokens.size()) - throw Exception("Parse error: unexpected end of expression"); + throw Exception("unexpected end of expression"); // Parse the next value (number, variable, function, parenthesized expression) @@ -220,7 +225,7 @@ ExpressionTreeNode Parser::parsePrecedence(const vector& tokens, int pos++; result = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0); if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen) - throw Exception("Parse error: unbalanced parentheses"); + throw Exception("unbalanced parentheses"); pos++; } else if (token.getType() == ParseToken::Function) { @@ -234,7 +239,7 @@ ExpressionTreeNode Parser::parsePrecedence(const vector& tokens, int pos++; } while (moreArgs); if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen) - throw Exception("Parse error: unbalanced parentheses"); + throw Exception("unbalanced parentheses"); pos++; Operation* op = getFunctionOperation(token.getText(), customFunctions); try { @@ -251,7 +256,7 @@ ExpressionTreeNode Parser::parsePrecedence(const vector& tokens, int result = ExpressionTreeNode(new Operation::Negate(), toNegate); } else - throw Exception("Parse error: unexpected token: "+token.getText()); + throw Exception("unexpected token: "+token.getText()); // Now deal with the next binary operator. @@ -288,7 +293,7 @@ Operation* Parser::getOperatorOperation(const std::string& name) { case Operation::POWER: return new Operation::Power(); default: - throw Exception("Parse error: unknown operator"); + throw Exception("unknown operator"); } } @@ -334,7 +339,7 @@ Operation* Parser::getFunctionOperation(const std::string& name, const map::const_iterator iter = opMap.find(trimmed); if (iter == opMap.end()) - throw Exception("Parse error: unknown function: "+trimmed); + throw Exception("unknown function: "+trimmed); switch (iter->second) { case Operation::SQRT: return new Operation::Sqrt(); @@ -387,6 +392,6 @@ Operation* Parser::getFunctionOperation(const std::string& name, const map Date: Fri, 13 Feb 2015 12:22:04 -0800 Subject: [PATCH 261/338] Custom expressions support floor() and ceil(). --- docs-source/Lepton User's Manual.doc | Bin 562176 -> 558592 bytes docs-source/usersguide/theory.rst | 2 +- libraries/lepton/include/lepton/Operation.h | 49 +++++++++++++++++- libraries/lepton/src/CompiledExpression.cpp | 6 +++ libraries/lepton/src/Operation.cpp | 8 +++ libraries/lepton/src/Parser.cpp | 6 +++ openmmapi/include/openmm/CustomAngleForce.h | 2 +- openmmapi/include/openmm/CustomBondForce.h | 2 +- .../include/openmm/CustomCompoundBondForce.h | 2 +- .../include/openmm/CustomExternalForce.h | 2 +- openmmapi/include/openmm/CustomGBForce.h | 2 +- openmmapi/include/openmm/CustomHbondForce.h | 2 +- openmmapi/include/openmm/CustomIntegrator.h | 2 +- .../include/openmm/CustomManyParticleForce.h | 2 +- .../include/openmm/CustomNonbondedForce.h | 2 +- openmmapi/include/openmm/CustomTorsionForce.h | 2 +- .../cuda/src/CudaExpressionUtilities.cpp | 6 +++ .../opencl/src/OpenCLExpressionUtilities.cpp | 6 +++ 18 files changed, 91 insertions(+), 12 deletions(-) diff --git a/docs-source/Lepton User's Manual.doc b/docs-source/Lepton User's Manual.doc index 10c8a2d53d95feb157ecbf24186dca985ee44f2b..8bf84d06fef28ea22e94835ac8b85b0d31f5c9c2 100644 GIT binary patch delta 4855 zcma)=2~duV)6) zaK;hC{@dPhXt<^?Zn8?TB3#8K)bZw65`*iP4QL+s-d;*eTc-+ zILx2`>0NY)l~0ARZzRh}nZ@adZ@<|(fKZdUc;e)r*kP0~%vNR!_}WwBM$HV!;DtObr%FFjmm z`Vsxshv@wUL<99kls(|O1!jZ>b4W*BgjHPk(61Y;G{C#!(ibP{zd+qjxEzwQW-{I{oGot{I|}SHK)Q_gnx4?Uv&O{=vouY zah8<4WtP~_{#?6fVicv9+NrD*Ztrg5_2#)lv3_69?2h4!QYh3RdW`2xbO*rUWG_0c0siADqMw$9@-HZn6hI492IZYbyF8&P_0a16loagJt9{bA^qv4%v#NThQVD_bA>4;;gEI; zHyVN#cUK$8SM5nZ78+yt5R_|$*R}AulOiP5Xk5z#HB&f}T*(yoFzJ5PImIytE5rMJ zfxUrdbq4>JLp+NPj#YATiot|b@KUH$QSBGeiGO>j-ap4b$(ZE zRq{a?4jh39>yuR!7koP?y61Fq+b0FkJ*5P@7-@)}dzIG)h!zU8JAUZXs`=d=vCcM| zSE_|ej~Do*buzEc)6IR~OvzEx<%w=gPB0?kV9O_c(9YTwxi?S}Z1Y>)>&~ zGzsbNpF{!0+NM$-6zcYBdpSuRhLjyyYQe6xC_B8Jy4W4(XSZuEDM?{5hPt$WS(I{a zDWgmnWzt4z$A@l8oH8COZmqs0g6xj;qRobMC%ck!ANhG!CUzyl*+AMxPS{ITQ~^XmVg_G_k|ZXVBy2a#t? zeFZBL2HorPQ#V{+UhnM>tYl%yIPXLYQ}+(Ms_dKd%c7LjaN9Gk-}!ji2^P~~NqAim zhiHdI3q#Jf6>aKq+qUXSYhGx~CW9$pIw%7V?x}y$?PIwyVym7h{zglxXL)^` z;c+2Ndp|;Z#YixofZ9_hy)=P3zElVewj6A381`??CK4GNIX+u^-g^=qiRsabQ`9rY zeToL!0}Z=3|HudaTDCRoVfuqANVbn2`HC=|FOr^W_(9nUwvWH-Vm=R@2%8AmMWro3 zPkn9_74!Ve@OW;c|1rha*YCfW9jO=TMsIHQ#kJn4{k7r9;Eg?brwpPuD zM@sgOZ%z=w7lBRyBG?ElWr8e_4RSzVAYv`zIuwZ5ia3q~B9?j_XF=WsHWy3nCz74D zCnA^ziFoNV5C zqxHt!8#}k))%Y{1;E#UlqV%I)dmbW_439JlHe@QH4T&eR*>BN)Pv&WFR$f}s)A%gb zMjMRRdQRd0mF#x)ycVf%FhC)jvBE9jH()Ce-gp=61^d8$Z~z~`>r(}2e_%s9Vv$IS`lOK$V+W!5|oWG?QD!xa5h4d zvvl3Ern9S>&N5&EW?%t6z}MAu)_Nt#b?C3wNG7knWUZ0r^MAhgrS(n>J0jox-uhYW z5qx_25FN#R3E$G~K2%_k7af&euqMg@53Ci*B9BD)d!T13=mmNMe3L5QTRAB4kxi52 z?GLPP_ZJ&j>`<|dgipoLBsBK~&wyl*0`MtI;`1;QWPxn?!eU-77rerw*<|_dL+eR) z#C7bEbu(i}U1Qs<+XGO)%lQnG$(biVT*M3IEdjj1--(5UE4cmsGk(2k@QUL>yhMBl&ukd$K`N}wcDB$vTygAUmlNC(U9vshO{e4W##JGi9xqNXvPwzRH?+M2oOsy7&$Vs{# zdAT^CJahN9HIb`&(2Q!u<7f$7==FfxE<@r;2T=ZA{(!@8u8Do(BBuZgdlo_rAQ+Zk!cGY!tE`O7m zMrF${SMZghY_H&zqO6+7OHsO-=kZNZ7V%qDB1qb=W{ zCLdbOuMZZwBpm)d!80Hkq<~b=3yAhUDAPbX$N-rj3uJ@G^0#Yv!p61SV#^m*bXQnk z{b*wYukagjdx!E9#$dUof!F$ejvMcalpi+m#lEeOEp_tZb-b4Cl^?F-i&+o3=5^G1 LyY9Wt1AP7i|C*tH delta 4662 zcma)=4R9036~}i^vb44(@R$67?O<$Sz$PHRU5Jgav7)#bC!Ksi0UHNM)L=f+)}#(# z*?cyE1j7OAgrSg7nlPlmL}1a9DTFdK&1$6IYB`jbM)!;mRz_ac#qP(FluIj8`Wffq~xm7oet z1>w|Htb=Y*@+epH6}R&}J6ZcE(daH$rz=N;kHh562lSV$YaygnA>`i$gt(#4EhJ)}Va{%Bd)a!4AxjQk3GkPpMm$9jq$|c@ral(MrfNW1vgj zY)wx(W=!$&C{#0pH%Aa6hNfZ$UX+*dW-OOnHA-o)v;s;z7xR0UawWP}U)lE@u!R|C zLMg|^m!HA@DH|E18QhJI(vX~=tP2;IpVA8TLc;iAVxHpp?`B;u-gg@gn5o{d)+uM2 zwZ(QcezdRt_vb|HwMT|)e;FZd352x#7|9?TQU0wNVXzSLBouaD^FQL0>l1zQ)c5_z(&SQNrC4F8#J;s6^rz~V6gnm}&;K(^ z_(U!9_7i_E+EqI3Trjz|ig;>Vq_GB$9;mQ(%X8IOv5iqzpthxiWClc!Cm0nS(k;)4 zS@hB+={0S9mMd^+@UM;bajdGoP6$9Y0MSfyk44N4w8Tvv@s&yrl3^0w1A2C52p?)}LbkK00X>fntTxE$O z91T={?D}g~l8{1m$w&6(fAnq)0C{8#gjR&lHBV)-okJOuaqxjOLgF zGqTG*#%@5fK7;?uA+bfL6==EmeUk~*J10|Znw6N-hkpm_-axyOs~auwyzREGMfeF4%f029E3Fwf75PbV@}oG13&h=qfKy5-r5x3Vbu-n&J0o z#QNH7ajBNA-m6a>*~h&4PPgcLN2`H`{`Ylbk+!2ub2hJ3bB~|J+!MOh@F^Xot;MS7 zTL%{aH6)~eQZY&P8JkMG8uabe(^#wzL(10GSg~uZ+76G9{;t5;XCj76{3SHsR9D|w zl&hUv+9(C16l0Wed`MH`l!;l1YUP$laRoe8uba}HxU`%*o)}x1*p&!R%nEU7yTL(B z%Fx|;r(?&2#f_6hU%Gl}NxoBei#$kqw7o5H{5vE9`6sVWSRf*_(aRn_YSr3;{#IFi`3v)nqt?(O?W14<>*z zFcC}w<)8vg2Gzg^{NNE#18RZF_DmS}tFxzeAn)W8OEPTL-}yc_l4>GrA7r{N)Y*G- zjGq`q<`dAkbv!jir1y^sp~04e&210=)3Av|#zrn2Yuxv-L`P!AwBi(vjftM34wu8U zdndj7^CTnN_R285r3ny)=-jLJh#ZL7^7Sw z3#NlQumC&*R`^I6SqVW*YBg8`UIrV$M(_&Q4mh}V_2PxoS1+DC`tH%Uj-K3&pR8X5 z&F2a-T0gZ!0+_Cy|CK26EH^GZq>5=UNi(G)K^rnl+$@PL?;y1_=Rs-wc9Lpwwi#W` zx2>TwTkjvl!rDMPSOtU=UIm*#2iOd@02OQn+kkY)ZKD40aJIVfNvFEc=>#Y5&e9HO1KC^#R!0{1e!bp zp=&n8IiMaifVtplZoOguE#=`4ZrER^^mKUMKkU1cQMcZ)&r_7n3VwGXtK|E;?cStL z*y@4Jp7QY5-S%ZxXE!RFpzHvhN7`7q5`JG{t1Kh;;_ZJ23Fu%0Zcq#+gDIfbzzPz6 z)y6P~oi^qOFJLTv5Vi0V#q1O>FJZ;H?BO2|VO#mo(x@UFEM;$IhzNw;UbdO03ZoM- zljw~2pQo_3%I>LrP$heaudHMr^0ifLV1jV{-0;3Cwt}YEIuP&3@xYbH@v^R&ofdw< z&$9TmYIZ1j-xd)U@fg|%e5@cT)|dNz%rk_tx3dX3uUxYRMCOoN11|b@y*yyOU^wYa zz&{%BlP)*B%g2_`)U>gK!)9L8&Vn0)qu4!xvrDJ(zEi1Kj)H(Rl zS~e)Juwt+HFt(sO(vyf%m=tAh_?NY8WPf@xd}%i8q{@jA{Dpe9PLz>)wpf%)8dwd= z@UaH=TCVkv7{zBSX9d~fA1qf;`wRFhxC*WT-m#qJSw$;9w47b>4#v@242FQAU>GO? zr9kw05akFk5_rHUFdB>jqJ8tUJbr!!8%llr&I)#8dn;>7oa_8V`_}jK=2jN8UB+uS n_yw>khcc;i$NBo@A11q_97k5o7+$u8~(bDB`5p`=1T{2 diff --git a/docs-source/usersguide/theory.rst b/docs-source/usersguide/theory.rst index 3b01346be..f3837df28 100644 --- a/docs-source/usersguide/theory.rst +++ b/docs-source/usersguide/theory.rst @@ -1040,7 +1040,7 @@ The following operators are supported: + (add), - (subtract), * (multiply), / The following standard functions are supported: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, -step, delta. step(x) = 0 if x < 0, 1 otherwise. delta(x) = 1 if x is 0, 0 +floor, ceil, step, delta. step(x) = 0 if x < 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. Some custom forces allow additional functions to be defined from tabulated values. diff --git a/libraries/lepton/include/lepton/Operation.h b/libraries/lepton/include/lepton/Operation.h index 4f5abe2cc..2fc34cf5e 100644 --- a/libraries/lepton/include/lepton/Operation.h +++ b/libraries/lepton/include/lepton/Operation.h @@ -64,7 +64,7 @@ public: */ enum Id {CONSTANT, VARIABLE, CUSTOM, ADD, SUBTRACT, MULTIPLY, DIVIDE, POWER, NEGATE, SQRT, EXP, LOG, SIN, COS, SEC, CSC, TAN, COT, ASIN, ACOS, ATAN, SINH, COSH, TANH, ERF, ERFC, STEP, DELTA, SQUARE, CUBE, RECIPROCAL, - ADD_CONSTANT, MULTIPLY_CONSTANT, POWER_CONSTANT, MIN, MAX, ABS}; + ADD_CONSTANT, MULTIPLY_CONSTANT, POWER_CONSTANT, MIN, MAX, ABS, FLOOR, CEIL}; /** * Get the name of this Operation. */ @@ -153,6 +153,8 @@ public: class Min; class Max; class Abs; + class Floor; + class Ceil; }; class LEPTON_EXPORT Operation::Constant : public Operation { @@ -1090,6 +1092,51 @@ public: ExpressionTreeNode differentiate(const std::vector& children, const std::vector& childDerivs, const std::string& variable) const; }; +class LEPTON_EXPORT Operation::Floor : public Operation { +public: + + Floor() { + } + std::string getName() const { + return "floor"; + } + Id getId() const { + return FLOOR; + } + int getNumArguments() const { + return 1; + } + Operation* clone() const { + return new Floor(); + } + double evaluate(double* args, const std::map& variables) const { + return std::floor(args[0]); + } + ExpressionTreeNode differentiate(const std::vector& children, const std::vector& childDerivs, const std::string& variable) const; +}; + +class LEPTON_EXPORT Operation::Ceil : public Operation { +public: + Ceil() { + } + std::string getName() const { + return "ceil"; + } + Id getId() const { + return CEIL; + } + int getNumArguments() const { + return 1; + } + Operation* clone() const { + return new Ceil(); + } + double evaluate(double* args, const std::map& variables) const { + return std::ceil(args[0]); + } + ExpressionTreeNode differentiate(const std::vector& children, const std::vector& childDerivs, const std::string& variable) const; +}; + } // namespace Lepton #endif /*LEPTON_OPERATION_H_*/ diff --git a/libraries/lepton/src/CompiledExpression.cpp b/libraries/lepton/src/CompiledExpression.cpp index b2eaf0cb4..6ecc64d86 100644 --- a/libraries/lepton/src/CompiledExpression.cpp +++ b/libraries/lepton/src/CompiledExpression.cpp @@ -343,6 +343,12 @@ void CompiledExpression::generateJitCode() { case Operation::ABS: generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], fabs); break; + case Operation::FLOOR: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], floor); + break; + case Operation::CEIL: + generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], ceil); + break; default: // Just invoke evaluateOperation(). diff --git a/libraries/lepton/src/Operation.cpp b/libraries/lepton/src/Operation.cpp index f10a21082..6d60340a4 100644 --- a/libraries/lepton/src/Operation.cpp +++ b/libraries/lepton/src/Operation.cpp @@ -317,3 +317,11 @@ ExpressionTreeNode Operation::Abs::differentiate(const std::vector& children, const std::vector& childDerivs, const std::string& variable) const { + return ExpressionTreeNode(new Operation::Constant(0.0)); +} + +ExpressionTreeNode Operation::Ceil::differentiate(const std::vector& children, const std::vector& childDerivs, const std::string& variable) const { + return ExpressionTreeNode(new Operation::Constant(0.0)); +} diff --git a/libraries/lepton/src/Parser.cpp b/libraries/lepton/src/Parser.cpp index efae69046..2a996a1d2 100644 --- a/libraries/lepton/src/Parser.cpp +++ b/libraries/lepton/src/Parser.cpp @@ -321,6 +321,8 @@ Operation* Parser::getFunctionOperation(const std::string& name, const map * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. */ diff --git a/openmmapi/include/openmm/CustomBondForce.h b/openmmapi/include/openmm/CustomBondForce.h index 84b38cd6b..9900eef43 100644 --- a/openmmapi/include/openmm/CustomBondForce.h +++ b/openmmapi/include/openmm/CustomBondForce.h @@ -65,7 +65,7 @@ namespace OpenMM { * * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. */ diff --git a/openmmapi/include/openmm/CustomCompoundBondForce.h b/openmmapi/include/openmm/CustomCompoundBondForce.h index 00d6aa25d..d75d3d3bb 100644 --- a/openmmapi/include/openmm/CustomCompoundBondForce.h +++ b/openmmapi/include/openmm/CustomCompoundBondForce.h @@ -89,7 +89,7 @@ namespace OpenMM { * * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. * * In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by diff --git a/openmmapi/include/openmm/CustomExternalForce.h b/openmmapi/include/openmm/CustomExternalForce.h index d6886bfc6..da7682da4 100644 --- a/openmmapi/include/openmm/CustomExternalForce.h +++ b/openmmapi/include/openmm/CustomExternalForce.h @@ -68,7 +68,7 @@ namespace OpenMM { * * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. */ diff --git a/openmmapi/include/openmm/CustomGBForce.h b/openmmapi/include/openmm/CustomGBForce.h index df7d76c9d..9f31cffc5 100644 --- a/openmmapi/include/openmm/CustomGBForce.h +++ b/openmmapi/include/openmm/CustomGBForce.h @@ -129,7 +129,7 @@ namespace OpenMM { * particular piece of the computation. * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. In expressions for * particle pair calculations, the names of per-particle parameters and computed values * have the suffix "1" or "2" appended to them to indicate the values for the two interacting particles. As seen in the above example, diff --git a/openmmapi/include/openmm/CustomHbondForce.h b/openmmapi/include/openmm/CustomHbondForce.h index 51475e588..c0a1071bd 100644 --- a/openmmapi/include/openmm/CustomHbondForce.h +++ b/openmmapi/include/openmm/CustomHbondForce.h @@ -89,7 +89,7 @@ namespace OpenMM { * * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. * * In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by diff --git a/openmmapi/include/openmm/CustomIntegrator.h b/openmmapi/include/openmm/CustomIntegrator.h index dcf842917..2d525f868 100644 --- a/openmmapi/include/openmm/CustomIntegrator.h +++ b/openmmapi/include/openmm/CustomIntegrator.h @@ -204,7 +204,7 @@ namespace OpenMM { * the force from a single force group, or a random number. * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. An expression * may also involve intermediate quantities that are defined following the main expression, using ";" as a separator. */ diff --git a/openmmapi/include/openmm/CustomManyParticleForce.h b/openmmapi/include/openmm/CustomManyParticleForce.h index c1257c801..339df1796 100644 --- a/openmmapi/include/openmm/CustomManyParticleForce.h +++ b/openmmapi/include/openmm/CustomManyParticleForce.h @@ -149,7 +149,7 @@ namespace OpenMM { * still only be evaluated once for each triplet, so it must still be symmetric with respect to p2 and p3. * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. * The names of per-particle parameters have the suffix "1", "2", etc. appended to them to indicate the values for the multiple interacting particles. * For example, if you define a per-particle parameter called "charge", then the variable "charge2" is the charge of particle p2. diff --git a/openmmapi/include/openmm/CustomNonbondedForce.h b/openmmapi/include/openmm/CustomNonbondedForce.h index 74fae4ec8..91983019b 100644 --- a/openmmapi/include/openmm/CustomNonbondedForce.h +++ b/openmmapi/include/openmm/CustomNonbondedForce.h @@ -120,7 +120,7 @@ namespace OpenMM { * frequently, the long range correction can be very slow. For this reason, it is disabled by default. * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. The names of per-particle parameters * have the suffix "1" or "2" appended to them to indicate the values for the two interacting particles. As seen in the above example, * the expression may also involve intermediate quantities that are defined following the main expression, using ";" as a separator. diff --git a/openmmapi/include/openmm/CustomTorsionForce.h b/openmmapi/include/openmm/CustomTorsionForce.h index a5a52557f..2826546e7 100644 --- a/openmmapi/include/openmm/CustomTorsionForce.h +++ b/openmmapi/include/openmm/CustomTorsionForce.h @@ -65,7 +65,7 @@ namespace OpenMM { * * * Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following - * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, step, delta. All trigonometric functions + * functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta. All trigonometric functions * are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise. */ diff --git a/platforms/cuda/src/CudaExpressionUtilities.cpp b/platforms/cuda/src/CudaExpressionUtilities.cpp index c43624257..67af84e2e 100644 --- a/platforms/cuda/src/CudaExpressionUtilities.cpp +++ b/platforms/cuda/src/CudaExpressionUtilities.cpp @@ -457,6 +457,12 @@ void CudaExpressionUtilities::processExpression(stringstream& out, const Express case Operation::ABS: out << "fabs(" << getTempName(node.getChildren()[0], temps) << ")"; break; + case Operation::FLOOR: + out << "floor(" << getTempName(node.getChildren()[0], temps) << ")"; + break; + case Operation::CEIL: + out << "ceil(" << getTempName(node.getChildren()[0], temps) << ")"; + break; default: throw OpenMMException("Internal error: Unknown operation in user-defined expression: "+node.getOperation().getName()); } diff --git a/platforms/opencl/src/OpenCLExpressionUtilities.cpp b/platforms/opencl/src/OpenCLExpressionUtilities.cpp index 2fd83226e..2a811c52a 100644 --- a/platforms/opencl/src/OpenCLExpressionUtilities.cpp +++ b/platforms/opencl/src/OpenCLExpressionUtilities.cpp @@ -449,6 +449,12 @@ void OpenCLExpressionUtilities::processExpression(stringstream& out, const Expre case Operation::ABS: out << "fabs(" << getTempName(node.getChildren()[0], temps) << ")"; break; + case Operation::FLOOR: + out << "floor(" << getTempName(node.getChildren()[0], temps) << ")"; + break; + case Operation::CEIL: + out << "ceil(" << getTempName(node.getChildren()[0], temps) << ")"; + break; default: throw OpenMMException("Internal error: Unknown operation in user-defined expression: "+node.getOperation().getName()); } -- GitLab From e0713aeb9725e8378d03560aa02b3dd6ca358e99 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 13 Feb 2015 12:22:40 -0800 Subject: [PATCH 262/338] Tests for floor() and ceil(). --- tests/TestParser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/TestParser.cpp b/tests/TestParser.cpp index 63c7a7735..9b3b7963d 100644 --- a/tests/TestParser.cpp +++ b/tests/TestParser.cpp @@ -247,6 +247,8 @@ int main() { verifyEvaluation("abs(x-y)", 2.0, 3.0, 1.0); verifyEvaluation("delta(x)+3*delta(y-1.5)", 2.0, 1.5, 3.0); verifyEvaluation("step(x-3)+y*step(x)", 2.0, 3.0, 3.0); + verifyEvaluation("floor(x)", -2.1, 3.0, -3.0); + verifyEvaluation("ceil(x)", -2.1, 3.0, -2.0); verifyInvalidExpression("1..2"); verifyInvalidExpression("1*(2+3"); verifyInvalidExpression("5++4"); @@ -279,6 +281,7 @@ int main() { verifyDerivative("min(x, 2*x)", "step(x-2*x)*2+(1-step(x-2*x))*1"); verifyDerivative("max(5, x^2)", "(1-step(5-x^2))*2*x"); verifyDerivative("abs(3*x)", "step(3*x)*3+(1-step(3*x))*-3"); + verifyDerivative("floor(x)+0.5*x*ceil(x)", "0.5*ceil(x)"); testCustomFunction("custom(x, y)/2", "x*y"); testCustomFunction("custom(x^2, 1)+custom(2, y-1)", "2*x^2+4*(y-1)"); cout << Parser::parse("x*x").optimize() << endl; -- GitLab From e84f07275641a0f34cb7f7671c3784665c4d8e55 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 17 Feb 2015 11:07:01 -0800 Subject: [PATCH 263/338] Topology records PDB ids for chains, residues, and atoms --- wrappers/python/simtk/openmm/app/pdbfile.py | 6 ++-- wrappers/python/simtk/openmm/app/pdbxfile.py | 7 ++-- wrappers/python/simtk/openmm/app/topology.py | 37 +++++++++++++++----- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/pdbfile.py b/wrappers/python/simtk/openmm/app/pdbfile.py index 7d23bed7d..4c449be5b 100644 --- a/wrappers/python/simtk/openmm/app/pdbfile.py +++ b/wrappers/python/simtk/openmm/app/pdbfile.py @@ -88,12 +88,12 @@ class PDBFile(object): atomByNumber = {} for chain in pdb.iter_chains(): - c = top.addChain() + c = top.addChain(chain.chain_id) for residue in chain.iter_residues(): resName = residue.get_name() if resName in PDBFile._residueNameReplacements: resName = PDBFile._residueNameReplacements[resName] - r = top.addResidue(resName, c) + r = top.addResidue(resName, c, str(residue.number)) if resName in PDBFile._atomNameReplacements: atomReplacements = PDBFile._atomNameReplacements[resName] else: @@ -129,7 +129,7 @@ class PDBFile(object): element = elem.get_by_symbol(atomName[0]) except KeyError: pass - newAtom = top.addAtom(atomName, element, r) + newAtom = top.addAtom(atomName, element, r, str(atom.serial_number)) atomByNumber[atom.serial_number] = newAtom self._positions = [] for model in pdb.iter_models(True): diff --git a/wrappers/python/simtk/openmm/app/pdbxfile.py b/wrappers/python/simtk/openmm/app/pdbxfile.py index 952eefa70..33902b012 100644 --- a/wrappers/python/simtk/openmm/app/pdbxfile.py +++ b/wrappers/python/simtk/openmm/app/pdbxfile.py @@ -78,6 +78,7 @@ class PDBxFile(object): atomIdCol = atomData.getAttributeIndex('id') resNameCol = atomData.getAttributeIndex('label_comp_id') resIdCol = atomData.getAttributeIndex('label_seq_id') + resNumCol = atomData.getAttributeIndex('auth_seq_id') asymIdCol = atomData.getAttributeIndex('label_asym_id') chainIdCol = atomData.getAttributeIndex('label_entity_id') elementCol = atomData.getAttributeIndex('type_symbol') @@ -107,13 +108,13 @@ class PDBxFile(object): if lastChainId != row[chainIdCol]: # The start of a new chain. - chain = top.addChain() + chain = top.addChain(row[chainIdCol]) lastChainId = row[chainIdCol] lastResId = None lastAsymId = None if lastResId != row[resIdCol] or lastAsymId != row[asymIdCol]: # The start of a new residue. - res = top.addResidue(row[resNameCol], chain) + res = top.addResidue(row[resNameCol], chain, None if resNumCol == -1 else row[resNumCol]) lastResId = row[resIdCol] if lastResId == '.': lastResId = None @@ -123,7 +124,7 @@ class PDBxFile(object): element = elem.get_by_symbol(row[elementCol]) except KeyError: pass - atom = top.addAtom(row[atomNameCol], element, res) + atom = top.addAtom(row[atomNameCol], element, res, row[atomIdCol]) atomTable[atomKey] = atom else: # This row defines coordinates for an existing atom in one of the later models. diff --git a/wrappers/python/simtk/openmm/app/topology.py b/wrappers/python/simtk/openmm/app/topology.py index 3c5d1e3e2..62dbf0cba 100644 --- a/wrappers/python/simtk/openmm/app/topology.py +++ b/wrappers/python/simtk/openmm/app/topology.py @@ -59,38 +59,51 @@ class Topology(object): self._bonds = [] self._periodicBoxVectors = None - def addChain(self): + def addChain(self, id=None): """Create a new Chain and add it to the Topology. + Parameters: + - id (string=None) An optional identifier for the chain. If this is omitted, an id + is generated based on the chain index. Returns: the newly created Chain """ - chain = Chain(len(self._chains), self) + if id is None: + id = str(len(self._chains)+1) + chain = Chain(len(self._chains), self, id) self._chains.append(chain) return chain - def addResidue(self, name, chain): + def addResidue(self, name, chain, id=None): """Create a new Residue and add it to the Topology. Parameters: - name (string) The name of the residue to add - chain (Chain) The Chain to add it to + - id (string=None) An optional identifier for the residue. If this is omitted, an id + is generated based on the residue index. Returns: the newly created Residue """ - residue = Residue(name, self._numResidues, chain) + if id is None: + id = str(self._numResidues+1) + residue = Residue(name, self._numResidues, chain, id) self._numResidues += 1 chain._residues.append(residue) return residue - def addAtom(self, name, element, residue): + def addAtom(self, name, element, residue, id=None): """Create a new Atom and add it to the Topology. Parameters: - name (string) The name of the atom to add - element (Element) The element of the atom to add - residue (Residue) The Residue to add it to + - id (string=None) An optional identifier for the atom. If this is omitted, an id + is generated based on the atom index. Returns: the newly created Atom """ - atom = Atom(name, element, self._numAtoms, residue) + if id is None: + id = str(self._numAtoms+1) + atom = Atom(name, element, self._numAtoms, residue, id) self._numAtoms += 1 residue._atoms.append(atom) return atom @@ -258,12 +271,14 @@ class Topology(object): class Chain(object): """A Chain object represents a chain within a Topology.""" - def __init__(self, index, topology): + def __init__(self, index, topology, id): """Construct a new Chain. You should call addChain() on the Topology instead of calling this directly.""" ## The index of the Chain within its Topology self.index = index ## The Topology this Chain belongs to self.topology = topology + ## A user defined identifier for this Chain + self.id = id self._residues = [] def residues(self): @@ -278,7 +293,7 @@ class Chain(object): class Residue(object): """A Residue object represents a residue within a Topology.""" - def __init__(self, name, index, chain): + def __init__(self, name, index, chain, id): """Construct a new Residue. You should call addResidue() on the Topology instead of calling this directly.""" ## The name of the Residue self.name = name @@ -286,6 +301,8 @@ class Residue(object): self.index = index ## The Chain this Residue belongs to self.chain = chain + ## A user defined identifier for this Residue + self.id = id self._atoms = [] def atoms(self): @@ -295,7 +312,7 @@ class Residue(object): class Atom(object): """An Atom object represents a residue within a Topology.""" - def __init__(self, name, element, index, residue): + def __init__(self, name, element, index, residue, id): """Construct a new Atom. You should call addAtom() on the Topology instead of calling this directly.""" ## The name of the Atom self.name = name @@ -305,4 +322,6 @@ class Atom(object): self.index = index ## The Residue this Atom belongs to self.residue = residue + ## A user defined identifier for this Atom + self.id = id -- GitLab From bfe7570e653efa36492c77bba153a4a7c29749fd Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 17 Feb 2015 11:41:21 -0800 Subject: [PATCH 264/338] Workaround for Nvidia bug on Maxwell in CUDA 6 --- platforms/opencl/src/OpenCLContext.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platforms/opencl/src/OpenCLContext.cpp b/platforms/opencl/src/OpenCLContext.cpp index 120e651bf..d9a71adce 100644 --- a/platforms/opencl/src/OpenCLContext.cpp +++ b/platforms/opencl/src/OpenCLContext.cpp @@ -190,6 +190,13 @@ OpenCLContext::OpenCLContext(const System& system, int platformIndex, int device clGetDeviceInfo(device(), CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, sizeof(cl_uint), &computeCapabilityMajor, NULL); if (computeCapabilityMajor > 1) supports64BitGlobalAtomics = true; + if (computeCapabilityMajor == 5) { + // Workaround for a bug in Maxwell on CUDA 6.x. + + string platformVersion = platforms[bestPlatform].getInfo(); + if (platformVersion.find("CUDA 6") != string::npos) + supports64BitGlobalAtomics = false; + } } } else if (vendor.size() >= 28 && vendor.substr(0, 28) == "Advanced Micro Devices, Inc.") { -- GitLab From f025c5f4175e8a7e70ea11002186ad948442d71f Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 17 Feb 2015 16:52:39 -0800 Subject: [PATCH 265/338] Modeller preserves chain, residue, and atom ids when reasonable --- wrappers/python/simtk/openmm/app/modeller.py | 38 ++++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/modeller.py b/wrappers/python/simtk/openmm/app/modeller.py index a5f240dc7..fff6c81e2 100644 --- a/wrappers/python/simtk/openmm/app/modeller.py +++ b/wrappers/python/simtk/openmm/app/modeller.py @@ -98,11 +98,11 @@ class Modeller(object): newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): - newChain = newTopology.addChain() + newChain = newTopology.addChain(chain.id) for residue in chain.residues(): - newResidue = newTopology.addResidue(residue.name, newChain) + newResidue = newTopology.addResidue(residue.name, newChain, residue.id) for atom in residue.atoms(): - newAtom = newTopology.addAtom(atom.name, atom.element, newResidue) + newAtom = newTopology.addAtom(atom.name, atom.element, newResidue, atom.id) newAtoms[atom] = newAtom newPositions.append(deepcopy(self.positions[atom.index])) for bond in self.topology.bonds(): @@ -112,11 +112,11 @@ class Modeller(object): newAtoms = {} for chain in addTopology.chains(): - newChain = newTopology.addChain() + newChain = newTopology.addChain(chain.id) for residue in chain.residues(): - newResidue = newTopology.addResidue(residue.name, newChain) + newResidue = newTopology.addResidue(residue.name, newChain, residue.id) for atom in residue.atoms(): - newAtom = newTopology.addAtom(atom.name, atom.element, newResidue) + newAtom = newTopology.addAtom(atom.name, atom.element, newResidue, atom.id) newAtoms[atom] = newAtom newPositions.append(deepcopy(addPositions[atom.index])) for bond in addTopology.bonds(): @@ -153,12 +153,12 @@ class Modeller(object): for atom in residue.atoms(): if atom not in deleteSet: if needNewChain: - newChain = newTopology.addChain() + newChain = newTopology.addChain(chain.id) needNewChain = False; if needNewResidue: - newResidue = newTopology.addResidue(residue.name, newChain) + newResidue = newTopology.addResidue(residue.name, newChain, residue.id) needNewResidue = False; - newAtom = newTopology.addAtom(atom.name, atom.element, newResidue) + newAtom = newTopology.addAtom(atom.name, atom.element, newResidue, atom.id) newAtoms[atom] = newAtom newPositions.append(deepcopy(self.positions[atom.index])) for bond in self.topology.bonds(): @@ -193,9 +193,9 @@ class Modeller(object): newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): - newChain = newTopology.addChain() + newChain = newTopology.addChain(chain.id) for residue in chain.residues(): - newResidue = newTopology.addResidue(residue.name, newChain) + newResidue = newTopology.addResidue(residue.name, newChain, residue.id) if residue.name == "HOH": # Copy the oxygen and hydrogens oatom = [atom for atom in residue.atoms() if atom.element == elem.oxygen] @@ -231,7 +231,7 @@ class Modeller(object): else: # Just copy the residue over. for atom in residue.atoms(): - newAtom = newTopology.addAtom(atom.name, atom.element, newResidue) + newAtom = newTopology.addAtom(atom.name, atom.element, newResidue, atom.id) newAtoms[atom] = newAtom newPositions.append(deepcopy(self.positions[atom.index])) for bond in self.topology.bonds(): @@ -347,11 +347,11 @@ class Modeller(object): newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): - newChain = newTopology.addChain() + newChain = newTopology.addChain(chain.id) for residue in chain.residues(): - newResidue = newTopology.addResidue(residue.name, newChain) + newResidue = newTopology.addResidue(residue.name, newChain, residue.id) for atom in residue.atoms(): - newAtom = newTopology.addAtom(atom.name, atom.element, newResidue) + newAtom = newTopology.addAtom(atom.name, atom.element, newResidue, atom.id) newAtoms[atom] = newAtom newPositions.append(deepcopy(self.positions[atom.index])) for bond in self.topology.bonds(): @@ -629,9 +629,9 @@ class Modeller(object): newIndices = [] acceptors = [atom for atom in self.topology.atoms() if atom.element in (elem.oxygen, elem.nitrogen)] for chain in self.topology.chains(): - newChain = newTopology.addChain() + newChain = newTopology.addChain(chain.id) for residue in chain.residues(): - newResidue = newTopology.addResidue(residue.name, newChain) + newResidue = newTopology.addResidue(residue.name, newChain, residue.id) isNTerminal = (residue == chain._residues[0]) isCTerminal = (residue == chain._residues[-1]) if residue.name in Modeller._residueHydrogens: @@ -900,9 +900,9 @@ class Modeller(object): newAtoms = {} newPositions = []*nanometer for chain in self.topology.chains(): - newChain = newTopology.addChain() + newChain = newTopology.addChain(chain.id) for residue in chain.residues(): - newResidue = newTopology.addResidue(residue.name, newChain) + newResidue = newTopology.addResidue(residue.name, newChain, residue.id) # Look for a matching template. -- GitLab From 5c7321cad5317a77e36118965f7e4c30699812be Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 18 Feb 2015 14:13:51 -0800 Subject: [PATCH 266/338] Created RPMDMonteCarloBarostat --- .../include/openmm/RPMDMonteCarloBarostat.h | 134 ++++++++++++++ .../openmmapi/include/openmm/RPMDUpdater.h | 54 ++++++ .../internal/RPMDMonteCarloBarostatImpl.h | 77 ++++++++ plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp | 7 + .../openmmapi/src/RPMDMonteCarloBarostat.cpp | 44 +++++ .../src/RPMDMonteCarloBarostatImpl.cpp | 172 ++++++++++++++++++ wrappers/python/src/swig_doxygen/OpenMM.i | 1 + .../src/swig_doxygen/doxygen/Doxyfile.in | 1 + 8 files changed, 490 insertions(+) create mode 100644 plugins/rpmd/openmmapi/include/openmm/RPMDMonteCarloBarostat.h create mode 100644 plugins/rpmd/openmmapi/include/openmm/RPMDUpdater.h create mode 100644 plugins/rpmd/openmmapi/include/openmm/internal/RPMDMonteCarloBarostatImpl.h create mode 100644 plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostat.cpp create mode 100644 plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostatImpl.cpp diff --git a/plugins/rpmd/openmmapi/include/openmm/RPMDMonteCarloBarostat.h b/plugins/rpmd/openmmapi/include/openmm/RPMDMonteCarloBarostat.h new file mode 100644 index 000000000..ba76c75bf --- /dev/null +++ b/plugins/rpmd/openmmapi/include/openmm/RPMDMonteCarloBarostat.h @@ -0,0 +1,134 @@ +#ifndef OPENMM_RPMDMONTECARLOBAROSTAT_H_ +#define OPENMM_RPMDMONTECARLOBAROSTAT_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) 2010-2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/Force.h" +#include +#include "internal/windowsExportRpmd.h" + +namespace OpenMM { + +/** + * This class is very similar to MonteCarloBarostat, but it is specifically designed for use + * with RPMDIntegrator. For each trial move, it scales all copies of the system by the same + * amount, then accepts or rejects the move based on the change to the total energy of the + * ring polymer (as returned by the integrator's getTotalEnergy() method). + */ + +class OPENMM_EXPORT_RPMD RPMDMonteCarloBarostat : public Force { +public: + /** + * This is the name of the parameter which stores the current pressure acting on + * the system (in bar). + */ + static const std::string& Pressure() { + static const std::string key = "RPMDMonteCarloPressure"; + return key; + } + /** + * Create a MonteCarloBarostat. + * + * @param defaultPressure the default pressure acting on the system (in bar) + * @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps) + */ + RPMDMonteCarloBarostat(double defaultPressure, int frequency = 25); + /** + * Get the default pressure acting on the system (in bar). + * + * @return the default pressure acting on the system, measured in bar. + */ + double getDefaultPressure() const { + return defaultPressure; + } + /** + * Set the default pressure acting on the system. This will affect any new Contexts you create, + * but not ones that already exist. + * + * @param pressure the default pressure acting on the system, measured in bar. + */ + void setDefaultPressure(double pressure) { + defaultPressure = pressure; + } + /** + * Get the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to + * 0, the barostat is disabled. + */ + int getFrequency() const { + return frequency; + } + /** + * Set the frequency (in time steps) at which Monte Carlo pressure changes should be attempted. If this is set to + * 0, the barostat is disabled. + */ + void setFrequency(int freq) { + frequency = freq; + } + /** + * Get the random number seed. See setRandomNumberSeed() for details. + */ + int getRandomNumberSeed() const { + return randomNumberSeed; + } + /** + * Set the random number seed. It is guaranteed that if two simulations are run + * with different random number seeds, the sequence of Monte Carlo steps will be different. On + * the other hand, no guarantees are made about the behavior of simulations that use the same seed. + * In particular, Platforms are permitted to use non-deterministic algorithms which produce different + * results on successive runs, even if those runs were initialized identically. + * + * If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context + * is created from this Force. This is done to ensure that each Context receives unique random seeds + * without you needing to set them explicitly. + */ + void setRandomNumberSeed(int seed) { + randomNumberSeed = seed; + } + /** + * Returns whether or not this force makes use of periodic boundary + * conditions. + * + * @returns true if force uses PBC and false otherwise + */ + bool usesPeriodicBoundaryConditions() const { + return true; + } +protected: + ForceImpl* createImpl() const; +private: + double defaultPressure; + int frequency, randomNumberSeed; +}; + +} // namespace OpenMM + +#endif /*OPENMM_RPMDMONTECARLOBAROSTAT_H_*/ diff --git a/plugins/rpmd/openmmapi/include/openmm/RPMDUpdater.h b/plugins/rpmd/openmmapi/include/openmm/RPMDUpdater.h new file mode 100644 index 000000000..f03618a70 --- /dev/null +++ b/plugins/rpmd/openmmapi/include/openmm/RPMDUpdater.h @@ -0,0 +1,54 @@ +#ifndef OPENMM_RPMDUPDATER_H_ +#define OPENMM_RPMDUPDATER_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) 2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/internal/ForceImpl.h" +#include "internal/windowsExportRpmd.h" + +namespace OpenMM { + +/** + * This ForceImpl subclass is for forces specifically designed to work with RPMDIntegrator. + * It adds an updateRPMDState() method that is invoked at the start of each time step + * (in contrast to updateContextState(), which gets invoked many times per time step, once + * for each copy). + */ + +class OPENMM_EXPORT_RPMD RPMDUpdater : public ForceImpl { +public: + virtual void updateRPMDState(ContextImpl& context) = 0; +}; + +} // namespace OpenMM + +#endif /*OPENMM_RPMDUPDATER_H_*/ diff --git a/plugins/rpmd/openmmapi/include/openmm/internal/RPMDMonteCarloBarostatImpl.h b/plugins/rpmd/openmmapi/include/openmm/internal/RPMDMonteCarloBarostatImpl.h new file mode 100644 index 000000000..90aca33cd --- /dev/null +++ b/plugins/rpmd/openmmapi/include/openmm/internal/RPMDMonteCarloBarostatImpl.h @@ -0,0 +1,77 @@ +#ifndef OPENMM_RPMDMONTECARLOBAROSTATIMPL_H_ +#define OPENMM_RPMDMONTECARLOBAROSTATIMPL_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) 2010-2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/RPMDMonteCarloBarostat.h" +#include "openmm/RPMDUpdater.h" +#include "openmm/Kernel.h" +#include "openmm/Vec3.h" +#include "sfmt/SFMT.h" +#include +#include + +namespace OpenMM { + +/** + * This is the internal implementation of RPMDMonteCarloBarostat. + */ + +class RPMDMonteCarloBarostatImpl : public RPMDUpdater { +public: + RPMDMonteCarloBarostatImpl(const RPMDMonteCarloBarostat& owner); + void initialize(ContextImpl& context); + const RPMDMonteCarloBarostat& getOwner() const { + return owner; + } + void updateRPMDState(ContextImpl& context); + void updateContextState(ContextImpl& context) { + // This is unused, since the updating is done in updateRPMDState(). + } + double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) { + // This force doesn't apply forces to particles. + return 0.0; + } + std::map getDefaultParameters(); + std::vector getKernelNames(); +private: + const RPMDMonteCarloBarostat& owner; + int step, numAttempted, numAccepted; + double volumeScale; + OpenMM_SFMT::SFMT random; + std::vector > savedPositions; + Kernel kernel; +}; + +} // namespace OpenMM + +#endif /*OPENMM_RPMDMONTECARLOBAROSTATIMPL_H_*/ diff --git a/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp b/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp index a705be1e5..74c6b74c8 100644 --- a/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp +++ b/plugins/rpmd/openmmapi/src/RPMDIntegrator.cpp @@ -34,6 +34,7 @@ #include "openmm/OpenMMException.h" #include "openmm/internal/ContextImpl.h" #include "openmm/RpmdKernels.h" +#include "openmm/RPMDUpdater.h" #include "SimTKOpenMMRealType.h" #include #include @@ -190,6 +191,12 @@ void RPMDIntegrator::step(int steps) { context->getOwner().setPositions(p); isFirstStep = false; } + vector& forceImpls = context->getForceImpls(); + for (int i = 0; i < (int) forceImpls.size(); i++) { + RPMDUpdater* updater = dynamic_cast(forceImpls[i]); + if (updater != NULL) + updater->updateRPMDState(*context); + } for (int i = 0; i < steps; ++i) { kernel.getAs().execute(*context, *this, forcesAreValid); forcesAreValid = true; diff --git a/plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostat.cpp b/plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostat.cpp new file mode 100644 index 000000000..1721f2f30 --- /dev/null +++ b/plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostat.cpp @@ -0,0 +1,44 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/RPMDMonteCarloBarostat.h" +#include "openmm/internal/RPMDMonteCarloBarostatImpl.h" + +using namespace OpenMM; + +RPMDMonteCarloBarostat::RPMDMonteCarloBarostat(double defaultPressure, int frequency) : + defaultPressure(defaultPressure), frequency(frequency) { + setRandomNumberSeed(0); +} + +ForceImpl* RPMDMonteCarloBarostat::createImpl() const { + return new RPMDMonteCarloBarostatImpl(*this); +} diff --git a/plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostatImpl.cpp b/plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostatImpl.cpp new file mode 100644 index 000000000..93a06a764 --- /dev/null +++ b/plugins/rpmd/openmmapi/src/RPMDMonteCarloBarostatImpl.cpp @@ -0,0 +1,172 @@ +/* -------------------------------------------------------------------------- * + * 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) 2010-2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/internal/RPMDMonteCarloBarostatImpl.h" +#include "openmm/internal/ContextImpl.h" +#include "openmm/internal/OSRngSeed.h" +#include "openmm/Context.h" +#include "openmm/kernels.h" +#include "openmm/OpenMMException.h" +#include "openmm/RPMDIntegrator.h" +#include +#include +#include + +using namespace OpenMM; +using namespace OpenMM_SFMT; +using std::vector; + +const float BOLTZMANN = 1.380658e-23f; // (J/K) +const float AVOGADRO = 6.0221367e23f; +const float RGAS = BOLTZMANN*AVOGADRO; // (J/(mol K)) +const float BOLTZ = RGAS/1000; // (kJ/(mol K)) + +RPMDMonteCarloBarostatImpl::RPMDMonteCarloBarostatImpl(const RPMDMonteCarloBarostat& owner) : owner(owner), step(0) { +} + +void RPMDMonteCarloBarostatImpl::initialize(ContextImpl& context) { + RPMDIntegrator* integrator = dynamic_cast(&context.getIntegrator()); + if (integrator == NULL) + throw OpenMMException("RPMDMonteCarloBarostat must be used with an RPMDIntegrator");; + if (!integrator->getApplyThermostat()) + throw OpenMMException("RPMDMonteCarloBarostat requires the integrator's thermostat to be enabled");; + kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); + kernel.getAs().initialize(context.getSystem(), owner); + savedPositions.resize(integrator->getNumCopies()); + Vec3 box[3]; + context.getPeriodicBoxVectors(box[0], box[1], box[2]); + double volume = box[0][0]*box[1][1]*box[2][2]; + volumeScale = 0.01*volume; + numAttempted = 0; + numAccepted = 0; + int randSeed = owner.getRandomNumberSeed(); + // A random seed of 0 means use a unique one + if (randSeed == 0) randSeed = osrngseed(); + init_gen_rand(randSeed, random); +} + +void RPMDMonteCarloBarostatImpl::updateRPMDState(ContextImpl& context) { + if (++step < owner.getFrequency() || owner.getFrequency() == 0) + return; + step = 0; + + // Compute the current potential energy. + + RPMDIntegrator& integrator = dynamic_cast(context.getIntegrator()); + + // Record the initial positions and energy + + double initialEnergy = 0; + int numCopies = integrator.getNumCopies(); + for (int i = 0; i < numCopies; i++) { + State state = integrator.getState(i, State::Positions | State::Energy); + savedPositions[i] = state.getPositions(); + initialEnergy += state.getPotentialEnergy(); + } + + // Compute the centroid. + + int numParticles = context.getSystem().getNumParticles(); + vector centroid(numParticles, Vec3()); + for (int i = 0; i < numParticles; i++) { + for (int j = 0; j < numCopies; j++) + centroid[i] += savedPositions[j][i]; + centroid[i] *= 1.0/numCopies; + } + + // Modify the periodic box size and scale the coordinates of the centroid. + + Vec3 box[3]; + context.getPeriodicBoxVectors(box[0], box[1], box[2]); + double volume = box[0][0]*box[1][1]*box[2][2]; + double deltaVolume = volumeScale*2*(genrand_real2(random)-0.5); + double newVolume = volume+deltaVolume; + double lengthScale = std::pow(newVolume/volume, 1.0/3.0); + context.setPositions(centroid); + kernel.getAs().scaleCoordinates(context, lengthScale, lengthScale, lengthScale); + context.getOwner().setPeriodicBoxVectors(box[0]*lengthScale, box[1]*lengthScale, box[2]*lengthScale); + State scaledState = context.getOwner().getState(State::Positions); + + // Now apply the same offset to all the copies. + + vector delta(numParticles); + for (int i = 0; i < numParticles; i++) + delta[i] = scaledState.getPositions()[i]-centroid[i]; + double finalEnergy = 0; + vector positions(numParticles); + for (int copy = 0; copy < numCopies; copy++) { + for (int i = 0; i < numParticles; i++) + positions[i] = savedPositions[copy][i]+delta[i]; + integrator.setPositions(copy, positions); + finalEnergy += integrator.getState(copy, State::Energy).getPotentialEnergy(); + } + + // Compute the energy of the modified system. + + double pressure = context.getParameter(RPMDMonteCarloBarostat::Pressure())*(AVOGADRO*1e-25); + double kT = BOLTZ*integrator.getTemperature(); + double w = (finalEnergy-initialEnergy)/numCopies + pressure*deltaVolume - context.getMolecules().size()*kT*std::log(newVolume/volume); + if (w > 0 && genrand_real2(random) > std::exp(-w/kT)) { + // Reject the step. + + for (int copy = 0; copy < numCopies; copy++) + integrator.setPositions(copy, savedPositions[copy]); + context.getOwner().setPeriodicBoxVectors(box[0], box[1], box[2]); + volume = newVolume; + } + else + numAccepted++; + numAttempted++; + if (numAttempted >= 10) { + if (numAccepted < 0.25*numAttempted) { + volumeScale /= 1.1; + numAttempted = 0; + numAccepted = 0; + } + else if (numAccepted > 0.75*numAttempted) { + volumeScale = std::min(volumeScale*1.1, volume*0.3); + numAttempted = 0; + numAccepted = 0; + } + } +} + +std::map RPMDMonteCarloBarostatImpl::getDefaultParameters() { + std::map parameters; + parameters[RPMDMonteCarloBarostat::Pressure()] = getOwner().getDefaultPressure(); + return parameters; +} + +std::vector RPMDMonteCarloBarostatImpl::getKernelNames() { + std::vector names; + names.push_back(ApplyMonteCarloBarostatKernel::Name()); + return names; +} diff --git a/wrappers/python/src/swig_doxygen/OpenMM.i b/wrappers/python/src/swig_doxygen/OpenMM.i index 8a21e3918..7a5931839 100644 --- a/wrappers/python/src/swig_doxygen/OpenMM.i +++ b/wrappers/python/src/swig_doxygen/OpenMM.i @@ -48,6 +48,7 @@ namespace std { #include "OpenMM.h" #include "OpenMMAmoeba.h" #include "openmm/RPMDIntegrator.h" +#include "openmm/RPMDMonteCarloBarostat.h" #include "OpenMMDrude.h" #include "openmm/serialization/SerializationNode.h" #include "openmm/serialization/SerializationProxy.h" diff --git a/wrappers/python/src/swig_doxygen/doxygen/Doxyfile.in b/wrappers/python/src/swig_doxygen/doxygen/Doxyfile.in index 3e20502ed..031df680a 100644 --- a/wrappers/python/src/swig_doxygen/doxygen/Doxyfile.in +++ b/wrappers/python/src/swig_doxygen/doxygen/Doxyfile.in @@ -621,6 +621,7 @@ EXCLUDE_PATTERNS = */tests/* \ *amoebaKernels.h \ *DrudeKernels.h \ *RpmdKernels.h \ + *RPMDUpdater.h \ *OpenMMFortranModule.f90 \ *OpenMMCWrapper.h -- GitLab From 38e19cbe8f52f3ce97b9237ab6f42e408d564b7c Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 18 Feb 2015 15:07:43 -0800 Subject: [PATCH 267/338] Do not allow standard barostats to be used with RPMDIntegrator --- plugins/rpmd/platforms/cuda/src/CudaRpmdKernels.cpp | 9 ++------- plugins/rpmd/platforms/cuda/tests/TestCudaRpmd.cpp | 8 ++++---- .../rpmd/platforms/opencl/src/OpenCLRpmdKernels.cpp | 9 ++------- .../rpmd/platforms/opencl/tests/TestOpenCLRpmd.cpp | 8 ++++---- .../reference/src/ReferenceRpmdKernels.cpp | 13 ++----------- .../platforms/reference/tests/TestReferenceRpmd.cpp | 8 ++++---- 6 files changed, 18 insertions(+), 37 deletions(-) diff --git a/plugins/rpmd/platforms/cuda/src/CudaRpmdKernels.cpp b/plugins/rpmd/platforms/cuda/src/CudaRpmdKernels.cpp index a34b07ae1..5eef68b3d 100644 --- a/plugins/rpmd/platforms/cuda/src/CudaRpmdKernels.cpp +++ b/plugins/rpmd/platforms/cuda/src/CudaRpmdKernels.cpp @@ -257,13 +257,8 @@ void CudaIntegrateRPMDStepKernel::computeForces(ContextImpl& context) { context.updateContextState(); Vec3 finalBox[3]; context.getPeriodicBoxVectors(finalBox[0], finalBox[1], finalBox[2]); - if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) { - // A barostat was applied during updateContextState(). Adjust the particle positions in all the - // other copies to match this one. - - void* args[] = {&positions->getDevicePointer(), &cu.getPosq().getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i}; - cu.executeKernel(translateKernel, args, cu.getNumAtoms()); - } + if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) + throw OpenMMException("Standard barostats cannot be used with RPMDIntegrator. Use RPMDMonteCarloBarostat instead."); context.calcForcesAndEnergy(true, false, groupsNotContracted); void* copyFromContextArgs[] = {&cu.getForce().getDevicePointer(), &forces->getDevicePointer(), &cu.getVelm().getDevicePointer(), &velocities->getDevicePointer(), &cu.getPosq().getDevicePointer(), &positions->getDevicePointer(), &cu.getAtomIndexArray().getDevicePointer(), &i}; diff --git a/plugins/rpmd/platforms/cuda/tests/TestCudaRpmd.cpp b/plugins/rpmd/platforms/cuda/tests/TestCudaRpmd.cpp index 25307c67c..cf7492632 100644 --- a/plugins/rpmd/platforms/cuda/tests/TestCudaRpmd.cpp +++ b/plugins/rpmd/platforms/cuda/tests/TestCudaRpmd.cpp @@ -38,11 +38,11 @@ #include "openmm/Context.h" #include "openmm/CustomNonbondedForce.h" #include "openmm/HarmonicBondForce.h" -#include "openmm/MonteCarloBarostat.h" #include "openmm/NonbondedForce.h" #include "openmm/Platform.h" #include "openmm/System.h" #include "openmm/RPMDIntegrator.h" +#include "openmm/RPMDMonteCarloBarostat.h" #include "openmm/VirtualSite.h" #include "SimTKOpenMMUtilities.h" #include "sfmt/SFMT.h" @@ -371,7 +371,7 @@ void testContractions() { system.addForce(bonds); NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setCutoffDistance(cutoff); - nonbonded->setNonbondedMethod(NonbondedForce::PME); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); nonbonded->setForceGroup(1); nonbonded->setReciprocalSpaceForceGroup(2); system.addForce(nonbonded); @@ -491,11 +491,11 @@ void testWithBarostat() { system.addForce(bonds); NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setCutoffDistance(cutoff); - nonbonded->setNonbondedMethod(NonbondedForce::PME); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); nonbonded->setForceGroup(1); nonbonded->setReciprocalSpaceForceGroup(2); system.addForce(nonbonded); - system.addForce(new MonteCarloBarostat(0.5, temperature)); + system.addForce(new RPMDMonteCarloBarostat(0.5, 10)); // Create a cloud of molecules. diff --git a/plugins/rpmd/platforms/opencl/src/OpenCLRpmdKernels.cpp b/plugins/rpmd/platforms/opencl/src/OpenCLRpmdKernels.cpp index 5c9292726..62313ea96 100644 --- a/plugins/rpmd/platforms/opencl/src/OpenCLRpmdKernels.cpp +++ b/plugins/rpmd/platforms/opencl/src/OpenCLRpmdKernels.cpp @@ -273,13 +273,8 @@ void OpenCLIntegrateRPMDStepKernel::computeForces(ContextImpl& context) { context.updateContextState(); Vec3 finalBox[3]; context.getPeriodicBoxVectors(finalBox[0], finalBox[1], finalBox[2]); - if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) { - // A barostat was applied during updateContextState(). Adjust the particle positions in all the - // other copies to match this one. - - translateKernel.setArg(3, i); - cl.executeKernel(translateKernel, cl.getNumAtoms()); - } + if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) + throw OpenMMException("Standard barostats cannot be used with RPMDIntegrator. Use RPMDMonteCarloBarostat instead."); context.calcForcesAndEnergy(true, false, groupsNotContracted); copyFromContextKernel.setArg(7, i); cl.executeKernel(copyFromContextKernel, cl.getNumAtoms()); diff --git a/plugins/rpmd/platforms/opencl/tests/TestOpenCLRpmd.cpp b/plugins/rpmd/platforms/opencl/tests/TestOpenCLRpmd.cpp index 3b4037695..c1d8bc656 100644 --- a/plugins/rpmd/platforms/opencl/tests/TestOpenCLRpmd.cpp +++ b/plugins/rpmd/platforms/opencl/tests/TestOpenCLRpmd.cpp @@ -38,11 +38,11 @@ #include "openmm/Context.h" #include "openmm/CustomNonbondedForce.h" #include "openmm/HarmonicBondForce.h" -#include "openmm/MonteCarloBarostat.h" #include "openmm/NonbondedForce.h" #include "openmm/Platform.h" #include "openmm/System.h" #include "openmm/RPMDIntegrator.h" +#include "openmm/RPMDMonteCarloBarostat.h" #include "openmm/VirtualSite.h" #include "SimTKOpenMMUtilities.h" #include "sfmt/SFMT.h" @@ -372,7 +372,7 @@ void testContractions() { system.addForce(bonds); NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setCutoffDistance(cutoff); - nonbonded->setNonbondedMethod(NonbondedForce::PME); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); nonbonded->setForceGroup(1); nonbonded->setReciprocalSpaceForceGroup(2); system.addForce(nonbonded); @@ -492,11 +492,11 @@ void testWithBarostat() { system.addForce(bonds); NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setCutoffDistance(cutoff); - nonbonded->setNonbondedMethod(NonbondedForce::PME); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); nonbonded->setForceGroup(1); nonbonded->setReciprocalSpaceForceGroup(2); system.addForce(nonbonded); - system.addForce(new MonteCarloBarostat(0.5, temperature)); + system.addForce(new RPMDMonteCarloBarostat(0.5, 10)); // Create a cloud of molecules. diff --git a/plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.cpp b/plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.cpp index 647faf3b8..abda39196 100644 --- a/plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.cpp +++ b/plugins/rpmd/platforms/reference/src/ReferenceRpmdKernels.cpp @@ -280,17 +280,8 @@ void ReferenceIntegrateRPMDStepKernel::computeForces(ContextImpl& context, const context.updateContextState(); Vec3 finalBox[3]; context.getPeriodicBoxVectors(finalBox[0], finalBox[1], finalBox[2]); - if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) { - // A barostat was applied during updateContextState(). Adjust the particle positions in all the - // other copies to match this one. - - for (int j = 0; j < numParticles; j++) { - Vec3 delta = pos[j]-positions[i][j]; - for (int k = 0; k < totalCopies; k++) - if (k != i) - positions[k][j] += delta; - } - } + if (initialBox[0] != finalBox[0] || initialBox[1] != finalBox[1] || initialBox[2] != finalBox[2]) + throw OpenMMException("Standard barostats cannot be used with RPMDIntegrator. Use RPMDMonteCarloBarostat instead."); positions[i] = pos; velocities[i] = vel; context.calcForcesAndEnergy(true, false, groupsNotContracted); diff --git a/plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp b/plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp index 8928eda79..5c22a2976 100644 --- a/plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp +++ b/plugins/rpmd/platforms/reference/tests/TestReferenceRpmd.cpp @@ -37,11 +37,11 @@ #include "openmm/CMMotionRemover.h" #include "openmm/Context.h" #include "openmm/HarmonicBondForce.h" -#include "openmm/MonteCarloBarostat.h" #include "openmm/NonbondedForce.h" #include "openmm/Platform.h" #include "openmm/System.h" #include "openmm/RPMDIntegrator.h" +#include "openmm/RPMDMonteCarloBarostat.h" #include "openmm/VirtualSite.h" #include "SimTKOpenMMUtilities.h" #include "sfmt/SFMT.h" @@ -255,7 +255,7 @@ void testContractions() { system.addForce(bonds); NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setCutoffDistance(cutoff); - nonbonded->setNonbondedMethod(NonbondedForce::PME); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); nonbonded->setForceGroup(1); nonbonded->setReciprocalSpaceForceGroup(2); system.addForce(nonbonded); @@ -375,11 +375,11 @@ void testWithBarostat() { system.addForce(bonds); NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setCutoffDistance(cutoff); - nonbonded->setNonbondedMethod(NonbondedForce::PME); + nonbonded->setNonbondedMethod(NonbondedForce::CutoffPeriodic); nonbonded->setForceGroup(1); nonbonded->setReciprocalSpaceForceGroup(2); system.addForce(nonbonded); - system.addForce(new MonteCarloBarostat(0.5, temperature)); + system.addForce(new RPMDMonteCarloBarostat(0.5, 10)); // Create a cloud of molecules. -- GitLab From f2958043a7a60e19484e3290232dc41a2fadfbf3 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 18 Feb 2015 16:19:27 -0800 Subject: [PATCH 268/338] Minor changes to speed up some test cases --- platforms/cuda/tests/TestCudaLocalEnergyMinimizer.cpp | 8 ++++---- .../cuda/tests/TestCudaVariableLangevinIntegrator.cpp | 8 ++++---- platforms/opencl/tests/TestOpenCLLocalEnergyMinimizer.cpp | 8 ++++---- .../opencl/tests/TestOpenCLVariableLangevinIntegrator.cpp | 8 ++++---- .../reference/tests/TestReferenceCustomNonbondedForce.cpp | 6 +++--- .../reference/tests/TestReferenceLocalEnergyMinimizer.cpp | 8 ++++---- .../tests/TestReferenceVariableLangevinIntegrator.cpp | 8 ++++---- .../tests/TestReferenceDrudeLangevinIntegrator.cpp | 2 +- .../reference/tests/TestReferenceDrudeSCFIntegrator.cpp | 2 +- 9 files changed, 29 insertions(+), 29 deletions(-) diff --git a/platforms/cuda/tests/TestCudaLocalEnergyMinimizer.cpp b/platforms/cuda/tests/TestCudaLocalEnergyMinimizer.cpp index 483d744cf..6b7bc4a9f 100644 --- a/platforms/cuda/tests/TestCudaLocalEnergyMinimizer.cpp +++ b/platforms/cuda/tests/TestCudaLocalEnergyMinimizer.cpp @@ -77,10 +77,10 @@ void testHarmonicBonds() { } void testLargeSystem() { - const int numMolecules = 50; + const int numMolecules = 25; const int numParticles = numMolecules*2; const double cutoff = 2.0; - const double boxSize = 5.0; + const double boxSize = 4.0; const double tolerance = 5; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); @@ -134,10 +134,10 @@ void testLargeSystem() { } void testVirtualSites() { - const int numMolecules = 50; + const int numMolecules = 25; const int numParticles = numMolecules*3; const double cutoff = 2.0; - const double boxSize = 5.0; + const double boxSize = 4.0; const double tolerance = 5; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); diff --git a/platforms/cuda/tests/TestCudaVariableLangevinIntegrator.cpp b/platforms/cuda/tests/TestCudaVariableLangevinIntegrator.cpp index 8ad144d4e..7abb555a5 100644 --- a/platforms/cuda/tests/TestCudaVariableLangevinIntegrator.cpp +++ b/platforms/cuda/tests/TestCudaVariableLangevinIntegrator.cpp @@ -296,7 +296,7 @@ void testArgonBox() { system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); system.addForce(nonbonded); - VariableLangevinIntegrator integrator(temp, 6.0, 1e-5); + VariableLangevinIntegrator integrator(temp, 6.0, 1e-4); Context context(system, integrator, platform); context.setPositions(positions); context.setVelocitiesToTemperature(temp); @@ -308,13 +308,13 @@ void testArgonBox() { // Make sure the temperature is correct. double ke = 0.0; - for (int i = 0; i < 2000; ++i) { - double t = 2.0 + 0.01 * (i + 1); + for (int i = 0; i < 1000; ++i) { + double t = 2.0 + 0.02 * (i + 1); integrator.stepTo(t); State state = context.getState(State::Energy); ke += state.getKineticEnergy(); } - ke /= 2000; + ke /= 1000; double expected = 1.5 * numParticles * BOLTZ * temp; ASSERT_USUALLY_EQUAL_TOL(expected, ke, 0.01); } diff --git a/platforms/opencl/tests/TestOpenCLLocalEnergyMinimizer.cpp b/platforms/opencl/tests/TestOpenCLLocalEnergyMinimizer.cpp index 24d74d31e..c6ff143a9 100644 --- a/platforms/opencl/tests/TestOpenCLLocalEnergyMinimizer.cpp +++ b/platforms/opencl/tests/TestOpenCLLocalEnergyMinimizer.cpp @@ -77,10 +77,10 @@ void testHarmonicBonds() { } void testLargeSystem() { - const int numMolecules = 50; + const int numMolecules = 25; const int numParticles = numMolecules*2; const double cutoff = 2.0; - const double boxSize = 5.0; + const double boxSize = 4.0; const double tolerance = 5; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); @@ -134,10 +134,10 @@ void testLargeSystem() { } void testVirtualSites() { - const int numMolecules = 50; + const int numMolecules = 25; const int numParticles = numMolecules*3; const double cutoff = 2.0; - const double boxSize = 5.0; + const double boxSize = 4.0; const double tolerance = 5; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); diff --git a/platforms/opencl/tests/TestOpenCLVariableLangevinIntegrator.cpp b/platforms/opencl/tests/TestOpenCLVariableLangevinIntegrator.cpp index fea406d7a..613e4acf0 100644 --- a/platforms/opencl/tests/TestOpenCLVariableLangevinIntegrator.cpp +++ b/platforms/opencl/tests/TestOpenCLVariableLangevinIntegrator.cpp @@ -296,7 +296,7 @@ void testArgonBox() { system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); system.addForce(nonbonded); - VariableLangevinIntegrator integrator(temp, 6.0, 1e-5); + VariableLangevinIntegrator integrator(temp, 6.0, 1e-4); Context context(system, integrator, platform); context.setPositions(positions); context.setVelocitiesToTemperature(temp); @@ -308,13 +308,13 @@ void testArgonBox() { // Make sure the temperature is correct. double ke = 0.0; - for (int i = 0; i < 2000; ++i) { - double t = 2.0 + 0.01 * (i + 1); + for (int i = 0; i < 1000; ++i) { + double t = 2.0 + 0.02 * (i + 1); integrator.stepTo(t); State state = context.getState(State::Energy); ke += state.getKineticEnergy(); } - ke /= 2000; + ke /= 1000; double expected = 1.5 * numParticles * BOLTZ * temp; ASSERT_USUALLY_EQUAL_TOL(expected, ke, 0.01); } diff --git a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp index d8e8a158c..a4209c6e6 100644 --- a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp @@ -383,12 +383,12 @@ void testContinuous3DFunction() { const int xsize = 10; const int ysize = 11; const int zsize = 12; - const double xmin = 0.4; + const double xmin = 0.6; const double xmax = 1.1; const double ymin = 0.0; - const double ymax = 0.9; + const double ymax = 0.7; const double zmin = 0.2; - const double zmax = 1.3; + const double zmax = 0.9; ReferencePlatform platform; System system; system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp b/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp index e628d1e19..f49bed60b 100644 --- a/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp +++ b/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp @@ -76,10 +76,10 @@ void testHarmonicBonds() { } void testLargeSystem() { - const int numMolecules = 50; + const int numMolecules = 25; const int numParticles = numMolecules*2; const double cutoff = 2.0; - const double boxSize = 5.0; + const double boxSize = 4.0; const double tolerance = 5; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); @@ -134,10 +134,10 @@ void testLargeSystem() { } void testVirtualSites() { - const int numMolecules = 50; + const int numMolecules = 25; const int numParticles = numMolecules*3; const double cutoff = 2.0; - const double boxSize = 5.0; + const double boxSize = 4.0; const double tolerance = 5; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); diff --git a/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp b/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp index fb0376378..7fa226530 100644 --- a/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp +++ b/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp @@ -300,7 +300,7 @@ void testArgonBox() { system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); system.addForce(nonbonded); - VariableLangevinIntegrator integrator(temp, 6.0, 1e-5); + VariableLangevinIntegrator integrator(temp, 6.0, 1e-4); Context context(system, integrator, platform); context.setPositions(positions); context.setVelocitiesToTemperature(temp); @@ -312,13 +312,13 @@ void testArgonBox() { // Make sure the temperature is correct. double ke = 0.0; - for (int i = 0; i < 2000; ++i) { - double t = 2.0 + 0.01 * (i + 1); + for (int i = 0; i < 1000; ++i) { + double t = 2.0 + 0.02 * (i + 1); integrator.stepTo(t); State state = context.getState(State::Energy); ke += state.getKineticEnergy(); } - ke /= 2000; + ke /= 1000; double expected = 1.5 * numParticles * BOLTZ * temp; ASSERT_USUALLY_EQUAL_TOL(expected, ke, 0.01); } diff --git a/plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp b/plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp index 6bae52cb0..f046c36e2 100644 --- a/plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp +++ b/plugins/drude/platforms/reference/tests/TestReferenceDrudeLangevinIntegrator.cpp @@ -99,7 +99,7 @@ void testWater() { // Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites, // and Drude particles. - const int gridSize = 4; + const int gridSize = 3; const int numMolecules = gridSize*gridSize*gridSize; const double spacing = 0.6; const double boxSize = spacing*(gridSize+1); diff --git a/plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp b/plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp index 430d2a0f9..4dc85ac3d 100644 --- a/plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp +++ b/plugins/drude/platforms/reference/tests/TestReferenceDrudeSCFIntegrator.cpp @@ -54,7 +54,7 @@ void testWater() { // Create a box of SWM4-NDP water molecules. This involves constraints, virtual sites, // and Drude particles. - const int gridSize = 4; + const int gridSize = 3; const int numMolecules = gridSize*gridSize*gridSize; const double spacing = 0.6; const double boxSize = spacing*(gridSize+1); -- GitLab From 1ce175908f3c65e083b75279309142fc8d2101ee Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 19 Feb 2015 15:22:13 -0800 Subject: [PATCH 269/338] Fixed some test cases that were failing --- platforms/cuda/src/CudaContext.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/platforms/cuda/src/CudaContext.cpp b/platforms/cuda/src/CudaContext.cpp index febdaff34..481fe801f 100644 --- a/platforms/cuda/src/CudaContext.cpp +++ b/platforms/cuda/src/CudaContext.cpp @@ -77,12 +77,14 @@ CudaContext::CudaContext(const System& system, int deviceIndex, bool useBlocking time(0.0), platformData(platformData), stepCount(0), computeForceCount(0), stepsSinceReorder(99999), contextIsValid(false), atomsWereReordered(false), hasCompilerKernel(false), pinnedBuffer(NULL), posq(NULL), posqCorrection(NULL), velm(NULL), force(NULL), energyBuffer(NULL), integration(NULL), expression(NULL), bonded(NULL), nonbonded(NULL), thread(NULL) { this->compiler = "\""+compiler+"\""; - try { - compilerKernel = platformData.context->getPlatform().createKernel(CudaCompilerKernel::Name(), *platformData.context); - hasCompilerKernel = true; - } - catch (...) { - // The runtime compiler plugin isn't available. + if (platformData.context != NULL) { + try { + compilerKernel = platformData.context->getPlatform().createKernel(CudaCompilerKernel::Name(), *platformData.context); + hasCompilerKernel = true; + } + catch (...) { + // The runtime compiler plugin isn't available. + } } if (hostCompiler.size() > 0) this->compiler = compiler+" --compiler-bindir "+hostCompiler; -- GitLab From 9f5a02cd44d9ac35578abeed8a89ada6f39ea695 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 19 Feb 2015 16:52:47 -0800 Subject: [PATCH 270/338] Regenerated AMOEBA2013 based on Tinker 7.0.1 --- devtools/forcefield-scripts/residuesFinal.xml | 945 ++++++++++++++++++ .../simtk/openmm/app/data/amoeba2013.xml | 6 +- .../simtk/openmm/app/data/amoeba2013_gk.xml | 4 +- 3 files changed, 950 insertions(+), 5 deletions(-) create mode 100644 devtools/forcefield-scripts/residuesFinal.xml diff --git a/devtools/forcefield-scripts/residuesFinal.xml b/devtools/forcefield-scripts/residuesFinal.xml new file mode 100644 index 000000000..b19c320bf --- /dev/null +++ b/devtools/forcefield-scripts/residuesFinal.xml @@ -0,0 +1,945 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wrappers/python/simtk/openmm/app/data/amoeba2013.xml b/wrappers/python/simtk/openmm/app/data/amoeba2013.xml index e9af92c80..16a587135 100644 --- a/wrappers/python/simtk/openmm/app/data/amoeba2013.xml +++ b/wrappers/python/simtk/openmm/app/data/amoeba2013.xml @@ -1,7 +1,7 @@ - amoebapro13_5-2014.prm - 2014-05-08 + amoebapro13.prm + 2015-02-19 Yue Shi, Zhen Xia, Jiajing Zhang, Robert Best, Chuanjie Wu, Jay W. Ponder, and Pengyu Ren. Polarizable Atomic Multipole-Based AMOEBA Force Field for Proteins. Journal of Chemical Theory and Computation, 9(9):4046–4063, 2013. @@ -170,7 +170,7 @@ - + diff --git a/wrappers/python/simtk/openmm/app/data/amoeba2013_gk.xml b/wrappers/python/simtk/openmm/app/data/amoeba2013_gk.xml index a887290b3..4276a8a5a 100644 --- a/wrappers/python/simtk/openmm/app/data/amoeba2013_gk.xml +++ b/wrappers/python/simtk/openmm/app/data/amoeba2013_gk.xml @@ -1,7 +1,7 @@ - amoebapro13_5-2014.prm - 2014-05-08 + amoebapro13.prm + 2015-02-19 Yue Shi, Zhen Xia, Jiajing Zhang, Robert Best, Chuanjie Wu, Jay W. Ponder, and Pengyu Ren. Polarizable Atomic Multipole-Based AMOEBA Force Field for Proteins. Journal of Chemical Theory and Computation, 9(9):4046–4063, 2013. -- GitLab From 1004e6e5b02f122d2a1ea366312421167c2231b3 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 19 Feb 2015 20:23:05 -0500 Subject: [PATCH 271/338] Fix bug in unitcell.py (computeLengthsAndAngles), which resulted in a NameError. Also added a test suite for them. --- .../simtk/openmm/app/internal/unitcell.py | 4 +- wrappers/python/tests/TestUnitCell.py | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 wrappers/python/tests/TestUnitCell.py diff --git a/wrappers/python/simtk/openmm/app/internal/unitcell.py b/wrappers/python/simtk/openmm/app/internal/unitcell.py index 1c4e6d6ba..3b2249c16 100644 --- a/wrappers/python/simtk/openmm/app/internal/unitcell.py +++ b/wrappers/python/simtk/openmm/app/internal/unitcell.py @@ -85,9 +85,9 @@ def computeLengthsAndAngles(periodicBoxVectors): Lengths are returned in nanometers and angles in radians. """ if is_quantity(periodicBoxVectors): - (a, b, c) = vectors.value_in_unit(nanometers) + (a, b, c) = periodicBoxVectors.value_in_unit(nanometers) else: - a, b, c = vectors + a, b, c = periodicBoxVectors a_length = norm(a) b_length = norm(b) c_length = norm(c) diff --git a/wrappers/python/tests/TestUnitCell.py b/wrappers/python/tests/TestUnitCell.py new file mode 100644 index 000000000..3477ebffb --- /dev/null +++ b/wrappers/python/tests/TestUnitCell.py @@ -0,0 +1,64 @@ +import unittest +import math +from simtk.unit import * +from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors +from simtk.openmm.app.internal.unitcell import computeLengthsAndAngles + +def strip_units(x): + if is_quantity(x): return x.value_in_unit_system(md_unit_system) + return x + +class TestAmberPrmtopFile(unittest.TestCase): + + """Test the AmberPrmtopFile.createSystem() method.""" + + def testComputePBCVectors(self): + """ Tests computing periodic box vectors """ + deg90 = 90 * degrees + vecs = computePeriodicBoxVectors(1, 2, 3, deg90, deg90, deg90) + a, b, c = vecs + self.assertAlmostEqual(a[0]/nanometers, 1) + self.assertAlmostEqual(a[1]/nanometers, 0) + self.assertAlmostEqual(a[2]/nanometers, 0) + self.assertAlmostEqual(b[0]/nanometers, 0) + self.assertAlmostEqual(b[1]/nanometers, 2) + self.assertAlmostEqual(b[2]/nanometers, 0) + self.assertAlmostEqual(c[0]/nanometers, 0) + self.assertAlmostEqual(c[1]/nanometers, 0) + self.assertAlmostEqual(c[2]/nanometers, 3) + + # Make sure round-trip works + la, lb, lc, al, be, ga = computeLengthsAndAngles(vecs) + self.assertAlmostEqual(la, 1) + self.assertAlmostEqual(lb, 2) + self.assertAlmostEqual(lc, 3) + self.assertAlmostEqual(al, math.pi / 2) + self.assertAlmostEqual(be, math.pi / 2) + self.assertAlmostEqual(ga, math.pi / 2) + + # Now test a truncated octahedron. Can't do a simple round-trip though, + # due to the reduced form. So test the *second* round-trip, which should + # yield the same measurements + vecs = computePeriodicBoxVectors(4.24388485, 4.24388485, 4.24388485, + 109.4712190*degrees, 109.4712190*degrees, 109.4712190*degrees) + la, lb, lc, al, be, ga = computeLengthsAndAngles(vecs) + vecs2 = computePeriodicBoxVectors(la, lb, lc, al, be, ga) + la2, lb2, lc2, al2, be2, ga2 = computeLengthsAndAngles(vecs2) + + # Now make sure that the round-trip worked + self.assertAlmostEqual(strip_units(la), strip_units(la2)) + self.assertAlmostEqual(strip_units(lb), strip_units(lb2)) + self.assertAlmostEqual(strip_units(lc), strip_units(lc2)) + self.assertAlmostEqual(strip_units(al), strip_units(al2)) + self.assertAlmostEqual(strip_units(be), strip_units(be2)) + self.assertAlmostEqual(strip_units(ga), strip_units(ga2)) + + # Check that the vectors are the same + a1, a2, a3 = vecs + b1, b2, b3 = vecs2 + for x, y in zip(a1, b1): + self.assertAlmostEqual(strip_units(x), strip_units(y)) + for x, y in zip(a2, b2): + self.assertAlmostEqual(strip_units(x), strip_units(y)) + for x, y in zip(a3, b3): + self.assertAlmostEqual(strip_units(x), strip_units(y)) -- GitLab From fd1827e08e35defdffb3e374403fd911469e5032 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 19 Feb 2015 20:32:54 -0500 Subject: [PATCH 272/338] Add a reducePeriodicBoxVectors function, since many helpers (like the one in mdtraj) does *not* fully reduce the vectors. Also adds a test for this. --- .../simtk/openmm/app/internal/unitcell.py | 18 ++++++++++++++++ wrappers/python/tests/TestUnitCell.py | 21 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/wrappers/python/simtk/openmm/app/internal/unitcell.py b/wrappers/python/simtk/openmm/app/internal/unitcell.py index 3b2249c16..308415d83 100644 --- a/wrappers/python/simtk/openmm/app/internal/unitcell.py +++ b/wrappers/python/simtk/openmm/app/internal/unitcell.py @@ -79,6 +79,24 @@ def computePeriodicBoxVectors(a_length, b_length, c_length, alpha, beta, gamma): b = b - a*round(b[0]/a[0]) return (a, b, c)*nanometers +def reducePeriodicBoxVectors(periodicBoxVectors): + """ Reduces the representation of the PBC. periodicBoxVectors is expected to + be an unpackable iterable of length-3 iterables + """ + if is_quantity(periodicBoxVectors): + a, b, c = periodicBoxVectors.value_in_unit(nanometers) + else: + a, b, c = periodicBoxVectors + a = Vec3(*a) + b = Vec3(*b) + c = Vec3(*c) + + c = c - b*round(c[1]/b[1]) + c = c - a*round(c[0]/a[0]) + b = b - a*round(b[0]/a[0]) + + return (a, b, c) * nanometers + def computeLengthsAndAngles(periodicBoxVectors): """Convert periodic box vectors to lengths and angles. diff --git a/wrappers/python/tests/TestUnitCell.py b/wrappers/python/tests/TestUnitCell.py index 3477ebffb..c304e78a8 100644 --- a/wrappers/python/tests/TestUnitCell.py +++ b/wrappers/python/tests/TestUnitCell.py @@ -1,8 +1,10 @@ import unittest import math +from simtk.openmm import Vec3 from simtk.unit import * from simtk.openmm.app.internal.unitcell import computePeriodicBoxVectors from simtk.openmm.app.internal.unitcell import computeLengthsAndAngles +from simtk.openmm.app.internal.unitcell import reducePeriodicBoxVectors def strip_units(x): if is_quantity(x): return x.value_in_unit_system(md_unit_system) @@ -12,6 +14,25 @@ class TestAmberPrmtopFile(unittest.TestCase): """Test the AmberPrmtopFile.createSystem() method.""" + def testReducePBCVectors(self): + """ Checks that reducePeriodicBoxVectors properly reduces vectors """ + a = Vec3(4.24388485, 0.0, 0.0) + b = Vec3(-1.4146281691908937, 4.001173048368583, 0.0) + c = Vec3(-1.4146281691908937, -2.0005862820516203, 3.4651176446201674) + vecs = reducePeriodicBoxVectors((a, b, c)*nanometers) + vecs2 = computePeriodicBoxVectors(4.24388485, 4.24388485, 4.24388485, + 109.4712190*degrees, 109.4712190*degrees, 109.4712190*degrees) + + # Check that the vectors are the same + a1, a2, a3 = vecs + b1, b2, b3 = vecs2 + for x, y in zip(a1, b1): + self.assertAlmostEqual(strip_units(x), strip_units(y)) + for x, y in zip(a2, b2): + self.assertAlmostEqual(strip_units(x), strip_units(y)) + for x, y in zip(a3, b3): + self.assertAlmostEqual(strip_units(x), strip_units(y)) + def testComputePBCVectors(self): """ Tests computing periodic box vectors """ deg90 = 90 * degrees -- GitLab From 7a60e4343e3e7157380bac641396a5250549deb9 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Fri, 20 Feb 2015 13:07:05 -0500 Subject: [PATCH 273/338] Fix names. --- wrappers/python/tests/TestUnitCell.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/tests/TestUnitCell.py b/wrappers/python/tests/TestUnitCell.py index c304e78a8..fe5a86a59 100644 --- a/wrappers/python/tests/TestUnitCell.py +++ b/wrappers/python/tests/TestUnitCell.py @@ -10,9 +10,9 @@ def strip_units(x): if is_quantity(x): return x.value_in_unit_system(md_unit_system) return x -class TestAmberPrmtopFile(unittest.TestCase): +class TestUnitCell(unittest.TestCase): - """Test the AmberPrmtopFile.createSystem() method.""" + """ Test the unitcell.py module """ def testReducePBCVectors(self): """ Checks that reducePeriodicBoxVectors properly reduces vectors """ -- GitLab From 65d0449ebfc62a405170730f7d10734e57608ada Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 10:23:10 -0800 Subject: [PATCH 274/338] Added removeForce() and removeConstraint() to System --- openmmapi/include/openmm/System.h | 13 ++++ openmmapi/src/System.cpp | 14 +++- tests/TestSystem.cpp | 124 ++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 tests/TestSystem.cpp diff --git a/openmmapi/include/openmm/System.h b/openmmapi/include/openmm/System.h index 829e6887b..f9fcf79ce 100644 --- a/openmmapi/include/openmm/System.h +++ b/openmmapi/include/openmm/System.h @@ -168,6 +168,12 @@ public: * @param distance the required distance between the two particles, measured in nm */ void setConstraintParameters(int index, int particle1, int particle2, double distance); + /** + * Remove a constraint from the System. + * + * @param index the index of the constraint to remove + */ + void removeConstraint(int index); /** * Add a Force to the System. The Force should have been created on the heap with the * "new" operator. The System takes over ownership of it, and deletes the Force when the @@ -198,6 +204,13 @@ public: * @param index the index of the Force to get */ Force& getForce(int index); + /** + * Remove a Force from the System. The memory associated with the removed Force + * object is deleted. + * + * @param index the index of the Force to remove + */ + void removeForce(int index); /** * Get the default values of the vectors defining the axes of the periodic box (measured in nm). Any newly * created Context will have its box vectors set to these. They will affect diff --git a/openmmapi/src/System.cpp b/openmmapi/src/System.cpp index 987d52eca..c59535656 100644 --- a/openmmapi/src/System.cpp +++ b/openmmapi/src/System.cpp @@ -61,10 +61,11 @@ void System::setParticleMass(int index, double mass) { masses[index] = mass; } - void System::setVirtualSite(int index, VirtualSite* virtualSite) { if (index >= (int) virtualSites.size()) virtualSites.resize(getNumParticles(), NULL); + if (virtualSites[index] != NULL) + delete virtualSites[index]; virtualSites[index] = virtualSite; } @@ -93,6 +94,11 @@ void System::setConstraintParameters(int index, int particle1, int particle2, do constraints[index].distance = distance; } +void System::removeConstraint(int index) { + ASSERT_VALID_INDEX(index, constraints); + constraints.erase(constraints.begin()+index); +} + const Force& System::getForce(int index) const { ASSERT_VALID_INDEX(index, forces); return *forces[index]; @@ -103,6 +109,12 @@ Force& System::getForce(int index) { return *forces[index]; } +void System::removeForce(int index) { + ASSERT_VALID_INDEX(index, forces); + delete forces[index]; + forces.erase(forces.begin()+index); +} + void System::getDefaultPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) const { a = periodicBoxVectors[0]; b = periodicBoxVectors[1]; diff --git a/tests/TestSystem.cpp b/tests/TestSystem.cpp new file mode 100644 index 000000000..471ac15a2 --- /dev/null +++ b/tests/TestSystem.cpp @@ -0,0 +1,124 @@ +/* -------------------------------------------------------------------------- * + * 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) 2015 Stanford University and the Authors. * + * Authors: Peter Eastman * + * 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/internal/AssertionUtilities.h" +#include "openmm/HarmonicAngleForce.h" +#include "openmm/HarmonicBondForce.h" +#include "openmm/System.h" +#include "openmm/VirtualSite.h" +#include + +using namespace OpenMM; +using namespace std; + +/** + * Test the methods for manipulating System objects. + */ +void testCreateSystem() { + int numParticles = 10; + System system; + + // Test adding and modifying particles. + + for (int i = 0; i < numParticles; i++) + system.addParticle(1.0+0.1*i); + system.setParticleMass(5, 100.0); + ASSERT_EQUAL(numParticles, system.getNumParticles()); + for (int i = 0; i < numParticles; i++) { + double mass = (i == 5 ? 100.0 : 1.0+0.1*i); + ASSERT_EQUAL(mass, system.getParticleMass(i)); + } + + // Test adding, removing, and modifying constraints. + + for (int i = 0; i < numParticles-1; i++) + system.addConstraint(i, i+1, 0.2*i); + system.removeConstraint(5); + system.setConstraintParameters(3, 0, 5, 99.0); + ASSERT_EQUAL(numParticles-2, system.getNumConstraints()); + for (int i = 0; i < numParticles-2; i++) { + int p1, p2; + double dist; + system.getConstraintParameters(i, p1, p2, dist); + if (i == 3) { + ASSERT_EQUAL(0, p1); + ASSERT_EQUAL(5, p2); + ASSERT_EQUAL(99.0, dist); + } + else { + int j = (i < 5 ? i : i+1); + ASSERT_EQUAL(j, p1); + ASSERT_EQUAL(j+1, p2); + ASSERT_EQUAL(0.2*j, dist); + } + } + + // Test adding and removing forces. + + HarmonicBondForce* bonds = new HarmonicBondForce(); + system.addForce(bonds); + HarmonicAngleForce* angles = new HarmonicAngleForce(); + system.addForce(angles); + ASSERT_EQUAL(2, system.getNumForces()); + ASSERT_EQUAL(bonds, &system.getForce(0)); + ASSERT_EQUAL(angles, &system.getForce(1)); + system.removeForce(0); + ASSERT_EQUAL(1, system.getNumForces()); + ASSERT_EQUAL(angles, &system.getForce(0)); + + // Test adding and removing virtual sites. + + for (int i = 0; i < numParticles; i++) { + ASSERT_EQUAL(false, system.isVirtualSite(i)); + } + TwoParticleAverageSite* site = new TwoParticleAverageSite(2, 3, 0.4, 0.6); + system.setVirtualSite(4, site); + for (int i = 0; i < numParticles; i++) { + ASSERT_EQUAL(i == 4, system.isVirtualSite(i)); + } + ASSERT_EQUAL(site, &system.getVirtualSite(4)); + system.setVirtualSite(4, NULL); + for (int i = 0; i < numParticles; i++) { + ASSERT_EQUAL(false, system.isVirtualSite(i)); + } +} + +int main() { + try { + testCreateSystem(); + } + catch(const exception& e) { + cout << "exception: " << e.what() << endl; + return 1; + } + cout << "Done" << endl; + return 0; +} -- GitLab From 89ab01de75354e4aa96dc974bfffb083c4c3be9a Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 11:04:49 -0800 Subject: [PATCH 275/338] Fixed an incorrect unit conversion when constraining angles with AMOEBA --- wrappers/python/simtk/openmm/app/forcefield.py | 5 +++-- wrappers/python/tests/TestForceField.py | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/forcefield.py b/wrappers/python/simtk/openmm/app/forcefield.py index 48da5edda..e0480a727 100644 --- a/wrappers/python/simtk/openmm/app/forcefield.py +++ b/wrappers/python/simtk/openmm/app/forcefield.py @@ -34,6 +34,7 @@ __version__ = "1.0" import os import itertools import xml.etree.ElementTree as etree +import math from math import sqrt, cos import simtk.openmm as mm import simtk.unit as unit @@ -2101,7 +2102,7 @@ class AmoebaAngleGenerator: hit = 1 if isConstrained and self.k[i] != 0.0: angleDict['idealAngle'] = self.angle[i][0] - addAngleConstraint(angle, self.angle[i][0], data, sys) + addAngleConstraint(angle, self.angle[i][0]*math.pi/180.0, data, sys) elif self.k[i] != 0: lenAngle = len(self.angle[i]) if (lenAngle > 1): @@ -2179,7 +2180,7 @@ class AmoebaAngleGenerator: hit = 1 angleDict['idealAngle'] = self.angle[i][0] if (isConstrained and self.k[i] != 0.0): - addAngleConstraint(angle, self.angle[i][0], data, sys) + addAngleConstraint(angle, self.angle[i][0]*math.pi/180.0, data, sys) else: force.addAngle(angle[0], angle[1], angle[2], angle[3], self.angle[i][0], self.k[i]) break diff --git a/wrappers/python/tests/TestForceField.py b/wrappers/python/tests/TestForceField.py index 740462f08..c49440be7 100644 --- a/wrappers/python/tests/TestForceField.py +++ b/wrappers/python/tests/TestForceField.py @@ -5,6 +5,7 @@ from simtk.openmm import * from simtk.unit import * import simtk.openmm.app.element as elem import simtk.openmm.app.forcefield as forcefield +import math class TestForceField(unittest.TestCase): """Test the ForceField.createSystem() method.""" @@ -208,7 +209,7 @@ class AmoebaTestForceField(unittest.TestCase): """ self.pdb1 = PDBFile('systems/amoeba-ion-in-water.pdb') - self.forcefield1 = ForceField('amoeba2009.xml') + self.forcefield1 = ForceField('amoeba2013.xml') self.topology1 = self.pdb1.topology @@ -253,6 +254,21 @@ class AmoebaTestForceField(unittest.TestCase): if isinstance(force, AmoebaVdwForce): self.assertEqual(useDispersionCorrection, force.getUseDispersionCorrection()) + def test_RigidWater(self): + """Test that AMOEBA creates rigid water with the correct geometry.""" + + system = self.forcefield1.createSystem(self.pdb1.topology, rigidWater=True) + constraints = dict() + for i in range(system.getNumConstraints()): + p1,p2,dist = system.getConstraintParameters(i) + if p1 < 3: + constraints[(min(p1,p2), max(p1,p2))] = dist.value_in_unit(nanometers) + hoDist = 0.09572 + hohAngle = 108.50*math.pi/180.0 + hohDist = math.sqrt(2*hoDist**2 - 2*hoDist**2*math.cos(hohAngle)) + self.assertAlmostEqual(constraints[(0,1)], hoDist) + self.assertAlmostEqual(constraints[(0,2)], hoDist) + self.assertAlmostEqual(constraints[(1,2)], hohDist) if __name__ == '__main__': unittest.main() -- GitLab From 9111cca092a59ae505625da07abf5c7d41a80925 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 14:40:07 -0800 Subject: [PATCH 276/338] Moved reference platform classes into OpenMM namespace --- platforms/cpu/include/CpuLangevinDynamics.h | 4 ++-- platforms/reference/include/CpuGBVI.h | 4 ++-- platforms/reference/include/CpuObc.h | 4 ++-- platforms/reference/include/GBVIParameters.h | 6 ++++-- platforms/reference/include/ObcParameters.h | 6 +++--- .../reference/include/ReferenceAndersenThermostat.h | 4 ++-- platforms/reference/include/ReferenceAngleBondIxn.h | 4 ++-- platforms/reference/include/ReferenceBondForce.h | 4 ++-- platforms/reference/include/ReferenceBondIxn.h | 4 ++-- .../reference/include/ReferenceBrownianDynamics.h | 4 ++-- platforms/reference/include/ReferenceCCMAAlgorithm.h | 4 ++-- platforms/reference/include/ReferenceCMAPTorsionIxn.h | 4 +++- .../reference/include/ReferenceConstraintAlgorithm.h | 4 +++- platforms/reference/include/ReferenceCustomAngleIxn.h | 4 ++-- platforms/reference/include/ReferenceCustomBondIxn.h | 4 ++-- .../include/ReferenceCustomCompoundBondIxn.h | 4 +++- platforms/reference/include/ReferenceCustomDynamics.h | 4 ++-- .../reference/include/ReferenceCustomExternalIxn.h | 4 ++-- platforms/reference/include/ReferenceCustomGBIxn.h | 4 +++- platforms/reference/include/ReferenceCustomHbondIxn.h | 4 +++- .../include/ReferenceCustomManyParticleIxn.h | 4 +++- .../reference/include/ReferenceCustomNonbondedIxn.h | 4 +++- .../reference/include/ReferenceCustomTorsionIxn.h | 4 ++-- platforms/reference/include/ReferenceDynamics.h | 5 +++-- platforms/reference/include/ReferenceForce.h | 4 ++-- .../reference/include/ReferenceHarmonicBondIxn.h | 4 ++-- platforms/reference/include/ReferenceKernels.h | 4 ++-- platforms/reference/include/ReferenceLJCoulomb14.h | 4 ++-- platforms/reference/include/ReferenceLJCoulombIxn.h | 4 ++-- platforms/reference/include/ReferenceLincsAlgorithm.h | 4 ++-- .../reference/include/ReferenceMonteCarloBarostat.h | 4 ++-- platforms/reference/include/ReferencePME.h | 9 +++++++++ platforms/reference/include/ReferencePairIxn.h | 4 ++-- .../reference/include/ReferenceProperDihedralBond.h | 4 ++-- platforms/reference/include/ReferenceRbDihedralBond.h | 4 ++-- .../reference/include/ReferenceStochasticDynamics.h | 4 ++-- .../include/ReferenceVariableStochasticDynamics.h | 4 ++-- .../include/ReferenceVariableVerletDynamics.h | 4 ++-- platforms/reference/include/ReferenceVerletDynamics.h | 4 ++-- platforms/reference/include/ReferenceVirtualSites.h | 4 ++++ platforms/reference/include/SimTKOpenMMCommon.h | 11 +++-------- platforms/reference/include/SimTKOpenMMLog.h | 4 ++++ platforms/reference/include/SimTKOpenMMUtilities.h | 6 ++++-- .../SimTKReference/ReferenceAndersenThermostat.cpp | 2 +- .../src/SimTKReference/ReferenceAngleBondIxn.cpp | 2 +- .../src/SimTKReference/ReferenceBondForce.cpp | 2 +- .../reference/src/SimTKReference/ReferenceBondIxn.cpp | 2 +- .../src/SimTKReference/ReferenceBrownianDynamics.cpp | 2 +- .../src/SimTKReference/ReferenceCCMAAlgorithm.cpp | 4 +--- .../src/SimTKReference/ReferenceCMAPTorsionIxn.cpp | 2 +- .../SimTKReference/ReferenceCustomCompoundBondIxn.cpp | 2 +- .../src/SimTKReference/ReferenceCustomGBIxn.cpp | 2 +- .../src/SimTKReference/ReferenceCustomHbondIxn.cpp | 2 +- .../SimTKReference/ReferenceCustomNonbondedIxn.cpp | 2 +- .../src/SimTKReference/ReferenceDynamics.cpp | 2 +- .../reference/src/SimTKReference/ReferenceForce.cpp | 2 +- .../src/SimTKReference/ReferenceHarmonicBondIxn.cpp | 2 +- .../src/SimTKReference/ReferenceLJCoulomb14.cpp | 2 +- .../src/SimTKReference/ReferenceLJCoulombIxn.cpp | 2 +- .../src/SimTKReference/ReferenceLincsAlgorithm.cpp | 2 +- .../reference/src/SimTKReference/ReferencePME.cpp | 4 +++- .../reference/src/SimTKReference/ReferencePairIxn.cpp | 2 ++ .../SimTKReference/ReferenceProperDihedralBond.cpp | 2 +- .../src/SimTKReference/ReferenceRbDihedralBond.cpp | 2 +- .../SimTKReference/ReferenceStochasticDynamics.cpp | 2 +- .../ReferenceVariableStochasticDynamics.cpp | 2 +- .../ReferenceVariableVerletDynamics.cpp | 2 +- .../src/SimTKReference/ReferenceVerletDynamics.cpp | 2 +- .../src/SimTKUtilities/SimTKOpenMMCommon.cpp | 2 ++ .../reference/src/SimTKUtilities/SimTKOpenMMLog.cpp | 2 ++ .../src/SimTKUtilities/SimTKOpenMMUtilities.cpp | 2 ++ platforms/reference/src/gbsa/GBVIParameters.cpp | 2 +- platforms/reference/src/gbsa/ObcParameters.cpp | 1 + 73 files changed, 147 insertions(+), 107 deletions(-) diff --git a/platforms/cpu/include/CpuLangevinDynamics.h b/platforms/cpu/include/CpuLangevinDynamics.h index 609b098a3..416104229 100644 --- a/platforms/cpu/include/CpuLangevinDynamics.h +++ b/platforms/cpu/include/CpuLangevinDynamics.h @@ -31,7 +31,7 @@ #include "openmm/internal/ThreadPool.h" #include "sfmt/SFMT.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class CpuLangevinDynamics : public ReferenceStochasticDynamics { public: @@ -95,6 +95,6 @@ private: OpenMM::RealVec* xPrime; }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __CPU_LANGEVIN_DYNAMICS_H__ diff --git a/platforms/reference/include/CpuGBVI.h b/platforms/reference/include/CpuGBVI.h index cc7f09b12..2c00529f8 100644 --- a/platforms/reference/include/CpuGBVI.h +++ b/platforms/reference/include/CpuGBVI.h @@ -30,7 +30,7 @@ #include "RealVec.h" #include "GBVIParameters.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class CpuGBVI { @@ -311,6 +311,6 @@ class CpuGBVI { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __CpuGBVI_H__ diff --git a/platforms/reference/include/CpuObc.h b/platforms/reference/include/CpuObc.h index 53a5f352e..5e8879e72 100644 --- a/platforms/reference/include/CpuObc.h +++ b/platforms/reference/include/CpuObc.h @@ -27,7 +27,7 @@ #include "ObcParameters.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class CpuObc { @@ -181,6 +181,6 @@ class CpuObc { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __CpuObc_H__ diff --git a/platforms/reference/include/GBVIParameters.h b/platforms/reference/include/GBVIParameters.h index 425039e47..44e3403e7 100644 --- a/platforms/reference/include/GBVIParameters.h +++ b/platforms/reference/include/GBVIParameters.h @@ -27,7 +27,7 @@ #include "SimTKOpenMMCommon.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class GBVIParameters { @@ -337,5 +337,7 @@ class GBVIParameters { void setQuinticUpperBornRadiusLimit( RealOpenMM quinticUpperSplineLimit ); }; - + +} // namespace OpenMM + #endif // __GBVIParameters_H__ diff --git a/platforms/reference/include/ObcParameters.h b/platforms/reference/include/ObcParameters.h index c55eef696..3eb10c706 100644 --- a/platforms/reference/include/ObcParameters.h +++ b/platforms/reference/include/ObcParameters.h @@ -27,7 +27,7 @@ #include "SimTKOpenMMCommon.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ObcParameters { @@ -352,7 +352,7 @@ class ObcParameters { const OpenMM::RealVec* getPeriodicBox(); }; - -// --------------------------------------------------------------------------------------- + +} // namespace OpenMM #endif // __ObcParameters_H__ diff --git a/platforms/reference/include/ReferenceAndersenThermostat.h b/platforms/reference/include/ReferenceAndersenThermostat.h index 8cfab6772..e4dbba765 100644 --- a/platforms/reference/include/ReferenceAndersenThermostat.h +++ b/platforms/reference/include/ReferenceAndersenThermostat.h @@ -28,7 +28,7 @@ #include "SimTKOpenMMCommon.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceAndersenThermostat { @@ -70,6 +70,6 @@ class ReferenceAndersenThermostat { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceAndersenThermostat_H__ diff --git a/platforms/reference/include/ReferenceAngleBondIxn.h b/platforms/reference/include/ReferenceAngleBondIxn.h index e7bd2d7a0..226515b65 100644 --- a/platforms/reference/include/ReferenceAngleBondIxn.h +++ b/platforms/reference/include/ReferenceAngleBondIxn.h @@ -27,7 +27,7 @@ #include "ReferenceBondIxn.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceAngleBondIxn : public ReferenceBondIxn { @@ -86,6 +86,6 @@ class ReferenceAngleBondIxn : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceAngleBondIxn_H__ diff --git a/platforms/reference/include/ReferenceBondForce.h b/platforms/reference/include/ReferenceBondForce.h index 4d4d61296..db836d635 100644 --- a/platforms/reference/include/ReferenceBondForce.h +++ b/platforms/reference/include/ReferenceBondForce.h @@ -28,7 +28,7 @@ #include "ReferenceForce.h" #include "ReferenceBondIxn.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceBondForce : public ReferenceForce { @@ -74,6 +74,6 @@ class OPENMM_EXPORT ReferenceBondForce : public ReferenceForce { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceBondForce_H__ diff --git a/platforms/reference/include/ReferenceBondIxn.h b/platforms/reference/include/ReferenceBondIxn.h index 57ecb4916..d07e84d79 100644 --- a/platforms/reference/include/ReferenceBondIxn.h +++ b/platforms/reference/include/ReferenceBondIxn.h @@ -29,7 +29,7 @@ #include "openmm/internal/windowsExport.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceBondIxn { @@ -126,6 +126,6 @@ class OPENMM_EXPORT ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceBondIxn_H__ diff --git a/platforms/reference/include/ReferenceBrownianDynamics.h b/platforms/reference/include/ReferenceBrownianDynamics.h index f8c6319e7..935545123 100644 --- a/platforms/reference/include/ReferenceBrownianDynamics.h +++ b/platforms/reference/include/ReferenceBrownianDynamics.h @@ -27,7 +27,7 @@ #include "ReferenceDynamics.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceBrownianDynamics : public ReferenceDynamics { @@ -88,6 +88,6 @@ class ReferenceBrownianDynamics : public ReferenceDynamics { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceBrownianDynamics_H__ diff --git a/platforms/reference/include/ReferenceCCMAAlgorithm.h b/platforms/reference/include/ReferenceCCMAAlgorithm.h index d01c5fd11..d1e7d5fe7 100644 --- a/platforms/reference/include/ReferenceCCMAAlgorithm.h +++ b/platforms/reference/include/ReferenceCCMAAlgorithm.h @@ -30,7 +30,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceCCMAAlgorithm : public ReferenceConstraintAlgorithm { @@ -120,6 +120,6 @@ public: } }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceCCMAAlgorithm_H__ diff --git a/platforms/reference/include/ReferenceCMAPTorsionIxn.h b/platforms/reference/include/ReferenceCMAPTorsionIxn.h index c03654acb..23019c728 100644 --- a/platforms/reference/include/ReferenceCMAPTorsionIxn.h +++ b/platforms/reference/include/ReferenceCMAPTorsionIxn.h @@ -30,7 +30,7 @@ #include "ReferenceBondIxn.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCMAPTorsionIxn : public ReferenceBondIxn { @@ -92,4 +92,6 @@ public: }; +} // namespace OpenMM + #endif // __ReferenceCMAPTorsionIxn_H__ diff --git a/platforms/reference/include/ReferenceConstraintAlgorithm.h b/platforms/reference/include/ReferenceConstraintAlgorithm.h index 3e24c23b6..e3f06875f 100644 --- a/platforms/reference/include/ReferenceConstraintAlgorithm.h +++ b/platforms/reference/include/ReferenceConstraintAlgorithm.h @@ -28,6 +28,8 @@ #include "SimTKOpenMMCommon.h" #include "openmm/internal/windowsExport.h" +namespace OpenMM { + /** * This abstract class defines the interface which constraint algorithms must implement. */ @@ -59,6 +61,6 @@ public: std::vector& velocities, std::vector& inverseMasses, RealOpenMM tolerance) = 0; }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceConstraintAlgorithm_H__ diff --git a/platforms/reference/include/ReferenceCustomAngleIxn.h b/platforms/reference/include/ReferenceCustomAngleIxn.h index 541fac9c4..e98584929 100644 --- a/platforms/reference/include/ReferenceCustomAngleIxn.h +++ b/platforms/reference/include/ReferenceCustomAngleIxn.h @@ -27,7 +27,7 @@ #include "ReferenceBondIxn.h" #include "lepton/CompiledExpression.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomAngleIxn : public ReferenceBondIxn { @@ -78,6 +78,6 @@ class ReferenceCustomAngleIxn : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _ReferenceCustomAngleIxn___ diff --git a/platforms/reference/include/ReferenceCustomBondIxn.h b/platforms/reference/include/ReferenceCustomBondIxn.h index f674409b6..b9fffd846 100644 --- a/platforms/reference/include/ReferenceCustomBondIxn.h +++ b/platforms/reference/include/ReferenceCustomBondIxn.h @@ -28,7 +28,7 @@ #include "ReferenceBondIxn.h" #include "lepton/CompiledExpression.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomBondIxn : public ReferenceBondIxn { @@ -79,6 +79,6 @@ class ReferenceCustomBondIxn : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _ReferenceCustomBondIxn___ diff --git a/platforms/reference/include/ReferenceCustomCompoundBondIxn.h b/platforms/reference/include/ReferenceCustomCompoundBondIxn.h index 7aba01879..d453550b0 100644 --- a/platforms/reference/include/ReferenceCustomCompoundBondIxn.h +++ b/platforms/reference/include/ReferenceCustomCompoundBondIxn.h @@ -31,7 +31,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomCompoundBondIxn : public ReferenceBondIxn { @@ -169,4 +169,6 @@ public: } }; +} // namespace OpenMM + #endif // __ReferenceCustomCompoundBondIxn_H__ diff --git a/platforms/reference/include/ReferenceCustomDynamics.h b/platforms/reference/include/ReferenceCustomDynamics.h index 837d1e053..a9b55ea7c 100644 --- a/platforms/reference/include/ReferenceCustomDynamics.h +++ b/platforms/reference/include/ReferenceCustomDynamics.h @@ -34,7 +34,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomDynamics : public ReferenceDynamics { private: @@ -121,6 +121,6 @@ public: std::map& globals, std::vector >& perDof, bool& forcesAreValid); }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceCustomDynamics_H__ diff --git a/platforms/reference/include/ReferenceCustomExternalIxn.h b/platforms/reference/include/ReferenceCustomExternalIxn.h index 1f803deac..cae1f8da4 100644 --- a/platforms/reference/include/ReferenceCustomExternalIxn.h +++ b/platforms/reference/include/ReferenceCustomExternalIxn.h @@ -28,7 +28,7 @@ #include "ReferenceCustomExternalIxn.h" #include "lepton/CompiledExpression.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomExternalIxn { @@ -85,6 +85,6 @@ class ReferenceCustomExternalIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _ReferenceCustomBondIxn___ diff --git a/platforms/reference/include/ReferenceCustomGBIxn.h b/platforms/reference/include/ReferenceCustomGBIxn.h index b92211f05..c6c642898 100644 --- a/platforms/reference/include/ReferenceCustomGBIxn.h +++ b/platforms/reference/include/ReferenceCustomGBIxn.h @@ -32,7 +32,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomGBIxn { @@ -290,4 +290,6 @@ class ReferenceCustomGBIxn { }; +} // namespace OpenMM + #endif // __ReferenceCustomGBIxn_H__ diff --git a/platforms/reference/include/ReferenceCustomHbondIxn.h b/platforms/reference/include/ReferenceCustomHbondIxn.h index d6052d514..4a55c4a18 100644 --- a/platforms/reference/include/ReferenceCustomHbondIxn.h +++ b/platforms/reference/include/ReferenceCustomHbondIxn.h @@ -32,7 +32,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomHbondIxn : public ReferenceBondIxn { @@ -198,4 +198,6 @@ public: } }; +} // namespace OpenMM + #endif // __ReferenceCustomHbondIxn_H__ diff --git a/platforms/reference/include/ReferenceCustomManyParticleIxn.h b/platforms/reference/include/ReferenceCustomManyParticleIxn.h index 616caf4d3..4f56cdf93 100644 --- a/platforms/reference/include/ReferenceCustomManyParticleIxn.h +++ b/platforms/reference/include/ReferenceCustomManyParticleIxn.h @@ -33,7 +33,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomManyParticleIxn { @@ -192,4 +192,6 @@ public: } }; +} // namespace OpenMM + #endif // __ReferenceCustomManyParticleIxn_H__ diff --git a/platforms/reference/include/ReferenceCustomNonbondedIxn.h b/platforms/reference/include/ReferenceCustomNonbondedIxn.h index 4ac419ca8..91b3f9854 100644 --- a/platforms/reference/include/ReferenceCustomNonbondedIxn.h +++ b/platforms/reference/include/ReferenceCustomNonbondedIxn.h @@ -33,7 +33,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomNonbondedIxn { @@ -161,4 +161,6 @@ class ReferenceCustomNonbondedIxn { }; +} // namespace OpenMM + #endif // __ReferenceCustomNonbondedxIxn_H__ diff --git a/platforms/reference/include/ReferenceCustomTorsionIxn.h b/platforms/reference/include/ReferenceCustomTorsionIxn.h index de8c0b4ef..73ea6a8fd 100644 --- a/platforms/reference/include/ReferenceCustomTorsionIxn.h +++ b/platforms/reference/include/ReferenceCustomTorsionIxn.h @@ -27,7 +27,7 @@ #include "ReferenceBondIxn.h" #include "lepton/CompiledExpression.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceCustomTorsionIxn : public ReferenceBondIxn { @@ -78,6 +78,6 @@ class ReferenceCustomTorsionIxn : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _ReferenceCustomTorsionIxn___ diff --git a/platforms/reference/include/ReferenceDynamics.h b/platforms/reference/include/ReferenceDynamics.h index f23ff9d41..9a3bb3ea5 100644 --- a/platforms/reference/include/ReferenceDynamics.h +++ b/platforms/reference/include/ReferenceDynamics.h @@ -31,7 +31,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { /**--------------------------------------------------------------------------------------- @@ -173,6 +173,7 @@ class OPENMM_EXPORT ReferenceDynamics { void setReferenceConstraintAlgorithm( ReferenceConstraintAlgorithm* referenceConstraint ); }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM + #endif // __ReferenceDynamics_H__ diff --git a/platforms/reference/include/ReferenceForce.h b/platforms/reference/include/ReferenceForce.h index 200ab66fb..1a2b4a999 100644 --- a/platforms/reference/include/ReferenceForce.h +++ b/platforms/reference/include/ReferenceForce.h @@ -28,7 +28,7 @@ #include "lepton/CompiledExpression.h" #include "openmm/internal/windowsExport.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceForce { @@ -126,6 +126,6 @@ class OPENMM_EXPORT ReferenceForce { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceForce_H__ diff --git a/platforms/reference/include/ReferenceHarmonicBondIxn.h b/platforms/reference/include/ReferenceHarmonicBondIxn.h index cd560d9a0..5fab10326 100644 --- a/platforms/reference/include/ReferenceHarmonicBondIxn.h +++ b/platforms/reference/include/ReferenceHarmonicBondIxn.h @@ -27,7 +27,7 @@ #include "ReferenceBondIxn.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceHarmonicBondIxn : public ReferenceBondIxn { @@ -70,6 +70,6 @@ class ReferenceHarmonicBondIxn : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _ReferenceHarmonicBondIxn___ diff --git a/platforms/reference/include/ReferenceKernels.h b/platforms/reference/include/ReferenceKernels.h index 8278862ce..f11aefbd3 100644 --- a/platforms/reference/include/ReferenceKernels.h +++ b/platforms/reference/include/ReferenceKernels.h @@ -39,6 +39,8 @@ #include "lepton/CompiledExpression.h" #include "lepton/ExpressionProgram.h" +namespace OpenMM { + class CpuObc; class CpuGBVI; class ReferenceAndersenThermostat; @@ -54,8 +56,6 @@ class ReferenceVariableVerletDynamics; class ReferenceVerletDynamics; class ReferenceCustomDynamics; -namespace OpenMM { - /** * This kernel is invoked at the beginning and end of force and energy computations. It gives the * Platform a chance to clear buffers and do other initialization at the beginning, and to do any diff --git a/platforms/reference/include/ReferenceLJCoulomb14.h b/platforms/reference/include/ReferenceLJCoulomb14.h index f4c505f6e..f286ebf15 100644 --- a/platforms/reference/include/ReferenceLJCoulomb14.h +++ b/platforms/reference/include/ReferenceLJCoulomb14.h @@ -28,7 +28,7 @@ #include "ReferenceBondIxn.h" #include "openmm/internal/windowsExport.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceLJCoulomb14 : public ReferenceBondIxn { @@ -68,6 +68,6 @@ class OPENMM_EXPORT ReferenceLJCoulomb14 : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceLJCoulomb14_H__ diff --git a/platforms/reference/include/ReferenceLJCoulombIxn.h b/platforms/reference/include/ReferenceLJCoulombIxn.h index dce5bd55b..f0d3f8fda 100644 --- a/platforms/reference/include/ReferenceLJCoulombIxn.h +++ b/platforms/reference/include/ReferenceLJCoulombIxn.h @@ -28,7 +28,7 @@ #include "ReferencePairIxn.h" #include "ReferenceNeighborList.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceLJCoulombIxn { @@ -197,6 +197,6 @@ private: RealOpenMM* energyByAtom, RealOpenMM* totalEnergy, bool includeDirect, bool includeReciprocal) const; }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceLJCoulombIxn_H__ diff --git a/platforms/reference/include/ReferenceLincsAlgorithm.h b/platforms/reference/include/ReferenceLincsAlgorithm.h index 4dab145ec..1271fa82c 100644 --- a/platforms/reference/include/ReferenceLincsAlgorithm.h +++ b/platforms/reference/include/ReferenceLincsAlgorithm.h @@ -28,7 +28,7 @@ #include "SimTKOpenMMRealType.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { @@ -157,6 +157,6 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { std::vector& velocities, std::vector& inverseMasses); }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceLincsAlgorithm_H__ diff --git a/platforms/reference/include/ReferenceMonteCarloBarostat.h b/platforms/reference/include/ReferenceMonteCarloBarostat.h index cfc6f67aa..361f21036 100644 --- a/platforms/reference/include/ReferenceMonteCarloBarostat.h +++ b/platforms/reference/include/ReferenceMonteCarloBarostat.h @@ -29,7 +29,7 @@ #include #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceMonteCarloBarostat { @@ -82,6 +82,6 @@ class ReferenceMonteCarloBarostat { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceMonteCarloBarostat_H__ diff --git a/platforms/reference/include/ReferencePME.h b/platforms/reference/include/ReferencePME.h index b8056008d..bd0a12ff3 100644 --- a/platforms/reference/include/ReferencePME.h +++ b/platforms/reference/include/ReferencePME.h @@ -29,10 +29,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef __ReferencePME_H__ +#define __ReferencePME_H__ + #include "SimTKOpenMMCommon.h" #include "openmm/internal/windowsExport.h" #include +namespace OpenMM { + typedef RealOpenMM rvec[3]; @@ -86,3 +91,7 @@ pme_exec(pme_t pme, /* Release all memory in pme structure */ int OPENMM_EXPORT pme_destroy(pme_t pme); + +} // namespace OpenMM + +#endif // __ReferencePME_H__ \ No newline at end of file diff --git a/platforms/reference/include/ReferencePairIxn.h b/platforms/reference/include/ReferencePairIxn.h index 5dfbaa4ab..a093d04eb 100644 --- a/platforms/reference/include/ReferencePairIxn.h +++ b/platforms/reference/include/ReferencePairIxn.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include "openmm/internal/windowsExport.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferencePairIxn { @@ -74,6 +74,6 @@ class OPENMM_EXPORT ReferencePairIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferencePairIxn_H__ diff --git a/platforms/reference/include/ReferenceProperDihedralBond.h b/platforms/reference/include/ReferenceProperDihedralBond.h index 834d4a060..ad2b89b39 100644 --- a/platforms/reference/include/ReferenceProperDihedralBond.h +++ b/platforms/reference/include/ReferenceProperDihedralBond.h @@ -27,7 +27,7 @@ #include "ReferenceBondIxn.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceProperDihedralBond : public ReferenceBondIxn { @@ -71,6 +71,6 @@ class OPENMM_EXPORT ReferenceProperDihedralBond : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceProperDihedralBond_H__ diff --git a/platforms/reference/include/ReferenceRbDihedralBond.h b/platforms/reference/include/ReferenceRbDihedralBond.h index 72d425e81..832389c09 100644 --- a/platforms/reference/include/ReferenceRbDihedralBond.h +++ b/platforms/reference/include/ReferenceRbDihedralBond.h @@ -27,7 +27,7 @@ #include "ReferenceBondIxn.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceRbDihedralBond : public ReferenceBondIxn { @@ -69,6 +69,6 @@ class OPENMM_EXPORT ReferenceRbDihedralBond : public ReferenceBondIxn { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceRbDihedralBond_H__ diff --git a/platforms/reference/include/ReferenceStochasticDynamics.h b/platforms/reference/include/ReferenceStochasticDynamics.h index 6de867b35..e7c86d13c 100644 --- a/platforms/reference/include/ReferenceStochasticDynamics.h +++ b/platforms/reference/include/ReferenceStochasticDynamics.h @@ -28,7 +28,7 @@ #include "ReferenceDynamics.h" #include "openmm/internal/windowsExport.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class OPENMM_EXPORT ReferenceStochasticDynamics : public ReferenceDynamics { @@ -120,6 +120,6 @@ class OPENMM_EXPORT ReferenceStochasticDynamics : public ReferenceDynamics { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceStochasticDynamics_H__ diff --git a/platforms/reference/include/ReferenceVariableStochasticDynamics.h b/platforms/reference/include/ReferenceVariableStochasticDynamics.h index fa3296f97..9379f1e01 100644 --- a/platforms/reference/include/ReferenceVariableStochasticDynamics.h +++ b/platforms/reference/include/ReferenceVariableStochasticDynamics.h @@ -27,7 +27,7 @@ #include "ReferenceDynamics.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceVariableStochasticDynamics : public ReferenceDynamics { @@ -142,6 +142,6 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceVariableStochasticDynamics_H__ diff --git a/platforms/reference/include/ReferenceVariableVerletDynamics.h b/platforms/reference/include/ReferenceVariableVerletDynamics.h index 15df84cfe..8bc2a250d 100644 --- a/platforms/reference/include/ReferenceVariableVerletDynamics.h +++ b/platforms/reference/include/ReferenceVariableVerletDynamics.h @@ -27,7 +27,7 @@ #include "ReferenceDynamics.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceVariableVerletDynamics : public ReferenceDynamics { @@ -95,6 +95,6 @@ class ReferenceVariableVerletDynamics : public ReferenceDynamics { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceVariableVerletDynamics_H__ diff --git a/platforms/reference/include/ReferenceVerletDynamics.h b/platforms/reference/include/ReferenceVerletDynamics.h index 79100a7f0..1a3316728 100644 --- a/platforms/reference/include/ReferenceVerletDynamics.h +++ b/platforms/reference/include/ReferenceVerletDynamics.h @@ -27,7 +27,7 @@ #include "ReferenceDynamics.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { class ReferenceVerletDynamics : public ReferenceDynamics { @@ -77,6 +77,6 @@ class ReferenceVerletDynamics : public ReferenceDynamics { }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // __ReferenceVerletDynamics_H__ diff --git a/platforms/reference/include/ReferenceVirtualSites.h b/platforms/reference/include/ReferenceVirtualSites.h index e20f18a65..086bc6762 100644 --- a/platforms/reference/include/ReferenceVirtualSites.h +++ b/platforms/reference/include/ReferenceVirtualSites.h @@ -36,6 +36,8 @@ #include "RealVec.h" #include +namespace OpenMM { + class OPENMM_EXPORT ReferenceVirtualSites { public: /** @@ -48,4 +50,6 @@ public: static void distributeForces(const OpenMM::System& system, const std::vector& atomCoordinates, std::vector& forces); }; +} // namespace OpenMM + #endif // __ReferenceVirtualSites_H__ diff --git a/platforms/reference/include/SimTKOpenMMCommon.h b/platforms/reference/include/SimTKOpenMMCommon.h index 804e6d0f3..51d3b7990 100644 --- a/platforms/reference/include/SimTKOpenMMCommon.h +++ b/platforms/reference/include/SimTKOpenMMCommon.h @@ -25,18 +25,11 @@ #ifndef __SimTKOpenMMCommon_H__ #define __SimTKOpenMMCommon_H__ -// include file containing entries commonly used - -// STL includes - #include #include - -// --------------------------------------------------------------------------------------- - #include "RealVec.h" -// --------------------------------------------------------------------------------------- +namespace OpenMM { typedef std::vector RealOpenMMVector; typedef RealOpenMMVector::iterator RealOpenMMVectorI; @@ -62,4 +55,6 @@ class SimTKOpenMMCommon { static const int ErrorReturn; }; +} // namespace OpenMM + #endif // __SimTKOpenMMCommon_H__ diff --git a/platforms/reference/include/SimTKOpenMMLog.h b/platforms/reference/include/SimTKOpenMMLog.h index 0ed90e73f..5a6b97121 100644 --- a/platforms/reference/include/SimTKOpenMMLog.h +++ b/platforms/reference/include/SimTKOpenMMLog.h @@ -30,6 +30,8 @@ #include "SimTKOpenMMCommon.h" #include "openmm/internal/windowsExport.h" +namespace OpenMM { + /** --------------------------------------------------------------------------------------- SimTKOpenMMLog class used for logging @@ -182,4 +184,6 @@ class OPENMM_EXPORT SimTKOpenMMLog { }; +} // namespace OpenMM + #endif //__SimTKOpenMMLog_H__ diff --git a/platforms/reference/include/SimTKOpenMMUtilities.h b/platforms/reference/include/SimTKOpenMMUtilities.h index eb65ba9e4..b1aa0d625 100644 --- a/platforms/reference/include/SimTKOpenMMUtilities.h +++ b/platforms/reference/include/SimTKOpenMMUtilities.h @@ -33,6 +33,8 @@ #include +namespace OpenMM { + /**--------------------------------------------------------------------------------------- Class of static methods to be shared @@ -219,7 +221,7 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { static void loadCheckpoint(std::istream& stream); }; - -// --------------------------------------------------------------------------------------- + +} // namespace OpenMM #endif // __SimTKOpenMMUtilities_H__ diff --git a/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp b/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp index a5ac3fdbd..f3e5f7c4d 100644 --- a/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp @@ -29,7 +29,7 @@ #include "ReferenceAndersenThermostat.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp index 5f0d0438e..d2cfee2f3 100644 --- a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp @@ -32,7 +32,7 @@ #include "ReferenceForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp index 217fbdc4c..97d5497b9 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp @@ -31,7 +31,7 @@ #include "ReferenceBondForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp index f4b739f97..96f07159a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp @@ -32,7 +32,7 @@ #include "ReferenceBondIxn.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp index 42474f99c..662fda07d 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp @@ -34,7 +34,7 @@ #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp index 3a2214258..06ba9652a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp @@ -39,9 +39,7 @@ using std::map; using std::pair; using std::vector; using std::set; -using OpenMM::OpenMMException; -using OpenMM::Vec3; -using OpenMM::RealVec; +using namespace OpenMM; ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms, int numberOfConstraints, diff --git a/platforms/reference/src/SimTKReference/ReferenceCMAPTorsionIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCMAPTorsionIxn.cpp index 88675d300..9b5def3d8 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCMAPTorsionIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCMAPTorsionIxn.cpp @@ -26,7 +26,7 @@ #include "ReferenceForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp index 19e5287d7..ac952fa6e 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp @@ -37,7 +37,7 @@ using std::pair; using std::string; using std::stringstream; using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp index aeb9bc308..24c18b175 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp @@ -36,7 +36,7 @@ using std::set; using std::string; using std::stringstream; using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp index 2f9aeb482..b7b2bceaf 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp @@ -38,7 +38,7 @@ using std::set; using std::string; using std::stringstream; using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp index 17b16163a..8d3ae88b7 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp @@ -37,7 +37,7 @@ using std::string; using std::stringstream; using std::set; using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp index 633dcb44a..2f21528a1 100644 --- a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp @@ -33,7 +33,7 @@ #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceForce.cpp b/platforms/reference/src/SimTKReference/ReferenceForce.cpp index 7718e66cb..a908a3fa9 100644 --- a/platforms/reference/src/SimTKReference/ReferenceForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceForce.cpp @@ -32,7 +32,7 @@ #include -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp index d45114dc7..04e09714a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp @@ -32,7 +32,7 @@ #include "ReferenceForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp index e9e80055f..e8198aca7 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp @@ -32,7 +32,7 @@ #include "ReferenceForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp index 8de3cd3f9..4781dc43a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp @@ -40,7 +40,7 @@ using std::set; using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp index 4ee1d7646..dad3d2a0a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp @@ -32,7 +32,7 @@ #include "openmm/OpenMMException.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferencePME.cpp b/platforms/reference/src/SimTKReference/ReferencePME.cpp index df9ef153f..5a1946f28 100644 --- a/platforms/reference/src/SimTKReference/ReferencePME.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePME.cpp @@ -37,10 +37,10 @@ #include "fftpack.h" using std::vector; -using OpenMM::RealVec; typedef int ivec[3]; +namespace OpenMM { struct pme { @@ -729,3 +729,5 @@ pme_destroy(pme_t pme) return 0; } + +} // namespace OpenMM diff --git a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp index ce107eed6..6892cd5bb 100644 --- a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp @@ -31,6 +31,8 @@ #include "ReferenceForce.h" #include "ReferencePairIxn.h" +using namespace OpenMM; + /**--------------------------------------------------------------------------------------- ReferencePairIxn constructor diff --git a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp index b36a715b8..f8d0b6d5a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp @@ -32,7 +32,7 @@ #include "ReferenceForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp index 6961bda11..3adc8b0b4 100644 --- a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp @@ -32,7 +32,7 @@ #include "ReferenceForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp index 9a3d2fdeb..7da2f2ecc 100644 --- a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp @@ -34,7 +34,7 @@ #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp index 5c3a3c4b7..c45fc1b07 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp @@ -35,7 +35,7 @@ #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp index ee367accf..b0a1fbd32 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp @@ -33,7 +33,7 @@ #include "ReferenceVirtualSites.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp index 98598c1a4..ee8aa661f 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp @@ -34,7 +34,7 @@ #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp index c6d9803ce..4313eb494 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp @@ -24,6 +24,8 @@ #include "SimTKOpenMMCommon.h" +using namespace OpenMM; + // static settings // initialization of static data members diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp index 0c44480be..17cb27bb4 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp @@ -26,6 +26,8 @@ #include #include "openmm/OpenMMException.h" +using namespace OpenMM; + // static settings SimTKOpenMMLog* SimTKOpenMMLog::_simTKOpenMMLog = NULL; diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp index ba7511dde..90d8b13de 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp @@ -36,6 +36,8 @@ #include #include +using namespace OpenMM; + uint32_t SimTKOpenMMUtilities::_randomNumberSeed = 0; bool SimTKOpenMMUtilities::_randomInitialized = false; bool SimTKOpenMMUtilities::nextGaussianIsValid = false; diff --git a/platforms/reference/src/gbsa/GBVIParameters.cpp b/platforms/reference/src/gbsa/GBVIParameters.cpp index 170f1f5c9..c7cfd2809 100644 --- a/platforms/reference/src/gbsa/GBVIParameters.cpp +++ b/platforms/reference/src/gbsa/GBVIParameters.cpp @@ -31,7 +31,7 @@ #include "SimTKOpenMMCommon.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/gbsa/ObcParameters.cpp b/platforms/reference/src/gbsa/ObcParameters.cpp index 1641ee4e2..e1521cdde 100644 --- a/platforms/reference/src/gbsa/ObcParameters.cpp +++ b/platforms/reference/src/gbsa/ObcParameters.cpp @@ -31,6 +31,7 @@ #include "SimTKOpenMMCommon.h" using std::vector; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- -- GitLab From 1d3ffd7bd7ad5f8f4d7589ef02040f0edce07328 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 14:53:26 -0800 Subject: [PATCH 277/338] Deleted obsolete logging class --- platforms/cpu/src/CpuCustomGBForce.cpp | 1 - .../cpu/src/CpuCustomManyParticleForce.cpp | 1 - platforms/cpu/src/CpuCustomNonbondedForce.cpp | 1 - platforms/cpu/src/CpuLangevinDynamics.cpp | 1 - platforms/reference/include/SimTKOpenMMLog.h | 189 ----------- .../SimTKReference/ReferenceAngleBondIxn.cpp | 1 - .../src/SimTKReference/ReferenceBondForce.cpp | 1 - .../src/SimTKReference/ReferenceBondIxn.cpp | 1 - .../ReferenceBrownianDynamics.cpp | 22 +- .../SimTKReference/ReferenceCCMAAlgorithm.cpp | 1 - .../ReferenceCustomAngleIxn.cpp | 1 - .../SimTKReference/ReferenceCustomBondIxn.cpp | 1 - .../ReferenceCustomCompoundBondIxn.cpp | 1 - .../ReferenceCustomDynamics.cpp | 1 - .../ReferenceCustomExternalIxn.cpp | 1 - .../SimTKReference/ReferenceCustomGBIxn.cpp | 1 - .../ReferenceCustomHbondIxn.cpp | 1 - .../ReferenceCustomManyParticleIxn.cpp | 1 - .../ReferenceCustomNonbondedIxn.cpp | 1 - .../ReferenceCustomTorsionIxn.cpp | 1 - .../src/SimTKReference/ReferenceDynamics.cpp | 1 - .../src/SimTKReference/ReferenceForce.cpp | 1 - .../ReferenceHarmonicBondIxn.cpp | 1 - .../SimTKReference/ReferenceLJCoulomb14.cpp | 1 - .../SimTKReference/ReferenceLJCoulombIxn.cpp | 9 +- .../ReferenceLincsAlgorithm.cpp | 1 - .../src/SimTKReference/ReferencePairIxn.cpp | 1 - .../ReferenceProperDihedralBond.cpp | 1 - .../ReferenceRbDihedralBond.cpp | 1 - .../ReferenceStochasticDynamics.cpp | 25 +- .../ReferenceVariableStochasticDynamics.cpp | 25 +- .../ReferenceVariableVerletDynamics.cpp | 1 - .../ReferenceVerletDynamics.cpp | 1 - .../src/SimTKUtilities/SimTKOpenMMLog.cpp | 306 ------------------ .../SimTKUtilities/SimTKOpenMMUtilities.cpp | 1 - 35 files changed, 15 insertions(+), 590 deletions(-) delete mode 100644 platforms/reference/include/SimTKOpenMMLog.h delete mode 100644 platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index 906c42cfe..892e20db5 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "CpuCustomGBForce.h" diff --git a/platforms/cpu/src/CpuCustomManyParticleForce.cpp b/platforms/cpu/src/CpuCustomManyParticleForce.cpp index e4f4d53fc..362bbba22 100644 --- a/platforms/cpu/src/CpuCustomManyParticleForce.cpp +++ b/platforms/cpu/src/CpuCustomManyParticleForce.cpp @@ -27,7 +27,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "CpuCustomManyParticleForce.h" diff --git a/platforms/cpu/src/CpuCustomNonbondedForce.cpp b/platforms/cpu/src/CpuCustomNonbondedForce.cpp index 660a8d02f..0a45d559f 100644 --- a/platforms/cpu/src/CpuCustomNonbondedForce.cpp +++ b/platforms/cpu/src/CpuCustomNonbondedForce.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "CpuCustomNonbondedForce.h" diff --git a/platforms/cpu/src/CpuLangevinDynamics.cpp b/platforms/cpu/src/CpuLangevinDynamics.cpp index fce25f1b2..59d87b4e1 100644 --- a/platforms/cpu/src/CpuLangevinDynamics.cpp +++ b/platforms/cpu/src/CpuLangevinDynamics.cpp @@ -24,7 +24,6 @@ */ #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "CpuLangevinDynamics.h" diff --git a/platforms/reference/include/SimTKOpenMMLog.h b/platforms/reference/include/SimTKOpenMMLog.h deleted file mode 100644 index 5a6b97121..000000000 --- a/platforms/reference/include/SimTKOpenMMLog.h +++ /dev/null @@ -1,189 +0,0 @@ - -/* Portions copyright (c) 2006 Stanford University and Simbios. - * Contributors: Pande Group - * - * 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. - */ - -#ifndef __SimTKOpenMMLog_H__ -#define __SimTKOpenMMLog_H__ - -#include -#include -#include "SimTKOpenMMCommon.h" -#include "openmm/internal/windowsExport.h" - -namespace OpenMM { - -/** --------------------------------------------------------------------------------------- - - SimTKOpenMMLog class used for logging - - --------------------------------------------------------------------------------------- */ - -class OPENMM_EXPORT SimTKOpenMMLog { - - public: - - // log levels - - enum LogLevels { LogOff, LogLowLevel, LogHighLevel }; - - private: - - // file to write to - - FILE* _logFile; - - // log level - - LogLevels _logLevel; - - // global reference - - static SimTKOpenMMLog* _simTKOpenMMLog; - - public: - - /**--------------------------------------------------------------------------------------- - - SimTKOpenMMLog constructor (Simbios) - - @param logFile file reference for logging - - --------------------------------------------------------------------------------------- */ - - SimTKOpenMMLog( FILE* logFile = NULL ); - - /**--------------------------------------------------------------------------------------- - - SimTKOpenMMLog destructor (Simbios) - - --------------------------------------------------------------------------------------- */ - - ~SimTKOpenMMLog( ); - - /**--------------------------------------------------------------------------------------- - - SimTKOpenMMLog log message to log (Simbios) - - @param message message to log - - --------------------------------------------------------------------------------------- */ - - void logMessage( const std::stringstream& message ) const; - - /**--------------------------------------------------------------------------------------- - - Get LogFile - - @return logFile - - --------------------------------------------------------------------------------------- */ - - FILE* getLogFile( void ) const; - - /**--------------------------------------------------------------------------------------- - - Set LogFile - - @param input logFile - - --------------------------------------------------------------------------------------- */ - - void setLogFile( FILE* logFile ); - - /**--------------------------------------------------------------------------------------- - - Set LogLevel - - @param input logLevel - - --------------------------------------------------------------------------------------- */ - - void setLogLevel( SimTKOpenMMLog::LogLevels logLevel ); - - /**--------------------------------------------------------------------------------------- - - Set global simTKLog (Simbios) - - @param logFile file to log to - - @return new SimTKOpenMMLog - - --------------------------------------------------------------------------------------- */ - - static SimTKOpenMMLog* setSimTKOpenMMLog( FILE* logFile = NULL ); - - /**--------------------------------------------------------------------------------------- - - Get global simTKLog -- static method (Simbios) - - @return static member - - --------------------------------------------------------------------------------------- */ - - static SimTKOpenMMLog* getSimTKOpenMMLog( void ); - - /**--------------------------------------------------------------------------------------- - - Get global simTKLog (Simbios) - - @return FILE reference - - --------------------------------------------------------------------------------------- */ - - static FILE* getSimTKOpenMMLogFile( void ); - - /**--------------------------------------------------------------------------------------- - - Staitc method to print message (Simbios) - - @param message message to log - - --------------------------------------------------------------------------------------- */ - - static void printMessage( const std::stringstream& message ); - - /**--------------------------------------------------------------------------------------- - - Staitc method to print warning message (Simbios) - - @param message message to log - - --------------------------------------------------------------------------------------- */ - - static void printWarning( const std::stringstream& message ); - - /**--------------------------------------------------------------------------------------- - - Static method to print error message and exist program (Simbios) - - @param message message to log - - --------------------------------------------------------------------------------------- */ - - static void printError( const std::stringstream& message ); - -}; - -} // namespace OpenMM - -#endif //__SimTKOpenMMLog_H__ diff --git a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp index d2cfee2f3..067501c9b 100644 --- a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceAngleBondIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp index 97d5497b9..a3f7f1018 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceBondForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp index 96f07159a..8e53cd226 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceBondIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp index 662fda07d..5f9d53054 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp @@ -26,10 +26,10 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceBrownianDynamics.h" #include "ReferenceVirtualSites.h" +#include "openmm/OpenMMException.h" #include @@ -52,24 +52,10 @@ ReferenceBrownianDynamics::ReferenceBrownianDynamics( int numberOfAtoms, RealOpenMM temperature ) : ReferenceDynamics( numberOfAtoms, deltaT, temperature ), friction( friction ) { - // --------------------------------------------------------------------------------------- - - static const char* methodName = "\nReferenceBrownianDynamics::ReferenceBrownianDynamics"; - - static const RealOpenMM zero = 0.0; - static const RealOpenMM one = 1.0; - - // --------------------------------------------------------------------------------------- - - if( friction <= zero ){ - + if (friction <= 0) { std::stringstream message; - message << methodName; - message << " input frction value=" << friction << " is invalid -- setting to 1."; - SimTKOpenMMLog::printError( message ); - - this->friction = one; - + message << "illegal friction value: " << friction; + throw OpenMMException(message.str()); } xPrime.resize(numberOfAtoms); inverseMasses.resize(numberOfAtoms); diff --git a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp index 06ba9652a..eee7c7d78 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp @@ -27,7 +27,6 @@ #include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" -#include "SimTKOpenMMLog.h" #include "ReferenceCCMAAlgorithm.h" #include "ReferenceDynamics.h" #include "quern.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp index 8336f2453..5ef2eabc3 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp @@ -25,7 +25,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomAngleIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp index 1bf7ffcca..91ef124ee 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomBondIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp index ac952fa6e..4ef74636f 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp @@ -27,7 +27,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomCompoundBondIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp index 46366f3d6..fcacbd013 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp @@ -23,7 +23,6 @@ */ #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVirtualSites.h" #include "ReferenceCustomDynamics.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp index eb236af47..7f950b8e8 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomExternalIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp index 24c18b175..624052c1b 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomGBIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp index b7b2bceaf..2e3bf18f3 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp @@ -27,7 +27,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomHbondIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp index 868684c21..715a790ec 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp @@ -27,7 +27,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomManyParticleIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp index 8d3ae88b7..82056be0c 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomNonbondedIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp index 4107cb4ac..8d4aa4c98 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp @@ -25,7 +25,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomTorsionIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp index 2f21528a1..898c919bd 100644 --- a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceDynamics.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceForce.cpp b/platforms/reference/src/SimTKReference/ReferenceForce.cpp index a908a3fa9..78f12d59a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceForce.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp index 04e09714a..ec13dd963 100644 --- a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceHarmonicBondIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp index e8198aca7..159dd7e6b 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceLJCoulomb14.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp index 4781dc43a..50ccf1759 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp @@ -28,11 +28,11 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceLJCoulombIxn.h" #include "ReferenceForce.h" #include "ReferencePME.h" +#include "openmm/OpenMMException.h" // In case we're using some primitive version of Visual Studio this will // make sure that erf() and erfc() are defined. @@ -264,11 +264,8 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector vector tab_xy(numberOfAtoms); vector tab_qxyz(numberOfAtoms); - if (kmax < 1) { - std::stringstream message; - message << " kmax < 1 , Aborting" << std::endl; - SimTKOpenMMLog::printError( message ); - } + if (kmax < 1) + throw OpenMMException("kmax for Ewald summation < 1"); for(int i = 0; (i < numberOfAtoms); i++) { for(int m = 0; (m < 3); m++) diff --git a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp index dad3d2a0a..da67ee67e 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp @@ -26,7 +26,6 @@ #include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" -#include "SimTKOpenMMLog.h" #include "ReferenceLincsAlgorithm.h" #include "ReferenceDynamics.h" #include "openmm/OpenMMException.h" diff --git a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp index 6892cd5bb..541d793a9 100644 --- a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferencePairIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp index f8d0b6d5a..e381431de 100644 --- a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceProperDihedralBond.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp index 3adc8b0b4..652e01f38 100644 --- a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceRbDihedralBond.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp index 7da2f2ecc..d04b0a5a6 100644 --- a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp @@ -26,10 +26,10 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceStochasticDynamics.h" #include "ReferenceVirtualSites.h" +#include "openmm/OpenMMException.h" #include @@ -51,27 +51,10 @@ ReferenceStochasticDynamics::ReferenceStochasticDynamics( int numberOfAtoms, RealOpenMM deltaT, RealOpenMM tau, RealOpenMM temperature ) : ReferenceDynamics( numberOfAtoms, deltaT, temperature ), _tau( tau ) { - - // --------------------------------------------------------------------------------------- - - static const char* methodName = "\nReferenceStochasticDynamics::ReferenceStochasticDynamics"; - - static const RealOpenMM zero = 0.0; - static const RealOpenMM one = 1.0; - - // --------------------------------------------------------------------------------------- - - // ensure tau is not zero -- if it is print warning message - - if( _tau == zero ){ - + if (tau <= 0) { std::stringstream message; - message << methodName; - message << " input tau value=" << tau << " is invalid -- setting to 1."; - SimTKOpenMMLog::printError( message ); - - _tau = one; - + message << "illegal tau value: " << tau; + throw OpenMMException(message.str()); } xPrime.resize(numberOfAtoms); inverseMasses.resize(numberOfAtoms); diff --git a/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp index c45fc1b07..bc88cf850 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp @@ -27,10 +27,10 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVariableStochasticDynamics.h" #include "ReferenceVirtualSites.h" +#include "openmm/OpenMMException.h" #include @@ -53,27 +53,10 @@ ReferenceVariableStochasticDynamics::ReferenceVariableStochasticDynamics( int nu RealOpenMM tau, RealOpenMM temperature, RealOpenMM accuracy ) : ReferenceDynamics(numberOfAtoms, 0.0f, temperature), _tau(tau), _accuracy(accuracy) { - - // --------------------------------------------------------------------------------------- - - static const char* methodName = "\nReferenceVariableStochasticDynamics::ReferenceVariableStochasticDynamics"; - - static const RealOpenMM zero = 0.0; - static const RealOpenMM one = 1.0; - - // --------------------------------------------------------------------------------------- - - // ensure tau is not zero -- if it is print warning message - - if( _tau == zero ){ - + if (tau <= 0) { std::stringstream message; - message << methodName; - message << " input tau value=" << tau << " is invalid -- setting to 1."; - SimTKOpenMMLog::printError( message ); - - _tau = one; - + message << "illegal tau value: " << tau; + throw OpenMMException(message.str()); } xPrime.resize(numberOfAtoms); inverseMasses.resize(numberOfAtoms); diff --git a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp index b0a1fbd32..dc84f6c8e 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp @@ -27,7 +27,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVariableVerletDynamics.h" #include "ReferenceVirtualSites.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp index ee8aa661f..f9b77aca6 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp @@ -26,7 +26,6 @@ #include #include "SimTKOpenMMCommon.h" -#include "SimTKOpenMMLog.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVerletDynamics.h" #include "ReferenceVirtualSites.h" diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp deleted file mode 100644 index 17cb27bb4..000000000 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMLog.cpp +++ /dev/null @@ -1,306 +0,0 @@ - -/* Portions copyright (c) 2006 Stanford University and Simbios. - * Contributors: Pande Group - * - * 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 "SimTKOpenMMLog.h" -#include -#include "openmm/OpenMMException.h" - -using namespace OpenMM; - -// static settings - -SimTKOpenMMLog* SimTKOpenMMLog::_simTKOpenMMLog = NULL; - -/**--------------------------------------------------------------------------------------- - - SimTKOpenMMLog constructor (Simbios) - - @param logFile file reference for logging - - --------------------------------------------------------------------------------------- */ - -SimTKOpenMMLog::SimTKOpenMMLog( FILE* logFile ) : _logFile( logFile ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::SimTKOpenMMLog"; - -// --------------------------------------------------------------------------------------- - - _logLevel = LogLowLevel; - -} - -/**--------------------------------------------------------------------------------------- - - SimTKOpenMMLog destructor (Simbios) - - --------------------------------------------------------------------------------------- */ - -SimTKOpenMMLog::~SimTKOpenMMLog( ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::~SimTKOpenMMLog"; - -// --------------------------------------------------------------------------------------- - -} - -/**--------------------------------------------------------------------------------------- - - Get LogFile - - @return logFile - - --------------------------------------------------------------------------------------- */ - -FILE* SimTKOpenMMLog::getLogFile( void ) const { - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::getLogFile"; - -// --------------------------------------------------------------------------------------- - - return _logFile; - -} - -/**--------------------------------------------------------------------------------------- - - Set LogFile - - @param input logFile - - --------------------------------------------------------------------------------------- */ - -void SimTKOpenMMLog::setLogFile( FILE* logFile ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::setLogFile"; - -// --------------------------------------------------------------------------------------- - - _logFile = logFile; - -} - -/**--------------------------------------------------------------------------------------- - - Set LogLevel - - @param input logLevel - - --------------------------------------------------------------------------------------- */ - -void SimTKOpenMMLog::setLogLevel( SimTKOpenMMLog::LogLevels logLevel ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::setLogLevel"; - -// --------------------------------------------------------------------------------------- - - _logLevel = logLevel; - -} - -/**--------------------------------------------------------------------------------------- - - SimTKOpenMMLog log message to log (Simbios) - - @param message message to log - - --------------------------------------------------------------------------------------- */ - -void SimTKOpenMMLog::logMessage( const std::stringstream& message ) const { - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::logMessage"; - -// --------------------------------------------------------------------------------------- - - if( _logFile ){ - -// (void) fprintf( stderr, "%s", message.str().c_str() ); -// (void) fflush( stderr ); - - (void) fprintf( _logFile, "%s", message.str().c_str() ); - (void) fflush( _logFile ); - - } -} - -/**--------------------------------------------------------------------------------------- - - Set global simTKOpenMMLog (Simbios) - - @param logFile file to log to - - @return new SimTKOpenMMLog - - --------------------------------------------------------------------------------------- */ - -SimTKOpenMMLog* SimTKOpenMMLog::setSimTKOpenMMLog( FILE* logFile ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::setSimTKOpenMMLog"; - -// --------------------------------------------------------------------------------------- - - // allow for multiple logs - -/* - if( _simTKOpenMMLog ){ - delete _simTKOpenMMLog; - } -*/ - _simTKOpenMMLog = new SimTKOpenMMLog( logFile ); - - return _simTKOpenMMLog; -} - -/**--------------------------------------------------------------------------------------- - - Get global simTKOpenMMLog -- static method (Simbios) - - @return static member - - --------------------------------------------------------------------------------------- */ - -SimTKOpenMMLog* SimTKOpenMMLog::getSimTKOpenMMLog( void ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::getSimTKOpenMMLog"; - -// --------------------------------------------------------------------------------------- - - if( !_simTKOpenMMLog ){ - _simTKOpenMMLog = new SimTKOpenMMLog( ); - } - return _simTKOpenMMLog; -} - -/**--------------------------------------------------------------------------------------- - - Get global simTKOpenMMLog (Simbios) - - @return FILE reference - - --------------------------------------------------------------------------------------- */ - -FILE* SimTKOpenMMLog::getSimTKOpenMMLogFile( void ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::getSimTKOpenMMLogFile"; - -// --------------------------------------------------------------------------------------- - - SimTKOpenMMLog* simTKOpenMMLog = getSimTKOpenMMLog( ); - return simTKOpenMMLog->getLogFile(); -} - -/**--------------------------------------------------------------------------------------- - - Static method to print message (Simbios) - - @param message message to log - - --------------------------------------------------------------------------------------- */ - -void SimTKOpenMMLog::printMessage( const std::stringstream& message ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::printMessage"; - -// --------------------------------------------------------------------------------------- - - if( _simTKOpenMMLog ){ - _simTKOpenMMLog->logMessage( message ); - } else { - (void) fprintf( stderr, "%s", message.str().c_str() ); - (void) fflush( stderr ); - } -} - -/**--------------------------------------------------------------------------------------- - - Static method to print warning message (Simbios) - If global _simTKOpenMMLog is not set, then print to stderr - - @param message message to log - - --------------------------------------------------------------------------------------- */ - -void SimTKOpenMMLog::printWarning( const std::stringstream& message ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::printWarning"; - -// --------------------------------------------------------------------------------------- - - if( _simTKOpenMMLog ){ - std::stringstream messageWithHeader; - messageWithHeader << "Warning: " << message.str(); - _simTKOpenMMLog->logMessage( messageWithHeader ); - } else { - (void) fprintf( stderr, "Warning: %s", message.str().c_str() ); - } -} - -/**--------------------------------------------------------------------------------------- - - Static method to print error message and exit program (Simbios) - If global _simTKOpenMMLog is not set, then print to stderr - - @param message message to log - - --------------------------------------------------------------------------------------- */ - -void SimTKOpenMMLog::printError( const std::stringstream& message ){ - -// --------------------------------------------------------------------------------------- - -// static const std::string methodName = "\nSimTKOpenMMLog::printError"; - -// --------------------------------------------------------------------------------------- - - std::stringstream messageWithHeader; - messageWithHeader << "Error: " << message.str(); - if( _simTKOpenMMLog ){ - _simTKOpenMMLog->logMessage( messageWithHeader ); - } else { - (void) fprintf( stderr, "%s", messageWithHeader.str().c_str() ); - (void) fflush( stderr ); - } - throw OpenMM::OpenMMException(messageWithHeader.str()); -} diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp index 90d8b13de..d5d343aea 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp @@ -26,7 +26,6 @@ #include "openmm/internal/OSRngSeed.h" #include "SimTKOpenMMUtilities.h" -#include "SimTKOpenMMLog.h" #include "sfmt/SFMT.h" // fabs(), ... -- GitLab From 7fb10336a145166b8f74c0e991dadf3f04fadf6b Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 15:19:50 -0800 Subject: [PATCH 278/338] Cleaned up lots of formatting to be more consistent with the rest of OpenMM --- platforms/reference/include/CpuGBVI.h | 56 +-- platforms/reference/include/CpuObc.h | 36 +- platforms/reference/include/GBVIParameters.h | 44 +-- platforms/reference/include/ObcParameters.h | 48 +-- .../include/ReferenceAndersenThermostat.h | 8 +- .../reference/include/ReferenceAngleBondIxn.h | 12 +- .../reference/include/ReferenceBondForce.h | 8 +- .../reference/include/ReferenceBondIxn.h | 22 +- .../include/ReferenceBrownianDynamics.h | 6 +- .../include/ReferenceCCMAAlgorithm.h | 8 +- .../include/ReferenceCustomAngleIxn.h | 4 +- .../include/ReferenceCustomBondIxn.h | 6 +- .../include/ReferenceCustomExternalIxn.h | 6 +- .../reference/include/ReferenceCustomGBIxn.h | 4 +- .../include/ReferenceCustomNonbondedIxn.h | 14 +- .../include/ReferenceCustomTorsionIxn.h | 6 +- .../reference/include/ReferenceDynamics.h | 20 +- platforms/reference/include/ReferenceForce.h | 16 +- .../include/ReferenceHarmonicBondIxn.h | 8 +- .../reference/include/ReferenceLJCoulomb14.h | 8 +- .../reference/include/ReferenceLJCoulombIxn.h | 14 +- .../include/ReferenceLincsAlgorithm.h | 12 +- .../reference/include/ReferenceNeighborList.h | 4 +- .../reference/include/ReferencePairIxn.h | 8 +- .../include/ReferenceProperDihedralBond.h | 8 +- .../include/ReferenceRbDihedralBond.h | 8 +- .../include/ReferenceStochasticDynamics.h | 14 +- .../ReferenceVariableStochasticDynamics.h | 18 +- .../include/ReferenceVariableVerletDynamics.h | 8 +- .../include/ReferenceVerletDynamics.h | 4 +- .../reference/include/SimTKOpenMMUtilities.h | 34 +- .../reference/src/ReferenceKernelFactory.cpp | 2 +- platforms/reference/src/ReferenceKernels.cpp | 18 +- .../ReferenceAndersenThermostat.cpp | 8 +- .../SimTKReference/ReferenceAngleBondIxn.cpp | 44 +-- .../src/SimTKReference/ReferenceBondForce.cpp | 14 +- .../src/SimTKReference/ReferenceBondIxn.cpp | 98 ++--- .../ReferenceBrownianDynamics.cpp | 18 +- .../ReferenceCustomAngleIxn.cpp | 12 +- .../SimTKReference/ReferenceCustomBondIxn.cpp | 14 +- .../ReferenceCustomCompoundBondIxn.cpp | 4 +- .../ReferenceCustomDynamics.cpp | 2 +- .../ReferenceCustomExternalIxn.cpp | 6 +- .../SimTKReference/ReferenceCustomGBIxn.cpp | 16 +- .../ReferenceCustomHbondIxn.cpp | 6 +- .../ReferenceCustomManyParticleIxn.cpp | 2 +- .../ReferenceCustomNonbondedIxn.cpp | 26 +- .../ReferenceCustomTorsionIxn.cpp | 18 +- .../src/SimTKReference/ReferenceDynamics.cpp | 24 +- .../src/SimTKReference/ReferenceForce.cpp | 24 +- .../ReferenceHarmonicBondIxn.cpp | 10 +- .../SimTKReference/ReferenceLJCoulomb14.cpp | 16 +- .../SimTKReference/ReferenceLJCoulombIxn.cpp | 100 ++--- .../ReferenceLincsAlgorithm.cpp | 18 +- .../ReferenceMonteCarloBarostat.cpp | 2 +- .../SimTKReference/ReferenceNeighborList.cpp | 14 +- .../src/SimTKReference/ReferencePME.cpp | 70 ++-- .../src/SimTKReference/ReferencePairIxn.cpp | 4 +- .../ReferenceProperDihedralBond.cpp | 36 +- .../ReferenceRbDihedralBond.cpp | 40 +- .../ReferenceStochasticDynamics.cpp | 28 +- .../ReferenceVariableStochasticDynamics.cpp | 30 +- .../ReferenceVariableVerletDynamics.cpp | 14 +- .../ReferenceVerletDynamics.cpp | 13 +- .../reference/src/SimTKReference/fftpack.cpp | 86 ++--- .../src/SimTKUtilities/SimTKOpenMMCommon.cpp | 6 +- .../SimTKUtilities/SimTKOpenMMUtilities.cpp | 82 ++-- platforms/reference/src/gbsa/CpuGBVI.cpp | 364 +++++++++--------- platforms/reference/src/gbsa/CpuObc.cpp | 206 +++++----- .../reference/src/gbsa/GBVIParameters.cpp | 82 ++-- .../reference/src/gbsa/ObcParameters.cpp | 82 ++-- .../tests/TestReferenceCustomGBForce.cpp | 130 +++---- .../tests/TestReferenceGBVIForce.cpp | 88 ++--- 73 files changed, 1174 insertions(+), 1175 deletions(-) diff --git a/platforms/reference/include/CpuGBVI.h b/platforms/reference/include/CpuGBVI.h index 2c00529f8..1b822c12d 100644 --- a/platforms/reference/include/CpuGBVI.h +++ b/platforms/reference/include/CpuGBVI.h @@ -53,7 +53,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - CpuGBVI( GBVIParameters* gbviParameters ); + CpuGBVI(GBVIParameters* gbviParameters); /**--------------------------------------------------------------------------------------- @@ -61,7 +61,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - ~CpuGBVI( ); + ~CpuGBVI(); /**--------------------------------------------------------------------------------------- @@ -71,7 +71,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - GBVIParameters* getGBVIParameters( void ) const; + GBVIParameters* getGBVIParameters() const; /**--------------------------------------------------------------------------------------- @@ -81,7 +81,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void setGBVIParameters( GBVIParameters* gbviParameters ); + void setGBVIParameters(GBVIParameters* gbviParameters); /**--------------------------------------------------------------------------------------- @@ -93,7 +93,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void computeBornRadii( const std::vector& atomCoordinates, RealOpenMMVector& bornRadii ); + void computeBornRadii(const std::vector& atomCoordinates, RealOpenMMVector& bornRadii); /**--------------------------------------------------------------------------------------- @@ -107,7 +107,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static RealOpenMM getVolume( RealOpenMM r, RealOpenMM R, RealOpenMM S ); + static RealOpenMM getVolume(RealOpenMM r, RealOpenMM R, RealOpenMM S); /**--------------------------------------------------------------------------------------- @@ -121,7 +121,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static RealOpenMM getL( RealOpenMM r, RealOpenMM x, RealOpenMM S ); + static RealOpenMM getL(RealOpenMM r, RealOpenMM x, RealOpenMM S); /**--------------------------------------------------------------------------------------- @@ -135,7 +135,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static RealOpenMM dL_dr( RealOpenMM r, RealOpenMM x, RealOpenMM S ); + static RealOpenMM dL_dr(RealOpenMM r, RealOpenMM x, RealOpenMM S); /**--------------------------------------------------------------------------------------- @@ -149,7 +149,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static RealOpenMM dL_dx( RealOpenMM r, RealOpenMM x, RealOpenMM S ); + static RealOpenMM dL_dx(RealOpenMM r, RealOpenMM x, RealOpenMM S); /**--------------------------------------------------------------------------------------- @@ -161,7 +161,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static RealOpenMM Sgb( RealOpenMM t ); + static RealOpenMM Sgb(RealOpenMM t); /**--------------------------------------------------------------------------------------- @@ -174,7 +174,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - RealOpenMM computeBornEnergy( const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges ); + RealOpenMM computeBornEnergy(const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges); /**--------------------------------------------------------------------------------------- @@ -186,8 +186,8 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void computeBornForces( std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, std::vector& inputForces ); + void computeBornForces(std::vector& atomCoordinates, + const RealOpenMMVector& partialCharges, std::vector& inputForces); /**--------------------------------------------------------------------------------------- @@ -201,7 +201,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static double getVolumeD( double r, double R, double S ); + static double getVolumeD(double r, double R, double S); /**--------------------------------------------------------------------------------------- @@ -215,7 +215,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static double getLD( double r, double x, double S ); + static double getLD(double r, double x, double S); /**--------------------------------------------------------------------------------------- @@ -229,7 +229,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static double dL_drD( double r, double x, double S ); + static double dL_drD(double r, double x, double S); /**--------------------------------------------------------------------------------------- @@ -243,7 +243,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - static double dL_dxD( double r, double x, double S ); + static double dL_dxD(double r, double x, double S); /**--------------------------------------------------------------------------------------- @@ -254,7 +254,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - RealOpenMMVector& getSwitchDeriviative( void ); + RealOpenMMVector& getSwitchDeriviative(); /**--------------------------------------------------------------------------------------- @@ -268,8 +268,8 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void quinticSpline( RealOpenMM x, RealOpenMM rl, RealOpenMM ru, - RealOpenMM* outValue, RealOpenMM* outDerivative ); + void quinticSpline(RealOpenMM x, RealOpenMM rl, RealOpenMM ru, + RealOpenMM* outValue, RealOpenMM* outDerivative); /**--------------------------------------------------------------------------------------- @@ -285,9 +285,9 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void computeBornRadiiUsingQuinticSpline( RealOpenMM atomicRadius3, RealOpenMM bornSum, - GBVIParameters* gbviParameters, - RealOpenMM* bornRadius, RealOpenMM* switchDeriviative ); + void computeBornRadiiUsingQuinticSpline(RealOpenMM atomicRadius3, RealOpenMM bornSum, + GBVIParameters* gbviParameters, + RealOpenMM* bornRadius, RealOpenMM* switchDeriviative); /**--------------------------------------------------------------------------------------- @@ -303,11 +303,11 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void printGbvi( const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log ); + void printGbvi(const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, + const RealOpenMMVector& bornRadii, + const RealOpenMMVector& bornForces, + const std::vector& forces, + const std::string& idString, FILE* log); }; diff --git a/platforms/reference/include/CpuObc.h b/platforms/reference/include/CpuObc.h index 5e8879e72..df9565a42 100644 --- a/platforms/reference/include/CpuObc.h +++ b/platforms/reference/include/CpuObc.h @@ -59,7 +59,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - CpuObc( ObcParameters* obcParameters ); + CpuObc(ObcParameters* obcParameters); /**--------------------------------------------------------------------------------------- @@ -67,7 +67,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - ~CpuObc( ); + ~CpuObc(); /**--------------------------------------------------------------------------------------- @@ -77,7 +77,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - ObcParameters* getObcParameters( void ) const; + ObcParameters* getObcParameters() const; /**--------------------------------------------------------------------------------------- @@ -87,7 +87,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - void setObcParameters( ObcParameters* obcParameters ); + void setObcParameters(ObcParameters* obcParameters); /**--------------------------------------------------------------------------------------- @@ -97,7 +97,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - int includeAceApproximation( void ) const; + int includeAceApproximation() const; /**--------------------------------------------------------------------------------------- @@ -107,7 +107,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - void setIncludeAceApproximation( int includeAceApproximation ); + void setIncludeAceApproximation(int includeAceApproximation); /**--------------------------------------------------------------------------------------- @@ -117,7 +117,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - RealOpenMMVector& getObcChain( void ); + RealOpenMMVector& getObcChain(); /**--------------------------------------------------------------------------------------- @@ -128,7 +128,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - void computeBornRadii( const std::vector& atomCoordinates, RealOpenMMVector& bornRadii ); + void computeBornRadii(const std::vector& atomCoordinates, RealOpenMMVector& bornRadii); /**--------------------------------------------------------------------------------------- @@ -142,8 +142,8 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - void computeAceNonPolarForce( const ObcParameters* obcParameters, const RealOpenMMVector& bornRadii, - RealOpenMM* energy, RealOpenMMVector& forces ) const; + void computeAceNonPolarForce(const ObcParameters* obcParameters, const RealOpenMMVector& bornRadii, + RealOpenMM* energy, RealOpenMMVector& forces) const; /**--------------------------------------------------------------------------------------- @@ -155,8 +155,8 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - RealOpenMM computeBornEnergyForces( const std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, std::vector& forces ); + RealOpenMM computeBornEnergyForces(const std::vector& atomCoordinates, + const RealOpenMMVector& partialCharges, std::vector& forces); /**--------------------------------------------------------------------------------------- @@ -172,12 +172,12 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - void printObc( const std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log ); + void printObc(const std::vector& atomCoordinates, + const RealOpenMMVector& partialCharges, + const RealOpenMMVector& bornRadii, + const RealOpenMMVector& bornForces, + const std::vector& forces, + const std::string& idString, FILE* log); }; diff --git a/platforms/reference/include/GBVIParameters.h b/platforms/reference/include/GBVIParameters.h index 44e3403e7..54028ae25 100644 --- a/platforms/reference/include/GBVIParameters.h +++ b/platforms/reference/include/GBVIParameters.h @@ -82,7 +82,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - GBVIParameters( int numberOfAtoms ); + GBVIParameters(int numberOfAtoms); /**--------------------------------------------------------------------------------------- @@ -90,7 +90,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - ~GBVIParameters( ); + ~GBVIParameters(); /**--------------------------------------------------------------------------------------- @@ -100,7 +100,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - int getNumberOfAtoms( void ) const; + int getNumberOfAtoms() const; /**--------------------------------------------------------------------------------------- @@ -110,7 +110,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getElectricConstant( void ) const; + RealOpenMM getElectricConstant() const; /**--------------------------------------------------------------------------------------- @@ -120,7 +120,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getSolventDielectric( void ) const; + RealOpenMM getSolventDielectric() const; /**--------------------------------------------------------------------------------------- @@ -130,7 +130,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setSolventDielectric( RealOpenMM solventDielectric ); + void setSolventDielectric(RealOpenMM solventDielectric); /**--------------------------------------------------------------------------------------- @@ -140,7 +140,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getSoluteDielectric( void ) const; + RealOpenMM getSoluteDielectric() const; /**--------------------------------------------------------------------------------------- @@ -150,7 +150,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setSoluteDielectric( RealOpenMM soluteDielectric ); + void setSoluteDielectric(RealOpenMM soluteDielectric); /**--------------------------------------------------------------------------------------- @@ -160,7 +160,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getScaledRadii( void ) const; + const RealOpenMMVector& getScaledRadii() const; /**--------------------------------------------------------------------------------------- @@ -170,7 +170,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setScaledRadii( const RealOpenMMVector& scaledRadii ); + void setScaledRadii(const RealOpenMMVector& scaledRadii); /**--------------------------------------------------------------------------------------- @@ -180,7 +180,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getAtomicRadii( void ) const; + const RealOpenMMVector& getAtomicRadii() const; /**--------------------------------------------------------------------------------------- @@ -190,7 +190,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setAtomicRadii( const RealOpenMMVector& atomicRadii ); + void setAtomicRadii(const RealOpenMMVector& atomicRadii); /**--------------------------------------------------------------------------------------- @@ -200,7 +200,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getGammaParameters( void ) const; + const RealOpenMMVector& getGammaParameters() const; /**--------------------------------------------------------------------------------------- @@ -210,7 +210,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setGammaParameters( const RealOpenMMVector& gammaParameters ); + void setGammaParameters(const RealOpenMMVector& gammaParameters); /**--------------------------------------------------------------------------------------- @@ -220,7 +220,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setUseCutoff( RealOpenMM distance ); + void setUseCutoff(RealOpenMM distance); /**--------------------------------------------------------------------------------------- @@ -274,7 +274,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getTau( void ) const; + RealOpenMM getTau() const; /**--------------------------------------------------------------------------------------- @@ -284,7 +284,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - int getBornRadiusScalingMethod( void ) const; + int getBornRadiusScalingMethod() const; /**--------------------------------------------------------------------------------------- @@ -294,7 +294,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setBornRadiusScalingMethod( int bornRadiusScalingMethod ); + void setBornRadiusScalingMethod(int bornRadiusScalingMethod); /**--------------------------------------------------------------------------------------- @@ -304,7 +304,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getQuinticLowerLimitFactor( void ) const; + RealOpenMM getQuinticLowerLimitFactor() const; /**--------------------------------------------------------------------------------------- @@ -314,7 +314,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setQuinticLowerLimitFactor( RealOpenMM quinticLowerLimitFactor ); + void setQuinticLowerLimitFactor(RealOpenMM quinticLowerLimitFactor); /**--------------------------------------------------------------------------------------- @@ -324,7 +324,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getQuinticUpperBornRadiusLimit( void ) const; + RealOpenMM getQuinticUpperBornRadiusLimit() const; /**--------------------------------------------------------------------------------------- @@ -334,7 +334,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setQuinticUpperBornRadiusLimit( RealOpenMM quinticUpperSplineLimit ); + void setQuinticUpperBornRadiusLimit(RealOpenMM quinticUpperSplineLimit); }; diff --git a/platforms/reference/include/ObcParameters.h b/platforms/reference/include/ObcParameters.h index 3eb10c706..129380e80 100644 --- a/platforms/reference/include/ObcParameters.h +++ b/platforms/reference/include/ObcParameters.h @@ -75,7 +75,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setDielectricOffset( RealOpenMM dielectricOffset ); + void setDielectricOffset(RealOpenMM dielectricOffset); public: @@ -87,7 +87,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - ObcParameters( int numberOfAtoms, ObcParameters::ObcType obcType = ObcTypeII ); + ObcParameters(int numberOfAtoms, ObcParameters::ObcType obcType = ObcTypeII); /**--------------------------------------------------------------------------------------- @@ -95,7 +95,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - ~ObcParameters( ); + ~ObcParameters(); /**--------------------------------------------------------------------------------------- @@ -105,7 +105,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - int getNumberOfAtoms( void ) const; + int getNumberOfAtoms() const; /**--------------------------------------------------------------------------------------- @@ -115,7 +115,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getElectricConstant( void ) const; + RealOpenMM getElectricConstant() const; /**--------------------------------------------------------------------------------------- @@ -125,7 +125,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getProbeRadius( void ) const; + RealOpenMM getProbeRadius() const; /**--------------------------------------------------------------------------------------- @@ -135,7 +135,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setProbeRadius( RealOpenMM probeRadius ); + void setProbeRadius(RealOpenMM probeRadius); /**--------------------------------------------------------------------------------------- @@ -146,7 +146,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getPi4Asolv( void ) const; + RealOpenMM getPi4Asolv() const; /**--------------------------------------------------------------------------------------- @@ -154,7 +154,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setPi4Asolv( RealOpenMM pi4Asolv ); + void setPi4Asolv(RealOpenMM pi4Asolv); /**--------------------------------------------------------------------------------------- @@ -164,7 +164,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getSolventDielectric( void ) const; + RealOpenMM getSolventDielectric() const; /**--------------------------------------------------------------------------------------- @@ -174,7 +174,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setSolventDielectric( RealOpenMM solventDielectric ); + void setSolventDielectric(RealOpenMM solventDielectric); /**--------------------------------------------------------------------------------------- @@ -184,7 +184,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getSoluteDielectric( void ) const; + RealOpenMM getSoluteDielectric() const; /**--------------------------------------------------------------------------------------- @@ -194,7 +194,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setSoluteDielectric( RealOpenMM soluteDielectric ); + void setSoluteDielectric(RealOpenMM soluteDielectric); /**--------------------------------------------------------------------------------------- @@ -204,7 +204,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - ObcParameters::ObcType getObcType( void ) const; + ObcParameters::ObcType getObcType() const; /**--------------------------------------------------------------------------------------- @@ -214,7 +214,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setObcTypeParameters( ObcParameters::ObcType obcType ); + void setObcTypeParameters(ObcParameters::ObcType obcType); /**--------------------------------------------------------------------------------------- @@ -224,7 +224,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getAlphaObc( void ) const; + RealOpenMM getAlphaObc() const; /**--------------------------------------------------------------------------------------- @@ -234,7 +234,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getBetaObc( void ) const; + RealOpenMM getBetaObc() const; /**--------------------------------------------------------------------------------------- @@ -244,7 +244,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getGammaObc( void ) const; + RealOpenMM getGammaObc() const; /**--------------------------------------------------------------------------------------- @@ -254,7 +254,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - RealOpenMM getDielectricOffset( void ) const; + RealOpenMM getDielectricOffset() const; /**--------------------------------------------------------------------------------------- @@ -264,7 +264,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getScaledRadiusFactors( void ) const; + const RealOpenMMVector& getScaledRadiusFactors() const; /**--------------------------------------------------------------------------------------- @@ -274,7 +274,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setScaledRadiusFactors( const RealOpenMMVector& scaledRadiusFactors ); + void setScaledRadiusFactors(const RealOpenMMVector& scaledRadiusFactors); /**--------------------------------------------------------------------------------------- @@ -284,7 +284,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getAtomicRadii( void ) const; + const RealOpenMMVector& getAtomicRadii() const; /**--------------------------------------------------------------------------------------- @@ -294,7 +294,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setAtomicRadii( const RealOpenMMVector& atomicRadii ); + void setAtomicRadii(const RealOpenMMVector& atomicRadii); /**--------------------------------------------------------------------------------------- @@ -305,7 +305,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setUseCutoff( RealOpenMM distance ); + void setUseCutoff(RealOpenMM distance); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceAndersenThermostat.h b/platforms/reference/include/ReferenceAndersenThermostat.h index e4dbba765..856d7ebb5 100644 --- a/platforms/reference/include/ReferenceAndersenThermostat.h +++ b/platforms/reference/include/ReferenceAndersenThermostat.h @@ -42,7 +42,7 @@ class ReferenceAndersenThermostat { --------------------------------------------------------------------------------------- */ - ReferenceAndersenThermostat( ); + ReferenceAndersenThermostat(); /**--------------------------------------------------------------------------------------- @@ -50,7 +50,7 @@ class ReferenceAndersenThermostat { --------------------------------------------------------------------------------------- */ - ~ReferenceAndersenThermostat( ); + ~ReferenceAndersenThermostat(); /**--------------------------------------------------------------------------------------- @@ -65,8 +65,8 @@ class ReferenceAndersenThermostat { --------------------------------------------------------------------------------------- */ - void applyThermostat( const std::vector >& atomGroups, std::vector& atomVelocities, std::vector& atomMasses, - RealOpenMM temperature, RealOpenMM collisionFrequency, RealOpenMM stepSize ) const; + void applyThermostat(const std::vector >& atomGroups, std::vector& atomVelocities, std::vector& atomMasses, + RealOpenMM temperature, RealOpenMM collisionFrequency, RealOpenMM stepSize) const; }; diff --git a/platforms/reference/include/ReferenceAngleBondIxn.h b/platforms/reference/include/ReferenceAngleBondIxn.h index 226515b65..4a18be67e 100644 --- a/platforms/reference/include/ReferenceAngleBondIxn.h +++ b/platforms/reference/include/ReferenceAngleBondIxn.h @@ -41,7 +41,7 @@ class ReferenceAngleBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ReferenceAngleBondIxn( ); + ReferenceAngleBondIxn(); /**--------------------------------------------------------------------------------------- @@ -49,7 +49,7 @@ class ReferenceAngleBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceAngleBondIxn( ); + ~ReferenceAngleBondIxn(); /**--------------------------------------------------------------------------------------- @@ -63,8 +63,8 @@ class ReferenceAngleBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void getPrefactorsGivenAngleCosine( RealOpenMM cosine, RealOpenMM* angleParameters, - RealOpenMM* dEdR, RealOpenMM* energyTerm ) const; + void getPrefactorsGivenAngleCosine(RealOpenMM cosine, RealOpenMM* angleParameters, + RealOpenMM* dEdR, RealOpenMM* energyTerm) const; /**--------------------------------------------------------------------------------------- @@ -79,9 +79,9 @@ class ReferenceAngleBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; }; diff --git a/platforms/reference/include/ReferenceBondForce.h b/platforms/reference/include/ReferenceBondForce.h index db836d635..7c8c0c67a 100644 --- a/platforms/reference/include/ReferenceBondForce.h +++ b/platforms/reference/include/ReferenceBondForce.h @@ -42,7 +42,7 @@ class OPENMM_EXPORT ReferenceBondForce : public ReferenceForce { --------------------------------------------------------------------------------------- */ - ReferenceBondForce( ); + ReferenceBondForce(); /**--------------------------------------------------------------------------------------- @@ -50,7 +50,7 @@ class OPENMM_EXPORT ReferenceBondForce : public ReferenceForce { --------------------------------------------------------------------------------------- */ - ~ReferenceBondForce( ); + ~ReferenceBondForce(); /**--------------------------------------------------------------------------------------- @@ -67,10 +67,10 @@ class OPENMM_EXPORT ReferenceBondForce : public ReferenceForce { --------------------------------------------------------------------------------------- */ - void calculateForce( int numberOfBonds, int** atomIndices, + void calculateForce(int numberOfBonds, int** atomIndices, std::vector& atomCoordinates, RealOpenMM** parameters, std::vector& forces, - RealOpenMM* totalEnergy, ReferenceBondIxn& referenceBondIxn ); + RealOpenMM* totalEnergy, ReferenceBondIxn& referenceBondIxn); }; diff --git a/platforms/reference/include/ReferenceBondIxn.h b/platforms/reference/include/ReferenceBondIxn.h index d07e84d79..cdc07c1ea 100644 --- a/platforms/reference/include/ReferenceBondIxn.h +++ b/platforms/reference/include/ReferenceBondIxn.h @@ -43,7 +43,7 @@ class OPENMM_EXPORT ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ReferenceBondIxn( ); + ReferenceBondIxn(); /**--------------------------------------------------------------------------------------- @@ -51,7 +51,7 @@ class OPENMM_EXPORT ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceBondIxn( ); + ~ReferenceBondIxn(); /**--------------------------------------------------------------------------------------- @@ -65,9 +65,9 @@ class OPENMM_EXPORT ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - virtual void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + virtual void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; /**--------------------------------------------------------------------------------------- @@ -82,7 +82,7 @@ class OPENMM_EXPORT ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - static RealOpenMM getNormedDotProduct( RealOpenMM* vector1, RealOpenMM* vector2, int hasREntry ); + static RealOpenMM getNormedDotProduct(RealOpenMM* vector1, RealOpenMM* vector2, int hasREntry); /**--------------------------------------------------------------------------------------- @@ -98,8 +98,8 @@ class OPENMM_EXPORT ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - static RealOpenMM getAngleBetweenTwoVectors( RealOpenMM* vector1, RealOpenMM* vector2, - RealOpenMM* outputDotProduct, int hasREntry ); + static RealOpenMM getAngleBetweenTwoVectors(RealOpenMM* vector1, RealOpenMM* vector2, + RealOpenMM* outputDotProduct, int hasREntry); /**--------------------------------------------------------------------------------------- @@ -119,10 +119,10 @@ class OPENMM_EXPORT ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - static RealOpenMM getDihedralAngleBetweenThreeVectors( RealOpenMM* vector1, RealOpenMM* vector2, - RealOpenMM* vector3, RealOpenMM** outputCrossProduct, - RealOpenMM* cosineOfAngle, RealOpenMM* signVector, - RealOpenMM* signOfAngle, int hasREntry ); + static RealOpenMM getDihedralAngleBetweenThreeVectors(RealOpenMM* vector1, RealOpenMM* vector2, + RealOpenMM* vector3, RealOpenMM** outputCrossProduct, + RealOpenMM* cosineOfAngle, RealOpenMM* signVector, + RealOpenMM* signOfAngle, int hasREntry); }; diff --git a/platforms/reference/include/ReferenceBrownianDynamics.h b/platforms/reference/include/ReferenceBrownianDynamics.h index 935545123..f2d7e08b8 100644 --- a/platforms/reference/include/ReferenceBrownianDynamics.h +++ b/platforms/reference/include/ReferenceBrownianDynamics.h @@ -50,7 +50,7 @@ class ReferenceBrownianDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ReferenceBrownianDynamics( int numberOfAtoms, RealOpenMM deltaT, RealOpenMM friction, RealOpenMM temperature ); + ReferenceBrownianDynamics(int numberOfAtoms, RealOpenMM deltaT, RealOpenMM friction, RealOpenMM temperature); /**--------------------------------------------------------------------------------------- @@ -58,7 +58,7 @@ class ReferenceBrownianDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ~ReferenceBrownianDynamics( ); + ~ReferenceBrownianDynamics(); /**--------------------------------------------------------------------------------------- @@ -68,7 +68,7 @@ class ReferenceBrownianDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - RealOpenMM getFriction( void ) const; + RealOpenMM getFriction() const; /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceCCMAAlgorithm.h b/platforms/reference/include/ReferenceCCMAAlgorithm.h index d1e7d5fe7..ff8021414 100644 --- a/platforms/reference/include/ReferenceCCMAAlgorithm.h +++ b/platforms/reference/include/ReferenceCCMAAlgorithm.h @@ -69,22 +69,22 @@ public: */ ReferenceCCMAAlgorithm(int numberOfAtoms, int numberOfConstraints, const std::vector >& atomIndices, const std::vector& distance, std::vector& masses, std::vector& angles); - ~ReferenceCCMAAlgorithm( ); + ~ReferenceCCMAAlgorithm(); /** * Get the number of constraints. */ - int getNumberOfConstraints( void ) const; + int getNumberOfConstraints() const; /** * Get the maximum number of iterations to perform. */ - int getMaximumNumberOfIterations( void ) const; + int getMaximumNumberOfIterations() const; /** * Set the maximum number of iterations to perform. */ - void setMaximumNumberOfIterations( int maximumNumberOfIterations ); + void setMaximumNumberOfIterations(int maximumNumberOfIterations); /** * Apply the constraint algorithm. diff --git a/platforms/reference/include/ReferenceCustomAngleIxn.h b/platforms/reference/include/ReferenceCustomAngleIxn.h index e98584929..507236db7 100644 --- a/platforms/reference/include/ReferenceCustomAngleIxn.h +++ b/platforms/reference/include/ReferenceCustomAngleIxn.h @@ -57,7 +57,7 @@ class ReferenceCustomAngleIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceCustomAngleIxn( ); + ~ReferenceCustomAngleIxn(); /**--------------------------------------------------------------------------------------- @@ -71,7 +71,7 @@ class ReferenceCustomAngleIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, RealOpenMM* totalEnergy) const; diff --git a/platforms/reference/include/ReferenceCustomBondIxn.h b/platforms/reference/include/ReferenceCustomBondIxn.h index b9fffd846..8bec456b5 100644 --- a/platforms/reference/include/ReferenceCustomBondIxn.h +++ b/platforms/reference/include/ReferenceCustomBondIxn.h @@ -58,7 +58,7 @@ class ReferenceCustomBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceCustomBondIxn( ); + ~ReferenceCustomBondIxn(); /**--------------------------------------------------------------------------------------- @@ -72,9 +72,9 @@ class ReferenceCustomBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; }; diff --git a/platforms/reference/include/ReferenceCustomExternalIxn.h b/platforms/reference/include/ReferenceCustomExternalIxn.h index cae1f8da4..39af99366 100644 --- a/platforms/reference/include/ReferenceCustomExternalIxn.h +++ b/platforms/reference/include/ReferenceCustomExternalIxn.h @@ -65,7 +65,7 @@ class ReferenceCustomExternalIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceCustomExternalIxn( ); + ~ReferenceCustomExternalIxn(); /**--------------------------------------------------------------------------------------- @@ -79,8 +79,8 @@ class ReferenceCustomExternalIxn { --------------------------------------------------------------------------------------- */ - void calculateForce( int atomIndex, std::vector& atomCoordinates, - RealOpenMM* parameters, std::vector& forces, RealOpenMM* energy ) const; + void calculateForce(int atomIndex, std::vector& atomCoordinates, + RealOpenMM* parameters, std::vector& forces, RealOpenMM* energy) const; }; diff --git a/platforms/reference/include/ReferenceCustomGBIxn.h b/platforms/reference/include/ReferenceCustomGBIxn.h index c6c642898..9acae1dde 100644 --- a/platforms/reference/include/ReferenceCustomGBIxn.h +++ b/platforms/reference/include/ReferenceCustomGBIxn.h @@ -244,7 +244,7 @@ class ReferenceCustomGBIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceCustomGBIxn( ); + ~ReferenceCustomGBIxn(); /**--------------------------------------------------------------------------------------- @@ -255,7 +255,7 @@ class ReferenceCustomGBIxn { --------------------------------------------------------------------------------------- */ - void setUseCutoff( RealOpenMM distance, const OpenMM::NeighborList& neighbors ); + void setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceCustomNonbondedIxn.h b/platforms/reference/include/ReferenceCustomNonbondedIxn.h index 91b3f9854..3325bd510 100644 --- a/platforms/reference/include/ReferenceCustomNonbondedIxn.h +++ b/platforms/reference/include/ReferenceCustomNonbondedIxn.h @@ -68,8 +68,8 @@ class ReferenceCustomNonbondedIxn { --------------------------------------------------------------------------------------- */ - void calculateOneIxn( int atom1, int atom2, std::vector& atomCoordinates, std::vector& forces, - RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ); + void calculateOneIxn(int atom1, int atom2, std::vector& atomCoordinates, std::vector& forces, + RealOpenMM* energyByAtom, RealOpenMM* totalEnergy); public: @@ -89,7 +89,7 @@ class ReferenceCustomNonbondedIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceCustomNonbondedIxn( ); + ~ReferenceCustomNonbondedIxn(); /**--------------------------------------------------------------------------------------- @@ -100,7 +100,7 @@ class ReferenceCustomNonbondedIxn { --------------------------------------------------------------------------------------- */ - void setUseCutoff( RealOpenMM distance, const OpenMM::NeighborList& neighbors ); + void setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors); /**--------------------------------------------------------------------------------------- @@ -121,7 +121,7 @@ class ReferenceCustomNonbondedIxn { --------------------------------------------------------------------------------------- */ - void setUseSwitchingFunction( RealOpenMM distance ); + void setUseSwitchingFunction(RealOpenMM distance); /**--------------------------------------------------------------------------------------- @@ -152,10 +152,10 @@ class ReferenceCustomNonbondedIxn { --------------------------------------------------------------------------------------- */ - void calculatePairIxn( int numberOfAtoms, std::vector& atomCoordinates, + void calculatePairIxn(int numberOfAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, std::vector >& exclusions, RealOpenMM* fixedParameters, const std::map& globalParameters, - std::vector& forces, RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ); + std::vector& forces, RealOpenMM* energyByAtom, RealOpenMM* totalEnergy); // --------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceCustomTorsionIxn.h b/platforms/reference/include/ReferenceCustomTorsionIxn.h index 73ea6a8fd..ae024f792 100644 --- a/platforms/reference/include/ReferenceCustomTorsionIxn.h +++ b/platforms/reference/include/ReferenceCustomTorsionIxn.h @@ -57,7 +57,7 @@ class ReferenceCustomTorsionIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceCustomTorsionIxn( ); + ~ReferenceCustomTorsionIxn(); /**--------------------------------------------------------------------------------------- @@ -71,9 +71,9 @@ class ReferenceCustomTorsionIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; }; diff --git a/platforms/reference/include/ReferenceDynamics.h b/platforms/reference/include/ReferenceDynamics.h index 9a3bb3ea5..f5ee1fb4f 100644 --- a/platforms/reference/include/ReferenceDynamics.h +++ b/platforms/reference/include/ReferenceDynamics.h @@ -68,7 +68,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ReferenceDynamics( int numberOfAtoms, RealOpenMM _deltaT, RealOpenMM temperature ); + ReferenceDynamics(int numberOfAtoms, RealOpenMM _deltaT, RealOpenMM temperature); /**--------------------------------------------------------------------------------------- @@ -76,7 +76,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - virtual ~ReferenceDynamics( ); + virtual ~ReferenceDynamics(); /**--------------------------------------------------------------------------------------- @@ -86,7 +86,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - int getNumberOfAtoms( void ) const; + int getNumberOfAtoms() const; /**--------------------------------------------------------------------------------------- @@ -96,7 +96,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - int getTimeStep( void ) const; + int getTimeStep() const; /**--------------------------------------------------------------------------------------- @@ -106,7 +106,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - int incrementTimeStep( void ); + int incrementTimeStep(); /**--------------------------------------------------------------------------------------- @@ -116,7 +116,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - RealOpenMM getDeltaT( void ) const; + RealOpenMM getDeltaT() const; /**--------------------------------------------------------------------------------------- @@ -124,7 +124,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - void setDeltaT( RealOpenMM deltaT ); + void setDeltaT(RealOpenMM deltaT); /**--------------------------------------------------------------------------------------- @@ -134,7 +134,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - RealOpenMM getTemperature( void ) const; + RealOpenMM getTemperature() const; /**--------------------------------------------------------------------------------------- @@ -160,7 +160,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ReferenceConstraintAlgorithm* getReferenceConstraintAlgorithm( void ) const; + ReferenceConstraintAlgorithm* getReferenceConstraintAlgorithm() const; /**--------------------------------------------------------------------------------------- @@ -170,7 +170,7 @@ class OPENMM_EXPORT ReferenceDynamics { --------------------------------------------------------------------------------------- */ - void setReferenceConstraintAlgorithm( ReferenceConstraintAlgorithm* referenceConstraint ); + void setReferenceConstraintAlgorithm(ReferenceConstraintAlgorithm* referenceConstraint); }; } // namespace OpenMM diff --git a/platforms/reference/include/ReferenceForce.h b/platforms/reference/include/ReferenceForce.h index 1a2b4a999..12f79b3c9 100644 --- a/platforms/reference/include/ReferenceForce.h +++ b/platforms/reference/include/ReferenceForce.h @@ -44,7 +44,7 @@ class OPENMM_EXPORT ReferenceForce { --------------------------------------------------------------------------------------- */ - ReferenceForce( ); + ReferenceForce(); /**--------------------------------------------------------------------------------------- @@ -52,7 +52,7 @@ class OPENMM_EXPORT ReferenceForce { --------------------------------------------------------------------------------------- */ - ~ReferenceForce( ); + ~ReferenceForce(); /**--------------------------------------------------------------------------------------- @@ -80,8 +80,8 @@ class OPENMM_EXPORT ReferenceForce { --------------------------------------------------------------------------------------- */ - static void getDeltaR( const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, - RealOpenMM* deltaR ); + static void getDeltaR(const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, + RealOpenMM* deltaR); /**--------------------------------------------------------------------------------------- @@ -95,8 +95,8 @@ class OPENMM_EXPORT ReferenceForce { --------------------------------------------------------------------------------------- */ - static void getDeltaRPeriodic( const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, - const RealOpenMM* boxSize, RealOpenMM* deltaR ); + static void getDeltaRPeriodic(const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, + const RealOpenMM* boxSize, RealOpenMM* deltaR); /**--------------------------------------------------------------------------------------- @@ -110,8 +110,8 @@ class OPENMM_EXPORT ReferenceForce { --------------------------------------------------------------------------------------- */ - static void getDeltaRPeriodic( const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, - const OpenMM::RealVec* boxVectors, RealOpenMM* deltaR ); + static void getDeltaRPeriodic(const OpenMM::RealVec& atomCoordinatesI, const OpenMM::RealVec& atomCoordinatesJ, + const OpenMM::RealVec* boxVectors, RealOpenMM* deltaR); /** * Get a pointer to the memory for setting a variable in a CompiledExpression. If the expression diff --git a/platforms/reference/include/ReferenceHarmonicBondIxn.h b/platforms/reference/include/ReferenceHarmonicBondIxn.h index 5fab10326..9c8a6b087 100644 --- a/platforms/reference/include/ReferenceHarmonicBondIxn.h +++ b/platforms/reference/include/ReferenceHarmonicBondIxn.h @@ -41,7 +41,7 @@ class ReferenceHarmonicBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ReferenceHarmonicBondIxn( ); + ReferenceHarmonicBondIxn(); /**--------------------------------------------------------------------------------------- @@ -49,7 +49,7 @@ class ReferenceHarmonicBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceHarmonicBondIxn( ); + ~ReferenceHarmonicBondIxn(); /**--------------------------------------------------------------------------------------- @@ -64,9 +64,9 @@ class ReferenceHarmonicBondIxn : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; }; diff --git a/platforms/reference/include/ReferenceLJCoulomb14.h b/platforms/reference/include/ReferenceLJCoulomb14.h index f286ebf15..744eb7411 100644 --- a/platforms/reference/include/ReferenceLJCoulomb14.h +++ b/platforms/reference/include/ReferenceLJCoulomb14.h @@ -40,7 +40,7 @@ class OPENMM_EXPORT ReferenceLJCoulomb14 : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ReferenceLJCoulomb14( ); + ReferenceLJCoulomb14(); /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ class OPENMM_EXPORT ReferenceLJCoulomb14 : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceLJCoulomb14( ); + ~ReferenceLJCoulomb14(); /**--------------------------------------------------------------------------------------- @@ -62,9 +62,9 @@ class OPENMM_EXPORT ReferenceLJCoulomb14 : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; }; diff --git a/platforms/reference/include/ReferenceLJCoulombIxn.h b/platforms/reference/include/ReferenceLJCoulombIxn.h index f0d3f8fda..25a429994 100644 --- a/platforms/reference/include/ReferenceLJCoulombIxn.h +++ b/platforms/reference/include/ReferenceLJCoulombIxn.h @@ -67,9 +67,9 @@ class ReferenceLJCoulombIxn { --------------------------------------------------------------------------------------- */ - void calculateOneIxn( int atom1, int atom2, std::vector& atomCoordinates, - RealOpenMM** atomParameters, std::vector& forces, - RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const; + void calculateOneIxn(int atom1, int atom2, std::vector& atomCoordinates, + RealOpenMM** atomParameters, std::vector& forces, + RealOpenMM* energyByAtom, RealOpenMM* totalEnergy) const; public: @@ -80,7 +80,7 @@ class ReferenceLJCoulombIxn { --------------------------------------------------------------------------------------- */ - ReferenceLJCoulombIxn( ); + ReferenceLJCoulombIxn(); /**--------------------------------------------------------------------------------------- @@ -88,7 +88,7 @@ class ReferenceLJCoulombIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceLJCoulombIxn( ); + ~ReferenceLJCoulombIxn(); /**--------------------------------------------------------------------------------------- @@ -100,7 +100,7 @@ class ReferenceLJCoulombIxn { --------------------------------------------------------------------------------------- */ - void setUseCutoff( RealOpenMM distance, const OpenMM::NeighborList& neighbors, RealOpenMM solventDielectric ); + void setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors, RealOpenMM solventDielectric); /**--------------------------------------------------------------------------------------- @@ -110,7 +110,7 @@ class ReferenceLJCoulombIxn { --------------------------------------------------------------------------------------- */ - void setUseSwitchingFunction( RealOpenMM distance ); + void setUseSwitchingFunction(RealOpenMM distance); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceLincsAlgorithm.h b/platforms/reference/include/ReferenceLincsAlgorithm.h index 1271fa82c..04ba35157 100644 --- a/platforms/reference/include/ReferenceLincsAlgorithm.h +++ b/platforms/reference/include/ReferenceLincsAlgorithm.h @@ -92,7 +92,7 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { --------------------------------------------------------------------------------------- */ - ReferenceLincsAlgorithm( int numberOfConstraints, int** atomIndices, RealOpenMM* distance ); + ReferenceLincsAlgorithm(int numberOfConstraints, int** atomIndices, RealOpenMM* distance); /**--------------------------------------------------------------------------------------- @@ -102,7 +102,7 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { --------------------------------------------------------------------------------------- */ - int getNumberOfConstraints( void ) const; + int getNumberOfConstraints() const; /**--------------------------------------------------------------------------------------- @@ -112,7 +112,7 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { --------------------------------------------------------------------------------------- */ - int getNumTerms( void ) const; + int getNumTerms() const; /**--------------------------------------------------------------------------------------- @@ -120,7 +120,7 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { --------------------------------------------------------------------------------------- */ - void setNumTerms( int terms ); + void setNumTerms(int terms); /**--------------------------------------------------------------------------------------- @@ -136,8 +136,8 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { --------------------------------------------------------------------------------------- */ - int apply( int numberOfAtoms, std::vector& atomCoordinates, - std::vector& atomCoordinatesP, std::vector& inverseMasses ); + int apply(int numberOfAtoms, std::vector& atomCoordinates, + std::vector& atomCoordinatesP, std::vector& inverseMasses); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceNeighborList.h b/platforms/reference/include/ReferenceNeighborList.h index 0e36f96b0..f7e094fcf 100644 --- a/platforms/reference/include/ReferenceNeighborList.h +++ b/platforms/reference/include/ReferenceNeighborList.h @@ -27,7 +27,7 @@ void OPENMM_EXPORT computeNeighborListNaive( double maxDistance, double minDistance = 0.0, bool reportSymmetricPairs = false - ); + ); // O(n) neighbor list method using voxel hash data structure // parameter neighborList is automatically clear()ed before @@ -42,7 +42,7 @@ void OPENMM_EXPORT computeNeighborListVoxelHash( double maxDistance, double minDistance = 0.0, bool reportSymmetricPairs = false - ); + ); } // namespace OpenMM diff --git a/platforms/reference/include/ReferencePairIxn.h b/platforms/reference/include/ReferencePairIxn.h index a093d04eb..e03e75dc2 100644 --- a/platforms/reference/include/ReferencePairIxn.h +++ b/platforms/reference/include/ReferencePairIxn.h @@ -42,7 +42,7 @@ class OPENMM_EXPORT ReferencePairIxn { --------------------------------------------------------------------------------------- */ - ReferencePairIxn( ); + ReferencePairIxn(); /**--------------------------------------------------------------------------------------- @@ -50,7 +50,7 @@ class OPENMM_EXPORT ReferencePairIxn { --------------------------------------------------------------------------------------- */ - ~ReferencePairIxn( ); + ~ReferencePairIxn(); /**--------------------------------------------------------------------------------------- @@ -67,10 +67,10 @@ class OPENMM_EXPORT ReferencePairIxn { --------------------------------------------------------------------------------------- */ - virtual void calculatePairIxn( int numberOfAtoms, std::vector& atomCoordinates, + virtual void calculatePairIxn(int numberOfAtoms, std::vector& atomCoordinates, RealOpenMM** atomParameters, int** exclusions, RealOpenMM* fixedParameters, std::vector& forces, - RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const = 0; + RealOpenMM* energyByAtom, RealOpenMM* totalEnergy) const = 0; }; diff --git a/platforms/reference/include/ReferenceProperDihedralBond.h b/platforms/reference/include/ReferenceProperDihedralBond.h index ad2b89b39..e16cf762f 100644 --- a/platforms/reference/include/ReferenceProperDihedralBond.h +++ b/platforms/reference/include/ReferenceProperDihedralBond.h @@ -41,7 +41,7 @@ class OPENMM_EXPORT ReferenceProperDihedralBond : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ReferenceProperDihedralBond( ); + ReferenceProperDihedralBond(); /**--------------------------------------------------------------------------------------- @@ -49,7 +49,7 @@ class OPENMM_EXPORT ReferenceProperDihedralBond : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceProperDihedralBond( ); + ~ReferenceProperDihedralBond(); /**--------------------------------------------------------------------------------------- @@ -65,9 +65,9 @@ class OPENMM_EXPORT ReferenceProperDihedralBond : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; }; diff --git a/platforms/reference/include/ReferenceRbDihedralBond.h b/platforms/reference/include/ReferenceRbDihedralBond.h index 832389c09..398d9237b 100644 --- a/platforms/reference/include/ReferenceRbDihedralBond.h +++ b/platforms/reference/include/ReferenceRbDihedralBond.h @@ -41,7 +41,7 @@ class OPENMM_EXPORT ReferenceRbDihedralBond : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ReferenceRbDihedralBond( ); + ReferenceRbDihedralBond(); /**--------------------------------------------------------------------------------------- @@ -49,7 +49,7 @@ class OPENMM_EXPORT ReferenceRbDihedralBond : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - ~ReferenceRbDihedralBond( ); + ~ReferenceRbDihedralBond(); /**--------------------------------------------------------------------------------------- @@ -63,9 +63,9 @@ class OPENMM_EXPORT ReferenceRbDihedralBond : public ReferenceBondIxn { --------------------------------------------------------------------------------------- */ - void calculateBondIxn( int* atomIndices, std::vector& atomCoordinates, + void calculateBondIxn(int* atomIndices, std::vector& atomCoordinates, RealOpenMM* parameters, std::vector& forces, - RealOpenMM* totalEnergy ) const; + RealOpenMM* totalEnergy) const; }; diff --git a/platforms/reference/include/ReferenceStochasticDynamics.h b/platforms/reference/include/ReferenceStochasticDynamics.h index e7c86d13c..d11ece3ec 100644 --- a/platforms/reference/include/ReferenceStochasticDynamics.h +++ b/platforms/reference/include/ReferenceStochasticDynamics.h @@ -51,7 +51,7 @@ class OPENMM_EXPORT ReferenceStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ReferenceStochasticDynamics( int numberOfAtoms, RealOpenMM deltaT, RealOpenMM tau, RealOpenMM temperature ); + ReferenceStochasticDynamics(int numberOfAtoms, RealOpenMM deltaT, RealOpenMM tau, RealOpenMM temperature); /**--------------------------------------------------------------------------------------- @@ -59,7 +59,7 @@ class OPENMM_EXPORT ReferenceStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ~ReferenceStochasticDynamics( ); + ~ReferenceStochasticDynamics(); /**--------------------------------------------------------------------------------------- @@ -69,7 +69,7 @@ class OPENMM_EXPORT ReferenceStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - RealOpenMM getTau( void ) const; + RealOpenMM getTau() const; /**--------------------------------------------------------------------------------------- @@ -100,8 +100,8 @@ class OPENMM_EXPORT ReferenceStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - virtual void updatePart1( int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, - std::vector& forces, std::vector& inverseMasses, std::vector& xPrime ); + virtual void updatePart1(int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, + std::vector& forces, std::vector& inverseMasses, std::vector& xPrime); /**--------------------------------------------------------------------------------------- @@ -115,8 +115,8 @@ class OPENMM_EXPORT ReferenceStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - virtual void updatePart2( int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, - std::vector& forces, std::vector& inverseMasses, std::vector& xPrime ); + virtual void updatePart2(int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, + std::vector& forces, std::vector& inverseMasses, std::vector& xPrime); }; diff --git a/platforms/reference/include/ReferenceVariableStochasticDynamics.h b/platforms/reference/include/ReferenceVariableStochasticDynamics.h index 9379f1e01..4f837f739 100644 --- a/platforms/reference/include/ReferenceVariableStochasticDynamics.h +++ b/platforms/reference/include/ReferenceVariableStochasticDynamics.h @@ -50,7 +50,7 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ReferenceVariableStochasticDynamics( int numberOfAtoms, RealOpenMM tau, RealOpenMM temperature, RealOpenMM accuracy ); + ReferenceVariableStochasticDynamics(int numberOfAtoms, RealOpenMM tau, RealOpenMM temperature, RealOpenMM accuracy); /**--------------------------------------------------------------------------------------- @@ -58,7 +58,7 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ~ReferenceVariableStochasticDynamics( ); + ~ReferenceVariableStochasticDynamics(); /**--------------------------------------------------------------------------------------- @@ -68,7 +68,7 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - RealOpenMM getTau( void ) const; + RealOpenMM getTau() const; /**--------------------------------------------------------------------------------------- @@ -78,7 +78,7 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - RealOpenMM getAccuracy( void ) const; + RealOpenMM getAccuracy() const; /**--------------------------------------------------------------------------------------- @@ -86,7 +86,7 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - void setAccuracy( RealOpenMM accuracy ); + void setAccuracy(RealOpenMM accuracy); /**--------------------------------------------------------------------------------------- @@ -120,9 +120,9 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - void updatePart1( int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, + void updatePart1(int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, std::vector& forces, std::vector& masses, std::vector& inverseMasses, - std::vector& xPrime, RealOpenMM maxStepSize ); + std::vector& xPrime, RealOpenMM maxStepSize); /**--------------------------------------------------------------------------------------- @@ -136,9 +136,9 @@ class ReferenceVariableStochasticDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - void updatePart2( int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, + void updatePart2(int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, std::vector& forces, std::vector& inverseMasses, - std::vector& xPrime ); + std::vector& xPrime); }; diff --git a/platforms/reference/include/ReferenceVariableVerletDynamics.h b/platforms/reference/include/ReferenceVariableVerletDynamics.h index 8bc2a250d..1827e53cf 100644 --- a/platforms/reference/include/ReferenceVariableVerletDynamics.h +++ b/platforms/reference/include/ReferenceVariableVerletDynamics.h @@ -48,7 +48,7 @@ class ReferenceVariableVerletDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ReferenceVariableVerletDynamics( int numberOfAtoms, RealOpenMM accuracy ); + ReferenceVariableVerletDynamics(int numberOfAtoms, RealOpenMM accuracy); /**--------------------------------------------------------------------------------------- @@ -56,7 +56,7 @@ class ReferenceVariableVerletDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ~ReferenceVariableVerletDynamics( ); + ~ReferenceVariableVerletDynamics(); /**--------------------------------------------------------------------------------------- @@ -66,7 +66,7 @@ class ReferenceVariableVerletDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - RealOpenMM getAccuracy( void ) const; + RealOpenMM getAccuracy() const; /**--------------------------------------------------------------------------------------- @@ -74,7 +74,7 @@ class ReferenceVariableVerletDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - void setAccuracy( RealOpenMM accuracy ); + void setAccuracy(RealOpenMM accuracy); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceVerletDynamics.h b/platforms/reference/include/ReferenceVerletDynamics.h index 1a3316728..b2dc27e54 100644 --- a/platforms/reference/include/ReferenceVerletDynamics.h +++ b/platforms/reference/include/ReferenceVerletDynamics.h @@ -49,7 +49,7 @@ class ReferenceVerletDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ReferenceVerletDynamics( int numberOfAtoms, RealOpenMM deltaT ); + ReferenceVerletDynamics(int numberOfAtoms, RealOpenMM deltaT); /**--------------------------------------------------------------------------------------- @@ -57,7 +57,7 @@ class ReferenceVerletDynamics : public ReferenceDynamics { --------------------------------------------------------------------------------------- */ - ~ReferenceVerletDynamics( ); + ~ReferenceVerletDynamics(); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/SimTKOpenMMUtilities.h b/platforms/reference/include/SimTKOpenMMUtilities.h index b1aa0d625..49fa1c664 100644 --- a/platforms/reference/include/SimTKOpenMMUtilities.h +++ b/platforms/reference/include/SimTKOpenMMUtilities.h @@ -56,8 +56,8 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { // dummy constructor/destructor - SimTKOpenMMUtilities(){}; - ~SimTKOpenMMUtilities(){}; + SimTKOpenMMUtilities() {}; + ~SimTKOpenMMUtilities() {}; /**--------------------------------------------------------------------------------------- @@ -75,9 +75,9 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static RealOpenMM* allocateOneDRealOpenMMArray( int iSize, RealOpenMM* array1D, int initialize, + static RealOpenMM* allocateOneDRealOpenMMArray(int iSize, RealOpenMM* array1D, int initialize, RealOpenMM initialValue, - const std::string& idString = std::string( "1DArray" ) ); + const std::string& idString = std::string("1DArray")); /**--------------------------------------------------------------------------------------- @@ -96,10 +96,10 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static RealOpenMM** allocateTwoDRealOpenMMArray( int iSize, int jSize, + static RealOpenMM** allocateTwoDRealOpenMMArray(int iSize, int jSize, RealOpenMM** array2D, int initialize, RealOpenMM initialValue, - const std::string& idString = std::string( "2DArray" ) ); + const std::string& idString = std::string("2DArray")); /* --------------------------------------------------------------------------------------- @@ -112,8 +112,8 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static void freeOneDRealOpenMMArray( RealOpenMM* array1D, - const std::string& idString = std::string( "1DArray" ) ); + static void freeOneDRealOpenMMArray(RealOpenMM* array1D, + const std::string& idString = std::string("1DArray")); /* --------------------------------------------------------------------------------------- @@ -126,8 +126,8 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static void freeTwoDRealOpenMMArray( RealOpenMM** array2D, - const std::string& idString = std::string( "2DArray" ) ); + static void freeTwoDRealOpenMMArray(RealOpenMM** array2D, + const std::string& idString = std::string("2DArray")); /**--------------------------------------------------------------------------------------- @@ -142,8 +142,8 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static void initialize2DRealOpenMMArray( int iSize, int jSize, - RealOpenMM** array2D, RealOpenMM initialValue ); + static void initialize2DRealOpenMMArray(int iSize, int jSize, + RealOpenMM** array2D, RealOpenMM initialValue); /**--------------------------------------------------------------------------------------- @@ -159,7 +159,7 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static void crossProductVector3( RealOpenMM* vectorX, RealOpenMM* vectorY, RealOpenMM* vectorZ ); + static void crossProductVector3(RealOpenMM* vectorX, RealOpenMM* vectorY, RealOpenMM* vectorZ); /**--------------------------------------------------------------------------------------- @@ -169,7 +169,7 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static RealOpenMM getNormallyDistributedRandomNumber( void ); + static RealOpenMM getNormallyDistributedRandomNumber(); /**--------------------------------------------------------------------------------------- @@ -179,7 +179,7 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static RealOpenMM getUniformlyDistributedRandomNumber( void ); + static RealOpenMM getUniformlyDistributedRandomNumber(); /**--------------------------------------------------------------------------------------- @@ -189,7 +189,7 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static uint32_t getRandomNumberSeed( void ); + static uint32_t getRandomNumberSeed(); /**--------------------------------------------------------------------------------------- @@ -199,7 +199,7 @@ class OPENMM_EXPORT SimTKOpenMMUtilities { --------------------------------------------------------------------------------------- */ - static void setRandomNumberSeed( uint32_t seed ); + static void setRandomNumberSeed(uint32_t seed); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/ReferenceKernelFactory.cpp b/platforms/reference/src/ReferenceKernelFactory.cpp index 64c9c7044..b7be168a9 100644 --- a/platforms/reference/src/ReferenceKernelFactory.cpp +++ b/platforms/reference/src/ReferenceKernelFactory.cpp @@ -100,5 +100,5 @@ KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Pla return new ReferenceApplyMonteCarloBarostatKernel(name, platform); if (name == RemoveCMMotionKernel::Name()) return new ReferenceRemoveCMMotionKernel(name, platform, data); - throw OpenMMException( (std::string("Tried to create kernel with illegal kernel name '") + name + "'").c_str() ); + throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '") + name + "'").c_str()); } diff --git a/platforms/reference/src/ReferenceKernels.cpp b/platforms/reference/src/ReferenceKernels.cpp index f455125f3..eb829f2d8 100644 --- a/platforms/reference/src/ReferenceKernels.cpp +++ b/platforms/reference/src/ReferenceKernels.cpp @@ -1105,8 +1105,8 @@ void ReferenceCalcGBSAOBCForceKernel::initialize(const System& system, const GBS ObcParameters* obcParameters = new ObcParameters(numParticles, ObcParameters::ObcTypeII); obcParameters->setAtomicRadii(atomicRadii); obcParameters->setScaledRadiusFactors(scaleFactors); - obcParameters->setSolventDielectric( static_cast(force.getSolventDielectric()) ); - obcParameters->setSoluteDielectric( static_cast(force.getSoluteDielectric()) ); + obcParameters->setSolventDielectric(static_cast(force.getSolventDielectric())); + obcParameters->setSoluteDielectric(static_cast(force.getSoluteDielectric())); obcParameters->setPi4Asolv(4*M_PI*force.getSurfaceAreaEnergy()); if (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff) obcParameters->setUseCutoff(static_cast(force.getCutoffDistance())); @@ -1152,7 +1152,7 @@ ReferenceCalcGBVIForceKernel::~ReferenceCalcGBVIForceKernel() { } } -void ReferenceCalcGBVIForceKernel::initialize(const System& system, const GBVIForce& force, const std::vector & inputScaledRadii ) { +void ReferenceCalcGBVIForceKernel::initialize(const System& system, const GBVIForce& force, const std::vector & inputScaledRadii) { int numParticles = system.getNumParticles(); @@ -1201,7 +1201,7 @@ double ReferenceCalcGBVIForceKernel::execute(ContextImpl& context, bool includeF gbvi->computeBornForces(posData, charges, forceData); energy = 0.0; } - if( includeEnergy ){ + if (includeEnergy) { energy = gbvi->computeBornEnergy(posData, charges); } return static_cast(energy); @@ -1710,7 +1710,7 @@ void ReferenceIntegrateVerletStepKernel::execute(ContextImpl& context, const Ver if (dynamics) delete dynamics; - dynamics = new ReferenceVerletDynamics(context.getSystem().getNumParticles(), static_cast(stepSize) ); + dynamics = new ReferenceVerletDynamics(context.getSystem().getNumParticles(), static_cast(stepSize)); dynamics->setReferenceConstraintAlgorithm(&extractConstraints(context)); prevStepSize = stepSize; } @@ -1748,12 +1748,12 @@ void ReferenceIntegrateLangevinStepKernel::execute(ContextImpl& context, const L if (dynamics) delete dynamics; - RealOpenMM tau = static_cast( friction == 0.0 ? 0.0 : 1.0/friction ); + RealOpenMM tau = static_cast(friction == 0.0 ? 0.0 : 1.0/friction); dynamics = new ReferenceStochasticDynamics( context.getSystem().getNumParticles(), static_cast(stepSize), static_cast(tau), - static_cast(temperature) ); + static_cast(temperature)); dynamics->setReferenceConstraintAlgorithm(&extractConstraints(context)); prevTemp = temperature; prevFriction = friction; @@ -1797,7 +1797,7 @@ void ReferenceIntegrateBrownianStepKernel::execute(ContextImpl& context, const B context.getSystem().getNumParticles(), static_cast(stepSize), static_cast(friction), - static_cast(temperature) ); + static_cast(temperature)); dynamics->setReferenceConstraintAlgorithm(&extractConstraints(context)); prevTemp = temperature; prevFriction = friction; @@ -1837,7 +1837,7 @@ double ReferenceIntegrateVariableLangevinStepKernel::execute(ContextImpl& contex if (dynamics) delete dynamics; - RealOpenMM tau = static_cast( friction == 0.0 ? 0.0 : 1.0/friction ); + RealOpenMM tau = static_cast(friction == 0.0 ? 0.0 : 1.0/friction); dynamics = new ReferenceVariableStochasticDynamics(context.getSystem().getNumParticles(), (RealOpenMM) tau, (RealOpenMM) temperature, (RealOpenMM) errorTol); dynamics->setReferenceConstraintAlgorithm(&extractConstraints(context)); prevTemp = temperature; diff --git a/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp b/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp index f3e5f7c4d..3ddb71076 100644 --- a/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceAndersenThermostat.cpp @@ -37,7 +37,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ - ReferenceAndersenThermostat::ReferenceAndersenThermostat( ) { + ReferenceAndersenThermostat::ReferenceAndersenThermostat() { } /**--------------------------------------------------------------------------------------- @@ -46,7 +46,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ - ReferenceAndersenThermostat::~ReferenceAndersenThermostat( ) { + ReferenceAndersenThermostat::~ReferenceAndersenThermostat() { } /**--------------------------------------------------------------------------------------- @@ -61,8 +61,8 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ - void ReferenceAndersenThermostat::applyThermostat( const vector >& atomGroups, vector& atomVelocities, vector& atomMasses, - RealOpenMM temperature, RealOpenMM collisionFrequency, RealOpenMM stepSize ) const { + void ReferenceAndersenThermostat::applyThermostat(const vector >& atomGroups, vector& atomVelocities, vector& atomMasses, + RealOpenMM temperature, RealOpenMM collisionFrequency, RealOpenMM stepSize) const { const RealOpenMM collisionProbability = 1.0f - EXP(-collisionFrequency*stepSize); for (int i = 0; i < (int) atomGroups.size(); ++i) { diff --git a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp index 067501c9b..82ebc2bdd 100644 --- a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp @@ -39,7 +39,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceAngleBondIxn::ReferenceAngleBondIxn( ){ +ReferenceAngleBondIxn::ReferenceAngleBondIxn() { // --------------------------------------------------------------------------------------- @@ -55,7 +55,7 @@ ReferenceAngleBondIxn::ReferenceAngleBondIxn( ){ --------------------------------------------------------------------------------------- */ -ReferenceAngleBondIxn::~ReferenceAngleBondIxn( ){ +ReferenceAngleBondIxn::~ReferenceAngleBondIxn() { // --------------------------------------------------------------------------------------- @@ -77,8 +77,8 @@ ReferenceAngleBondIxn::~ReferenceAngleBondIxn( ){ --------------------------------------------------------------------------------------- */ -void ReferenceAngleBondIxn::getPrefactorsGivenAngleCosine( RealOpenMM cosine, RealOpenMM* angleParameters, - RealOpenMM* dEdR, RealOpenMM* energyTerm ) const { +void ReferenceAngleBondIxn::getPrefactorsGivenAngleCosine(RealOpenMM cosine, RealOpenMM* angleParameters, + RealOpenMM* dEdR, RealOpenMM* energyTerm) const { // --------------------------------------------------------------------------------------- @@ -91,9 +91,9 @@ void ReferenceAngleBondIxn::getPrefactorsGivenAngleCosine( RealOpenMM cosine, Re // --------------------------------------------------------------------------------------- RealOpenMM angle; - if( cosine >= one ){ + if (cosine >= one) { angle = zero; - } else if( cosine <= -one ){ + } else if (cosine <= -one) { angle = PI_M; } else { angle = ACOS(cosine); @@ -119,11 +119,11 @@ void ReferenceAngleBondIxn::getPrefactorsGivenAngleCosine( RealOpenMM cosine, Re --------------------------------------------------------------------------------------- */ -void ReferenceAngleBondIxn::calculateBondIxn( int* atomIndices, +void ReferenceAngleBondIxn::calculateBondIxn(int* atomIndices, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* totalEnergy ) const { + RealOpenMM* totalEnergy) const { // constants -- reduce Visual Studio warnings regarding conversions between float & double @@ -146,31 +146,31 @@ void ReferenceAngleBondIxn::calculateBondIxn( int* atomIndices, int atomAIndex = atomIndices[0]; int atomBIndex = atomIndices[1]; int atomCIndex = atomIndices[2]; - ReferenceForce::getDeltaR( atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR[0] ); - ReferenceForce::getDeltaR( atomCoordinates[atomCIndex], atomCoordinates[atomBIndex], deltaR[1] ); + ReferenceForce::getDeltaR(atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR[0]); + ReferenceForce::getDeltaR(atomCoordinates[atomCIndex], atomCoordinates[atomBIndex], deltaR[1]); RealOpenMM pVector[threeI]; - SimTKOpenMMUtilities::crossProductVector3( deltaR[0], deltaR[1], pVector ); - RealOpenMM rp = DOT3( pVector, pVector ); - rp = SQRT( rp ); - if( rp < 1.0e-06 ){ + SimTKOpenMMUtilities::crossProductVector3(deltaR[0], deltaR[1], pVector); + RealOpenMM rp = DOT3(pVector, pVector); + rp = SQRT(rp); + if (rp < 1.0e-06) { rp = (RealOpenMM) 1.0e-06; } - RealOpenMM dot = DOT3( deltaR[0], deltaR[1] ); - RealOpenMM cosine = dot/SQRT( (deltaR[0][ReferenceForce::R2Index]*deltaR[1][ReferenceForce::R2Index]) ); + RealOpenMM dot = DOT3(deltaR[0], deltaR[1]); + RealOpenMM cosine = dot/SQRT((deltaR[0][ReferenceForce::R2Index]*deltaR[1][ReferenceForce::R2Index])); RealOpenMM dEdR; RealOpenMM energy; - getPrefactorsGivenAngleCosine( cosine, parameters, &dEdR, &energy ); + getPrefactorsGivenAngleCosine(cosine, parameters, &dEdR, &energy); RealOpenMM termA = dEdR/(deltaR[0][ReferenceForce::R2Index]*rp); RealOpenMM termC = -dEdR/(deltaR[1][ReferenceForce::R2Index]*rp); RealOpenMM deltaCrossP[LastAtomIndex][threeI]; - SimTKOpenMMUtilities::crossProductVector3( deltaR[0], pVector, deltaCrossP[0] ); - SimTKOpenMMUtilities::crossProductVector3( deltaR[1], pVector, deltaCrossP[2] ); + SimTKOpenMMUtilities::crossProductVector3(deltaR[0], pVector, deltaCrossP[0]); + SimTKOpenMMUtilities::crossProductVector3(deltaR[1], pVector, deltaCrossP[2]); - for( int ii = 0; ii < threeI; ii++ ){ + for (int ii = 0; ii < threeI; ii++) { deltaCrossP[0][ii] *= termA; deltaCrossP[2][ii] *= termC; deltaCrossP[1][ii] = oneM*(deltaCrossP[0][ii] + deltaCrossP[2][ii]); @@ -178,8 +178,8 @@ void ReferenceAngleBondIxn::calculateBondIxn( int* atomIndices, // accumulate forces - for( int jj = 0; jj < LastAtomIndex; jj++ ){ - for( int ii = 0; ii < threeI; ii++ ){ + for (int jj = 0; jj < LastAtomIndex; jj++) { + for (int ii = 0; ii < threeI; ii++) { forces[atomIndices[jj]][ii] += deltaCrossP[jj][ii]; } } diff --git a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp index a3f7f1018..2851706d2 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp @@ -38,7 +38,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceBondForce::ReferenceBondForce( ){ +ReferenceBondForce::ReferenceBondForce() { // --------------------------------------------------------------------------------------- @@ -54,7 +54,7 @@ ReferenceBondForce::ReferenceBondForce( ){ --------------------------------------------------------------------------------------- */ -ReferenceBondForce::~ReferenceBondForce( ){ +ReferenceBondForce::~ReferenceBondForce() { // --------------------------------------------------------------------------------------- @@ -79,12 +79,12 @@ ReferenceBondForce::~ReferenceBondForce( ){ --------------------------------------------------------------------------------------- */ -void ReferenceBondForce::calculateForce( int numberOfBonds, int** atomIndices, +void ReferenceBondForce::calculateForce(int numberOfBonds, int** atomIndices, vector& atomCoordinates, RealOpenMM** parameters, vector& forces, RealOpenMM *totalEnergy, - ReferenceBondIxn& referenceBondIxn ){ + ReferenceBondIxn& referenceBondIxn) { // --------------------------------------------------------------------------------------- @@ -93,12 +93,12 @@ void ReferenceBondForce::calculateForce( int numberOfBonds, int** atomIndices, // --------------------------------------------------------------------------------------- - for( int ii = 0; ii < numberOfBonds; ii++ ){ + for (int ii = 0; ii < numberOfBonds; ii++) { // calculate bond ixn - referenceBondIxn.calculateBondIxn( atomIndices[ii], atomCoordinates, parameters[ii], - forces, totalEnergy ); + referenceBondIxn.calculateBondIxn(atomIndices[ii], atomCoordinates, parameters[ii], + forces, totalEnergy); } } diff --git a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp index 8e53cd226..29e52964a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp @@ -39,7 +39,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceBondIxn::ReferenceBondIxn( ){ +ReferenceBondIxn::ReferenceBondIxn() { // --------------------------------------------------------------------------------------- @@ -55,7 +55,7 @@ ReferenceBondIxn::ReferenceBondIxn( ){ --------------------------------------------------------------------------------------- */ -ReferenceBondIxn::~ReferenceBondIxn( ){ +ReferenceBondIxn::~ReferenceBondIxn() { // --------------------------------------------------------------------------------------- @@ -77,9 +77,9 @@ ReferenceBondIxn::~ReferenceBondIxn( ){ --------------------------------------------------------------------------------------- */ - void ReferenceBondIxn::calculateBondIxn( int* atomIndices, vector& atomCoordinates, + void ReferenceBondIxn::calculateBondIxn(int* atomIndices, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* totalEnergy ) const { + RealOpenMM* totalEnergy) const { // --------------------------------------------------------------------------------------- // static const std::string methodName = "\nReferenceBondIxn::calculateBondIxn"; @@ -103,8 +103,8 @@ ReferenceBondIxn::~ReferenceBondIxn( ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceBondIxn::getNormedDotProduct( RealOpenMM* vector1, RealOpenMM* vector2, - int hasREntry = 0 ) { +RealOpenMM ReferenceBondIxn::getNormedDotProduct(RealOpenMM* vector1, RealOpenMM* vector2, + int hasREntry = 0) { // --------------------------------------------------------------------------------------- @@ -123,35 +123,35 @@ RealOpenMM ReferenceBondIxn::getNormedDotProduct( RealOpenMM* vector1, RealOpenM #if defined USE_DOUBLE_FOR_NORMED_DOT_PRODUCT double v1D[3]; double v2D[3]; - v1D[0] = static_cast( vector1[0] ); - v1D[1] = static_cast( vector1[1] ); - v1D[2] = static_cast( vector1[2] ); - - v2D[0] = static_cast( vector2[0] ); - v2D[1] = static_cast( vector2[1] ); - v2D[2] = static_cast( vector2[2] ); - double dotProductD = DOT3( v1D, v2D ); - if( dotProductD != 0.0 ){ - if( hasREntry ){ - dotProductD /= ( static_cast(vector1[ReferenceForce::RIndex])*static_cast(vector2[ReferenceForce::RIndex]) ); + v1D[0] = static_cast(vector1[0]); + v1D[1] = static_cast(vector1[1]); + v1D[2] = static_cast(vector1[2]); + + v2D[0] = static_cast(vector2[0]); + v2D[1] = static_cast(vector2[1]); + v2D[2] = static_cast(vector2[2]); + double dotProductD = DOT3(v1D, v2D); + if (dotProductD != 0.0) { + if (hasREntry) { + dotProductD /= (static_cast(vector1[ReferenceForce::RIndex])*static_cast(vector2[ReferenceForce::RIndex])); } else { - double norm1 = DOT3( v1D, v1D ); - double norm2 = DOT3( v2D, v2D); - dotProductD /= sqrt( norm1*norm2 ); + double norm1 = DOT3(v1D, v1D); + double norm2 = DOT3(v2D, v2D); + dotProductD /= sqrt(norm1*norm2); } } RealOpenMM dotProduct = static_cast(dotProductD); #else - RealOpenMM dotProduct = DOT3( vector1, vector2 ); - if( dotProduct != zero ){ - if( hasREntry ){ - dotProduct /= ( vector1[ReferenceForce::RIndex]*vector2[ReferenceForce::RIndex] ); + RealOpenMM dotProduct = DOT3(vector1, vector2); + if (dotProduct != zero) { + if (hasREntry) { + dotProduct /= (vector1[ReferenceForce::RIndex]*vector2[ReferenceForce::RIndex]); } else { - RealOpenMM norm1 = DOT3( vector1, vector1 ); - RealOpenMM norm2 = DOT3( vector2, vector2 ); - dotProduct /= SQRT( norm1*norm2 ); + RealOpenMM norm1 = DOT3(vector1, vector1); + RealOpenMM norm2 = DOT3(vector2, vector2); + dotProduct /= SQRT(norm1*norm2); } } @@ -160,9 +160,9 @@ RealOpenMM ReferenceBondIxn::getNormedDotProduct( RealOpenMM* vector1, RealOpenM // clamp dot product to [-1,1] - if( dotProduct > one ){ + if (dotProduct > one) { dotProduct = one; - } else if( dotProduct < -one ){ + } else if (dotProduct < -one) { dotProduct = -one; } @@ -184,9 +184,9 @@ RealOpenMM ReferenceBondIxn::getNormedDotProduct( RealOpenMM* vector1, RealOpenM --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors( RealOpenMM* vector1, RealOpenMM* vector2, - RealOpenMM* outputDotProduct = NULL, - int hasREntry = 0 ) { +RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors(RealOpenMM* vector1, RealOpenMM* vector2, + RealOpenMM* outputDotProduct = NULL, + int hasREntry = 0) { // --------------------------------------------------------------------------------------- @@ -199,7 +199,7 @@ RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors( RealOpenMM* vector1, Rea // get dot product betweenn vectors and then angle - RealOpenMM dotProduct = getNormedDotProduct( vector1, vector2, hasREntry ); + RealOpenMM dotProduct = getNormedDotProduct(vector1, vector2, hasREntry); RealOpenMM angle; if (dotProduct > (RealOpenMM) 0.99 || dotProduct < (RealOpenMM) -0.99) { @@ -215,7 +215,7 @@ RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors( RealOpenMM* vector1, Rea angle = ACOS(dotProduct); } - if( outputDotProduct ){ + if (outputDotProduct) { *outputDotProduct = dotProduct; } @@ -241,14 +241,14 @@ RealOpenMM ReferenceBondIxn::getAngleBetweenTwoVectors( RealOpenMM* vector1, Rea --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceBondIxn::getDihedralAngleBetweenThreeVectors( RealOpenMM* vector1, - RealOpenMM* vector2, - RealOpenMM* vector3, - RealOpenMM** outputCrossProduct = NULL, - RealOpenMM* cosineOfAngle = NULL, - RealOpenMM* signVector = NULL, - RealOpenMM* signOfAngle = NULL, - int hasREntry = 0 ) { +RealOpenMM ReferenceBondIxn::getDihedralAngleBetweenThreeVectors(RealOpenMM* vector1, + RealOpenMM* vector2, + RealOpenMM* vector3, + RealOpenMM** outputCrossProduct = NULL, + RealOpenMM* cosineOfAngle = NULL, + RealOpenMM* signVector = NULL, + RealOpenMM* signOfAngle = NULL, + int hasREntry = 0) { // --------------------------------------------------------------------------------------- @@ -264,7 +264,7 @@ RealOpenMM ReferenceBondIxn::getDihedralAngleBetweenThreeVectors( RealOpenMM* v // get cross products between vectors and then angle between cross product vectors RealOpenMM* crossProduct[2]; - if( outputCrossProduct ){ + if (outputCrossProduct) { crossProduct[0] = outputCrossProduct[0]; crossProduct[1] = outputCrossProduct[1]; } else { @@ -272,17 +272,17 @@ RealOpenMM ReferenceBondIxn::getDihedralAngleBetweenThreeVectors( RealOpenMM* v crossProduct[1] = tempVectors + 3; } - SimTKOpenMMUtilities::crossProductVector3( vector1, vector2, crossProduct[0] ); - SimTKOpenMMUtilities::crossProductVector3( vector2, vector3, crossProduct[1] ); + SimTKOpenMMUtilities::crossProductVector3(vector1, vector2, crossProduct[0]); + SimTKOpenMMUtilities::crossProductVector3(vector2, vector3, crossProduct[1]); - RealOpenMM angle = getAngleBetweenTwoVectors( crossProduct[0], crossProduct[1], cosineOfAngle, 0 ); + RealOpenMM angle = getAngleBetweenTwoVectors(crossProduct[0], crossProduct[1], cosineOfAngle, 0); // take care of sign of angle - if( signVector ){ - RealOpenMM dotProduct = DOT3( signVector, crossProduct[1] ); + if (signVector) { + RealOpenMM dotProduct = DOT3(signVector, crossProduct[1]); RealOpenMM sign = dotProduct < zero ? -one : one; - if( signOfAngle ){ + if (signOfAngle) { *signOfAngle = sign; } angle *= sign; diff --git a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp index 5f9d53054..eff76ce9e 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp @@ -47,10 +47,10 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceBrownianDynamics::ReferenceBrownianDynamics( int numberOfAtoms, +ReferenceBrownianDynamics::ReferenceBrownianDynamics(int numberOfAtoms, RealOpenMM deltaT, RealOpenMM friction, - RealOpenMM temperature ) : - ReferenceDynamics( numberOfAtoms, deltaT, temperature ), friction( friction ) { + RealOpenMM temperature) : + ReferenceDynamics(numberOfAtoms, deltaT, temperature), friction(friction) { if (friction <= 0) { std::stringstream message; @@ -67,7 +67,7 @@ ReferenceBrownianDynamics::ReferenceBrownianDynamics( int numberOfAtoms, --------------------------------------------------------------------------------------- */ -ReferenceBrownianDynamics::~ReferenceBrownianDynamics( ){ +ReferenceBrownianDynamics::~ReferenceBrownianDynamics() { // --------------------------------------------------------------------------------------- @@ -85,7 +85,7 @@ ReferenceBrownianDynamics::~ReferenceBrownianDynamics( ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceBrownianDynamics::getFriction( void ) const { +RealOpenMM ReferenceBrownianDynamics::getFriction() const { // --------------------------------------------------------------------------------------- @@ -125,10 +125,10 @@ void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector( sqrt(2.0*BOLTZ*getTemperature()*getDeltaT()/getFriction()) ); + const RealOpenMM noiseAmplitude = static_cast(sqrt(2.0*BOLTZ*getTemperature()*getDeltaT()/getFriction())); const RealOpenMM forceScale = getDeltaT()/getFriction(); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != zero) @@ -152,7 +152,7 @@ void ReferenceBrownianDynamics::update(const OpenMM::System& system, vector( 1.0/getDeltaT() ); + RealOpenMM velocityScale = static_cast(1.0/getDeltaT()); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != zero) for (int j = 0; j < 3; ++j) { diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp index 5ef2eabc3..6f6a590df 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp @@ -61,7 +61,7 @@ ReferenceCustomAngleIxn::ReferenceCustomAngleIxn(const Lepton::CompiledExpressio --------------------------------------------------------------------------------------- */ -ReferenceCustomAngleIxn::~ReferenceCustomAngleIxn( ){ +ReferenceCustomAngleIxn::~ReferenceCustomAngleIxn() { // --------------------------------------------------------------------------------------- @@ -83,11 +83,11 @@ ReferenceCustomAngleIxn::~ReferenceCustomAngleIxn( ){ --------------------------------------------------------------------------------------- */ -void ReferenceCustomAngleIxn::calculateBondIxn( int* atomIndices, - vector& atomCoordinates, - RealOpenMM* parameters, - vector& forces, - RealOpenMM* totalEnergy ) const { +void ReferenceCustomAngleIxn::calculateBondIxn(int* atomIndices, + vector& atomCoordinates, + RealOpenMM* parameters, + vector& forces, + RealOpenMM* totalEnergy) const { static const std::string methodName = "\nReferenceCustomAngleIxn::calculateAngleIxn"; diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp index 91ef124ee..fecfe0975 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp @@ -61,7 +61,7 @@ ReferenceCustomBondIxn::ReferenceCustomBondIxn(const Lepton::CompiledExpression& --------------------------------------------------------------------------------------- */ -ReferenceCustomBondIxn::~ReferenceCustomBondIxn( ){ +ReferenceCustomBondIxn::~ReferenceCustomBondIxn() { // --------------------------------------------------------------------------------------- @@ -83,11 +83,11 @@ ReferenceCustomBondIxn::~ReferenceCustomBondIxn( ){ --------------------------------------------------------------------------------------- */ -void ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices, - vector& atomCoordinates, - RealOpenMM* parameters, - vector& forces, - RealOpenMM* totalEnergy ) const { +void ReferenceCustomBondIxn::calculateBondIxn(int* atomIndices, + vector& atomCoordinates, + RealOpenMM* parameters, + vector& forces, + RealOpenMM* totalEnergy) const { static const std::string methodName = "\nReferenceCustomBondIxn::calculateBondIxn"; @@ -109,7 +109,7 @@ void ReferenceCustomBondIxn::calculateBondIxn( int* atomIndices, int atomAIndex = atomIndices[0]; int atomBIndex = atomIndices[1]; - ReferenceForce::getDeltaR( atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR); ReferenceForce::setVariable(energyR, deltaR[ReferenceForce::RIndex]); ReferenceForce::setVariable(forceR, deltaR[ReferenceForce::RIndex]); diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp index 4ef74636f..5a4374986 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp @@ -71,7 +71,7 @@ ReferenceCustomCompoundBondIxn::ReferenceCustomCompoundBondIxn(int numParticlesP --------------------------------------------------------------------------------------- */ -ReferenceCustomCompoundBondIxn::~ReferenceCustomCompoundBondIxn( ){ +ReferenceCustomCompoundBondIxn::~ReferenceCustomCompoundBondIxn() { } /**--------------------------------------------------------------------------------------- @@ -92,7 +92,7 @@ void ReferenceCustomCompoundBondIxn::calculatePairIxn(vector& atomCoord map variables = globalParameters; int numBonds = bondAtoms.size(); - for (int bond = 0; bond < numBonds; bond++){ + for (int bond = 0; bond < numBonds; bond++) { for (int j = 0; j < (int) bondParamNames.size(); j++) variables[bondParamNames[j]] = bondParameters[bond][j]; calculateOneIxn(bond, atomCoordinates, variables, forces, totalEnergy); diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp index fcacbd013..e8b5fa6a5 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp @@ -96,7 +96,7 @@ ReferenceCustomDynamics::~ReferenceCustomDynamics() { void ReferenceCustomDynamics::update(ContextImpl& context, int numberOfAtoms, vector& atomCoordinates, vector& velocities, vector& forces, vector& masses, - map& globals, vector >& perDof, bool& forcesAreValid, RealOpenMM tolerance){ + map& globals, vector >& perDof, bool& forcesAreValid, RealOpenMM tolerance) { int numSteps = stepType.size(); globals.insert(context.getParameters().begin(), context.getParameters().end()); oldPos = atomCoordinates; diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp index 7f950b8e8..91a5297c5 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp @@ -78,7 +78,7 @@ ReferenceCustomExternalIxn::ReferenceCustomExternalIxn(const Lepton::CompiledExp --------------------------------------------------------------------------------------- */ -ReferenceCustomExternalIxn::~ReferenceCustomExternalIxn( ){ +ReferenceCustomExternalIxn::~ReferenceCustomExternalIxn() { // --------------------------------------------------------------------------------------- @@ -100,11 +100,11 @@ ReferenceCustomExternalIxn::~ReferenceCustomExternalIxn( ){ --------------------------------------------------------------------------------------- */ -void ReferenceCustomExternalIxn::calculateForce( int atomIndex, +void ReferenceCustomExternalIxn::calculateForce(int atomIndex, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* energy ) const { + RealOpenMM* energy) const { static const std::string methodName = "\nReferenceCustomExternalIxn::calculateBondIxn"; diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp index 624052c1b..76ae6c4eb 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp @@ -85,7 +85,7 @@ ReferenceCustomGBIxn::ReferenceCustomGBIxn(const vector >& don --------------------------------------------------------------------------------------- */ -ReferenceCustomHbondIxn::~ReferenceCustomHbondIxn( ){ +ReferenceCustomHbondIxn::~ReferenceCustomHbondIxn() { } /**--------------------------------------------------------------------------------------- @@ -128,7 +128,7 @@ void ReferenceCustomHbondIxn::calculatePairIxn(vector& atomCoordinates, int numDonors = donorAtoms.size(); int numAcceptors = acceptorAtoms.size(); - for( int donor = 0; donor < numDonors; donor++ ){ + for (int donor = 0; donor < numDonors; donor++) { // Initialize per-donor parameters. for (int j = 0; j < (int) donorParamNames.size(); j++) @@ -136,7 +136,7 @@ void ReferenceCustomHbondIxn::calculatePairIxn(vector& atomCoordinates, // loop over atom pairs - for( int acceptor = 0; acceptor < numAcceptors; acceptor++ ){ + for (int acceptor = 0; acceptor < numAcceptors; acceptor++) { if (exclusions[donor].find(acceptor) == exclusions[donor].end()) { for (int j = 0; j < (int) acceptorParamNames.size(); j++) variables[acceptorParamNames[j]] = acceptorParameters[acceptor][j]; diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp index 715a790ec..9a3169245 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp @@ -103,7 +103,7 @@ ReferenceCustomManyParticleIxn::ReferenceCustomManyParticleIxn(const CustomManyP CustomManyParticleForceImpl::buildFilterArrays(force, numTypes, particleTypes, orderIndex, particleOrder); } -ReferenceCustomManyParticleIxn::~ReferenceCustomManyParticleIxn( ){ +ReferenceCustomManyParticleIxn::~ReferenceCustomManyParticleIxn() { } void ReferenceCustomManyParticleIxn::calculateIxn(vector& atomCoordinates, RealOpenMM** particleParameters, diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp index 82056be0c..cabfbbc7c 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp @@ -72,7 +72,7 @@ ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::CompiledE --------------------------------------------------------------------------------------- */ -ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn( ){ +ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn() { // --------------------------------------------------------------------------------------- @@ -91,7 +91,7 @@ ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn( ){ --------------------------------------------------------------------------------------- */ - void ReferenceCustomNonbondedIxn::setUseCutoff( RealOpenMM distance, const OpenMM::NeighborList& neighbors ) { + void ReferenceCustomNonbondedIxn::setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors) { cutoff = true; cutoffDistance = distance; @@ -119,7 +119,7 @@ void ReferenceCustomNonbondedIxn::setInteractionGroups(const vector& atomCoordinates, +void ReferenceCustomNonbondedIxn::calculatePairIxn(int numberOfAtoms, vector& atomCoordinates, RealOpenMM** atomParameters, vector >& exclusions, RealOpenMM* fixedParameters, const map& globalParameters, vector& forces, - RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) { + RealOpenMM* energyByAtom, RealOpenMM* totalEnergy) { for (map::const_iterator iter = globalParameters.begin(); iter != globalParameters.end(); ++iter) { ReferenceForce::setVariable(ReferenceForce::getVariablePointer(energyExpression, iter->first), iter->second); @@ -244,8 +244,8 @@ void ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, vector& atomCoordinates, vector& forces, - RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) { +void ReferenceCustomNonbondedIxn::calculateOneIxn(int ii, int jj, vector& atomCoordinates, vector& forces, + RealOpenMM* energyByAtom, RealOpenMM* totalEnergy) { // --------------------------------------------------------------------------------------- @@ -267,9 +267,9 @@ void ReferenceCustomNonbondedIxn::calculateOneIxn( int ii, int jj, vector= cutoffDistance) return; @@ -289,7 +289,7 @@ void ReferenceCustomNonbondedIxn::calculateOneIxn( int ii, int jj, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* totalEnergy ) const { + RealOpenMM* totalEnergy) const { static const std::string methodName = "\nReferenceCustomTorsionIxn::calculateTorsionIxn"; @@ -135,20 +135,20 @@ void ReferenceCustomTorsionIxn::calculateBondIxn( int* atomIndices, RealOpenMM internalF[4][3]; RealOpenMM forceFactors[4]; - RealOpenMM normCross1 = DOT3( crossProduct[0], crossProduct[0] ); + RealOpenMM normCross1 = DOT3(crossProduct[0], crossProduct[0]); RealOpenMM normBC = deltaR[1][ReferenceForce::RIndex]; forceFactors[0] = (-dEdAngle*normBC)/normCross1; - RealOpenMM normCross2 = DOT3( crossProduct[1], crossProduct[1] ); + RealOpenMM normCross2 = DOT3(crossProduct[1], crossProduct[1]); forceFactors[3] = (dEdAngle*normBC)/normCross2; - forceFactors[1] = DOT3( deltaR[0], deltaR[1] ); + forceFactors[1] = DOT3(deltaR[0], deltaR[1]); forceFactors[1] /= deltaR[1][ReferenceForce::R2Index]; - forceFactors[2] = DOT3( deltaR[2], deltaR[1] ); + forceFactors[2] = DOT3(deltaR[2], deltaR[1]); forceFactors[2] /= deltaR[1][ReferenceForce::R2Index]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { internalF[0][ii] = forceFactors[0]*crossProduct[0][ii]; internalF[3][ii] = forceFactors[3]*crossProduct[1][ii]; @@ -161,7 +161,7 @@ void ReferenceCustomTorsionIxn::calculateBondIxn( int* atomIndices, // accumulate forces - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forces[atomAIndex][ii] += internalF[0][ii]; forces[atomBIndex][ii] -= internalF[1][ii]; forces[atomCIndex][ii] -= internalF[2][ii]; diff --git a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp index 898c919bd..153db9998 100644 --- a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp @@ -45,7 +45,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceDynamics::ReferenceDynamics( int numberOfAtoms, RealOpenMM deltaT, RealOpenMM temperature ) : +ReferenceDynamics::ReferenceDynamics(int numberOfAtoms, RealOpenMM deltaT, RealOpenMM temperature) : _numberOfAtoms(numberOfAtoms), _deltaT(deltaT), _temperature(temperature) { // --------------------------------------------------------------------------------------- @@ -68,7 +68,7 @@ ReferenceDynamics::ReferenceDynamics( int numberOfAtoms, RealOpenMM deltaT, Rea --------------------------------------------------------------------------------------- */ -ReferenceDynamics::~ReferenceDynamics( ){ +ReferenceDynamics::~ReferenceDynamics() { // --------------------------------------------------------------------------------------- @@ -76,7 +76,7 @@ ReferenceDynamics::~ReferenceDynamics( ){ // --------------------------------------------------------------------------------------- - if( _ownReferenceConstraint ){ + if (_ownReferenceConstraint) { delete _referenceConstraint; } } @@ -89,7 +89,7 @@ ReferenceDynamics::~ReferenceDynamics( ){ --------------------------------------------------------------------------------------- */ -int ReferenceDynamics::getNumberOfAtoms( void ) const { +int ReferenceDynamics::getNumberOfAtoms() const { // --------------------------------------------------------------------------------------- @@ -108,7 +108,7 @@ int ReferenceDynamics::getNumberOfAtoms( void ) const { --------------------------------------------------------------------------------------- */ -int ReferenceDynamics::getTimeStep( void ) const { +int ReferenceDynamics::getTimeStep() const { // --------------------------------------------------------------------------------------- @@ -127,7 +127,7 @@ int ReferenceDynamics::getTimeStep( void ) const { --------------------------------------------------------------------------------------- */ -int ReferenceDynamics::incrementTimeStep( void ){ +int ReferenceDynamics::incrementTimeStep() { // --------------------------------------------------------------------------------------- @@ -146,7 +146,7 @@ int ReferenceDynamics::incrementTimeStep( void ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceDynamics::getDeltaT( void ) const { +RealOpenMM ReferenceDynamics::getDeltaT() const { // --------------------------------------------------------------------------------------- @@ -163,7 +163,7 @@ RealOpenMM ReferenceDynamics::getDeltaT( void ) const { --------------------------------------------------------------------------------------- */ -void ReferenceDynamics::setDeltaT( RealOpenMM deltaT ) { +void ReferenceDynamics::setDeltaT(RealOpenMM deltaT) { // --------------------------------------------------------------------------------------- @@ -182,7 +182,7 @@ void ReferenceDynamics::setDeltaT( RealOpenMM deltaT ) { --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceDynamics::getTemperature( void ) const { +RealOpenMM ReferenceDynamics::getTemperature() const { // --------------------------------------------------------------------------------------- @@ -201,7 +201,7 @@ RealOpenMM ReferenceDynamics::getTemperature( void ) const { --------------------------------------------------------------------------------------- */ -ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm( void ) const { +ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm() const { // --------------------------------------------------------------------------------------- @@ -220,7 +220,7 @@ ReferenceConstraintAlgorithm* ReferenceDynamics::getReferenceConstraintAlgorithm --------------------------------------------------------------------------------------- */ -void ReferenceDynamics::setReferenceConstraintAlgorithm( ReferenceConstraintAlgorithm* referenceConstraint ){ +void ReferenceDynamics::setReferenceConstraintAlgorithm(ReferenceConstraintAlgorithm* referenceConstraint) { // --------------------------------------------------------------------------------------- @@ -230,7 +230,7 @@ void ReferenceDynamics::setReferenceConstraintAlgorithm( ReferenceConstraintAlgo // delete if own - if( _referenceConstraint && _ownReferenceConstraint ){ + if (_referenceConstraint && _ownReferenceConstraint) { delete _referenceConstraint; } diff --git a/platforms/reference/src/SimTKReference/ReferenceForce.cpp b/platforms/reference/src/SimTKReference/ReferenceForce.cpp index 78f12d59a..348ecced9 100644 --- a/platforms/reference/src/SimTKReference/ReferenceForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceForce.cpp @@ -39,7 +39,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceForce::ReferenceForce( ){ +ReferenceForce::ReferenceForce() { } /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ ReferenceForce::ReferenceForce( ){ --------------------------------------------------------------------------------------- */ -ReferenceForce::~ReferenceForce( ){ +ReferenceForce::~ReferenceForce() { } /**--------------------------------------------------------------------------------------- @@ -64,28 +64,28 @@ RealOpenMM ReferenceForce::periodicDifference(RealOpenMM val1, RealOpenMM val2, } -void ReferenceForce::getDeltaR( const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, - RealOpenMM* deltaR ){ +void ReferenceForce::getDeltaR(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, + RealOpenMM* deltaR) { deltaR[XIndex] = atomCoordinatesJ[0] - atomCoordinatesI[0]; deltaR[YIndex] = atomCoordinatesJ[1] - atomCoordinatesI[1]; deltaR[ZIndex] = atomCoordinatesJ[2] - atomCoordinatesI[2]; - deltaR[R2Index] = DOT3( deltaR, deltaR ); - deltaR[RIndex] = (RealOpenMM) SQRT( deltaR[R2Index] ); + deltaR[R2Index] = DOT3(deltaR, deltaR); + deltaR[RIndex] = (RealOpenMM) SQRT(deltaR[R2Index]); } -void ReferenceForce::getDeltaRPeriodic( const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, - const RealOpenMM* boxSize, RealOpenMM* deltaR ){ +void ReferenceForce::getDeltaRPeriodic(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, + const RealOpenMM* boxSize, RealOpenMM* deltaR) { deltaR[XIndex] = periodicDifference(atomCoordinatesJ[0], atomCoordinatesI[0], boxSize[0]); deltaR[YIndex] = periodicDifference(atomCoordinatesJ[1], atomCoordinatesI[1], boxSize[1]); deltaR[ZIndex] = periodicDifference(atomCoordinatesJ[2], atomCoordinatesI[2], boxSize[2]); - deltaR[R2Index] = DOT3( deltaR, deltaR ); - deltaR[RIndex] = (RealOpenMM) SQRT( deltaR[R2Index] ); + deltaR[R2Index] = DOT3(deltaR, deltaR); + deltaR[RIndex] = (RealOpenMM) SQRT(deltaR[R2Index]); } -void ReferenceForce::getDeltaRPeriodic( const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, - const RealVec* boxVectors, RealOpenMM* deltaR ){ +void ReferenceForce::getDeltaRPeriodic(const RealVec& atomCoordinatesI, const RealVec& atomCoordinatesJ, + const RealVec* boxVectors, RealOpenMM* deltaR) { RealVec diff = atomCoordinatesJ-atomCoordinatesI; diff -= boxVectors[2]*floor(diff[2]/boxVectors[2][2]+0.5); diff -= boxVectors[1]*floor(diff[1]/boxVectors[1][1]+0.5); diff --git a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp index ec13dd963..3e6fd382f 100644 --- a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp @@ -39,7 +39,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceHarmonicBondIxn::ReferenceHarmonicBondIxn( ){ +ReferenceHarmonicBondIxn::ReferenceHarmonicBondIxn() { // --------------------------------------------------------------------------------------- @@ -55,7 +55,7 @@ ReferenceHarmonicBondIxn::ReferenceHarmonicBondIxn( ){ --------------------------------------------------------------------------------------- */ -ReferenceHarmonicBondIxn::~ReferenceHarmonicBondIxn( ){ +ReferenceHarmonicBondIxn::~ReferenceHarmonicBondIxn() { // --------------------------------------------------------------------------------------- @@ -78,11 +78,11 @@ ReferenceHarmonicBondIxn::~ReferenceHarmonicBondIxn( ){ --------------------------------------------------------------------------------------- */ -void ReferenceHarmonicBondIxn::calculateBondIxn( int* atomIndices, +void ReferenceHarmonicBondIxn::calculateBondIxn(int* atomIndices, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* totalEnergy ) const { + RealOpenMM* totalEnergy) const { static const std::string methodName = "\nReferenceHarmonicBondIxn::calculateBondIxn"; @@ -100,7 +100,7 @@ void ReferenceHarmonicBondIxn::calculateBondIxn( int* atomIndices, int atomAIndex = atomIndices[0]; int atomBIndex = atomIndices[1]; - ReferenceForce::getDeltaR( atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomAIndex], atomCoordinates[atomBIndex], deltaR); // deltaIdeal = r - r_0 diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp index 159dd7e6b..c55ba04c6 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp @@ -39,7 +39,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceLJCoulomb14::ReferenceLJCoulomb14( ) { +ReferenceLJCoulomb14::ReferenceLJCoulomb14() { // --------------------------------------------------------------------------------------- @@ -55,7 +55,7 @@ ReferenceLJCoulomb14::ReferenceLJCoulomb14( ) { --------------------------------------------------------------------------------------- */ -ReferenceLJCoulomb14::~ReferenceLJCoulomb14( ){ +ReferenceLJCoulomb14::~ReferenceLJCoulomb14() { // --------------------------------------------------------------------------------------- @@ -80,9 +80,9 @@ ReferenceLJCoulomb14::~ReferenceLJCoulomb14( ){ --------------------------------------------------------------------------------------- */ -void ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, vector& atomCoordinates, +void ReferenceLJCoulomb14::calculateBondIxn(int* atomIndices, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* totalEnergy ) const { + RealOpenMM* totalEnergy) const { static const std::string methodName = "\nReferenceLJCoulomb14::calculateBondIxn"; @@ -112,7 +112,7 @@ void ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, vector& int atomAIndex = atomIndices[0]; int atomBIndex = atomIndices[1]; - ReferenceForce::getDeltaR( atomCoordinates[atomBIndex], atomCoordinates[atomAIndex], deltaR[0] ); + ReferenceForce::getDeltaR(atomCoordinates[atomBIndex], atomCoordinates[atomAIndex], deltaR[0]); RealOpenMM r2 = deltaR[0][ReferenceForce::R2Index]; RealOpenMM inverseR = one/(deltaR[0][ReferenceForce::RIndex]); @@ -120,13 +120,13 @@ void ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, vector& sig2 *= sig2; RealOpenMM sig6 = sig2*sig2*sig2; - RealOpenMM dEdR = parameters[1]*( twelve*sig6 - six )*sig6; + RealOpenMM dEdR = parameters[1]*(twelve*sig6 - six)*sig6; dEdR += (RealOpenMM) (ONE_4PI_EPS0*parameters[2]*inverseR); dEdR *= inverseR*inverseR; // accumulate forces - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { RealOpenMM force = dEdR*deltaR[0][ii]; forces[atomAIndex][ii] += force; forces[atomBIndex][ii] -= force; @@ -135,5 +135,5 @@ void ReferenceLJCoulomb14::calculateBondIxn( int* atomIndices, vector& // accumulate energies if (totalEnergy != NULL) - *totalEnergy += parameters[1]*( sig6 - one )*sig6 + (ONE_4PI_EPS0*parameters[2]*inverseR); + *totalEnergy += parameters[1]*(sig6 - one)*sig6 + (ONE_4PI_EPS0*parameters[2]*inverseR); } diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp index 50ccf1759..72345f354 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp @@ -48,7 +48,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceLJCoulombIxn::ReferenceLJCoulombIxn( ) : cutoff(false), useSwitch(false), periodic(false), ewald(false), pme(false) { +ReferenceLJCoulombIxn::ReferenceLJCoulombIxn() : cutoff(false), useSwitch(false), periodic(false), ewald(false), pme(false) { // --------------------------------------------------------------------------------------- @@ -64,7 +64,7 @@ ReferenceLJCoulombIxn::ReferenceLJCoulombIxn( ) : cutoff(false), useSwitch(false --------------------------------------------------------------------------------------- */ -ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){ +ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn() { // --------------------------------------------------------------------------------------- @@ -84,7 +84,7 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){ --------------------------------------------------------------------------------------- */ - void ReferenceLJCoulombIxn::setUseCutoff( RealOpenMM distance, const OpenMM::NeighborList& neighbors, RealOpenMM solventDielectric ) { + void ReferenceLJCoulombIxn::setUseCutoff(RealOpenMM distance, const OpenMM::NeighborList& neighbors, RealOpenMM solventDielectric) { cutoff = true; cutoffDistance = distance; @@ -101,7 +101,7 @@ ReferenceLJCoulombIxn::~ReferenceLJCoulombIxn( ){ --------------------------------------------------------------------------------------- */ -void ReferenceLJCoulombIxn::setUseSwitchingFunction( RealOpenMM distance ) { +void ReferenceLJCoulombIxn::setUseSwitchingFunction(RealOpenMM distance) { useSwitch = true; switchingDistance = distance; } @@ -210,16 +210,16 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector // ************************************************************************************** if (includeReciprocal) { - for( int atomID = 0; atomID < numberOfAtoms; atomID++ ){ + for (int atomID = 0; atomID < numberOfAtoms; atomID++) { RealOpenMM selfEwaldEnergy = (RealOpenMM) (ONE_4PI_EPS0*atomParameters[atomID][QIndex]*atomParameters[atomID][QIndex] * alphaEwald/SQRT_PI); totalSelfEwaldEnergy -= selfEwaldEnergy; - if( energyByAtom ){ + if (energyByAtom) { energyByAtom[atomID] -= selfEwaldEnergy; } } } - if( totalEnergy ){ + if (totalEnergy) { *totalEnergy += totalSelfEwaldEnergy; } @@ -238,11 +238,11 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector charges[i] = atomParameters[i][QIndex]; pme_exec(pmedata,atomCoordinates,forces,charges,periodicBoxVectors,&recipEnergy); - if( totalEnergy ) + if (totalEnergy) *totalEnergy += recipEnergy; - if( energyByAtom ) - for(int n = 0; n < numberOfAtoms; n++) + if (energyByAtom) + for (int n = 0; n < numberOfAtoms; n++) energyByAtom[n] += recipEnergy; pme_destroy(pmedata); @@ -267,16 +267,16 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector if (kmax < 1) throw OpenMMException("kmax for Ewald summation < 1"); - for(int i = 0; (i < numberOfAtoms); i++) { - for(int m = 0; (m < 3); m++) + for (int i = 0; (i < numberOfAtoms); i++) { + for (int m = 0; (m < 3); m++) EIR(0, i, m) = d_complex(1,0); - for(int m=0; (m<3); m++) + for (int m=0; (m<3); m++) EIR(1, i, m) = d_complex(cos(atomCoordinates[i][m]*recipBoxSize[m]), sin(atomCoordinates[i][m]*recipBoxSize[m])); - for(int j=2; (j int lowry = 0; int lowrz = 1; - for(int rx = 0; rx < numRx; rx++) { + for (int rx = 0; rx < numRx; rx++) { RealOpenMM kx = rx * recipBoxSize[0]; - for(int ry = lowry; ry < numRy; ry++) { + for (int ry = lowry; ry < numRy; ry++) { RealOpenMM ky = ry * recipBoxSize[1]; - if(ry >= 0) { - for(int n = 0; n < numberOfAtoms; n++) + if (ry >= 0) { + for (int n = 0; n < numberOfAtoms; n++) tab_xy[n] = EIR(rx, n, 0) * EIR(ry, n, 1); } else { - for(int n = 0; n < numberOfAtoms; n++) + for (int n = 0; n < numberOfAtoms; n++) tab_xy[n]= EIR(rx, n, 0) * conj (EIR(-ry, n, 1)); } for (int rz = lowrz; rz < numRz; rz++) { - if( rz >= 0) { - for( int n = 0; n < numberOfAtoms; n++) + if (rz >= 0) { + for (int n = 0; n < numberOfAtoms; n++) tab_qxyz[n] = atomParameters[n][QIndex] * (tab_xy[n] * EIR(rz, n, 2)); } else { - for( int n = 0; n < numberOfAtoms; n++) + for (int n = 0; n < numberOfAtoms; n++) tab_qxyz[n] = atomParameters[n][QIndex] * (tab_xy[n] * conj(EIR(-rz, n, 2))); } RealOpenMM cs = 0.0f; RealOpenMM ss = 0.0f; - for( int n = 0; n < numberOfAtoms; n++) { + for (int n = 0; n < numberOfAtoms; n++) { cs += tab_qxyz[n].real(); ss += tab_qxyz[n].imag(); } @@ -327,21 +327,21 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector RealOpenMM k2 = kx * kx + ky * ky + kz * kz; RealOpenMM ak = exp(k2*factorEwald) / k2; - for(int n = 0; n < numberOfAtoms; n++) { + for (int n = 0; n < numberOfAtoms; n++) { RealOpenMM force = ak * (cs * tab_qxyz[n].imag() - ss * tab_qxyz[n].real()); forces[n][0] += 2 * recipCoeff * force * kx ; forces[n][1] += 2 * recipCoeff * force * ky ; forces[n][2] += 2 * recipCoeff * force * kz ; } - recipEnergy = recipCoeff * ak * ( cs * cs + ss * ss); + recipEnergy = recipCoeff * ak * (cs * cs + ss * ss); totalRecipEnergy += recipEnergy; - if( totalEnergy ) + if (totalEnergy) *totalEnergy += recipEnergy; - if( energyByAtom ) - for(int n = 0; n < numberOfAtoms; n++) + if (energyByAtom) + for (int n = 0; n < numberOfAtoms; n++) energyByAtom[n] += recipEnergy; lowrz = 1 - numRz; @@ -366,7 +366,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector int jj = pair.second; RealOpenMM deltaR[2][ReferenceForce::LastDeltaRIndex]; - ReferenceForce::getDeltaRPeriodic( atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR[0] ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR[0]); RealOpenMM r = deltaR[0][ReferenceForce::RIndex]; RealOpenMM inverseR = one/(deltaR[0][ReferenceForce::RIndex]); RealOpenMM switchValue = 1, switchDeriv = 0; @@ -379,14 +379,14 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector RealOpenMM dEdR = (RealOpenMM) (ONE_4PI_EPS0 * atomParameters[ii][QIndex] * atomParameters[jj][QIndex] * inverseR * inverseR * inverseR); - dEdR = (RealOpenMM) (dEdR * (erfc(alphaR) + 2 * alphaR * exp ( - alphaR * alphaR) / SQRT_PI )); + dEdR = (RealOpenMM) (dEdR * (erfc(alphaR) + 2 * alphaR * exp (- alphaR * alphaR) / SQRT_PI)); RealOpenMM sig = atomParameters[ii][SigIndex] + atomParameters[jj][SigIndex]; RealOpenMM sig2 = inverseR*sig; sig2 *= sig2; RealOpenMM sig6 = sig2*sig2*sig2; RealOpenMM eps = atomParameters[ii][EpsIndex]*atomParameters[jj][EpsIndex]; - dEdR += switchValue*eps*( twelve*sig6 - six )*sig6*inverseR*inverseR; + dEdR += switchValue*eps*(twelve*sig6 - six)*sig6*inverseR*inverseR; vdwEnergy = eps*(sig6-one)*sig6; if (useSwitch) { dEdR -= vdwEnergy*switchDeriv*inverseR; @@ -395,7 +395,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector // accumulate forces - for( int kk = 0; kk < 3; kk++ ){ + for (int kk = 0; kk < 3; kk++) { RealOpenMM force = dEdR*deltaR[0][kk]; forces[ii][kk] += force; forces[jj][kk] -= force; @@ -408,14 +408,14 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector totalVdwEnergy += vdwEnergy; totalRealSpaceEwaldEnergy += realSpaceEwaldEnergy; - if( energyByAtom ){ + if (energyByAtom) { energyByAtom[ii] += realSpaceEwaldEnergy + vdwEnergy; energyByAtom[jj] += realSpaceEwaldEnergy + vdwEnergy; } } - if( totalEnergy ) + if (totalEnergy) *totalEnergy += totalRealSpaceEwaldEnergy + totalVdwEnergy; // Now subtract off the exclusions, since they were implicitly included in the reciprocal space sum. @@ -428,17 +428,17 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector int jj = *iter; RealOpenMM deltaR[2][ReferenceForce::LastDeltaRIndex]; - ReferenceForce::getDeltaR( atomCoordinates[jj], atomCoordinates[ii], deltaR[0] ); + ReferenceForce::getDeltaR(atomCoordinates[jj], atomCoordinates[ii], deltaR[0]); RealOpenMM r = deltaR[0][ReferenceForce::RIndex]; RealOpenMM inverseR = one/(deltaR[0][ReferenceForce::RIndex]); RealOpenMM alphaR = alphaEwald * r; if (erf(alphaR) > 1e-6) { RealOpenMM dEdR = (RealOpenMM) (ONE_4PI_EPS0 * atomParameters[ii][QIndex] * atomParameters[jj][QIndex] * inverseR * inverseR * inverseR); - dEdR = (RealOpenMM) (dEdR * (erf(alphaR) - 2 * alphaR * exp ( - alphaR * alphaR) / SQRT_PI )); + dEdR = (RealOpenMM) (dEdR * (erf(alphaR) - 2 * alphaR * exp (- alphaR * alphaR) / SQRT_PI)); // accumulate forces - for( int kk = 0; kk < 3; kk++ ){ + for (int kk = 0; kk < 3; kk++) { RealOpenMM force = dEdR*deltaR[0][kk]; forces[ii][kk] -= force; forces[jj][kk] += force; @@ -449,7 +449,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector realSpaceEwaldEnergy = (RealOpenMM) (ONE_4PI_EPS0*atomParameters[ii][QIndex]*atomParameters[jj][QIndex]*inverseR*erf(alphaR)); totalExclusionEnergy += realSpaceEwaldEnergy; - if( energyByAtom ){ + if (energyByAtom) { energyByAtom[ii] -= realSpaceEwaldEnergy; energyByAtom[jj] -= realSpaceEwaldEnergy; } @@ -457,7 +457,7 @@ void ReferenceLJCoulombIxn::calculateEwaldIxn(int numberOfAtoms, vector } } - if( totalEnergy ) + if (totalEnergy) *totalEnergy -= totalExclusionEnergy; } @@ -499,10 +499,10 @@ void ReferenceLJCoulombIxn::calculatePairIxn(int numberOfAtoms, vector& } } else { - for( int ii = 0; ii < numberOfAtoms; ii++ ){ + for (int ii = 0; ii < numberOfAtoms; ii++) { // loop over atom pairs - for( int jj = ii+1; jj < numberOfAtoms; jj++ ) + for (int jj = ii+1; jj < numberOfAtoms; jj++) if (exclusions[jj].find(ii) == exclusions[jj].end()) calculateOneIxn(ii, jj, atomCoordinates, atomParameters, forces, energyByAtom, totalEnergy); } @@ -523,9 +523,9 @@ void ReferenceLJCoulombIxn::calculatePairIxn(int numberOfAtoms, vector& --------------------------------------------------------------------------------------- */ -void ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, vector& atomCoordinates, +void ReferenceLJCoulombIxn::calculateOneIxn(int ii, int jj, vector& atomCoordinates, RealOpenMM** atomParameters, vector& forces, - RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const { + RealOpenMM* energyByAtom, RealOpenMM* totalEnergy) const { // --------------------------------------------------------------------------------------- @@ -552,9 +552,9 @@ void ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, vector& at // get deltaR, R2, and R between 2 atoms if (periodic) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR[0] ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[jj], atomCoordinates[ii], periodicBoxVectors, deltaR[0]); else - ReferenceForce::getDeltaR( atomCoordinates[jj], atomCoordinates[ii], deltaR[0] ); + ReferenceForce::getDeltaR(atomCoordinates[jj], atomCoordinates[ii], deltaR[0]); RealOpenMM r2 = deltaR[0][ReferenceForce::R2Index]; RealOpenMM inverseR = one/(deltaR[0][ReferenceForce::RIndex]); @@ -573,7 +573,7 @@ void ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, vector& at RealOpenMM sig6 = sig2*sig2*sig2; RealOpenMM eps = atomParameters[ii][EpsIndex]*atomParameters[jj][EpsIndex]; - RealOpenMM dEdR = switchValue*eps*( twelve*sig6 - six )*sig6; + RealOpenMM dEdR = switchValue*eps*(twelve*sig6 - six)*sig6; if (cutoff) dEdR += (RealOpenMM) (ONE_4PI_EPS0*atomParameters[ii][QIndex]*atomParameters[jj][QIndex]*(inverseR-2.0f*krf*r2)); else @@ -591,7 +591,7 @@ void ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, vector& at // accumulate forces - for( int kk = 0; kk < 3; kk++ ){ + for (int kk = 0; kk < 3; kk++) { RealOpenMM force = dEdR*deltaR[0][kk]; forces[ii][kk] += force; forces[jj][kk] -= force; @@ -599,9 +599,9 @@ void ReferenceLJCoulombIxn::calculateOneIxn( int ii, int jj, vector& at // accumulate energies - if( totalEnergy ) + if (totalEnergy) *totalEnergy += energy; - if( energyByAtom ){ + if (energyByAtom) { energyByAtom[ii] += energy; energyByAtom[jj] += energy; } diff --git a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp index da67ee67e..766884dd0 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp @@ -43,9 +43,9 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceLincsAlgorithm::ReferenceLincsAlgorithm( int numberOfConstraints, - int** atomIndices, - RealOpenMM* distance ){ +ReferenceLincsAlgorithm::ReferenceLincsAlgorithm(int numberOfConstraints, + int** atomIndices, + RealOpenMM* distance) { // --------------------------------------------------------------------------------------- @@ -69,7 +69,7 @@ ReferenceLincsAlgorithm::ReferenceLincsAlgorithm( int numberOfConstraints, --------------------------------------------------------------------------------------- */ -int ReferenceLincsAlgorithm::getNumberOfConstraints( void ) const { +int ReferenceLincsAlgorithm::getNumberOfConstraints() const { // --------------------------------------------------------------------------------------- @@ -88,7 +88,7 @@ int ReferenceLincsAlgorithm::getNumberOfConstraints( void ) const { --------------------------------------------------------------------------------------- */ -int ReferenceLincsAlgorithm::getNumTerms( void ) const { +int ReferenceLincsAlgorithm::getNumTerms() const { // --------------------------------------------------------------------------------------- @@ -105,7 +105,7 @@ int ReferenceLincsAlgorithm::getNumTerms( void ) const { --------------------------------------------------------------------------------------- */ -void ReferenceLincsAlgorithm::setNumTerms( int terms ){ +void ReferenceLincsAlgorithm::setNumTerms(int terms) { // --------------------------------------------------------------------------------------- @@ -218,9 +218,9 @@ void ReferenceLincsAlgorithm::updateAtomPositions(int numberOfAtoms, vector& atomCoordinates, +int ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector& atomCoordinates, vector& atomCoordinatesP, - vector& inverseMasses ){ + vector& inverseMasses) { // --------------------------------------------------------------------------------------- @@ -235,7 +235,7 @@ int ReferenceLincsAlgorithm::apply( int numberOfAtoms, vector& atomCoor if (_numberOfConstraints == 0) return SimTKOpenMMCommon::DefaultReturn; - if( !_hasInitialized ) + if (!_hasInitialized) initialize(numberOfAtoms, inverseMasses); // Calculate the direction of each constraint, along with the initial RHS and solution vectors. diff --git a/platforms/reference/src/SimTKReference/ReferenceMonteCarloBarostat.cpp b/platforms/reference/src/SimTKReference/ReferenceMonteCarloBarostat.cpp index 15a55fc4d..c2b7b852f 100644 --- a/platforms/reference/src/SimTKReference/ReferenceMonteCarloBarostat.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceMonteCarloBarostat.cpp @@ -49,7 +49,7 @@ ReferenceMonteCarloBarostat::ReferenceMonteCarloBarostat(int numAtoms, const vec --------------------------------------------------------------------------------------- */ -ReferenceMonteCarloBarostat::~ReferenceMonteCarloBarostat( ) { +ReferenceMonteCarloBarostat::~ReferenceMonteCarloBarostat() { } /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp index 428588334..72eca2903 100644 --- a/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceNeighborList.cpp @@ -45,12 +45,12 @@ void OPENMM_EXPORT computeNeighborListNaive( for (AtomIndex atomJ = atomI + 1; atomJ < (AtomIndex) nAtoms; ++atomJ) { double pairDistanceSquared = compPairDistanceSquared(atomLocations[atomI], atomLocations[atomJ], periodicBoxVectors, usePeriodic); - if ( (pairDistanceSquared <= maxDistanceSquared) && (pairDistanceSquared >= minDistanceSquared)) + if ((pairDistanceSquared <= maxDistanceSquared) && (pairDistanceSquared >= minDistanceSquared)) if (exclusions[atomI].find(atomJ) == exclusions[atomI].end()) { - neighborList.push_back( AtomPair(atomI, atomJ) ); + neighborList.push_back(AtomPair(atomI, atomJ)); if (reportSymmetricPairs) - neighborList.push_back( AtomPair(atomI, atomJ) ); + neighborList.push_back(AtomPair(atomI, atomJ)); } } } @@ -199,9 +199,9 @@ public: // Ignore exclusions. if (exclusions[atomI].find(atomJ) != exclusions[atomI].end()) continue; - neighbors.push_back( AtomPair(atomI, atomJ) ); + neighbors.push_back(AtomPair(atomI, atomJ)); if (reportSymmetricPairs) - neighbors.push_back( AtomPair(atomJ, atomI) ); + neighbors.push_back(AtomPair(atomJ, atomI)); } } } @@ -228,7 +228,7 @@ void OPENMM_EXPORT computeNeighborListVoxelHash( double maxDistance, double minDistance, bool reportSymmetricPairs - ) + ) { neighborList.clear(); @@ -245,7 +245,7 @@ void OPENMM_EXPORT computeNeighborListVoxelHash( { // 1) Find other atoms that are close to this one const RealVec& location = atomLocations[atomJ]; - voxelHash.getNeighbors( + voxelHash.getNeighbors( neighborList, VoxelItem(&location, atomJ), exclusions, diff --git a/platforms/reference/src/SimTKReference/ReferencePME.cpp b/platforms/reference/src/SimTKReference/ReferencePME.cpp index 5a1946f28..c01b5fb3f 100644 --- a/platforms/reference/src/SimTKReference/ReferencePME.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePME.cpp @@ -77,7 +77,7 @@ struct pme * If particle i has coordinates { 0.543 , 6.235 , -0.73 }, we will get: * * particleindex[i] = { 5 , 62 , 92 } (-0.73 + 10 = 9.27, we always apply PBC for grid calculations!) - * particlefraction[i] = { 0.43 , 0.35 , 0.7 } ( this is the fraction of the cell length where the atom is) + * particlefraction[i] = { 0.43 , 0.35 , 0.7 } (this is the fraction of the cell length where the atom is) * * (The reason for precaculating / storing these is that it gets a bit more complex for triclinic cells :-) * @@ -108,7 +108,7 @@ pme_calculate_bsplines_moduli(pme_t pme) RealOpenMM sc,ss,arg; nmax = 0; - for(d=0;d<3;d++) + for (d=0;d<3;d++) { nmax = (pme->ngrid[d] > nmax) ? pme->ngrid[d] : nmax; pme->bsplines_moduli[d] = (RealOpenMM *) malloc(sizeof(RealOpenMM)*pme->ngrid[d]); @@ -125,11 +125,11 @@ pme_calculate_bsplines_moduli(pme_t pme) data[1]=0; data[0]=1; - for(k=3;kngrid[d]; - for(i=0;ibsplines_moduli[d][i]=sc*sc+ss*ss; } - for(i=0;ibsplines_moduli[d][i]<1.0e-7) + if (pme->bsplines_moduli[d][i]<1.0e-7) { pme->bsplines_moduli[d][i]=(pme->bsplines_moduli[d][i-1]+pme->bsplines_moduli[d][i+1])/2; } @@ -213,7 +213,7 @@ pme_update_grid_index_and_fraction(pme_t pme, RealOpenMM t; int ti; - for(i=0;inatoms;i++) + for (i=0;inatoms;i++) { /* Index calculation (Look mom, no conditionals!): * @@ -252,7 +252,7 @@ pme_update_grid_index_and_fraction(pme_t pme, * (And, by adding 100.0 box lengths, we would lose a bit of numerical accuracy here!) */ RealVec coord = atomCoordinates[i]; - for(d=0;d<3;d++) + for (d=0;d<3;d++) { t = coord[0]*recipBoxVectors[0][d]+coord[1]*recipBoxVectors[1][d]+coord[2]*recipBoxVectors[2][d]; t = (t-floor(t))*pme->ngrid[d]; @@ -281,9 +281,9 @@ pme_update_bsplines(pme_t pme) order = pme->order; - for(i=0; (inatoms); i++) + for (i=0; (inatoms); i++) { - for(j=0; j<3; j++) + for (j=0; j<3; j++) { /* dr is relative offset from lower cell limit */ dr = pme->particlefraction[i][j]; @@ -294,11 +294,11 @@ pme_update_bsplines(pme_t pme) data[1] = dr; data[0] = 1-dr; - for(k=3; k& charges) order = pme->order; /* Reset the grid */ - for(i=0;ingrid[0]*pme->ngrid[1]*pme->ngrid[2];i++) + for (i=0;ingrid[0]*pme->ngrid[1]*pme->ngrid[2];i++) { pme->grid[i].re = pme->grid[i].im = 0; } - for(i=0;inatoms;i++) + for (i=0;inatoms;i++) { q = charges[i]; @@ -380,16 +380,16 @@ pme_grid_spread_charge(pme_t pme, const vector& charges) * 3) When we parallelize things, we only need to communicate in one direction instead of two! */ - for(ix=0;ixngrid[0]; - for(iy=0;iyngrid[1]; - for(iz=0;izngrid[2]; @@ -448,21 +448,21 @@ pme_reciprocal_convolution(pme_t pme, maxky = (RealOpenMM) ((ny+1)/2); maxkz = (RealOpenMM) ((nz+1)/2); - for(kx=0;kxbsplines_moduli[0][kx]; - for(ky=0;kybsplines_moduli[1][ky]; - for(kz=0;kznatoms;i++) + for (i=0;inatoms;i++) { fx = fy = fz = 0; @@ -570,21 +570,21 @@ pme_grid_interpolate_force(pme_t pme, /* Since we will add order^3 (typically 4*4*4=64) terms to the force on each particle, we use temporary fx/fy/fz * variables, and only add it to memory forces[] at the end. */ - for(ix=0;ixngrid[0]; /* Get both the bspline factor and its derivative with respect to the x coordinate! */ tx = thetax[ix]; dtx = dthetax[ix]; - for(iy=0;iyngrid[1]; /* bspline + derivative wrt y */ ty = thetay[iy]; dty = dthetay[iy]; - for(iz=0;izngrid[2]; @@ -633,7 +633,7 @@ pme_init(pme_t * ppme, pme->ewaldcoeff = ewaldcoeff; pme->natoms = natoms; - for(d=0;d<3;d++) + for (d=0;d<3;d++) { pme->ngrid[d] = ngrid[d]; pme->bsplines_theta[d] = (RealOpenMM *)malloc(sizeof(RealOpenMM)*pme_order*natoms); @@ -712,7 +712,7 @@ pme_destroy(pme_t pme) free(pme->grid); - for(d=0;d<3;d++) + for (d=0;d<3;d++) { free(pme->bsplines_moduli[d]); free(pme->bsplines_theta[d]); diff --git a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp index 541d793a9..f0fdfa1f1 100644 --- a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp @@ -38,7 +38,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferencePairIxn::ReferencePairIxn( ){ +ReferencePairIxn::ReferencePairIxn() { // --------------------------------------------------------------------------------------- @@ -54,7 +54,7 @@ ReferencePairIxn::ReferencePairIxn( ){ --------------------------------------------------------------------------------------- */ -ReferencePairIxn::~ReferencePairIxn( ){ +ReferencePairIxn::~ReferencePairIxn() { // --------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp index e381431de..c090671eb 100644 --- a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp @@ -39,7 +39,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceProperDihedralBond::ReferenceProperDihedralBond( ){ +ReferenceProperDihedralBond::ReferenceProperDihedralBond() { // --------------------------------------------------------------------------------------- @@ -55,7 +55,7 @@ ReferenceProperDihedralBond::ReferenceProperDihedralBond( ){ --------------------------------------------------------------------------------------- */ -ReferenceProperDihedralBond::~ReferenceProperDihedralBond( ){ +ReferenceProperDihedralBond::~ReferenceProperDihedralBond() { // --------------------------------------------------------------------------------------- @@ -79,11 +79,11 @@ ReferenceProperDihedralBond::~ReferenceProperDihedralBond( ){ --------------------------------------------------------------------------------------- */ -void ReferenceProperDihedralBond::calculateBondIxn( int* atomIndices, +void ReferenceProperDihedralBond::calculateBondIxn(int* atomIndices, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* totalEnergy ) const { + RealOpenMM* totalEnergy) const { static const std::string methodName = "\nReferenceProperDihedralBond::calculateBondIxn"; @@ -111,9 +111,9 @@ void ReferenceProperDihedralBond::calculateBondIxn( int* atomIndices, int atomBIndex = atomIndices[1]; int atomCIndex = atomIndices[2]; int atomDIndex = atomIndices[3]; - ReferenceForce::getDeltaR( atomCoordinates[atomBIndex], atomCoordinates[atomAIndex], deltaR[0] ); - ReferenceForce::getDeltaR( atomCoordinates[atomBIndex], atomCoordinates[atomCIndex], deltaR[1] ); - ReferenceForce::getDeltaR( atomCoordinates[atomDIndex], atomCoordinates[atomCIndex], deltaR[2] ); + ReferenceForce::getDeltaR(atomCoordinates[atomBIndex], atomCoordinates[atomAIndex], deltaR[0]); + ReferenceForce::getDeltaR(atomCoordinates[atomBIndex], atomCoordinates[atomCIndex], deltaR[1]); + ReferenceForce::getDeltaR(atomCoordinates[atomDIndex], atomCoordinates[atomCIndex], deltaR[2]); RealOpenMM dotDihedral; RealOpenMM signOfAngle; @@ -127,35 +127,35 @@ void ReferenceProperDihedralBond::calculateBondIxn( int* atomIndices, // get dihedral angle - RealOpenMM dihedralAngle = getDihedralAngleBetweenThreeVectors( deltaR[0], deltaR[1], deltaR[2], - crossProduct, &dotDihedral, deltaR[0], - &signOfAngle, hasREntry ); + RealOpenMM dihedralAngle = getDihedralAngleBetweenThreeVectors(deltaR[0], deltaR[1], deltaR[2], + crossProduct, &dotDihedral, deltaR[0], + &signOfAngle, hasREntry); // evaluate delta angle, dE/d(angle) RealOpenMM deltaAngle = parameters[2]*dihedralAngle - parameters[1]; - RealOpenMM sinDeltaAngle = SIN( deltaAngle ); + RealOpenMM sinDeltaAngle = SIN(deltaAngle); RealOpenMM dEdAngle = -parameters[0]*parameters[2]*sinDeltaAngle; - RealOpenMM energy = parameters[0]*(one + COS( deltaAngle ) ); + RealOpenMM energy = parameters[0]*(one + COS(deltaAngle)); // compute force RealOpenMM internalF[4][3]; RealOpenMM forceFactors[4]; - RealOpenMM normCross1 = DOT3( crossProduct[0], crossProduct[0] ); + RealOpenMM normCross1 = DOT3(crossProduct[0], crossProduct[0]); RealOpenMM normBC = deltaR[1][ReferenceForce::RIndex]; forceFactors[0] = (-dEdAngle*normBC)/normCross1; - RealOpenMM normCross2 = DOT3( crossProduct[1], crossProduct[1] ); + RealOpenMM normCross2 = DOT3(crossProduct[1], crossProduct[1]); forceFactors[3] = (dEdAngle*normBC)/normCross2; - forceFactors[1] = DOT3( deltaR[0], deltaR[1] ); + forceFactors[1] = DOT3(deltaR[0], deltaR[1]); forceFactors[1] /= deltaR[1][ReferenceForce::R2Index]; - forceFactors[2] = DOT3( deltaR[2], deltaR[1] ); + forceFactors[2] = DOT3(deltaR[2], deltaR[1]); forceFactors[2] /= deltaR[1][ReferenceForce::R2Index]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { internalF[0][ii] = forceFactors[0]*crossProduct[0][ii]; internalF[3][ii] = forceFactors[3]*crossProduct[1][ii]; @@ -168,7 +168,7 @@ void ReferenceProperDihedralBond::calculateBondIxn( int* atomIndices, // accumulate forces - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forces[atomAIndex][ii] += internalF[0][ii]; forces[atomBIndex][ii] -= internalF[1][ii]; forces[atomCIndex][ii] -= internalF[2][ii]; diff --git a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp index 652e01f38..f6c8f06d3 100644 --- a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp @@ -39,7 +39,7 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceRbDihedralBond::ReferenceRbDihedralBond( ){ +ReferenceRbDihedralBond::ReferenceRbDihedralBond() { // --------------------------------------------------------------------------------------- @@ -55,7 +55,7 @@ ReferenceRbDihedralBond::ReferenceRbDihedralBond( ){ --------------------------------------------------------------------------------------- */ -ReferenceRbDihedralBond::~ReferenceRbDihedralBond( ){ +ReferenceRbDihedralBond::~ReferenceRbDihedralBond() { // --------------------------------------------------------------------------------------- @@ -77,11 +77,11 @@ ReferenceRbDihedralBond::~ReferenceRbDihedralBond( ){ --------------------------------------------------------------------------------------- */ -void ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices, +void ReferenceRbDihedralBond::calculateBondIxn(int* atomIndices, vector& atomCoordinates, RealOpenMM* parameters, vector& forces, - RealOpenMM* totalEnergy ) const { + RealOpenMM* totalEnergy) const { static const std::string methodName = "\nReferenceRbDihedralBond::calculateBondIxn"; @@ -113,9 +113,9 @@ void ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices, int atomBIndex = atomIndices[1]; int atomCIndex = atomIndices[2]; int atomDIndex = atomIndices[3]; - ReferenceForce::getDeltaR( atomCoordinates[atomBIndex], atomCoordinates[atomAIndex], deltaR[0] ); - ReferenceForce::getDeltaR( atomCoordinates[atomBIndex], atomCoordinates[atomCIndex], deltaR[1] ); - ReferenceForce::getDeltaR( atomCoordinates[atomDIndex], atomCoordinates[atomCIndex], deltaR[2] ); + ReferenceForce::getDeltaR(atomCoordinates[atomBIndex], atomCoordinates[atomAIndex], deltaR[0]); + ReferenceForce::getDeltaR(atomCoordinates[atomBIndex], atomCoordinates[atomCIndex], deltaR[1]); + ReferenceForce::getDeltaR(atomCoordinates[atomDIndex], atomCoordinates[atomCIndex], deltaR[2]); RealOpenMM cosPhi; RealOpenMM signOfAngle; @@ -126,13 +126,13 @@ void ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices, RealOpenMM* crossProduct[2]; crossProduct[0] = crossProductMemory; crossProduct[1] = crossProductMemory + 3; - RealOpenMM dihederalAngle = getDihedralAngleBetweenThreeVectors( deltaR[0], deltaR[1], deltaR[2], - crossProduct, &cosPhi, deltaR[0], - &signOfAngle, hasREntry ); + RealOpenMM dihederalAngle = getDihedralAngleBetweenThreeVectors(deltaR[0], deltaR[1], deltaR[2], + crossProduct, &cosPhi, deltaR[0], + &signOfAngle, hasREntry); // Gromacs: use polymer convention - if( dihederalAngle < zero ){ + if (dihederalAngle < zero) { dihederalAngle += PI_M; } else { dihederalAngle -= PI_M; @@ -141,36 +141,36 @@ void ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices, // Ryckaert-Bellemans: - // V = sum over i: { C_i*cos( psi )**i }, where psi = phi - PI, + // V = sum over i: { C_i*cos(psi)**i }, where psi = phi - PI, // C_i is ith RB coefficient RealOpenMM dEdAngle = zero; RealOpenMM energy = parameters[0]; RealOpenMM cosFactor = one; - for( int ii = 1; ii < numberOfParameters; ii++ ){ + for (int ii = 1; ii < numberOfParameters; ii++) { dEdAngle -= ((RealOpenMM) ii)*parameters[ii]*cosFactor; cosFactor *= cosPhi; energy += cosFactor*parameters[ii]; } - dEdAngle *= SIN( dihederalAngle ); + dEdAngle *= SIN(dihederalAngle); RealOpenMM internalF[4][3]; RealOpenMM forceFactors[4]; - RealOpenMM normCross1 = DOT3( crossProduct[0], crossProduct[0] ); + RealOpenMM normCross1 = DOT3(crossProduct[0], crossProduct[0]); RealOpenMM normBC = deltaR[1][ReferenceForce::RIndex]; forceFactors[0] = (-dEdAngle*normBC)/normCross1; - RealOpenMM normCross2 = DOT3( crossProduct[1], crossProduct[1] ); + RealOpenMM normCross2 = DOT3(crossProduct[1], crossProduct[1]); forceFactors[3] = (dEdAngle*normBC)/normCross2; - forceFactors[1] = DOT3( deltaR[0], deltaR[1] ); + forceFactors[1] = DOT3(deltaR[0], deltaR[1]); forceFactors[1] /= deltaR[1][ReferenceForce::R2Index]; - forceFactors[2] = DOT3( deltaR[2], deltaR[1] ); + forceFactors[2] = DOT3(deltaR[2], deltaR[1]); forceFactors[2] /= deltaR[1][ReferenceForce::R2Index]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { internalF[0][ii] = forceFactors[0]*crossProduct[0][ii]; internalF[3][ii] = forceFactors[3]*crossProduct[1][ii]; @@ -183,7 +183,7 @@ void ReferenceRbDihedralBond::calculateBondIxn( int* atomIndices, // accumulate forces - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forces[atomAIndex][ii] += internalF[0][ii]; forces[atomBIndex][ii] -= internalF[1][ii]; forces[atomCIndex][ii] -= internalF[2][ii]; diff --git a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp index d04b0a5a6..fe6c333d7 100644 --- a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp @@ -47,10 +47,10 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceStochasticDynamics::ReferenceStochasticDynamics( int numberOfAtoms, - RealOpenMM deltaT, RealOpenMM tau, - RealOpenMM temperature ) : - ReferenceDynamics( numberOfAtoms, deltaT, temperature ), _tau( tau ) { +ReferenceStochasticDynamics::ReferenceStochasticDynamics(int numberOfAtoms, + RealOpenMM deltaT, RealOpenMM tau, + RealOpenMM temperature) : + ReferenceDynamics(numberOfAtoms, deltaT, temperature), _tau(tau) { if (tau <= 0) { std::stringstream message; message << "illegal tau value: " << tau; @@ -66,7 +66,7 @@ ReferenceStochasticDynamics::ReferenceStochasticDynamics( int numberOfAtoms, --------------------------------------------------------------------------------------- */ -ReferenceStochasticDynamics::~ReferenceStochasticDynamics( ){ +ReferenceStochasticDynamics::~ReferenceStochasticDynamics() { // --------------------------------------------------------------------------------------- @@ -84,7 +84,7 @@ ReferenceStochasticDynamics::~ReferenceStochasticDynamics( ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceStochasticDynamics::getTau( void ) const { +RealOpenMM ReferenceStochasticDynamics::getTau() const { // --------------------------------------------------------------------------------------- @@ -108,10 +108,10 @@ RealOpenMM ReferenceStochasticDynamics::getTau( void ) const { --------------------------------------------------------------------------------------- */ -void ReferenceStochasticDynamics::updatePart1( int numberOfAtoms, vector& atomCoordinates, +void ReferenceStochasticDynamics::updatePart1(int numberOfAtoms, vector& atomCoordinates, vector& velocities, vector& forces, vector& inverseMasses, - vector& xPrime ){ + vector& xPrime) { // --------------------------------------------------------------------------------------- @@ -149,10 +149,10 @@ void ReferenceStochasticDynamics::updatePart1( int numberOfAtoms, vector& atomCoordinates, +void ReferenceStochasticDynamics::updatePart2(int numberOfAtoms, vector& atomCoordinates, vector& velocities, vector& forces, vector& inverseMasses, - vector& xPrime ){ + vector& xPrime) { // --------------------------------------------------------------------------------------- @@ -197,10 +197,10 @@ void ReferenceStochasticDynamics::update(const OpenMM::System& system, vector& atomCoordinates, +void ReferenceVariableStochasticDynamics::updatePart1(int numberOfAtoms, vector& atomCoordinates, vector& velocities, vector& forces, vector& masses, vector& inverseMasses, - vector& xPrime, RealOpenMM maxStepSize ){ + vector& xPrime, RealOpenMM maxStepSize) { // --------------------------------------------------------------------------------------- @@ -148,10 +148,10 @@ void ReferenceVariableStochasticDynamics::updatePart1( int numberOfAtoms, vector // first-time-through initialization - if( getTimeStep() == 0 ){ + if (getTimeStep() == 0) { // invert masses - for( int ii = 0; ii < numberOfAtoms; ii++ ){ + for (int ii = 0; ii < numberOfAtoms; ii++) { if (masses[ii] == 0) inverseMasses[ii] = 0; else @@ -208,10 +208,10 @@ void ReferenceVariableStochasticDynamics::updatePart1( int numberOfAtoms, vector --------------------------------------------------------------------------------------- */ -void ReferenceVariableStochasticDynamics::updatePart2( int numberOfAtoms, vector& atomCoordinates, +void ReferenceVariableStochasticDynamics::updatePart2(int numberOfAtoms, vector& atomCoordinates, vector& velocities, vector& forces, vector& inverseMasses, - vector& xPrime ){ + vector& xPrime) { // --------------------------------------------------------------------------------------- @@ -255,11 +255,11 @@ void ReferenceVariableStochasticDynamics::update(const OpenMM::System& system, v // 1st update int numberOfAtoms = system.getNumParticles(); - updatePart1( numberOfAtoms, atomCoordinates, velocities, forces, masses, inverseMasses, xPrime, maxStepSize ); + updatePart1(numberOfAtoms, atomCoordinates, velocities, forces, masses, inverseMasses, xPrime, maxStepSize); // 2nd update - updatePart2( numberOfAtoms, atomCoordinates, velocities, forces, inverseMasses, xPrime ); + updatePart2(numberOfAtoms, atomCoordinates, velocities, forces, inverseMasses, xPrime); ReferenceConstraintAlgorithm* referenceConstraintAlgorithm = getReferenceConstraintAlgorithm(); if (referenceConstraintAlgorithm) @@ -267,7 +267,7 @@ void ReferenceVariableStochasticDynamics::update(const OpenMM::System& system, v // copy xPrime -> atomCoordinates - for( int ii = 0; ii < numberOfAtoms; ii++ ) { + for (int ii = 0; ii < numberOfAtoms; ii++) { if (masses[ii] != 0.0) { atomCoordinates[ii][0] = xPrime[ii][0]; atomCoordinates[ii][1] = xPrime[ii][1]; diff --git a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp index dc84f6c8e..5becb5fb5 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp @@ -44,8 +44,8 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceVariableVerletDynamics::ReferenceVariableVerletDynamics( int numberOfAtoms, RealOpenMM accuracy ) : - ReferenceDynamics( numberOfAtoms, 0.0f, 0.0f ), _accuracy(accuracy) { +ReferenceVariableVerletDynamics::ReferenceVariableVerletDynamics(int numberOfAtoms, RealOpenMM accuracy) : + ReferenceDynamics(numberOfAtoms, 0.0f, 0.0f), _accuracy(accuracy) { xPrime.resize(numberOfAtoms); inverseMasses.resize(numberOfAtoms); } @@ -56,7 +56,7 @@ ReferenceVariableVerletDynamics::ReferenceVariableVerletDynamics( int numberOfAt --------------------------------------------------------------------------------------- */ -ReferenceVariableVerletDynamics::~ReferenceVariableVerletDynamics( ){ +ReferenceVariableVerletDynamics::~ReferenceVariableVerletDynamics() { // --------------------------------------------------------------------------------------- @@ -74,7 +74,7 @@ ReferenceVariableVerletDynamics::~ReferenceVariableVerletDynamics( ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ReferenceVariableVerletDynamics::getAccuracy( void ) const { +RealOpenMM ReferenceVariableVerletDynamics::getAccuracy() const { return _accuracy; } @@ -84,7 +84,7 @@ RealOpenMM ReferenceVariableVerletDynamics::getAccuracy( void ) const { --------------------------------------------------------------------------------------- */ -void ReferenceVariableVerletDynamics::setAccuracy( RealOpenMM accuracy ) { +void ReferenceVariableVerletDynamics::setAccuracy(RealOpenMM accuracy) { _accuracy = accuracy; } @@ -118,10 +118,10 @@ void ReferenceVariableVerletDynamics::update(const OpenMM::System& system, vecto // first-time-through initialization int numberOfAtoms = system.getNumParticles(); - if( getTimeStep() == 0 ){ + if (getTimeStep() == 0) { // invert masses - for( int ii = 0; ii < numberOfAtoms; ii++ ){ + for (int ii = 0; ii < numberOfAtoms; ii++) { if (masses[ii] == zero) inverseMasses[ii] = zero; else diff --git a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp index f9b77aca6..921e0504c 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp @@ -46,9 +46,8 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ReferenceVerletDynamics::ReferenceVerletDynamics( int numberOfAtoms, - RealOpenMM deltaT ) : - ReferenceDynamics( numberOfAtoms, deltaT, 0.0 ) { +ReferenceVerletDynamics::ReferenceVerletDynamics(int numberOfAtoms, RealOpenMM deltaT) : + ReferenceDynamics(numberOfAtoms, deltaT, 0.0) { // --------------------------------------------------------------------------------------- @@ -69,7 +68,7 @@ ReferenceVerletDynamics::ReferenceVerletDynamics( int numberOfAtoms, --------------------------------------------------------------------------------------- */ -ReferenceVerletDynamics::~ReferenceVerletDynamics( ){ +ReferenceVerletDynamics::~ReferenceVerletDynamics() { // --------------------------------------------------------------------------------------- @@ -108,10 +107,10 @@ void ReferenceVerletDynamics::update(const OpenMM::System& system, vector( 1.0/getDeltaT() ); + RealOpenMM velocityScale = static_cast(1.0/getDeltaT()); for (int i = 0; i < numberOfAtoms; ++i) { if (masses[i] != zero) for (int j = 0; j < 3; ++j) { diff --git a/platforms/reference/src/SimTKReference/fftpack.cpp b/platforms/reference/src/SimTKReference/fftpack.cpp index c53f60884..4145bc555 100644 --- a/platforms/reference/src/SimTKReference/fftpack.cpp +++ b/platforms/reference/src/SimTKReference/fftpack.cpp @@ -672,16 +672,16 @@ fftpack_transpose_2d(t_complex * in_data, t_complex * src; int i,j; - if(nx<2 || ny<2) + if (nx<2 || ny<2) { - if(in_data != out_data) + if (in_data != out_data) { memcpy(out_data,in_data,sizeof(t_complex)*nx*ny); } return 0; } - if(in_data == out_data) + if (in_data == out_data) { src = (t_complex *)malloc(sizeof(t_complex)*nx*ny); memcpy(src,in_data,sizeof(t_complex)*nx*ny); @@ -691,16 +691,16 @@ fftpack_transpose_2d(t_complex * in_data, src = in_data; } - for(i=0;in = nx; /* Need 4*n storage for 1D complex FFT */ - if( (fft->work = (RealOpenMM *)malloc(sizeof(RealOpenMM)*(4*nx))) == NULL) + if ((fft->work = (RealOpenMM *)malloc(sizeof(RealOpenMM)*(4*nx))) == NULL) { free(fft); return ENOMEM; } - if(fft->n>1) + if (fft->n>1) fftpack_cffti1(nx,fft->work,fft->ifac); *pfft = fft; @@ -807,7 +807,7 @@ fftpack_init_2d(fftpack_t * pfft, fftpack_t fft; int rc; - if(pfft==NULL) + if (pfft==NULL) { fprintf(stderr,"Fatal error - Invalid FFT opaque type pointer."); return EINVAL; @@ -815,13 +815,13 @@ fftpack_init_2d(fftpack_t * pfft, *pfft = NULL; /* Create the X transform */ - if( (rc = fftpack_init_1d(&fft,nx)) != 0) + if ((rc = fftpack_init_1d(&fft,nx)) != 0) { return rc; } /* Create Y transform as a link from X */ - if( (rc=fftpack_init_1d(&(fft->next),ny)) != 0) + if ((rc=fftpack_init_1d(&(fft->next),ny)) != 0) { free(fft); return rc; @@ -842,7 +842,7 @@ fftpack_init_3d(fftpack_t * pfft, fftpack_t fft; int rc; - if(pfft==NULL) + if (pfft==NULL) { fprintf(stderr,"Fatal error - Invalid FFT opaque type pointer."); return EINVAL; @@ -851,7 +851,7 @@ fftpack_init_3d(fftpack_t * pfft, /* Create the X transform */ - if( (fft = (struct fftpack *)malloc(sizeof(struct fftpack))) == NULL) + if ((fft = (struct fftpack *)malloc(sizeof(struct fftpack))) == NULL) { return ENOMEM; } @@ -860,7 +860,7 @@ fftpack_init_3d(fftpack_t * pfft, /* Need 4*nx storage for 1D complex FFT. */ - if( (fft->work = (RealOpenMM *)malloc(sizeof(RealOpenMM)*(4*nx))) == NULL) + if ((fft->work = (RealOpenMM *)malloc(sizeof(RealOpenMM)*(4*nx))) == NULL) { free(fft); return ENOMEM; @@ -869,7 +869,7 @@ fftpack_init_3d(fftpack_t * pfft, fftpack_cffti1(nx,fft->work,fft->ifac); /* Create 2D Y/Z transforms as a link from X */ - if( (rc=fftpack_init_2d(&(fft->next),ny,nz)) != 0) + if ((rc=fftpack_init_2d(&(fft->next),ny,nz)) != 0) { free(fft); return rc; @@ -893,7 +893,7 @@ fftpack_exec_1d (fftpack_t fft, n=fft->n; - if(n==1) + if (n==1) { p1 = (RealOpenMM *)in_data; p2 = (RealOpenMM *)out_data; @@ -904,13 +904,13 @@ fftpack_exec_1d (fftpack_t fft, /* FFTPACK only does in-place transforms, so emulate out-of-place * by copying data to the output array first. */ - if( in_data != out_data ) + if (in_data != out_data) { p1 = (RealOpenMM *)in_data; p2 = (RealOpenMM *)out_data; /* n complex = 2*n RealOpenMM elements */ - for(i=0;i<2*n;i++) + for (i=0;i<2*n;i++) { p2[i] = p1[i]; } @@ -920,11 +920,11 @@ fftpack_exec_1d (fftpack_t fft, * Elements 2*n .. 4*n-1 are internal FFTPACK work space. */ - if(dir == FFTPACK_FORWARD) + if (dir == FFTPACK_FORWARD) { fftpack_cfftf1(n,(RealOpenMM *)out_data,fft->work+2*n,fft->work,fft->ifac, -1); } - else if(dir == FFTPACK_BACKWARD) + else if (dir == FFTPACK_BACKWARD) { fftpack_cfftf1(n,(RealOpenMM *)out_data,fft->work+2*n,fft->work,fft->ifac, 1); } @@ -957,7 +957,7 @@ fftpack_exec_2d (fftpack_t fft, * by copying data to the output array first. * For 2D there is likely enough data to benefit from memcpy(). */ - if( in_data != out_data ) + if (in_data != out_data) { memcpy(out_data,in_data,sizeof(t_complex)*nx*ny); } @@ -966,7 +966,7 @@ fftpack_exec_2d (fftpack_t fft, data = (t_complex *)out_data; /* y transforms */ - for(i=0;inext,dir,data+i*ny,data+i*ny); } @@ -975,7 +975,7 @@ fftpack_exec_2d (fftpack_t fft, fftpack_transpose_2d(data,data,nx,ny); /* x transforms */ - for(i=0;inext->next,dir,data+i*nz,data+i*nz); /* For each X slice, transpose the y & z dimensions inside the slice */ - for(i=0;inext,dir,data+i*ny,data+i*ny); } /* Transpose back to (nx,ny,nz) */ - for(i=0;iwork); - if(fft->next != NULL) + if (fft->next != NULL) fftpack_destroy(fft->next); free(fft); } diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp index 4313eb494..05f48b229 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp @@ -30,9 +30,9 @@ using namespace OpenMM; // initialization of static data members -const std::string SimTKOpenMMCommon::NotSet = std::string( "NotSet" ); -const std::string SimTKOpenMMCommon::Comment = std::string( "#" ); -const std::string SimTKOpenMMCommon::Tab = std::string( "\t" ); +const std::string SimTKOpenMMCommon::NotSet = std::string("NotSet"); +const std::string SimTKOpenMMCommon::Comment = std::string("#"); +const std::string SimTKOpenMMCommon::Tab = std::string("\t"); const int SimTKOpenMMCommon::DefaultReturn = 0; const int SimTKOpenMMCommon::ErrorReturn = -1; diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp index d5d343aea..35c392167 100644 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp +++ b/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp @@ -59,9 +59,9 @@ OpenMM_SFMT::SFMT SimTKOpenMMUtilities::sfmt; --------------------------------------------------------------------------------------- */ -RealOpenMM* SimTKOpenMMUtilities::allocateOneDRealOpenMMArray( int iSize, RealOpenMM* array1D, - int initialize, RealOpenMM initialValue, - const std::string& idString ){ +RealOpenMM* SimTKOpenMMUtilities::allocateOneDRealOpenMMArray(int iSize, RealOpenMM* array1D, + int initialize, RealOpenMM initialValue, + const std::string& idString) { // --------------------------------------------------------------------------------------- @@ -71,17 +71,17 @@ RealOpenMM* SimTKOpenMMUtilities::allocateOneDRealOpenMMArray( int iSize, RealOp // --------------------------------------------------------------------------------------- - if( array1D == NULL ){ + if (array1D == NULL) { array1D = new RealOpenMM[iSize]; } - if( initialize ){ - if( initialValue == zero ){ - memset( array1D, 0, iSize*sizeof( RealOpenMM ) ); + if (initialize) { + if (initialValue == zero) { + memset(array1D, 0, iSize*sizeof(RealOpenMM)); } else { - for( int ii = 0; ii < iSize; ii++ ){ + for (int ii = 0; ii < iSize; ii++) { array1D[ii] = initialValue; } } @@ -107,9 +107,9 @@ RealOpenMM* SimTKOpenMMUtilities::allocateOneDRealOpenMMArray( int iSize, RealOp --------------------------------------------------------------------------------------- */ -RealOpenMM** SimTKOpenMMUtilities::allocateTwoDRealOpenMMArray( int iSize, int jSize, RealOpenMM** array2D, - int initialize, RealOpenMM initialValue, - const std::string& idString ){ +RealOpenMM** SimTKOpenMMUtilities::allocateTwoDRealOpenMMArray(int iSize, int jSize, RealOpenMM** array2D, + int initialize, RealOpenMM initialValue, + const std::string& idString) { // --------------------------------------------------------------------------------------- @@ -117,22 +117,22 @@ RealOpenMM** SimTKOpenMMUtilities::allocateTwoDRealOpenMMArray( int iSize, int j // --------------------------------------------------------------------------------------- - if( array2D == NULL ){ + if (array2D == NULL) { array2D = new RealOpenMM*[iSize]; std::string blockString = idString; - blockString.append( "Block" ); + blockString.append("Block"); RealOpenMM* block = new RealOpenMM[jSize*iSize]; - for( int ii = 0; ii < iSize; ii++ ){ + for (int ii = 0; ii < iSize; ii++) { array2D[ii] = block; block += jSize; } } - if( initialize ){ - initialize2DRealOpenMMArray( iSize, jSize, array2D, initialValue ); + if (initialize) { + initialize2DRealOpenMMArray(iSize, jSize, array2D, initialValue); } return array2D; @@ -149,7 +149,7 @@ RealOpenMM** SimTKOpenMMUtilities::allocateTwoDRealOpenMMArray( int iSize, int j --------------------------------------------------------------------------------------- */ -void SimTKOpenMMUtilities::freeTwoDRealOpenMMArray( RealOpenMM** array2D, const std::string& idString ){ +void SimTKOpenMMUtilities::freeTwoDRealOpenMMArray(RealOpenMM** array2D, const std::string& idString) { // --------------------------------------------------------------------------------------- @@ -157,10 +157,10 @@ void SimTKOpenMMUtilities::freeTwoDRealOpenMMArray( RealOpenMM** array2D, const // --------------------------------------------------------------------------------------- - if( array2D != NULL ){ + if (array2D != NULL) { std::string blockString = idString; - blockString.append( "Block" ); + blockString.append("Block"); delete[] array2D[0]; delete[] array2D; @@ -178,7 +178,7 @@ void SimTKOpenMMUtilities::freeTwoDRealOpenMMArray( RealOpenMM** array2D, const --------------------------------------------------------------------------------------- */ -void SimTKOpenMMUtilities::freeOneDRealOpenMMArray( RealOpenMM* array1D, const std::string& idString ){ +void SimTKOpenMMUtilities::freeOneDRealOpenMMArray(RealOpenMM* array1D, const std::string& idString) { // --------------------------------------------------------------------------------------- @@ -186,7 +186,7 @@ void SimTKOpenMMUtilities::freeOneDRealOpenMMArray( RealOpenMM* array1D, const s // --------------------------------------------------------------------------------------- - if( array1D != NULL ){ + if (array1D != NULL) { delete[] array1D; } } @@ -204,9 +204,9 @@ void SimTKOpenMMUtilities::freeOneDRealOpenMMArray( RealOpenMM* array1D, const s --------------------------------------------------------------------------------------- */ -void SimTKOpenMMUtilities::initialize2DRealOpenMMArray( int iSize, int jSize, +void SimTKOpenMMUtilities::initialize2DRealOpenMMArray(int iSize, int jSize, RealOpenMM** array2D, - RealOpenMM initialValue ){ + RealOpenMM initialValue) { // --------------------------------------------------------------------------------------- @@ -217,9 +217,9 @@ void SimTKOpenMMUtilities::initialize2DRealOpenMMArray( int iSize, int jSize, bool useMemset; bool useMemsetSingleBlock; - if( initialValue == 0.0f ){ + if (initialValue == 0.0f) { useMemset = true; - if( jSize > 1 && (array2D[0] + jSize) == array2D[1] ){ + if (jSize > 1 && (array2D[0] + jSize) == array2D[1]) { useMemsetSingleBlock = true; } else { useMemsetSingleBlock = false; @@ -229,17 +229,17 @@ void SimTKOpenMMUtilities::initialize2DRealOpenMMArray( int iSize, int jSize, useMemset = false; } - if( useMemset ){ - if( useMemsetSingleBlock ){ - memset( array2D[0], 0, iSize*jSize*sizeof( RealOpenMM ) ); + if (useMemset) { + if (useMemsetSingleBlock) { + memset(array2D[0], 0, iSize*jSize*sizeof(RealOpenMM)); } else { - for( int ii = 0; ii < iSize; ii++ ){ - memset( array2D[ii], 0, jSize*sizeof( RealOpenMM ) ); + for (int ii = 0; ii < iSize; ii++) { + memset(array2D[ii], 0, jSize*sizeof(RealOpenMM)); } } } else { - for( int ii = 0; ii < iSize; ii++ ){ - for( int jj = 0; jj < jSize; jj++ ){ + for (int ii = 0; ii < iSize; ii++) { + for (int jj = 0; jj < jSize; jj++) { array2D[ii][jj] = initialValue; } } @@ -260,9 +260,9 @@ void SimTKOpenMMUtilities::initialize2DRealOpenMMArray( int iSize, int jSize, --------------------------------------------------------------------------------------- */ -void SimTKOpenMMUtilities::crossProductVector3( RealOpenMM* vectorX, - RealOpenMM* vectorY, - RealOpenMM* vectorZ ){ +void SimTKOpenMMUtilities::crossProductVector3(RealOpenMM* vectorX, + RealOpenMM* vectorY, + RealOpenMM* vectorZ) { // --------------------------------------------------------------------------------------- @@ -285,7 +285,7 @@ void SimTKOpenMMUtilities::crossProductVector3( RealOpenMM* vectorX, --------------------------------------------------------------------------------------- */ -RealOpenMM SimTKOpenMMUtilities::getNormallyDistributedRandomNumber( void ) { +RealOpenMM SimTKOpenMMUtilities::getNormallyDistributedRandomNumber() { if (nextGaussianIsValid) { nextGaussianIsValid = false; return nextGaussian; @@ -304,7 +304,7 @@ RealOpenMM SimTKOpenMMUtilities::getNormallyDistributedRandomNumber( void ) { y = static_cast(2.0 * genrand_real2(sfmt) - 1.0); r2 = x*x + y*y; } while (r2 >= 1.0 || r2 == 0.0); - RealOpenMM multiplier = static_cast( sqrt((-2.0*log(r2))/r2) ); + RealOpenMM multiplier = static_cast(sqrt((-2.0*log(r2))/r2)); nextGaussian = y*multiplier; nextGaussianIsValid = true; return x*multiplier; @@ -318,13 +318,13 @@ RealOpenMM SimTKOpenMMUtilities::getNormallyDistributedRandomNumber( void ) { --------------------------------------------------------------------------------------- */ -RealOpenMM SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber( void ) { +RealOpenMM SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() { if (!_randomInitialized) { init_gen_rand(_randomNumberSeed, sfmt); _randomInitialized = true; nextGaussianIsValid = false; } - RealOpenMM value = static_cast( genrand_real2(sfmt) ); + RealOpenMM value = static_cast(genrand_real2(sfmt)); return value; } @@ -336,7 +336,7 @@ RealOpenMM SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber( void ) { --------------------------------------------------------------------------------------- */ -uint32_t SimTKOpenMMUtilities::getRandomNumberSeed( void ) { +uint32_t SimTKOpenMMUtilities::getRandomNumberSeed() { // --------------------------------------------------------------------------------------- @@ -355,7 +355,7 @@ uint32_t SimTKOpenMMUtilities::getRandomNumberSeed( void ) { --------------------------------------------------------------------------------------- */ -void SimTKOpenMMUtilities::setRandomNumberSeed( uint32_t seed ) { +void SimTKOpenMMUtilities::setRandomNumberSeed(uint32_t seed) { // --------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/gbsa/CpuGBVI.cpp b/platforms/reference/src/gbsa/CpuGBVI.cpp index a3da45375..acd8a5136 100644 --- a/platforms/reference/src/gbsa/CpuGBVI.cpp +++ b/platforms/reference/src/gbsa/CpuGBVI.cpp @@ -41,8 +41,8 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -CpuGBVI::CpuGBVI( GBVIParameters* gbviParameters ) : _gbviParameters(gbviParameters) { - _switchDeriviative.resize( gbviParameters->getNumberOfAtoms() ); +CpuGBVI::CpuGBVI(GBVIParameters* gbviParameters) : _gbviParameters(gbviParameters) { + _switchDeriviative.resize(gbviParameters->getNumberOfAtoms()); } /**--------------------------------------------------------------------------------------- @@ -51,7 +51,7 @@ CpuGBVI::CpuGBVI( GBVIParameters* gbviParameters ) : _gbviParameters(gbviParamet --------------------------------------------------------------------------------------- */ -CpuGBVI::~CpuGBVI( ){ +CpuGBVI::~CpuGBVI() { } /**--------------------------------------------------------------------------------------- @@ -62,7 +62,7 @@ CpuGBVI::~CpuGBVI( ){ --------------------------------------------------------------------------------------- */ -GBVIParameters* CpuGBVI::getGBVIParameters( void ) const { +GBVIParameters* CpuGBVI::getGBVIParameters() const { return _gbviParameters; } @@ -74,7 +74,7 @@ GBVIParameters* CpuGBVI::getGBVIParameters( void ) const { --------------------------------------------------------------------------------------- */ -void CpuGBVI::setGBVIParameters( GBVIParameters* gbviParameters ){ +void CpuGBVI::setGBVIParameters(GBVIParameters* gbviParameters) { _gbviParameters = gbviParameters; } @@ -86,7 +86,7 @@ void CpuGBVI::setGBVIParameters( GBVIParameters* gbviParameters ){ --------------------------------------------------------------------------------------- */ -RealOpenMMVector& CpuGBVI::getSwitchDeriviative( void ){ +RealOpenMMVector& CpuGBVI::getSwitchDeriviative() { return _switchDeriviative; } @@ -102,17 +102,17 @@ RealOpenMMVector& CpuGBVI::getSwitchDeriviative( void ){ --------------------------------------------------------------------------------------- */ -void CpuGBVI::quinticSpline( RealOpenMM x, RealOpenMM rl, RealOpenMM ru, - RealOpenMM* outValue, RealOpenMM* outDerivative ){ +void CpuGBVI::quinticSpline(RealOpenMM x, RealOpenMM rl, RealOpenMM ru, + RealOpenMM* outValue, RealOpenMM* outDerivative) { // --------------------------------------------------------------------------------------- - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM minusSix = static_cast( -6.0 ); - static const RealOpenMM minusTen = static_cast( -10.0 ); - static const RealOpenMM minusThirty = static_cast( -30.0 ); - static const RealOpenMM fifteen = static_cast( 15.0 ); - static const RealOpenMM sixty = static_cast( 60.0 ); + static const RealOpenMM one = static_cast( 1.0); + static const RealOpenMM minusSix = static_cast( -6.0); + static const RealOpenMM minusTen = static_cast(-10.0); + static const RealOpenMM minusThirty = static_cast(-30.0); + static const RealOpenMM fifteen = static_cast( 15.0); + static const RealOpenMM sixty = static_cast( 60.0); // --------------------------------------------------------------------------------------- @@ -140,19 +140,19 @@ void CpuGBVI::quinticSpline( RealOpenMM x, RealOpenMM rl, RealOpenMM ru, --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornRadiiUsingQuinticSpline( RealOpenMM atomicRadius3, RealOpenMM bornSum, - GBVIParameters* gbviParameters, - RealOpenMM* bornRadius, RealOpenMM* switchDeriviative ){ +void CpuGBVI::computeBornRadiiUsingQuinticSpline(RealOpenMM atomicRadius3, RealOpenMM bornSum, + GBVIParameters* gbviParameters, + RealOpenMM* bornRadius, RealOpenMM* switchDeriviative) { // --------------------------------------------------------------------------------------- - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM minusOne = static_cast( -1.0 ); - static const RealOpenMM minusThree = static_cast( -3.0 ); - static const RealOpenMM oneEighth = static_cast( 0.125 ); - static const RealOpenMM minusOneThird = static_cast( (-1.0/3.0) ); - static const RealOpenMM three = static_cast( 3.0 ); + static const RealOpenMM zero = static_cast( 0.0); + static const RealOpenMM one = static_cast( 1.0); + static const RealOpenMM minusOne = static_cast(-1.0); + static const RealOpenMM minusThree = static_cast(-3.0); + static const RealOpenMM oneEighth = static_cast( 0.125); + static const RealOpenMM minusOneThird = static_cast((-1.0/3.0)); + static const RealOpenMM three = static_cast( 3.0); // --------------------------------------------------------------------------------------- @@ -176,10 +176,10 @@ void CpuGBVI::computeBornRadiiUsingQuinticSpline( RealOpenMM atomicRadius3, Real RealOpenMM splineL = gbviParameters->getQuinticLowerLimitFactor()*atomicRadius3; RealOpenMM sum; - if( bornSum > splineL ){ - if( bornSum < atomicRadius3 ){ + if (bornSum > splineL) { + if (bornSum < atomicRadius3) { RealOpenMM splineValue, splineDerivative; - quinticSpline( bornSum, splineL, atomicRadius3, &splineValue, &splineDerivative ); + quinticSpline(bornSum, splineL, atomicRadius3, &splineValue, &splineDerivative); sum = (atomicRadius3 - bornSum)*splineValue + gbviParameters->getQuinticUpperBornRadiusLimit(); *switchDeriviative = splineValue - (atomicRadius3 - bornSum)*splineDerivative; } else { @@ -190,7 +190,7 @@ void CpuGBVI::computeBornRadiiUsingQuinticSpline( RealOpenMM atomicRadius3, Real sum = atomicRadius3 - bornSum; *switchDeriviative = one; } - *bornRadius = POW( sum, minusOneThird ); + *bornRadius = POW(sum, minusOneThird); } /**--------------------------------------------------------------------------------------- @@ -203,16 +203,16 @@ void CpuGBVI::computeBornRadiiUsingQuinticSpline( RealOpenMM atomicRadius3, Real --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornRadii( const vector& atomCoordinates, RealOpenMMVector& bornRadii ){ +void CpuGBVI::computeBornRadii(const vector& atomCoordinates, RealOpenMMVector& bornRadii) { // --------------------------------------------------------------------------------------- - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM minusThree = static_cast( -3.0 ); - static const RealOpenMM oneEighth = static_cast( 0.125 ); - static const RealOpenMM minusOneThird = static_cast( (-1.0/3.0) ); - static const RealOpenMM three = static_cast( 3.0 ); + static const RealOpenMM zero = static_cast(0.0); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM minusThree = static_cast(-3.0); + static const RealOpenMM oneEighth = static_cast(0.125); + static const RealOpenMM minusOneThird = static_cast((-1.0/3.0)); + static const RealOpenMM three = static_cast(3.0); // --------------------------------------------------------------------------------------- @@ -227,42 +227,42 @@ void CpuGBVI::computeBornRadii( const vector& atomCoordinates, RealOpen // calculate Born radii - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { RealOpenMM radiusI = atomicRadii[atomI]; RealOpenMM sum = zero; // sum over volumes - for( int atomJ = 0; atomJ < numberOfAtoms; atomJ++ ){ + for (int atomJ = 0; atomJ < numberOfAtoms; atomJ++) { - if( atomJ != atomI ){ + if (atomJ != atomI) { RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (_gbviParameters->getPeriodic()) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR); else - ReferenceForce::getDeltaR( atomCoordinates[atomI], atomCoordinates[atomJ], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomI], atomCoordinates[atomJ], deltaR); RealOpenMM r = deltaR[ReferenceForce::RIndex]; if (_gbviParameters->getUseCutoff() && r > _gbviParameters->getCutoffDistance()) continue; - sum += CpuGBVI::getVolume( r, radiusI, scaledRadii[atomJ] ); + sum += CpuGBVI::getVolume(r, radiusI, scaledRadii[atomJ]); } } - RealOpenMM atomicRadius3 = POW( radiusI, minusThree ); - if( _gbviParameters->getBornRadiusScalingMethod() != GBVIParameters::QuinticSpline ){ + RealOpenMM atomicRadius3 = POW(radiusI, minusThree); + if (_gbviParameters->getBornRadiusScalingMethod() != GBVIParameters::QuinticSpline) { sum = atomicRadius3 - sum; - bornRadii[atomI] = POW( sum, minusOneThird ); + bornRadii[atomI] = POW(sum, minusOneThird); switchDeriviatives[atomI] = one; } else { RealOpenMM bornRadius, switchDeriviative; - computeBornRadiiUsingQuinticSpline( atomicRadius3, sum, gbviParameters, - &bornRadius, &switchDeriviative ); + computeBornRadiiUsingQuinticSpline(atomicRadius3, sum, gbviParameters, + &bornRadius, &switchDeriviative); bornRadii[atomI] = bornRadius; switchDeriviatives[atomI] = switchDeriviative; } @@ -281,25 +281,25 @@ void CpuGBVI::computeBornRadii( const vector& atomCoordinates, RealOpen --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::getVolume( RealOpenMM r, RealOpenMM R, RealOpenMM S ){ +RealOpenMM CpuGBVI::getVolume(RealOpenMM r, RealOpenMM R, RealOpenMM S) { // --------------------------------------------------------------------------------------- - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM minusThree = static_cast( -3.0 ); + static const RealOpenMM zero = static_cast( 0.0); + static const RealOpenMM minusThree = static_cast(-3.0); RealOpenMM diff = (S - R); - if( FABS( diff ) < r ){ + if (FABS(diff) < r) { RealOpenMM lowerBound = (R > (r - S)) ? R : (r - S); - return (CpuGBVI::getL( r, (r + S), S ) - - CpuGBVI::getL( r, lowerBound, S )); + return (CpuGBVI::getL(r, (r + S), S) - + CpuGBVI::getL(r, lowerBound, S)); - } else if( r <= diff ){ + } else if (r <= diff) { - return CpuGBVI::getL( r, (r + S), S ) - - CpuGBVI::getL( r, (r - S), S ) + - POW( R, minusThree ); + return CpuGBVI::getL(r, (r + S), S) - + CpuGBVI::getL(r, (r - S), S) + + POW(R, minusThree); } else { return zero; @@ -318,15 +318,15 @@ RealOpenMM CpuGBVI::getVolume( RealOpenMM r, RealOpenMM R, RealOpenMM S ){ --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::getL( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ +RealOpenMM CpuGBVI::getL(RealOpenMM r, RealOpenMM x, RealOpenMM S) { // --------------------------------------------------------------------------------------- - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM threeHalves = static_cast( 1.5 ); - static const RealOpenMM third = static_cast( (1.0/3.0) ); - static const RealOpenMM fourth = static_cast( 0.25 ); - static const RealOpenMM eighth = static_cast( 0.125 ); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM threeHalves = static_cast(1.5); + static const RealOpenMM third = static_cast((1.0/3.0)); + static const RealOpenMM fourth = static_cast(0.25); + static const RealOpenMM eighth = static_cast(0.125); // --------------------------------------------------------------------------------------- @@ -338,7 +338,7 @@ RealOpenMM CpuGBVI::getL( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ RealOpenMM diff2 = (r + S)*(r - S); - return (threeHalves*xInv)*( (xInv*fourth*rInv) - (xInv2*third) + (diff2*xInv3*eighth*rInv) ); + return (threeHalves*xInv)*((xInv*fourth*rInv) - (xInv2*third) + (diff2*xInv3*eighth*rInv)); } /**--------------------------------------------------------------------------------------- @@ -353,16 +353,16 @@ RealOpenMM CpuGBVI::getL( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::dL_dr( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ +RealOpenMM CpuGBVI::dL_dr(RealOpenMM r, RealOpenMM x, RealOpenMM S) { // --------------------------------------------------------------------------------------- - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM threeHalves = static_cast( 1.5 ); - static const RealOpenMM threeEights = static_cast( 0.375 ); - static const RealOpenMM third = static_cast( (1.0/3.0) ); - static const RealOpenMM fourth = static_cast( 0.25 ); - static const RealOpenMM eighth = static_cast( 0.125 ); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM threeHalves = static_cast(1.5); + static const RealOpenMM threeEights = static_cast(0.375); + static const RealOpenMM third = static_cast((1.0/3.0)); + static const RealOpenMM fourth = static_cast(0.25); + static const RealOpenMM eighth = static_cast(0.125); // --------------------------------------------------------------------------------------- @@ -375,7 +375,7 @@ RealOpenMM CpuGBVI::dL_dr( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ RealOpenMM diff2 = (r + S)*(r - S); - return ( (-threeHalves*xInv2*rInv2)*( fourth + eighth*diff2*xInv2 ) + threeEights*xInv3*xInv ); + return ((-threeHalves*xInv2*rInv2)*(fourth + eighth*diff2*xInv2) + threeEights*xInv3*xInv); } /**--------------------------------------------------------------------------------------- @@ -390,14 +390,14 @@ RealOpenMM CpuGBVI::dL_dr( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::dL_dx( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ +RealOpenMM CpuGBVI::dL_dx(RealOpenMM r, RealOpenMM x, RealOpenMM S) { // --------------------------------------------------------------------------------------- - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM half = static_cast( 0.5 ); - static const RealOpenMM threeHalvesM = static_cast( -1.5 ); - static const RealOpenMM third = static_cast( (1.0/3.0) ); + static const RealOpenMM one = static_cast( 1.0); + static const RealOpenMM half = static_cast( 0.5); + static const RealOpenMM threeHalvesM = static_cast(-1.5); + static const RealOpenMM third = static_cast( (1.0/3.0)); // --------------------------------------------------------------------------------------- @@ -409,7 +409,7 @@ RealOpenMM CpuGBVI::dL_dx( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ RealOpenMM diff = (r + S)*(r - S); - return (threeHalvesM*xInv3)*( (half*rInv) - xInv + (half*diff*xInv2*rInv) ); + return (threeHalvesM*xInv3)*((half*rInv) - xInv + (half*diff*xInv2*rInv)); } /**--------------------------------------------------------------------------------------- @@ -422,19 +422,19 @@ RealOpenMM CpuGBVI::dL_dx( RealOpenMM r, RealOpenMM x, RealOpenMM S ){ --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::Sgb( RealOpenMM t ){ +RealOpenMM CpuGBVI::Sgb(RealOpenMM t) { // --------------------------------------------------------------------------------------- // static const char* methodName = "CpuGBVI::Sgb"; - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM fourth = static_cast( 0.25 ); + static const RealOpenMM zero = static_cast(0.0); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM fourth = static_cast(0.25); // --------------------------------------------------------------------------------------- - return ( (t != zero) ? one/SQRT( (one + (fourth*EXP( -t ))/t) ) : zero); + return ((t != zero) ? one/SQRT((one + (fourth*EXP(-t))/t)) : zero); } /**--------------------------------------------------------------------------------------- @@ -448,18 +448,18 @@ RealOpenMM CpuGBVI::Sgb( RealOpenMM t ){ --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::computeBornEnergy( const vector& atomCoordinates, const RealOpenMMVector& partialCharges ){ +RealOpenMM CpuGBVI::computeBornEnergy(const vector& atomCoordinates, const RealOpenMMVector& partialCharges) { // --------------------------------------------------------------------------------------- - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM two = static_cast( 2.0 ); - static const RealOpenMM three = static_cast( 3.0 ); - static const RealOpenMM four = static_cast( 4.0 ); - static const RealOpenMM half = static_cast( 0.5 ); - static const RealOpenMM fourth = static_cast( 0.25 ); - static const RealOpenMM eighth = static_cast( 0.125 ); + static const RealOpenMM zero = static_cast(0.0); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM two = static_cast(2.0); + static const RealOpenMM three = static_cast(3.0); + static const RealOpenMM four = static_cast(4.0); + static const RealOpenMM half = static_cast(0.5); + static const RealOpenMM fourth = static_cast(0.25); + static const RealOpenMM eighth = static_cast(0.125); // --------------------------------------------------------------------------------------- @@ -471,8 +471,8 @@ RealOpenMM CpuGBVI::computeBornEnergy( const vector& atomCoordinates, c // compute Born radii - RealOpenMMVector bornRadii( numberOfAtoms ); - computeBornRadii( atomCoordinates, bornRadii ); + RealOpenMMVector bornRadii(numberOfAtoms); + computeBornRadii(atomCoordinates, bornRadii); // --------------------------------------------------------------------------------------- @@ -483,7 +483,7 @@ RealOpenMM CpuGBVI::computeBornEnergy( const vector& atomCoordinates, c RealOpenMM energy = zero; RealOpenMM cavityEnergy = zero; - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { RealOpenMM partialChargeI = partialCharges[atomI]; @@ -496,19 +496,19 @@ RealOpenMM CpuGBVI::computeBornEnergy( const vector& atomCoordinates, c RealOpenMM ratio = (atomicRadii[atomI]/bornRadii[atomI]); cavityEnergy += gammaParameters[atomI]*ratio*ratio*ratio; - for( int atomJ = atomI + 1; atomJ < numberOfAtoms; atomJ++ ){ + for (int atomJ = atomI + 1; atomJ < numberOfAtoms; atomJ++) { RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (_gbviParameters->getPeriodic()) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR); else - ReferenceForce::getDeltaR( atomCoordinates[atomI], atomCoordinates[atomJ], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomI], atomCoordinates[atomJ], deltaR); if (_gbviParameters->getUseCutoff() && deltaR[ReferenceForce::RIndex] > _gbviParameters->getCutoffDistance()) continue; RealOpenMM r2 = deltaR[ReferenceForce::R2Index]; RealOpenMM t = fourth*r2/(bornRadii[atomI]*bornRadii[atomJ]); - atomIEnergy += partialCharges[atomJ]*Sgb( t )/deltaR[ReferenceForce::RIndex]; + atomIEnergy += partialCharges[atomJ]*Sgb(t)/deltaR[ReferenceForce::RIndex]; } energy += two*partialChargeI*atomIEnergy; @@ -532,20 +532,20 @@ RealOpenMM CpuGBVI::computeBornEnergy( const vector& atomCoordinates, c --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, - std::vector& inputForces){ +void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, + std::vector& inputForces) { // --------------------------------------------------------------------------------------- - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM two = static_cast( 2.0 ); - static const RealOpenMM three = static_cast( 3.0 ); - static const RealOpenMM four = static_cast( 4.0 ); - static const RealOpenMM half = static_cast( 0.5 ); - static const RealOpenMM oneThird = static_cast( (1.0/3.0) ); - static const RealOpenMM fourth = static_cast( 0.25 ); - static const RealOpenMM eighth = static_cast( 0.125 ); + static const RealOpenMM zero = static_cast(0.0); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM two = static_cast(2.0); + static const RealOpenMM three = static_cast(3.0); + static const RealOpenMM four = static_cast(4.0); + static const RealOpenMM half = static_cast(0.5); + static const RealOpenMM oneThird = static_cast((1.0/3.0)); + static const RealOpenMM fourth = static_cast(0.25); + static const RealOpenMM eighth = static_cast(0.125); // --------------------------------------------------------------------------------------- @@ -564,37 +564,37 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re // compute Born radii - RealOpenMMVector bornRadii( numberOfAtoms ); - computeBornRadii( atomCoordinates, bornRadii ); + RealOpenMMVector bornRadii(numberOfAtoms); + computeBornRadii(atomCoordinates, bornRadii); // set energy/forces to zero - std::vector forces( numberOfAtoms ); - for( int ii = 0; ii < numberOfAtoms; ii++ ){ + std::vector forces(numberOfAtoms); + for (int ii = 0; ii < numberOfAtoms; ii++) { forces[ii][0] = zero; forces[ii][1] = zero; forces[ii][2] = zero; } - RealOpenMMVector bornForces( numberOfAtoms, 0.0); + RealOpenMMVector bornForces(numberOfAtoms, 0.0); // --------------------------------------------------------------------------------------- // first main loop - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { // partial of polar term wrt Born radius // and (dGpol/dr)(dr/dx) RealOpenMM partialChargeI = preFactor*partialCharges[atomI]; - for( int atomJ = atomI; atomJ < numberOfAtoms; atomJ++ ){ + for (int atomJ = atomI; atomJ < numberOfAtoms; atomJ++) { RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (_gbviParameters->getPeriodic()) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR); else - ReferenceForce::getDeltaR( atomCoordinates[atomI], atomCoordinates[atomJ], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomI], atomCoordinates[atomJ], deltaR); if (_gbviParameters->getUseCutoff() && deltaR[ReferenceForce::RIndex] > _gbviParameters->getCutoffDistance()) continue; @@ -607,16 +607,16 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re RealOpenMM alpha2_ij = bornRadii[atomI]*bornRadii[atomJ]; RealOpenMM D_ij = r2/(four*alpha2_ij); - RealOpenMM expTerm = EXP( -D_ij ); + RealOpenMM expTerm = EXP(-D_ij); RealOpenMM denominator2 = r2 + alpha2_ij*expTerm; - RealOpenMM denominator = SQRT( denominator2 ); + RealOpenMM denominator = SQRT(denominator2); RealOpenMM Gpol = (partialChargeI*partialCharges[atomJ])/denominator; - RealOpenMM dGpol_dr = -Gpol*( one - fourth*expTerm )/denominator2; + RealOpenMM dGpol_dr = -Gpol*(one - fourth*expTerm)/denominator2; - RealOpenMM dGpol_dalpha2_ij = -half*Gpol*expTerm*( one + D_ij )/denominator2; + RealOpenMM dGpol_dalpha2_ij = -half*Gpol*expTerm*(one + D_ij)/denominator2; - if( atomI != atomJ ){ + if (atomI != atomJ) { bornForces[atomJ] += dGpol_dalpha2_ij*bornRadii[atomI]; @@ -647,7 +647,7 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re const RealOpenMMVector& scaledRadii = gbviParameters->getScaledRadii(); const RealOpenMMVector& switchDeriviative = getSwitchDeriviative(); - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { RealOpenMM R = atomicRadii[atomI]; @@ -659,9 +659,9 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re RealOpenMM b2 = bornRadii[atomI]*bornRadii[atomI]; bornForces[atomI] *= switchDeriviative[atomI]*oneThird*b2*b2; - for( int atomJ = 0; atomJ < numberOfAtoms; atomJ++ ){ + for (int atomJ = 0; atomJ < numberOfAtoms; atomJ++) { - if( atomJ != atomI ){ + if (atomJ != atomI) { RealOpenMM deltaX = atomCoordinates[atomJ][0] - atomCoordinates[atomI][0]; RealOpenMM deltaY = atomCoordinates[atomJ][1] - atomCoordinates[atomI][1]; @@ -669,9 +669,9 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (_gbviParameters->getPeriodic()) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atomI], atomCoordinates[atomJ], _gbviParameters->getPeriodicBox(), deltaR); else - ReferenceForce::getDeltaR( atomCoordinates[atomI], atomCoordinates[atomJ], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomI], atomCoordinates[atomJ], deltaR); if (_gbviParameters->getUseCutoff() && deltaR[ReferenceForce::RIndex] > _gbviParameters->getCutoffDistance()) continue; @@ -680,7 +680,7 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re deltaY = deltaR[ReferenceForce::YIndex]; deltaZ = deltaR[ReferenceForce::ZIndex]; - RealOpenMM r = SQRT( r2 ); + RealOpenMM r = SQRT(r2); RealOpenMM S = scaledRadii[atomJ]; RealOpenMM diff = (S - R); @@ -689,16 +689,16 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re // find dRb/dr, where Rb is the Born radius - if( FABS( diff ) < r ){ - de = CpuGBVI::dL_dr( r, r+S, S ) + CpuGBVI::dL_dx( r, r+S, S ); - if( R > (r - S) ){ - de -= CpuGBVI::dL_dr( r, R, S ); + if (FABS(diff) < r) { + de = CpuGBVI::dL_dr(r, r+S, S) + CpuGBVI::dL_dx(r, r+S, S); + if (R > (r - S)) { + de -= CpuGBVI::dL_dr(r, R, S); } else { - de -= ( CpuGBVI::dL_dr( r, (r-S), S ) + CpuGBVI::dL_dx( r, (r-S), S ) ); + de -= (CpuGBVI::dL_dr(r, (r-S), S) + CpuGBVI::dL_dx(r, (r-S), S)); } - } else if( r < (S - R) ){ - de = CpuGBVI::dL_dr( r, r+S, S ) + CpuGBVI::dL_dx( r, r+S, S ); - de -= ( CpuGBVI::dL_dr( r, r-S, S ) + CpuGBVI::dL_dx( r, r-S, S ) ); + } else if (r < (S - R)) { + de = CpuGBVI::dL_dr(r, r+S, S) + CpuGBVI::dL_dx(r, r+S, S); + de -= (CpuGBVI::dL_dr(r, r-S, S) + CpuGBVI::dL_dx(r, r-S, S)); } // de = (dG/dRb)(dRb/dr) @@ -721,12 +721,12 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re } } - //printGbvi( atomCoordinates, partialCharges, bornRadii, bornForces, forces, "GBVI: Post loop2", stderr ); + //printGbvi(atomCoordinates, partialCharges, bornRadii, bornForces, forces, "GBVI: Post loop2", stderr); // convert from cal to Joule & apply prefactor tau = (1/diel_solute - 1/diel_solvent) RealOpenMM conversion = static_cast(gbviParameters->getTau()); - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { inputForces[atomI][0] += conversion*forces[atomI][0]; inputForces[atomI][1] += conversion*forces[atomI][1]; inputForces[atomI][2] += conversion*forces[atomI][2]; @@ -748,11 +748,11 @@ void CpuGBVI::computeBornForces( std::vector& atomCoordinates, const Re --------------------------------------------------------------------------------------- */ -void CpuGBVI::printGbvi( const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log ){ +void CpuGBVI::printGbvi(const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, + const RealOpenMMVector& bornRadii, + const RealOpenMMVector& bornForces, + const std::vector& forces, + const std::string& idString, FILE* log) { // --------------------------------------------------------------------------------------- @@ -775,45 +775,45 @@ void CpuGBVI::printGbvi( const std::vector& atomCoordinates, co int useComparisonFormat = 1; - (void) fprintf( log, "Reference Gbvi %s atoms=%d\n", idString.c_str(), numberOfAtoms ); - (void) fprintf( log, " tau %15.7e\n", tau ); - (void) fprintf( log, " scaleMethod %d (QuinticEnum=%d)\n", - _gbviParameters->getBornRadiusScalingMethod(), GBVIParameters::QuinticSpline ); - (void) fprintf( log, " preFactor %15.7e)\n", preFactor ); + (void) fprintf(log, "Reference Gbvi %s atoms=%d\n", idString.c_str(), numberOfAtoms); + (void) fprintf(log, " tau %15.7e\n", tau); + (void) fprintf(log, " scaleMethod %d (QuinticEnum=%d)\n", + _gbviParameters->getBornRadiusScalingMethod(), GBVIParameters::QuinticSpline); + (void) fprintf(log, " preFactor %15.7e)\n", preFactor); - if( useComparisonFormat ){ - (void) fprintf( log, " br bF swd r scR tau*gamma q)\n" ); - for( unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++ ){ - (void) fprintf( log, "%6d ", atomI ); - if( bornRadii.size() > atomI ){ - (void) fprintf( log, "%15.7e ", bornRadii[atomI] ); + if (useComparisonFormat) { + (void) fprintf(log, " br bF swd r scR tau*gamma q)\n"); + for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { + (void) fprintf(log, "%6d ", atomI); + if (bornRadii.size() > atomI) { + (void) fprintf(log, "%15.7e ", bornRadii[atomI]); } - if( bornForces.size() > atomI ){ - (void) fprintf( log, "%15.7e ", tau*bornForces[atomI] ); + if (bornForces.size() > atomI) { + (void) fprintf(log, "%15.7e ", tau*bornForces[atomI]); } - (void) fprintf( log, " %15.7e %15.7e %15.7e %15.7e %15.7e", + (void) fprintf(log, " %15.7e %15.7e %15.7e %15.7e %15.7e", switchDeriviative[atomI], atomicRadii[atomI], scaledRadii[atomI], tau*gammaParameters[atomI], - partialCharges[atomI] ); - (void) fprintf( log, "\n" ); + partialCharges[atomI]); + (void) fprintf(log, "\n"); } } else { - for( unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++ ){ - (void) fprintf( log, "%6d r=%15.7e rSc=%15.7e swd=%15.7e tau*gam=%15.7e q=%15.7e", atomI, + for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { + (void) fprintf(log, "%6d r=%15.7e rSc=%15.7e swd=%15.7e tau*gam=%15.7e q=%15.7e", atomI, atomicRadii[atomI], scaledRadii[atomI], switchDeriviative[atomI], tau*gammaParameters[atomI], - partialCharges[atomI] ); - if( bornRadii.size() > atomI ){ - (void) fprintf( log, " bR=%15.7e", bornRadii[atomI] ); + partialCharges[atomI]); + if (bornRadii.size() > atomI) { + (void) fprintf(log, " bR=%15.7e", bornRadii[atomI]); } - if( bornForces.size() > atomI ){ - (void) fprintf( log, " tau*bF=%15.7e", tau*bornForces[atomI] ); + if (bornForces.size() > atomI) { + (void) fprintf(log, " tau*bF=%15.7e", tau*bornForces[atomI]); } - (void) fprintf( log, "\n" ); + (void) fprintf(log, "\n"); } } @@ -835,7 +835,7 @@ void CpuGBVI::printGbvi( const std::vector& atomCoordinates, co --------------------------------------------------------------------------------------- */ -double CpuGBVI::getVolumeD( double r, double R, double S ){ +double CpuGBVI::getVolumeD(double r, double R, double S) { // --------------------------------------------------------------------------------------- @@ -843,18 +843,18 @@ double CpuGBVI::getVolumeD( double r, double R, double S ){ static const double minusThree = -3.0; double diff = (S - R); - if( fabs( diff ) < r ){ + if (fabs(diff) < r) { double lowerBound = (R > (r - S)) ? R : (r - S); - return (CpuGBVI::getLD( r, (r + S), S ) - - CpuGBVI::getLD( r, lowerBound, S )); + return (CpuGBVI::getLD(r, (r + S), S) - + CpuGBVI::getLD(r, lowerBound, S)); - } else if( r < diff ){ + } else if (r < diff) { - return CpuGBVI::getLD( r, (r + S), S ) - - CpuGBVI::getLD( r, (r - S), S ) + - pow( R, minusThree ); + return CpuGBVI::getLD(r, (r + S), S) - + CpuGBVI::getLD(r, (r - S), S) + + pow(R, minusThree); } else { return zero; @@ -875,7 +875,7 @@ double CpuGBVI::getVolumeD( double r, double R, double S ){ --------------------------------------------------------------------------------------- */ -double CpuGBVI::getLD( double r, double x, double S ){ +double CpuGBVI::getLD(double r, double x, double S) { // --------------------------------------------------------------------------------------- @@ -895,7 +895,7 @@ double CpuGBVI::getLD( double r, double x, double S ){ double diff2 = (r + S)*(r - S); - return (threeHalves*xInv)*( (xInv*fourth*rInv) - (xInv2*third) + (diff2*xInv3*eighth*rInv) ); + return (threeHalves*xInv)*((xInv*fourth*rInv) - (xInv2*third) + (diff2*xInv3*eighth*rInv)); } /**--------------------------------------------------------------------------------------- @@ -912,7 +912,7 @@ double CpuGBVI::getLD( double r, double x, double S ){ --------------------------------------------------------------------------------------- */ -double CpuGBVI::dL_drD( double r, double x, double S ){ +double CpuGBVI::dL_drD(double r, double x, double S) { // --------------------------------------------------------------------------------------- @@ -934,7 +934,7 @@ double CpuGBVI::dL_drD( double r, double x, double S ){ double diff2 = (r + S)*(r - S); - return ( (-threeHalves*xInv2*rInv2)*( fourth + eighth*diff2*xInv2 ) + threeEights*xInv3*xInv ); + return ((-threeHalves*xInv2*rInv2)*(fourth + eighth*diff2*xInv2) + threeEights*xInv3*xInv); } /**--------------------------------------------------------------------------------------- @@ -951,7 +951,7 @@ double CpuGBVI::dL_drD( double r, double x, double S ){ --------------------------------------------------------------------------------------- */ -double CpuGBVI::dL_dxD( double r, double x, double S ){ +double CpuGBVI::dL_dxD(double r, double x, double S) { // --------------------------------------------------------------------------------------- @@ -970,5 +970,5 @@ double CpuGBVI::dL_dxD( double r, double x, double S ){ double diff = (r + S)*(r - S); - return (threeHalvesM*xInv3)*( (half*rInv) - xInv + (half*diff*xInv2*rInv) ); + return (threeHalvesM*xInv3)*((half*rInv) - xInv + (half*diff*xInv2*rInv)); } diff --git a/platforms/reference/src/gbsa/CpuObc.cpp b/platforms/reference/src/gbsa/CpuObc.cpp index 04e83688a..be6297695 100644 --- a/platforms/reference/src/gbsa/CpuObc.cpp +++ b/platforms/reference/src/gbsa/CpuObc.cpp @@ -43,7 +43,7 @@ using namespace std; --------------------------------------------------------------------------------------- */ -CpuObc::CpuObc( ObcParameters* obcParameters ) : _obcParameters(obcParameters), _includeAceApproximation(1) { +CpuObc::CpuObc(ObcParameters* obcParameters) : _obcParameters(obcParameters), _includeAceApproximation(1) { _obcChain.resize(_obcParameters->getNumberOfAtoms()); } @@ -53,7 +53,7 @@ CpuObc::CpuObc( ObcParameters* obcParameters ) : _obcParameters(obcParameters), --------------------------------------------------------------------------------------- */ -CpuObc::~CpuObc( ){ +CpuObc::~CpuObc() { } /**--------------------------------------------------------------------------------------- @@ -64,7 +64,7 @@ CpuObc::~CpuObc( ){ --------------------------------------------------------------------------------------- */ -ObcParameters* CpuObc::getObcParameters( void ) const { +ObcParameters* CpuObc::getObcParameters() const { return _obcParameters; } @@ -76,7 +76,7 @@ ObcParameters* CpuObc::getObcParameters( void ) const { --------------------------------------------------------------------------------------- */ -void CpuObc::setObcParameters( ObcParameters* obcParameters ){ +void CpuObc::setObcParameters( ObcParameters* obcParameters) { _obcParameters = obcParameters; } @@ -88,7 +88,7 @@ void CpuObc::setObcParameters( ObcParameters* obcParameters ){ --------------------------------------------------------------------------------------- */ -int CpuObc::includeAceApproximation( void ) const { +int CpuObc::includeAceApproximation() const { return _includeAceApproximation; } @@ -100,7 +100,7 @@ int CpuObc::includeAceApproximation( void ) const { --------------------------------------------------------------------------------------- */ -void CpuObc::setIncludeAceApproximation( int includeAceApproximation ){ +void CpuObc::setIncludeAceApproximation(int includeAceApproximation) { _includeAceApproximation = includeAceApproximation; } @@ -112,7 +112,7 @@ void CpuObc::setIncludeAceApproximation( int includeAceApproximation ){ --------------------------------------------------------------------------------------- */ -vector& CpuObc::getObcChain( void ){ +vector& CpuObc::getObcChain() { return _obcChain; } @@ -128,16 +128,16 @@ vector& CpuObc::getObcChain( void ){ --------------------------------------------------------------------------------------- */ -void CpuObc::computeBornRadii( const vector& atomCoordinates, vector& bornRadii ){ +void CpuObc::computeBornRadii(const vector& atomCoordinates, vector& bornRadii) { // --------------------------------------------------------------------------------------- - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM two = static_cast( 2.0 ); - static const RealOpenMM three = static_cast( 3.0 ); - static const RealOpenMM half = static_cast( 0.5 ); - static const RealOpenMM fourth = static_cast( 0.25 ); + static const RealOpenMM zero = static_cast(0.0); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM two = static_cast(2.0); + static const RealOpenMM three = static_cast(3.0); + static const RealOpenMM half = static_cast(0.5); + static const RealOpenMM fourth = static_cast(0.25); // --------------------------------------------------------------------------------------- @@ -157,7 +157,7 @@ void CpuObc::computeBornRadii( const vector& atomCoordinates, vector& atomCoordinates, vectorgetPeriodic()) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[atomI], atomCoordinates[atomJ], _obcParameters->getPeriodicBox(), deltaR ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atomI], atomCoordinates[atomJ], _obcParameters->getPeriodicBox(), deltaR); else - ReferenceForce::getDeltaR( atomCoordinates[atomI], atomCoordinates[atomJ], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomI], atomCoordinates[atomJ], deltaR); RealOpenMM r = deltaR[ReferenceForce::RIndex]; if (_obcParameters->getUseCutoff() && r > _obcParameters->getCutoffDistance()) continue; @@ -184,9 +184,9 @@ void CpuObc::computeBornRadii( const vector& atomCoordinates, vector FABS( r - scaledRadiusJ ) ? offsetRadiusI : FABS( r - scaledRadiusJ ); + RealOpenMM l_ij = offsetRadiusI > FABS(r - scaledRadiusJ) ? offsetRadiusI : FABS(r - scaledRadiusJ); l_ij = one/l_ij; RealOpenMM u_ij = one/rScaledRadiusJ; @@ -194,15 +194,15 @@ void CpuObc::computeBornRadii( const vector& atomCoordinates, vector& atomCoordinates, vector& atomCoordinates, vector( 0.0 ); + static const RealOpenMM zero = static_cast(0.0); static const RealOpenMM minusSix = -6.0; - static const RealOpenMM six = static_cast( 6.0 ); + static const RealOpenMM six = static_cast(6.0); // --------------------------------------------------------------------------------------- @@ -271,10 +271,10 @@ void CpuObc::computeAceNonPolarForce( const ObcParameters* obcParameters, // observed values. He did not think it was important enough to write up, so there is // no paper to cite. - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ - if( bornRadii[atomI] > zero ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { + if (bornRadii[atomI] > zero) { RealOpenMM r = atomicRadii[atomI] + probeRadius; - RealOpenMM ratio6 = POW( atomicRadii[atomI]/bornRadii[atomI], six ); + RealOpenMM ratio6 = POW(atomicRadii[atomI]/bornRadii[atomI], six); RealOpenMM saTerm = surfaceAreaFactor*r*r*ratio6; *energy += saTerm; forces[atomI] += minusSix*saTerm/bornRadii[atomI]; @@ -294,19 +294,19 @@ void CpuObc::computeAceNonPolarForce( const ObcParameters* obcParameters, --------------------------------------------------------------------------------------- */ -RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinates, - const RealOpenMMVector& partialCharges, vector& inputForces ){ +RealOpenMM CpuObc::computeBornEnergyForces(const vector& atomCoordinates, + const RealOpenMMVector& partialCharges, vector& inputForces) { // --------------------------------------------------------------------------------------- - static const RealOpenMM zero = static_cast( 0.0 ); - static const RealOpenMM one = static_cast( 1.0 ); - static const RealOpenMM two = static_cast( 2.0 ); - static const RealOpenMM three = static_cast( 3.0 ); - static const RealOpenMM four = static_cast( 4.0 ); - static const RealOpenMM half = static_cast( 0.5 ); - static const RealOpenMM fourth = static_cast( 0.25 ); - static const RealOpenMM eighth = static_cast( 0.125 ); + static const RealOpenMM zero = static_cast(0.0); + static const RealOpenMM one = static_cast(1.0); + static const RealOpenMM two = static_cast(2.0); + static const RealOpenMM three = static_cast(3.0); + static const RealOpenMM four = static_cast(4.0); + static const RealOpenMM half = static_cast(0.5); + static const RealOpenMM fourth = static_cast(0.25); + static const RealOpenMM eighth = static_cast(0.125); // constants @@ -325,36 +325,36 @@ RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinat // compute Born radii - RealOpenMMVector bornRadii( numberOfAtoms ); - computeBornRadii( atomCoordinates, bornRadii ); + RealOpenMMVector bornRadii(numberOfAtoms); + computeBornRadii(atomCoordinates, bornRadii); // set energy/forces to zero RealOpenMM obcEnergy = zero; - RealOpenMMVector bornForces( numberOfAtoms, 0.0 ); + RealOpenMMVector bornForces(numberOfAtoms, 0.0); // --------------------------------------------------------------------------------------- // compute the nonpolar solvation via ACE approximation - if( includeAceApproximation() ){ - computeAceNonPolarForce( _obcParameters, bornRadii, &obcEnergy, bornForces ); + if (includeAceApproximation()) { + computeAceNonPolarForce(_obcParameters, bornRadii, &obcEnergy, bornForces); } // --------------------------------------------------------------------------------------- // first main loop - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { RealOpenMM partialChargeI = preFactor*partialCharges[atomI]; - for( int atomJ = atomI; atomJ < numberOfAtoms; atomJ++ ){ + for (int atomJ = atomI; atomJ < numberOfAtoms; atomJ++) { RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (_obcParameters->getPeriodic()) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[atomI], atomCoordinates[atomJ], _obcParameters->getPeriodicBox(), deltaR ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atomI], atomCoordinates[atomJ], _obcParameters->getPeriodicBox(), deltaR); else - ReferenceForce::getDeltaR( atomCoordinates[atomI], atomCoordinates[atomJ], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomI], atomCoordinates[atomJ], deltaR); if (_obcParameters->getUseCutoff() && deltaR[ReferenceForce::RIndex] > cutoffDistance) continue; @@ -366,18 +366,18 @@ RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinat RealOpenMM alpha2_ij = bornRadii[atomI]*bornRadii[atomJ]; RealOpenMM D_ij = r2/(four*alpha2_ij); - RealOpenMM expTerm = EXP( -D_ij ); + RealOpenMM expTerm = EXP(-D_ij); RealOpenMM denominator2 = r2 + alpha2_ij*expTerm; - RealOpenMM denominator = SQRT( denominator2 ); + RealOpenMM denominator = SQRT(denominator2); RealOpenMM Gpol = (partialChargeI*partialCharges[atomJ])/denominator; - RealOpenMM dGpol_dr = -Gpol*( one - fourth*expTerm )/denominator2; + RealOpenMM dGpol_dr = -Gpol*(one - fourth*expTerm)/denominator2; - RealOpenMM dGpol_dalpha2_ij = -half*Gpol*expTerm*( one + D_ij )/denominator2; + RealOpenMM dGpol_dalpha2_ij = -half*Gpol*expTerm*(one + D_ij)/denominator2; RealOpenMM energy = Gpol; - if( atomI != atomJ ){ + if (atomI != atomJ) { if (_obcParameters->getUseCutoff()) energy -= partialChargeI*partialCharges[atomJ]/cutoffDistance; @@ -420,26 +420,26 @@ RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinat // compute factor that depends only on the outer loop index - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { bornForces[atomI] *= bornRadii[atomI]*bornRadii[atomI]*obcChain[atomI]; } - for( int atomI = 0; atomI < numberOfAtoms; atomI++ ){ + for (int atomI = 0; atomI < numberOfAtoms; atomI++) { // radius w/ dielectric offset applied RealOpenMM radiusI = atomicRadii[atomI]; RealOpenMM offsetRadiusI = radiusI - dielectricOffset; - for( int atomJ = 0; atomJ < numberOfAtoms; atomJ++ ){ + for (int atomJ = 0; atomJ < numberOfAtoms; atomJ++) { - if( atomJ != atomI ){ + if (atomJ != atomI) { RealOpenMM deltaR[ReferenceForce::LastDeltaRIndex]; if (_obcParameters->getPeriodic()) - ReferenceForce::getDeltaRPeriodic( atomCoordinates[atomI], atomCoordinates[atomJ], _obcParameters->getPeriodicBox(), deltaR ); + ReferenceForce::getDeltaRPeriodic(atomCoordinates[atomI], atomCoordinates[atomJ], _obcParameters->getPeriodicBox(), deltaR); else - ReferenceForce::getDeltaR( atomCoordinates[atomI], atomCoordinates[atomJ], deltaR ); + ReferenceForce::getDeltaR(atomCoordinates[atomI], atomCoordinates[atomJ], deltaR); if (_obcParameters->getUseCutoff() && deltaR[ReferenceForce::RIndex] > cutoffDistance) continue; @@ -459,9 +459,9 @@ RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinat // dL/dr & dU/dr are zero (this can be shown analytically) // removed from calculation - if( offsetRadiusI < rScaledRadiusJ ){ + if (offsetRadiusI < rScaledRadiusJ) { - RealOpenMM l_ij = offsetRadiusI > FABS( r - scaledRadiusJ ) ? offsetRadiusI : FABS( r - scaledRadiusJ ); + RealOpenMM l_ij = offsetRadiusI > FABS(r - scaledRadiusJ) ? offsetRadiusI : FABS(r - scaledRadiusJ); l_ij = one/l_ij; RealOpenMM u_ij = one/rScaledRadiusJ; @@ -473,7 +473,7 @@ RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinat RealOpenMM rInverse = one/r; RealOpenMM r2Inverse = rInverse*rInverse; - RealOpenMM t3 = eighth*(one + scaledRadiusJ2*r2Inverse)*(l_ij2 - u_ij2) + fourth*LN( u_ij/l_ij )*r2Inverse; + RealOpenMM t3 = eighth*(one + scaledRadiusJ2*r2Inverse)*(l_ij2 - u_ij2) + fourth*LN(u_ij/l_ij)*r2Inverse; RealOpenMM de = bornForces[atomI]*t3*rInverse; @@ -495,7 +495,7 @@ RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinat } - //printObc( atomCoordinates, partialCharges, bornRadii, bornForces, inputForces, "Obc Post loop2", stderr ); + //printObc(atomCoordinates, partialCharges, bornRadii, bornForces, inputForces, "Obc Post loop2", stderr); return obcEnergy; } @@ -514,12 +514,12 @@ RealOpenMM CpuObc::computeBornEnergyForces( const vector& atomCoordinat --------------------------------------------------------------------------------------- */ -void CpuObc::printObc( const std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log ){ +void CpuObc::printObc(const std::vector& atomCoordinates, + const RealOpenMMVector& partialCharges, + const RealOpenMMVector& bornRadii, + const RealOpenMMVector& bornForces, + const std::vector& forces, + const std::string& idString, FILE* log) { // --------------------------------------------------------------------------------------- @@ -538,43 +538,43 @@ void CpuObc::printObc( const std::vector& atomCoordinates, // --------------------------------------------------------------------------------------- - (void) fprintf( log, "Reference Obc %s atoms=%d\n", idString.c_str(), numberOfAtoms ); - if( comparisonFormat ){ - (void) fprintf( log, "Reference Obc %s atoms=%d Chain/Radii/Force\n", idString.c_str(), numberOfAtoms ); - for( unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++ ){ - (void) fprintf( log, "%6d ", atomI ); - if( obcChain.size() > atomI ){ - (void) fprintf( log, " %15.7e", obcChain[atomI] ); + (void) fprintf(log, "Reference Obc %s atoms=%d\n", idString.c_str(), numberOfAtoms); + if (comparisonFormat) { + (void) fprintf(log, "Reference Obc %s atoms=%d Chain/Radii/Force\n", idString.c_str(), numberOfAtoms); + for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { + (void) fprintf(log, "%6d ", atomI); + if (obcChain.size() > atomI) { + (void) fprintf(log, " %15.7e", obcChain[atomI]); } - if( bornRadii.size() > atomI ){ - (void) fprintf( log, " %15.7e", bornRadii[atomI] ); + if (bornRadii.size() > atomI) { + (void) fprintf(log, " %15.7e", bornRadii[atomI]); } - if( bornForces.size() > atomI ){ - (void) fprintf( log, " %15.7e", bornForces[atomI] ); + if (bornForces.size() > atomI) { + (void) fprintf(log, " %15.7e", bornForces[atomI]); } - (void) fprintf( log, " %15.7e %6.3f", atomicRadii[atomI], partialCharges[atomI] ); - (void) fprintf( log, "\n" ); + (void) fprintf(log, " %15.7e %6.3f", atomicRadii[atomI], partialCharges[atomI]); + (void) fprintf(log, "\n"); } } else { - (void) fprintf( log, "Reference Obc %s atoms=%d\n", idString.c_str(), numberOfAtoms ); - (void) fprintf( log, " preFactor %15.7e\n", preFactor ); - (void) fprintf( log, " alpha %15.7e\n", alphaObc); - (void) fprintf( log, " beta %15.7e\n", betaObc); - (void) fprintf( log, " gamma %15.7e\n", gammaObc ); + (void) fprintf(log, "Reference Obc %s atoms=%d\n", idString.c_str(), numberOfAtoms); + (void) fprintf(log, " preFactor %15.7e\n", preFactor); + (void) fprintf(log, " alpha %15.7e\n", alphaObc); + (void) fprintf(log, " beta %15.7e\n", betaObc); + (void) fprintf(log, " gamma %15.7e\n", gammaObc); - for( unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++ ){ - (void) fprintf( log, "%6d r=%15.7e q=%6.3f", atomI, - atomicRadii[atomI], partialCharges[atomI] ); - if( obcChain.size() > atomI ){ - (void) fprintf( log, " bChn=%15.7e", obcChain[atomI] ); + for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { + (void) fprintf(log, "%6d r=%15.7e q=%6.3f", atomI, + atomicRadii[atomI], partialCharges[atomI]); + if (obcChain.size() > atomI) { + (void) fprintf(log, " bChn=%15.7e", obcChain[atomI]); } - if( bornRadii.size() > atomI ){ - (void) fprintf( log, " bR=%15.7e", bornRadii[atomI] ); + if (bornRadii.size() > atomI) { + (void) fprintf(log, " bR=%15.7e", bornRadii[atomI]); } - if( bornForces.size() > atomI ){ - (void) fprintf( log, " bF=%15.7e", bornForces[atomI] ); + if (bornForces.size() > atomI) { + (void) fprintf(log, " bF=%15.7e", bornForces[atomI]); } - (void) fprintf( log, "\n" ); + (void) fprintf(log, "\n"); } } diff --git a/platforms/reference/src/gbsa/GBVIParameters.cpp b/platforms/reference/src/gbsa/GBVIParameters.cpp index c7cfd2809..4b5745e8a 100644 --- a/platforms/reference/src/gbsa/GBVIParameters.cpp +++ b/platforms/reference/src/gbsa/GBVIParameters.cpp @@ -41,19 +41,19 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -GBVIParameters::GBVIParameters( int numberOfAtoms ) : _numberOfAtoms(numberOfAtoms), - _soluteDielectric(1.0), - _solventDielectric(78.3), - _electricConstant(-0.5*ONE_4PI_EPS0), - _cutoff(false), - _periodic(false), - _bornRadiusScalingMethod(0), - _quinticLowerLimitFactor(0.8), - _quinticUpperBornRadiusLimit(5.0) { - - _atomicRadii.resize( numberOfAtoms ); - _scaledRadii.resize( numberOfAtoms ); - _gammaParameters.resize( numberOfAtoms ); +GBVIParameters::GBVIParameters(int numberOfAtoms) : _numberOfAtoms(numberOfAtoms), + _soluteDielectric(1.0), + _solventDielectric(78.3), + _electricConstant(-0.5*ONE_4PI_EPS0), + _cutoff(false), + _periodic(false), + _bornRadiusScalingMethod(0), + _quinticLowerLimitFactor(0.8), + _quinticUpperBornRadiusLimit(5.0) { + + _atomicRadii.resize(numberOfAtoms); + _scaledRadii.resize(numberOfAtoms); + _gammaParameters.resize(numberOfAtoms); } @@ -63,7 +63,7 @@ GBVIParameters::GBVIParameters( int numberOfAtoms ) : _numberOfAtoms(numberOfAto --------------------------------------------------------------------------------------- */ -GBVIParameters::~GBVIParameters( ){ +GBVIParameters::~GBVIParameters() { } /**--------------------------------------------------------------------------------------- @@ -74,7 +74,7 @@ GBVIParameters::~GBVIParameters( ){ --------------------------------------------------------------------------------------- */ -int GBVIParameters::getNumberOfAtoms( void ) const { +int GBVIParameters::getNumberOfAtoms() const { return _numberOfAtoms; } @@ -86,7 +86,7 @@ int GBVIParameters::getNumberOfAtoms( void ) const { --------------------------------------------------------------------------------------- */ -RealOpenMM GBVIParameters::getElectricConstant( void ) const { +RealOpenMM GBVIParameters::getElectricConstant() const { return _electricConstant; } @@ -98,7 +98,7 @@ RealOpenMM GBVIParameters::getElectricConstant( void ) const { --------------------------------------------------------------------------------------- */ -RealOpenMM GBVIParameters::getSolventDielectric( void ) const { +RealOpenMM GBVIParameters::getSolventDielectric() const { return _solventDielectric; } @@ -110,7 +110,7 @@ RealOpenMM GBVIParameters::getSolventDielectric( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setSolventDielectric( RealOpenMM solventDielectric ){ +void GBVIParameters::setSolventDielectric(RealOpenMM solventDielectric) { _solventDielectric = solventDielectric; } @@ -122,7 +122,7 @@ void GBVIParameters::setSolventDielectric( RealOpenMM solventDielectric ){ --------------------------------------------------------------------------------------- */ -RealOpenMM GBVIParameters::getSoluteDielectric( void ) const { +RealOpenMM GBVIParameters::getSoluteDielectric() const { return _soluteDielectric; } @@ -134,7 +134,7 @@ RealOpenMM GBVIParameters::getSoluteDielectric( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setSoluteDielectric( RealOpenMM soluteDielectric ){ +void GBVIParameters::setSoluteDielectric(RealOpenMM soluteDielectric) { _soluteDielectric = soluteDielectric; } @@ -146,7 +146,7 @@ void GBVIParameters::setSoluteDielectric( RealOpenMM soluteDielectric ){ --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& GBVIParameters::getAtomicRadii( void ) const { +const RealOpenMMVector& GBVIParameters::getAtomicRadii() const { return _atomicRadii; } @@ -158,10 +158,10 @@ const RealOpenMMVector& GBVIParameters::getAtomicRadii( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setAtomicRadii( const RealOpenMMVector& atomicRadii ){ +void GBVIParameters::setAtomicRadii(const RealOpenMMVector& atomicRadii) { - if( atomicRadii.size() == _atomicRadii.size() ){ - for( unsigned int ii = 0; ii < atomicRadii.size(); ii++ ){ + if (atomicRadii.size() == _atomicRadii.size()) { + for (unsigned int ii = 0; ii < atomicRadii.size(); ii++) { _atomicRadii[ii] = atomicRadii[ii]; } } else { @@ -181,7 +181,7 @@ void GBVIParameters::setAtomicRadii( const RealOpenMMVector& atomicRadii ){ --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& GBVIParameters::getScaledRadii( void ) const { +const RealOpenMMVector& GBVIParameters::getScaledRadii() const { return _scaledRadii; } @@ -193,10 +193,10 @@ const RealOpenMMVector& GBVIParameters::getScaledRadii( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setScaledRadii( const RealOpenMMVector& scaledRadii ){ +void GBVIParameters::setScaledRadii(const RealOpenMMVector& scaledRadii) { - if( scaledRadii.size() == _scaledRadii.size() ){ - for( unsigned int ii = 0; ii < scaledRadii.size(); ii++ ){ + if (scaledRadii.size() == _scaledRadii.size()) { + for (unsigned int ii = 0; ii < scaledRadii.size(); ii++) { _scaledRadii[ii] = scaledRadii[ii]; } } else { @@ -218,7 +218,7 @@ void GBVIParameters::setScaledRadii( const RealOpenMMVector& scaledRadii ){ --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& GBVIParameters::getGammaParameters( void ) const { +const RealOpenMMVector& GBVIParameters::getGammaParameters() const { return _gammaParameters; } @@ -230,10 +230,10 @@ const RealOpenMMVector& GBVIParameters::getGammaParameters( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setGammaParameters( const RealOpenMMVector& gammas ){ +void GBVIParameters::setGammaParameters(const RealOpenMMVector& gammas) { - if( gammas.size() == _gammaParameters.size() ){ - for( unsigned int ii = 0; ii < gammas.size(); ii++ ){ + if (gammas.size() == _gammaParameters.size()) { + for (unsigned int ii = 0; ii < gammas.size(); ii++) { _gammaParameters[ii] = gammas[ii]; } } else { @@ -254,7 +254,7 @@ void GBVIParameters::setGammaParameters( const RealOpenMMVector& gammas ){ --------------------------------------------------------------------------------------- */ -void GBVIParameters::setUseCutoff( RealOpenMM distance ) { +void GBVIParameters::setUseCutoff(RealOpenMM distance) { _cutoff = true; _cutoffDistance = distance; @@ -330,7 +330,7 @@ const OpenMM::RealVec* GBVIParameters::getPeriodicBox() { --------------------------------------------------------------------------------------- */ -RealOpenMM GBVIParameters::getTau( void ) const { +RealOpenMM GBVIParameters::getTau() const { // --------------------------------------------------------------------------------------- @@ -340,7 +340,7 @@ RealOpenMM GBVIParameters::getTau( void ) const { // --------------------------------------------------------------------------------------- RealOpenMM tau; - if( getSoluteDielectric() != zero && getSolventDielectric() != zero ){ + if (getSoluteDielectric() != zero && getSolventDielectric() != zero) { tau = (one/getSoluteDielectric()) - (one/getSolventDielectric()); } else { tau = zero; @@ -357,7 +357,7 @@ RealOpenMM GBVIParameters::getTau( void ) const { --------------------------------------------------------------------------------------- */ -int GBVIParameters::getBornRadiusScalingMethod( void ) const { +int GBVIParameters::getBornRadiusScalingMethod() const { return _bornRadiusScalingMethod; } @@ -369,7 +369,7 @@ int GBVIParameters::getBornRadiusScalingMethod( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setBornRadiusScalingMethod( int bornRadiusScalingMethod ){ +void GBVIParameters::setBornRadiusScalingMethod(int bornRadiusScalingMethod) { _bornRadiusScalingMethod = bornRadiusScalingMethod; } @@ -381,7 +381,7 @@ void GBVIParameters::setBornRadiusScalingMethod( int bornRadiusScalingMethod ){ --------------------------------------------------------------------------------------- */ -RealOpenMM GBVIParameters::getQuinticLowerLimitFactor( void ) const { +RealOpenMM GBVIParameters::getQuinticLowerLimitFactor() const { return _quinticLowerLimitFactor; } @@ -393,7 +393,7 @@ RealOpenMM GBVIParameters::getQuinticLowerLimitFactor( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setQuinticLowerLimitFactor( RealOpenMM quinticLowerLimitFactor ){ +void GBVIParameters::setQuinticLowerLimitFactor(RealOpenMM quinticLowerLimitFactor) { _quinticLowerLimitFactor = quinticLowerLimitFactor; } @@ -405,7 +405,7 @@ void GBVIParameters::setQuinticLowerLimitFactor( RealOpenMM quinticLowerLimitFac --------------------------------------------------------------------------------------- */ -RealOpenMM GBVIParameters::getQuinticUpperBornRadiusLimit( void ) const { +RealOpenMM GBVIParameters::getQuinticUpperBornRadiusLimit() const { return _quinticUpperBornRadiusLimit; } @@ -417,6 +417,6 @@ RealOpenMM GBVIParameters::getQuinticUpperBornRadiusLimit( void ) const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setQuinticUpperBornRadiusLimit( RealOpenMM quinticUpperBornRadiusLimit ){ +void GBVIParameters::setQuinticUpperBornRadiusLimit(RealOpenMM quinticUpperBornRadiusLimit) { _quinticUpperBornRadiusLimit = quinticUpperBornRadiusLimit; } diff --git a/platforms/reference/src/gbsa/ObcParameters.cpp b/platforms/reference/src/gbsa/ObcParameters.cpp index e1521cdde..cf19af020 100644 --- a/platforms/reference/src/gbsa/ObcParameters.cpp +++ b/platforms/reference/src/gbsa/ObcParameters.cpp @@ -42,21 +42,21 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -ObcParameters::ObcParameters( int numberOfAtoms, ObcParameters::ObcType obcType ) : - _numberOfAtoms(numberOfAtoms), - _solventDielectric( 78.3 ), - _soluteDielectric( 1.0 ), - _electricConstant(-0.5*ONE_4PI_EPS0), - _probeRadius(0.14), - _pi4Asolv( 28.3919551), - _dielectricOffset( 0.009 ), - _obcType( obcType ), - _cutoff(false), - _periodic(false) { - - _atomicRadii.resize( numberOfAtoms ); - _scaledRadiusFactors.resize( numberOfAtoms ); - setObcTypeParameters( obcType ); +ObcParameters::ObcParameters(int numberOfAtoms, ObcParameters::ObcType obcType) : + _numberOfAtoms(numberOfAtoms), + _solventDielectric(78.3), + _soluteDielectric(1.0), + _electricConstant(-0.5*ONE_4PI_EPS0), + _probeRadius(0.14), + _pi4Asolv(28.3919551), + _dielectricOffset(0.009), + _obcType(obcType), + _cutoff(false), + _periodic(false) { + + _atomicRadii.resize(numberOfAtoms); + _scaledRadiusFactors.resize(numberOfAtoms); + setObcTypeParameters(obcType); } @@ -66,7 +66,7 @@ ObcParameters::ObcParameters( int numberOfAtoms, ObcParameters::ObcType obcType --------------------------------------------------------------------------------------- */ -ObcParameters::~ObcParameters( ){ +ObcParameters::~ObcParameters() { } /**--------------------------------------------------------------------------------------- @@ -77,7 +77,7 @@ ObcParameters::~ObcParameters( ){ --------------------------------------------------------------------------------------- */ -int ObcParameters::getNumberOfAtoms( void ) const { +int ObcParameters::getNumberOfAtoms() const { return _numberOfAtoms; } @@ -89,7 +89,7 @@ int ObcParameters::getNumberOfAtoms( void ) const { --------------------------------------------------------------------------------------- */ -ObcParameters::ObcType ObcParameters::getObcType( void ) const { +ObcParameters::ObcType ObcParameters::getObcType() const { return _obcType; } @@ -101,8 +101,8 @@ ObcParameters::ObcType ObcParameters::getObcType( void ) const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setObcTypeParameters( ObcParameters::ObcType obcType ){ - if( obcType == ObcTypeI ){ +void ObcParameters::setObcTypeParameters(ObcParameters::ObcType obcType) { + if (obcType == ObcTypeI) { _alphaObc = 0.8f; _betaObc = 0.0f; _gammaObc = 2.91f; @@ -122,7 +122,7 @@ void ObcParameters::setObcTypeParameters( ObcParameters::ObcType obcType ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getDielectricOffset( void ) const { +RealOpenMM ObcParameters::getDielectricOffset() const { return _dielectricOffset; } @@ -134,7 +134,7 @@ RealOpenMM ObcParameters::getDielectricOffset( void ) const { --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getAlphaObc( void ) const { +RealOpenMM ObcParameters::getAlphaObc() const { return _alphaObc; } @@ -146,7 +146,7 @@ RealOpenMM ObcParameters::getAlphaObc( void ) const { --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getBetaObc( void ) const { +RealOpenMM ObcParameters::getBetaObc() const { return _betaObc; } @@ -158,7 +158,7 @@ RealOpenMM ObcParameters::getBetaObc( void ) const { --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getGammaObc( void ) const { +RealOpenMM ObcParameters::getGammaObc() const { return _gammaObc; } @@ -170,7 +170,7 @@ RealOpenMM ObcParameters::getGammaObc( void ) const { --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getSolventDielectric( void ) const { +RealOpenMM ObcParameters::getSolventDielectric() const { return _solventDielectric; } @@ -182,7 +182,7 @@ RealOpenMM ObcParameters::getSolventDielectric( void ) const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setSolventDielectric( RealOpenMM solventDielectric ){ +void ObcParameters::setSolventDielectric(RealOpenMM solventDielectric) { _solventDielectric = solventDielectric; } /**--------------------------------------------------------------------------------------- @@ -193,7 +193,7 @@ void ObcParameters::setSolventDielectric( RealOpenMM solventDielectric ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getSoluteDielectric( void ) const { +RealOpenMM ObcParameters::getSoluteDielectric() const { return _soluteDielectric; } @@ -205,7 +205,7 @@ RealOpenMM ObcParameters::getSoluteDielectric( void ) const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setSoluteDielectric( RealOpenMM soluteDielectric ){ +void ObcParameters::setSoluteDielectric(RealOpenMM soluteDielectric) { _soluteDielectric = soluteDielectric; } @@ -217,7 +217,7 @@ void ObcParameters::setSoluteDielectric( RealOpenMM soluteDielectric ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getElectricConstant( void ) const { +RealOpenMM ObcParameters::getElectricConstant() const { return _electricConstant; } @@ -229,7 +229,7 @@ RealOpenMM ObcParameters::getElectricConstant( void ) const { --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getProbeRadius( void ) const { +RealOpenMM ObcParameters::getProbeRadius() const { return _probeRadius; } @@ -241,7 +241,7 @@ RealOpenMM ObcParameters::getProbeRadius( void ) const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setProbeRadius( RealOpenMM probeRadius ){ +void ObcParameters::setProbeRadius(RealOpenMM probeRadius) { _probeRadius = probeRadius; } @@ -255,7 +255,7 @@ void ObcParameters::setProbeRadius( RealOpenMM probeRadius ){ --------------------------------------------------------------------------------------- */ -RealOpenMM ObcParameters::getPi4Asolv( void ) const { +RealOpenMM ObcParameters::getPi4Asolv() const { return _pi4Asolv; } @@ -271,7 +271,7 @@ void ObcParameters::setPi4Asolv(RealOpenMM pi4Asolv) { --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& ObcParameters::getAtomicRadii( void ) const { +const RealOpenMMVector& ObcParameters::getAtomicRadii() const { return _atomicRadii; } @@ -283,10 +283,10 @@ const RealOpenMMVector& ObcParameters::getAtomicRadii( void ) const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setAtomicRadii( const RealOpenMMVector& atomicRadii ){ +void ObcParameters::setAtomicRadii(const RealOpenMMVector& atomicRadii) { - if( atomicRadii.size() == _atomicRadii.size() ){ - for( unsigned int ii = 0; ii < atomicRadii.size(); ii++ ){ + if (atomicRadii.size() == _atomicRadii.size()) { + for (unsigned int ii = 0; ii < atomicRadii.size(); ii++) { _atomicRadii[ii] = atomicRadii[ii]; } } else { @@ -307,7 +307,7 @@ void ObcParameters::setAtomicRadii( const RealOpenMMVector& atomicRadii ){ --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& ObcParameters::getScaledRadiusFactors( void ) const { +const RealOpenMMVector& ObcParameters::getScaledRadiusFactors() const { return _scaledRadiusFactors; } @@ -319,10 +319,10 @@ const RealOpenMMVector& ObcParameters::getScaledRadiusFactors( void ) const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setScaledRadiusFactors( const RealOpenMMVector& scaledRadiusFactors ){ +void ObcParameters::setScaledRadiusFactors(const RealOpenMMVector& scaledRadiusFactors) { - if( scaledRadiusFactors.size() == _scaledRadiusFactors.size() ){ - for( unsigned int ii = 0; ii < scaledRadiusFactors.size(); ii++ ){ + if (scaledRadiusFactors.size() == _scaledRadiusFactors.size()) { + for (unsigned int ii = 0; ii < scaledRadiusFactors.size(); ii++) { _scaledRadiusFactors[ii] = scaledRadiusFactors[ii]; } } else { @@ -343,7 +343,7 @@ void ObcParameters::setScaledRadiusFactors( const RealOpenMMVector& scaledRadius --------------------------------------------------------------------------------------- */ -void ObcParameters::setUseCutoff( RealOpenMM distance ) { +void ObcParameters::setUseCutoff(RealOpenMM distance) { _cutoff = true; _cutoffDistance = distance; diff --git a/platforms/reference/tests/TestReferenceCustomGBForce.cpp b/platforms/reference/tests/TestReferenceCustomGBForce.cpp index 44f04d9bc..b8b4130fe 100644 --- a/platforms/reference/tests/TestReferenceCustomGBForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomGBForce.cpp @@ -473,7 +473,7 @@ void testExclusions() { // create custom GB/VI force -static CustomGBForce* createCustomGBVI( double solventDielectric, double soluteDielectric ) { +static CustomGBForce* createCustomGBVI(double solventDielectric, double soluteDielectric) { CustomGBForce* customGbviForce = new CustomGBForce(); @@ -524,7 +524,7 @@ static CustomGBForce* createCustomGBVI( double solventDielectric, double soluteD // ethance GB/VI test case -static void buildEthane( GBVIForce* gbviForce, std::vector& positions ) { +static void buildEthane(GBVIForce* gbviForce, std::vector& positions) { const int numParticles = 8; @@ -535,7 +535,7 @@ static void buildEthane( GBVIForce* gbviForce, std::vector& positions ) { int AM1_BCC = 1; H_charge = -0.053; C_charge = -3.0*H_charge; - if( AM1_BCC ){ + if (AM1_BCC) { C_radius = 0.180; C_gamma = -0.2863; H_radius = 0.125; @@ -548,43 +548,43 @@ static void buildEthane( GBVIForce* gbviForce, std::vector& positions ) { H_gamma = 0.1237; } - for( int i = 0; i < numParticles; i++ ){ - gbviForce->addParticle( H_charge, H_radius, H_gamma); + for (int i = 0; i < numParticles; i++) { + gbviForce->addParticle(H_charge, H_radius, H_gamma); } - gbviForce->setParticleParameters( 1, C_charge, C_radius, C_gamma); - gbviForce->setParticleParameters( 4, C_charge, C_radius, C_gamma); + gbviForce->setParticleParameters(1, C_charge, C_radius, C_gamma); + gbviForce->setParticleParameters(4, C_charge, C_radius, C_gamma); - gbviForce->addBond( 0, 1, C_HBondDistance ); - gbviForce->addBond( 2, 1, C_HBondDistance ); - gbviForce->addBond( 3, 1, C_HBondDistance ); - gbviForce->addBond( 1, 4, C_CBondDistance ); - gbviForce->addBond( 5, 4, C_HBondDistance ); - gbviForce->addBond( 6, 4, C_HBondDistance ); - gbviForce->addBond( 7, 4, C_HBondDistance ); + gbviForce->addBond(0, 1, C_HBondDistance); + gbviForce->addBond(2, 1, C_HBondDistance); + gbviForce->addBond(3, 1, C_HBondDistance); + gbviForce->addBond(1, 4, C_CBondDistance); + gbviForce->addBond(5, 4, C_HBondDistance); + gbviForce->addBond(6, 4, C_HBondDistance); + gbviForce->addBond(7, 4, C_HBondDistance); std::vector > bondExceptions; std::vector bondDistances; bondExceptions.push_back(pair(0, 1)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(2, 1)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(3, 1)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(1, 4)); - bondDistances.push_back( C_CBondDistance ); + bondDistances.push_back(C_CBondDistance); bondExceptions.push_back(pair(5, 4)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(6, 4)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(7, 4)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); positions.resize(numParticles); positions[0] = Vec3(0.5480, 1.7661, 0.0000); @@ -600,7 +600,7 @@ static void buildEthane( GBVIForce* gbviForce, std::vector& positions ) { // dimer GB/VI test case -static void buildDimer( GBVIForce* gbviForce, std::vector& positions ) { +static void buildDimer(GBVIForce* gbviForce, std::vector& positions) { const int numParticles = 2; @@ -614,7 +614,7 @@ static void buildDimer( GBVIForce* gbviForce, std::vector& positions ) { H_charge = 0.0; C_charge = 0.0; - if( AM1_BCC ){ + if (AM1_BCC) { C_radius = 0.180; C_gamma = -0.2863; H_radius = 0.125; @@ -627,17 +627,17 @@ static void buildDimer( GBVIForce* gbviForce, std::vector& positions ) { H_gamma = 0.1237; } - for( int i = 0; i < numParticles; i++ ){ - gbviForce->addParticle( H_charge, H_radius, H_gamma); + for (int i = 0; i < numParticles; i++) { + gbviForce->addParticle(H_charge, H_radius, H_gamma); } - gbviForce->setParticleParameters( 1, C_charge, C_radius, C_gamma); + gbviForce->setParticleParameters(1, C_charge, C_radius, C_gamma); - gbviForce->addBond( 0, 1, C_HBondDistance ); + gbviForce->addBond(0, 1, C_HBondDistance); std::vector > bondExceptions; std::vector bondDistances; bondExceptions.push_back(pair(0, 1)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); positions.resize(numParticles); positions[0] = Vec3(0.0, 0.0, 0.0); @@ -646,7 +646,7 @@ static void buildDimer( GBVIForce* gbviForce, std::vector& positions ) { // monomer GB/VI test case -static void buildMonomer( GBVIForce* gbviForce, std::vector& positions ) { +static void buildMonomer(GBVIForce* gbviForce, std::vector& positions) { const int numParticles = 1; @@ -656,8 +656,8 @@ static void buildMonomer( GBVIForce* gbviForce, std::vector& positions ) { H_radius = 0.125; H_gamma = 0.2437; - for( int i = 0; i < numParticles; i++ ){ - gbviForce->addParticle( H_charge, H_radius, H_gamma); + for (int i = 0; i < numParticles; i++) { + gbviForce->addParticle(H_charge, H_radius, H_gamma); } positions.resize(numParticles); positions[0] = Vec3(0.0, 0.0, 0.0); @@ -666,7 +666,7 @@ static void buildMonomer( GBVIForce* gbviForce, std::vector& positions ) { // taken from gbviForceImpl class // computes the scaled radii based on covalent info and atomic radii -static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledRadii) { +static void findScaledRadii(GBVIForce& gbviForce, std::vector & scaledRadii) { int numberOfParticles = gbviForce.getNumParticles(); int numberOfBonds = gbviForce.getNumBonds(); @@ -674,15 +674,15 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR // load 1-2 atom pairs along w/ bond distance using HarmonicBondForce & constraints // numberOfBonds < 1, indicating they were not set by the user - if( numberOfBonds < 1 && numberOfParticles > 1 ){ - (void) fprintf( stderr, "Warning: no covalent bonds set for GB/VI force!\n" ); + if (numberOfBonds < 1 && numberOfParticles > 1) { + (void) fprintf(stderr, "Warning: no covalent bonds set for GB/VI force!\n"); } std::vector< std::vector > bondIndices; - bondIndices.resize( numberOfBonds ); + bondIndices.resize(numberOfBonds); std::vector bondLengths; - bondLengths.resize( numberOfBonds ); + bondLengths.resize(numberOfBonds); scaledRadii.resize(numberOfParticles); for (int i = 0; i < numberOfParticles; i++) { @@ -707,14 +707,14 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR msg << particle2; throw OpenMMException(msg.str()); } - if (bondLength < 0 ) { + if (bondLength < 0) { std::stringstream msg; msg << "GBVISoftcoreForce: negative bondlength: "; msg << bondLength; throw OpenMMException(msg.str()); } - bondIndices[i].push_back( particle1 ); - bondIndices[i].push_back( particle2 ); + bondIndices[i].push_back(particle1); + bondIndices[i].push_back(particle2); bondLengths[i] = bondLength; } @@ -732,7 +732,7 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR // compute scaled radii (Eq. 5 of Labute paper [JCC 29 p. 1693-1698 2008]) - for (int j = 0; j < (int) bonded12.size(); ++j){ + for (int j = 0; j < (int) bonded12.size(); ++j) { double charge; double gamma; @@ -741,9 +741,9 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR gbviForce.getParticleParameters(j, charge, radiusJ, gamma); - if( bonded12[j].size() == 0 ){ - if( numberOfParticles > 1 ){ - (void) fprintf( stderr, "Warning GBVIForceImpl::findScaledRadii atom %d has no covalent bonds; using atomic radius=%.3f.\n", j, radiusJ ); + if ( bonded12[j].size() == 0) { + if (numberOfParticles > 1) { + (void) fprintf(stderr, "Warning GBVIForceImpl::findScaledRadii atom %d has no covalent bonds; using atomic radius=%.3f.\n", j, radiusJ); } scaledRadiusJ = radiusJ; // errors++; @@ -755,7 +755,7 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR // loop over bonded neighbors of atom j, applying Eq. 5 in Labute scaledRadiusJ = 0.0; - for (int i = 0; i < (int) bonded12[j].size(); ++i){ + for (int i = 0; i < (int) bonded12[j].size(); ++i) { int index = bonded12[j][i]; int bondedAtomIndex = (j == bondIndices[index][0]) ? bondIndices[index][1] : bondIndices[index][0]; @@ -772,32 +772,32 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR a_ji *= a_ji; a_ji = (rI2 - a_ji)/(2.0*bondLengths[index]); - scaledRadiusJ += a_ij*a_ij*(3.0*radiusI - a_ij) + a_ji*a_ji*( 3.0*radiusJ - a_ji ); + scaledRadiusJ += a_ij*a_ij*(3.0*radiusI - a_ij) + a_ji*a_ji*(3.0*radiusJ - a_ji); } scaledRadiusJ = (radiusJ*radiusJ*radiusJ) - 0.125*scaledRadiusJ; - if( scaledRadiusJ > 0.0 ){ - scaledRadiusJ = 0.95*pow( scaledRadiusJ, (1.0/3.0) ); + if (scaledRadiusJ > 0.0) { + scaledRadiusJ = 0.95*pow(scaledRadiusJ, (1.0/3.0)); } else { scaledRadiusJ = 0.0; } } - //(void) fprintf( stderr, "scaledRadii %d %12.4f\n", j, scaledRadiusJ ); + //(void) fprintf(stderr, "scaledRadii %d %12.4f\n", j, scaledRadiusJ); scaledRadii[j] = scaledRadiusJ; } // abort if errors - if( errors ){ + if (errors) { throw OpenMMException("GBVIForceImpl::findScaledRadii errors -- aborting"); } #if GBVIDebug - (void) fprintf( stderr, " R q gamma scaled radii no. bnds\n" ); + (void) fprintf(stderr, " R q gamma scaled radii no. bnds\n"); double totalQ = 0.0; - for( int i = 0; i < (int) scaledRadii.size(); i++ ){ + for (int i = 0; i < (int) scaledRadii.size(); i++) { double charge; double gamma; @@ -805,10 +805,10 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR gbviForce.getParticleParameters(i, charge, radiusI, gamma); totalQ += charge; - (void) fprintf( stderr, "%4d %14.5e %14.5e %14.5e %14.5e %d\n", i, radiusI, charge, gamma, scaledRadii[i], (int) bonded12[i].size() ); + (void) fprintf(stderr, "%4d %14.5e %14.5e %14.5e %14.5e %d\n", i, radiusI, charge, gamma, scaledRadii[i], (int) bonded12[i].size()); } - (void) fprintf( stderr, "Total charge=%e\n", totalQ ); - (void) fflush( stderr ); + (void) fprintf(stderr, "Total charge=%e\n", totalQ); + (void) fflush(stderr); #endif #undef GBVIDebug @@ -819,7 +819,7 @@ static void findScaledRadii( GBVIForce& gbviForce, std::vector & scaledR // findScaledRadii() is called to calculate the scaled radii (S) // S is derived quantity in GBVIForce, not a parameter is the case here -static void loadGbviParameters( GBVIForce* gbviForce, CustomGBForce* customGbviForce ) { +static void loadGbviParameters(GBVIForce* gbviForce, CustomGBForce* customGbviForce) { int numParticles = gbviForce->getNumParticles(); @@ -827,11 +827,11 @@ static void loadGbviParameters( GBVIForce* gbviForce, CustomGBForce* customGbviF vector params(4); std::vector scaledRadii; - findScaledRadii( *gbviForce, scaledRadii); + findScaledRadii(*gbviForce, scaledRadii); - for( int ii = 0; ii < numParticles; ii++) { + for (int ii = 0; ii < numParticles; ii++) { double charge, radius, gamma; - gbviForce->getParticleParameters( ii, charge, radius, gamma ); + gbviForce->getParticleParameters(ii, charge, radius, gamma); params[0] = charge; params[1] = radius; params[2] = scaledRadii[ii]; @@ -852,14 +852,14 @@ void testGBVI(GBVIForce::NonbondedMethod gbviMethod, CustomGBForce::NonbondedMet // select molecule - if( molecule == "Monomer" ){ - buildMonomer( gbvi, positions ); + if (molecule == "Monomer") { + buildMonomer(gbvi, positions); } - else if( molecule == "Dimer" ){ - buildDimer( gbvi, positions ); + else if (molecule == "Dimer") { + buildDimer(gbvi, positions); } else { - buildEthane( gbvi, positions ); + buildEthane(gbvi, positions); } int numParticles = gbvi->getNumParticles(); @@ -875,12 +875,12 @@ void testGBVI(GBVIForce::NonbondedMethod gbviMethod, CustomGBForce::NonbondedMet // create customGbviForce GBVI force - CustomGBForce* customGbviForce = createCustomGBVI( gbvi->getSolventDielectric(), gbvi->getSoluteDielectric() ); + CustomGBForce* customGbviForce = createCustomGBVI(gbvi->getSolventDielectric(), gbvi->getSoluteDielectric()); customGbviForce->setCutoffDistance(2.0); // load parameters from gbvi to customGbviForce - loadGbviParameters( gbvi, customGbviForce ); + loadGbviParameters(gbvi, customGbviForce); OpenMM_SFMT::SFMT sfmt; init_gen_rand(0, sfmt); diff --git a/platforms/reference/tests/TestReferenceGBVIForce.cpp b/platforms/reference/tests/TestReferenceGBVIForce.cpp index 485ad2ac0..d926980e3 100644 --- a/platforms/reference/tests/TestReferenceGBVIForce.cpp +++ b/platforms/reference/tests/TestReferenceGBVIForce.cpp @@ -80,20 +80,20 @@ void testSingleParticle() { double tau = (1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric()); double bornEnergy = (-charge*charge/(8*PI_M*eps0))*tau/bornRadius; - double nonpolarEnergy = -gamma*tau*std::pow( radius/bornRadius, 3.0); + double nonpolarEnergy = -gamma*tau*std::pow(radius/bornRadius, 3.0); double expectedE = (bornEnergy+nonpolarEnergy); double obtainedE = state.getPotentialEnergy(); - double diff = fabs( (obtainedE - expectedE)/expectedE ); - if( log ){ - (void) fprintf( stderr, "testSingleParticle expected=%14.6e obtained=%14.6e diff=%14.6e breakdown:[%14.6e %14.6e]\n", - expectedE, obtainedE, diff, bornEnergy, nonpolarEnergy ); + double diff = fabs((obtainedE - expectedE)/expectedE); + if (log) { + (void) fprintf(stderr, "testSingleParticle expected=%14.6e obtained=%14.6e diff=%14.6e breakdown:[%14.6e %14.6e]\n", + expectedE, obtainedE, diff, bornEnergy, nonpolarEnergy); } ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); } -void testEnergyEthane( int applyBornRadiiScaling ) { +void testEnergyEthane(int applyBornRadiiScaling) { ReferencePlatform platform; const int numParticles = 8; @@ -123,7 +123,7 @@ void testEnergyEthane( int applyBornRadiiScaling ) { int AM1_BCC = 1; H_charge = -0.053; C_charge = -3.0*H_charge; - if( AM1_BCC ){ + if (AM1_BCC) { C_radius = 0.180; C_gamma = -0.2863; H_radius = 0.125; @@ -139,59 +139,59 @@ void testEnergyEthane( int applyBornRadiiScaling ) { NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setNonbondedMethod(NonbondedForce::NoCutoff); - if( log ){ - (void) fprintf( stderr, "Applying GB/VI\n" ); + if (log) { + (void) fprintf(stderr, "Applying GB/VI\n"); } GBVIForce* forceField = new GBVIForce(); - if( applyBornRadiiScaling ){ - forceField->setBornRadiusScalingMethod( GBVIForce::QuinticSpline ); + if (applyBornRadiiScaling) { + forceField->setBornRadiusScalingMethod(GBVIForce::QuinticSpline); } else { - forceField->setBornRadiusScalingMethod( GBVIForce::NoScaling ); + forceField->setBornRadiusScalingMethod(GBVIForce::NoScaling); } - for( int i = 0; i < numParticles; i++ ){ + for (int i = 0; i < numParticles; i++) { system.addParticle(1.0); - forceField->addParticle( H_charge, H_radius, H_gamma); - nonbonded->addParticle( H_charge, H_radius, 0.0); + forceField->addParticle(H_charge, H_radius, H_gamma); + nonbonded->addParticle( H_charge, H_radius, 0.0); } - forceField->setParticleParameters( 1, C_charge, C_radius, C_gamma); - forceField->setParticleParameters( 4, C_charge, C_radius, C_gamma); + forceField->setParticleParameters(1, C_charge, C_radius, C_gamma); + forceField->setParticleParameters(4, C_charge, C_radius, C_gamma); - nonbonded->setParticleParameters( 1, C_charge, C_radius, 0.0); - nonbonded->setParticleParameters( 4, C_charge, C_radius, 0.0); + nonbonded->setParticleParameters( 1, C_charge, C_radius, 0.0); + nonbonded->setParticleParameters( 4, C_charge, C_radius, 0.0); - forceField->addBond( 0, 1, C_HBondDistance ); - forceField->addBond( 2, 1, C_HBondDistance ); - forceField->addBond( 3, 1, C_HBondDistance ); - forceField->addBond( 1, 4, C_CBondDistance ); - forceField->addBond( 5, 4, C_HBondDistance ); - forceField->addBond( 6, 4, C_HBondDistance ); - forceField->addBond( 7, 4, C_HBondDistance ); + forceField->addBond(0, 1, C_HBondDistance); + forceField->addBond(2, 1, C_HBondDistance); + forceField->addBond(3, 1, C_HBondDistance); + forceField->addBond(1, 4, C_CBondDistance); + forceField->addBond(5, 4, C_HBondDistance); + forceField->addBond(6, 4, C_HBondDistance); + forceField->addBond(7, 4, C_HBondDistance); std::vector > bondExceptions; std::vector bondDistances; bondExceptions.push_back(pair(0, 1)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(2, 1)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(3, 1)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(1, 4)); - bondDistances.push_back( C_CBondDistance ); + bondDistances.push_back(C_CBondDistance); bondExceptions.push_back(pair(5, 4)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(6, 4)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); bondExceptions.push_back(pair(7, 4)); - bondDistances.push_back( C_HBondDistance ); + bondDistances.push_back(C_HBondDistance); nonbonded->createExceptionsFromBonds(bondExceptions, 0.0, 0.0); @@ -212,8 +212,8 @@ void testEnergyEthane( int applyBornRadiiScaling ) { context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); - if( log ){ - (void) fprintf( stderr, "Energy %.4e\n", state.getPotentialEnergy() ); + if (log) { + (void) fprintf(stderr, "Energy %.4e\n", state.getPotentialEnergy()); } // Take a small step in the direction of the energy gradient. @@ -222,8 +222,8 @@ void testEnergyEthane( int applyBornRadiiScaling ) { double forceSum[3] = { 0.0, 0.0, 0.0 }; for (int i = 0; i < numParticles; ++i) { Vec3 f = state.getForces()[i]; - if( log ){ - (void) fprintf( stderr, "F %d [%14.6e %14.6e %14.6e]\n", i, f[0], f[1], f[2] ); + if (log) { + (void) fprintf(stderr, "F %d [%14.6e %14.6e %14.6e]\n", i, f[0], f[1], f[2]); } norm += f[0]*f[0] + f[1]*f[1] + f[2]*f[2]; forceSum[0] += f[0]; @@ -231,8 +231,8 @@ void testEnergyEthane( int applyBornRadiiScaling ) { forceSum[2] += f[2]; } norm = std::sqrt(norm); - if( log ){ - (void) fprintf( stderr, "Fsum [%14.6e %14.6e %14.6e] norm=%14.6e\n", forceSum[0], forceSum[1], forceSum[2], norm ); + if (log) { + (void) fprintf(stderr, "Fsum [%14.6e %14.6e %14.6e] norm=%14.6e\n", forceSum[0], forceSum[1], forceSum[2], norm); } const double delta = 1e-4; @@ -246,10 +246,10 @@ void testEnergyEthane( int applyBornRadiiScaling ) { State state2 = context.getState(State::Energy); - if( log ){ - double deltaE = fabs( state.getPotentialEnergy() - state2.getPotentialEnergy() )/delta; + if (log) { + double deltaE = fabs(state.getPotentialEnergy() - state2.getPotentialEnergy())/delta; double diff = (deltaE - norm)/norm; - (void) fprintf( stderr, "Energies %.8e %.8e deltaE=%14.7e %14.7e diff=%14.7e\n", state.getPotentialEnergy(), state2.getPotentialEnergy(), deltaE, norm, diff ); + (void) fprintf(stderr, "Energies %.8e %.8e deltaE=%14.7e %14.7e diff=%14.7e\n", state.getPotentialEnergy(), state2.getPotentialEnergy(), deltaE, norm, diff); } // See whether the potential energy changed by the expected amount. @@ -260,8 +260,8 @@ void testEnergyEthane( int applyBornRadiiScaling ) { int main() { try { testSingleParticle(); - testEnergyEthane( 0 ); - testEnergyEthane( 1 ); + testEnergyEthane(0); + testEnergyEthane(1); } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From 0671c7b00df6624163dc3e52268ad04338a9e4d1 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 15:55:30 -0800 Subject: [PATCH 279/338] Elimininated obsolete SimTKOpenMMCommon files --- platforms/cpu/src/CpuCustomGBForce.cpp | 1 - .../cpu/src/CpuCustomManyParticleForce.cpp | 1 - platforms/cpu/src/CpuCustomNonbondedForce.cpp | 1 - platforms/cpu/src/CpuLangevinDynamics.cpp | 1 - platforms/cpu/src/CpuNonbondedForce.cpp | 1 - platforms/cpu/src/CpuNonbondedForceVec4.cpp | 1 - platforms/cpu/src/CpuNonbondedForceVec8.cpp | 1 - platforms/reference/include/CpuGBVI.h | 16 ++--- platforms/reference/include/CpuObc.h | 18 +++--- platforms/reference/include/GBVIParameters.h | 21 +++---- platforms/reference/include/ObcParameters.h | 15 ++--- .../include/ReferenceAndersenThermostat.h | 1 - .../include/ReferenceCMAPTorsionIxn.h | 1 - .../include/ReferenceConstraintAlgorithm.h | 3 +- .../reference/include/ReferenceDynamics.h | 1 - .../include/ReferenceLincsAlgorithm.h | 10 +--- .../include/ReferenceMonteCarloBarostat.h | 1 - platforms/reference/include/ReferencePME.h | 2 +- .../reference/include/ReferencePairIxn.h | 1 + .../reference/include/SimTKOpenMMCommon.h | 60 ------------------- .../reference/include/SimTKOpenMMUtilities.h | 2 +- platforms/reference/include/fftpack.h | 3 +- .../SimTKReference/ReferenceAngleBondIxn.cpp | 1 - .../src/SimTKReference/ReferenceBondForce.cpp | 1 - .../src/SimTKReference/ReferenceBondIxn.cpp | 1 - .../ReferenceBrownianDynamics.cpp | 1 - .../SimTKReference/ReferenceCCMAAlgorithm.cpp | 1 - .../ReferenceCustomAngleIxn.cpp | 1 - .../SimTKReference/ReferenceCustomBondIxn.cpp | 1 - .../ReferenceCustomCompoundBondIxn.cpp | 1 - .../ReferenceCustomDynamics.cpp | 1 - .../ReferenceCustomExternalIxn.cpp | 1 - .../SimTKReference/ReferenceCustomGBIxn.cpp | 1 - .../ReferenceCustomHbondIxn.cpp | 1 - .../ReferenceCustomManyParticleIxn.cpp | 1 - .../ReferenceCustomNonbondedIxn.cpp | 1 - .../ReferenceCustomTorsionIxn.cpp | 1 - .../src/SimTKReference/ReferenceDynamics.cpp | 1 - .../src/SimTKReference/ReferenceForce.cpp | 1 - .../ReferenceHarmonicBondIxn.cpp | 1 - .../SimTKReference/ReferenceLJCoulomb14.cpp | 1 - .../SimTKReference/ReferenceLJCoulombIxn.cpp | 1 - .../ReferenceLincsAlgorithm.cpp | 16 +---- .../src/SimTKReference/ReferencePairIxn.cpp | 1 - .../ReferenceProperDihedralBond.cpp | 1 - .../ReferenceRbDihedralBond.cpp | 1 - .../ReferenceStochasticDynamics.cpp | 1 - .../ReferenceVariableStochasticDynamics.cpp | 1 - .../ReferenceVariableVerletDynamics.cpp | 1 - .../ReferenceVerletDynamics.cpp | 1 - .../src/SimTKUtilities/SimTKOpenMMCommon.cpp | 40 ------------- platforms/reference/src/gbsa/CpuGBVI.cpp | 47 +++++++-------- platforms/reference/src/gbsa/CpuObc.cpp | 37 ++++++------ .../reference/src/gbsa/GBVIParameters.cpp | 15 +++-- .../reference/src/gbsa/ObcParameters.cpp | 9 ++- 55 files changed, 99 insertions(+), 254 deletions(-) delete mode 100644 platforms/reference/include/SimTKOpenMMCommon.h delete mode 100644 platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp diff --git a/platforms/cpu/src/CpuCustomGBForce.cpp b/platforms/cpu/src/CpuCustomGBForce.cpp index 892e20db5..ead738c61 100644 --- a/platforms/cpu/src/CpuCustomGBForce.cpp +++ b/platforms/cpu/src/CpuCustomGBForce.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "CpuCustomGBForce.h" diff --git a/platforms/cpu/src/CpuCustomManyParticleForce.cpp b/platforms/cpu/src/CpuCustomManyParticleForce.cpp index 362bbba22..c7f253624 100644 --- a/platforms/cpu/src/CpuCustomManyParticleForce.cpp +++ b/platforms/cpu/src/CpuCustomManyParticleForce.cpp @@ -26,7 +26,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "CpuCustomManyParticleForce.h" diff --git a/platforms/cpu/src/CpuCustomNonbondedForce.cpp b/platforms/cpu/src/CpuCustomNonbondedForce.cpp index 0a45d559f..71662ebdd 100644 --- a/platforms/cpu/src/CpuCustomNonbondedForce.cpp +++ b/platforms/cpu/src/CpuCustomNonbondedForce.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "CpuCustomNonbondedForce.h" diff --git a/platforms/cpu/src/CpuLangevinDynamics.cpp b/platforms/cpu/src/CpuLangevinDynamics.cpp index 59d87b4e1..576309ffc 100644 --- a/platforms/cpu/src/CpuLangevinDynamics.cpp +++ b/platforms/cpu/src/CpuLangevinDynamics.cpp @@ -23,7 +23,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "CpuLangevinDynamics.h" diff --git a/platforms/cpu/src/CpuNonbondedForce.cpp b/platforms/cpu/src/CpuNonbondedForce.cpp index 190dcf6f1..107c8da99 100644 --- a/platforms/cpu/src/CpuNonbondedForce.cpp +++ b/platforms/cpu/src/CpuNonbondedForce.cpp @@ -24,7 +24,6 @@ #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "CpuNonbondedForce.h" #include "ReferenceForce.h" diff --git a/platforms/cpu/src/CpuNonbondedForceVec4.cpp b/platforms/cpu/src/CpuNonbondedForceVec4.cpp index 789060e6e..2de909c53 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec4.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec4.cpp @@ -22,7 +22,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "CpuNonbondedForceVec4.h" diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index 15c90d44b..6567f8cc0 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -22,7 +22,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "CpuNonbondedForceVec8.h" #include "openmm/OpenMMException.h" diff --git a/platforms/reference/include/CpuGBVI.h b/platforms/reference/include/CpuGBVI.h index 1b822c12d..6ed47e156 100644 --- a/platforms/reference/include/CpuGBVI.h +++ b/platforms/reference/include/CpuGBVI.h @@ -39,7 +39,7 @@ class CpuGBVI { // GB/VI parameters GBVIParameters* _gbviParameters; - RealOpenMMVector _switchDeriviative; + std::vector _switchDeriviative; public: @@ -93,7 +93,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void computeBornRadii(const std::vector& atomCoordinates, RealOpenMMVector& bornRadii); + void computeBornRadii(const std::vector& atomCoordinates, std::vector& bornRadii); /**--------------------------------------------------------------------------------------- @@ -174,7 +174,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - RealOpenMM computeBornEnergy(const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges); + RealOpenMM computeBornEnergy(const std::vector& atomCoordinates, const std::vector& partialCharges); /**--------------------------------------------------------------------------------------- @@ -187,7 +187,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ void computeBornForces(std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, std::vector& inputForces); + const std::vector& partialCharges, std::vector& inputForces); /**--------------------------------------------------------------------------------------- @@ -254,7 +254,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - RealOpenMMVector& getSwitchDeriviative(); + std::vector& getSwitchDeriviative(); /**--------------------------------------------------------------------------------------- @@ -303,9 +303,9 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - void printGbvi(const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, + void printGbvi(const std::vector& atomCoordinates, const std::vector& partialCharges, + const std::vector& bornRadii, + const std::vector& bornForces, const std::vector& forces, const std::string& idString, FILE* log); diff --git a/platforms/reference/include/CpuObc.h b/platforms/reference/include/CpuObc.h index df9565a42..19343331b 100644 --- a/platforms/reference/include/CpuObc.h +++ b/platforms/reference/include/CpuObc.h @@ -39,7 +39,7 @@ class CpuObc { // arrays containing OBC chain derivative - RealOpenMMVector _obcChain; + std::vector _obcChain; // flag to signal whether ACE approximation // is to be included @@ -117,7 +117,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - RealOpenMMVector& getObcChain(); + std::vector& getObcChain(); /**--------------------------------------------------------------------------------------- @@ -128,7 +128,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - void computeBornRadii(const std::vector& atomCoordinates, RealOpenMMVector& bornRadii); + void computeBornRadii(const std::vector& atomCoordinates, std::vector& bornRadii); /**--------------------------------------------------------------------------------------- @@ -142,8 +142,8 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - void computeAceNonPolarForce(const ObcParameters* obcParameters, const RealOpenMMVector& bornRadii, - RealOpenMM* energy, RealOpenMMVector& forces) const; + void computeAceNonPolarForce(const ObcParameters* obcParameters, const std::vector& bornRadii, + RealOpenMM* energy, std::vector& forces) const; /**--------------------------------------------------------------------------------------- @@ -156,7 +156,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ RealOpenMM computeBornEnergyForces(const std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, std::vector& forces); + const std::vector& partialCharges, std::vector& forces); /**--------------------------------------------------------------------------------------- @@ -173,9 +173,9 @@ class CpuObc { --------------------------------------------------------------------------------------- */ void printObc(const std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, + const std::vector& partialCharges, + const std::vector& bornRadii, + const std::vector& bornForces, const std::vector& forces, const std::string& idString, FILE* log); diff --git a/platforms/reference/include/GBVIParameters.h b/platforms/reference/include/GBVIParameters.h index 54028ae25..4eb1e1e14 100644 --- a/platforms/reference/include/GBVIParameters.h +++ b/platforms/reference/include/GBVIParameters.h @@ -25,7 +25,8 @@ #ifndef __GBVIParameters_H__ #define __GBVIParameters_H__ -#include "SimTKOpenMMCommon.h" +#include "RealVec.h" +#include namespace OpenMM { @@ -57,9 +58,9 @@ class GBVIParameters { // parameter vectors - RealOpenMMVector _atomicRadii; - RealOpenMMVector _scaledRadii; - RealOpenMMVector _gammaParameters; + std::vector _atomicRadii; + std::vector _scaledRadii; + std::vector _gammaParameters; // cutoff and periodic boundary conditions @@ -160,7 +161,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getScaledRadii() const; + const std::vector& getScaledRadii() const; /**--------------------------------------------------------------------------------------- @@ -170,7 +171,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setScaledRadii(const RealOpenMMVector& scaledRadii); + void setScaledRadii(const std::vector& scaledRadii); /**--------------------------------------------------------------------------------------- @@ -180,7 +181,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getAtomicRadii() const; + const std::vector& getAtomicRadii() const; /**--------------------------------------------------------------------------------------- @@ -190,7 +191,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setAtomicRadii(const RealOpenMMVector& atomicRadii); + void setAtomicRadii(const std::vector& atomicRadii); /**--------------------------------------------------------------------------------------- @@ -200,7 +201,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getGammaParameters() const; + const std::vector& getGammaParameters() const; /**--------------------------------------------------------------------------------------- @@ -210,7 +211,7 @@ class GBVIParameters { --------------------------------------------------------------------------------------- */ - void setGammaParameters(const RealOpenMMVector& gammaParameters); + void setGammaParameters(const std::vector& gammaParameters); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ObcParameters.h b/platforms/reference/include/ObcParameters.h index 129380e80..409934b50 100644 --- a/platforms/reference/include/ObcParameters.h +++ b/platforms/reference/include/ObcParameters.h @@ -25,7 +25,8 @@ #ifndef __ObcParameters_H__ #define __ObcParameters_H__ -#include "SimTKOpenMMCommon.h" +#include "RealVec.h" +#include namespace OpenMM { @@ -57,8 +58,8 @@ class ObcParameters { // scaled radius factors (S_kk in HCT paper) - RealOpenMMVector _atomicRadii; - RealOpenMMVector _scaledRadiusFactors; + std::vector _atomicRadii; + std::vector _scaledRadiusFactors; // cutoff and periodic boundary conditions @@ -264,7 +265,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getScaledRadiusFactors() const; + const std::vector& getScaledRadiusFactors() const; /**--------------------------------------------------------------------------------------- @@ -274,7 +275,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setScaledRadiusFactors(const RealOpenMMVector& scaledRadiusFactors); + void setScaledRadiusFactors(const std::vector& scaledRadiusFactors); /**--------------------------------------------------------------------------------------- @@ -284,7 +285,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - const RealOpenMMVector& getAtomicRadii() const; + const std::vector& getAtomicRadii() const; /**--------------------------------------------------------------------------------------- @@ -294,7 +295,7 @@ class ObcParameters { --------------------------------------------------------------------------------------- */ - void setAtomicRadii(const RealOpenMMVector& atomicRadii); + void setAtomicRadii(const std::vector& atomicRadii); /**--------------------------------------------------------------------------------------- diff --git a/platforms/reference/include/ReferenceAndersenThermostat.h b/platforms/reference/include/ReferenceAndersenThermostat.h index 856d7ebb5..235234715 100644 --- a/platforms/reference/include/ReferenceAndersenThermostat.h +++ b/platforms/reference/include/ReferenceAndersenThermostat.h @@ -25,7 +25,6 @@ #ifndef __ReferenceAndersenThermostat_H__ #define __ReferenceAndersenThermostat_H__ -#include "SimTKOpenMMCommon.h" #include namespace OpenMM { diff --git a/platforms/reference/include/ReferenceCMAPTorsionIxn.h b/platforms/reference/include/ReferenceCMAPTorsionIxn.h index 23019c728..77b055e30 100644 --- a/platforms/reference/include/ReferenceCMAPTorsionIxn.h +++ b/platforms/reference/include/ReferenceCMAPTorsionIxn.h @@ -25,7 +25,6 @@ #ifndef __ReferenceCMAPTorsionIxn_H__ #define __ReferenceCMAPTorsionIxn_H__ -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceBondIxn.h" #include diff --git a/platforms/reference/include/ReferenceConstraintAlgorithm.h b/platforms/reference/include/ReferenceConstraintAlgorithm.h index e3f06875f..75036eb0f 100644 --- a/platforms/reference/include/ReferenceConstraintAlgorithm.h +++ b/platforms/reference/include/ReferenceConstraintAlgorithm.h @@ -25,8 +25,9 @@ #ifndef __ReferenceConstraintAlgorithm_H__ #define __ReferenceConstraintAlgorithm_H__ -#include "SimTKOpenMMCommon.h" +#include "RealVec.h" #include "openmm/internal/windowsExport.h" +#include namespace OpenMM { diff --git a/platforms/reference/include/ReferenceDynamics.h b/platforms/reference/include/ReferenceDynamics.h index f5ee1fb4f..ff30ebfb4 100644 --- a/platforms/reference/include/ReferenceDynamics.h +++ b/platforms/reference/include/ReferenceDynamics.h @@ -26,7 +26,6 @@ #define __ReferenceDynamics_H__ #include "ReferenceConstraintAlgorithm.h" -#include "SimTKOpenMMCommon.h" #include "openmm/System.h" #include #include diff --git a/platforms/reference/include/ReferenceLincsAlgorithm.h b/platforms/reference/include/ReferenceLincsAlgorithm.h index 04ba35157..78b7fcd40 100644 --- a/platforms/reference/include/ReferenceLincsAlgorithm.h +++ b/platforms/reference/include/ReferenceLincsAlgorithm.h @@ -131,12 +131,9 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { @param atomCoordinatesP atom coordinates prime @param inverseMasses 1/mass - @return SimTKOpenMMCommon::DefaultReturn if converge; else - return SimTKOpenMMCommon::ErrorReturn - --------------------------------------------------------------------------------------- */ - int apply(int numberOfAtoms, std::vector& atomCoordinates, + void apply(int numberOfAtoms, std::vector& atomCoordinates, std::vector& atomCoordinatesP, std::vector& inverseMasses); /**--------------------------------------------------------------------------------------- @@ -148,12 +145,9 @@ class ReferenceLincsAlgorithm : public ReferenceConstraintAlgorithm { @param velocities atom velocities @param inverseMasses 1/mass - @return SimTKOpenMMCommon::DefaultReturn if converge; else - return SimTKOpenMMCommon::ErrorReturn - --------------------------------------------------------------------------------------- */ - int applyToVelocities(int numberOfAtoms, std::vector& atomCoordinates, + void applyToVelocities(int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, std::vector& inverseMasses); }; diff --git a/platforms/reference/include/ReferenceMonteCarloBarostat.h b/platforms/reference/include/ReferenceMonteCarloBarostat.h index 361f21036..1d0f99439 100644 --- a/platforms/reference/include/ReferenceMonteCarloBarostat.h +++ b/platforms/reference/include/ReferenceMonteCarloBarostat.h @@ -25,7 +25,6 @@ #ifndef __ReferenceMonteCarloBarostat_H__ #define __ReferenceMonteCarloBarostat_H__ -#include "SimTKOpenMMCommon.h" #include #include diff --git a/platforms/reference/include/ReferencePME.h b/platforms/reference/include/ReferencePME.h index bd0a12ff3..74ec81769 100644 --- a/platforms/reference/include/ReferencePME.h +++ b/platforms/reference/include/ReferencePME.h @@ -32,7 +32,7 @@ #ifndef __ReferencePME_H__ #define __ReferencePME_H__ -#include "SimTKOpenMMCommon.h" +#include "RealVec.h" #include "openmm/internal/windowsExport.h" #include diff --git a/platforms/reference/include/ReferencePairIxn.h b/platforms/reference/include/ReferencePairIxn.h index e03e75dc2..9388411d4 100644 --- a/platforms/reference/include/ReferencePairIxn.h +++ b/platforms/reference/include/ReferencePairIxn.h @@ -27,6 +27,7 @@ #include "RealVec.h" #include "openmm/internal/windowsExport.h" +#include namespace OpenMM { diff --git a/platforms/reference/include/SimTKOpenMMCommon.h b/platforms/reference/include/SimTKOpenMMCommon.h deleted file mode 100644 index 51d3b7990..000000000 --- a/platforms/reference/include/SimTKOpenMMCommon.h +++ /dev/null @@ -1,60 +0,0 @@ - -/* Portions copyright (c) 2006 Stanford University and Simbios. - * Contributors: Pande Group - * - * 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. - */ - -#ifndef __SimTKOpenMMCommon_H__ -#define __SimTKOpenMMCommon_H__ - -#include -#include -#include "RealVec.h" - -namespace OpenMM { - -typedef std::vector RealOpenMMVector; -typedef RealOpenMMVector::iterator RealOpenMMVectorI; -typedef RealOpenMMVector::const_iterator RealOpenMMVectorCI; - -// --------------------------------------------------------------------------------------- - -class SimTKOpenMMCommon { - - public: - - static const std::string NotSet; - static const RealOpenMM BigCutoffValue; - static const std::string Comment; - static const std::string Tab; - static const std::string YesU; - static const std::string YesUl; - static const std::string YesL; - - // subroutine returns - - static const int DefaultReturn; - static const int ErrorReturn; -}; - -} // namespace OpenMM - -#endif // __SimTKOpenMMCommon_H__ diff --git a/platforms/reference/include/SimTKOpenMMUtilities.h b/platforms/reference/include/SimTKOpenMMUtilities.h index 49fa1c664..df9a7c46b 100644 --- a/platforms/reference/include/SimTKOpenMMUtilities.h +++ b/platforms/reference/include/SimTKOpenMMUtilities.h @@ -27,7 +27,7 @@ // class of shared, static utility methods -#include "SimTKOpenMMCommon.h" +#include "RealVec.h" #include "sfmt/SFMT.h" #include "openmm/internal/windowsExport.h" diff --git a/platforms/reference/include/fftpack.h b/platforms/reference/include/fftpack.h index d5c2eefa4..b84b81440 100644 --- a/platforms/reference/include/fftpack.h +++ b/platforms/reference/include/fftpack.h @@ -14,14 +14,13 @@ * drop a line to lindahl@cbr.su.se and let me know about it! */ -#include "SimTKOpenMMCommon.h" - #ifndef _FFTPACK_H_ #define _FFTPACK_H_ #include +#include "RealVec.h" #include "openmm/internal/windowsExport.h" #ifdef __cplusplus diff --git a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp index 82ebc2bdd..39cf5699f 100644 --- a/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceAngleBondIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceAngleBondIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp index 2851706d2..e9f99a98b 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondForce.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceBondForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp index 29e52964a..ac9d2d533 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBondIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceBondIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp index eff76ce9e..ea74090c9 100644 --- a/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceBrownianDynamics.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceBrownianDynamics.h" #include "ReferenceVirtualSites.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp index eee7c7d78..714b988f9 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCCMAAlgorithm.h" #include "ReferenceDynamics.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp index 6f6a590df..51958cedb 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomAngleIxn.cpp @@ -24,7 +24,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomAngleIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp index fecfe0975..95f541da3 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomBondIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomBondIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp index 5a4374986..0db9071b7 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomCompoundBondIxn.cpp @@ -26,7 +26,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomCompoundBondIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp index e8b5fa6a5..dedc074a4 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomDynamics.cpp @@ -22,7 +22,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVirtualSites.h" #include "ReferenceCustomDynamics.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp index 91a5297c5..35d5a7b5a 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomExternalIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomExternalIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp index 76ae6c4eb..8d2a5c0be 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomGBIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomGBIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp index f36a3c5a9..15b4eec59 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomHbondIxn.cpp @@ -26,7 +26,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomHbondIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp index 9a3169245..341a23dd4 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomManyParticleIxn.cpp @@ -26,7 +26,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomManyParticleIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp index cabfbbc7c..091004b13 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomNonbondedIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferenceCustomNonbondedIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp index 4d669919e..5d5de2ff3 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCustomTorsionIxn.cpp @@ -24,7 +24,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceCustomTorsionIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp index 153db9998..b60f11b69 100644 --- a/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceDynamics.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceDynamics.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceForce.cpp b/platforms/reference/src/SimTKReference/ReferenceForce.cpp index 348ecced9..65de8ed00 100644 --- a/platforms/reference/src/SimTKReference/ReferenceForce.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceForce.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp index 3e6fd382f..b2d6cfb63 100644 --- a/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceHarmonicBondIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceHarmonicBondIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp index c55ba04c6..418b1d666 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulomb14.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceLJCoulomb14.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp index 72345f354..274434d84 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLJCoulombIxn.cpp @@ -27,7 +27,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceLJCoulombIxn.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp index 766884dd0..9598208b4 100644 --- a/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceLincsAlgorithm.cpp @@ -24,7 +24,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceLincsAlgorithm.h" #include "ReferenceDynamics.h" @@ -213,12 +212,9 @@ void ReferenceLincsAlgorithm::updateAtomPositions(int numberOfAtoms, vector& atomCoordinates, +void ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector& atomCoordinates, vector& atomCoordinatesP, vector& inverseMasses) { @@ -233,7 +229,7 @@ int ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector& atomCoord // --------------------------------------------------------------------------------------- if (_numberOfConstraints == 0) - return SimTKOpenMMCommon::DefaultReturn; + return; if (!_hasInitialized) initialize(numberOfAtoms, inverseMasses); @@ -287,9 +283,6 @@ int ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector& atomCoord } solveMatrix(); updateAtomPositions(numberOfAtoms, atomCoordinatesP, inverseMasses); - - return SimTKOpenMMCommon::DefaultReturn; - } /**--------------------------------------------------------------------------------------- @@ -301,12 +294,9 @@ int ReferenceLincsAlgorithm::apply(int numberOfAtoms, vector& atomCoord @param velocities atom velocities @param inverseMasses 1/mass - @return SimTKOpenMMCommon::DefaultReturn if converge; else - return SimTKOpenMMCommon::ErrorReturn - --------------------------------------------------------------------------------------- */ -int ReferenceLincsAlgorithm::applyToVelocities(int numberOfAtoms, std::vector& atomCoordinates, +void ReferenceLincsAlgorithm::applyToVelocities(int numberOfAtoms, std::vector& atomCoordinates, std::vector& velocities, std::vector& inverseMasses) { throw OpenMM::OpenMMException("applyToVelocities is not implemented"); } diff --git a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp index f0fdfa1f1..955fbface 100644 --- a/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp +++ b/platforms/reference/src/SimTKReference/ReferencePairIxn.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceForce.h" #include "ReferencePairIxn.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp index c090671eb..cbab40495 100644 --- a/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceProperDihedralBond.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceProperDihedralBond.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp index f6c8f06d3..ad0ca4d4c 100644 --- a/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceRbDihedralBond.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceRbDihedralBond.h" #include "ReferenceForce.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp index fe6c333d7..eb2637ff2 100644 --- a/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceStochasticDynamics.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceStochasticDynamics.h" #include "ReferenceVirtualSites.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp index 34b4578cf..8d87a1f91 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVariableStochasticDynamics.cpp @@ -26,7 +26,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVariableStochasticDynamics.h" #include "ReferenceVirtualSites.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp index 5becb5fb5..ca0621d37 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVariableVerletDynamics.cpp @@ -26,7 +26,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVariableVerletDynamics.h" #include "ReferenceVirtualSites.h" diff --git a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp index 921e0504c..6652dc0bd 100644 --- a/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceVerletDynamics.cpp @@ -25,7 +25,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "SimTKOpenMMUtilities.h" #include "ReferenceVerletDynamics.h" #include "ReferenceVirtualSites.h" diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp b/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp deleted file mode 100644 index 05f48b229..000000000 --- a/platforms/reference/src/SimTKUtilities/SimTKOpenMMCommon.cpp +++ /dev/null @@ -1,40 +0,0 @@ - -/* Portions copyright (c) 2006 Stanford University and Simbios. - * Contributors: Pande Group - * - * 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 "SimTKOpenMMCommon.h" - -using namespace OpenMM; - -// static settings - -// initialization of static data members - -const std::string SimTKOpenMMCommon::NotSet = std::string("NotSet"); -const std::string SimTKOpenMMCommon::Comment = std::string("#"); -const std::string SimTKOpenMMCommon::Tab = std::string("\t"); - -const int SimTKOpenMMCommon::DefaultReturn = 0; -const int SimTKOpenMMCommon::ErrorReturn = -1; -const RealOpenMM SimTKOpenMMCommon::BigCutoffValue = 1.0e+05; - diff --git a/platforms/reference/src/gbsa/CpuGBVI.cpp b/platforms/reference/src/gbsa/CpuGBVI.cpp index acd8a5136..fc4724b3f 100644 --- a/platforms/reference/src/gbsa/CpuGBVI.cpp +++ b/platforms/reference/src/gbsa/CpuGBVI.cpp @@ -26,7 +26,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "ReferenceForce.h" #include "CpuGBVI.h" @@ -86,7 +85,7 @@ void CpuGBVI::setGBVIParameters(GBVIParameters* gbviParameters) { --------------------------------------------------------------------------------------- */ -RealOpenMMVector& CpuGBVI::getSwitchDeriviative() { +vector& CpuGBVI::getSwitchDeriviative() { return _switchDeriviative; } @@ -203,7 +202,7 @@ void CpuGBVI::computeBornRadiiUsingQuinticSpline(RealOpenMM atomicRadius3, RealO --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornRadii(const vector& atomCoordinates, RealOpenMMVector& bornRadii) { +void CpuGBVI::computeBornRadii(const vector& atomCoordinates, vector& bornRadii) { // --------------------------------------------------------------------------------------- @@ -218,10 +217,10 @@ void CpuGBVI::computeBornRadii(const vector& atomCoordinates, RealOpenM GBVIParameters* gbviParameters = getGBVIParameters(); int numberOfAtoms = gbviParameters->getNumberOfAtoms(); - const RealOpenMMVector& atomicRadii = gbviParameters->getAtomicRadii(); - const RealOpenMMVector& scaledRadii = gbviParameters->getScaledRadii(); + const vector& atomicRadii = gbviParameters->getAtomicRadii(); + const vector& scaledRadii = gbviParameters->getScaledRadii(); - RealOpenMMVector& switchDeriviatives = getSwitchDeriviative(); + vector& switchDeriviatives = getSwitchDeriviative(); // --------------------------------------------------------------------------------------- @@ -448,7 +447,7 @@ RealOpenMM CpuGBVI::Sgb(RealOpenMM t) { --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::computeBornEnergy(const vector& atomCoordinates, const RealOpenMMVector& partialCharges) { +RealOpenMM CpuGBVI::computeBornEnergy(const vector& atomCoordinates, const vector& partialCharges) { // --------------------------------------------------------------------------------------- @@ -466,12 +465,12 @@ RealOpenMM CpuGBVI::computeBornEnergy(const vector& atomCoordinates, co const GBVIParameters* gbviParameters = getGBVIParameters(); const RealOpenMM preFactor = gbviParameters->getElectricConstant(); const int numberOfAtoms = gbviParameters->getNumberOfAtoms(); - const RealOpenMMVector& atomicRadii = gbviParameters->getAtomicRadii(); - const RealOpenMMVector& gammaParameters = gbviParameters->getGammaParameters(); + const vector& atomicRadii = gbviParameters->getAtomicRadii(); + const vector& gammaParameters = gbviParameters->getGammaParameters(); // compute Born radii - RealOpenMMVector bornRadii(numberOfAtoms); + vector bornRadii(numberOfAtoms); computeBornRadii(atomCoordinates, bornRadii); // --------------------------------------------------------------------------------------- @@ -532,7 +531,7 @@ RealOpenMM CpuGBVI::computeBornEnergy(const vector& atomCoordinates, co --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, +void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const vector& partialCharges, std::vector& inputForces) { // --------------------------------------------------------------------------------------- @@ -551,8 +550,8 @@ void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const Rea const GBVIParameters* gbviParameters = getGBVIParameters(); const int numberOfAtoms = gbviParameters->getNumberOfAtoms(); - const RealOpenMMVector& atomicRadii = gbviParameters->getAtomicRadii(); - const RealOpenMMVector& gammaParameters = gbviParameters->getGammaParameters(); + const vector& atomicRadii = gbviParameters->getAtomicRadii(); + const vector& gammaParameters = gbviParameters->getGammaParameters(); // --------------------------------------------------------------------------------------- @@ -564,7 +563,7 @@ void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const Rea // compute Born radii - RealOpenMMVector bornRadii(numberOfAtoms); + vector bornRadii(numberOfAtoms); computeBornRadii(atomCoordinates, bornRadii); // set energy/forces to zero @@ -576,7 +575,7 @@ void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const Rea forces[ii][2] = zero; } - RealOpenMMVector bornForces(numberOfAtoms, 0.0); + vector bornForces(numberOfAtoms, 0.0); // --------------------------------------------------------------------------------------- @@ -645,8 +644,8 @@ void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const Rea // dGpol/dBornRadius) = bornForces[] // dBornRadius/dr = (1/3)*(bR**4)*(dV/dr) - const RealOpenMMVector& scaledRadii = gbviParameters->getScaledRadii(); - const RealOpenMMVector& switchDeriviative = getSwitchDeriviative(); + const vector& scaledRadii = gbviParameters->getScaledRadii(); + const vector& switchDeriviative = getSwitchDeriviative(); for (int atomI = 0; atomI < numberOfAtoms; atomI++) { RealOpenMM R = atomicRadii[atomI]; @@ -748,9 +747,9 @@ void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const Rea --------------------------------------------------------------------------------------- */ -void CpuGBVI::printGbvi(const std::vector& atomCoordinates, const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, +void CpuGBVI::printGbvi(const std::vector& atomCoordinates, const vector& partialCharges, + const vector& bornRadii, + const vector& bornForces, const std::vector& forces, const std::string& idString, FILE* log) { @@ -758,8 +757,8 @@ void CpuGBVI::printGbvi(const std::vector& atomCoordinates, con const GBVIParameters* gbviParameters = getGBVIParameters(); const int numberOfAtoms = gbviParameters->getNumberOfAtoms(); - const RealOpenMMVector& atomicRadii = gbviParameters->getAtomicRadii(); - const RealOpenMMVector& gammaParameters = gbviParameters->getGammaParameters(); + const vector& atomicRadii = gbviParameters->getAtomicRadii(); + const vector& gammaParameters = gbviParameters->getGammaParameters(); // --------------------------------------------------------------------------------------- @@ -769,8 +768,8 @@ void CpuGBVI::printGbvi(const std::vector& atomCoordinates, con // --------------------------------------------------------------------------------------- - const RealOpenMMVector& scaledRadii = gbviParameters->getScaledRadii(); - const RealOpenMMVector& switchDeriviative = getSwitchDeriviative(); + const vector& scaledRadii = gbviParameters->getScaledRadii(); + const vector& switchDeriviative = getSwitchDeriviative(); RealOpenMM tau = static_cast(gbviParameters->getTau()); int useComparisonFormat = 1; diff --git a/platforms/reference/src/gbsa/CpuObc.cpp b/platforms/reference/src/gbsa/CpuObc.cpp index be6297695..c249d4d25 100644 --- a/platforms/reference/src/gbsa/CpuObc.cpp +++ b/platforms/reference/src/gbsa/CpuObc.cpp @@ -28,7 +28,6 @@ #include #include -#include "SimTKOpenMMCommon.h" #include "ReferenceForce.h" #include "CpuObc.h" @@ -144,9 +143,9 @@ void CpuObc::computeBornRadii(const vector& atomCoordinates, vectorgetNumberOfAtoms(); - const RealOpenMMVector& atomicRadii = obcParameters->getAtomicRadii(); - const RealOpenMMVector& scaledRadiusFactor = obcParameters->getScaledRadiusFactors(); - RealOpenMMVector& obcChain = getObcChain(); + const vector& atomicRadii = obcParameters->getAtomicRadii(); + const vector& scaledRadiusFactor = obcParameters->getScaledRadiusFactors(); + vector& obcChain = getObcChain(); RealOpenMM dielectricOffset = obcParameters->getDielectricOffset(); RealOpenMM alphaObc = obcParameters->getAlphaObc(); @@ -237,9 +236,9 @@ void CpuObc::computeBornRadii(const vector& atomCoordinates, vector& bornRadii, RealOpenMM* energy, - RealOpenMMVector& forces) const { + vector& forces) const { // --------------------------------------------------------------------------------------- @@ -254,7 +253,7 @@ void CpuObc::computeAceNonPolarForce(const ObcParameters* obcParameters, const RealOpenMM probeRadius = obcParameters->getProbeRadius(); const RealOpenMM surfaceAreaFactor = obcParameters->getPi4Asolv(); - const RealOpenMMVector& atomicRadii = obcParameters->getAtomicRadii(); + const vector& atomicRadii = obcParameters->getAtomicRadii(); int numberOfAtoms = obcParameters->getNumberOfAtoms(); // the original ACE equation is based on Eq.2 of @@ -295,7 +294,7 @@ void CpuObc::computeAceNonPolarForce(const ObcParameters* obcParameters, --------------------------------------------------------------------------------------- */ RealOpenMM CpuObc::computeBornEnergyForces(const vector& atomCoordinates, - const RealOpenMMVector& partialCharges, vector& inputForces) { + const vector& partialCharges, vector& inputForces) { // --------------------------------------------------------------------------------------- @@ -325,13 +324,13 @@ RealOpenMM CpuObc::computeBornEnergyForces(const vector& atomCoordinate // compute Born radii - RealOpenMMVector bornRadii(numberOfAtoms); + vector bornRadii(numberOfAtoms); computeBornRadii(atomCoordinates, bornRadii); // set energy/forces to zero RealOpenMM obcEnergy = zero; - RealOpenMMVector bornForces(numberOfAtoms, 0.0); + vector bornForces(numberOfAtoms, 0.0); // --------------------------------------------------------------------------------------- @@ -410,13 +409,13 @@ RealOpenMM CpuObc::computeBornEnergyForces(const vector& atomCoordinate // second main loop - const RealOpenMMVector& obcChain = getObcChain(); - const RealOpenMMVector& atomicRadii = _obcParameters->getAtomicRadii(); + const vector& obcChain = getObcChain(); + const vector& atomicRadii = _obcParameters->getAtomicRadii(); const RealOpenMM alphaObc = _obcParameters->getAlphaObc(); const RealOpenMM betaObc = _obcParameters->getBetaObc(); const RealOpenMM gammaObc = _obcParameters->getGammaObc(); - const RealOpenMMVector& scaledRadiusFactor = _obcParameters->getScaledRadiusFactors(); + const vector& scaledRadiusFactor = _obcParameters->getScaledRadiusFactors(); // compute factor that depends only on the outer loop index @@ -515,9 +514,9 @@ RealOpenMM CpuObc::computeBornEnergyForces(const vector& atomCoordinate --------------------------------------------------------------------------------------- */ void CpuObc::printObc(const std::vector& atomCoordinates, - const RealOpenMMVector& partialCharges, - const RealOpenMMVector& bornRadii, - const RealOpenMMVector& bornForces, + const vector& partialCharges, + const vector& bornRadii, + const vector& bornForces, const std::vector& forces, const std::string& idString, FILE* log) { @@ -525,10 +524,10 @@ void CpuObc::printObc(const std::vector& atomCoordinates, const ObcParameters* obcParameters = getObcParameters(); const int numberOfAtoms = obcParameters->getNumberOfAtoms(); - const RealOpenMMVector& atomicRadii = obcParameters->getAtomicRadii(); + const vector& atomicRadii = obcParameters->getAtomicRadii(); const RealOpenMM preFactor = 2.0*obcParameters->getElectricConstant(); - const RealOpenMMVector& obcChain = getObcChain(); - const RealOpenMMVector& scaledRadiusFactor = obcParameters->getScaledRadiusFactors(); + const vector& obcChain = getObcChain(); + const vector& scaledRadiusFactor = obcParameters->getScaledRadiusFactors(); const RealOpenMM alphaObc = obcParameters->getAlphaObc(); const RealOpenMM betaObc = obcParameters->getBetaObc(); diff --git a/platforms/reference/src/gbsa/GBVIParameters.cpp b/platforms/reference/src/gbsa/GBVIParameters.cpp index 4b5745e8a..a073d2c41 100644 --- a/platforms/reference/src/gbsa/GBVIParameters.cpp +++ b/platforms/reference/src/gbsa/GBVIParameters.cpp @@ -28,7 +28,6 @@ #include "openmm/OpenMMException.h" #include "GBVIParameters.h" -#include "SimTKOpenMMCommon.h" using std::vector; using namespace OpenMM; @@ -146,7 +145,7 @@ void GBVIParameters::setSoluteDielectric(RealOpenMM soluteDielectric) { --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& GBVIParameters::getAtomicRadii() const { +const vector& GBVIParameters::getAtomicRadii() const { return _atomicRadii; } @@ -158,7 +157,7 @@ const RealOpenMMVector& GBVIParameters::getAtomicRadii() const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setAtomicRadii(const RealOpenMMVector& atomicRadii) { +void GBVIParameters::setAtomicRadii(const vector& atomicRadii) { if (atomicRadii.size() == _atomicRadii.size()) { for (unsigned int ii = 0; ii < atomicRadii.size(); ii++) { @@ -170,7 +169,7 @@ void GBVIParameters::setAtomicRadii(const RealOpenMMVector& atomicRadii) { msg << atomicRadii.size(); msg << " current size=" << _atomicRadii.size(); throw OpenMM::OpenMMException(msg.str()); - } + } } @@ -181,7 +180,7 @@ void GBVIParameters::setAtomicRadii(const RealOpenMMVector& atomicRadii) { --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& GBVIParameters::getScaledRadii() const { +const vector& GBVIParameters::getScaledRadii() const { return _scaledRadii; } @@ -193,7 +192,7 @@ const RealOpenMMVector& GBVIParameters::getScaledRadii() const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setScaledRadii(const RealOpenMMVector& scaledRadii) { +void GBVIParameters::setScaledRadii(const vector& scaledRadii) { if (scaledRadii.size() == _scaledRadii.size()) { for (unsigned int ii = 0; ii < scaledRadii.size(); ii++) { @@ -218,7 +217,7 @@ void GBVIParameters::setScaledRadii(const RealOpenMMVector& scaledRadii) { --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& GBVIParameters::getGammaParameters() const { +const vector& GBVIParameters::getGammaParameters() const { return _gammaParameters; } @@ -230,7 +229,7 @@ const RealOpenMMVector& GBVIParameters::getGammaParameters() const { --------------------------------------------------------------------------------------- */ -void GBVIParameters::setGammaParameters(const RealOpenMMVector& gammas) { +void GBVIParameters::setGammaParameters(const vector& gammas) { if (gammas.size() == _gammaParameters.size()) { for (unsigned int ii = 0; ii < gammas.size(); ii++) { diff --git a/platforms/reference/src/gbsa/ObcParameters.cpp b/platforms/reference/src/gbsa/ObcParameters.cpp index cf19af020..5537f51f3 100644 --- a/platforms/reference/src/gbsa/ObcParameters.cpp +++ b/platforms/reference/src/gbsa/ObcParameters.cpp @@ -28,7 +28,6 @@ #include "openmm/OpenMMException.h" #include "ObcParameters.h" -#include "SimTKOpenMMCommon.h" using std::vector; using namespace OpenMM; @@ -271,7 +270,7 @@ void ObcParameters::setPi4Asolv(RealOpenMM pi4Asolv) { --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& ObcParameters::getAtomicRadii() const { +const vector& ObcParameters::getAtomicRadii() const { return _atomicRadii; } @@ -283,7 +282,7 @@ const RealOpenMMVector& ObcParameters::getAtomicRadii() const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setAtomicRadii(const RealOpenMMVector& atomicRadii) { +void ObcParameters::setAtomicRadii(const vector& atomicRadii) { if (atomicRadii.size() == _atomicRadii.size()) { for (unsigned int ii = 0; ii < atomicRadii.size(); ii++) { @@ -307,7 +306,7 @@ void ObcParameters::setAtomicRadii(const RealOpenMMVector& atomicRadii) { --------------------------------------------------------------------------------------- */ -const RealOpenMMVector& ObcParameters::getScaledRadiusFactors() const { +const vector& ObcParameters::getScaledRadiusFactors() const { return _scaledRadiusFactors; } @@ -319,7 +318,7 @@ const RealOpenMMVector& ObcParameters::getScaledRadiusFactors() const { --------------------------------------------------------------------------------------- */ -void ObcParameters::setScaledRadiusFactors(const RealOpenMMVector& scaledRadiusFactors) { +void ObcParameters::setScaledRadiusFactors(const vector& scaledRadiusFactors) { if (scaledRadiusFactors.size() == _scaledRadiusFactors.size()) { for (unsigned int ii = 0; ii < scaledRadiusFactors.size(); ii++) { -- GitLab From 3d69185ab6ae9fd4c35482b1787799869ff4703a Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 16:04:14 -0800 Subject: [PATCH 280/338] Combined subfolders in reference source, and renamed a couple of badly named classes --- .../include/{CpuGBVI.h => ReferenceGBVI.h} | 12 +-- .../reference/include/ReferenceKernels.h | 8 +- .../include/{CpuObc.h => ReferenceObc.h} | 12 +-- platforms/reference/src/ReferenceKernels.cpp | 8 +- .../GBVIParameters.cpp | 0 .../ObcParameters.cpp | 0 .../ReferenceGBVI.cpp} | 76 +++++++++---------- .../ReferenceObc.cpp} | 28 +++---- .../SimTKOpenMMUtilities.cpp | 0 9 files changed, 72 insertions(+), 72 deletions(-) rename platforms/reference/include/{CpuGBVI.h => ReferenceGBVI.h} (98%) rename platforms/reference/include/{CpuObc.h => ReferenceObc.h} (97%) rename platforms/reference/src/{gbsa => SimTKReference}/GBVIParameters.cpp (100%) rename platforms/reference/src/{gbsa => SimTKReference}/ObcParameters.cpp (100%) rename platforms/reference/src/{gbsa/CpuGBVI.cpp => SimTKReference/ReferenceGBVI.cpp} (93%) rename platforms/reference/src/{gbsa/CpuObc.cpp => SimTKReference/ReferenceObc.cpp} (96%) rename platforms/reference/src/{SimTKUtilities => SimTKReference}/SimTKOpenMMUtilities.cpp (100%) diff --git a/platforms/reference/include/CpuGBVI.h b/platforms/reference/include/ReferenceGBVI.h similarity index 98% rename from platforms/reference/include/CpuGBVI.h rename to platforms/reference/include/ReferenceGBVI.h index 6ed47e156..69be5e81e 100644 --- a/platforms/reference/include/CpuGBVI.h +++ b/platforms/reference/include/ReferenceGBVI.h @@ -22,8 +22,8 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef __CpuGBVI_H__ -#define __CpuGBVI_H__ +#ifndef __ReferenceGBVI_H__ +#define __ReferenceGBVI_H__ #include @@ -32,7 +32,7 @@ namespace OpenMM { -class CpuGBVI { +class ReferenceGBVI { private: @@ -53,7 +53,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - CpuGBVI(GBVIParameters* gbviParameters); + ReferenceGBVI(GBVIParameters* gbviParameters); /**--------------------------------------------------------------------------------------- @@ -61,7 +61,7 @@ class CpuGBVI { --------------------------------------------------------------------------------------- */ - ~CpuGBVI(); + ~ReferenceGBVI(); /**--------------------------------------------------------------------------------------- @@ -313,4 +313,4 @@ class CpuGBVI { } // namespace OpenMM -#endif // __CpuGBVI_H__ +#endif // __ReferenceGBVI_H__ diff --git a/platforms/reference/include/ReferenceKernels.h b/platforms/reference/include/ReferenceKernels.h index f11aefbd3..c380a9b85 100644 --- a/platforms/reference/include/ReferenceKernels.h +++ b/platforms/reference/include/ReferenceKernels.h @@ -41,8 +41,8 @@ namespace OpenMM { -class CpuObc; -class CpuGBVI; +class ReferenceObc; +class ReferenceGBVI; class ReferenceAndersenThermostat; class ReferenceCustomCompoundBondIxn; class ReferenceCustomHbondIxn; @@ -658,7 +658,7 @@ public: */ void copyParametersToContext(ContextImpl& context, const GBSAOBCForce& force); private: - CpuObc* obc; + ReferenceObc* obc; std::vector charges; bool isPeriodic; }; @@ -689,7 +689,7 @@ public: */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); private: - CpuGBVI * gbvi; + ReferenceGBVI * gbvi; std::vector charges; bool isPeriodic; }; diff --git a/platforms/reference/include/CpuObc.h b/platforms/reference/include/ReferenceObc.h similarity index 97% rename from platforms/reference/include/CpuObc.h rename to platforms/reference/include/ReferenceObc.h index 19343331b..f796961c1 100644 --- a/platforms/reference/include/CpuObc.h +++ b/platforms/reference/include/ReferenceObc.h @@ -22,14 +22,14 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef __CpuObc_H__ -#define __CpuObc_H__ +#ifndef __ReferenceObc_H__ +#define __ReferenceObc_H__ #include "ObcParameters.h" namespace OpenMM { -class CpuObc { +class ReferenceObc { private: @@ -59,7 +59,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - CpuObc(ObcParameters* obcParameters); + ReferenceObc(ObcParameters* obcParameters); /**--------------------------------------------------------------------------------------- @@ -67,7 +67,7 @@ class CpuObc { --------------------------------------------------------------------------------------- */ - ~CpuObc(); + ~ReferenceObc(); /**--------------------------------------------------------------------------------------- @@ -183,4 +183,4 @@ class CpuObc { } // namespace OpenMM -#endif // __CpuObc_H__ +#endif // __ReferenceObc_H__ diff --git a/platforms/reference/src/ReferenceKernels.cpp b/platforms/reference/src/ReferenceKernels.cpp index eb829f2d8..c895833dc 100644 --- a/platforms/reference/src/ReferenceKernels.cpp +++ b/platforms/reference/src/ReferenceKernels.cpp @@ -30,8 +30,8 @@ * -------------------------------------------------------------------------- */ #include "ReferenceKernels.h" -#include "CpuObc.h" -#include "CpuGBVI.h" +#include "ReferenceObc.h" +#include "ReferenceGBVI.h" #include "ReferenceAndersenThermostat.h" #include "ReferenceAngleBondIxn.h" #include "ReferenceBondForce.h" @@ -1111,7 +1111,7 @@ void ReferenceCalcGBSAOBCForceKernel::initialize(const System& system, const GBS if (force.getNonbondedMethod() != GBSAOBCForce::NoCutoff) obcParameters->setUseCutoff(static_cast(force.getCutoffDistance())); isPeriodic = (force.getNonbondedMethod() == GBSAOBCForce::CutoffPeriodic); - obc = new CpuObc(obcParameters); + obc = new ReferenceObc(obcParameters); obc->setIncludeAceApproximation(true); } @@ -1185,7 +1185,7 @@ void ReferenceCalcGBVIForceKernel::initialize(const System& system, const GBVIFo if (force.getNonbondedMethod() != GBVIForce::NoCutoff) gBVIParameters->setUseCutoff(static_cast(force.getCutoffDistance())); isPeriodic = (force.getNonbondedMethod() == GBVIForce::CutoffPeriodic); - gbvi = new CpuGBVI(gBVIParameters); + gbvi = new ReferenceGBVI(gBVIParameters); } double ReferenceCalcGBVIForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { diff --git a/platforms/reference/src/gbsa/GBVIParameters.cpp b/platforms/reference/src/SimTKReference/GBVIParameters.cpp similarity index 100% rename from platforms/reference/src/gbsa/GBVIParameters.cpp rename to platforms/reference/src/SimTKReference/GBVIParameters.cpp diff --git a/platforms/reference/src/gbsa/ObcParameters.cpp b/platforms/reference/src/SimTKReference/ObcParameters.cpp similarity index 100% rename from platforms/reference/src/gbsa/ObcParameters.cpp rename to platforms/reference/src/SimTKReference/ObcParameters.cpp diff --git a/platforms/reference/src/gbsa/CpuGBVI.cpp b/platforms/reference/src/SimTKReference/ReferenceGBVI.cpp similarity index 93% rename from platforms/reference/src/gbsa/CpuGBVI.cpp rename to platforms/reference/src/SimTKReference/ReferenceGBVI.cpp index fc4724b3f..1daf423f5 100644 --- a/platforms/reference/src/gbsa/CpuGBVI.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceGBVI.cpp @@ -27,30 +27,30 @@ #include #include "ReferenceForce.h" -#include "CpuGBVI.h" +#include "ReferenceGBVI.h" using namespace std; using namespace OpenMM; /**--------------------------------------------------------------------------------------- - CpuGBVI constructor + ReferenceGBVI constructor gbviParameters gbviParameters object --------------------------------------------------------------------------------------- */ -CpuGBVI::CpuGBVI(GBVIParameters* gbviParameters) : _gbviParameters(gbviParameters) { +ReferenceGBVI::ReferenceGBVI(GBVIParameters* gbviParameters) : _gbviParameters(gbviParameters) { _switchDeriviative.resize(gbviParameters->getNumberOfAtoms()); } /**--------------------------------------------------------------------------------------- - CpuGBVI destructor + ReferenceGBVI destructor --------------------------------------------------------------------------------------- */ -CpuGBVI::~CpuGBVI() { +ReferenceGBVI::~ReferenceGBVI() { } /**--------------------------------------------------------------------------------------- @@ -61,7 +61,7 @@ CpuGBVI::~CpuGBVI() { --------------------------------------------------------------------------------------- */ -GBVIParameters* CpuGBVI::getGBVIParameters() const { +GBVIParameters* ReferenceGBVI::getGBVIParameters() const { return _gbviParameters; } @@ -73,7 +73,7 @@ GBVIParameters* CpuGBVI::getGBVIParameters() const { --------------------------------------------------------------------------------------- */ -void CpuGBVI::setGBVIParameters(GBVIParameters* gbviParameters) { +void ReferenceGBVI::setGBVIParameters(GBVIParameters* gbviParameters) { _gbviParameters = gbviParameters; } @@ -85,7 +85,7 @@ void CpuGBVI::setGBVIParameters(GBVIParameters* gbviParameters) { --------------------------------------------------------------------------------------- */ -vector& CpuGBVI::getSwitchDeriviative() { +vector& ReferenceGBVI::getSwitchDeriviative() { return _switchDeriviative; } @@ -101,7 +101,7 @@ vector& CpuGBVI::getSwitchDeriviative() { --------------------------------------------------------------------------------------- */ -void CpuGBVI::quinticSpline(RealOpenMM x, RealOpenMM rl, RealOpenMM ru, +void ReferenceGBVI::quinticSpline(RealOpenMM x, RealOpenMM rl, RealOpenMM ru, RealOpenMM* outValue, RealOpenMM* outDerivative) { // --------------------------------------------------------------------------------------- @@ -139,7 +139,7 @@ void CpuGBVI::quinticSpline(RealOpenMM x, RealOpenMM rl, RealOpenMM ru, --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornRadiiUsingQuinticSpline(RealOpenMM atomicRadius3, RealOpenMM bornSum, +void ReferenceGBVI::computeBornRadiiUsingQuinticSpline(RealOpenMM atomicRadius3, RealOpenMM bornSum, GBVIParameters* gbviParameters, RealOpenMM* bornRadius, RealOpenMM* switchDeriviative) { @@ -202,7 +202,7 @@ void CpuGBVI::computeBornRadiiUsingQuinticSpline(RealOpenMM atomicRadius3, RealO --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornRadii(const vector& atomCoordinates, vector& bornRadii) { +void ReferenceGBVI::computeBornRadii(const vector& atomCoordinates, vector& bornRadii) { // --------------------------------------------------------------------------------------- @@ -248,7 +248,7 @@ void CpuGBVI::computeBornRadii(const vector& atomCoordinates, vectorgetUseCutoff() && r > _gbviParameters->getCutoffDistance()) continue; - sum += CpuGBVI::getVolume(r, radiusI, scaledRadii[atomJ]); + sum += ReferenceGBVI::getVolume(r, radiusI, scaledRadii[atomJ]); } } @@ -280,7 +280,7 @@ void CpuGBVI::computeBornRadii(const vector& atomCoordinates, vector (r - S)) ? R : (r - S); - return (CpuGBVI::getL(r, (r + S), S) - - CpuGBVI::getL(r, lowerBound, S)); + return (ReferenceGBVI::getL(r, (r + S), S) - + ReferenceGBVI::getL(r, lowerBound, S)); } else if (r <= diff) { - return CpuGBVI::getL(r, (r + S), S) - - CpuGBVI::getL(r, (r - S), S) + + return ReferenceGBVI::getL(r, (r + S), S) - + ReferenceGBVI::getL(r, (r - S), S) + POW(R, minusThree); } else { @@ -317,7 +317,7 @@ RealOpenMM CpuGBVI::getVolume(RealOpenMM r, RealOpenMM R, RealOpenMM S) { --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::getL(RealOpenMM r, RealOpenMM x, RealOpenMM S) { +RealOpenMM ReferenceGBVI::getL(RealOpenMM r, RealOpenMM x, RealOpenMM S) { // --------------------------------------------------------------------------------------- @@ -352,7 +352,7 @@ RealOpenMM CpuGBVI::getL(RealOpenMM r, RealOpenMM x, RealOpenMM S) { --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::dL_dr(RealOpenMM r, RealOpenMM x, RealOpenMM S) { +RealOpenMM ReferenceGBVI::dL_dr(RealOpenMM r, RealOpenMM x, RealOpenMM S) { // --------------------------------------------------------------------------------------- @@ -389,7 +389,7 @@ RealOpenMM CpuGBVI::dL_dr(RealOpenMM r, RealOpenMM x, RealOpenMM S) { --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::dL_dx(RealOpenMM r, RealOpenMM x, RealOpenMM S) { +RealOpenMM ReferenceGBVI::dL_dx(RealOpenMM r, RealOpenMM x, RealOpenMM S) { // --------------------------------------------------------------------------------------- @@ -421,11 +421,11 @@ RealOpenMM CpuGBVI::dL_dx(RealOpenMM r, RealOpenMM x, RealOpenMM S) { --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::Sgb(RealOpenMM t) { +RealOpenMM ReferenceGBVI::Sgb(RealOpenMM t) { // --------------------------------------------------------------------------------------- - // static const char* methodName = "CpuGBVI::Sgb"; + // static const char* methodName = "ReferenceGBVI::Sgb"; static const RealOpenMM zero = static_cast(0.0); static const RealOpenMM one = static_cast(1.0); @@ -447,7 +447,7 @@ RealOpenMM CpuGBVI::Sgb(RealOpenMM t) { --------------------------------------------------------------------------------------- */ -RealOpenMM CpuGBVI::computeBornEnergy(const vector& atomCoordinates, const vector& partialCharges) { +RealOpenMM ReferenceGBVI::computeBornEnergy(const vector& atomCoordinates, const vector& partialCharges) { // --------------------------------------------------------------------------------------- @@ -531,7 +531,7 @@ RealOpenMM CpuGBVI::computeBornEnergy(const vector& atomCoordinates, co --------------------------------------------------------------------------------------- */ -void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const vector& partialCharges, +void ReferenceGBVI::computeBornForces(std::vector& atomCoordinates, const vector& partialCharges, std::vector& inputForces) { // --------------------------------------------------------------------------------------- @@ -689,15 +689,15 @@ void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const vec // find dRb/dr, where Rb is the Born radius if (FABS(diff) < r) { - de = CpuGBVI::dL_dr(r, r+S, S) + CpuGBVI::dL_dx(r, r+S, S); + de = ReferenceGBVI::dL_dr(r, r+S, S) + ReferenceGBVI::dL_dx(r, r+S, S); if (R > (r - S)) { - de -= CpuGBVI::dL_dr(r, R, S); + de -= ReferenceGBVI::dL_dr(r, R, S); } else { - de -= (CpuGBVI::dL_dr(r, (r-S), S) + CpuGBVI::dL_dx(r, (r-S), S)); + de -= (ReferenceGBVI::dL_dr(r, (r-S), S) + ReferenceGBVI::dL_dx(r, (r-S), S)); } } else if (r < (S - R)) { - de = CpuGBVI::dL_dr(r, r+S, S) + CpuGBVI::dL_dx(r, r+S, S); - de -= (CpuGBVI::dL_dr(r, r-S, S) + CpuGBVI::dL_dx(r, r-S, S)); + de = ReferenceGBVI::dL_dr(r, r+S, S) + ReferenceGBVI::dL_dx(r, r+S, S); + de -= (ReferenceGBVI::dL_dr(r, r-S, S) + ReferenceGBVI::dL_dx(r, r-S, S)); } // de = (dG/dRb)(dRb/dr) @@ -747,7 +747,7 @@ void CpuGBVI::computeBornForces(std::vector& atomCoordinates, const vec --------------------------------------------------------------------------------------- */ -void CpuGBVI::printGbvi(const std::vector& atomCoordinates, const vector& partialCharges, +void ReferenceGBVI::printGbvi(const std::vector& atomCoordinates, const vector& partialCharges, const vector& bornRadii, const vector& bornForces, const std::vector& forces, @@ -834,7 +834,7 @@ void CpuGBVI::printGbvi(const std::vector& atomCoordinates, con --------------------------------------------------------------------------------------- */ -double CpuGBVI::getVolumeD(double r, double R, double S) { +double ReferenceGBVI::getVolumeD(double r, double R, double S) { // --------------------------------------------------------------------------------------- @@ -846,13 +846,13 @@ double CpuGBVI::getVolumeD(double r, double R, double S) { double lowerBound = (R > (r - S)) ? R : (r - S); - return (CpuGBVI::getLD(r, (r + S), S) - - CpuGBVI::getLD(r, lowerBound, S)); + return (ReferenceGBVI::getLD(r, (r + S), S) - + ReferenceGBVI::getLD(r, lowerBound, S)); } else if (r < diff) { - return CpuGBVI::getLD(r, (r + S), S) - - CpuGBVI::getLD(r, (r - S), S) + + return ReferenceGBVI::getLD(r, (r + S), S) - + ReferenceGBVI::getLD(r, (r - S), S) + pow(R, minusThree); } else { @@ -874,7 +874,7 @@ double CpuGBVI::getVolumeD(double r, double R, double S) { --------------------------------------------------------------------------------------- */ -double CpuGBVI::getLD(double r, double x, double S) { +double ReferenceGBVI::getLD(double r, double x, double S) { // --------------------------------------------------------------------------------------- @@ -911,7 +911,7 @@ double CpuGBVI::getLD(double r, double x, double S) { --------------------------------------------------------------------------------------- */ -double CpuGBVI::dL_drD(double r, double x, double S) { +double ReferenceGBVI::dL_drD(double r, double x, double S) { // --------------------------------------------------------------------------------------- @@ -950,7 +950,7 @@ double CpuGBVI::dL_drD(double r, double x, double S) { --------------------------------------------------------------------------------------- */ -double CpuGBVI::dL_dxD(double r, double x, double S) { +double ReferenceGBVI::dL_dxD(double r, double x, double S) { // --------------------------------------------------------------------------------------- diff --git a/platforms/reference/src/gbsa/CpuObc.cpp b/platforms/reference/src/SimTKReference/ReferenceObc.cpp similarity index 96% rename from platforms/reference/src/gbsa/CpuObc.cpp rename to platforms/reference/src/SimTKReference/ReferenceObc.cpp index c249d4d25..f139e297d 100644 --- a/platforms/reference/src/gbsa/CpuObc.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceObc.cpp @@ -29,30 +29,30 @@ #include #include "ReferenceForce.h" -#include "CpuObc.h" +#include "ReferenceObc.h" using namespace OpenMM; using namespace std; /**--------------------------------------------------------------------------------------- - CpuObc constructor + ReferenceObc constructor obcParameters obcParameters object --------------------------------------------------------------------------------------- */ -CpuObc::CpuObc(ObcParameters* obcParameters) : _obcParameters(obcParameters), _includeAceApproximation(1) { +ReferenceObc::ReferenceObc(ObcParameters* obcParameters) : _obcParameters(obcParameters), _includeAceApproximation(1) { _obcChain.resize(_obcParameters->getNumberOfAtoms()); } /**--------------------------------------------------------------------------------------- - CpuObc destructor + ReferenceObc destructor --------------------------------------------------------------------------------------- */ -CpuObc::~CpuObc() { +ReferenceObc::~ReferenceObc() { } /**--------------------------------------------------------------------------------------- @@ -63,7 +63,7 @@ CpuObc::~CpuObc() { --------------------------------------------------------------------------------------- */ -ObcParameters* CpuObc::getObcParameters() const { +ObcParameters* ReferenceObc::getObcParameters() const { return _obcParameters; } @@ -75,7 +75,7 @@ ObcParameters* CpuObc::getObcParameters() const { --------------------------------------------------------------------------------------- */ -void CpuObc::setObcParameters( ObcParameters* obcParameters) { +void ReferenceObc::setObcParameters( ObcParameters* obcParameters) { _obcParameters = obcParameters; } @@ -87,7 +87,7 @@ void CpuObc::setObcParameters( ObcParameters* obcParameters) { --------------------------------------------------------------------------------------- */ -int CpuObc::includeAceApproximation() const { +int ReferenceObc::includeAceApproximation() const { return _includeAceApproximation; } @@ -99,7 +99,7 @@ int CpuObc::includeAceApproximation() const { --------------------------------------------------------------------------------------- */ -void CpuObc::setIncludeAceApproximation(int includeAceApproximation) { +void ReferenceObc::setIncludeAceApproximation(int includeAceApproximation) { _includeAceApproximation = includeAceApproximation; } @@ -111,7 +111,7 @@ void CpuObc::setIncludeAceApproximation(int includeAceApproximation) { --------------------------------------------------------------------------------------- */ -vector& CpuObc::getObcChain() { +vector& ReferenceObc::getObcChain() { return _obcChain; } @@ -127,7 +127,7 @@ vector& CpuObc::getObcChain() { --------------------------------------------------------------------------------------- */ -void CpuObc::computeBornRadii(const vector& atomCoordinates, vector& bornRadii) { +void ReferenceObc::computeBornRadii(const vector& atomCoordinates, vector& bornRadii) { // --------------------------------------------------------------------------------------- @@ -235,7 +235,7 @@ void CpuObc::computeBornRadii(const vector& atomCoordinates, vector& bornRadii, RealOpenMM* energy, vector& forces) const { @@ -293,7 +293,7 @@ void CpuObc::computeAceNonPolarForce(const ObcParameters* obcParameters, --------------------------------------------------------------------------------------- */ -RealOpenMM CpuObc::computeBornEnergyForces(const vector& atomCoordinates, +RealOpenMM ReferenceObc::computeBornEnergyForces(const vector& atomCoordinates, const vector& partialCharges, vector& inputForces) { // --------------------------------------------------------------------------------------- @@ -513,7 +513,7 @@ RealOpenMM CpuObc::computeBornEnergyForces(const vector& atomCoordinate --------------------------------------------------------------------------------------- */ -void CpuObc::printObc(const std::vector& atomCoordinates, +void ReferenceObc::printObc(const std::vector& atomCoordinates, const vector& partialCharges, const vector& bornRadii, const vector& bornForces, diff --git a/platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp b/platforms/reference/src/SimTKReference/SimTKOpenMMUtilities.cpp similarity index 100% rename from platforms/reference/src/SimTKUtilities/SimTKOpenMMUtilities.cpp rename to platforms/reference/src/SimTKReference/SimTKOpenMMUtilities.cpp -- GitLab From f72062af63665571d900d45dd64f7a1474a73e4f Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 16:13:37 -0800 Subject: [PATCH 281/338] Deleted obsolete debugging code --- platforms/reference/include/ReferenceGBVI.h | 20 ----- platforms/reference/include/ReferenceObc.h | 21 ----- .../src/SimTKReference/ReferenceGBVI.cpp | 89 ------------------- .../src/SimTKReference/ReferenceObc.cpp | 85 ------------------ .../tests/TestReferenceCustomGBForce.cpp | 28 ------ .../tests/TestReferenceGBVIForce.cpp | 24 ----- 6 files changed, 267 deletions(-) diff --git a/platforms/reference/include/ReferenceGBVI.h b/platforms/reference/include/ReferenceGBVI.h index 69be5e81e..2f35c26da 100644 --- a/platforms/reference/include/ReferenceGBVI.h +++ b/platforms/reference/include/ReferenceGBVI.h @@ -289,26 +289,6 @@ class ReferenceGBVI { GBVIParameters* gbviParameters, RealOpenMM* bornRadius, RealOpenMM* switchDeriviative); - /**--------------------------------------------------------------------------------------- - - Print GB/VI parameters, radii, forces, ... - - @param atomCoordinates atomic coordinates - @param partialCharges partial charges - @param bornRadii Born radii (may be empty) - @param bornForces Born forces (may be empty) - @param forces forces (may be empty) - @param idString id string (who is calling) - @param log log file - - --------------------------------------------------------------------------------------- */ - - void printGbvi(const std::vector& atomCoordinates, const std::vector& partialCharges, - const std::vector& bornRadii, - const std::vector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log); - }; } // namespace OpenMM diff --git a/platforms/reference/include/ReferenceObc.h b/platforms/reference/include/ReferenceObc.h index f796961c1..92d44154b 100644 --- a/platforms/reference/include/ReferenceObc.h +++ b/platforms/reference/include/ReferenceObc.h @@ -157,27 +157,6 @@ class ReferenceObc { RealOpenMM computeBornEnergyForces(const std::vector& atomCoordinates, const std::vector& partialCharges, std::vector& forces); - - /**--------------------------------------------------------------------------------------- - - Print Obc parameters, radii, forces, ... - - @param atomCoordinates atomic coordinates - @param partialCharges partial charges - @param bornRadii Born radii (may be empty) - @param bornForces Born forces (may be empty) - @param forces forces (may be empty) - @param idString id string (who is calling) - @param log log file - - --------------------------------------------------------------------------------------- */ - - void printObc(const std::vector& atomCoordinates, - const std::vector& partialCharges, - const std::vector& bornRadii, - const std::vector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log); }; diff --git a/platforms/reference/src/SimTKReference/ReferenceGBVI.cpp b/platforms/reference/src/SimTKReference/ReferenceGBVI.cpp index 1daf423f5..da02e2cef 100644 --- a/platforms/reference/src/SimTKReference/ReferenceGBVI.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceGBVI.cpp @@ -720,8 +720,6 @@ void ReferenceGBVI::computeBornForces(std::vector& atomCoordinates, con } } - //printGbvi(atomCoordinates, partialCharges, bornRadii, bornForces, forces, "GBVI: Post loop2", stderr); - // convert from cal to Joule & apply prefactor tau = (1/diel_solute - 1/diel_solvent) RealOpenMM conversion = static_cast(gbviParameters->getTau()); @@ -733,93 +731,6 @@ void ReferenceGBVI::computeBornForces(std::vector& atomCoordinates, con } -/**--------------------------------------------------------------------------------------- - - Print GB/VI parameters, radii, forces, ... - - @param atomCoordinates atomic coordinates - @param partialCharges partial charges - @param bornRadii Born radii (may be empty) - @param bornForces Born forces (may be empty) - @param forces forces (may be empty) - @param idString id string (who is calling) - @param log log file - - --------------------------------------------------------------------------------------- */ - -void ReferenceGBVI::printGbvi(const std::vector& atomCoordinates, const vector& partialCharges, - const vector& bornRadii, - const vector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log) { - - // --------------------------------------------------------------------------------------- - - const GBVIParameters* gbviParameters = getGBVIParameters(); - const int numberOfAtoms = gbviParameters->getNumberOfAtoms(); - const vector& atomicRadii = gbviParameters->getAtomicRadii(); - const vector& gammaParameters = gbviParameters->getGammaParameters(); - - // --------------------------------------------------------------------------------------- - - // constants - - const RealOpenMM preFactor = 2.0*gbviParameters->getElectricConstant(); - - // --------------------------------------------------------------------------------------- - - const vector& scaledRadii = gbviParameters->getScaledRadii(); - const vector& switchDeriviative = getSwitchDeriviative(); - RealOpenMM tau = static_cast(gbviParameters->getTau()); - - int useComparisonFormat = 1; - - (void) fprintf(log, "Reference Gbvi %s atoms=%d\n", idString.c_str(), numberOfAtoms); - (void) fprintf(log, " tau %15.7e\n", tau); - (void) fprintf(log, " scaleMethod %d (QuinticEnum=%d)\n", - _gbviParameters->getBornRadiusScalingMethod(), GBVIParameters::QuinticSpline); - (void) fprintf(log, " preFactor %15.7e)\n", preFactor); - - if (useComparisonFormat) { - (void) fprintf(log, " br bF swd r scR tau*gamma q)\n"); - for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { - (void) fprintf(log, "%6d ", atomI); - if (bornRadii.size() > atomI) { - (void) fprintf(log, "%15.7e ", bornRadii[atomI]); - } - if (bornForces.size() > atomI) { - (void) fprintf(log, "%15.7e ", tau*bornForces[atomI]); - } - (void) fprintf(log, " %15.7e %15.7e %15.7e %15.7e %15.7e", - switchDeriviative[atomI], - atomicRadii[atomI], - scaledRadii[atomI], - tau*gammaParameters[atomI], - partialCharges[atomI]); - (void) fprintf(log, "\n"); - } - } else { - for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { - (void) fprintf(log, "%6d r=%15.7e rSc=%15.7e swd=%15.7e tau*gam=%15.7e q=%15.7e", atomI, - atomicRadii[atomI], - scaledRadii[atomI], - switchDeriviative[atomI], - tau*gammaParameters[atomI], - partialCharges[atomI]); - if (bornRadii.size() > atomI) { - (void) fprintf(log, " bR=%15.7e", bornRadii[atomI]); - } - if (bornForces.size() > atomI) { - (void) fprintf(log, " tau*bF=%15.7e", tau*bornForces[atomI]); - } - (void) fprintf(log, "\n"); - } - } - - return; - -} - /**--------------------------------------------------------------------------------------- Use double precision diff --git a/platforms/reference/src/SimTKReference/ReferenceObc.cpp b/platforms/reference/src/SimTKReference/ReferenceObc.cpp index f139e297d..e9f97db44 100644 --- a/platforms/reference/src/SimTKReference/ReferenceObc.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceObc.cpp @@ -494,90 +494,5 @@ RealOpenMM ReferenceObc::computeBornEnergyForces(const vector& atomCoor } - //printObc(atomCoordinates, partialCharges, bornRadii, bornForces, inputForces, "Obc Post loop2", stderr); - return obcEnergy; } - -/**--------------------------------------------------------------------------------------- - - Print Obc parameters, radii, forces, ... - - @param atomCoordinates atomic coordinates - @param partialCharges partial charges - @param bornRadii Born radii (may be empty) - @param bornForces Born forces (may be empty) - @param forces forces (may be empty) - @param idString id string (who is calling) - @param log log file - - --------------------------------------------------------------------------------------- */ - -void ReferenceObc::printObc(const std::vector& atomCoordinates, - const vector& partialCharges, - const vector& bornRadii, - const vector& bornForces, - const std::vector& forces, - const std::string& idString, FILE* log) { - - // --------------------------------------------------------------------------------------- - - const ObcParameters* obcParameters = getObcParameters(); - const int numberOfAtoms = obcParameters->getNumberOfAtoms(); - const vector& atomicRadii = obcParameters->getAtomicRadii(); - const RealOpenMM preFactor = 2.0*obcParameters->getElectricConstant(); - const vector& obcChain = getObcChain(); - const vector& scaledRadiusFactor = obcParameters->getScaledRadiusFactors(); - - const RealOpenMM alphaObc = obcParameters->getAlphaObc(); - const RealOpenMM betaObc = obcParameters->getBetaObc(); - const RealOpenMM gammaObc = obcParameters->getGammaObc(); - - const int comparisonFormat = 1; - - // --------------------------------------------------------------------------------------- - - (void) fprintf(log, "Reference Obc %s atoms=%d\n", idString.c_str(), numberOfAtoms); - if (comparisonFormat) { - (void) fprintf(log, "Reference Obc %s atoms=%d Chain/Radii/Force\n", idString.c_str(), numberOfAtoms); - for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { - (void) fprintf(log, "%6d ", atomI); - if (obcChain.size() > atomI) { - (void) fprintf(log, " %15.7e", obcChain[atomI]); - } - if (bornRadii.size() > atomI) { - (void) fprintf(log, " %15.7e", bornRadii[atomI]); - } - if (bornForces.size() > atomI) { - (void) fprintf(log, " %15.7e", bornForces[atomI]); - } - (void) fprintf(log, " %15.7e %6.3f", atomicRadii[atomI], partialCharges[atomI]); - (void) fprintf(log, "\n"); - } - } else { - (void) fprintf(log, "Reference Obc %s atoms=%d\n", idString.c_str(), numberOfAtoms); - (void) fprintf(log, " preFactor %15.7e\n", preFactor); - (void) fprintf(log, " alpha %15.7e\n", alphaObc); - (void) fprintf(log, " beta %15.7e\n", betaObc); - (void) fprintf(log, " gamma %15.7e\n", gammaObc); - - for (unsigned int atomI = 0; atomI < static_cast(numberOfAtoms); atomI++) { - (void) fprintf(log, "%6d r=%15.7e q=%6.3f", atomI, - atomicRadii[atomI], partialCharges[atomI]); - if (obcChain.size() > atomI) { - (void) fprintf(log, " bChn=%15.7e", obcChain[atomI]); - } - if (bornRadii.size() > atomI) { - (void) fprintf(log, " bR=%15.7e", bornRadii[atomI]); - } - if (bornForces.size() > atomI) { - (void) fprintf(log, " bF=%15.7e", bornForces[atomI]); - } - (void) fprintf(log, "\n"); - } - } - - return; - -} - diff --git a/platforms/reference/tests/TestReferenceCustomGBForce.cpp b/platforms/reference/tests/TestReferenceCustomGBForce.cpp index b8b4130fe..c3fa72de7 100644 --- a/platforms/reference/tests/TestReferenceCustomGBForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomGBForce.cpp @@ -674,10 +674,6 @@ static void findScaledRadii(GBVIForce& gbviForce, std::vector & scaledRa // load 1-2 atom pairs along w/ bond distance using HarmonicBondForce & constraints // numberOfBonds < 1, indicating they were not set by the user - if (numberOfBonds < 1 && numberOfParticles > 1) { - (void) fprintf(stderr, "Warning: no covalent bonds set for GB/VI force!\n"); - } - std::vector< std::vector > bondIndices; bondIndices.resize(numberOfBonds); @@ -742,9 +738,6 @@ static void findScaledRadii(GBVIForce& gbviForce, std::vector & scaledRa gbviForce.getParticleParameters(j, charge, radiusJ, gamma); if ( bonded12[j].size() == 0) { - if (numberOfParticles > 1) { - (void) fprintf(stderr, "Warning GBVIForceImpl::findScaledRadii atom %d has no covalent bonds; using atomic radius=%.3f.\n", j, radiusJ); - } scaledRadiusJ = radiusJ; // errors++; } @@ -783,7 +776,6 @@ static void findScaledRadii(GBVIForce& gbviForce, std::vector & scaledRa scaledRadiusJ = 0.0; } } - //(void) fprintf(stderr, "scaledRadii %d %12.4f\n", j, scaledRadiusJ); scaledRadii[j] = scaledRadiusJ; } @@ -793,26 +785,6 @@ static void findScaledRadii(GBVIForce& gbviForce, std::vector & scaledRa if (errors) { throw OpenMMException("GBVIForceImpl::findScaledRadii errors -- aborting"); } - -#if GBVIDebug - (void) fprintf(stderr, " R q gamma scaled radii no. bnds\n"); - double totalQ = 0.0; - for (int i = 0; i < (int) scaledRadii.size(); i++) { - - double charge; - double gamma; - double radiusI; - - gbviForce.getParticleParameters(i, charge, radiusI, gamma); - totalQ += charge; - (void) fprintf(stderr, "%4d %14.5e %14.5e %14.5e %14.5e %d\n", i, radiusI, charge, gamma, scaledRadii[i], (int) bonded12[i].size()); - } - (void) fprintf(stderr, "Total charge=%e\n", totalQ); - (void) fflush(stderr); -#endif - -#undef GBVIDebug - } // load parameters from gbviForce to customGbviForce diff --git a/platforms/reference/tests/TestReferenceGBVIForce.cpp b/platforms/reference/tests/TestReferenceGBVIForce.cpp index d926980e3..ed1f782fb 100644 --- a/platforms/reference/tests/TestReferenceGBVIForce.cpp +++ b/platforms/reference/tests/TestReferenceGBVIForce.cpp @@ -53,7 +53,6 @@ using namespace std; const double TOL = 1e-5; void testSingleParticle() { - const int log = 0; ReferencePlatform platform; System system; system.addParticle(2.0); @@ -85,10 +84,6 @@ void testSingleParticle() { double expectedE = (bornEnergy+nonpolarEnergy); double obtainedE = state.getPotentialEnergy(); double diff = fabs((obtainedE - expectedE)/expectedE); - if (log) { - (void) fprintf(stderr, "testSingleParticle expected=%14.6e obtained=%14.6e diff=%14.6e breakdown:[%14.6e %14.6e]\n", - expectedE, obtainedE, diff, bornEnergy, nonpolarEnergy); - } ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01); } @@ -97,7 +92,6 @@ void testEnergyEthane(int applyBornRadiiScaling) { ReferencePlatform platform; const int numParticles = 8; - const int log = 0; System system; LangevinIntegrator integrator(0, 0.1, 0.01); @@ -139,9 +133,6 @@ void testEnergyEthane(int applyBornRadiiScaling) { NonbondedForce* nonbonded = new NonbondedForce(); nonbonded->setNonbondedMethod(NonbondedForce::NoCutoff); - if (log) { - (void) fprintf(stderr, "Applying GB/VI\n"); - } GBVIForce* forceField = new GBVIForce(); if (applyBornRadiiScaling) { forceField->setBornRadiusScalingMethod(GBVIForce::QuinticSpline); @@ -212,9 +203,6 @@ void testEnergyEthane(int applyBornRadiiScaling) { context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); - if (log) { - (void) fprintf(stderr, "Energy %.4e\n", state.getPotentialEnergy()); - } // Take a small step in the direction of the energy gradient. @@ -222,18 +210,12 @@ void testEnergyEthane(int applyBornRadiiScaling) { double forceSum[3] = { 0.0, 0.0, 0.0 }; for (int i = 0; i < numParticles; ++i) { Vec3 f = state.getForces()[i]; - if (log) { - (void) fprintf(stderr, "F %d [%14.6e %14.6e %14.6e]\n", i, f[0], f[1], f[2]); - } norm += f[0]*f[0] + f[1]*f[1] + f[2]*f[2]; forceSum[0] += f[0]; forceSum[1] += f[1]; forceSum[2] += f[2]; } norm = std::sqrt(norm); - if (log) { - (void) fprintf(stderr, "Fsum [%14.6e %14.6e %14.6e] norm=%14.6e\n", forceSum[0], forceSum[1], forceSum[2], norm); - } const double delta = 1e-4; double step = delta/norm; @@ -246,12 +228,6 @@ void testEnergyEthane(int applyBornRadiiScaling) { State state2 = context.getState(State::Energy); - if (log) { - double deltaE = fabs(state.getPotentialEnergy() - state2.getPotentialEnergy())/delta; - double diff = (deltaE - norm)/norm; - (void) fprintf(stderr, "Energies %.8e %.8e deltaE=%14.7e %14.7e diff=%14.7e\n", state.getPotentialEnergy(), state2.getPotentialEnergy(), deltaE, norm, diff); - } - // See whether the potential energy changed by the expected amount. ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/delta, 0.01) -- GitLab From 25a308e68a4d24571c85e83adee3f0ba1fbc56c9 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 16:21:41 -0800 Subject: [PATCH 282/338] Moved AMOEBA reference code into OpenMM namespace --- .../src/SimTKReference/AmoebaReferenceAngleForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferenceAngleForce.h | 4 ++-- .../src/SimTKReference/AmoebaReferenceBondForce.cpp | 2 +- .../reference/src/SimTKReference/AmoebaReferenceBondForce.h | 4 ++-- .../reference/src/SimTKReference/AmoebaReferenceForce.cpp | 2 +- .../reference/src/SimTKReference/AmoebaReferenceForce.h | 4 ++-- .../AmoebaReferenceGeneralizedKirkwoodForce.cpp | 2 +- .../AmoebaReferenceGeneralizedKirkwoodForce.h | 4 +++- .../src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h | 4 ++-- .../src/SimTKReference/AmoebaReferenceMultipoleForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferenceMultipoleForce.h | 4 ++++ .../SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h | 4 ++-- .../src/SimTKReference/AmoebaReferencePiTorsionForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferencePiTorsionForce.h | 4 ++-- .../src/SimTKReference/AmoebaReferenceStretchBendForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferenceStretchBendForce.h | 4 ++-- .../SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h | 4 ++-- .../SimTKReference/AmoebaReferenceWcaDispersionForce.cpp | 2 +- .../src/SimTKReference/AmoebaReferenceWcaDispersionForce.h | 6 ++---- 22 files changed, 36 insertions(+), 32 deletions(-) diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp index 4fdc3f1a3..50728bfd3 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp @@ -26,7 +26,7 @@ #include "AmoebaReferenceAngleForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h index 17ae0ca05..84395d991 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceAngleForce { @@ -137,6 +137,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceAngleForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp index 3a138aea9..289ddaae0 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp @@ -26,7 +26,7 @@ #include "AmoebaReferenceForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h index a4821a911..da93661b5 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceBondForce { @@ -102,6 +102,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceBondForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp index c363362ca..8988d8448 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp @@ -25,7 +25,7 @@ #include "AmoebaReferenceForce.h" #include -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h index 76845999a..522ed9546 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h @@ -29,7 +29,7 @@ #include "openmm/Vec3.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceForce { @@ -137,6 +137,6 @@ public: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp index c751909fb..4db10918d 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp @@ -24,7 +24,7 @@ #include "AmoebaReferenceGeneralizedKirkwoodForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; AmoebaReferenceGeneralizedKirkwoodForce::AmoebaReferenceGeneralizedKirkwoodForce( ) : _numParticles(0), _includeCavityTerm(1), diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h index 12b485c61..9cb351626 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h @@ -31,7 +31,7 @@ using namespace OpenMM; using namespace std; -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceGeneralizedKirkwoodForce { @@ -251,4 +251,6 @@ private: }; +} // namespace OpenMM + #endif // _AmoebaReferenceGeneralizedKirkwoodForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp index fa84a6679..b1d4c228d 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp @@ -26,7 +26,7 @@ #include "AmoebaReferenceInPlaneAngleForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h index 9f5689a7d..352cda4fb 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceInPlaneAngleForce { @@ -140,6 +140,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceInPlaneAngleForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp index f21d20951..d2bdb8288 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp @@ -31,7 +31,7 @@ #include "openmm/internal/MSVC_erfc.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; #undef AMOEBA_DEBUG diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h index 2d065e995..048549a49 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h @@ -31,6 +31,8 @@ #include "fftpack.h" #include +namespace OpenMM { + typedef std::map< unsigned int, RealOpenMM> MapIntRealOpenMM; typedef MapIntRealOpenMM::iterator MapIntRealOpenMMI; typedef MapIntRealOpenMM::const_iterator MapIntRealOpenMMCI; @@ -1664,4 +1666,6 @@ private: }; +} // namespace OpenMM + #endif // _AmoebaReferenceMultipoleForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp index c26886d22..a2838e301 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp @@ -26,7 +26,7 @@ #include "AmoebaReferenceOutOfPlaneBendForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h index faef32628..ce08fe510 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceOutOfPlaneBendForce { @@ -114,6 +114,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceOutOfPlaneBendForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp index de9e68cf5..df480a9d5 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp @@ -27,7 +27,7 @@ #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h index 384209c86..de8c29424 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferencePiTorsionForce { @@ -109,6 +109,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferencePiTorsionForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp index 68d26e85b..9802e423f 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp @@ -27,7 +27,7 @@ #include using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h index 78cba2c01..ee4ece712 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceStretchBendForce { @@ -110,6 +110,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceStretchBendForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp index 851daed5b..39074a455 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp @@ -26,7 +26,7 @@ #include "AmoebaReferenceTorsionTorsionForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h index 63a386b23..a0a8dbadf 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h @@ -28,7 +28,7 @@ #include "RealVec.h" #include -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceTorsionTorsionForce { @@ -212,6 +212,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceTorsionTorsionForce___ diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp index ca143de0e..3b69d0e2a 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp @@ -26,7 +26,7 @@ #include "AmoebaReferenceWcaDispersionForce.h" using std::vector; -using OpenMM::RealVec; +using namespace OpenMM; AmoebaReferenceWcaDispersionForce::AmoebaReferenceWcaDispersionForce( RealOpenMM epso, RealOpenMM epsh, RealOpenMM rmino, RealOpenMM rminh, RealOpenMM awater, RealOpenMM shctd, RealOpenMM dispoff, RealOpenMM slevy ) : diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h index 40b0feea5..02248870f 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h @@ -30,9 +30,7 @@ #include #include -using namespace OpenMM; - -// --------------------------------------------------------------------------------------- +namespace OpenMM { class AmoebaReferenceWcaDispersionForce { @@ -118,6 +116,6 @@ private: }; -// --------------------------------------------------------------------------------------- +} // namespace OpenMM #endif // _AmoebaReferenceWcaDispersionForce___ -- GitLab From 41cd79a5b4af0bb49ce61e4eef5b84691cca6d52 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 16:53:05 -0800 Subject: [PATCH 283/338] Cleaned up formatting of AMOEBA reference code --- .../reference/src/AmoebaReferenceKernels.cpp | 396 +- .../reference/src/AmoebaReferenceKernels.h | 28 +- .../AmoebaReferenceAngleForce.cpp | 62 +- .../AmoebaReferenceAngleForce.h | 46 +- .../AmoebaReferenceBondForce.cpp | 22 +- .../SimTKReference/AmoebaReferenceBondForce.h | 26 +- .../SimTKReference/AmoebaReferenceForce.cpp | 52 +- .../src/SimTKReference/AmoebaReferenceForce.h | 32 +- ...moebaReferenceGeneralizedKirkwoodForce.cpp | 92 +- .../AmoebaReferenceGeneralizedKirkwoodForce.h | 50 +- .../AmoebaReferenceInPlaneAngleForce.cpp | 122 +- .../AmoebaReferenceInPlaneAngleForce.h | 48 +- .../AmoebaReferenceMultipoleForce.cpp | 6 +- .../AmoebaReferenceMultipoleForce.h | 2 +- .../AmoebaReferenceOutOfPlaneBendForce.cpp | 80 +- .../AmoebaReferenceOutOfPlaneBendForce.h | 38 +- .../AmoebaReferencePiTorsionForce.cpp | 112 +- .../AmoebaReferencePiTorsionForce.h | 30 +- .../AmoebaReferenceStretchBendForce.cpp | 62 +- .../AmoebaReferenceStretchBendForce.h | 34 +- .../AmoebaReferenceTorsionTorsionForce.cpp | 212 +- .../AmoebaReferenceTorsionTorsionForce.h | 46 +- .../AmoebaReferenceVdwForce.cpp | 188 +- .../SimTKReference/AmoebaReferenceVdwForce.h | 84 +- .../AmoebaReferenceWcaDispersionForce.cpp | 68 +- .../AmoebaReferenceWcaDispersionForce.h | 22 +- .../tests/TestReferenceAmoebaAngleForce.cpp | 132 +- .../tests/TestReferenceAmoebaBondForce.cpp | 86 +- ...eferenceAmoebaGeneralizedKirkwoodForce.cpp | 516 +-- .../TestReferenceAmoebaInPlaneAngleForce.cpp | 174 +- .../TestReferenceAmoebaMultipoleForce.cpp | 3684 ++++++++--------- ...TestReferenceAmoebaOutOfPlaneBendForce.cpp | 320 +- .../TestReferenceAmoebaPiTorsionForce.cpp | 162 +- .../TestReferenceAmoebaStretchBendForce.cpp | 128 +- ...TestReferenceAmoebaTorsionTorsionForce.cpp | 78 +- .../tests/TestReferenceAmoebaVdwForce.cpp | 3094 +++++++------- .../tests/TestReferenceWcaDispersionForce.cpp | 88 +- 37 files changed, 5211 insertions(+), 5211 deletions(-) diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp index 1483c0199..5adaba8b9 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp @@ -91,16 +91,16 @@ ReferenceCalcAmoebaBondForceKernel::~ReferenceCalcAmoebaBondForceKernel() { void ReferenceCalcAmoebaBondForceKernel::initialize(const System& system, const AmoebaBondForce& force) { numBonds = force.getNumBonds(); - for( int ii = 0; ii < numBonds; ii++) { + for (int ii = 0; ii < numBonds; ii++) { int particle1Index, particle2Index; double lengthValue, kValue; - force.getBondParameters(ii, particle1Index, particle2Index, lengthValue, kValue ); + force.getBondParameters(ii, particle1Index, particle2Index, lengthValue, kValue); - particle1.push_back( particle1Index ); - particle2.push_back( particle2Index ); - length.push_back( static_cast( lengthValue ) ); - kQuadratic.push_back( static_cast( kValue ) ); + particle1.push_back(particle1Index); + particle2.push_back(particle2Index); + length.push_back( static_cast(lengthValue)); + kQuadratic.push_back(static_cast(kValue)); } globalBondCubic = static_cast(force.getAmoebaGlobalBondCubic()); globalBondQuartic = static_cast(force.getAmoebaGlobalBondQuartic()); @@ -110,9 +110,9 @@ double ReferenceCalcAmoebaBondForceKernel::execute(ContextImpl& context, bool in vector& posData = extractPositions(context); vector& forceData = extractForces(context); AmoebaReferenceBondForce amoebaReferenceBondForce; - RealOpenMM energy = amoebaReferenceBondForce.calculateForceAndEnergy( numBonds, posData, particle1, particle2, length, kQuadratic, + RealOpenMM energy = amoebaReferenceBondForce.calculateForceAndEnergy(numBonds, posData, particle1, particle2, length, kQuadratic, globalBondCubic, globalBondQuartic, - forceData ); + forceData); return static_cast(energy); } @@ -150,11 +150,11 @@ void ReferenceCalcAmoebaAngleForceKernel::initialize(const System& system, const int particle1Index, particle2Index, particle3Index; double angleValue, k; force.getAngleParameters(ii, particle1Index, particle2Index, particle3Index, angleValue, k); - particle1.push_back( particle1Index ); - particle2.push_back( particle2Index ); - particle3.push_back( particle3Index ); - angle.push_back( static_cast( angleValue ) ); - kQuadratic.push_back( static_cast( k) ); + particle1.push_back(particle1Index); + particle2.push_back(particle2Index); + particle3.push_back(particle3Index); + angle.push_back( static_cast(angleValue)); + kQuadratic.push_back(static_cast(k)); } globalAngleCubic = static_cast(force.getAmoebaGlobalAngleCubic()); globalAngleQuartic = static_cast(force.getAmoebaGlobalAngleQuartic()); @@ -166,8 +166,8 @@ double ReferenceCalcAmoebaAngleForceKernel::execute(ContextImpl& context, bool i vector& posData = extractPositions(context); vector& forceData = extractForces(context); AmoebaReferenceAngleForce amoebaReferenceAngleForce; - RealOpenMM energy = amoebaReferenceAngleForce.calculateForceAndEnergy( numAngles, - posData, particle1, particle2, particle3, angle, kQuadratic, globalAngleCubic, globalAngleQuartic, globalAnglePentic, globalAngleSextic, forceData ); + RealOpenMM energy = amoebaReferenceAngleForce.calculateForceAndEnergy(numAngles, + posData, particle1, particle2, particle3, angle, kQuadratic, globalAngleCubic, globalAngleQuartic, globalAnglePentic, globalAngleSextic, forceData); return static_cast(energy); } @@ -202,12 +202,12 @@ void ReferenceCalcAmoebaInPlaneAngleForceKernel::initialize(const System& system int particle1Index, particle2Index, particle3Index, particle4Index; double angleValue, k; force.getAngleParameters(ii, particle1Index, particle2Index, particle3Index, particle4Index, angleValue, k); - particle1.push_back( particle1Index ); - particle2.push_back( particle2Index ); - particle3.push_back( particle3Index ); - particle4.push_back( particle4Index ); - angle.push_back( static_cast( angleValue ) ); - kQuadratic.push_back( static_cast( k ) ); + particle1.push_back(particle1Index); + particle2.push_back(particle2Index); + particle3.push_back(particle3Index); + particle4.push_back(particle4Index); + angle.push_back( static_cast(angleValue)); + kQuadratic.push_back( static_cast(k)); } globalInPlaneAngleCubic = static_cast(force.getAmoebaGlobalInPlaneAngleCubic()); globalInPlaneAngleQuartic = static_cast(force.getAmoebaGlobalInPlaneAngleQuartic()); @@ -220,9 +220,9 @@ double ReferenceCalcAmoebaInPlaneAngleForceKernel::execute(ContextImpl& context, vector& posData = extractPositions(context); vector& forceData = extractForces(context); AmoebaReferenceInPlaneAngleForce amoebaReferenceInPlaneAngleForce; - RealOpenMM energy = amoebaReferenceInPlaneAngleForce.calculateForceAndEnergy( numAngles, posData, particle1, particle2, particle3, particle4, + RealOpenMM energy = amoebaReferenceInPlaneAngleForce.calculateForceAndEnergy(numAngles, posData, particle1, particle2, particle3, particle4, angle, kQuadratic, globalInPlaneAngleCubic, globalInPlaneAngleQuartic, - globalInPlaneAnglePentic, globalInPlaneAngleSextic, forceData ); + globalInPlaneAnglePentic, globalInPlaneAngleSextic, forceData); return static_cast(energy); } @@ -257,14 +257,14 @@ void ReferenceCalcAmoebaPiTorsionForceKernel::initialize(const System& system, c int particle1Index, particle2Index, particle3Index, particle4Index, particle5Index, particle6Index; double kTorsionParameter; - force.getPiTorsionParameters(ii, particle1Index, particle2Index, particle3Index, particle4Index, particle5Index, particle6Index, kTorsionParameter ); - particle1.push_back( particle1Index ); - particle2.push_back( particle2Index ); - particle3.push_back( particle3Index ); - particle4.push_back( particle4Index ); - particle5.push_back( particle5Index ); - particle6.push_back( particle6Index ); - kTorsion.push_back( static_cast(kTorsionParameter) ); + force.getPiTorsionParameters(ii, particle1Index, particle2Index, particle3Index, particle4Index, particle5Index, particle6Index, kTorsionParameter); + particle1.push_back(particle1Index); + particle2.push_back(particle2Index); + particle3.push_back(particle3Index); + particle4.push_back(particle4Index); + particle5.push_back(particle5Index); + particle6.push_back(particle6Index); + kTorsion.push_back(static_cast(kTorsionParameter)); } } @@ -272,9 +272,9 @@ double ReferenceCalcAmoebaPiTorsionForceKernel::execute(ContextImpl& context, bo vector& posData = extractPositions(context); vector& forceData = extractForces(context); AmoebaReferencePiTorsionForce amoebaReferencePiTorsionForce; - RealOpenMM energy = amoebaReferencePiTorsionForce.calculateForceAndEnergy( numPiTorsions, posData, particle1, particle2, + RealOpenMM energy = amoebaReferencePiTorsionForce.calculateForceAndEnergy(numPiTorsions, posData, particle1, particle2, particle3, particle4, particle5, particle6, - kTorsion, forceData ); + kTorsion, forceData); return static_cast(energy); } @@ -305,18 +305,18 @@ ReferenceCalcAmoebaStretchBendForceKernel::~ReferenceCalcAmoebaStretchBendForceK void ReferenceCalcAmoebaStretchBendForceKernel::initialize(const System& system, const AmoebaStretchBendForce& force) { numStretchBends = force.getNumStretchBends(); - for ( int ii = 0; ii < numStretchBends; ii++) { + for (int ii = 0; ii < numStretchBends; ii++) { int particle1Index, particle2Index, particle3Index; double lengthAB, lengthCB, angle, k1, k2; force.getStretchBendParameters(ii, particle1Index, particle2Index, particle3Index, lengthAB, lengthCB, angle, k1, k2); - particle1.push_back( particle1Index ); - particle2.push_back( particle2Index ); - particle3.push_back( particle3Index ); - lengthABParameters.push_back( static_cast(lengthAB) ); - lengthCBParameters.push_back( static_cast(lengthCB) ); - angleParameters.push_back( static_cast(angle) ); - k1Parameters.push_back( static_cast(k1) ); - k2Parameters.push_back( static_cast(k2) ); + particle1.push_back(particle1Index); + particle2.push_back(particle2Index); + particle3.push_back(particle3Index); + lengthABParameters.push_back(static_cast(lengthAB)); + lengthCBParameters.push_back(static_cast(lengthCB)); + angleParameters.push_back( static_cast(angle)); + k1Parameters.push_back( static_cast(k1)); + k2Parameters.push_back( static_cast(k2)); } } @@ -324,9 +324,9 @@ double ReferenceCalcAmoebaStretchBendForceKernel::execute(ContextImpl& context, vector& posData = extractPositions(context); vector& forceData = extractForces(context); AmoebaReferenceStretchBendForce amoebaReferenceStretchBendForce; - RealOpenMM energy = amoebaReferenceStretchBendForce.calculateForceAndEnergy( numStretchBends, posData, particle1, particle2, particle3, + RealOpenMM energy = amoebaReferenceStretchBendForce.calculateForceAndEnergy(numStretchBends, posData, particle1, particle2, particle3, lengthABParameters, lengthCBParameters, angleParameters, k1Parameters, - k2Parameters, forceData ); + k2Parameters, forceData); return static_cast(energy); } @@ -366,16 +366,16 @@ void ReferenceCalcAmoebaOutOfPlaneBendForceKernel::initialize(const System& syst double k; force.getOutOfPlaneBendParameters(ii, particle1Index, particle2Index, particle3Index, particle4Index, k); - particle1.push_back( particle1Index ); - particle2.push_back( particle2Index ); - particle3.push_back( particle3Index ); - particle4.push_back( particle4Index ); - kParameters.push_back( static_cast(k) ); + particle1.push_back(particle1Index); + particle2.push_back(particle2Index); + particle3.push_back(particle3Index); + particle4.push_back(particle4Index); + kParameters.push_back(static_cast(k)); } - globalOutOfPlaneBendAngleCubic = static_cast( force.getAmoebaGlobalOutOfPlaneBendCubic()); - globalOutOfPlaneBendAngleQuartic = static_cast( force.getAmoebaGlobalOutOfPlaneBendQuartic()); - globalOutOfPlaneBendAnglePentic = static_cast( force.getAmoebaGlobalOutOfPlaneBendPentic()); - globalOutOfPlaneBendAngleSextic = static_cast( force.getAmoebaGlobalOutOfPlaneBendSextic()); + globalOutOfPlaneBendAngleCubic = static_cast(force.getAmoebaGlobalOutOfPlaneBendCubic()); + globalOutOfPlaneBendAngleQuartic = static_cast(force.getAmoebaGlobalOutOfPlaneBendQuartic()); + globalOutOfPlaneBendAnglePentic = static_cast(force.getAmoebaGlobalOutOfPlaneBendPentic()); + globalOutOfPlaneBendAngleSextic = static_cast(force.getAmoebaGlobalOutOfPlaneBendSextic()); } @@ -383,13 +383,13 @@ double ReferenceCalcAmoebaOutOfPlaneBendForceKernel::execute(ContextImpl& contex vector& posData = extractPositions(context); vector& forceData = extractForces(context); AmoebaReferenceOutOfPlaneBendForce amoebaReferenceOutOfPlaneBendForce; - RealOpenMM energy = amoebaReferenceOutOfPlaneBendForce.calculateForceAndEnergy( numOutOfPlaneBends, posData, + RealOpenMM energy = amoebaReferenceOutOfPlaneBendForce.calculateForceAndEnergy(numOutOfPlaneBends, posData, particle1, particle2, particle3, particle4, kParameters, globalOutOfPlaneBendAngleCubic, globalOutOfPlaneBendAngleQuartic, globalOutOfPlaneBendAnglePentic, - globalOutOfPlaneBendAngleSextic, forceData ); + globalOutOfPlaneBendAngleSextic, forceData); return static_cast(energy); } @@ -426,13 +426,13 @@ void ReferenceCalcAmoebaTorsionTorsionForceKernel::initialize(const System& syst int particle1Index, particle2Index, particle3Index, particle4Index, particle5Index, chiralCheckAtomIndex, gridIndex; force.getTorsionTorsionParameters(ii, particle1Index, particle2Index, particle3Index, particle4Index, particle5Index, chiralCheckAtomIndex, gridIndex); - particle1.push_back( particle1Index ); - particle2.push_back( particle2Index ); - particle3.push_back( particle3Index ); - particle4.push_back( particle4Index ); - particle5.push_back( particle5Index ); - chiralCheckAtom.push_back( chiralCheckAtomIndex ); - gridIndices.push_back( gridIndex ); + particle1.push_back(particle1Index); + particle2.push_back(particle2Index); + particle3.push_back(particle3Index); + particle4.push_back(particle4Index); + particle5.push_back(particle5Index); + chiralCheckAtom.push_back(chiralCheckAtomIndex); + gridIndices.push_back(gridIndex); } // torsion-torsion grids @@ -441,25 +441,25 @@ void ReferenceCalcAmoebaTorsionTorsionForceKernel::initialize(const System& syst torsionTorsionGrids.resize(numTorsionTorsionGrids); for (int ii = 0; ii < numTorsionTorsionGrids; ii++) { - const TorsionTorsionGrid grid = force.getTorsionTorsionGrid( ii ); - torsionTorsionGrids[ii].resize( grid.size() ); + const TorsionTorsionGrid grid = force.getTorsionTorsionGrid(ii); + torsionTorsionGrids[ii].resize(grid.size()); // check if grid needs to be reordered: x-angle should be 'slow' index TorsionTorsionGrid reorderedGrid; int reorder = 0; - if( grid[0][0][0] != grid[0][1][0] ){ - AmoebaTorsionTorsionForceImpl::reorderGrid( grid, reorderedGrid ); + if (grid[0][0][0] != grid[0][1][0]) { + AmoebaTorsionTorsionForceImpl::reorderGrid(grid, reorderedGrid); reorder = 1; } for (unsigned int kk = 0; kk < grid.size(); kk++) { - torsionTorsionGrids[ii][kk].resize( grid[kk].size() ); + torsionTorsionGrids[ii][kk].resize(grid[kk].size()); for (unsigned int jj = 0; jj < grid[kk].size(); jj++) { - torsionTorsionGrids[ii][kk][jj].resize( grid[kk][jj].size() ); - if( reorder ){ + torsionTorsionGrids[ii][kk][jj].resize(grid[kk][jj].size()); + if (reorder) { for (unsigned int ll = 0; ll < grid[ll][jj].size(); ll++) { torsionTorsionGrids[ii][kk][jj][ll] = static_cast(reorderedGrid[kk][jj][ll]); } @@ -478,9 +478,9 @@ double ReferenceCalcAmoebaTorsionTorsionForceKernel::execute(ContextImpl& contex vector& posData = extractPositions(context); vector& forceData = extractForces(context); AmoebaReferenceTorsionTorsionForce amoebaReferenceTorsionTorsionForce; - RealOpenMM energy = amoebaReferenceTorsionTorsionForce.calculateForceAndEnergy( numTorsionTorsions, posData, + RealOpenMM energy = amoebaReferenceTorsionTorsionForce.calculateForceAndEnergy(numTorsionTorsions, posData, particle1, particle2, particle3, particle4, particle5, - chiralCheckAtom, gridIndices, torsionTorsionGrids, forceData ); + chiralCheckAtom, gridIndices, torsionTorsionGrids, forceData); return static_cast(energy); } @@ -517,7 +517,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c int quadrupoleIndex = 0; int maxCovalentRange = 0; double totalCharge = 0.0; - for( int ii = 0; ii < numMultipoles; ii++ ){ + for (int ii = 0; ii < numMultipoles; ii++) { // multipoles @@ -526,7 +526,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c std::vector dipolesD; std::vector quadrupolesD; force.getMultipoleParameters(ii, charge, dipolesD, quadrupolesD, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, - tholeD, dampingFactorD, polarityD ); + tholeD, dampingFactorD, polarityD); totalCharge += charge; axisTypes[ii] = axisType; @@ -556,13 +556,13 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c // covalent info std::vector< std::vector > covalentLists; - force.getCovalentMaps(ii, covalentLists ); + force.getCovalentMaps(ii, covalentLists); multipoleAtomCovalentInfo[ii] = covalentLists; } polarizationType = force.getPolarizationType(); - if( polarizationType == AmoebaMultipoleForce::Mutual ){ + if (polarizationType == AmoebaMultipoleForce::Mutual) { mutualInducedMaxIterations = force.getMutualInducedMaxIterations(); mutualInducedTargetEpsilon = force.getMutualInducedTargetEpsilon(); } @@ -570,7 +570,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c // PME nonbondedMethod = force.getNonbondedMethod(); - if( nonbondedMethod == AmoebaMultipoleForce::PME ){ + if (nonbondedMethod == AmoebaMultipoleForce::PME) { usePme = true; alphaEwald = force.getAEwald(); cutoffDistance = force.getCutoffDistance(); @@ -591,7 +591,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::initialize(const System& system, c return; } -AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmoebaReferenceMultipoleForce(ContextImpl& context ) +AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmoebaReferenceMultipoleForce(ContextImpl& context) { // amoebaReferenceMultipoleForce is set to AmoebaReferenceGeneralizedKirkwoodForce if AmoebaGeneralizedKirkwoodForce is present @@ -609,66 +609,66 @@ AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmo } AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = NULL; - if( gkKernel ){ + if (gkKernel) { // amoebaReferenceGeneralizedKirkwoodForce is deleted in AmoebaReferenceGeneralizedKirkwoodMultipoleForce // destructor AmoebaReferenceGeneralizedKirkwoodForce* amoebaReferenceGeneralizedKirkwoodForce = new AmoebaReferenceGeneralizedKirkwoodForce(); - amoebaReferenceGeneralizedKirkwoodForce->setNumParticles( gkKernel->getNumParticles() ); - amoebaReferenceGeneralizedKirkwoodForce->setSoluteDielectric( gkKernel->getSoluteDielectric() ); - amoebaReferenceGeneralizedKirkwoodForce->setSolventDielectric( gkKernel->getSolventDielectric() ); - amoebaReferenceGeneralizedKirkwoodForce->setDielectricOffset( gkKernel->getDielectricOffset() ); - amoebaReferenceGeneralizedKirkwoodForce->setProbeRadius( gkKernel->getProbeRadius() ); - amoebaReferenceGeneralizedKirkwoodForce->setSurfaceAreaFactor( gkKernel->getSurfaceAreaFactor() ); - amoebaReferenceGeneralizedKirkwoodForce->setIncludeCavityTerm( gkKernel->getIncludeCavityTerm() ); - amoebaReferenceGeneralizedKirkwoodForce->setDirectPolarization( gkKernel->getDirectPolarization() ); + amoebaReferenceGeneralizedKirkwoodForce->setNumParticles(gkKernel->getNumParticles()); + amoebaReferenceGeneralizedKirkwoodForce->setSoluteDielectric(gkKernel->getSoluteDielectric()); + amoebaReferenceGeneralizedKirkwoodForce->setSolventDielectric(gkKernel->getSolventDielectric()); + amoebaReferenceGeneralizedKirkwoodForce->setDielectricOffset(gkKernel->getDielectricOffset()); + amoebaReferenceGeneralizedKirkwoodForce->setProbeRadius(gkKernel->getProbeRadius()); + amoebaReferenceGeneralizedKirkwoodForce->setSurfaceAreaFactor(gkKernel->getSurfaceAreaFactor()); + amoebaReferenceGeneralizedKirkwoodForce->setIncludeCavityTerm(gkKernel->getIncludeCavityTerm()); + amoebaReferenceGeneralizedKirkwoodForce->setDirectPolarization(gkKernel->getDirectPolarization()); vector parameters; - gkKernel->getAtomicRadii( parameters ); - amoebaReferenceGeneralizedKirkwoodForce->setAtomicRadii( parameters ); + gkKernel->getAtomicRadii(parameters); + amoebaReferenceGeneralizedKirkwoodForce->setAtomicRadii(parameters); - gkKernel->getScaleFactors( parameters ); - amoebaReferenceGeneralizedKirkwoodForce->setScaleFactors( parameters ); + gkKernel->getScaleFactors(parameters); + amoebaReferenceGeneralizedKirkwoodForce->setScaleFactors(parameters); - gkKernel->getCharges( parameters ); - amoebaReferenceGeneralizedKirkwoodForce->setCharges( parameters ); + gkKernel->getCharges(parameters); + amoebaReferenceGeneralizedKirkwoodForce->setCharges(parameters); // calculate Grycuk Born radii vector& posData = extractPositions(context); - amoebaReferenceGeneralizedKirkwoodForce->calculateGrycukBornRadii( posData ); + amoebaReferenceGeneralizedKirkwoodForce->calculateGrycukBornRadii(posData); - amoebaReferenceMultipoleForce = new AmoebaReferenceGeneralizedKirkwoodMultipoleForce( amoebaReferenceGeneralizedKirkwoodForce ); + amoebaReferenceMultipoleForce = new AmoebaReferenceGeneralizedKirkwoodMultipoleForce(amoebaReferenceGeneralizedKirkwoodForce); - } else if( usePme ) { + } else if (usePme) { - AmoebaReferencePmeMultipoleForce* amoebaReferencePmeMultipoleForce = new AmoebaReferencePmeMultipoleForce( ); - amoebaReferencePmeMultipoleForce->setAlphaEwald( alphaEwald ); - amoebaReferencePmeMultipoleForce->setCutoffDistance( cutoffDistance ); - amoebaReferencePmeMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + AmoebaReferencePmeMultipoleForce* amoebaReferencePmeMultipoleForce = new AmoebaReferencePmeMultipoleForce(); + amoebaReferencePmeMultipoleForce->setAlphaEwald(alphaEwald); + amoebaReferencePmeMultipoleForce->setCutoffDistance(cutoffDistance); + amoebaReferencePmeMultipoleForce->setPmeGridDimensions(pmeGridDimension); RealVec* boxVectors = extractBoxVectors(context); double minAllowedSize = 1.999999*cutoffDistance; - if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize){ + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) { throw OpenMMException("The periodic box size has decreased to less than twice the nonbonded cutoff."); } amoebaReferencePmeMultipoleForce->setPeriodicBoxSize(boxVectors); amoebaReferenceMultipoleForce = static_cast(amoebaReferencePmeMultipoleForce); } else { - amoebaReferenceMultipoleForce = new AmoebaReferenceMultipoleForce( AmoebaReferenceMultipoleForce::NoCutoff ); + amoebaReferenceMultipoleForce = new AmoebaReferenceMultipoleForce(AmoebaReferenceMultipoleForce::NoCutoff); } // set polarization type - if( polarizationType == AmoebaMultipoleForce::Mutual ){ - amoebaReferenceMultipoleForce->setPolarizationType( AmoebaReferenceMultipoleForce::Mutual ); - amoebaReferenceMultipoleForce->setMutualInducedDipoleTargetEpsilon( mutualInducedTargetEpsilon ); - amoebaReferenceMultipoleForce->setMaximumMutualInducedDipoleIterations( mutualInducedMaxIterations ); - } else if( polarizationType == AmoebaMultipoleForce::Direct ){ - amoebaReferenceMultipoleForce->setPolarizationType( AmoebaReferenceMultipoleForce::Direct ); + if (polarizationType == AmoebaMultipoleForce::Mutual) { + amoebaReferenceMultipoleForce->setPolarizationType(AmoebaReferenceMultipoleForce::Mutual); + amoebaReferenceMultipoleForce->setMutualInducedDipoleTargetEpsilon(mutualInducedTargetEpsilon); + amoebaReferenceMultipoleForce->setMaximumMutualInducedDipoleIterations(mutualInducedMaxIterations); + } else if (polarizationType == AmoebaMultipoleForce::Direct) { + amoebaReferenceMultipoleForce->setPolarizationType(AmoebaReferenceMultipoleForce::Direct); } else { - throw OpenMMException("Polarization type not recognzied." ); + throw OpenMMException("Polarization type not recognzied."); } return amoebaReferenceMultipoleForce; @@ -677,11 +677,11 @@ AmoebaReferenceMultipoleForce* ReferenceCalcAmoebaMultipoleForceKernel::setupAmo double ReferenceCalcAmoebaMultipoleForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { - AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce( context ); + AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce(context); vector& posData = extractPositions(context); vector& forceData = extractForces(context); - RealOpenMM energy = amoebaReferenceMultipoleForce->calculateForceAndEnergy( posData, charges, dipoles, quadrupoles, tholes, + RealOpenMM energy = amoebaReferenceMultipoleForce->calculateForceAndEnergy(posData, charges, dipoles, quadrupoles, tholes, dampingFactors, polarity, axisTypes, multipoleAtomZs, multipoleAtomXs, multipoleAtomYs, multipoleAtomCovalentInfo, forceData); @@ -697,7 +697,7 @@ void ReferenceCalcAmoebaMultipoleForceKernel::getInducedDipoles(ContextImpl& con // Create an AmoebaReferenceMultipoleForce to do the calculation. - AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce( context ); + AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce(context); vector& posData = extractPositions(context); // Retrieve the induced dipoles. @@ -711,44 +711,44 @@ void ReferenceCalcAmoebaMultipoleForceKernel::getInducedDipoles(ContextImpl& con } void ReferenceCalcAmoebaMultipoleForceKernel::getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, - std::vector< double >& outputElectrostaticPotential ){ + std::vector< double >& outputElectrostaticPotential) { - AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce( context ); + AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce(context); vector& posData = extractPositions(context); - vector grid( inputGrid.size() ); - vector potential( inputGrid.size() ); - for( unsigned int ii = 0; ii < inputGrid.size(); ii++ ){ + vector grid(inputGrid.size()); + vector potential(inputGrid.size()); + for (unsigned int ii = 0; ii < inputGrid.size(); ii++) { grid[ii] = inputGrid[ii]; } - amoebaReferenceMultipoleForce->calculateElectrostaticPotential( posData, charges, dipoles, quadrupoles, tholes, - dampingFactors, polarity, axisTypes, - multipoleAtomZs, multipoleAtomXs, multipoleAtomYs, - multipoleAtomCovalentInfo, grid, potential ); + amoebaReferenceMultipoleForce->calculateElectrostaticPotential(posData, charges, dipoles, quadrupoles, tholes, + dampingFactors, polarity, axisTypes, + multipoleAtomZs, multipoleAtomXs, multipoleAtomYs, + multipoleAtomCovalentInfo, grid, potential); - outputElectrostaticPotential.resize( inputGrid.size() ); - for( unsigned int ii = 0; ii < inputGrid.size(); ii++ ){ + outputElectrostaticPotential.resize(inputGrid.size()); + for (unsigned int ii = 0; ii < inputGrid.size(); ii++) { outputElectrostaticPotential[ii] = potential[ii]; } delete amoebaReferenceMultipoleForce; } -void ReferenceCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments){ +void ReferenceCalcAmoebaMultipoleForceKernel::getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments) { // retrieve masses const System& system = context.getSystem(); vector masses; for (int i = 0; i < system.getNumParticles(); ++i) { - masses.push_back( static_cast(system.getParticleMass(i)) ); + masses.push_back(static_cast(system.getParticleMass(i))); } - AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce( context ); + AmoebaReferenceMultipoleForce* amoebaReferenceMultipoleForce = setupAmoebaReferenceMultipoleForce(context); vector& posData = extractPositions(context); - amoebaReferenceMultipoleForce->calculateAmoebaSystemMultipoleMoments( masses, posData, charges, dipoles, quadrupoles, tholes, - dampingFactors, polarity, axisTypes, - multipoleAtomZs, multipoleAtomXs, multipoleAtomYs, - multipoleAtomCovalentInfo, outputMultipoleMoments ); + amoebaReferenceMultipoleForce->calculateAmoebaSystemMultipoleMoments(masses, posData, charges, dipoles, quadrupoles, tholes, + dampingFactors, polarity, axisTypes, + multipoleAtomZs, multipoleAtomXs, multipoleAtomYs, + multipoleAtomCovalentInfo, outputMultipoleMoments); delete amoebaReferenceMultipoleForce; } @@ -801,51 +801,51 @@ ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::ReferenceCalcAmoebaGeneralize ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::~ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel() { } -int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getNumParticles( void ) const { +int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getNumParticles() const { return numParticles; } -int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getIncludeCavityTerm( void ) const { +int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getIncludeCavityTerm() const { return includeCavityTerm; } -int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getDirectPolarization( void ) const { +int ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getDirectPolarization() const { return directPolarization; } -RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSoluteDielectric( void ) const { +RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSoluteDielectric() const { return soluteDielectric; } -RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSolventDielectric( void ) const { +RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSolventDielectric() const { return solventDielectric; } -RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getDielectricOffset( void ) const { +RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getDielectricOffset() const { return dielectricOffset; } -RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getProbeRadius( void ) const { +RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getProbeRadius() const { return probeRadius; } -RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSurfaceAreaFactor( void ) const { +RealOpenMM ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getSurfaceAreaFactor() const { return surfaceAreaFactor; } -void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getAtomicRadii( vector& outputAtomicRadii ) const { - outputAtomicRadii.resize( atomicRadii.size() ); - copy( atomicRadii.begin(), atomicRadii.end(), outputAtomicRadii.begin() ); +void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getAtomicRadii(vector& outputAtomicRadii) const { + outputAtomicRadii.resize(atomicRadii.size()); + copy(atomicRadii.begin(), atomicRadii.end(), outputAtomicRadii.begin()); } -void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getScaleFactors( vector& outputScaleFactors ) const { - outputScaleFactors.resize( scaleFactors.size() ); - copy( scaleFactors.begin(), scaleFactors.end(), outputScaleFactors.begin() ); +void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getScaleFactors(vector& outputScaleFactors) const { + outputScaleFactors.resize(scaleFactors.size()); + copy(scaleFactors.begin(), scaleFactors.end(), outputScaleFactors.begin()); } -void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getCharges( vector& outputCharges ) const { - outputCharges.resize( charges.size() ); - copy( charges.begin(), charges.end(), outputCharges.begin() ); +void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::getCharges(vector& outputCharges) const { + outputCharges.resize(charges.size()); + copy(charges.begin(), charges.end(), outputCharges.begin()); } void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::initialize(const System& system, const AmoebaGeneralizedKirkwoodForce& force) { @@ -861,37 +861,37 @@ void ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel::initialize(const System& throw OpenMMException("AmoebaGeneralizedKirkwoodForce requires the System to also contain an AmoebaMultipoleForce."); } - if (amoebaMultipoleForce->getNonbondedMethod() != AmoebaMultipoleForce::NoCutoff ) { + if (amoebaMultipoleForce->getNonbondedMethod() != AmoebaMultipoleForce::NoCutoff) { throw OpenMMException("AmoebaGeneralizedKirkwoodForce requires the AmoebaMultipoleForce use the NoCutoff nonbonded method."); } numParticles = system.getNumParticles(); - for( int ii = 0; ii < numParticles; ii++ ){ + for (int ii = 0; ii < numParticles; ii++) { double particleCharge, particleRadius, scalingFactor; force.getParticleParameters(ii, particleCharge, particleRadius, scalingFactor); - atomicRadii.push_back( static_cast( particleRadius ) ); - scaleFactors.push_back( static_cast( scalingFactor ) ); - charges.push_back( static_cast( particleCharge ) ); + atomicRadii.push_back(static_cast(particleRadius)); + scaleFactors.push_back(static_cast(scalingFactor)); + charges.push_back(static_cast(particleCharge)); // Make sure the charge matches the one specified by the AmoebaMultipoleForce. double charge2, thole, damping, polarity; int axisType, atomX, atomY, atomZ; vector dipole, quadrupole; - amoebaMultipoleForce->getMultipoleParameters( ii, charge2, dipole, quadrupole, axisType, atomZ, atomX, atomY, thole, damping, polarity); - if ( particleCharge != charge2 ){ + amoebaMultipoleForce->getMultipoleParameters(ii, charge2, dipole, quadrupole, axisType, atomZ, atomX, atomY, thole, damping, polarity); + if (particleCharge != charge2) { throw OpenMMException("AmoebaGeneralizedKirkwoodForce and AmoebaMultipoleForce must specify the same charge for every atom."); } } includeCavityTerm = force.getIncludeCavityTerm(); - soluteDielectric = static_cast( force.getSoluteDielectric() ); - solventDielectric = static_cast( force.getSolventDielectric() ); - dielectricOffset = static_cast( 0.009 ); - probeRadius = static_cast( force.getProbeRadius() ), - surfaceAreaFactor = static_cast( force.getSurfaceAreaFactor() ); + soluteDielectric = static_cast(force.getSoluteDielectric()); + solventDielectric = static_cast(force.getSolventDielectric()); + dielectricOffset = static_cast(0.009); + probeRadius = static_cast(force.getProbeRadius()), + surfaceAreaFactor = static_cast(force.getSurfaceAreaFactor()); directPolarization = amoebaMultipoleForce->getPolarizationType() == AmoebaMultipoleForce::Direct ? 1 : 0; } @@ -924,7 +924,7 @@ ReferenceCalcAmoebaVdwForceKernel::ReferenceCalcAmoebaVdwForceKernel(std::string } ReferenceCalcAmoebaVdwForceKernel::~ReferenceCalcAmoebaVdwForceKernel() { - if( neighborList ){ + if (neighborList) { delete neighborList; } } @@ -935,28 +935,28 @@ void ReferenceCalcAmoebaVdwForceKernel::initialize(const System& system, const A numParticles = system.getNumParticles(); - indexIVs.resize( numParticles ); - allExclusions.resize( numParticles ); - sigmas.resize( numParticles ); - epsilons.resize( numParticles ); - reductions.resize( numParticles ); + indexIVs.resize(numParticles); + allExclusions.resize(numParticles); + sigmas.resize(numParticles); + epsilons.resize(numParticles); + reductions.resize(numParticles); - for( int ii = 0; ii < numParticles; ii++ ){ + for (int ii = 0; ii < numParticles; ii++) { int indexIV; double sigma, epsilon, reduction; std::vector exclusions; - force.getParticleParameters( ii, indexIV, sigma, epsilon, reduction ); - force.getParticleExclusions( ii, exclusions ); - for( unsigned int jj = 0; jj < exclusions.size(); jj++ ){ - allExclusions[ii].insert( exclusions[jj] ); + force.getParticleParameters(ii, indexIV, sigma, epsilon, reduction); + force.getParticleExclusions(ii, exclusions); + for (unsigned int jj = 0; jj < exclusions.size(); jj++) { + allExclusions[ii].insert(exclusions[jj]); } indexIVs[ii] = indexIV; - sigmas[ii] = static_cast( sigma ); - epsilons[ii] = static_cast( epsilon ); - reductions[ii] = static_cast( reduction ); + sigmas[ii] = static_cast(sigma); + epsilons[ii] = static_cast(epsilon); + reductions[ii] = static_cast(reduction); } sigmaCombiningRule = force.getSigmaCombiningRule(); epsilonCombiningRule = force.getEpsilonCombiningRule(); @@ -972,27 +972,27 @@ double ReferenceCalcAmoebaVdwForceKernel::execute(ContextImpl& context, bool inc vector& posData = extractPositions(context); vector& forceData = extractForces(context); - AmoebaReferenceVdwForce vdwForce( sigmaCombiningRule, epsilonCombiningRule ); + AmoebaReferenceVdwForce vdwForce(sigmaCombiningRule, epsilonCombiningRule); RealOpenMM energy; - if( useCutoff ){ - vdwForce.setCutoff( cutoff ); - computeNeighborListVoxelHash( *neighborList, numParticles, posData, allExclusions, extractBoxVectors(context), usePBC, cutoff, 0.0); - if( usePBC ){ - vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::CutoffPeriodic); + if (useCutoff) { + vdwForce.setCutoff(cutoff); + computeNeighborListVoxelHash(*neighborList, numParticles, posData, allExclusions, extractBoxVectors(context), usePBC, cutoff, 0.0); + if (usePBC) { + vdwForce.setNonbondedMethod(AmoebaReferenceVdwForce::CutoffPeriodic); RealVec* boxVectors = extractBoxVectors(context); double minAllowedSize = 1.999999*cutoff; - if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize){ + if (boxVectors[0][0] < minAllowedSize || boxVectors[1][1] < minAllowedSize || boxVectors[2][2] < minAllowedSize) { throw OpenMMException("The periodic box size has decreased to less than twice the cutoff."); } vdwForce.setPeriodicBox(boxVectors); - energy = vdwForce.calculateForceAndEnergy( numParticles, posData, indexIVs, sigmas, epsilons, reductions, *neighborList, forceData); + energy = vdwForce.calculateForceAndEnergy(numParticles, posData, indexIVs, sigmas, epsilons, reductions, *neighborList, forceData); energy += dispersionCoefficient/(boxVectors[0][0]*boxVectors[1][1]*boxVectors[2][2]); } else { - vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::CutoffNonPeriodic); + vdwForce.setNonbondedMethod(AmoebaReferenceVdwForce::CutoffNonPeriodic); } } else { - vdwForce.setNonbondedMethod( AmoebaReferenceVdwForce::NoCutoff ); - energy = vdwForce.calculateForceAndEnergy( numParticles, posData, indexIVs, sigmas, epsilons, reductions, allExclusions, forceData); + vdwForce.setNonbondedMethod(AmoebaReferenceVdwForce::NoCutoff); + energy = vdwForce.calculateForceAndEnergy(numParticles, posData, indexIVs, sigmas, epsilons, reductions, allExclusions, forceData); } return static_cast(energy); } @@ -1032,32 +1032,32 @@ void ReferenceCalcAmoebaWcaDispersionForceKernel::initialize(const System& syste numParticles = system.getNumParticles(); radii.resize(numParticles); epsilons.resize(numParticles); - for( int ii = 0; ii < numParticles; ii++ ){ + for (int ii = 0; ii < numParticles; ii++) { double radius, epsilon; - force.getParticleParameters( ii, radius, epsilon ); + force.getParticleParameters(ii, radius, epsilon); - radii[ii] = static_cast( radius ); - epsilons[ii] = static_cast( epsilon ); + radii[ii] = static_cast(radius); + epsilons[ii] = static_cast(epsilon); } - totalMaximumDispersionEnergy = static_cast( AmoebaWcaDispersionForceImpl::getTotalMaximumDispersionEnergy( force ) ); + totalMaximumDispersionEnergy = static_cast(AmoebaWcaDispersionForceImpl::getTotalMaximumDispersionEnergy(force)); - epso = static_cast( force.getEpso() ); - epsh = static_cast( force.getEpsh() ); - rmino = static_cast( force.getRmino() ); - rminh = static_cast( force.getRminh() ); - awater = static_cast( force.getAwater() ); - shctd = static_cast( force.getShctd() ); - dispoff = static_cast( force.getDispoff()); - slevy = static_cast( force.getSlevy() ); + epso = static_cast(force.getEpso() ); + epsh = static_cast(force.getEpsh() ); + rmino = static_cast(force.getRmino() ); + rminh = static_cast(force.getRminh() ); + awater = static_cast(force.getAwater()); + shctd = static_cast(force.getShctd() ); + dispoff = static_cast(force.getDispoff()); + slevy = static_cast(force.getSlevy() ); } double ReferenceCalcAmoebaWcaDispersionForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { vector& posData = extractPositions(context); vector& forceData = extractForces(context); - AmoebaReferenceWcaDispersionForce amoebaReferenceWcaDispersionForce( epso, epsh, rmino, rminh, awater, shctd, dispoff, slevy ); - RealOpenMM energy = amoebaReferenceWcaDispersionForce.calculateForceAndEnergy( numParticles, posData, radii, epsilons, totalMaximumDispersionEnergy, forceData); + AmoebaReferenceWcaDispersionForce amoebaReferenceWcaDispersionForce(epso, epsh, rmino, rminh, awater, shctd, dispoff, slevy); + RealOpenMM energy = amoebaReferenceWcaDispersionForce.calculateForceAndEnergy(numParticles, posData, radii, epsilons, totalMaximumDispersionEnergy, forceData); return static_cast(energy); } diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h index 19017fd63..f8a407335 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.h @@ -357,7 +357,7 @@ public: * * @return pointer to initialized instance of AmoebaReferenceMultipoleForce */ - AmoebaReferenceMultipoleForce* setupAmoebaReferenceMultipoleForce(ContextImpl& context ); + AmoebaReferenceMultipoleForce* setupAmoebaReferenceMultipoleForce(ContextImpl& context); /** * Execute the kernel to calculate the forces and/or energy. * @@ -382,7 +382,7 @@ public: * @param outputElectrostaticPotential output potential */ void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, - std::vector< double >& outputElectrostaticPotential ); + std::vector< double >& outputElectrostaticPotential); /** * Get the system multipole moments. @@ -393,7 +393,7 @@ public: dipole_x, dipole_y, dipole_z, quadrupole_xx, quadrupole_xy, quadrupole_xz, quadrupole_yx, quadrupole_yy, quadrupole_yz, - quadrupole_zx, quadrupole_zy, quadrupole_zz ) + quadrupole_zx, quadrupole_zy, quadrupole_zz) */ void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments); /** @@ -555,14 +555,14 @@ public: * * @return includeCavityTerm */ - int getIncludeCavityTerm( void ) const; + int getIncludeCavityTerm() const; /** * Get the number of particles. * * @return number of particles */ - int getNumParticles( void ) const; + int getNumParticles() const; /** * Get Direct Polarization flag. @@ -570,7 +570,7 @@ public: * @return directPolarization * */ - int getDirectPolarization( void ) const; + int getDirectPolarization() const; /** * Get the solute dielectric. @@ -578,7 +578,7 @@ public: * @return soluteDielectric * */ - RealOpenMM getSoluteDielectric( void ) const; + RealOpenMM getSoluteDielectric() const; /** * Get the solvent dielectric. @@ -586,7 +586,7 @@ public: * @return solventDielectric * */ - RealOpenMM getSolventDielectric( void ) const; + RealOpenMM getSolventDielectric() const; /** * Get the dielectric offset. @@ -594,7 +594,7 @@ public: * @return dielectricOffset * */ - RealOpenMM getDielectricOffset( void ) const; + RealOpenMM getDielectricOffset() const; /** * Get the probe radius. @@ -602,7 +602,7 @@ public: * @return probeRadius * */ - RealOpenMM getProbeRadius( void ) const; + RealOpenMM getProbeRadius() const; /** * Get the surface area factor. @@ -610,7 +610,7 @@ public: * @return surfaceAreaFactor * */ - RealOpenMM getSurfaceAreaFactor( void ) const; + RealOpenMM getSurfaceAreaFactor() const; /** * Get the vector of particle radii. @@ -618,7 +618,7 @@ public: * @param atomicRadii vector of atomic radii * */ - void getAtomicRadii( std::vector& atomicRadii ) const; + void getAtomicRadii(std::vector& atomicRadii) const; /** * Get the vector of scale factors. @@ -626,7 +626,7 @@ public: * @param scaleFactors vector of scale factors * */ - void getScaleFactors( std::vector& scaleFactors ) const; + void getScaleFactors(std::vector& scaleFactors) const; /** * Get the vector of charges. @@ -634,7 +634,7 @@ public: * @param charges vector of charges * */ - void getCharges( std::vector& charges ) const; + void getCharges(std::vector& charges) const; /** * Copy changed parameters over to a context. diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp index 50728bfd3..97e435878 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.cpp @@ -46,11 +46,11 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceAngleForce::getPrefactorsGivenAngleCosine( RealOpenMM cosine, +RealOpenMM AmoebaReferenceAngleForce::getPrefactorsGivenAngleCosine(RealOpenMM cosine, RealOpenMM idealAngle, RealOpenMM angleK, RealOpenMM angleCubic, RealOpenMM angleQuartic, RealOpenMM anglePentic, RealOpenMM angleSextic, - RealOpenMM* dEdR ) const { + RealOpenMM* dEdR) const { // --------------------------------------------------------------------------------------- @@ -67,9 +67,9 @@ RealOpenMM AmoebaReferenceAngleForce::getPrefactorsGivenAngleCosine( RealOpenMM // --------------------------------------------------------------------------------------- RealOpenMM angle; - if( cosine >= one ){ + if (cosine >= one) { angle = zero; - } else if( cosine <= -one ){ + } else if (cosine <= -one) { angle = RADIAN*PI_M; } else { angle = RADIAN*ACOS(cosine); @@ -79,10 +79,10 @@ RealOpenMM AmoebaReferenceAngleForce::getPrefactorsGivenAngleCosine( RealOpenMM RealOpenMM deltaIdeal3 = deltaIdeal*deltaIdeal2; RealOpenMM deltaIdeal4 = deltaIdeal2*deltaIdeal2; - *dEdR = ( two + three*angleCubic*deltaIdeal + - four*angleQuartic*deltaIdeal2 + - five*anglePentic*deltaIdeal3 + - six*angleSextic*deltaIdeal4 ); + *dEdR = (two + three*angleCubic*deltaIdeal + + four*angleQuartic*deltaIdeal2 + + five*anglePentic*deltaIdeal3 + + six*angleSextic*deltaIdeal4); *dEdR *= RADIAN*angleK*deltaIdeal; @@ -113,12 +113,12 @@ RealOpenMM AmoebaReferenceAngleForce::getPrefactorsGivenAngleCosine( RealOpenMM --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, +RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn(const RealVec& positionAtomA, const RealVec& positionAtomB, const RealVec& positionAtomC, RealOpenMM angle, RealOpenMM angleK, RealOpenMM angleCubic, RealOpenMM angleQuartic, RealOpenMM anglePentic, RealOpenMM angleSextic, - RealVec* forces ) const { + RealVec* forces) const { // --------------------------------------------------------------------------------------- @@ -132,30 +132,30 @@ RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn( const RealVec& position // --------------------------------------------------------------------------------------- std::vector deltaR[2]; - AmoebaReferenceForce::loadDeltaR( positionAtomA, positionAtomB, deltaR[0] ); - RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3( deltaR[0] ); - RealOpenMM rAB = SQRT( rAB2 ); + AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR[0]); + RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3(deltaR[0]); + RealOpenMM rAB = SQRT(rAB2); - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomB, deltaR[1] ); - RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3( deltaR[1] ); - RealOpenMM rCB = SQRT( rCB2 ); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomB, deltaR[1]); + RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3(deltaR[1]); + RealOpenMM rCB = SQRT(rCB2); - if( rAB <= zero || rCB <= zero ){ + if (rAB <= zero || rCB <= zero) { return zero; } std::vector pVector(3); - AmoebaReferenceForce::getCrossProduct( deltaR[0], deltaR[1], pVector ); - RealOpenMM rp = AmoebaReferenceForce::getNorm3( pVector ); - if( rp < 1.0e-06 ){ + AmoebaReferenceForce::getCrossProduct(deltaR[0], deltaR[1], pVector); + RealOpenMM rp = AmoebaReferenceForce::getNorm3(pVector); + if (rp < 1.0e-06) { rp = 1.0e-06; } - RealOpenMM dot = AmoebaReferenceForce::getDotProduct3( deltaR[0], deltaR[1] ); + RealOpenMM dot = AmoebaReferenceForce::getDotProduct3(deltaR[0], deltaR[1]); RealOpenMM cosine = dot/(rAB*rCB); RealOpenMM dEdR; - RealOpenMM energy = getPrefactorsGivenAngleCosine( cosine, angle, angleK, angleCubic, angleQuartic, - anglePentic, angleSextic, &dEdR ); + RealOpenMM energy = getPrefactorsGivenAngleCosine(cosine, angle, angleK, angleCubic, angleQuartic, + anglePentic, angleSextic, &dEdR); RealOpenMM termA = dEdR/(rAB2*rp); RealOpenMM termC = -dEdR/(rCB2*rp); @@ -164,9 +164,9 @@ RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn( const RealVec& position deltaCrossP[0].resize(3); deltaCrossP[1].resize(3); deltaCrossP[2].resize(3); - AmoebaReferenceForce::getCrossProduct( deltaR[0], pVector, deltaCrossP[0] ); - AmoebaReferenceForce::getCrossProduct( deltaR[1], pVector, deltaCrossP[2] ); - for( unsigned int ii = 0; ii < 3; ii++ ){ + AmoebaReferenceForce::getCrossProduct(deltaR[0], pVector, deltaCrossP[0]); + AmoebaReferenceForce::getCrossProduct(deltaR[1], pVector, deltaCrossP[2]); + for (unsigned int ii = 0; ii < 3; ii++) { deltaCrossP[0][ii] *= termA; deltaCrossP[2][ii] *= termC; deltaCrossP[1][ii] = -1.0f*(deltaCrossP[0][ii] + deltaCrossP[2][ii]); @@ -174,7 +174,7 @@ RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn( const RealVec& position // accumulate forces - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { forces[jj][0] = deltaCrossP[jj][0]; forces[jj][1] = deltaCrossP[jj][1]; forces[jj][2] = deltaCrossP[jj][2]; @@ -183,7 +183,7 @@ RealOpenMM AmoebaReferenceAngleForce::calculateAngleIxn( const RealVec& position return energy; } -RealOpenMM AmoebaReferenceAngleForce::calculateForceAndEnergy( int numAngles, vector& posData, +RealOpenMM AmoebaReferenceAngleForce::calculateForceAndEnergy(int numAngles, vector& posData, const std::vector& particle1, const std::vector& particle2, const std::vector& particle3, @@ -202,10 +202,10 @@ RealOpenMM AmoebaReferenceAngleForce::calculateForceAndEnergy( int numAngles, ve RealOpenMM idealAngle = angle[ii]; RealOpenMM angleK = kQuadratic[ii]; RealVec forces[3]; - energy += calculateAngleIxn( posData[particle1Index], posData[particle2Index], posData[particle3Index], - idealAngle, angleK, angleCubic, angleQuartic, anglePentic, angleSextic, forces ); + energy += calculateAngleIxn(posData[particle1Index], posData[particle2Index], posData[particle3Index], + idealAngle, angleK, angleCubic, angleQuartic, anglePentic, angleSextic, forces); - for( unsigned int jj = 0; jj < 3; jj++ ){ + for (unsigned int jj = 0; jj < 3; jj++) { forceData[particle1Index][jj] += forces[0][jj]; forceData[particle2Index][jj] += forces[1][jj]; forceData[particle3Index][jj] += forces[2][jj]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h index 84395d991..46f638d14 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceAngleForce.h @@ -40,7 +40,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceAngleForce( ){}; + AmoebaReferenceAngleForce() {}; /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceAngleForce( ){}; + ~AmoebaReferenceAngleForce() {}; /**--------------------------------------------------------------------------------------- @@ -72,17 +72,17 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numAngles, std::vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& angle, - const std::vector& kQuadratic, - RealOpenMM globalAngleCubic, - RealOpenMM globalAngleQuartic, - RealOpenMM globalAnglePentic, - RealOpenMM globalAngleSextic, - std::vector& forceData ) const; + RealOpenMM calculateForceAndEnergy(int numAngles, std::vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& angle, + const std::vector& kQuadratic, + RealOpenMM globalAngleCubic, + RealOpenMM globalAngleQuartic, + RealOpenMM globalAnglePentic, + RealOpenMM globalAngleSextic, + std::vector& forceData) const; private: @@ -104,10 +104,10 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM getPrefactorsGivenAngleCosine( RealOpenMM cosine, RealOpenMM idealAngle, RealOpenMM angleK, - RealOpenMM angleCubic, RealOpenMM angleQuartic, - RealOpenMM anglePentic, RealOpenMM angleSextic, - RealOpenMM* dEdR ) const; + RealOpenMM getPrefactorsGivenAngleCosine(RealOpenMM cosine, RealOpenMM idealAngle, RealOpenMM angleK, + RealOpenMM angleCubic, RealOpenMM angleQuartic, + RealOpenMM anglePentic, RealOpenMM angleSextic, + RealOpenMM* dEdR) const; /**--------------------------------------------------------------------------------------- @@ -128,12 +128,12 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateAngleIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - const OpenMM::RealVec& positionAtomC, - RealOpenMM angle, RealOpenMM angleK, - RealOpenMM angleCubic, RealOpenMM angleQuartic, - RealOpenMM anglePentic, RealOpenMM angleSextic, - OpenMM::RealVec* forces ) const; + RealOpenMM calculateAngleIxn(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + const OpenMM::RealVec& positionAtomC, + RealOpenMM angle, RealOpenMM angleK, + RealOpenMM angleCubic, RealOpenMM angleQuartic, + RealOpenMM anglePentic, RealOpenMM angleSextic, + OpenMM::RealVec* forces) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp index 289ddaae0..8a6ff3fc4 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.cpp @@ -44,10 +44,10 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceBondForce::calculateBondIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, +RealOpenMM AmoebaReferenceBondForce::calculateBondIxn(const RealVec& positionAtomA, const RealVec& positionAtomB, RealOpenMM bondLength, RealOpenMM bondK, RealOpenMM bondCubic, RealOpenMM bondQuartic, - RealVec* forces ) const { + RealVec* forces) const { // --------------------------------------------------------------------------------------- @@ -63,8 +63,8 @@ RealOpenMM AmoebaReferenceBondForce::calculateBondIxn( const RealVec& positionAt // get deltaR, R2, and R between 2 atoms std::vector deltaR; - AmoebaReferenceForce::loadDeltaR( positionAtomA, positionAtomB, deltaR ); - RealOpenMM r = AmoebaReferenceForce::getNorm3( deltaR ); + AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR); + RealOpenMM r = AmoebaReferenceForce::getNorm3(deltaR); // deltaIdeal = r - r_0 @@ -84,11 +84,11 @@ RealOpenMM AmoebaReferenceBondForce::calculateBondIxn( const RealVec& positionAt forces[1][1] = dEdR*deltaR[1]; forces[1][2] = dEdR*deltaR[2]; - RealOpenMM energy = bondK*deltaIdeal2*( one + bondCubic*deltaIdeal + bondQuartic*deltaIdeal2 ); + RealOpenMM energy = bondK*deltaIdeal2*(one + bondCubic*deltaIdeal + bondQuartic*deltaIdeal2); return energy; } -RealOpenMM AmoebaReferenceBondForce::calculateForceAndEnergy( int numBonds, +RealOpenMM AmoebaReferenceBondForce::calculateForceAndEnergy(int numBonds, vector& particlePositions, const std::vector& particle1, const std::vector& particle2, @@ -96,20 +96,20 @@ RealOpenMM AmoebaReferenceBondForce::calculateForceAndEnergy( int numBonds, const std::vector& kQuadratic, RealOpenMM globalBondCubic, RealOpenMM globalBondQuartic, - vector& forceData ) const { + vector& forceData) const { RealOpenMM energy = 0.0; - for( int ii = 0; ii < numBonds; ii++ ){ + for (int ii = 0; ii < numBonds; ii++) { int particle1Index = particle1[ii]; int particle2Index = particle2[ii]; RealOpenMM bondLength = length[ii]; RealOpenMM bondK = kQuadratic[ii]; RealVec forces[2]; - energy += calculateBondIxn( particlePositions[particle1Index], particlePositions[particle2Index], + energy += calculateBondIxn(particlePositions[particle1Index], particlePositions[particle2Index], bondLength, bondK, globalBondCubic, globalBondQuartic, - forces ); + forces); - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { forceData[particle1Index][jj] += forces[0][jj]; forceData[particle2Index][jj] += forces[1][jj]; } diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h index da93661b5..6cd08ff55 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceBondForce.h @@ -40,7 +40,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceBondForce( ){}; + AmoebaReferenceBondForce() {}; /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceBondForce( ){}; + ~AmoebaReferenceBondForce() {}; /**--------------------------------------------------------------------------------------- @@ -69,13 +69,13 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numBonds, std::vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& bondLength, - const std::vector& bondK, - RealOpenMM bondCubic, RealOpenMM bondQuartic, - std::vector& forceData ) const; + RealOpenMM calculateForceAndEnergy(int numBonds, std::vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& bondLength, + const std::vector& bondK, + RealOpenMM bondCubic, RealOpenMM bondQuartic, + std::vector& forceData) const; private: @@ -95,10 +95,10 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateBondIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - RealOpenMM bondLength, RealOpenMM bondK, - RealOpenMM bondCubic, RealOpenMM bondQuartic, - OpenMM::RealVec* forces ) const; + RealOpenMM calculateBondIxn(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + RealOpenMM bondLength, RealOpenMM bondK, + RealOpenMM bondCubic, RealOpenMM bondQuartic, + OpenMM::RealVec* forces) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp index 8988d8448..5c7b20577 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.cpp @@ -37,8 +37,8 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -void AmoebaReferenceForce::loadDeltaR( const RealVec& xVector, const RealVec& yVector, - std::vector& deltaR ){ +void AmoebaReferenceForce::loadDeltaR(const RealVec& xVector, const RealVec& yVector, + std::vector& deltaR) { // --------------------------------------------------------------------------------------- @@ -48,9 +48,9 @@ void AmoebaReferenceForce::loadDeltaR( const RealVec& xVector, const RealVec& yV // --------------------------------------------------------------------------------------- deltaR.resize(0); - deltaR.push_back( yVector[0] - xVector[0] ); - deltaR.push_back( yVector[1] - xVector[1] ); - deltaR.push_back( yVector[2] - xVector[2] ); + deltaR.push_back(yVector[0] - xVector[0]); + deltaR.push_back(yVector[1] - xVector[1]); + deltaR.push_back(yVector[2] - xVector[2]); } /**--------------------------------------------------------------------------------------- @@ -63,7 +63,7 @@ void AmoebaReferenceForce::loadDeltaR( const RealVec& xVector, const RealVec& yV --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceForce::getNormSquared3( const std::vector& inputVector ){ +RealOpenMM AmoebaReferenceForce::getNormSquared3(const std::vector& inputVector) { // --------------------------------------------------------------------------------------- @@ -73,7 +73,7 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3( const std::vector& // get 3 norm - return ( inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2] ); + return (inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); } /**--------------------------------------------------------------------------------------- @@ -86,7 +86,7 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3( const std::vector& --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceForce::getNormSquared3( const RealOpenMM* inputVector ){ +RealOpenMM AmoebaReferenceForce::getNormSquared3(const RealOpenMM* inputVector) { // --------------------------------------------------------------------------------------- @@ -96,7 +96,7 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3( const RealOpenMM* inputVector // get 3 norm - return ( inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2] ); + return (inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); } /**--------------------------------------------------------------------------------------- @@ -109,7 +109,7 @@ RealOpenMM AmoebaReferenceForce::getNormSquared3( const RealOpenMM* inputVector --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceForce::getNorm3( const std::vector& inputVector ){ +RealOpenMM AmoebaReferenceForce::getNorm3(const std::vector& inputVector) { // --------------------------------------------------------------------------------------- @@ -119,10 +119,10 @@ RealOpenMM AmoebaReferenceForce::getNorm3( const std::vector& inputV // get 3 norm - return SQRT( inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2] ); + return SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); } -RealOpenMM AmoebaReferenceForce::getNorm3( const RealOpenMM* inputVector ){ +RealOpenMM AmoebaReferenceForce::getNorm3(const RealOpenMM* inputVector) { // --------------------------------------------------------------------------------------- @@ -132,10 +132,10 @@ RealOpenMM AmoebaReferenceForce::getNorm3( const RealOpenMM* inputVector ){ // get 3 norm - return SQRT( inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2] ); + return SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); } -RealOpenMM AmoebaReferenceForce::normalizeVector3( RealOpenMM* inputVector ){ +RealOpenMM AmoebaReferenceForce::normalizeVector3(RealOpenMM* inputVector) { // --------------------------------------------------------------------------------------- @@ -143,8 +143,8 @@ RealOpenMM AmoebaReferenceForce::normalizeVector3( RealOpenMM* inputVector ){ // --------------------------------------------------------------------------------------- - RealOpenMM norm = SQRT( inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2] ); - if( norm > 0.0 ){ + RealOpenMM norm = SQRT(inputVector[0]*inputVector[0] + inputVector[1]*inputVector[1] + inputVector[2]*inputVector[2]); + if (norm > 0.0) { RealOpenMM normI = 1.0/norm; inputVector[0] *= normI; inputVector[1] *= normI; @@ -165,7 +165,7 @@ RealOpenMM AmoebaReferenceForce::normalizeVector3( RealOpenMM* inputVector ){ --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceForce::getDotProduct3( const std::vector& xVector, const std::vector& yVector ){ +RealOpenMM AmoebaReferenceForce::getDotProduct3(const std::vector& xVector, const std::vector& yVector) { // --------------------------------------------------------------------------------------- @@ -189,7 +189,7 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3( const std::vector& --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceForce::getDotProduct3( const RealOpenMM* xVector, const RealOpenMM* yVector ){ +RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const RealOpenMM* yVector) { // --------------------------------------------------------------------------------------- @@ -202,7 +202,7 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3( const RealOpenMM* xVector, cons return xVector[0]*yVector[0] + xVector[1]*yVector[1] + xVector[2]*yVector[2]; } -RealOpenMM AmoebaReferenceForce::getDotProduct3( const RealOpenMM* xVector, const OpenMM::Vec3& yVector ){ +RealOpenMM AmoebaReferenceForce::getDotProduct3(const RealOpenMM* xVector, const OpenMM::Vec3& yVector) { // --------------------------------------------------------------------------------------- @@ -227,7 +227,7 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3( const RealOpenMM* xVector, cons --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceForce::getDotProduct3( unsigned int vectorOffset, const std::vector& xVector, const RealOpenMM* yVector ){ +RealOpenMM AmoebaReferenceForce::getDotProduct3(unsigned int vectorOffset, const std::vector& xVector, const RealOpenMM* yVector) { // --------------------------------------------------------------------------------------- @@ -250,9 +250,9 @@ RealOpenMM AmoebaReferenceForce::getDotProduct3( unsigned int vectorOffset, cons --------------------------------------------------------------------------------------- */ -void AmoebaReferenceForce::getCrossProduct( const std::vector& xVector, - const std::vector& yVector, - std::vector& zVector ){ +void AmoebaReferenceForce::getCrossProduct(const std::vector& xVector, + const std::vector& yVector, + std::vector& zVector) { // --------------------------------------------------------------------------------------- @@ -277,9 +277,9 @@ void AmoebaReferenceForce::getCrossProduct( const std::vector& xVect --------------------------------------------------------------------------------------- */ -void AmoebaReferenceForce::getCrossProduct( const RealOpenMM* xVector, - const RealOpenMM* yVector, - RealOpenMM* zVector ){ +void AmoebaReferenceForce::getCrossProduct(const RealOpenMM* xVector, + const RealOpenMM* yVector, + RealOpenMM* zVector) { // --------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h index 522ed9546..ff87be126 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceForce.h @@ -41,7 +41,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceForce( ); + AmoebaReferenceForce(); /**--------------------------------------------------------------------------------------- @@ -49,7 +49,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceForce( ); + ~AmoebaReferenceForce(); /**--------------------------------------------------------------------------------------- @@ -62,8 +62,8 @@ public: --------------------------------------------------------------------------------------- */ - static void loadDeltaR( const OpenMM::RealVec& xVector, const OpenMM::RealVec& yVector, - std::vector& deltaR ); + static void loadDeltaR(const OpenMM::RealVec& xVector, const OpenMM::RealVec& yVector, + std::vector& deltaR); /**--------------------------------------------------------------------------------------- @@ -75,8 +75,8 @@ public: --------------------------------------------------------------------------------------- */ - static RealOpenMM getNormSquared3( const std::vector& inputVector ); - static RealOpenMM getNormSquared3( const RealOpenMM* inputVector ); + static RealOpenMM getNormSquared3(const std::vector& inputVector); + static RealOpenMM getNormSquared3(const RealOpenMM* inputVector); /**--------------------------------------------------------------------------------------- @@ -88,8 +88,8 @@ public: --------------------------------------------------------------------------------------- */ - static RealOpenMM getNorm3( const std::vector& inputVector ); - static RealOpenMM getNorm3( const RealOpenMM* inputVector ); + static RealOpenMM getNorm3(const std::vector& inputVector); + static RealOpenMM getNorm3(const RealOpenMM* inputVector); /**--------------------------------------------------------------------------------------- @@ -101,7 +101,7 @@ public: --------------------------------------------------------------------------------------- */ - static RealOpenMM normalizeVector3( RealOpenMM* inputVector ); + static RealOpenMM normalizeVector3(RealOpenMM* inputVector); /**--------------------------------------------------------------------------------------- @@ -114,10 +114,10 @@ public: --------------------------------------------------------------------------------------- */ - static RealOpenMM getDotProduct3( const std::vector& xVector, const std::vector& yVector ); - static RealOpenMM getDotProduct3( const RealOpenMM* xVector, const RealOpenMM* yVector ); - static RealOpenMM getDotProduct3( const RealOpenMM* xVector, const OpenMM::Vec3& yVector ); - static RealOpenMM getDotProduct3( unsigned int vectorOffset, const std::vector& xVector, const RealOpenMM* yVector ); + static RealOpenMM getDotProduct3(const std::vector& xVector, const std::vector& yVector); + static RealOpenMM getDotProduct3(const RealOpenMM* xVector, const RealOpenMM* yVector); + static RealOpenMM getDotProduct3(const RealOpenMM* xVector, const OpenMM::Vec3& yVector); + static RealOpenMM getDotProduct3(unsigned int vectorOffset, const std::vector& xVector, const RealOpenMM* yVector); /**--------------------------------------------------------------------------------------- @@ -129,10 +129,10 @@ public: --------------------------------------------------------------------------------------- */ - static void getCrossProduct( const std::vector& xVector, const std::vector& yVector, - std::vector& zVector ); + static void getCrossProduct(const std::vector& xVector, const std::vector& yVector, + std::vector& zVector); - static void getCrossProduct( const RealOpenMM* xVector, const RealOpenMM* yVector, RealOpenMM* zVector ); + static void getCrossProduct(const RealOpenMM* xVector, const RealOpenMM* yVector, RealOpenMM* zVector); }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp index 4db10918d..f8505b9b9 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.cpp @@ -26,7 +26,7 @@ using std::vector; using namespace OpenMM; -AmoebaReferenceGeneralizedKirkwoodForce::AmoebaReferenceGeneralizedKirkwoodForce( ) : _numParticles(0), +AmoebaReferenceGeneralizedKirkwoodForce::AmoebaReferenceGeneralizedKirkwoodForce() : _numParticles(0), _includeCavityTerm(1), _directPolarization(0), _soluteDielectric(1.0), @@ -37,101 +37,101 @@ AmoebaReferenceGeneralizedKirkwoodForce::AmoebaReferenceGeneralizedKirkwoodForce } -void AmoebaReferenceGeneralizedKirkwoodForce::setNumParticles( int numParticles ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setNumParticles(int numParticles) { _numParticles = numParticles; } -int AmoebaReferenceGeneralizedKirkwoodForce::getNumParticles( void ) const { +int AmoebaReferenceGeneralizedKirkwoodForce::getNumParticles() const { return _numParticles; } -void AmoebaReferenceGeneralizedKirkwoodForce::setIncludeCavityTerm( int includeCavityTerm ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setIncludeCavityTerm(int includeCavityTerm) { _includeCavityTerm = includeCavityTerm; } -int AmoebaReferenceGeneralizedKirkwoodForce::getIncludeCavityTerm( void ) const { +int AmoebaReferenceGeneralizedKirkwoodForce::getIncludeCavityTerm() const { return _includeCavityTerm; } -void AmoebaReferenceGeneralizedKirkwoodForce::setDirectPolarization( int directPolarization ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setDirectPolarization(int directPolarization) { _directPolarization = directPolarization; } -int AmoebaReferenceGeneralizedKirkwoodForce::getDirectPolarization( void ) const { +int AmoebaReferenceGeneralizedKirkwoodForce::getDirectPolarization() const { return _directPolarization; } -void AmoebaReferenceGeneralizedKirkwoodForce::setSoluteDielectric( RealOpenMM soluteDielectric ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setSoluteDielectric(RealOpenMM soluteDielectric) { _soluteDielectric = soluteDielectric; } -RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSoluteDielectric( void ) const { +RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSoluteDielectric() const { return _soluteDielectric; } -void AmoebaReferenceGeneralizedKirkwoodForce::setSolventDielectric( RealOpenMM solventDielectric ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setSolventDielectric(RealOpenMM solventDielectric) { _solventDielectric = solventDielectric; } -RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSolventDielectric( void ) const { +RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSolventDielectric() const { return _solventDielectric; } -void AmoebaReferenceGeneralizedKirkwoodForce::setDielectricOffset( RealOpenMM dielectricOffset ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setDielectricOffset(RealOpenMM dielectricOffset) { _dielectricOffset = dielectricOffset; } -RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getDielectricOffset( void ) const { +RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getDielectricOffset() const { return _dielectricOffset; } -void AmoebaReferenceGeneralizedKirkwoodForce::setProbeRadius( RealOpenMM probeRadius ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setProbeRadius(RealOpenMM probeRadius) { _probeRadius = probeRadius; } -RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getProbeRadius( void ) const { +RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getProbeRadius() const { return _probeRadius; } -void AmoebaReferenceGeneralizedKirkwoodForce::setSurfaceAreaFactor( RealOpenMM surfaceAreaFactor ){ +void AmoebaReferenceGeneralizedKirkwoodForce::setSurfaceAreaFactor(RealOpenMM surfaceAreaFactor) { _surfaceAreaFactor = surfaceAreaFactor; } -RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSurfaceAreaFactor( void ) const { +RealOpenMM AmoebaReferenceGeneralizedKirkwoodForce::getSurfaceAreaFactor() const { return _surfaceAreaFactor; } -void AmoebaReferenceGeneralizedKirkwoodForce::setAtomicRadii( const vector& atomicRadii ){ - _atomicRadii.resize( atomicRadii.size() ); - copy( atomicRadii.begin(), atomicRadii.end(), _atomicRadii.begin() ); +void AmoebaReferenceGeneralizedKirkwoodForce::setAtomicRadii(const vector& atomicRadii) { + _atomicRadii.resize(atomicRadii.size()); + copy(atomicRadii.begin(), atomicRadii.end(), _atomicRadii.begin()); } -void AmoebaReferenceGeneralizedKirkwoodForce::getAtomicRadii( vector& atomicRadii ) const { - atomicRadii.resize( _atomicRadii.size() ); - copy( _atomicRadii.begin(), _atomicRadii.end(), atomicRadii.begin() ); +void AmoebaReferenceGeneralizedKirkwoodForce::getAtomicRadii(vector& atomicRadii) const { + atomicRadii.resize(_atomicRadii.size()); + copy(_atomicRadii.begin(), _atomicRadii.end(), atomicRadii.begin()); } -void AmoebaReferenceGeneralizedKirkwoodForce::setScaleFactors( const vector& scaleFactors ){ - _scaleFactors.resize( scaleFactors.size() ); - copy( scaleFactors.begin(), scaleFactors.end(), _scaleFactors.begin() ); +void AmoebaReferenceGeneralizedKirkwoodForce::setScaleFactors(const vector& scaleFactors) { + _scaleFactors.resize(scaleFactors.size()); + copy(scaleFactors.begin(), scaleFactors.end(), _scaleFactors.begin()); } -void AmoebaReferenceGeneralizedKirkwoodForce::getScaleFactors( vector& scaleFactors ) const { - scaleFactors.resize( _scaleFactors.size() ); - copy( _scaleFactors.begin(), _scaleFactors.end(), scaleFactors.begin() ); +void AmoebaReferenceGeneralizedKirkwoodForce::getScaleFactors(vector& scaleFactors) const { + scaleFactors.resize(_scaleFactors.size()); + copy(_scaleFactors.begin(), _scaleFactors.end(), scaleFactors.begin()); } -void AmoebaReferenceGeneralizedKirkwoodForce::setCharges( const vector& charges ){ - _charges.resize( charges.size() ); - copy( charges.begin(), charges.end(), _charges.begin() ); +void AmoebaReferenceGeneralizedKirkwoodForce::setCharges(const vector& charges) { + _charges.resize(charges.size()); + copy(charges.begin(), charges.end(), _charges.begin()); } -void AmoebaReferenceGeneralizedKirkwoodForce::getGrycukBornRadii( vector& bornRadii ) const { - bornRadii.resize( _bornRadii.size() ); - copy( _bornRadii.begin(), _bornRadii.end(), bornRadii.begin() ); +void AmoebaReferenceGeneralizedKirkwoodForce::getGrycukBornRadii(vector& bornRadii) const { + bornRadii.resize(_bornRadii.size()); + copy(_bornRadii.begin(), _bornRadii.end(), bornRadii.begin()); } -void AmoebaReferenceGeneralizedKirkwoodForce::calculateGrycukBornRadii( const vector& particlePositions ) { +void AmoebaReferenceGeneralizedKirkwoodForce::calculateGrycukBornRadii(const vector& particlePositions) { const RealOpenMM zero = 0.0; const RealOpenMM one = 1.0; @@ -142,30 +142,30 @@ void AmoebaReferenceGeneralizedKirkwoodForce::calculateGrycukBornRadii( const ve const RealOpenMM oneThird = 1.0/3.0; const RealOpenMM bigRadius = 1000.0; - _bornRadii.resize( _numParticles ); - for( unsigned int ii = 0; ii < _numParticles; ii++ ){ + _bornRadii.resize(_numParticles); + for (unsigned int ii = 0; ii < _numParticles; ii++) { - if( _atomicRadii[ii] <= zero ){ + if (_atomicRadii[ii] <= zero) { _bornRadii[ii] = bigRadius; continue; } RealOpenMM bornSum = zero; - for( unsigned int jj = 0; jj < _numParticles; jj++ ){ + for (unsigned int jj = 0; jj < _numParticles; jj++) { - if( ii == jj || _atomicRadii[jj] < zero )continue; + if (ii == jj || _atomicRadii[jj] < zero)continue; RealOpenMM xr = particlePositions[jj][0] - particlePositions[ii][0]; RealOpenMM yr = particlePositions[jj][1] - particlePositions[ii][1]; RealOpenMM zr = particlePositions[jj][2] - particlePositions[ii][2]; RealOpenMM r2 = xr*xr + yr*yr + zr*zr; - RealOpenMM r = SQRT( r2 ); + RealOpenMM r = SQRT(r2); RealOpenMM sk = _atomicRadii[jj]*_scaleFactors[jj]; RealOpenMM sk2 = sk*sk; - if( (_atomicRadii[ii] + r) < sk ){ + if ((_atomicRadii[ii] + r) < sk) { RealOpenMM lik = _atomicRadii[ii]; RealOpenMM uik = sk - r; RealOpenMM lik3 = lik*lik*lik; @@ -175,9 +175,9 @@ void AmoebaReferenceGeneralizedKirkwoodForce::calculateGrycukBornRadii( const ve RealOpenMM uik = r + sk; RealOpenMM lik; - if( (_atomicRadii[ii] + r) < sk ){ + if ((_atomicRadii[ii] + r) < sk) { lik = sk - r; - } else if( r < (_atomicRadii[ii] + sk) ){ + } else if (r < (_atomicRadii[ii] + sk)) { lik = _atomicRadii[ii]; } else { lik = r - sk; @@ -198,7 +198,7 @@ void AmoebaReferenceGeneralizedKirkwoodForce::calculateGrycukBornRadii( const ve } bornSum = one/(_atomicRadii[ii]*_atomicRadii[ii]*_atomicRadii[ii]) - bornSum; - _bornRadii[ii] = (bornSum <= zero) ? bigRadius : POW( bornSum, -oneThird ); + _bornRadii[ii] = (bornSum <= zero) ? bigRadius : POW(bornSum, -oneThird); } return; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h index 9cb351626..638bd6f60 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceGeneralizedKirkwoodForce.h @@ -41,13 +41,13 @@ public: * Constructor * */ - AmoebaReferenceGeneralizedKirkwoodForce( ); + AmoebaReferenceGeneralizedKirkwoodForce(); /** * Destructor * */ - ~AmoebaReferenceGeneralizedKirkwoodForce( ){}; + ~AmoebaReferenceGeneralizedKirkwoodForce() {}; /** * Get number of particles @@ -55,7 +55,7 @@ public: * @return numParticles * */ - int getNumParticles( void ) const; + int getNumParticles() const; /** * Set numParticles @@ -63,7 +63,7 @@ public: * @param numParticles * */ - void setNumParticles( int numParticles ); + void setNumParticles(int numParticles); /** * Get includeCavityTerm flag @@ -71,7 +71,7 @@ public: * @return includeCavityTerm * */ - int getIncludeCavityTerm( void ) const; + int getIncludeCavityTerm() const; /** * Set includeCavityTerm flag @@ -79,7 +79,7 @@ public: * @param includeCavityTerm flag indicating whether surface area term is to be included * */ - void setIncludeCavityTerm( int includeCavityTerm ); + void setIncludeCavityTerm(int includeCavityTerm); /** * Get directPolarization flag @@ -87,21 +87,21 @@ public: * @return directPolarization * */ - int getDirectPolarization( void ) const; + int getDirectPolarization() const; /** * Set directPolarization flag * * @param directPolarization nonzero if direct as opposed to mutual polarization */ - void setDirectPolarization( int directPolarization ); + void setDirectPolarization(int directPolarization); /** * Get solute dielectric * * @return soluteDielectric */ - RealOpenMM getSoluteDielectric( void ) const; + RealOpenMM getSoluteDielectric() const; /** * Set solute dielectric @@ -109,7 +109,7 @@ public: * @param soluteDielectric solute dielectric * */ - void setSoluteDielectric( RealOpenMM soluteDielectric ); + void setSoluteDielectric(RealOpenMM soluteDielectric); /** * Get solvent dielectric @@ -117,7 +117,7 @@ public: * @return solventDielectric * */ - RealOpenMM getSolventDielectric( void ) const; + RealOpenMM getSolventDielectric() const; /** * Set solvent dielectric @@ -125,7 +125,7 @@ public: * @param solventDielectric solvent dielectric * */ - void setSolventDielectric( RealOpenMM solventDielectric ); + void setSolventDielectric(RealOpenMM solventDielectric); /** * Get dielectric offset @@ -133,7 +133,7 @@ public: * @return dielectricOffset * */ - RealOpenMM getDielectricOffset( void ) const; + RealOpenMM getDielectricOffset() const; /** * Set dielectric offset @@ -141,7 +141,7 @@ public: * @param dielectricOffset dielectric offset * */ - void setDielectricOffset( RealOpenMM dielectricOffset ); + void setDielectricOffset(RealOpenMM dielectricOffset); /** * Get probeRadius @@ -149,7 +149,7 @@ public: * @return probeRadius * */ - RealOpenMM getProbeRadius( void ) const; + RealOpenMM getProbeRadius() const; /** * Set probe radius @@ -157,7 +157,7 @@ public: * @param probeRadius probe radiue * */ - void setProbeRadius( RealOpenMM probeRadius ); + void setProbeRadius(RealOpenMM probeRadius); /** * Get surfaceAreaFactor @@ -165,7 +165,7 @@ public: * @return surfaceAreaFactor * */ - RealOpenMM getSurfaceAreaFactor( void ) const; + RealOpenMM getSurfaceAreaFactor() const; /** * Set surface area factor @@ -173,7 +173,7 @@ public: * @param surfaceAreaFactor surface area factor * */ - void setSurfaceAreaFactor( RealOpenMM surfaceAreaFactor ); + void setSurfaceAreaFactor(RealOpenMM surfaceAreaFactor); /** * Set atomic radii @@ -181,7 +181,7 @@ public: * @param atomicRadii input vector of atomic radii * */ - void setAtomicRadii( const vector& atomicRadii ); + void setAtomicRadii(const vector& atomicRadii); /** * Get atomic radii @@ -189,7 +189,7 @@ public: * @param atomicRadii output vector of atomic radii * */ - void getAtomicRadii( vector& atomicRadii ) const; + void getAtomicRadii(vector& atomicRadii) const; /** * Set scale factors @@ -197,7 +197,7 @@ public: * @param scaleFactors input vector of scale factors * */ - void setScaleFactors( const vector& scaleFactors ); + void setScaleFactors(const vector& scaleFactors); /** * Get scale factors @@ -205,7 +205,7 @@ public: * @param scaleFactors output vector of scale factors * */ - void getScaleFactors( vector& scaleFactors ) const; + void getScaleFactors(vector& scaleFactors) const; /** * Set charges @@ -213,7 +213,7 @@ public: * @param charges input vector of charges * */ - void setCharges( const vector& charges ); + void setCharges(const vector& charges); /** * Calculate Grycuk Born radii @@ -221,7 +221,7 @@ public: * @param particlePositions particle positions * */ - void calculateGrycukBornRadii( const vector& particlePositions ); + void calculateGrycukBornRadii(const vector& particlePositions); /** * Get Grycik Born radii (must have called calculateGrycukBornRadii()) @@ -229,7 +229,7 @@ public: * @param bornRadii vector of Born radii * */ - void getGrycukBornRadii( vector& bornRadii ) const; + void getGrycukBornRadii(vector& bornRadii) const; private: diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp index b1d4c228d..cd4dd6ed7 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp @@ -46,11 +46,11 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceInPlaneAngleForce::getPrefactorsGivenAngleCosine( RealOpenMM cosine, +RealOpenMM AmoebaReferenceInPlaneAngleForce::getPrefactorsGivenAngleCosine(RealOpenMM cosine, RealOpenMM idealAngle, RealOpenMM angleK, RealOpenMM angleCubic, RealOpenMM angleQuartic, RealOpenMM anglePentic, RealOpenMM angleSextic, - RealOpenMM* dEdR ) const { + RealOpenMM* dEdR) const { // --------------------------------------------------------------------------------------- @@ -67,9 +67,9 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::getPrefactorsGivenAngleCosine( Real // --------------------------------------------------------------------------------------- RealOpenMM angle; - if( cosine >= one ){ + if (cosine >= one) { angle = zero; - } else if( cosine <= -one ){ + } else if (cosine <= -one) { angle = RADIAN*PI_M; } else { angle = RADIAN*ACOS(cosine); @@ -79,10 +79,10 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::getPrefactorsGivenAngleCosine( Real RealOpenMM deltaIdeal3 = deltaIdeal*deltaIdeal2; RealOpenMM deltaIdeal4 = deltaIdeal2*deltaIdeal2; - *dEdR = ( two + three*angleCubic*deltaIdeal + - four*angleQuartic*deltaIdeal2 + - five*anglePentic*deltaIdeal3 + - six*angleSextic*deltaIdeal4 ); + *dEdR = (two + three*angleCubic*deltaIdeal + + four*angleQuartic*deltaIdeal2 + + five*anglePentic*deltaIdeal3 + + six*angleSextic*deltaIdeal4); *dEdR *= RADIAN*angleK*deltaIdeal; @@ -114,12 +114,12 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::getPrefactorsGivenAngleCosine( Real --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, +RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& positionAtomA, const RealVec& positionAtomB, const RealVec& positionAtomC, const RealVec& positionAtomD, RealOpenMM angle, RealOpenMM angleK, RealOpenMM angleCubic, RealOpenMM angleQuartic, RealOpenMM anglePentic, RealOpenMM angleSextic, - RealVec* forces ) const { + RealVec* forces) const { // --------------------------------------------------------------------------------------- @@ -140,80 +140,80 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn( const RealVec& p enum { AD, BD, CD, T, AP, P, CP, M, APxM, CPxM, ADxBD, BDxCD, TxCD, ADxT, dBxAD, CDxdB, LastDeltaAtomIndex }; std::vector deltaR[LastDeltaAtomIndex]; - for( int ii = 0; ii < LastDeltaAtomIndex; ii++ ){ + for (int ii = 0; ii < LastDeltaAtomIndex; ii++) { deltaR[ii].resize(3); } - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomA, deltaR[AD] ); - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomB, deltaR[BD] ); - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomC, deltaR[CD] ); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomB, deltaR[BD]); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomC, deltaR[CD]); - AmoebaReferenceForce::getCrossProduct( deltaR[AD], deltaR[CD], deltaR[T] ); + AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[CD], deltaR[T]); - RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3( deltaR[T] ); - RealOpenMM delta = AmoebaReferenceForce::getDotProduct3( deltaR[T], deltaR[BD] )/rT2; + RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3(deltaR[T]); + RealOpenMM delta = AmoebaReferenceForce::getDotProduct3(deltaR[T], deltaR[BD])/rT2; delta *= -one; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[P][ii] = positionAtomB[ii] + deltaR[T][ii]*delta; deltaR[AP][ii] = positionAtomA[ii] - deltaR[P][ii]; deltaR[CP][ii] = positionAtomC[ii] - deltaR[P][ii]; } - RealOpenMM rAp2 = AmoebaReferenceForce::getNormSquared3( deltaR[AP] ); - RealOpenMM rCp2 = AmoebaReferenceForce::getNormSquared3( deltaR[CP] ); - if( rAp2 <= zero && rCp2 <= zero ){ + RealOpenMM rAp2 = AmoebaReferenceForce::getNormSquared3(deltaR[AP]); + RealOpenMM rCp2 = AmoebaReferenceForce::getNormSquared3(deltaR[CP]); + if (rAp2 <= zero && rCp2 <= zero) { return zero; } - AmoebaReferenceForce::getCrossProduct( deltaR[CP], deltaR[AP], deltaR[M] ); + AmoebaReferenceForce::getCrossProduct(deltaR[CP], deltaR[AP], deltaR[M]); - RealOpenMM rm = AmoebaReferenceForce::getNorm3( deltaR[M] ); - if( rm < 1.0e-06 ){ + RealOpenMM rm = AmoebaReferenceForce::getNorm3(deltaR[M]); + if (rm < 1.0e-06) { rm = 1.0e-06; } - RealOpenMM dot = AmoebaReferenceForce::getDotProduct3( deltaR[AP], deltaR[CP] ); - RealOpenMM cosine = dot/SQRT( rAp2*rCp2 ); + RealOpenMM dot = AmoebaReferenceForce::getDotProduct3(deltaR[AP], deltaR[CP]); + RealOpenMM cosine = dot/SQRT(rAp2*rCp2); RealOpenMM dEdR; - RealOpenMM energy = getPrefactorsGivenAngleCosine( cosine, angle, angleK, angleCubic, angleQuartic, - anglePentic, angleSextic, &dEdR ); + RealOpenMM energy = getPrefactorsGivenAngleCosine(cosine, angle, angleK, angleCubic, angleQuartic, + anglePentic, angleSextic, &dEdR); RealOpenMM termA = -dEdR/(rAp2*rm); RealOpenMM termC = dEdR/(rCp2*rm); - AmoebaReferenceForce::getCrossProduct( deltaR[AP], deltaR[M], deltaR[APxM] ); - AmoebaReferenceForce::getCrossProduct( deltaR[CP], deltaR[M], deltaR[CPxM] ); + AmoebaReferenceForce::getCrossProduct(deltaR[AP], deltaR[M], deltaR[APxM]); + AmoebaReferenceForce::getCrossProduct(deltaR[CP], deltaR[M], deltaR[CPxM]); // forces will be gathered here enum { dA, dB, dC, dD, LastDIndex }; std::vector forceTerm[LastDIndex]; - for( int ii = 0; ii < LastDIndex; ii++ ){ + for (int ii = 0; ii < LastDIndex; ii++) { forceTerm[ii].resize(3); } - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forceTerm[dA][ii] = deltaR[APxM][ii]*termA; forceTerm[dC][ii] = deltaR[CPxM][ii]*termC; - forceTerm[dB][ii] = -one*( forceTerm[dA][ii] + forceTerm[dC][ii] ); + forceTerm[dB][ii] = -one*(forceTerm[dA][ii] + forceTerm[dC][ii]); } - RealOpenMM pTrT2 = AmoebaReferenceForce::getDotProduct3( forceTerm[dB], deltaR[T] ); + RealOpenMM pTrT2 = AmoebaReferenceForce::getDotProduct3(forceTerm[dB], deltaR[T]); pTrT2 /= rT2; - AmoebaReferenceForce::getCrossProduct( deltaR[CD], forceTerm[dB], deltaR[CDxdB] ); - AmoebaReferenceForce::getCrossProduct( forceTerm[dB], deltaR[AD], deltaR[dBxAD] ); + AmoebaReferenceForce::getCrossProduct(deltaR[CD], forceTerm[dB], deltaR[CDxdB]); + AmoebaReferenceForce::getCrossProduct(forceTerm[dB], deltaR[AD], deltaR[dBxAD]); - if( FABS( pTrT2 ) > 1.0e-08 ){ + if (FABS(pTrT2) > 1.0e-08) { RealOpenMM delta2 = delta*two; - AmoebaReferenceForce::getCrossProduct( deltaR[BD], deltaR[CD], deltaR[BDxCD] ); - AmoebaReferenceForce::getCrossProduct( deltaR[T], deltaR[CD], deltaR[TxCD] ); - AmoebaReferenceForce::getCrossProduct( deltaR[AD], deltaR[BD], deltaR[ADxBD] ); - AmoebaReferenceForce::getCrossProduct( deltaR[AD], deltaR[T], deltaR[ADxT] ); - for( int ii = 0; ii < 3; ii++ ){ + AmoebaReferenceForce::getCrossProduct(deltaR[BD], deltaR[CD], deltaR[BDxCD]); + AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[CD], deltaR[TxCD] ); + AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[BD], deltaR[ADxBD]); + AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[T], deltaR[ADxT] ); + for (int ii = 0; ii < 3; ii++) { RealOpenMM term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii]; forceTerm[dA][ii] += delta*deltaR[CDxdB][ii] + term*pTrT2; @@ -221,21 +221,21 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn( const RealVec& p term = deltaR[ADxBD][ii] + delta2*deltaR[ADxT][ii]; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii] + term*pTrT2; - forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); + forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]); } } else { - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forceTerm[dA][ii] += delta*deltaR[CDxdB][ii]; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii]; - forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); + forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]); } } // accumulate forces - for( int jj = 0; jj < 4; jj++ ){ + for (int jj = 0; jj < 4; jj++) { forces[jj][0] = forceTerm[jj][0]; forces[jj][1] = forceTerm[jj][1]; forces[jj][2] = forceTerm[jj][2]; @@ -245,18 +245,18 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn( const RealVec& p } -RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateForceAndEnergy( int numAngles, vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& particle4, - const std::vector& angle, - const std::vector& kQuadratic, - RealOpenMM angleCubic, - RealOpenMM angleQuartic, - RealOpenMM anglePentic, - RealOpenMM angleSextic, - vector& forceData) const { +RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateForceAndEnergy(int numAngles, vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& particle4, + const std::vector& angle, + const std::vector& kQuadratic, + RealOpenMM angleCubic, + RealOpenMM angleQuartic, + RealOpenMM anglePentic, + RealOpenMM angleSextic, + vector& forceData) const { RealOpenMM energy = 0.0; for (unsigned int ii = 0; ii < static_cast(numAngles); ii++) { int particle1Index = particle1[ii]; @@ -266,12 +266,12 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateForceAndEnergy( int numAng RealOpenMM idealAngle = angle[ii]; RealOpenMM angleK = kQuadratic[ii]; RealVec forces[4]; - energy += calculateAngleIxn( posData[particle1Index], posData[particle2Index], posData[particle3Index], posData[particle4Index], - idealAngle, angleK, angleCubic, angleQuartic, anglePentic, angleSextic, forces ); + energy += calculateAngleIxn(posData[particle1Index], posData[particle2Index], posData[particle3Index], posData[particle4Index], + idealAngle, angleK, angleCubic, angleQuartic, anglePentic, angleSextic, forces); // accumulate forces - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { forceData[particle1Index][jj] -= forces[0][jj]; forceData[particle2Index][jj] -= forces[1][jj]; forceData[particle3Index][jj] -= forces[2][jj]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h index 352cda4fb..d9d7a1660 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.h @@ -40,7 +40,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceInPlaneAngleForce( ){}; + AmoebaReferenceInPlaneAngleForce() {}; /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceInPlaneAngleForce( ){}; + ~AmoebaReferenceInPlaneAngleForce() {}; /**--------------------------------------------------------------------------------------- @@ -73,18 +73,18 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numAngles, std::vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& particle4, - const std::vector& angle, - const std::vector& kQuadratic, - RealOpenMM globalAngleCubic, - RealOpenMM globalAngleQuartic, - RealOpenMM globalAnglePentic, - RealOpenMM globalAngleSextic, - std::vector& forceData ) const; + RealOpenMM calculateForceAndEnergy(int numAngles, std::vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& particle4, + const std::vector& angle, + const std::vector& kQuadratic, + RealOpenMM globalAngleCubic, + RealOpenMM globalAngleQuartic, + RealOpenMM globalAnglePentic, + RealOpenMM globalAngleSextic, + std::vector& forceData) const; private: @@ -106,10 +106,10 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM getPrefactorsGivenAngleCosine( RealOpenMM cosine, RealOpenMM idealAngle, RealOpenMM angleK, - RealOpenMM angleCubic, RealOpenMM angleQuartic, - RealOpenMM anglePentic, RealOpenMM angleSextic, - RealOpenMM* dEdR ) const; + RealOpenMM getPrefactorsGivenAngleCosine(RealOpenMM cosine, RealOpenMM idealAngle, RealOpenMM angleK, + RealOpenMM angleCubic, RealOpenMM angleQuartic, + RealOpenMM anglePentic, RealOpenMM angleSextic, + RealOpenMM* dEdR) const; /**--------------------------------------------------------------------------------------- @@ -131,12 +131,12 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateAngleIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, - RealOpenMM angle, RealOpenMM angleK, - RealOpenMM angleCubic, RealOpenMM angleQuartic, - RealOpenMM anglePentic, RealOpenMM angleSextic, - OpenMM::RealVec* forces ) const; + RealOpenMM calculateAngleIxn(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, + RealOpenMM angle, RealOpenMM angleK, + RealOpenMM angleCubic, RealOpenMM angleQuartic, + RealOpenMM anglePentic, RealOpenMM angleSextic, + OpenMM::RealVec* forces) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp index d2bdb8288..4906a04ca 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp @@ -789,7 +789,7 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesBySOR(const vector(_numParticles))); @@ -1868,7 +1868,7 @@ void AmoebaReferenceMultipoleForce::calculateElectrostaticPotential(const vector for (unsigned int ii = 0; ii < _numParticles; ii++) { for (unsigned int jj = 0; jj < grid.size(); jj++) { - potential[jj] += calculateElectrostaticPotentialForParticleGridPoint(particleData[ii], grid[jj] ); + potential[jj] += calculateElectrostaticPotentialForParticleGridPoint(particleData[ii], grid[jj]); } } @@ -4947,7 +4947,7 @@ void AmoebaReferencePmeMultipoleForce::calculateFixedMultipoleField(const vector /** * This is called from computeBsplines(). It calculates the spline coefficients for a single atom along a single axis. */ -void AmoebaReferencePmeMultipoleForce::computeBSplinePoint(vector& thetai, RealOpenMM w ) +void AmoebaReferencePmeMultipoleForce::computeBSplinePoint(vector& thetai, RealOpenMM w) { RealOpenMM array[AMOEBA_PME_ORDER*AMOEBA_PME_ORDER]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h index 048549a49..4616ea491 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h @@ -354,7 +354,7 @@ public: * Destructor * */ - virtual ~AmoebaReferenceMultipoleForce(){}; + virtual ~AmoebaReferenceMultipoleForce() {}; /** * Get nonbonded method. diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp index a2838e301..459766435 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp @@ -48,12 +48,12 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, - const RealVec& positionAtomC, const RealVec& positionAtomD, - RealOpenMM angleK, - RealOpenMM angleCubic, RealOpenMM angleQuartic, - RealOpenMM anglePentic, RealOpenMM angleSextic, - RealVec* forces ) const { +RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn(const RealVec& positionAtomA, const RealVec& positionAtomB, + const RealVec& positionAtomC, const RealVec& positionAtomD, + RealOpenMM angleK, + RealOpenMM angleCubic, RealOpenMM angleQuartic, + RealOpenMM anglePentic, RealOpenMM angleSextic, + RealVec* forces) const { // --------------------------------------------------------------------------------------- @@ -76,34 +76,34 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn( const // and various intermediate terms std::vector deltaR[LastDeltaIndex]; - for( int ii = 0; ii < LastDeltaIndex; ii++ ){ + for (int ii = 0; ii < LastDeltaIndex; ii++) { deltaR[ii].resize(3); } - AmoebaReferenceForce::loadDeltaR( positionAtomB, positionAtomA, deltaR[AB] ); - AmoebaReferenceForce::loadDeltaR( positionAtomB, positionAtomC, deltaR[CB] ); - AmoebaReferenceForce::loadDeltaR( positionAtomB, positionAtomD, deltaR[DB] ); - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomA, deltaR[AD] ); - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomC, deltaR[CD] ); + AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomA, deltaR[AB]); + AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]); + AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomD, deltaR[DB]); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomC, deltaR[CD]); - RealOpenMM rDB2 = AmoebaReferenceForce::getNormSquared3( deltaR[DB] ); - RealOpenMM rAD2 = AmoebaReferenceForce::getNormSquared3( deltaR[AD] ); - RealOpenMM rCD2 = AmoebaReferenceForce::getNormSquared3( deltaR[CD] ); + RealOpenMM rDB2 = AmoebaReferenceForce::getNormSquared3(deltaR[DB]); + RealOpenMM rAD2 = AmoebaReferenceForce::getNormSquared3(deltaR[AD]); + RealOpenMM rCD2 = AmoebaReferenceForce::getNormSquared3(deltaR[CD]); std::vector tempVector(3); - AmoebaReferenceForce::getCrossProduct( deltaR[CB], deltaR[DB], tempVector ); - RealOpenMM eE = AmoebaReferenceForce::getDotProduct3( deltaR[AB], tempVector ); - RealOpenMM dot = AmoebaReferenceForce::getDotProduct3( deltaR[AD], deltaR[CD] ); + AmoebaReferenceForce::getCrossProduct(deltaR[CB], deltaR[DB], tempVector); + RealOpenMM eE = AmoebaReferenceForce::getDotProduct3(deltaR[AB], tempVector ); + RealOpenMM dot = AmoebaReferenceForce::getDotProduct3(deltaR[AD], deltaR[CD]); RealOpenMM cc = rAD2*rCD2 - dot*dot; - if( rDB2 <= zero || cc == zero ){ + if (rDB2 <= zero || cc == zero) { return zero; } RealOpenMM bkk2 = rDB2 - eE*eE/cc; RealOpenMM cosine = SQRT(bkk2/rDB2); RealOpenMM angle; - if( cosine >= one ){ + if (cosine >= one) { angle = zero; - } else if( cosine <= -one ){ + } else if (cosine <= -one) { angle = PI_M; } else { angle = RADIAN*ACOS(cosine); @@ -122,7 +122,7 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn( const dEdDt *= angleK*dt*RADIAN; RealOpenMM dEdCos = dEdDt/SQRT(cc*bkk2); - if( eE > zero ){ + if (eE > zero) { dEdCos *= -one; } @@ -131,20 +131,20 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn( const std::vector dccd[LastAtomIndex]; std::vector deed[LastAtomIndex]; std::vector subForce[LastAtomIndex]; - for( int ii = 0; ii < LastAtomIndex; ii++ ){ + for (int ii = 0; ii < LastAtomIndex; ii++) { dccd[ii].resize(3); deed[ii].resize(3); subForce[ii].resize(3); } - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { dccd[A][ii] = (deltaR[AD][ii]*rCD2 - deltaR[CD][ii]*dot)*term; dccd[C][ii] = (deltaR[CD][ii]*rAD2 - deltaR[AD][ii]*dot)*term; dccd[D][ii] = -one*(dccd[A][ii] + dccd[C][ii]); } - AmoebaReferenceForce::getCrossProduct( deltaR[DB], deltaR[CB], deed[A] ); - AmoebaReferenceForce::getCrossProduct( deltaR[AB], deltaR[DB], deed[C] ); - AmoebaReferenceForce::getCrossProduct( deltaR[CB], deltaR[AB], deed[D] ); + AmoebaReferenceForce::getCrossProduct(deltaR[DB], deltaR[CB], deed[A]); + AmoebaReferenceForce::getCrossProduct(deltaR[AB], deltaR[DB], deed[C]); + AmoebaReferenceForce::getCrossProduct(deltaR[CB], deltaR[AB], deed[D]); term = eE/rDB2; deed[D][0] += deltaR[DB][0]*term; @@ -156,23 +156,23 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn( const // forces // calculate forces for atoms a, c, d - // the force for b is then -( a+ c + d) + // the force for b is then -(a+ c + d) - for( int jj = 0; jj < LastAtomIndex; jj++ ){ + for (int jj = 0; jj < LastAtomIndex; jj++) { // A, C, D - for( int ii = 0; ii < 3; ii++ ){ - subForce[jj][ii] = dEdCos*( dccd[jj][ii] + deed[jj][ii] ); + for (int ii = 0; ii < 3; ii++) { + subForce[jj][ii] = dEdCos*(dccd[jj][ii] + deed[jj][ii]); } - if( jj == 0 )jj++; // skip B + if (jj == 0)jj++; // skip B // now compute B - if( jj == 3 ){ - for( int ii = 0; ii < 3; ii++ ){ + if (jj == 3) { + for (int ii = 0; ii < 3; ii++) { subForce[1][ii] = -one*(subForce[0][ii] + subForce[2][ii] + subForce[3][ii]); } } @@ -180,8 +180,8 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn( const // add in forces - for( int jj = 0; jj < LastAtomIndex; jj++ ){ - for( int ii = 0; ii < 3; ii++ ){ + for (int jj = 0; jj < LastAtomIndex; jj++) { + for (int ii = 0; ii < 3; ii++) { forces[jj][ii] = subForce[jj][ii]; } } @@ -196,7 +196,7 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn( const return energy; } -RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateForceAndEnergy( int numOutOfPlaneBends, vector& posData, +RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateForceAndEnergy(int numOutOfPlaneBends, vector& posData, const std::vector& particle1, const std::vector& particle2, const std::vector& particle3, @@ -215,9 +215,9 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateForceAndEnergy( int numO int particle4Index = particle4[ii]; RealOpenMM kAngle = kQuadratic[ii]; RealVec forces[4]; - energy += calculateOutOfPlaneBendIxn( posData[particle1Index], posData[particle2Index], posData[particle3Index], posData[particle4Index], - kAngle, angleCubic, angleQuartic, anglePentic, angleSextic, forces ); - for( int jj = 0; jj < 3; jj++ ){ + energy += calculateOutOfPlaneBendIxn(posData[particle1Index], posData[particle2Index], posData[particle3Index], posData[particle4Index], + kAngle, angleCubic, angleQuartic, anglePentic, angleSextic, forces); + for (int jj = 0; jj < 3; jj++) { forceData[particle1Index][jj] -= forces[0][jj]; forceData[particle2Index][jj] -= forces[1][jj]; forceData[particle3Index][jj] -= forces[2][jj]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h index ce08fe510..ef361dd55 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.h @@ -40,7 +40,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceOutOfPlaneBendForce( ){}; + AmoebaReferenceOutOfPlaneBendForce() {}; /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceOutOfPlaneBendForce( ){}; + ~AmoebaReferenceOutOfPlaneBendForce() {}; /**--------------------------------------------------------------------------------------- @@ -72,17 +72,17 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numOutOfPlaneBends, std::vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& particle4, - const std::vector& kAngle, - RealOpenMM angleCubic, - RealOpenMM angleQuartic, - RealOpenMM anglePentic, - RealOpenMM angleSextic, - std::vector& forceData) const; + RealOpenMM calculateForceAndEnergy(int numOutOfPlaneBends, std::vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& particle4, + const std::vector& kAngle, + RealOpenMM angleCubic, + RealOpenMM angleQuartic, + RealOpenMM anglePentic, + RealOpenMM angleSextic, + std::vector& forceData) const; private: @@ -105,12 +105,12 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateOutOfPlaneBendIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, - RealOpenMM angleK, - RealOpenMM angleCubic, RealOpenMM angleQuartic, - RealOpenMM anglePentic, RealOpenMM angleSextic, - OpenMM::RealVec* forces ) const; + RealOpenMM calculateOutOfPlaneBendIxn(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, + RealOpenMM angleK, + RealOpenMM angleCubic, RealOpenMM angleQuartic, + RealOpenMM anglePentic, RealOpenMM angleSextic, + OpenMM::RealVec* forces) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp index df480a9d5..e46680087 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp @@ -46,10 +46,10 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, - const RealVec& positionAtomC, const RealVec& positionAtomD, - const RealVec& positionAtomE, const RealVec& positionAtomF, - RealOpenMM piTorsionK, RealVec* forces ) const { +RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn(const RealVec& positionAtomA, const RealVec& positionAtomB, + const RealVec& positionAtomC, const RealVec& positionAtomD, + const RealVec& positionAtomE, const RealVec& positionAtomF, + RealOpenMM piTorsionK, RealVec* forces) const { // --------------------------------------------------------------------------------------- @@ -64,23 +64,23 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn( const RealVec& enum { AD, BD, EC, FC, P, Q, CP, DC, QD, T, U, TU, DP, QC, dT, dU, dP, dQ, dC1, dC2, dD1, dD2, LastDeltaIndex }; std::vector deltaR[LastDeltaIndex]; - for( unsigned int ii = 0; ii < LastDeltaIndex; ii++ ){ + for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) { deltaR[ii].resize(3); } - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomA, deltaR[AD] ); - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomB, deltaR[BD] ); - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomE, deltaR[EC] ); - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomF, deltaR[FC] ); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomA, deltaR[AD]); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomB, deltaR[BD]); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomE, deltaR[EC]); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomF, deltaR[FC]); enum { A, B, C, D, E, F, LastAtomIndex }; std::vector d[LastAtomIndex]; - for( unsigned int ii = 0; ii < LastAtomIndex; ii++ ){ + for (unsigned int ii = 0; ii < LastAtomIndex; ii++) { d[ii].resize(3); } - AmoebaReferenceForce::getCrossProduct( deltaR[AD], deltaR[BD], deltaR[P] ); - AmoebaReferenceForce::getCrossProduct( deltaR[EC], deltaR[FC], deltaR[Q] ); - for( int ii = 0; ii < 3; ii++ ){ + AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[BD], deltaR[P]); + AmoebaReferenceForce::getCrossProduct(deltaR[EC], deltaR[FC], deltaR[Q]); + for (int ii = 0; ii < 3; ii++) { deltaR[CP][ii] = -deltaR[P][ii]; deltaR[DC][ii] = positionAtomD[ii] - positionAtomC[ii]; deltaR[QD][ii] = deltaR[Q][ii]; @@ -88,24 +88,24 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn( const RealVec& deltaR[P][ii] += positionAtomC[ii]; deltaR[Q][ii] += positionAtomD[ii]; } - AmoebaReferenceForce::getCrossProduct( deltaR[CP], deltaR[DC], deltaR[T] ); - AmoebaReferenceForce::getCrossProduct( deltaR[DC], deltaR[QD], deltaR[U] ); - AmoebaReferenceForce::getCrossProduct( deltaR[T], deltaR[U], deltaR[TU] ); - - RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3( deltaR[T] ); - RealOpenMM rU2 = AmoebaReferenceForce::getNormSquared3( deltaR[U] ); - RealOpenMM rTrU = SQRT( rT2*rU2 ); - if( rTrU <= zero ){ + AmoebaReferenceForce::getCrossProduct(deltaR[CP], deltaR[DC], deltaR[T] ); + AmoebaReferenceForce::getCrossProduct(deltaR[DC], deltaR[QD], deltaR[U] ); + AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[U], deltaR[TU]); + + RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3(deltaR[T]); + RealOpenMM rU2 = AmoebaReferenceForce::getNormSquared3(deltaR[U]); + RealOpenMM rTrU = SQRT(rT2*rU2); + if (rTrU <= zero) { return zero; } - RealOpenMM rDC = AmoebaReferenceForce::getNorm3( deltaR[DC] ); + RealOpenMM rDC = AmoebaReferenceForce::getNorm3(deltaR[DC]); - RealOpenMM cosine = AmoebaReferenceForce::getDotProduct3( deltaR[T], deltaR[U] ); + RealOpenMM cosine = AmoebaReferenceForce::getDotProduct3(deltaR[T], deltaR[U]); cosine /= rTrU; - RealOpenMM sine = AmoebaReferenceForce::getDotProduct3( deltaR[DC], deltaR[TU] ); - sine /= ( rDC*rTrU ); + RealOpenMM sine = AmoebaReferenceForce::getDotProduct3(deltaR[DC], deltaR[TU]); + sine /= (rDC*rTrU); RealOpenMM cosine2 = cosine*cosine - sine*sine; RealOpenMM sine2 = two*cosine*sine; @@ -115,37 +115,37 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn( const RealVec& RealOpenMM dedphi = piTorsionK*dphi2; - for( unsigned int ii = 0; ii < 3; ii++ ){ + for (unsigned int ii = 0; ii < 3; ii++) { deltaR[DP][ii] = positionAtomD[ii] - deltaR[P][ii]; deltaR[QC][ii] = deltaR[Q][ii] - positionAtomC[ii]; } - RealOpenMM factorT = dedphi/( rDC*rT2 ); - RealOpenMM factorU = -dedphi/( rDC*rU2 ); + RealOpenMM factorT = dedphi/(rDC*rT2); + RealOpenMM factorU = -dedphi/(rDC*rU2); - AmoebaReferenceForce::getCrossProduct( deltaR[T], deltaR[DC], deltaR[dT] ); - AmoebaReferenceForce::getCrossProduct( deltaR[U], deltaR[DC], deltaR[dU] ); - for( int ii = 0; ii < 3; ii++ ){ + AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[DC], deltaR[dT] ); + AmoebaReferenceForce::getCrossProduct(deltaR[U], deltaR[DC], deltaR[dU] ); + for (int ii = 0; ii < 3; ii++) { deltaR[dT][ii] *= factorT; deltaR[dU][ii] *= factorU; } - AmoebaReferenceForce::getCrossProduct( deltaR[dT], deltaR[DC], deltaR[dP] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dU], deltaR[DC], deltaR[dQ] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[DC], deltaR[dP] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[DC], deltaR[dQ] ); - AmoebaReferenceForce::getCrossProduct( deltaR[DP], deltaR[dT], deltaR[dC1] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dU], deltaR[QD], deltaR[dC2] ); + AmoebaReferenceForce::getCrossProduct(deltaR[DP], deltaR[dT], deltaR[dC1] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[QD], deltaR[dC2] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dT], deltaR[CP], deltaR[dD1] ); - AmoebaReferenceForce::getCrossProduct( deltaR[QC], deltaR[dU], deltaR[dD2] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[CP], deltaR[dD1] ); + AmoebaReferenceForce::getCrossProduct(deltaR[QC], deltaR[dU], deltaR[dD2] ); - AmoebaReferenceForce::getCrossProduct( deltaR[BD], deltaR[dP], d[A] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dP], deltaR[AD], d[B] ); + AmoebaReferenceForce::getCrossProduct(deltaR[BD], deltaR[dP], d[A] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dP], deltaR[AD], d[B] ); - AmoebaReferenceForce::getCrossProduct( deltaR[FC], deltaR[dQ], d[E] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dQ], deltaR[EC], d[F] ); + AmoebaReferenceForce::getCrossProduct(deltaR[FC], deltaR[dQ], d[E] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dQ], deltaR[EC], d[F] ); - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { d[C][ii] = deltaR[dC1][ii] + deltaR[dC2][ii] + deltaR[dP][ii] - d[E][ii] - d[F][ii]; d[D][ii] = deltaR[dD1][ii] + deltaR[dD2][ii] + deltaR[dQ][ii] - d[A][ii] - d[B][ii]; } @@ -186,15 +186,15 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn( const RealVec& } -RealOpenMM AmoebaReferencePiTorsionForce::calculateForceAndEnergy( int numPiTorsions, vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& particle4, - const std::vector& particle5, - const std::vector& particle6, - const std::vector& kTorsion, - vector& forceData ) const { +RealOpenMM AmoebaReferencePiTorsionForce::calculateForceAndEnergy(int numPiTorsions, vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& particle4, + const std::vector& particle5, + const std::vector& particle6, + const std::vector& kTorsion, + vector& forceData) const { RealOpenMM energy = 0.0; for (unsigned int ii = 0; ii < static_cast(numPiTorsions); ii++) { @@ -206,13 +206,13 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculateForceAndEnergy( int numPiTors int particle6Index = particle6[ii]; RealVec forces[6]; - energy += calculatePiTorsionIxn( posData[particle1Index], posData[particle2Index], - posData[particle3Index], posData[particle4Index], - posData[particle5Index], posData[particle6Index], - kTorsion[ii], forces ); + energy += calculatePiTorsionIxn(posData[particle1Index], posData[particle2Index], + posData[particle3Index], posData[particle4Index], + posData[particle5Index], posData[particle6Index], + kTorsion[ii], forces); // accumulate forces - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { forceData[particle1Index][jj] -= forces[0][jj]; forceData[particle2Index][jj] -= forces[1][jj]; forceData[particle3Index][jj] -= forces[2][jj]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h index de8c29424..9cb3965c3 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.h @@ -40,7 +40,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferencePiTorsionForce( ){}; + AmoebaReferencePiTorsionForce() {}; /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferencePiTorsionForce( ){}; + ~AmoebaReferencePiTorsionForce() {}; /**--------------------------------------------------------------------------------------- @@ -72,15 +72,15 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numPiTorsions, std::vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& particle4, - const std::vector& particle5, - const std::vector& particle6, - const std::vector& kTorsion, - std::vector& forceData ) const; + RealOpenMM calculateForceAndEnergy(int numPiTorsions, std::vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& particle4, + const std::vector& particle5, + const std::vector& particle6, + const std::vector& kTorsion, + std::vector& forceData) const; private: @@ -102,10 +102,10 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculatePiTorsionIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, - const OpenMM::RealVec& positionAtomE, const OpenMM::RealVec& positionAtomF, - RealOpenMM kTorsion, OpenMM::RealVec* forces ) const; + RealOpenMM calculatePiTorsionIxn(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, + const OpenMM::RealVec& positionAtomE, const OpenMM::RealVec& positionAtomF, + RealOpenMM kTorsion, OpenMM::RealVec* forces) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp index 9802e423f..c9d8dc573 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.cpp @@ -49,11 +49,11 @@ using namespace OpenMM; --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, - const RealVec& positionAtomC, - RealOpenMM lengthAB, RealOpenMM lengthCB, - RealOpenMM idealAngle, RealOpenMM k1Parameter, - RealOpenMM k2Parameter, RealVec* forces ) const { +RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn(const RealVec& positionAtomA, const RealVec& positionAtomB, + const RealVec& positionAtomC, + RealOpenMM lengthAB, RealOpenMM lengthCB, + RealOpenMM idealAngle, RealOpenMM k1Parameter, + RealOpenMM k2Parameter, RealVec* forces) const { // --------------------------------------------------------------------------------------- @@ -73,28 +73,28 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV // and various intermediate terms std::vector deltaR[LastDeltaIndex]; - for( unsigned int ii = 0; ii < LastDeltaIndex; ii++ ){ + for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) { deltaR[ii].resize(3); } - AmoebaReferenceForce::loadDeltaR( positionAtomB, positionAtomA, deltaR[AB] ); - AmoebaReferenceForce::loadDeltaR( positionAtomB, positionAtomC, deltaR[CB] ); - RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3( deltaR[AB] ); - RealOpenMM rAB = SQRT( rAB2 ); - RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3( deltaR[CB] ); - RealOpenMM rCB = SQRT( rCB2 ); - - AmoebaReferenceForce::getCrossProduct( deltaR[CB], deltaR[AB], deltaR[CBxAB] ); - RealOpenMM rP = AmoebaReferenceForce::getNorm3( deltaR[CBxAB] ); - if( rP <= zero ){ + AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomA, deltaR[AB]); + AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]); + RealOpenMM rAB2 = AmoebaReferenceForce::getNormSquared3(deltaR[AB]); + RealOpenMM rAB = SQRT(rAB2); + RealOpenMM rCB2 = AmoebaReferenceForce::getNormSquared3(deltaR[CB]); + RealOpenMM rCB = SQRT(rCB2); + + AmoebaReferenceForce::getCrossProduct(deltaR[CB], deltaR[AB], deltaR[CBxAB]); + RealOpenMM rP = AmoebaReferenceForce::getNorm3(deltaR[CBxAB]); + if (rP <= zero) { return zero; } - RealOpenMM dot = AmoebaReferenceForce::getDotProduct3( deltaR[CB], deltaR[AB] ); + RealOpenMM dot = AmoebaReferenceForce::getDotProduct3(deltaR[CB], deltaR[AB]); RealOpenMM cosine = dot/(rAB*rCB); RealOpenMM angle; - if( cosine >= one ){ + if (cosine >= one) { angle = zero; - } else if( cosine <= -one ){ + } else if (cosine <= -one) { angle = PI_M; } else { angle = RADIAN*ACOS(cosine); @@ -105,9 +105,9 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV // P = CBxAB - AmoebaReferenceForce::getCrossProduct( deltaR[AB], deltaR[CBxAB], deltaR[ABxP] ); - AmoebaReferenceForce::getCrossProduct( deltaR[CB], deltaR[CBxAB], deltaR[CBxP] ); - for( int ii = 0; ii < 3; ii++ ){ + AmoebaReferenceForce::getCrossProduct(deltaR[AB], deltaR[CBxAB], deltaR[ABxP]); + AmoebaReferenceForce::getCrossProduct(deltaR[CB], deltaR[CBxAB], deltaR[CBxP]); + for (int ii = 0; ii < 3; ii++) { deltaR[ABxP][ii] *= termA; deltaR[CBxP][ii] *= termC; } @@ -123,22 +123,22 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV // forces // calculate forces for atoms a, b, c - // the force for b is then -( a + c) + // the force for b is then -(a + c) std::vector subForce[LastAtomIndex]; - for( int ii = 0; ii < LastAtomIndex; ii++ ){ + for (int ii = 0; ii < LastAtomIndex; ii++) { subForce[ii].resize(3); } RealOpenMM dt = angle - idealAngle*RADIAN; - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { subForce[A][jj] = k1Parameter*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj]; subForce[C][jj] = k2Parameter*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj]; - subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); + subForce[B][jj] = -(subForce[A][jj] + subForce[C][jj]); } // add in forces - for( int jj = 0; jj < LastAtomIndex; jj++ ){ + for (int jj = 0; jj < LastAtomIndex; jj++) { forces[jj][0] = subForce[jj][0]; forces[jj][1] = subForce[jj][1]; forces[jj][2] = subForce[jj][2]; @@ -149,7 +149,7 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateStretchBendIxn( const RealV return dt*drkk; } -RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStretchBends, vector& posData, +RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy(int numStretchBends, vector& posData, const std::vector& particle1, const std::vector& particle2, const std::vector& particle3, @@ -170,11 +170,11 @@ RealOpenMM AmoebaReferenceStretchBendForce::calculateForceAndEnergy( int numStre RealOpenMM angleK1 = k1Quadratic[ii]; RealOpenMM angleK2 = k2Quadratic[ii]; RealVec forces[3]; - energy += calculateStretchBendIxn( posData[particle1Index], posData[particle2Index], posData[particle3Index], - abLength, cbLength, idealAngle, angleK1, angleK2, forces ); + energy += calculateStretchBendIxn(posData[particle1Index], posData[particle2Index], posData[particle3Index], + abLength, cbLength, idealAngle, angleK1, angleK2, forces); // accumulate forces - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { forceData[particle1Index][jj] -= forces[0][jj]; forceData[particle2Index][jj] -= forces[1][jj]; forceData[particle3Index][jj] -= forces[2][jj]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h index ee4ece712..6d2e308b1 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceStretchBendForce.h @@ -40,7 +40,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceStretchBendForce( ){}; + AmoebaReferenceStretchBendForce() {}; /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceStretchBendForce( ){}; + ~AmoebaReferenceStretchBendForce() {}; /**--------------------------------------------------------------------------------------- @@ -70,16 +70,16 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numAngles, std::vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& lengthABParameters, - const std::vector& lengthCBParameters, - const std::vector& angle, - const std::vector& k1Quadratic, - const std::vector& k2Quadratic, - std::vector& forceData ) const; + RealOpenMM calculateForceAndEnergy(int numAngles, std::vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& lengthABParameters, + const std::vector& lengthCBParameters, + const std::vector& angle, + const std::vector& k1Quadratic, + const std::vector& k2Quadratic, + std::vector& forceData) const; private: @@ -102,11 +102,11 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateStretchBendIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - const OpenMM::RealVec& positionAtomC, - RealOpenMM lengthAB, RealOpenMM lengthCB, - RealOpenMM idealAngle, RealOpenMM k1Parameter, - RealOpenMM k2Parameter, OpenMM::RealVec* forces ) const; + RealOpenMM calculateStretchBendIxn(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + const OpenMM::RealVec& positionAtomC, + RealOpenMM lengthAB, RealOpenMM lengthCB, + RealOpenMM idealAngle, RealOpenMM k1Parameter, + RealOpenMM k2Parameter, OpenMM::RealVec* forces) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp index 39074a455..1775b9ae6 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp @@ -50,7 +50,7 @@ using namespace OpenMM; void AmoebaReferenceTorsionTorsionForce::loadGridValuesFromEnclosingRectangle( const std::vector< std::vector< std::vector > >& grid, RealOpenMM angle1, RealOpenMM angle2, RealOpenMM corners[2][2], - RealOpenMM* fValues, RealOpenMM* fValues1, RealOpenMM* fValues2, RealOpenMM* fValues12 ) const { + RealOpenMM* fValues, RealOpenMM* fValues1, RealOpenMM* fValues2, RealOpenMM* fValues12) const { // --------------------------------------------------------------------------------------- @@ -62,8 +62,8 @@ void AmoebaReferenceTorsionTorsionForce::loadGridValuesFromEnclosingRectangle( unsigned int gridSize = grid.size(); double gridSpacingI = static_cast(gridSize-1)/360.0; - const int X_gridIndex = (int) ( (angle1 - grid[0][0][0] )*gridSpacingI + 1.0e-06); - const int Y_gridIndex = (int) ( (angle2 - grid[0][0][1] )*gridSpacingI + 1.0e-06); + const int X_gridIndex = (int) ((angle1 - grid[0][0][0])*gridSpacingI + 1.0e-06); + const int Y_gridIndex = (int) ((angle2 - grid[0][0][1])*gridSpacingI + 1.0e-06); // get coordinates of corner indices @@ -73,15 +73,15 @@ void AmoebaReferenceTorsionTorsionForce::loadGridValuesFromEnclosingRectangle( corners[1][0] = grid[X_gridIndex][Y_gridIndex ][1]; corners[1][1] = grid[X_gridIndex+1][Y_gridIndex+1][1]; - for( int ii = 0; ii < 4; ii++ ){ + for (int ii = 0; ii < 4; ii++) { int gridX = X_gridIndex; int gridY = Y_gridIndex; - if( ii == 1 ){ + if (ii == 1) { gridX++; - } else if( ii == 2 ){ + } else if (ii == 2) { gridX++; gridY++; - } else if( ii == 3 ){ + } else if (ii == 3) { gridY++; } @@ -117,9 +117,9 @@ void AmoebaReferenceTorsionTorsionForce::loadGridValuesFromEnclosingRectangle( --------------------------------------------------------------------------------------- */ -void AmoebaReferenceTorsionTorsionForce::getBicubicCoefficientMatrix( const RealOpenMM* y, +void AmoebaReferenceTorsionTorsionForce::getBicubicCoefficientMatrix(const RealOpenMM* y, const RealOpenMM* y1, const RealOpenMM* y2, const RealOpenMM* y12, const RealOpenMM d1, const RealOpenMM d2, - RealOpenMM c[4][4] ) const { + RealOpenMM c[4][4]) const { // --------------------------------------------------------------------------------------- @@ -159,9 +159,9 @@ void AmoebaReferenceTorsionTorsionForce::getBicubicCoefficientMatrix( const Real // pack y, y1, y2, y12 into single vector of dimension 16 - std::vector x( 16 ); + std::vector x(16); RealOpenMM d1d2 = d1*d2; - for( int ii = 0; ii < 4; ii++ ){ + for (int ii = 0; ii < 4; ii++) { x[ii] = y[ii]; x[ii+4] = y1[ii]*d1; x[ii+8] = y2[ii]*d2; @@ -172,13 +172,13 @@ void AmoebaReferenceTorsionTorsionForce::getBicubicCoefficientMatrix( const Real int rowIndex = 0; int colIndex = 0; - for( int ii = 0; ii < 16; ii++ ){ + for (int ii = 0; ii < 16; ii++) { RealOpenMM sum = weightMatrix[0][ii]*x[0]; - for( int jj = 1; jj < 16; jj++ ){ + for (int jj = 1; jj < 16; jj++) { sum += weightMatrix[jj][ii]*x[jj]; } c[rowIndex][colIndex++] = sum; - if( !(colIndex % 4) ){ + if (!(colIndex % 4)) { colIndex = 0; rowIndex++; } @@ -216,12 +216,12 @@ void AmoebaReferenceTorsionTorsionForce::getBicubicCoefficientMatrix( const Real --------------------------------------------------------------------------------------- */ -void AmoebaReferenceTorsionTorsionForce::getBicubicValues( +void AmoebaReferenceTorsionTorsionForce::getBicubicValues( const RealOpenMM* y, const RealOpenMM* y1, const RealOpenMM* y2, const RealOpenMM* y12, const RealOpenMM x1Lower, const RealOpenMM x1Upper, const RealOpenMM x2Lower, const RealOpenMM x2Upper, const RealOpenMM gridValue1, const RealOpenMM gridValue2, - RealOpenMM* functionValue, RealOpenMM* functionValue1, RealOpenMM* functionValue2 ) const { + RealOpenMM* functionValue, RealOpenMM* functionValue1, RealOpenMM* functionValue2) const { // --------------------------------------------------------------------------------------- @@ -236,7 +236,7 @@ void AmoebaReferenceTorsionTorsionForce::getBicubicValues( // get coefficent matrix RealOpenMM coefficientMatrix[4][4]; - getBicubicCoefficientMatrix( y, y1, y2, y12, x1Upper-x1Lower, x2Upper-x2Lower, coefficientMatrix ); + getBicubicCoefficientMatrix(y, y1, y2, y12, x1Upper-x1Lower, x2Upper-x2Lower, coefficientMatrix); // apply coefficent matrix @@ -247,10 +247,10 @@ void AmoebaReferenceTorsionTorsionForce::getBicubicValues( *functionValue1 = zero; *functionValue2 = zero; - for( int ii = 3; ii >= 0; ii-- ){ - *functionValue = t*(*functionValue) + ( ( coefficientMatrix[ii][3]*u + coefficientMatrix[ii][2] )*u + coefficientMatrix[ii][1])*u + coefficientMatrix[ii][0]; - *functionValue1 = u*(*functionValue1) + ( three*coefficientMatrix[3][ii]*t + two*coefficientMatrix[2][ii] )*t + coefficientMatrix[1][ii]; - *functionValue2 = t*(*functionValue2) + ( three*coefficientMatrix[ii][3]*u + two*coefficientMatrix[ii][2] )*u + coefficientMatrix[ii][1]; + for (int ii = 3; ii >= 0; ii--) { + *functionValue = t*(*functionValue) + ( (coefficientMatrix[ii][3]*u + coefficientMatrix[ii][2])*u + coefficientMatrix[ii][1])*u + coefficientMatrix[ii][0]; + *functionValue1 = u*(*functionValue1) + (three*coefficientMatrix[3][ii]*t + two*coefficientMatrix[2][ii])*t + coefficientMatrix[1][ii]; + *functionValue2 = t*(*functionValue2) + (three*coefficientMatrix[ii][3]*u + two*coefficientMatrix[ii][2])*u + coefficientMatrix[ii][1]; } *functionValue1 /= (x1Upper - x1Lower); @@ -273,9 +273,9 @@ void AmoebaReferenceTorsionTorsionForce::getBicubicValues( --------------------------------------------------------------------------------------- */ -int AmoebaReferenceTorsionTorsionForce::checkTorsionSign( +int AmoebaReferenceTorsionTorsionForce::checkTorsionSign( const RealVec& positionAtomA, const RealVec& positionAtomB, - const RealVec& positionAtomC, const RealVec& positionAtomD ) const { + const RealVec& positionAtomC, const RealVec& positionAtomD) const { // --------------------------------------------------------------------------------------- @@ -290,17 +290,17 @@ int AmoebaReferenceTorsionTorsionForce::checkTorsionSign( enum { CA, CB, CD, LastDeltaIndex }; std::vector deltaR[LastDeltaIndex]; - for( unsigned int ii = 0; ii < LastDeltaIndex; ii++ ){ + for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) { deltaR[ii].resize(3); } - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomA, deltaR[CA] ); - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomB, deltaR[CB] ); - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomD, deltaR[CD] ); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomA, deltaR[CA]); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomB, deltaR[CB]); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomD, deltaR[CD]); - RealOpenMM volume = deltaR[CA][0]*( deltaR[CB][1]*deltaR[CD][2] - deltaR[CB][2]*deltaR[CD][1] ) + - deltaR[CB][0]*( deltaR[CD][1]*deltaR[CA][2] - deltaR[CD][2]*deltaR[CA][1] ) + - deltaR[CD][0]*( deltaR[CA][1]*deltaR[CB][2] - deltaR[CA][2]*deltaR[CB][1] ); + RealOpenMM volume = deltaR[CA][0]*(deltaR[CB][1]*deltaR[CD][2] - deltaR[CB][2]*deltaR[CD][1]) + + deltaR[CB][0]*(deltaR[CD][1]*deltaR[CA][2] - deltaR[CD][2]*deltaR[CA][1]) + + deltaR[CD][0]*(deltaR[CA][1]*deltaR[CB][2] - deltaR[CA][2]*deltaR[CB][1]); return (volume >= zero ? one : -one); @@ -324,11 +324,11 @@ int AmoebaReferenceTorsionTorsionForce::checkTorsionSign( --------------------------------------------------------------------------------------- */ -RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const RealVec& positionAtomA, const RealVec& positionAtomB, - const RealVec& positionAtomC, const RealVec& positionAtomD, - const RealVec& positionAtomE, const RealVec* positionChiralCheckAtom, - const std::vector< std::vector< std::vector > >& grid, - RealVec* forces ) const { +RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn(const RealVec& positionAtomA, const RealVec& positionAtomB, + const RealVec& positionAtomC, const RealVec& positionAtomD, + const RealVec& positionAtomE, const RealVec* positionChiralCheckAtom, + const std::vector< std::vector< std::vector > >& grid, + RealVec* forces) const { // --------------------------------------------------------------------------------------- @@ -347,83 +347,83 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const enum { BA, CB, DC, ED, T, U, V, UxV, CA, DB, EC, dT, dU, dU2, dV2, LastDeltaIndex }; std::vector deltaR[LastDeltaIndex]; - for( unsigned int ii = 0; ii < LastDeltaIndex; ii++ ){ + for (unsigned int ii = 0; ii < LastDeltaIndex; ii++) { deltaR[ii].resize(3); } - AmoebaReferenceForce::loadDeltaR( positionAtomA, positionAtomB, deltaR[BA] ); - AmoebaReferenceForce::loadDeltaR( positionAtomB, positionAtomC, deltaR[CB] ); - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomD, deltaR[DC] ); - AmoebaReferenceForce::loadDeltaR( positionAtomD, positionAtomE, deltaR[ED] ); - AmoebaReferenceForce::loadDeltaR( positionAtomA, positionAtomC, deltaR[CA] ); - AmoebaReferenceForce::loadDeltaR( positionAtomB, positionAtomD, deltaR[DB] ); - AmoebaReferenceForce::loadDeltaR( positionAtomC, positionAtomE, deltaR[EC] ); + AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomB, deltaR[BA]); + AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomC, deltaR[CB]); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomD, deltaR[DC]); + AmoebaReferenceForce::loadDeltaR(positionAtomD, positionAtomE, deltaR[ED]); + AmoebaReferenceForce::loadDeltaR(positionAtomA, positionAtomC, deltaR[CA]); + AmoebaReferenceForce::loadDeltaR(positionAtomB, positionAtomD, deltaR[DB]); + AmoebaReferenceForce::loadDeltaR(positionAtomC, positionAtomE, deltaR[EC]); std::vector d[LastAtomIndex]; - for( unsigned int ii = 0; ii < LastAtomIndex; ii++ ){ + for (unsigned int ii = 0; ii < LastAtomIndex; ii++) { d[ii].resize(3); } - AmoebaReferenceForce::getCrossProduct( deltaR[BA], deltaR[CB], deltaR[T] ); - AmoebaReferenceForce::getCrossProduct( deltaR[CB], deltaR[DC], deltaR[U] ); - AmoebaReferenceForce::getCrossProduct( deltaR[DC], deltaR[ED], deltaR[V] ); + AmoebaReferenceForce::getCrossProduct(deltaR[BA], deltaR[CB], deltaR[T]); + AmoebaReferenceForce::getCrossProduct(deltaR[CB], deltaR[DC], deltaR[U]); + AmoebaReferenceForce::getCrossProduct(deltaR[DC], deltaR[ED], deltaR[V]); - AmoebaReferenceForce::getCrossProduct( deltaR[U], deltaR[V], deltaR[UxV] ); + AmoebaReferenceForce::getCrossProduct(deltaR[U], deltaR[V], deltaR[UxV]); - RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3( deltaR[T] ); - RealOpenMM rU2 = AmoebaReferenceForce::getNormSquared3( deltaR[U] ); - RealOpenMM rV2 = AmoebaReferenceForce::getNormSquared3( deltaR[V] ); - RealOpenMM rUrV = SQRT( rU2*rV2 ); + RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3(deltaR[T]); + RealOpenMM rU2 = AmoebaReferenceForce::getNormSquared3(deltaR[U]); + RealOpenMM rV2 = AmoebaReferenceForce::getNormSquared3(deltaR[V]); + RealOpenMM rUrV = SQRT(rU2*rV2); - RealOpenMM rTrU = SQRT( rT2*rU2 ); + RealOpenMM rTrU = SQRT(rT2*rU2); - if( rTrU <= zero || rUrV <= zero ){ + if (rTrU <= zero || rUrV <= zero) { return zero; } - RealOpenMM rCB = AmoebaReferenceForce::getNorm3( deltaR[CB] ); - RealOpenMM cosine1 = AmoebaReferenceForce::getDotProduct3( deltaR[T], deltaR[U] ); + RealOpenMM rCB = AmoebaReferenceForce::getNorm3(deltaR[CB]); + RealOpenMM cosine1 = AmoebaReferenceForce::getDotProduct3(deltaR[T], deltaR[U]); cosine1 /= rTrU; RealOpenMM angle1; - if( cosine1 <= -one ){ + if (cosine1 <= -one) { angle1 = PI_M*RADIAN; - } else if( cosine1 >= one ){ + } else if (cosine1 >= one) { angle1 = zero; } else { angle1 = RADIAN*ACOS(cosine1); } - RealOpenMM sign = AmoebaReferenceForce::getDotProduct3( deltaR[BA], deltaR[U] ); - if( sign < zero ){ + RealOpenMM sign = AmoebaReferenceForce::getDotProduct3(deltaR[BA], deltaR[U]); + if (sign < zero) { angle1 = -angle1; } // value1 = angle1; - RealOpenMM rDC = AmoebaReferenceForce::getNorm3( deltaR[DC] ); - RealOpenMM cosine2 = AmoebaReferenceForce::getDotProduct3( deltaR[U], deltaR[V] ); + RealOpenMM rDC = AmoebaReferenceForce::getNorm3(deltaR[DC]); + RealOpenMM cosine2 = AmoebaReferenceForce::getDotProduct3(deltaR[U], deltaR[V]); cosine2 /= rUrV; RealOpenMM angle2; - if( cosine2 <= -one ){ + if (cosine2 <= -one) { angle2 = PI_M*RADIAN; - } else if( cosine1 >= one ){ + } else if (cosine1 >= one) { angle2 = zero; } else { angle2 = RADIAN*ACOS(cosine2); } - sign = AmoebaReferenceForce::getDotProduct3( deltaR[CB], deltaR[V] ); - if( sign < zero ){ + sign = AmoebaReferenceForce::getDotProduct3(deltaR[CB], deltaR[V]); + if (sign < zero) { angle2 = -angle2; } // swap signs of angles if chirality at central atom // is 'negative' - if( positionChiralCheckAtom ){ - sign = checkTorsionSign( *positionChiralCheckAtom, positionAtomB, positionAtomC, positionAtomD ); - if( sign < zero ){ + if (positionChiralCheckAtom) { + sign = checkTorsionSign(*positionChiralCheckAtom, positionAtomB, positionAtomC, positionAtomD); + if (sign < zero) { angle1 = -angle1; angle2 = -angle2; } @@ -436,7 +436,7 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const RealOpenMM corners[2][2]; RealOpenMM eValues[4][4]; enum { E0, E1, E2, E12, LastEIndex }; - loadGridValuesFromEnclosingRectangle( grid, angle1, angle2, corners, eValues[E0], eValues[E1], eValues[E2], eValues[E12] ); + loadGridValuesFromEnclosingRectangle(grid, angle1, angle2, corners, eValues[E0], eValues[E1], eValues[E2], eValues[E12]); // get coordinates of point in grid closest to angle1 & angle2 @@ -446,16 +446,16 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const RealOpenMM gridEnergy; RealOpenMM dEdAngle1; RealOpenMM dEdAngle2; - AmoebaReferenceTorsionTorsionForce::getBicubicValues( + AmoebaReferenceTorsionTorsionForce::getBicubicValues( eValues[E0], eValues[E1], eValues[E2], eValues[E12], corners[0][0], corners[0][1], corners[1][0], corners[1][1], - angle1, angle2, &gridEnergy, &dEdAngle1, &dEdAngle2 ); + angle1, angle2, &gridEnergy, &dEdAngle1, &dEdAngle2); dEdAngle1 = sign*RADIAN*dEdAngle1; dEdAngle2 = sign*RADIAN*dEdAngle2; - AmoebaReferenceForce::getCrossProduct( deltaR[T], deltaR[CB], deltaR[dT] ); - AmoebaReferenceForce::getCrossProduct( deltaR[U], deltaR[CB], deltaR[dU] ); + AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[CB], deltaR[dT]); + AmoebaReferenceForce::getCrossProduct(deltaR[U], deltaR[CB], deltaR[dU]); RealOpenMM factorT = dEdAngle1/(rCB*rT2); RealOpenMM factorU = -dEdAngle1/(rCB*rU2); @@ -468,18 +468,18 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const deltaR[dU][1] *= factorU; deltaR[dU][2] *= factorU; - AmoebaReferenceForce::getCrossProduct( deltaR[dT], deltaR[CB], d[A] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dU], deltaR[CB], d[D] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[CB], d[A]); + AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[CB], d[D]); std::vector tmp[3]; - for( unsigned int ii = 0; ii < 3; ii++ ){ + for (unsigned int ii = 0; ii < 3; ii++) { tmp[ii].resize(3); } - AmoebaReferenceForce::getCrossProduct( deltaR[CA], deltaR[dT], d[B] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dU], deltaR[DC], tmp[0] ); + AmoebaReferenceForce::getCrossProduct(deltaR[CA], deltaR[dT], d[B]); + AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[DC], tmp[0]); - AmoebaReferenceForce::getCrossProduct( deltaR[dT], deltaR[BA], d[C] ); - AmoebaReferenceForce::getCrossProduct( deltaR[DB], deltaR[dU], tmp[1]); + AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[BA], d[C] ); + AmoebaReferenceForce::getCrossProduct(deltaR[DB], deltaR[dU], tmp[1]); d[B][0] += tmp[0][0]; d[B][1] += tmp[0][1]; @@ -491,8 +491,8 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const // angle2 - AmoebaReferenceForce::getCrossProduct( deltaR[U], deltaR[DC], deltaR[dU2] ); - AmoebaReferenceForce::getCrossProduct( deltaR[V], deltaR[DC], deltaR[dV2] ); + AmoebaReferenceForce::getCrossProduct(deltaR[U], deltaR[DC], deltaR[dU2]); + AmoebaReferenceForce::getCrossProduct(deltaR[V], deltaR[DC], deltaR[dV2]); RealOpenMM factorU2 = dEdAngle2/(rDC*rU2); RealOpenMM factorV2 = -dEdAngle2/(rDC*rV2); @@ -507,12 +507,12 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const // dB2 - AmoebaReferenceForce::getCrossProduct( deltaR[dU2], deltaR[DC], tmp[0] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dU2], deltaR[DC], tmp[0] ); // dC2 - AmoebaReferenceForce::getCrossProduct( deltaR[DB], deltaR[dU2], tmp[1] ); - AmoebaReferenceForce::getCrossProduct( deltaR[dV2], deltaR[ED], tmp[2] ); + AmoebaReferenceForce::getCrossProduct(deltaR[DB], deltaR[dU2], tmp[1] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dV2], deltaR[ED], tmp[2] ); d[B][0] += tmp[0][0]; d[B][1] += tmp[0][1]; @@ -524,8 +524,8 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const // dD2 - AmoebaReferenceForce::getCrossProduct( deltaR[dU2], deltaR[CB], tmp[0] ); - AmoebaReferenceForce::getCrossProduct( deltaR[EC], deltaR[dV2], tmp[1] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dU2], deltaR[CB], tmp[0] ); + AmoebaReferenceForce::getCrossProduct(deltaR[EC], deltaR[dV2], tmp[1] ); d[D][0] += tmp[0][0] + tmp[1][0]; d[D][1] += tmp[0][1] + tmp[1][1]; @@ -533,13 +533,13 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const // dE - AmoebaReferenceForce::getCrossProduct( deltaR[dV2], deltaR[DC], d[E] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dV2], deltaR[DC], d[E] ); // --------------------------------------------------------------------------------------- // add in forces - for( int jj = 0; jj < LastAtomIndex; jj++ ){ + for (int jj = 0; jj < LastAtomIndex; jj++) { forces[jj][0] = d[jj][0]; forces[jj][1] = d[jj][1]; forces[jj][2] = d[jj][2]; @@ -550,16 +550,16 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn( const return gridEnergy; } -RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateForceAndEnergy( int numTorsionTorsions, vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& particle4, - const std::vector& particle5, - const std::vector& chiralCheckAtom, - const std::vector& gridIndices, - const std::vector< std::vector< std::vector< std::vector > > >& torsionTorsionGrids, - vector& forceData ) const { +RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateForceAndEnergy(int numTorsionTorsions, vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& particle4, + const std::vector& particle5, + const std::vector& chiralCheckAtom, + const std::vector& gridIndices, + const std::vector< std::vector< std::vector< std::vector > > >& torsionTorsionGrids, + vector& forceData) const { RealOpenMM energy = 0.0; for (unsigned int ii = 0; ii < static_cast(numTorsionTorsions); ii++) { @@ -575,19 +575,19 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateForceAndEnergy( int numT RealVec forces[5]; RealVec* chiralCheckAtom; - if( chiralCheckAtomIndex > -1 ){ + if (chiralCheckAtomIndex > -1) { chiralCheckAtom = &posData[chiralCheckAtomIndex]; } else { chiralCheckAtom = NULL; } - energy += calculateTorsionTorsionIxn( posData[particle1Index], posData[particle2Index], - posData[particle3Index], posData[particle4Index], - posData[particle5Index], chiralCheckAtom, torsionTorsionGrids[gridIndex], - forces ); + energy += calculateTorsionTorsionIxn(posData[particle1Index], posData[particle2Index], + posData[particle3Index], posData[particle4Index], + posData[particle5Index], chiralCheckAtom, torsionTorsionGrids[gridIndex], + forces); // accumulate forces - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { forceData[particle1Index][jj] -= forces[0][jj]; forceData[particle2Index][jj] -= forces[1][jj]; forceData[particle3Index][jj] -= forces[2][jj]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h index a0a8dbadf..e5b5fb202 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.h @@ -40,7 +40,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceTorsionTorsionForce( ){}; + AmoebaReferenceTorsionTorsionForce() {}; /**--------------------------------------------------------------------------------------- @@ -48,7 +48,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceTorsionTorsionForce( ){}; + ~AmoebaReferenceTorsionTorsionForce() {}; /**--------------------------------------------------------------------------------------- @@ -71,16 +71,16 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numTorsionTorsions, std::vector& posData, - const std::vector& particle1, - const std::vector& particle2, - const std::vector& particle3, - const std::vector& particle4, - const std::vector& particle5, - const std::vector& chiralCheckAtom, - const std::vector& gridIndices, - const std::vector< std::vector< std::vector< std::vector > > >& torsionTorsionGrids, - std::vector& forceData ) const; + RealOpenMM calculateForceAndEnergy(int numTorsionTorsions, std::vector& posData, + const std::vector& particle1, + const std::vector& particle2, + const std::vector& particle3, + const std::vector& particle4, + const std::vector& particle5, + const std::vector& chiralCheckAtom, + const std::vector& gridIndices, + const std::vector< std::vector< std::vector< std::vector > > >& torsionTorsionGrids, + std::vector& forceData) const; private: @@ -105,7 +105,7 @@ private: void loadGridValuesFromEnclosingRectangle( const std::vector< std::vector< std::vector > >& grid, RealOpenMM angle1, RealOpenMM angle2, RealOpenMM corners[2][2], - RealOpenMM* fValues, RealOpenMM* fValues1, RealOpenMM* fValues2, RealOpenMM* fValues12 ) const; + RealOpenMM* fValues, RealOpenMM* fValues1, RealOpenMM* fValues2, RealOpenMM* fValues12) const; /**--------------------------------------------------------------------------------------- @@ -128,8 +128,8 @@ private: --------------------------------------------------------------------------------------- */ - void getBicubicCoefficientMatrix( const RealOpenMM* y, const RealOpenMM* y1, const RealOpenMM* y2, const RealOpenMM* y12, - const RealOpenMM d1, const RealOpenMM d2, RealOpenMM c[4][4] ) const; + void getBicubicCoefficientMatrix(const RealOpenMM* y, const RealOpenMM* y1, const RealOpenMM* y2, const RealOpenMM* y12, + const RealOpenMM d1, const RealOpenMM d2, RealOpenMM c[4][4]) const; /**--------------------------------------------------------------------------------------- @@ -167,7 +167,7 @@ private: const RealOpenMM x1Lower, const RealOpenMM x1Upper, const RealOpenMM x2Lower, const RealOpenMM x2Upper, const RealOpenMM gridValue1, const RealOpenMM gridValue2, - RealOpenMM* functionValue, RealOpenMM* functionValue1, RealOpenMM* functionValue2 ) const; + RealOpenMM* functionValue, RealOpenMM* functionValue1, RealOpenMM* functionValue2) const; /**--------------------------------------------------------------------------------------- @@ -183,8 +183,8 @@ private: --------------------------------------------------------------------------------------- */ - int checkTorsionSign( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD ) const; + int checkTorsionSign(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD) const; /**--------------------------------------------------------------------------------------- @@ -204,11 +204,11 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateTorsionTorsionIxn( const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, - const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, - const OpenMM::RealVec& positionAtomE, const OpenMM::RealVec* chiralCheckAtom, - const std::vector< std::vector< std::vector > >& grid, - OpenMM::RealVec* forces ) const; + RealOpenMM calculateTorsionTorsionIxn(const OpenMM::RealVec& positionAtomA, const OpenMM::RealVec& positionAtomB, + const OpenMM::RealVec& positionAtomC, const OpenMM::RealVec& positionAtomD, + const OpenMM::RealVec& positionAtomE, const OpenMM::RealVec* chiralCheckAtom, + const std::vector< std::vector< std::vector > >& grid, + OpenMM::RealVec* forces) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp index aa396ff06..233d423b3 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.cpp @@ -31,32 +31,32 @@ using std::vector; using namespace OpenMM; -AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( ) : _nonbondedMethod(NoCutoff), _cutoff(1.0e+10), _taperCutoffFactor(0.9) { +AmoebaReferenceVdwForce::AmoebaReferenceVdwForce() : _nonbondedMethod(NoCutoff), _cutoff(1.0e+10), _taperCutoffFactor(0.9) { - setTaperCoefficients( _cutoff ); - setSigmaCombiningRule( "ARITHMETIC" ); - setEpsilonCombiningRule( "GEOMETRIC" ); + setTaperCoefficients(_cutoff); + setSigmaCombiningRule("ARITHMETIC"); + setEpsilonCombiningRule("GEOMETRIC"); } -AmoebaReferenceVdwForce::AmoebaReferenceVdwForce( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule ) : _nonbondedMethod(NoCutoff), _cutoff(1.0e+10), _taperCutoffFactor(0.9) { +AmoebaReferenceVdwForce::AmoebaReferenceVdwForce(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule) : _nonbondedMethod(NoCutoff), _cutoff(1.0e+10), _taperCutoffFactor(0.9) { - setTaperCoefficients( _cutoff ); - setSigmaCombiningRule( sigmaCombiningRule ); - setEpsilonCombiningRule( epsilonCombiningRule ); + setTaperCoefficients(_cutoff); + setSigmaCombiningRule(sigmaCombiningRule); + setEpsilonCombiningRule(epsilonCombiningRule); } -AmoebaReferenceVdwForce::NonbondedMethod AmoebaReferenceVdwForce::getNonbondedMethod( void ) const { +AmoebaReferenceVdwForce::NonbondedMethod AmoebaReferenceVdwForce::getNonbondedMethod() const { return _nonbondedMethod; } -void AmoebaReferenceVdwForce::setNonbondedMethod( AmoebaReferenceVdwForce::NonbondedMethod nonbondedMethod ){ +void AmoebaReferenceVdwForce::setNonbondedMethod(AmoebaReferenceVdwForce::NonbondedMethod nonbondedMethod) { _nonbondedMethod = nonbondedMethod; } -void AmoebaReferenceVdwForce::setTaperCoefficients( double cutoff ){ +void AmoebaReferenceVdwForce::setTaperCoefficients(double cutoff) { _taperCutoff = cutoff*_taperCutoffFactor; - if( _taperCutoff != cutoff ){ + if (_taperCutoff != cutoff) { _taperCoefficients[C3] = 10.0/pow(_taperCutoff - cutoff, 3.0); _taperCoefficients[C4] = 15.0/pow(_taperCutoff - cutoff, 4.0); _taperCoefficients[C5] = 6.0/pow(_taperCutoff - cutoff, 5.0); @@ -67,12 +67,12 @@ void AmoebaReferenceVdwForce::setTaperCoefficients( double cutoff ){ } } -void AmoebaReferenceVdwForce::setCutoff( double cutoff ){ +void AmoebaReferenceVdwForce::setCutoff(double cutoff) { _cutoff = cutoff; - setTaperCoefficients( _cutoff ); + setTaperCoefficients(_cutoff); } -double AmoebaReferenceVdwForce::getCutoff( void ) const { +double AmoebaReferenceVdwForce::getCutoff() const { return _cutoff; } @@ -82,35 +82,35 @@ void AmoebaReferenceVdwForce::setPeriodicBox(OpenMM::RealVec* vectors) { _periodicBoxVectors[2] = vectors[2]; } -void AmoebaReferenceVdwForce::setSigmaCombiningRule( const std::string& sigmaCombiningRule ){ +void AmoebaReferenceVdwForce::setSigmaCombiningRule(const std::string& sigmaCombiningRule) { _sigmaCombiningRule = sigmaCombiningRule; // convert to upper case and set combining function - std::transform( _sigmaCombiningRule.begin(), _sigmaCombiningRule.end(), _sigmaCombiningRule.begin(), (int(*)(int)) std::toupper); - if( _sigmaCombiningRule == "GEOMETRIC" ){ + std::transform(_sigmaCombiningRule.begin(), _sigmaCombiningRule.end(), _sigmaCombiningRule.begin(), (int(*)(int)) std::toupper); + if (_sigmaCombiningRule == "GEOMETRIC") { _combineSigmas = &AmoebaReferenceVdwForce::geometricSigmaCombiningRule; - } else if( _sigmaCombiningRule == "CUBIC-MEAN" ){ + } else if (_sigmaCombiningRule == "CUBIC-MEAN") { _combineSigmas = &AmoebaReferenceVdwForce::cubicMeanSigmaCombiningRule; } else { _combineSigmas = &AmoebaReferenceVdwForce::arithmeticSigmaCombiningRule; } } -std::string AmoebaReferenceVdwForce::getSigmaCombiningRule( void ) const { +std::string AmoebaReferenceVdwForce::getSigmaCombiningRule() const { return _sigmaCombiningRule; } -RealOpenMM AmoebaReferenceVdwForce::arithmeticSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const { +RealOpenMM AmoebaReferenceVdwForce::arithmeticSigmaCombiningRule(RealOpenMM sigmaI, RealOpenMM sigmaJ) const { return (sigmaI + sigmaJ); } -RealOpenMM AmoebaReferenceVdwForce::geometricSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const { +RealOpenMM AmoebaReferenceVdwForce::geometricSigmaCombiningRule(RealOpenMM sigmaI, RealOpenMM sigmaJ) const { return 2.0*SQRT(sigmaI*sigmaJ); } -RealOpenMM AmoebaReferenceVdwForce::cubicMeanSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const { +RealOpenMM AmoebaReferenceVdwForce::cubicMeanSigmaCombiningRule(RealOpenMM sigmaI, RealOpenMM sigmaJ) const { const RealOpenMM zero = 0.0; @@ -120,48 +120,48 @@ RealOpenMM AmoebaReferenceVdwForce::cubicMeanSigmaCombiningRule( RealOpenMM sigm return sigmaI != zero && sigmaJ != 0.0 ? 2.0*(sigmaI2*sigmaI + sigmaJ2*sigmaJ)/(sigmaI2 + sigmaJ2) : zero; } -void AmoebaReferenceVdwForce::setEpsilonCombiningRule( const std::string& epsilonCombiningRule ){ +void AmoebaReferenceVdwForce::setEpsilonCombiningRule(const std::string& epsilonCombiningRule) { _epsilonCombiningRule = epsilonCombiningRule; - std::transform( _epsilonCombiningRule.begin(), _epsilonCombiningRule.end(), _epsilonCombiningRule.begin(), (int(*)(int)) std::toupper); + std::transform(_epsilonCombiningRule.begin(), _epsilonCombiningRule.end(), _epsilonCombiningRule.begin(), (int(*)(int)) std::toupper); // convert to upper case and set combining function - if( _epsilonCombiningRule == "ARITHMETIC" ){ + if (_epsilonCombiningRule == "ARITHMETIC") { _combineEpsilons = &AmoebaReferenceVdwForce::arithmeticEpsilonCombiningRule; - } else if( _epsilonCombiningRule == "HARMONIC" ){ + } else if (_epsilonCombiningRule == "HARMONIC") { _combineEpsilons = &AmoebaReferenceVdwForce::harmonicEpsilonCombiningRule; - } else if( _epsilonCombiningRule == "HHG" ){ + } else if (_epsilonCombiningRule == "HHG") { _combineEpsilons = &AmoebaReferenceVdwForce::hhgEpsilonCombiningRule; } else { _combineEpsilons = &AmoebaReferenceVdwForce::geometricEpsilonCombiningRule; } } -std::string AmoebaReferenceVdwForce::getEpsilonCombiningRule( void ) const { +std::string AmoebaReferenceVdwForce::getEpsilonCombiningRule() const { return _epsilonCombiningRule; } -RealOpenMM AmoebaReferenceVdwForce::arithmeticEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const { +RealOpenMM AmoebaReferenceVdwForce::arithmeticEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const { return 0.5*(epsilonI + epsilonJ); } -RealOpenMM AmoebaReferenceVdwForce::geometricEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const { +RealOpenMM AmoebaReferenceVdwForce::geometricEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const { return SQRT(epsilonI*epsilonJ); } -RealOpenMM AmoebaReferenceVdwForce::harmonicEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const { +RealOpenMM AmoebaReferenceVdwForce::harmonicEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const { return (epsilonI != 0.0 && epsilonJ != 0.0) ? 2.0*(epsilonI*epsilonJ)/(epsilonI + epsilonJ) : 0.0; } -RealOpenMM AmoebaReferenceVdwForce::hhgEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const { +RealOpenMM AmoebaReferenceVdwForce::hhgEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const { RealOpenMM denominator = SQRT(epsilonI) + SQRT(epsilonJ); return (epsilonI != 0.0 && epsilonJ != 0.0) ? 4.0*(epsilonI*epsilonJ)/(denominator*denominator) : 0.0; } -void AmoebaReferenceVdwForce::addReducedForce( unsigned int particleI, unsigned int particleIV, - RealOpenMM reduction, RealOpenMM sign, - Vec3& force, vector& forces ) const { +void AmoebaReferenceVdwForce::addReducedForce(unsigned int particleI, unsigned int particleIV, + RealOpenMM reduction, RealOpenMM sign, + Vec3& force, vector& forces) const { // --------------------------------------------------------------------------------------- @@ -178,10 +178,10 @@ void AmoebaReferenceVdwForce::addReducedForce( unsigned int particleI, unsigned forces[particleIV][2] += sign*force[2]*(one - reduction); } -RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combinedSigma, RealOpenMM combinedEpsilon, - const Vec3& particleIPosition, - const Vec3& particleJPosition, - Vec3& force ) const { +RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn(RealOpenMM combinedSigma, RealOpenMM combinedEpsilon, + const Vec3& particleIPosition, + const Vec3& particleJPosition, + Vec3& force) const { // --------------------------------------------------------------------------------------- @@ -221,13 +221,13 @@ RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combinedSigma, RealOpenMM ratio = (sigma_7/rho); RealOpenMM gtau = combinedEpsilon*tau_7*r_ij_6*(ghal+one)*ratio*ratio; - RealOpenMM energy = combinedEpsilon*tau_7*sigma_7*( (ghal+one)*sigma_7/rho - two); + RealOpenMM energy = combinedEpsilon*tau_7*sigma_7*((ghal+one)*sigma_7/rho - two); RealOpenMM dEdR = -seven*(dtau*energy + gtau); // tapering - if( (_nonbondedMethod == CutoffNonPeriodic || _nonbondedMethod == CutoffPeriodic) && r_ij > _taperCutoff ){ + if ((_nonbondedMethod == CutoffNonPeriodic || _nonbondedMethod == CutoffPeriodic) && r_ij > _taperCutoff) { RealOpenMM delta = r_ij - _taperCutoff; RealOpenMM taper = 1.0 + delta*delta*delta*(_taperCoefficients[C3] + delta*(_taperCoefficients[C4] + delta*_taperCoefficients[C5])); RealOpenMM dtaper = delta*delta*(3.0*_taperCoefficients[C3] + delta*(4.0*_taperCoefficients[C4] + delta*5.0*_taperCoefficients[C5])); @@ -245,35 +245,35 @@ RealOpenMM AmoebaReferenceVdwForce::calculatePairIxn( RealOpenMM combinedSigma, } -void AmoebaReferenceVdwForce::setReducedPositions( int numParticles, - const vector& particlePositions, - const std::vector& indexIVs, - const std::vector& reductions, - std::vector& reducedPositions ) const { +void AmoebaReferenceVdwForce::setReducedPositions(int numParticles, + const vector& particlePositions, + const std::vector& indexIVs, + const std::vector& reductions, + std::vector& reducedPositions) const { static const RealOpenMM zero = 0.0; reducedPositions.resize(numParticles); - for( unsigned int ii = 0; ii < static_cast(numParticles); ii++ ){ - if( reductions[ii] != zero ){ + for (unsigned int ii = 0; ii < static_cast(numParticles); ii++) { + if (reductions[ii] != zero) { int reductionIndex = indexIVs[ii]; - reducedPositions[ii] = Vec3( reductions[ii]*( particlePositions[ii][0] - particlePositions[reductionIndex][0] ) + particlePositions[reductionIndex][0], - reductions[ii]*( particlePositions[ii][1] - particlePositions[reductionIndex][1] ) + particlePositions[reductionIndex][1], - reductions[ii]*( particlePositions[ii][2] - particlePositions[reductionIndex][2] ) + particlePositions[reductionIndex][2] ); + reducedPositions[ii] = Vec3(reductions[ii]*(particlePositions[ii][0] - particlePositions[reductionIndex][0]) + particlePositions[reductionIndex][0], + reductions[ii]*(particlePositions[ii][1] - particlePositions[reductionIndex][1]) + particlePositions[reductionIndex][1], + reductions[ii]*(particlePositions[ii][2] - particlePositions[reductionIndex][2]) + particlePositions[reductionIndex][2]); } else { - reducedPositions[ii] = Vec3( particlePositions[ii][0], particlePositions[ii][1], particlePositions[ii][2] ); + reducedPositions[ii] = Vec3(particlePositions[ii][0], particlePositions[ii][1], particlePositions[ii][2]); } } } -RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, - const vector& particlePositions, - const std::vector& indexIVs, - const std::vector& sigmas, - const std::vector& epsilons, - const std::vector& reductions, - const std::vector< std::set >& allExclusions, - vector& forces ) const { +RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy(int numParticles, + const vector& particlePositions, + const std::vector& indexIVs, + const std::vector& sigmas, + const std::vector& epsilons, + const std::vector& reductions, + const std::vector< std::set >& allExclusions, + vector& forces) const { // --------------------------------------------------------------------------------------- @@ -286,7 +286,7 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, // set reduced coordinates std::vector reducedPositions; - setReducedPositions( numParticles, particlePositions, indexIVs, reductions, reducedPositions ); + setReducedPositions(numParticles, particlePositions, indexIVs, reductions, reducedPositions); // loop over all particle pairs @@ -299,44 +299,44 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, RealOpenMM energy = zero; std::vector exclusions(numParticles, 0); - for( unsigned int ii = 0; ii < static_cast(numParticles); ii++ ){ + for (unsigned int ii = 0; ii < static_cast(numParticles); ii++) { RealOpenMM sigmaI = sigmas[ii]; RealOpenMM epsilonI = epsilons[ii]; - for( std::set::const_iterator jj = allExclusions[ii].begin(); jj != allExclusions[ii].end(); jj++ ){ + for (std::set::const_iterator jj = allExclusions[ii].begin(); jj != allExclusions[ii].end(); jj++) { exclusions[*jj] = 1; } - for( unsigned int jj = ii+1; jj < static_cast(numParticles); jj++ ){ - if( exclusions[jj] == 0 ){ + for (unsigned int jj = ii+1; jj < static_cast(numParticles); jj++) { + if (exclusions[jj] == 0) { - RealOpenMM combinedSigma = (this->*_combineSigmas)(sigmaI, sigmas[jj] ); - RealOpenMM combinedEpsilon = (this->*_combineEpsilons)(epsilonI, epsilons[jj] ); + RealOpenMM combinedSigma = (this->*_combineSigmas)(sigmaI, sigmas[jj]); + RealOpenMM combinedEpsilon = (this->*_combineEpsilons)(epsilonI, epsilons[jj]); Vec3 force; - energy += calculatePairIxn( combinedSigma, combinedEpsilon, - reducedPositions[ii], reducedPositions[jj], - force ); + energy += calculatePairIxn(combinedSigma, combinedEpsilon, + reducedPositions[ii], reducedPositions[jj], + force); - if( indexIVs[ii] == ii ){ + if (indexIVs[ii] == ii) { forces[ii][0] -= force[0]; forces[ii][1] -= force[1]; forces[ii][2] -= force[2]; } else { - addReducedForce( ii, indexIVs[ii], reductions[ii], -one, force, forces ); + addReducedForce(ii, indexIVs[ii], reductions[ii], -one, force, forces); } - if( indexIVs[jj] == jj ){ + if (indexIVs[jj] == jj) { forces[jj][0] += force[0]; forces[jj][1] += force[1]; forces[jj][2] += force[2]; } else { - addReducedForce( jj, indexIVs[jj], reductions[jj], one, force, forces ); + addReducedForce(jj, indexIVs[jj], reductions[jj], one, force, forces); } } } - for( std::set::const_iterator jj = allExclusions[ii].begin(); jj != allExclusions[ii].end(); jj++ ){ + for (std::set::const_iterator jj = allExclusions[ii].begin(); jj != allExclusions[ii].end(); jj++) { exclusions[*jj] = 0; } } @@ -344,14 +344,14 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, return energy; } -RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, - const vector& particlePositions, - const std::vector& indexIVs, - const std::vector& sigmas, - const std::vector& epsilons, - const std::vector& reductions, - const NeighborList& neighborList, - vector& forces ) const { +RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy(int numParticles, + const vector& particlePositions, + const std::vector& indexIVs, + const std::vector& sigmas, + const std::vector& epsilons, + const std::vector& reductions, + const NeighborList& neighborList, + vector& forces) const { // --------------------------------------------------------------------------------------- @@ -364,7 +364,7 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, // set reduced coordinates std::vector reducedPositions; - setReducedPositions( numParticles, particlePositions, indexIVs, reductions, reducedPositions ); + setReducedPositions(numParticles, particlePositions, indexIVs, reductions, reducedPositions); // loop over neighbor list // (1) calculate pair vdw ixn @@ -373,32 +373,32 @@ RealOpenMM AmoebaReferenceVdwForce::calculateForceAndEnergy( int numParticles, // based on reduction factor RealOpenMM energy = zero; - for( unsigned int ii = 0; ii < neighborList.size(); ii++ ){ + for (unsigned int ii = 0; ii < neighborList.size(); ii++) { OpenMM::AtomPair pair = neighborList[ii]; int siteI = pair.first; int siteJ = pair.second; - RealOpenMM combinedSigma = (this->*_combineSigmas)( sigmas[siteI], sigmas[siteJ] ); - RealOpenMM combinedEpsilon = (this->*_combineEpsilons)( epsilons[siteI], epsilons[siteJ] ); + RealOpenMM combinedSigma = (this->*_combineSigmas)(sigmas[siteI], sigmas[siteJ]); + RealOpenMM combinedEpsilon = (this->*_combineEpsilons)(epsilons[siteI], epsilons[siteJ]); Vec3 force; - energy += calculatePairIxn( combinedSigma, combinedEpsilon, - reducedPositions[siteI], reducedPositions[siteJ], force ); + energy += calculatePairIxn(combinedSigma, combinedEpsilon, + reducedPositions[siteI], reducedPositions[siteJ], force); - if( indexIVs[siteI] == siteI ){ + if (indexIVs[siteI] == siteI) { forces[siteI][0] -= force[0]; forces[siteI][1] -= force[1]; forces[siteI][2] -= force[2]; } else { - addReducedForce( siteI, indexIVs[siteI], reductions[siteI], -one, force, forces ); + addReducedForce(siteI, indexIVs[siteI], reductions[siteI], -one, force, forces); } - if( indexIVs[siteJ] == siteJ ){ + if (indexIVs[siteJ] == siteJ) { forces[siteJ][0] += force[0]; forces[siteJ][1] += force[1]; forces[siteJ][2] += force[2]; } else { - addReducedForce( siteJ, indexIVs[siteJ], reductions[siteJ], one, force, forces ); + addReducedForce(siteJ, indexIVs[siteJ], reductions[siteJ], one, force, forces); } } diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h index 4c7089bf2..49985d5c4 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h @@ -34,7 +34,7 @@ namespace OpenMM { class AmoebaReferenceVdwForce; -typedef RealOpenMM (AmoebaReferenceVdwForce::*CombiningFunction)( RealOpenMM x, RealOpenMM y) const; +typedef RealOpenMM (AmoebaReferenceVdwForce::*CombiningFunction)(RealOpenMM x, RealOpenMM y) const; // --------------------------------------------------------------------------------------- @@ -71,7 +71,7 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceVdwForce( ); + AmoebaReferenceVdwForce(); /**--------------------------------------------------------------------------------------- @@ -79,8 +79,8 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceVdwForce( const std::string& sigmaCombiningRule, - const std::string& epsilonCombiningRule ); + AmoebaReferenceVdwForce(const std::string& sigmaCombiningRule, + const std::string& epsilonCombiningRule); /**--------------------------------------------------------------------------------------- @@ -88,7 +88,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceVdwForce( ){}; + ~AmoebaReferenceVdwForce() {}; /**--------------------------------------------------------------------------------------- @@ -98,7 +98,7 @@ public: --------------------------------------------------------------------------------------- */ - NonbondedMethod getNonbondedMethod( void ) const; + NonbondedMethod getNonbondedMethod() const; /**--------------------------------------------------------------------------------------- @@ -108,7 +108,7 @@ public: --------------------------------------------------------------------------------------- */ - void setNonbondedMethod( NonbondedMethod nonbondedMethod ); + void setNonbondedMethod(NonbondedMethod nonbondedMethod); /**--------------------------------------------------------------------------------------- @@ -118,7 +118,7 @@ public: --------------------------------------------------------------------------------------- */ - double getCutoff( void ) const; + double getCutoff() const; /**--------------------------------------------------------------------------------------- @@ -128,7 +128,7 @@ public: --------------------------------------------------------------------------------------- */ - void setCutoff( double cutoff ); + void setCutoff(double cutoff); /**--------------------------------------------------------------------------------------- @@ -138,7 +138,7 @@ public: --------------------------------------------------------------------------------------- */ - void setSigmaCombiningRule( const std::string& sigmaCombiningRule ); + void setSigmaCombiningRule(const std::string& sigmaCombiningRule); /**--------------------------------------------------------------------------------------- @@ -148,7 +148,7 @@ public: --------------------------------------------------------------------------------------- */ - std::string getSigmaCombiningRule( void ) const; + std::string getSigmaCombiningRule() const; /**--------------------------------------------------------------------------------------- @@ -158,7 +158,7 @@ public: --------------------------------------------------------------------------------------- */ - void setEpsilonCombiningRule( const std::string& epsilonCombiningRule ); + void setEpsilonCombiningRule(const std::string& epsilonCombiningRule); /**--------------------------------------------------------------------------------------- @@ -168,7 +168,7 @@ public: --------------------------------------------------------------------------------------- */ - std::string getEpsilonCombiningRule( void ) const; + std::string getEpsilonCombiningRule() const; /**--------------------------------------------------------------------------------------- @@ -197,12 +197,12 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numParticles, const std::vector& particlePositions, - const std::vector& indexIVs, - const std::vector& sigmas, const std::vector& epsilons, - const std::vector& reductions, - const std::vector< std::set >& vdwExclusions, - std::vector& forces ) const; + RealOpenMM calculateForceAndEnergy(int numParticles, const std::vector& particlePositions, + const std::vector& indexIVs, + const std::vector& sigmas, const std::vector& epsilons, + const std::vector& reductions, + const std::vector< std::set >& vdwExclusions, + std::vector& forces) const; /**--------------------------------------------------------------------------------------- @@ -221,12 +221,12 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numParticles, const std::vector& particlePositions, - const std::vector& indexIVs, - const std::vector& sigmas, const std::vector& epsilons, - const std::vector& reductions, - const NeighborList& neighborList, - std::vector& forces ) const; + RealOpenMM calculateForceAndEnergy(int numParticles, const std::vector& particlePositions, + const std::vector& indexIVs, + const std::vector& sigmas, const std::vector& epsilons, + const std::vector& reductions, + const NeighborList& neighborList, + std::vector& forces) const; private: @@ -245,15 +245,15 @@ private: RealOpenMM _taperCoefficients[3]; RealVec _periodicBoxVectors[3]; CombiningFunction _combineSigmas; - RealOpenMM arithmeticSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const; - RealOpenMM geometricSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const; - RealOpenMM cubicMeanSigmaCombiningRule( RealOpenMM sigmaI, RealOpenMM sigmaJ ) const; + RealOpenMM arithmeticSigmaCombiningRule(RealOpenMM sigmaI, RealOpenMM sigmaJ) const; + RealOpenMM geometricSigmaCombiningRule(RealOpenMM sigmaI, RealOpenMM sigmaJ) const; + RealOpenMM cubicMeanSigmaCombiningRule(RealOpenMM sigmaI, RealOpenMM sigmaJ) const; CombiningFunction _combineEpsilons; - RealOpenMM arithmeticEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const; - RealOpenMM geometricEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const; - RealOpenMM harmonicEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const; - RealOpenMM hhgEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ ) const; + RealOpenMM arithmeticEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const; + RealOpenMM geometricEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const; + RealOpenMM harmonicEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ) const; + RealOpenMM hhgEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ) const; /**--------------------------------------------------------------------------------------- @@ -272,9 +272,9 @@ private: --------------------------------------------------------------------------------------- */ - void setReducedPositions( int numParticles, const std::vector& particlePositions, - const std::vector& indexIVs, const std::vector& reductions, - std::vector& reducedPositions ) const; + void setReducedPositions(int numParticles, const std::vector& particlePositions, + const std::vector& indexIVs, const std::vector& reductions, + std::vector& reducedPositions) const; /**--------------------------------------------------------------------------------------- @@ -289,9 +289,9 @@ private: --------------------------------------------------------------------------------------- */ - void addReducedForce( unsigned int particleI, unsigned int particleIV, - RealOpenMM reduction, RealOpenMM sign, - Vec3& force, std::vector& forces ) const; + void addReducedForce(unsigned int particleI, unsigned int particleIV, + RealOpenMM reduction, RealOpenMM sign, + Vec3& force, std::vector& forces) const; /**--------------------------------------------------------------------------------------- @@ -301,7 +301,7 @@ private: --------------------------------------------------------------------------------------- */ - void setTaperCoefficients( double cutoff ); + void setTaperCoefficients(double cutoff); /**--------------------------------------------------------------------------------------- @@ -317,9 +317,9 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculatePairIxn( RealOpenMM combindedSigma, RealOpenMM combindedEpsilon, - const Vec3& particleIPosition, const Vec3& particleJPosition, - Vec3& force ) const; + RealOpenMM calculatePairIxn(RealOpenMM combindedSigma, RealOpenMM combindedEpsilon, + const Vec3& particleIPosition, const Vec3& particleJPosition, + Vec3& force) const; }; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp index 3b69d0e2a..92c640b60 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.cpp @@ -28,17 +28,17 @@ using std::vector; using namespace OpenMM; -AmoebaReferenceWcaDispersionForce::AmoebaReferenceWcaDispersionForce( RealOpenMM epso, RealOpenMM epsh, RealOpenMM rmino, RealOpenMM rminh, - RealOpenMM awater, RealOpenMM shctd, RealOpenMM dispoff, RealOpenMM slevy ) : +AmoebaReferenceWcaDispersionForce::AmoebaReferenceWcaDispersionForce(RealOpenMM epso, RealOpenMM epsh, RealOpenMM rmino, RealOpenMM rminh, + RealOpenMM awater, RealOpenMM shctd, RealOpenMM dispoff, RealOpenMM slevy) : _epso(epso), _epsh(epsh), _rmino(rmino), _rminh(rminh), _awater(awater), _shctd(shctd), _dispoff(dispoff), _slevy(slevy) { } -RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiusI, RealOpenMM radiusK, - const RealVec& particleIPosition, - const RealVec& particleJPosition, - const RealOpenMM* const intermediateValues, - Vec3& force ) const { +RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn(RealOpenMM radiusI, RealOpenMM radiusK, + const RealVec& particleIPosition, + const RealVec& particleJPosition, + const RealOpenMM* const intermediateValues, + Vec3& force) const { // --------------------------------------------------------------------------------------- @@ -62,7 +62,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM zr = particleIPosition[2] - particleJPosition[2]; RealOpenMM r2 = xr*xr + yr*yr + zr*zr; - RealOpenMM r = SQRT( r2 ); + RealOpenMM r = SQRT(r2); RealOpenMM r3 = r2*r; RealOpenMM sK = radiusK*_shctd; @@ -84,7 +84,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM sum = zero; RealOpenMM de = zero; - if( radiusI < (r + sK) ){ + if (radiusI < (r + sK)) { RealOpenMM rmax = (radiusI > (r - sK)) ? radiusI : (r - sK); @@ -93,7 +93,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM lik3 = lik2*lik; RealOpenMM lik4 = lik2*lik2; - if( lik < rmixo ){ + if (lik < rmixo) { RealOpenMM uik = (r + sK) < rmixo ? (r + sK) : rmixo; RealOpenMM uik2 = uik*uik; @@ -103,7 +103,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM term = four*PI/(fortyEight*r)* (three*(lik4-uik4) - eight*r*(lik3-uik3) + six*(r2-sK2)*(lik2-uik2)); RealOpenMM dl; - if( radiusI > (r - sK) ){ + if (radiusI > (r - sK)) { dl = -lik2 + two*(r2 + sK2); dl *= lik2; } else { @@ -112,7 +112,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu } RealOpenMM du; - if( (r+sK) > rmixo ){ + if ((r+sK) > rmixo) { du = -uik2 + two*(r2 + sK2); du *= -uik2; } else { @@ -123,7 +123,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu sum += -emixo*term; } - if( lik < rmixh ){ + if (lik < rmixh) { RealOpenMM uik = (r + sK) < rmixh ? (r + sK) : rmixh; RealOpenMM uik2 = uik*uik; @@ -131,7 +131,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM uik4 = uik2*uik2; RealOpenMM term = four*PI / (fortyEight*r)*(three*(lik4-uik4) - eight*r*(lik3-uik3) + six*(r2-sK2)*(lik2-uik2)); RealOpenMM dl; - if( radiusI > (r-sK) ){ + if (radiusI > (r-sK)) { dl = -lik2 + two*(r2 + sK2); dl *= lik2; } else { @@ -140,7 +140,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu } RealOpenMM du; - if (r+sK > rmixh){ + if (r+sK > rmixh) { du = -uik2 + two*(r2 + sK2); du *= -uik2; } else { @@ -162,7 +162,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM uik12 = uik6 * uik6; RealOpenMM uik13 = uik10 * uik3; - if( uik > rmixo ){ + if (uik > rmixo) { RealOpenMM lik = rmax > rmixo ? rmax : rmixo; RealOpenMM lik2 = lik * lik; @@ -177,7 +177,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM term = four*PI/(120.0*r*lik5*uik5)*(15.0*uik*lik*r*(uik4-lik4) - ten*uik2*lik2*(uik3-lik3) + six*(sK2-r2)*(uik5-lik5)); RealOpenMM dl; - if( radiusI > (r-sK) || rmax < rmixo ){ + if (radiusI > (r-sK) || rmax < rmixo) { dl = -five*lik2 + three*(r2 + sK2); dl /= -lik5; } else { @@ -189,7 +189,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM idisp = -two*ao*term; de -= two*ao*PI*(dl + du)/(15.0*r2); term = four*PI/(2640.0*r*lik12*uik12) * (120.0*uik*lik*r*(uik11-lik11) - 66.0*uik2*lik2*(uik10-lik10) + 55.0*(sK2-r2)*(uik12-lik12)); - if( radiusI > (r-sK) || rmax < rmixo ){ + if (radiusI > (r-sK) || rmax < rmixo) { dl = -six*lik2 + five*r2 + five*sK2; dl /= -lik12; } else { @@ -201,7 +201,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu de += ao*rmixo7*PI*(dl + du)/(60.0*r2); sum += ao*rmixo7*term + idisp; } - if (uik > rmixh){ + if (uik > rmixh) { lik = rmax > rmixh ? rmax : rmixh; lik2 = lik * lik; lik3 = lik2 * lik; @@ -215,7 +215,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM term = four*PI / (120.0*r*lik5*uik5)*(15.0*uik*lik*r*(uik4-lik4) - ten*uik2*lik2*(uik3-lik3) + six*(sK2-r2)*(uik5-lik5)); RealOpenMM dl; - if( radiusI > (r-sK) || rmax < rmixh ){ + if (radiusI > (r-sK) || rmax < rmixh) { dl = -five*lik2 + three*(r2 + sK2); dl /= -lik5; } else { @@ -227,7 +227,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu RealOpenMM idisp = -four*ah*term; de = de - four*ah*PI*(dl + du)/(15.0*r2); term = four*PI / (2640.0*r*lik12*uik12)* (120.0*uik*lik*r*(uik11-lik11)- 66.0*uik2*lik2*(uik10-lik10)+ 55.0*(sK2-r2)*(uik12-lik12)); - if( radiusI > (r-sK) || rmax < rmixh){ + if (radiusI > (r-sK) || rmax < rmixh) { dl = -six*lik2 + five*r2 + five*sK2; dl = -dl / lik12; } else {; @@ -254,12 +254,12 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculatePairIxn( RealOpenMM radiu } -RealOpenMM AmoebaReferenceWcaDispersionForce::calculateForceAndEnergy( int numParticles, - const vector& particlePositions, - const std::vector& radii, - const std::vector& epsilons, - RealOpenMM totalMaximumDispersionEnergy, - vector& forces ) const { +RealOpenMM AmoebaReferenceWcaDispersionForce::calculateForceAndEnergy(int numParticles, + const vector& particlePositions, + const std::vector& radii, + const std::vector& epsilons, + RealOpenMM totalMaximumDispersionEnergy, + vector& forces) const { // --------------------------------------------------------------------------------------- @@ -284,7 +284,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculateForceAndEnergy( int numPa RealOpenMM intermediateValues[LastIntermediateValueIndex]; - for( unsigned int ii = 0; ii < static_cast(numParticles); ii++ ){ + for (unsigned int ii = 0; ii < static_cast(numParticles); ii++) { RealOpenMM epsi = epsilons[ii]; RealOpenMM rmini = radii[ii]; @@ -296,7 +296,7 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculateForceAndEnergy( int numPa RealOpenMM rminI2 = rmini*rmini; RealOpenMM rminI3 = rminI2*rmini; - RealOpenMM rmixo = two*(rmino3 + rminI3 ) / (rmino2 + rminI2); + RealOpenMM rmixo = two*(rmino3 + rminI3) / (rmino2 + rminI2); intermediateValues[RMIXO] = rmixo; RealOpenMM rmixo7 = rmixo*rmixo*rmixo; @@ -319,14 +319,14 @@ RealOpenMM AmoebaReferenceWcaDispersionForce::calculateForceAndEnergy( int numPa intermediateValues[AH] = emixh*rmixh7; - for( unsigned int jj = 0; jj < static_cast(numParticles); jj++ ){ + for (unsigned int jj = 0; jj < static_cast(numParticles); jj++) { - if( ii == jj )continue; + if (ii == jj)continue; Vec3 force; - energy += calculatePairIxn( rmini, radii[jj], - particlePositions[ii], particlePositions[jj], - intermediateValues, force ); + energy += calculatePairIxn(rmini, radii[jj], + particlePositions[ii], particlePositions[jj], + intermediateValues, force); forces[ii][0] += force[0]; forces[ii][1] += force[1]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h index 02248870f..46c790926 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceWcaDispersionForce.h @@ -51,8 +51,8 @@ public: --------------------------------------------------------------------------------------- */ - AmoebaReferenceWcaDispersionForce( RealOpenMM epso, RealOpenMM epsh, RealOpenMM rmino, RealOpenMM rminh, - RealOpenMM awater, RealOpenMM shctd, RealOpenMM dispoff, RealOpenMM slevy ); + AmoebaReferenceWcaDispersionForce(RealOpenMM epso, RealOpenMM epsh, RealOpenMM rmino, RealOpenMM rminh, + RealOpenMM awater, RealOpenMM shctd, RealOpenMM dispoff, RealOpenMM slevy); /**--------------------------------------------------------------------------------------- @@ -60,7 +60,7 @@ public: --------------------------------------------------------------------------------------- */ - ~AmoebaReferenceWcaDispersionForce( ){}; + ~AmoebaReferenceWcaDispersionForce() {}; /**--------------------------------------------------------------------------------------- @@ -77,10 +77,10 @@ public: --------------------------------------------------------------------------------------- */ - RealOpenMM calculateForceAndEnergy( int numParticles, const std::vector& particlePositions, - const std::vector& radii, - const std::vector& epsilons, - RealOpenMM totalMaximumDispersionEnergy, std::vector& forces ) const; + RealOpenMM calculateForceAndEnergy(int numParticles, const std::vector& particlePositions, + const std::vector& radii, + const std::vector& epsilons, + RealOpenMM totalMaximumDispersionEnergy, std::vector& forces) const; private: RealOpenMM _epso; @@ -109,10 +109,10 @@ private: --------------------------------------------------------------------------------------- */ - RealOpenMM calculatePairIxn( RealOpenMM radiusI, RealOpenMM radiusJ, - const OpenMM::RealVec& particleIPosition, const OpenMM::RealVec& particleJPosition, - const RealOpenMM* const intermediateValues, - Vec3& force ) const; + RealOpenMM calculatePairIxn(RealOpenMM radiusI, RealOpenMM radiusJ, + const OpenMM::RealVec& particleIPosition, const OpenMM::RealVec& particleJPosition, + const RealOpenMM* const intermediateValues, + Vec3& force) const; }; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp index 56e2ddc24..152143e1b 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp @@ -66,7 +66,7 @@ const double TOL = 1e-5; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -75,24 +75,24 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, double quadraticK, double cubicK, - double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm, FILE* log ) { +static void getPrefactorsGivenAngleCosine(double cosine, double idealAngle, double quadraticK, double cubicK, + double quarticK, double penticK, double sexticK, + double* dEdR, double* energyTerm, FILE* log) { double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0f; } - else if( cosine <= -1.0 ){ + else if (cosine <= -1.0) { angle = RADIAN*PI_M; } else { angle = RADIAN*acos(cosine); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "getPrefactorsGivenAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealAngle ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "getPrefactorsGivenAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealAngle); + (void) fflush(log); } #endif @@ -103,11 +103,11 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou // deltaIdeal = r - r_0 - *dEdR = ( 2.0 + - 3.0*cubicK* deltaIdeal + - 4.0*quarticK*deltaIdeal2 + - 5.0*penticK* deltaIdeal3 + - 6.0*sexticK* deltaIdeal4 ); + *dEdR = (2.0 + + 3.0*cubicK* deltaIdeal + + 4.0*quarticK*deltaIdeal2 + + 5.0*penticK* deltaIdeal3 + + 6.0*sexticK* deltaIdeal4 ); *dEdR *= RADIAN*quadraticK*deltaIdeal; @@ -122,29 +122,29 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou } static void computeAmoebaAngleForce(int bondIndex, std::vector& positions, AmoebaAngleForce& AmoebaAngleForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy, FILE* log) { int particle1, particle2, particle3; double idealAngle; double quadraticK; - AmoebaAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, idealAngle, quadraticK ); + AmoebaAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, idealAngle, quadraticK); double cubicK = AmoebaAngleForce.getAmoebaGlobalAngleCubic(); double quarticK = AmoebaAngleForce.getAmoebaGlobalAngleQuartic(); double penticK = AmoebaAngleForce.getAmoebaGlobalAnglePentic(); double sexticK = AmoebaAngleForce.getAmoebaGlobalAngleSextic(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaAngleForce: bond %d [%d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, idealAngle, quadraticK, cubicK, quarticK, penticK, sexticK ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaAngleForce: bond %d [%d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", + bondIndex, particle1, particle2, particle3, idealAngle, quadraticK, cubicK, quarticK, penticK, sexticK); + (void) fflush(log); } #endif double deltaR[2][3]; double r2_0 = 0.0; double r2_1 = 0.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[0][ii] = positions[particle1][ii] - positions[particle2][ii]; r2_0 += deltaR[0][ii]*deltaR[0][ii]; @@ -155,33 +155,33 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions } double pVector[3]; - crossProductVector3( deltaR[0], deltaR[1], pVector ); - double rp = sqrt( pVector[0]*pVector[0] + pVector[1]*pVector[1] + pVector[2]*pVector[2] ); - if( rp < 1.0e-06 ){ + crossProductVector3(deltaR[0], deltaR[1], pVector); + double rp = sqrt(pVector[0]*pVector[0] + pVector[1]*pVector[1] + pVector[2]*pVector[2]); + if (rp < 1.0e-06) { rp = 1.0e-06; } double dot = deltaR[0][0]*deltaR[1][0] + deltaR[0][1]*deltaR[1][1] + deltaR[0][2]*deltaR[1][2]; double cosine = dot/sqrt(r2_0*r2_1); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "dot=%10.3e r2_0=%10.3e r2_1=%10.3e\n", dot, r2_0, r2_1 ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "dot=%10.3e r2_0=%10.3e r2_1=%10.3e\n", dot, r2_0, r2_1); + (void) fflush(log); } #endif double dEdR; double energyTerm; - getPrefactorsGivenAngleCosine( cosine, idealAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm, log ); + getPrefactorsGivenAngleCosine(cosine, idealAngle, quadraticK, cubicK, + quarticK, penticK, sexticK, &dEdR, &energyTerm, log); double termA = -dEdR/(r2_0*rp); double termC = dEdR/(r2_1*rp); double deltaCrossP[3][3]; - crossProductVector3( deltaR[0], pVector, deltaCrossP[0] ); - crossProductVector3( deltaR[1], pVector, deltaCrossP[2] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[0], pVector, deltaCrossP[0]); + crossProductVector3(deltaR[1], pVector, deltaCrossP[2]); + for (int ii = 0; ii < 3; ii++) { deltaCrossP[0][ii] *= termA; deltaCrossP[2][ii] *= termC; deltaCrossP[1][ii] = -1.0*(deltaCrossP[0][ii] + deltaCrossP[2][ii]); @@ -202,71 +202,71 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions *energy += energyTerm; } -static void computeAmoebaAngleForces( Context& context, AmoebaAngleForce& AmoebaAngleForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { +static void computeAmoebaAngleForces(Context& context, AmoebaAngleForce& AmoebaAngleForce, + std::vector& expectedForces, double* expectedEnergy, FILE* log) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < AmoebaAngleForce.getNumAngles(); ii++ ){ - computeAmoebaAngleForce(ii, positions, AmoebaAngleForce, expectedForces, expectedEnergy, log ); + for (int ii = 0; ii < AmoebaAngleForce.getNumAngles(); ii++) { + computeAmoebaAngleForce(ii, positions, AmoebaAngleForce, expectedForces, expectedEnergy, log); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaAngleForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaAngleForces: expected energy=%14.7e\n", *expectedEnergy); + for (unsigned int ii = 0; ii < positions.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif return; } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaAngleForce& AmoebaAngleForce, - double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaAngleForce& AmoebaAngleForce, + double tolerance, const std::string& idString, FILE* log) { std::vector expectedForces; double expectedEnergy; - computeAmoebaAngleForces( context, AmoebaAngleForce, expectedForces, &expectedEnergy, log ); + computeAmoebaAngleForces(context, AmoebaAngleForce, expectedForces, &expectedEnergy, log); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneAngle( FILE* log ) { +void testOneAngle(FILE* log) { System system; int numberOfParticles = 3; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -290,7 +290,7 @@ void testOneAngle( FILE* log ) { system.addForce(amoebaAngleForce); ASSERT(!amoebaAngleForce->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(numberOfParticles); @@ -299,7 +299,7 @@ void testOneAngle( FILE* log ) { positions[2] = Vec3(0, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle", log); // Try changing the angle parameters and make sure it's still correct. @@ -307,29 +307,29 @@ void testOneAngle( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle", log); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle", log); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestCudaAmoebaAngleForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - //FILE* log = fopen( "AmoebaAngleForce.log", "w" );; + //FILE* log = fopen("AmoebaAngleForce.log", "w");; FILE* log = NULL; //FILE* log = stderr; - testOneAngle( log ); + testOneAngle(log); #ifdef AMOEBA_DEBUG - if( log && log != stderr ) - (void) fclose( log ); + if (log && log != stderr) + (void) fclose(log); #endif } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp index baf391719..cb9fee6c5 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp @@ -49,22 +49,22 @@ extern "C" OPENMM_EXPORT void registerAmoebaReferenceKernelFactories(); const double TOL = 1e-5; static void computeAmoebaBondForce(int bondIndex, std::vector& positions, AmoebaBondForce& AmoebaBondForce, - std::vector& forces, double* energy ) { + std::vector& forces, double* energy) { int particle1, particle2; double bondLength; double quadraticK; double cubicK = AmoebaBondForce.getAmoebaGlobalBondCubic(); double quarticK = AmoebaBondForce.getAmoebaGlobalBondQuartic(); - AmoebaBondForce.getBondParameters(bondIndex, particle1, particle2, bondLength, quadraticK ); + AmoebaBondForce.getBondParameters(bondIndex, particle1, particle2, bondLength, quadraticK); double deltaR[3]; double r2 = 0.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[ii] = positions[particle2][ii] - positions[particle1][ii]; r2 += deltaR[ii]*deltaR[ii]; } - double r = sqrt( r2 ); + double r = sqrt(r2); double bondDelta = (r - bondLength); double bondDelta2 = bondDelta*bondDelta; @@ -84,64 +84,64 @@ static void computeAmoebaBondForce(int bondIndex, std::vector& positions, } -static void computeAmoebaBondForces( Context& context, AmoebaBondForce& AmoebaBondForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { +static void computeAmoebaBondForces(Context& context, AmoebaBondForce& AmoebaBondForce, + std::vector& expectedForces, double* expectedEnergy, FILE* log) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < AmoebaBondForce.getNumBonds(); ii++ ){ - computeAmoebaBondForce(ii, positions, AmoebaBondForce, expectedForces, expectedEnergy ); + for (int ii = 0; ii < AmoebaBondForce.getNumBonds(); ii++) { + computeAmoebaBondForce(ii, positions, AmoebaBondForce, expectedForces, expectedEnergy); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaBondForces: expected energy=%15.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%15.7e %15.7e %15.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaBondForces: expected energy=%15.7e\n", *expectedEnergy); + for (unsigned int ii = 0; ii < positions.size(); ii++) { + (void) fprintf(log, "%6u [%15.7e %15.7e %15.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif return; } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaBondForce& AmoebaBondForce, double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaBondForce& AmoebaBondForce, double tolerance, const std::string& idString, FILE* log) { std::vector expectedForces; double expectedEnergy; - computeAmoebaBondForces( context, AmoebaBondForce, expectedForces, &expectedEnergy, NULL ); + computeAmoebaBondForces(context, AmoebaBondForce, expectedForces, &expectedEnergy, NULL); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaBondForces: expected energy=%15.7e %15.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%15.7e %15.7e %15.7e] [%15.7e %15.7e %15.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaBondForces: expected energy=%15.7e %15.7e\n", expectedEnergy, state.getPotentialEnergy()); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%15.7e %15.7e %15.7e] [%15.7e %15.7e %15.7e]\n", ii, + expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneBond( FILE* log ) { +void testOneBond(FILE* log) { System system; @@ -156,22 +156,22 @@ void testOneBond( FILE* log ) { double quadraticK = 1.0; double cubicK = 2.0; double quarticicK = 3.0; - amoebaBondForce->setAmoebaGlobalBondCubic( cubicK ); - amoebaBondForce->setAmoebaGlobalBondQuartic( quarticicK ); + amoebaBondForce->setAmoebaGlobalBondCubic(cubicK); + amoebaBondForce->setAmoebaGlobalBondQuartic(quarticicK); amoebaBondForce->addBond(0, 1, bondLength, quadraticK); system.addForce(amoebaBondForce); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(2); positions[0] = Vec3(0, 1, 0); positions[1] = Vec3(0, 0, 0); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testOneBond", log ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testOneBond", log); } -void testTwoBond( FILE* log ) { +void testTwoBond(FILE* log) { System system; @@ -187,15 +187,15 @@ void testTwoBond( FILE* log ) { double quadraticK = 1.0; double cubicK = 2.0; double quarticicK = 3.0; - amoebaBondForce->setAmoebaGlobalBondCubic( cubicK ); - amoebaBondForce->setAmoebaGlobalBondQuartic( quarticicK ); + amoebaBondForce->setAmoebaGlobalBondCubic(cubicK); + amoebaBondForce->setAmoebaGlobalBondQuartic(quarticicK); amoebaBondForce->addBond(0, 1, bondLength, quadraticK); amoebaBondForce->addBond(1, 2, bondLength, quadraticK); system.addForce(amoebaBondForce); ASSERT(!amoebaBondForce->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(3); positions[0] = Vec3(0, 1, 0); @@ -203,7 +203,7 @@ void testTwoBond( FILE* log ) { positions[2] = Vec3(1, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond", log); // Try changing the bond parameters and make sure it's still correct. @@ -212,17 +212,17 @@ void testTwoBond( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond", log); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaBondForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond", log); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaBondForce running test..." << std::endl; @@ -230,11 +230,11 @@ int main( int numberOfArguments, char* argv[] ) { FILE* log = NULL; //FILE* log = stderr; - //testOneBond( log ); - testTwoBond( log ); + //testOneBond(log); + testTwoBond(log); #ifdef AMOEBA_DEBUG - if( log && log != stderr ) - (void) fclose( log ); + if (log && log != stderr) + (void) fclose(log); #endif } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp index e754b6e35..9a981fed8 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp @@ -65,10 +65,10 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 8; - amoebaMultipoleForce->setNonbondedMethod( AmoebaMultipoleForce::NoCutoff ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); + amoebaMultipoleForce->setNonbondedMethod(AmoebaMultipoleForce::NoCutoff); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); std::vector nitrogenMolecularDipole(3); std::vector nitrogenMolecularQuadrupole(9); @@ -89,8 +89,8 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce // first N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03 ); + system.addParticle(1.4007000e+01); + amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to first N @@ -110,167 +110,167 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 2.4549167e-06; - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); // second N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03 ); + system.addParticle( 1.4007000e+01); + amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to second N - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); // covalent maps std::vector< int > covalentMap; covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(0), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(1, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(1), covalentMap ); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(3, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + amoebaMultipoleForce->setCovalentMap(3, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(3, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(0), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(5, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(1), covalentMap ); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(6, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(7, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + amoebaMultipoleForce->setCovalentMap(7, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(7, static_cast(4), covalentMap); system.addForce(amoebaMultipoleForce); // GK force - amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01 ); - amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00 ); - amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm( includeCavityTerm ); + amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01); + amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); + amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm(includeCavityTerm); // addParticle: charge, radius, scalingFactor - for( unsigned int ii = 0; ii < 2; ii++ ){ - amoebaGeneralizedKirkwoodForce->addParticle( -5.7960000e-01, 1.5965000e-01, 6.9000000e-01 ); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01 ); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01 ); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01 ); + for (unsigned int ii = 0; ii < 2; ii++) { + amoebaGeneralizedKirkwoodForce->addParticle( -5.7960000e-01, 1.5965000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); } system.addForce(amoebaGeneralizedKirkwoodForce); } @@ -278,14 +278,14 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy, FILE* log) { std::vector positions(context.getSystem().getNumParticles()); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -295,8 +295,8 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& // setup for villin -static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::PolarizationType polarizationType, - int includeCavityTerm, std::vector& forces, double& energy, FILE* log ){ +static void setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::PolarizationType polarizationType, + int includeCavityTerm, std::vector& forces, double& energy, FILE* log) { // beginning of Multipole setup @@ -305,13 +305,13 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 596; - amoebaMultipoleForce->setNonbondedMethod( AmoebaMultipoleForce::NoCutoff ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); + amoebaMultipoleForce->setNonbondedMethod(AmoebaMultipoleForce::NoCutoff); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - system.addParticle( 1.0 ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + system.addParticle(1.0); } static const double multipoleData[] = { @@ -929,7 +929,7 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari std::vector quadrupole(9); unsigned int entriesPerParticle = 21; const double* data = multipoleData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { dipole[0] = data[dipoleIndex + 0]; dipole[1] = data[dipoleIndex + 1]; @@ -945,9 +945,9 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari quadrupole[7] = data[quadrupoleIndex + 7]; quadrupole[8] = data[quadrupoleIndex + 8]; - amoebaMultipoleForce->addMultipole( data[chargeIndex], dipole, quadrupole, static_cast(data[axisTypeIndex]), + amoebaMultipoleForce->addMultipole(data[chargeIndex], dipole, quadrupole, static_cast(data[axisTypeIndex]), static_cast(data[multipoleAtomZIndex]), static_cast(data[multipoleAtomXIndex]), static_cast(data[multipoleAtomYIndex]), - data[tholeIndex], data[dampingFactorIndex], data[polarityIndex] ); + data[tholeIndex], data[dampingFactorIndex], data[polarityIndex]); data += entriesPerParticle; } @@ -5727,15 +5727,15 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari unsigned int covalentMapDataSize = sizeof(covalentMapData)/sizeof(int); unsigned int covalentIndex = 0; - while( covalentIndex < covalentMapDataSize ){ + while (covalentIndex < covalentMapDataSize) { int particleIndex = covalentMapData[covalentIndex++]; int typeIndex = covalentMapData[covalentIndex++]; int entries = covalentMapData[covalentIndex++]; std::vector< int > covalentMap(entries); - for( unsigned int ii = 0; ii < entries; ii++ ){ + for (unsigned int ii = 0; ii < entries; ii++) { covalentMap[ii] = covalentMapData[covalentIndex++]; } - amoebaMultipoleForce->setCovalentMap( particleIndex, static_cast(typeIndex), covalentMap ); + amoebaMultipoleForce->setCovalentMap(particleIndex, static_cast(typeIndex), covalentMap); } system.addForce(amoebaMultipoleForce); @@ -5744,9 +5744,9 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari // GK force AmoebaGeneralizedKirkwoodForce* amoebaGeneralizedKirkwoodForce = new AmoebaGeneralizedKirkwoodForce(); - amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01 ); - amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00 ); - amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm( includeCavityTerm ); + amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01); + amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); + amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm(includeCavityTerm); // addParticle: charge, radius, scalingFactor @@ -6350,8 +6350,8 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari }; const double* gkData = generalizedKirkwoodData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - amoebaGeneralizedKirkwoodForce->addParticle( gkData[0], gkData[1], gkData[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + amoebaGeneralizedKirkwoodForce->addParticle(gkData[0], gkData[1], gkData[2]); gkData += 3; } system.addForce(amoebaGeneralizedKirkwoodForce); @@ -6960,15 +6960,15 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari }; const double* positionsDataPtr = positionsData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - positions[ii] = Vec3( positionsDataPtr[0], positionsDataPtr[1], positionsDataPtr[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + positions[ii] = Vec3(positionsDataPtr[0], positionsDataPtr[1], positionsDataPtr[2]); positionsDataPtr += 3; } std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -6978,117 +6978,117 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari // compare forces and energies -static void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, - const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { +static void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, + const std::vector& expectedForces, + const std::vector& forces, double tolerance, FILE* log) { //#define AMOEBA_DEBUG #ifdef AMOEBA_DEBUG - if( log ){ + if (log) { double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); - - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); - - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*absDiff, conversion*relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm ); + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, + conversion*energyAbsDiff, conversion*energyRelDiff); + if (conversion != 1.0)conversion *= -0.1; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + + expectedForces[ii][1]*expectedForces[ii][1] + + expectedForces[ii][2]*expectedForces[ii][2]); + + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs(norm - expectedNorm); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); + + (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + conversion*absDiff, conversion*relDiff, + conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], + conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm); } - (void) fflush( log ); + (void) fflush(log); conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); + (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); + if (conversion != 1.0)conversion = -1.0; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], + conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // compare relative differences in force norms and energies -static void compareForceNormsEnergy( std::string& testName, double expectedEnergy, double energy, - std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { +static void compareForceNormsEnergy(std::string& testName, double expectedEnergy, double energy, + std::vector& expectedForces, + const std::vector& forces, double tolerance, FILE* log) { //#define AMOEBA_DEBUG #ifdef AMOEBA_DEBUG - if( log ){ + if (log) { double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); - - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( (norm - expectedNorm) ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); - - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, + conversion*energyAbsDiff, conversion*energyRelDiff); + if (conversion != 1.0)conversion *= -0.1; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + + expectedForces[ii][1]*expectedForces[ii][1] + + expectedForces[ii][2]*expectedForces[ii][2]); + + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs((norm - expectedNorm)); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); + + (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, fabs(conversion)*absDiff, relDiff, conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], - fabs(conversion)*expectedNorm, fabs(conversion)*norm ); + fabs(conversion)*expectedNorm, fabs(conversion)*norm); } - (void) fflush( log ); + (void) fflush(log); conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); + if (conversion != 1.0)conversion = -1.0; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); + conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + + expectedForces[ii][1]*expectedForces[ii][1] + + expectedForces[ii][2]*expectedForces[ii][2]); - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs(norm - expectedNorm); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - if( relDiff > tolerance && absDiff > 0.001 ){ + if (relDiff > tolerance && absDiff > 0.001) { std::stringstream details; details << testName << "Relative difference in norms " << relDiff << " larger than allowed tolerance at particle=" << ii; details << ": norms=" << norm << " expected norm=" << expectedNorm; throwException(__FILE__, __LINE__, details.str()); } } - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - if( energyRelDiff > tolerance ){ + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + if (energyRelDiff > tolerance) { std::stringstream details; details << testName << "Relative difference in energies " << energyRelDiff << " larger than allowed tolerance."; details << "Energies=" << energy << " expected energy=" << expectedEnergy; @@ -7098,7 +7098,7 @@ static void compareForceNormsEnergy( std::string& testName, double expectedEnerg // test GK direct polarization for system comprised of two ammonia molecules -static void testGeneralizedKirkwoodAmmoniaDirectPolarization( FILE* log ) { +static void testGeneralizedKirkwoodAmmoniaDirectPolarization(FILE* log) { std::string testName = "testGeneralizedKirkwoodAmmoniaDirectPolarization"; @@ -7111,27 +7111,27 @@ static void testGeneralizedKirkwoodAmmoniaDirectPolarization( FILE* log ) { setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Direct, 0); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log ); + getForcesEnergyMultipoleAmmonia(context, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = -7.6636680e+01; - expectedForces[0] = Vec3( -6.9252994e+02, -8.9085133e+00, 9.6489739e+01 ); - expectedForces[1] = Vec3( 1.5593797e+02, -6.0331931e+01, 1.5104507e+01 ); - expectedForces[2] = Vec3( 1.5870088e+02, 6.1702809e+01, 6.7708985e+00 ); - expectedForces[3] = Vec3( 1.4089885e+02, 7.5870617e+00, -1.1362294e+02 ); - expectedForces[4] = Vec3( -1.8916205e+02, 2.1465549e-01, -4.3433152e+02 ); - expectedForces[5] = Vec3( 1.0208290e+01, 6.2676753e+01, 1.4987953e+02 ); - expectedForces[6] = Vec3( 4.0621859e+02, 1.8962203e-01, 1.3021956e+02 ); - expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02 ); + expectedForces[0] = Vec3( -6.9252994e+02, -8.9085133e+00, 9.6489739e+01); + expectedForces[1] = Vec3( 1.5593797e+02, -6.0331931e+01, 1.5104507e+01); + expectedForces[2] = Vec3( 1.5870088e+02, 6.1702809e+01, 6.7708985e+00); + expectedForces[3] = Vec3( 1.4089885e+02, 7.5870617e+00, -1.1362294e+02); + expectedForces[4] = Vec3( -1.8916205e+02, 2.1465549e-01, -4.3433152e+02); + expectedForces[5] = Vec3( 1.0208290e+01, 6.2676753e+01, 1.4987953e+02); + expectedForces[6] = Vec3( 4.0621859e+02, 1.8962203e-01, 1.3021956e+02); + expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test GK mutual polarization for system comprised of two ammonia molecules -static void testGeneralizedKirkwoodAmmoniaMutualPolarization( FILE* log ) { +static void testGeneralizedKirkwoodAmmoniaMutualPolarization(FILE* log) { std::string testName = "testGeneralizedKirkwoodAmmoniaMutualPolarization"; @@ -7144,28 +7144,28 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarization( FILE* log ) { setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Mutual, 0); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log ); + getForcesEnergyMultipoleAmmonia(context, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = -7.8018875e+01; - expectedForces[0] = Vec3( -7.6820301e+02, -1.0102760e+01, 1.0094389e+02 ); - expectedForces[1] = Vec3( 1.7037307e+02, -7.5621857e+01, 2.3320365e+01 ); - expectedForces[2] = Vec3( 1.7353828e+02, 7.7199741e+01, 1.3965379e+01 ); - expectedForces[3] = Vec3( 1.5045244e+02, 8.5784569e+00, -1.3377619e+02 ); - expectedForces[4] = Vec3( -2.1811615e+02, -1.6818022e-01, -4.6103163e+02 ); - expectedForces[5] = Vec3( 6.2091942e+00, 7.6748687e+01, 1.5883463e+02 ); - expectedForces[6] = Vec3( 4.8035662e+02, 4.9704902e-01, 1.3948083e+02 ); - expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02 ); + expectedForces[0] = Vec3( -7.6820301e+02, -1.0102760e+01, 1.0094389e+02); + expectedForces[1] = Vec3( 1.7037307e+02, -7.5621857e+01, 2.3320365e+01); + expectedForces[2] = Vec3( 1.7353828e+02, 7.7199741e+01, 1.3965379e+01); + expectedForces[3] = Vec3( 1.5045244e+02, 8.5784569e+00, -1.3377619e+02); + expectedForces[4] = Vec3( -2.1811615e+02, -1.6818022e-01, -4.6103163e+02); + expectedForces[5] = Vec3( 6.2091942e+00, 7.6748687e+01, 1.5883463e+02); + expectedForces[6] = Vec3( 4.8035662e+02, 4.9704902e-01, 1.3948083e+02); + expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test GK mutual polarization for system comprised of two ammonia molecules // including cavity term -static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE* log ) { +static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(FILE* log) { std::string testName = "testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm"; @@ -7180,22 +7180,22 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE ASSERT(!system.usesPeriodicBoundaryConditions()); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log ); + getForcesEnergyMultipoleAmmonia(context, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = -6.0434582e+01; - expectedForces[0] = Vec3( -7.8323218e+02, -1.0097644e+01, 1.0256890e+02 ); - expectedForces[1] = Vec3( 1.7078480e+02, -7.1896701e+01, 2.0840172e+01 ); - expectedForces[2] = Vec3( 1.7394089e+02, 7.3488594e+01, 1.1484648e+01 ); - expectedForces[3] = Vec3( 1.5169364e+02, 8.5611299e+00, -1.2968050e+02 ); - expectedForces[4] = Vec3( -2.1669693e+02, -1.5926823e-01, -4.6636274e+02 ); - expectedForces[5] = Vec3( 8.7397444e+00, 7.3330990e+01, 1.6016898e+02 ); - expectedForces[6] = Vec3( 4.8684950e+02, 4.8937161e-01, 1.4137061e+02 ); - expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02 ); + expectedForces[0] = Vec3( -7.8323218e+02, -1.0097644e+01, 1.0256890e+02); + expectedForces[1] = Vec3( 1.7078480e+02, -7.1896701e+01, 2.0840172e+01); + expectedForces[2] = Vec3( 1.7394089e+02, 7.3488594e+01, 1.1484648e+01); + expectedForces[3] = Vec3( 1.5169364e+02, 8.5611299e+00, -1.2968050e+02); + expectedForces[4] = Vec3( -2.1669693e+02, -1.5926823e-01, -4.6636274e+02); + expectedForces[5] = Vec3( 8.7397444e+00, 7.3330990e+01, 1.6016898e+02); + expectedForces[6] = Vec3( 4.8684950e+02, 4.8937161e-01, 1.4137061e+02); + expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); // Try changing the particle parameters and make sure it's still correct. @@ -7225,7 +7225,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE // test GK direct polarization for villin system -static void testGeneralizedKirkwoodVillinDirectPolarization( FILE* log ) { +static void testGeneralizedKirkwoodVillinDirectPolarization(FILE* log) { std::string testName = "testGeneralizedKirkwoodVillinDirectPolarization"; @@ -7233,7 +7233,7 @@ static void testGeneralizedKirkwoodVillinDirectPolarization( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Direct, 0, forces, energy, log ); + setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Direct, 0, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.4281157e+03; @@ -7838,18 +7838,18 @@ static void testGeneralizedKirkwoodVillinDirectPolarization( FILE* log ) { }; const double* forceDataPtr = forceData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - expectedForces[ii] = Vec3( forceDataPtr[0], forceDataPtr[1], forceDataPtr[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + expectedForces[ii] = Vec3(forceDataPtr[0], forceDataPtr[1], forceDataPtr[2]); forceDataPtr += 3; } double tolerance = 1.0e-05; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test GK mutual polarization for villin system -static void testGeneralizedKirkwoodVillinMutualPolarization( FILE* log ) { +static void testGeneralizedKirkwoodVillinMutualPolarization(FILE* log) { std::string testName = "testGeneralizedKirkwoodVillinMutualPolarization"; @@ -7857,7 +7857,7 @@ static void testGeneralizedKirkwoodVillinMutualPolarization( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Mutual, 0, forces, energy, log ); + setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Mutual, 0, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.6477811e+03; @@ -8462,16 +8462,16 @@ static void testGeneralizedKirkwoodVillinMutualPolarization( FILE* log ) { }; const double* forceDataPtr = forceData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - expectedForces[ii] = Vec3( forceDataPtr[0], forceDataPtr[1], forceDataPtr[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + expectedForces[ii] = Vec3(forceDataPtr[0], forceDataPtr[1], forceDataPtr[2]); forceDataPtr += 3; } double tolerance = 1.0e-05; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaGeneralizedKirkwoodForce running test..." << std::endl; @@ -8482,11 +8482,11 @@ int main( int numberOfArguments, char* argv[] ) { // test direct and mutual polarization cases and // mutual polarization w/ the cavity term - testGeneralizedKirkwoodAmmoniaMutualPolarization( log ); - testGeneralizedKirkwoodAmmoniaDirectPolarization( log ); - testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( log ); - testGeneralizedKirkwoodVillinDirectPolarization( log ); - testGeneralizedKirkwoodVillinMutualPolarization( log ); + testGeneralizedKirkwoodAmmoniaMutualPolarization(log); + testGeneralizedKirkwoodAmmoniaDirectPolarization(log); + testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(log); + testGeneralizedKirkwoodVillinDirectPolarization(log); + testGeneralizedKirkwoodVillinMutualPolarization(log); } catch(const std::exception& e) { diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp index bbcf4b513..c561efd73 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp @@ -64,7 +64,7 @@ const double TOL = 1e-5; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -73,28 +73,28 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } -static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInPlaneAngle, double quadraticK, double cubicK, - double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm, FILE* log ) { +static void getPrefactorsGivenInPlaneAngleCosine(double cosine, double idealInPlaneAngle, double quadraticK, double cubicK, + double quarticK, double penticK, double sexticK, + double* dEdR, double* energyTerm, FILE* log) { double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0f; } - else if( cosine <= -1.0 ){ + else if (cosine <= -1.0) { angle = RADIAN*PI_M; } else { angle = RADIAN*acos(cosine); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "getPrefactorsGivenInPlaneAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealInPlaneAngle ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "getPrefactorsGivenInPlaneAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealInPlaneAngle); + (void) fflush(log); } #endif @@ -105,11 +105,11 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP // deltaIdeal = r - r_0 - *dEdR = ( 2.0 + + *dEdR = (2.0 + 3.0*cubicK* deltaIdeal + 4.0*quarticK*deltaIdeal2 + 5.0*penticK* deltaIdeal3 + - 6.0*sexticK* deltaIdeal4 ); + 6.0*sexticK* deltaIdeal4 ); *dEdR *= RADIAN*quadraticK*deltaIdeal; @@ -124,22 +124,22 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP } static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& positions, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy, FILE* log) { int particle1, particle2, particle3, particle4; double idealInPlaneAngle; double quadraticK; - AmoebaInPlaneAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK ); + AmoebaInPlaneAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK); double cubicK = AmoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleCubic(); double quarticK = AmoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleQuartic(); double penticK = AmoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAnglePentic(); double sexticK = AmoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleSextic(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForce: bond %d [%d %d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK, cubicK, quarticK, penticK, sexticK ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaInPlaneAngleForce: bond %d [%d %d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", + bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK, cubicK, quarticK, penticK, sexticK); + (void) fflush(log); } #endif @@ -162,82 +162,82 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po // APxM, CPxM, ADxBD, BDxCD, TxCD, ADxT, dBxAD, CDxdB, LastDeltaAtomIndex double deltaR[LastDeltaAtomIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii]; deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii]; deltaR[CD][ii] = positions[particle3][ii] - positions[particle4][ii]; } - crossProductVector3( deltaR[AD], deltaR[CD], deltaR[T] ); + crossProductVector3(deltaR[AD], deltaR[CD], deltaR[T]); - double rT2 = dotVector3( deltaR[T], deltaR[T] ); - double delta = dotVector3( deltaR[T], deltaR[BD] ); + double rT2 = dotVector3(deltaR[T], deltaR[T]); + double delta = dotVector3(deltaR[T], deltaR[BD]); delta *= -1.0/rT2; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[P][ii] = positions[particle2][ii] + deltaR[T][ii]*delta; deltaR[AP][ii] = positions[particle1][ii] - deltaR[P][ii]; deltaR[CP][ii] = positions[particle3][ii] - deltaR[P][ii]; } - double rAp2 = dotVector3( deltaR[AP], deltaR[AP] ); - double rCp2 = dotVector3( deltaR[CP], deltaR[CP] ); - if( rAp2 <= 0.0 && rCp2 <= 0.0 ){ + double rAp2 = dotVector3(deltaR[AP], deltaR[AP]); + double rCp2 = dotVector3(deltaR[CP], deltaR[CP]); + if (rAp2 <= 0.0 && rCp2 <= 0.0) { #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForce: rAp2 or rCp2 <= 0.0\n" ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaInPlaneAngleForce: rAp2 or rCp2 <= 0.0\n"); + (void) fflush(log); } #endif return; } - crossProductVector3( deltaR[CP], deltaR[AP], deltaR[M] ); + crossProductVector3(deltaR[CP], deltaR[AP], deltaR[M]); - double rm = dotVector3( deltaR[M], deltaR[M] ); - rm = sqrt( rm ); - if( rm < 0.000001 ){ + double rm = dotVector3(deltaR[M], deltaR[M]); + rm = sqrt(rm); + if (rm < 0.000001) { rm = 0.000001; } - double dot = dotVector3( deltaR[AP], deltaR[CP] ); - double cosine = dot/sqrt( rAp2*rCp2 ); + double dot = dotVector3(deltaR[AP], deltaR[CP]); + double cosine = dot/sqrt(rAp2*rCp2); double dEdR; double energyTerm; - getPrefactorsGivenInPlaneAngleCosine( cosine, idealInPlaneAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm, log ); + getPrefactorsGivenInPlaneAngleCosine(cosine, idealInPlaneAngle, quadraticK, cubicK, + quarticK, penticK, sexticK, &dEdR, &energyTerm, log); double termA = -dEdR/(rAp2*rm); double termC = dEdR/(rCp2*rm); - crossProductVector3( deltaR[AP], deltaR[M], deltaR[APxM] ); - crossProductVector3( deltaR[CP], deltaR[M], deltaR[CPxM] ); + crossProductVector3(deltaR[AP], deltaR[M], deltaR[APxM]); + crossProductVector3(deltaR[CP], deltaR[M], deltaR[CPxM]); // forces will be gathered here enum { dA, dB, dC, dD, LastDIndex }; double forceTerm[LastDIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forceTerm[dA][ii] = deltaR[APxM][ii]*termA; forceTerm[dC][ii] = deltaR[CPxM][ii]*termC; - forceTerm[dB][ii] = -1.0*( forceTerm[dA][ii] + forceTerm[dC][ii] ); + forceTerm[dB][ii] = -1.0*(forceTerm[dA][ii] + forceTerm[dC][ii]); } - double pTrT2 = dotVector3( forceTerm[dB], deltaR[T] ); + double pTrT2 = dotVector3(forceTerm[dB], deltaR[T]); pTrT2 /= rT2; - crossProductVector3( deltaR[CD], forceTerm[dB], deltaR[CDxdB] ); - crossProductVector3( forceTerm[dB], deltaR[AD], deltaR[dBxAD] ); + crossProductVector3(deltaR[CD], forceTerm[dB], deltaR[CDxdB]); + crossProductVector3(forceTerm[dB], deltaR[AD], deltaR[dBxAD]); - if( fabs( pTrT2 ) > 1.0e-08 ){ + if (fabs(pTrT2) > 1.0e-08) { double delta2 = delta*2.0; - crossProductVector3( deltaR[BD], deltaR[CD], deltaR[BDxCD] ); - crossProductVector3( deltaR[T], deltaR[CD], deltaR[TxCD] ); - crossProductVector3( deltaR[AD], deltaR[BD], deltaR[ADxBD] ); - crossProductVector3( deltaR[AD], deltaR[T], deltaR[ADxT] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[BD], deltaR[CD], deltaR[BDxCD]); + crossProductVector3(deltaR[T], deltaR[CD], deltaR[TxCD] ); + crossProductVector3(deltaR[AD], deltaR[BD], deltaR[ADxBD]); + crossProductVector3(deltaR[AD], deltaR[T], deltaR[ADxT] ); + for (int ii = 0; ii < 3; ii++) { double term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii]; forceTerm[dA][ii] += delta*deltaR[CDxdB][ii] + term*pTrT2; @@ -245,16 +245,16 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po term = deltaR[ADxBD][ii] + delta2*deltaR[ADxT][ii]; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii] + term*pTrT2; - forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); + forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]); } } else { - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forceTerm[dA][ii] += delta*deltaR[CDxdB][ii]; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii]; - forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); + forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]); } } @@ -280,69 +280,69 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po } -static void computeAmoebaInPlaneAngleForces( Context& context, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { +static void computeAmoebaInPlaneAngleForces(Context& context, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, + std::vector& expectedForces, double* expectedEnergy, FILE* log) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < AmoebaInPlaneAngleForce.getNumAngles(); ii++ ){ - computeAmoebaInPlaneAngleForce(ii, positions, AmoebaInPlaneAngleForce, expectedForces, expectedEnergy, log ); + for (int ii = 0; ii < AmoebaInPlaneAngleForce.getNumAngles(); ii++) { + computeAmoebaInPlaneAngleForce(ii, positions, AmoebaInPlaneAngleForce, expectedForces, expectedEnergy, log); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e\n", *expectedEnergy); + for (unsigned int ii = 0; ii < positions.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif return; } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, - double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, + double tolerance, const std::string& idString, FILE* log) { std::vector expectedForces; double expectedEnergy; - computeAmoebaInPlaneAngleForces( context, AmoebaInPlaneAngleForce, expectedForces, &expectedEnergy, log ); + computeAmoebaInPlaneAngleForces(context, AmoebaInPlaneAngleForce, expectedForces, &expectedEnergy, log); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneAngle( FILE* log ) { +void testOneAngle(FILE* log) { System system; int numberOfParticles = 4; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -366,7 +366,7 @@ void testOneAngle( FILE* log ) { system.addForce(amoebaInPlaneAngleForce); ASSERT(!amoebaInPlaneAngleForce->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(numberOfParticles); @@ -376,7 +376,7 @@ void testOneAngle( FILE* log ) { positions[3] = Vec3(1, 1, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log); // Try changing the angle parameters and make sure it's still correct. @@ -384,29 +384,29 @@ void testOneAngle( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaInPlaneAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaInPlaneAngleForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); FILE* log = NULL; //FILE* log = stderr; - //FILE* log = fopen( "AmoebaInPlaneAngleForce.log", "w" );; + //FILE* log = fopen("AmoebaInPlaneAngleForce.log", "w");; - testOneAngle( NULL ); + testOneAngle(NULL); #ifdef AMOEBA_DEBUG - if( log && log != stderr ) - (void) fclose( log ); + if (log && log != stderr) + (void) fclose(log); #endif } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp index 21d8c1a5f..9b562d226 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp @@ -66,24 +66,24 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu // box double boxDimension = 0.6; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); int numberOfParticles = 8; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 1.4024714e+01 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(1.4024714e+01); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); - std::vector pmeGridDimension( 3 ); + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); std::vector nitrogenMolecularDipole(3); std::vector nitrogenMolecularQuadrupole(9); @@ -104,8 +104,8 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu // first N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03 ); + system.addParticle(1.4007000e+01); + amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to first N @@ -125,165 +125,165 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 2.4549167e-06; - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9e-01, 2.8135002e-01, 4.96e-04 ); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9e-01, 2.8135002e-01, 4.96e-04); // second N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.796e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9e-01, 3.1996314e-01, 1.073e-03 ); + system.addParticle( 1.4007000e+01); + amoebaMultipoleForce->addMultipole( -5.796e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9e-01, 3.1996314e-01, 1.073e-03); // 3 H attached to second N - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9e-01, 2.8135002e-01, 4.96e-04 ); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9e-01, 2.8135002e-01, 4.96e-04); // covalent maps std::vector< int > covalentMap; covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(0), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(1, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(1), covalentMap ); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(3, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + amoebaMultipoleForce->setCovalentMap(3, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(3, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(0), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(5, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(1), covalentMap ); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(6, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(7, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + amoebaMultipoleForce->setCovalentMap(7, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(7, static_cast(4), covalentMap); system.addForce(amoebaMultipoleForce); } static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy) { std::vector positions(context.getSystem().getNumParticles()); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -293,116 +293,116 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& // compare forces and energies -static void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, - const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { +static void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, + const std::vector& expectedForces, + const std::vector& forces, double tolerance, FILE* log) { //#define AMOEBA_DEBUG #ifdef AMOEBA_DEBUG - if( log ){ + if (log) { double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, + conversion*energyAbsDiff, conversion*energyRelDiff); + if (conversion != 1.0)conversion *= -0.1; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); + expectedForces[ii][2]*expectedForces[ii][2]); - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs(norm - expectedNorm); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, conversion*absDiff, conversion*relDiff, conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm ); + conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm); } - (void) fflush( log ); + (void) fflush(log); conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); + if (conversion != 1.0)conversion = -1.0; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); + conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // compare relative differences in force norms and energies -static void compareForceNormsEnergy( std::string& testName, double expectedEnergy, double energy, - std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { +static void compareForceNormsEnergy(std::string& testName, double expectedEnergy, double energy, + std::vector& expectedForces, + const std::vector& forces, double tolerance, FILE* log) { //#define AMOEBA_DEBUG #ifdef AMOEBA_DEBUG - if( log ){ + if (log) { double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); - - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( (norm - expectedNorm) ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); - - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, + conversion*energyAbsDiff, conversion*energyRelDiff); + if (conversion != 1.0)conversion *= -0.1; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + + expectedForces[ii][1]*expectedForces[ii][1] + + expectedForces[ii][2]*expectedForces[ii][2]); + + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs((norm - expectedNorm)); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); + + (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, fabs(conversion)*absDiff, relDiff, conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], - fabs(conversion)*expectedNorm, fabs(conversion)*norm ); + fabs(conversion)*expectedNorm, fabs(conversion)*norm); } - (void) fflush( log ); + (void) fflush(log); conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); + if (conversion != 1.0)conversion = -1.0; + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); + conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + + expectedForces[ii][1]*expectedForces[ii][1] + + expectedForces[ii][2]*expectedForces[ii][2]); - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs(norm - expectedNorm); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - if( relDiff > tolerance && absDiff > 0.001 ){ + if (relDiff > tolerance && absDiff > 0.001) { std::stringstream details; details << testName << "Relative difference in norms " << relDiff << " larger than allowed tolerance at particle=" << ii; details << ": norms=" << norm << " expected norm=" << expectedNorm; throwException(__FILE__, __LINE__, details.str()); } } - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - if( energyRelDiff > tolerance ){ + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + if (energyRelDiff > tolerance) { std::stringstream details; details << testName << "Relative difference in energies " << energyRelDiff << " larger than allowed tolerance."; details << "Energies=" << energy << " expected energy=" << expectedEnergy; @@ -412,7 +412,7 @@ static void compareForceNormsEnergy( std::string& testName, double expectedEnerg // test multipole direct polarization for system comprised of two ammonia molecules; no cutoff -static void testMultipoleAmmoniaDirectPolarization( FILE* log ) { +static void testMultipoleAmmoniaDirectPolarization(FILE* log) { std::string testName = "testMultipoleAmmoniaDirectPolarization"; @@ -433,22 +433,22 @@ static void testMultipoleAmmoniaDirectPolarization( FILE* log ) { double expectedEnergy = -1.7428832e+01; - expectedForces[0] = Vec3( -3.5574000e+02, -7.3919340e+00, 3.8989934e+01 ); - expectedForces[1] = Vec3( 3.0368045e+01, -8.7325694e+00, 6.9731151e+00 ); - expectedForces[2] = Vec3( 3.2358980e+01, 1.0234924e+01, 4.7203694e-01 ); - expectedForces[3] = Vec3( 2.1439022e+01, 5.8998414e+00, -3.8355239e+01 ); - expectedForces[4] = Vec3( -1.8052760e+02, -1.0618455e+00, -7.0030146e+01 ); - expectedForces[5] = Vec3( 4.2411304e+01, -1.6569222e+01, 1.9047581e+00 ); - expectedForces[6] = Vec3( 3.6823677e+02, 7.7839986e-01, 5.8404590e+01 ); - expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00 ); + expectedForces[0] = Vec3( -3.5574000e+02, -7.3919340e+00, 3.8989934e+01); + expectedForces[1] = Vec3( 3.0368045e+01, -8.7325694e+00, 6.9731151e+00); + expectedForces[2] = Vec3( 3.2358980e+01, 1.0234924e+01, 4.7203694e-01); + expectedForces[3] = Vec3( 2.1439022e+01, 5.8998414e+00, -3.8355239e+01); + expectedForces[4] = Vec3( -1.8052760e+02, -1.0618455e+00, -7.0030146e+01); + expectedForces[5] = Vec3( 4.2411304e+01, -1.6569222e+01, 1.9047581e+00); + expectedForces[6] = Vec3( 3.6823677e+02, 7.7839986e-01, 5.8404590e+01); + expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test multipole mutual polarization for system comprised of two ammonia molecules; no cutoff -static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { +static void testMultipoleAmmoniaMutualPolarization(FILE* log) { std::string testName = "testMultipoleAmmoniaMutualPolarization"; @@ -471,17 +471,17 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { double expectedEnergy = -1.7790449e+01; - expectedForces[0] = Vec3( -3.7523158e+02, -7.9806295e+00, 3.7464051e+01 ); - expectedForces[1] = Vec3( 3.1352410e+01, -9.4055551e+00, 8.5230415e+00 ); - expectedForces[2] = Vec3( 3.3504923e+01, 1.1029935e+01, 1.5052263e+00 ); - expectedForces[3] = Vec3( 2.3295507e+01, 6.3698827e+00, -4.0403553e+01 ); - expectedForces[4] = Vec3( -1.9379275e+02, -1.0903937e+00, -7.3461740e+01 ); - expectedForces[5] = Vec3( 4.3278067e+01, -1.6906589e+01, 1.5721909e+00 ); - expectedForces[6] = Vec3( 3.9529983e+02, 7.9661172e-01, 6.3499055e+01 ); - expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00 ); + expectedForces[0] = Vec3( -3.7523158e+02, -7.9806295e+00, 3.7464051e+01); + expectedForces[1] = Vec3( 3.1352410e+01, -9.4055551e+00, 8.5230415e+00); + expectedForces[2] = Vec3( 3.3504923e+01, 1.1029935e+01, 1.5052263e+00); + expectedForces[3] = Vec3( 2.3295507e+01, 6.3698827e+00, -4.0403553e+01); + expectedForces[4] = Vec3( -1.9379275e+02, -1.0903937e+00, -7.3461740e+01); + expectedForces[5] = Vec3( 4.3278067e+01, -1.6906589e+01, 1.5721909e+00); + expectedForces[6] = Vec3( 3.9529983e+02, 7.9661172e-01, 6.3499055e+01); + expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); // Try changing the particle parameters and make sure it's still correct. @@ -503,7 +503,7 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log ); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); } catch (std::exception ex) { exceptionThrown = true; @@ -511,15 +511,15 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { ASSERT(exceptionThrown); amoebaMultipoleForce->updateParametersInContext(context); state1 = context.getState(State::Forces | State::Energy); - compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log ); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); } // setup for box of 4 water molecules -- used to test PME -static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, - AmoebaMultipoleForce::PolarizationType polarizationType, - double cutoff, int inputPmeGridDimension, std::vector& forces, - double& energy, FILE* log ){ +static void setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, + AmoebaMultipoleForce::PolarizationType polarizationType, + double cutoff, int inputPmeGridDimension, std::vector& forces, + double& energy, FILE* log) { // beginning of Multipole setup @@ -528,29 +528,29 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond // box dimensions double boxDimension = 1.8643; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 12; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); - - std::vector pmeGridDimension( 3 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); + + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5995000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5995000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -586,61 +586,61 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps std::vector< int > covalentMap; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(0), covalentMap ); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(4), covalentMap ); + covalentMap.push_back(jj); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(0), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(0), covalentMap ); + covalentMap.push_back(jj); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(0), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(1), covalentMap ); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); + covalentMap.push_back(jj+1); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(1), covalentMap); } std::vector positions(numberOfParticles); - positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03 ); - positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02 ); - positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01 ); - positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01 ); - positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01 ); - positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01 ); - positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01 ); - positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01 ); - positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01 ); - positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01 ); - positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01 ); - positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01 ); + positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03); + positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02); + positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01); + positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); + positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); + positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); + positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); + positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); + positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); + positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); + positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); + positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); system.addForce(amoebaMultipoleForce); ASSERT(amoebaMultipoleForce->usesPeriodicBoundaryConditions()); @@ -649,7 +649,7 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -659,7 +659,7 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond // test multipole direct polarization using PME for box of water -static void testMultipoleWaterPMEDirectPolarization( FILE* log ) { +static void testMultipoleWaterPMEDirectPolarization(FILE* log) { std::string testName = "testMultipoleWaterDirectPolarization"; @@ -669,32 +669,32 @@ static void testMultipoleWaterPMEDirectPolarization( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, forces, energy, log ); + setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, + cutoff, inputPmeGridDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.4585115e-01; - expectedForces[0] = Vec3( -1.2396731e+00, -2.4231698e+01, 8.3348523e+00 ); - expectedForces[1] = Vec3( -3.3737276e+00, 9.9304523e+00, -6.3917827e+00 ); - expectedForces[2] = Vec3( 4.4062247e+00, 1.9518971e+01, -4.6552873e+00 ); - expectedForces[3] = Vec3( -1.3128824e+00, -1.2887339e+00, -1.4473147e+00 ); - expectedForces[4] = Vec3( 2.1137034e+00, 3.9457973e-01, 2.9269129e-01 ); - expectedForces[5] = Vec3( 1.0271174e+00, 1.2039367e+00, 1.2112214e+00 ); - expectedForces[6] = Vec3( -3.2082903e+00, 1.4979371e+01, -1.0274832e+00 ); - expectedForces[7] = Vec3( -1.1880320e+00, -1.5177166e+01, 2.5525509e+00 ); - expectedForces[8] = Vec3( 4.3607105e+00, -7.0253274e+00, 2.9522580e-01 ); - expectedForces[9] = Vec3( -3.0175134e+00, 1.3607102e+00, 6.6883370e+00 ); - expectedForces[10] = Vec3( 9.2036949e-01, -1.4717629e+00, -3.3362339e+00 ); - expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00 ); + expectedForces[0] = Vec3( -1.2396731e+00, -2.4231698e+01, 8.3348523e+00); + expectedForces[1] = Vec3( -3.3737276e+00, 9.9304523e+00, -6.3917827e+00); + expectedForces[2] = Vec3( 4.4062247e+00, 1.9518971e+01, -4.6552873e+00); + expectedForces[3] = Vec3( -1.3128824e+00, -1.2887339e+00, -1.4473147e+00); + expectedForces[4] = Vec3( 2.1137034e+00, 3.9457973e-01, 2.9269129e-01); + expectedForces[5] = Vec3( 1.0271174e+00, 1.2039367e+00, 1.2112214e+00); + expectedForces[6] = Vec3( -3.2082903e+00, 1.4979371e+01, -1.0274832e+00); + expectedForces[7] = Vec3( -1.1880320e+00, -1.5177166e+01, 2.5525509e+00); + expectedForces[8] = Vec3( 4.3607105e+00, -7.0253274e+00, 2.9522580e-01); + expectedForces[9] = Vec3( -3.0175134e+00, 1.3607102e+00, 6.6883370e+00); + expectedForces[10] = Vec3( 9.2036949e-01, -1.4717629e+00, -3.3362339e+00); + expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00); double tolerance = 1.0e-03; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test multipole mutual polarization using PME for box of water -static void testMultipoleWaterPMEMutualPolarization( FILE* log ) { +static void testMultipoleWaterPMEMutualPolarization(FILE* log) { std::string testName = "testMultipoleWaterMutualPolarization"; @@ -704,32 +704,32 @@ static void testMultipoleWaterPMEMutualPolarization( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, forces, energy, log ); + setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.5029855e-01; - expectedForces[0] = Vec3( -1.2367386e+00, -2.4197036e+01, 8.3256759e+00 ); - expectedForces[1] = Vec3( -3.3825187e+00, 9.9387618e+00, -6.4200475e+00 ); - expectedForces[2] = Vec3( 4.4108644e+00, 1.9486127e+01, -4.6530661e+00 ); - expectedForces[3] = Vec3( -1.3129168e+00, -1.2947383e+00, -1.4438198e+00 ); - expectedForces[4] = Vec3( 2.1144837e+00, 3.9590305e-01, 2.9040889e-01 ); - expectedForces[5] = Vec3( 1.0287222e+00, 1.2100201e+00, 1.2103068e+00 ); - expectedForces[6] = Vec3( -3.2017550e+00, 1.4995985e+01, -1.1036504e+00 ); - expectedForces[7] = Vec3( -1.2065398e+00, -1.5192899e+01, 2.6233368e+00 ); - expectedForces[8] = Vec3( 4.3698604e+00, -7.0550315e+00, 3.4204565e-01 ); - expectedForces[9] = Vec3( -3.0082825e+00, 1.3575082e+00, 6.6901032e+00 ); - expectedForces[10] = Vec3( 9.1775539e-01, -1.4651882e+00, -3.3322516e+00 ); - expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00 ); + expectedForces[0] = Vec3( -1.2367386e+00, -2.4197036e+01, 8.3256759e+00); + expectedForces[1] = Vec3( -3.3825187e+00, 9.9387618e+00, -6.4200475e+00); + expectedForces[2] = Vec3( 4.4108644e+00, 1.9486127e+01, -4.6530661e+00); + expectedForces[3] = Vec3( -1.3129168e+00, -1.2947383e+00, -1.4438198e+00); + expectedForces[4] = Vec3( 2.1144837e+00, 3.9590305e-01, 2.9040889e-01); + expectedForces[5] = Vec3( 1.0287222e+00, 1.2100201e+00, 1.2103068e+00); + expectedForces[6] = Vec3( -3.2017550e+00, 1.4995985e+01, -1.1036504e+00); + expectedForces[7] = Vec3( -1.2065398e+00, -1.5192899e+01, 2.6233368e+00); + expectedForces[8] = Vec3( 4.3698604e+00, -7.0550315e+00, 3.4204565e-01); + expectedForces[9] = Vec3( -3.0082825e+00, 1.3575082e+00, 6.6901032e+00); + expectedForces[10] = Vec3( 9.1775539e-01, -1.4651882e+00, -3.3322516e+00); + expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00); double tolerance = 1.0e-03; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // check validation of traceless/symmetric quadrupole tensor -static void testQuadrupoleValidation( FILE* log ){ +static void testQuadrupoleValidation(FILE* log) { std::string testName = "checkQuadrupoleValidation"; @@ -742,29 +742,29 @@ static void testQuadrupoleValidation( FILE* log ){ System system; double boxDimension = 1.8643; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; std::vector expectedForces(numberOfParticles); - amoebaMultipoleForce->setNonbondedMethod( AmoebaMultipoleForce::PME ); - amoebaMultipoleForce->setPolarizationType( AmoebaMultipoleForce::Direct ); - amoebaMultipoleForce->setCutoffDistance( 0.7 ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); - - std::vector pmeGridDimensions( 3 ); + amoebaMultipoleForce->setNonbondedMethod(AmoebaMultipoleForce::PME); + amoebaMultipoleForce->setPolarizationType(AmoebaMultipoleForce::Direct); + amoebaMultipoleForce->setCutoffDistance(0.7); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); + + std::vector pmeGridDimensions(3); pmeGridDimensions[0] = pmeGridDimensions[1] = pmeGridDimensions[2] = pmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimensions ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimensions); - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5995000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5995000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -800,36 +800,36 @@ static void testQuadrupoleValidation( FILE* log ){ hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } std::vector positions(numberOfParticles); - positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03 ); - positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02 ); - positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01 ); - positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01 ); - positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01 ); - positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01 ); - positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01 ); - positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01 ); - positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01 ); - positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01 ); - positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01 ); - positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01 ); + positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03); + positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02); + positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01); + positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); + positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); + positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); + positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); + positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); + positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); + positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); + positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); + positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); system.addForce(amoebaMultipoleForce); std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); @@ -837,8 +837,8 @@ static void testQuadrupoleValidation( FILE* log ){ try { oxygenMolecularQuadrupole[4] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -854,8 +854,8 @@ static void testQuadrupoleValidation( FILE* log ){ try { oxygenMolecularQuadrupole[1] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -869,8 +869,8 @@ static void testQuadrupoleValidation( FILE* log ){ try { oxygenMolecularQuadrupole[2] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -884,8 +884,8 @@ static void testQuadrupoleValidation( FILE* log ){ try { oxygenMolecularQuadrupole[5] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -902,10 +902,10 @@ static void testQuadrupoleValidation( FILE* log ){ // this method does too much; I tried passing the context ptr back to // the tests methods, but the tests would seg fault w/ a bad_alloc error -static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, - AmoebaMultipoleForce::PolarizationType polarizationType, - double cutoff, int inputPmeGridDimension, std::string testName, - std::vector& forces, double& energy, FILE* log ){ +static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, + AmoebaMultipoleForce::PolarizationType polarizationType, + double cutoff, int inputPmeGridDimension, std::string testName, + std::vector& forces, double& energy, FILE* log) { // beginning of Multipole setup @@ -914,10 +914,10 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: // box dimensions double boxDimensions[3] = { 6.7538, 7.2977, 7.4897 }; - Vec3 a( boxDimensions[0], 0.0, 0.0 ); - Vec3 b( 0.0, boxDimensions[1], 0.0 ); - Vec3 c( 0.0, 0.0, boxDimensions[2] ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimensions[0], 0.0, 0.0); + Vec3 b(0.0, boxDimensions[1], 0.0); + Vec3 c(0.0, 0.0, boxDimensions[2]); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; @@ -925,22 +925,22 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: int numberOfWaters = 2; int numberOfIons = numberOfParticles - numberOfWaters*3; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-05 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-05); - std::vector pmeGridDimension( 3 ); + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); // 2 ions - system.addParticle( 3.5453000e+01 ); - system.addParticle( 2.2990000e+01 ); + system.addParticle(3.5453000e+01 ); + system.addParticle(2.2990000e+01); std::vector ionDipole(3); std::vector ionQuadrupole(9); @@ -958,15 +958,15 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: ionQuadrupole[6] = 0.0000000e+00; ionQuadrupole[7] = 0.0000000e+00; ionQuadrupole[8] = 0.0000000e+00; - amoebaMultipoleForce->addMultipole( -1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 3.9842202e-01, 4.00e-03 ); - amoebaMultipoleForce->addMultipole( 1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 2.2209062e-01, 1.20e-04 ); + amoebaMultipoleForce->addMultipole( -1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 3.9842202e-01, 4.00e-03); + amoebaMultipoleForce->addMultipole( 1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 2.2209062e-01, 1.20e-04); // waters - for( unsigned int jj = 2; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5999000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5999000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -1002,72 +1002,72 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 2; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps std::vector< int > covalentMap; covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(4), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(0, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(4), covalentMap ); + covalentMap.push_back(1); + amoebaMultipoleForce->setCovalentMap(1, static_cast(4), covalentMap); - for( unsigned int jj = 2; jj < numberOfParticles; jj += 3 ){ + for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(0), covalentMap ); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(4), covalentMap ); + covalentMap.push_back(jj); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(0), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(0), covalentMap ); + covalentMap.push_back(jj); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(0), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(1), covalentMap ); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); + covalentMap.push_back(jj+1); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(1), covalentMap); } std::vector positions(numberOfParticles); - positions[0] = Vec3( -1.4364000e+00, -1.2848000e+00, 5.1940000e-01 ); - positions[1] = Vec3( -3.2644000e+00, 2.3620000e+00, 1.3643000e+00 ); - positions[2] = Vec3( -2.3780000e+00, 1.8976000e+00, -1.5921000e+00 ); - positions[3] = Vec3( -2.3485183e+00, 1.8296632e+00, -1.5310146e+00 ); - positions[4] = Vec3( -2.3784362e+00, 1.8623910e+00, -1.6814092e+00 ); - positions[5] = Vec3( -2.1821000e+00, -1.0808000e+00, 2.9547000e+00 ); - positions[6] = Vec3( -2.1198155e+00, -1.0925202e+00, 2.8825940e+00 ); - positions[7] = Vec3( -2.1537255e+00, -1.0076218e+00, 3.0099797e+00 ); + positions[0] = Vec3( -1.4364000e+00, -1.2848000e+00, 5.1940000e-01); + positions[1] = Vec3( -3.2644000e+00, 2.3620000e+00, 1.3643000e+00); + positions[2] = Vec3( -2.3780000e+00, 1.8976000e+00, -1.5921000e+00); + positions[3] = Vec3( -2.3485183e+00, 1.8296632e+00, -1.5310146e+00); + positions[4] = Vec3( -2.3784362e+00, 1.8623910e+00, -1.6814092e+00); + positions[5] = Vec3( -2.1821000e+00, -1.0808000e+00, 2.9547000e+00); + positions[6] = Vec3( -2.1198155e+00, -1.0925202e+00, 2.8825940e+00); + positions[7] = Vec3( -2.1537255e+00, -1.0076218e+00, 3.0099797e+00); system.addForce(amoebaMultipoleForce); std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context = Context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context = Context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); @@ -1081,7 +1081,7 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEDirectPolarization( FILE* log ) { +static void testMultipoleIonsAndWaterPMEDirectPolarization(FILE* log) { std::string testName = "testMultipoleIonsAndWaterDirectPolarization"; @@ -1092,30 +1092,30 @@ static void testMultipoleIonsAndWaterPMEDirectPolarization( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, testName, forces, energy, log ); + setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, + cutoff, inputPmeGridDimension, testName, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = -4.6859568e+01; - expectedForces[0] = Vec3( -9.1266563e+00, 1.5193632e+01, -4.0047974e+00 ); - expectedForces[1] = Vec3( -1.0497973e+00, 1.4622548e+01, 1.1789324e+01 ); - expectedForces[2] = Vec3( -3.2564644e+00, 6.5325105e+00, -2.9698616e+00 ); - expectedForces[3] = Vec3( 3.0687040e+00, -8.4253665e-01, -3.4081010e+00 ); - expectedForces[4] = Vec3( 1.1407201e+00, -3.1491550e+00, -1.1326031e+00 ); - expectedForces[5] = Vec3( -6.1046529e+00, 9.5686061e-01, 1.1506333e-01 ); - expectedForces[6] = Vec3( 1.9275403e+00, -5.6007439e-01, -4.8387346e+00 ); - expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00 ); + expectedForces[0] = Vec3( -9.1266563e+00, 1.5193632e+01, -4.0047974e+00); + expectedForces[1] = Vec3( -1.0497973e+00, 1.4622548e+01, 1.1789324e+01); + expectedForces[2] = Vec3( -3.2564644e+00, 6.5325105e+00, -2.9698616e+00); + expectedForces[3] = Vec3( 3.0687040e+00, -8.4253665e-01, -3.4081010e+00); + expectedForces[4] = Vec3( 1.1407201e+00, -3.1491550e+00, -1.1326031e+00); + expectedForces[5] = Vec3( -6.1046529e+00, 9.5686061e-01, 1.1506333e-01); + expectedForces[6] = Vec3( 1.9275403e+00, -5.6007439e-01, -4.8387346e+00); + expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00); double tolerance = 5.0e-04; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEMutualPolarization( FILE* log ) { +static void testMultipoleIonsAndWaterPMEMutualPolarization(FILE* log) { std::string testName = "testMultipoleIonsAndWaterMutualPolarization"; @@ -1128,38 +1128,38 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization( FILE* log ) { std::vector inputGrid; - setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, forces, energy, log ); + setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, testName, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = -4.6859424e+01; - expectedForces[0] = Vec3( -9.1272358e+00, 1.5191516e+01, -4.0058826e+00 ); - expectedForces[1] = Vec3( -1.0497156e+00, 1.4622425e+01, 1.1789420e+01 ); - expectedForces[2] = Vec3( -3.2560478e+00, 6.5289712e+00, -2.9779483e+00 ); - expectedForces[3] = Vec3( 3.0672153e+00, -8.4407797e-01, -3.4094884e+00 ); - expectedForces[4] = Vec3( 1.1382586e+00, -3.1512949e+00, -1.1387028e+00 ); - expectedForces[5] = Vec3( -6.1050295e+00, 9.5345692e-01, 1.1488832e-01 ); - expectedForces[6] = Vec3( 1.9319945e+00, -5.5747599e-01, -4.8469044e+00 ); - expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00 ); + expectedForces[0] = Vec3( -9.1272358e+00, 1.5191516e+01, -4.0058826e+00); + expectedForces[1] = Vec3( -1.0497156e+00, 1.4622425e+01, 1.1789420e+01); + expectedForces[2] = Vec3( -3.2560478e+00, 6.5289712e+00, -2.9779483e+00); + expectedForces[3] = Vec3( 3.0672153e+00, -8.4407797e-01, -3.4094884e+00); + expectedForces[4] = Vec3( 1.1382586e+00, -3.1512949e+00, -1.1387028e+00); + expectedForces[5] = Vec3( -6.1050295e+00, 9.5345692e-01, 1.1488832e-01); + expectedForces[6] = Vec3( 1.9319945e+00, -5.5747599e-01, -4.8469044e+00); + expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00); //double tolerance = 1.0e-03; - //compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + //compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); double tolerance = 5.0e-04; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // setup for box of 216 water molecules -- used to test PME -static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, - AmoebaMultipoleForce::PolarizationType polarizationType, - double cutoff, int inputPmeGridDimension, std::string& testName, - std::vector& forces, double& energy, - std::vector< double >& outputMultipoleMoments, - std::vector< Vec3 >& inputGrid, - std::vector< double >& outputGridPotential, FILE* log ){ +static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, + AmoebaMultipoleForce::PolarizationType polarizationType, + double cutoff, int inputPmeGridDimension, std::string& testName, + std::vector& forces, double& energy, + std::vector< double >& outputMultipoleMoments, + std::vector< Vec3 >& inputGrid, + std::vector< double >& outputGridPotential, FILE* log) { // beginning of Multipole setup @@ -1168,29 +1168,29 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No // box dimensions double boxDimension = 1.8643; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 648; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); - - std::vector pmeGridDimension( 3 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); + + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5995000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5995000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -1226,44 +1226,44 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps std::vector< int > covalentMap; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(0), covalentMap ); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(4), covalentMap ); + covalentMap.push_back(jj); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(0), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(0), covalentMap ); + covalentMap.push_back(jj); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(0), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(1), covalentMap ); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); + covalentMap.push_back(jj+1); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(1), covalentMap); } system.addForce(amoebaMultipoleForce); @@ -1271,667 +1271,667 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No static std::vector positions; // Static to work around bug in Visual Studio that makes compilation very very slow. positions.resize(numberOfParticles); - positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02 ); - positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02 ); - positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02 ); - positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01 ); - positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01 ); - positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01 ); - positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01 ); - positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01 ); - positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01 ); - positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01 ); - positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01 ); - positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01 ); - positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01 ); - positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01 ); - positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01 ); - positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01 ); - positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01 ); - positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01 ); - positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01 ); - positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01 ); - positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01 ); - positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01 ); - positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01 ); - positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01 ); - positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01 ); - positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01 ); - positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02 ); - positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02 ); - positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01 ); - positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01 ); - positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01 ); - positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01 ); - positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01 ); - positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01 ); - positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01 ); - positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01 ); - positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01 ); - positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01 ); - positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01 ); - positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01 ); - positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01 ); - positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01 ); - positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01 ); - positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01 ); - positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01 ); - positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01 ); - positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01 ); - positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01 ); - positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01 ); - positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01 ); - positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01 ); - positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01 ); - positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01 ); - positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01 ); - positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01 ); - positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01 ); - positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01 ); - positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01 ); - positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01 ); - positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01 ); - positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01 ); - positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01 ); - positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01 ); - positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02 ); - positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02 ); - positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01 ); - positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02 ); - positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02 ); - positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01 ); - positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01 ); - positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01 ); - positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01 ); - positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01 ); - positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01 ); - positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01 ); - positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01 ); - positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02 ); - positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01 ); - positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01 ); - positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01 ); - positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01 ); - positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02 ); - positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01 ); - positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02 ); - positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01 ); - positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01 ); - positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01 ); - positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01 ); - positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01 ); - positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01 ); - positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01 ); - positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01 ); - positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01 ); - positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01 ); - positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01 ); - positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01 ); - positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01 ); - positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01 ); - positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01 ); - positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01 ); - positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01 ); - positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01 ); - positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01 ); - positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01 ); - positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01 ); - positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01 ); - positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01 ); - positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01 ); - positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01 ); - positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01 ); - positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01 ); - positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02 ); - positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02 ); - positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01 ); - positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01 ); - positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01 ); - positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01 ); - positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01 ); - positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01 ); - positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01 ); - positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01 ); - positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01 ); - positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01 ); - positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01 ); - positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02 ); - positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01 ); - positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01 ); - positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01 ); - positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01 ); - positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01 ); - positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01 ); - positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01 ); - positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01 ); - positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01 ); - positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01 ); - positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01 ); - positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01 ); - positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01 ); - positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01 ); - positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01 ); - positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01 ); - positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01 ); - positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01 ); - positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01 ); - positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01 ); - positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01 ); - positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01 ); - positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01 ); - positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01 ); - positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01 ); - positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01 ); - positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01 ); - positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01 ); - positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01 ); - positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01 ); - positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01 ); - positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02 ); - positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02 ); - positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02 ); - positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01 ); - positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02 ); - positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02 ); - positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01 ); - positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01 ); - positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01 ); - positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01 ); - positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01 ); - positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01 ); - positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01 ); - positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01 ); - positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01 ); - positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01 ); - positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01 ); - positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01 ); - positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01 ); - positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01 ); - positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01 ); - positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01 ); - positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01 ); - positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01 ); - positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01 ); - positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01 ); - positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01 ); - positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01 ); - positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01 ); - positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01 ); - positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02 ); - positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01 ); - positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03 ); - positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01 ); - positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01 ); - positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01 ); - positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01 ); - positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01 ); - positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01 ); - positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01 ); - positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01 ); - positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01 ); - positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01 ); - positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01 ); - positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01 ); - positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02 ); - positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01 ); - positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02 ); - positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01 ); - positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01 ); - positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01 ); - positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01 ); - positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01 ); - positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01 ); - positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01 ); - positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01 ); - positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01 ); - positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01 ); - positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01 ); - positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01 ); - positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01 ); - positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01 ); - positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01 ); - positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01 ); - positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01 ); - positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01 ); - positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01 ); - positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01 ); - positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01 ); - positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02 ); - positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01 ); - positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02 ); - positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01 ); - positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01 ); - positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01 ); - positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01 ); - positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01 ); - positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01 ); - positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01 ); - positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01 ); - positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01 ); - positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01 ); - positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01 ); - positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01 ); - positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01 ); - positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01 ); - positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01 ); - positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02 ); - positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01 ); - positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02 ); - positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01 ); - positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01 ); - positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01 ); - positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01 ); - positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01 ); - positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01 ); - positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01 ); - positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01 ); - positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01 ); - positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01 ); - positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01 ); - positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01 ); - positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01 ); - positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01 ); - positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01 ); - positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01 ); - positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01 ); - positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01 ); - positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03 ); - positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03 ); - positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02 ); - positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01 ); - positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01 ); - positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01 ); - positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01 ); - positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01 ); - positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01 ); - positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01 ); - positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01 ); - positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01 ); - positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01 ); - positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01 ); - positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01 ); - positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01 ); - positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01 ); - positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01 ); - positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01 ); - positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01 ); - positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01 ); - positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01 ); - positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01 ); - positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01 ); - positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02 ); - positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01 ); - positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02 ); - positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01 ); - positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01 ); - positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01 ); - positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01 ); - positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02 ); - positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02 ); - positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01 ); - positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01 ); - positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01 ); - positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01 ); - positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01 ); - positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01 ); - positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01 ); - positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01 ); - positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01 ); - positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01 ); - positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01 ); - positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01 ); - positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01 ); - positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01 ); - positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01 ); - positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01 ); - positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01 ); - positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01 ); - positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02 ); - positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01 ); - positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02 ); - positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01 ); - positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01 ); - positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01 ); - positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01 ); - positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01 ); - positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01 ); - positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01 ); - positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01 ); - positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01 ); - positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02 ); - positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02 ); - positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02 ); - positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01 ); - positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01 ); - positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01 ); - positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01 ); - positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01 ); - positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01 ); - positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01 ); - positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01 ); - positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01 ); - positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01 ); - positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01 ); - positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01 ); - positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02 ); - positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02 ); - positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02 ); - positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01 ); - positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01 ); - positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01 ); - positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01 ); - positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01 ); - positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01 ); - positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01 ); - positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01 ); - positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01 ); - positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01 ); - positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01 ); - positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01 ); - positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01 ); - positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01 ); - positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01 ); - positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01 ); - positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01 ); - positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01 ); - positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01 ); - positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02 ); - positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01 ); - positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01 ); - positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02 ); - positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01 ); - positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01 ); - positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01 ); - positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01 ); - positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01 ); - positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01 ); - positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01 ); - positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01 ); - positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01 ); - positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01 ); - positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02 ); - positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02 ); - positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02 ); - positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01 ); - positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01 ); - positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01 ); - positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01 ); - positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01 ); - positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01 ); - positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01 ); - positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01 ); - positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01 ); - positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01 ); - positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01 ); - positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01 ); - positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01 ); - positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01 ); - positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01 ); - positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01 ); - positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01 ); - positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01 ); - positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01 ); - positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01 ); - positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01 ); - positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01 ); - positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01 ); - positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01 ); - positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02 ); - positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01 ); - positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03 ); - positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01 ); - positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01 ); - positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01 ); - positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01 ); - positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01 ); - positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01 ); - positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03 ); - positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02 ); - positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03 ); - positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01 ); - positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01 ); - positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01 ); - positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01 ); - positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01 ); - positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01 ); - positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01 ); - positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01 ); - positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01 ); - positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01 ); - positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01 ); - positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01 ); - positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01 ); - positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01 ); - positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01 ); - positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01 ); - positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01 ); - positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01 ); - positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01 ); - positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01 ); - positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01 ); - positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01 ); - positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01 ); - positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01 ); - positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02 ); - positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02 ); - positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01 ); - positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01 ); - positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01 ); - positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01 ); - positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01 ); - positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01 ); - positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01 ); - positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01 ); - positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01 ); - positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01 ); - positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01 ); - positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01 ); - positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01 ); - positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01 ); - positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01 ); - positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01 ); - positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01 ); - positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01 ); - positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01 ); - positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01 ); - positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01 ); - positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01 ); - positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01 ); - positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01 ); - positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01 ); - positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01 ); - positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01 ); - positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01 ); - positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02 ); - positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03 ); - positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01 ); - positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01 ); - positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01 ); - positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01 ); - positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01 ); - positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01 ); - positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01 ); - positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01 ); - positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01 ); - positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01 ); - positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01 ); - positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01 ); - positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02 ); - positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01 ); - positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01 ); - positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01 ); - positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01 ); - positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01 ); - positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01 ); - positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01 ); - positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01 ); - positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01 ); - positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01 ); - positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01 ); - positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01 ); - positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01 ); - positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01 ); - positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01 ); - positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01 ); - positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01 ); - positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01 ); - positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01 ); - positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01 ); - positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01 ); - positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01 ); - positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01 ); - positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01 ); - positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01 ); - positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01 ); - positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01 ); - positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01 ); - positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01 ); - positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01 ); - positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01 ); - positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01 ); - positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01 ); - positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01 ); - positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01 ); - positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01 ); - positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01 ); - positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01 ); - positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01 ); - positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01 ); - positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01 ); - positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01 ); - positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01 ); - positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01 ); - positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01 ); - positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01 ); - positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01 ); - positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01 ); - positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01 ); - positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01 ); - positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01 ); - positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01 ); - positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01 ); - positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01 ); - positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01 ); - positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01 ); - positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01 ); - positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01 ); - positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01 ); - positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01 ); - positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01 ); - positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01 ); - positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01 ); - positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01 ); - positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01 ); - positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01 ); - positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02 ); - positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01 ); - positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02 ); - positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01 ); - positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01 ); - positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02 ); - positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02 ); - positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02 ); - positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02 ); - positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01 ); - positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01 ); - positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01 ); - positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01 ); - positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02 ); - positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02 ); - positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01 ); - positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01 ); - positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01 ); - positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01 ); - positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01 ); - positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01 ); - positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01 ); - positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01 ); - positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01 ); - positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02 ); - positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02 ); - positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02 ); - positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02 ); - positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02 ); - positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01 ); - positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01 ); - positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01 ); - positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01 ); - positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01 ); - positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01 ); - positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01 ); - positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01 ); - positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01 ); - positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01 ); - positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01 ); - positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01 ); - positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01 ); - positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01 ); - positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01 ); - positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01 ); - positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01 ); - positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01 ); - positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01 ); - positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01 ); - positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01 ); - positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01 ); - positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01 ); - positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01 ); - positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01 ); - positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01 ); - positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01 ); - positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01 ); - positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01 ); - positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01 ); - positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01 ); - positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01 ); - positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01 ); - positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01 ); - positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01 ); - positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01 ); - positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01 ); - positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01 ); - positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01 ); - positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01 ); - positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01 ); - positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01 ); - positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01 ); - positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01 ); - positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01 ); - positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01 ); - positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01 ); - positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01 ); - positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01 ); - positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01 ); - positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01 ); - positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01 ); - positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01 ); - positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01 ); - positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01 ); - positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01 ); - positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01 ); - positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01 ); - positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01 ); - positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01 ); - positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01 ); - positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01 ); - positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01 ); - positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01 ); - positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01 ); - positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01 ); - positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01 ); + positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); + positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); + positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); + positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); + positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); + positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); + positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01); + positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01); + positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01); + positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); + positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); + positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); + positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); + positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); + positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); + positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01); + positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01); + positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01); + positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01); + positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01); + positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01); + positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01); + positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01); + positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); + positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01); + positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01); + positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02); + positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02); + positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01); + positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01); + positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); + positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); + positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); + positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); + positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01); + positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); + positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); + positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); + positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01); + positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); + positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); + positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); + positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); + positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); + positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); + positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); + positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); + positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); + positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01); + positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01); + positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01); + positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01); + positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01); + positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01); + positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); + positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); + positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); + positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01); + positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01); + positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01); + positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); + positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); + positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); + positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02); + positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02); + positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01); + positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02); + positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02); + positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01); + positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01); + positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01); + positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01); + positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); + positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); + positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); + positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01); + positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02); + positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01); + positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); + positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); + positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); + positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); + positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); + positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); + positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01); + positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); + positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); + positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); + positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); + positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); + positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); + positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); + positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); + positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01); + positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01); + positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01); + positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); + positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); + positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); + positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); + positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); + positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); + positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01); + positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01); + positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01); + positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); + positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); + positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); + positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); + positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); + positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); + positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); + positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); + positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); + positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01); + positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01); + positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01); + positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01); + positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01); + positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01); + positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); + positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); + positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); + positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01); + positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02); + positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01); + positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01); + positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01); + positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01); + positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); + positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); + positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); + positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01); + positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01); + positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01); + positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01); + positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01); + positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01); + positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01); + positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01); + positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01); + positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); + positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); + positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); + positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); + positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); + positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); + positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); + positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); + positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); + positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01); + positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01); + positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01); + positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01); + positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01); + positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01); + positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02); + positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02); + positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); + positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); + positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); + positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); + positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); + positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); + positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); + positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); + positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); + positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); + positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); + positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01); + positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); + positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01); + positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01); + positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01); + positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); + positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); + positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); + positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01); + positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01); + positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01); + positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); + positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); + positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); + positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01); + positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01); + positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01); + positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02); + positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01); + positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03); + positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01); + positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01); + positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01); + positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); + positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); + positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); + positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); + positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01); + positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); + positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01); + positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01); + positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01); + positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); + positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); + positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); + positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); + positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); + positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); + positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01); + positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01); + positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01); + positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); + positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); + positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); + positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01); + positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01); + positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01); + positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); + positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); + positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); + positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); + positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01); + positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01); + positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); + positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); + positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); + positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); + positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); + positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); + positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01); + positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01); + positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01); + positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01); + positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01); + positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01); + positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); + positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); + positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); + positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01); + positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01); + positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01); + positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01); + positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01); + positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01); + positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); + positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); + positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); + positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01); + positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01); + positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01); + positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); + positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); + positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); + positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); + positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); + positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); + positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01); + positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01); + positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); + positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01); + positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01); + positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01); + positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01); + positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01); + positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01); + positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); + positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); + positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); + positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01); + positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01); + positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01); + positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); + positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); + positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); + positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); + positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); + positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); + positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); + positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); + positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); + positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01); + positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01); + positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01); + positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01); + positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01); + positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01); + positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01); + positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01); + positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01); + positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02); + positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01); + positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02); + positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01); + positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01); + positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01); + positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); + positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); + positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); + positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01); + positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); + positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01); + positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01); + positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01); + positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01); + positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01); + positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01); + positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01); + positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); + positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); + positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); + positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); + positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); + positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); + positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01); + positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01); + positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01); + positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02); + positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01); + positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02); + positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); + positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); + positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); + positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01); + positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01); + positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01); + positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01); + positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01); + positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01); + positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02); + positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02); + positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02); + positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01); + positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01); + positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01); + positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01); + positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01); + positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01); + positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01); + positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01); + positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01); + positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); + positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); + positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); + positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); + positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); + positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); + positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01); + positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01); + positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01); + positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); + positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); + positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); + positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01); + positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01); + positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01); + positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); + positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); + positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); + positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); + positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); + positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); + positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01); + positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01); + positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01); + positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01); + positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02); + positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01); + positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01); + positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02); + positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01); + positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01); + positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01); + positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01); + positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01); + positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01); + positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01); + positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); + positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); + positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); + positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); + positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); + positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); + positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); + positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); + positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); + positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); + positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); + positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); + positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01); + positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01); + positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01); + positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01); + positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01); + positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01); + positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); + positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); + positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); + positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01); + positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01); + positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01); + positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); + positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); + positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); + positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); + positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); + positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); + positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); + positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); + positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); + positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); + positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); + positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01); + positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); + positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); + positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); + positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); + positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); + positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); + positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01); + positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01); + positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01); + positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); + positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); + positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); + positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01); + positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01); + positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01); + positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); + positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); + positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); + positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01); + positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01); + positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01); + positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); + positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); + positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); + positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01); + positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01); + positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01); + positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); + positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); + positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); + positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02); + positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); + positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01); + positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); + positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); + positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); + positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); + positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); + positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); + positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01); + positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01); + positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01); + positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01); + positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01); + positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01); + positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); + positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); + positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); + positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01); + positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01); + positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01); + positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01); + positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01); + positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01); + positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01); + positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01); + positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01); + positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); + positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); + positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); + positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); + positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); + positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); + positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); + positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); + positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); + positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); + positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); + positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); + positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01); + positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01); + positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01); + positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01); + positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01); + positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02); + positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01); + positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01); + positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01); + positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); + positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); + positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); + positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01); + positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01); + positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01); + positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01); + positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01); + positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01); + positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01); + positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01); + positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01); + positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01); + positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01); + positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01); + positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01); + positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01); + positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01); + positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); + positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); + positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); + positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); + positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); + positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); + positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01); + positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01); + positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01); + positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01); + positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01); + positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01); + positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); + positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); + positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); + positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); + positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); + positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); + positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); + positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); + positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); + positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); + positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); + positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); + positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); + positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); + positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); + positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); + positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); + positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); + positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); + positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); + positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); + positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); + positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); + positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); + positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01); + positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01); + positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01); + positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01); + positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01); + positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01); + positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01); + positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01); + positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01); + positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); + positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); + positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); + positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01); + positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01); + positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02); + positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02); + positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02); + positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02); + positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01); + positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01); + positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01); + positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); + positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); + positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); + positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01); + positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01); + positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); + positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01); + positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01); + positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01); + positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01); + positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01); + positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01); + positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); + positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02); + positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); + positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02); + positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02); + positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01); + positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01); + positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01); + positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01); + positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); + positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); + positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); + positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); + positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); + positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); + positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01); + positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01); + positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01); + positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01); + positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01); + positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01); + positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01); + positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01); + positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01); + positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); + positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); + positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); + positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01); + positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01); + positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01); + positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); + positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); + positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); + positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); + positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); + positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); + positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01); + positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01); + positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01); + positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); + positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); + positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); + positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01); + positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01); + positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01); + positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01); + positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01); + positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01); + positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); + positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); + positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); + positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); + positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); + positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); + positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01); + positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01); + positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01); + positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); + positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); + positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); + positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); + positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); + positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); + positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01); + positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01); + positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01); + positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); + positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); + positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); + positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01); + positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01); + positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01); std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); - if( testName == "testSystemMultipoleMoments" ){ - amoebaMultipoleForce->getSystemMultipoleMoments( context, outputMultipoleMoments ); + if (testName == "testSystemMultipoleMoments") { + amoebaMultipoleForce->getSystemMultipoleMoments(context, outputMultipoleMoments); } - else if( testName == "testMultipoleGridPotential" ){ - amoebaMultipoleForce->getElectrostaticPotential( inputGrid, context, outputGridPotential ); + else if (testName == "testMultipoleGridPotential") { + amoebaMultipoleForce->getElectrostaticPotential(inputGrid, context, outputGridPotential); } else { @@ -1945,7 +1945,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No // test multipole mutual polarization using PME for box of water -static void testPMEMutualPolarizationLargeWater( FILE* log ) { +static void testPMEMutualPolarizationLargeWater(FILE* log) { std::string testName = "testPMEMutualPolarizationLargeWater"; @@ -1958,665 +1958,665 @@ static void testPMEMutualPolarizationLargeWater( FILE* log ) { std::vector< Vec3 > inputGrid; std::vector< double > outputGridPotential; - setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log ); + setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, testName, + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log); static std::vector expectedForces; // Static to work around bug in Visual Studio that makes compilation very very slow. expectedForces.resize(numberOfParticles); double expectedEnergy = -1.3268930e+04; - expectedForces[0] = Vec3( -5.2764003e+02, 6.5154502e+02, 7.8683284e+02 ); - expectedForces[1] = Vec3( 3.3391292e+02, -1.1162521e+03, -2.9173021e+02 ); - expectedForces[2] = Vec3( 9.4613310e+01, -5.8988099e+01, -6.2871010e+02 ); - expectedForces[3] = Vec3( -1.6179658e+03, 1.8222798e+02, -1.0373083e+02 ); - expectedForces[4] = Vec3( 1.0177962e+03, 1.7118957e+02, 4.0084976e+02 ); - expectedForces[5] = Vec3( 3.0582540e+02, -5.5215191e+02, 4.8287747e+01 ); - expectedForces[6] = Vec3( -5.4931641e+01, -6.7689368e+02, -1.2260977e+03 ); - expectedForces[7] = Vec3( -2.9961754e+02, 1.3602079e+03, -2.2087612e+02 ); - expectedForces[8] = Vec3( -3.1788045e+02, -1.3540025e+02, 1.1250958e+03 ); - expectedForces[9] = Vec3( 1.0275111e+03, 1.9279625e+02, -6.0872252e+02 ); - expectedForces[10] = Vec3( -5.7512410e+02, -5.6280482e+01, 7.5039261e+02 ); - expectedForces[11] = Vec3( -4.7291981e+02, -3.5875411e+01, 5.2335135e+00 ); - expectedForces[12] = Vec3( -1.5619899e+02, -1.3743370e+02, 1.3587339e+03 ); - expectedForces[13] = Vec3( -4.7423876e+02, 1.0032873e+02, -2.0875847e+02 ); - expectedForces[14] = Vec3( 7.5621178e+02, 3.7979419e+01, -4.1221012e+02 ); - expectedForces[15] = Vec3( 6.7318876e+02, 4.9937148e+02, 1.1665351e+03 ); - expectedForces[16] = Vec3( -7.0858091e+01, 8.4758233e+01, -1.3126942e+03 ); - expectedForces[17] = Vec3( -1.0636296e+03, -1.6254851e+02, -1.0982809e+02 ); - expectedForces[18] = Vec3( -1.0249489e+03, 6.7073895e+02, -2.0754278e+02 ); - expectedForces[19] = Vec3( 5.6396078e+02, -1.1702137e+03, 1.5324295e+02 ); - expectedForces[20] = Vec3( 6.1635144e+02, 5.6122242e+02, -7.9410893e+01 ); - expectedForces[21] = Vec3( -1.5785582e+02, -1.0857764e+03, -1.1010131e+03 ); - expectedForces[22] = Vec3( 2.3733181e+01, 2.0158373e+02, 3.2583783e+02 ); - expectedForces[23] = Vec3( 1.8855396e+02, 1.2408889e+03, 4.5759149e+02 ); - expectedForces[24] = Vec3( 9.3643408e+02, -6.1331107e+01, -3.8601431e+02 ); - expectedForces[25] = Vec3( -3.1972504e+02, -1.5783340e+02, -1.3838003e+02 ); - expectedForces[26] = Vec3( -5.1178039e+02, -2.5998898e+02, 6.1021975e+02 ); - expectedForces[27] = Vec3( 9.1836250e+02, -4.3288112e+02, -9.5579501e+02 ); - expectedForces[28] = Vec3( -9.3325184e+02, 6.2859013e+01, 5.0743198e+02 ); - expectedForces[29] = Vec3( 3.1839963e+02, 5.4102155e+02, 1.1261345e+03 ); - expectedForces[30] = Vec3( 7.3842640e+02, 1.0907054e+02, -2.1126612e+02 ); - expectedForces[31] = Vec3( -1.8470175e+02, -4.0377182e+01, 1.2464073e+02 ); - expectedForces[32] = Vec3( -5.8931386e+02, -3.5021489e+02, -7.2769901e+01 ); - expectedForces[33] = Vec3( 1.4804452e+02, -1.2138869e+02, -1.2423820e+03 ); - expectedForces[34] = Vec3( -2.4850935e+02, 2.3113218e+01, 1.4041979e+02 ); - expectedForces[35] = Vec3( 1.3188525e+02, -6.1243481e+02, 6.4886373e+02 ); - expectedForces[36] = Vec3( 5.0217683e+02, 9.2857480e+02, -7.2500648e+02 ); - expectedForces[37] = Vec3( 9.9446320e+01, -3.0337270e+02, 8.0439741e+02 ); - expectedForces[38] = Vec3( -1.7167491e+02, -9.3911948e+02, 5.6412500e+01 ); - expectedForces[39] = Vec3( -6.6143649e+02, 1.0876882e+03, 3.3801466e+02 ); - expectedForces[40] = Vec3( 5.6748150e+02, -2.2459572e+02, 3.8360728e+02 ); - expectedForces[41] = Vec3( 7.7688834e+02, -6.7341171e+02, -6.4292796e+02 ); - expectedForces[42] = Vec3( 1.0253263e+02, -1.3212797e+03, 9.3279892e+02 ); - expectedForces[43] = Vec3( 1.5424247e+02, -1.0197346e+01, -8.0230728e+02 ); - expectedForces[44] = Vec3( -6.6499384e+02, 1.2534353e+03, -1.6748341e+02 ); - expectedForces[45] = Vec3( -1.9282945e+02, 5.1764789e+02, 1.5108154e+03 ); - expectedForces[46] = Vec3( -4.9204245e+02, 8.8664089e+02, -8.8381078e+02 ); - expectedForces[47] = Vec3( 1.3207641e+01, -5.7765859e+02, -3.5921690e+02 ); - expectedForces[48] = Vec3( 4.1691955e+02, -1.1292452e+03, -6.2339128e+02 ); - expectedForces[49] = Vec3( 4.8613761e+02, 6.8325845e+02, 2.3424652e+02 ); - expectedForces[50] = Vec3( 3.1827501e+01, 6.8442319e+02, -5.8685438e+02 ); - expectedForces[51] = Vec3( 1.1834790e+03, -1.3418299e+03, 5.6280882e+02 ); - expectedForces[52] = Vec3( -5.8629616e+02, -6.9100489e+01, -9.7784543e+02 ); - expectedForces[53] = Vec3( -4.0294748e+02, 5.0669032e+02, 5.3893512e+02 ); - expectedForces[54] = Vec3( 6.3555947e+01, -9.0345643e+02, 7.2235587e+02 ); - expectedForces[55] = Vec3( 4.9353706e+02, 4.3952680e+02, -1.5413911e+02 ); - expectedForces[56] = Vec3( -3.4663273e+02, 8.4708544e+02, -8.8983178e+01 ); - expectedForces[57] = Vec3( 1.5746383e+03, 5.8209931e+02, 3.6645765e+02 ); - expectedForces[58] = Vec3( -4.0076588e+02, -1.2311235e+02, -1.6226002e+02 ); - expectedForces[59] = Vec3( -3.3837369e+02, -5.3890252e+02, -5.5997831e+02 ); - expectedForces[60] = Vec3( 8.6512912e+02, -1.0775827e+03, -3.6920406e+02 ); - expectedForces[61] = Vec3( 1.0588621e+01, 4.4531974e+02, 1.1838800e+02 ); - expectedForces[62] = Vec3( -7.0505255e+02, 1.5737739e+02, 3.0134165e+02 ); - expectedForces[63] = Vec3( -1.2833932e+03, 5.1206074e+02, -9.3423828e+01 ); - expectedForces[64] = Vec3( 2.0863538e+02, -6.7108922e+02, 3.5777952e+02 ); - expectedForces[65] = Vec3( 4.9710436e+02, -6.8550896e+01, -2.7502680e+02 ); - expectedForces[66] = Vec3( 4.0388289e+02, 1.0051571e+03, -2.3823633e+02 ); - expectedForces[67] = Vec3( -3.3895858e+02, -6.7577709e+02, 3.1521120e+02 ); - expectedForces[68] = Vec3( -4.8763670e+02, -2.9427128e+02, 2.9500438e+02 ); - expectedForces[69] = Vec3( -8.4080783e+02, -1.7777886e+02, 6.5087880e+02 ); - expectedForces[70] = Vec3( 2.1136356e+02, 6.6812142e+01, -5.5437438e+02 ); - expectedForces[71] = Vec3( -1.3829189e+01, 7.0936421e+02, -5.0847380e+02 ); - expectedForces[72] = Vec3( -1.5684247e+03, 1.6837339e+02, -4.6044105e+02 ); - expectedForces[73] = Vec3( 9.9163605e+02, -4.1397181e+02, -3.9624142e+02 ); - expectedForces[74] = Vec3( 6.7355000e+02, 5.7652252e+02, 1.0565003e+03 ); - expectedForces[75] = Vec3( -1.3722105e+03, -1.4035644e+03, 2.7882380e+02 ); - expectedForces[76] = Vec3( 5.2187588e+02, 3.9602986e+02, -2.2564009e+02 ); - expectedForces[77] = Vec3( 2.6381283e+02, 4.2945748e+02, 1.8339201e+02 ); - expectedForces[78] = Vec3( 5.3099327e+02, 1.7312849e+03, 3.5385638e+01 ); - expectedForces[79] = Vec3( -2.1320977e+02, -1.1795453e+03, -5.1691859e+02 ); - expectedForces[80] = Vec3( -7.1445218e+02, -5.8918750e+02, 7.6494816e+02 ); - expectedForces[81] = Vec3( 1.0849545e+03, 6.5058603e+02, -5.6051049e+02 ); - expectedForces[82] = Vec3( -4.6986151e+02, -3.3868080e+02, 7.9000645e+02 ); - expectedForces[83] = Vec3( -3.8404718e+02, -4.4915037e+02, -4.2069600e+02 ); - expectedForces[84] = Vec3( -3.0678477e+02, -7.2558567e+02, 2.0276275e+02 ); - expectedForces[85] = Vec3( 6.2969625e+01, 3.4257826e+02, -6.8348290e+02 ); - expectedForces[86] = Vec3( 3.1042613e+02, 9.6563445e+01, -1.8788848e+02 ); - expectedForces[87] = Vec3( 2.4427535e+01, 5.8460648e+02, -1.3720684e+03 ); - expectedForces[88] = Vec3( -4.9904469e+02, -9.1309605e+02, 1.4350031e+02 ); - expectedForces[89] = Vec3( -4.0910847e+01, 5.2845046e+01, 2.7341591e+02 ); - expectedForces[90] = Vec3( -4.5190765e+02, 2.2820859e+02, -1.1052181e+03 ); - expectedForces[91] = Vec3( 9.1626336e+01, -1.0496400e+03, 1.0216011e+02 ); - expectedForces[92] = Vec3( -1.2592678e+02, -4.4050520e+01, 1.0764584e+03 ); - expectedForces[93] = Vec3( 8.4216135e+02, 1.7603150e+02, 1.3698861e+03 ); - expectedForces[94] = Vec3( 1.2583734e+02, 3.4343971e+02, -7.3070182e+02 ); - expectedForces[95] = Vec3( -4.5597370e+02, -6.8170738e+02, -5.2258658e+02 ); - expectedForces[96] = Vec3( 1.3295639e+03, 2.5031118e+02, -3.5171095e+02 ); - expectedForces[97] = Vec3( -2.0136001e+02, -2.2978012e+02, 2.1122610e+02 ); - expectedForces[98] = Vec3( -1.1279722e+03, -9.9794730e+02, -1.1321006e+02 ); - expectedForces[99] = Vec3( 2.9553179e+02, -2.0727600e+02, -1.8912317e+03 ); - expectedForces[100] = Vec3( -9.3777487e+02, 4.3417972e+02, 5.7436670e+02 ); - expectedForces[101] = Vec3( 3.1120364e+02, -4.3241206e+00, 5.6666340e+02 ); - expectedForces[102] = Vec3( -6.6764840e+02, -2.3563274e+02, 9.9017992e+02 ); - expectedForces[103] = Vec3( 8.2857598e+02, 1.9030059e+02, -2.4295780e+02 ); - expectedForces[104] = Vec3( -2.6709334e+02, 7.3284851e+01, -3.9157038e+02 ); - expectedForces[105] = Vec3( 6.6235629e+02, -8.4502811e+02, -5.3670716e+02 ); - expectedForces[106] = Vec3( 3.8449086e+02, 8.0775263e+02, 5.2003911e+02 ); - expectedForces[107] = Vec3( -3.4338589e+02, 1.7870086e+02, -6.1047615e+01 ); - expectedForces[108] = Vec3( 4.3523975e+02, 2.8776092e+02, -1.5333067e+03 ); - expectedForces[109] = Vec3( 1.9214022e+01, -9.9449061e+01, 3.9153169e+02 ); - expectedForces[110] = Vec3( -7.7525496e+02, 7.7309387e+01, 7.8886699e+02 ); - expectedForces[111] = Vec3( -1.1510224e+03, -2.8207337e+02, 1.4866455e+03 ); - expectedForces[112] = Vec3( 1.1281316e+03, -3.0961130e+02, -1.3894255e+02 ); - expectedForces[113] = Vec3( -2.4829062e+02, 5.9466066e+02, -9.0749265e+02 ); - expectedForces[114] = Vec3( -1.6228531e+02, -4.1281378e+02, -1.4860946e+03 ); - expectedForces[115] = Vec3( -2.9071192e+02, 7.5335271e+02, 6.5205720e+02 ); - expectedForces[116] = Vec3( 3.2042337e+02, -4.0237231e+02, 1.0068554e+03 ); - expectedForces[117] = Vec3( -1.4081272e+03, -5.5227579e+02, 2.8376428e+02 ); - expectedForces[118] = Vec3( 9.6978276e+02, -9.6232683e+02, 2.3399918e+02 ); - expectedForces[119] = Vec3( 2.0781312e+02, 9.0531947e+01, 8.3513783e+01 ); - expectedForces[120] = Vec3( 2.9200105e+02, 1.0746865e+03, -6.0773727e+02 ); - expectedForces[121] = Vec3( -8.7546167e+02, 3.1969683e+02, 8.1033199e+01 ); - expectedForces[122] = Vec3( -5.3422658e+01, -3.8456585e+02, 1.4595003e+02 ); - expectedForces[123] = Vec3( -9.5134908e+01, 8.6818098e+02, -1.3111403e+03 ); - expectedForces[124] = Vec3( -7.2576830e+02, 6.3811172e+01, 7.0993488e+02 ); - expectedForces[125] = Vec3( 5.6200572e+02, -1.0972338e+03, -3.5278717e+02 ); - expectedForces[126] = Vec3( -1.6903718e+02, 2.6804112e+02, -8.9811032e+02 ); - expectedForces[127] = Vec3( 7.0934165e+02, -3.2328700e+02, 1.0037562e+02 ); - expectedForces[128] = Vec3( -2.5937738e+00, -3.3758145e+02, 3.6354335e+02 ); - expectedForces[129] = Vec3( -1.1993601e+03, 1.1618922e+02, -1.1329865e+03 ); - expectedForces[130] = Vec3( 8.3480845e+02, 5.2646427e+02, 9.1816763e+01 ); - expectedForces[131] = Vec3( 1.9407174e+02, 7.3877492e+00, 8.8648162e+02 ); - expectedForces[132] = Vec3( -1.0820540e+03, 2.7482390e+02, -1.4876848e+03 ); - expectedForces[133] = Vec3( 9.5717027e+02, -4.7758356e+02, 4.0692835e+02 ); - expectedForces[134] = Vec3( 2.4979896e+02, 7.1530552e+02, 6.5834243e+02 ); - expectedForces[135] = Vec3( -2.7549874e+02, 1.6613806e+03, -5.0628865e+02 ); - expectedForces[136] = Vec3( -1.5960544e+02, -4.5920421e+02, 9.4068762e+02 ); - expectedForces[137] = Vec3( 6.9764295e+01, -4.4024430e+02, -2.3545402e+02 ); - expectedForces[138] = Vec3( 2.0207569e+03, -2.6846158e+02, 3.3977998e+02 ); - expectedForces[139] = Vec3( -9.9905342e+02, 9.5155462e+02, 8.3259854e+01 ); - expectedForces[140] = Vec3( -8.0836255e+02, -6.3005196e+02, 1.2603525e+02 ); - expectedForces[141] = Vec3( 5.2279913e+02, 1.5356061e+03, -1.4399009e+02 ); - expectedForces[142] = Vec3( -1.3088783e+02, -9.0861449e+02, 9.7040422e+02 ); - expectedForces[143] = Vec3( 2.8006682e+01, -1.1783245e+03, -3.7285390e+02 ); - expectedForces[144] = Vec3( 6.1040927e+01, 2.1747286e+01, 9.0366011e+02 ); - expectedForces[145] = Vec3( 7.0396235e+02, -2.3865001e+02, -6.8794682e+02 ); - expectedForces[146] = Vec3( -5.1132933e+02, 7.7102556e+02, -4.7805042e+02 ); - expectedForces[147] = Vec3( 6.2879945e+02, -6.9758821e+02, 1.0983043e+03 ); - expectedForces[148] = Vec3( -9.2449123e+02, 5.0248042e+02, -2.0065211e+02 ); - expectedForces[149] = Vec3( -3.9485154e+02, 3.4679511e+02, -7.3889603e+02 ); - expectedForces[150] = Vec3( 4.9834751e+02, -1.0117501e+03, 1.2510946e+03 ); - expectedForces[151] = Vec3( -1.4942699e+02, -7.4362790e+01, -6.8008427e+02 ); - expectedForces[152] = Vec3( -1.8353666e+02, 5.1697483e+02, -8.4397292e+01 ); - expectedForces[153] = Vec3( 7.0253008e+02, -1.5361338e+02, 8.6830836e+02 ); - expectedForces[154] = Vec3( -4.1108898e+02, -6.8181350e+02, -5.6516951e+02 ); - expectedForces[155] = Vec3( 3.9294374e+02, 3.7294948e+02, -4.9795080e+02 ); - expectedForces[156] = Vec3( -7.3716758e+02, -5.5465931e+02, -9.3434525e+02 ); - expectedForces[157] = Vec3( 1.8240105e+02, 1.5494359e+02, 1.3626243e+02 ); - expectedForces[158] = Vec3( 9.3172059e+02, 1.4431275e+02, 6.6916065e+02 ); - expectedForces[159] = Vec3( 7.3399513e+01, -3.6000187e+02, 1.9853052e+03 ); - expectedForces[160] = Vec3( -2.4842520e+02, -4.0819514e+02, -8.0624794e+02 ); - expectedForces[161] = Vec3( 4.3585911e+02, -2.6521764e+02, -6.7985842e+02 ); - expectedForces[162] = Vec3( -8.2255783e+02, 1.1430906e+03, 1.2991183e+03 ); - expectedForces[163] = Vec3( 5.6437196e+02, -1.5391213e+02, -5.0013503e+02 ); - expectedForces[164] = Vec3( 3.8485296e+02, -1.1754088e+02, -1.4315511e+03 ); - expectedForces[165] = Vec3( 9.8205241e+02, 1.3278205e+01, 3.0367584e+02 ); - expectedForces[166] = Vec3( -3.2909916e+02, 4.5169387e+01, -3.2019488e+02 ); - expectedForces[167] = Vec3( -4.2382795e+02, -8.1938351e+02, -1.5360675e+02 ); - expectedForces[168] = Vec3( 9.1689997e+02, 1.4443113e+03, -1.8886795e+02 ); - expectedForces[169] = Vec3( -1.2161000e+03, -2.3826187e+02, 3.4004889e+02 ); - expectedForces[170] = Vec3( -2.2837927e+02, -9.8334152e+02, 3.0313790e+02 ); - expectedForces[171] = Vec3( 5.2598040e+02, -1.2766936e+03, 8.1247934e+01 ); - expectedForces[172] = Vec3( -6.7839687e+01, 6.9220160e+02, 3.1975320e+02 ); - expectedForces[173] = Vec3( -4.8519844e+02, 4.3008979e+02, -7.6788762e+02 ); - expectedForces[174] = Vec3( 3.9550092e+01, 1.0900122e+03, 5.0955281e+02 ); - expectedForces[175] = Vec3( -6.3000735e+02, -7.2335263e+02, -2.2590661e+02 ); - expectedForces[176] = Vec3( 1.5048762e+02, -4.0086126e+02, -1.2159849e+02 ); - expectedForces[177] = Vec3( -7.1939527e+02, -1.0640815e+03, -3.1826393e+02 ); - expectedForces[178] = Vec3( 7.7492135e+02, 1.0620129e+02, 3.6733165e+02 ); - expectedForces[179] = Vec3( -3.5466457e+02, 7.0081887e+02, 2.2629152e+02 ); - expectedForces[180] = Vec3( 3.0338275e+02, -1.1243396e+02, -1.3408996e+03 ); - expectedForces[181] = Vec3( 9.0394088e+00, 4.8818819e+02, 7.3781403e+02 ); - expectedForces[182] = Vec3( -5.6111982e+01, -2.5224925e+02, 3.0344460e+02 ); - expectedForces[183] = Vec3( -7.4693225e+02, 1.1370727e+03, 9.3958175e+02 ); - expectedForces[184] = Vec3( 3.1310327e+02, -1.2133761e+03, 2.6768166e+02 ); - expectedForces[185] = Vec3( 6.0706899e+02, 9.8403362e+01, -5.0781782e+02 ); - expectedForces[186] = Vec3( -6.2721609e+02, 1.7751567e+02, 2.6230643e+02 ); - expectedForces[187] = Vec3( 3.5425475e+02, -3.3336896e+02, 2.9529930e+02 ); - expectedForces[188] = Vec3( 4.7499029e+02, 4.5552354e+02, -2.4939310e+02 ); - expectedForces[189] = Vec3( 1.1556321e+02, 2.5995186e+02, -8.4171376e+02 ); - expectedForces[190] = Vec3( -4.5095184e+02, -1.6639362e+01, 4.2956175e+02 ); - expectedForces[191] = Vec3( -7.5904218e+01, 3.9416063e+02, 4.2573815e+02 ); - expectedForces[192] = Vec3( 2.3041013e+02, -1.2883920e+03, -5.1943189e+02 ); - expectedForces[193] = Vec3( 8.6086944e+01, 1.8626094e+02, 3.7641641e+02 ); - expectedForces[194] = Vec3( -5.9266805e+02, 4.4766229e+02, -4.5835497e+02 ); - expectedForces[195] = Vec3( 3.9368476e+02, 1.1050329e+03, -1.3906133e+03 ); - expectedForces[196] = Vec3( -1.2912212e+03, -2.9660534e+02, 3.9659215e+02 ); - expectedForces[197] = Vec3( -2.4803663e+01, -2.7945607e+02, 3.5315630e+02 ); - expectedForces[198] = Vec3( 1.4147479e+02, 3.2766723e+02, 1.1137899e+03 ); - expectedForces[199] = Vec3( 7.8383167e+01, 2.2385715e+00, -1.0346820e+03 ); - expectedForces[200] = Vec3( -2.9231551e+02, -5.4648720e+02, -6.5500265e+02 ); - expectedForces[201] = Vec3( 1.3708284e+03, -1.0716376e+03, 4.5781190e+02 ); - expectedForces[202] = Vec3( -7.5533654e+02, 6.5396686e+02, -4.2683276e+02 ); - expectedForces[203] = Vec3( -6.5558825e+02, 3.1164131e+02, 2.6323555e+02 ); - expectedForces[204] = Vec3( 1.3173432e+03, 1.3775889e+03, 1.2933072e+02 ); - expectedForces[205] = Vec3( -4.0922505e+02, -7.5709333e+02, -3.4967434e+02 ); - expectedForces[206] = Vec3( 4.2270572e+01, -7.4393359e+02, 5.2985443e+02 ); - expectedForces[207] = Vec3( -1.5327880e+03, 7.3186706e+02, -2.3440058e+02 ); - expectedForces[208] = Vec3( 1.4650210e+03, 2.8661572e+02, -2.4233049e+02 ); - expectedForces[209] = Vec3( 8.4124688e+02, -3.4020518e+02, -3.1773592e+01 ); - expectedForces[210] = Vec3( -1.1480436e+03, -7.4089732e+02, -4.8883682e+02 ); - expectedForces[211] = Vec3( 3.5682075e+02, 2.1918110e+01, -1.2558000e+02 ); - expectedForces[212] = Vec3( 1.6505256e+02, 7.9867933e+02, 9.9760760e+02 ); - expectedForces[213] = Vec3( 1.2477725e+03, -8.8687803e+02, -8.2498529e+02 ); - expectedForces[214] = Vec3( 1.7357042e+02, 2.0185456e+02, 8.0965301e+02 ); - expectedForces[215] = Vec3( -9.0937500e+02, 5.5968713e+01, 1.7581913e+02 ); - expectedForces[216] = Vec3( 1.3030711e+03, -8.2642443e+02, 1.6679926e+02 ); - expectedForces[217] = Vec3( -8.4295510e+02, 2.0237547e+01, 4.0163431e+02 ); - expectedForces[218] = Vec3( -3.2088719e+02, 3.0824476e+02, 9.9166532e+01 ); - expectedForces[219] = Vec3( 1.4585495e+03, -4.1497503e+01, -2.2539636e+02 ); - expectedForces[220] = Vec3( -2.6148433e+02, 1.7592075e+02, 2.0638296e+02 ); - expectedForces[221] = Vec3( -9.2100962e+02, 2.6090225e+02, -8.4461867e+02 ); - expectedForces[222] = Vec3( -9.0597287e+02, -4.8246138e+02, -1.8012972e+03 ); - expectedForces[223] = Vec3( -1.1775667e+02, 1.7275816e+02, 1.1286513e+03 ); - expectedForces[224] = Vec3( 1.0682239e+03, 8.0853797e+02, 2.5601774e+02 ); - expectedForces[225] = Vec3( -1.6637330e+02, 7.6165466e+02, -5.9394315e+02 ); - expectedForces[226] = Vec3( 2.6206832e+02, -1.5011747e+02, 5.4532792e+02 ); - expectedForces[227] = Vec3( -2.6474701e+02, -1.4218144e+02, 1.1099125e+02 ); - expectedForces[228] = Vec3( -9.7365994e+02, -5.5282012e+02, -6.3158992e+02 ); - expectedForces[229] = Vec3( 1.1482718e+03, 1.4958662e+02, -5.6523355e+02 ); - expectedForces[230] = Vec3( 4.4084982e+02, 7.9662251e+02, 4.9732039e+02 ); - expectedForces[231] = Vec3( -4.8746806e+02, -1.5522005e+03, 1.0133483e+03 ); - expectedForces[232] = Vec3( 1.1332903e+03, 1.2836176e+03, -2.0897082e+02 ); - expectedForces[233] = Vec3( -7.9973372e+01, 6.3066961e+02, -5.8656505e+02 ); - expectedForces[234] = Vec3( -8.3714021e+02, -1.5385924e+03, 1.0179672e+03 ); - expectedForces[235] = Vec3( 3.5358323e+02, 9.3554369e+02, 1.6565605e+02 ); - expectedForces[236] = Vec3( 1.7532341e+02, 3.0381323e+01, -1.2538424e+03 ); - expectedForces[237] = Vec3( -1.0437301e+03, -4.4804918e+02, 1.5276435e+03 ); - expectedForces[238] = Vec3( 8.5470872e+02, 1.0725550e+03, -9.7359443e+01 ); - expectedForces[239] = Vec3( 1.8192015e+02, -7.6967211e+01, -8.6054596e+02 ); - expectedForces[240] = Vec3( 1.5910180e+03, -7.9601605e+02, -8.4030326e+02 ); - expectedForces[241] = Vec3( -6.4638370e+02, 4.0538540e+02, 2.3396878e+01 ); - expectedForces[242] = Vec3( -5.2648918e+02, 1.3689201e+02, 9.3014716e+02 ); - expectedForces[243] = Vec3( 2.2248997e+02, -6.3647370e+02, -8.3913128e+02 ); - expectedForces[244] = Vec3( -7.5759832e+02, 4.7985429e+01, 5.8577833e+02 ); - expectedForces[245] = Vec3( 1.2983550e+02, 4.4401985e+02, 2.3556259e+02 ); - expectedForces[246] = Vec3( 7.8075637e+02, 9.9893821e+02, 7.3511307e+02 ); - expectedForces[247] = Vec3( -8.6411159e+02, 2.3812628e+02, 1.9007971e+02 ); - expectedForces[248] = Vec3( 2.0762263e+02, -7.0123789e+02, -4.8175733e+02 ); - expectedForces[249] = Vec3( -8.2749187e+02, -7.8772346e+02, -9.8536337e+02 ); - expectedForces[250] = Vec3( 8.3905893e+01, -2.8770518e+02, 6.0690561e+02 ); - expectedForces[251] = Vec3( 7.2280803e+02, 4.9294103e+02, -1.2915033e+02 ); - expectedForces[252] = Vec3( -1.3615809e+03, -1.8564754e+02, -4.2172817e+02 ); - expectedForces[253] = Vec3( 9.2102155e+02, 5.4063967e+02, -2.7291760e+02 ); - expectedForces[254] = Vec3( 7.0204283e+02, -3.0338605e+02, 6.6795953e+02 ); - expectedForces[255] = Vec3( -7.2261285e+00, 3.2570478e+02, 5.9010590e+02 ); - expectedForces[256] = Vec3( -8.3167819e+02, 3.0568475e+02, -9.9230441e+02 ); - expectedForces[257] = Vec3( 2.1074297e+02, -4.0099946e+01, -1.2770634e+02 ); - expectedForces[258] = Vec3( 1.1218559e+03, -8.8304672e+02, 1.0217945e+03 ); - expectedForces[259] = Vec3( -4.4730264e+01, 5.3616918e+02, -3.2704110e+02 ); - expectedForces[260] = Vec3( -1.1106141e+03, 3.3541536e+02, -1.0552986e+02 ); - expectedForces[261] = Vec3( -9.3728497e+01, 4.7397796e+01, -1.1294332e+03 ); - expectedForces[262] = Vec3( 5.1424956e+01, 4.0854995e+02, 5.6832607e+02 ); - expectedForces[263] = Vec3( 1.4286074e+02, 2.9172921e+01, 5.1355833e+02 ); - expectedForces[264] = Vec3( -4.4318133e+02, -9.5478293e+02, -1.8067439e+03 ); - expectedForces[265] = Vec3( -2.8083245e+02, 8.1414586e+02, 6.6089404e+02 ); - expectedForces[266] = Vec3( 1.0434876e+02, 3.0664078e+02, 1.3658532e+03 ); - expectedForces[267] = Vec3( 1.2999089e+03, 5.6746563e+02, 1.2200612e+03 ); - expectedForces[268] = Vec3( -5.9546942e+02, 3.6897149e+02, -8.3331437e+02 ); - expectedForces[269] = Vec3( -1.1094881e+03, -5.1903335e+02, -3.5729033e+02 ); - expectedForces[270] = Vec3( 4.1873464e+02, 6.9788983e+02, -1.3191929e+03 ); - expectedForces[271] = Vec3( -1.0086080e+02, 3.3114447e+02, 6.3419860e+02 ); - expectedForces[272] = Vec3( -2.8783906e+02, -8.8308011e+02, -5.4816768e+01 ); - expectedForces[273] = Vec3( 1.0254638e+03, 2.8710026e+02, -1.9779676e+02 ); - expectedForces[274] = Vec3( -3.5906548e+02, -5.5531449e+02, -6.0205492e+01 ); - expectedForces[275] = Vec3( -3.9578349e+02, 5.9217272e+01, 1.0735648e+02 ); - expectedForces[276] = Vec3( -8.7298871e+02, -1.5584711e+02, 9.2571354e+02 ); - expectedForces[277] = Vec3( 4.1520558e+02, 5.6442126e+02, -1.8142289e+02 ); - expectedForces[278] = Vec3( 6.5423421e+02, -4.1631573e+02, 1.0996479e+02 ); - expectedForces[279] = Vec3( -8.0063899e+01, -1.2880940e+03, 2.9304469e+02 ); - expectedForces[280] = Vec3( -9.5930841e+02, 5.8293485e+02, -1.1632205e+03 ); - expectedForces[281] = Vec3( 6.3492338e+02, 2.5550931e+02, 1.7380517e+02 ); - expectedForces[282] = Vec3( -1.9188175e+02, 1.0257290e+03, -8.6438702e+02 ); - expectedForces[283] = Vec3( 4.0063530e+01, -5.1808902e+02, 4.9556015e+02 ); - expectedForces[284] = Vec3( 5.8250018e+02, -2.5030700e+02, 1.1762860e+03 ); - expectedForces[285] = Vec3( -4.3195459e+02, 7.4733530e+02, -1.3002210e+03 ); - expectedForces[286] = Vec3( 2.7567334e+01, -5.1662654e+02, 3.3258050e+02 ); - expectedForces[287] = Vec3( 6.1700857e+02, 3.0016354e+02, 9.5519139e+02 ); - expectedForces[288] = Vec3( 7.7553094e+02, 8.6453551e+02, -1.0122996e+03 ); - expectedForces[289] = Vec3( -2.6730796e+02, -7.7560875e+02, 4.3195620e+02 ); - expectedForces[290] = Vec3( -8.5982146e+02, 1.6692057e+02, 4.3838169e+02 ); - expectedForces[291] = Vec3( 1.2945126e+03, 6.3231748e+02, -8.3020592e+02 ); - expectedForces[292] = Vec3( -6.9510729e+02, -3.1930013e+02, -1.3919425e+01 ); - expectedForces[293] = Vec3( -4.1154200e+02, -3.3562358e+02, 6.3292682e+02 ); - expectedForces[294] = Vec3( -4.0919783e+02, -3.8282298e+02, -4.9125465e+02 ); - expectedForces[295] = Vec3( 6.3932145e+02, -1.8769713e+01, 9.9241332e+01 ); - expectedForces[296] = Vec3( 8.6847663e+01, 8.7234739e+02, 2.7124112e+02 ); - expectedForces[297] = Vec3( -1.0307576e+03, -6.2447562e+02, -1.5796976e+03 ); - expectedForces[298] = Vec3( 6.2464595e+02, 1.0608165e+03, 3.1422521e+01 ); - expectedForces[299] = Vec3( 3.7767184e+02, 4.1170186e+02, 1.0696495e+03 ); - expectedForces[300] = Vec3( 1.0578030e+02, -1.9544726e+03, -4.6243957e+02 ); - expectedForces[301] = Vec3( -3.1074896e+02, 8.6738333e+02, -2.0241448e+02 ); - expectedForces[302] = Vec3( -2.7350519e+02, 6.9945273e+02, 7.8755130e+02 ); - expectedForces[303] = Vec3( 7.8083070e+02, 6.5199614e+02, -6.6698950e+02 ); - expectedForces[304] = Vec3( 1.3647451e+02, -4.2490411e+02, 1.3236061e+01 ); - expectedForces[305] = Vec3( -1.1048984e+03, 3.7582184e+02, -6.4718844e+01 ); - expectedForces[306] = Vec3( 1.5976050e+03, -8.9091819e+02, 9.7113419e+02 ); - expectedForces[307] = Vec3( -4.5545384e+01, 8.8683300e+02, -6.5927739e+01 ); - expectedForces[308] = Vec3( -1.3883497e+03, -4.6171498e+02, -2.9117829e+02 ); - expectedForces[309] = Vec3( -6.6661140e+02, -8.1394964e+02, 1.2397900e+03 ); - expectedForces[310] = Vec3( -2.5293546e+02, 1.8568554e+02, -6.8919479e+02 ); - expectedForces[311] = Vec3( 5.2052057e+02, 1.0288555e+03, 3.1435700e+02 ); - expectedForces[312] = Vec3( -2.4245555e+02, -1.1100993e+03, -1.6937710e+03 ); - expectedForces[313] = Vec3( 1.6647470e+02, 9.5272347e+02, 9.2528380e+02 ); - expectedForces[314] = Vec3( 8.6946518e+02, -1.6295251e+02, 5.7452409e+02 ); - expectedForces[315] = Vec3( 1.4059831e+02, 5.6780959e+02, -4.6024149e+02 ); - expectedForces[316] = Vec3( 2.3327811e+02, -2.2376697e+02, 1.3399582e+01 ); - expectedForces[317] = Vec3( -2.6583612e+01, -4.5801841e+02, 2.9595361e+01 ); - expectedForces[318] = Vec3( 1.2361796e+03, -1.9473934e+02, -2.6179421e+02 ); - expectedForces[319] = Vec3( -4.2330105e+02, 5.0768290e+02, 6.8352494e+02 ); - expectedForces[320] = Vec3( -2.0826312e+02, 1.4720747e+02, -9.8828425e-01 ); - expectedForces[321] = Vec3( -7.3226106e+02, -1.5366771e+01, 2.7882968e+02 ); - expectedForces[322] = Vec3( 4.2634684e+02, -6.2926647e+02, 3.6300784e+02 ); - expectedForces[323] = Vec3( 1.7826269e+02, 1.0038378e+02, -4.2408556e+02 ); - expectedForces[324] = Vec3( -1.1690005e+03, 2.1777241e+02, 9.1980300e+02 ); - expectedForces[325] = Vec3( 5.6841370e+02, -2.6614377e+02, -6.4968364e+01 ); - expectedForces[326] = Vec3( 3.5710749e+02, 1.3228373e+02, -3.6567433e+02 ); - expectedForces[327] = Vec3( 8.1957745e+02, 7.3903486e+02, 3.9487193e+02 ); - expectedForces[328] = Vec3( -8.5354740e+02, 8.9297958e+01, 9.0615539e+01 ); - expectedForces[329] = Vec3( -2.3935807e+02, -2.2950021e+02, -4.6193868e+01 ); - expectedForces[330] = Vec3( 8.6120406e+01, 1.4046499e+03, -1.5899345e+02 ); - expectedForces[331] = Vec3( 4.6319634e+02, -4.6309406e+02, -2.2891416e+02 ); - expectedForces[332] = Vec3( -4.2592255e+02, -2.6503000e+02, 6.1788141e+02 ); - expectedForces[333] = Vec3( -2.4468457e+02, -7.7827760e+02, 4.2470013e+02 ); - expectedForces[334] = Vec3( 2.6006448e+02, 7.6289112e+01, -4.3430411e+02 ); - expectedForces[335] = Vec3( -2.5268926e+02, 7.7381529e+02, -5.0896414e+02 ); - expectedForces[336] = Vec3( 1.0414844e+03, -6.1885512e+02, 1.4495539e+03 ); - expectedForces[337] = Vec3( -5.9522011e+01, 1.3607073e+03, -7.3705640e+01 ); - expectedForces[338] = Vec3( -5.9857094e+02, -2.7213045e+02, -9.7516268e+02 ); - expectedForces[339] = Vec3( 9.2852178e+02, 3.0121600e+02, -7.4982031e+00 ); - expectedForces[340] = Vec3( -1.0201472e+03, 1.6269359e+02, 1.9280960e+02 ); - expectedForces[341] = Vec3( -1.8744984e+02, -4.9790658e+02, 4.2841303e+02 ); - expectedForces[342] = Vec3( -1.0893114e+03, -4.6044565e+02, -2.0537532e+02 ); - expectedForces[343] = Vec3( 5.1068148e+02, -3.0889884e+02, 1.7703226e+01 ); - expectedForces[344] = Vec3( 2.0128423e+02, 5.0813056e+02, -5.0941772e+01 ); - expectedForces[345] = Vec3( -6.0195519e+02, 1.1710803e+03, -5.8271481e+02 ); - expectedForces[346] = Vec3( 1.3898239e+02, -3.2598252e+02, 1.0877023e+03 ); - expectedForces[347] = Vec3( 3.1630812e+02, -8.9974673e+02, 9.6573268e+01 ); - expectedForces[348] = Vec3( -5.5334313e+01, -1.1529065e+03, -2.1949997e+02 ); - expectedForces[349] = Vec3( -4.4904784e+02, 2.4036076e+02, 4.1328142e+02 ); - expectedForces[350] = Vec3( 1.0611611e+03, 4.1620143e+02, 9.1677657e+01 ); - expectedForces[351] = Vec3( 1.3489840e+03, 9.9500659e+02, -4.5894902e+01 ); - expectedForces[352] = Vec3( -9.8051252e+01, -9.0794586e+02, -8.9918421e+02 ); - expectedForces[353] = Vec3( -3.5567408e+02, -7.2914902e+01, 4.7977644e+01 ); - expectedForces[354] = Vec3( -1.5976501e+03, -1.2202674e+03, 7.2159213e+02 ); - expectedForces[355] = Vec3( 1.7391266e+02, 1.0197773e+03, -9.1284547e+02 ); - expectedForces[356] = Vec3( 7.8937287e+02, 1.1964969e+02, -3.8520683e+02 ); - expectedForces[357] = Vec3( 2.8170878e+02, 1.0377979e+03, -5.0609230e+02 ); - expectedForces[358] = Vec3( -4.0852118e+01, -4.3087314e+02, 4.1855459e+01 ); - expectedForces[359] = Vec3( -3.2767902e+02, -7.8083477e+02, 1.1111190e+03 ); - expectedForces[360] = Vec3( -1.0691030e+03, 3.1877408e+02, -7.9684323e+02 ); - expectedForces[361] = Vec3( 7.7603235e+02, 3.6577850e+02, -1.9093841e+02 ); - expectedForces[362] = Vec3( -4.7607360e+02, -5.1710653e+02, 7.2740737e+02 ); - expectedForces[363] = Vec3( 9.3461900e+02, 7.9988609e+01, -5.8055314e+02 ); - expectedForces[364] = Vec3( -9.8128918e+02, -2.6706371e+02, -3.5178135e+01 ); - expectedForces[365] = Vec3( -6.5196668e+02, 8.7618054e+02, 3.3040412e+02 ); - expectedForces[366] = Vec3( 5.5458970e+02, -1.1281839e+03, -8.2774754e+02 ); - expectedForces[367] = Vec3( 1.8491757e+02, -5.1421593e+01, 4.7068191e+02 ); - expectedForces[368] = Vec3( -4.3945944e+02, 8.2740025e+02, -2.1736033e+01 ); - expectedForces[369] = Vec3( -2.5609394e+02, -6.7141305e+02, -3.2964376e+02 ); - expectedForces[370] = Vec3( 1.4932730e+02, 2.2746635e+02, -3.7606156e+01 ); - expectedForces[371] = Vec3( 3.0873674e+02, 5.9974800e+02, 4.2207331e+02 ); - expectedForces[372] = Vec3( -3.8828932e+02, -2.1491002e+02, 1.5266506e+03 ); - expectedForces[373] = Vec3( 4.4495676e+02, 6.4708482e+02, -9.2222368e+02 ); - expectedForces[374] = Vec3( -4.8420767e+01, -4.3781484e+02, -5.0107314e+02 ); - expectedForces[375] = Vec3( 5.7593719e+02, -1.8140066e+03, -4.0189721e+02 ); - expectedForces[376] = Vec3( -5.1276233e+02, 6.6981030e+02, 3.9050744e+02 ); - expectedForces[377] = Vec3( 4.0809391e+02, 1.1596412e+03, -4.1325341e+02 ); - expectedForces[378] = Vec3( 1.4975560e+03, 1.7852942e+02, -7.6514466e+02 ); - expectedForces[379] = Vec3( -2.2890988e+02, 2.6128742e+02, 3.8545036e+02 ); - expectedForces[380] = Vec3( -3.8899762e+02, -2.5609958e+02, 2.0655882e+02 ); - expectedForces[381] = Vec3( -1.9500869e+02, -1.0947633e+03, -9.1786660e+02 ); - expectedForces[382] = Vec3( 8.6146884e+02, 2.5767444e+02, 3.6801549e+02 ); - expectedForces[383] = Vec3( -2.0008562e+02, 2.1549793e+02, 2.5175877e+02 ); - expectedForces[384] = Vec3( -5.6491749e+02, 5.4714989e+02, 3.1934114e+02 ); - expectedForces[385] = Vec3( 1.7665111e+02, -4.5297277e+02, 2.2387580e+02 ); - expectedForces[386] = Vec3( 6.2697664e+02, 1.1271358e+02, 2.9498078e+00 ); - expectedForces[387] = Vec3( -2.1918090e+03, -7.8914005e+01, 1.0632280e+03 ); - expectedForces[388] = Vec3( 7.5750278e+02, -5.0217666e+02, -1.3057335e+02 ); - expectedForces[389] = Vec3( 1.0621096e+03, 1.6022661e+01, -1.1645539e+03 ); - expectedForces[390] = Vec3( -4.7808938e+02, -1.2425496e+03, -1.5543074e+02 ); - expectedForces[391] = Vec3( -3.4676860e+02, 8.5391303e+02, 3.5351618e+01 ); - expectedForces[392] = Vec3( 5.4017203e+02, 8.6467815e+01, 1.1898140e+02 ); - expectedForces[393] = Vec3( -1.8873828e+01, 2.2133074e+02, -1.3378739e+03 ); - expectedForces[394] = Vec3( 7.5888012e+01, -1.6517743e+01, 1.1817186e+02 ); - expectedForces[395] = Vec3( 1.1912944e+02, -1.6083226e+02, 7.8733940e+02 ); - expectedForces[396] = Vec3( -1.2400005e+03, -3.9434827e+02, 1.4071802e+02 ); - expectedForces[397] = Vec3( 9.6249284e+02, 1.1394516e+02, -3.4977717e+02 ); - expectedForces[398] = Vec3( 2.4187486e+02, 1.3373651e+02, 6.5894105e+01 ); - expectedForces[399] = Vec3( 8.8628445e+02, 7.8083892e+01, -1.0288922e+03 ); - expectedForces[400] = Vec3( -9.4613057e+02, -1.9076053e+02, 6.7506442e+02 ); - expectedForces[401] = Vec3( -6.2746897e+02, 2.9376858e+02, 9.2767458e+02 ); - expectedForces[402] = Vec3( 5.5409175e+01, -1.2583442e+03, 7.1728490e+02 ); - expectedForces[403] = Vec3( -2.9076856e+02, 7.5539656e+02, 7.0121763e+00 ); - expectedForces[404] = Vec3( 2.6220897e+02, -9.5606102e+01, -7.7725998e+02 ); - expectedForces[405] = Vec3( -8.6582014e+02, 9.5597761e+02, 1.5941783e+02 ); - expectedForces[406] = Vec3( -1.6910265e+02, -7.2646192e+02, -3.5476587e+02 ); - expectedForces[407] = Vec3( 9.7629076e+02, -8.3969437e+01, 2.5523637e+02 ); - expectedForces[408] = Vec3( -4.9553396e+01, 6.3557270e+02, -7.5908312e+02 ); - expectedForces[409] = Vec3( 3.3210227e+01, 1.5198340e+02, 7.0322192e+02 ); - expectedForces[410] = Vec3( -2.6532687e+01, -4.1589199e+02, 4.2771258e+02 ); - expectedForces[411] = Vec3( 1.1412630e+03, -2.7366656e+02, 9.8419548e+02 ); - expectedForces[412] = Vec3( -3.7239786e+02, 7.2244667e+01, -9.9502150e+02 ); - expectedForces[413] = Vec3( -4.6476941e+02, -6.1433607e+01, -2.5459288e+02 ); - expectedForces[414] = Vec3( 9.7028883e+02, 5.5981848e+02, 8.4425262e+02 ); - expectedForces[415] = Vec3( 7.2811577e+01, 2.2872709e+02, -1.3822700e+03 ); - expectedForces[416] = Vec3( -1.0105821e+03, -2.8444698e+02, -7.2506392e+02 ); - expectedForces[417] = Vec3( 1.0027865e+03, 6.0924816e+02, -5.7818592e+01 ); - expectedForces[418] = Vec3( -3.4173955e+02, -1.1932310e+02, -2.9495449e+01 ); - expectedForces[419] = Vec3( -2.7281265e+02, -1.8869212e+02, 1.9643932e+02 ); - expectedForces[420] = Vec3( -7.4036328e+02, -4.8733524e+02, 1.5862094e+03 ); - expectedForces[421] = Vec3( 5.6387864e+02, 3.0991659e+02, -8.6746725e+02 ); - expectedForces[422] = Vec3( 6.2954421e-01, 4.9665567e+02, -1.0114913e+03 ); - expectedForces[423] = Vec3( 8.9668630e+02, -1.0121499e+03, -1.1520006e+03 ); - expectedForces[424] = Vec3( -2.5699741e+02, 3.3243520e+02, 7.6038873e+02 ); - expectedForces[425] = Vec3( -1.2755484e+03, -2.7786159e+01, 3.0900583e+02 ); - expectedForces[426] = Vec3( -1.2587339e+03, -8.6851333e+02, 1.6295957e+02 ); - expectedForces[427] = Vec3( 6.4923970e+02, 4.4600015e+02, 3.3033348e+02 ); - expectedForces[428] = Vec3( 5.8905637e+02, -1.1589062e+02, -1.8168184e+02 ); - expectedForces[429] = Vec3( -1.1223714e+03, 3.0322406e+01, 8.7272053e+02 ); - expectedForces[430] = Vec3( 3.0982625e+02, 3.1418220e+02, -3.9301742e+02 ); - expectedForces[431] = Vec3( 2.4213933e+02, -7.2382572e+02, -1.0155346e+03 ); - expectedForces[432] = Vec3( 1.1479692e+03, -1.6837721e+03, 1.0545407e+02 ); - expectedForces[433] = Vec3( -8.2496264e+02, 6.0540594e+02, 1.3979931e+02 ); - expectedForces[434] = Vec3( -6.8171514e+02, 4.0392791e+02, -3.4712316e+02 ); - expectedForces[435] = Vec3( -1.5568889e+02, -1.4652975e+03, 5.1518148e+01 ); - expectedForces[436] = Vec3( 5.6573856e+02, 3.5494119e+02, -3.3796345e+02 ); - expectedForces[437] = Vec3( -1.3938679e+02, 4.2296152e+02, -2.0539863e+02 ); - expectedForces[438] = Vec3( 8.9203493e+01, 2.8764597e+02, -7.3273496e+02 ); - expectedForces[439] = Vec3( 4.3114292e+02, 9.4778082e+01, 1.8894761e+02 ); - expectedForces[440] = Vec3( -2.2798193e+01, -4.5460891e+01, 9.8310963e+01 ); - expectedForces[441] = Vec3( -2.1793579e+02, -1.0807542e+03, -2.3470465e+01 ); - expectedForces[442] = Vec3( 1.3881360e+02, 3.9806903e+02, 4.1089741e+01 ); - expectedForces[443] = Vec3( -4.5604974e+02, 4.8515999e+02, -6.6025174e+02 ); - expectedForces[444] = Vec3( 3.6437700e+02, -8.1622511e+02, -9.6454258e+02 ); - expectedForces[445] = Vec3( 3.1998690e+02, -3.3342314e+02, 1.2441763e+03 ); - expectedForces[446] = Vec3( 3.0822409e+01, 2.0596612e+02, 2.0937122e+02 ); - expectedForces[447] = Vec3( -8.4938718e+02, -1.1366483e+03, -1.3638049e+02 ); - expectedForces[448] = Vec3( -5.5232451e+01, 4.7335097e+02, -5.4433565e+02 ); - expectedForces[449] = Vec3( 6.5928852e+02, 1.7488804e+02, 6.7879378e+02 ); - expectedForces[450] = Vec3( -9.4572079e+02, 1.9162420e+02, 4.7935043e+02 ); - expectedForces[451] = Vec3( 2.5029547e+02, 3.6606767e+01, -9.3423713e+01 ); - expectedForces[452] = Vec3( 1.6543841e+02, -1.1892943e+02, -5.8737050e+02 ); - expectedForces[453] = Vec3( -9.8495219e+02, -1.6882428e+03, -4.0576035e+02 ); - expectedForces[454] = Vec3( 7.9182557e+02, 5.3997699e+02, 3.3231603e+02 ); - expectedForces[455] = Vec3( 1.8277090e+01, 1.4623150e+03, -9.4985721e+01 ); - expectedForces[456] = Vec3( -1.0471948e+03, 4.6746395e+02, -1.5020000e+03 ); - expectedForces[457] = Vec3( 7.2055316e+02, -5.4467216e+02, 4.0459421e+02 ); - expectedForces[458] = Vec3( 7.5475531e+01, 4.9532870e+02, 1.3002474e+03 ); - expectedForces[459] = Vec3( 6.3589773e+02, -2.1402397e+02, -1.4147509e+03 ); - expectedForces[460] = Vec3( 2.8391861e+02, -8.0142885e+01, 5.6445225e+02 ); - expectedForces[461] = Vec3( -8.2442674e+02, 5.3520687e+02, 1.1406667e+03 ); - expectedForces[462] = Vec3( -5.7988771e+02, -3.3512887e+02, 4.5461752e+02 ); - expectedForces[463] = Vec3( 4.5746059e+02, 3.1029926e+02, -5.0060176e+02 ); - expectedForces[464] = Vec3( 7.7747136e+02, 4.2131732e+02, 5.5836239e+02 ); - expectedForces[465] = Vec3( -1.2315491e+03, 9.4066088e+02, 9.6145313e+02 ); - expectedForces[466] = Vec3( 7.9043841e+02, -2.2172613e+02, -2.6508587e+02 ); - expectedForces[467] = Vec3( 7.8197894e+02, -3.1383822e+02, 2.5444013e+02 ); - expectedForces[468] = Vec3( -7.1139498e+01, -7.1203189e+01, -4.6845544e+02 ); - expectedForces[469] = Vec3( -8.9774100e+01, 1.4389287e+02, 9.8957451e+01 ); - expectedForces[470] = Vec3( 3.0397922e+02, -2.8247850e+01, 4.4896034e+02 ); - expectedForces[471] = Vec3( -9.7808367e+02, 1.0170553e+03, 8.1594649e+02 ); - expectedForces[472] = Vec3( 1.8933676e+02, -8.8053046e+02, 6.8784042e+01 ); - expectedForces[473] = Vec3( 5.1636668e+02, 1.2970985e+02, -8.9380858e+02 ); - expectedForces[474] = Vec3( -5.8549608e+02, -1.8351156e+02, -5.8043066e+02 ); - expectedForces[475] = Vec3( 2.7877663e+02, -3.6576715e+02, 3.5497095e+02 ); - expectedForces[476] = Vec3( 3.0642370e+02, 5.3438407e+02, 1.9409584e+02 ); - expectedForces[477] = Vec3( -4.8523805e+02, 1.2253320e+03, 9.6414379e+02 ); - expectedForces[478] = Vec3( -1.5213013e+02, -2.0017205e+02, -6.6602643e+02 ); - expectedForces[479] = Vec3( 4.6435225e+02, -4.1945066e+02, -8.6774270e+01 ); - expectedForces[480] = Vec3( 2.4946889e+02, -1.0456281e+03, 4.7404434e+02 ); - expectedForces[481] = Vec3( -3.0813505e+01, 2.8598938e+02, 7.7374350e+01 ); - expectedForces[482] = Vec3( -2.4538851e+02, 3.8306987e+02, -5.0235520e+02 ); - expectedForces[483] = Vec3( 4.0348805e+01, 1.3050360e+03, -6.8725580e+02 ); - expectedForces[484] = Vec3( -1.1095514e+02, -2.7711572e+02, 2.6929959e+02 ); - expectedForces[485] = Vec3( -6.8071081e+01, -3.4398150e+02, 2.5209743e+02 ); - expectedForces[486] = Vec3( 2.1534786e+03, 1.3249493e+01, 7.4171165e+01 ); - expectedForces[487] = Vec3( -7.2618755e+02, -3.2914219e+02, 2.5917332e+02 ); - expectedForces[488] = Vec3( -1.0231949e+03, 7.2426062e+02, 1.9111862e+02 ); - expectedForces[489] = Vec3( 1.1408866e+03, 6.7858353e+02, -2.1410916e+02 ); - expectedForces[490] = Vec3( -4.5559047e+02, -1.3597950e+02, -3.2284091e+02 ); - expectedForces[491] = Vec3( -8.5558133e+02, -7.1748324e+01, 5.3332261e+02 ); - expectedForces[492] = Vec3( -7.1393886e+02, -1.1275222e+03, -6.2147584e+02 ); - expectedForces[493] = Vec3( 4.4029614e+02, 1.0518224e+02, 4.6519788e+02 ); - expectedForces[494] = Vec3( -3.5770378e+02, 1.0311834e+03, 2.2141802e+02 ); - expectedForces[495] = Vec3( -2.6023787e+02, 1.0070248e+03, -1.1113552e+03 ); - expectedForces[496] = Vec3( -3.4950242e+02, 2.8418846e+01, 1.2865161e+03 ); - expectedForces[497] = Vec3( 1.5030225e+02, -7.7257505e+02, 8.7232628e+02 ); - expectedForces[498] = Vec3( -1.7416695e+02, 9.9945569e+02, -1.6742483e+02 ); - expectedForces[499] = Vec3( 2.0837481e+02, -1.9388709e+02, 9.7409815e+01 ); - expectedForces[500] = Vec3( -1.0129845e+02, -6.8652976e+02, 8.4930186e+02 ); - expectedForces[501] = Vec3( 1.2276099e+03, 1.6531986e+02, 3.6342506e+02 ); - expectedForces[502] = Vec3( -1.9998077e+02, -2.6164759e+02, -1.6601933e+02 ); - expectedForces[503] = Vec3( -4.0356327e+02, 4.0549152e+02, 2.9710052e+02 ); - expectedForces[504] = Vec3( -7.3045150e+02, -1.6677706e+03, -9.8671765e+02 ); - expectedForces[505] = Vec3( -2.1441879e+02, 1.4962605e+03, 5.6350856e+02 ); - expectedForces[506] = Vec3( 7.1102593e+02, 5.9407971e+02, 9.5452239e+02 ); - expectedForces[507] = Vec3( 3.2291041e+02, 1.3943261e+03, -1.8477432e+03 ); - expectedForces[508] = Vec3( -1.7778104e+02, 2.8034575e+02, 1.1385089e+03 ); - expectedForces[509] = Vec3( -2.4943297e+02, -9.0965773e+02, 5.2737490e+02 ); - expectedForces[510] = Vec3( -3.8318508e+02, 1.3999092e+03, -5.9960180e+02 ); - expectedForces[511] = Vec3( 2.6930065e+01, -3.6603454e+02, 1.0460530e+03 ); - expectedForces[512] = Vec3( -1.8964668e+02, -1.1663184e+03, -2.8438291e+02 ); - expectedForces[513] = Vec3( -9.4679273e+02, 8.7408257e+01, -2.5740702e+02 ); - expectedForces[514] = Vec3( 1.6558849e+02, 3.3561310e+02, 3.8532718e+02 ); - expectedForces[515] = Vec3( 4.0403504e+02, -8.5545173e+02, 4.0647038e+02 ); - expectedForces[516] = Vec3( 8.3825526e+02, 5.0343638e+01, -3.9171626e+02 ); - expectedForces[517] = Vec3( -4.0069871e+02, -6.4140295e+02, 7.5218861e+01 ); - expectedForces[518] = Vec3( -6.5213072e+02, 4.1689581e+02, -8.9280241e+01 ); - expectedForces[519] = Vec3( 4.0832996e+02, -3.4272605e+02, -9.2740030e+02 ); - expectedForces[520] = Vec3( -2.1128040e+01, -7.3467005e+02, 6.5449252e+02 ); - expectedForces[521] = Vec3( -2.8042421e+02, 3.3193211e+02, 5.1272473e+02 ); - expectedForces[522] = Vec3( -1.2057322e+03, 3.3276609e+02, 6.8838073e+02 ); - expectedForces[523] = Vec3( 8.9270663e+02, 1.3914748e+02, -8.7213182e+02 ); - expectedForces[524] = Vec3( 8.8063936e+02, -2.4952564e+02, -8.3942753e+01 ); - expectedForces[525] = Vec3( 3.6527919e+02, 3.3758036e+02, -1.3449147e+03 ); - expectedForces[526] = Vec3( 7.1836993e+01, -3.9380031e+01, 4.7169292e+02 ); - expectedForces[527] = Vec3( -7.2114939e+01, -1.3679457e+02, 3.9080695e+02 ); - expectedForces[528] = Vec3( 1.1465645e+02, -4.4994719e+02, -3.4180224e+02 ); - expectedForces[529] = Vec3( -6.0950292e+01, 4.2825716e+02, -1.4233246e+02 ); - expectedForces[530] = Vec3( -1.9112828e+02, -2.8511065e+00, 2.6894050e+02 ); - expectedForces[531] = Vec3( 4.4955085e+02, 2.0459389e+02, 8.9486972e+02 ); - expectedForces[532] = Vec3( 6.6339624e+01, -4.2734850e+01, -4.8004048e+02 ); - expectedForces[533] = Vec3( -5.0521801e+02, -1.6330265e+02, -6.2374206e+02 ); - expectedForces[534] = Vec3( -1.1019306e+03, -4.5760347e+02, 4.6134602e+01 ); - expectedForces[535] = Vec3( 4.9278700e+02, 8.0495847e+02, -5.7470233e+01 ); - expectedForces[536] = Vec3( 9.9361557e+02, -2.4453172e+02, -3.7696369e+02 ); - expectedForces[537] = Vec3( -1.1168499e+03, -2.1108925e+02, -4.1233970e+02 ); - expectedForces[538] = Vec3( 5.6559058e+02, -2.8153614e+02, 3.0539700e+02 ); - expectedForces[539] = Vec3( 4.0805303e+02, 2.8796083e+02, -3.0009135e+01 ); - expectedForces[540] = Vec3( -8.5249075e+02, -1.0560038e+03, -6.5111795e+02 ); - expectedForces[541] = Vec3( 8.4653565e+02, 2.0615416e+02, -1.5085906e+02 ); - expectedForces[542] = Vec3( -2.8200251e+02, 6.6950966e+02, 5.9661450e+02 ); - expectedForces[543] = Vec3( -9.3339994e+01, 8.7084190e+02, -7.8375352e+02 ); - expectedForces[544] = Vec3( 1.4187243e+02, 1.2829809e+02, 8.0626841e+02 ); - expectedForces[545] = Vec3( 1.5403073e+02, -4.5932125e+02, -8.3051878e+00 ); - expectedForces[546] = Vec3( 1.3919197e+03, 5.4728737e+02, -1.0548033e+03 ); - expectedForces[547] = Vec3( -2.7215065e+02, 1.5112718e+02, 6.7366542e+02 ); - expectedForces[548] = Vec3( -7.8677637e+02, -2.6895175e+02, 4.3374996e+02 ); - expectedForces[549] = Vec3( 6.6014864e+02, -1.1474704e+03, -3.7199889e+02 ); - expectedForces[550] = Vec3( -5.8741315e+02, 2.6286109e+02, 1.9036264e+02 ); - expectedForces[551] = Vec3( 1.4325969e+02, 7.8928381e+02, 3.6304214e+02 ); - expectedForces[552] = Vec3( -9.6661866e+02, -1.0462801e+03, -6.3261994e+02 ); - expectedForces[553] = Vec3( 5.5171916e+02, 2.8672800e+02, 2.7240662e+02 ); - expectedForces[554] = Vec3( 1.1625052e+03, 7.7864110e+02, -5.2588322e+02 ); - expectedForces[555] = Vec3( 1.7042269e+03, -5.8973225e+02, 1.4814500e+02 ); - expectedForces[556] = Vec3( -7.7324022e+02, 2.9167426e+02, -1.0262563e+02 ); - expectedForces[557] = Vec3( -5.4655014e+02, -8.4339654e+01, 9.7375629e+02 ); - expectedForces[558] = Vec3( -6.9618127e+02, -1.6878530e+02, 7.1078501e+02 ); - expectedForces[559] = Vec3( 6.9623995e+02, -3.7038954e+01, 2.2671528e+02 ); - expectedForces[560] = Vec3( -7.1025694e+01, -1.8643963e+02, -8.0181026e+02 ); - expectedForces[561] = Vec3( -1.4598467e+02, 1.7170707e+03, -4.3305456e+02 ); - expectedForces[562] = Vec3( 7.9582463e+02, -5.9551245e+02, 8.3485625e+01 ); - expectedForces[563] = Vec3( -4.6812643e+02, -3.4598874e+02, -3.6753356e+01 ); - expectedForces[564] = Vec3( -1.8586268e+02, 3.1377143e+02, -1.6616022e+03 ); - expectedForces[565] = Vec3( 7.4400496e+02, 5.5058789e+02, 7.5374599e+02 ); - expectedForces[566] = Vec3( -6.3347529e+02, -3.1407006e+02, 8.2964691e+02 ); - expectedForces[567] = Vec3( -4.2499528e+02, 9.4575975e+02, -6.6700103e+02 ); - expectedForces[568] = Vec3( -9.2637696e+02, -6.6301622e+02, 3.9913705e+02 ); - expectedForces[569] = Vec3( 5.0588430e+02, -8.1942697e+01, 4.2128365e+02 ); - expectedForces[570] = Vec3( 2.7165158e+02, 2.7387902e+02, 1.0850277e+03 ); - expectedForces[571] = Vec3( -6.8391471e+00, -1.2886307e+02, -5.3501450e+02 ); - expectedForces[572] = Vec3( -2.9936240e+02, -2.2085475e+02, -6.9670281e+01 ); - expectedForces[573] = Vec3( 1.6853422e+02, 4.8410887e+02, 1.0517406e+03 ); - expectedForces[574] = Vec3( -4.9287521e+02, 1.6557733e+01, -3.4008916e+02 ); - expectedForces[575] = Vec3( 1.1132397e+02, -9.8734894e+02, -1.1154151e+02 ); - expectedForces[576] = Vec3( 3.8645582e+02, 4.3709361e+02, 1.4861132e+03 ); - expectedForces[577] = Vec3( -1.0169967e+03, -3.5279110e+02, -5.4860861e+02 ); - expectedForces[578] = Vec3( 2.8875246e+02, 5.3726711e+01, -5.9395936e+02 ); - expectedForces[579] = Vec3( 1.5169994e+03, 8.7535209e+01, 1.0103159e+03 ); - expectedForces[580] = Vec3( -1.9439968e+02, -7.9639200e+02, -1.0439069e+03 ); - expectedForces[581] = Vec3( -8.7374025e+02, 2.0597360e+02, 1.0218319e+02 ); - expectedForces[582] = Vec3( 6.4275846e+02, -6.2671529e+02, 8.9274592e+02 ); - expectedForces[583] = Vec3( -5.4449356e+01, 7.2615928e+02, -9.1355057e+02 ); - expectedForces[584] = Vec3( -2.7242606e+02, 3.9376960e+02, -4.7692581e+01 ); - expectedForces[585] = Vec3( 2.6578654e+02, -6.7385441e+02, -1.5306127e+03 ); - expectedForces[586] = Vec3( 5.1049761e+02, 7.3430855e+02, 6.1178168e+02 ); - expectedForces[587] = Vec3( -3.3593193e+02, 3.5079666e+01, 9.7444298e+02 ); - expectedForces[588] = Vec3( -7.8227654e+01, -1.1050481e+03, 1.4161574e+03 ); - expectedForces[589] = Vec3( -7.6753407e+02, 9.7291633e+02, 1.9943116e+02 ); - expectedForces[590] = Vec3( 2.9274184e+02, -2.5706985e+01, -5.8944290e+02 ); - expectedForces[591] = Vec3( -1.2502829e+03, 2.2304820e+02, -8.8573767e+02 ); - expectedForces[592] = Vec3( 1.2218682e+02, -8.2110835e+02, 3.4276058e+02 ); - expectedForces[593] = Vec3( 8.9529566e+02, -1.8417573e+02, 8.4717919e+02 ); - expectedForces[594] = Vec3( -4.6475772e+01, -1.5493620e+03, 4.8004365e+02 ); - expectedForces[595] = Vec3( 6.7104033e+02, 4.7267915e+02, -6.2630817e+02 ); - expectedForces[596] = Vec3( -2.2771561e+02, 2.7463551e+02, -2.9704610e+00 ); - expectedForces[597] = Vec3( 1.7757815e+02, -1.8906761e+03, -1.6656886e+02 ); - expectedForces[598] = Vec3( -7.4745588e+01, 1.0353962e+03, 4.2924498e+02 ); - expectedForces[599] = Vec3( -5.5648197e+02, 7.7838572e+02, -4.1677346e+02 ); - expectedForces[600] = Vec3( -5.2972489e+02, 1.1967117e+02, 1.0565388e+03 ); - expectedForces[601] = Vec3( 7.8379665e+02, -4.1803420e+02, 2.0308387e+02 ); - expectedForces[602] = Vec3( 1.2705528e+02, 1.1663435e+02, -7.6514830e+02 ); - expectedForces[603] = Vec3( -1.5203094e+03, -8.5825144e+01, -2.3039380e+02 ); - expectedForces[604] = Vec3( 5.2063739e+02, -1.7259834e+02, -2.9854160e+01 ); - expectedForces[605] = Vec3( 4.7448961e+02, 2.8282389e+02, 3.4257463e+01 ); - expectedForces[606] = Vec3( 1.4519531e+03, -1.2031444e+03, -6.7084095e+02 ); - expectedForces[607] = Vec3( -7.5308994e+02, -3.2117501e+02, 5.7700017e+02 ); - expectedForces[608] = Vec3( -1.7643179e+02, 8.5655779e+02, -2.6285482e+02 ); - expectedForces[609] = Vec3( -1.3868959e+03, -1.6195505e+01, -1.3783528e+03 ); - expectedForces[610] = Vec3( 2.8034476e+02, -4.2360778e+02, 4.5904202e+02 ); - expectedForces[611] = Vec3( 1.0938532e+03, 6.2455629e+02, -1.0108636e+02 ); - expectedForces[612] = Vec3( 9.1439974e+01, -7.2813810e+02, 1.0197075e+03 ); - expectedForces[613] = Vec3( 1.4048294e+02, 2.5667744e+02, -5.1914694e+02 ); - expectedForces[614] = Vec3( -2.5604629e+01, 2.9915218e+01, -5.1582702e+02 ); - expectedForces[615] = Vec3( 2.0331673e+02, 1.5538650e+02, -1.1836865e+03 ); - expectedForces[616] = Vec3( -2.3788957e+02, -1.1872269e+02, 9.7052698e+02 ); - expectedForces[617] = Vec3( -3.2419551e+01, -1.8828745e+02, 4.3037423e+02 ); - expectedForces[618] = Vec3( -4.8585762e+02, 1.4114027e+02, 1.6021114e+02 ); - expectedForces[619] = Vec3( 2.8744134e+02, -5.7197623e+02, -1.8323508e+02 ); - expectedForces[620] = Vec3( 2.3652930e+02, -1.5448350e+01, 2.1721186e+01 ); - expectedForces[621] = Vec3( 1.1684581e+03, 2.2790484e+02, 2.7798348e+02 ); - expectedForces[622] = Vec3( -4.6823976e+02, -6.1804544e+02, 2.7193441e+02 ); - expectedForces[623] = Vec3( -5.8173089e+02, 4.4573870e+02, -6.0699430e+02 ); - expectedForces[624] = Vec3( 7.9759250e+02, 1.8480473e+03, -5.1434277e+02 ); - expectedForces[625] = Vec3( -1.0945975e+03, -6.0402685e+02, 1.5843017e+02 ); - expectedForces[626] = Vec3( 1.2334392e+02, -9.5602838e+02, 7.8137824e+02 ); - expectedForces[627] = Vec3( -8.5863208e+02, -5.7413454e+02, 1.7014217e+02 ); - expectedForces[628] = Vec3( -1.2232569e+02, 6.0505774e+02, -1.6806693e+02 ); - expectedForces[629] = Vec3( 6.1488135e+02, 4.1603705e+02, 2.1121948e+02 ); - expectedForces[630] = Vec3( 2.1858899e+02, 1.2961013e+03, 4.8534041e+02 ); - expectedForces[631] = Vec3( 2.1292701e+02, -4.1049165e+02, 3.9057142e+00 ); - expectedForces[632] = Vec3( -6.3342469e+02, -8.7529004e+02, 6.1928550e+01 ); - expectedForces[633] = Vec3( -7.3207079e+02, -1.3874807e+03, 8.6303032e+02 ); - expectedForces[634] = Vec3( 6.6660351e+02, 9.5813895e+02, -1.4555416e+02 ); - expectedForces[635] = Vec3( 4.1800653e+02, 2.4677420e+02, -1.1424272e+03 ); - expectedForces[636] = Vec3( 8.3570430e+02, -1.5342969e+03, -1.2510269e+03 ); - expectedForces[637] = Vec3( -3.0635229e+02, 1.2465088e+03, -1.9679529e+01 ); - expectedForces[638] = Vec3( -6.5317178e+02, -1.6432929e+02, 9.2427724e+02 ); - expectedForces[639] = Vec3( 1.5665680e+03, 9.8040004e+01, 1.0786497e+02 ); - expectedForces[640] = Vec3( -4.6590380e+02, -3.7603795e+02, -9.4955273e+02 ); - expectedForces[641] = Vec3( -8.7572108e+02, 5.1750570e+02, -1.2268062e+02 ); - expectedForces[642] = Vec3( 1.1575067e+03, -2.2857204e+02, -2.3816900e+02 ); - expectedForces[643] = Vec3( -2.6229644e+02, 3.1069110e+02, -1.2098536e+02 ); - expectedForces[644] = Vec3( -1.8195659e+02, -3.8984698e+02, 6.4622752e+02 ); - expectedForces[645] = Vec3( 1.0756277e+03, 2.7459106e+01, 1.0850508e+03 ); - expectedForces[646] = Vec3( -6.4620310e+02, 2.5885783e+02, -2.0567224e+02 ); - expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02 ); + expectedForces[0] = Vec3( -5.2764003e+02, 6.5154502e+02, 7.8683284e+02); + expectedForces[1] = Vec3( 3.3391292e+02, -1.1162521e+03, -2.9173021e+02); + expectedForces[2] = Vec3( 9.4613310e+01, -5.8988099e+01, -6.2871010e+02); + expectedForces[3] = Vec3( -1.6179658e+03, 1.8222798e+02, -1.0373083e+02); + expectedForces[4] = Vec3( 1.0177962e+03, 1.7118957e+02, 4.0084976e+02); + expectedForces[5] = Vec3( 3.0582540e+02, -5.5215191e+02, 4.8287747e+01); + expectedForces[6] = Vec3( -5.4931641e+01, -6.7689368e+02, -1.2260977e+03); + expectedForces[7] = Vec3( -2.9961754e+02, 1.3602079e+03, -2.2087612e+02); + expectedForces[8] = Vec3( -3.1788045e+02, -1.3540025e+02, 1.1250958e+03); + expectedForces[9] = Vec3( 1.0275111e+03, 1.9279625e+02, -6.0872252e+02); + expectedForces[10] = Vec3( -5.7512410e+02, -5.6280482e+01, 7.5039261e+02); + expectedForces[11] = Vec3( -4.7291981e+02, -3.5875411e+01, 5.2335135e+00); + expectedForces[12] = Vec3( -1.5619899e+02, -1.3743370e+02, 1.3587339e+03); + expectedForces[13] = Vec3( -4.7423876e+02, 1.0032873e+02, -2.0875847e+02); + expectedForces[14] = Vec3( 7.5621178e+02, 3.7979419e+01, -4.1221012e+02); + expectedForces[15] = Vec3( 6.7318876e+02, 4.9937148e+02, 1.1665351e+03); + expectedForces[16] = Vec3( -7.0858091e+01, 8.4758233e+01, -1.3126942e+03); + expectedForces[17] = Vec3( -1.0636296e+03, -1.6254851e+02, -1.0982809e+02); + expectedForces[18] = Vec3( -1.0249489e+03, 6.7073895e+02, -2.0754278e+02); + expectedForces[19] = Vec3( 5.6396078e+02, -1.1702137e+03, 1.5324295e+02); + expectedForces[20] = Vec3( 6.1635144e+02, 5.6122242e+02, -7.9410893e+01); + expectedForces[21] = Vec3( -1.5785582e+02, -1.0857764e+03, -1.1010131e+03); + expectedForces[22] = Vec3( 2.3733181e+01, 2.0158373e+02, 3.2583783e+02); + expectedForces[23] = Vec3( 1.8855396e+02, 1.2408889e+03, 4.5759149e+02); + expectedForces[24] = Vec3( 9.3643408e+02, -6.1331107e+01, -3.8601431e+02); + expectedForces[25] = Vec3( -3.1972504e+02, -1.5783340e+02, -1.3838003e+02); + expectedForces[26] = Vec3( -5.1178039e+02, -2.5998898e+02, 6.1021975e+02); + expectedForces[27] = Vec3( 9.1836250e+02, -4.3288112e+02, -9.5579501e+02); + expectedForces[28] = Vec3( -9.3325184e+02, 6.2859013e+01, 5.0743198e+02); + expectedForces[29] = Vec3( 3.1839963e+02, 5.4102155e+02, 1.1261345e+03); + expectedForces[30] = Vec3( 7.3842640e+02, 1.0907054e+02, -2.1126612e+02); + expectedForces[31] = Vec3( -1.8470175e+02, -4.0377182e+01, 1.2464073e+02); + expectedForces[32] = Vec3( -5.8931386e+02, -3.5021489e+02, -7.2769901e+01); + expectedForces[33] = Vec3( 1.4804452e+02, -1.2138869e+02, -1.2423820e+03); + expectedForces[34] = Vec3( -2.4850935e+02, 2.3113218e+01, 1.4041979e+02); + expectedForces[35] = Vec3( 1.3188525e+02, -6.1243481e+02, 6.4886373e+02); + expectedForces[36] = Vec3( 5.0217683e+02, 9.2857480e+02, -7.2500648e+02); + expectedForces[37] = Vec3( 9.9446320e+01, -3.0337270e+02, 8.0439741e+02); + expectedForces[38] = Vec3( -1.7167491e+02, -9.3911948e+02, 5.6412500e+01); + expectedForces[39] = Vec3( -6.6143649e+02, 1.0876882e+03, 3.3801466e+02); + expectedForces[40] = Vec3( 5.6748150e+02, -2.2459572e+02, 3.8360728e+02); + expectedForces[41] = Vec3( 7.7688834e+02, -6.7341171e+02, -6.4292796e+02); + expectedForces[42] = Vec3( 1.0253263e+02, -1.3212797e+03, 9.3279892e+02); + expectedForces[43] = Vec3( 1.5424247e+02, -1.0197346e+01, -8.0230728e+02); + expectedForces[44] = Vec3( -6.6499384e+02, 1.2534353e+03, -1.6748341e+02); + expectedForces[45] = Vec3( -1.9282945e+02, 5.1764789e+02, 1.5108154e+03); + expectedForces[46] = Vec3( -4.9204245e+02, 8.8664089e+02, -8.8381078e+02); + expectedForces[47] = Vec3( 1.3207641e+01, -5.7765859e+02, -3.5921690e+02); + expectedForces[48] = Vec3( 4.1691955e+02, -1.1292452e+03, -6.2339128e+02); + expectedForces[49] = Vec3( 4.8613761e+02, 6.8325845e+02, 2.3424652e+02); + expectedForces[50] = Vec3( 3.1827501e+01, 6.8442319e+02, -5.8685438e+02); + expectedForces[51] = Vec3( 1.1834790e+03, -1.3418299e+03, 5.6280882e+02); + expectedForces[52] = Vec3( -5.8629616e+02, -6.9100489e+01, -9.7784543e+02); + expectedForces[53] = Vec3( -4.0294748e+02, 5.0669032e+02, 5.3893512e+02); + expectedForces[54] = Vec3( 6.3555947e+01, -9.0345643e+02, 7.2235587e+02); + expectedForces[55] = Vec3( 4.9353706e+02, 4.3952680e+02, -1.5413911e+02); + expectedForces[56] = Vec3( -3.4663273e+02, 8.4708544e+02, -8.8983178e+01); + expectedForces[57] = Vec3( 1.5746383e+03, 5.8209931e+02, 3.6645765e+02); + expectedForces[58] = Vec3( -4.0076588e+02, -1.2311235e+02, -1.6226002e+02); + expectedForces[59] = Vec3( -3.3837369e+02, -5.3890252e+02, -5.5997831e+02); + expectedForces[60] = Vec3( 8.6512912e+02, -1.0775827e+03, -3.6920406e+02); + expectedForces[61] = Vec3( 1.0588621e+01, 4.4531974e+02, 1.1838800e+02); + expectedForces[62] = Vec3( -7.0505255e+02, 1.5737739e+02, 3.0134165e+02); + expectedForces[63] = Vec3( -1.2833932e+03, 5.1206074e+02, -9.3423828e+01); + expectedForces[64] = Vec3( 2.0863538e+02, -6.7108922e+02, 3.5777952e+02); + expectedForces[65] = Vec3( 4.9710436e+02, -6.8550896e+01, -2.7502680e+02); + expectedForces[66] = Vec3( 4.0388289e+02, 1.0051571e+03, -2.3823633e+02); + expectedForces[67] = Vec3( -3.3895858e+02, -6.7577709e+02, 3.1521120e+02); + expectedForces[68] = Vec3( -4.8763670e+02, -2.9427128e+02, 2.9500438e+02); + expectedForces[69] = Vec3( -8.4080783e+02, -1.7777886e+02, 6.5087880e+02); + expectedForces[70] = Vec3( 2.1136356e+02, 6.6812142e+01, -5.5437438e+02); + expectedForces[71] = Vec3( -1.3829189e+01, 7.0936421e+02, -5.0847380e+02); + expectedForces[72] = Vec3( -1.5684247e+03, 1.6837339e+02, -4.6044105e+02); + expectedForces[73] = Vec3( 9.9163605e+02, -4.1397181e+02, -3.9624142e+02); + expectedForces[74] = Vec3( 6.7355000e+02, 5.7652252e+02, 1.0565003e+03); + expectedForces[75] = Vec3( -1.3722105e+03, -1.4035644e+03, 2.7882380e+02); + expectedForces[76] = Vec3( 5.2187588e+02, 3.9602986e+02, -2.2564009e+02); + expectedForces[77] = Vec3( 2.6381283e+02, 4.2945748e+02, 1.8339201e+02); + expectedForces[78] = Vec3( 5.3099327e+02, 1.7312849e+03, 3.5385638e+01); + expectedForces[79] = Vec3( -2.1320977e+02, -1.1795453e+03, -5.1691859e+02); + expectedForces[80] = Vec3( -7.1445218e+02, -5.8918750e+02, 7.6494816e+02); + expectedForces[81] = Vec3( 1.0849545e+03, 6.5058603e+02, -5.6051049e+02); + expectedForces[82] = Vec3( -4.6986151e+02, -3.3868080e+02, 7.9000645e+02); + expectedForces[83] = Vec3( -3.8404718e+02, -4.4915037e+02, -4.2069600e+02); + expectedForces[84] = Vec3( -3.0678477e+02, -7.2558567e+02, 2.0276275e+02); + expectedForces[85] = Vec3( 6.2969625e+01, 3.4257826e+02, -6.8348290e+02); + expectedForces[86] = Vec3( 3.1042613e+02, 9.6563445e+01, -1.8788848e+02); + expectedForces[87] = Vec3( 2.4427535e+01, 5.8460648e+02, -1.3720684e+03); + expectedForces[88] = Vec3( -4.9904469e+02, -9.1309605e+02, 1.4350031e+02); + expectedForces[89] = Vec3( -4.0910847e+01, 5.2845046e+01, 2.7341591e+02); + expectedForces[90] = Vec3( -4.5190765e+02, 2.2820859e+02, -1.1052181e+03); + expectedForces[91] = Vec3( 9.1626336e+01, -1.0496400e+03, 1.0216011e+02); + expectedForces[92] = Vec3( -1.2592678e+02, -4.4050520e+01, 1.0764584e+03); + expectedForces[93] = Vec3( 8.4216135e+02, 1.7603150e+02, 1.3698861e+03); + expectedForces[94] = Vec3( 1.2583734e+02, 3.4343971e+02, -7.3070182e+02); + expectedForces[95] = Vec3( -4.5597370e+02, -6.8170738e+02, -5.2258658e+02); + expectedForces[96] = Vec3( 1.3295639e+03, 2.5031118e+02, -3.5171095e+02); + expectedForces[97] = Vec3( -2.0136001e+02, -2.2978012e+02, 2.1122610e+02); + expectedForces[98] = Vec3( -1.1279722e+03, -9.9794730e+02, -1.1321006e+02); + expectedForces[99] = Vec3( 2.9553179e+02, -2.0727600e+02, -1.8912317e+03); + expectedForces[100] = Vec3( -9.3777487e+02, 4.3417972e+02, 5.7436670e+02); + expectedForces[101] = Vec3( 3.1120364e+02, -4.3241206e+00, 5.6666340e+02); + expectedForces[102] = Vec3( -6.6764840e+02, -2.3563274e+02, 9.9017992e+02); + expectedForces[103] = Vec3( 8.2857598e+02, 1.9030059e+02, -2.4295780e+02); + expectedForces[104] = Vec3( -2.6709334e+02, 7.3284851e+01, -3.9157038e+02); + expectedForces[105] = Vec3( 6.6235629e+02, -8.4502811e+02, -5.3670716e+02); + expectedForces[106] = Vec3( 3.8449086e+02, 8.0775263e+02, 5.2003911e+02); + expectedForces[107] = Vec3( -3.4338589e+02, 1.7870086e+02, -6.1047615e+01); + expectedForces[108] = Vec3( 4.3523975e+02, 2.8776092e+02, -1.5333067e+03); + expectedForces[109] = Vec3( 1.9214022e+01, -9.9449061e+01, 3.9153169e+02); + expectedForces[110] = Vec3( -7.7525496e+02, 7.7309387e+01, 7.8886699e+02); + expectedForces[111] = Vec3( -1.1510224e+03, -2.8207337e+02, 1.4866455e+03); + expectedForces[112] = Vec3( 1.1281316e+03, -3.0961130e+02, -1.3894255e+02); + expectedForces[113] = Vec3( -2.4829062e+02, 5.9466066e+02, -9.0749265e+02); + expectedForces[114] = Vec3( -1.6228531e+02, -4.1281378e+02, -1.4860946e+03); + expectedForces[115] = Vec3( -2.9071192e+02, 7.5335271e+02, 6.5205720e+02); + expectedForces[116] = Vec3( 3.2042337e+02, -4.0237231e+02, 1.0068554e+03); + expectedForces[117] = Vec3( -1.4081272e+03, -5.5227579e+02, 2.8376428e+02); + expectedForces[118] = Vec3( 9.6978276e+02, -9.6232683e+02, 2.3399918e+02); + expectedForces[119] = Vec3( 2.0781312e+02, 9.0531947e+01, 8.3513783e+01); + expectedForces[120] = Vec3( 2.9200105e+02, 1.0746865e+03, -6.0773727e+02); + expectedForces[121] = Vec3( -8.7546167e+02, 3.1969683e+02, 8.1033199e+01); + expectedForces[122] = Vec3( -5.3422658e+01, -3.8456585e+02, 1.4595003e+02); + expectedForces[123] = Vec3( -9.5134908e+01, 8.6818098e+02, -1.3111403e+03); + expectedForces[124] = Vec3( -7.2576830e+02, 6.3811172e+01, 7.0993488e+02); + expectedForces[125] = Vec3( 5.6200572e+02, -1.0972338e+03, -3.5278717e+02); + expectedForces[126] = Vec3( -1.6903718e+02, 2.6804112e+02, -8.9811032e+02); + expectedForces[127] = Vec3( 7.0934165e+02, -3.2328700e+02, 1.0037562e+02); + expectedForces[128] = Vec3( -2.5937738e+00, -3.3758145e+02, 3.6354335e+02); + expectedForces[129] = Vec3( -1.1993601e+03, 1.1618922e+02, -1.1329865e+03); + expectedForces[130] = Vec3( 8.3480845e+02, 5.2646427e+02, 9.1816763e+01); + expectedForces[131] = Vec3( 1.9407174e+02, 7.3877492e+00, 8.8648162e+02); + expectedForces[132] = Vec3( -1.0820540e+03, 2.7482390e+02, -1.4876848e+03); + expectedForces[133] = Vec3( 9.5717027e+02, -4.7758356e+02, 4.0692835e+02); + expectedForces[134] = Vec3( 2.4979896e+02, 7.1530552e+02, 6.5834243e+02); + expectedForces[135] = Vec3( -2.7549874e+02, 1.6613806e+03, -5.0628865e+02); + expectedForces[136] = Vec3( -1.5960544e+02, -4.5920421e+02, 9.4068762e+02); + expectedForces[137] = Vec3( 6.9764295e+01, -4.4024430e+02, -2.3545402e+02); + expectedForces[138] = Vec3( 2.0207569e+03, -2.6846158e+02, 3.3977998e+02); + expectedForces[139] = Vec3( -9.9905342e+02, 9.5155462e+02, 8.3259854e+01); + expectedForces[140] = Vec3( -8.0836255e+02, -6.3005196e+02, 1.2603525e+02); + expectedForces[141] = Vec3( 5.2279913e+02, 1.5356061e+03, -1.4399009e+02); + expectedForces[142] = Vec3( -1.3088783e+02, -9.0861449e+02, 9.7040422e+02); + expectedForces[143] = Vec3( 2.8006682e+01, -1.1783245e+03, -3.7285390e+02); + expectedForces[144] = Vec3( 6.1040927e+01, 2.1747286e+01, 9.0366011e+02); + expectedForces[145] = Vec3( 7.0396235e+02, -2.3865001e+02, -6.8794682e+02); + expectedForces[146] = Vec3( -5.1132933e+02, 7.7102556e+02, -4.7805042e+02); + expectedForces[147] = Vec3( 6.2879945e+02, -6.9758821e+02, 1.0983043e+03); + expectedForces[148] = Vec3( -9.2449123e+02, 5.0248042e+02, -2.0065211e+02); + expectedForces[149] = Vec3( -3.9485154e+02, 3.4679511e+02, -7.3889603e+02); + expectedForces[150] = Vec3( 4.9834751e+02, -1.0117501e+03, 1.2510946e+03); + expectedForces[151] = Vec3( -1.4942699e+02, -7.4362790e+01, -6.8008427e+02); + expectedForces[152] = Vec3( -1.8353666e+02, 5.1697483e+02, -8.4397292e+01); + expectedForces[153] = Vec3( 7.0253008e+02, -1.5361338e+02, 8.6830836e+02); + expectedForces[154] = Vec3( -4.1108898e+02, -6.8181350e+02, -5.6516951e+02); + expectedForces[155] = Vec3( 3.9294374e+02, 3.7294948e+02, -4.9795080e+02); + expectedForces[156] = Vec3( -7.3716758e+02, -5.5465931e+02, -9.3434525e+02); + expectedForces[157] = Vec3( 1.8240105e+02, 1.5494359e+02, 1.3626243e+02); + expectedForces[158] = Vec3( 9.3172059e+02, 1.4431275e+02, 6.6916065e+02); + expectedForces[159] = Vec3( 7.3399513e+01, -3.6000187e+02, 1.9853052e+03); + expectedForces[160] = Vec3( -2.4842520e+02, -4.0819514e+02, -8.0624794e+02); + expectedForces[161] = Vec3( 4.3585911e+02, -2.6521764e+02, -6.7985842e+02); + expectedForces[162] = Vec3( -8.2255783e+02, 1.1430906e+03, 1.2991183e+03); + expectedForces[163] = Vec3( 5.6437196e+02, -1.5391213e+02, -5.0013503e+02); + expectedForces[164] = Vec3( 3.8485296e+02, -1.1754088e+02, -1.4315511e+03); + expectedForces[165] = Vec3( 9.8205241e+02, 1.3278205e+01, 3.0367584e+02); + expectedForces[166] = Vec3( -3.2909916e+02, 4.5169387e+01, -3.2019488e+02); + expectedForces[167] = Vec3( -4.2382795e+02, -8.1938351e+02, -1.5360675e+02); + expectedForces[168] = Vec3( 9.1689997e+02, 1.4443113e+03, -1.8886795e+02); + expectedForces[169] = Vec3( -1.2161000e+03, -2.3826187e+02, 3.4004889e+02); + expectedForces[170] = Vec3( -2.2837927e+02, -9.8334152e+02, 3.0313790e+02); + expectedForces[171] = Vec3( 5.2598040e+02, -1.2766936e+03, 8.1247934e+01); + expectedForces[172] = Vec3( -6.7839687e+01, 6.9220160e+02, 3.1975320e+02); + expectedForces[173] = Vec3( -4.8519844e+02, 4.3008979e+02, -7.6788762e+02); + expectedForces[174] = Vec3( 3.9550092e+01, 1.0900122e+03, 5.0955281e+02); + expectedForces[175] = Vec3( -6.3000735e+02, -7.2335263e+02, -2.2590661e+02); + expectedForces[176] = Vec3( 1.5048762e+02, -4.0086126e+02, -1.2159849e+02); + expectedForces[177] = Vec3( -7.1939527e+02, -1.0640815e+03, -3.1826393e+02); + expectedForces[178] = Vec3( 7.7492135e+02, 1.0620129e+02, 3.6733165e+02); + expectedForces[179] = Vec3( -3.5466457e+02, 7.0081887e+02, 2.2629152e+02); + expectedForces[180] = Vec3( 3.0338275e+02, -1.1243396e+02, -1.3408996e+03); + expectedForces[181] = Vec3( 9.0394088e+00, 4.8818819e+02, 7.3781403e+02); + expectedForces[182] = Vec3( -5.6111982e+01, -2.5224925e+02, 3.0344460e+02); + expectedForces[183] = Vec3( -7.4693225e+02, 1.1370727e+03, 9.3958175e+02); + expectedForces[184] = Vec3( 3.1310327e+02, -1.2133761e+03, 2.6768166e+02); + expectedForces[185] = Vec3( 6.0706899e+02, 9.8403362e+01, -5.0781782e+02); + expectedForces[186] = Vec3( -6.2721609e+02, 1.7751567e+02, 2.6230643e+02); + expectedForces[187] = Vec3( 3.5425475e+02, -3.3336896e+02, 2.9529930e+02); + expectedForces[188] = Vec3( 4.7499029e+02, 4.5552354e+02, -2.4939310e+02); + expectedForces[189] = Vec3( 1.1556321e+02, 2.5995186e+02, -8.4171376e+02); + expectedForces[190] = Vec3( -4.5095184e+02, -1.6639362e+01, 4.2956175e+02); + expectedForces[191] = Vec3( -7.5904218e+01, 3.9416063e+02, 4.2573815e+02); + expectedForces[192] = Vec3( 2.3041013e+02, -1.2883920e+03, -5.1943189e+02); + expectedForces[193] = Vec3( 8.6086944e+01, 1.8626094e+02, 3.7641641e+02); + expectedForces[194] = Vec3( -5.9266805e+02, 4.4766229e+02, -4.5835497e+02); + expectedForces[195] = Vec3( 3.9368476e+02, 1.1050329e+03, -1.3906133e+03); + expectedForces[196] = Vec3( -1.2912212e+03, -2.9660534e+02, 3.9659215e+02); + expectedForces[197] = Vec3( -2.4803663e+01, -2.7945607e+02, 3.5315630e+02); + expectedForces[198] = Vec3( 1.4147479e+02, 3.2766723e+02, 1.1137899e+03); + expectedForces[199] = Vec3( 7.8383167e+01, 2.2385715e+00, -1.0346820e+03); + expectedForces[200] = Vec3( -2.9231551e+02, -5.4648720e+02, -6.5500265e+02); + expectedForces[201] = Vec3( 1.3708284e+03, -1.0716376e+03, 4.5781190e+02); + expectedForces[202] = Vec3( -7.5533654e+02, 6.5396686e+02, -4.2683276e+02); + expectedForces[203] = Vec3( -6.5558825e+02, 3.1164131e+02, 2.6323555e+02); + expectedForces[204] = Vec3( 1.3173432e+03, 1.3775889e+03, 1.2933072e+02); + expectedForces[205] = Vec3( -4.0922505e+02, -7.5709333e+02, -3.4967434e+02); + expectedForces[206] = Vec3( 4.2270572e+01, -7.4393359e+02, 5.2985443e+02); + expectedForces[207] = Vec3( -1.5327880e+03, 7.3186706e+02, -2.3440058e+02); + expectedForces[208] = Vec3( 1.4650210e+03, 2.8661572e+02, -2.4233049e+02); + expectedForces[209] = Vec3( 8.4124688e+02, -3.4020518e+02, -3.1773592e+01); + expectedForces[210] = Vec3( -1.1480436e+03, -7.4089732e+02, -4.8883682e+02); + expectedForces[211] = Vec3( 3.5682075e+02, 2.1918110e+01, -1.2558000e+02); + expectedForces[212] = Vec3( 1.6505256e+02, 7.9867933e+02, 9.9760760e+02); + expectedForces[213] = Vec3( 1.2477725e+03, -8.8687803e+02, -8.2498529e+02); + expectedForces[214] = Vec3( 1.7357042e+02, 2.0185456e+02, 8.0965301e+02); + expectedForces[215] = Vec3( -9.0937500e+02, 5.5968713e+01, 1.7581913e+02); + expectedForces[216] = Vec3( 1.3030711e+03, -8.2642443e+02, 1.6679926e+02); + expectedForces[217] = Vec3( -8.4295510e+02, 2.0237547e+01, 4.0163431e+02); + expectedForces[218] = Vec3( -3.2088719e+02, 3.0824476e+02, 9.9166532e+01); + expectedForces[219] = Vec3( 1.4585495e+03, -4.1497503e+01, -2.2539636e+02); + expectedForces[220] = Vec3( -2.6148433e+02, 1.7592075e+02, 2.0638296e+02); + expectedForces[221] = Vec3( -9.2100962e+02, 2.6090225e+02, -8.4461867e+02); + expectedForces[222] = Vec3( -9.0597287e+02, -4.8246138e+02, -1.8012972e+03); + expectedForces[223] = Vec3( -1.1775667e+02, 1.7275816e+02, 1.1286513e+03); + expectedForces[224] = Vec3( 1.0682239e+03, 8.0853797e+02, 2.5601774e+02); + expectedForces[225] = Vec3( -1.6637330e+02, 7.6165466e+02, -5.9394315e+02); + expectedForces[226] = Vec3( 2.6206832e+02, -1.5011747e+02, 5.4532792e+02); + expectedForces[227] = Vec3( -2.6474701e+02, -1.4218144e+02, 1.1099125e+02); + expectedForces[228] = Vec3( -9.7365994e+02, -5.5282012e+02, -6.3158992e+02); + expectedForces[229] = Vec3( 1.1482718e+03, 1.4958662e+02, -5.6523355e+02); + expectedForces[230] = Vec3( 4.4084982e+02, 7.9662251e+02, 4.9732039e+02); + expectedForces[231] = Vec3( -4.8746806e+02, -1.5522005e+03, 1.0133483e+03); + expectedForces[232] = Vec3( 1.1332903e+03, 1.2836176e+03, -2.0897082e+02); + expectedForces[233] = Vec3( -7.9973372e+01, 6.3066961e+02, -5.8656505e+02); + expectedForces[234] = Vec3( -8.3714021e+02, -1.5385924e+03, 1.0179672e+03); + expectedForces[235] = Vec3( 3.5358323e+02, 9.3554369e+02, 1.6565605e+02); + expectedForces[236] = Vec3( 1.7532341e+02, 3.0381323e+01, -1.2538424e+03); + expectedForces[237] = Vec3( -1.0437301e+03, -4.4804918e+02, 1.5276435e+03); + expectedForces[238] = Vec3( 8.5470872e+02, 1.0725550e+03, -9.7359443e+01); + expectedForces[239] = Vec3( 1.8192015e+02, -7.6967211e+01, -8.6054596e+02); + expectedForces[240] = Vec3( 1.5910180e+03, -7.9601605e+02, -8.4030326e+02); + expectedForces[241] = Vec3( -6.4638370e+02, 4.0538540e+02, 2.3396878e+01); + expectedForces[242] = Vec3( -5.2648918e+02, 1.3689201e+02, 9.3014716e+02); + expectedForces[243] = Vec3( 2.2248997e+02, -6.3647370e+02, -8.3913128e+02); + expectedForces[244] = Vec3( -7.5759832e+02, 4.7985429e+01, 5.8577833e+02); + expectedForces[245] = Vec3( 1.2983550e+02, 4.4401985e+02, 2.3556259e+02); + expectedForces[246] = Vec3( 7.8075637e+02, 9.9893821e+02, 7.3511307e+02); + expectedForces[247] = Vec3( -8.6411159e+02, 2.3812628e+02, 1.9007971e+02); + expectedForces[248] = Vec3( 2.0762263e+02, -7.0123789e+02, -4.8175733e+02); + expectedForces[249] = Vec3( -8.2749187e+02, -7.8772346e+02, -9.8536337e+02); + expectedForces[250] = Vec3( 8.3905893e+01, -2.8770518e+02, 6.0690561e+02); + expectedForces[251] = Vec3( 7.2280803e+02, 4.9294103e+02, -1.2915033e+02); + expectedForces[252] = Vec3( -1.3615809e+03, -1.8564754e+02, -4.2172817e+02); + expectedForces[253] = Vec3( 9.2102155e+02, 5.4063967e+02, -2.7291760e+02); + expectedForces[254] = Vec3( 7.0204283e+02, -3.0338605e+02, 6.6795953e+02); + expectedForces[255] = Vec3( -7.2261285e+00, 3.2570478e+02, 5.9010590e+02); + expectedForces[256] = Vec3( -8.3167819e+02, 3.0568475e+02, -9.9230441e+02); + expectedForces[257] = Vec3( 2.1074297e+02, -4.0099946e+01, -1.2770634e+02); + expectedForces[258] = Vec3( 1.1218559e+03, -8.8304672e+02, 1.0217945e+03); + expectedForces[259] = Vec3( -4.4730264e+01, 5.3616918e+02, -3.2704110e+02); + expectedForces[260] = Vec3( -1.1106141e+03, 3.3541536e+02, -1.0552986e+02); + expectedForces[261] = Vec3( -9.3728497e+01, 4.7397796e+01, -1.1294332e+03); + expectedForces[262] = Vec3( 5.1424956e+01, 4.0854995e+02, 5.6832607e+02); + expectedForces[263] = Vec3( 1.4286074e+02, 2.9172921e+01, 5.1355833e+02); + expectedForces[264] = Vec3( -4.4318133e+02, -9.5478293e+02, -1.8067439e+03); + expectedForces[265] = Vec3( -2.8083245e+02, 8.1414586e+02, 6.6089404e+02); + expectedForces[266] = Vec3( 1.0434876e+02, 3.0664078e+02, 1.3658532e+03); + expectedForces[267] = Vec3( 1.2999089e+03, 5.6746563e+02, 1.2200612e+03); + expectedForces[268] = Vec3( -5.9546942e+02, 3.6897149e+02, -8.3331437e+02); + expectedForces[269] = Vec3( -1.1094881e+03, -5.1903335e+02, -3.5729033e+02); + expectedForces[270] = Vec3( 4.1873464e+02, 6.9788983e+02, -1.3191929e+03); + expectedForces[271] = Vec3( -1.0086080e+02, 3.3114447e+02, 6.3419860e+02); + expectedForces[272] = Vec3( -2.8783906e+02, -8.8308011e+02, -5.4816768e+01); + expectedForces[273] = Vec3( 1.0254638e+03, 2.8710026e+02, -1.9779676e+02); + expectedForces[274] = Vec3( -3.5906548e+02, -5.5531449e+02, -6.0205492e+01); + expectedForces[275] = Vec3( -3.9578349e+02, 5.9217272e+01, 1.0735648e+02); + expectedForces[276] = Vec3( -8.7298871e+02, -1.5584711e+02, 9.2571354e+02); + expectedForces[277] = Vec3( 4.1520558e+02, 5.6442126e+02, -1.8142289e+02); + expectedForces[278] = Vec3( 6.5423421e+02, -4.1631573e+02, 1.0996479e+02); + expectedForces[279] = Vec3( -8.0063899e+01, -1.2880940e+03, 2.9304469e+02); + expectedForces[280] = Vec3( -9.5930841e+02, 5.8293485e+02, -1.1632205e+03); + expectedForces[281] = Vec3( 6.3492338e+02, 2.5550931e+02, 1.7380517e+02); + expectedForces[282] = Vec3( -1.9188175e+02, 1.0257290e+03, -8.6438702e+02); + expectedForces[283] = Vec3( 4.0063530e+01, -5.1808902e+02, 4.9556015e+02); + expectedForces[284] = Vec3( 5.8250018e+02, -2.5030700e+02, 1.1762860e+03); + expectedForces[285] = Vec3( -4.3195459e+02, 7.4733530e+02, -1.3002210e+03); + expectedForces[286] = Vec3( 2.7567334e+01, -5.1662654e+02, 3.3258050e+02); + expectedForces[287] = Vec3( 6.1700857e+02, 3.0016354e+02, 9.5519139e+02); + expectedForces[288] = Vec3( 7.7553094e+02, 8.6453551e+02, -1.0122996e+03); + expectedForces[289] = Vec3( -2.6730796e+02, -7.7560875e+02, 4.3195620e+02); + expectedForces[290] = Vec3( -8.5982146e+02, 1.6692057e+02, 4.3838169e+02); + expectedForces[291] = Vec3( 1.2945126e+03, 6.3231748e+02, -8.3020592e+02); + expectedForces[292] = Vec3( -6.9510729e+02, -3.1930013e+02, -1.3919425e+01); + expectedForces[293] = Vec3( -4.1154200e+02, -3.3562358e+02, 6.3292682e+02); + expectedForces[294] = Vec3( -4.0919783e+02, -3.8282298e+02, -4.9125465e+02); + expectedForces[295] = Vec3( 6.3932145e+02, -1.8769713e+01, 9.9241332e+01); + expectedForces[296] = Vec3( 8.6847663e+01, 8.7234739e+02, 2.7124112e+02); + expectedForces[297] = Vec3( -1.0307576e+03, -6.2447562e+02, -1.5796976e+03); + expectedForces[298] = Vec3( 6.2464595e+02, 1.0608165e+03, 3.1422521e+01); + expectedForces[299] = Vec3( 3.7767184e+02, 4.1170186e+02, 1.0696495e+03); + expectedForces[300] = Vec3( 1.0578030e+02, -1.9544726e+03, -4.6243957e+02); + expectedForces[301] = Vec3( -3.1074896e+02, 8.6738333e+02, -2.0241448e+02); + expectedForces[302] = Vec3( -2.7350519e+02, 6.9945273e+02, 7.8755130e+02); + expectedForces[303] = Vec3( 7.8083070e+02, 6.5199614e+02, -6.6698950e+02); + expectedForces[304] = Vec3( 1.3647451e+02, -4.2490411e+02, 1.3236061e+01); + expectedForces[305] = Vec3( -1.1048984e+03, 3.7582184e+02, -6.4718844e+01); + expectedForces[306] = Vec3( 1.5976050e+03, -8.9091819e+02, 9.7113419e+02); + expectedForces[307] = Vec3( -4.5545384e+01, 8.8683300e+02, -6.5927739e+01); + expectedForces[308] = Vec3( -1.3883497e+03, -4.6171498e+02, -2.9117829e+02); + expectedForces[309] = Vec3( -6.6661140e+02, -8.1394964e+02, 1.2397900e+03); + expectedForces[310] = Vec3( -2.5293546e+02, 1.8568554e+02, -6.8919479e+02); + expectedForces[311] = Vec3( 5.2052057e+02, 1.0288555e+03, 3.1435700e+02); + expectedForces[312] = Vec3( -2.4245555e+02, -1.1100993e+03, -1.6937710e+03); + expectedForces[313] = Vec3( 1.6647470e+02, 9.5272347e+02, 9.2528380e+02); + expectedForces[314] = Vec3( 8.6946518e+02, -1.6295251e+02, 5.7452409e+02); + expectedForces[315] = Vec3( 1.4059831e+02, 5.6780959e+02, -4.6024149e+02); + expectedForces[316] = Vec3( 2.3327811e+02, -2.2376697e+02, 1.3399582e+01); + expectedForces[317] = Vec3( -2.6583612e+01, -4.5801841e+02, 2.9595361e+01); + expectedForces[318] = Vec3( 1.2361796e+03, -1.9473934e+02, -2.6179421e+02); + expectedForces[319] = Vec3( -4.2330105e+02, 5.0768290e+02, 6.8352494e+02); + expectedForces[320] = Vec3( -2.0826312e+02, 1.4720747e+02, -9.8828425e-01); + expectedForces[321] = Vec3( -7.3226106e+02, -1.5366771e+01, 2.7882968e+02); + expectedForces[322] = Vec3( 4.2634684e+02, -6.2926647e+02, 3.6300784e+02); + expectedForces[323] = Vec3( 1.7826269e+02, 1.0038378e+02, -4.2408556e+02); + expectedForces[324] = Vec3( -1.1690005e+03, 2.1777241e+02, 9.1980300e+02); + expectedForces[325] = Vec3( 5.6841370e+02, -2.6614377e+02, -6.4968364e+01); + expectedForces[326] = Vec3( 3.5710749e+02, 1.3228373e+02, -3.6567433e+02); + expectedForces[327] = Vec3( 8.1957745e+02, 7.3903486e+02, 3.9487193e+02); + expectedForces[328] = Vec3( -8.5354740e+02, 8.9297958e+01, 9.0615539e+01); + expectedForces[329] = Vec3( -2.3935807e+02, -2.2950021e+02, -4.6193868e+01); + expectedForces[330] = Vec3( 8.6120406e+01, 1.4046499e+03, -1.5899345e+02); + expectedForces[331] = Vec3( 4.6319634e+02, -4.6309406e+02, -2.2891416e+02); + expectedForces[332] = Vec3( -4.2592255e+02, -2.6503000e+02, 6.1788141e+02); + expectedForces[333] = Vec3( -2.4468457e+02, -7.7827760e+02, 4.2470013e+02); + expectedForces[334] = Vec3( 2.6006448e+02, 7.6289112e+01, -4.3430411e+02); + expectedForces[335] = Vec3( -2.5268926e+02, 7.7381529e+02, -5.0896414e+02); + expectedForces[336] = Vec3( 1.0414844e+03, -6.1885512e+02, 1.4495539e+03); + expectedForces[337] = Vec3( -5.9522011e+01, 1.3607073e+03, -7.3705640e+01); + expectedForces[338] = Vec3( -5.9857094e+02, -2.7213045e+02, -9.7516268e+02); + expectedForces[339] = Vec3( 9.2852178e+02, 3.0121600e+02, -7.4982031e+00); + expectedForces[340] = Vec3( -1.0201472e+03, 1.6269359e+02, 1.9280960e+02); + expectedForces[341] = Vec3( -1.8744984e+02, -4.9790658e+02, 4.2841303e+02); + expectedForces[342] = Vec3( -1.0893114e+03, -4.6044565e+02, -2.0537532e+02); + expectedForces[343] = Vec3( 5.1068148e+02, -3.0889884e+02, 1.7703226e+01); + expectedForces[344] = Vec3( 2.0128423e+02, 5.0813056e+02, -5.0941772e+01); + expectedForces[345] = Vec3( -6.0195519e+02, 1.1710803e+03, -5.8271481e+02); + expectedForces[346] = Vec3( 1.3898239e+02, -3.2598252e+02, 1.0877023e+03); + expectedForces[347] = Vec3( 3.1630812e+02, -8.9974673e+02, 9.6573268e+01); + expectedForces[348] = Vec3( -5.5334313e+01, -1.1529065e+03, -2.1949997e+02); + expectedForces[349] = Vec3( -4.4904784e+02, 2.4036076e+02, 4.1328142e+02); + expectedForces[350] = Vec3( 1.0611611e+03, 4.1620143e+02, 9.1677657e+01); + expectedForces[351] = Vec3( 1.3489840e+03, 9.9500659e+02, -4.5894902e+01); + expectedForces[352] = Vec3( -9.8051252e+01, -9.0794586e+02, -8.9918421e+02); + expectedForces[353] = Vec3( -3.5567408e+02, -7.2914902e+01, 4.7977644e+01); + expectedForces[354] = Vec3( -1.5976501e+03, -1.2202674e+03, 7.2159213e+02); + expectedForces[355] = Vec3( 1.7391266e+02, 1.0197773e+03, -9.1284547e+02); + expectedForces[356] = Vec3( 7.8937287e+02, 1.1964969e+02, -3.8520683e+02); + expectedForces[357] = Vec3( 2.8170878e+02, 1.0377979e+03, -5.0609230e+02); + expectedForces[358] = Vec3( -4.0852118e+01, -4.3087314e+02, 4.1855459e+01); + expectedForces[359] = Vec3( -3.2767902e+02, -7.8083477e+02, 1.1111190e+03); + expectedForces[360] = Vec3( -1.0691030e+03, 3.1877408e+02, -7.9684323e+02); + expectedForces[361] = Vec3( 7.7603235e+02, 3.6577850e+02, -1.9093841e+02); + expectedForces[362] = Vec3( -4.7607360e+02, -5.1710653e+02, 7.2740737e+02); + expectedForces[363] = Vec3( 9.3461900e+02, 7.9988609e+01, -5.8055314e+02); + expectedForces[364] = Vec3( -9.8128918e+02, -2.6706371e+02, -3.5178135e+01); + expectedForces[365] = Vec3( -6.5196668e+02, 8.7618054e+02, 3.3040412e+02); + expectedForces[366] = Vec3( 5.5458970e+02, -1.1281839e+03, -8.2774754e+02); + expectedForces[367] = Vec3( 1.8491757e+02, -5.1421593e+01, 4.7068191e+02); + expectedForces[368] = Vec3( -4.3945944e+02, 8.2740025e+02, -2.1736033e+01); + expectedForces[369] = Vec3( -2.5609394e+02, -6.7141305e+02, -3.2964376e+02); + expectedForces[370] = Vec3( 1.4932730e+02, 2.2746635e+02, -3.7606156e+01); + expectedForces[371] = Vec3( 3.0873674e+02, 5.9974800e+02, 4.2207331e+02); + expectedForces[372] = Vec3( -3.8828932e+02, -2.1491002e+02, 1.5266506e+03); + expectedForces[373] = Vec3( 4.4495676e+02, 6.4708482e+02, -9.2222368e+02); + expectedForces[374] = Vec3( -4.8420767e+01, -4.3781484e+02, -5.0107314e+02); + expectedForces[375] = Vec3( 5.7593719e+02, -1.8140066e+03, -4.0189721e+02); + expectedForces[376] = Vec3( -5.1276233e+02, 6.6981030e+02, 3.9050744e+02); + expectedForces[377] = Vec3( 4.0809391e+02, 1.1596412e+03, -4.1325341e+02); + expectedForces[378] = Vec3( 1.4975560e+03, 1.7852942e+02, -7.6514466e+02); + expectedForces[379] = Vec3( -2.2890988e+02, 2.6128742e+02, 3.8545036e+02); + expectedForces[380] = Vec3( -3.8899762e+02, -2.5609958e+02, 2.0655882e+02); + expectedForces[381] = Vec3( -1.9500869e+02, -1.0947633e+03, -9.1786660e+02); + expectedForces[382] = Vec3( 8.6146884e+02, 2.5767444e+02, 3.6801549e+02); + expectedForces[383] = Vec3( -2.0008562e+02, 2.1549793e+02, 2.5175877e+02); + expectedForces[384] = Vec3( -5.6491749e+02, 5.4714989e+02, 3.1934114e+02); + expectedForces[385] = Vec3( 1.7665111e+02, -4.5297277e+02, 2.2387580e+02); + expectedForces[386] = Vec3( 6.2697664e+02, 1.1271358e+02, 2.9498078e+00); + expectedForces[387] = Vec3( -2.1918090e+03, -7.8914005e+01, 1.0632280e+03); + expectedForces[388] = Vec3( 7.5750278e+02, -5.0217666e+02, -1.3057335e+02); + expectedForces[389] = Vec3( 1.0621096e+03, 1.6022661e+01, -1.1645539e+03); + expectedForces[390] = Vec3( -4.7808938e+02, -1.2425496e+03, -1.5543074e+02); + expectedForces[391] = Vec3( -3.4676860e+02, 8.5391303e+02, 3.5351618e+01); + expectedForces[392] = Vec3( 5.4017203e+02, 8.6467815e+01, 1.1898140e+02); + expectedForces[393] = Vec3( -1.8873828e+01, 2.2133074e+02, -1.3378739e+03); + expectedForces[394] = Vec3( 7.5888012e+01, -1.6517743e+01, 1.1817186e+02); + expectedForces[395] = Vec3( 1.1912944e+02, -1.6083226e+02, 7.8733940e+02); + expectedForces[396] = Vec3( -1.2400005e+03, -3.9434827e+02, 1.4071802e+02); + expectedForces[397] = Vec3( 9.6249284e+02, 1.1394516e+02, -3.4977717e+02); + expectedForces[398] = Vec3( 2.4187486e+02, 1.3373651e+02, 6.5894105e+01); + expectedForces[399] = Vec3( 8.8628445e+02, 7.8083892e+01, -1.0288922e+03); + expectedForces[400] = Vec3( -9.4613057e+02, -1.9076053e+02, 6.7506442e+02); + expectedForces[401] = Vec3( -6.2746897e+02, 2.9376858e+02, 9.2767458e+02); + expectedForces[402] = Vec3( 5.5409175e+01, -1.2583442e+03, 7.1728490e+02); + expectedForces[403] = Vec3( -2.9076856e+02, 7.5539656e+02, 7.0121763e+00); + expectedForces[404] = Vec3( 2.6220897e+02, -9.5606102e+01, -7.7725998e+02); + expectedForces[405] = Vec3( -8.6582014e+02, 9.5597761e+02, 1.5941783e+02); + expectedForces[406] = Vec3( -1.6910265e+02, -7.2646192e+02, -3.5476587e+02); + expectedForces[407] = Vec3( 9.7629076e+02, -8.3969437e+01, 2.5523637e+02); + expectedForces[408] = Vec3( -4.9553396e+01, 6.3557270e+02, -7.5908312e+02); + expectedForces[409] = Vec3( 3.3210227e+01, 1.5198340e+02, 7.0322192e+02); + expectedForces[410] = Vec3( -2.6532687e+01, -4.1589199e+02, 4.2771258e+02); + expectedForces[411] = Vec3( 1.1412630e+03, -2.7366656e+02, 9.8419548e+02); + expectedForces[412] = Vec3( -3.7239786e+02, 7.2244667e+01, -9.9502150e+02); + expectedForces[413] = Vec3( -4.6476941e+02, -6.1433607e+01, -2.5459288e+02); + expectedForces[414] = Vec3( 9.7028883e+02, 5.5981848e+02, 8.4425262e+02); + expectedForces[415] = Vec3( 7.2811577e+01, 2.2872709e+02, -1.3822700e+03); + expectedForces[416] = Vec3( -1.0105821e+03, -2.8444698e+02, -7.2506392e+02); + expectedForces[417] = Vec3( 1.0027865e+03, 6.0924816e+02, -5.7818592e+01); + expectedForces[418] = Vec3( -3.4173955e+02, -1.1932310e+02, -2.9495449e+01); + expectedForces[419] = Vec3( -2.7281265e+02, -1.8869212e+02, 1.9643932e+02); + expectedForces[420] = Vec3( -7.4036328e+02, -4.8733524e+02, 1.5862094e+03); + expectedForces[421] = Vec3( 5.6387864e+02, 3.0991659e+02, -8.6746725e+02); + expectedForces[422] = Vec3( 6.2954421e-01, 4.9665567e+02, -1.0114913e+03); + expectedForces[423] = Vec3( 8.9668630e+02, -1.0121499e+03, -1.1520006e+03); + expectedForces[424] = Vec3( -2.5699741e+02, 3.3243520e+02, 7.6038873e+02); + expectedForces[425] = Vec3( -1.2755484e+03, -2.7786159e+01, 3.0900583e+02); + expectedForces[426] = Vec3( -1.2587339e+03, -8.6851333e+02, 1.6295957e+02); + expectedForces[427] = Vec3( 6.4923970e+02, 4.4600015e+02, 3.3033348e+02); + expectedForces[428] = Vec3( 5.8905637e+02, -1.1589062e+02, -1.8168184e+02); + expectedForces[429] = Vec3( -1.1223714e+03, 3.0322406e+01, 8.7272053e+02); + expectedForces[430] = Vec3( 3.0982625e+02, 3.1418220e+02, -3.9301742e+02); + expectedForces[431] = Vec3( 2.4213933e+02, -7.2382572e+02, -1.0155346e+03); + expectedForces[432] = Vec3( 1.1479692e+03, -1.6837721e+03, 1.0545407e+02); + expectedForces[433] = Vec3( -8.2496264e+02, 6.0540594e+02, 1.3979931e+02); + expectedForces[434] = Vec3( -6.8171514e+02, 4.0392791e+02, -3.4712316e+02); + expectedForces[435] = Vec3( -1.5568889e+02, -1.4652975e+03, 5.1518148e+01); + expectedForces[436] = Vec3( 5.6573856e+02, 3.5494119e+02, -3.3796345e+02); + expectedForces[437] = Vec3( -1.3938679e+02, 4.2296152e+02, -2.0539863e+02); + expectedForces[438] = Vec3( 8.9203493e+01, 2.8764597e+02, -7.3273496e+02); + expectedForces[439] = Vec3( 4.3114292e+02, 9.4778082e+01, 1.8894761e+02); + expectedForces[440] = Vec3( -2.2798193e+01, -4.5460891e+01, 9.8310963e+01); + expectedForces[441] = Vec3( -2.1793579e+02, -1.0807542e+03, -2.3470465e+01); + expectedForces[442] = Vec3( 1.3881360e+02, 3.9806903e+02, 4.1089741e+01); + expectedForces[443] = Vec3( -4.5604974e+02, 4.8515999e+02, -6.6025174e+02); + expectedForces[444] = Vec3( 3.6437700e+02, -8.1622511e+02, -9.6454258e+02); + expectedForces[445] = Vec3( 3.1998690e+02, -3.3342314e+02, 1.2441763e+03); + expectedForces[446] = Vec3( 3.0822409e+01, 2.0596612e+02, 2.0937122e+02); + expectedForces[447] = Vec3( -8.4938718e+02, -1.1366483e+03, -1.3638049e+02); + expectedForces[448] = Vec3( -5.5232451e+01, 4.7335097e+02, -5.4433565e+02); + expectedForces[449] = Vec3( 6.5928852e+02, 1.7488804e+02, 6.7879378e+02); + expectedForces[450] = Vec3( -9.4572079e+02, 1.9162420e+02, 4.7935043e+02); + expectedForces[451] = Vec3( 2.5029547e+02, 3.6606767e+01, -9.3423713e+01); + expectedForces[452] = Vec3( 1.6543841e+02, -1.1892943e+02, -5.8737050e+02); + expectedForces[453] = Vec3( -9.8495219e+02, -1.6882428e+03, -4.0576035e+02); + expectedForces[454] = Vec3( 7.9182557e+02, 5.3997699e+02, 3.3231603e+02); + expectedForces[455] = Vec3( 1.8277090e+01, 1.4623150e+03, -9.4985721e+01); + expectedForces[456] = Vec3( -1.0471948e+03, 4.6746395e+02, -1.5020000e+03); + expectedForces[457] = Vec3( 7.2055316e+02, -5.4467216e+02, 4.0459421e+02); + expectedForces[458] = Vec3( 7.5475531e+01, 4.9532870e+02, 1.3002474e+03); + expectedForces[459] = Vec3( 6.3589773e+02, -2.1402397e+02, -1.4147509e+03); + expectedForces[460] = Vec3( 2.8391861e+02, -8.0142885e+01, 5.6445225e+02); + expectedForces[461] = Vec3( -8.2442674e+02, 5.3520687e+02, 1.1406667e+03); + expectedForces[462] = Vec3( -5.7988771e+02, -3.3512887e+02, 4.5461752e+02); + expectedForces[463] = Vec3( 4.5746059e+02, 3.1029926e+02, -5.0060176e+02); + expectedForces[464] = Vec3( 7.7747136e+02, 4.2131732e+02, 5.5836239e+02); + expectedForces[465] = Vec3( -1.2315491e+03, 9.4066088e+02, 9.6145313e+02); + expectedForces[466] = Vec3( 7.9043841e+02, -2.2172613e+02, -2.6508587e+02); + expectedForces[467] = Vec3( 7.8197894e+02, -3.1383822e+02, 2.5444013e+02); + expectedForces[468] = Vec3( -7.1139498e+01, -7.1203189e+01, -4.6845544e+02); + expectedForces[469] = Vec3( -8.9774100e+01, 1.4389287e+02, 9.8957451e+01); + expectedForces[470] = Vec3( 3.0397922e+02, -2.8247850e+01, 4.4896034e+02); + expectedForces[471] = Vec3( -9.7808367e+02, 1.0170553e+03, 8.1594649e+02); + expectedForces[472] = Vec3( 1.8933676e+02, -8.8053046e+02, 6.8784042e+01); + expectedForces[473] = Vec3( 5.1636668e+02, 1.2970985e+02, -8.9380858e+02); + expectedForces[474] = Vec3( -5.8549608e+02, -1.8351156e+02, -5.8043066e+02); + expectedForces[475] = Vec3( 2.7877663e+02, -3.6576715e+02, 3.5497095e+02); + expectedForces[476] = Vec3( 3.0642370e+02, 5.3438407e+02, 1.9409584e+02); + expectedForces[477] = Vec3( -4.8523805e+02, 1.2253320e+03, 9.6414379e+02); + expectedForces[478] = Vec3( -1.5213013e+02, -2.0017205e+02, -6.6602643e+02); + expectedForces[479] = Vec3( 4.6435225e+02, -4.1945066e+02, -8.6774270e+01); + expectedForces[480] = Vec3( 2.4946889e+02, -1.0456281e+03, 4.7404434e+02); + expectedForces[481] = Vec3( -3.0813505e+01, 2.8598938e+02, 7.7374350e+01); + expectedForces[482] = Vec3( -2.4538851e+02, 3.8306987e+02, -5.0235520e+02); + expectedForces[483] = Vec3( 4.0348805e+01, 1.3050360e+03, -6.8725580e+02); + expectedForces[484] = Vec3( -1.1095514e+02, -2.7711572e+02, 2.6929959e+02); + expectedForces[485] = Vec3( -6.8071081e+01, -3.4398150e+02, 2.5209743e+02); + expectedForces[486] = Vec3( 2.1534786e+03, 1.3249493e+01, 7.4171165e+01); + expectedForces[487] = Vec3( -7.2618755e+02, -3.2914219e+02, 2.5917332e+02); + expectedForces[488] = Vec3( -1.0231949e+03, 7.2426062e+02, 1.9111862e+02); + expectedForces[489] = Vec3( 1.1408866e+03, 6.7858353e+02, -2.1410916e+02); + expectedForces[490] = Vec3( -4.5559047e+02, -1.3597950e+02, -3.2284091e+02); + expectedForces[491] = Vec3( -8.5558133e+02, -7.1748324e+01, 5.3332261e+02); + expectedForces[492] = Vec3( -7.1393886e+02, -1.1275222e+03, -6.2147584e+02); + expectedForces[493] = Vec3( 4.4029614e+02, 1.0518224e+02, 4.6519788e+02); + expectedForces[494] = Vec3( -3.5770378e+02, 1.0311834e+03, 2.2141802e+02); + expectedForces[495] = Vec3( -2.6023787e+02, 1.0070248e+03, -1.1113552e+03); + expectedForces[496] = Vec3( -3.4950242e+02, 2.8418846e+01, 1.2865161e+03); + expectedForces[497] = Vec3( 1.5030225e+02, -7.7257505e+02, 8.7232628e+02); + expectedForces[498] = Vec3( -1.7416695e+02, 9.9945569e+02, -1.6742483e+02); + expectedForces[499] = Vec3( 2.0837481e+02, -1.9388709e+02, 9.7409815e+01); + expectedForces[500] = Vec3( -1.0129845e+02, -6.8652976e+02, 8.4930186e+02); + expectedForces[501] = Vec3( 1.2276099e+03, 1.6531986e+02, 3.6342506e+02); + expectedForces[502] = Vec3( -1.9998077e+02, -2.6164759e+02, -1.6601933e+02); + expectedForces[503] = Vec3( -4.0356327e+02, 4.0549152e+02, 2.9710052e+02); + expectedForces[504] = Vec3( -7.3045150e+02, -1.6677706e+03, -9.8671765e+02); + expectedForces[505] = Vec3( -2.1441879e+02, 1.4962605e+03, 5.6350856e+02); + expectedForces[506] = Vec3( 7.1102593e+02, 5.9407971e+02, 9.5452239e+02); + expectedForces[507] = Vec3( 3.2291041e+02, 1.3943261e+03, -1.8477432e+03); + expectedForces[508] = Vec3( -1.7778104e+02, 2.8034575e+02, 1.1385089e+03); + expectedForces[509] = Vec3( -2.4943297e+02, -9.0965773e+02, 5.2737490e+02); + expectedForces[510] = Vec3( -3.8318508e+02, 1.3999092e+03, -5.9960180e+02); + expectedForces[511] = Vec3( 2.6930065e+01, -3.6603454e+02, 1.0460530e+03); + expectedForces[512] = Vec3( -1.8964668e+02, -1.1663184e+03, -2.8438291e+02); + expectedForces[513] = Vec3( -9.4679273e+02, 8.7408257e+01, -2.5740702e+02); + expectedForces[514] = Vec3( 1.6558849e+02, 3.3561310e+02, 3.8532718e+02); + expectedForces[515] = Vec3( 4.0403504e+02, -8.5545173e+02, 4.0647038e+02); + expectedForces[516] = Vec3( 8.3825526e+02, 5.0343638e+01, -3.9171626e+02); + expectedForces[517] = Vec3( -4.0069871e+02, -6.4140295e+02, 7.5218861e+01); + expectedForces[518] = Vec3( -6.5213072e+02, 4.1689581e+02, -8.9280241e+01); + expectedForces[519] = Vec3( 4.0832996e+02, -3.4272605e+02, -9.2740030e+02); + expectedForces[520] = Vec3( -2.1128040e+01, -7.3467005e+02, 6.5449252e+02); + expectedForces[521] = Vec3( -2.8042421e+02, 3.3193211e+02, 5.1272473e+02); + expectedForces[522] = Vec3( -1.2057322e+03, 3.3276609e+02, 6.8838073e+02); + expectedForces[523] = Vec3( 8.9270663e+02, 1.3914748e+02, -8.7213182e+02); + expectedForces[524] = Vec3( 8.8063936e+02, -2.4952564e+02, -8.3942753e+01); + expectedForces[525] = Vec3( 3.6527919e+02, 3.3758036e+02, -1.3449147e+03); + expectedForces[526] = Vec3( 7.1836993e+01, -3.9380031e+01, 4.7169292e+02); + expectedForces[527] = Vec3( -7.2114939e+01, -1.3679457e+02, 3.9080695e+02); + expectedForces[528] = Vec3( 1.1465645e+02, -4.4994719e+02, -3.4180224e+02); + expectedForces[529] = Vec3( -6.0950292e+01, 4.2825716e+02, -1.4233246e+02); + expectedForces[530] = Vec3( -1.9112828e+02, -2.8511065e+00, 2.6894050e+02); + expectedForces[531] = Vec3( 4.4955085e+02, 2.0459389e+02, 8.9486972e+02); + expectedForces[532] = Vec3( 6.6339624e+01, -4.2734850e+01, -4.8004048e+02); + expectedForces[533] = Vec3( -5.0521801e+02, -1.6330265e+02, -6.2374206e+02); + expectedForces[534] = Vec3( -1.1019306e+03, -4.5760347e+02, 4.6134602e+01); + expectedForces[535] = Vec3( 4.9278700e+02, 8.0495847e+02, -5.7470233e+01); + expectedForces[536] = Vec3( 9.9361557e+02, -2.4453172e+02, -3.7696369e+02); + expectedForces[537] = Vec3( -1.1168499e+03, -2.1108925e+02, -4.1233970e+02); + expectedForces[538] = Vec3( 5.6559058e+02, -2.8153614e+02, 3.0539700e+02); + expectedForces[539] = Vec3( 4.0805303e+02, 2.8796083e+02, -3.0009135e+01); + expectedForces[540] = Vec3( -8.5249075e+02, -1.0560038e+03, -6.5111795e+02); + expectedForces[541] = Vec3( 8.4653565e+02, 2.0615416e+02, -1.5085906e+02); + expectedForces[542] = Vec3( -2.8200251e+02, 6.6950966e+02, 5.9661450e+02); + expectedForces[543] = Vec3( -9.3339994e+01, 8.7084190e+02, -7.8375352e+02); + expectedForces[544] = Vec3( 1.4187243e+02, 1.2829809e+02, 8.0626841e+02); + expectedForces[545] = Vec3( 1.5403073e+02, -4.5932125e+02, -8.3051878e+00); + expectedForces[546] = Vec3( 1.3919197e+03, 5.4728737e+02, -1.0548033e+03); + expectedForces[547] = Vec3( -2.7215065e+02, 1.5112718e+02, 6.7366542e+02); + expectedForces[548] = Vec3( -7.8677637e+02, -2.6895175e+02, 4.3374996e+02); + expectedForces[549] = Vec3( 6.6014864e+02, -1.1474704e+03, -3.7199889e+02); + expectedForces[550] = Vec3( -5.8741315e+02, 2.6286109e+02, 1.9036264e+02); + expectedForces[551] = Vec3( 1.4325969e+02, 7.8928381e+02, 3.6304214e+02); + expectedForces[552] = Vec3( -9.6661866e+02, -1.0462801e+03, -6.3261994e+02); + expectedForces[553] = Vec3( 5.5171916e+02, 2.8672800e+02, 2.7240662e+02); + expectedForces[554] = Vec3( 1.1625052e+03, 7.7864110e+02, -5.2588322e+02); + expectedForces[555] = Vec3( 1.7042269e+03, -5.8973225e+02, 1.4814500e+02); + expectedForces[556] = Vec3( -7.7324022e+02, 2.9167426e+02, -1.0262563e+02); + expectedForces[557] = Vec3( -5.4655014e+02, -8.4339654e+01, 9.7375629e+02); + expectedForces[558] = Vec3( -6.9618127e+02, -1.6878530e+02, 7.1078501e+02); + expectedForces[559] = Vec3( 6.9623995e+02, -3.7038954e+01, 2.2671528e+02); + expectedForces[560] = Vec3( -7.1025694e+01, -1.8643963e+02, -8.0181026e+02); + expectedForces[561] = Vec3( -1.4598467e+02, 1.7170707e+03, -4.3305456e+02); + expectedForces[562] = Vec3( 7.9582463e+02, -5.9551245e+02, 8.3485625e+01); + expectedForces[563] = Vec3( -4.6812643e+02, -3.4598874e+02, -3.6753356e+01); + expectedForces[564] = Vec3( -1.8586268e+02, 3.1377143e+02, -1.6616022e+03); + expectedForces[565] = Vec3( 7.4400496e+02, 5.5058789e+02, 7.5374599e+02); + expectedForces[566] = Vec3( -6.3347529e+02, -3.1407006e+02, 8.2964691e+02); + expectedForces[567] = Vec3( -4.2499528e+02, 9.4575975e+02, -6.6700103e+02); + expectedForces[568] = Vec3( -9.2637696e+02, -6.6301622e+02, 3.9913705e+02); + expectedForces[569] = Vec3( 5.0588430e+02, -8.1942697e+01, 4.2128365e+02); + expectedForces[570] = Vec3( 2.7165158e+02, 2.7387902e+02, 1.0850277e+03); + expectedForces[571] = Vec3( -6.8391471e+00, -1.2886307e+02, -5.3501450e+02); + expectedForces[572] = Vec3( -2.9936240e+02, -2.2085475e+02, -6.9670281e+01); + expectedForces[573] = Vec3( 1.6853422e+02, 4.8410887e+02, 1.0517406e+03); + expectedForces[574] = Vec3( -4.9287521e+02, 1.6557733e+01, -3.4008916e+02); + expectedForces[575] = Vec3( 1.1132397e+02, -9.8734894e+02, -1.1154151e+02); + expectedForces[576] = Vec3( 3.8645582e+02, 4.3709361e+02, 1.4861132e+03); + expectedForces[577] = Vec3( -1.0169967e+03, -3.5279110e+02, -5.4860861e+02); + expectedForces[578] = Vec3( 2.8875246e+02, 5.3726711e+01, -5.9395936e+02); + expectedForces[579] = Vec3( 1.5169994e+03, 8.7535209e+01, 1.0103159e+03); + expectedForces[580] = Vec3( -1.9439968e+02, -7.9639200e+02, -1.0439069e+03); + expectedForces[581] = Vec3( -8.7374025e+02, 2.0597360e+02, 1.0218319e+02); + expectedForces[582] = Vec3( 6.4275846e+02, -6.2671529e+02, 8.9274592e+02); + expectedForces[583] = Vec3( -5.4449356e+01, 7.2615928e+02, -9.1355057e+02); + expectedForces[584] = Vec3( -2.7242606e+02, 3.9376960e+02, -4.7692581e+01); + expectedForces[585] = Vec3( 2.6578654e+02, -6.7385441e+02, -1.5306127e+03); + expectedForces[586] = Vec3( 5.1049761e+02, 7.3430855e+02, 6.1178168e+02); + expectedForces[587] = Vec3( -3.3593193e+02, 3.5079666e+01, 9.7444298e+02); + expectedForces[588] = Vec3( -7.8227654e+01, -1.1050481e+03, 1.4161574e+03); + expectedForces[589] = Vec3( -7.6753407e+02, 9.7291633e+02, 1.9943116e+02); + expectedForces[590] = Vec3( 2.9274184e+02, -2.5706985e+01, -5.8944290e+02); + expectedForces[591] = Vec3( -1.2502829e+03, 2.2304820e+02, -8.8573767e+02); + expectedForces[592] = Vec3( 1.2218682e+02, -8.2110835e+02, 3.4276058e+02); + expectedForces[593] = Vec3( 8.9529566e+02, -1.8417573e+02, 8.4717919e+02); + expectedForces[594] = Vec3( -4.6475772e+01, -1.5493620e+03, 4.8004365e+02); + expectedForces[595] = Vec3( 6.7104033e+02, 4.7267915e+02, -6.2630817e+02); + expectedForces[596] = Vec3( -2.2771561e+02, 2.7463551e+02, -2.9704610e+00); + expectedForces[597] = Vec3( 1.7757815e+02, -1.8906761e+03, -1.6656886e+02); + expectedForces[598] = Vec3( -7.4745588e+01, 1.0353962e+03, 4.2924498e+02); + expectedForces[599] = Vec3( -5.5648197e+02, 7.7838572e+02, -4.1677346e+02); + expectedForces[600] = Vec3( -5.2972489e+02, 1.1967117e+02, 1.0565388e+03); + expectedForces[601] = Vec3( 7.8379665e+02, -4.1803420e+02, 2.0308387e+02); + expectedForces[602] = Vec3( 1.2705528e+02, 1.1663435e+02, -7.6514830e+02); + expectedForces[603] = Vec3( -1.5203094e+03, -8.5825144e+01, -2.3039380e+02); + expectedForces[604] = Vec3( 5.2063739e+02, -1.7259834e+02, -2.9854160e+01); + expectedForces[605] = Vec3( 4.7448961e+02, 2.8282389e+02, 3.4257463e+01); + expectedForces[606] = Vec3( 1.4519531e+03, -1.2031444e+03, -6.7084095e+02); + expectedForces[607] = Vec3( -7.5308994e+02, -3.2117501e+02, 5.7700017e+02); + expectedForces[608] = Vec3( -1.7643179e+02, 8.5655779e+02, -2.6285482e+02); + expectedForces[609] = Vec3( -1.3868959e+03, -1.6195505e+01, -1.3783528e+03); + expectedForces[610] = Vec3( 2.8034476e+02, -4.2360778e+02, 4.5904202e+02); + expectedForces[611] = Vec3( 1.0938532e+03, 6.2455629e+02, -1.0108636e+02); + expectedForces[612] = Vec3( 9.1439974e+01, -7.2813810e+02, 1.0197075e+03); + expectedForces[613] = Vec3( 1.4048294e+02, 2.5667744e+02, -5.1914694e+02); + expectedForces[614] = Vec3( -2.5604629e+01, 2.9915218e+01, -5.1582702e+02); + expectedForces[615] = Vec3( 2.0331673e+02, 1.5538650e+02, -1.1836865e+03); + expectedForces[616] = Vec3( -2.3788957e+02, -1.1872269e+02, 9.7052698e+02); + expectedForces[617] = Vec3( -3.2419551e+01, -1.8828745e+02, 4.3037423e+02); + expectedForces[618] = Vec3( -4.8585762e+02, 1.4114027e+02, 1.6021114e+02); + expectedForces[619] = Vec3( 2.8744134e+02, -5.7197623e+02, -1.8323508e+02); + expectedForces[620] = Vec3( 2.3652930e+02, -1.5448350e+01, 2.1721186e+01); + expectedForces[621] = Vec3( 1.1684581e+03, 2.2790484e+02, 2.7798348e+02); + expectedForces[622] = Vec3( -4.6823976e+02, -6.1804544e+02, 2.7193441e+02); + expectedForces[623] = Vec3( -5.8173089e+02, 4.4573870e+02, -6.0699430e+02); + expectedForces[624] = Vec3( 7.9759250e+02, 1.8480473e+03, -5.1434277e+02); + expectedForces[625] = Vec3( -1.0945975e+03, -6.0402685e+02, 1.5843017e+02); + expectedForces[626] = Vec3( 1.2334392e+02, -9.5602838e+02, 7.8137824e+02); + expectedForces[627] = Vec3( -8.5863208e+02, -5.7413454e+02, 1.7014217e+02); + expectedForces[628] = Vec3( -1.2232569e+02, 6.0505774e+02, -1.6806693e+02); + expectedForces[629] = Vec3( 6.1488135e+02, 4.1603705e+02, 2.1121948e+02); + expectedForces[630] = Vec3( 2.1858899e+02, 1.2961013e+03, 4.8534041e+02); + expectedForces[631] = Vec3( 2.1292701e+02, -4.1049165e+02, 3.9057142e+00); + expectedForces[632] = Vec3( -6.3342469e+02, -8.7529004e+02, 6.1928550e+01); + expectedForces[633] = Vec3( -7.3207079e+02, -1.3874807e+03, 8.6303032e+02); + expectedForces[634] = Vec3( 6.6660351e+02, 9.5813895e+02, -1.4555416e+02); + expectedForces[635] = Vec3( 4.1800653e+02, 2.4677420e+02, -1.1424272e+03); + expectedForces[636] = Vec3( 8.3570430e+02, -1.5342969e+03, -1.2510269e+03); + expectedForces[637] = Vec3( -3.0635229e+02, 1.2465088e+03, -1.9679529e+01); + expectedForces[638] = Vec3( -6.5317178e+02, -1.6432929e+02, 9.2427724e+02); + expectedForces[639] = Vec3( 1.5665680e+03, 9.8040004e+01, 1.0786497e+02); + expectedForces[640] = Vec3( -4.6590380e+02, -3.7603795e+02, -9.4955273e+02); + expectedForces[641] = Vec3( -8.7572108e+02, 5.1750570e+02, -1.2268062e+02); + expectedForces[642] = Vec3( 1.1575067e+03, -2.2857204e+02, -2.3816900e+02); + expectedForces[643] = Vec3( -2.6229644e+02, 3.1069110e+02, -1.2098536e+02); + expectedForces[644] = Vec3( -1.8195659e+02, -3.8984698e+02, 6.4622752e+02); + expectedForces[645] = Vec3( 1.0756277e+03, 2.7459106e+01, 1.0850508e+03); + expectedForces[646] = Vec3( -6.4620310e+02, 2.5885783e+02, -2.0567224e+02); + expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02); double tolerance = 1.0e-03; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } @@ -2656,7 +2656,7 @@ static void testParticleInducedDipoles() { // test computation of system multipole moments -static void testSystemMultipoleMoments( FILE* log ) { +static void testSystemMultipoleMoments(FILE* log) { std::string testName = "testSystemMultipoleMoments"; @@ -2670,9 +2670,9 @@ static void testSystemMultipoleMoments( FILE* log ) { std::vector< Vec3 > inputGrid; std::vector< double > outputGridPotential; - setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log ); + setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, testName, + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log); std::vector tinkerMoments(4); @@ -2691,22 +2691,22 @@ static void testSystemMultipoleMoments( FILE* log ) { // tinkerMoments[12] = 4.3292490e-02; double tolerance = 1.0e-04; - if( log ){ - (void) fprintf( log, "%s RelativeDifference Tinker OpenMM\n", testName.c_str() ); + if (log) { + (void) fprintf(log, "%s RelativeDifference Tinker OpenMM\n", testName.c_str()); } - for( unsigned int ii = 0; ii < tinkerMoments.size(); ii++ ){ + for (unsigned int ii = 0; ii < tinkerMoments.size(); ii++) { double difference; - if( fabs( tinkerMoments[ii] ) > 0.0 ){ - difference = fabs( outputMultipoleMoments[ii] - tinkerMoments[ii] )/fabs( tinkerMoments[ii] ); + if (fabs(tinkerMoments[ii]) > 0.0) { + difference = fabs(outputMultipoleMoments[ii] - tinkerMoments[ii])/fabs(tinkerMoments[ii]); } else { - difference = fabs( outputMultipoleMoments[ii] - tinkerMoments[ii] ); + difference = fabs(outputMultipoleMoments[ii] - tinkerMoments[ii]); } - if( log ){ - (void) fprintf( log, "%2d %15.7e %15.7e %15.7e\n", ii, difference, tinkerMoments[ii], outputMultipoleMoments[ii] ); + if (log) { + (void) fprintf(log, "%2d %15.7e %15.7e %15.7e\n", ii, difference, tinkerMoments[ii], outputMultipoleMoments[ii]); } - if( difference > tolerance ){ + if (difference > tolerance) { std::stringstream details; details << testName << "Multipole moment " << ii << " does not agree w/ TINKER computed moments: OpenMM=" << outputMultipoleMoments[ii]; details << " TINKER=" << tinkerMoments[ii] << " difference=" << difference; @@ -2719,7 +2719,7 @@ static void testSystemMultipoleMoments( FILE* log ) { // test computation of multipole potential on a grid -static void testMultipoleGridPotential( FILE* log ) { +static void testMultipoleGridPotential(FILE* log) { std::string testName = "testMultipoleGridPotential"; @@ -2735,40 +2735,40 @@ static void testMultipoleGridPotential( FILE* log ) { int gridSize = 27; std::vector inputGrid(gridSize); - inputGrid[0] = Vec3( -1.0318535e+00, -1.0224502e+00, -1.0202836e+00); - inputGrid[1] = Vec3( -1.0318535e+00, -1.0224502e+00, -3.4032700e-02); - inputGrid[2] = Vec3( -1.0318535e+00, -1.0224502e+00, 9.5221820e-01); - inputGrid[3] = Vec3( -1.0318535e+00, -3.0961200e-02, -1.0202836e+00); - inputGrid[4] = Vec3( -1.0318535e+00, -3.0961200e-02, -3.4032700e-02); - inputGrid[5] = Vec3( -1.0318535e+00, -3.0961200e-02, 9.5221820e-01); - inputGrid[6] = Vec3( -1.0318535e+00, 9.6052780e-01, -1.0202836e+00); - inputGrid[7] = Vec3( -1.0318535e+00, 9.6052780e-01, -3.4032700e-02); - inputGrid[8] = Vec3( -1.0318535e+00, 9.6052780e-01, 9.5221820e-01); - inputGrid[9] = Vec3( -3.3969000e-02, -1.0224502e+00, -1.0202836e+00); - inputGrid[10] = Vec3( -3.3969000e-02, -1.0224502e+00, -3.4032700e-02); - inputGrid[11] = Vec3( -3.3969000e-02, -1.0224502e+00, 9.5221820e-01); - inputGrid[12] = Vec3( -3.3969000e-02, -3.0961200e-02, -1.0202836e+00); - inputGrid[13] = Vec3( -3.3969000e-02, -3.0961200e-02, -3.4032700e-02); - inputGrid[14] = Vec3( -3.3969000e-02, -3.0961200e-02, 9.5221820e-01); - inputGrid[15] = Vec3( -3.3969000e-02, 9.6052780e-01, -1.0202836e+00); - inputGrid[16] = Vec3( -3.3969000e-02, 9.6052780e-01, -3.4032700e-02); - inputGrid[17] = Vec3( -3.3969000e-02, 9.6052780e-01, 9.5221820e-01); - inputGrid[18] = Vec3( 9.6391550e-01, -1.0224502e+00, -1.0202836e+00); - inputGrid[19] = Vec3( 9.6391550e-01, -1.0224502e+00, -3.4032700e-02); - inputGrid[20] = Vec3( 9.6391550e-01, -1.0224502e+00, 9.5221820e-01); - inputGrid[21] = Vec3( 9.6391550e-01, -3.0961200e-02, -1.0202836e+00); - inputGrid[22] = Vec3( 9.6391550e-01, -3.0961200e-02, -3.4032700e-02); - inputGrid[23] = Vec3( 9.6391550e-01, -3.0961200e-02, 9.5221820e-01); - inputGrid[24] = Vec3( 9.6391550e-01, 9.6052780e-01, -1.0202836e+00); - inputGrid[25] = Vec3( 9.6391550e-01, 9.6052780e-01, -3.4032700e-02); - inputGrid[26] = Vec3( 9.6391550e-01, 9.6052780e-01, 9.5221820e-01); + inputGrid[0] = Vec3(-1.0318535e+00, -1.0224502e+00, -1.0202836e+00); + inputGrid[1] = Vec3(-1.0318535e+00, -1.0224502e+00, -3.4032700e-02); + inputGrid[2] = Vec3(-1.0318535e+00, -1.0224502e+00, 9.5221820e-01); + inputGrid[3] = Vec3(-1.0318535e+00, -3.0961200e-02, -1.0202836e+00); + inputGrid[4] = Vec3(-1.0318535e+00, -3.0961200e-02, -3.4032700e-02); + inputGrid[5] = Vec3(-1.0318535e+00, -3.0961200e-02, 9.5221820e-01); + inputGrid[6] = Vec3(-1.0318535e+00, 9.6052780e-01, -1.0202836e+00); + inputGrid[7] = Vec3(-1.0318535e+00, 9.6052780e-01, -3.4032700e-02); + inputGrid[8] = Vec3(-1.0318535e+00, 9.6052780e-01, 9.5221820e-01); + inputGrid[9] = Vec3(-3.3969000e-02, -1.0224502e+00, -1.0202836e+00); + inputGrid[10] = Vec3(-3.3969000e-02, -1.0224502e+00, -3.4032700e-02); + inputGrid[11] = Vec3(-3.3969000e-02, -1.0224502e+00, 9.5221820e-01); + inputGrid[12] = Vec3(-3.3969000e-02, -3.0961200e-02, -1.0202836e+00); + inputGrid[13] = Vec3(-3.3969000e-02, -3.0961200e-02, -3.4032700e-02); + inputGrid[14] = Vec3(-3.3969000e-02, -3.0961200e-02, 9.5221820e-01); + inputGrid[15] = Vec3(-3.3969000e-02, 9.6052780e-01, -1.0202836e+00); + inputGrid[16] = Vec3(-3.3969000e-02, 9.6052780e-01, -3.4032700e-02); + inputGrid[17] = Vec3(-3.3969000e-02, 9.6052780e-01, 9.5221820e-01); + inputGrid[18] = Vec3( 9.6391550e-01, -1.0224502e+00, -1.0202836e+00); + inputGrid[19] = Vec3( 9.6391550e-01, -1.0224502e+00, -3.4032700e-02); + inputGrid[20] = Vec3( 9.6391550e-01, -1.0224502e+00, 9.5221820e-01); + inputGrid[21] = Vec3( 9.6391550e-01, -3.0961200e-02, -1.0202836e+00); + inputGrid[22] = Vec3( 9.6391550e-01, -3.0961200e-02, -3.4032700e-02); + inputGrid[23] = Vec3( 9.6391550e-01, -3.0961200e-02, 9.5221820e-01); + inputGrid[24] = Vec3( 9.6391550e-01, 9.6052780e-01, -1.0202836e+00); + inputGrid[25] = Vec3( 9.6391550e-01, 9.6052780e-01, -3.4032700e-02); + inputGrid[26] = Vec3( 9.6391550e-01, 9.6052780e-01, 9.5221820e-01); std::vector outputGridPotential; std::vector< double > outputMultipoleMoments; - setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, forces, energy, - outputMultipoleMoments, inputGrid, outputGridPotential, log ); + setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, testName, forces, energy, + outputMultipoleMoments, inputGrid, outputGridPotential, log); // TINKER computed grid values @@ -2803,9 +2803,9 @@ static void testMultipoleGridPotential( FILE* log ) { tinkerGridPotential[26] = 1.3960144e+02; double tolerance = 3.0e-04; - for( unsigned int ii = 0; ii < gridSize; ii++ ){ - double difference = fabs( (outputGridPotential[ii] - tinkerGridPotential[ii] )/tinkerGridPotential[ii] ); - if( difference > tolerance ){ + for (unsigned int ii = 0; ii < gridSize; ii++) { + double difference = fabs((outputGridPotential[ii] - tinkerGridPotential[ii])/tinkerGridPotential[ii]); + if (difference > tolerance) { std::stringstream details; details << testName << " potential for grid point " << ii << " does not agree w/ TINKER computed value: OpenMM=" << outputGridPotential[ii]; details << " TINKER=" << tinkerGridPotential[ii] << " difference=" << difference; @@ -2942,7 +2942,7 @@ void testTriclinic() { ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), 1e-2); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaMultipoleForce running test..." << std::endl; @@ -2954,7 +2954,7 @@ int main( int numberOfArguments, char* argv[] ) { // test direct polarization, no cutoff - testMultipoleAmmoniaDirectPolarization( log ); + testMultipoleAmmoniaDirectPolarization(log); // test querying induced dipoles @@ -2962,33 +2962,33 @@ int main( int numberOfArguments, char* argv[] ) { // test mutual polarization, no cutoff - testMultipoleAmmoniaMutualPolarization( log ); + testMultipoleAmmoniaMutualPolarization(log); // test multipole direct & mutual polarization using PME - testMultipoleWaterPMEDirectPolarization( log ); - testMultipoleWaterPMEMutualPolarization( log ); + testMultipoleWaterPMEDirectPolarization(log); + testMultipoleWaterPMEMutualPolarization(log); // check validation of traceless/symmetric quadrupole tensor - testQuadrupoleValidation( log ); + testQuadrupoleValidation(log); // system w/ 2 ions and 2 water molecules - testMultipoleIonsAndWaterPMEMutualPolarization( log ); - testMultipoleIonsAndWaterPMEDirectPolarization( log ); + testMultipoleIonsAndWaterPMEMutualPolarization(log); + testMultipoleIonsAndWaterPMEDirectPolarization(log); // test computation of system multipole moments - testSystemMultipoleMoments( log ); + testSystemMultipoleMoments(log); // test computation of grid potential - testMultipoleGridPotential( log ); + testMultipoleGridPotential(log); // large box of water - testPMEMutualPolarizationLargeWater( log ); + testPMEMutualPolarizationLargeWater(log); // triclinic box of water diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp index 8bd47a61c..c5832c239 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp @@ -64,7 +64,7 @@ const double TOL = 1e-3; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -73,13 +73,13 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& positions, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy, FILE* log) { double kAngleCubic = amoebaOutOfPlaneBendForce.getAmoebaGlobalOutOfPlaneBendCubic(); @@ -89,12 +89,12 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& int particle1, particle2, particle3, particle4; double kAngleQuadratic; - amoebaOutOfPlaneBendForce.getOutOfPlaneBendParameters(bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic ); + amoebaOutOfPlaneBendForce.getOutOfPlaneBendParameters(bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForce: bond %d [%d %d %d %d] k=[%10.3e %10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic, kAngleCubic, kAngleQuartic, kAnglePentic, kAngleSextic ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaOutOfPlaneBendForce: bond %d [%d %d %d %d] k=[%10.3e %10.3e %10.3e %10.3e %10.3e]\n", + bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic, kAngleCubic, kAngleQuartic, kAnglePentic, kAngleSextic); + (void) fflush(log); } #endif @@ -108,7 +108,7 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& // and various intermediate terms double deltaR[LastDeltaIndex][6]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AB][ii] = positions[particle1][ii] - positions[particle2][ii]; deltaR[CB][ii] = positions[particle3][ii] - positions[particle2][ii]; deltaR[DB][ii] = positions[particle4][ii] - positions[particle2][ii]; @@ -116,36 +116,36 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& deltaR[CD][ii] = positions[particle3][ii] - positions[particle4][ii]; } - double rDB2 = dotVector3( deltaR[DB], deltaR[DB] ); - double rAD2 = dotVector3( deltaR[AD], deltaR[AD] ); - double rCD2 = dotVector3( deltaR[CD], deltaR[CD] ); + double rDB2 = dotVector3(deltaR[DB], deltaR[DB]); + double rAD2 = dotVector3(deltaR[AD], deltaR[AD]); + double rCD2 = dotVector3(deltaR[CD], deltaR[CD]); double tempVector[3]; - crossProductVector3( deltaR[CB], deltaR[DB], tempVector ); - double eE = dotVector3( deltaR[AB], tempVector ); - double dot = dotVector3( deltaR[AD], deltaR[CD] ); + crossProductVector3(deltaR[CB], deltaR[DB], tempVector); + double eE = dotVector3(deltaR[AB], tempVector ); + double dot = dotVector3(deltaR[AD], deltaR[CD]); double cc = rAD2*rCD2 - dot*dot; - if( rDB2 <= 0.0 || cc == 0.0 ){ + if (rDB2 <= 0.0 || cc == 0.0) { return; } double bkk2 = rDB2 - eE*eE/cc; double cosine = sqrt(bkk2/rDB2); double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0; } - else if( cosine <= -1.0 ){ + else if (cosine <= -1.0) { angle = PI_M; } else { angle = RADIAN*acos(cosine); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForce: bkk2=%14.7e rDB2=%14.7e cos=%14.7e dt=%14.7e]\n", - bkk2, rDB2, cosine, angle ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaOutOfPlaneBendForce: bkk2=%14.7e rDB2=%14.7e cos=%14.7e dt=%14.7e]\n", + bkk2, rDB2, cosine, angle); + (void) fflush(log); } #endif @@ -161,23 +161,23 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& double dEdCos; dEdCos = dEdDt/sqrt(cc*bkk2); - if( eE > 0.0 ){ + if (eE > 0.0) { dEdCos *= -1.0; } double term = eE/cc; double dccd[LastAtomIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { dccd[A][ii] = (deltaR[AD][ii]*rCD2 - deltaR[CD][ii]*dot)*term; dccd[C][ii] = (deltaR[CD][ii]*rAD2 - deltaR[AD][ii]*dot)*term; dccd[D][ii] = -1.0*(dccd[A][ii] + dccd[C][ii]); } double deed[LastAtomIndex][3]; - crossProductVector3( deltaR[DB], deltaR[CB], deed[A] ); - crossProductVector3( deltaR[AB], deltaR[DB], deed[C] ); - crossProductVector3( deltaR[CB], deltaR[AB], deed[D] ); + crossProductVector3(deltaR[DB], deltaR[CB], deed[A]); + crossProductVector3(deltaR[AB], deltaR[DB], deed[C]); + crossProductVector3(deltaR[CB], deltaR[AB], deed[D]); term = eE/rDB2; deed[D][0] += deltaR[DB][0]*term; @@ -189,24 +189,24 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& // forces // calculate forces for atoms a, c, d - // the force for b is then -( a+ c + d) + // the force for b is then -(a+ c + d) double subForce[LastAtomIndex][3]; - for( int jj = 0; jj < LastAtomIndex; jj++ ){ + for (int jj = 0; jj < LastAtomIndex; jj++) { // A, C, D - for( int ii = 0; ii < 3; ii++ ){ - subForce[jj][ii] = dEdCos*( dccd[jj][ii] + deed[jj][ii] ); + for (int ii = 0; ii < 3; ii++) { + subForce[jj][ii] = dEdCos*(dccd[jj][ii] + deed[jj][ii]); } - if( jj == 0 )jj++; // skip B + if (jj == 0)jj++; // skip B // now compute B - if( jj == 3 ){ - for( int ii = 0; ii < 3; ii++ ){ + if (jj == 3) { + for (int ii = 0; ii < 3; ii++) { subForce[1][ii] = -1.0*(subForce[0][ii] + subForce[2][ii] + subForce[3][ii]); } } @@ -243,70 +243,70 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& return; } -static void computeAmoebaOutOfPlaneBendForces( Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { +static void computeAmoebaOutOfPlaneBendForces(Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, + std::vector& expectedForces, double* expectedEnergy, FILE* log) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaOutOfPlaneBendForce.getNumOutOfPlaneBends(); ii++ ){ - computeAmoebaOutOfPlaneBendForce(ii, positions, amoebaOutOfPlaneBendForce, expectedForces, expectedEnergy, log ); + for (int ii = 0; ii < amoebaOutOfPlaneBendForce.getNumOutOfPlaneBends(); ii++) { + computeAmoebaOutOfPlaneBendForce(ii, positions, amoebaOutOfPlaneBendForce, expectedForces, expectedEnergy, log); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e\n", *expectedEnergy); + for (unsigned int ii = 0; ii < positions.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif return; } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, + double tolerance, const std::string& idString, FILE* log) { std::vector expectedForces; double expectedEnergy; - computeAmoebaOutOfPlaneBendForces( context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy, log ); + computeAmoebaOutOfPlaneBendForces(context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy, log); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneOutOfPlaneBend( FILE* log ) { +void testOneOutOfPlaneBend(FILE* log) { System system; int numberOfParticles = 4; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -314,29 +314,29 @@ void testOneOutOfPlaneBend( FILE* log ) { AmoebaOutOfPlaneBendForce* amoebaOutOfPlaneBendForce = new AmoebaOutOfPlaneBendForce(); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07 ); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); double kOutOfPlaneBend = 0.328682196E-01; - amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend ); + amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend); system.addForce(amoebaOutOfPlaneBendForce); ASSERT(!amoebaOutOfPlaneBendForce->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(numberOfParticles); - positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); - positions[1] = Vec3( 0.269130000E+02, 0.266390000E+02, 0.353100000E+01 ); + positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01); + positions[1] = Vec3(0.269130000E+02, 0.266390000E+02, 0.353100000E+01); - positions[2] = Vec3( 0.278860000E+02, 0.264630000E+02, 0.426300000E+01 ); - positions[3] = Vec3( 0.245568230E+02, 0.250215290E+02, 0.796852800E+01 ); + positions[2] = Vec3(0.278860000E+02, 0.264630000E+02, 0.426300000E+01); + positions[3] = Vec3(0.245568230E+02, 0.250215290E+02, 0.796852800E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); // Try changing the bend parameters and make sure it's still correct. @@ -344,21 +344,21 @@ void testOneOutOfPlaneBend( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaOutOfPlaneBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); } -void testOneOutOfPlaneBend2( FILE* log, int setId ) { +void testOneOutOfPlaneBend2(FILE* log, int setId) { System system; int numberOfParticles = 4; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -366,10 +366,10 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { AmoebaOutOfPlaneBendForce* amoebaOutOfPlaneBendForce = new AmoebaOutOfPlaneBendForce(); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07 ); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); /* 285 441 442 443 444 0.328682196E-01 286 441 442 444 443 0.164493407E-01 @@ -389,147 +389,147 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { */ std::map coordinates; - coordinates[440] = Vec3( 0.893800000E+01, 0.439800000E+01, 0.343100000E+01 ); - coordinates[441] = Vec3( 0.779100000E+01, 0.614600000E+01, 0.390100000E+01 ); - coordinates[442] = Vec3( 0.915400000E+01, 0.683900000E+01, 0.389400000E+01 ); - coordinates[443] = Vec3( 0.101770000E+02, 0.619000000E+01, 0.379900000E+01 ); - coordinates[444] = Vec3( 0.921000000E+01, 0.813800000E+01, 0.398600000E+01 ); - coordinates[445] = Vec3( 0.708500000E+01, 0.672900000E+01, 0.332700000E+01 ); - coordinates[446] = Vec3( 0.744300000E+01, 0.605200000E+01, 0.491900000E+01 ); - coordinates[447] = Vec3( 0.100820000E+02, 0.859300000E+01, 0.398200000E+01 ); - coordinates[448] = Vec3( 0.838000000E+01, 0.866100000E+01, 0.406000000E+01 ); + coordinates[440] = Vec3( 0.893800000E+01, 0.439800000E+01, 0.343100000E+01); + coordinates[441] = Vec3( 0.779100000E+01, 0.614600000E+01, 0.390100000E+01); + coordinates[442] = Vec3( 0.915400000E+01, 0.683900000E+01, 0.389400000E+01); + coordinates[443] = Vec3( 0.101770000E+02, 0.619000000E+01, 0.379900000E+01); + coordinates[444] = Vec3( 0.921000000E+01, 0.813800000E+01, 0.398600000E+01); + coordinates[445] = Vec3( 0.708500000E+01, 0.672900000E+01, 0.332700000E+01); + coordinates[446] = Vec3( 0.744300000E+01, 0.605200000E+01, 0.491900000E+01); + coordinates[447] = Vec3( 0.100820000E+02, 0.859300000E+01, 0.398200000E+01); + coordinates[448] = Vec3( 0.838000000E+01, 0.866100000E+01, 0.406000000E+01); double kOutOfPlaneBend = 0.328682196E-01; std::vector particleIndices; - if( setId == 1 ){ - particleIndices.push_back( 441 ); - particleIndices.push_back( 442 ); - particleIndices.push_back( 443 ); - particleIndices.push_back( 444 ); + if (setId == 1) { + particleIndices.push_back(441); + particleIndices.push_back(442); + particleIndices.push_back(443); + particleIndices.push_back(444); kOutOfPlaneBend = 0.328682196E-01; } - else if( setId == 2 ){ - particleIndices.push_back( 441 ); - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 443 ); + else if (setId == 2) { + particleIndices.push_back(441); + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(443); kOutOfPlaneBend = 0.164493407E-01; } - else if( setId == 3 ){ - particleIndices.push_back( 443 ); - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 441 ); + else if (setId == 3) { + particleIndices.push_back(443); + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(441); kOutOfPlaneBend = 0.636650407E-02; } - else if( setId == 4 ){ - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 447 ); - particleIndices.push_back( 448 ); + else if (setId == 4) { + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(447); + particleIndices.push_back(448); kOutOfPlaneBend = 0.392956472E-02; } - else if( setId == 5 ){ - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 448 ); - particleIndices.push_back( 447 ); + else if (setId == 5) { + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(448); + particleIndices.push_back(447); kOutOfPlaneBend = 0.392956472E-02; } - else if( setId == 6 ){ - particleIndices.push_back( 447 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 448 ); - particleIndices.push_back( 442 ); + else if (setId == 6) { + particleIndices.push_back(447); + particleIndices.push_back(444); + particleIndices.push_back(448); + particleIndices.push_back(442); kOutOfPlaneBend = 0.214755281E-01; } else { #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "Set id %d not recognized.\n", setId ); + if (log) { + (void) fprintf(log, "Set id %d not recognized.\n", setId); } #endif std::stringstream buffer; buffer << "Set id " << setId << " not recognized."; - throw OpenMMException( buffer.str() ); + throw OpenMMException(buffer.str()); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "Set id %d.\n", setId ); + if (log) { + (void) fprintf(log, "Set id %d.\n", setId); } #endif - amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend ); + amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend); system.addForce(amoebaOutOfPlaneBendForce); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(numberOfParticles); - for( unsigned int ii = 0; ii < static_cast(numberOfParticles); ii++ ){ - if( coordinates.find( particleIndices[ii] ) == coordinates.end() ){ + for (unsigned int ii = 0; ii < static_cast(numberOfParticles); ii++) { + if (coordinates.find(particleIndices[ii]) == coordinates.end()) { #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "Coordinates %d not loaded.", particleIndices[ii] ); + if (log) { + (void) fprintf(log, "Coordinates %d not loaded.", particleIndices[ii]); } #endif std::stringstream buffer; buffer << "Coordinates " << particleIndices[ii] << " not loaded."; - throw OpenMMException( buffer.str() ); + throw OpenMMException(buffer.str()); } positions[ii] = coordinates[particleIndices[ii]]; } context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); static int iter = 0; static std::map totalForces; static double totalEnergy; - if( iter == 0 ){ - - totalForces[441] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[442] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[443] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[444] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[445] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[446] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[447] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[448] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[449] = Vec3( 0.0, 0.0, 0.0 ); + if (iter == 0) { + + totalForces[441] = Vec3( 0.0, 0.0, 0.0); + totalForces[442] = Vec3( 0.0, 0.0, 0.0); + totalForces[443] = Vec3( 0.0, 0.0, 0.0); + totalForces[444] = Vec3( 0.0, 0.0, 0.0); + totalForces[445] = Vec3( 0.0, 0.0, 0.0); + totalForces[446] = Vec3( 0.0, 0.0, 0.0); + totalForces[447] = Vec3( 0.0, 0.0, 0.0); + totalForces[448] = Vec3( 0.0, 0.0, 0.0); + totalForces[449] = Vec3( 0.0, 0.0, 0.0); totalEnergy = 0.0; } iter++; std::vector forces; - forces.resize( numberOfParticles ); + forces.resize(numberOfParticles); double energy; - computeAmoebaOutOfPlaneBendForce( 0, positions, *amoebaOutOfPlaneBendForce, forces, &energy, log ); + computeAmoebaOutOfPlaneBendForce(0, positions, *amoebaOutOfPlaneBendForce, forces, &energy, log); totalEnergy += energy; - for( unsigned int ii = 0; ii < static_cast(numberOfParticles); ii++ ){ - for( unsigned int jj = 0; jj < 3; jj++ ){ + for (unsigned int ii = 0; ii < static_cast(numberOfParticles); ii++) { + for (unsigned int jj = 0; jj < 3; jj++) { totalForces[particleIndices[ii]][jj] += forces[ii][jj]; } } - if( iter == 6 ){ + if (iter == 6) { #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForces: energy=%14.7e\n", totalEnergy); - for( std::map::iterator ii = totalForces.begin(); ii != totalForces.end(); ii++ ){ + if (log) { + (void) fprintf(log, "computeAmoebaOutOfPlaneBendForces: energy=%14.7e\n", totalEnergy); + for (std::map::iterator ii = totalForces.begin(); ii != totalForces.end(); ii++) { int particleIndex = ii->first; Vec3 forces = ii->second; - (void) fprintf( log, "%6d [%14.7e %14.7e %14.7e] \n", particleIndex, - forces[0], forces[1], forces[2] ); + (void) fprintf(log, "%6d [%14.7e %14.7e %14.7e] \n", particleIndex, + forces[0], forces[1], forces[2]); } - (void) fflush( log ); + (void) fflush(log); } #endif } } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaOutOfPlaneBendForce running test..." << std::endl; @@ -537,16 +537,16 @@ int main( int numberOfArguments, char* argv[] ) { //FILE* log = stderr; FILE* log = NULL; - //FILE* log = fopen( "AmoebaOutOfPlaneBendForce.log", "w" );; + //FILE* log = fopen("AmoebaOutOfPlaneBendForce.log", "w");; - testOneOutOfPlaneBend( log ); - //testOneOutOfPlaneBend2( log, atoi( argv[1] ) ); - //for( int ii = 1; ii <= 6; ii++ ){ - // testOneOutOfPlaneBend2( log, ii ); + testOneOutOfPlaneBend(log); + //testOneOutOfPlaneBend2(log, atoi(argv[1])); + //for (int ii = 1; ii <= 6; ii++) { + // testOneOutOfPlaneBend2(log, ii); //} #ifdef AMOEBA_DEBUG - if( log && log != stderr ) - (void) fclose( log ); + if (log && log != stderr) + (void) fclose(log); #endif } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp index 8b204c4d0..8d9ee5b5b 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp @@ -63,7 +63,7 @@ const double TOL = 1e-5; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -72,23 +72,23 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& positions, AmoebaPiTorsionForce& amoebaPiTorsionForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy, FILE* log) { int particle1, particle2, particle3, particle4, particle5, particle6; double kTorsion; amoebaPiTorsionForce.getPiTorsionParameters(bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaPiTorsionForce: bond %d [%d %d %d %d %d %d] k=%10.3e\n", - bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaPiTorsionForce: bond %d [%d %d %d %d %d %d] k=%10.3e\n", + bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion); + (void) fflush(log); } #endif @@ -98,16 +98,16 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit enum { A, B, C, D, E, F, LastAtomIndex }; double d[LastAtomIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii]; deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii]; deltaR[EC][ii] = positions[particle5][ii] - positions[particle3][ii]; deltaR[FC][ii] = positions[particle6][ii] - positions[particle3][ii]; } - crossProductVector3( deltaR[AD], deltaR[BD], deltaR[P] ); - crossProductVector3( deltaR[EC], deltaR[FC], deltaR[Q] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[AD], deltaR[BD], deltaR[P]); + crossProductVector3(deltaR[EC], deltaR[FC], deltaR[Q]); + for (int ii = 0; ii < 3; ii++) { deltaR[CP][ii] = -deltaR[P][ii]; deltaR[DC][ii] = positions[particle4][ii] - positions[particle3][ii]; deltaR[QD][ii] = deltaR[Q][ii]; @@ -115,25 +115,25 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit deltaR[P][ii] += positions[particle3][ii]; deltaR[Q][ii] += positions[particle4][ii]; } - crossProductVector3( deltaR[CP], deltaR[DC], deltaR[T] ); - crossProductVector3( deltaR[DC], deltaR[QD], deltaR[U] ); - crossProductVector3( deltaR[T], deltaR[U], deltaR[TU] ); + crossProductVector3(deltaR[CP], deltaR[DC], deltaR[T] ); + crossProductVector3(deltaR[DC], deltaR[QD], deltaR[U] ); + crossProductVector3(deltaR[T], deltaR[U], deltaR[TU]); - double rT2 = dotVector3( deltaR[T], deltaR[T] ); - double rU2 = dotVector3( deltaR[U], deltaR[U] ); - double rTrU = sqrt( rT2*rU2 ); - if( rTrU <= 0.0 ){ + double rT2 = dotVector3(deltaR[T], deltaR[T]); + double rU2 = dotVector3(deltaR[U], deltaR[U]); + double rTrU = sqrt(rT2*rU2); + if (rTrU <= 0.0) { return; } - double rDC = dotVector3( deltaR[DC], deltaR[DC] ); - rDC = sqrt( rDC ); + double rDC = dotVector3(deltaR[DC], deltaR[DC]); + rDC = sqrt(rDC); - double cosine = dotVector3( deltaR[T], deltaR[U] ); + double cosine = dotVector3(deltaR[T], deltaR[U]); cosine /= rTrU; - double sine = dotVector3( deltaR[DC], deltaR[TU] ); - sine /= ( rDC*rTrU ); + double sine = dotVector3(deltaR[DC], deltaR[TU]); + sine /= (rDC*rTrU); double cosine2 = cosine*cosine - sine*sine; double sine2 = 2.0*cosine*sine; @@ -143,37 +143,37 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit double dedphi = kTorsion*dphi2; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[DP][ii] = positions[particle4][ii] - deltaR[P][ii]; deltaR[QC][ii] = deltaR[Q][ii] - positions[particle3][ii]; } - double factorT = dedphi/( rDC*rT2 ); - double factorU = -dedphi/( rDC*rU2 ); + double factorT = dedphi/(rDC*rT2); + double factorU = -dedphi/(rDC*rU2); - crossProductVector3( deltaR[T], deltaR[DC], deltaR[dT] ); - crossProductVector3( deltaR[U], deltaR[DC], deltaR[dU] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[T], deltaR[DC], deltaR[dT] ); + crossProductVector3(deltaR[U], deltaR[DC], deltaR[dU] ); + for (int ii = 0; ii < 3; ii++) { deltaR[dT][ii] *= factorT; deltaR[dU][ii] *= factorU; } - crossProductVector3( deltaR[dT], deltaR[DC], deltaR[dP] ); - crossProductVector3( deltaR[dU], deltaR[DC], deltaR[dQ] ); + crossProductVector3(deltaR[dT], deltaR[DC], deltaR[dP] ); + crossProductVector3(deltaR[dU], deltaR[DC], deltaR[dQ] ); - crossProductVector3( deltaR[DP], deltaR[dT], deltaR[dC1] ); - crossProductVector3( deltaR[dU], deltaR[QD], deltaR[dC2] ); + crossProductVector3(deltaR[DP], deltaR[dT], deltaR[dC1] ); + crossProductVector3(deltaR[dU], deltaR[QD], deltaR[dC2] ); - crossProductVector3( deltaR[dT], deltaR[CP], deltaR[dD1] ); - crossProductVector3( deltaR[QC], deltaR[dU], deltaR[dD2] ); + crossProductVector3(deltaR[dT], deltaR[CP], deltaR[dD1] ); + crossProductVector3(deltaR[QC], deltaR[dU], deltaR[dD2] ); - crossProductVector3( deltaR[BD], deltaR[dP], d[A] ); - crossProductVector3( deltaR[dP], deltaR[AD], d[B] ); + crossProductVector3(deltaR[BD], deltaR[dP], d[A] ); + crossProductVector3(deltaR[dP], deltaR[AD], d[B] ); - crossProductVector3( deltaR[FC], deltaR[dQ], d[E] ); - crossProductVector3( deltaR[dQ], deltaR[EC], d[F] ); + crossProductVector3(deltaR[FC], deltaR[dQ], d[E] ); + crossProductVector3(deltaR[dQ], deltaR[EC], d[F] ); - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { d[C][ii] = deltaR[dC1][ii] + deltaR[dC2][ii] + deltaR[dP][ii] - d[E][ii] - d[F][ii]; d[D][ii] = deltaR[dD1][ii] + deltaR[dD2][ii] + deltaR[dQ][ii] - d[A][ii] - d[B][ii]; } @@ -211,69 +211,69 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit return; } -static void computeAmoebaPiTorsionForces( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { +static void computeAmoebaPiTorsionForces(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, + std::vector& expectedForces, double* expectedEnergy, FILE* log) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++ ){ - computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy, log ); + for (int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++) { + computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy, log); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaPiTorsionForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaPiTorsionForces: expected energy=%14.7e\n", *expectedEnergy); + for (unsigned int ii = 0; ii < positions.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif return; } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, - double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, + double tolerance, const std::string& idString, FILE* log) { std::vector expectedForces; double expectedEnergy; - computeAmoebaPiTorsionForces( context, amoebaPiTorsionForce, expectedForces, &expectedEnergy, log ); + computeAmoebaPiTorsionForces(context, amoebaPiTorsionForce, expectedForces, &expectedEnergy, log); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaPiTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaPiTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOnePiTorsion( FILE* log ) { +void testOnePiTorsion(FILE* log) { System system; int numberOfParticles = 6; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -282,25 +282,25 @@ void testOnePiTorsion( FILE* log ) { AmoebaPiTorsionForce* amoebaPiTorsionForce = new AmoebaPiTorsionForce(); double kTorsion = 6.85; - amoebaPiTorsionForce->addPiTorsion(0, 1, 2, 3, 4, 5, kTorsion ); + amoebaPiTorsionForce->addPiTorsion(0, 1, 2, 3, 4, 5, kTorsion); system.addForce(amoebaPiTorsionForce); ASSERT(!amoebaPiTorsionForce->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(numberOfParticles); - positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); - positions[1] = Vec3( 0.278860000E+02, 0.264630000E+02, 0.426300000E+01 ); - positions[2] = Vec3( 0.269130000E+02, 0.266390000E+02, 0.353100000E+01 ); + positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01); + positions[1] = Vec3(0.278860000E+02, 0.264630000E+02, 0.426300000E+01); + positions[2] = Vec3(0.269130000E+02, 0.266390000E+02, 0.353100000E+01); - positions[3] = Vec3( 0.245568230E+02, 0.250215290E+02, 0.796852800E+01 ); - positions[4] = Vec3( 0.261000000E+02, 0.292530000E+02, 0.520200000E+01 ); - positions[5] = Vec3( 0.254124630E+02, 0.234691880E+02, 0.773335400E+01 ); + positions[3] = Vec3(0.245568230E+02, 0.250215290E+02, 0.796852800E+01); + positions[4] = Vec3(0.261000000E+02, 0.292530000E+02, 0.520200000E+01); + positions[5] = Vec3(0.254124630E+02, 0.234691880E+02, 0.773335400E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log); // Try changing the torsion parameters and make sure it's still correct. @@ -308,29 +308,29 @@ void testOnePiTorsion( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaPiTorsionForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaPiTorsionForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); FILE* log = NULL; //FILE* log = stderr; - //FILE* log = fopen( "AmoebaPiTorsionForce1.log", "w" );; + //FILE* log = fopen("AmoebaPiTorsionForce1.log", "w");; - testOnePiTorsion( log ); + testOnePiTorsion(log); #ifdef AMOEBA_DEBUG - if( log && log != stderr ) - (void) fclose( log ); + if (log && log != stderr) + (void) fclose(log); #endif } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp index f64a3e153..1969cf716 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp @@ -65,7 +65,7 @@ const double TOL = 1e-4; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -74,13 +74,13 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } static void computeAmoebaStretchBendForce(int bondIndex, std::vector& positions, AmoebaStretchBendForce& amoebaStretchBendForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy, FILE* log) { int particle1, particle2, particle3; double abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend; @@ -88,10 +88,10 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); angleStretchBend *= RADIAN; #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k1=%10.3e k2=%10.3e\n", - bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k1=%10.3e k2=%10.3e\n", + bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); + (void) fflush(log); } #endif @@ -106,31 +106,31 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos double deltaR[LastDeltaIndex][3]; double rAB2 = 0.0; double rCB2 = 0.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AB][ii] = positions[particle1][ii] - positions[particle2][ii]; rAB2 += deltaR[AB][ii]*deltaR[AB][ii]; deltaR[CB][ii] = positions[particle3][ii] - positions[particle2][ii]; rCB2 += deltaR[CB][ii]*deltaR[CB][ii]; } - double rAB = sqrt( rAB2 ); - double rCB = sqrt( rCB2 ); + double rAB = sqrt(rAB2); + double rCB = sqrt(rCB2); - crossProductVector3( deltaR[CB], deltaR[AB], deltaR[CBxAB] ); - double rP = dotVector3( deltaR[CBxAB], deltaR[CBxAB] ); - rP = sqrt( rP ); + crossProductVector3(deltaR[CB], deltaR[AB], deltaR[CBxAB]); + double rP = dotVector3(deltaR[CBxAB], deltaR[CBxAB]); + rP = sqrt(rP); - if( rP <= 0.0 ){ + if (rP <= 0.0) { return; } - double dot = dotVector3( deltaR[CB], deltaR[AB] ); + double dot = dotVector3(deltaR[CB], deltaR[AB]); double cosine = dot/(rAB*rCB); double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0; } - else if( cosine <= -1.0 ){ + else if (cosine <= -1.0) { angle = PI_M; } else { @@ -142,9 +142,9 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos // P = CBxAB - crossProductVector3( deltaR[AB], deltaR[CBxAB], deltaR[ABxP] ); - crossProductVector3( deltaR[CB], deltaR[CBxAB], deltaR[CBxP] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[AB], deltaR[CBxAB], deltaR[ABxP]); + crossProductVector3(deltaR[CB], deltaR[CBxAB], deltaR[CBxP]); + for (int ii = 0; ii < 3; ii++) { deltaR[ABxP][ii] *= termA; deltaR[CBxP][ii] *= termC; } @@ -162,14 +162,14 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos // forces // calculate forces for atoms a, b, c - // the force for b is then -( a + c) + // the force for b is then -(a + c) double subForce[LastAtomIndex][3]; double dt = angle - angleStretchBend; - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { subForce[A][jj] = kStretchBend*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj]; subForce[C][jj] = k2StretchBend*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj]; - subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); + subForce[B][jj] = -(subForce[A][jj] + subForce[C][jj]); } // --------------------------------------------------------------------------------------- @@ -190,78 +190,78 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos *energy += dt*drkk; #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForce: angle=%10.3e dt=%10.3e dr=%10.3e\n", angle, dt, dr ); - (void) fflush( log ); + if (log) { + (void) fprintf(log, "computeAmoebaStretchBendForce: angle=%10.3e dt=%10.3e dr=%10.3e\n", angle, dt, dr); + (void) fflush(log); } #endif return; } -static void computeAmoebaStretchBendForces( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { +static void computeAmoebaStretchBendForces(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, + std::vector& expectedForces, double* expectedEnergy, FILE* log) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++ ){ - computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy, log ); + for (int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++) { + computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy, log); } #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaStretchBendForces: expected energy=%14.7e\n", *expectedEnergy); + for (unsigned int ii = 0; ii < positions.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif return; } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, - double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, + double tolerance, const std::string& idString, FILE* log) { std::vector expectedForces; double expectedEnergy; - computeAmoebaStretchBendForces( context, amoebaStretchBendForce, expectedForces, &expectedEnergy, log ); + computeAmoebaStretchBendForces(context, amoebaStretchBendForce, expectedForces, &expectedEnergy, log); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaStretchBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneStretchBend( FILE* log ) { +void testOneStretchBend(FILE* log) { System system; int numberOfParticles = 3; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -275,21 +275,21 @@ void testOneStretchBend( FILE* log ) { //double kStretchBend = 0.750491578E-01; double kStretchBend = 1.0; - amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend ); + amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend); system.addForce(amoebaStretchBendForce); ASSERT(!amoebaStretchBendForce->usesPeriodicBoundaryConditions()); ASSERT(!system.usesPeriodicBoundaryConditions()); - Context context(system, integrator, Platform::getPlatformByName( "Reference")); + Context context(system, integrator, Platform::getPlatformByName("Reference")); std::vector positions(numberOfParticles); - positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); - positions[1] = Vec3( 0.273400000E+02, 0.244300000E+02, 0.261400000E+01 ); - positions[2] = Vec3( 0.269573220E+02, 0.236108860E+02, 0.216376800E+01 ); + positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01); + positions[1] = Vec3(0.273400000E+02, 0.244300000E+02, 0.261400000E+01); + positions[2] = Vec3(0.269573220E+02, 0.236108860E+02, 0.216376800E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log); // Try changing the stretch-bend parameters and make sure it's still correct. @@ -297,17 +297,17 @@ void testOneStretchBend( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaStretchBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaStretchBendForce running test..." << std::endl; @@ -315,11 +315,11 @@ int main( int numberOfArguments, char* argv[] ) { FILE* log = NULL; //FILE* log = stderr; - //FILE* log = fopen( "AmoebaStretchBendForce1.log", "w" );; - testOneStretchBend( log ); + //FILE* log = fopen("AmoebaStretchBendForce1.log", "w");; + testOneStretchBend(log); #ifdef AMOEBA_DEBUG - if( log && log != stderr ) - (void) fclose( log ); + if (log && log != stderr) + (void) fclose(log); #endif } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp index d37698f4d..604b45ffe 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp @@ -2559,20 +2559,20 @@ static double grid[4][625][6] = { int elementCount = (includeDerivs ? 6 : 3); std::vector grids(4); - for( int ii = 0; ii < 4; ii++ ){ - grids[ii].resize( 25 ); - for( int jj = 0; jj < 25; jj++ ){ + for (int ii = 0; ii < 4; ii++) { + grids[ii].resize(25); + for (int jj = 0; jj < 25; jj++) { grids[ii][jj].resize(25); - for( int kk = 0; kk < 25; kk++ ){ + for (int kk = 0; kk < 25; kk++) { grids[ii][jj][kk].resize(elementCount); } } int index = 0; - for( int jj = 0; jj < 25; jj++ ){ - for( int kk = 0; kk < 25; kk++ ){ + for (int jj = 0; jj < 25; jj++) { + for (int kk = 0; kk < 25; kk++) { int jjIndex = static_cast(((grid[ii][index][0] + 180.0)/15.0)+1.0e-05); int kkIndex = static_cast(((grid[ii][index][1] + 180.0)/15.0)+1.0e-05); - for( int ll = 0; ll < elementCount; ll++ ){ + for (int ll = 0; ll < elementCount; ll++) { grids[ii][kk][jj][ll] = grid[ii][index][ll]; } index++; @@ -2586,7 +2586,7 @@ void testTorsionTorsion(int systemId, bool includeDerivs) { System system; int numberOfParticles = 6; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } LangevinIntegrator integrator(0.0, 0.1, 0.01); @@ -2598,48 +2598,48 @@ void testTorsionTorsion(int systemId, bool includeDerivs) { std::vector positions(numberOfParticles); std::vector expectedForces(numberOfParticles); double expectedEnergy; - if( systemId == 0 ){ + if (systemId == 0) { // villin: 2 19 20 21 38 25 grid=2 chiralCheckAtomIndex = 5; gridIndex = 2; - positions[0] = Vec3( -0.422792800E+01, -0.110605910E+02, -0.508156700E+01 ); - positions[1] = Vec3( -0.447153100E+01, -0.978627900E+01, -0.466405800E+01 ); - positions[2] = Vec3( -0.531878400E+01, -0.940508600E+01, -0.352283100E+01 ); - positions[3] = Vec3( -0.679606000E+01, -0.974353100E+01, -0.382975700E+01 ); - positions[4] = Vec3( -0.760612300E+01, -0.992590200E+01, -0.275088400E+01 ); - positions[5] = Vec3( -0.516893900E+01, -0.788347000E+01, -0.316943000E+01 ); + positions[0] = Vec3(-0.422792800E+01, -0.110605910E+02, -0.508156700E+01); + positions[1] = Vec3(-0.447153100E+01, -0.978627900E+01, -0.466405800E+01); + positions[2] = Vec3(-0.531878400E+01, -0.940508600E+01, -0.352283100E+01); + positions[3] = Vec3(-0.679606000E+01, -0.974353100E+01, -0.382975700E+01); + positions[4] = Vec3(-0.760612300E+01, -0.992590200E+01, -0.275088400E+01); + positions[5] = Vec3(-0.516893900E+01, -0.788347000E+01, -0.316943000E+01); - expectedForces[0] = Vec3( 0.906091624E+00, -0.529814945E-01, 0.690384140E+00 ); - expectedForces[1] = Vec3( -0.124550232E+01, -0.999341692E+00, -0.590867130E+00 ); - expectedForces[2] = Vec3( 0.534419689E+00, 0.612404926E-01, 0.547380310E-01 ); - expectedForces[3] = Vec3( -5.732010432E-01, 2.645718463E+00, -1.585204274E-01 ); - expectedForces[4] = Vec3( 3.781920539E-01, -1.654635768E+00, 4.265386268E-03 ); - expectedForces[5] = Vec3( 0.0, 0.0, 0.0 ); + expectedForces[0] = Vec3( 0.906091624E+00, -0.529814945E-01, 0.690384140E+00); + expectedForces[1] = Vec3(-0.124550232E+01, -0.999341692E+00, -0.590867130E+00); + expectedForces[2] = Vec3( 0.534419689E+00, 0.612404926E-01, 0.547380310E-01); + expectedForces[3] = Vec3(-5.732010432E-01, 2.645718463E+00, -1.585204274E-01); + expectedForces[4] = Vec3( 3.781920539E-01, -1.654635768E+00, 4.265386268E-03); + expectedForces[5] = Vec3( 0.0, 0.0, 0.0); expectedEnergy = -2.699654759E+00; } - else if( systemId == 1 ){ + else if (systemId == 1) { // villin: 158 176 177 178 183 -1 0 chiralCheckAtomIndex = -1; gridIndex = 0; - positions[0] = Vec3( -0.105946640E+02, -0.917797000E+00, 0.105486310E+02 ); - positions[1] = Vec3( -0.115059090E+02, -0.141876700E+01, 0.966933200E+01 ); - positions[2] = Vec3( -0.128314660E+02, -0.876338000E+00, 0.942959800E+01 ); - positions[3] = Vec3( -0.130879850E+02, -0.760280000E-01, 0.814732200E+01 ); - positions[4] = Vec3( -0.120888080E+02, 0.112050000E-01, 0.722704500E+01 ); - positions[5] = Vec3( 0.0, 0.0, 0.0 ); + positions[0] = Vec3(-0.105946640E+02, -0.917797000E+00, 0.105486310E+02); + positions[1] = Vec3(-0.115059090E+02, -0.141876700E+01, 0.966933200E+01); + positions[2] = Vec3(-0.128314660E+02, -0.876338000E+00, 0.942959800E+01); + positions[3] = Vec3(-0.130879850E+02, -0.760280000E-01, 0.814732200E+01); + positions[4] = Vec3(-0.120888080E+02, 0.112050000E-01, 0.722704500E+01); + positions[5] = Vec3( 0.0, 0.0, 0.0); - expectedForces[0] = Vec3( 4.165851130E-01, 6.608242922E-01, -8.082168261E-01 ); - expectedForces[1] = Vec3( -6.024659721E-01, -8.878744406E-01, 1.322274444E+00 ); - expectedForces[2] = Vec3( 3.196925118E-02, -3.137497848E-01, -8.207984001E-01 ); - expectedForces[3] = Vec3( 3.842205941E-02, 2.602732089E-01, 1.547586195E-01 ); - expectedForces[4] = Vec3( 1.154895485E-01, 2.805267242E-01, 1.519821623E-01 ); - expectedForces[5] = Vec3( 0.0, 0.0, 0.0 ); + expectedForces[0] = Vec3( 4.165851130E-01, 6.608242922E-01, -8.082168261E-01); + expectedForces[1] = Vec3(-6.024659721E-01, -8.878744406E-01, 1.322274444E+00); + expectedForces[2] = Vec3( 3.196925118E-02, -3.137497848E-01, -8.207984001E-01); + expectedForces[3] = Vec3( 3.842205941E-02, 2.602732089E-01, 1.547586195E-01); + expectedForces[4] = Vec3( 1.154895485E-01, 2.805267242E-01, 1.519821623E-01); + expectedForces[5] = Vec3( 0.0, 0.0, 0.0); expectedEnergy = -3.372536909E+00; } @@ -2656,21 +2656,21 @@ void testTorsionTorsion(int systemId, bool includeDerivs) { std::vector forces = state.getForces(); const double conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ + for (unsigned int ii = 0; ii < forces.size(); ii++) { forces[ii][0] *= conversion; forces[ii][1] *= conversion; forces[ii][2] *= conversion; } double tolerance = 1.0e-03; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaTorsionTorsionForce running test..." << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp index e63e4e4de..4f9416e3e 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp @@ -57,21 +57,21 @@ extern "C" OPENMM_EXPORT void registerAmoebaReferenceKernelFactories(); const double TOL = 1e-4; -void testVdw( FILE* log ) { +void testVdw(FILE* log) { System system; int numberOfParticles = 6; AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce(); std::string sigmaCombiningRule = std::string("CUBIC-MEAN"); - amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule ); + amoebaVdwForce->setSigmaCombiningRule(sigmaCombiningRule); std::string epsilonCombiningRule = std::string("HHG"); - amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule ); - for( int ii = 0; ii < numberOfParticles; ii++ ){ + amoebaVdwForce->setEpsilonCombiningRule(epsilonCombiningRule); + for (int ii = 0; ii < numberOfParticles; ii++) { int indexIV; double mass, sigma, epsilon, reduction; std::vector< int > exclusions; - if( ii == 0 || ii == 3 ){ + if (ii == 0 || ii == 3) { mass = 16.0; indexIV = ii; sigma = 1.70250E+00; @@ -88,19 +88,19 @@ void testVdw( FILE* log ) { // exclusions - if( ii < 3 ){ - exclusions.push_back ( 0 ); - exclusions.push_back ( 1 ); - exclusions.push_back ( 2 ); + if (ii < 3) { + exclusions.push_back (0); + exclusions.push_back (1); + exclusions.push_back (2); } else { - exclusions.push_back ( 3 ); - exclusions.push_back ( 4 ); - exclusions.push_back ( 5 ); + exclusions.push_back (3); + exclusions.push_back (4); + exclusions.push_back (5); } system.addParticle(mass); - amoebaVdwForce->addParticle( indexIV, sigma, epsilon, reduction ); - amoebaVdwForce->setParticleExclusions( ii, exclusions ); + amoebaVdwForce->addParticle(indexIV, sigma, epsilon, reduction); + amoebaVdwForce->setParticleExclusions(ii, exclusions); } LangevinIntegrator integrator(0.0, 0.1, 0.01); @@ -108,25 +108,25 @@ void testVdw( FILE* log ) { std::vector expectedForces(numberOfParticles); double expectedEnergy; - positions[0] = Vec3( -0.254893450E+02, -0.876646600E+01, 0.174761600E+01 ); - positions[1] = Vec3( -0.263489690E+02, -0.907798000E+01, 0.205385100E+01 ); - positions[2] = Vec3( -0.252491680E+02, -0.949411200E+01, 0.115017600E+01 ); - positions[3] = Vec3( 0.172827200E+01, 0.195873090E+02, 0.100059800E+01 ); - positions[4] = Vec3( 0.129370700E+01, 0.190112810E+02, 0.169576300E+01 ); - positions[5] = Vec3( 0.256122300E+01, 0.191601930E+02, 0.854382000E+00 ); + positions[0] = Vec3(-0.254893450E+02, -0.876646600E+01, 0.174761600E+01); + positions[1] = Vec3(-0.263489690E+02, -0.907798000E+01, 0.205385100E+01); + positions[2] = Vec3(-0.252491680E+02, -0.949411200E+01, 0.115017600E+01); + positions[3] = Vec3( 0.172827200E+01, 0.195873090E+02, 0.100059800E+01); + positions[4] = Vec3( 0.129370700E+01, 0.190112810E+02, 0.169576300E+01); + positions[5] = Vec3( 0.256122300E+01, 0.191601930E+02, 0.854382000E+00); double offset = 27.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { positions[ii][0] += offset; positions[ii][1] += offset; } - expectedForces[0] = Vec3( -0.729561040E+03, 0.425828484E+04, -0.769114213E+03 ); - expectedForces[1] = Vec3( 0.181000041E+02, 0.328216639E+02, -0.126210511E+02 ); - expectedForces[2] = Vec3( -0.943743014E+00, 0.199728310E+02, 0.884567842E+00 ); - expectedForces[3] = Vec3( 0.615734500E+01, -0.747350431E+03, 0.264726489E+03 ); - expectedForces[4] = Vec3( 0.735772031E+03, -0.353310112E+04, 0.490066356E+03 ); - expectedForces[5] = Vec3( -0.295245970E+02, -0.306277797E+02, 0.260578506E+02 ); + expectedForces[0] = Vec3( -0.729561040E+03, 0.425828484E+04, -0.769114213E+03); + expectedForces[1] = Vec3( 0.181000041E+02, 0.328216639E+02, -0.126210511E+02); + expectedForces[2] = Vec3( -0.943743014E+00, 0.199728310E+02, 0.884567842E+00); + expectedForces[3] = Vec3( 0.615734500E+01, -0.747350431E+03, 0.264726489E+03); + expectedForces[4] = Vec3( 0.735772031E+03, -0.353310112E+04, 0.490066356E+03); + expectedForces[5] = Vec3( -0.295245970E+02, -0.306277797E+02, 0.260578506E+02); expectedEnergy = 0.740688488E+03; @@ -134,28 +134,28 @@ void testVdw( FILE* log ) { std::string platformName; #define AngstromToNm 0.1 #define CalToJoule 4.184 - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { positions[ii][0] *= AngstromToNm; positions[ii][1] *= AngstromToNm; positions[ii][2] *= AngstromToNm; } - for( int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++ ){ + for (int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++) { int indexIV; double sigma, epsilon, reduction; - amoebaVdwForce->getParticleParameters( ii, indexIV, sigma, epsilon, reduction ); + amoebaVdwForce->getParticleParameters(ii, indexIV, sigma, epsilon, reduction); sigma *= AngstromToNm; epsilon *= CalToJoule; - amoebaVdwForce->setParticleParameters( ii, indexIV, sigma, epsilon, reduction ); + amoebaVdwForce->setParticleParameters(ii, indexIV, sigma, epsilon, reduction); } platformName = "Reference"; - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); std::vector forces = state.getForces(); const double conversion = -AngstromToNm/CalToJoule; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ + for (unsigned int ii = 0; ii < forces.size(); ii++) { forces[ii][0] *= conversion; forces[ii][1] *= conversion; forces[ii][2] *= conversion; @@ -163,21 +163,21 @@ void testVdw( FILE* log ) { expectedEnergy *= CalToJoule; #ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaVdwForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); + if (log) { + (void) fprintf(log, "computeAmoebaVdwForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif double tolerance = 1.0e-03; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); // Try changing the particle parameters and make sure it's still correct. @@ -209,131 +209,131 @@ void testVdw( FILE* log ) { ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), tolerance); } -void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, - double boxDimension, std::vector& forces, double& energy, FILE* log ){ +void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, + double boxDimension, std::vector& forces, double& energy, FILE* log) { // beginning of Vdw setup System system; AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce();; int numberOfParticles = 8; - amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule ); - amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule ); - amoebaVdwForce->setCutoff( cutoff ); - if( boxDimension > 0.0 ){ - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + amoebaVdwForce->setSigmaCombiningRule(sigmaCombiningRule); + amoebaVdwForce->setEpsilonCombiningRule(epsilonCombiningRule); + amoebaVdwForce->setCutoff(cutoff); + if (boxDimension > 0.0) { + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); - amoebaVdwForce->setUseDispersionCorrection( 1 ); + amoebaVdwForce->setUseDispersionCorrection(1); } else { amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff); - amoebaVdwForce->setUseDispersionCorrection( 0 ); + amoebaVdwForce->setUseDispersionCorrection(0); } // addParticle: ivIndex, radius, epsilon, reductionFactor - system.addParticle( 1.4007000e+01 ); - amoebaVdwForce->addParticle( 0, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 ); + system.addParticle( 1.4007000e+01); + amoebaVdwForce->addParticle(0, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.4007000e+01 ); - amoebaVdwForce->addParticle( 4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 ); + system.addParticle( 1.4007000e+01); + amoebaVdwForce->addParticle(4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); // ParticleExclusions std::vector< int > exclusions; exclusions.resize(0); - exclusions.push_back( 0 ); - exclusions.push_back( 1 ); - exclusions.push_back( 2 ); - exclusions.push_back( 3 ); - amoebaVdwForce->setParticleExclusions( 0, exclusions ); + exclusions.push_back(0); + exclusions.push_back(1); + exclusions.push_back(2); + exclusions.push_back(3); + amoebaVdwForce->setParticleExclusions(0, exclusions); exclusions.resize(0); - exclusions.push_back( 1 ); - exclusions.push_back( 0 ); - exclusions.push_back( 2 ); - exclusions.push_back( 3 ); - amoebaVdwForce->setParticleExclusions( 1, exclusions ); + exclusions.push_back(1); + exclusions.push_back(0); + exclusions.push_back(2); + exclusions.push_back(3); + amoebaVdwForce->setParticleExclusions(1, exclusions); exclusions.resize(0); - exclusions.push_back( 2 ); - exclusions.push_back( 0 ); - exclusions.push_back( 1 ); - exclusions.push_back( 3 ); - amoebaVdwForce->setParticleExclusions( 2, exclusions ); + exclusions.push_back(2); + exclusions.push_back(0); + exclusions.push_back(1); + exclusions.push_back(3); + amoebaVdwForce->setParticleExclusions(2, exclusions); exclusions.resize(0); - exclusions.push_back( 3 ); - exclusions.push_back( 0 ); - exclusions.push_back( 1 ); - exclusions.push_back( 2 ); - amoebaVdwForce->setParticleExclusions( 3, exclusions ); + exclusions.push_back(3); + exclusions.push_back(0); + exclusions.push_back(1); + exclusions.push_back(2); + amoebaVdwForce->setParticleExclusions(3, exclusions); exclusions.resize(0); - exclusions.push_back( 4 ); - exclusions.push_back( 5 ); - exclusions.push_back( 6 ); - exclusions.push_back( 7 ); - amoebaVdwForce->setParticleExclusions( 4, exclusions ); + exclusions.push_back(4); + exclusions.push_back(5); + exclusions.push_back(6); + exclusions.push_back(7); + amoebaVdwForce->setParticleExclusions(4, exclusions); exclusions.resize(0); - exclusions.push_back( 5 ); - exclusions.push_back( 4 ); - exclusions.push_back( 6 ); - exclusions.push_back( 7 ); - amoebaVdwForce->setParticleExclusions( 5, exclusions ); + exclusions.push_back(5); + exclusions.push_back(4); + exclusions.push_back(6); + exclusions.push_back(7); + amoebaVdwForce->setParticleExclusions(5, exclusions); exclusions.resize(0); - exclusions.push_back( 6 ); - exclusions.push_back( 4 ); - exclusions.push_back( 5 ); - exclusions.push_back( 7 ); - amoebaVdwForce->setParticleExclusions( 6, exclusions ); + exclusions.push_back(6); + exclusions.push_back(4); + exclusions.push_back(5); + exclusions.push_back(7); + amoebaVdwForce->setParticleExclusions(6, exclusions); exclusions.resize(0); - exclusions.push_back( 7 ); - exclusions.push_back( 4 ); - exclusions.push_back( 5 ); - exclusions.push_back( 6 ); - amoebaVdwForce->setParticleExclusions( 7, exclusions ); + exclusions.push_back(7); + exclusions.push_back(4); + exclusions.push_back(5); + exclusions.push_back(6); + amoebaVdwForce->setParticleExclusions(7, exclusions); // end of Vdw setup std::vector positions(numberOfParticles); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); system.addForce(amoebaVdwForce); - if( boxDimension > 0.0 ){ + if (boxDimension > 0.0) { ASSERT(amoebaVdwForce->usesPeriodicBoundaryConditions()); } else { @@ -343,7 +343,7 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -351,35 +351,35 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c energy = state.getPotentialEnergy(); } -void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, - std::vector& expectedForces, - std::vector& forces, double tolerance, FILE* log ) { +void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, + std::vector& expectedForces, + std::vector& forces, double tolerance, FILE* log) { //#define AMOEBA_DEBUG #ifdef AMOEBA_DEBUG - if( log ){ + if (log) { double conversion = 1.0/4.184; - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); + (void) fprintf(log, "%s: expected energy=%14.7e %14.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, + for (unsigned int ii = 0; ii < forces.size(); ii++) { + (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); + conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); } - (void) fflush( log ); + (void) fflush(log); } #endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG -void testVdwAmmoniaCubicMeanHhg( FILE* log ) { +void testVdwAmmoniaCubicMeanHhg(FILE* log) { std::string testName = "testVdwAmmoniaCubicMeanHhg"; @@ -389,27 +389,27 @@ void testVdwAmmoniaCubicMeanHhg( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.8012258e+00; - expectedForces[0] = Vec3( 2.9265247e+02, -1.4507808e-02, -6.9562123e+00 ); - expectedForces[1] = Vec3( -2.2451693e+00, 4.8143073e-01, -2.0041494e-01 ); - expectedForces[2] = Vec3( -2.2440698e+00, -4.7905450e-01, -2.0125284e-01 ); - expectedForces[3] = Vec3( -1.0840394e+00, -5.8531253e-04, 2.6934135e-01 ); - expectedForces[4] = Vec3( -5.6305662e+01, 1.4733908e-03, -1.8083306e-01 ); - expectedForces[5] = Vec3( 1.6750145e+00, -3.2448374e-01, -1.8030914e-01 ); - expectedForces[6] = Vec3( -2.3412420e+02, 1.0754069e-02, 7.6287492e+00 ); - expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01 ); + expectedForces[0] = Vec3( 2.9265247e+02, -1.4507808e-02, -6.9562123e+00); + expectedForces[1] = Vec3( -2.2451693e+00, 4.8143073e-01, -2.0041494e-01); + expectedForces[2] = Vec3( -2.2440698e+00, -4.7905450e-01, -2.0125284e-01); + expectedForces[3] = Vec3( -1.0840394e+00, -5.8531253e-04, 2.6934135e-01); + expectedForces[4] = Vec3( -5.6305662e+01, 1.4733908e-03, -1.8083306e-01); + expectedForces[5] = Vec3( 1.6750145e+00, -3.2448374e-01, -1.8030914e-01); + expectedForces[6] = Vec3( -2.3412420e+02, 1.0754069e-02, 7.6287492e+00); + expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic -void testVdwAmmoniaArithmeticArithmetic( FILE* log ) { +void testVdwAmmoniaArithmeticArithmetic(FILE* log) { std::string testName = "testVdwAmmoniaArithmeticArithmetic"; @@ -419,27 +419,27 @@ void testVdwAmmoniaArithmeticArithmetic( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia("ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.2252403e+00; - expectedForces[0] = Vec3( 3.0603839e+02, -1.5550310e-02, -7.2661707e+00 ); - expectedForces[1] = Vec3( -2.7801357e+00, 5.8805051e-01, -2.5907269e-01 ); - expectedForces[2] = Vec3( -2.7753968e+00, -5.8440732e-01, -2.5969111e-01 ); - expectedForces[3] = Vec3( -2.2496416e+00, -1.1797440e-03, 5.5501757e-01 ); - expectedForces[4] = Vec3( -5.5077629e+01, 8.3417114e-04, -3.3668921e-01 ); - expectedForces[5] = Vec3( 2.3752452e+00, -4.6788669e-01, -2.4907764e-01 ); - expectedForces[6] = Vec3( -2.4790697e+02, 1.1419770e-02, 8.0629999e+00 ); - expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01 ); + expectedForces[0] = Vec3( 3.0603839e+02, -1.5550310e-02, -7.2661707e+00); + expectedForces[1] = Vec3( -2.7801357e+00, 5.8805051e-01, -2.5907269e-01); + expectedForces[2] = Vec3( -2.7753968e+00, -5.8440732e-01, -2.5969111e-01); + expectedForces[3] = Vec3( -2.2496416e+00, -1.1797440e-03, 5.5501757e-01); + expectedForces[4] = Vec3( -5.5077629e+01, 8.3417114e-04, -3.3668921e-01); + expectedForces[5] = Vec3( 2.3752452e+00, -4.6788669e-01, -2.4907764e-01); + expectedForces[6] = Vec3( -2.4790697e+02, 1.1419770e-02, 8.0629999e+00); + expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test VDW w/ sigmaRule=Geometric and epsilonRule=Geometric -void testVdwAmmoniaGeometricGeometric( FILE* log ) { +void testVdwAmmoniaGeometricGeometric(FILE* log) { std::string testName = "testVdwAmmoniaGeometricGeometric"; @@ -448,25 +448,25 @@ void testVdwAmmoniaGeometricGeometric( FILE* log ) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia("GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 2.5249914e+00; - expectedForces[0] = Vec3( 2.1169631e+02, -1.0710925e-02, -4.3728025e+00 ); - expectedForces[1] = Vec3( -2.2585621e+00, 4.8409995e-01, -2.0188344e-01 ); - expectedForces[2] = Vec3( -2.2551351e+00, -4.8124855e-01, -2.0246986e-01 ); - expectedForces[3] = Vec3( -1.7178028e+00, -9.0851787e-04, 4.2466975e-01 ); - expectedForces[4] = Vec3( -4.8302147e+01, 9.6603376e-04, -5.7972068e-01 ); - expectedForces[5] = Vec3( 1.8100634e+00, -3.5214093e-01, -1.9357207e-01 ); - expectedForces[6] = Vec3( -1.6078365e+02, 7.2117601e-03, 5.3180261e+00 ); - expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01 ); + expectedForces[0] = Vec3( 2.1169631e+02, -1.0710925e-02, -4.3728025e+00); + expectedForces[1] = Vec3( -2.2585621e+00, 4.8409995e-01, -2.0188344e-01); + expectedForces[2] = Vec3( -2.2551351e+00, -4.8124855e-01, -2.0246986e-01); + expectedForces[3] = Vec3( -1.7178028e+00, -9.0851787e-04, 4.2466975e-01); + expectedForces[4] = Vec3( -4.8302147e+01, 9.6603376e-04, -5.7972068e-01); + expectedForces[5] = Vec3( 1.8100634e+00, -3.5214093e-01, -1.9357207e-01); + expectedForces[6] = Vec3( -1.6078365e+02, 7.2117601e-03, 5.3180261e+00); + expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } -void testVdwAmmoniaCubicMeanHarmonic( FILE* log ) { +void testVdwAmmoniaCubicMeanHarmonic(FILE* log) { std::string testName = "testVdwAmmoniaCubicMeanHarmonic"; @@ -475,29 +475,29 @@ void testVdwAmmoniaCubicMeanHarmonic( FILE* log ) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.1369069e+00; - expectedForces[0] = Vec3( 2.5854436e+02, -1.2779529e-02, -5.9041148e+00 ); - expectedForces[1] = Vec3( -2.0832419e+00, 4.4915831e-01, -1.8266000e-01 ); - expectedForces[2] = Vec3( -2.0823991e+00, -4.4699804e-01, -1.8347141e-01 ); - expectedForces[3] = Vec3( -9.5914714e-01, -5.2162026e-04, 2.3873165e-01 ); - expectedForces[4] = Vec3( -5.3724787e+01, 1.4838241e-03, -2.8089191e-01 ); - expectedForces[5] = Vec3( 1.5074325e+00, -2.9016397e-01, -1.6385118e-01 ); - expectedForces[6] = Vec3( -2.0271029e+02, 9.2367947e-03, 6.6389988e+00 ); - expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01 ); + expectedForces[0] = Vec3( 2.5854436e+02, -1.2779529e-02, -5.9041148e+00); + expectedForces[1] = Vec3( -2.0832419e+00, 4.4915831e-01, -1.8266000e-01); + expectedForces[2] = Vec3( -2.0823991e+00, -4.4699804e-01, -1.8347141e-01); + expectedForces[3] = Vec3( -9.5914714e-01, -5.2162026e-04, 2.3873165e-01); + expectedForces[4] = Vec3( -5.3724787e+01, 1.4838241e-03, -2.8089191e-01); + expectedForces[5] = Vec3( 1.5074325e+00, -2.9016397e-01, -1.6385118e-01); + expectedForces[6] = Vec3( -2.0271029e+02, 9.2367947e-03, 6.6389988e+00); + expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test w/ cutoff=0.25 nm; single ixn between two particles (0 and 6); force nonzero on // particle 4 due to reduction applied to NH // the distance between 0 and 6 is ~ 0.235 so the ixn is in the tapered region -void testVdwTaper( FILE* log ) { +void testVdwTaper(FILE* log) { std::string testName = "testVdwTaper"; @@ -507,27 +507,27 @@ void testVdwTaper( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 3.5478444e+00; - expectedForces[0] = Vec3( 5.6710779e+02, -2.7391004e-02, -1.7867730e+01 ); - expectedForces[1] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[2] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[4] = Vec3( -5.1039701e+01, 2.4651903e-03, 1.6080957e+00 ); - expectedForces[5] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01 ); - expectedForces[7] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); + expectedForces[0] = Vec3( 5.6710779e+02, -2.7391004e-02, -1.7867730e+01); + expectedForces[1] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[2] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[4] = Vec3( -5.1039701e+01, 2.4651903e-03, 1.6080957e+00); + expectedForces[5] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01); + expectedForces[7] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // test PBC -void testVdwPBC( FILE* log ) { +void testVdwPBC(FILE* log) { std::string testName = "testVdwPBC"; @@ -537,79 +537,79 @@ void testVdwPBC( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log); std::vector expectedForces(numberOfParticles); double expectedEnergy = 1.4949141e+01; - expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01 ); - expectedForces[1] = Vec3( -2.5622586e+02, -4.6524265e+01, 2.4281465e+01 ); - expectedForces[2] = Vec3( -2.7538705e+02, 5.1831690e+01, 2.7367710e+01 ); - expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[4] = Vec3( 3.0883034e+02, -5.8876974e+00, -5.8286122e+01 ); - expectedForces[5] = Vec3( 1.1319359e+02, -3.2047069e-01, 1.6181231e+00 ); - expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01 ); - expectedForces[7] = Vec3( 1.1112638e+02, 3.7829857e-01, 1.5187587e+00 ); + expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01); + expectedForces[1] = Vec3( -2.5622586e+02, -4.6524265e+01, 2.4281465e+01); + expectedForces[2] = Vec3( -2.7538705e+02, 5.1831690e+01, 2.7367710e+01); + expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[4] = Vec3( 3.0883034e+02, -5.8876974e+00, -5.8286122e+01); + expectedForces[5] = Vec3( 1.1319359e+02, -3.2047069e-01, 1.6181231e+00); + expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01); + expectedForces[7] = Vec3( 1.1112638e+02, 3.7829857e-01, 1.5187587e+00); // tolerance is higher here due to interpolation used in setting tapering coefficients; // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); } // create box of 216 water molecules -void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, - double boxDimension, int includeVdwDispersionCorrection, - std::vector& forces, double& energy, FILE* log ){ +void setupAndGetForcesEnergyVdwWater(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, + double boxDimension, int includeVdwDispersionCorrection, + std::vector& forces, double& energy, FILE* log) { // beginning of Vdw setup System system; AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce();; int numberOfParticles = 648; - amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule ); - amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule ); - amoebaVdwForce->setCutoff( cutoff ); - if( boxDimension > 0.0 ){ - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + amoebaVdwForce->setSigmaCombiningRule(sigmaCombiningRule); + amoebaVdwForce->setEpsilonCombiningRule(epsilonCombiningRule); + amoebaVdwForce->setCutoff(cutoff); + if (boxDimension > 0.0) { + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); - amoebaVdwForce->setUseDispersionCorrection( includeVdwDispersionCorrection ); + amoebaVdwForce->setUseDispersionCorrection(includeVdwDispersionCorrection); } else { amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff); - amoebaVdwForce->setUseDispersionCorrection( 0 ); + amoebaVdwForce->setUseDispersionCorrection(0); } // addParticle: ivIndex, radius, epsilon, reductionFactor int classIndex = 0; - for( int ii = 0; ii < numberOfParticles; ii += 3 ){ + for (int ii = 0; ii < numberOfParticles; ii += 3) { - system.addParticle( 1.5995000e+01 ); - amoebaVdwForce->addParticle( ii, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00 ); + system.addParticle( 1.5995000e+01); + amoebaVdwForce->addParticle(ii, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01); } // exclusions std::vector< int > exclusions(3); - for( int ii = 0; ii < numberOfParticles; ii += 3 ){ + for (int ii = 0; ii < numberOfParticles; ii += 3) { exclusions[0] = ii; exclusions[1] = ii+1; exclusions[2] = ii+2; - amoebaVdwForce->setParticleExclusions( ii, exclusions ); - amoebaVdwForce->setParticleExclusions( ii+1, exclusions ); - amoebaVdwForce->setParticleExclusions( ii+2, exclusions ); + amoebaVdwForce->setParticleExclusions(ii, exclusions); + amoebaVdwForce->setParticleExclusions(ii+1, exclusions); + amoebaVdwForce->setParticleExclusions(ii+2, exclusions); } // end of Vdw setup @@ -618,661 +618,661 @@ void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, con std::vector positions(numberOfParticles); - positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02 ); - positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02 ); - positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02 ); - positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01 ); - positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01 ); - positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01 ); - positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01 ); - positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01 ); - positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01 ); - positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01 ); - positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01 ); - positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01 ); - positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01 ); - positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01 ); - positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01 ); - positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01 ); - positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01 ); - positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01 ); - positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01 ); - positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01 ); - positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01 ); - positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01 ); - positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01 ); - positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01 ); - positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01 ); - positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01 ); - positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02 ); - positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02 ); - positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01 ); - positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01 ); - positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01 ); - positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01 ); - positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01 ); - positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01 ); - positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01 ); - positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01 ); - positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01 ); - positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01 ); - positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01 ); - positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01 ); - positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01 ); - positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01 ); - positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01 ); - positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01 ); - positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01 ); - positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01 ); - positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01 ); - positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01 ); - positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01 ); - positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01 ); - positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01 ); - positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01 ); - positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01 ); - positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01 ); - positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01 ); - positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01 ); - positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01 ); - positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01 ); - positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01 ); - positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01 ); - positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01 ); - positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01 ); - positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01 ); - positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02 ); - positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02 ); - positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01 ); - positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02 ); - positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02 ); - positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01 ); - positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01 ); - positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01 ); - positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01 ); - positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01 ); - positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01 ); - positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01 ); - positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01 ); - positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02 ); - positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01 ); - positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01 ); - positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01 ); - positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01 ); - positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02 ); - positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01 ); - positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02 ); - positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01 ); - positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01 ); - positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01 ); - positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01 ); - positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01 ); - positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01 ); - positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01 ); - positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01 ); - positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01 ); - positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01 ); - positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01 ); - positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01 ); - positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01 ); - positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01 ); - positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01 ); - positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01 ); - positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01 ); - positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01 ); - positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01 ); - positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01 ); - positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01 ); - positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01 ); - positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01 ); - positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01 ); - positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01 ); - positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01 ); - positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01 ); - positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02 ); - positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02 ); - positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01 ); - positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01 ); - positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01 ); - positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01 ); - positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01 ); - positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01 ); - positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01 ); - positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01 ); - positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01 ); - positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01 ); - positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01 ); - positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02 ); - positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01 ); - positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01 ); - positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01 ); - positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01 ); - positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01 ); - positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01 ); - positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01 ); - positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01 ); - positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01 ); - positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01 ); - positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01 ); - positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01 ); - positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01 ); - positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01 ); - positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01 ); - positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01 ); - positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01 ); - positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01 ); - positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01 ); - positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01 ); - positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01 ); - positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01 ); - positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01 ); - positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01 ); - positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01 ); - positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01 ); - positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01 ); - positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01 ); - positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01 ); - positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01 ); - positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01 ); - positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02 ); - positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02 ); - positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02 ); - positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01 ); - positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02 ); - positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02 ); - positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01 ); - positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01 ); - positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01 ); - positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01 ); - positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01 ); - positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01 ); - positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01 ); - positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01 ); - positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01 ); - positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01 ); - positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01 ); - positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01 ); - positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01 ); - positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01 ); - positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01 ); - positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01 ); - positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01 ); - positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01 ); - positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01 ); - positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01 ); - positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01 ); - positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01 ); - positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01 ); - positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01 ); - positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02 ); - positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01 ); - positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03 ); - positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01 ); - positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01 ); - positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01 ); - positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01 ); - positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01 ); - positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01 ); - positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01 ); - positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01 ); - positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01 ); - positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01 ); - positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01 ); - positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01 ); - positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02 ); - positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01 ); - positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02 ); - positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01 ); - positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01 ); - positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01 ); - positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01 ); - positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01 ); - positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01 ); - positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01 ); - positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01 ); - positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01 ); - positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01 ); - positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01 ); - positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01 ); - positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01 ); - positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01 ); - positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01 ); - positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01 ); - positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01 ); - positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01 ); - positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01 ); - positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01 ); - positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01 ); - positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02 ); - positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01 ); - positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02 ); - positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01 ); - positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01 ); - positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01 ); - positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01 ); - positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01 ); - positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01 ); - positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01 ); - positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01 ); - positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01 ); - positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01 ); - positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01 ); - positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01 ); - positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01 ); - positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01 ); - positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01 ); - positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02 ); - positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01 ); - positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02 ); - positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01 ); - positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01 ); - positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01 ); - positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01 ); - positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01 ); - positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01 ); - positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01 ); - positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01 ); - positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01 ); - positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01 ); - positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01 ); - positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01 ); - positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01 ); - positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01 ); - positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01 ); - positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01 ); - positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01 ); - positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01 ); - positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03 ); - positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03 ); - positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02 ); - positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01 ); - positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01 ); - positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01 ); - positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01 ); - positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01 ); - positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01 ); - positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01 ); - positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01 ); - positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01 ); - positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01 ); - positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01 ); - positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01 ); - positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01 ); - positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01 ); - positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01 ); - positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01 ); - positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01 ); - positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01 ); - positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01 ); - positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01 ); - positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01 ); - positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02 ); - positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01 ); - positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02 ); - positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01 ); - positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01 ); - positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01 ); - positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01 ); - positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02 ); - positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02 ); - positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01 ); - positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01 ); - positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01 ); - positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01 ); - positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01 ); - positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01 ); - positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01 ); - positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01 ); - positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01 ); - positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01 ); - positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01 ); - positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01 ); - positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01 ); - positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01 ); - positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01 ); - positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01 ); - positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01 ); - positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01 ); - positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02 ); - positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01 ); - positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02 ); - positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01 ); - positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01 ); - positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01 ); - positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01 ); - positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01 ); - positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01 ); - positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01 ); - positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01 ); - positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01 ); - positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02 ); - positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02 ); - positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02 ); - positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01 ); - positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01 ); - positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01 ); - positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01 ); - positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01 ); - positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01 ); - positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01 ); - positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01 ); - positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01 ); - positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01 ); - positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01 ); - positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01 ); - positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02 ); - positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02 ); - positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02 ); - positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01 ); - positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01 ); - positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01 ); - positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01 ); - positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01 ); - positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01 ); - positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01 ); - positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01 ); - positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01 ); - positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01 ); - positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01 ); - positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01 ); - positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01 ); - positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01 ); - positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01 ); - positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01 ); - positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01 ); - positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01 ); - positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01 ); - positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02 ); - positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01 ); - positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01 ); - positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02 ); - positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01 ); - positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01 ); - positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01 ); - positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01 ); - positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01 ); - positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01 ); - positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01 ); - positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01 ); - positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01 ); - positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01 ); - positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02 ); - positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02 ); - positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02 ); - positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01 ); - positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01 ); - positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01 ); - positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01 ); - positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01 ); - positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01 ); - positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01 ); - positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01 ); - positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01 ); - positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01 ); - positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01 ); - positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01 ); - positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01 ); - positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01 ); - positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01 ); - positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01 ); - positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01 ); - positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01 ); - positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01 ); - positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01 ); - positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01 ); - positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01 ); - positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01 ); - positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01 ); - positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02 ); - positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01 ); - positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03 ); - positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01 ); - positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01 ); - positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01 ); - positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01 ); - positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01 ); - positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01 ); - positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03 ); - positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02 ); - positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03 ); - positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01 ); - positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01 ); - positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01 ); - positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01 ); - positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01 ); - positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01 ); - positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01 ); - positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01 ); - positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01 ); - positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01 ); - positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01 ); - positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01 ); - positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01 ); - positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01 ); - positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01 ); - positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01 ); - positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01 ); - positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01 ); - positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01 ); - positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01 ); - positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01 ); - positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01 ); - positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01 ); - positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01 ); - positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02 ); - positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02 ); - positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01 ); - positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01 ); - positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01 ); - positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01 ); - positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01 ); - positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01 ); - positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01 ); - positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01 ); - positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01 ); - positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01 ); - positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01 ); - positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01 ); - positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01 ); - positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01 ); - positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01 ); - positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01 ); - positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01 ); - positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01 ); - positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01 ); - positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01 ); - positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01 ); - positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01 ); - positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01 ); - positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01 ); - positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01 ); - positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01 ); - positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01 ); - positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01 ); - positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02 ); - positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03 ); - positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01 ); - positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01 ); - positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01 ); - positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01 ); - positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01 ); - positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01 ); - positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01 ); - positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01 ); - positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01 ); - positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01 ); - positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01 ); - positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01 ); - positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02 ); - positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01 ); - positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01 ); - positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01 ); - positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01 ); - positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01 ); - positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01 ); - positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01 ); - positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01 ); - positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01 ); - positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01 ); - positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01 ); - positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01 ); - positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01 ); - positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01 ); - positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01 ); - positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01 ); - positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01 ); - positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01 ); - positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01 ); - positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01 ); - positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01 ); - positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01 ); - positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01 ); - positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01 ); - positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01 ); - positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01 ); - positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01 ); - positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01 ); - positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01 ); - positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01 ); - positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01 ); - positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01 ); - positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01 ); - positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01 ); - positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01 ); - positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01 ); - positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01 ); - positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01 ); - positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01 ); - positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01 ); - positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01 ); - positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01 ); - positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01 ); - positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01 ); - positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01 ); - positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01 ); - positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01 ); - positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01 ); - positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01 ); - positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01 ); - positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01 ); - positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01 ); - positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01 ); - positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01 ); - positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01 ); - positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01 ); - positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01 ); - positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01 ); - positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01 ); - positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01 ); - positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01 ); - positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01 ); - positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01 ); - positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01 ); - positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01 ); - positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01 ); - positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02 ); - positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01 ); - positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02 ); - positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01 ); - positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01 ); - positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02 ); - positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02 ); - positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02 ); - positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02 ); - positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01 ); - positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01 ); - positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01 ); - positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01 ); - positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02 ); - positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02 ); - positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01 ); - positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01 ); - positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01 ); - positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01 ); - positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01 ); - positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01 ); - positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01 ); - positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01 ); - positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01 ); - positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02 ); - positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02 ); - positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02 ); - positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02 ); - positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02 ); - positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01 ); - positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01 ); - positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01 ); - positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01 ); - positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01 ); - positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01 ); - positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01 ); - positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01 ); - positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01 ); - positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01 ); - positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01 ); - positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01 ); - positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01 ); - positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01 ); - positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01 ); - positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01 ); - positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01 ); - positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01 ); - positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01 ); - positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01 ); - positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01 ); - positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01 ); - positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01 ); - positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01 ); - positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01 ); - positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01 ); - positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01 ); - positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01 ); - positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01 ); - positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01 ); - positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01 ); - positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01 ); - positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01 ); - positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01 ); - positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01 ); - positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01 ); - positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01 ); - positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01 ); - positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01 ); - positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01 ); - positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01 ); - positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01 ); - positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01 ); - positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01 ); - positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01 ); - positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01 ); - positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01 ); - positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01 ); - positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01 ); - positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01 ); - positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01 ); - positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01 ); - positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01 ); - positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01 ); - positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01 ); - positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01 ); - positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01 ); - positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01 ); - positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01 ); - positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01 ); - positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01 ); - positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01 ); - positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01 ); - positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01 ); - positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01 ); - positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01 ); - positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01 ); + positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); + positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); + positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); + positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); + positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); + positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); + positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01); + positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01); + positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01); + positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); + positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); + positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); + positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); + positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); + positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); + positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01); + positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01); + positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01); + positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01); + positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01); + positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01); + positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01); + positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01); + positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); + positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01); + positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01); + positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02); + positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02); + positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01); + positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01); + positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); + positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); + positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); + positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); + positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01); + positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); + positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); + positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); + positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01); + positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); + positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); + positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); + positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); + positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); + positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); + positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); + positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); + positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); + positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01); + positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01); + positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01); + positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01); + positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01); + positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01); + positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); + positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); + positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); + positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01); + positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01); + positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01); + positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); + positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); + positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); + positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02); + positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02); + positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01); + positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02); + positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02); + positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01); + positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01); + positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01); + positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01); + positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); + positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); + positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); + positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01); + positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02); + positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01); + positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); + positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); + positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); + positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); + positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); + positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); + positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01); + positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); + positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); + positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); + positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); + positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); + positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); + positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); + positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); + positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01); + positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01); + positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01); + positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); + positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); + positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); + positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); + positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); + positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); + positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01); + positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01); + positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01); + positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); + positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); + positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); + positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); + positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); + positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); + positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); + positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); + positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); + positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01); + positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01); + positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01); + positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01); + positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01); + positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01); + positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); + positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); + positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); + positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01); + positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02); + positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01); + positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01); + positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01); + positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01); + positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); + positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); + positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); + positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01); + positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01); + positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01); + positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01); + positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01); + positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01); + positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01); + positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01); + positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01); + positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); + positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); + positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); + positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); + positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); + positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); + positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); + positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); + positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); + positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01); + positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01); + positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01); + positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01); + positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01); + positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01); + positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02); + positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02); + positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); + positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); + positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); + positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); + positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); + positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); + positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); + positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); + positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); + positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); + positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); + positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01); + positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); + positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01); + positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01); + positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01); + positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); + positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); + positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); + positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01); + positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01); + positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01); + positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); + positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); + positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); + positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01); + positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01); + positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01); + positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02); + positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01); + positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03); + positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01); + positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01); + positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01); + positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); + positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); + positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); + positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); + positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01); + positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); + positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01); + positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01); + positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01); + positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); + positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); + positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); + positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); + positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); + positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); + positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01); + positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01); + positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01); + positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); + positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); + positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); + positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01); + positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01); + positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01); + positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); + positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); + positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); + positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); + positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01); + positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01); + positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); + positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); + positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); + positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); + positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); + positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); + positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01); + positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01); + positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01); + positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01); + positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01); + positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01); + positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); + positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); + positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); + positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01); + positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01); + positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01); + positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01); + positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01); + positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01); + positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); + positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); + positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); + positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01); + positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01); + positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01); + positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); + positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); + positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); + positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); + positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); + positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); + positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01); + positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01); + positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); + positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01); + positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01); + positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01); + positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01); + positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01); + positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01); + positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); + positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); + positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); + positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01); + positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01); + positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01); + positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); + positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); + positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); + positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); + positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); + positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); + positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); + positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); + positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); + positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01); + positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01); + positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01); + positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01); + positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01); + positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01); + positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01); + positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01); + positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01); + positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02); + positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01); + positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02); + positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01); + positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01); + positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01); + positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); + positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); + positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); + positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01); + positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); + positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01); + positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01); + positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01); + positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01); + positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01); + positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01); + positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01); + positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); + positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); + positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); + positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); + positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); + positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); + positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01); + positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01); + positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01); + positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02); + positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01); + positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02); + positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); + positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); + positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); + positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01); + positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01); + positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01); + positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01); + positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01); + positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01); + positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02); + positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02); + positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02); + positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01); + positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01); + positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01); + positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01); + positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01); + positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01); + positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01); + positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01); + positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01); + positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); + positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); + positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); + positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); + positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); + positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); + positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01); + positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01); + positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01); + positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); + positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); + positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); + positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01); + positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01); + positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01); + positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); + positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); + positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); + positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); + positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); + positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); + positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01); + positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01); + positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01); + positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01); + positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02); + positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01); + positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01); + positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02); + positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01); + positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01); + positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01); + positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01); + positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01); + positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01); + positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01); + positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); + positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); + positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); + positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); + positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); + positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); + positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); + positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); + positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); + positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); + positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); + positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); + positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01); + positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01); + positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01); + positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01); + positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01); + positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01); + positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); + positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); + positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); + positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01); + positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01); + positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01); + positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); + positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); + positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); + positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); + positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); + positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); + positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); + positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); + positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); + positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); + positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); + positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01); + positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); + positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); + positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); + positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); + positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); + positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); + positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01); + positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01); + positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01); + positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); + positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); + positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); + positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01); + positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01); + positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01); + positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); + positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); + positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); + positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01); + positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01); + positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01); + positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); + positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); + positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); + positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01); + positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01); + positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01); + positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); + positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); + positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); + positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02); + positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); + positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01); + positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); + positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); + positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); + positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); + positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); + positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); + positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01); + positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01); + positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01); + positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01); + positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01); + positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01); + positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); + positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); + positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); + positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01); + positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01); + positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01); + positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01); + positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01); + positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01); + positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01); + positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01); + positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01); + positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); + positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); + positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); + positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); + positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); + positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); + positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); + positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); + positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); + positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); + positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); + positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); + positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01); + positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01); + positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01); + positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01); + positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01); + positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02); + positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01); + positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01); + positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01); + positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); + positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); + positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); + positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01); + positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01); + positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01); + positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01); + positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01); + positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01); + positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01); + positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01); + positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01); + positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01); + positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01); + positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01); + positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01); + positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01); + positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01); + positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); + positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); + positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); + positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); + positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); + positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); + positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01); + positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01); + positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01); + positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01); + positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01); + positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01); + positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); + positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); + positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); + positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); + positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); + positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); + positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); + positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); + positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); + positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); + positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); + positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); + positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); + positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); + positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); + positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); + positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); + positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); + positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); + positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); + positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); + positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); + positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); + positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); + positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01); + positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01); + positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01); + positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01); + positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01); + positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01); + positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01); + positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01); + positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01); + positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); + positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); + positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); + positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01); + positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01); + positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02); + positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02); + positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02); + positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02); + positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01); + positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01); + positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01); + positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); + positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); + positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); + positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01); + positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01); + positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); + positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01); + positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01); + positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01); + positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01); + positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01); + positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01); + positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); + positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02); + positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); + positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02); + positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02); + positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01); + positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01); + positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01); + positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01); + positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); + positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); + positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); + positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); + positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); + positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); + positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01); + positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01); + positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01); + positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01); + positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01); + positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01); + positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01); + positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01); + positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01); + positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); + positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); + positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); + positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01); + positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01); + positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01); + positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); + positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); + positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); + positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); + positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); + positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); + positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01); + positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01); + positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01); + positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); + positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); + positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); + positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01); + positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01); + positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01); + positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01); + positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01); + positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01); + positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); + positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); + positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); + positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); + positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); + positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); + positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01); + positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01); + positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01); + positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); + positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); + positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); + positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); + positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); + positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); + positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01); + positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01); + positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01); + positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); + positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); + positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); + positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01); + positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01); + positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01); system.addForce(amoebaVdwForce); std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -1282,11 +1282,11 @@ void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, con // test employing box of 216 water molecules w/ and w/o dispersion correction -void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { +void testVdwWater(int includeVdwDispersionCorrection, FILE* log) { std::string testName; - if( includeVdwDispersionCorrection ){ + if (includeVdwDispersionCorrection) { testName = "testVdwWaterWithDispersionCorrection"; } else { @@ -1299,698 +1299,698 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwWater( "CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log ); + setupAndGetForcesEnergyVdwWater("CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log); std::vector expectedForces(numberOfParticles); // initialize expected energy and forces double expectedEnergy; - if( includeVdwDispersionCorrection ){ + if (includeVdwDispersionCorrection) { expectedEnergy = 4.0108819792e+03; } else { expectedEnergy = 4.0349101e+03; } - expectedForces[0] = Vec3( 2.3025909e+02, -1.0422757e+01, -2.1413965e+02 ); - expectedForces[1] = Vec3( 1.1261936e+02, 5.5882575e+02, 9.6539143e+01 ); - expectedForces[2] = Vec3( -8.8436857e+01, -4.4737313e+01, 2.5242022e+02 ); - expectedForces[3] = Vec3( 6.3548886e+02, -1.9582636e+02, -1.2229882e+02 ); - expectedForces[4] = Vec3( -3.9513809e+02, -1.3738635e+02, -1.2488717e+02 ); - expectedForces[5] = Vec3( 6.8771170e+00, 9.1574345e+01, -1.3865672e+00 ); - expectedForces[6] = Vec3( 3.6928792e+02, -7.1025648e+01, 5.2550320e+02 ); - expectedForces[7] = Vec3( 1.5531325e+02, -7.9256260e+02, 3.8119809e+02 ); - expectedForces[8] = Vec3( 1.5408049e+02, 1.4633285e+02, -5.4573735e+02 ); - expectedForces[9] = Vec3( -3.2549641e+02, 2.8613802e+01, 1.8082150e+02 ); - expectedForces[10] = Vec3( 1.9968249e+02, -7.7742415e+01, -4.2188467e+02 ); - expectedForces[11] = Vec3( 4.6645952e+01, 2.1362909e+01, 5.7120135e+01 ); - expectedForces[12] = Vec3( 4.2971265e+01, -4.2927865e+01, -7.6319121e+02 ); - expectedForces[13] = Vec3( 2.1889551e+02, -5.1806784e+01, 7.6637073e+01 ); - expectedForces[14] = Vec3( -3.0028991e+02, 9.0479382e+01, 1.3199449e+02 ); - expectedForces[15] = Vec3( -1.8041801e+00, -1.2176813e+03, -5.9679371e+02 ); - expectedForces[16] = Vec3( -1.4773339e+02, -1.2582057e+02, 8.4242040e+02 ); - expectedForces[17] = Vec3( 6.8633312e+02, -2.4864325e+01, 1.0675519e+01 ); - expectedForces[18] = Vec3( 4.8211733e+02, -2.2044742e+02, 1.8105309e+02 ); - expectedForces[19] = Vec3( -2.1956736e+02, 5.4786741e+02, -1.4827263e+02 ); - expectedForces[20] = Vec3( -1.0476100e+02, -1.6922280e+02, 8.3220473e+01 ); - expectedForces[21] = Vec3( 5.5455350e+01, 1.7851224e+02, 6.0598643e+02 ); - expectedForces[22] = Vec3( 7.1915871e+00, -1.6455057e+01, -6.3929797e+00 ); - expectedForces[23] = Vec3( -2.4371864e+02, -7.0765288e+02, -1.7820148e+02 ); - expectedForces[24] = Vec3( -4.3715367e+02, 2.8707226e+02, 2.2558361e+02 ); - expectedForces[25] = Vec3( 2.3735557e+00, -4.2064130e+00, 2.5933632e+01 ); - expectedForces[26] = Vec3( 1.0192415e+02, 5.3205842e+01, -2.0158900e+02 ); - expectedForces[27] = Vec3( -5.1276812e+02, 2.4860179e+02, 2.5150125e+02 ); - expectedForces[28] = Vec3( 3.9608987e+02, -4.0544816e+01, -2.1579831e+02 ); - expectedForces[29] = Vec3( -2.5926005e+02, -1.1691294e+02, -4.7278417e+02 ); - expectedForces[30] = Vec3( -1.1036158e+02, 3.3229287e+01, 8.8351491e+01 ); - expectedForces[31] = Vec3( -4.1178603e+00, 1.2957632e+00, 1.2617868e+00 ); - expectedForces[32] = Vec3( 1.9401524e+02, 1.0030314e+02, 3.0386141e+01 ); - expectedForces[33] = Vec3( 1.0870981e+02, 2.1865882e+02, 6.7672725e+02 ); - expectedForces[34] = Vec3( 3.6812338e+01, -2.9347382e-01, 1.2959790e+01 ); - expectedForces[35] = Vec3( -5.5738560e+01, 2.2268442e+02, -1.4911862e+02 ); - expectedForces[36] = Vec3( -1.6659719e+02, 8.1941190e+01, 7.8132996e+01 ); - expectedForces[37] = Vec3( -1.1985659e+02, 7.1891763e+01, -3.2559738e+02 ); - expectedForces[38] = Vec3( 1.4441653e+02, 4.1824194e+02, 3.4293255e+01 ); - expectedForces[39] = Vec3( 1.1307312e+02, -3.4981802e+02, -1.0676819e+02 ); - expectedForces[40] = Vec3( -1.2857487e+02, -4.0798950e+01, -1.7800009e+02 ); - expectedForces[41] = Vec3( -4.1244991e+02, 2.3439565e+02, 3.8546709e+02 ); - expectedForces[42] = Vec3( 2.1799653e+02, 2.9397348e+02, -3.8955146e+02 ); - expectedForces[43] = Vec3( -9.4254462e+01, 5.0157547e+01, 1.3707146e+02 ); - expectedForces[44] = Vec3( 8.0520929e+02, -1.0228045e+03, -4.5813594e+01 ); - expectedForces[45] = Vec3( 5.3451125e+02, -7.0725115e+02, -2.3828883e+02 ); - expectedForces[46] = Vec3( 3.6991801e+02, -1.0410466e+03, 8.4889413e+02 ); - expectedForces[47] = Vec3( 5.8096458e+01, 2.3859368e+02, 7.3104979e+01 ); - expectedForces[48] = Vec3( -1.3230378e+03, 7.1827816e+02, 9.4372946e+02 ); - expectedForces[49] = Vec3( -4.2398413e+02, -3.6766481e+02, -1.6666711e+02 ); - expectedForces[50] = Vec3( 8.6374766e+00, -2.7870227e+02, 3.0621233e+02 ); - expectedForces[51] = Vec3( -2.4404981e+02, 1.0510491e+03, -3.5202340e+02 ); - expectedForces[52] = Vec3( 1.7461155e+02, 1.3419948e+02, 5.0279733e+02 ); - expectedForces[53] = Vec3( 9.7089193e+01, -1.4826120e+02, -2.3426711e+02 ); - expectedForces[54] = Vec3( -1.0647432e+02, 2.3266543e+02, -3.5025025e+02 ); - expectedForces[55] = Vec3( -1.9951717e+02, -1.0804258e+02, 6.2114265e+01 ); - expectedForces[56] = Vec3( 2.5354284e+02, -3.5074926e+02, -2.9176946e+01 ); - expectedForces[57] = Vec3( -8.8328002e+02, -1.8937053e+02, 2.0772189e+02 ); - expectedForces[58] = Vec3( 4.5809698e+01, -1.8636513e+00, 1.6742910e+01 ); - expectedForces[59] = Vec3( 8.6670673e+01, 1.2653519e+02, 2.0046372e+02 ); - expectedForces[60] = Vec3( -9.6142275e+02, 1.1800289e+03, 1.0064471e+02 ); - expectedForces[61] = Vec3( -6.9751453e+01, -1.9324691e+02, 2.2638891e+01 ); - expectedForces[62] = Vec3( 1.3671815e+02, 1.0129231e+01, -6.1136892e+01 ); - expectedForces[63] = Vec3( 7.6032938e+02, -1.9779542e+02, -2.5706161e+01 ); - expectedForces[64] = Vec3( -9.8966607e+00, 3.6294058e+02, -2.3247376e+02 ); - expectedForces[65] = Vec3( -1.3142673e+02, 9.9368000e+00, 1.4225069e+02 ); - expectedForces[66] = Vec3( 5.2691625e+01, -4.0618331e+02, -1.0942115e+02 ); - expectedForces[67] = Vec3( 5.8137742e+01, 2.1942441e+02, -1.7191686e+02 ); - expectedForces[68] = Vec3( 1.2480778e+02, 2.4086799e+01, -1.9588545e+02 ); - expectedForces[69] = Vec3( 2.4577512e+02, -2.3516051e+01, 2.3764379e+02 ); - expectedForces[70] = Vec3( 4.2298797e+01, 8.6807583e+01, 2.9276129e+02 ); - expectedForces[71] = Vec3( 3.0309915e+01, -3.4686002e+02, 1.0849989e+02 ); - expectedForces[72] = Vec3( 5.5170999e+02, -1.5797913e+02, 9.8379834e+01 ); - expectedForces[73] = Vec3( -5.3706921e+02, 2.2236470e+02, 2.7548665e+02 ); - expectedForces[74] = Vec3( -2.7734936e+02, -4.2949693e+02, -8.2303469e+02 ); - expectedForces[75] = Vec3( 1.1749001e+03, 9.2734627e+02, -2.6342291e+02 ); - expectedForces[76] = Vec3( -1.2345216e+02, -6.6220297e+01, 1.1022778e+02 ); - expectedForces[77] = Vec3( -4.4861284e+01, -7.4560959e+01, -8.0791275e+01 ); - expectedForces[78] = Vec3( 1.7692476e+01, -9.9067626e+02, -3.3083363e+02 ); - expectedForces[79] = Vec3( 6.4276566e+01, 5.1865608e+02, 4.1241764e+02 ); - expectedForces[80] = Vec3( 6.5867999e+02, 2.0995465e+02, -5.0989840e+02 ); - expectedForces[81] = Vec3( -5.2826435e+02, -1.3719887e+02, 1.9730314e+02 ); - expectedForces[82] = Vec3( 2.3329314e+02, 5.1589944e+01, -3.3942818e+02 ); - expectedForces[83] = Vec3( -2.5756193e+00, 1.3788257e+02, 1.3074778e+02 ); - expectedForces[84] = Vec3( -2.8925811e+01, 8.8185346e+01, 1.1547804e+02 ); - expectedForces[85] = Vec3( -3.3582542e+01, -1.3079843e+02, 3.4774799e+02 ); - expectedForces[86] = Vec3( -5.9585326e+01, -3.7973755e+01, 1.0206767e+01 ); - expectedForces[87] = Vec3( -7.1691223e+01, -1.9547311e+02, 9.3856472e+02 ); - expectedForces[88] = Vec3( 1.4832977e+02, 4.2005795e+02, 2.7235044e+01 ); - expectedForces[89] = Vec3( 8.6221698e+00, -1.3935906e+01, -2.5473157e+00 ); - expectedForces[90] = Vec3( 3.0044348e+02, 3.4320406e+02, 2.5305998e+02 ); - expectedForces[91] = Vec3( -1.6694013e+02, 7.4645776e+02, 3.3266168e+01 ); - expectedForces[92] = Vec3( 1.6931562e+02, -2.3972286e+01, -3.0802865e+02 ); - expectedForces[93] = Vec3( -2.5931152e+02, -9.7825375e+01, -5.5598386e+02 ); - expectedForces[94] = Vec3( -7.8473519e+01, -2.6244561e+02, 2.9622027e+02 ); - expectedForces[95] = Vec3( 1.5788473e+02, 2.9806605e+02, 1.8283700e+02 ); - expectedForces[96] = Vec3( -4.2033208e+02, 4.8745845e+02, 9.7957219e+01 ); - expectedForces[97] = Vec3( 1.3261733e+00, 3.7143158e+00, -1.8329960e+00 ); - expectedForces[98] = Vec3( 7.4741051e+02, 1.0482696e+03, 1.7182445e+02 ); - expectedForces[99] = Vec3( 2.0366606e+02, 1.1586652e+02, 1.5482927e+03 ); - expectedForces[100] = Vec3( 5.7569884e+02, -2.2068597e+02, -1.9305186e+02 ); - expectedForces[101] = Vec3( -2.4259775e+02, -6.1359858e+01, -7.5753918e+01 ); - expectedForces[102] = Vec3( 2.4382837e+02, 1.3660693e+01, -2.8717824e+02 ); - expectedForces[103] = Vec3( -4.1914381e+02, -1.4506334e+02, 7.7692658e+01 ); - expectedForces[104] = Vec3( 9.5422158e+01, -1.4261849e+01, 1.0122453e+02 ); - expectedForces[105] = Vec3( -6.1222151e+02, 6.1398147e+01, 3.2961693e+02 ); - expectedForces[106] = Vec3( -2.7982116e+02, -3.7564793e+02, -2.4318658e+02 ); - expectedForces[107] = Vec3( 8.2892383e+01, 1.1992522e+01, 2.4802899e+01 ); - expectedForces[108] = Vec3( -3.3626753e+02, -7.8892295e+01, 8.1184535e+02 ); - expectedForces[109] = Vec3( -4.6396103e+01, 3.1165111e+01, -3.5184949e+01 ); - expectedForces[110] = Vec3( 4.6295297e+02, -8.0135823e+01, -3.2963637e+02 ); - expectedForces[111] = Vec3( 5.5325945e+02, 3.8213691e+02, -5.9449911e+02 ); - expectedForces[112] = Vec3( -6.1770559e+02, 2.2322880e+02, -2.1022934e+01 ); - expectedForces[113] = Vec3( 2.3716825e+02, -3.8085281e+02, 4.9618193e+02 ); - expectedForces[114] = Vec3( 2.9972570e+02, 3.3773759e+02, 3.4933501e+02 ); - expectedForces[115] = Vec3( 1.9913039e+02, -3.2035626e+02, -9.7987777e+01 ); - expectedForces[116] = Vec3( -2.3506456e+02, 4.0030561e+02, -6.2604809e+02 ); - expectedForces[117] = Vec3( 6.0408777e+02, 5.6271523e+02, -5.8742635e+02 ); - expectedForces[118] = Vec3( -5.0707285e+02, 7.8511351e+02, -1.7561830e+02 ); - expectedForces[119] = Vec3( 5.6759945e+00, 6.9735233e+00, -9.8853787e+00 ); - expectedForces[120] = Vec3( 1.1918531e+02, -5.6200785e+02, 3.2333502e+02 ); - expectedForces[121] = Vec3( 5.1801315e+02, -3.4460898e+02, 1.1488242e+02 ); - expectedForces[122] = Vec3( 7.5859703e+00, 6.9528951e+01, -6.2437444e+00 ); - expectedForces[123] = Vec3( 1.1990899e+03, -1.2507886e+01, 1.1906562e+03 ); - expectedForces[124] = Vec3( 2.6001536e+02, -9.5041373e+01, -4.2547252e+02 ); - expectedForces[125] = Vec3( -3.5601586e+01, 9.1460220e+02, 6.2306102e+02 ); - expectedForces[126] = Vec3( -3.8254176e+01, 2.4796243e+02, 3.0638741e+02 ); - expectedForces[127] = Vec3( -3.8798311e+02, 1.2532794e+02, -3.1926601e+01 ); - expectedForces[128] = Vec3( 5.7672682e+01, 1.7487900e+02, -1.0319581e+02 ); - expectedForces[129] = Vec3( 4.4276215e+02, -1.5517993e+02, 3.8122873e+02 ); - expectedForces[130] = Vec3( -2.8119980e+02, -2.6530936e+02, 4.3545814e+01 ); - expectedForces[131] = Vec3( 5.9375768e+00, 1.6335780e+01, -3.6204644e+02 ); - expectedForces[132] = Vec3( 5.9733834e+02, -2.9843602e+02, 1.0541092e+03 ); - expectedForces[133] = Vec3( -3.4568461e+02, 2.2794808e+02, -8.4675886e+01 ); - expectedForces[134] = Vec3( -6.7882706e+01, -4.5016799e+02, -1.9387646e+02 ); - expectedForces[135] = Vec3( 5.6125478e+02, -1.1741092e+03, 1.4214256e+02 ); - expectedForces[136] = Vec3( 1.2766648e+02, 1.2519441e+02, -4.4359129e+02 ); - expectedForces[137] = Vec3( -2.7235507e+01, -1.0871423e+01, 3.2406976e+01 ); - expectedForces[138] = Vec3( -1.2110689e+03, 1.3038667e+02, -7.5331947e+02 ); - expectedForces[139] = Vec3( 3.2504988e+02, -7.1577942e+02, -2.4351454e+02 ); - expectedForces[140] = Vec3( 2.6466925e+02, 3.6878498e+02, -6.2044711e+01 ); - expectedForces[141] = Vec3( -6.2647276e+02, -4.7112562e+02, -6.1885184e+01 ); - expectedForces[142] = Vec3( 3.0996699e+01, 3.1033732e+02, -5.7493337e+02 ); - expectedForces[143] = Vec3( 2.4664962e+01, 7.8306665e+02, 3.7907751e+02 ); - expectedForces[144] = Vec3( -1.9847551e+02, -3.0052499e+02, -6.5192951e+01 ); - expectedForces[145] = Vec3( -5.0686773e+02, 1.1972933e+02, 3.6202910e+02 ); - expectedForces[146] = Vec3( 4.0004521e+02, -4.3205645e+02, 2.8583074e+02 ); - expectedForces[147] = Vec3( -2.9447542e+01, 6.3434099e+02, -6.5189179e+02 ); - expectedForces[148] = Vec3( 4.1588516e+02, -1.5534873e+02, -1.1031323e+01 ); - expectedForces[149] = Vec3( 1.2761543e+01, -5.6871456e+01, 2.8032565e+02 ); - expectedForces[150] = Vec3( -4.7527199e+01, 6.2549647e+02, -8.5007589e+02 ); - expectedForces[151] = Vec3( 1.6598949e+01, 1.1210199e+02, 2.0667266e+02 ); - expectedForces[152] = Vec3( -2.4012423e+00, -6.1728962e+01, -1.5057977e+01 ); - expectedForces[153] = Vec3( -3.6934056e+02, 2.3087063e+02, -3.3268511e+02 ); - expectedForces[154] = Vec3( 1.2658460e+02, 4.1809355e+02, 1.9550635e+02 ); - expectedForces[155] = Vec3( -1.9528152e+02, -1.9035919e+02, 1.4986704e+02 ); - expectedForces[156] = Vec3( -5.9608803e+00, 2.7258190e+02, 5.5318395e+02 ); - expectedForces[157] = Vec3( -1.0545084e+01, -1.8397001e+00, -3.3615498e+00 ); - expectedForces[158] = Vec3( -4.0827462e+02, -6.4070993e+01, -2.6614992e+02 ); - expectedForces[159] = Vec3( -1.5773827e+02, 4.7708702e+02, -9.9622711e+02 ); - expectedForces[160] = Vec3( 8.3896122e+01, 2.5959601e+02, 1.7728081e+02 ); - expectedForces[161] = Vec3( -2.4859055e+02, 8.1617294e+01, 2.7905586e+02 ); - expectedForces[162] = Vec3( 1.3694593e+02, -6.2640483e+02, -2.5308878e+02 ); - expectedForces[163] = Vec3( -1.5156337e+02, 1.1567379e+02, 1.8384602e+02 ); - expectedForces[164] = Vec3( -1.4794785e+02, -8.0381965e+01, 9.4028021e+02 ); - expectedForces[165] = Vec3( -3.5851252e+02, 2.6066489e+02, -4.1225343e+01 ); - expectedForces[166] = Vec3( 1.0820389e+02, -8.3485138e+01, 9.5047812e+01 ); - expectedForces[167] = Vec3( 2.0019411e+02, 5.0864719e+02, -4.8662239e+01 ); - expectedForces[168] = Vec3( -3.0716707e+02, -9.8820762e+02, 1.3660536e+01 ); - expectedForces[169] = Vec3( 8.5788590e+02, -1.0335921e+02, -2.2197815e+02 ); - expectedForces[170] = Vec3( 9.8072705e+00, 6.6224870e+02, -1.1594055e+02 ); - expectedForces[171] = Vec3( -3.6572453e+01, 2.4062731e+02, 1.7831682e+02 ); - expectedForces[172] = Vec3( -2.1274187e+00, -2.5471785e+02, -2.5813525e+02 ); - expectedForces[173] = Vec3( 3.4763673e+02, -2.0753062e+02, 7.5125390e+02 ); - expectedForces[174] = Vec3( 2.9010685e+01, -4.1894498e+02, -6.3847846e+02 ); - expectedForces[175] = Vec3( 3.0255245e+02, 2.5945698e+02, 2.3530662e+01 ); - expectedForces[176] = Vec3( -2.0827676e+01, 2.2568888e+01, 1.0890440e+01 ); - expectedForces[177] = Vec3( 2.2415739e+02, 3.5720682e+02, -8.7208211e+01 ); - expectedForces[178] = Vec3( -2.9808276e+02, 7.0108444e+01, -1.5361211e+02 ); - expectedForces[179] = Vec3( 2.3882234e+02, -2.6764176e+02, -1.7847229e+01 ); - expectedForces[180] = Vec3( -4.7380966e+02, 5.2547306e+01, 7.4446526e+02 ); - expectedForces[181] = Vec3( 4.2804072e+00, -2.2456284e+02, -2.0288206e+02 ); - expectedForces[182] = Vec3( 2.5474630e+00, 2.5211778e+01, 1.2675317e+01 ); - expectedForces[183] = Vec3( -1.4519676e+02, -1.7268277e+02, -8.4750014e+02 ); - expectedForces[184] = Vec3( -1.6850633e+02, 9.5223081e+02, -2.5415253e+02 ); - expectedForces[185] = Vec3( -2.1600185e+02, -1.6313340e+02, 1.8746411e+02 ); - expectedForces[186] = Vec3( 4.5719348e+01, -5.8877840e+01, -1.1199622e+02 ); - expectedForces[187] = Vec3( -9.0377199e+01, 2.2045926e+02, -3.2532356e+02 ); - expectedForces[188] = Vec3( -1.4523032e+02, -2.2127499e+02, 1.1526636e+02 ); - expectedForces[189] = Vec3( 1.9857975e+02, -1.8170037e+02, 3.2016150e+02 ); - expectedForces[190] = Vec3( 1.5659789e+02, 5.2984420e+01, -1.0121553e+02 ); - expectedForces[191] = Vec3( 1.3925504e+01, -1.1627739e+02, 1.7106106e+00 ); - expectedForces[192] = Vec3( 1.7560737e+01, 3.1275548e+02, 1.4568181e+02 ); - expectedForces[193] = Vec3( 8.5129168e-01, 3.2688468e+01, -2.0471785e+02 ); - expectedForces[194] = Vec3( 2.5640904e+02, -1.8345358e+02, 3.3082812e+02 ); - expectedForces[195] = Vec3( 1.5159266e+02, -7.9091822e+02, 7.6475475e+02 ); - expectedForces[196] = Vec3( 7.8546101e+02, 1.7887845e+02, -7.4508377e+01 ); - expectedForces[197] = Vec3( 6.9010029e+00, 2.1336674e+01, -7.8256484e+01 ); - expectedForces[198] = Vec3( -3.4033432e+01, -1.6471994e+02, -2.8721884e+02 ); - expectedForces[199] = Vec3( -1.2248359e+02, 5.3002993e+01, 3.5296174e+02 ); - expectedForces[200] = Vec3( 1.7497881e+02, 1.1744848e+02, 1.8127502e+02 ); - expectedForces[201] = Vec3( -1.1710882e+03, 8.7114752e+02, -1.3353036e+02 ); - expectedForces[202] = Vec3( 2.7510368e+02, -1.9393814e+02, 2.6671453e+02 ); - expectedForces[203] = Vec3( 7.3421287e+01, -3.8409917e+01, -1.0910368e+02 ); - expectedForces[204] = Vec3( -8.7394869e+02, -1.2323430e+03, -1.3693068e+02 ); - expectedForces[205] = Vec3( 2.5439149e+02, 2.4002077e+02, 3.0231859e+02 ); - expectedForces[206] = Vec3( -9.8167431e+01, 3.1515278e+02, -2.5512038e+02 ); - expectedForces[207] = Vec3( 2.7501189e+02, -4.9189774e+02, 4.5827877e+02 ); - expectedForces[208] = Vec3( -8.2333908e+02, -7.0609881e+02, 2.9188070e+02 ); - expectedForces[209] = Vec3( -2.9200330e+02, 1.9955124e+02, -7.9227826e+00 ); - expectedForces[210] = Vec3( 8.0151971e+02, 3.8996996e+02, -1.9508756e+02 ); - expectedForces[211] = Vec3( -6.2168096e+01, 2.4323951e+01, 9.8845638e+01 ); - expectedForces[212] = Vec3( 2.2980428e+01, -6.2829693e+02, -7.5253154e+02 ); - expectedForces[213] = Vec3( -5.7502634e+02, 8.2310635e+02, 3.7934867e+02 ); - expectedForces[214] = Vec3( -8.9168889e+01, 5.0052167e+01, -8.6850564e+01 ); - expectedForces[215] = Vec3( 2.7414821e+02, -5.9725191e+01, -3.7278778e+00 ); - expectedForces[216] = Vec3( -5.3230933e+02, 4.7698725e+02, -2.5857751e+02 ); - expectedForces[217] = Vec3( 2.1615644e+02, 6.0001233e+01, -1.1880182e+02 ); - expectedForces[218] = Vec3( 2.9837823e+01, -3.9275454e+01, -4.3913571e+01 ); - expectedForces[219] = Vec3( -5.6516561e+02, -1.6539113e+02, 3.3185872e+02 ); - expectedForces[220] = Vec3( -1.5484833e+01, -1.0085566e+01, -2.8199778e+01 ); - expectedForces[221] = Vec3( 6.4295337e+02, -2.7398997e+02, 8.2320867e+02 ); - expectedForces[222] = Vec3( 3.3816540e+02, -1.8492046e+02, 8.6215770e+02 ); - expectedForces[223] = Vec3( 2.4367872e+02, 8.9527142e+01, -5.9973680e+02 ); - expectedForces[224] = Vec3( -6.1601439e+02, -5.3093862e+02, 4.1696221e+01 ); - expectedForces[225] = Vec3( 2.2521478e+02, -2.9234267e+02, 2.9760244e+02 ); - expectedForces[226] = Vec3( -1.2672295e+02, 2.5753736e+01, -1.6216252e+02 ); - expectedForces[227] = Vec3( 1.1136724e+02, 4.3446676e+00, -1.4045447e+01 ); - expectedForces[228] = Vec3( 3.5554849e+02, 7.7446255e+00, 5.8722356e+02 ); - expectedForces[229] = Vec3( -7.8313952e+02, -5.9206053e+01, 5.1181391e+02 ); - expectedForces[230] = Vec3( -9.5647729e+01, -4.6045792e+02, -3.1515210e+02 ); - expectedForces[231] = Vec3( 8.7273284e+01, 8.0310279e+02, -1.2212040e+03 ); - expectedForces[232] = Vec3( -9.0853819e+02, -7.6005570e+02, 1.8578569e+02 ); - expectedForces[233] = Vec3( 1.2061615e+02, -3.2834560e+02, 5.1291192e+01 ); - expectedForces[234] = Vec3( 6.0149262e+02, 1.6081852e+03, -1.0922015e+03 ); - expectedForces[235] = Vec3( -5.8087260e+01, -2.6676779e+02, -1.5006920e+02 ); - expectedForces[236] = Vec3( -1.0997771e+01, 1.3012815e+02, 5.8615633e+02 ); - expectedForces[237] = Vec3( 4.9821503e+02, -9.5783644e+01, -6.5708073e+02 ); - expectedForces[238] = Vec3( -4.9394992e+02, -7.0445435e+02, -1.5540228e+02 ); - expectedForces[239] = Vec3( 1.5710340e+01, 1.9170336e+02, 4.6707393e+02 ); - expectedForces[240] = Vec3( -1.2599557e+03, 5.6104975e+02, 6.5853210e+02 ); - expectedForces[241] = Vec3( 1.3032986e+01, -2.7481865e+01, 8.0373029e+00 ); - expectedForces[242] = Vec3( 1.4371505e+02, -5.2615293e+01, -3.7929456e+02 ); - expectedForces[243] = Vec3( 6.0025739e+01, 1.4474905e+02, 3.6414330e+02 ); - expectedForces[244] = Vec3( 4.5364033e+02, 7.0785823e+01, -2.9279112e+02 ); - expectedForces[245] = Vec3( -9.7012956e+01, -8.2545229e+01, -5.4567106e+01 ); - expectedForces[246] = Vec3( -3.6449281e+02, -5.6669832e+02, -3.5196038e+02 ); - expectedForces[247] = Vec3( 2.6571354e+02, -2.5051716e+02, -4.7199161e+01 ); - expectedForces[248] = Vec3( -4.7285701e+01, 1.7950093e+02, 8.0633971e+01 ); - expectedForces[249] = Vec3( 1.8035439e+02, 4.6977540e+02, 2.2589769e+02 ); - expectedForces[250] = Vec3( 5.9853399e+01, 1.5477006e+02, -1.7011806e+02 ); - expectedForces[251] = Vec3( -2.6084741e+02, -2.0538756e+02, 1.0269002e+02 ); - expectedForces[252] = Vec3( 4.0221722e+02, -1.0368371e+02, -1.3842460e+01 ); - expectedForces[253] = Vec3( -4.4264447e+02, -3.0334810e+02, 1.6740779e+02 ); - expectedForces[254] = Vec3( -1.7373662e+02, 1.5020202e+02, -3.3761418e+02 ); - expectedForces[255] = Vec3( 4.7508953e+01, -5.4028784e+02, -3.6291329e+01 ); - expectedForces[256] = Vec3( 5.4807168e+02, -2.0293664e+02, 5.5114363e+02 ); - expectedForces[257] = Vec3( -4.9787370e+01, 4.5106329e+01, -5.7524550e+01 ); - expectedForces[258] = Vec3( -5.1584935e+02, 1.5014186e+02, -6.6369834e+02 ); - expectedForces[259] = Vec3( -6.0140298e+01, -9.4127280e+01, 8.7495796e+01 ); - expectedForces[260] = Vec3( 8.0619588e+02, -2.1066454e+02, -5.9371508e+01 ); - expectedForces[261] = Vec3( 1.2817429e+02, -2.7044116e+02, 5.3213275e+02 ); - expectedForces[262] = Vec3( -4.1467442e-01, -1.3641138e+02, -8.5576287e+01 ); - expectedForces[263] = Vec3( -5.6508528e+01, 2.4091504e+01, -7.9236147e+01 ); - expectedForces[264] = Vec3( 1.4123799e+02, 2.1326444e+02, 1.9141445e+02 ); - expectedForces[265] = Vec3( 1.6579721e+02, -3.2221503e+02, -1.5197776e+02 ); - expectedForces[266] = Vec3( -2.5871222e+02, -2.6345996e+02, -1.1149413e+03 ); - expectedForces[267] = Vec3( -1.2859743e+02, -3.9214753e+02, -6.5874862e+02 ); - expectedForces[268] = Vec3( 1.7237157e+02, -2.8729010e+02, 3.2000889e+02 ); - expectedForces[269] = Vec3( 6.6312203e+02, 3.5683926e+02, 9.7235616e+01 ); - expectedForces[270] = Vec3( -1.1860349e+02, -4.3528895e+02, 1.1598672e+03 ); - expectedForces[271] = Vec3( 7.7135123e+01, -2.1671305e+02, -2.3088548e+02 ); - expectedForces[272] = Vec3( 7.2863708e+01, 5.2065158e+02, 1.5704752e+02 ); - expectedForces[273] = Vec3( -3.6727477e+02, -6.0885463e+01, 4.1193960e+01 ); - expectedForces[274] = Vec3( 5.4858881e+01, 1.6886577e+02, -1.1662392e+01 ); - expectedForces[275] = Vec3( 3.2070061e+01, -1.6138709e+01, -7.6648912e+00 ); - expectedForces[276] = Vec3( 2.5695892e+02, 7.7719531e+01, -8.3154765e+02 ); - expectedForces[277] = Vec3( -3.3460202e+01, -1.3077348e+02, 3.6110539e+01 ); - expectedForces[278] = Vec3( -4.1360402e+02, 2.7754335e+02, -1.1139467e+02 ); - expectedForces[279] = Vec3( 1.0012775e+02, 1.4365237e+03, 2.6972544e+02 ); - expectedForces[280] = Vec3( 7.8750024e+02, -2.3376123e+02, 9.5969232e+02 ); - expectedForces[281] = Vec3( -2.2493912e+02, -1.1444344e+01, -6.3713547e+01 ); - expectedForces[282] = Vec3( -9.4211966e+01, -3.9286586e+02, -7.0932607e+01 ); - expectedForces[283] = Vec3( 1.6192138e+02, 2.3010404e+02, -2.1511498e+02 ); - expectedForces[284] = Vec3( -4.9644702e+02, -1.1894844e+01, -4.7458477e+02 ); - expectedForces[285] = Vec3( -1.0151600e+02, -4.2789293e+02, 5.2698223e+02 ); - expectedForces[286] = Vec3( 1.1350409e+01, 1.5126445e+02, -5.2740587e+01 ); - expectedForces[287] = Vec3( -4.7715521e+02, -3.6476152e+02, -5.4346958e+02 ); - expectedForces[288] = Vec3( -9.4019721e+01, -2.4758228e+02, 4.2219712e+02 ); - expectedForces[289] = Vec3( 3.1525053e+01, 3.7927245e+02, -2.4577041e+02 ); - expectedForces[290] = Vec3( 4.4004025e+02, -9.4883983e+01, -6.9075632e+01 ); - expectedForces[291] = Vec3( -2.6553328e+02, -2.7059185e+02, 3.1145935e+02 ); - expectedForces[292] = Vec3( 1.1199463e+02, 9.0805870e+01, 8.0258804e+01 ); - expectedForces[293] = Vec3( 7.8056273e+01, -3.5931761e+01, -1.9249727e+02 ); - expectedForces[294] = Vec3( -1.2443366e+01, -1.4631721e+02, 7.9733561e+01 ); - expectedForces[295] = Vec3( -3.2866900e+02, 1.1527926e+02, -9.3135590e+01 ); - expectedForces[296] = Vec3( 7.5078643e+01, -7.2653837e+02, -1.0830908e+02 ); - expectedForces[297] = Vec3( 1.0361037e+02, 1.5478274e+02, 1.1293089e+03 ); - expectedForces[298] = Vec3( -2.4014663e+02, -5.6771824e+02, 1.5441974e+02 ); - expectedForces[299] = Vec3( -6.8441034e+01, -1.1226846e+02, -5.4497343e+02 ); - expectedForces[300] = Vec3( 2.9803689e+02, 1.0649462e+03, 2.5408768e+02 ); - expectedForces[301] = Vec3( 5.6356599e+01, -2.3035579e+02, 7.6928758e+01 ); - expectedForces[302] = Vec3( 1.0229494e+02, -1.9615696e+02, -3.2600199e+02 ); - expectedForces[303] = Vec3( -7.0312065e+01, -3.1170055e+02, 5.6453888e+02 ); - expectedForces[304] = Vec3( -7.0752582e+01, 1.2273280e+02, -1.6740503e+01 ); - expectedForces[305] = Vec3( 6.8972998e+02, -2.8067032e+02, 6.6502848e+01 ); - expectedForces[306] = Vec3( -8.8407472e+02, 3.7818347e+02, -1.2141945e+03 ); - expectedForces[307] = Vec3( -1.0445122e+02, -4.4818836e+02, -9.5227168e+00 ); - expectedForces[308] = Vec3( 8.3015802e+02, 5.0941309e+02, 3.2593793e+01 ); - expectedForces[309] = Vec3( 7.6887033e+02, 4.3490548e+02, -1.0826101e+03 ); - expectedForces[310] = Vec3( 1.4352949e+02, -3.9479802e+01, 1.7718790e+02 ); - expectedForces[311] = Vec3( -2.5204642e+02, -3.3888239e+02, -2.7365802e+02 ); - expectedForces[312] = Vec3( -4.4783121e+02, 4.4465580e+02, 9.2506336e+02 ); - expectedForces[313] = Vec3( -3.3390337e+01, -5.0097602e+02, -3.6812516e+02 ); - expectedForces[314] = Vec3( -4.1862341e+02, 1.9519764e+02, -2.4571211e+02 ); - expectedForces[315] = Vec3( -1.4176845e+02, -3.3767798e+01, 1.7800248e+02 ); - expectedForces[316] = Vec3( -4.7411046e+01, 2.3841278e+01, -1.5183689e+01 ); - expectedForces[317] = Vec3( 1.6723204e+01, 1.4145797e+02, -1.6930384e+01 ); - expectedForces[318] = Vec3( -8.4841167e+02, -2.1282818e+02, 8.1614626e+01 ); - expectedForces[319] = Vec3( 6.5941519e+00, -1.1472179e+02, -2.3181002e+02 ); - expectedForces[320] = Vec3( 2.2464095e+01, -5.7606215e+00, 5.2865780e+00 ); - expectedForces[321] = Vec3( 3.8063827e+02, 2.4597014e+02, -4.1947008e+01 ); - expectedForces[322] = Vec3( -3.1531672e+02, 3.5038104e+02, -3.2724191e+02 ); - expectedForces[323] = Vec3( 7.4741163e+01, 7.2296536e+01, 3.1768919e+02 ); - expectedForces[324] = Vec3( 7.9578966e+02, -1.5345175e+02, -7.1301288e+02 ); - expectedForces[325] = Vec3( -3.1387318e+01, 1.7528515e+01, -3.4100670e+01 ); - expectedForces[326] = Vec3( 9.3853572e-01, 6.8496077e+00, 1.2234894e+01 ); - expectedForces[327] = Vec3( -1.3099690e+02, -4.0135958e+02, -4.3248135e+02 ); - expectedForces[328] = Vec3( 4.3988113e+02, -1.5944416e+02, 5.4620163e+01 ); - expectedForces[329] = Vec3( 1.3509243e+01, 3.6990268e+00, -2.6251838e-01 ); - expectedForces[330] = Vec3( -8.7459998e+01, -6.4319025e+02, 2.2863360e+02 ); - expectedForces[331] = Vec3( -3.5181606e+02, 3.1131978e+02, 2.8037788e+02 ); - expectedForces[332] = Vec3( 1.9545884e+02, 4.3994512e+01, -2.5158598e+02 ); - expectedForces[333] = Vec3( 1.8100917e+00, 1.9534738e+02, 1.7181161e+02 ); - expectedForces[334] = Vec3( -1.1846876e+02, 1.5368782e+02, 2.2261016e+02 ); - expectedForces[335] = Vec3( 1.4866155e+02, -4.7983795e+02, 3.0361323e+02 ); - expectedForces[336] = Vec3( -7.7242468e+02, 2.0736079e+02, -8.6661236e+02 ); - expectedForces[337] = Vec3( -7.9875679e+00, -9.0946585e+02, -7.1617627e+01 ); - expectedForces[338] = Vec3( 2.2543457e+02, 2.0215639e+02, 4.4285374e+02 ); - expectedForces[339] = Vec3( -2.6252013e+02, -1.0336519e+02, -2.6630451e+02 ); - expectedForces[340] = Vec3( 5.0907589e+02, -1.2491931e+02, -4.3015857e+01 ); - expectedForces[341] = Vec3( -6.0362692e+01, 1.0025664e+02, -9.3389235e+01 ); - expectedForces[342] = Vec3( 5.8779874e+02, 3.7600030e+02, 2.5345454e+02 ); - expectedForces[343] = Vec3( -1.3661048e+02, 1.6498482e+02, -2.6789925e+01 ); - expectedForces[344] = Vec3( 4.9840419e+01, -1.2136315e+02, 2.5455320e+01 ); - expectedForces[345] = Vec3( 2.3324807e+02, -3.6601512e+02, 5.6798114e+01 ); - expectedForces[346] = Vec3( 5.5853546e+01, -4.9035168e+00, -5.8726331e+02 ); - expectedForces[347] = Vec3( -3.8918158e+01, 3.0380495e+02, 1.0944883e+01 ); - expectedForces[348] = Vec3( -2.6092065e+02, 4.3443036e+02, -1.3673862e+02 ); - expectedForces[349] = Vec3( 1.5195166e+02, 1.1879426e+01, -1.1429493e+02 ); - expectedForces[350] = Vec3( -8.5687107e+02, -1.7938881e+02, 4.5576455e+00 ); - expectedForces[351] = Vec3( -1.0117388e+03, -3.2686610e+02, 2.9733049e+02 ); - expectedForces[352] = Vec3( -2.3946369e+02, 4.9753786e+02, 7.2681440e+02 ); - expectedForces[353] = Vec3( 3.9085837e+01, 7.4391931e+00, 3.4179196e+00 ); - expectedForces[354] = Vec3( 1.0462977e+03, 4.3639578e+02, -5.7349371e+02 ); - expectedForces[355] = Vec3( 1.2715333e+02, -5.7907885e+02, 5.7463165e+02 ); - expectedForces[356] = Vec3( -1.5968981e+02, 2.2295605e+01, 6.3554487e+01 ); - expectedForces[357] = Vec3( -1.9666111e+02, -2.0286725e+02, -8.3590992e+01 ); - expectedForces[358] = Vec3( 5.9985006e+00, 2.9764307e+01, 3.1304672e+01 ); - expectedForces[359] = Vec3( 1.0409792e+02, 4.3974987e+02, -9.1530162e+02 ); - expectedForces[360] = Vec3( 2.9538724e+02, 1.4353710e+02, 2.1558768e+02 ); - expectedForces[361] = Vec3( -3.7974445e+02, -9.0749144e+01, 1.4531502e+02 ); - expectedForces[362] = Vec3( 3.7089093e+02, 2.2523397e+02, -2.9760698e+02 ); - expectedForces[363] = Vec3( -7.6884906e+01, -2.7486958e+02, 3.5671043e+02 ); - expectedForces[364] = Vec3( 4.3400097e+02, 2.2275226e+02, 5.9201087e+01 ); - expectedForces[365] = Vec3( 2.1177620e+02, -6.4990517e+02, -1.8431623e+02 ); - expectedForces[366] = Vec3( -8.2234148e+01, 4.9900036e+02, 3.0906858e+02 ); - expectedForces[367] = Vec3( -1.4784097e+02, 1.3442463e+02, -2.6811487e+02 ); - expectedForces[368] = Vec3( 2.2289541e+02, -4.1933983e+02, 1.3646246e+01 ); - expectedForces[369] = Vec3( -2.1199481e+02, 6.2103281e+01, 1.6049768e+02 ); - expectedForces[370] = Vec3( -2.9429845e+01, -1.3944740e+01, 1.6000003e+01 ); - expectedForces[371] = Vec3( -1.5093250e+02, -1.9541345e+02, -1.5879844e+02 ); - expectedForces[372] = Vec3( 2.2218133e+02, 7.5740668e+01, -7.0754853e+02 ); - expectedForces[373] = Vec3( -4.7529615e+02, -3.5259490e+02, 3.8025744e+02 ); - expectedForces[374] = Vec3( 4.9308495e+01, 1.2206152e+02, 4.2704595e+01 ); - expectedForces[375] = Vec3( -3.6408113e+02, 9.5905960e+02, 3.3861668e+02 ); - expectedForces[376] = Vec3( 1.5324093e+02, -1.4375341e+02, -9.1369900e+01 ); - expectedForces[377] = Vec3( -3.5343609e+02, -4.4662438e+02, 3.1741831e+02 ); - expectedForces[378] = Vec3( -8.2721281e+02, -6.4969313e+01, 4.1869320e+02 ); - expectedForces[379] = Vec3( -8.7419096e+00, -4.6278343e+01, -3.0259942e+01 ); - expectedForces[380] = Vec3( 1.6814871e+01, 4.5462601e+01, -3.5204538e+01 ); - expectedForces[381] = Vec3( 1.9043143e+02, 5.1101135e+02, 2.9970918e+02 ); - expectedForces[382] = Vec3( -4.3547560e+02, -7.7495770e+01, -8.2311440e+01 ); - expectedForces[383] = Vec3( 1.3206505e+02, 4.0993476e+01, 1.5150623e+01 ); - expectedForces[384] = Vec3( 4.6163268e+01, -2.7722119e+01, -2.2996255e+02 ); - expectedForces[385] = Vec3( -4.7033552e+01, 1.5721545e+02, -9.2562636e+01 ); - expectedForces[386] = Vec3( -2.4164903e+02, -1.4771464e+02, -5.1675638e+01 ); - expectedForces[387] = Vec3( 1.3445564e+03, 3.5387081e+02, -3.7402713e+02 ); - expectedForces[388] = Vec3( -2.6290280e+02, 2.5025510e+02, 3.0570707e+01 ); - expectedForces[389] = Vec3( -4.4624214e+02, -2.4919412e+02, 1.1336564e+03 ); - expectedForces[390] = Vec3( 3.1188483e+02, 6.4836125e+02, 4.5477683e+01 ); - expectedForces[391] = Vec3( 2.5570674e+02, -2.7101115e+02, -1.2579817e+02 ); - expectedForces[392] = Vec3( -3.4941759e+02, -3.2508734e+01, -5.6131515e+01 ); - expectedForces[393] = Vec3( -1.2734301e+02, -2.0417657e+02, 5.7738004e+02 ); - expectedForces[394] = Vec3( 5.0435795e+01, -9.5203527e+01, -4.1237509e+00 ); - expectedForces[395] = Vec3( -6.8258463e+01, 1.7475914e+02, -1.6422294e+02 ); - expectedForces[396] = Vec3( 2.6455575e+02, 2.6880230e+02, -1.6607620e+01 ); - expectedForces[397] = Vec3( -3.5968167e+02, 6.6092937e+01, 1.5915445e+02 ); - expectedForces[398] = Vec3( 8.4092494e-01, -5.9896731e+01, -2.1856007e+01 ); - expectedForces[399] = Vec3( -1.9237984e+02, -1.6506355e+02, 1.3370845e+02 ); - expectedForces[400] = Vec3( 4.7023043e+02, 1.2931257e+02, -1.7013618e+02 ); - expectedForces[401] = Vec3( 9.4928843e+01, -3.1613892e+02, -4.6973091e+02 ); - expectedForces[402] = Vec3( -2.9180818e+02, 6.5496755e+02, -2.9430870e+02 ); - expectedForces[403] = Vec3( 1.6670668e+02, -2.4693913e+02, -8.8775735e+01 ); - expectedForces[404] = Vec3( -1.4218604e+02, 2.3173349e+02, 3.9869740e+02 ); - expectedForces[405] = Vec3( 4.3469431e+02, -2.4686568e+02, -2.6838523e+02 ); - expectedForces[406] = Vec3( 1.0671130e+02, 3.9710106e+02, 2.6478100e+02 ); - expectedForces[407] = Vec3( -4.4281099e+02, -3.2746126e+01, -2.0719929e+02 ); - expectedForces[408] = Vec3( 1.1864952e+01, -1.5901568e+02, 1.1865945e+01 ); - expectedForces[409] = Vec3( -6.0546863e+01, -1.3488005e+02, -2.9223986e+02 ); - expectedForces[410] = Vec3( 2.5845942e+01, 1.7545933e+02, -1.4590654e+02 ); - expectedForces[411] = Vec3( -3.0776460e+02, 2.7351986e+02, -2.0386483e+02 ); - expectedForces[412] = Vec3( 1.7301558e+02, 8.3012339e+01, 7.6018513e+02 ); - expectedForces[413] = Vec3( 1.2893147e+02, -3.9937475e+00, 1.4197628e+01 ); - expectedForces[414] = Vec3( -3.9803615e+02, -4.4825663e+02, 2.8616211e+01 ); - expectedForces[415] = Vec3( -2.3586809e+02, -8.9306136e+01, 7.5265669e+02 ); - expectedForces[416] = Vec3( 8.3814512e+02, -9.5563706e+00, 2.8738759e+02 ); - expectedForces[417] = Vec3( -3.8269399e+02, -2.3650170e+02, 1.7330415e+01 ); - expectedForces[418] = Vec3( 7.2310675e+00, 2.4731653e+01, 1.9491126e+01 ); - expectedForces[419] = Vec3( 8.4485111e+01, 9.0560261e+01, -1.4261777e+01 ); - expectedForces[420] = Vec3( 2.1829925e+02, -8.3951651e+01, -7.8910117e+02 ); - expectedForces[421] = Vec3( -2.4228018e+02, -5.7097512e+01, 2.6447829e+02 ); - expectedForces[422] = Vec3( 6.9666665e+01, -4.7313678e+02, 4.5559673e+02 ); - expectedForces[423] = Vec3( 1.0108369e+02, 4.6568610e+02, 2.5612541e+02 ); - expectedForces[424] = Vec3( 7.2334238e+01, -1.5660040e+02, -2.6278686e+02 ); - expectedForces[425] = Vec3( 1.0749954e+03, 2.4395658e+02, -8.7308262e+01 ); - expectedForces[426] = Vec3( 5.4983082e+02, 5.6528577e+02, -3.0489991e+02 ); - expectedForces[427] = Vec3( -2.1210132e+02, -1.5871954e+02, -1.6936452e+02 ); - expectedForces[428] = Vec3( -9.5473983e+01, 7.4879276e+01, 5.5720204e+01 ); - expectedForces[429] = Vec3( 5.6417182e+02, -1.3478250e+02, -4.8006673e+01 ); - expectedForces[430] = Vec3( -1.0055266e+02, -8.3811289e+01, 6.5259748e+01 ); - expectedForces[431] = Vec3( 3.0553989e+01, 4.0927300e+02, 6.2242246e+02 ); - expectedForces[432] = Vec3( -6.0956353e+02, 9.0301312e+02, -1.4063582e+01 ); - expectedForces[433] = Vec3( 3.2774559e+02, -1.0849473e+02, -8.8877712e+01 ); - expectedForces[434] = Vec3( 2.1371643e+02, -7.2067980e+01, 2.4803863e+02 ); - expectedForces[435] = Vec3( -9.0636479e+01, 1.0673514e+03, 1.3005625e+02 ); - expectedForces[436] = Vec3( -3.5058624e+02, -1.4968284e+02, 1.4340635e+02 ); - expectedForces[437] = Vec3( 3.4640813e+01, -4.8035225e+01, 4.4066226e+01 ); - expectedForces[438] = Vec3( -2.3414523e+02, -9.1359130e+01, 2.8535427e+02 ); - expectedForces[439] = Vec3( -2.7156547e+02, -6.3426763e+01, 1.6968017e+01 ); - expectedForces[440] = Vec3( -2.8751166e+00, 4.3192169e+00, -2.1401359e+00 ); - expectedForces[441] = Vec3( -2.0241419e+01, 4.2856138e+02, 7.3204868e+01 ); - expectedForces[442] = Vec3( -4.2166169e+01, -2.2454013e+01, -5.4998450e+01 ); - expectedForces[443] = Vec3( 2.6442026e+02, -1.1670567e+02, 2.8879291e+02 ); - expectedForces[444] = Vec3( -4.9762729e+02, 4.7320314e+02, 3.2506251e+02 ); - expectedForces[445] = Vec3( -3.0994232e+02, 3.6728867e+02, -6.8793662e+02 ); - expectedForces[446] = Vec3( -5.6328374e+00, -2.3284824e+00, 1.9650486e+01 ); - expectedForces[447] = Vec3( 4.0145354e+02, 7.0143762e+02, 1.3039041e+02 ); - expectedForces[448] = Vec3( 1.3270713e+02, -3.3050447e+02, 2.8630784e+02 ); - expectedForces[449] = Vec3( -3.8904836e+02, -4.6125118e+01, -3.8815388e+02 ); - expectedForces[450] = Vec3( 4.6293066e+02, -2.4970158e+02, -5.7231818e+01 ); - expectedForces[451] = Vec3( -4.7707142e+00, 1.7120822e-01, 4.5081299e+00 ); - expectedForces[452] = Vec3( 3.5968818e+01, -1.1892248e+01, 1.2184792e+02 ); - expectedForces[453] = Vec3( 4.4939172e+02, 4.8377647e+02, 3.0529778e+02 ); - expectedForces[454] = Vec3( -2.9071570e+02, -9.0611613e+01, -2.5190431e+02 ); - expectedForces[455] = Vec3( -1.4344537e+02, -1.3061997e+03, 3.8343947e+02 ); - expectedForces[456] = Vec3( 4.1580940e+02, -3.6864043e+02, 6.6384066e+02 ); - expectedForces[457] = Vec3( -3.4869949e+02, 3.3262427e+02, -8.3156358e+01 ); - expectedForces[458] = Vec3( -5.8565457e+00, -5.1879987e+02, -7.2717213e+02 ); - expectedForces[459] = Vec3( -1.0514593e+02, -2.6844396e+02, 3.0849659e+02 ); - expectedForces[460] = Vec3( -1.2562153e+02, 6.5438031e+01, -2.3521687e+02 ); - expectedForces[461] = Vec3( 8.3330016e+02, -6.7961048e+02, -7.2442064e+02 ); - expectedForces[462] = Vec3( -1.3328298e+02, 1.6143544e+02, -3.2000493e+02 ); - expectedForces[463] = Vec3( -1.1035002e+02, -8.6040775e+01, 2.0953986e+02 ); - expectedForces[464] = Vec3( -2.7702219e+02, -1.2156319e+02, -3.8897654e+02 ); - expectedForces[465] = Vec3( 3.6277432e+02, -7.0422679e+02, -8.2487472e+02 ); - expectedForces[466] = Vec3( -2.3947587e+02, -4.3625964e+00, 4.8716989e+01 ); - expectedForces[467] = Vec3( -2.6210552e+02, 9.9730213e+01, -2.4465307e+02 ); - expectedForces[468] = Vec3( -4.1344138e+01, -3.8636310e+01, -1.0720610e+01 ); - expectedForces[469] = Vec3( 2.3928584e+01, -1.3030908e+01, -1.7631168e+01 ); - expectedForces[470] = Vec3( -1.1873594e+02, -3.3905287e+00, -8.4575994e+01 ); - expectedForces[471] = Vec3( 4.3384846e+02, -4.8660929e+02, -2.4015737e+02 ); - expectedForces[472] = Vec3( 3.8974922e+01, 2.4401913e+02, -1.2060132e+02 ); - expectedForces[473] = Vec3( -4.2239647e+02, -8.6924630e+01, 5.7884013e+02 ); - expectedForces[474] = Vec3( 1.7222431e+02, -1.9292167e+01, 4.4184770e+01 ); - expectedForces[475] = Vec3( -4.8871102e+01, 1.8185057e+02, -1.3144294e+02 ); - expectedForces[476] = Vec3( -1.1467881e+02, -1.8387284e+02, -2.6935761e+01 ); - expectedForces[477] = Vec3( 4.4415601e+02, -8.6415426e+02, -2.2765803e+02 ); - expectedForces[478] = Vec3( 2.0893474e+02, 1.3529112e+02, 2.4108004e+02 ); - expectedForces[479] = Vec3( -1.2802570e+01, -4.7089261e+00, -7.0024810e+00 ); - expectedForces[480] = Vec3( -1.0878354e+02, 4.5030357e+02, -3.9086153e+02 ); - expectedForces[481] = Vec3( -3.7659745e+01, -4.9295745e+01, -6.0028516e+01 ); - expectedForces[482] = Vec3( 1.8851809e+02, -1.6863914e+02, 1.2031505e+02 ); - expectedForces[483] = Vec3( 2.2040686e+02, -1.1953187e+03, 2.9106238e+02 ); - expectedForces[484] = Vec3( -1.1642847e+01, 5.6739977e+01, 3.7532413e+00 ); - expectedForces[485] = Vec3( 3.5013234e+00, 2.8236323e+01, -1.1738866e+01 ); - expectedForces[486] = Vec3( -2.0051506e+03, -5.3138994e+02, 4.0428126e+02 ); - expectedForces[487] = Vec3( 1.6887843e+02, 1.1687735e+02, -9.6232177e+01 ); - expectedForces[488] = Vec3( 2.5030722e+02, -3.6662537e+02, -5.8595505e+01 ); - expectedForces[489] = Vec3( -1.5924273e+01, -2.1761920e+02, -3.4885425e+01 ); - expectedForces[490] = Vec3( 1.0423157e+02, 4.0767827e+01, 1.4036192e+02 ); - expectedForces[491] = Vec3( 5.0090776e+02, -5.0455702e+01, -4.2524815e+02 ); - expectedForces[492] = Vec3( 3.8037844e+02, 5.7460724e+02, 2.1243310e+02 ); - expectedForces[493] = Vec3( -1.1487653e+02, 3.3550952e+01, -5.7050397e+01 ); - expectedForces[494] = Vec3( 1.8425697e+02, -2.7223857e+02, -2.9384020e+01 ); - expectedForces[495] = Vec3( -1.1115514e+02, -4.4519957e+02, -3.3628896e+02 ); - expectedForces[496] = Vec3( 3.8865823e+02, -2.1372852e+02, -7.8979988e+02 ); - expectedForces[497] = Vec3( -3.1740258e+02, 4.4824683e+02, -5.0382680e+02 ); - expectedForces[498] = Vec3( 1.5521684e+02, -1.5278429e+02, -1.8418006e+02 ); - expectedForces[499] = Vec3( -2.2213191e+01, 7.1015095e+00, 1.0308820e+01 ); - expectedForces[500] = Vec3( 3.0011560e+01, 2.4584541e+02, -5.3231694e+02 ); - expectedForces[501] = Vec3( -8.4865171e+02, -2.0279022e+02, -6.8435095e+02 ); - expectedForces[502] = Vec3( 7.0477549e+00, 2.7626774e+01, -1.6246047e+01 ); - expectedForces[503] = Vec3( -7.1309648e+01, -1.6054218e+02, -3.1621746e+01 ); - expectedForces[504] = Vec3( 3.6317856e+02, 1.9055487e+02, 3.9196046e+01 ); - expectedForces[505] = Vec3( 1.4643265e+02, -1.2295335e+03, -2.2268806e+01 ); - expectedForces[506] = Vec3( -3.6638240e+02, -6.5310612e+00, -6.8077013e+02 ); - expectedForces[507] = Vec3( 1.9107813e+02, -6.2176534e+02, 5.1826941e+02 ); - expectedForces[508] = Vec3( 1.7226933e+02, -3.8939126e+02, -7.4174355e+02 ); - expectedForces[509] = Vec3( 1.3541890e+02, 4.1350561e+02, -2.6155396e+02 ); - expectedForces[510] = Vec3( 1.6452609e+02, -4.1963597e+02, 1.6322800e+02 ); - expectedForces[511] = Vec3( 9.1248387e+01, -1.3380408e+01, -5.1326806e+02 ); - expectedForces[512] = Vec3( 1.2420564e+02, 8.9492432e+02, 2.8660661e+02 ); - expectedForces[513] = Vec3( 4.5609859e+02, 3.4252036e+01, -2.3830457e+02 ); - expectedForces[514] = Vec3( -8.8282131e+01, -1.4512876e+02, -4.5703642e+01 ); - expectedForces[515] = Vec3( -6.9194714e+01, 5.5053415e+02, -3.9527911e+02 ); - expectedForces[516] = Vec3( -1.5570798e+02, 4.1650792e-02, 3.0224667e+02 ); - expectedForces[517] = Vec3( 9.2007640e+01, 3.6378499e+02, -2.2069415e+01 ); - expectedForces[518] = Vec3( 2.7996922e+02, -2.0932322e+02, 6.2987796e+01 ); - expectedForces[519] = Vec3( -7.4985282e+01, 1.3508916e+02, 1.1453750e+02 ); - expectedForces[520] = Vec3( 1.2149786e+01, 4.2161047e+02, -2.9521571e+02 ); - expectedForces[521] = Vec3( 1.9419524e+01, -8.6619683e+01, -9.4040609e+01 ); - expectedForces[522] = Vec3( 3.5495800e+01, 6.4028894e+01, 1.2320699e+02 ); - expectedForces[523] = Vec3( -5.6501302e+02, -1.2497462e+02, 8.1633096e+02 ); - expectedForces[524] = Vec3( -3.1775230e+02, 1.6467221e+02, -4.8242287e+01 ); - expectedForces[525] = Vec3( -1.8325245e+02, -1.0751941e+02, 6.2172117e+02 ); - expectedForces[526] = Vec3( 1.8164299e+00, 8.0654784e-01, -1.4484741e+01 ); - expectedForces[527] = Vec3( 2.6686986e+00, 1.5933475e+01, -6.8843007e+01 ); - expectedForces[528] = Vec3( -1.3208642e+02, -1.2281791e+02, 7.8417959e+01 ); - expectedForces[529] = Vec3( -4.8078193e+01, -1.5140963e+02, 8.3605002e+01 ); - expectedForces[530] = Vec3( 8.5925332e+01, 1.9959621e+01, -5.9034655e+01 ); - expectedForces[531] = Vec3( -3.1311626e+00, -3.4009931e+01, -1.5895685e+02 ); - expectedForces[532] = Vec3( -9.9694666e+01, 1.0296874e+00, 1.0482739e+02 ); - expectedForces[533] = Vec3( 2.8954747e+02, 1.2018666e+02, 2.2155006e+02 ); - expectedForces[534] = Vec3( 3.2588176e+02, 3.6622498e+01, 3.5801460e+02 ); - expectedForces[535] = Vec3( -6.5985617e+01, -3.5501709e+02, 6.8149810e+01 ); - expectedForces[536] = Vec3( -4.7632753e+02, 2.7936656e+02, 1.5548558e+02 ); - expectedForces[537] = Vec3( 4.7724904e+02, 2.1647106e+02, 1.2003317e+02 ); - expectedForces[538] = Vec3( -1.6225405e+02, 1.4264998e+02, -1.0113321e+02 ); - expectedForces[539] = Vec3( -3.2540487e+01, -7.5643223e+01, 1.6054148e+01 ); - expectedForces[540] = Vec3( 4.3311991e+02, 5.8082595e+02, 1.9354276e+02 ); - expectedForces[541] = Vec3( -3.4924430e+02, -7.0056069e+01, 1.0274560e+02 ); - expectedForces[542] = Vec3( 1.9441645e+02, -2.0017354e+02, -2.3280717e+02 ); - expectedForces[543] = Vec3( -4.1530380e+01, -5.6394351e+02, 2.4472509e+02 ); - expectedForces[544] = Vec3( -1.6193396e+01, -8.0431396e+01, -2.9094018e+02 ); - expectedForces[545] = Vec3( -1.9414773e+01, 4.6180982e+01, 3.3123072e+01 ); - expectedForces[546] = Vec3( -3.9314039e+02, -3.9874866e+02, 4.5308571e+02 ); - expectedForces[547] = Vec3( -7.1897482e+01, -1.1940445e+02, -2.7405931e+02 ); - expectedForces[548] = Vec3( 3.0646396e+02, 6.1235747e+01, -1.5253270e+02 ); - expectedForces[549] = Vec3( -3.2480464e+02, 4.3056561e+02, 3.2532485e+01 ); - expectedForces[550] = Vec3( 1.2818655e+02, 7.4294994e-01, -5.7650521e+00 ); - expectedForces[551] = Vec3( -1.7481437e+02, -2.6203225e+02, -9.6793481e+01 ); - expectedForces[552] = Vec3( 1.9259110e+02, 3.0171883e+02, 5.2403235e+02 ); - expectedForces[553] = Vec3( -7.8132123e+01, -7.6569340e+00, -1.1140240e+02 ); - expectedForces[554] = Vec3( -5.2504673e+02, -4.3700574e+02, 4.3321261e+02 ); - expectedForces[555] = Vec3( -9.9785283e+02, 2.7139143e+02, -4.1723547e+02 ); - expectedForces[556] = Vec3( 2.7115933e+02, -8.7444541e+01, 1.0745103e+02 ); - expectedForces[557] = Vec3( 1.4348018e+02, 1.4013343e+02, -4.0305733e+02 ); - expectedForces[558] = Vec3( 4.9491010e+02, 4.3040089e+02, -3.5558583e+02 ); - expectedForces[559] = Vec3( -1.8510736e+02, 6.7129731e+01, -2.1324364e+02 ); - expectedForces[560] = Vec3( 8.4478090e+01, 4.0986269e+01, 4.1401094e+02 ); - expectedForces[561] = Vec3( 4.4188419e+01, -8.6520108e+02, 6.8555821e+02 ); - expectedForces[562] = Vec3( -4.5036974e+02, 2.2379481e+02, 6.2457971e+01 ); - expectedForces[563] = Vec3( 2.4325836e+02, 6.9725116e+01, 3.6266296e+01 ); - expectedForces[564] = Vec3( 1.5611925e+02, -2.4471023e+02, 4.7857332e+02 ); - expectedForces[565] = Vec3( -3.5692822e+02, -2.7248961e+02, -1.8165146e+02 ); - expectedForces[566] = Vec3( 4.3093388e+02, 1.6944839e+02, -4.4177741e+02 ); - expectedForces[567] = Vec3( 5.2118711e+02, -1.5252783e+02, -1.6964047e+02 ); - expectedForces[568] = Vec3( 1.3899083e+03, 3.8363654e+02, -6.4623177e+02 ); - expectedForces[569] = Vec3( -1.4984858e+02, 4.5097170e+01, -5.0257768e+01 ); - expectedForces[570] = Vec3( -8.1979709e+01, -4.1632909e+01, -5.1367825e+02 ); - expectedForces[571] = Vec3( -7.8645235e+00, 1.8105470e+01, 9.2902759e+01 ); - expectedForces[572] = Vec3( 1.2725548e+02, 1.3926229e+02, -4.3752260e+01 ); - expectedForces[573] = Vec3( -2.7817289e+01, -8.0900345e+01, -4.3178498e+02 ); - expectedForces[574] = Vec3( 2.2115263e+02, -7.8807799e+01, 8.8367391e+01 ); - expectedForces[575] = Vec3( -1.2756938e+02, 4.2170937e+02, -6.8418245e+01 ); - expectedForces[576] = Vec3( 8.8370341e+01, -1.4671130e+02, -5.6211071e+02 ); - expectedForces[577] = Vec3( 6.7701453e+02, 2.1228010e+02, 2.3047236e+02 ); - expectedForces[578] = Vec3( -1.2694819e+02, -7.2734890e+00, 1.1007893e+02 ); - expectedForces[579] = Vec3( -6.8945756e+02, 1.7359485e+02, -2.5607776e+02 ); - expectedForces[580] = Vec3( 6.7323923e+00, 3.1574487e+02, 5.9741152e+02 ); - expectedForces[581] = Vec3( 2.1214031e+02, -4.7565197e+01, -9.6896159e+01 ); - expectedForces[582] = Vec3( -3.4876562e+02, 5.8335489e+01, -1.7058451e+02 ); - expectedForces[583] = Vec3( -1.6516914e+02, -3.8913162e+02, 5.8832025e+02 ); - expectedForces[584] = Vec3( 4.7753612e+01, -6.6792213e+01, -4.6492749e+01 ); - expectedForces[585] = Vec3( -4.7166578e+02, 7.1811831e+02, 7.0620222e+02 ); - expectedForces[586] = Vec3( -3.0570577e+02, -1.7681907e+02, -2.1227370e+02 ); - expectedForces[587] = Vec3( 1.8122997e+02, -6.8318737e+01, -3.4853368e+02 ); - expectedForces[588] = Vec3( 7.5752093e+01, 3.9702196e+02, -9.0196404e+02 ); - expectedForces[589] = Vec3( 5.1185528e+02, -7.7747186e+02, -3.3969581e+02 ); - expectedForces[590] = Vec3( -3.1187606e+01, 5.9593198e+01, 7.7918649e+01 ); - expectedForces[591] = Vec3( 2.2741676e+02, 2.1705631e+02, 3.9920149e+02 ); - expectedForces[592] = Vec3( 7.0516894e+01, 3.3389665e+02, -6.8443760e+00 ); - expectedForces[593] = Vec3( -9.9645406e+02, 2.8574127e+02, -8.0946834e+02 ); - expectedForces[594] = Vec3( 1.0930460e+02, 1.5869363e+03, -4.0704089e+02 ); - expectedForces[595] = Vec3( -3.0341438e+02, -5.7494385e+00, 2.9655509e+02 ); - expectedForces[596] = Vec3( 8.7955203e+01, -7.6811348e+01, -6.9558652e+01 ); - expectedForces[597] = Vec3( -9.4378353e+01, 3.6253070e+02, 9.0703343e-01 ); - expectedForces[598] = Vec3( -4.7595525e+01, -6.9148379e+02, -4.6737971e+02 ); - expectedForces[599] = Vec3( 2.2339987e+02, -2.5503335e+02, 2.8552040e+02 ); - expectedForces[600] = Vec3( 1.0309072e+02, -2.1298204e+02, -4.3393283e+02 ); - expectedForces[601] = Vec3( -2.4581477e+02, 2.5126386e+02, -1.8679710e+02 ); - expectedForces[602] = Vec3( 7.7926618e+00, -2.4947558e+01, 1.5962011e+02 ); - expectedForces[603] = Vec3( 7.0099476e+02, 5.9496129e+01, 2.0314640e+02 ); - expectedForces[604] = Vec3( -5.2583810e+01, 3.1237489e+01, -4.0902937e+00 ); - expectedForces[605] = Vec3( -5.4435871e+01, -7.7056693e+01, -1.5137215e+01 ); - expectedForces[606] = Vec3( -7.8684074e+02, 8.1673860e+02, 5.0192222e+02 ); - expectedForces[607] = Vec3( 2.9859285e+02, 1.9661708e+02, -1.9940993e+02 ); - expectedForces[608] = Vec3( -9.9358476e-01, -3.4789219e+02, 1.7693106e+02 ); - expectedForces[609] = Vec3( 6.7880927e+02, 7.2768533e+01, 1.1973248e+03 ); - expectedForces[610] = Vec3( -1.2072838e+00, 1.1770157e+02, -8.6765918e+01 ); - expectedForces[611] = Vec3( -4.3236695e+02, -2.8583002e+02, 1.3459508e+02 ); - expectedForces[612] = Vec3( -6.1894609e+01, 4.4705141e+02, -2.3264215e+02 ); - expectedForces[613] = Vec3( -2.6948720e+01, -2.7688230e+01, 4.6300601e+01 ); - expectedForces[614] = Vec3( 4.3954815e+01, 6.1244278e+01, 1.0727211e+02 ); - expectedForces[615] = Vec3( -2.2049132e+02, -9.7233594e+01, 8.3807949e+01 ); - expectedForces[616] = Vec3( 2.8631226e+02, -1.3478640e+02, -5.0675977e+02 ); - expectedForces[617] = Vec3( -1.1458029e+01, 6.3762007e+01, -4.9643140e+01 ); - expectedForces[618] = Vec3( 7.7363305e+01, 1.1936816e+02, 3.9692323e+01 ); - expectedForces[619] = Vec3( -8.4199858e+01, 2.3567494e+02, 7.2885200e+01 ); - expectedForces[620] = Vec3( -7.4500104e+00, 3.5567340e+00, -2.2676267e+01 ); - expectedForces[621] = Vec3( -7.9200057e+02, 3.2245192e+01, 1.1829644e+01 ); - expectedForces[622] = Vec3( 3.9959336e+02, 2.2447865e+02, -3.1413233e+02 ); - expectedForces[623] = Vec3( 1.5810527e+02, -2.2341997e+02, 2.3388212e+02 ); - expectedForces[624] = Vec3( -2.9248657e+02, -1.0806250e+03, -6.1268035e+01 ); - expectedForces[625] = Vec3( 6.5061442e+02, 1.2244756e+02, -1.1976147e+02 ); - expectedForces[626] = Vec3( -1.7787710e+02, 3.7279354e+02, -3.7911745e+02 ); - expectedForces[627] = Vec3( 3.7145927e+02, -2.5203732e+02, -2.2889342e+02 ); - expectedForces[628] = Vec3( 1.9440281e+02, -2.3076142e+02, 7.2945279e+01 ); - expectedForces[629] = Vec3( -2.3603693e+02, -1.1987203e+02, -1.2000208e+02 ); - expectedForces[630] = Vec3( -8.4811726e+01, -6.4500846e+02, -5.1257210e+02 ); - expectedForces[631] = Vec3( -1.6183393e+01, 1.3980655e+01, -2.3189702e+00 ); - expectedForces[632] = Vec3( 1.3526098e+02, 1.3800365e+02, -9.4360476e+01 ); - expectedForces[633] = Vec3( 2.0983514e+01, 5.1156494e+02, -4.3526557e+01 ); - expectedForces[634] = Vec3( -2.8666500e+02, -5.8235691e+02, -8.7425194e+01 ); - expectedForces[635] = Vec3( -1.7183604e+02, 1.0002944e+01, 6.5855812e+02 ); - expectedForces[636] = Vec3( -2.1735465e+02, 9.4664675e+02, 8.9132890e+02 ); - expectedForces[637] = Vec3( 6.3759184e+01, -5.2436201e+02, 1.2455578e+02 ); - expectedForces[638] = Vec3( 3.2176621e+02, 1.8182348e+02, -4.4863340e+02 ); - expectedForces[639] = Vec3( -8.4308252e+02, -1.6268681e+02, 5.8113352e+02 ); - expectedForces[640] = Vec3( 6.1223389e+01, 3.6767423e+02, 5.9071999e+02 ); - expectedForces[641] = Vec3( 2.2546928e+02, -2.2022805e+02, 8.3027103e+01 ); - expectedForces[642] = Vec3( -4.0385190e+02, 2.0141033e+02, 2.7296512e+01 ); - expectedForces[643] = Vec3( 8.4204485e+01, -7.1102294e+01, 5.7642677e+01 ); - expectedForces[644] = Vec3( 6.1859901e+01, 1.4828523e+02, -2.6764016e+02 ); - expectedForces[645] = Vec3( -6.7249932e+02, -8.4613525e+01, -3.9792609e+02 ); - expectedForces[646] = Vec3( 9.9116485e+01, -3.7714583e+01, -5.3966332e+01 ); - expectedForces[647] = Vec3( 2.0868628e+02, 2.9747206e+02, 3.3931416e+02 ); + expectedForces[0] = Vec3( 2.3025909e+02, -1.0422757e+01, -2.1413965e+02); + expectedForces[1] = Vec3( 1.1261936e+02, 5.5882575e+02, 9.6539143e+01); + expectedForces[2] = Vec3( -8.8436857e+01, -4.4737313e+01, 2.5242022e+02); + expectedForces[3] = Vec3( 6.3548886e+02, -1.9582636e+02, -1.2229882e+02); + expectedForces[4] = Vec3( -3.9513809e+02, -1.3738635e+02, -1.2488717e+02); + expectedForces[5] = Vec3( 6.8771170e+00, 9.1574345e+01, -1.3865672e+00); + expectedForces[6] = Vec3( 3.6928792e+02, -7.1025648e+01, 5.2550320e+02); + expectedForces[7] = Vec3( 1.5531325e+02, -7.9256260e+02, 3.8119809e+02); + expectedForces[8] = Vec3( 1.5408049e+02, 1.4633285e+02, -5.4573735e+02); + expectedForces[9] = Vec3( -3.2549641e+02, 2.8613802e+01, 1.8082150e+02); + expectedForces[10] = Vec3( 1.9968249e+02, -7.7742415e+01, -4.2188467e+02); + expectedForces[11] = Vec3( 4.6645952e+01, 2.1362909e+01, 5.7120135e+01); + expectedForces[12] = Vec3( 4.2971265e+01, -4.2927865e+01, -7.6319121e+02); + expectedForces[13] = Vec3( 2.1889551e+02, -5.1806784e+01, 7.6637073e+01); + expectedForces[14] = Vec3( -3.0028991e+02, 9.0479382e+01, 1.3199449e+02); + expectedForces[15] = Vec3( -1.8041801e+00, -1.2176813e+03, -5.9679371e+02); + expectedForces[16] = Vec3( -1.4773339e+02, -1.2582057e+02, 8.4242040e+02); + expectedForces[17] = Vec3( 6.8633312e+02, -2.4864325e+01, 1.0675519e+01); + expectedForces[18] = Vec3( 4.8211733e+02, -2.2044742e+02, 1.8105309e+02); + expectedForces[19] = Vec3( -2.1956736e+02, 5.4786741e+02, -1.4827263e+02); + expectedForces[20] = Vec3( -1.0476100e+02, -1.6922280e+02, 8.3220473e+01); + expectedForces[21] = Vec3( 5.5455350e+01, 1.7851224e+02, 6.0598643e+02); + expectedForces[22] = Vec3( 7.1915871e+00, -1.6455057e+01, -6.3929797e+00); + expectedForces[23] = Vec3( -2.4371864e+02, -7.0765288e+02, -1.7820148e+02); + expectedForces[24] = Vec3( -4.3715367e+02, 2.8707226e+02, 2.2558361e+02); + expectedForces[25] = Vec3( 2.3735557e+00, -4.2064130e+00, 2.5933632e+01); + expectedForces[26] = Vec3( 1.0192415e+02, 5.3205842e+01, -2.0158900e+02); + expectedForces[27] = Vec3( -5.1276812e+02, 2.4860179e+02, 2.5150125e+02); + expectedForces[28] = Vec3( 3.9608987e+02, -4.0544816e+01, -2.1579831e+02); + expectedForces[29] = Vec3( -2.5926005e+02, -1.1691294e+02, -4.7278417e+02); + expectedForces[30] = Vec3( -1.1036158e+02, 3.3229287e+01, 8.8351491e+01); + expectedForces[31] = Vec3( -4.1178603e+00, 1.2957632e+00, 1.2617868e+00); + expectedForces[32] = Vec3( 1.9401524e+02, 1.0030314e+02, 3.0386141e+01); + expectedForces[33] = Vec3( 1.0870981e+02, 2.1865882e+02, 6.7672725e+02); + expectedForces[34] = Vec3( 3.6812338e+01, -2.9347382e-01, 1.2959790e+01); + expectedForces[35] = Vec3( -5.5738560e+01, 2.2268442e+02, -1.4911862e+02); + expectedForces[36] = Vec3( -1.6659719e+02, 8.1941190e+01, 7.8132996e+01); + expectedForces[37] = Vec3( -1.1985659e+02, 7.1891763e+01, -3.2559738e+02); + expectedForces[38] = Vec3( 1.4441653e+02, 4.1824194e+02, 3.4293255e+01); + expectedForces[39] = Vec3( 1.1307312e+02, -3.4981802e+02, -1.0676819e+02); + expectedForces[40] = Vec3( -1.2857487e+02, -4.0798950e+01, -1.7800009e+02); + expectedForces[41] = Vec3( -4.1244991e+02, 2.3439565e+02, 3.8546709e+02); + expectedForces[42] = Vec3( 2.1799653e+02, 2.9397348e+02, -3.8955146e+02); + expectedForces[43] = Vec3( -9.4254462e+01, 5.0157547e+01, 1.3707146e+02); + expectedForces[44] = Vec3( 8.0520929e+02, -1.0228045e+03, -4.5813594e+01); + expectedForces[45] = Vec3( 5.3451125e+02, -7.0725115e+02, -2.3828883e+02); + expectedForces[46] = Vec3( 3.6991801e+02, -1.0410466e+03, 8.4889413e+02); + expectedForces[47] = Vec3( 5.8096458e+01, 2.3859368e+02, 7.3104979e+01); + expectedForces[48] = Vec3( -1.3230378e+03, 7.1827816e+02, 9.4372946e+02); + expectedForces[49] = Vec3( -4.2398413e+02, -3.6766481e+02, -1.6666711e+02); + expectedForces[50] = Vec3( 8.6374766e+00, -2.7870227e+02, 3.0621233e+02); + expectedForces[51] = Vec3( -2.4404981e+02, 1.0510491e+03, -3.5202340e+02); + expectedForces[52] = Vec3( 1.7461155e+02, 1.3419948e+02, 5.0279733e+02); + expectedForces[53] = Vec3( 9.7089193e+01, -1.4826120e+02, -2.3426711e+02); + expectedForces[54] = Vec3( -1.0647432e+02, 2.3266543e+02, -3.5025025e+02); + expectedForces[55] = Vec3( -1.9951717e+02, -1.0804258e+02, 6.2114265e+01); + expectedForces[56] = Vec3( 2.5354284e+02, -3.5074926e+02, -2.9176946e+01); + expectedForces[57] = Vec3( -8.8328002e+02, -1.8937053e+02, 2.0772189e+02); + expectedForces[58] = Vec3( 4.5809698e+01, -1.8636513e+00, 1.6742910e+01); + expectedForces[59] = Vec3( 8.6670673e+01, 1.2653519e+02, 2.0046372e+02); + expectedForces[60] = Vec3( -9.6142275e+02, 1.1800289e+03, 1.0064471e+02); + expectedForces[61] = Vec3( -6.9751453e+01, -1.9324691e+02, 2.2638891e+01); + expectedForces[62] = Vec3( 1.3671815e+02, 1.0129231e+01, -6.1136892e+01); + expectedForces[63] = Vec3( 7.6032938e+02, -1.9779542e+02, -2.5706161e+01); + expectedForces[64] = Vec3( -9.8966607e+00, 3.6294058e+02, -2.3247376e+02); + expectedForces[65] = Vec3( -1.3142673e+02, 9.9368000e+00, 1.4225069e+02); + expectedForces[66] = Vec3( 5.2691625e+01, -4.0618331e+02, -1.0942115e+02); + expectedForces[67] = Vec3( 5.8137742e+01, 2.1942441e+02, -1.7191686e+02); + expectedForces[68] = Vec3( 1.2480778e+02, 2.4086799e+01, -1.9588545e+02); + expectedForces[69] = Vec3( 2.4577512e+02, -2.3516051e+01, 2.3764379e+02); + expectedForces[70] = Vec3( 4.2298797e+01, 8.6807583e+01, 2.9276129e+02); + expectedForces[71] = Vec3( 3.0309915e+01, -3.4686002e+02, 1.0849989e+02); + expectedForces[72] = Vec3( 5.5170999e+02, -1.5797913e+02, 9.8379834e+01); + expectedForces[73] = Vec3( -5.3706921e+02, 2.2236470e+02, 2.7548665e+02); + expectedForces[74] = Vec3( -2.7734936e+02, -4.2949693e+02, -8.2303469e+02); + expectedForces[75] = Vec3( 1.1749001e+03, 9.2734627e+02, -2.6342291e+02); + expectedForces[76] = Vec3( -1.2345216e+02, -6.6220297e+01, 1.1022778e+02); + expectedForces[77] = Vec3( -4.4861284e+01, -7.4560959e+01, -8.0791275e+01); + expectedForces[78] = Vec3( 1.7692476e+01, -9.9067626e+02, -3.3083363e+02); + expectedForces[79] = Vec3( 6.4276566e+01, 5.1865608e+02, 4.1241764e+02); + expectedForces[80] = Vec3( 6.5867999e+02, 2.0995465e+02, -5.0989840e+02); + expectedForces[81] = Vec3( -5.2826435e+02, -1.3719887e+02, 1.9730314e+02); + expectedForces[82] = Vec3( 2.3329314e+02, 5.1589944e+01, -3.3942818e+02); + expectedForces[83] = Vec3( -2.5756193e+00, 1.3788257e+02, 1.3074778e+02); + expectedForces[84] = Vec3( -2.8925811e+01, 8.8185346e+01, 1.1547804e+02); + expectedForces[85] = Vec3( -3.3582542e+01, -1.3079843e+02, 3.4774799e+02); + expectedForces[86] = Vec3( -5.9585326e+01, -3.7973755e+01, 1.0206767e+01); + expectedForces[87] = Vec3( -7.1691223e+01, -1.9547311e+02, 9.3856472e+02); + expectedForces[88] = Vec3( 1.4832977e+02, 4.2005795e+02, 2.7235044e+01); + expectedForces[89] = Vec3( 8.6221698e+00, -1.3935906e+01, -2.5473157e+00); + expectedForces[90] = Vec3( 3.0044348e+02, 3.4320406e+02, 2.5305998e+02); + expectedForces[91] = Vec3( -1.6694013e+02, 7.4645776e+02, 3.3266168e+01); + expectedForces[92] = Vec3( 1.6931562e+02, -2.3972286e+01, -3.0802865e+02); + expectedForces[93] = Vec3( -2.5931152e+02, -9.7825375e+01, -5.5598386e+02); + expectedForces[94] = Vec3( -7.8473519e+01, -2.6244561e+02, 2.9622027e+02); + expectedForces[95] = Vec3( 1.5788473e+02, 2.9806605e+02, 1.8283700e+02); + expectedForces[96] = Vec3( -4.2033208e+02, 4.8745845e+02, 9.7957219e+01); + expectedForces[97] = Vec3( 1.3261733e+00, 3.7143158e+00, -1.8329960e+00); + expectedForces[98] = Vec3( 7.4741051e+02, 1.0482696e+03, 1.7182445e+02); + expectedForces[99] = Vec3( 2.0366606e+02, 1.1586652e+02, 1.5482927e+03); + expectedForces[100] = Vec3( 5.7569884e+02, -2.2068597e+02, -1.9305186e+02); + expectedForces[101] = Vec3( -2.4259775e+02, -6.1359858e+01, -7.5753918e+01); + expectedForces[102] = Vec3( 2.4382837e+02, 1.3660693e+01, -2.8717824e+02); + expectedForces[103] = Vec3( -4.1914381e+02, -1.4506334e+02, 7.7692658e+01); + expectedForces[104] = Vec3( 9.5422158e+01, -1.4261849e+01, 1.0122453e+02); + expectedForces[105] = Vec3( -6.1222151e+02, 6.1398147e+01, 3.2961693e+02); + expectedForces[106] = Vec3( -2.7982116e+02, -3.7564793e+02, -2.4318658e+02); + expectedForces[107] = Vec3( 8.2892383e+01, 1.1992522e+01, 2.4802899e+01); + expectedForces[108] = Vec3( -3.3626753e+02, -7.8892295e+01, 8.1184535e+02); + expectedForces[109] = Vec3( -4.6396103e+01, 3.1165111e+01, -3.5184949e+01); + expectedForces[110] = Vec3( 4.6295297e+02, -8.0135823e+01, -3.2963637e+02); + expectedForces[111] = Vec3( 5.5325945e+02, 3.8213691e+02, -5.9449911e+02); + expectedForces[112] = Vec3( -6.1770559e+02, 2.2322880e+02, -2.1022934e+01); + expectedForces[113] = Vec3( 2.3716825e+02, -3.8085281e+02, 4.9618193e+02); + expectedForces[114] = Vec3( 2.9972570e+02, 3.3773759e+02, 3.4933501e+02); + expectedForces[115] = Vec3( 1.9913039e+02, -3.2035626e+02, -9.7987777e+01); + expectedForces[116] = Vec3( -2.3506456e+02, 4.0030561e+02, -6.2604809e+02); + expectedForces[117] = Vec3( 6.0408777e+02, 5.6271523e+02, -5.8742635e+02); + expectedForces[118] = Vec3( -5.0707285e+02, 7.8511351e+02, -1.7561830e+02); + expectedForces[119] = Vec3( 5.6759945e+00, 6.9735233e+00, -9.8853787e+00); + expectedForces[120] = Vec3( 1.1918531e+02, -5.6200785e+02, 3.2333502e+02); + expectedForces[121] = Vec3( 5.1801315e+02, -3.4460898e+02, 1.1488242e+02); + expectedForces[122] = Vec3( 7.5859703e+00, 6.9528951e+01, -6.2437444e+00); + expectedForces[123] = Vec3( 1.1990899e+03, -1.2507886e+01, 1.1906562e+03); + expectedForces[124] = Vec3( 2.6001536e+02, -9.5041373e+01, -4.2547252e+02); + expectedForces[125] = Vec3( -3.5601586e+01, 9.1460220e+02, 6.2306102e+02); + expectedForces[126] = Vec3( -3.8254176e+01, 2.4796243e+02, 3.0638741e+02); + expectedForces[127] = Vec3( -3.8798311e+02, 1.2532794e+02, -3.1926601e+01); + expectedForces[128] = Vec3( 5.7672682e+01, 1.7487900e+02, -1.0319581e+02); + expectedForces[129] = Vec3( 4.4276215e+02, -1.5517993e+02, 3.8122873e+02); + expectedForces[130] = Vec3( -2.8119980e+02, -2.6530936e+02, 4.3545814e+01); + expectedForces[131] = Vec3( 5.9375768e+00, 1.6335780e+01, -3.6204644e+02); + expectedForces[132] = Vec3( 5.9733834e+02, -2.9843602e+02, 1.0541092e+03); + expectedForces[133] = Vec3( -3.4568461e+02, 2.2794808e+02, -8.4675886e+01); + expectedForces[134] = Vec3( -6.7882706e+01, -4.5016799e+02, -1.9387646e+02); + expectedForces[135] = Vec3( 5.6125478e+02, -1.1741092e+03, 1.4214256e+02); + expectedForces[136] = Vec3( 1.2766648e+02, 1.2519441e+02, -4.4359129e+02); + expectedForces[137] = Vec3( -2.7235507e+01, -1.0871423e+01, 3.2406976e+01); + expectedForces[138] = Vec3( -1.2110689e+03, 1.3038667e+02, -7.5331947e+02); + expectedForces[139] = Vec3( 3.2504988e+02, -7.1577942e+02, -2.4351454e+02); + expectedForces[140] = Vec3( 2.6466925e+02, 3.6878498e+02, -6.2044711e+01); + expectedForces[141] = Vec3( -6.2647276e+02, -4.7112562e+02, -6.1885184e+01); + expectedForces[142] = Vec3( 3.0996699e+01, 3.1033732e+02, -5.7493337e+02); + expectedForces[143] = Vec3( 2.4664962e+01, 7.8306665e+02, 3.7907751e+02); + expectedForces[144] = Vec3( -1.9847551e+02, -3.0052499e+02, -6.5192951e+01); + expectedForces[145] = Vec3( -5.0686773e+02, 1.1972933e+02, 3.6202910e+02); + expectedForces[146] = Vec3( 4.0004521e+02, -4.3205645e+02, 2.8583074e+02); + expectedForces[147] = Vec3( -2.9447542e+01, 6.3434099e+02, -6.5189179e+02); + expectedForces[148] = Vec3( 4.1588516e+02, -1.5534873e+02, -1.1031323e+01); + expectedForces[149] = Vec3( 1.2761543e+01, -5.6871456e+01, 2.8032565e+02); + expectedForces[150] = Vec3( -4.7527199e+01, 6.2549647e+02, -8.5007589e+02); + expectedForces[151] = Vec3( 1.6598949e+01, 1.1210199e+02, 2.0667266e+02); + expectedForces[152] = Vec3( -2.4012423e+00, -6.1728962e+01, -1.5057977e+01); + expectedForces[153] = Vec3( -3.6934056e+02, 2.3087063e+02, -3.3268511e+02); + expectedForces[154] = Vec3( 1.2658460e+02, 4.1809355e+02, 1.9550635e+02); + expectedForces[155] = Vec3( -1.9528152e+02, -1.9035919e+02, 1.4986704e+02); + expectedForces[156] = Vec3( -5.9608803e+00, 2.7258190e+02, 5.5318395e+02); + expectedForces[157] = Vec3( -1.0545084e+01, -1.8397001e+00, -3.3615498e+00); + expectedForces[158] = Vec3( -4.0827462e+02, -6.4070993e+01, -2.6614992e+02); + expectedForces[159] = Vec3( -1.5773827e+02, 4.7708702e+02, -9.9622711e+02); + expectedForces[160] = Vec3( 8.3896122e+01, 2.5959601e+02, 1.7728081e+02); + expectedForces[161] = Vec3( -2.4859055e+02, 8.1617294e+01, 2.7905586e+02); + expectedForces[162] = Vec3( 1.3694593e+02, -6.2640483e+02, -2.5308878e+02); + expectedForces[163] = Vec3( -1.5156337e+02, 1.1567379e+02, 1.8384602e+02); + expectedForces[164] = Vec3( -1.4794785e+02, -8.0381965e+01, 9.4028021e+02); + expectedForces[165] = Vec3( -3.5851252e+02, 2.6066489e+02, -4.1225343e+01); + expectedForces[166] = Vec3( 1.0820389e+02, -8.3485138e+01, 9.5047812e+01); + expectedForces[167] = Vec3( 2.0019411e+02, 5.0864719e+02, -4.8662239e+01); + expectedForces[168] = Vec3( -3.0716707e+02, -9.8820762e+02, 1.3660536e+01); + expectedForces[169] = Vec3( 8.5788590e+02, -1.0335921e+02, -2.2197815e+02); + expectedForces[170] = Vec3( 9.8072705e+00, 6.6224870e+02, -1.1594055e+02); + expectedForces[171] = Vec3( -3.6572453e+01, 2.4062731e+02, 1.7831682e+02); + expectedForces[172] = Vec3( -2.1274187e+00, -2.5471785e+02, -2.5813525e+02); + expectedForces[173] = Vec3( 3.4763673e+02, -2.0753062e+02, 7.5125390e+02); + expectedForces[174] = Vec3( 2.9010685e+01, -4.1894498e+02, -6.3847846e+02); + expectedForces[175] = Vec3( 3.0255245e+02, 2.5945698e+02, 2.3530662e+01); + expectedForces[176] = Vec3( -2.0827676e+01, 2.2568888e+01, 1.0890440e+01); + expectedForces[177] = Vec3( 2.2415739e+02, 3.5720682e+02, -8.7208211e+01); + expectedForces[178] = Vec3( -2.9808276e+02, 7.0108444e+01, -1.5361211e+02); + expectedForces[179] = Vec3( 2.3882234e+02, -2.6764176e+02, -1.7847229e+01); + expectedForces[180] = Vec3( -4.7380966e+02, 5.2547306e+01, 7.4446526e+02); + expectedForces[181] = Vec3( 4.2804072e+00, -2.2456284e+02, -2.0288206e+02); + expectedForces[182] = Vec3( 2.5474630e+00, 2.5211778e+01, 1.2675317e+01); + expectedForces[183] = Vec3( -1.4519676e+02, -1.7268277e+02, -8.4750014e+02); + expectedForces[184] = Vec3( -1.6850633e+02, 9.5223081e+02, -2.5415253e+02); + expectedForces[185] = Vec3( -2.1600185e+02, -1.6313340e+02, 1.8746411e+02); + expectedForces[186] = Vec3( 4.5719348e+01, -5.8877840e+01, -1.1199622e+02); + expectedForces[187] = Vec3( -9.0377199e+01, 2.2045926e+02, -3.2532356e+02); + expectedForces[188] = Vec3( -1.4523032e+02, -2.2127499e+02, 1.1526636e+02); + expectedForces[189] = Vec3( 1.9857975e+02, -1.8170037e+02, 3.2016150e+02); + expectedForces[190] = Vec3( 1.5659789e+02, 5.2984420e+01, -1.0121553e+02); + expectedForces[191] = Vec3( 1.3925504e+01, -1.1627739e+02, 1.7106106e+00); + expectedForces[192] = Vec3( 1.7560737e+01, 3.1275548e+02, 1.4568181e+02); + expectedForces[193] = Vec3( 8.5129168e-01, 3.2688468e+01, -2.0471785e+02); + expectedForces[194] = Vec3( 2.5640904e+02, -1.8345358e+02, 3.3082812e+02); + expectedForces[195] = Vec3( 1.5159266e+02, -7.9091822e+02, 7.6475475e+02); + expectedForces[196] = Vec3( 7.8546101e+02, 1.7887845e+02, -7.4508377e+01); + expectedForces[197] = Vec3( 6.9010029e+00, 2.1336674e+01, -7.8256484e+01); + expectedForces[198] = Vec3( -3.4033432e+01, -1.6471994e+02, -2.8721884e+02); + expectedForces[199] = Vec3( -1.2248359e+02, 5.3002993e+01, 3.5296174e+02); + expectedForces[200] = Vec3( 1.7497881e+02, 1.1744848e+02, 1.8127502e+02); + expectedForces[201] = Vec3( -1.1710882e+03, 8.7114752e+02, -1.3353036e+02); + expectedForces[202] = Vec3( 2.7510368e+02, -1.9393814e+02, 2.6671453e+02); + expectedForces[203] = Vec3( 7.3421287e+01, -3.8409917e+01, -1.0910368e+02); + expectedForces[204] = Vec3( -8.7394869e+02, -1.2323430e+03, -1.3693068e+02); + expectedForces[205] = Vec3( 2.5439149e+02, 2.4002077e+02, 3.0231859e+02); + expectedForces[206] = Vec3( -9.8167431e+01, 3.1515278e+02, -2.5512038e+02); + expectedForces[207] = Vec3( 2.7501189e+02, -4.9189774e+02, 4.5827877e+02); + expectedForces[208] = Vec3( -8.2333908e+02, -7.0609881e+02, 2.9188070e+02); + expectedForces[209] = Vec3( -2.9200330e+02, 1.9955124e+02, -7.9227826e+00); + expectedForces[210] = Vec3( 8.0151971e+02, 3.8996996e+02, -1.9508756e+02); + expectedForces[211] = Vec3( -6.2168096e+01, 2.4323951e+01, 9.8845638e+01); + expectedForces[212] = Vec3( 2.2980428e+01, -6.2829693e+02, -7.5253154e+02); + expectedForces[213] = Vec3( -5.7502634e+02, 8.2310635e+02, 3.7934867e+02); + expectedForces[214] = Vec3( -8.9168889e+01, 5.0052167e+01, -8.6850564e+01); + expectedForces[215] = Vec3( 2.7414821e+02, -5.9725191e+01, -3.7278778e+00); + expectedForces[216] = Vec3( -5.3230933e+02, 4.7698725e+02, -2.5857751e+02); + expectedForces[217] = Vec3( 2.1615644e+02, 6.0001233e+01, -1.1880182e+02); + expectedForces[218] = Vec3( 2.9837823e+01, -3.9275454e+01, -4.3913571e+01); + expectedForces[219] = Vec3( -5.6516561e+02, -1.6539113e+02, 3.3185872e+02); + expectedForces[220] = Vec3( -1.5484833e+01, -1.0085566e+01, -2.8199778e+01); + expectedForces[221] = Vec3( 6.4295337e+02, -2.7398997e+02, 8.2320867e+02); + expectedForces[222] = Vec3( 3.3816540e+02, -1.8492046e+02, 8.6215770e+02); + expectedForces[223] = Vec3( 2.4367872e+02, 8.9527142e+01, -5.9973680e+02); + expectedForces[224] = Vec3( -6.1601439e+02, -5.3093862e+02, 4.1696221e+01); + expectedForces[225] = Vec3( 2.2521478e+02, -2.9234267e+02, 2.9760244e+02); + expectedForces[226] = Vec3( -1.2672295e+02, 2.5753736e+01, -1.6216252e+02); + expectedForces[227] = Vec3( 1.1136724e+02, 4.3446676e+00, -1.4045447e+01); + expectedForces[228] = Vec3( 3.5554849e+02, 7.7446255e+00, 5.8722356e+02); + expectedForces[229] = Vec3( -7.8313952e+02, -5.9206053e+01, 5.1181391e+02); + expectedForces[230] = Vec3( -9.5647729e+01, -4.6045792e+02, -3.1515210e+02); + expectedForces[231] = Vec3( 8.7273284e+01, 8.0310279e+02, -1.2212040e+03); + expectedForces[232] = Vec3( -9.0853819e+02, -7.6005570e+02, 1.8578569e+02); + expectedForces[233] = Vec3( 1.2061615e+02, -3.2834560e+02, 5.1291192e+01); + expectedForces[234] = Vec3( 6.0149262e+02, 1.6081852e+03, -1.0922015e+03); + expectedForces[235] = Vec3( -5.8087260e+01, -2.6676779e+02, -1.5006920e+02); + expectedForces[236] = Vec3( -1.0997771e+01, 1.3012815e+02, 5.8615633e+02); + expectedForces[237] = Vec3( 4.9821503e+02, -9.5783644e+01, -6.5708073e+02); + expectedForces[238] = Vec3( -4.9394992e+02, -7.0445435e+02, -1.5540228e+02); + expectedForces[239] = Vec3( 1.5710340e+01, 1.9170336e+02, 4.6707393e+02); + expectedForces[240] = Vec3( -1.2599557e+03, 5.6104975e+02, 6.5853210e+02); + expectedForces[241] = Vec3( 1.3032986e+01, -2.7481865e+01, 8.0373029e+00); + expectedForces[242] = Vec3( 1.4371505e+02, -5.2615293e+01, -3.7929456e+02); + expectedForces[243] = Vec3( 6.0025739e+01, 1.4474905e+02, 3.6414330e+02); + expectedForces[244] = Vec3( 4.5364033e+02, 7.0785823e+01, -2.9279112e+02); + expectedForces[245] = Vec3( -9.7012956e+01, -8.2545229e+01, -5.4567106e+01); + expectedForces[246] = Vec3( -3.6449281e+02, -5.6669832e+02, -3.5196038e+02); + expectedForces[247] = Vec3( 2.6571354e+02, -2.5051716e+02, -4.7199161e+01); + expectedForces[248] = Vec3( -4.7285701e+01, 1.7950093e+02, 8.0633971e+01); + expectedForces[249] = Vec3( 1.8035439e+02, 4.6977540e+02, 2.2589769e+02); + expectedForces[250] = Vec3( 5.9853399e+01, 1.5477006e+02, -1.7011806e+02); + expectedForces[251] = Vec3( -2.6084741e+02, -2.0538756e+02, 1.0269002e+02); + expectedForces[252] = Vec3( 4.0221722e+02, -1.0368371e+02, -1.3842460e+01); + expectedForces[253] = Vec3( -4.4264447e+02, -3.0334810e+02, 1.6740779e+02); + expectedForces[254] = Vec3( -1.7373662e+02, 1.5020202e+02, -3.3761418e+02); + expectedForces[255] = Vec3( 4.7508953e+01, -5.4028784e+02, -3.6291329e+01); + expectedForces[256] = Vec3( 5.4807168e+02, -2.0293664e+02, 5.5114363e+02); + expectedForces[257] = Vec3( -4.9787370e+01, 4.5106329e+01, -5.7524550e+01); + expectedForces[258] = Vec3( -5.1584935e+02, 1.5014186e+02, -6.6369834e+02); + expectedForces[259] = Vec3( -6.0140298e+01, -9.4127280e+01, 8.7495796e+01); + expectedForces[260] = Vec3( 8.0619588e+02, -2.1066454e+02, -5.9371508e+01); + expectedForces[261] = Vec3( 1.2817429e+02, -2.7044116e+02, 5.3213275e+02); + expectedForces[262] = Vec3( -4.1467442e-01, -1.3641138e+02, -8.5576287e+01); + expectedForces[263] = Vec3( -5.6508528e+01, 2.4091504e+01, -7.9236147e+01); + expectedForces[264] = Vec3( 1.4123799e+02, 2.1326444e+02, 1.9141445e+02); + expectedForces[265] = Vec3( 1.6579721e+02, -3.2221503e+02, -1.5197776e+02); + expectedForces[266] = Vec3( -2.5871222e+02, -2.6345996e+02, -1.1149413e+03); + expectedForces[267] = Vec3( -1.2859743e+02, -3.9214753e+02, -6.5874862e+02); + expectedForces[268] = Vec3( 1.7237157e+02, -2.8729010e+02, 3.2000889e+02); + expectedForces[269] = Vec3( 6.6312203e+02, 3.5683926e+02, 9.7235616e+01); + expectedForces[270] = Vec3( -1.1860349e+02, -4.3528895e+02, 1.1598672e+03); + expectedForces[271] = Vec3( 7.7135123e+01, -2.1671305e+02, -2.3088548e+02); + expectedForces[272] = Vec3( 7.2863708e+01, 5.2065158e+02, 1.5704752e+02); + expectedForces[273] = Vec3( -3.6727477e+02, -6.0885463e+01, 4.1193960e+01); + expectedForces[274] = Vec3( 5.4858881e+01, 1.6886577e+02, -1.1662392e+01); + expectedForces[275] = Vec3( 3.2070061e+01, -1.6138709e+01, -7.6648912e+00); + expectedForces[276] = Vec3( 2.5695892e+02, 7.7719531e+01, -8.3154765e+02); + expectedForces[277] = Vec3( -3.3460202e+01, -1.3077348e+02, 3.6110539e+01); + expectedForces[278] = Vec3( -4.1360402e+02, 2.7754335e+02, -1.1139467e+02); + expectedForces[279] = Vec3( 1.0012775e+02, 1.4365237e+03, 2.6972544e+02); + expectedForces[280] = Vec3( 7.8750024e+02, -2.3376123e+02, 9.5969232e+02); + expectedForces[281] = Vec3( -2.2493912e+02, -1.1444344e+01, -6.3713547e+01); + expectedForces[282] = Vec3( -9.4211966e+01, -3.9286586e+02, -7.0932607e+01); + expectedForces[283] = Vec3( 1.6192138e+02, 2.3010404e+02, -2.1511498e+02); + expectedForces[284] = Vec3( -4.9644702e+02, -1.1894844e+01, -4.7458477e+02); + expectedForces[285] = Vec3( -1.0151600e+02, -4.2789293e+02, 5.2698223e+02); + expectedForces[286] = Vec3( 1.1350409e+01, 1.5126445e+02, -5.2740587e+01); + expectedForces[287] = Vec3( -4.7715521e+02, -3.6476152e+02, -5.4346958e+02); + expectedForces[288] = Vec3( -9.4019721e+01, -2.4758228e+02, 4.2219712e+02); + expectedForces[289] = Vec3( 3.1525053e+01, 3.7927245e+02, -2.4577041e+02); + expectedForces[290] = Vec3( 4.4004025e+02, -9.4883983e+01, -6.9075632e+01); + expectedForces[291] = Vec3( -2.6553328e+02, -2.7059185e+02, 3.1145935e+02); + expectedForces[292] = Vec3( 1.1199463e+02, 9.0805870e+01, 8.0258804e+01); + expectedForces[293] = Vec3( 7.8056273e+01, -3.5931761e+01, -1.9249727e+02); + expectedForces[294] = Vec3( -1.2443366e+01, -1.4631721e+02, 7.9733561e+01); + expectedForces[295] = Vec3( -3.2866900e+02, 1.1527926e+02, -9.3135590e+01); + expectedForces[296] = Vec3( 7.5078643e+01, -7.2653837e+02, -1.0830908e+02); + expectedForces[297] = Vec3( 1.0361037e+02, 1.5478274e+02, 1.1293089e+03); + expectedForces[298] = Vec3( -2.4014663e+02, -5.6771824e+02, 1.5441974e+02); + expectedForces[299] = Vec3( -6.8441034e+01, -1.1226846e+02, -5.4497343e+02); + expectedForces[300] = Vec3( 2.9803689e+02, 1.0649462e+03, 2.5408768e+02); + expectedForces[301] = Vec3( 5.6356599e+01, -2.3035579e+02, 7.6928758e+01); + expectedForces[302] = Vec3( 1.0229494e+02, -1.9615696e+02, -3.2600199e+02); + expectedForces[303] = Vec3( -7.0312065e+01, -3.1170055e+02, 5.6453888e+02); + expectedForces[304] = Vec3( -7.0752582e+01, 1.2273280e+02, -1.6740503e+01); + expectedForces[305] = Vec3( 6.8972998e+02, -2.8067032e+02, 6.6502848e+01); + expectedForces[306] = Vec3( -8.8407472e+02, 3.7818347e+02, -1.2141945e+03); + expectedForces[307] = Vec3( -1.0445122e+02, -4.4818836e+02, -9.5227168e+00); + expectedForces[308] = Vec3( 8.3015802e+02, 5.0941309e+02, 3.2593793e+01); + expectedForces[309] = Vec3( 7.6887033e+02, 4.3490548e+02, -1.0826101e+03); + expectedForces[310] = Vec3( 1.4352949e+02, -3.9479802e+01, 1.7718790e+02); + expectedForces[311] = Vec3( -2.5204642e+02, -3.3888239e+02, -2.7365802e+02); + expectedForces[312] = Vec3( -4.4783121e+02, 4.4465580e+02, 9.2506336e+02); + expectedForces[313] = Vec3( -3.3390337e+01, -5.0097602e+02, -3.6812516e+02); + expectedForces[314] = Vec3( -4.1862341e+02, 1.9519764e+02, -2.4571211e+02); + expectedForces[315] = Vec3( -1.4176845e+02, -3.3767798e+01, 1.7800248e+02); + expectedForces[316] = Vec3( -4.7411046e+01, 2.3841278e+01, -1.5183689e+01); + expectedForces[317] = Vec3( 1.6723204e+01, 1.4145797e+02, -1.6930384e+01); + expectedForces[318] = Vec3( -8.4841167e+02, -2.1282818e+02, 8.1614626e+01); + expectedForces[319] = Vec3( 6.5941519e+00, -1.1472179e+02, -2.3181002e+02); + expectedForces[320] = Vec3( 2.2464095e+01, -5.7606215e+00, 5.2865780e+00); + expectedForces[321] = Vec3( 3.8063827e+02, 2.4597014e+02, -4.1947008e+01); + expectedForces[322] = Vec3( -3.1531672e+02, 3.5038104e+02, -3.2724191e+02); + expectedForces[323] = Vec3( 7.4741163e+01, 7.2296536e+01, 3.1768919e+02); + expectedForces[324] = Vec3( 7.9578966e+02, -1.5345175e+02, -7.1301288e+02); + expectedForces[325] = Vec3( -3.1387318e+01, 1.7528515e+01, -3.4100670e+01); + expectedForces[326] = Vec3( 9.3853572e-01, 6.8496077e+00, 1.2234894e+01); + expectedForces[327] = Vec3( -1.3099690e+02, -4.0135958e+02, -4.3248135e+02); + expectedForces[328] = Vec3( 4.3988113e+02, -1.5944416e+02, 5.4620163e+01); + expectedForces[329] = Vec3( 1.3509243e+01, 3.6990268e+00, -2.6251838e-01); + expectedForces[330] = Vec3( -8.7459998e+01, -6.4319025e+02, 2.2863360e+02); + expectedForces[331] = Vec3( -3.5181606e+02, 3.1131978e+02, 2.8037788e+02); + expectedForces[332] = Vec3( 1.9545884e+02, 4.3994512e+01, -2.5158598e+02); + expectedForces[333] = Vec3( 1.8100917e+00, 1.9534738e+02, 1.7181161e+02); + expectedForces[334] = Vec3( -1.1846876e+02, 1.5368782e+02, 2.2261016e+02); + expectedForces[335] = Vec3( 1.4866155e+02, -4.7983795e+02, 3.0361323e+02); + expectedForces[336] = Vec3( -7.7242468e+02, 2.0736079e+02, -8.6661236e+02); + expectedForces[337] = Vec3( -7.9875679e+00, -9.0946585e+02, -7.1617627e+01); + expectedForces[338] = Vec3( 2.2543457e+02, 2.0215639e+02, 4.4285374e+02); + expectedForces[339] = Vec3( -2.6252013e+02, -1.0336519e+02, -2.6630451e+02); + expectedForces[340] = Vec3( 5.0907589e+02, -1.2491931e+02, -4.3015857e+01); + expectedForces[341] = Vec3( -6.0362692e+01, 1.0025664e+02, -9.3389235e+01); + expectedForces[342] = Vec3( 5.8779874e+02, 3.7600030e+02, 2.5345454e+02); + expectedForces[343] = Vec3( -1.3661048e+02, 1.6498482e+02, -2.6789925e+01); + expectedForces[344] = Vec3( 4.9840419e+01, -1.2136315e+02, 2.5455320e+01); + expectedForces[345] = Vec3( 2.3324807e+02, -3.6601512e+02, 5.6798114e+01); + expectedForces[346] = Vec3( 5.5853546e+01, -4.9035168e+00, -5.8726331e+02); + expectedForces[347] = Vec3( -3.8918158e+01, 3.0380495e+02, 1.0944883e+01); + expectedForces[348] = Vec3( -2.6092065e+02, 4.3443036e+02, -1.3673862e+02); + expectedForces[349] = Vec3( 1.5195166e+02, 1.1879426e+01, -1.1429493e+02); + expectedForces[350] = Vec3( -8.5687107e+02, -1.7938881e+02, 4.5576455e+00); + expectedForces[351] = Vec3( -1.0117388e+03, -3.2686610e+02, 2.9733049e+02); + expectedForces[352] = Vec3( -2.3946369e+02, 4.9753786e+02, 7.2681440e+02); + expectedForces[353] = Vec3( 3.9085837e+01, 7.4391931e+00, 3.4179196e+00); + expectedForces[354] = Vec3( 1.0462977e+03, 4.3639578e+02, -5.7349371e+02); + expectedForces[355] = Vec3( 1.2715333e+02, -5.7907885e+02, 5.7463165e+02); + expectedForces[356] = Vec3( -1.5968981e+02, 2.2295605e+01, 6.3554487e+01); + expectedForces[357] = Vec3( -1.9666111e+02, -2.0286725e+02, -8.3590992e+01); + expectedForces[358] = Vec3( 5.9985006e+00, 2.9764307e+01, 3.1304672e+01); + expectedForces[359] = Vec3( 1.0409792e+02, 4.3974987e+02, -9.1530162e+02); + expectedForces[360] = Vec3( 2.9538724e+02, 1.4353710e+02, 2.1558768e+02); + expectedForces[361] = Vec3( -3.7974445e+02, -9.0749144e+01, 1.4531502e+02); + expectedForces[362] = Vec3( 3.7089093e+02, 2.2523397e+02, -2.9760698e+02); + expectedForces[363] = Vec3( -7.6884906e+01, -2.7486958e+02, 3.5671043e+02); + expectedForces[364] = Vec3( 4.3400097e+02, 2.2275226e+02, 5.9201087e+01); + expectedForces[365] = Vec3( 2.1177620e+02, -6.4990517e+02, -1.8431623e+02); + expectedForces[366] = Vec3( -8.2234148e+01, 4.9900036e+02, 3.0906858e+02); + expectedForces[367] = Vec3( -1.4784097e+02, 1.3442463e+02, -2.6811487e+02); + expectedForces[368] = Vec3( 2.2289541e+02, -4.1933983e+02, 1.3646246e+01); + expectedForces[369] = Vec3( -2.1199481e+02, 6.2103281e+01, 1.6049768e+02); + expectedForces[370] = Vec3( -2.9429845e+01, -1.3944740e+01, 1.6000003e+01); + expectedForces[371] = Vec3( -1.5093250e+02, -1.9541345e+02, -1.5879844e+02); + expectedForces[372] = Vec3( 2.2218133e+02, 7.5740668e+01, -7.0754853e+02); + expectedForces[373] = Vec3( -4.7529615e+02, -3.5259490e+02, 3.8025744e+02); + expectedForces[374] = Vec3( 4.9308495e+01, 1.2206152e+02, 4.2704595e+01); + expectedForces[375] = Vec3( -3.6408113e+02, 9.5905960e+02, 3.3861668e+02); + expectedForces[376] = Vec3( 1.5324093e+02, -1.4375341e+02, -9.1369900e+01); + expectedForces[377] = Vec3( -3.5343609e+02, -4.4662438e+02, 3.1741831e+02); + expectedForces[378] = Vec3( -8.2721281e+02, -6.4969313e+01, 4.1869320e+02); + expectedForces[379] = Vec3( -8.7419096e+00, -4.6278343e+01, -3.0259942e+01); + expectedForces[380] = Vec3( 1.6814871e+01, 4.5462601e+01, -3.5204538e+01); + expectedForces[381] = Vec3( 1.9043143e+02, 5.1101135e+02, 2.9970918e+02); + expectedForces[382] = Vec3( -4.3547560e+02, -7.7495770e+01, -8.2311440e+01); + expectedForces[383] = Vec3( 1.3206505e+02, 4.0993476e+01, 1.5150623e+01); + expectedForces[384] = Vec3( 4.6163268e+01, -2.7722119e+01, -2.2996255e+02); + expectedForces[385] = Vec3( -4.7033552e+01, 1.5721545e+02, -9.2562636e+01); + expectedForces[386] = Vec3( -2.4164903e+02, -1.4771464e+02, -5.1675638e+01); + expectedForces[387] = Vec3( 1.3445564e+03, 3.5387081e+02, -3.7402713e+02); + expectedForces[388] = Vec3( -2.6290280e+02, 2.5025510e+02, 3.0570707e+01); + expectedForces[389] = Vec3( -4.4624214e+02, -2.4919412e+02, 1.1336564e+03); + expectedForces[390] = Vec3( 3.1188483e+02, 6.4836125e+02, 4.5477683e+01); + expectedForces[391] = Vec3( 2.5570674e+02, -2.7101115e+02, -1.2579817e+02); + expectedForces[392] = Vec3( -3.4941759e+02, -3.2508734e+01, -5.6131515e+01); + expectedForces[393] = Vec3( -1.2734301e+02, -2.0417657e+02, 5.7738004e+02); + expectedForces[394] = Vec3( 5.0435795e+01, -9.5203527e+01, -4.1237509e+00); + expectedForces[395] = Vec3( -6.8258463e+01, 1.7475914e+02, -1.6422294e+02); + expectedForces[396] = Vec3( 2.6455575e+02, 2.6880230e+02, -1.6607620e+01); + expectedForces[397] = Vec3( -3.5968167e+02, 6.6092937e+01, 1.5915445e+02); + expectedForces[398] = Vec3( 8.4092494e-01, -5.9896731e+01, -2.1856007e+01); + expectedForces[399] = Vec3( -1.9237984e+02, -1.6506355e+02, 1.3370845e+02); + expectedForces[400] = Vec3( 4.7023043e+02, 1.2931257e+02, -1.7013618e+02); + expectedForces[401] = Vec3( 9.4928843e+01, -3.1613892e+02, -4.6973091e+02); + expectedForces[402] = Vec3( -2.9180818e+02, 6.5496755e+02, -2.9430870e+02); + expectedForces[403] = Vec3( 1.6670668e+02, -2.4693913e+02, -8.8775735e+01); + expectedForces[404] = Vec3( -1.4218604e+02, 2.3173349e+02, 3.9869740e+02); + expectedForces[405] = Vec3( 4.3469431e+02, -2.4686568e+02, -2.6838523e+02); + expectedForces[406] = Vec3( 1.0671130e+02, 3.9710106e+02, 2.6478100e+02); + expectedForces[407] = Vec3( -4.4281099e+02, -3.2746126e+01, -2.0719929e+02); + expectedForces[408] = Vec3( 1.1864952e+01, -1.5901568e+02, 1.1865945e+01); + expectedForces[409] = Vec3( -6.0546863e+01, -1.3488005e+02, -2.9223986e+02); + expectedForces[410] = Vec3( 2.5845942e+01, 1.7545933e+02, -1.4590654e+02); + expectedForces[411] = Vec3( -3.0776460e+02, 2.7351986e+02, -2.0386483e+02); + expectedForces[412] = Vec3( 1.7301558e+02, 8.3012339e+01, 7.6018513e+02); + expectedForces[413] = Vec3( 1.2893147e+02, -3.9937475e+00, 1.4197628e+01); + expectedForces[414] = Vec3( -3.9803615e+02, -4.4825663e+02, 2.8616211e+01); + expectedForces[415] = Vec3( -2.3586809e+02, -8.9306136e+01, 7.5265669e+02); + expectedForces[416] = Vec3( 8.3814512e+02, -9.5563706e+00, 2.8738759e+02); + expectedForces[417] = Vec3( -3.8269399e+02, -2.3650170e+02, 1.7330415e+01); + expectedForces[418] = Vec3( 7.2310675e+00, 2.4731653e+01, 1.9491126e+01); + expectedForces[419] = Vec3( 8.4485111e+01, 9.0560261e+01, -1.4261777e+01); + expectedForces[420] = Vec3( 2.1829925e+02, -8.3951651e+01, -7.8910117e+02); + expectedForces[421] = Vec3( -2.4228018e+02, -5.7097512e+01, 2.6447829e+02); + expectedForces[422] = Vec3( 6.9666665e+01, -4.7313678e+02, 4.5559673e+02); + expectedForces[423] = Vec3( 1.0108369e+02, 4.6568610e+02, 2.5612541e+02); + expectedForces[424] = Vec3( 7.2334238e+01, -1.5660040e+02, -2.6278686e+02); + expectedForces[425] = Vec3( 1.0749954e+03, 2.4395658e+02, -8.7308262e+01); + expectedForces[426] = Vec3( 5.4983082e+02, 5.6528577e+02, -3.0489991e+02); + expectedForces[427] = Vec3( -2.1210132e+02, -1.5871954e+02, -1.6936452e+02); + expectedForces[428] = Vec3( -9.5473983e+01, 7.4879276e+01, 5.5720204e+01); + expectedForces[429] = Vec3( 5.6417182e+02, -1.3478250e+02, -4.8006673e+01); + expectedForces[430] = Vec3( -1.0055266e+02, -8.3811289e+01, 6.5259748e+01); + expectedForces[431] = Vec3( 3.0553989e+01, 4.0927300e+02, 6.2242246e+02); + expectedForces[432] = Vec3( -6.0956353e+02, 9.0301312e+02, -1.4063582e+01); + expectedForces[433] = Vec3( 3.2774559e+02, -1.0849473e+02, -8.8877712e+01); + expectedForces[434] = Vec3( 2.1371643e+02, -7.2067980e+01, 2.4803863e+02); + expectedForces[435] = Vec3( -9.0636479e+01, 1.0673514e+03, 1.3005625e+02); + expectedForces[436] = Vec3( -3.5058624e+02, -1.4968284e+02, 1.4340635e+02); + expectedForces[437] = Vec3( 3.4640813e+01, -4.8035225e+01, 4.4066226e+01); + expectedForces[438] = Vec3( -2.3414523e+02, -9.1359130e+01, 2.8535427e+02); + expectedForces[439] = Vec3( -2.7156547e+02, -6.3426763e+01, 1.6968017e+01); + expectedForces[440] = Vec3( -2.8751166e+00, 4.3192169e+00, -2.1401359e+00); + expectedForces[441] = Vec3( -2.0241419e+01, 4.2856138e+02, 7.3204868e+01); + expectedForces[442] = Vec3( -4.2166169e+01, -2.2454013e+01, -5.4998450e+01); + expectedForces[443] = Vec3( 2.6442026e+02, -1.1670567e+02, 2.8879291e+02); + expectedForces[444] = Vec3( -4.9762729e+02, 4.7320314e+02, 3.2506251e+02); + expectedForces[445] = Vec3( -3.0994232e+02, 3.6728867e+02, -6.8793662e+02); + expectedForces[446] = Vec3( -5.6328374e+00, -2.3284824e+00, 1.9650486e+01); + expectedForces[447] = Vec3( 4.0145354e+02, 7.0143762e+02, 1.3039041e+02); + expectedForces[448] = Vec3( 1.3270713e+02, -3.3050447e+02, 2.8630784e+02); + expectedForces[449] = Vec3( -3.8904836e+02, -4.6125118e+01, -3.8815388e+02); + expectedForces[450] = Vec3( 4.6293066e+02, -2.4970158e+02, -5.7231818e+01); + expectedForces[451] = Vec3( -4.7707142e+00, 1.7120822e-01, 4.5081299e+00); + expectedForces[452] = Vec3( 3.5968818e+01, -1.1892248e+01, 1.2184792e+02); + expectedForces[453] = Vec3( 4.4939172e+02, 4.8377647e+02, 3.0529778e+02); + expectedForces[454] = Vec3( -2.9071570e+02, -9.0611613e+01, -2.5190431e+02); + expectedForces[455] = Vec3( -1.4344537e+02, -1.3061997e+03, 3.8343947e+02); + expectedForces[456] = Vec3( 4.1580940e+02, -3.6864043e+02, 6.6384066e+02); + expectedForces[457] = Vec3( -3.4869949e+02, 3.3262427e+02, -8.3156358e+01); + expectedForces[458] = Vec3( -5.8565457e+00, -5.1879987e+02, -7.2717213e+02); + expectedForces[459] = Vec3( -1.0514593e+02, -2.6844396e+02, 3.0849659e+02); + expectedForces[460] = Vec3( -1.2562153e+02, 6.5438031e+01, -2.3521687e+02); + expectedForces[461] = Vec3( 8.3330016e+02, -6.7961048e+02, -7.2442064e+02); + expectedForces[462] = Vec3( -1.3328298e+02, 1.6143544e+02, -3.2000493e+02); + expectedForces[463] = Vec3( -1.1035002e+02, -8.6040775e+01, 2.0953986e+02); + expectedForces[464] = Vec3( -2.7702219e+02, -1.2156319e+02, -3.8897654e+02); + expectedForces[465] = Vec3( 3.6277432e+02, -7.0422679e+02, -8.2487472e+02); + expectedForces[466] = Vec3( -2.3947587e+02, -4.3625964e+00, 4.8716989e+01); + expectedForces[467] = Vec3( -2.6210552e+02, 9.9730213e+01, -2.4465307e+02); + expectedForces[468] = Vec3( -4.1344138e+01, -3.8636310e+01, -1.0720610e+01); + expectedForces[469] = Vec3( 2.3928584e+01, -1.3030908e+01, -1.7631168e+01); + expectedForces[470] = Vec3( -1.1873594e+02, -3.3905287e+00, -8.4575994e+01); + expectedForces[471] = Vec3( 4.3384846e+02, -4.8660929e+02, -2.4015737e+02); + expectedForces[472] = Vec3( 3.8974922e+01, 2.4401913e+02, -1.2060132e+02); + expectedForces[473] = Vec3( -4.2239647e+02, -8.6924630e+01, 5.7884013e+02); + expectedForces[474] = Vec3( 1.7222431e+02, -1.9292167e+01, 4.4184770e+01); + expectedForces[475] = Vec3( -4.8871102e+01, 1.8185057e+02, -1.3144294e+02); + expectedForces[476] = Vec3( -1.1467881e+02, -1.8387284e+02, -2.6935761e+01); + expectedForces[477] = Vec3( 4.4415601e+02, -8.6415426e+02, -2.2765803e+02); + expectedForces[478] = Vec3( 2.0893474e+02, 1.3529112e+02, 2.4108004e+02); + expectedForces[479] = Vec3( -1.2802570e+01, -4.7089261e+00, -7.0024810e+00); + expectedForces[480] = Vec3( -1.0878354e+02, 4.5030357e+02, -3.9086153e+02); + expectedForces[481] = Vec3( -3.7659745e+01, -4.9295745e+01, -6.0028516e+01); + expectedForces[482] = Vec3( 1.8851809e+02, -1.6863914e+02, 1.2031505e+02); + expectedForces[483] = Vec3( 2.2040686e+02, -1.1953187e+03, 2.9106238e+02); + expectedForces[484] = Vec3( -1.1642847e+01, 5.6739977e+01, 3.7532413e+00); + expectedForces[485] = Vec3( 3.5013234e+00, 2.8236323e+01, -1.1738866e+01); + expectedForces[486] = Vec3( -2.0051506e+03, -5.3138994e+02, 4.0428126e+02); + expectedForces[487] = Vec3( 1.6887843e+02, 1.1687735e+02, -9.6232177e+01); + expectedForces[488] = Vec3( 2.5030722e+02, -3.6662537e+02, -5.8595505e+01); + expectedForces[489] = Vec3( -1.5924273e+01, -2.1761920e+02, -3.4885425e+01); + expectedForces[490] = Vec3( 1.0423157e+02, 4.0767827e+01, 1.4036192e+02); + expectedForces[491] = Vec3( 5.0090776e+02, -5.0455702e+01, -4.2524815e+02); + expectedForces[492] = Vec3( 3.8037844e+02, 5.7460724e+02, 2.1243310e+02); + expectedForces[493] = Vec3( -1.1487653e+02, 3.3550952e+01, -5.7050397e+01); + expectedForces[494] = Vec3( 1.8425697e+02, -2.7223857e+02, -2.9384020e+01); + expectedForces[495] = Vec3( -1.1115514e+02, -4.4519957e+02, -3.3628896e+02); + expectedForces[496] = Vec3( 3.8865823e+02, -2.1372852e+02, -7.8979988e+02); + expectedForces[497] = Vec3( -3.1740258e+02, 4.4824683e+02, -5.0382680e+02); + expectedForces[498] = Vec3( 1.5521684e+02, -1.5278429e+02, -1.8418006e+02); + expectedForces[499] = Vec3( -2.2213191e+01, 7.1015095e+00, 1.0308820e+01); + expectedForces[500] = Vec3( 3.0011560e+01, 2.4584541e+02, -5.3231694e+02); + expectedForces[501] = Vec3( -8.4865171e+02, -2.0279022e+02, -6.8435095e+02); + expectedForces[502] = Vec3( 7.0477549e+00, 2.7626774e+01, -1.6246047e+01); + expectedForces[503] = Vec3( -7.1309648e+01, -1.6054218e+02, -3.1621746e+01); + expectedForces[504] = Vec3( 3.6317856e+02, 1.9055487e+02, 3.9196046e+01); + expectedForces[505] = Vec3( 1.4643265e+02, -1.2295335e+03, -2.2268806e+01); + expectedForces[506] = Vec3( -3.6638240e+02, -6.5310612e+00, -6.8077013e+02); + expectedForces[507] = Vec3( 1.9107813e+02, -6.2176534e+02, 5.1826941e+02); + expectedForces[508] = Vec3( 1.7226933e+02, -3.8939126e+02, -7.4174355e+02); + expectedForces[509] = Vec3( 1.3541890e+02, 4.1350561e+02, -2.6155396e+02); + expectedForces[510] = Vec3( 1.6452609e+02, -4.1963597e+02, 1.6322800e+02); + expectedForces[511] = Vec3( 9.1248387e+01, -1.3380408e+01, -5.1326806e+02); + expectedForces[512] = Vec3( 1.2420564e+02, 8.9492432e+02, 2.8660661e+02); + expectedForces[513] = Vec3( 4.5609859e+02, 3.4252036e+01, -2.3830457e+02); + expectedForces[514] = Vec3( -8.8282131e+01, -1.4512876e+02, -4.5703642e+01); + expectedForces[515] = Vec3( -6.9194714e+01, 5.5053415e+02, -3.9527911e+02); + expectedForces[516] = Vec3( -1.5570798e+02, 4.1650792e-02, 3.0224667e+02); + expectedForces[517] = Vec3( 9.2007640e+01, 3.6378499e+02, -2.2069415e+01); + expectedForces[518] = Vec3( 2.7996922e+02, -2.0932322e+02, 6.2987796e+01); + expectedForces[519] = Vec3( -7.4985282e+01, 1.3508916e+02, 1.1453750e+02); + expectedForces[520] = Vec3( 1.2149786e+01, 4.2161047e+02, -2.9521571e+02); + expectedForces[521] = Vec3( 1.9419524e+01, -8.6619683e+01, -9.4040609e+01); + expectedForces[522] = Vec3( 3.5495800e+01, 6.4028894e+01, 1.2320699e+02); + expectedForces[523] = Vec3( -5.6501302e+02, -1.2497462e+02, 8.1633096e+02); + expectedForces[524] = Vec3( -3.1775230e+02, 1.6467221e+02, -4.8242287e+01); + expectedForces[525] = Vec3( -1.8325245e+02, -1.0751941e+02, 6.2172117e+02); + expectedForces[526] = Vec3( 1.8164299e+00, 8.0654784e-01, -1.4484741e+01); + expectedForces[527] = Vec3( 2.6686986e+00, 1.5933475e+01, -6.8843007e+01); + expectedForces[528] = Vec3( -1.3208642e+02, -1.2281791e+02, 7.8417959e+01); + expectedForces[529] = Vec3( -4.8078193e+01, -1.5140963e+02, 8.3605002e+01); + expectedForces[530] = Vec3( 8.5925332e+01, 1.9959621e+01, -5.9034655e+01); + expectedForces[531] = Vec3( -3.1311626e+00, -3.4009931e+01, -1.5895685e+02); + expectedForces[532] = Vec3( -9.9694666e+01, 1.0296874e+00, 1.0482739e+02); + expectedForces[533] = Vec3( 2.8954747e+02, 1.2018666e+02, 2.2155006e+02); + expectedForces[534] = Vec3( 3.2588176e+02, 3.6622498e+01, 3.5801460e+02); + expectedForces[535] = Vec3( -6.5985617e+01, -3.5501709e+02, 6.8149810e+01); + expectedForces[536] = Vec3( -4.7632753e+02, 2.7936656e+02, 1.5548558e+02); + expectedForces[537] = Vec3( 4.7724904e+02, 2.1647106e+02, 1.2003317e+02); + expectedForces[538] = Vec3( -1.6225405e+02, 1.4264998e+02, -1.0113321e+02); + expectedForces[539] = Vec3( -3.2540487e+01, -7.5643223e+01, 1.6054148e+01); + expectedForces[540] = Vec3( 4.3311991e+02, 5.8082595e+02, 1.9354276e+02); + expectedForces[541] = Vec3( -3.4924430e+02, -7.0056069e+01, 1.0274560e+02); + expectedForces[542] = Vec3( 1.9441645e+02, -2.0017354e+02, -2.3280717e+02); + expectedForces[543] = Vec3( -4.1530380e+01, -5.6394351e+02, 2.4472509e+02); + expectedForces[544] = Vec3( -1.6193396e+01, -8.0431396e+01, -2.9094018e+02); + expectedForces[545] = Vec3( -1.9414773e+01, 4.6180982e+01, 3.3123072e+01); + expectedForces[546] = Vec3( -3.9314039e+02, -3.9874866e+02, 4.5308571e+02); + expectedForces[547] = Vec3( -7.1897482e+01, -1.1940445e+02, -2.7405931e+02); + expectedForces[548] = Vec3( 3.0646396e+02, 6.1235747e+01, -1.5253270e+02); + expectedForces[549] = Vec3( -3.2480464e+02, 4.3056561e+02, 3.2532485e+01); + expectedForces[550] = Vec3( 1.2818655e+02, 7.4294994e-01, -5.7650521e+00); + expectedForces[551] = Vec3( -1.7481437e+02, -2.6203225e+02, -9.6793481e+01); + expectedForces[552] = Vec3( 1.9259110e+02, 3.0171883e+02, 5.2403235e+02); + expectedForces[553] = Vec3( -7.8132123e+01, -7.6569340e+00, -1.1140240e+02); + expectedForces[554] = Vec3( -5.2504673e+02, -4.3700574e+02, 4.3321261e+02); + expectedForces[555] = Vec3( -9.9785283e+02, 2.7139143e+02, -4.1723547e+02); + expectedForces[556] = Vec3( 2.7115933e+02, -8.7444541e+01, 1.0745103e+02); + expectedForces[557] = Vec3( 1.4348018e+02, 1.4013343e+02, -4.0305733e+02); + expectedForces[558] = Vec3( 4.9491010e+02, 4.3040089e+02, -3.5558583e+02); + expectedForces[559] = Vec3( -1.8510736e+02, 6.7129731e+01, -2.1324364e+02); + expectedForces[560] = Vec3( 8.4478090e+01, 4.0986269e+01, 4.1401094e+02); + expectedForces[561] = Vec3( 4.4188419e+01, -8.6520108e+02, 6.8555821e+02); + expectedForces[562] = Vec3( -4.5036974e+02, 2.2379481e+02, 6.2457971e+01); + expectedForces[563] = Vec3( 2.4325836e+02, 6.9725116e+01, 3.6266296e+01); + expectedForces[564] = Vec3( 1.5611925e+02, -2.4471023e+02, 4.7857332e+02); + expectedForces[565] = Vec3( -3.5692822e+02, -2.7248961e+02, -1.8165146e+02); + expectedForces[566] = Vec3( 4.3093388e+02, 1.6944839e+02, -4.4177741e+02); + expectedForces[567] = Vec3( 5.2118711e+02, -1.5252783e+02, -1.6964047e+02); + expectedForces[568] = Vec3( 1.3899083e+03, 3.8363654e+02, -6.4623177e+02); + expectedForces[569] = Vec3( -1.4984858e+02, 4.5097170e+01, -5.0257768e+01); + expectedForces[570] = Vec3( -8.1979709e+01, -4.1632909e+01, -5.1367825e+02); + expectedForces[571] = Vec3( -7.8645235e+00, 1.8105470e+01, 9.2902759e+01); + expectedForces[572] = Vec3( 1.2725548e+02, 1.3926229e+02, -4.3752260e+01); + expectedForces[573] = Vec3( -2.7817289e+01, -8.0900345e+01, -4.3178498e+02); + expectedForces[574] = Vec3( 2.2115263e+02, -7.8807799e+01, 8.8367391e+01); + expectedForces[575] = Vec3( -1.2756938e+02, 4.2170937e+02, -6.8418245e+01); + expectedForces[576] = Vec3( 8.8370341e+01, -1.4671130e+02, -5.6211071e+02); + expectedForces[577] = Vec3( 6.7701453e+02, 2.1228010e+02, 2.3047236e+02); + expectedForces[578] = Vec3( -1.2694819e+02, -7.2734890e+00, 1.1007893e+02); + expectedForces[579] = Vec3( -6.8945756e+02, 1.7359485e+02, -2.5607776e+02); + expectedForces[580] = Vec3( 6.7323923e+00, 3.1574487e+02, 5.9741152e+02); + expectedForces[581] = Vec3( 2.1214031e+02, -4.7565197e+01, -9.6896159e+01); + expectedForces[582] = Vec3( -3.4876562e+02, 5.8335489e+01, -1.7058451e+02); + expectedForces[583] = Vec3( -1.6516914e+02, -3.8913162e+02, 5.8832025e+02); + expectedForces[584] = Vec3( 4.7753612e+01, -6.6792213e+01, -4.6492749e+01); + expectedForces[585] = Vec3( -4.7166578e+02, 7.1811831e+02, 7.0620222e+02); + expectedForces[586] = Vec3( -3.0570577e+02, -1.7681907e+02, -2.1227370e+02); + expectedForces[587] = Vec3( 1.8122997e+02, -6.8318737e+01, -3.4853368e+02); + expectedForces[588] = Vec3( 7.5752093e+01, 3.9702196e+02, -9.0196404e+02); + expectedForces[589] = Vec3( 5.1185528e+02, -7.7747186e+02, -3.3969581e+02); + expectedForces[590] = Vec3( -3.1187606e+01, 5.9593198e+01, 7.7918649e+01); + expectedForces[591] = Vec3( 2.2741676e+02, 2.1705631e+02, 3.9920149e+02); + expectedForces[592] = Vec3( 7.0516894e+01, 3.3389665e+02, -6.8443760e+00); + expectedForces[593] = Vec3( -9.9645406e+02, 2.8574127e+02, -8.0946834e+02); + expectedForces[594] = Vec3( 1.0930460e+02, 1.5869363e+03, -4.0704089e+02); + expectedForces[595] = Vec3( -3.0341438e+02, -5.7494385e+00, 2.9655509e+02); + expectedForces[596] = Vec3( 8.7955203e+01, -7.6811348e+01, -6.9558652e+01); + expectedForces[597] = Vec3( -9.4378353e+01, 3.6253070e+02, 9.0703343e-01); + expectedForces[598] = Vec3( -4.7595525e+01, -6.9148379e+02, -4.6737971e+02); + expectedForces[599] = Vec3( 2.2339987e+02, -2.5503335e+02, 2.8552040e+02); + expectedForces[600] = Vec3( 1.0309072e+02, -2.1298204e+02, -4.3393283e+02); + expectedForces[601] = Vec3( -2.4581477e+02, 2.5126386e+02, -1.8679710e+02); + expectedForces[602] = Vec3( 7.7926618e+00, -2.4947558e+01, 1.5962011e+02); + expectedForces[603] = Vec3( 7.0099476e+02, 5.9496129e+01, 2.0314640e+02); + expectedForces[604] = Vec3( -5.2583810e+01, 3.1237489e+01, -4.0902937e+00); + expectedForces[605] = Vec3( -5.4435871e+01, -7.7056693e+01, -1.5137215e+01); + expectedForces[606] = Vec3( -7.8684074e+02, 8.1673860e+02, 5.0192222e+02); + expectedForces[607] = Vec3( 2.9859285e+02, 1.9661708e+02, -1.9940993e+02); + expectedForces[608] = Vec3( -9.9358476e-01, -3.4789219e+02, 1.7693106e+02); + expectedForces[609] = Vec3( 6.7880927e+02, 7.2768533e+01, 1.1973248e+03); + expectedForces[610] = Vec3( -1.2072838e+00, 1.1770157e+02, -8.6765918e+01); + expectedForces[611] = Vec3( -4.3236695e+02, -2.8583002e+02, 1.3459508e+02); + expectedForces[612] = Vec3( -6.1894609e+01, 4.4705141e+02, -2.3264215e+02); + expectedForces[613] = Vec3( -2.6948720e+01, -2.7688230e+01, 4.6300601e+01); + expectedForces[614] = Vec3( 4.3954815e+01, 6.1244278e+01, 1.0727211e+02); + expectedForces[615] = Vec3( -2.2049132e+02, -9.7233594e+01, 8.3807949e+01); + expectedForces[616] = Vec3( 2.8631226e+02, -1.3478640e+02, -5.0675977e+02); + expectedForces[617] = Vec3( -1.1458029e+01, 6.3762007e+01, -4.9643140e+01); + expectedForces[618] = Vec3( 7.7363305e+01, 1.1936816e+02, 3.9692323e+01); + expectedForces[619] = Vec3( -8.4199858e+01, 2.3567494e+02, 7.2885200e+01); + expectedForces[620] = Vec3( -7.4500104e+00, 3.5567340e+00, -2.2676267e+01); + expectedForces[621] = Vec3( -7.9200057e+02, 3.2245192e+01, 1.1829644e+01); + expectedForces[622] = Vec3( 3.9959336e+02, 2.2447865e+02, -3.1413233e+02); + expectedForces[623] = Vec3( 1.5810527e+02, -2.2341997e+02, 2.3388212e+02); + expectedForces[624] = Vec3( -2.9248657e+02, -1.0806250e+03, -6.1268035e+01); + expectedForces[625] = Vec3( 6.5061442e+02, 1.2244756e+02, -1.1976147e+02); + expectedForces[626] = Vec3( -1.7787710e+02, 3.7279354e+02, -3.7911745e+02); + expectedForces[627] = Vec3( 3.7145927e+02, -2.5203732e+02, -2.2889342e+02); + expectedForces[628] = Vec3( 1.9440281e+02, -2.3076142e+02, 7.2945279e+01); + expectedForces[629] = Vec3( -2.3603693e+02, -1.1987203e+02, -1.2000208e+02); + expectedForces[630] = Vec3( -8.4811726e+01, -6.4500846e+02, -5.1257210e+02); + expectedForces[631] = Vec3( -1.6183393e+01, 1.3980655e+01, -2.3189702e+00); + expectedForces[632] = Vec3( 1.3526098e+02, 1.3800365e+02, -9.4360476e+01); + expectedForces[633] = Vec3( 2.0983514e+01, 5.1156494e+02, -4.3526557e+01); + expectedForces[634] = Vec3( -2.8666500e+02, -5.8235691e+02, -8.7425194e+01); + expectedForces[635] = Vec3( -1.7183604e+02, 1.0002944e+01, 6.5855812e+02); + expectedForces[636] = Vec3( -2.1735465e+02, 9.4664675e+02, 8.9132890e+02); + expectedForces[637] = Vec3( 6.3759184e+01, -5.2436201e+02, 1.2455578e+02); + expectedForces[638] = Vec3( 3.2176621e+02, 1.8182348e+02, -4.4863340e+02); + expectedForces[639] = Vec3( -8.4308252e+02, -1.6268681e+02, 5.8113352e+02); + expectedForces[640] = Vec3( 6.1223389e+01, 3.6767423e+02, 5.9071999e+02); + expectedForces[641] = Vec3( 2.2546928e+02, -2.2022805e+02, 8.3027103e+01); + expectedForces[642] = Vec3( -4.0385190e+02, 2.0141033e+02, 2.7296512e+01); + expectedForces[643] = Vec3( 8.4204485e+01, -7.1102294e+01, 5.7642677e+01); + expectedForces[644] = Vec3( 6.1859901e+01, 1.4828523e+02, -2.6764016e+02); + expectedForces[645] = Vec3( -6.7249932e+02, -8.4613525e+01, -3.9792609e+02); + expectedForces[646] = Vec3( 9.9116485e+01, -3.7714583e+01, -5.3966332e+01); + expectedForces[647] = Vec3( 2.0868628e+02, 2.9747206e+02, 3.3931416e+02); // tolerance is higher here due to interpolation used in setting tapering coefficients; // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); // test sigma/epsilon rules for dispersion correction - if( includeVdwDispersionCorrection ){ + if (includeVdwDispersionCorrection) { std::vector sigmaRules; std::vector epsilonRules; std::vector expectedEnergies; - sigmaRules.push_back( "ARITHMETIC" ); - epsilonRules.push_back( "ARITHMETIC" ); - expectedEnergies.push_back( 6.2137988e+03 ); + sigmaRules.push_back("ARITHMETIC"); + epsilonRules.push_back("ARITHMETIC"); + expectedEnergies.push_back(6.2137988e+03); - sigmaRules.push_back( "GEOMETRIC" ); - epsilonRules.push_back( "GEOMETRIC" ); - expectedEnergies.push_back( 3.6358216e+03 ); + sigmaRules.push_back("GEOMETRIC"); + epsilonRules.push_back("GEOMETRIC"); + expectedEnergies.push_back( 3.6358216e+03); - sigmaRules.push_back( "CUBIC-MEAN" ); - epsilonRules.push_back( "HARMONIC" ); - expectedEnergies.push_back( 3.2774624e+03 ); + sigmaRules.push_back("CUBIC-MEAN"); + epsilonRules.push_back("HARMONIC"); + expectedEnergies.push_back(3.2774624e+03); - for( unsigned int ii = 0; ii < sigmaRules.size(); ii++ ){ - setupAndGetForcesEnergyVdwWater( sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log ); + for (unsigned int ii = 0; ii < sigmaRules.size(); ii++) { + setupAndGetForcesEnergyVdwWater(sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log); testName = "testVdwWaterWithDispersionCorrection_" + sigmaRules[ii] + '_' + epsilonRules[ii]; - ASSERT_EQUAL_TOL_MOD( expectedEnergies[ii], energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergies[ii], energy, tolerance, testName); } } @@ -2052,7 +2052,7 @@ void testTriclinic() { } } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaVdwForce running test..." << std::endl; @@ -2060,46 +2060,46 @@ int main( int numberOfArguments, char* argv[] ) { FILE* log = NULL; - testVdw( log ); + testVdw(log); // tests using two ammonia molecules // test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG - testVdwAmmoniaCubicMeanHhg( log ); + testVdwAmmoniaCubicMeanHhg(log); // test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic - testVdwAmmoniaArithmeticArithmetic( log ); + testVdwAmmoniaArithmeticArithmetic(log); // test VDW w/ sigmaRule=Geometric and epsilonRule=Geometric - testVdwAmmoniaGeometricGeometric( log ); + testVdwAmmoniaGeometricGeometric(log); // test VDW w/ sigmaRule=CubicMean and epsilonRule=Harmonic - testVdwAmmoniaCubicMeanHarmonic( log ); + testVdwAmmoniaCubicMeanHarmonic(log); // test w/ cutoff=0.25 nm; single ixn between two particles (0 and 6); force nonzero on // particle 4 due to reduction applied to NH // the distance between 0 and 6 is ~ 0.235 so the ixn is in the tapered region - testVdwTaper( log ); + testVdwTaper(log); // test PBC - testVdwPBC( log ); + testVdwPBC(log); // tests based on box of water int includeVdwDispersionCorrection = 0; - testVdwWater( includeVdwDispersionCorrection, log ); + testVdwWater(includeVdwDispersionCorrection, log); // includes tests for various combinations of sigma/epsilon rules // when computing vdw dispersion correction includeVdwDispersionCorrection = 1; - testVdwWater( includeVdwDispersionCorrection, log ); + testVdwWater(includeVdwDispersionCorrection, log); // test triclinic boxes diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp index 5fd12e486..8cdbbc4d8 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp @@ -55,21 +55,21 @@ extern "C" OPENMM_EXPORT void registerAmoebaReferenceKernelFactories(); const double TOL = 1e-4; -void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, - const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { +void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, + const std::vector& expectedForces, + const std::vector& forces, double tolerance, FILE* log) { // beginning of WcaDispersion setup - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // test Wca dispersion -void testWcaDispersionAmmonia( FILE* log ) { +void testWcaDispersionAmmonia(FILE* log) { std::string testName = "testWcaDispersionAmmonia"; int numberOfParticles = 8; @@ -79,41 +79,41 @@ void testWcaDispersionAmmonia( FILE* log ) { System system; AmoebaWcaDispersionForce* amoebaWcaDispersionForce = new AmoebaWcaDispersionForce();; - amoebaWcaDispersionForce->setEpso( 4.6024000e-01 ); - amoebaWcaDispersionForce->setEpsh( 5.6484000e-02 ); - amoebaWcaDispersionForce->setRmino( 1.7025000e-01 ); - amoebaWcaDispersionForce->setRminh( 1.3275000e-01 ); - amoebaWcaDispersionForce->setDispoff( 2.6000000e-02 ); - amoebaWcaDispersionForce->setAwater( 3.3428000e+01 ); - amoebaWcaDispersionForce->setSlevy( 1.0000000e+00 ); - amoebaWcaDispersionForce->setShctd( 8.1000000e-01 ); + amoebaWcaDispersionForce->setEpso( 4.6024000e-01); + amoebaWcaDispersionForce->setEpsh( 5.6484000e-02); + amoebaWcaDispersionForce->setRmino( 1.7025000e-01); + amoebaWcaDispersionForce->setRminh( 1.3275000e-01); + amoebaWcaDispersionForce->setDispoff(2.6000000e-02); + amoebaWcaDispersionForce->setAwater( 3.3428000e+01); + amoebaWcaDispersionForce->setSlevy( 1.0000000e+00); + amoebaWcaDispersionForce->setShctd( 8.1000000e-01); // addParticle: radius, epsilon - for( unsigned int ii = 0; ii < 2; ii++ ){ - system.addParticle( 1.4007000e+01 ); - amoebaWcaDispersionForce->addParticle( 1.8550000e-01, 4.3932000e-01 ); + for (unsigned int ii = 0; ii < 2; ii++) { + system.addParticle( 1.4007000e+01); + amoebaWcaDispersionForce->addParticle( 1.8550000e-01, 4.3932000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02 ); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); - system.addParticle( 1.0080000e+00 ); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02 ); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); - system.addParticle( 1.0080000e+00 ); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02 ); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); } std::vector positions(numberOfParticles); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); system.addForce(amoebaWcaDispersionForce); ASSERT(!amoebaWcaDispersionForce->usesPeriodicBoundaryConditions()); @@ -122,7 +122,7 @@ void testWcaDispersionAmmonia( FILE* log ) { std::string platformName; platformName = "Reference"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -134,17 +134,17 @@ void testWcaDispersionAmmonia( FILE* log ) { std::vector expectedForces(numberOfParticles); double expectedEnergy = -2.6981209e+01; - expectedForces[0] = Vec3( 4.7839388e+00, -7.3510133e-04, -5.0382764e-01 ); - expectedForces[1] = Vec3( 1.4657758e+00, 1.2431003e+00, -6.7075886e-01 ); - expectedForces[2] = Vec3( 1.4563936e+00, -1.2399917e+00, -6.7443841e-01 ); - expectedForces[3] = Vec3( 2.1116744e+00, -2.7407512e-03, 1.3271245e+00 ); - expectedForces[4] = Vec3( -4.7528440e+00, -1.5148066e-03, 1.2653813e+00 ); - expectedForces[5] = Vec3( -1.1875619e+00, -1.2866678e+00, -3.9109060e-01 ); - expectedForces[6] = Vec3( -2.6885679e+00, -4.3038639e-04, 3.3763583e-02 ); - expectedForces[7] = Vec3( -1.1888087e+00, 1.2889802e+00, -3.8615387e-01 ); + expectedForces[0] = Vec3( 4.7839388e+00, -7.3510133e-04, -5.0382764e-01); + expectedForces[1] = Vec3( 1.4657758e+00, 1.2431003e+00, -6.7075886e-01); + expectedForces[2] = Vec3( 1.4563936e+00, -1.2399917e+00, -6.7443841e-01); + expectedForces[3] = Vec3( 2.1116744e+00, -2.7407512e-03, 1.3271245e+00); + expectedForces[4] = Vec3( -4.7528440e+00, -1.5148066e-03, 1.2653813e+00); + expectedForces[5] = Vec3( -1.1875619e+00, -1.2866678e+00, -3.9109060e-01); + expectedForces[6] = Vec3( -2.6885679e+00, -4.3038639e-04, 3.3763583e-02); + expectedForces[7] = Vec3( -1.1888087e+00, 1.2889802e+00, -3.8615387e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); // Try changing the particle parameters and make sure it's still correct. @@ -172,7 +172,7 @@ void testWcaDispersionAmmonia( FILE* log ) { compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(), state2.getForces(), tolerance, log); } -int main( int numberOfArguments, char* argv[] ) { +int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestCudaAmoebaWcaDispersionForce running test..." << std::endl; @@ -182,7 +182,7 @@ int main( int numberOfArguments, char* argv[] ) { // test Wca dispersion force using two ammonia molecules - testWcaDispersionAmmonia( log ); + testWcaDispersionAmmonia(log); } -- GitLab From c44c956de6fa2c94cb17f7a308c975c029d94f3e Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 20 Feb 2015 17:16:01 -0800 Subject: [PATCH 284/338] Deleted lots of debugging code --- openmmapi/include/openmm/GBVIForce.h | 8 +- openmmapi/src/GBVIForce.cpp | 8 +- openmmapi/src/GBVIForceImpl.cpp | 22 --- .../include/openmm/AmoebaAngleForce.h | 8 +- .../include/openmm/AmoebaBondForce.h | 4 +- .../openmm/AmoebaGeneralizedKirkwoodForce.h | 2 +- .../include/openmm/AmoebaInPlaneAngleForce.h | 8 +- .../internal/AmoebaMultipoleForceImpl.h | 2 +- .../amoeba/openmmapi/src/AmoebaAngleForce.cpp | 8 +- .../amoeba/openmmapi/src/AmoebaBondForce.cpp | 4 +- .../openmmapi/src/AmoebaInPlaneAngleForce.cpp | 8 +- .../openmmapi/src/AmoebaMultipoleForce.cpp | 10 +- .../src/AmoebaMultipoleForceImpl.cpp | 2 +- .../src/AmoebaOutOfPlaneBendForce.cpp | 8 +- .../amoeba/openmmapi/src/AmoebaVdwForce.cpp | 4 +- .../src/AmoebaWcaDispersionForce.cpp | 16 +- .../AmoebaReferenceMultipoleForce.cpp | 29 --- .../AmoebaReferenceMultipoleForce.h | 9 - .../tests/TestReferenceAmoebaAngleForce.cpp | 76 ++------ .../tests/TestReferenceAmoebaBondForce.cpp | 51 ++---- ...eferenceAmoebaGeneralizedKirkwoodForce.cpp | 131 +++----------- .../TestReferenceAmoebaInPlaneAngleForce.cpp | 73 ++------ .../TestReferenceAmoebaMultipoleForce.cpp | 169 +++++------------- ...TestReferenceAmoebaOutOfPlaneBendForce.cpp | 108 ++--------- .../TestReferenceAmoebaPiTorsionForce.cpp | 57 ++---- .../TestReferenceAmoebaStretchBendForce.cpp | 66 ++----- .../tests/TestReferenceAmoebaVdwForce.cpp | 101 ++++------- 27 files changed, 223 insertions(+), 769 deletions(-) diff --git a/openmmapi/include/openmm/GBVIForce.h b/openmmapi/include/openmm/GBVIForce.h index 41a96cd26..ae61363d1 100644 --- a/openmmapi/include/openmm/GBVIForce.h +++ b/openmmapi/include/openmm/GBVIForce.h @@ -157,7 +157,7 @@ public: * * @return number of bonds */ - int getNumBonds( void ) const; + int getNumBonds() const; /** * Get the dielectric constant for the solvent. @@ -208,7 +208,7 @@ public: /** * Get Born radius scaling method */ - BornRadiusScalingMethod getBornRadiusScalingMethod( void ) const; + BornRadiusScalingMethod getBornRadiusScalingMethod() const; /** * Set Born radius scaling method */ @@ -216,7 +216,7 @@ public: /** * Get the lower limit factor used in the quintic spline scaling method (typically 0.5-0.8) */ - double getQuinticLowerLimitFactor( void ) const; + double getQuinticLowerLimitFactor() const; /** * Set the lower limit factor used in the quintic spline scaling method (typically 0.5-0.8) */ @@ -224,7 +224,7 @@ public: /** * Get the upper limit used in the quintic spline scaling method, measured in nm (~5.0) */ - double getQuinticUpperBornRadiusLimit( void ) const; + double getQuinticUpperBornRadiusLimit() const; /** * Set the upper limit used in the quintic spline scaling method, measured in nm (~5.0) */ diff --git a/openmmapi/src/GBVIForce.cpp b/openmmapi/src/GBVIForce.cpp index 6ee9d551b..9401436cc 100644 --- a/openmmapi/src/GBVIForce.cpp +++ b/openmmapi/src/GBVIForce.cpp @@ -77,7 +77,7 @@ void GBVIForce::setCutoffDistance(double distance) { cutoffDistance = distance; } -GBVIForce::BornRadiusScalingMethod GBVIForce::getBornRadiusScalingMethod( void ) const { +GBVIForce::BornRadiusScalingMethod GBVIForce::getBornRadiusScalingMethod() const { return scalingMethod; } @@ -85,7 +85,7 @@ void GBVIForce::setBornRadiusScalingMethod(BornRadiusScalingMethod method) { scalingMethod = method; } -double GBVIForce::getQuinticLowerLimitFactor( void ) const { +double GBVIForce::getQuinticLowerLimitFactor() const { return quinticLowerLimitFactor; } @@ -93,7 +93,7 @@ void GBVIForce::setQuinticLowerLimitFactor(double inputQuinticLowerLimitFactor ) quinticLowerLimitFactor = inputQuinticLowerLimitFactor; } -double GBVIForce::getQuinticUpperBornRadiusLimit( void ) const { +double GBVIForce::getQuinticUpperBornRadiusLimit() const { return quinticUpperBornRadiusLimit; } @@ -113,7 +113,7 @@ void GBVIForce::setBondParameters( int index, int particle1, int particle2, doub bonds[index].bondLength = bondLength; } -int GBVIForce::getNumBonds( void ) const { +int GBVIForce::getNumBonds() const { return (int) bonds.size(); } diff --git a/openmmapi/src/GBVIForceImpl.cpp b/openmmapi/src/GBVIForceImpl.cpp index f68a1a2cf..f6ea2c3a0 100644 --- a/openmmapi/src/GBVIForceImpl.cpp +++ b/openmmapi/src/GBVIForceImpl.cpp @@ -145,8 +145,6 @@ int GBVIForceImpl::getBondsFromForces(ContextImpl& context) { } */ -#define GBVIDebug 0 - void GBVIForceImpl::findScaledRadii( int numberOfParticles, const std::vector >& bondIndices, const std::vector & bondLengths, std::vector & scaledRadii) const { @@ -219,26 +217,6 @@ void GBVIForceImpl::findScaledRadii( int numberOfParticles, const std::vector& gridDim return; } -int AmoebaMultipoleForce::getMutualInducedMaxIterations( void ) const { +int AmoebaMultipoleForce::getMutualInducedMaxIterations() const { return mutualInducedMaxIterations; } @@ -111,7 +111,7 @@ void AmoebaMultipoleForce::setMutualInducedMaxIterations( int inputMutualInduced mutualInducedMaxIterations = inputMutualInducedMaxIterations; } -double AmoebaMultipoleForce::getMutualInducedTargetEpsilon( void ) const { +double AmoebaMultipoleForce::getMutualInducedTargetEpsilon() const { return mutualInducedTargetEpsilon; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp index 146501de3..9dcff51ee 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp @@ -138,7 +138,7 @@ std::vector AmoebaMultipoleForceImpl::getKernelNames() { return names; } -const int* AmoebaMultipoleForceImpl::getCovalentDegrees( void ) { +const int* AmoebaMultipoleForceImpl::getCovalentDegrees() { if( !initializedCovalentDegrees ){ initializedCovalentDegrees = true; CovalentDegrees[AmoebaMultipoleForce::Covalent12] = 1; diff --git a/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp index e8697f6b2..46aebf8ea 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp @@ -44,7 +44,7 @@ AmoebaOutOfPlaneBendForce::AmoebaOutOfPlaneBendForce() { } -double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendCubic( void ) const { +double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendCubic() const { return _globalCubicK; } @@ -52,7 +52,7 @@ void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendCubic(double cubicK _globalCubicK = cubicK; } -double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendQuartic( void ) const { +double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendQuartic() const { return _globalQuarticK; } @@ -60,7 +60,7 @@ void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendQuartic(double quar _globalQuarticK = quarticK; } -double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendPentic( void ) const { +double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendPentic() const { return _globalPenticK; } @@ -68,7 +68,7 @@ void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendPentic(double penti _globalPenticK = penticK; } -double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendSextic( void ) const { +double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendSextic() const { return _globalSexticK; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp index b8601cf65..d5c04871f 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp @@ -66,7 +66,7 @@ void AmoebaVdwForce::setSigmaCombiningRule( const std::string& inputSigmaCombini sigmaCombiningRule = inputSigmaCombiningRule; } -const std::string& AmoebaVdwForce::getSigmaCombiningRule( void ) const { +const std::string& AmoebaVdwForce::getSigmaCombiningRule() const { return sigmaCombiningRule; } @@ -74,7 +74,7 @@ void AmoebaVdwForce::setEpsilonCombiningRule( const std::string& inputEpsilonCom epsilonCombiningRule = inputEpsilonCombiningRule; } -const std::string& AmoebaVdwForce::getEpsilonCombiningRule( void ) const { +const std::string& AmoebaVdwForce::getEpsilonCombiningRule() const { return epsilonCombiningRule; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp index 3e69fa41a..fbe36d4d7 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp @@ -63,35 +63,35 @@ void AmoebaWcaDispersionForce::setParticleParameters(int particleIndex, double r parameters[particleIndex].epsilon = epsilon; } -double AmoebaWcaDispersionForce::getEpso( void ) const { +double AmoebaWcaDispersionForce::getEpso() const { return epso; } -double AmoebaWcaDispersionForce::getEpsh( void ) const { +double AmoebaWcaDispersionForce::getEpsh() const { return epsh; } -double AmoebaWcaDispersionForce::getRmino( void ) const { +double AmoebaWcaDispersionForce::getRmino() const { return rmino; } -double AmoebaWcaDispersionForce::getRminh( void ) const { +double AmoebaWcaDispersionForce::getRminh() const { return rminh; } -double AmoebaWcaDispersionForce::getAwater( void ) const { +double AmoebaWcaDispersionForce::getAwater() const { return awater; } -double AmoebaWcaDispersionForce::getShctd( void ) const { +double AmoebaWcaDispersionForce::getShctd() const { return shctd; } -double AmoebaWcaDispersionForce::getDispoff( void ) const { +double AmoebaWcaDispersionForce::getDispoff() const { return dispoff; } -double AmoebaWcaDispersionForce::getSlevy( void ) const { +double AmoebaWcaDispersionForce::getSlevy() const { return slevy; } diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp index 4906a04ca..4fc481e68 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp @@ -33,8 +33,6 @@ using std::vector; using namespace OpenMM; -#undef AMOEBA_DEBUG - AmoebaReferenceMultipoleForce::AmoebaReferenceMultipoleForce() : _nonbondedMethod(NoCutoff), _numParticles(0), @@ -233,33 +231,6 @@ void AmoebaReferenceMultipoleForce::setupScaleMaps(const vector< vector< vector< } } } - - //showScaleMapForParticle(2, stderr); - //showScaleMapForParticle(10, stderr); - - return; -} - -void AmoebaReferenceMultipoleForce::showScaleMapForParticle(unsigned int particleI, FILE* log) const -{ - -#ifdef AMOEBA_DEBUG - (void) fprintf(log, "Scale map particle %5u maxIndex=%u\n", particleI, _maxScaleIndex[particleI]); - - std::string scaleNames[LAST_SCALE_TYPE_INDEX] = { "D", "P", "M" }; - for (unsigned int ii = 0; ii < _scaleMaps[particleI].size(); ii++) { - MapIntRealOpenMM scaleMap = _scaleMaps[particleI][ii]; - (void) fprintf(log, " %s scale ", scaleNames[ii].c_str()); - for (MapIntRealOpenMMCI jj = scaleMap.begin(); jj != scaleMap.end(); jj++) { - //if (jj->first > particleI && jj->second < 1.0) - if (jj->second < 1.0) - (void) fprintf(log, "%4d=%5.2f ", jj->first, jj->second); - } - (void) fprintf(log, "\n"); - } - (void) fprintf(log, "\n"); - (void) fflush(log); -#endif } RealOpenMM AmoebaReferenceMultipoleForce::getMultipoleScaleFactor(unsigned int particleI, unsigned int particleJ, ScaleType scaleType) const diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h index 4616ea491..2c8dd4411 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.h @@ -712,15 +712,6 @@ protected: */ void setupScaleMaps(const std::vector< std::vector< std::vector > >& multipoleAtomCovalentInfo); - /** - * Show scaling factor map - * - * @param particleI index of particle whose scale map is to be shown - * @param log output destination - * - */ - void showScaleMapForParticle(unsigned int particleI, FILE* log) const; - /** * Get multipole scale factor for particleI & particleJ * diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp index 152143e1b..f93af0950 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp @@ -77,7 +77,7 @@ static void crossProductVector3(double* vectorX, double* vectorY, double* vector static void getPrefactorsGivenAngleCosine(double cosine, double idealAngle, double quadraticK, double cubicK, double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm, FILE* log) { + double* dEdR, double* energyTerm) { double angle; if (cosine >= 1.0) { @@ -89,12 +89,6 @@ static void getPrefactorsGivenAngleCosine(double cosine, double idealAngle, doub else { angle = RADIAN*acos(cosine); } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "getPrefactorsGivenAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealAngle); - (void) fflush(log); - } -#endif double deltaIdeal = angle - idealAngle; double deltaIdeal2 = deltaIdeal*deltaIdeal; @@ -122,7 +116,7 @@ static void getPrefactorsGivenAngleCosine(double cosine, double idealAngle, doub } static void computeAmoebaAngleForce(int bondIndex, std::vector& positions, AmoebaAngleForce& AmoebaAngleForce, - std::vector& forces, double* energy, FILE* log) { + std::vector& forces, double* energy) { int particle1, particle2, particle3; double idealAngle; @@ -133,13 +127,6 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions double quarticK = AmoebaAngleForce.getAmoebaGlobalAngleQuartic(); double penticK = AmoebaAngleForce.getAmoebaGlobalAnglePentic(); double sexticK = AmoebaAngleForce.getAmoebaGlobalAngleSextic(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaAngleForce: bond %d [%d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, idealAngle, quadraticK, cubicK, quarticK, penticK, sexticK); - (void) fflush(log); - } -#endif double deltaR[2][3]; double r2_0 = 0.0; @@ -163,17 +150,10 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions double dot = deltaR[0][0]*deltaR[1][0] + deltaR[0][1]*deltaR[1][1] + deltaR[0][2]*deltaR[1][2]; double cosine = dot/sqrt(r2_0*r2_1); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "dot=%10.3e r2_0=%10.3e r2_1=%10.3e\n", dot, r2_0, r2_1); - (void) fflush(log); - } -#endif - double dEdR; double energyTerm; getPrefactorsGivenAngleCosine(cosine, idealAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm, log); + quarticK, penticK, sexticK, &dEdR, &energyTerm); double termA = -dEdR/(r2_0*rp); double termC = dEdR/(r2_1*rp); @@ -203,7 +183,7 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions } static void computeAmoebaAngleForces(Context& context, AmoebaAngleForce& AmoebaAngleForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log) { + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces @@ -219,50 +199,27 @@ static void computeAmoebaAngleForces(Context& context, AmoebaAngleForce& AmoebaA *expectedEnergy = 0.0; for (int ii = 0; ii < AmoebaAngleForce.getNumAngles(); ii++) { - computeAmoebaAngleForce(ii, positions, AmoebaAngleForce, expectedForces, expectedEnergy, log); - } - -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaAngleForces: expected energy=%14.7e\n", *expectedEnergy); - for (unsigned int ii = 0; ii < positions.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); - } - (void) fflush(log); + computeAmoebaAngleForce(ii, positions, AmoebaAngleForce, expectedForces, expectedEnergy); } -#endif - return; - } void compareWithExpectedForceAndEnergy(Context& context, AmoebaAngleForce& AmoebaAngleForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaAngleForces(context, AmoebaAngleForce, expectedForces, &expectedEnergy, log); + computeAmoebaAngleForces(context, AmoebaAngleForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); - } - (void) fflush(log); - } -#endif - for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneAngle(FILE* log) { +void testOneAngle() { System system; int numberOfParticles = 3; @@ -299,7 +256,7 @@ void testOneAngle(FILE* log) { positions[2] = Vec3(0, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle", log); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle"); // Try changing the angle parameters and make sure it's still correct. @@ -307,14 +264,14 @@ void testOneAngle(FILE* log) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle", log); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle", log); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle"); } int main(int numberOfArguments, char* argv[]) { @@ -322,16 +279,7 @@ int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestCudaAmoebaAngleForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - //FILE* log = fopen("AmoebaAngleForce.log", "w");; - FILE* log = NULL; - //FILE* log = stderr; - - testOneAngle(log); -#ifdef AMOEBA_DEBUG - if (log && log != stderr) - (void) fclose(log); -#endif - + testOneAngle(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp index cb9fee6c5..55ce6bf85 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaBondForce.cpp @@ -85,7 +85,7 @@ static void computeAmoebaBondForce(int bondIndex, std::vector& positions, } static void computeAmoebaBondForces(Context& context, AmoebaBondForce& AmoebaBondForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log) { + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces @@ -103,37 +103,16 @@ static void computeAmoebaBondForces(Context& context, AmoebaBondForce& AmoebaBon for (int ii = 0; ii < AmoebaBondForce.getNumBonds(); ii++) { computeAmoebaBondForce(ii, positions, AmoebaBondForce, expectedForces, expectedEnergy); } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaBondForces: expected energy=%15.7e\n", *expectedEnergy); - for (unsigned int ii = 0; ii < positions.size(); ii++) { - (void) fprintf(log, "%6u [%15.7e %15.7e %15.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); - } - (void) fflush(log); - } -#endif - return; - } -void compareWithExpectedForceAndEnergy(Context& context, AmoebaBondForce& AmoebaBondForce, double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaBondForce& AmoebaBondForce, double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaBondForces(context, AmoebaBondForce, expectedForces, &expectedEnergy, NULL); + computeAmoebaBondForces(context, AmoebaBondForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaBondForces: expected energy=%15.7e %15.7e\n", expectedEnergy, state.getPotentialEnergy()); - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%15.7e %15.7e %15.7e] [%15.7e %15.7e %15.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); - } - (void) fflush(log); - } -#endif for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); @@ -141,7 +120,7 @@ void compareWithExpectedForceAndEnergy(Context& context, AmoebaBondForce& Amoeba ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneBond(FILE* log) { +void testOneBond() { System system; @@ -168,10 +147,10 @@ void testOneBond(FILE* log) { positions[1] = Vec3(0, 0, 0); context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testOneBond", log); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testOneBond"); } -void testTwoBond(FILE* log) { +void testTwoBond() { System system; @@ -203,7 +182,7 @@ void testTwoBond(FILE* log) { positions[2] = Vec3(1, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond", log); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond"); // Try changing the bond parameters and make sure it's still correct. @@ -212,14 +191,14 @@ void testTwoBond(FILE* log) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond", log); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaBondForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond", log); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond"); } int main(int numberOfArguments, char* argv[]) { @@ -227,16 +206,8 @@ int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaBondForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - FILE* log = NULL; - //FILE* log = stderr; - - //testOneBond(log); - testTwoBond(log); -#ifdef AMOEBA_DEBUG - if (log && log != stderr) - (void) fclose(log); -#endif - + //testOneBond(); + testTwoBond(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp index 9a981fed8..2fa66f55c 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp @@ -275,7 +275,7 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce system.addForce(amoebaGeneralizedKirkwoodForce); } -static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy, FILE* log) { +static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy) { std::vector positions(context.getSystem().getNumParticles()); positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); @@ -296,7 +296,7 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& // setup for villin static void setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::PolarizationType polarizationType, - int includeCavityTerm, std::vector& forces, double& energy, FILE* log) { + int includeCavityTerm, std::vector& forces, double& energy) { // beginning of Multipole setup @@ -6980,44 +6980,7 @@ static void setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Polariz static void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log) { - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if (log) { - double conversion = 1.0/4.184; - double energyAbsDiff = fabs(expectedEnergy - energy); - double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); - (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff); - if (conversion != 1.0)conversion *= -0.1; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - - double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2]); - - double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); - double absDiff = fabs(norm - expectedNorm); - double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - - (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*absDiff, conversion*relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm); - } - (void) fflush(log); - conversion = 1.0; - (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); - if (conversion != 1.0)conversion = -1.0; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); - } - (void) fflush(log); - } -#endif + const std::vector& forces, double tolerance) { for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); @@ -7029,47 +6992,7 @@ static void compareForcesEnergy(std::string& testName, double expectedEnergy, do static void compareForceNormsEnergy(std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log) { - - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if (log) { - double conversion = 1.0/4.184; - double energyAbsDiff = fabs(expectedEnergy - energy); - double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); - (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff); - if (conversion != 1.0)conversion *= -0.1; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - - double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2]); - - double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); - double absDiff = fabs((norm - expectedNorm)); - double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - - (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, - fabs(conversion)*absDiff, relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], - fabs(conversion)*expectedNorm, fabs(conversion)*norm); - } - (void) fflush(log); - conversion = 1.0; - (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); - if (conversion != 1.0)conversion = -1.0; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); - } - (void) fflush(log); - } -#endif - + const std::vector& forces, double tolerance) { for (unsigned int ii = 0; ii < forces.size(); ii++) { double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + expectedForces[ii][1]*expectedForces[ii][1] + @@ -7098,7 +7021,7 @@ static void compareForceNormsEnergy(std::string& testName, double expectedEnergy // test GK direct polarization for system comprised of two ammonia molecules -static void testGeneralizedKirkwoodAmmoniaDirectPolarization(FILE* log) { +static void testGeneralizedKirkwoodAmmoniaDirectPolarization() { std::string testName = "testGeneralizedKirkwoodAmmoniaDirectPolarization"; @@ -7111,7 +7034,7 @@ static void testGeneralizedKirkwoodAmmoniaDirectPolarization(FILE* log) { setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Direct, 0); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log); + getForcesEnergyMultipoleAmmonia(context, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -7.6636680e+01; @@ -7126,12 +7049,12 @@ static void testGeneralizedKirkwoodAmmoniaDirectPolarization(FILE* log) { expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for system comprised of two ammonia molecules -static void testGeneralizedKirkwoodAmmoniaMutualPolarization(FILE* log) { +static void testGeneralizedKirkwoodAmmoniaMutualPolarization() { std::string testName = "testGeneralizedKirkwoodAmmoniaMutualPolarization"; @@ -7144,7 +7067,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarization(FILE* log) { setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Mutual, 0); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log); + getForcesEnergyMultipoleAmmonia(context, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -7.8018875e+01; @@ -7159,13 +7082,13 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarization(FILE* log) { expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for system comprised of two ammonia molecules // including cavity term -static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(FILE* log) { +static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm() { std::string testName = "testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm"; @@ -7180,7 +7103,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(FILE* ASSERT(!system.usesPeriodicBoundaryConditions()); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("Reference")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log); + getForcesEnergyMultipoleAmmonia(context, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -6.0434582e+01; @@ -7195,7 +7118,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(FILE* expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); // Try changing the particle parameters and make sure it's still correct. @@ -7212,7 +7135,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(FILE* bool exceptionThrown = false; try { // This should throw an exception. - compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); } catch (std::exception ex) { exceptionThrown = true; @@ -7220,12 +7143,12 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(FILE* ASSERT(exceptionThrown); amoebaGeneralizedKirkwoodForce->updateParametersInContext(context); state1 = context.getState(State::Forces | State::Energy); - compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); } // test GK direct polarization for villin system -static void testGeneralizedKirkwoodVillinDirectPolarization(FILE* log) { +static void testGeneralizedKirkwoodVillinDirectPolarization() { std::string testName = "testGeneralizedKirkwoodVillinDirectPolarization"; @@ -7233,7 +7156,7 @@ static void testGeneralizedKirkwoodVillinDirectPolarization(FILE* log) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Direct, 0, forces, energy, log); + setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Direct, 0, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.4281157e+03; @@ -7844,12 +7767,12 @@ static void testGeneralizedKirkwoodVillinDirectPolarization(FILE* log) { } double tolerance = 1.0e-05; - compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for villin system -static void testGeneralizedKirkwoodVillinMutualPolarization(FILE* log) { +static void testGeneralizedKirkwoodVillinMutualPolarization() { std::string testName = "testGeneralizedKirkwoodVillinMutualPolarization"; @@ -7857,7 +7780,7 @@ static void testGeneralizedKirkwoodVillinMutualPolarization(FILE* log) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Mutual, 0, forces, energy, log); + setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Mutual, 0, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.6477811e+03; @@ -8468,7 +8391,7 @@ static void testGeneralizedKirkwoodVillinMutualPolarization(FILE* log) { } double tolerance = 1.0e-05; - compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } int main(int numberOfArguments, char* argv[]) { @@ -8477,16 +8400,14 @@ int main(int numberOfArguments, char* argv[]) { std::cout << "TestReferenceAmoebaGeneralizedKirkwoodForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - FILE* log = NULL; - // test direct and mutual polarization cases and // mutual polarization w/ the cavity term - testGeneralizedKirkwoodAmmoniaMutualPolarization(log); - testGeneralizedKirkwoodAmmoniaDirectPolarization(log); - testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(log); - testGeneralizedKirkwoodVillinDirectPolarization(log); - testGeneralizedKirkwoodVillinMutualPolarization(log); + testGeneralizedKirkwoodAmmoniaMutualPolarization(); + testGeneralizedKirkwoodAmmoniaDirectPolarization(); + testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(); + testGeneralizedKirkwoodVillinDirectPolarization(); + testGeneralizedKirkwoodVillinMutualPolarization(); } catch(const std::exception& e) { diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp index c561efd73..0499ca7e9 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp @@ -79,7 +79,7 @@ static double dotVector3(double* vectorX, double* vectorY) { static void getPrefactorsGivenInPlaneAngleCosine(double cosine, double idealInPlaneAngle, double quadraticK, double cubicK, double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm, FILE* log) { + double* dEdR, double* energyTerm) { double angle; if (cosine >= 1.0) { @@ -91,12 +91,6 @@ static void getPrefactorsGivenInPlaneAngleCosine(double cosine, double idealInPl else { angle = RADIAN*acos(cosine); } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "getPrefactorsGivenInPlaneAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealInPlaneAngle); - (void) fflush(log); - } -#endif double deltaIdeal = angle - idealInPlaneAngle; double deltaIdeal2 = deltaIdeal*deltaIdeal; @@ -124,7 +118,7 @@ static void getPrefactorsGivenInPlaneAngleCosine(double cosine, double idealInPl } static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& positions, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, - std::vector& forces, double* energy, FILE* log) { + std::vector& forces, double* energy) { int particle1, particle2, particle3, particle4; double idealInPlaneAngle; @@ -135,13 +129,6 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po double quarticK = AmoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleQuartic(); double penticK = AmoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAnglePentic(); double sexticK = AmoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleSextic(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaInPlaneAngleForce: bond %d [%d %d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK, cubicK, quarticK, penticK, sexticK); - (void) fflush(log); - } -#endif // T = AD x CD // P = B + T*delta @@ -182,12 +169,6 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po double rAp2 = dotVector3(deltaR[AP], deltaR[AP]); double rCp2 = dotVector3(deltaR[CP], deltaR[CP]); if (rAp2 <= 0.0 && rCp2 <= 0.0) { -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaInPlaneAngleForce: rAp2 or rCp2 <= 0.0\n"); - (void) fflush(log); - } -#endif return; } @@ -205,7 +186,7 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po double dEdR; double energyTerm; getPrefactorsGivenInPlaneAngleCosine(cosine, idealInPlaneAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm, log); + quarticK, penticK, sexticK, &dEdR, &energyTerm); double termA = -dEdR/(rAp2*rm); double termC = dEdR/(rCp2*rm); @@ -281,7 +262,7 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po } static void computeAmoebaInPlaneAngleForces(Context& context, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log) { + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces @@ -297,40 +278,19 @@ static void computeAmoebaInPlaneAngleForces(Context& context, AmoebaInPlaneAngle *expectedEnergy = 0.0; for (int ii = 0; ii < AmoebaInPlaneAngleForce.getNumAngles(); ii++) { - computeAmoebaInPlaneAngleForce(ii, positions, AmoebaInPlaneAngleForce, expectedForces, expectedEnergy, log); + computeAmoebaInPlaneAngleForce(ii, positions, AmoebaInPlaneAngleForce, expectedForces, expectedEnergy); } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e\n", *expectedEnergy); - for (unsigned int ii = 0; ii < positions.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); - } - (void) fflush(log); - } -#endif - return; - } void compareWithExpectedForceAndEnergy(Context& context, AmoebaInPlaneAngleForce& AmoebaInPlaneAngleForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaInPlaneAngleForces(context, AmoebaInPlaneAngleForce, expectedForces, &expectedEnergy, log); + computeAmoebaInPlaneAngleForces(context, AmoebaInPlaneAngleForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); - } - (void) fflush(log); - } -#endif for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); @@ -338,7 +298,7 @@ void compareWithExpectedForceAndEnergy(Context& context, AmoebaInPlaneAngleForce ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneAngle(FILE* log) { +void testOneAngle() { System system; int numberOfParticles = 4; @@ -376,7 +336,7 @@ void testOneAngle(FILE* log) { positions[3] = Vec3(1, 1, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle"); // Try changing the angle parameters and make sure it's still correct. @@ -384,14 +344,14 @@ void testOneAngle(FILE* log) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaInPlaneAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle"); } int main(int numberOfArguments, char* argv[]) { @@ -399,16 +359,7 @@ int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaInPlaneAngleForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - FILE* log = NULL; - //FILE* log = stderr; - //FILE* log = fopen("AmoebaInPlaneAngleForce.log", "w");; - - testOneAngle(NULL); -#ifdef AMOEBA_DEBUG - if (log && log != stderr) - (void) fclose(log); -#endif - + testOneAngle(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp index 9b562d226..aa8c791eb 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp @@ -295,44 +295,7 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& static void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log) { - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if (log) { - double conversion = 1.0/4.184; - double energyAbsDiff = fabs(expectedEnergy - energy); - double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); - (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff); - if (conversion != 1.0)conversion *= -0.1; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - - double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2]); - - double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); - double absDiff = fabs(norm - expectedNorm); - double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - - (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*absDiff, conversion*relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm); - } - (void) fflush(log); - conversion = 1.0; - (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); - if (conversion != 1.0)conversion = -1.0; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); - } - (void) fflush(log); - } -#endif + const std::vector& forces, double tolerance) { for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); @@ -344,46 +307,7 @@ static void compareForcesEnergy(std::string& testName, double expectedEnergy, do static void compareForceNormsEnergy(std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log) { - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if (log) { - double conversion = 1.0/4.184; - double energyAbsDiff = fabs(expectedEnergy - energy); - double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); - (void) fprintf(log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff); - if (conversion != 1.0)conversion *= -0.1; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - - double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2]); - - double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); - double absDiff = fabs((norm - expectedNorm)); - double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - - (void) fprintf(log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, - fabs(conversion)*absDiff, relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], - fabs(conversion)*expectedNorm, fabs(conversion)*norm); - } - (void) fflush(log); - conversion = 1.0; - (void) fprintf(log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); - if (conversion != 1.0)conversion = -1.0; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); - } - (void) fflush(log); - } -#endif - + const std::vector& forces, double tolerance) { for (unsigned int ii = 0; ii < forces.size(); ii++) { double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + expectedForces[ii][1]*expectedForces[ii][1] + @@ -412,7 +336,7 @@ static void compareForceNormsEnergy(std::string& testName, double expectedEnergy // test multipole direct polarization for system comprised of two ammonia molecules; no cutoff -static void testMultipoleAmmoniaDirectPolarization(FILE* log) { +static void testMultipoleAmmoniaDirectPolarization() { std::string testName = "testMultipoleAmmoniaDirectPolarization"; @@ -443,12 +367,12 @@ static void testMultipoleAmmoniaDirectPolarization(FILE* log) { expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test multipole mutual polarization for system comprised of two ammonia molecules; no cutoff -static void testMultipoleAmmoniaMutualPolarization(FILE* log) { +static void testMultipoleAmmoniaMutualPolarization() { std::string testName = "testMultipoleAmmoniaMutualPolarization"; @@ -481,7 +405,7 @@ static void testMultipoleAmmoniaMutualPolarization(FILE* log) { expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); // Try changing the particle parameters and make sure it's still correct. @@ -503,7 +427,7 @@ static void testMultipoleAmmoniaMutualPolarization(FILE* log) { bool exceptionThrown = false; try { // This should throw an exception. - compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); } catch (std::exception ex) { exceptionThrown = true; @@ -511,7 +435,7 @@ static void testMultipoleAmmoniaMutualPolarization(FILE* log) { ASSERT(exceptionThrown); amoebaMultipoleForce->updateParametersInContext(context); state1 = context.getState(State::Forces | State::Energy); - compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); } // setup for box of 4 water molecules -- used to test PME @@ -519,7 +443,7 @@ static void testMultipoleAmmoniaMutualPolarization(FILE* log) { static void setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, AmoebaMultipoleForce::PolarizationType polarizationType, double cutoff, int inputPmeGridDimension, std::vector& forces, - double& energy, FILE* log) { + double& energy) { // beginning of Multipole setup @@ -659,7 +583,7 @@ static void setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::Nonbonde // test multipole direct polarization using PME for box of water -static void testMultipoleWaterPMEDirectPolarization(FILE* log) { +static void testMultipoleWaterPMEDirectPolarization() { std::string testName = "testMultipoleWaterDirectPolarization"; @@ -670,7 +594,7 @@ static void testMultipoleWaterPMEDirectPolarization(FILE* log) { double energy; setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, forces, energy, log); + cutoff, inputPmeGridDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.4585115e-01; @@ -689,12 +613,12 @@ static void testMultipoleWaterPMEDirectPolarization(FILE* log) { expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00); double tolerance = 1.0e-03; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test multipole mutual polarization using PME for box of water -static void testMultipoleWaterPMEMutualPolarization(FILE* log) { +static void testMultipoleWaterPMEMutualPolarization() { std::string testName = "testMultipoleWaterMutualPolarization"; @@ -705,7 +629,7 @@ static void testMultipoleWaterPMEMutualPolarization(FILE* log) { double energy; setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, forces, energy, log); + cutoff, inputPmeGridDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.5029855e-01; @@ -724,12 +648,12 @@ static void testMultipoleWaterPMEMutualPolarization(FILE* log) { expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00); double tolerance = 1.0e-03; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // check validation of traceless/symmetric quadrupole tensor -static void testQuadrupoleValidation(FILE* log) { +static void testQuadrupoleValidation() { std::string testName = "checkQuadrupoleValidation"; @@ -905,7 +829,7 @@ static void testQuadrupoleValidation(FILE* log) { static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, AmoebaMultipoleForce::PolarizationType polarizationType, double cutoff, int inputPmeGridDimension, std::string testName, - std::vector& forces, double& energy, FILE* log) { + std::vector& forces, double& energy) { // beginning of Multipole setup @@ -1081,7 +1005,7 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::N // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEDirectPolarization(FILE* log) { +static void testMultipoleIonsAndWaterPMEDirectPolarization() { std::string testName = "testMultipoleIonsAndWaterDirectPolarization"; @@ -1093,7 +1017,7 @@ static void testMultipoleIonsAndWaterPMEDirectPolarization(FILE* log) { double energy; setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, testName, forces, energy, log); + cutoff, inputPmeGridDimension, testName, forces, energy); std::vector expectedForces(numberOfParticles); @@ -1109,13 +1033,13 @@ static void testMultipoleIonsAndWaterPMEDirectPolarization(FILE* log) { expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00); double tolerance = 5.0e-04; - compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEMutualPolarization(FILE* log) { +static void testMultipoleIonsAndWaterPMEMutualPolarization() { std::string testName = "testMultipoleIonsAndWaterMutualPolarization"; @@ -1129,7 +1053,7 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization(FILE* log) { std::vector inputGrid; setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, forces, energy, log); + cutoff, inputPmeGridDimension, testName, forces, energy); std::vector expectedForces(numberOfParticles); @@ -1145,9 +1069,9 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization(FILE* log) { expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00); //double tolerance = 1.0e-03; - //compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + //compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); double tolerance = 5.0e-04; - compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } @@ -1159,7 +1083,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::Non std::vector& forces, double& energy, std::vector< double >& outputMultipoleMoments, std::vector< Vec3 >& inputGrid, - std::vector< double >& outputGridPotential, FILE* log) { + std::vector< double >& outputGridPotential) { // beginning of Multipole setup @@ -1945,7 +1869,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::Non // test multipole mutual polarization using PME for box of water -static void testPMEMutualPolarizationLargeWater(FILE* log) { +static void testPMEMutualPolarizationLargeWater() { std::string testName = "testPMEMutualPolarizationLargeWater"; @@ -1960,7 +1884,7 @@ static void testPMEMutualPolarizationLargeWater(FILE* log) { setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log); + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential); static std::vector expectedForces; // Static to work around bug in Visual Studio that makes compilation very very slow. expectedForces.resize(numberOfParticles); @@ -2616,7 +2540,7 @@ static void testPMEMutualPolarizationLargeWater(FILE* log) { expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02); double tolerance = 1.0e-03; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } @@ -2656,7 +2580,7 @@ static void testParticleInducedDipoles() { // test computation of system multipole moments -static void testSystemMultipoleMoments(FILE* log) { +static void testSystemMultipoleMoments() { std::string testName = "testSystemMultipoleMoments"; @@ -2672,7 +2596,7 @@ static void testSystemMultipoleMoments(FILE* log) { setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log); + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential); std::vector tinkerMoments(4); @@ -2691,9 +2615,6 @@ static void testSystemMultipoleMoments(FILE* log) { // tinkerMoments[12] = 4.3292490e-02; double tolerance = 1.0e-04; - if (log) { - (void) fprintf(log, "%s RelativeDifference Tinker OpenMM\n", testName.c_str()); - } for (unsigned int ii = 0; ii < tinkerMoments.size(); ii++) { double difference; if (fabs(tinkerMoments[ii]) > 0.0) { @@ -2702,10 +2623,6 @@ static void testSystemMultipoleMoments(FILE* log) { else { difference = fabs(outputMultipoleMoments[ii] - tinkerMoments[ii]); } - if (log) { - (void) fprintf(log, "%2d %15.7e %15.7e %15.7e\n", ii, difference, tinkerMoments[ii], outputMultipoleMoments[ii]); - } - if (difference > tolerance) { std::stringstream details; details << testName << "Multipole moment " << ii << " does not agree w/ TINKER computed moments: OpenMM=" << outputMultipoleMoments[ii]; @@ -2719,7 +2636,7 @@ static void testSystemMultipoleMoments(FILE* log) { // test computation of multipole potential on a grid -static void testMultipoleGridPotential(FILE* log) { +static void testMultipoleGridPotential() { std::string testName = "testMultipoleGridPotential"; @@ -2768,7 +2685,7 @@ static void testMultipoleGridPotential(FILE* log) { setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension, testName, forces, energy, - outputMultipoleMoments, inputGrid, outputGridPotential, log); + outputMultipoleMoments, inputGrid, outputGridPotential); // TINKER computed grid values @@ -2948,13 +2865,11 @@ int main(int numberOfArguments, char* argv[]) { std::cout << "TestReferenceAmoebaMultipoleForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - FILE* log = NULL; - // tests using two ammonia molecules // test direct polarization, no cutoff - testMultipoleAmmoniaDirectPolarization(log); + testMultipoleAmmoniaDirectPolarization(); // test querying induced dipoles @@ -2962,33 +2877,33 @@ int main(int numberOfArguments, char* argv[]) { // test mutual polarization, no cutoff - testMultipoleAmmoniaMutualPolarization(log); + testMultipoleAmmoniaMutualPolarization(); // test multipole direct & mutual polarization using PME - testMultipoleWaterPMEDirectPolarization(log); - testMultipoleWaterPMEMutualPolarization(log); + testMultipoleWaterPMEDirectPolarization(); + testMultipoleWaterPMEMutualPolarization(); // check validation of traceless/symmetric quadrupole tensor - testQuadrupoleValidation(log); + testQuadrupoleValidation(); // system w/ 2 ions and 2 water molecules - testMultipoleIonsAndWaterPMEMutualPolarization(log); - testMultipoleIonsAndWaterPMEDirectPolarization(log); + testMultipoleIonsAndWaterPMEMutualPolarization(); + testMultipoleIonsAndWaterPMEDirectPolarization(); // test computation of system multipole moments - testSystemMultipoleMoments(log); + testSystemMultipoleMoments(); // test computation of grid potential - testMultipoleGridPotential(log); + testMultipoleGridPotential(); // large box of water - testPMEMutualPolarizationLargeWater(log); + testPMEMutualPolarizationLargeWater(); // triclinic box of water diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp index c5832c239..1eaacf700 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp @@ -79,7 +79,7 @@ static double dotVector3(double* vectorX, double* vectorY) { static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& positions, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& forces, double* energy, FILE* log) { + std::vector& forces, double* energy) { double kAngleCubic = amoebaOutOfPlaneBendForce.getAmoebaGlobalOutOfPlaneBendCubic(); @@ -90,14 +90,6 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& int particle1, particle2, particle3, particle4; double kAngleQuadratic; amoebaOutOfPlaneBendForce.getOutOfPlaneBendParameters(bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaOutOfPlaneBendForce: bond %d [%d %d %d %d] k=[%10.3e %10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic, kAngleCubic, kAngleQuartic, kAnglePentic, kAngleSextic); - (void) fflush(log); - } -#endif - enum { A, B, C, D, LastAtomIndex }; enum { AB, CB, DB, AD, CD, LastDeltaIndex }; @@ -141,13 +133,6 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& else { angle = RADIAN*acos(cosine); } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaOutOfPlaneBendForce: bkk2=%14.7e rDB2=%14.7e cos=%14.7e dt=%14.7e]\n", - bkk2, rDB2, cosine, angle); - (void) fflush(log); - } -#endif // chain rule @@ -244,7 +229,7 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& } static void computeAmoebaOutOfPlaneBendForces(Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log) { + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces @@ -260,41 +245,19 @@ static void computeAmoebaOutOfPlaneBendForces(Context& context, AmoebaOutOfPlane *expectedEnergy = 0.0; for (int ii = 0; ii < amoebaOutOfPlaneBendForce.getNumOutOfPlaneBends(); ii++) { - computeAmoebaOutOfPlaneBendForce(ii, positions, amoebaOutOfPlaneBendForce, expectedForces, expectedEnergy, log); - } - -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e\n", *expectedEnergy); - for (unsigned int ii = 0; ii < positions.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); - } - (void) fflush(log); + computeAmoebaOutOfPlaneBendForce(ii, positions, amoebaOutOfPlaneBendForce, expectedForces, expectedEnergy); } -#endif - return; - } void compareWithExpectedForceAndEnergy(Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaOutOfPlaneBendForces(context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy, log); + computeAmoebaOutOfPlaneBendForces(context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); - } - (void) fflush(log); - } -#endif for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); @@ -302,7 +265,7 @@ void compareWithExpectedForceAndEnergy(Context& context, AmoebaOutOfPlaneBendFor ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneOutOfPlaneBend(FILE* log) { +void testOneOutOfPlaneBend() { System system; int numberOfParticles = 4; @@ -336,7 +299,7 @@ void testOneOutOfPlaneBend(FILE* log) { positions[3] = Vec3(0.245568230E+02, 0.250215290E+02, 0.796852800E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); // Try changing the bend parameters and make sure it's still correct. @@ -344,17 +307,17 @@ void testOneOutOfPlaneBend(FILE* log) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaOutOfPlaneBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); } -void testOneOutOfPlaneBend2(FILE* log, int setId) { +void testOneOutOfPlaneBend2(int setId) { System system; int numberOfParticles = 4; @@ -444,20 +407,10 @@ void testOneOutOfPlaneBend2(FILE* log, int setId) { kOutOfPlaneBend = 0.214755281E-01; } else { -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "Set id %d not recognized.\n", setId); - } -#endif std::stringstream buffer; buffer << "Set id " << setId << " not recognized."; throw OpenMMException(buffer.str()); } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "Set id %d.\n", setId); - } -#endif amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend); @@ -467,11 +420,6 @@ void testOneOutOfPlaneBend2(FILE* log, int setId) { for (unsigned int ii = 0; ii < static_cast(numberOfParticles); ii++) { if (coordinates.find(particleIndices[ii]) == coordinates.end()) { -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "Coordinates %d not loaded.", particleIndices[ii]); - } -#endif std::stringstream buffer; buffer << "Coordinates " << particleIndices[ii] << " not loaded."; throw OpenMMException(buffer.str()); @@ -480,7 +428,7 @@ void testOneOutOfPlaneBend2(FILE* log, int setId) { } context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); static int iter = 0; static std::map totalForces; @@ -503,7 +451,7 @@ void testOneOutOfPlaneBend2(FILE* log, int setId) { std::vector forces; forces.resize(numberOfParticles); double energy; - computeAmoebaOutOfPlaneBendForce(0, positions, *amoebaOutOfPlaneBendForce, forces, &energy, log); + computeAmoebaOutOfPlaneBendForce(0, positions, *amoebaOutOfPlaneBendForce, forces, &energy); totalEnergy += energy; for (unsigned int ii = 0; ii < static_cast(numberOfParticles); ii++) { @@ -511,22 +459,6 @@ void testOneOutOfPlaneBend2(FILE* log, int setId) { totalForces[particleIndices[ii]][jj] += forces[ii][jj]; } } - - if (iter == 6) { -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaOutOfPlaneBendForces: energy=%14.7e\n", totalEnergy); - for (std::map::iterator ii = totalForces.begin(); ii != totalForces.end(); ii++) { - int particleIndex = ii->first; - Vec3 forces = ii->second; - (void) fprintf(log, "%6d [%14.7e %14.7e %14.7e] \n", particleIndex, - forces[0], forces[1], forces[2]); - } - (void) fflush(log); - } -#endif - } - } int main(int numberOfArguments, char* argv[]) { @@ -534,21 +466,11 @@ int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaOutOfPlaneBendForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - - //FILE* log = stderr; - FILE* log = NULL; - //FILE* log = fopen("AmoebaOutOfPlaneBendForce.log", "w");; - - testOneOutOfPlaneBend(log); - //testOneOutOfPlaneBend2(log, atoi(argv[1])); + testOneOutOfPlaneBend(); + //testOneOutOfPlaneBend2(atoi(argv[1])); //for (int ii = 1; ii <= 6; ii++) { - // testOneOutOfPlaneBend2(log, ii); + // testOneOutOfPlaneBend2(ii); //} -#ifdef AMOEBA_DEBUG - if (log && log != stderr) - (void) fclose(log); -#endif - } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp index 8d9ee5b5b..a8ea989b4 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp @@ -78,19 +78,12 @@ static double dotVector3(double* vectorX, double* vectorY) { static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& positions, AmoebaPiTorsionForce& amoebaPiTorsionForce, - std::vector& forces, double* energy, FILE* log) { + std::vector& forces, double* energy) { int particle1, particle2, particle3, particle4, particle5, particle6; double kTorsion; amoebaPiTorsionForce.getPiTorsionParameters(bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaPiTorsionForce: bond %d [%d %d %d %d %d %d] k=%10.3e\n", - bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion); - (void) fflush(log); - } -#endif enum { AD, BD, EC, FC, P, Q, CP, DC, QD, T, U, TU, DP, QC, dT, dU, dP, dQ, dC1, dC2, dD1, dD2, LastDeltaIndex }; double deltaR[LastDeltaIndex][3]; @@ -212,7 +205,7 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit } static void computeAmoebaPiTorsionForces(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log) { + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces @@ -228,40 +221,19 @@ static void computeAmoebaPiTorsionForces(Context& context, AmoebaPiTorsionForce& *expectedEnergy = 0.0; for (int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++) { - computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy, log); - } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaPiTorsionForces: expected energy=%14.7e\n", *expectedEnergy); - for (unsigned int ii = 0; ii < positions.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); - } - (void) fflush(log); + computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy); } -#endif - return; - } void compareWithExpectedForceAndEnergy(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaPiTorsionForces(context, amoebaPiTorsionForce, expectedForces, &expectedEnergy, log); + computeAmoebaPiTorsionForces(context, amoebaPiTorsionForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaPiTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); - } - (void) fflush(log); - } -#endif for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); @@ -269,7 +241,7 @@ void compareWithExpectedForceAndEnergy(Context& context, AmoebaPiTorsionForce& a ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOnePiTorsion(FILE* log) { +void testOnePiTorsion() { System system; int numberOfParticles = 6; @@ -300,7 +272,7 @@ void testOnePiTorsion(FILE* log) { positions[5] = Vec3(0.254124630E+02, 0.234691880E+02, 0.773335400E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); // Try changing the torsion parameters and make sure it's still correct. @@ -308,14 +280,14 @@ void testOnePiTorsion(FILE* log) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaPiTorsionForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); } int main(int numberOfArguments, char* argv[]) { @@ -323,16 +295,7 @@ int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaPiTorsionForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - FILE* log = NULL; - //FILE* log = stderr; - //FILE* log = fopen("AmoebaPiTorsionForce1.log", "w");; - - testOnePiTorsion(log); -#ifdef AMOEBA_DEBUG - if (log && log != stderr) - (void) fclose(log); -#endif - + testOnePiTorsion(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp index 1969cf716..dfbce9d03 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaStretchBendForce.cpp @@ -80,20 +80,13 @@ static double dotVector3(double* vectorX, double* vectorY) { static void computeAmoebaStretchBendForce(int bondIndex, std::vector& positions, AmoebaStretchBendForce& amoebaStretchBendForce, - std::vector& forces, double* energy, FILE* log) { + std::vector& forces, double* energy) { int particle1, particle2, particle3; double abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend; amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); angleStretchBend *= RADIAN; -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k1=%10.3e k2=%10.3e\n", - bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); - (void) fflush(log); - } -#endif enum { A, B, C, LastAtomIndex }; enum { AB, CB, CBxAB, ABxP, CBxP, LastDeltaIndex }; @@ -189,18 +182,10 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos forces[particle3][2] -= subForce[2][2]; *energy += dt*drkk; -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaStretchBendForce: angle=%10.3e dt=%10.3e dr=%10.3e\n", angle, dt, dr); - (void) fflush(log); - } -#endif - - return; } static void computeAmoebaStretchBendForces(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log) { + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces @@ -216,48 +201,26 @@ static void computeAmoebaStretchBendForces(Context& context, AmoebaStretchBendFo *expectedEnergy = 0.0; for (int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++) { - computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy, log); - } -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaStretchBendForces: expected energy=%14.7e\n", *expectedEnergy); - for (unsigned int ii = 0; ii < positions.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2]); - } - (void) fflush(log); + computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy); } -#endif - return; - } void compareWithExpectedForceAndEnergy(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaStretchBendForces(context, amoebaStretchBendForce, expectedForces, &expectedEnergy, log); + computeAmoebaStretchBendForces(context, amoebaStretchBendForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaStretchBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); - } - (void) fflush(log); - } -#endif - for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneStretchBend(FILE* log) { +void testOneStretchBend() { System system; int numberOfParticles = 3; @@ -289,7 +252,7 @@ void testOneStretchBend(FILE* log) { positions[2] = Vec3(0.269573220E+02, 0.236108860E+02, 0.216376800E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend"); // Try changing the stretch-bend parameters and make sure it's still correct. @@ -297,14 +260,14 @@ void testOneStretchBend(FILE* log) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaStretchBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend"); } int main(int numberOfArguments, char* argv[]) { @@ -312,16 +275,7 @@ int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaStretchBendForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - - FILE* log = NULL; - //FILE* log = stderr; - //FILE* log = fopen("AmoebaStretchBendForce1.log", "w");; - testOneStretchBend(log); -#ifdef AMOEBA_DEBUG - if (log && log != stderr) - (void) fclose(log); -#endif - + testOneStretchBend(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp index 4f9416e3e..73bfa84b5 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp @@ -57,7 +57,7 @@ extern "C" OPENMM_EXPORT void registerAmoebaReferenceKernelFactories(); const double TOL = 1e-4; -void testVdw(FILE* log) { +void testVdw() { System system; int numberOfParticles = 6; @@ -162,17 +162,6 @@ void testVdw(FILE* log) { } expectedEnergy *= CalToJoule; -#ifdef AMOEBA_DEBUG - if (log) { - (void) fprintf(log, "computeAmoebaVdwForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy()); - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2]); - } - (void) fflush(log); - } -#endif - double tolerance = 1.0e-03; for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); @@ -210,7 +199,7 @@ void testVdw(FILE* log) { } void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, - double boxDimension, std::vector& forces, double& energy, FILE* log) { + double boxDimension, std::vector& forces, double& energy) { // beginning of Vdw setup @@ -353,24 +342,7 @@ void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, co void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - std::vector& forces, double tolerance, FILE* log) { - - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if (log) { - double conversion = 1.0/4.184; - (void) fprintf(log, "%s: expected energy=%14.7e %14.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy); - conversion *= -0.1; - for (unsigned int ii = 0; ii < forces.size(); ii++) { - (void) fprintf(log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2]); - } - (void) fflush(log); - } -#endif - + std::vector& forces, double tolerance) { for (unsigned int ii = 0; ii < forces.size(); ii++) { ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } @@ -379,7 +351,7 @@ void compareForcesEnergy(std::string& testName, double expectedEnergy, double en // test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG -void testVdwAmmoniaCubicMeanHhg(FILE* log) { +void testVdwAmmoniaCubicMeanHhg() { std::string testName = "testVdwAmmoniaCubicMeanHhg"; @@ -389,7 +361,7 @@ void testVdwAmmoniaCubicMeanHhg(FILE* log) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.8012258e+00; @@ -404,12 +376,12 @@ void testVdwAmmoniaCubicMeanHhg(FILE* log) { expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic -void testVdwAmmoniaArithmeticArithmetic(FILE* log) { +void testVdwAmmoniaArithmeticArithmetic() { std::string testName = "testVdwAmmoniaArithmeticArithmetic"; @@ -419,7 +391,7 @@ void testVdwAmmoniaArithmeticArithmetic(FILE* log) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia("ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy, log); + setupAndGetForcesEnergyVdwAmmonia("ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.2252403e+00; @@ -434,12 +406,12 @@ void testVdwAmmoniaArithmeticArithmetic(FILE* log) { expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test VDW w/ sigmaRule=Geometric and epsilonRule=Geometric -void testVdwAmmoniaGeometricGeometric(FILE* log) { +void testVdwAmmoniaGeometricGeometric() { std::string testName = "testVdwAmmoniaGeometricGeometric"; @@ -448,7 +420,7 @@ void testVdwAmmoniaGeometricGeometric(FILE* log) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia("GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy, log); + setupAndGetForcesEnergyVdwAmmonia("GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 2.5249914e+00; @@ -463,10 +435,10 @@ void testVdwAmmoniaGeometricGeometric(FILE* log) { expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } -void testVdwAmmoniaCubicMeanHarmonic(FILE* log) { +void testVdwAmmoniaCubicMeanHarmonic() { std::string testName = "testVdwAmmoniaCubicMeanHarmonic"; @@ -475,7 +447,7 @@ void testVdwAmmoniaCubicMeanHarmonic(FILE* log) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy, log); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.1369069e+00; @@ -490,14 +462,14 @@ void testVdwAmmoniaCubicMeanHarmonic(FILE* log) { expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test w/ cutoff=0.25 nm; single ixn between two particles (0 and 6); force nonzero on // particle 4 due to reduction applied to NH // the distance between 0 and 6 is ~ 0.235 so the ixn is in the tapered region -void testVdwTaper(FILE* log) { +void testVdwTaper() { std::string testName = "testVdwTaper"; @@ -507,7 +479,7 @@ void testVdwTaper(FILE* log) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 3.5478444e+00; @@ -522,12 +494,12 @@ void testVdwTaper(FILE* log) { expectedForces[7] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); double tolerance = 1.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test PBC -void testVdwPBC(FILE* log) { +void testVdwPBC() { std::string testName = "testVdwPBC"; @@ -537,7 +509,7 @@ void testVdwPBC(FILE* log) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 1.4949141e+01; @@ -555,14 +527,14 @@ void testVdwPBC(FILE* log) { // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // create box of 216 water molecules void setupAndGetForcesEnergyVdwWater(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, double boxDimension, int includeVdwDispersionCorrection, - std::vector& forces, double& energy, FILE* log) { + std::vector& forces, double& energy) { // beginning of Vdw setup @@ -1282,7 +1254,7 @@ void setupAndGetForcesEnergyVdwWater(const std::string& sigmaCombiningRule, cons // test employing box of 216 water molecules w/ and w/o dispersion correction -void testVdwWater(int includeVdwDispersionCorrection, FILE* log) { +void testVdwWater(int includeVdwDispersionCorrection) { std::string testName; @@ -1299,7 +1271,7 @@ void testVdwWater(int includeVdwDispersionCorrection, FILE* log) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwWater("CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log); + setupAndGetForcesEnergyVdwWater("CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy); std::vector expectedForces(numberOfParticles); // initialize expected energy and forces @@ -1965,7 +1937,7 @@ void testVdwWater(int includeVdwDispersionCorrection, FILE* log) { // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); // test sigma/epsilon rules for dispersion correction @@ -1988,7 +1960,7 @@ void testVdwWater(int includeVdwDispersionCorrection, FILE* log) { expectedEnergies.push_back(3.2774624e+03); for (unsigned int ii = 0; ii < sigmaRules.size(); ii++) { - setupAndGetForcesEnergyVdwWater(sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log); + setupAndGetForcesEnergyVdwWater(sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy); testName = "testVdwWaterWithDispersionCorrection_" + sigmaRules[ii] + '_' + epsilonRules[ii]; ASSERT_EQUAL_TOL_MOD(expectedEnergies[ii], energy, tolerance, testName); } @@ -2057,49 +2029,46 @@ int main(int numberOfArguments, char* argv[]) { try { std::cout << "TestReferenceAmoebaVdwForce running test..." << std::endl; registerAmoebaReferenceKernelFactories(); - - FILE* log = NULL; - - testVdw(log); + testVdw(); // tests using two ammonia molecules // test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG - testVdwAmmoniaCubicMeanHhg(log); + testVdwAmmoniaCubicMeanHhg(); // test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic - testVdwAmmoniaArithmeticArithmetic(log); + testVdwAmmoniaArithmeticArithmetic(); // test VDW w/ sigmaRule=Geometric and epsilonRule=Geometric - testVdwAmmoniaGeometricGeometric(log); + testVdwAmmoniaGeometricGeometric(); // test VDW w/ sigmaRule=CubicMean and epsilonRule=Harmonic - testVdwAmmoniaCubicMeanHarmonic(log); + testVdwAmmoniaCubicMeanHarmonic(); // test w/ cutoff=0.25 nm; single ixn between two particles (0 and 6); force nonzero on // particle 4 due to reduction applied to NH // the distance between 0 and 6 is ~ 0.235 so the ixn is in the tapered region - testVdwTaper(log); + testVdwTaper(); // test PBC - testVdwPBC(log); + testVdwPBC(); // tests based on box of water int includeVdwDispersionCorrection = 0; - testVdwWater(includeVdwDispersionCorrection, log); + testVdwWater(includeVdwDispersionCorrection); // includes tests for various combinations of sigma/epsilon rules // when computing vdw dispersion correction includeVdwDispersionCorrection = 1; - testVdwWater(includeVdwDispersionCorrection, log); + testVdwWater(includeVdwDispersionCorrection); // test triclinic boxes -- GitLab From a568bb1293243114a1c8a7095b9b9e2c5e8ab7b5 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 23 Feb 2015 11:46:52 -0800 Subject: [PATCH 285/338] Deleted more debugging code --- .../cuda/tests/TestCudaAmoebaAngleForce.cpp | 68 ++----- .../cuda/tests/TestCudaAmoebaBondForce.cpp | 44 +---- ...TestCudaAmoebaGeneralizedKirkwoodForce.cpp | 132 +++----------- .../tests/TestCudaAmoebaInPlaneAngleForce.cpp | 72 ++------ .../tests/TestCudaAmoebaMultipoleForce.cpp | 172 +++++------------- .../TestCudaAmoebaOutOfPlaneBendForce.cpp | 101 ++-------- .../tests/TestCudaAmoebaPiTorsionForce.cpp | 52 +----- .../tests/TestCudaAmoebaStretchBendForce.cpp | 61 +------ .../TestCudaAmoebaTorsionTorsionForce.cpp | 18 +- .../cuda/tests/TestCudaAmoebaVdwForce.cpp | 100 ++++------ .../cuda/tests/TestCudaWcaDispersionForce.cpp | 25 +-- ...erializeAmoebaGeneralizedKirkwoodForce.cpp | 8 - .../TestSerializeAmoebaMultipoleForce.cpp | 7 - ...TestSerializeAmoebaTorsionTorsionForce.cpp | 8 - .../tests/TestSerializeAmoebaVdwForce.cpp | 8 - .../TestSerializeAmoebaWcaDispersionForce.cpp | 8 - 16 files changed, 179 insertions(+), 705 deletions(-) diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp index d870c31df..cd1c25cb9 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp @@ -77,7 +77,7 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, double quadraticK, double cubicK, double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm, FILE* log ) { + double* dEdR, double* energyTerm ) { double angle; if( cosine >= 1.0 ){ @@ -88,13 +88,6 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou angle = RADIAN*acos(cosine); } -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "getPrefactorsGivenAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealAngle ); - (void) fflush( log ); - } -#endif - double deltaIdeal = angle - idealAngle; double deltaIdeal2 = deltaIdeal*deltaIdeal; double deltaIdeal3 = deltaIdeal*deltaIdeal2; @@ -121,7 +114,7 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou } static void computeAmoebaAngleForce(int bondIndex, std::vector& positions, AmoebaAngleForce& amoebaAngleForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy ) { int particle1, particle2, particle3; double idealAngle; @@ -133,14 +126,6 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions double penticK = amoebaAngleForce.getAmoebaGlobalAnglePentic(); double sexticK = amoebaAngleForce.getAmoebaGlobalAngleSextic(); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaAngleForce: bond %d [%d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, idealAngle, quadraticK, cubicK, quarticK, penticK, sexticK ); - (void) fflush( log ); - } -#endif - double deltaR[2][3]; double r2_0 = 0.0; double r2_1 = 0.0; @@ -163,17 +148,10 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions double dot = deltaR[0][0]*deltaR[1][0] + deltaR[0][1]*deltaR[1][1] + deltaR[0][2]*deltaR[1][2]; double cosine = dot/sqrt(r2_0*r2_1); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "dot=%10.3e r2_0=%10.3e r2_1=%10.3e\n", dot, r2_0, r2_1 ); - (void) fflush( log ); - } -#endif - double dEdR; double energyTerm; getPrefactorsGivenAngleCosine( cosine, idealAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm, log ); + quarticK, penticK, sexticK, &dEdR, &energyTerm ); double termA = -dEdR/(r2_0*rp); double termC = dEdR/(r2_1*rp); @@ -203,7 +181,7 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions } static void computeAmoebaAngleForces( Context& context, AmoebaAngleForce& amoebaAngleForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { + std::vector& expectedForces, double* expectedEnergy ) { // get positions and zero forces @@ -219,51 +197,30 @@ static void computeAmoebaAngleForces( Context& context, AmoebaAngleForce& amoeba *expectedEnergy = 0.0; for( int ii = 0; ii < amoebaAngleForce.getNumAngles(); ii++ ){ - computeAmoebaAngleForce(ii, positions, amoebaAngleForce, expectedForces, expectedEnergy, log ); - } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaAngleForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); - } - (void) fflush( log ); + computeAmoebaAngleForce(ii, positions, amoebaAngleForce, expectedForces, expectedEnergy ); } -#endif return; } void compareWithExpectedForceAndEnergy( Context& context, AmoebaAngleForce& amoebaAngleForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaAngleForces( context, amoebaAngleForce, expectedForces, &expectedEnergy, log ); + computeAmoebaAngleForces( context, amoebaAngleForce, expectedForces, &expectedEnergy ); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); } ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); } -void testOneAngle( FILE* log ) { +void testOneAngle() { System system; int numberOfParticles = 3; @@ -298,7 +255,7 @@ void testOneAngle( FILE* log ) { positions[2] = Vec3(0, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); + compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle" ); // Try changing the angle parameters and make sure it's still correct. @@ -306,14 +263,14 @@ void testOneAngle( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); + compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle" ); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle", log ); + compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle" ); } int main(int argc, char* argv[]) { @@ -322,8 +279,7 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testOneAngle( log ); + testOneAngle(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp index 9c62bbbf6..2387593b4 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp @@ -84,7 +84,7 @@ static void computeAmoebaBondForce(int bondIndex, std::vector& positions, } static void computeAmoebaBondForces( Context& context, AmoebaBondForce& amoebaBondForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { + std::vector& expectedForces, double* expectedEnergy ) { // get positions and zero forces @@ -102,47 +102,24 @@ static void computeAmoebaBondForces( Context& context, AmoebaBondForce& amoebaBo for( int ii = 0; ii < amoebaBondForce.getNumBonds(); ii++ ){ computeAmoebaBondForce(ii, positions, amoebaBondForce, expectedForces, expectedEnergy ); } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaBondForces: expected energy=%15.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%15.7e %15.7e %15.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); - } - (void) fflush( log ); - } -#endif - return; - } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaBondForce& amoebaBondForce, double tolerance, const std::string& idString, FILE* log) { +void compareWithExpectedForceAndEnergy( Context& context, AmoebaBondForce& amoebaBondForce, double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaBondForces( context, amoebaBondForce, expectedForces, &expectedEnergy, NULL ); + computeAmoebaBondForces( context, amoebaBondForce, expectedForces, &expectedEnergy ); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaBondForces: expected energy=%15.7e %15.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%15.7e %15.7e %15.7e] [%15.7e %15.7e %15.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); } ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); } -void testOneBond( FILE* log ) { +void testOneBond() { System system; @@ -169,10 +146,10 @@ void testOneBond( FILE* log ) { positions[1] = Vec3(0, 0, 0); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testOneBond", log ); + compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testOneBond" ); } -void testTwoBond( FILE* log ) { +void testTwoBond( ) { System system; @@ -203,7 +180,7 @@ void testTwoBond( FILE* log ) { positions[2] = Vec3(1, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); + compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond" ); // Try changing the bond parameters and make sure it's still correct. @@ -212,14 +189,14 @@ void testTwoBond( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); + compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond" ); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaBondForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond", log ); + compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond" ); } int main(int argc, char* argv[]) { @@ -228,8 +205,7 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testTwoBond( log ); + testTwoBond(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp index affdf8157..205c36599 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp @@ -273,7 +273,7 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce system.addForce(amoebaGeneralizedKirkwoodForce); } -static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy, FILE* log) { +static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy) { std::vector positions(context.getSystem().getNumParticles()); positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); @@ -294,7 +294,7 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& // setup for villin static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::PolarizationType polarizationType, - int includeCavityTerm, std::vector& forces, double& energy, FILE* log ){ + int includeCavityTerm, std::vector& forces, double& energy ){ // beginning of Multipole setup @@ -6978,45 +6978,7 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari static void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if( log ){ - double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); - - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); - - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*absDiff, conversion*relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm ); - } - (void) fflush( log ); - conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - + const std::vector& forces, double tolerance ) { for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); } @@ -7027,47 +6989,7 @@ static void compareForcesEnergy( std::string& testName, double expectedEnergy, d static void compareForceNormsEnergy( std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { - - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if( log ){ - double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); - - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( (norm - expectedNorm) ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); - - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, - fabs(conversion)*absDiff, relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], - fabs(conversion)*expectedNorm, fabs(conversion)*norm ); - } - (void) fflush( log ); - conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - + const std::vector& forces, double tolerance ) { for( unsigned int ii = 0; ii < forces.size(); ii++ ){ double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + expectedForces[ii][1]*expectedForces[ii][1] + @@ -7096,7 +7018,7 @@ static void compareForceNormsEnergy( std::string& testName, double expectedEnerg // test GK direct polarization for system comprised of two ammonia molecules -static void testGeneralizedKirkwoodAmmoniaDirectPolarization( FILE* log ) { +static void testGeneralizedKirkwoodAmmoniaDirectPolarization() { std::string testName = "testGeneralizedKirkwoodAmmoniaDirectPolarization"; @@ -7109,7 +7031,7 @@ static void testGeneralizedKirkwoodAmmoniaDirectPolarization( FILE* log ) { setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Direct, 0); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("CUDA")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log ); + getForcesEnergyMultipoleAmmonia(context, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -7.6636680e+01; @@ -7124,12 +7046,12 @@ static void testGeneralizedKirkwoodAmmoniaDirectPolarization( FILE* log ) { expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test GK mutual polarization for system comprised of two ammonia molecules -static void testGeneralizedKirkwoodAmmoniaMutualPolarization( FILE* log ) { +static void testGeneralizedKirkwoodAmmoniaMutualPolarization() { std::string testName = "testGeneralizedKirkwoodAmmoniaMutualPolarization"; @@ -7142,7 +7064,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarization( FILE* log ) { setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Mutual, 0); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("CUDA")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log ); + getForcesEnergyMultipoleAmmonia(context, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -7.8018875e+01; @@ -7157,13 +7079,13 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarization( FILE* log ) { expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02 ); double tolerance = 2.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for system comprised of two ammonia molecules // including cavity term -static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE* log ) { +static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( ) { std::string testName = "testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm"; @@ -7176,7 +7098,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE setupMultipoleAmmonia(system, amoebaGeneralizedKirkwoodForce, AmoebaMultipoleForce::Mutual, 1); LangevinIntegrator integrator(0.0, 0.1, 0.01); Context context(system, integrator, Platform::getPlatformByName("CUDA")); - getForcesEnergyMultipoleAmmonia(context, forces, energy, log ); + getForcesEnergyMultipoleAmmonia(context, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -6.0434582e+01; @@ -7191,7 +7113,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance); // Try changing the particle parameters and make sure it's still correct. @@ -7208,7 +7130,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE bool exceptionThrown = false; try { // This should throw an exception. - compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); } catch (std::exception ex) { exceptionThrown = true; @@ -7216,12 +7138,12 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( FILE ASSERT(exceptionThrown); amoebaGeneralizedKirkwoodForce->updateParametersInContext(context); state1 = context.getState(State::Forces | State::Energy); - compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); } // test GK direct polarization for villin system -static void testGeneralizedKirkwoodVillinDirectPolarization( FILE* log ) { +static void testGeneralizedKirkwoodVillinDirectPolarization( ) { std::string testName = "testGeneralizedKirkwoodVillinDirectPolarization"; @@ -7229,7 +7151,7 @@ static void testGeneralizedKirkwoodVillinDirectPolarization( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Direct, 0, forces, energy, log ); + setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Direct, 0, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.4281157e+03; @@ -7840,12 +7762,12 @@ static void testGeneralizedKirkwoodVillinDirectPolarization( FILE* log ) { } double tolerance = 1.0e-05; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for villin system -static void testGeneralizedKirkwoodVillinMutualPolarization( FILE* log ) { +static void testGeneralizedKirkwoodVillinMutualPolarization( ) { std::string testName = "testGeneralizedKirkwoodVillinMutualPolarization"; @@ -7853,7 +7775,7 @@ static void testGeneralizedKirkwoodVillinMutualPolarization( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Mutual, 0, forces, energy, log ); + setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Mutual, 0, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.6477811e+03; @@ -8464,7 +8386,7 @@ static void testGeneralizedKirkwoodVillinMutualPolarization( FILE* log ) { } double tolerance = 1.0e-05; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } int main(int argc, char* argv[]) { @@ -8474,17 +8396,15 @@ int main(int argc, char* argv[]) { if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - // test direct and mutual polarization cases and // mutual polarization w/ the cavity term - testGeneralizedKirkwoodAmmoniaDirectPolarization( log ); - testGeneralizedKirkwoodAmmoniaMutualPolarization( log ); - testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( log ); + testGeneralizedKirkwoodAmmoniaDirectPolarization(); + testGeneralizedKirkwoodAmmoniaMutualPolarization(); + testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm(); - testGeneralizedKirkwoodVillinDirectPolarization( log ); - testGeneralizedKirkwoodVillinMutualPolarization( log ); + testGeneralizedKirkwoodVillinDirectPolarization(); + testGeneralizedKirkwoodVillinMutualPolarization(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp index bb758c875..eac90eec8 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp @@ -78,7 +78,7 @@ static double dotVector3( double* vectorX, double* vectorY ){ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInPlaneAngle, double quadraticK, double cubicK, double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm, FILE* log ) { + double* dEdR, double* energyTerm ) { double angle; if( cosine >= 1.0 ){ @@ -89,13 +89,6 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP angle = RADIAN*acos(cosine); } -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "getPrefactorsGivenInPlaneAngleCosine: cosine=%10.3e angle=%10.3e ideal=%10.3e\n", cosine, angle, idealInPlaneAngle ); - (void) fflush( log ); - } -#endif - double deltaIdeal = angle - idealInPlaneAngle; double deltaIdeal2 = deltaIdeal*deltaIdeal; double deltaIdeal3 = deltaIdeal*deltaIdeal2; @@ -122,7 +115,7 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP } static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& positions, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy ) { int particle1, particle2, particle3, particle4; double idealInPlaneAngle; @@ -134,14 +127,6 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po double penticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAnglePentic(); double sexticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleSextic(); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForce: bond %d [%d %d %d %d] ang=%10.3f k=%10.3f [%10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK, cubicK, quarticK, penticK, sexticK ); - (void) fflush( log ); - } -#endif - // T = AD x CD // P = B + T*delta // AP = A - P @@ -181,14 +166,6 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po double rAp2 = dotVector3( deltaR[AP], deltaR[AP] ); double rCp2 = dotVector3( deltaR[CP], deltaR[CP] ); if( rAp2 <= 0.0 && rCp2 <= 0.0 ){ -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForce: rAp2 or rCp2 <= 0.0\n" ); - (void) fflush( log ); - } -#endif - - return; } crossProductVector3( deltaR[CP], deltaR[AP], deltaR[M] ); @@ -205,7 +182,7 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po double dEdR; double energyTerm; getPrefactorsGivenInPlaneAngleCosine( cosine, idealInPlaneAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm, log ); + quarticK, penticK, sexticK, &dEdR, &energyTerm ); double termA = -dEdR/(rAp2*rm); double termC = dEdR/(rCp2*rm); @@ -280,7 +257,7 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po } static void computeAmoebaInPlaneAngleForces( Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { + std::vector& expectedForces, double* expectedEnergy ) { // get positions and zero forces @@ -296,50 +273,26 @@ static void computeAmoebaInPlaneAngleForces( Context& context, AmoebaInPlaneAngl *expectedEnergy = 0.0; for( int ii = 0; ii < amoebaInPlaneAngleForce.getNumAngles(); ii++ ){ - computeAmoebaInPlaneAngleForce(ii, positions, amoebaInPlaneAngleForce, expectedForces, expectedEnergy, log ); - } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); - } - (void) fflush( log ); + computeAmoebaInPlaneAngleForce(ii, positions, amoebaInPlaneAngleForce, expectedForces, expectedEnergy); } -#endif - return; - } void compareWithExpectedForceAndEnergy( Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaInPlaneAngleForces( context, amoebaInPlaneAngleForce, expectedForces, &expectedEnergy, log ); + computeAmoebaInPlaneAngleForces( context, amoebaInPlaneAngleForce, expectedForces, &expectedEnergy ); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaInPlaneAngleForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); } ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); } -void testOneAngle( FILE* log ) { +void testOneAngle() { System system; int numberOfParticles = 4; @@ -375,7 +328,7 @@ void testOneAngle( FILE* log ) { positions[3] = Vec3(1, 1, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); + compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle" ); // Try changing the angle parameters and make sure it's still correct. @@ -383,14 +336,14 @@ void testOneAngle( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); + compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle" ); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaInPlaneAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle", log ); + compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle" ); } int main(int argc, char* argv[]) { @@ -399,8 +352,7 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testOneAngle( NULL ); + testOneAngle(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp index 9273189d9..700c53db3 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp @@ -294,45 +294,7 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& static void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if( log ){ - double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); - - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); - - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*absDiff, conversion*relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], conversion*expectedNorm, conversion*norm ); - } - (void) fflush( log ); - conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - + const std::vector& forces, double tolerance ) { for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); } @@ -343,46 +305,7 @@ static void compareForcesEnergy( std::string& testName, double expectedEnergy, d static void compareForceNormsEnergy( std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { - -//#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if( log ){ - double conversion = 1.0/4.184; - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e absDiff=%15.7e relDiff=%15.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy, - conversion*energyAbsDiff, conversion*energyRelDiff ); - if( conversion != 1.0 )conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); - - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( (norm - expectedNorm) ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); - - (void) fprintf( log, "%6u %15.7e %15.7e [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e] %15.7e %15.7e\n", ii, - fabs(conversion)*absDiff, relDiff, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2], - fabs(conversion)*expectedNorm, fabs(conversion)*norm ); - } - (void) fflush( log ); - conversion = 1.0; - (void) fprintf( log, "\n%s: expected energy=%14.7e %14.7e no conversion\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - if( conversion != 1.0 )conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - + const std::vector& forces, double tolerance ) { for( unsigned int ii = 0; ii < forces.size(); ii++ ){ double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + expectedForces[ii][1]*expectedForces[ii][1] + @@ -411,7 +334,7 @@ static void compareForceNormsEnergy( std::string& testName, double expectedEnerg // test multipole direct polarization for system comprised of two ammonia molecules; no cutoff -static void testMultipoleAmmoniaDirectPolarization( FILE* log ) { +static void testMultipoleAmmoniaDirectPolarization() { std::string testName = "testMultipoleAmmoniaDirectPolarization"; @@ -442,12 +365,12 @@ static void testMultipoleAmmoniaDirectPolarization( FILE* log ) { expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test multipole mutual polarization for system comprised of two ammonia molecules; no cutoff -static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { +static void testMultipoleAmmoniaMutualPolarization( ) { std::string testName = "testMultipoleAmmoniaMutualPolarization"; @@ -478,7 +401,7 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); // Try changing the particle parameters and make sure it's still correct. @@ -500,7 +423,7 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log ); + compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance ); for (int i = 0; i < numberOfParticles; i++) ASSERT_EQUAL_VEC(state1.getForces()[i], state2.getForces()[i], tolerance); } @@ -510,7 +433,7 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { ASSERT(exceptionThrown); amoebaMultipoleForce->updateParametersInContext(context); state1 = context.getState(State::Forces | State::Energy); - compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance, log ); + compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance ); } // setup for box of 4 water molecules -- used to test PME @@ -518,7 +441,7 @@ static void testMultipoleAmmoniaMutualPolarization( FILE* log ) { static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, AmoebaMultipoleForce::PolarizationType polarizationType, double cutoff, int inputPmeGridDimension, std::vector& forces, - double& energy, FILE* log ){ + double& energy){ // beginning of Multipole setup @@ -671,7 +594,7 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond // test multipole direct polarization using PME for box of water -static void testMultipoleWaterPMEDirectPolarization( FILE* log ) { +static void testMultipoleWaterPMEDirectPolarization( ) { std::string testName = "testMultipoleWaterDirectPolarization"; @@ -682,7 +605,7 @@ static void testMultipoleWaterPMEDirectPolarization( FILE* log ) { double energy; setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, forces, energy, log ); + cutoff, inputPmeGridDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.4585115e-01; @@ -701,12 +624,12 @@ static void testMultipoleWaterPMEDirectPolarization( FILE* log ) { expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00 ); double tolerance = 1.0e-03; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test multipole mutual polarization using PME for box of water -static void testMultipoleWaterPMEMutualPolarization( FILE* log ) { +static void testMultipoleWaterPMEMutualPolarization( ) { std::string testName = "testMultipoleWaterMutualPolarization"; @@ -717,7 +640,7 @@ static void testMultipoleWaterPMEMutualPolarization( FILE* log ) { double energy; setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, forces, energy, log ); + cutoff, inputPmeGridDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.5029855e-01; @@ -736,12 +659,12 @@ static void testMultipoleWaterPMEMutualPolarization( FILE* log ) { expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00 ); double tolerance = 1.0e-03; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // check validation of traceless/symmetric quadrupole tensor -static void testQuadrupoleValidation( FILE* log ){ +static void testQuadrupoleValidation( ){ std::string testName = "checkQuadrupoleValidation"; @@ -958,7 +881,7 @@ static void testQuadrupoleValidation( FILE* log ){ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, AmoebaMultipoleForce::PolarizationType polarizationType, double cutoff, int inputPmeGridDimension, std::string testName, - std::vector& forces, double& energy, FILE* log ){ + std::vector& forces, double& energy ){ // beginning of Multipole setup @@ -1149,7 +1072,7 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEDirectPolarization( FILE* log ) { +static void testMultipoleIonsAndWaterPMEDirectPolarization( ) { std::string testName = "testMultipoleIonsAndWaterDirectPolarization"; @@ -1161,7 +1084,7 @@ static void testMultipoleIonsAndWaterPMEDirectPolarization( FILE* log ) { double energy; setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, testName, forces, energy, log ); + cutoff, inputPmeGridDimension, testName, forces, energy ); std::vector expectedForces(numberOfParticles); @@ -1177,13 +1100,13 @@ static void testMultipoleIonsAndWaterPMEDirectPolarization( FILE* log ) { expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00 ); double tolerance = 5.0e-04; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEMutualPolarization( FILE* log ) { +static void testMultipoleIonsAndWaterPMEMutualPolarization( ) { std::string testName = "testMultipoleIonsAndWaterMutualPolarization"; @@ -1197,7 +1120,7 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization( FILE* log ) { std::vector inputGrid; setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, forces, energy, log ); + cutoff, inputPmeGridDimension, testName, forces, energy ); std::vector expectedForces(numberOfParticles); @@ -1213,9 +1136,9 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization( FILE* log ) { expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00 ); //double tolerance = 1.0e-03; - //compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + //compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); double tolerance = 5.0e-04; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } @@ -1227,7 +1150,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No std::vector& forces, double& energy, std::vector< double >& outputMultipoleMoments, std::vector< Vec3 >& inputGrid, - std::vector< double >& outputGridPotential, FILE* log ){ + std::vector< double >& outputGridPotential ){ // beginning of Multipole setup @@ -2025,7 +1948,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No // test multipole mutual polarization using PME for box of water -static void testPMEMutualPolarizationLargeWater( FILE* log ) { +static void testPMEMutualPolarizationLargeWater( ) { std::string testName = "testPMEMutualPolarizationLargeWater"; @@ -2040,7 +1963,7 @@ static void testPMEMutualPolarizationLargeWater( FILE* log ) { setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log ); + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential ); static std::vector expectedForces; // Static to work around bug in Visual Studio that makes compilation very very slow. expectedForces.resize(numberOfParticles); @@ -2696,7 +2619,7 @@ static void testPMEMutualPolarizationLargeWater( FILE* log ) { expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } @@ -2736,7 +2659,7 @@ static void testParticleInducedDipoles() { // test computation of system multipole moments -static void testSystemMultipoleMoments( FILE* log ) { +static void testSystemMultipoleMoments( ) { std::string testName = "testSystemMultipoleMoments"; @@ -2752,7 +2675,7 @@ static void testSystemMultipoleMoments( FILE* log ) { setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential, log ); + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential ); std::vector tinkerMoments(4); @@ -2771,9 +2694,6 @@ static void testSystemMultipoleMoments( FILE* log ) { // tinkerMoments[12] = 4.3292490e-02; double tolerance = 1.0e-04; - if( log ){ - (void) fprintf( log, "%s RelativeDifference Tinker OpenMM\n", testName.c_str() ); - } for( unsigned int ii = 0; ii < tinkerMoments.size(); ii++ ){ double difference; if( fabs( tinkerMoments[ii] ) > 0.0 ){ @@ -2781,10 +2701,6 @@ static void testSystemMultipoleMoments( FILE* log ) { } else { difference = fabs( outputMultipoleMoments[ii] - tinkerMoments[ii] ); } - if( log ){ - (void) fprintf( log, "%2d %15.7e %15.7e %15.7e\n", ii, difference, tinkerMoments[ii], outputMultipoleMoments[ii] ); - } - if( difference > tolerance ){ std::stringstream details; details << testName << "Multipole moment " << ii << " does not agree w/ TINKER computed moments: OpenMM=" << outputMultipoleMoments[ii]; @@ -2798,7 +2714,7 @@ static void testSystemMultipoleMoments( FILE* log ) { // test computation of multipole potential on a grid -static void testMultipoleGridPotential( FILE* log ) { +static void testMultipoleGridPotential( ) { std::string testName = "testMultipoleGridPotential"; @@ -2847,7 +2763,7 @@ static void testMultipoleGridPotential( FILE* log ) { setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension, testName, forces, energy, - outputMultipoleMoments, inputGrid, outputGridPotential, log ); + outputMultipoleMoments, inputGrid, outputGridPotential ); // TINKER computed grid values @@ -2943,7 +2859,7 @@ static void testNoQuadrupoles(bool usePme) { double energy3; getForcesEnergyMultipoleAmmonia(context2, forces3, energy3); double tolerance = 1e-5; - compareForcesEnergy(testName, energy2, energy3, forces2, forces3, tolerance, NULL); + compareForcesEnergy(testName, energy2, energy3, forces2, forces3, tolerance); // If we try to set a quadrupole, that should produce and exception. @@ -3144,31 +3060,29 @@ int main(int argc, char* argv[]) { if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - // tests using two ammonia molecules // test direct polarization, no cutoff - testMultipoleAmmoniaDirectPolarization( log ); + testMultipoleAmmoniaDirectPolarization(); // test mutual polarization, no cutoff - testMultipoleAmmoniaMutualPolarization( log ); + testMultipoleAmmoniaMutualPolarization(); // test multipole direct & mutual polarization using PME - testMultipoleWaterPMEDirectPolarization( log ); - testMultipoleWaterPMEMutualPolarization( log ); + testMultipoleWaterPMEDirectPolarization(); + testMultipoleWaterPMEMutualPolarization(); // check validation of traceless/symmetric quadrupole tensor - testQuadrupoleValidation( log ); + testQuadrupoleValidation(); // system w/ 2 ions and 2 water molecules - testMultipoleIonsAndWaterPMEMutualPolarization( log ); - testMultipoleIonsAndWaterPMEDirectPolarization( log ); + testMultipoleIonsAndWaterPMEMutualPolarization(); + testMultipoleIonsAndWaterPMEDirectPolarization(); // test querying induced dipoles @@ -3176,14 +3090,14 @@ int main(int argc, char* argv[]) { // test computation of system multipole moments - testSystemMultipoleMoments( log ); + testSystemMultipoleMoments(); // test computation of grid potential - testMultipoleGridPotential( log ); + testMultipoleGridPotential(); // large box of water - testPMEMutualPolarizationLargeWater( log ); + testPMEMutualPolarizationLargeWater(); testNoQuadrupoles(false); testNoQuadrupoles(true); diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp index bea4f2e2e..687560c88 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp @@ -78,7 +78,7 @@ static double dotVector3( double* vectorX, double* vectorY ){ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& positions, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy ) { double kAngleCubic = amoebaOutOfPlaneBendForce.getAmoebaGlobalOutOfPlaneBendCubic(); @@ -90,14 +90,6 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& double kAngleQuadratic; amoebaOutOfPlaneBendForce.getOutOfPlaneBendParameters(bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic ); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForce: bond %d [%d %d %d %d] k=[%10.3e %10.3e %10.3e %10.3e %10.3e]\n", - bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic, kAngleCubic, kAngleQuartic, kAnglePentic, kAngleSextic ); - (void) fflush( log ); - } -#endif - enum { A, B, C, D, LastAtomIndex }; enum { AB, CB, DB, AD, CD, LastDeltaIndex }; @@ -138,14 +130,6 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& } else { angle = RADIAN*acos(cosine); } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForce: bkk2=%14.7e rDB2=%14.7e cos=%14.7e dt=%14.7e]\n", - bkk2, rDB2, cosine, angle ); - (void) fflush( log ); - } -#endif // chain rule @@ -242,7 +226,7 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& } static void computeAmoebaOutOfPlaneBendForces( Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { + std::vector& expectedForces, double* expectedEnergy ) { // get positions and zero forces @@ -258,51 +242,26 @@ static void computeAmoebaOutOfPlaneBendForces( Context& context, AmoebaOutOfPlan *expectedEnergy = 0.0; for( int ii = 0; ii < amoebaOutOfPlaneBendForce.getNumOutOfPlaneBends(); ii++ ){ - computeAmoebaOutOfPlaneBendForce(ii, positions, amoebaOutOfPlaneBendForce, expectedForces, expectedEnergy, log ); - } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); - } - (void) fflush( log ); + computeAmoebaOutOfPlaneBendForce(ii, positions, amoebaOutOfPlaneBendForce, expectedForces, expectedEnergy); } -#endif - - return; - } void compareWithExpectedForceAndEnergy( Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaOutOfPlaneBendForces( context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy, log ); + computeAmoebaOutOfPlaneBendForces( context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy ); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); } ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); } -void testOneOutOfPlaneBend( FILE* log ) { +void testOneOutOfPlaneBend( ) { System system; int numberOfParticles = 4; @@ -334,7 +293,7 @@ void testOneOutOfPlaneBend( FILE* log ) { positions[3] = Vec3( 0.245568230E+02, 0.250215290E+02, 0.796852800E+01 ); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); // Try changing the bend parameters and make sure it's still correct. @@ -342,17 +301,17 @@ void testOneOutOfPlaneBend( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaOutOfPlaneBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); } -void testOneOutOfPlaneBend2( FILE* log, int setId ) { +void testOneOutOfPlaneBend2(int setId ) { System system; int numberOfParticles = 4; @@ -436,21 +395,10 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { particleIndices.push_back( 442 ); kOutOfPlaneBend = 0.214755281E-01; } else { -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "Set id %d not recognized.\n", setId ); - } -#endif std::stringstream buffer; buffer << "Set id " << setId << " not recognized."; throw OpenMMException( buffer.str() ); } -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "Set id %d.\n", setId ); - } -#endif - amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend ); system.addForce(amoebaOutOfPlaneBendForce); @@ -459,12 +407,6 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ if( coordinates.find( particleIndices[ii] ) == coordinates.end() ){ -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "Coordinates %d not loaded.", particleIndices[ii] ); - } -#endif - std::stringstream buffer; buffer << "Coordinates " << particleIndices[ii] << " not loaded."; throw OpenMMException( buffer.str() ); @@ -473,7 +415,7 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { } context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend", log ); + compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); static int iter = 0; static std::map totalForces; @@ -496,7 +438,7 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { std::vector forces; forces.resize( numberOfParticles ); double energy; - computeAmoebaOutOfPlaneBendForce( 0, positions, *amoebaOutOfPlaneBendForce, forces, &energy, log ); + computeAmoebaOutOfPlaneBendForce( 0, positions, *amoebaOutOfPlaneBendForce, forces, &energy); totalEnergy += energy; for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ @@ -504,22 +446,6 @@ void testOneOutOfPlaneBend2( FILE* log, int setId ) { totalForces[particleIndices[ii]][jj] += forces[ii][jj]; } } - - if( iter == 6 ){ -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaOutOfPlaneBendForces: energy=%14.7e\n", totalEnergy); - for( std::map::iterator ii = totalForces.begin(); ii != totalForces.end(); ii++ ){ - int particleIndex = ii->first; - Vec3 forces = ii->second; - (void) fprintf( log, "%6d [%14.7e %14.7e %14.7e] \n", particleIndex, - forces[0], forces[1], forces[2] ); - } - (void) fflush( log ); - } -#endif - } - } int main(int argc, char* argv[]) { @@ -528,9 +454,8 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testOneOutOfPlaneBend( log ); + testOneOutOfPlaneBend(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp index d26d5d359..836423530 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp @@ -78,21 +78,13 @@ static double dotVector3( double* vectorX, double* vectorY ){ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& positions, AmoebaPiTorsionForce& amoebaPiTorsionForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy) { int particle1, particle2, particle3, particle4, particle5, particle6; double kTorsion; amoebaPiTorsionForce.getPiTorsionParameters(bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaPiTorsionForce: bond %d [%d %d %d %d %d %d] k=%10.3e\n", - bondIndex, particle1, particle2, particle3, particle4, particle5, particle6, kTorsion ); - (void) fflush( log ); - } -#endif - enum { AD, BD, EC, FC, P, Q, CP, DC, QD, T, U, TU, DP, QC, dT, dU, dP, dQ, dC1, dC2, dD1, dD2, LastDeltaIndex }; double deltaR[LastDeltaIndex][3]; @@ -213,7 +205,7 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit } static void computeAmoebaPiTorsionForces( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { + std::vector& expectedForces, double* expectedEnergy ) { // get positions and zero forces @@ -229,50 +221,27 @@ static void computeAmoebaPiTorsionForces( Context& context, AmoebaPiTorsionForce *expectedEnergy = 0.0; for( int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++ ){ - computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy, log ); - } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaPiTorsionForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); - } - (void) fflush( log ); + computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy); } -#endif - return; - } void compareWithExpectedForceAndEnergy( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaPiTorsionForces( context, amoebaPiTorsionForce, expectedForces, &expectedEnergy, log ); + computeAmoebaPiTorsionForces( context, amoebaPiTorsionForce, expectedForces, &expectedEnergy ); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaPiTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); } ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); } -void testOnePiTorsion( FILE* log ) { +void testOnePiTorsion() { System system; int numberOfParticles = 6; @@ -301,7 +270,7 @@ void testOnePiTorsion( FILE* log ) { positions[5] = Vec3( 0.254124630E+02, 0.234691880E+02, 0.773335400E+01 ); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); + compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); // Try changing the torsion parameters and make sure it's still correct. @@ -309,14 +278,14 @@ void testOnePiTorsion( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); + compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaPiTorsionForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion", log ); + compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion" ); } int main(int argc, char* argv[]) { @@ -325,8 +294,7 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testOnePiTorsion( log ); + testOnePiTorsion(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp index f5a683c2d..fd8725cfe 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp @@ -79,21 +79,13 @@ static double dotVector3( double* vectorX, double* vectorY ){ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& positions, AmoebaStretchBendForce& amoebaStretchBendForce, - std::vector& forces, double* energy, FILE* log ) { + std::vector& forces, double* energy) { int particle1, particle2, particle3; double abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend; amoebaStretchBendForce.getStretchBendParameters(bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend); angleStretchBend *= RADIAN; -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForce: bond %d [%d %d %d] ab=%10.3e cb=%10.3e angle=%10.3e k1=%10.3e k2=%10.3e\n", - bondIndex, particle1, particle2, particle3, abBondLength, cbBondLength, angleStretchBend, kStretchBend, k2StretchBend ); - (void) fflush( log ); - } -#endif - enum { A, B, C, LastAtomIndex }; enum { AB, CB, CBxAB, ABxP, CBxP, LastDeltaIndex }; @@ -188,18 +180,10 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos forces[particle3][2] -= subForce[2][2]; *energy += dt*drkk; -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForce: angle=%10.3e dt=%10.3e dr=%10.3e\n", angle, dt, dr ); - (void) fflush( log ); - } -#endif - - return; } static void computeAmoebaStretchBendForces( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, - std::vector& expectedForces, double* expectedEnergy, FILE* log ) { + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces @@ -215,50 +199,26 @@ static void computeAmoebaStretchBendForces( Context& context, AmoebaStretchBendF *expectedEnergy = 0.0; for( int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++ ){ - computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy, log ); - } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForces: expected energy=%14.7e\n", *expectedEnergy ); - for( unsigned int ii = 0; ii < positions.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e]\n", ii, expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2] ); - } - (void) fflush( log ); + computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy ); } -#endif - return; - } void compareWithExpectedForceAndEnergy( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, - double tolerance, const std::string& idString, FILE* log) { + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaStretchBendForces( context, amoebaStretchBendForce, expectedForces, &expectedEnergy, log ); + computeAmoebaStretchBendForces( context, amoebaStretchBendForce, expectedForces, &expectedEnergy ); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaStretchBendForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); } ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); } -void testOneStretchBend( FILE* log ) { +void testOneStretchBend() { System system; int numberOfParticles = 3; @@ -288,7 +248,7 @@ void testOneStretchBend( FILE* log ) { positions[2] = Vec3( 0.269573220E+02, 0.236108860E+02, 0.216376800E+01 ); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); + compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend" ); // Try changing the stretch-bend parameters and make sure it's still correct. @@ -296,14 +256,14 @@ void testOneStretchBend( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); + compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend" ); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaStretchBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend", log ); + compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend" ); } int main(int argc, char* argv[]) { @@ -312,8 +272,7 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testOneStretchBend( log ); + testOneStretchBend(); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp index 3bbfff2f4..556783682 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp @@ -2584,7 +2584,7 @@ TorsionTorsionGrid& getTorsionGrid( int gridIndex ) { return grids[gridIndex]; } -void testTorsionTorsion( FILE* log, int systemId ) { +void testTorsionTorsion(int systemId) { System system; int numberOfParticles = 6; @@ -2660,19 +2660,6 @@ void testTorsionTorsion( FILE* log, int systemId ) { forces[ii][1] *= conversion; forces[ii][2] *= conversion; } - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaTorsionTorsionForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], - forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - double tolerance = 1.0e-03; for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); @@ -2687,8 +2674,7 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testTorsionTorsion( log, 1 ); + testTorsionTorsion(1); } catch(const std::exception& e) { std::cout << "exception: " << e.what() << std::endl; std::cout << "FAIL - ERROR. Test failed." << std::endl; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp index 03c4c6c4d..d1e0248b7 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp @@ -57,7 +57,7 @@ extern "C" void registerAmoebaCudaKernelFactories(); const double TOL = 1e-4; -void testVdw( FILE* log ) { +void testVdw() { System system; int numberOfParticles = 6; @@ -159,18 +159,6 @@ void testVdw( FILE* log ) { forces[ii][2] *= conversion; } expectedEnergy *= CalToJoule; - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "computeAmoebaVdwForces: expected energy=%14.7e %14.7e\n", expectedEnergy, state.getPotentialEnergy() ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - double tolerance = 1.0e-03; for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); @@ -208,7 +196,7 @@ void testVdw( FILE* log ) { } void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, - double boxDimension, std::vector& forces, double& energy, FILE* log ){ + double boxDimension, std::vector& forces, double& energy){ // beginning of Vdw setup @@ -343,24 +331,7 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - std::vector& forces, double tolerance, FILE* log ) { - - -#define AMOEBA_DEBUG -#ifdef AMOEBA_DEBUG - if( log ){ - double conversion = 1.0/4.184; - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e\n", testName.c_str(), conversion*expectedEnergy, conversion*energy ); - conversion *= -0.1; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - conversion*expectedForces[ii][0], conversion*expectedForces[ii][1], conversion*expectedForces[ii][2], - conversion*forces[ii][0], conversion*forces[ii][1], conversion*forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - + std::vector& forces, double tolerance) { for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); } @@ -369,7 +340,7 @@ void compareForcesEnergy( std::string& testName, double expectedEnergy, double e // test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG -void testVdwAmmoniaCubicMeanHhg( FILE* log ) { +void testVdwAmmoniaCubicMeanHhg() { std::string testName = "testVdwAmmoniaCubicMeanHhg"; @@ -379,7 +350,7 @@ void testVdwAmmoniaCubicMeanHhg( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.8012258e+00; @@ -394,12 +365,12 @@ void testVdwAmmoniaCubicMeanHhg( FILE* log ) { expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic -void testVdwAmmoniaArithmeticArithmetic( FILE* log ) { +void testVdwAmmoniaArithmeticArithmetic() { std::string testName = "testVdwAmmoniaArithmeticArithmetic"; @@ -409,7 +380,7 @@ void testVdwAmmoniaArithmeticArithmetic( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia( "ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.2252403e+00; @@ -424,12 +395,12 @@ void testVdwAmmoniaArithmeticArithmetic( FILE* log ) { expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test VDW w/ sigmaRule=Geometric and epsilonRule=Geometric -void testVdwAmmoniaGeometricGeometric( FILE* log ) { +void testVdwAmmoniaGeometricGeometric( ) { std::string testName = "testVdwAmmoniaGeometricGeometric"; @@ -438,7 +409,7 @@ void testVdwAmmoniaGeometricGeometric( FILE* log ) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia( "GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 2.5249914e+00; @@ -453,10 +424,10 @@ void testVdwAmmoniaGeometricGeometric( FILE* log ) { expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } -void testVdwAmmoniaCubicMeanHarmonic( FILE* log ) { +void testVdwAmmoniaCubicMeanHarmonic( ) { std::string testName = "testVdwAmmoniaCubicMeanHarmonic"; @@ -465,7 +436,7 @@ void testVdwAmmoniaCubicMeanHarmonic( FILE* log ) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.1369069e+00; @@ -480,14 +451,14 @@ void testVdwAmmoniaCubicMeanHarmonic( FILE* log ) { expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test w/ cutoff=0.25 nm; single ixn between two particles (0 and 6); force nonzero on // particle 4 due to reduction applied to NH // the distance between 0 and 6 is ~ 0.235 so the ixn is in the tapered region -void testVdwTaper( FILE* log ) { +void testVdwTaper( ) { std::string testName = "testVdwTaper"; @@ -497,7 +468,7 @@ void testVdwTaper( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 3.5478444e+00; @@ -512,12 +483,12 @@ void testVdwTaper( FILE* log ) { expectedForces[7] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // test PBC -void testVdwPBC( FILE* log ) { +void testVdwPBC( ) { std::string testName = "testVdwPBC"; @@ -527,7 +498,7 @@ void testVdwPBC( FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy, log ); + setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy ); std::vector expectedForces(numberOfParticles); double expectedEnergy = 1.4949141e+01; @@ -545,14 +516,14 @@ void testVdwPBC( FILE* log ) { // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); } // create box of 216 water molecules void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, double boxDimension, int includeVdwDispersionCorrection, - std::vector& forces, double& energy, FILE* log ){ + std::vector& forces, double& energy ){ // beginning of Vdw setup @@ -1271,7 +1242,7 @@ void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, con // test employing box of 216 water molecules w/ and w/o dispersion correction -void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { +void testVdwWater( int includeVdwDispersionCorrection ) { std::string testName; @@ -1287,7 +1258,7 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwWater( "CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log ); + setupAndGetForcesEnergyVdwWater( "CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy ); std::vector expectedForces(numberOfParticles); // initialize expected energy and forces @@ -1952,7 +1923,7 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); // test sigma/epsilon rules for dispersion correction @@ -1975,7 +1946,7 @@ void testVdwWater( int includeVdwDispersionCorrection, FILE* log ) { expectedEnergies.push_back( 3.2774624e+03 ); for( unsigned int ii = 0; ii < sigmaRules.size(); ii++ ){ - setupAndGetForcesEnergyVdwWater( sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy, log ); + setupAndGetForcesEnergyVdwWater( sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy ); testName = "testVdwWaterWithDispersionCorrection_" + sigmaRules[ii] + '_' + epsilonRules[ii]; ASSERT_EQUAL_TOL_MOD( expectedEnergies[ii], energy, tolerance, testName ); } @@ -2045,48 +2016,47 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; - testVdw( log ); + testVdw(); // tests using two ammonia molecules // test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG - testVdwAmmoniaCubicMeanHhg( log ); + testVdwAmmoniaCubicMeanHhg(); // test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic - testVdwAmmoniaArithmeticArithmetic( log ); + testVdwAmmoniaArithmeticArithmetic(); // test VDW w/ sigmaRule=Geometric and epsilonRule=Geometric - testVdwAmmoniaGeometricGeometric( log ); + testVdwAmmoniaGeometricGeometric(); // test VDW w/ sigmaRule=CubicMean and epsilonRule=Harmonic - testVdwAmmoniaCubicMeanHarmonic( log ); + testVdwAmmoniaCubicMeanHarmonic(); // test w/ cutoff=0.25 nm; single ixn between two particles (0 and 6); force nonzero on // particle 4 due to reduction applied to NH // the distance between 0 and 6 is ~ 0.235 so the ixn is in the tapered region - testVdwTaper( log ); + testVdwTaper(); // test PBC - testVdwPBC( log ); + testVdwPBC(); // tests based on box of water int includeVdwDispersionCorrection = 0; - testVdwWater( includeVdwDispersionCorrection, log ); + testVdwWater( includeVdwDispersionCorrection); // includes tests for various combinations of sigma/epsilon rules // when computing vdw dispersion correction includeVdwDispersionCorrection = 1; - testVdwWater( includeVdwDispersionCorrection, log ); + testVdwWater( includeVdwDispersionCorrection); // test triclinic boxes diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp index 78f541e09..97c61ea8d 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp @@ -56,19 +56,7 @@ extern "C" void registerAmoebaCudaKernelFactories(); void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, const std::vector& expectedForces, - const std::vector& forces, double tolerance, FILE* log ) { - -#ifdef AMOEBA_DEBUG - if( log ){ - (void) fprintf( log, "%s: expected energy=%14.7e %14.7e\n", testName.c_str(), expectedEnergy, energy ); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - (void) fprintf( log, "%6u [%14.7e %14.7e %14.7e] [%14.7e %14.7e %14.7e]\n", ii, - expectedForces[ii][0], expectedForces[ii][1], expectedForces[ii][2], forces[ii][0], forces[ii][1], forces[ii][2] ); - } - (void) fflush( log ); - } -#endif - + const std::vector& forces, double tolerance) { for( unsigned int ii = 0; ii < forces.size(); ii++ ){ ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); } @@ -77,7 +65,7 @@ void compareForcesEnergy( std::string& testName, double expectedEnergy, double e // test Wca dispersion -void testWcaDispersionAmmonia( FILE* log ) { +void testWcaDispersionAmmonia() { std::string testName = "testWcaDispersionAmmonia"; @@ -151,7 +139,7 @@ void testWcaDispersionAmmonia( FILE* log ) { expectedForces[7] = Vec3( -1.1888087e+00, 1.2889802e+00, -3.8615387e-01 ); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance, log ); + compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); // Try changing the particle parameters and make sure it's still correct. @@ -168,7 +156,7 @@ void testWcaDispersionAmmonia( FILE* log ) { bool exceptionThrown = false; try { // This should throw an exception. - compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(), state2.getForces(), tolerance, log); + compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(), state2.getForces(), tolerance); } catch (std::exception ex) { exceptionThrown = true; @@ -176,7 +164,7 @@ void testWcaDispersionAmmonia( FILE* log ) { ASSERT(exceptionThrown); amoebaWcaDispersionForce->updateParametersInContext(context); state1 = context.getState(State::Forces | State::Energy); - compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(), state2.getForces(), tolerance, log); + compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(), state2.getForces(), tolerance); } int main(int argc, char* argv[]) { @@ -185,11 +173,10 @@ int main(int argc, char* argv[]) { registerAmoebaCudaKernelFactories(); if (argc > 1) Platform::getPlatformByName("CUDA").setPropertyDefaultValue("CudaPrecision", std::string(argv[1])); - FILE* log = NULL; // test Wca dispersion force using two ammonia molecules - testWcaDispersionAmmonia( log ); + testWcaDispersionAmmonia(); } catch(const std::exception& e) { diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp index 2470be5bd..475303e59 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp @@ -60,14 +60,6 @@ void testSerialization() { stringstream buffer; XmlSerializer::serialize(&force1, "Force", buffer); -#ifdef AMOEBA_DEBUG - if( 0 ){ - FILE* filePtr = fopen("GeneralizedKirkwood.xml", "w" ); - (void) fprintf( filePtr, "%s", buffer.str().c_str() ); - (void) fclose( filePtr ); - } -#endif - AmoebaGeneralizedKirkwoodForce* copy = XmlSerializer::deserialize(buffer); // Compare the two forces to see if they are identical. diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp index 8eb0c6f3c..35f28a34e 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp @@ -99,13 +99,6 @@ void testSerialization() { stringstream buffer; XmlSerializer::serialize(&force1, "Force", buffer); -#ifdef AMOEBA_DEBUG - if( 0 ){ - FILE* filePtr = fopen("Multipole.xml", "w" ); - (void) fprintf( filePtr, "%s", buffer.str().c_str() ); - (void) fclose( filePtr ); - } -#endif AmoebaMultipoleForce* copy = XmlSerializer::deserialize(buffer); diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp index ec5d06e8a..a70812b77 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp @@ -94,14 +94,6 @@ void testSerialization() { stringstream buffer; XmlSerializer::serialize(&force1, "Force", buffer); -#ifdef AMOEBA_DEBUG - if( 0 ){ - FILE* filePtr = fopen("TorsionTorsion.xml", "w" ); - (void) fprintf( filePtr, "%s", buffer.str().c_str() ); - (void) fclose( filePtr ); - } -#endif - AmoebaTorsionTorsionForce* copy = XmlSerializer::deserialize(buffer); // Compare the two force1s to see if they are identical. diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp index d8780353e..b63f74d96 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp @@ -65,14 +65,6 @@ void testSerialization() { stringstream buffer; XmlSerializer::serialize(&force1, "Force", buffer); -#ifdef AMOEBA_DEBUG - if( 0 ){ - FILE* filePtr = fopen("Vdw.xml", "w" ); - (void) fprintf( filePtr, "%s", buffer.str().c_str() ); - (void) fclose( filePtr ); - } -#endif - AmoebaVdwForce* copy = XmlSerializer::deserialize(buffer); // Compare the two forces to see if they are identical. diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp index b3c25af40..b52a95291 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp @@ -62,14 +62,6 @@ void testSerialization() { stringstream buffer; XmlSerializer::serialize(&force1, "Force", buffer); -#ifdef AMOEBA_DEBUG - if( 0 ){ - FILE* filePtr = fopen("WcaDispersion.xml", "w" ); - (void) fprintf( filePtr, "%s", buffer.str().c_str() ); - (void) fclose( filePtr ); - } -#endif - AmoebaWcaDispersionForce* copy = XmlSerializer::deserialize(buffer); // Compare the two forces to see if they are identical. -- GitLab From d95b90b9c9eb873a3837e5e589764e2585c18c81 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 23 Feb 2015 15:17:50 -0800 Subject: [PATCH 286/338] Cleaned up formatting in AMOEBA code --- libraries/validate/include/ValidateOpenMM.h | 4 +- .../validate/include/ValidateOpenMMForces.h | 72 +- libraries/validate/src/ValidateOpenMM.cpp | 4 +- .../validate/src/ValidateOpenMMForces.cpp | 24 +- .../include/openmm/AmoebaAngleForce.h | 16 +- .../include/openmm/AmoebaBondForce.h | 12 +- .../openmm/AmoebaGeneralizedKirkwoodForce.h | 2 +- .../include/openmm/AmoebaInPlaneAngleForce.h | 16 +- .../include/openmm/AmoebaStretchBendForce.h | 2 +- .../openmmapi/include/openmm/amoebaKernels.h | 6 +- .../internal/AmoebaMultipoleForceImpl.h | 14 +- .../internal/AmoebaTorsionTorsionForceImpl.h | 2 +- .../internal/AmoebaWcaDispersionForceImpl.h | 4 +- .../amoeba/openmmapi/src/AmoebaAngleForce.cpp | 12 +- .../amoeba/openmmapi/src/AmoebaBondForce.cpp | 10 +- .../src/AmoebaGeneralizedKirkwoodForce.cpp | 8 +- .../openmmapi/src/AmoebaInPlaneAngleForce.cpp | 16 +- .../openmmapi/src/AmoebaMultipoleForce.cpp | 56 +- .../src/AmoebaMultipoleForceImpl.cpp | 48 +- .../src/AmoebaOutOfPlaneBendForce.cpp | 10 +- .../openmmapi/src/AmoebaPiTorsionForce.cpp | 4 +- .../openmmapi/src/AmoebaStretchBendForce.cpp | 2 +- .../src/AmoebaTorsionTorsionForce.cpp | 8 +- .../src/AmoebaTorsionTorsionForceImpl.cpp | 50 +- .../amoeba/openmmapi/src/AmoebaVdwForce.cpp | 34 +- .../src/AmoebaWcaDispersionForce.cpp | 24 +- .../src/AmoebaWcaDispersionForceImpl.cpp | 21 +- .../platforms/cuda/src/AmoebaCudaKernels.cpp | 10 +- .../platforms/cuda/src/AmoebaCudaKernels.h | 4 +- .../platforms/cuda/src/kernels/bicubic.cu | 10 +- .../cuda/tests/TestCudaAmoebaAngleForce.cpp | 78 +- .../cuda/tests/TestCudaAmoebaBondForce.cpp | 54 +- ...TestCudaAmoebaGeneralizedKirkwoodForce.cpp | 386 +- .../tests/TestCudaAmoebaInPlaneAngleForce.cpp | 124 +- .../tests/TestCudaAmoebaMultipoleForce.cpp | 3607 ++++++++--------- .../TestCudaAmoebaOutOfPlaneBendForce.cpp | 238 +- .../tests/TestCudaAmoebaPiTorsionForce.cpp | 114 +- .../tests/TestCudaAmoebaStretchBendForce.cpp | 74 +- .../TestCudaAmoebaTorsionTorsionForce.cpp | 86 +- .../cuda/tests/TestCudaAmoebaVdwForce.cpp | 3046 +++++++------- .../cuda/tests/TestCudaWcaDispersionForce.cpp | 82 +- .../reference/src/AmoebaReferenceKernels.cpp | 26 +- .../AmoebaReferenceInPlaneAngleForce.cpp | 4 +- .../AmoebaReferenceOutOfPlaneBendForce.cpp | 2 +- .../AmoebaReferencePiTorsionForce.cpp | 28 +- .../AmoebaReferenceTorsionTorsionForce.cpp | 14 +- .../SimTKReference/AmoebaReferenceVdwForce.h | 4 +- .../tests/TestReferenceAmoebaAngleForce.cpp | 2 +- ...eferenceAmoebaGeneralizedKirkwoodForce.cpp | 104 +- .../TestReferenceAmoebaInPlaneAngleForce.cpp | 14 +- .../TestReferenceAmoebaMultipoleForce.cpp | 2852 ++++++------- ...TestReferenceAmoebaOutOfPlaneBendForce.cpp | 54 +- .../TestReferenceAmoebaPiTorsionForce.cpp | 28 +- ...TestReferenceAmoebaTorsionTorsionForce.cpp | 20 +- .../tests/TestReferenceAmoebaVdwForce.cpp | 2746 ++++++------- .../tests/TestReferenceWcaDispersionForce.cpp | 62 +- .../src/AmoebaAngleForceProxy.cpp | 8 +- .../src/AmoebaBondForceProxy.cpp | 2 +- .../AmoebaGeneralizedKirkwoodForceProxy.cpp | 28 +- .../src/AmoebaInPlaneAngleForceProxy.cpp | 8 +- .../src/AmoebaMultipoleForceProxy.cpp | 114 +- .../src/AmoebaOutOfPlaneBendForceProxy.cpp | 6 +- .../src/AmoebaPiTorsionForceProxy.cpp | 2 +- .../src/AmoebaStretchBendForceProxy.cpp | 2 +- .../src/AmoebaTorsionTorsionForceProxy.cpp | 58 +- .../serialization/src/AmoebaVdwForceProxy.cpp | 16 +- .../src/AmoebaWcaDispersionForceProxy.cpp | 20 +- .../tests/TestSerializeAmoebaAngleForce.cpp | 8 +- .../tests/TestSerializeAmoebaBondForce.cpp | 4 +- ...erializeAmoebaGeneralizedKirkwoodForce.cpp | 16 +- .../TestSerializeAmoebaInPlaneAngleForce.cpp | 10 +- .../TestSerializeAmoebaMultipoleForce.cpp | 98 +- ...TestSerializeAmoebaOutOfPlaneBendForce.cpp | 8 +- ...TestSerializeAmoebaTorsionTorsionForce.cpp | 46 +- .../tests/TestSerializeAmoebaVdwForce.cpp | 28 +- .../TestSerializeAmoebaWcaDispersionForce.cpp | 20 +- .../amoeba/wrappers/generateAmoebaWrappers.py | 30 +- 77 files changed, 7430 insertions(+), 7456 deletions(-) diff --git a/libraries/validate/include/ValidateOpenMM.h b/libraries/validate/include/ValidateOpenMM.h index 9ee3d022d..9e02afb57 100644 --- a/libraries/validate/include/ValidateOpenMM.h +++ b/libraries/validate/include/ValidateOpenMM.h @@ -83,7 +83,7 @@ typedef StringStringVectorMap::const_iterator StringStringVectorMapCI; class ValidateOpenMM { public: - ValidateOpenMM( void ); + ValidateOpenMM(); ~ValidateOpenMM(); // force names @@ -166,7 +166,7 @@ public: * @return log * */ - FILE* getLog( ) const; + FILE* getLog() const; /** * diff --git a/libraries/validate/include/ValidateOpenMMForces.h b/libraries/validate/include/ValidateOpenMMForces.h index a2278c58b..6daa94b19 100644 --- a/libraries/validate/include/ValidateOpenMMForces.h +++ b/libraries/validate/include/ValidateOpenMMForces.h @@ -41,7 +41,7 @@ typedef MapIntInt::const_iterator MapIntIntCI; class ForceValidationResult { public: - ForceValidationResult( const Context& context1, const Context& context2, StringUIntMap& forceNamesMap ); + ForceValidationResult(const Context& context1, const Context& context2, StringUIntMap& forceNamesMap); ~ForceValidationResult(); /** @@ -51,7 +51,7 @@ public: * * @throws OpenMMException if energyIndex is not 0 or 1 */ - double getPotentialEnergy( int energyIndex ) const; + double getPotentialEnergy(int energyIndex) const; /** * Get array of forces at specified platform index (0 || 1) @@ -60,7 +60,7 @@ public: * * @throws OpenMMException if forceIndex is not 0 or 1 */ - std::vector getForceNorms( int forceIndex ) const; + std::vector getForceNorms(int forceIndex) const; /** * Get array of forces at platform index (0 || 1) @@ -69,7 +69,7 @@ public: * * @throws OpenMMException if forceIndex is not 0 or 1 */ - std::vector getForces( int forceIndex ) const; + std::vector getForces(int forceIndex) const; /** * Get maximum delta in force norm @@ -78,7 +78,7 @@ public: * * @return max delta in norm of forces */ - double getMaxDeltaForceNorm( int* maxIndex = NULL ) const; + double getMaxDeltaForceNorm(int* maxIndex = NULL) const; /** * Get maximum relative delta in force norm @@ -87,7 +87,7 @@ public: * * @return max relative delta in norm of forces */ - double getMaxRelativeDeltaForceNorm( int* maxIndex = NULL ) const; + double getMaxRelativeDeltaForceNorm(int* maxIndex = NULL) const; /** * Get maximum dot product between forces @@ -96,7 +96,7 @@ public: * * @return max dot product between forces */ - double getMaxDotProduct( int* maxIndex = NULL ) const; + double getMaxDotProduct(int* maxIndex = NULL) const; /** * Get name of force associated w/ computed results @@ -104,7 +104,7 @@ public: * @return force name(s); if more than one force active in computation, * then names are concatenated and separated by '::' (e.g., 'NB_FORCE::GBSA_OBC_FORCE') */ - std::string getForceName( void ) const; + std::string getForceName() const; /** * Get platform name @@ -115,7 +115,7 @@ public: * * @throws OpenMMException if index is not 0 or 1 */ - std::string getPlatformName( int index ) const; + std::string getPlatformName(int index) const; /** * Register index of two entries that differ by a specified tolerance @@ -123,46 +123,46 @@ public: * @param index inconsistent index * */ - void registerInconsistentForceIndex( int index, int value = 1 ); + void registerInconsistentForceIndex(int index, int value = 1); /** * Clear list of entries that differ by a specified tolerance * */ - void clearInconsistentForceIndexList( void ); + void clearInconsistentForceIndexList(); /** * Get list of entries that differ by a specified tolerance * */ - void getInconsistentForceIndexList( std::vector& inconsistentIndices ) const; + void getInconsistentForceIndexList(std::vector& inconsistentIndices) const; /** * Get number of entries in inconsistent index list * */ - int getNumberOfInconsistentForceEntries( void ) const; + int getNumberOfInconsistentForceEntries() const; /** * Return true if nans were detected * * @return true if nans were detected */ - int nansDetected( void ) const; + int nansDetected() const; /** * Determine if force norms are valid * * @param tolerance tolerance */ - void compareForceNorms( double tolerance ); + void compareForceNorms(double tolerance); /** * Determine if forces are valid * * @param tolerance tolerance */ - void compareForces( double tolerance ); + void compareForces(double tolerance); private: @@ -193,13 +193,13 @@ private: * Calculate norms of vectors * */ - void _calculateNorms( void ); + void _calculateNorms(); /** * Calculate norms of specified vector * */ - void _calculateNormOfForceVector( int forceIndex ); + void _calculateNormOfForceVector(int forceIndex); // stat indices @@ -216,7 +216,7 @@ private: * Find vector stats * */ - void _findStatsForDouble( const std::vector& array, std::vector& statVector ) const; + void _findStatsForDouble(const std::vector& array, std::vector& statVector) const; }; // Class used to compare forces/potential energies on two platforms @@ -224,7 +224,7 @@ private: class ValidateOpenMMForces : public ValidateOpenMM { public: - OPENMM_VALIDATE_EXPORT ValidateOpenMMForces( void ); + OPENMM_VALIDATE_EXPORT ValidateOpenMMForces(); OPENMM_VALIDATE_EXPORT ~ValidateOpenMMForces(); /** @@ -236,7 +236,7 @@ public: * * @return number of inconsistent entries */ - int OPENMM_VALIDATE_EXPORT compareWithReferencePlatform(Context& context, std::string* summaryString = NULL ); + int OPENMM_VALIDATE_EXPORT compareWithReferencePlatform(Context& context, std::string* summaryString = NULL); /** * Validate force/energy by comparing the results between the forces/energies computed on two different platforms @@ -250,7 +250,7 @@ public: * on the two input platforms */ ForceValidationResult* compareForce(Context& context, std::vector& compareForces, - Platform& platform1, Platform& platform2 ) const; + Platform& platform1, Platform& platform2) const; /** * Compare individual forces by comparing calculations across two platforms (platform associated w/ input context and @@ -261,42 +261,42 @@ public: * @param forceValidationResults output vector of ForceValidationResult ptrs (user is responsible for deleting * individual ForceValidationResult objects) */ - void compareOpenMMForces(Context& context, Platform& comparisonPlatform, std::vector& forceValidationResults ) const; + void compareOpenMMForces(Context& context, Platform& comparisonPlatform, std::vector& forceValidationResults) const; /** * Determine if results are consistent * * @param forceValidationResults vector of ForceValidationResult ptrs to check if forces are consistent */ - void checkForInconsistentForceEntries( std::vector& forceValidationResults ) const; + void checkForInconsistentForceEntries(std::vector& forceValidationResults) const; /** * Get total number of force entries that are inconsistent * * @param forceValidationResults vector of ForceValidationResult ptrs to check if forces are consistent */ - int getTotalNumberOfInconsistentForceEntries( std::vector& forceValidationResults ) const; + int getTotalNumberOfInconsistentForceEntries(std::vector& forceValidationResults) const; /** * Get summary string of results * * @param forceValidationResults vector of ForceValidationResult ptrs */ - std::string getSummary( std::vector& forceValidationResults ) const; + std::string getSummary(std::vector& forceValidationResults) const; /** * Set force tolerance * * @param tolerance force tolerance */ - void setForceTolerance( double tolerance ); + void setForceTolerance(double tolerance); /** * Get force tolerance * * @return force tolerance */ - double getForceTolerance( void ) const; + double getForceTolerance() const; /* * Get force tolerance for specified force @@ -307,7 +307,7 @@ public: * * */ - double getForceTolerance( const std::string& forceName ) const; + double getForceTolerance(const std::string& forceName) const; /* * Get max errors to print in summary string @@ -316,7 +316,7 @@ public: * * */ - int getMaxErrorsToPrint( void ) const; + int getMaxErrorsToPrint() const; /* * Set max errors to print in summary string @@ -325,7 +325,7 @@ public: * * */ - void setMaxErrorsToPrint( int maxErrorsToPrint ); + void setMaxErrorsToPrint(int maxErrorsToPrint); /* * Return true if force is not to be validated (Andersen thermostat, CM motion remover, ...) @@ -335,13 +335,13 @@ public: * @return true if force is not currently validated **/ - int isExcludedForce( std::string forceName ) const; + int isExcludedForce(std::string forceName) const; private: // initialize class entries - void _initialize( void ); + void _initialize(); /* * Format output line @@ -354,9 +354,9 @@ private: * * */ - std::string _getLine( const std::string& tab, - const std::string& description, - const std::string& value ) const; + std::string _getLine(const std::string& tab, + const std::string& description, + const std::string& value) const; std::vector _forceValidationResults; diff --git a/libraries/validate/src/ValidateOpenMM.cpp b/libraries/validate/src/ValidateOpenMM.cpp index 5be578008..e8d449cd3 100644 --- a/libraries/validate/src/ValidateOpenMM.cpp +++ b/libraries/validate/src/ValidateOpenMM.cpp @@ -54,7 +54,7 @@ const std::string ValidateOpenMM::CUSTOM_EXTERNAL_FORCE = "CustomExter const std::string ValidateOpenMM::CUSTOM_NONBONDED_FORCE = "CustomNonBonded"; -ValidateOpenMM::ValidateOpenMM( void ) { +ValidateOpenMM::ValidateOpenMM() { _log = NULL; @@ -82,7 +82,7 @@ int ValidateOpenMM::isNanOrInfinity( double number ){ return (number != number || number == std::numeric_limits::infinity() || number == -std::numeric_limits::infinity()) ? 1 : 0; } -FILE* ValidateOpenMM::getLog( void ) const { +FILE* ValidateOpenMM::getLog() const { return _log; } diff --git a/libraries/validate/src/ValidateOpenMMForces.cpp b/libraries/validate/src/ValidateOpenMMForces.cpp index a9610502f..2b02e2d30 100644 --- a/libraries/validate/src/ValidateOpenMMForces.cpp +++ b/libraries/validate/src/ValidateOpenMMForces.cpp @@ -68,7 +68,7 @@ ForceValidationResult::ForceValidationResult( const Context& context1, const Con ForceValidationResult::~ForceValidationResult( ){ } -void ForceValidationResult::_calculateNorms( void ){ +void ForceValidationResult::_calculateNorms(){ // --------------------------------------------------------------------------------------- @@ -195,7 +195,7 @@ std::vector ForceValidationResult::getForceNorms( int forceIndex ) cons } } -int ForceValidationResult::nansDetected( void ) const { +int ForceValidationResult::nansDetected() const { return _nansDetected; } @@ -203,7 +203,7 @@ void ForceValidationResult::registerInconsistentForceIndex( int index, int value _inconsistentForceIndicies[index] = value; } -void ForceValidationResult::clearInconsistentForceIndexList( void ){ +void ForceValidationResult::clearInconsistentForceIndexList(){ _inconsistentForceIndicies.clear(); } @@ -213,7 +213,7 @@ void ForceValidationResult::getInconsistentForceIndexList( std::vector& inc } } -int ForceValidationResult::getNumberOfInconsistentForceEntries( void ) const { +int ForceValidationResult::getNumberOfInconsistentForceEntries() const { return static_cast(_inconsistentForceIndicies.size() ); } @@ -329,7 +329,7 @@ double ForceValidationResult::getMaxDotProduct( int* maxIndex ) const { return maxDotProduct; } -std::string ForceValidationResult::getForceName( void ) const { +std::string ForceValidationResult::getForceName() const { // --------------------------------------------------------------------------------------- @@ -376,7 +376,7 @@ void ForceValidationResult::compareForces( double tolerance ){ std::vector forces2 = getForces( 1 ); std::vector forceNorms2 = getForceNorms( 1 ); - clearInconsistentForceIndexList( ); + clearInconsistentForceIndexList(); for( unsigned int jj = 0; jj < forces1.size(); jj++ ){ if( ValidateOpenMM::isNanOrInfinity( forceNorms1[jj] ) || ValidateOpenMM::isNanOrInfinity( forceNorms2[jj] ) ){ registerInconsistentForceIndex( jj ); @@ -406,7 +406,7 @@ void ForceValidationResult::compareForceNorms( double tolerance ){ std::vector forceNorms0 = getForceNorms( 0 ); std::vector forceNorms1 = getForceNorms( 1 ); - clearInconsistentForceIndexList( ); + clearInconsistentForceIndexList(); for( unsigned int jj = 0; jj < forceNorms0.size(); jj++ ){ if( ValidateOpenMM::isNanOrInfinity( forceNorms0[jj] ) || ValidateOpenMM::isNanOrInfinity( forceNorms1[jj] ) ){ registerInconsistentForceIndex( jj ); @@ -420,11 +420,11 @@ void ForceValidationResult::compareForceNorms( double tolerance ){ } } -ValidateOpenMMForces::ValidateOpenMMForces( void ) { +ValidateOpenMMForces::ValidateOpenMMForces() { _initialize(); } -void ValidateOpenMMForces::_initialize( void ){ +void ValidateOpenMMForces::_initialize(){ _forceTolerance = 1.0e-02; _maxErrorsToPrint = 25; @@ -450,7 +450,7 @@ void ValidateOpenMMForces::_initialize( void ){ _forcesToBeExcluded[ANDERSEN_THERMOSTAT] = 1; } -ValidateOpenMMForces::~ValidateOpenMMForces( ){ +ValidateOpenMMForces::~ValidateOpenMMForces(){ for( unsigned int ii = 0; ii < _forceValidationResults.size(); ii++ ){ delete _forceValidationResults[ii]; @@ -459,7 +459,7 @@ ValidateOpenMMForces::~ValidateOpenMMForces( ){ } -double ValidateOpenMMForces::getForceTolerance( void ) const { +double ValidateOpenMMForces::getForceTolerance() const { return _forceTolerance; } @@ -706,7 +706,7 @@ double ValidateOpenMMForces::getForceTolerance( const std::string& forceName ) c return _forceTolerance; } -int ValidateOpenMMForces::getMaxErrorsToPrint( void ) const { +int ValidateOpenMMForces::getMaxErrorsToPrint() const { return _maxErrorsToPrint; } diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h index 16f936ff3..17a8061a1 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h @@ -70,7 +70,7 @@ public: * * @param cubicK the cubic force constant for the angle */ - void setAmoebaGlobalAngleCubic( double cubicK ); + void setAmoebaGlobalAngleCubic(double cubicK); /** * Get the global cubic term @@ -84,7 +84,7 @@ public: * * @param quarticK the quartic force constant for the angle */ - void setAmoebaGlobalAngleQuartic( double quarticK ); + void setAmoebaGlobalAngleQuartic(double quarticK); /** * Get the global quartic term @@ -98,7 +98,7 @@ public: * * @param penticK the pentic force constant for the angle */ - void setAmoebaGlobalAnglePentic( double penticK ); + void setAmoebaGlobalAnglePentic(double penticK); /** * Get the global pentic term @@ -112,7 +112,7 @@ public: * * @param sexticK the sextic force constant for the angle */ - void setAmoebaGlobalAngleSextic( double sexticK ); + void setAmoebaGlobalAngleSextic(double sexticK); /** * Get the global sextic term @@ -131,7 +131,7 @@ public: * @param quadratic k the quadratic force constant for the angle, measured in kJ/mol/radian^2 * @return the index of the angle that was added */ - int addAngle(int particle1, int particle2, int particle3, double length, double quadraticK ); + int addAngle(int particle1, int particle2, int particle3, double length, double quadraticK); /** * Get the force field parameters for an angle term. @@ -143,7 +143,7 @@ public: * @param length the equilibrium angle, measured in degress * @param quadratic k the quadratic force constant for the angle, measured in kJ/mol/radian^2 */ - void getAngleParameters(int index, int& particle1, int& particle2, int& particle3, double& length, double& quadraticK ) const; + void getAngleParameters(int index, int& particle1, int& particle2, int& particle3, double& length, double& quadraticK) const; /** * Set the force field parameters for an angle term. @@ -155,7 +155,7 @@ public: * @param length the equilibrium angle, measured in degrees * @param quadratic k the quadratic force constant for the angle, measured in kJ/mol/radian^2 */ - void setAngleParameters(int index, int particle1, int particle2, int particle3, double length, double quadraticK ); + void setAngleParameters(int index, int particle1, int particle2, int particle3, double length, double quadraticK); /** * Update the per-angle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. @@ -195,7 +195,7 @@ public: particle1 = particle2 = particle3 = -1; length = quadraticK = 0.0; } - AngleInfo(int particle1, int particle2, int particle3, double length, double quadraticK ) : + AngleInfo(int particle1, int particle2, int particle3, double length, double quadraticK) : particle1(particle1), particle2(particle2), particle3(particle3), length(length), quadraticK(quadraticK) { } }; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h index e174d44ad..0ff2b4944 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h @@ -71,7 +71,7 @@ public: * * @param cubicK the cubic force constant for the bond */ - void setAmoebaGlobalBondCubic( double cubicK ); + void setAmoebaGlobalBondCubic(double cubicK); /** * Get the global cubic term @@ -85,7 +85,7 @@ public: * * @param quarticK the quartic force constant for the bond */ - void setAmoebaGlobalBondQuartic( double quarticK ); + void setAmoebaGlobalBondQuartic(double quarticK); /** * Get the global quartic term @@ -104,7 +104,7 @@ public: * @return the index of the bond that was added */ - int addBond(int particle1, int particle2, double length, double quadraticK ); + int addBond(int particle1, int particle2, double length, double quadraticK); /** * Get the force field parameters for a bond term. @@ -116,7 +116,7 @@ public: * @param quadratic k the quadratic force constant for the bond */ - void getBondParameters(int index, int& particle1, int& particle2, double& length, double& quadraticK ) const; + void getBondParameters(int index, int& particle1, int& particle2, double& length, double& quadraticK) const; /** * Set the force field parameters for a bond term. @@ -127,7 +127,7 @@ public: * @param length the equilibrium length of the bond, measured in nm * @param k the quadratic force constant for the bond */ - void setBondParameters(int index, int particle1, int particle2, double length, double quadraticK ); + void setBondParameters(int index, int particle1, int particle2, double length, double quadraticK); /** * Update the per-bond parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. @@ -167,7 +167,7 @@ public: particle1 = particle2 = -1; length = quadraticK = 0.0; } - BondInfo(int particle1, int particle2, double length, double quadraticK ) : + BondInfo(int particle1, int particle2, double length, double quadraticK) : particle1(particle1), particle2(particle2), length(length), quadraticK(quadraticK) { } }; diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h index 506e8eb62..4ed9564a1 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h @@ -152,7 +152,7 @@ public: /** * Set the surface area factor kJ/(nm*nm) used in SASA contribution */ - void setSurfaceAreaFactor( double surfaceAreaFactor ); + void setSurfaceAreaFactor(double surfaceAreaFactor); /** * Update the per-particle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h index e727d6f64..39b23241b 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h @@ -70,7 +70,7 @@ public: * * @param cubicK the cubic force constant for the angle */ - void setAmoebaGlobalInPlaneAngleCubic( double cubicK ); + void setAmoebaGlobalInPlaneAngleCubic(double cubicK); /** * Get the global cubic term @@ -84,7 +84,7 @@ public: * * @param quarticK the quartic force constant for the angle */ - void setAmoebaGlobalInPlaneAngleQuartic( double quarticK ); + void setAmoebaGlobalInPlaneAngleQuartic(double quarticK); /** * Get the global quartic term @@ -98,7 +98,7 @@ public: * * @param penticK the pentic force constant for the angle */ - void setAmoebaGlobalInPlaneAnglePentic( double penticK ); + void setAmoebaGlobalInPlaneAnglePentic(double penticK); /** * Get the global pentic term @@ -112,7 +112,7 @@ public: * * @param sexticK the sextic force constant for the angle */ - void setAmoebaGlobalInPlaneAngleSextic( double sexticK ); + void setAmoebaGlobalInPlaneAngleSextic(double sexticK); /** * Get the global sextic term @@ -133,7 +133,7 @@ public: * @return the index of the angle that was added */ int addAngle(int particle1, int particle2, int particle3, int particle4, double length, - double quadraticK ); + double quadraticK); /** * Get the force field parameters for an angle term. @@ -147,7 +147,7 @@ public: * @param quadratic k the quadratic force constant for the angle measured in kJ/mol/radian^2 */ void getAngleParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, double& length, - double& quadraticK ) const; + double& quadraticK) const; /** * Set the force field parameters for an angle term. @@ -160,7 +160,7 @@ public: * @param length the equilibrium angle, measured in radians * @param quadratic k the quadratic force constant for the angle, measured in kJ/mol/radian^2 */ - void setAngleParameters(int index, int particle1, int particle2, int particle3, int particle4, double length, double quadraticK ); + void setAngleParameters(int index, int particle1, int particle2, int particle3, int particle4, double length, double quadraticK); /** * Update the per-angle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. @@ -200,7 +200,7 @@ public: particle1 = particle2 = particle3 = particle4 = -1; length = quadraticK = 0.0; } - AngleInfo(int particle1, int particle2, int particle3, int particle4, double length, double quadraticK ) : + AngleInfo(int particle1, int particle2, int particle3, int particle4, double length, double quadraticK) : particle1(particle1), particle2(particle2), particle3(particle3), particle4(particle4), length(length), quadraticK(quadraticK) { } diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index dbaf8221d..cd45844c0 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -148,7 +148,7 @@ public: lengthAB = lengthCB = angle = k1 = k2 = 0.0; } StretchBendInfo(int particle1, int particle2, int particle3, - double lengthAB, double lengthCB, double angle, double k1, double k2 ) : + double lengthAB, double lengthCB, double angle, double k1, double k2) : particle1(particle1), particle2(particle2), particle3(particle3), lengthAB(lengthAB), lengthCB(lengthCB), angle(angle), k1(k1), k2(k2) { } diff --git a/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h b/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h index 30c4ddba4..c509712f7 100644 --- a/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h +++ b/plugins/amoeba/openmmapi/include/openmm/amoebaKernels.h @@ -350,10 +350,10 @@ public: virtual void getInducedDipoles(ContextImpl& context, std::vector& dipoles) = 0; - virtual void getElectrostaticPotential( ContextImpl& context, const std::vector< Vec3 >& inputGrid, - std::vector< double >& outputElectrostaticPotential ) = 0; + virtual void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, + std::vector< double >& outputElectrostaticPotential) = 0; - virtual void getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMoments ) = 0; + virtual void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments) = 0; /** * Copy changed parameters over to a context. * diff --git a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h index 9fb69539a..2a1a97872 100644 --- a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h +++ b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaMultipoleForceImpl.h @@ -70,9 +70,9 @@ public: * @param minCovalentIndex minimum covalent index * @param maxCovalentIndex maximum covalent index */ - static void getCovalentRange( const AmoebaMultipoleForce& force, int index, - const std::vector< AmoebaMultipoleForce::CovalentType>& lists, - int* minCovalentIndex, int* maxCovalentIndex ); + static void getCovalentRange(const AmoebaMultipoleForce& force, int index, + const std::vector< AmoebaMultipoleForce::CovalentType>& lists, + int* minCovalentIndex, int* maxCovalentIndex); /** * Get the covalent degree for the CovalentEnd lists @@ -80,14 +80,14 @@ public: * @param force AmoebaMultipoleForce force reference * @param covalentDegree covalent degrees for the CovalentEnd lists */ - static void getCovalentDegree( const AmoebaMultipoleForce& force, std::vector& covalentDegree ); + static void getCovalentDegree(const AmoebaMultipoleForce& force, std::vector& covalentDegree); void getInducedDipoles(ContextImpl& context, std::vector& dipoles); - void getElectrostaticPotential( ContextImpl& context, const std::vector< Vec3 >& inputGrid, - std::vector< double >& outputElectrostaticPotential ); + void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, + std::vector< double >& outputElectrostaticPotential); - void getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMoments ); + void getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments); void updateParametersInContext(ContextImpl& context); diff --git a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaTorsionTorsionForceImpl.h b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaTorsionTorsionForceImpl.h index a586a81fb..5437baa28 100644 --- a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaTorsionTorsionForceImpl.h +++ b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaTorsionTorsionForceImpl.h @@ -61,7 +61,7 @@ public: } std::vector getKernelNames(); - OPENMM_EXPORT_AMOEBA static void reorderGrid( const TorsionTorsionGrid& grid, TorsionTorsionGrid& reorderedGrid ); + OPENMM_EXPORT_AMOEBA static void reorderGrid(const TorsionTorsionGrid& grid, TorsionTorsionGrid& reorderedGrid); private: const AmoebaTorsionTorsionForce& owner; diff --git a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaWcaDispersionForceImpl.h b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaWcaDispersionForceImpl.h index 8d3f0196e..54fef94e9 100644 --- a/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaWcaDispersionForceImpl.h +++ b/plugins/amoeba/openmmapi/include/openmm/internal/AmoebaWcaDispersionForceImpl.h @@ -69,7 +69,7 @@ public: * @param particleIndex the particle index * @param maxDispersionEnergy maximum dispersion energy */ - static void getMaximumDispersionEnergy( const AmoebaWcaDispersionForce& force, int particleIndex, double& maxDispersionEnergy ); + static void getMaximumDispersionEnergy(const AmoebaWcaDispersionForce& force, int particleIndex, double& maxDispersionEnergy); /** * Get the total maximum dispersion energy @@ -78,7 +78,7 @@ public: * * @return total maximum dispersion energy for the system */ - static double getTotalMaximumDispersionEnergy( const AmoebaWcaDispersionForce& force); + static double getTotalMaximumDispersionEnergy(const AmoebaWcaDispersionForce& force); void updateParametersInContext(ContextImpl& context); private: diff --git a/plugins/amoeba/openmmapi/src/AmoebaAngleForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaAngleForce.cpp index 6525c0c78..0cec83e80 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaAngleForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaAngleForce.cpp @@ -46,7 +46,7 @@ int AmoebaAngleForce::addAngle(int particle1, int particle2, int particle3, dou } void AmoebaAngleForce::getAngleParameters(int index, int& particle1, int& particle2, int& particle3, - double& length, double& quadraticK ) const { + double& length, double& quadraticK) const { particle1 = angles[index].particle1; particle2 = angles[index].particle2; particle3 = angles[index].particle3; @@ -55,7 +55,7 @@ void AmoebaAngleForce::getAngleParameters(int index, int& particle1, int& partic } void AmoebaAngleForce::setAngleParameters(int index, int particle1, int particle2, int particle3, - double length, double quadraticK ) { + double length, double quadraticK) { angles[index].particle1 = particle1; angles[index].particle2 = particle2; angles[index].particle3 = particle3; @@ -67,7 +67,7 @@ double AmoebaAngleForce::getAmoebaGlobalAngleCubic() const { return _globalCubicK; } -void AmoebaAngleForce::setAmoebaGlobalAngleCubic(double cubicK ) { +void AmoebaAngleForce::setAmoebaGlobalAngleCubic(double cubicK) { _globalCubicK = cubicK; } @@ -75,7 +75,7 @@ double AmoebaAngleForce::getAmoebaGlobalAngleQuartic() const { return _globalQuarticK; } -void AmoebaAngleForce::setAmoebaGlobalAngleQuartic(double quarticK ) { +void AmoebaAngleForce::setAmoebaGlobalAngleQuartic(double quarticK) { _globalQuarticK = quarticK; } @@ -83,7 +83,7 @@ double AmoebaAngleForce::getAmoebaGlobalAnglePentic() const { return _globalPenticK; } -void AmoebaAngleForce::setAmoebaGlobalAnglePentic(double penticK ) { +void AmoebaAngleForce::setAmoebaGlobalAnglePentic(double penticK) { _globalPenticK = penticK; } @@ -91,7 +91,7 @@ double AmoebaAngleForce::getAmoebaGlobalAngleSextic() const { return _globalSexticK; } -void AmoebaAngleForce::setAmoebaGlobalAngleSextic(double sexticK ) { +void AmoebaAngleForce::setAmoebaGlobalAngleSextic(double sexticK) { _globalSexticK = sexticK; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaBondForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaBondForce.cpp index 3f1fa1d4f..8fb5d335d 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaBondForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaBondForce.cpp @@ -41,29 +41,29 @@ AmoebaBondForce::AmoebaBondForce() { } int AmoebaBondForce::addBond(int particle1, int particle2, double length, double quadraticK) { - bonds.push_back(BondInfo(particle1, particle2, length, quadraticK )); + bonds.push_back(BondInfo(particle1, particle2, length, quadraticK)); return bonds.size()-1; } -void AmoebaBondForce::getBondParameters(int index, int& particle1, int& particle2, double& length, double& quadraticK ) const { +void AmoebaBondForce::getBondParameters(int index, int& particle1, int& particle2, double& length, double& quadraticK) const { particle1 = bonds[index].particle1; particle2 = bonds[index].particle2; length = bonds[index].length; quadraticK = bonds[index].quadraticK; } -void AmoebaBondForce::setBondParameters(int index, int particle1, int particle2, double length, double quadraticK ) { +void AmoebaBondForce::setBondParameters(int index, int particle1, int particle2, double length, double quadraticK) { bonds[index].particle1 = particle1; bonds[index].particle2 = particle2; bonds[index].length = length; bonds[index].quadraticK = quadraticK; } -void AmoebaBondForce::setAmoebaGlobalBondCubic(double cubicK ) { +void AmoebaBondForce::setAmoebaGlobalBondCubic(double cubicK) { _globalCubicK = cubicK; } -void AmoebaBondForce::setAmoebaGlobalBondQuartic(double quarticK ) { +void AmoebaBondForce::setAmoebaGlobalBondQuartic(double quarticK) { _globalQuarticK = quarticK; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaGeneralizedKirkwoodForce.cpp index b1c288ee0..afcd67eb7 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaGeneralizedKirkwoodForce.cpp @@ -62,7 +62,7 @@ double AmoebaGeneralizedKirkwoodForce::getDielectricOffset() const { return dielectricOffset; } -void AmoebaGeneralizedKirkwoodForce::setDielectricOffset(double inputDielectricOffset ) { +void AmoebaGeneralizedKirkwoodForce::setDielectricOffset(double inputDielectricOffset) { dielectricOffset = inputDielectricOffset; } */ @@ -70,7 +70,7 @@ int AmoebaGeneralizedKirkwoodForce::getIncludeCavityTerm() const { return includeCavityTerm; } -void AmoebaGeneralizedKirkwoodForce::setIncludeCavityTerm(int inputIncludeCavityTerm ) { +void AmoebaGeneralizedKirkwoodForce::setIncludeCavityTerm(int inputIncludeCavityTerm) { includeCavityTerm = inputIncludeCavityTerm; } @@ -78,7 +78,7 @@ double AmoebaGeneralizedKirkwoodForce::getProbeRadius() const { return probeRadius; } -void AmoebaGeneralizedKirkwoodForce::setProbeRadius(double inputProbeRadius ) { +void AmoebaGeneralizedKirkwoodForce::setProbeRadius(double inputProbeRadius) { probeRadius = inputProbeRadius; } @@ -86,7 +86,7 @@ double AmoebaGeneralizedKirkwoodForce::getSurfaceAreaFactor() const { return surfaceAreaFactor; } -void AmoebaGeneralizedKirkwoodForce::setSurfaceAreaFactor(double inputSurfaceAreaFactor ) { +void AmoebaGeneralizedKirkwoodForce::setSurfaceAreaFactor(double inputSurfaceAreaFactor) { surfaceAreaFactor = inputSurfaceAreaFactor; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaInPlaneAngleForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaInPlaneAngleForce.cpp index c325477b1..1b92dd643 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaInPlaneAngleForce.cpp @@ -40,13 +40,13 @@ AmoebaInPlaneAngleForce::AmoebaInPlaneAngleForce() { _globalCubicK = _globalQuarticK = _globalPenticK = _globalSexticK = 0.0; } -int AmoebaInPlaneAngleForce::addAngle(int particle1, int particle2, int particle3, int particle4, double length, double quadraticK ) { - angles.push_back(AngleInfo(particle1, particle2, particle3, particle4, length, quadraticK )); +int AmoebaInPlaneAngleForce::addAngle(int particle1, int particle2, int particle3, int particle4, double length, double quadraticK) { + angles.push_back(AngleInfo(particle1, particle2, particle3, particle4, length, quadraticK)); return angles.size()-1; } void AmoebaInPlaneAngleForce::getAngleParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, - double& length, double& quadraticK ) const { + double& length, double& quadraticK) const { particle1 = angles[index].particle1; particle2 = angles[index].particle2; particle3 = angles[index].particle3; @@ -56,7 +56,7 @@ void AmoebaInPlaneAngleForce::getAngleParameters(int index, int& particle1, int& } void AmoebaInPlaneAngleForce::setAngleParameters(int index, int particle1, int particle2, int particle3, int particle4, - double length, double quadraticK ) { + double length, double quadraticK) { angles[index].particle1 = particle1; angles[index].particle2 = particle2; angles[index].particle3 = particle3; @@ -65,11 +65,11 @@ void AmoebaInPlaneAngleForce::setAngleParameters(int index, int particle1, int p angles[index].quadraticK = quadraticK; } -void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAngleCubic(double cubicK ) { +void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAngleCubic(double cubicK) { _globalCubicK = cubicK; } -void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAngleQuartic(double quarticK ) { +void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAngleQuartic(double quarticK) { _globalQuarticK = quarticK; } @@ -81,11 +81,11 @@ double AmoebaInPlaneAngleForce::getAmoebaGlobalInPlaneAngleQuartic() const { return _globalQuarticK; } -void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAnglePentic(double cubicK ) { +void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAnglePentic(double cubicK) { _globalPenticK = cubicK; } -void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAngleSextic(double quarticK ) { +void AmoebaInPlaneAngleForce::setAmoebaGlobalInPlaneAngleSextic(double quarticK) { _globalSexticK = quarticK; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp index 104248aa2..b810108a8 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForce.cpp @@ -49,7 +49,7 @@ AmoebaMultipoleForce::NonbondedMethod AmoebaMultipoleForce::getNonbondedMethod() return nonbondedMethod; } -void AmoebaMultipoleForce::setNonbondedMethod( AmoebaMultipoleForce::NonbondedMethod method) { +void AmoebaMultipoleForce::setNonbondedMethod(AmoebaMultipoleForce::NonbondedMethod method) { nonbondedMethod = method; } @@ -57,7 +57,7 @@ AmoebaMultipoleForce::PolarizationType AmoebaMultipoleForce::getPolarizationType return polarizationType; } -void AmoebaMultipoleForce::setPolarizationType( AmoebaMultipoleForce::PolarizationType type ) { +void AmoebaMultipoleForce::setPolarizationType(AmoebaMultipoleForce::PolarizationType type) { polarizationType = type; } @@ -73,7 +73,7 @@ double AmoebaMultipoleForce::getAEwald() const { return aewald; } -void AmoebaMultipoleForce::setAEwald(double inputAewald ) { +void AmoebaMultipoleForce::setAEwald(double inputAewald) { aewald = inputAewald; } @@ -81,11 +81,11 @@ int AmoebaMultipoleForce::getPmeBSplineOrder() const { return pmeBSplineOrder; } -void AmoebaMultipoleForce::getPmeGridDimensions( std::vector& gridDimension ) const { - if( gridDimension.size() < 3 ){ +void AmoebaMultipoleForce::getPmeGridDimensions(std::vector& gridDimension) const { + if (gridDimension.size() < 3) { gridDimension.resize(3); } - if( pmeGridDimension.size() > 2 ){ + if (pmeGridDimension.size() > 2) { gridDimension[0] = pmeGridDimension[0]; gridDimension[1] = pmeGridDimension[1]; gridDimension[2] = pmeGridDimension[2]; @@ -95,7 +95,7 @@ void AmoebaMultipoleForce::getPmeGridDimensions( std::vector& gridDimension return; } -void AmoebaMultipoleForce::setPmeGridDimensions( const std::vector& gridDimension ) { +void AmoebaMultipoleForce::setPmeGridDimensions(const std::vector& gridDimension) { pmeGridDimension.resize(3); pmeGridDimension[0] = gridDimension[0]; pmeGridDimension[1] = gridDimension[1]; @@ -107,7 +107,7 @@ int AmoebaMultipoleForce::getMutualInducedMaxIterations() const { return mutualInducedMaxIterations; } -void AmoebaMultipoleForce::setMutualInducedMaxIterations( int inputMutualInducedMaxIterations ) { +void AmoebaMultipoleForce::setMutualInducedMaxIterations(int inputMutualInducedMaxIterations) { mutualInducedMaxIterations = inputMutualInducedMaxIterations; } @@ -115,7 +115,7 @@ double AmoebaMultipoleForce::getMutualInducedTargetEpsilon() const { return mutualInducedTargetEpsilon; } -void AmoebaMultipoleForce::setMutualInducedTargetEpsilon( double inputMutualInducedTargetEpsilon ) { +void AmoebaMultipoleForce::setMutualInducedTargetEpsilon(double inputMutualInducedTargetEpsilon) { mutualInducedTargetEpsilon = inputMutualInducedTargetEpsilon; } @@ -127,22 +127,22 @@ void AmoebaMultipoleForce::setEwaldErrorTolerance(double tol) { ewaldErrorTol = tol; } -int AmoebaMultipoleForce::addMultipole( double charge, const std::vector& molecularDipole, const std::vector& molecularQuadrupole, int axisType, +int AmoebaMultipoleForce::addMultipole(double charge, const std::vector& molecularDipole, const std::vector& molecularQuadrupole, int axisType, int multipoleAtomZ, int multipoleAtomX, int multipoleAtomY, double thole, double dampingFactor, double polarity) { - multipoles.push_back(MultipoleInfo( charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity)); + multipoles.push_back(MultipoleInfo(charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity)); return multipoles.size()-1; } void AmoebaMultipoleForce::getMultipoleParameters(int index, double& charge, std::vector& molecularDipole, std::vector& molecularQuadrupole, - int& axisType, int& multipoleAtomZ, int& multipoleAtomX, int& multipoleAtomY, double& thole, double& dampingFactor, double& polarity ) const { + int& axisType, int& multipoleAtomZ, int& multipoleAtomX, int& multipoleAtomY, double& thole, double& dampingFactor, double& polarity) const { charge = multipoles[index].charge; - molecularDipole.resize( 3 ); + molecularDipole.resize(3); molecularDipole[0] = multipoles[index].molecularDipole[0]; molecularDipole[1] = multipoles[index].molecularDipole[1]; molecularDipole[2] = multipoles[index].molecularDipole[2]; - molecularQuadrupole.resize( 9 ); + molecularQuadrupole.resize(9); molecularQuadrupole[0] = multipoles[index].molecularQuadrupole[0]; molecularQuadrupole[1] = multipoles[index].molecularQuadrupole[1]; molecularQuadrupole[2] = multipoles[index].molecularQuadrupole[2]; @@ -164,7 +164,7 @@ void AmoebaMultipoleForce::getMultipoleParameters(int index, double& charge, std } void AmoebaMultipoleForce::setMultipoleParameters(int index, double charge, const std::vector& molecularDipole, const std::vector& molecularQuadrupole, - int axisType, int multipoleAtomZ, int multipoleAtomX, int multipoleAtomY, double thole, double dampingFactor, double polarity ) { + int axisType, int multipoleAtomZ, int multipoleAtomX, int multipoleAtomY, double thole, double dampingFactor, double polarity) { multipoles[index].charge = charge; @@ -192,34 +192,34 @@ void AmoebaMultipoleForce::setMultipoleParameters(int index, double charge, cons } -void AmoebaMultipoleForce::setCovalentMap(int index, CovalentType typeId, const std::vector& covalentAtoms ) { +void AmoebaMultipoleForce::setCovalentMap(int index, CovalentType typeId, const std::vector& covalentAtoms) { std::vector& covalentList = multipoles[index].covalentInfo[typeId]; - covalentList.resize( covalentAtoms.size() ); - for( unsigned int ii = 0; ii < covalentAtoms.size(); ii++ ){ + covalentList.resize(covalentAtoms.size()); + for (unsigned int ii = 0; ii < covalentAtoms.size(); ii++) { covalentList[ii] = covalentAtoms[ii]; } } -void AmoebaMultipoleForce::getCovalentMap(int index, CovalentType typeId, std::vector& covalentAtoms ) const { +void AmoebaMultipoleForce::getCovalentMap(int index, CovalentType typeId, std::vector& covalentAtoms) const { // load covalent atom index entries for atomId==index and covalentId==typeId into covalentAtoms std::vector covalentList = multipoles[index].covalentInfo[typeId]; - covalentAtoms.resize( covalentList.size() ); - for( unsigned int ii = 0; ii < covalentList.size(); ii++ ){ + covalentAtoms.resize(covalentList.size()); + for (unsigned int ii = 0; ii < covalentList.size(); ii++) { covalentAtoms[ii] = covalentList[ii]; } } -void AmoebaMultipoleForce::getCovalentMaps(int index, std::vector< std::vector >& covalentLists ) const { +void AmoebaMultipoleForce::getCovalentMaps(int index, std::vector< std::vector >& covalentLists) const { - covalentLists.resize( CovalentEnd ); - for( unsigned int jj = 0; jj < CovalentEnd; jj++ ){ + covalentLists.resize(CovalentEnd); + for (unsigned int jj = 0; jj < CovalentEnd; jj++) { std::vector covalentList = multipoles[index].covalentInfo[jj]; std::vector covalentAtoms; - covalentAtoms.resize( covalentList.size() ); - for( unsigned int ii = 0; ii < covalentList.size(); ii++ ){ + covalentAtoms.resize(covalentList.size()); + for (unsigned int ii = 0; ii < covalentList.size(); ii++) { covalentAtoms[ii] = covalentList[ii]; } covalentLists[jj] = covalentAtoms; @@ -230,11 +230,11 @@ void AmoebaMultipoleForce::getInducedDipoles(Context& context, vector& dip dynamic_cast(getImplInContext(context)).getInducedDipoles(getContextImpl(context), dipoles); } -void AmoebaMultipoleForce::getElectrostaticPotential( const std::vector< Vec3 >& inputGrid, Context& context, std::vector< double >& outputElectrostaticPotential ){ +void AmoebaMultipoleForce::getElectrostaticPotential(const std::vector< Vec3 >& inputGrid, Context& context, std::vector< double >& outputElectrostaticPotential) { dynamic_cast(getImplInContext(context)).getElectrostaticPotential(getContextImpl(context), inputGrid, outputElectrostaticPotential); } -void AmoebaMultipoleForce::getSystemMultipoleMoments(Context& context, std::vector< double >& outputMultipoleMoments ){ +void AmoebaMultipoleForce::getSystemMultipoleMoments(Context& context, std::vector< double >& outputMultipoleMoments) { dynamic_cast(getImplInContext(context)).getSystemMultipoleMoments(getContextImpl(context), outputMultipoleMoments); } diff --git a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp index 9dcff51ee..b28733fbb 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaMultipoleForceImpl.cpp @@ -64,26 +64,26 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) { } double quadrupoleValidationTolerance = 1.0e-05; - for( int ii = 0; ii < system.getNumParticles(); ii++ ){ + for (int ii = 0; ii < system.getNumParticles(); ii++) { int axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY; double charge, thole, dampingFactor, polarity ; std::vector molecularDipole; std::vector molecularQuadrupole; - owner.getMultipoleParameters( ii, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, - thole, dampingFactor, polarity ); + owner.getMultipoleParameters(ii, charge, molecularDipole, molecularQuadrupole, axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, + thole, dampingFactor, polarity); // check quadrupole is traceless and symmetric - double trace = fabs( molecularQuadrupole[0] + molecularQuadrupole[4] + molecularQuadrupole[8] ); - if( trace > quadrupoleValidationTolerance ){ + double trace = fabs(molecularQuadrupole[0] + molecularQuadrupole[4] + molecularQuadrupole[8]); + if (trace > quadrupoleValidationTolerance) { std::stringstream buffer; buffer << "AmoebaMultipoleForce: qudarupole for particle=" << ii; buffer << " has nonzero trace: " << trace << "; AMOEBA plugin assumes traceless quadrupole."; throw OpenMMException(buffer.str()); } - if( fabs( molecularQuadrupole[1] - molecularQuadrupole[3] ) > quadrupoleValidationTolerance ){ + if (fabs(molecularQuadrupole[1] - molecularQuadrupole[3]) > quadrupoleValidationTolerance ) { std::stringstream buffer; buffer << "AmoebaMultipoleForce: XY and YX components of quadrupole for particle=" << ii; buffer << " are not equal: [" << molecularQuadrupole[1] << " " << molecularQuadrupole[3] << "];"; @@ -91,7 +91,7 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) { throw OpenMMException(buffer.str()); } - if( fabs( molecularQuadrupole[2] - molecularQuadrupole[6] ) > quadrupoleValidationTolerance ){ + if (fabs(molecularQuadrupole[2] - molecularQuadrupole[6]) > quadrupoleValidationTolerance ) { std::stringstream buffer; buffer << "AmoebaMultipoleForce: XZ and ZX components of quadrupole for particle=" << ii; buffer << " are not equal: [" << molecularQuadrupole[2] << " " << molecularQuadrupole[6] << "];"; @@ -99,7 +99,7 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) { throw OpenMMException(buffer.str()); } - if( fabs( molecularQuadrupole[5] - molecularQuadrupole[7] ) > quadrupoleValidationTolerance ){ + if (fabs(molecularQuadrupole[5] - molecularQuadrupole[7]) > quadrupoleValidationTolerance ) { std::stringstream buffer; buffer << "AmoebaMultipoleForce: YZ and ZY components of quadrupole for particle=" << ii; buffer << " are not equal: [" << molecularQuadrupole[5] << " " << molecularQuadrupole[7] << "];"; @@ -109,9 +109,9 @@ void AmoebaMultipoleForceImpl::initialize(ContextImpl& context) { // only 'Z-then-X', 'Bisector', Z-Bisect, ThreeFold currently handled - if( axisType != AmoebaMultipoleForce::ZThenX && axisType != AmoebaMultipoleForce::Bisector && + if (axisType != AmoebaMultipoleForce::ZThenX && axisType != AmoebaMultipoleForce::Bisector && axisType != AmoebaMultipoleForce::ZBisect && axisType != AmoebaMultipoleForce::ThreeFold && - axisType != AmoebaMultipoleForce::ZOnly && axisType != AmoebaMultipoleForce::NoAxisType ) { + axisType != AmoebaMultipoleForce::ZOnly && axisType != AmoebaMultipoleForce::NoAxisType) { std::stringstream buffer; buffer << "AmoebaMultipoleForce: axis type=" << axisType; buffer << " not currently handled - only axisTypes[ "; @@ -139,7 +139,7 @@ std::vector AmoebaMultipoleForceImpl::getKernelNames() { } const int* AmoebaMultipoleForceImpl::getCovalentDegrees() { - if( !initializedCovalentDegrees ){ + if (!initializedCovalentDegrees) { initializedCovalentDegrees = true; CovalentDegrees[AmoebaMultipoleForce::Covalent12] = 1; CovalentDegrees[AmoebaMultipoleForce::Covalent13] = 2; @@ -153,20 +153,20 @@ const int* AmoebaMultipoleForceImpl::getCovalentDegrees() { return CovalentDegrees; } -void AmoebaMultipoleForceImpl::getCovalentRange( const AmoebaMultipoleForce& force, int atomIndex, const std::vector& lists, - int* minCovalentIndex, int* maxCovalentIndex ){ +void AmoebaMultipoleForceImpl::getCovalentRange(const AmoebaMultipoleForce& force, int atomIndex, const std::vector& lists, + int* minCovalentIndex, int* maxCovalentIndex) { *minCovalentIndex = 999999999; *maxCovalentIndex = -999999999; - for( unsigned int kk = 0; kk < lists.size(); kk++ ){ + for (unsigned int kk = 0; kk < lists.size(); kk++) { AmoebaMultipoleForce::CovalentType jj = lists[kk]; std::vector covalentList; - force.getCovalentMap( atomIndex, jj, covalentList ); - for( unsigned int ii = 0; ii < covalentList.size(); ii++ ){ - if( *minCovalentIndex > covalentList[ii] ){ + force.getCovalentMap(atomIndex, jj, covalentList); + for (unsigned int ii = 0; ii < covalentList.size(); ii++) { + if (*minCovalentIndex > covalentList[ii]) { *minCovalentIndex = covalentList[ii]; } - if( *maxCovalentIndex < covalentList[ii] ){ + if (*maxCovalentIndex < covalentList[ii]) { *maxCovalentIndex = covalentList[ii]; } } @@ -174,10 +174,10 @@ void AmoebaMultipoleForceImpl::getCovalentRange( const AmoebaMultipoleForce& for return; } -void AmoebaMultipoleForceImpl::getCovalentDegree( const AmoebaMultipoleForce& force, std::vector& covalentDegree ){ - covalentDegree.resize( AmoebaMultipoleForce::CovalentEnd ); +void AmoebaMultipoleForceImpl::getCovalentDegree(const AmoebaMultipoleForce& force, std::vector& covalentDegree) { + covalentDegree.resize(AmoebaMultipoleForce::CovalentEnd); const int* CovalentDegrees = AmoebaMultipoleForceImpl::getCovalentDegrees(); - for( unsigned int kk = 0; kk < AmoebaMultipoleForce::CovalentEnd; kk++ ){ + for (unsigned int kk = 0; kk < AmoebaMultipoleForce::CovalentEnd; kk++) { covalentDegree[kk] = CovalentDegrees[kk]; } return; @@ -187,12 +187,12 @@ void AmoebaMultipoleForceImpl::getInducedDipoles(ContextImpl& context, vector().getInducedDipoles(context, dipoles); } -void AmoebaMultipoleForceImpl::getElectrostaticPotential( ContextImpl& context, const std::vector< Vec3 >& inputGrid, - std::vector< double >& outputElectrostaticPotential ){ +void AmoebaMultipoleForceImpl::getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, + std::vector< double >& outputElectrostaticPotential) { kernel.getAs().getElectrostaticPotential(context, inputGrid, outputElectrostaticPotential); } -void AmoebaMultipoleForceImpl::getSystemMultipoleMoments( ContextImpl& context, std::vector< double >& outputMultipoleMoments ){ +void AmoebaMultipoleForceImpl::getSystemMultipoleMoments(ContextImpl& context, std::vector< double >& outputMultipoleMoments) { kernel.getAs().getSystemMultipoleMoments(context, outputMultipoleMoments); } diff --git a/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp index 46aebf8ea..df2aa130d 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaOutOfPlaneBendForce.cpp @@ -48,7 +48,7 @@ double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendCubic() const { return _globalCubicK; } -void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendCubic(double cubicK ) { +void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendCubic(double cubicK) { _globalCubicK = cubicK; } @@ -56,7 +56,7 @@ double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendQuartic() const { return _globalQuarticK; } -void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendQuartic(double quarticK ) { +void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendQuartic(double quarticK) { _globalQuarticK = quarticK; } @@ -64,7 +64,7 @@ double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendPentic() const { return _globalPenticK; } -void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendPentic(double penticK ) { +void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendPentic(double penticK) { _globalPenticK = penticK; } @@ -72,7 +72,7 @@ double AmoebaOutOfPlaneBendForce::getAmoebaGlobalOutOfPlaneBendSextic() const { return _globalSexticK; } -void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendSextic(double sexticK ) { +void AmoebaOutOfPlaneBendForce::setAmoebaGlobalOutOfPlaneBendSextic(double sexticK) { _globalSexticK = sexticK; } @@ -82,7 +82,7 @@ int AmoebaOutOfPlaneBendForce::addOutOfPlaneBend(int particle1, int particle2, i } void AmoebaOutOfPlaneBendForce::getOutOfPlaneBendParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, - double& k ) const { + double& k) const { particle1 = outOfPlaneBends[index].particle1; particle2 = outOfPlaneBends[index].particle2; particle3 = outOfPlaneBends[index].particle3; diff --git a/plugins/amoeba/openmmapi/src/AmoebaPiTorsionForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaPiTorsionForce.cpp index b56b1b274..7046f3564 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaPiTorsionForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaPiTorsionForce.cpp @@ -44,7 +44,7 @@ int AmoebaPiTorsionForce::addPiTorsion(int particle1, int particle2, int particl return piTorsions.size()-1; } -void AmoebaPiTorsionForce::getPiTorsionParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, int& particle5, int& particle6, double& k ) const { +void AmoebaPiTorsionForce::getPiTorsionParameters(int index, int& particle1, int& particle2, int& particle3, int& particle4, int& particle5, int& particle6, double& k) const { particle1 = piTorsions[index].particle1; particle2 = piTorsions[index].particle2; particle3 = piTorsions[index].particle3; @@ -54,7 +54,7 @@ void AmoebaPiTorsionForce::getPiTorsionParameters(int index, int& particle1, int k = piTorsions[index].k; } -void AmoebaPiTorsionForce::setPiTorsionParameters(int index, int particle1, int particle2, int particle3, int particle4, int particle5, int particle6, double k ) { +void AmoebaPiTorsionForce::setPiTorsionParameters(int index, int particle1, int particle2, int particle3, int particle4, int particle5, int particle6, double k) { piTorsions[index].particle1 = particle1; piTorsions[index].particle2 = particle2; piTorsions[index].particle3 = particle3; diff --git a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp index 0be297e51..29fd559e4 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaStretchBendForce.cpp @@ -46,7 +46,7 @@ int AmoebaStretchBendForce::addStretchBend(int particle1, int particle2, int par } void AmoebaStretchBendForce::getStretchBendParameters(int index, int& particle1, int& particle2, int& particle3, - double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2 ) const { + double& lengthAB, double& lengthCB, double& angle, double& k1, double& k2) const { particle1 = stretchBends[index].particle1; particle2 = stretchBends[index].particle2; particle3 = stretchBends[index].particle3; diff --git a/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForce.cpp index 09cfe26b7..c2300cb01 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForce.cpp @@ -70,13 +70,13 @@ void AmoebaTorsionTorsionForce::setTorsionTorsionParameters(int index, int parti torsionTorsions[index].gridIndex = gridIndex; } -const TorsionTorsionGrid& AmoebaTorsionTorsionForce::getTorsionTorsionGrid(int index ) const { +const TorsionTorsionGrid& AmoebaTorsionTorsionForce::getTorsionTorsionGrid(int index) const { return torsionTorsionGrids[index].getTorsionTorsionGrid(); } -void AmoebaTorsionTorsionForce::setTorsionTorsionGrid(int index, const TorsionTorsionGrid& grid ) { - if( index >= static_cast(torsionTorsionGrids.size()) ){ - torsionTorsionGrids.resize( index + 1); +void AmoebaTorsionTorsionForce::setTorsionTorsionGrid(int index, const TorsionTorsionGrid& grid) { + if (index >= static_cast(torsionTorsionGrids.size())) { + torsionTorsionGrids.resize(index + 1); } torsionTorsionGrids[index] = grid; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForceImpl.cpp b/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForceImpl.cpp index ebe588a37..06e588876 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForceImpl.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaTorsionTorsionForceImpl.cpp @@ -70,12 +70,11 @@ typedef std::map< double, Map_Double_IntPair > Map_Double_MapDoubleIntPair; typedef Map_Double_MapDoubleIntPair::iterator Map_Double_MapDoubleIntPairI; typedef Map_Double_MapDoubleIntPair::const_iterator Map_Double_MapDoubleIntPairCI; -void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, TorsionTorsionGrid& reorderedGrid ){ +void AmoebaTorsionTorsionForceImpl::reorderGrid(const TorsionTorsionGrid& grid, TorsionTorsionGrid& reorderedGrid) { - reorderedGrid.resize( grid.size() ); - std::vector map_Double_IntPair_Vector( grid.size() ); + reorderedGrid.resize(grid.size()); + std::vector map_Double_IntPair_Vector(grid.size()); Map_Double_MapDoubleIntPair mapAngles; - //(void) fprintf( stderr, "AmoebaTorsionTorsionForceImpl::reorder grid\n" ); // (1) set dimensions for reorderd grid // (2) build map: @@ -84,27 +83,27 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, for (unsigned int ii = 0; ii < grid.size(); ii++) { - reorderedGrid[ii].resize( grid[ii].size() ); + reorderedGrid[ii].resize(grid[ii].size()); for (unsigned int jj = 0; jj < grid[ii].size(); jj++) { - reorderedGrid[ii][jj].resize( grid[ii][jj].size() ); + reorderedGrid[ii][jj].resize(grid[ii][jj].size()); double angleX = grid[ii][jj][0]; double angleY = grid[ii][jj][1]; - if( mapAngles.find( angleX ) == mapAngles.end() ){ - if( map_Double_IntPair_Vector[ii].size() > 0 ){ + if (mapAngles.find(angleX) == mapAngles.end()) { + if (map_Double_IntPair_Vector[ii].size() > 0) { char buffer[1024]; - (void) sprintf( buffer, "TorsionTorsion grid reorder: x-angle not set correctly: x=%15.7e y=%15.7e size=%u should be zero; ii/jj indies=%u %u.\n", - angleX, angleY, static_cast(map_Double_IntPair_Vector[ii].size()), ii, jj ); + (void) sprintf(buffer, "TorsionTorsion grid reorder: x-angle not set correctly: x=%15.7e y=%15.7e size=%u should be zero; ii/jj indies=%u %u.\n", + angleX, angleY, static_cast(map_Double_IntPair_Vector[ii].size()), ii, jj); throw OpenMMException(buffer); } mapAngles[angleX] = map_Double_IntPair_Vector[ii]; } Map_Double_IntPair& map_Double_IntPair = mapAngles[angleX]; - if( map_Double_IntPair.find( angleY ) != map_Double_IntPair.end() ){ + if (map_Double_IntPair.find(angleY) != map_Double_IntPair.end()) { char buffer[1024]; - (void) sprintf( buffer, "TorsionTorsion grid reorder: angle pair found twice: %15.7e %15.7e %u\n", angleX, angleY, static_cast(map_Double_IntPair.size()) ); + (void) sprintf(buffer, "TorsionTorsion grid reorder: angle pair found twice: %15.7e %15.7e %u\n", angleX, angleY, static_cast(map_Double_IntPair.size())); throw OpenMMException(buffer); } struct IntPair pair; @@ -114,24 +113,6 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, } } -#if 0 - (void) fprintf( stderr, "TorsionTorsion grid reorder map\n" ); - for( Map_Double_MapDoubleIntPairCI ii = mapAngles.begin(); ii != mapAngles.end(); ii++ ){ - double angleX = ii->first; - Map_Double_IntPair map_Double_IntPair = ii->second; - (void) fprintf( stderr, " %15.7e %u \n", angleX, static_cast(map_Double_IntPair.size()) ); - } - for( Map_Double_MapDoubleIntPairCI ii = mapAngles.begin(); ii != mapAngles.end(); ii++ ){ - double angleX = ii->first; - Map_Double_IntPair map_Double_IntPair = ii->second; - for( Map_Double_IntPairCI jj = map_Double_IntPair.begin(); jj != map_Double_IntPair.end(); jj++ ){ - double angle = jj->first; - struct IntPair pair = jj->second; - (void) fprintf( stderr, " %15.7e %15.7e %d %d\n", angleX, angle, pair.index1, pair.index2 ); - } - } -#endif - // load reordered entries Map_Double_MapDoubleIntPairCI mapII = mapAngles.begin(); @@ -144,7 +125,6 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, struct IntPair pair = mapJJ->second; int index1 = pair.index1; int index2 = pair.index2; - //(void) fprintf( stderr, " %3d %3d %15.7e %15.7e %3d %3d zzz\n", ii, jj, mapII->first, mapJJ->first, index1, index2 ); for (unsigned int kk = 0; kk < grid[ii][jj].size(); kk++) { reorderedGrid[ii][jj][kk] = static_cast(grid[index1][index2][kk]); @@ -153,12 +133,12 @@ void AmoebaTorsionTorsionForceImpl::reorderGrid( const TorsionTorsionGrid& grid, // increment map iterators mapJJ++; - if( mapJJ == map_Double_IntPair.end() ){ + if (mapJJ == map_Double_IntPair.end()) { mapII++; - if( mapII == mapAngles.end() ){ - if( (jj != (grid[ii].size()-1)) && (ii != (grid.size()-1)) ){ + if (mapII == mapAngles.end()) { + if ((jj != (grid[ii].size()-1)) && (ii != (grid.size()-1))) { char buffer[1024]; - (void) sprintf( buffer, "AmoebaTorsionTorsionForceImpl::reorderGrid: error detected with map iterators.\n" ); + (void) sprintf(buffer, "AmoebaTorsionTorsionForceImpl::reorderGrid: error detected with map iterators.\n"); throw OpenMMException(buffer); } } else { diff --git a/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp index d5c04871f..469e56d47 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaVdwForce.cpp @@ -41,13 +41,13 @@ using std::vector; AmoebaVdwForce::AmoebaVdwForce() : nonbondedMethod(NoCutoff), sigmaCombiningRule("CUBIC-MEAN"), epsilonCombiningRule("HHG"), cutoff(1.0e+10), useDispersionCorrection(true) { } -int AmoebaVdwForce::addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor ) { +int AmoebaVdwForce::addParticle(int parentIndex, double sigma, double epsilon, double reductionFactor) { parameters.push_back(VdwInfo(parentIndex, sigma, epsilon, reductionFactor)); return parameters.size()-1; } void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex, - double& sigma, double& epsilon, double& reductionFactor ) const { + double& sigma, double& epsilon, double& reductionFactor) const { parentIndex = parameters[particleIndex].parentIndex; sigma = parameters[particleIndex].sigma; epsilon = parameters[particleIndex].epsilon; @@ -55,14 +55,14 @@ void AmoebaVdwForce::getParticleParameters(int particleIndex, int& parentIndex, } void AmoebaVdwForce::setParticleParameters(int particleIndex, int parentIndex, - double sigma, double epsilon, double reductionFactor ) { + double sigma, double epsilon, double reductionFactor) { parameters[particleIndex].parentIndex = parentIndex; parameters[particleIndex].sigma = sigma; parameters[particleIndex].epsilon = epsilon; parameters[particleIndex].reductionFactor = reductionFactor; } -void AmoebaVdwForce::setSigmaCombiningRule( const std::string& inputSigmaCombiningRule ) { +void AmoebaVdwForce::setSigmaCombiningRule(const std::string& inputSigmaCombiningRule) { sigmaCombiningRule = inputSigmaCombiningRule; } @@ -70,7 +70,7 @@ const std::string& AmoebaVdwForce::getSigmaCombiningRule() const { return sigmaCombiningRule; } -void AmoebaVdwForce::setEpsilonCombiningRule( const std::string& inputEpsilonCombiningRule ) { +void AmoebaVdwForce::setEpsilonCombiningRule(const std::string& inputEpsilonCombiningRule) { epsilonCombiningRule = inputEpsilonCombiningRule; } @@ -78,31 +78,31 @@ const std::string& AmoebaVdwForce::getEpsilonCombiningRule() const { return epsilonCombiningRule; } -void AmoebaVdwForce::setParticleExclusions( int particleIndex, const std::vector< int >& inputExclusions ) { +void AmoebaVdwForce::setParticleExclusions(int particleIndex, const std::vector< int >& inputExclusions) { - if( exclusions.size() < parameters.size() ){ - exclusions.resize( parameters.size() ); + if (exclusions.size() < parameters.size()) { + exclusions.resize(parameters.size()); } - if( static_cast(exclusions.size()) < particleIndex ){ - exclusions.resize( particleIndex + 10 ); + if (static_cast(exclusions.size()) < particleIndex) { + exclusions.resize(particleIndex + 10); } - for( unsigned int ii = 0; ii < inputExclusions.size(); ii++ ){ - exclusions[particleIndex].push_back( inputExclusions[ii] ); + for (unsigned int ii = 0; ii < inputExclusions.size(); ii++) { + exclusions[particleIndex].push_back(inputExclusions[ii]); } } -void AmoebaVdwForce::getParticleExclusions( int particleIndex, std::vector< int >& outputExclusions ) const { +void AmoebaVdwForce::getParticleExclusions(int particleIndex, std::vector< int >& outputExclusions) const { - if( particleIndex < static_cast(exclusions.size()) ){ - outputExclusions.resize( exclusions[particleIndex].size() ); - for( unsigned int ii = 0; ii < exclusions[particleIndex].size(); ii++ ){ + if (particleIndex < static_cast(exclusions.size())) { + outputExclusions.resize(exclusions[particleIndex].size()); + for (unsigned int ii = 0; ii < exclusions[particleIndex].size(); ii++) { outputExclusions[ii] = exclusions[particleIndex][ii]; } } } -void AmoebaVdwForce::setCutoff( double inputCutoff ){ +void AmoebaVdwForce::setCutoff(double inputCutoff) { cutoff = inputCutoff; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp b/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp index fbe36d4d7..bb316da57 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForce.cpp @@ -48,17 +48,17 @@ AmoebaWcaDispersionForce::AmoebaWcaDispersionForce() { dispoff = 0.26; } -int AmoebaWcaDispersionForce::addParticle( double radius, double epsilon ) { - parameters.push_back(WcaDispersionInfo( radius, epsilon)); +int AmoebaWcaDispersionForce::addParticle(double radius, double epsilon) { + parameters.push_back(WcaDispersionInfo(radius, epsilon)); return parameters.size()-1; } -void AmoebaWcaDispersionForce::getParticleParameters(int particleIndex, double& radius, double& epsilon ) const { +void AmoebaWcaDispersionForce::getParticleParameters(int particleIndex, double& radius, double& epsilon) const { radius = parameters[particleIndex].radius; epsilon = parameters[particleIndex].epsilon; } -void AmoebaWcaDispersionForce::setParticleParameters(int particleIndex, double radius, double epsilon ) { +void AmoebaWcaDispersionForce::setParticleParameters(int particleIndex, double radius, double epsilon) { parameters[particleIndex].radius = radius; parameters[particleIndex].epsilon = epsilon; } @@ -95,35 +95,35 @@ double AmoebaWcaDispersionForce::getSlevy() const { return slevy; } -void AmoebaWcaDispersionForce::setEpso( double inputEpso ){ +void AmoebaWcaDispersionForce::setEpso(double inputEpso) { epso = inputEpso; } -void AmoebaWcaDispersionForce::setEpsh( double inputEpsh ){ +void AmoebaWcaDispersionForce::setEpsh(double inputEpsh) { epsh = inputEpsh; } -void AmoebaWcaDispersionForce::setRmino( double inputRmino ){ +void AmoebaWcaDispersionForce::setRmino(double inputRmino) { rmino = inputRmino; } -void AmoebaWcaDispersionForce::setRminh( double inputRminh ){ +void AmoebaWcaDispersionForce::setRminh(double inputRminh) { rminh = inputRminh; } -void AmoebaWcaDispersionForce::setAwater( double inputAwater ){ +void AmoebaWcaDispersionForce::setAwater(double inputAwater) { awater = inputAwater; } -void AmoebaWcaDispersionForce::setShctd( double inputShctd ){ +void AmoebaWcaDispersionForce::setShctd(double inputShctd) { shctd = inputShctd; } -void AmoebaWcaDispersionForce::setDispoff( double inputDispoff ){ +void AmoebaWcaDispersionForce::setDispoff(double inputDispoff) { dispoff = inputDispoff; } -void AmoebaWcaDispersionForce::setSlevy( double inputSlevy ){ +void AmoebaWcaDispersionForce::setSlevy(double inputSlevy) { slevy = inputSlevy; } diff --git a/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForceImpl.cpp b/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForceImpl.cpp index 81817b5e8..d8448d14e 100644 --- a/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForceImpl.cpp +++ b/plugins/amoeba/openmmapi/src/AmoebaWcaDispersionForceImpl.cpp @@ -61,15 +61,15 @@ double AmoebaWcaDispersionForceImpl::calcForcesAndEnergy(ContextImpl& context, b return kernel.getAs().execute(context, includeForces, includeEnergy); return 0.0; } -void AmoebaWcaDispersionForceImpl::getMaximumDispersionEnergy( const AmoebaWcaDispersionForce& force, int particleIndex, double& maxDispersionEnergy ) { +void AmoebaWcaDispersionForceImpl::getMaximumDispersionEnergy(const AmoebaWcaDispersionForce& force, int particleIndex, double& maxDispersionEnergy) { const double pi = 3.1415926535897; // from last loop in subroutine knp in ksolv.f double rdisp, epsi; - force.getParticleParameters( particleIndex, rdisp, epsi ); - if( epsi <= 0.0 || rdisp <= 0.0 ){ + force.getParticleParameters(particleIndex, rdisp, epsi); + if (epsi <= 0.0 || rdisp <= 0.0) { maxDispersionEnergy = 0.0; return; } @@ -104,32 +104,27 @@ void AmoebaWcaDispersionForceImpl::getMaximumDispersionEnergy( const AmoebaWcaDi double rdisp11 = rdisp7*rdisp3*rdisp; double cdisp; - if( rdisp < rmixh) { + if (rdisp < rmixh) { cdisp = -4.0*pi*emixh*(rmixh3-rdisp3)/3.0 - emixh*18.0/11.0*rmixh3*pi; } else { cdisp = 2.0*pi*(2.0*rmixh7-11.0*rdisp7)*ah/ (11.0*rdisp11); } cdisp *= 2.0; - if (rdisp < rmixo ) { + if (rdisp < rmixo) { cdisp -= 4.0*pi*emixo*(rmixo3-rdisp3)/3.0; cdisp -= emixo*18.0/11.0*rmixo3*pi; } else { cdisp += 2.0*pi*(2.0*rmixo7-11.0*rdisp7) * ao/(11.0*rdisp11); } maxDispersionEnergy = force.getSlevy()*force.getAwater()*cdisp; - -// (void) fprintf( stderr,"Wca %5d %14.7e %14.7e %14.7e %14.7e %14.7e %14.7e %14.7e %14.7e\n", -// particleIndex, rdisp,rmini,epsi, emixh,rmixh,emixo,rmixo,cdisp ); - - return; } -double AmoebaWcaDispersionForceImpl::getTotalMaximumDispersionEnergy( const AmoebaWcaDispersionForce& force ){ +double AmoebaWcaDispersionForceImpl::getTotalMaximumDispersionEnergy(const AmoebaWcaDispersionForce& force) { double totalMaximumDispersionEnergy = 0.0; - for( int ii = 0; ii < force.getNumParticles(); ii++ ){ + for (int ii = 0; ii < force.getNumParticles(); ii++) { double maximumDispersionEnergy; - getMaximumDispersionEnergy( force, ii, maximumDispersionEnergy ); + getMaximumDispersionEnergy(force, ii, maximumDispersionEnergy); totalMaximumDispersionEnergy += maximumDispersionEnergy; } return totalMaximumDispersionEnergy; diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp index 403066605..b11ff2e2b 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.cpp @@ -774,16 +774,16 @@ public: vector dipole1, dipole2, quadrupole1, quadrupole2; force.getMultipoleParameters(particle1, charge1, dipole1, quadrupole1, axis1, multipole11, multipole21, multipole31, thole1, damping1, polarity1); force.getMultipoleParameters(particle2, charge2, dipole2, quadrupole2, axis2, multipole12, multipole22, multipole32, thole2, damping2, polarity2); - if (charge1 != charge2 || thole1 != thole2 || damping1 != damping2 || polarity1 != polarity2 || axis1 != axis2){ + if (charge1 != charge2 || thole1 != thole2 || damping1 != damping2 || polarity1 != polarity2 || axis1 != axis2) { return false; } - for (int i = 0; i < (int) dipole1.size(); ++i){ - if (dipole1[i] != dipole2[i]){ + for (int i = 0; i < (int) dipole1.size(); ++i) { + if (dipole1[i] != dipole2[i]) { return false; } } - for (int i = 0; i < (int) quadrupole1.size(); ++i){ - if (quadrupole1[i] != quadrupole2[i]){ + for (int i = 0; i < (int) quadrupole1.size(); ++i) { + if (quadrupole1[i] != quadrupole2[i]) { return false; } } diff --git a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h index eed60f81a..a0c860824 100644 --- a/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h +++ b/plugins/amoeba/platforms/cuda/src/AmoebaCudaKernels.h @@ -343,7 +343,7 @@ public: * @param outputElectrostaticPotential output potential */ void getElectrostaticPotential(ContextImpl& context, const std::vector< Vec3 >& inputGrid, - std::vector< double >& outputElectrostaticPotential ); + std::vector< double >& outputElectrostaticPotential); /** * Get the system multipole moments @@ -353,7 +353,7 @@ public: * dipole_x, dipole_y, dipole_z, * quadrupole_xx, quadrupole_xy, quadrupole_xz, * quadrupole_yx, quadrupole_yy, quadrupole_yz, - * quadrupole_zx, quadrupole_zy, quadrupole_zz ) + * quadrupole_zx, quadrupole_zy, quadrupole_zz) */ void getSystemMultipoleMoments(ContextImpl& context, std::vector& outputMultipoleMoments); /** diff --git a/plugins/amoeba/platforms/cuda/src/kernels/bicubic.cu b/plugins/amoeba/platforms/cuda/src/kernels/bicubic.cu index 2e8521bc1..b2a391d31 100644 --- a/plugins/amoeba/platforms/cuda/src/kernels/bicubic.cu +++ b/plugins/amoeba/platforms/cuda/src/kernels/bicubic.cu @@ -26,13 +26,13 @@ __device__ void bicubic(real4 y, real4 y1i, real4 y2i, real4 y12i, real x1, real -2.0f*y12.x - y12.y - y12.z - 2.0f*y12.w; c[3][0] = 2.0f*(y.x - y.y) + y1.x + y1.y; c[3][1] = 2.0f*(y2.x - y2.y) + y12.x + y12.y; - c[3][2] = 6.0f*( y.y - y.x + y.w - y.z) + + c[3][2] = 6.0f*(y.y - y.x + y.w - y.z) + 3.0f*(y1.z + y1.w - y1.x - y1.y) + - 2.0f*( 2.0f*(y2.y - y2.x) + y2.z - y2.w) + + 2.0f*(2.0f*(y2.y - y2.x) + y2.z - y2.w) + -2.0f*(y12.x + y12.y) - y12.z - y12.w; - c[3][3] = 4.0f*( y.x - y.y + y.z - y.w) + - 2.0f*( y1.x + y1.y - y1.z - y1.w) + - 2.0f*( y2.x - y2.y - y2.z + y2.w) + + c[3][3] = 4.0f*( y.x - y.y + y.z - y.w) + + 2.0f*(y1.x + y1.y - y1.z - y1.w) + + 2.0f*(y2.x - y2.y - y2.z + y2.w) + y12.x + y12.y + y12.z + y12.w; real t = (x1-x1l) / (x1u-x1l); diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp index cd1c25cb9..1304506b8 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaAngleForce.cpp @@ -66,7 +66,7 @@ const double TOL = 1e-5; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -75,14 +75,14 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, double quadraticK, double cubicK, - double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm ) { +static void getPrefactorsGivenAngleCosine(double cosine, double idealAngle, double quadraticK, double cubicK, + double quarticK, double penticK, double sexticK, + double* dEdR, double* energyTerm) { double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0f; - } else if( cosine <= -1.0 ){ + } else if (cosine <= -1.0) { angle = RADIAN*PI_M; } else { angle = RADIAN*acos(cosine); @@ -95,11 +95,11 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou // deltaIdeal = r - r_0 - *dEdR = ( 2.0 + - 3.0*cubicK* deltaIdeal + - 4.0*quarticK*deltaIdeal2 + - 5.0*penticK* deltaIdeal3 + - 6.0*sexticK* deltaIdeal4 ); + *dEdR = (2.0 + + 3.0*cubicK* deltaIdeal + + 4.0*quarticK*deltaIdeal2 + + 5.0*penticK* deltaIdeal3 + + 6.0*sexticK* deltaIdeal4 ); *dEdR *= RADIAN*quadraticK*deltaIdeal; @@ -114,12 +114,12 @@ static void getPrefactorsGivenAngleCosine( double cosine, double idealAngle, dou } static void computeAmoebaAngleForce(int bondIndex, std::vector& positions, AmoebaAngleForce& amoebaAngleForce, - std::vector& forces, double* energy ) { + std::vector& forces, double* energy) { int particle1, particle2, particle3; double idealAngle; double quadraticK; - amoebaAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, idealAngle, quadraticK ); + amoebaAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, idealAngle, quadraticK); double cubicK = amoebaAngleForce.getAmoebaGlobalAngleCubic(); double quarticK = amoebaAngleForce.getAmoebaGlobalAngleQuartic(); @@ -129,7 +129,7 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions double deltaR[2][3]; double r2_0 = 0.0; double r2_1 = 0.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[0][ii] = positions[particle1][ii] - positions[particle2][ii]; r2_0 += deltaR[0][ii]*deltaR[0][ii]; @@ -140,9 +140,9 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions } double pVector[3]; - crossProductVector3( deltaR[0], deltaR[1], pVector ); - double rp = sqrt( pVector[0]*pVector[0] + pVector[1]*pVector[1] + pVector[2]*pVector[2] ); - if( rp < 1.0e-06 ){ + crossProductVector3(deltaR[0], deltaR[1], pVector); + double rp = sqrt(pVector[0]*pVector[0] + pVector[1]*pVector[1] + pVector[2]*pVector[2]); + if (rp < 1.0e-06) { rp = 1.0e-06; } double dot = deltaR[0][0]*deltaR[1][0] + deltaR[0][1]*deltaR[1][1] + deltaR[0][2]*deltaR[1][2]; @@ -150,16 +150,16 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions double dEdR; double energyTerm; - getPrefactorsGivenAngleCosine( cosine, idealAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm ); + getPrefactorsGivenAngleCosine(cosine, idealAngle, quadraticK, cubicK, + quarticK, penticK, sexticK, &dEdR, &energyTerm); double termA = -dEdR/(r2_0*rp); double termC = dEdR/(r2_1*rp); double deltaCrossP[3][3]; - crossProductVector3( deltaR[0], pVector, deltaCrossP[0] ); - crossProductVector3( deltaR[1], pVector, deltaCrossP[2] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[0], pVector, deltaCrossP[0]); + crossProductVector3(deltaR[1], pVector, deltaCrossP[2]); + for (int ii = 0; ii < 3; ii++) { deltaCrossP[0][ii] *= termA; deltaCrossP[2][ii] *= termC; deltaCrossP[1][ii] = -1.0*(deltaCrossP[0][ii] + deltaCrossP[2][ii]); @@ -180,51 +180,51 @@ static void computeAmoebaAngleForce(int bondIndex, std::vector& positions *energy += energyTerm; } -static void computeAmoebaAngleForces( Context& context, AmoebaAngleForce& amoebaAngleForce, - std::vector& expectedForces, double* expectedEnergy ) { +static void computeAmoebaAngleForces(Context& context, AmoebaAngleForce& amoebaAngleForce, + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaAngleForce.getNumAngles(); ii++ ){ - computeAmoebaAngleForce(ii, positions, amoebaAngleForce, expectedForces, expectedEnergy ); + for (int ii = 0; ii < amoebaAngleForce.getNumAngles(); ii++) { + computeAmoebaAngleForce(ii, positions, amoebaAngleForce, expectedForces, expectedEnergy); } return; } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaAngleForce& amoebaAngleForce, - double tolerance, const std::string& idString) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaAngleForce& amoebaAngleForce, + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaAngleForces( context, amoebaAngleForce, expectedForces, &expectedEnergy ); + computeAmoebaAngleForces(context, amoebaAngleForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } void testOneAngle() { System system; int numberOfParticles = 3; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -246,7 +246,7 @@ void testOneAngle() { amoebaAngleForce->setAmoebaGlobalAngleSextic(sexticK); system.addForce(amoebaAngleForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector positions(numberOfParticles); @@ -255,7 +255,7 @@ void testOneAngle() { positions[2] = Vec3(0, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle" ); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle"); // Try changing the angle parameters and make sure it's still correct. @@ -263,14 +263,14 @@ void testOneAngle() { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle" ); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaAngleForce, TOL, "testOneAngle" ); + compareWithExpectedForceAndEnergy(context, *amoebaAngleForce, TOL, "testOneAngle"); } int main(int argc, char* argv[]) { diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp index 2387593b4..d0e8cddb1 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaBondForce.cpp @@ -48,22 +48,22 @@ extern "C" void registerAmoebaCudaKernelFactories(); const double TOL = 1e-5; static void computeAmoebaBondForce(int bondIndex, std::vector& positions, AmoebaBondForce& amoebaBondForce, - std::vector& forces, double* energy ) { + std::vector& forces, double* energy) { int particle1, particle2; double bondLength; double quadraticK; double cubicK = amoebaBondForce.getAmoebaGlobalBondCubic(); double quarticK = amoebaBondForce.getAmoebaGlobalBondQuartic(); - amoebaBondForce.getBondParameters(bondIndex, particle1, particle2, bondLength, quadraticK ); + amoebaBondForce.getBondParameters(bondIndex, particle1, particle2, bondLength, quadraticK); double deltaR[3]; double r2 = 0.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[ii] = positions[particle2][ii] - positions[particle1][ii]; r2 += deltaR[ii]*deltaR[ii]; } - double r = sqrt( r2 ); + double r = sqrt(r2); double bondDelta = (r - bondLength); double bondDelta2 = bondDelta*bondDelta; @@ -83,40 +83,40 @@ static void computeAmoebaBondForce(int bondIndex, std::vector& positions, } -static void computeAmoebaBondForces( Context& context, AmoebaBondForce& amoebaBondForce, - std::vector& expectedForces, double* expectedEnergy ) { +static void computeAmoebaBondForces(Context& context, AmoebaBondForce& amoebaBondForce, + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaBondForce.getNumBonds(); ii++ ){ - computeAmoebaBondForce(ii, positions, amoebaBondForce, expectedForces, expectedEnergy ); + for (int ii = 0; ii < amoebaBondForce.getNumBonds(); ii++) { + computeAmoebaBondForce(ii, positions, amoebaBondForce, expectedForces, expectedEnergy); } } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaBondForce& amoebaBondForce, double tolerance, const std::string& idString) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaBondForce& amoebaBondForce, double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaBondForces( context, amoebaBondForce, expectedForces, &expectedEnergy ); + computeAmoebaBondForces(context, amoebaBondForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } void testOneBond() { @@ -134,22 +134,22 @@ void testOneBond() { double quadraticK = 1.0; double cubicK = 2.0; double quarticicK = 3.0; - amoebaBondForce->setAmoebaGlobalBondCubic( cubicK ); - amoebaBondForce->setAmoebaGlobalBondQuartic( quarticicK ); + amoebaBondForce->setAmoebaGlobalBondCubic(cubicK); + amoebaBondForce->setAmoebaGlobalBondQuartic(quarticicK); amoebaBondForce->addBond(0, 1, bondLength, quadraticK); system.addForce(amoebaBondForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector positions(2); positions[0] = Vec3(0, 1, 0); positions[1] = Vec3(0, 0, 0); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testOneBond" ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testOneBond"); } -void testTwoBond( ) { +void testTwoBond() { System system; @@ -165,14 +165,14 @@ void testTwoBond( ) { double quadraticK = 1.0; double cubicK = 2.0; double quarticicK = 3.0; - amoebaBondForce->setAmoebaGlobalBondCubic( cubicK ); - amoebaBondForce->setAmoebaGlobalBondQuartic( quarticicK ); + amoebaBondForce->setAmoebaGlobalBondCubic(cubicK); + amoebaBondForce->setAmoebaGlobalBondQuartic(quarticicK); amoebaBondForce->addBond(0, 1, bondLength, quadraticK); amoebaBondForce->addBond(1, 2, bondLength, quadraticK); system.addForce(amoebaBondForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); - //Context context(system, integrator, platform ); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); + //Context context(system, integrator, platform); std::vector positions(3); positions[0] = Vec3(0, 1, 0); @@ -180,7 +180,7 @@ void testTwoBond( ) { positions[2] = Vec3(1, 0, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond" ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond"); // Try changing the bond parameters and make sure it's still correct. @@ -189,14 +189,14 @@ void testTwoBond( ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond" ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaBondForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaBondForce, TOL, "testTwoBond" ); + compareWithExpectedForceAndEnergy(context, *amoebaBondForce, TOL, "testTwoBond"); } int main(int argc, char* argv[]) { diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp index 205c36599..bb1144953 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaGeneralizedKirkwoodForce.cpp @@ -64,10 +64,10 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 8; - amoebaMultipoleForce->setNonbondedMethod( AmoebaMultipoleForce::NoCutoff ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); + amoebaMultipoleForce->setNonbondedMethod(AmoebaMultipoleForce::NoCutoff); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); std::vector nitrogenMolecularDipole(3); std::vector nitrogenMolecularQuadrupole(9); @@ -88,8 +88,8 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce // first N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03 ); + system.addParticle(1.4007000e+01); + amoebaMultipoleForce->addMultipole(-5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to first N @@ -109,166 +109,166 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 2.4549167e-06; - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + amoebaMultipoleForce->addMultipole(1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole(1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole(1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); // second N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03 ); + system.addParticle( 1.4007000e+01); + amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to second N - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); // covalent maps std::vector< int > covalentMap; covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(0), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(1, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(1), covalentMap ); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(3, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + amoebaMultipoleForce->setCovalentMap(3, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(3, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(0), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(5, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(1), covalentMap ); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(6, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(7, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + amoebaMultipoleForce->setCovalentMap(7, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(7, static_cast(4), covalentMap); system.addForce(amoebaMultipoleForce); // GK force - amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01 ); - amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00 ); - amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm( includeCavityTerm ); + amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01); + amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); + amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm(includeCavityTerm); // addParticle: charge, radius, scalingFactor - for( unsigned int ii = 0; ii < 2; ii++ ){ - amoebaGeneralizedKirkwoodForce->addParticle( -5.7960000e-01, 1.5965000e-01, 6.9000000e-01 ); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01 ); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01 ); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01 ); + for (unsigned int ii = 0; ii < 2; ii++) { + amoebaGeneralizedKirkwoodForce->addParticle( -5.7960000e-01, 1.5965000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); } system.addForce(amoebaGeneralizedKirkwoodForce); } @@ -276,14 +276,14 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy) { std::vector positions(context.getSystem().getNumParticles()); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -293,8 +293,8 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& // setup for villin -static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::PolarizationType polarizationType, - int includeCavityTerm, std::vector& forces, double& energy ){ +static void setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::PolarizationType polarizationType, + int includeCavityTerm, std::vector& forces, double& energy) { // beginning of Multipole setup @@ -303,13 +303,13 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 596; - amoebaMultipoleForce->setNonbondedMethod( AmoebaMultipoleForce::NoCutoff ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); + amoebaMultipoleForce->setNonbondedMethod(AmoebaMultipoleForce::NoCutoff); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - system.addParticle( 1.0 ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + system.addParticle(1.0); } static const double multipoleData[] = { @@ -927,7 +927,7 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari std::vector quadrupole(9); unsigned int entriesPerParticle = 21; const double* data = multipoleData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { dipole[0] = data[dipoleIndex + 0]; dipole[1] = data[dipoleIndex + 1]; @@ -943,9 +943,9 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari quadrupole[7] = data[quadrupoleIndex + 7]; quadrupole[8] = data[quadrupoleIndex + 8]; - amoebaMultipoleForce->addMultipole( data[chargeIndex], dipole, quadrupole, static_cast(data[axisTypeIndex]), + amoebaMultipoleForce->addMultipole(data[chargeIndex], dipole, quadrupole, static_cast(data[axisTypeIndex]), static_cast(data[multipoleAtomZIndex]), static_cast(data[multipoleAtomXIndex]), static_cast(data[multipoleAtomYIndex]), - data[tholeIndex], data[dampingFactorIndex], data[polarityIndex] ); + data[tholeIndex], data[dampingFactorIndex], data[polarityIndex]); data += entriesPerParticle; } @@ -5725,15 +5725,15 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari unsigned int covalentMapDataSize = sizeof(covalentMapData)/sizeof(int); unsigned int covalentIndex = 0; - while( covalentIndex < covalentMapDataSize ){ + while (covalentIndex < covalentMapDataSize) { int particleIndex = covalentMapData[covalentIndex++]; int typeIndex = covalentMapData[covalentIndex++]; int entries = covalentMapData[covalentIndex++]; std::vector< int > covalentMap(entries); - for( unsigned int ii = 0; ii < entries; ii++ ){ + for (unsigned int ii = 0; ii < entries; ii++) { covalentMap[ii] = covalentMapData[covalentIndex++]; } - amoebaMultipoleForce->setCovalentMap( particleIndex, static_cast(typeIndex), covalentMap ); + amoebaMultipoleForce->setCovalentMap(particleIndex, static_cast(typeIndex), covalentMap); } system.addForce(amoebaMultipoleForce); @@ -5742,9 +5742,9 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari // GK force AmoebaGeneralizedKirkwoodForce* amoebaGeneralizedKirkwoodForce = new AmoebaGeneralizedKirkwoodForce(); - amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01 ); - amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00 ); - amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm( includeCavityTerm ); + amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01); + amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); + amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm(includeCavityTerm); // addParticle: charge, radius, scalingFactor @@ -6348,8 +6348,8 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari }; const double* gkData = generalizedKirkwoodData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - amoebaGeneralizedKirkwoodForce->addParticle( gkData[0], gkData[1], gkData[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + amoebaGeneralizedKirkwoodForce->addParticle(gkData[0], gkData[1], gkData[2]); gkData += 3; } system.addForce(amoebaGeneralizedKirkwoodForce); @@ -6958,15 +6958,15 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari }; const double* positionsDataPtr = positionsData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - positions[ii] = Vec3( positionsDataPtr[0], positionsDataPtr[1], positionsDataPtr[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + positions[ii] = Vec3(positionsDataPtr[0], positionsDataPtr[1], positionsDataPtr[2]); positionsDataPtr += 3; } std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -6976,39 +6976,39 @@ static void setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Polari // compare forces and energies -static void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, - const std::vector& expectedForces, - const std::vector& forces, double tolerance ) { - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); +static void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, + const std::vector& expectedForces, + const std::vector& forces, double tolerance) { + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // compare relative differences in force norms and energies -static void compareForceNormsEnergy( std::string& testName, double expectedEnergy, double energy, +static void compareForceNormsEnergy(std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - const std::vector& forces, double tolerance ) { - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + - expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); + const std::vector& forces, double tolerance) { + for (unsigned int ii = 0; ii < forces.size(); ii++) { + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + + expectedForces[ii][1]*expectedForces[ii][1] + + expectedForces[ii][2]*expectedForces[ii][2]); - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs(norm - expectedNorm); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - if( relDiff > tolerance && absDiff > 0.001 ){ + if (relDiff > tolerance && absDiff > 0.001) { std::stringstream details; details << testName << "Relative difference in norms " << relDiff << " larger than allowed tolerance at particle=" << ii; details << ": norms=" << norm << " expected norm=" << expectedNorm; throwException(__FILE__, __LINE__, details.str()); } } - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - if( energyRelDiff > tolerance ){ + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + if (energyRelDiff > tolerance) { std::stringstream details; details << testName << "Relative difference in energies " << energyRelDiff << " larger than allowed tolerance."; details << "Energies=" << energy << " expected energy=" << expectedEnergy; @@ -7036,17 +7036,17 @@ static void testGeneralizedKirkwoodAmmoniaDirectPolarization() { double expectedEnergy = -7.6636680e+01; - expectedForces[0] = Vec3( -6.9252994e+02, -8.9085133e+00, 9.6489739e+01 ); - expectedForces[1] = Vec3( 1.5593797e+02, -6.0331931e+01, 1.5104507e+01 ); - expectedForces[2] = Vec3( 1.5870088e+02, 6.1702809e+01, 6.7708985e+00 ); - expectedForces[3] = Vec3( 1.4089885e+02, 7.5870617e+00, -1.1362294e+02 ); - expectedForces[4] = Vec3( -1.8916205e+02, 2.1465549e-01, -4.3433152e+02 ); - expectedForces[5] = Vec3( 1.0208290e+01, 6.2676753e+01, 1.4987953e+02 ); - expectedForces[6] = Vec3( 4.0621859e+02, 1.8962203e-01, 1.3021956e+02 ); - expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02 ); + expectedForces[0] = Vec3( -6.9252994e+02, -8.9085133e+00, 9.6489739e+01); + expectedForces[1] = Vec3( 1.5593797e+02, -6.0331931e+01, 1.5104507e+01); + expectedForces[2] = Vec3( 1.5870088e+02, 6.1702809e+01, 6.7708985e+00); + expectedForces[3] = Vec3( 1.4089885e+02, 7.5870617e+00, -1.1362294e+02); + expectedForces[4] = Vec3( -1.8916205e+02, 2.1465549e-01, -4.3433152e+02); + expectedForces[5] = Vec3( 1.0208290e+01, 6.2676753e+01, 1.4987953e+02); + expectedForces[6] = Vec3( 4.0621859e+02, 1.8962203e-01, 1.3021956e+02); + expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for system comprised of two ammonia molecules @@ -7069,23 +7069,23 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarization() { double expectedEnergy = -7.8018875e+01; - expectedForces[0] = Vec3( -7.6820301e+02, -1.0102760e+01, 1.0094389e+02 ); - expectedForces[1] = Vec3( 1.7037307e+02, -7.5621857e+01, 2.3320365e+01 ); - expectedForces[2] = Vec3( 1.7353828e+02, 7.7199741e+01, 1.3965379e+01 ); - expectedForces[3] = Vec3( 1.5045244e+02, 8.5784569e+00, -1.3377619e+02 ); - expectedForces[4] = Vec3( -2.1811615e+02, -1.6818022e-01, -4.6103163e+02 ); - expectedForces[5] = Vec3( 6.2091942e+00, 7.6748687e+01, 1.5883463e+02 ); - expectedForces[6] = Vec3( 4.8035662e+02, 4.9704902e-01, 1.3948083e+02 ); - expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02 ); + expectedForces[0] = Vec3( -7.6820301e+02, -1.0102760e+01, 1.0094389e+02); + expectedForces[1] = Vec3( 1.7037307e+02, -7.5621857e+01, 2.3320365e+01); + expectedForces[2] = Vec3( 1.7353828e+02, 7.7199741e+01, 1.3965379e+01); + expectedForces[3] = Vec3( 1.5045244e+02, 8.5784569e+00, -1.3377619e+02); + expectedForces[4] = Vec3( -2.1811615e+02, -1.6818022e-01, -4.6103163e+02); + expectedForces[5] = Vec3( 6.2091942e+00, 7.6748687e+01, 1.5883463e+02); + expectedForces[6] = Vec3( 4.8035662e+02, 4.9704902e-01, 1.3948083e+02); + expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02); double tolerance = 2.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for system comprised of two ammonia molecules // including cavity term -static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( ) { +static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm() { std::string testName = "testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm"; @@ -7103,17 +7103,17 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( ) { double expectedEnergy = -6.0434582e+01; - expectedForces[0] = Vec3( -7.8323218e+02, -1.0097644e+01, 1.0256890e+02 ); - expectedForces[1] = Vec3( 1.7078480e+02, -7.1896701e+01, 2.0840172e+01 ); - expectedForces[2] = Vec3( 1.7394089e+02, 7.3488594e+01, 1.1484648e+01 ); - expectedForces[3] = Vec3( 1.5169364e+02, 8.5611299e+00, -1.2968050e+02 ); - expectedForces[4] = Vec3( -2.1669693e+02, -1.5926823e-01, -4.6636274e+02 ); - expectedForces[5] = Vec3( 8.7397444e+00, 7.3330990e+01, 1.6016898e+02 ); - expectedForces[6] = Vec3( 4.8684950e+02, 4.8937161e-01, 1.4137061e+02 ); - expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02 ); + expectedForces[0] = Vec3( -7.8323218e+02, -1.0097644e+01, 1.0256890e+02); + expectedForces[1] = Vec3( 1.7078480e+02, -7.1896701e+01, 2.0840172e+01); + expectedForces[2] = Vec3( 1.7394089e+02, 7.3488594e+01, 1.1484648e+01); + expectedForces[3] = Vec3( 1.5169364e+02, 8.5611299e+00, -1.2968050e+02); + expectedForces[4] = Vec3( -2.1669693e+02, -1.5926823e-01, -4.6636274e+02); + expectedForces[5] = Vec3( 8.7397444e+00, 7.3330990e+01, 1.6016898e+02); + expectedForces[6] = Vec3( 4.8684950e+02, 4.8937161e-01, 1.4137061e+02); + expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); // Try changing the particle parameters and make sure it's still correct. @@ -7143,7 +7143,7 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm( ) { // test GK direct polarization for villin system -static void testGeneralizedKirkwoodVillinDirectPolarization( ) { +static void testGeneralizedKirkwoodVillinDirectPolarization() { std::string testName = "testGeneralizedKirkwoodVillinDirectPolarization"; @@ -7151,7 +7151,7 @@ static void testGeneralizedKirkwoodVillinDirectPolarization( ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Direct, 0, forces, energy); + setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Direct, 0, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.4281157e+03; @@ -7756,18 +7756,18 @@ static void testGeneralizedKirkwoodVillinDirectPolarization( ) { }; const double* forceDataPtr = forceData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - expectedForces[ii] = Vec3( forceDataPtr[0], forceDataPtr[1], forceDataPtr[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + expectedForces[ii] = Vec3(forceDataPtr[0], forceDataPtr[1], forceDataPtr[2]); forceDataPtr += 3; } double tolerance = 1.0e-05; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test GK mutual polarization for villin system -static void testGeneralizedKirkwoodVillinMutualPolarization( ) { +static void testGeneralizedKirkwoodVillinMutualPolarization() { std::string testName = "testGeneralizedKirkwoodVillinMutualPolarization"; @@ -7775,7 +7775,7 @@ static void testGeneralizedKirkwoodVillinMutualPolarization( ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleVillin( AmoebaMultipoleForce::Mutual, 0, forces, energy); + setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Mutual, 0, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -8.6477811e+03; @@ -8380,13 +8380,13 @@ static void testGeneralizedKirkwoodVillinMutualPolarization( ) { }; const double* forceDataPtr = forceData; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - expectedForces[ii] = Vec3( forceDataPtr[0], forceDataPtr[1], forceDataPtr[2] ); + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + expectedForces[ii] = Vec3(forceDataPtr[0], forceDataPtr[1], forceDataPtr[2]); forceDataPtr += 3; } double tolerance = 1.0e-05; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } int main(int argc, char* argv[]) { diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp index eac90eec8..696c14daa 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaInPlaneAngleForce.cpp @@ -63,7 +63,7 @@ const double TOL = 1e-5; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -72,18 +72,18 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } -static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInPlaneAngle, double quadraticK, double cubicK, - double quarticK, double penticK, double sexticK, - double* dEdR, double* energyTerm ) { +static void getPrefactorsGivenInPlaneAngleCosine(double cosine, double idealInPlaneAngle, double quadraticK, double cubicK, + double quarticK, double penticK, double sexticK, + double* dEdR, double* energyTerm) { double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0f; - } else if( cosine <= -1.0 ){ + } else if (cosine <= -1.0) { angle = RADIAN*PI_M; } else { angle = RADIAN*acos(cosine); @@ -96,11 +96,11 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP // deltaIdeal = r - r_0 - *dEdR = ( 2.0 + - 3.0*cubicK* deltaIdeal + - 4.0*quarticK*deltaIdeal2 + - 5.0*penticK* deltaIdeal3 + - 6.0*sexticK* deltaIdeal4 ); + *dEdR = (2.0 + + 3.0*cubicK* deltaIdeal + + 4.0*quarticK*deltaIdeal2 + + 5.0*penticK* deltaIdeal3 + + 6.0*sexticK* deltaIdeal4 ); *dEdR *= RADIAN*quadraticK*deltaIdeal; @@ -115,12 +115,12 @@ static void getPrefactorsGivenInPlaneAngleCosine( double cosine, double idealInP } static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& positions, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, - std::vector& forces, double* energy ) { + std::vector& forces, double* energy) { int particle1, particle2, particle3, particle4; double idealInPlaneAngle; double quadraticK; - amoebaInPlaneAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK ); + amoebaInPlaneAngleForce.getAngleParameters(bondIndex, particle1, particle2, particle3, particle4, idealInPlaneAngle, quadraticK); double cubicK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleCubic(); double quarticK = amoebaInPlaneAngleForce.getAmoebaGlobalInPlaneAngleQuartic(); @@ -146,75 +146,75 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po // APxM, CPxM, ADxBD, BDxCD, TxCD, ADxT, dBxAD, CDxdB, LastDeltaAtomIndex double deltaR[LastDeltaAtomIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii]; deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii]; deltaR[CD][ii] = positions[particle3][ii] - positions[particle4][ii]; } - crossProductVector3( deltaR[AD], deltaR[CD], deltaR[T] ); + crossProductVector3(deltaR[AD], deltaR[CD], deltaR[T]); - double rT2 = dotVector3( deltaR[T], deltaR[T] ); - double delta = dotVector3( deltaR[T], deltaR[BD] ); + double rT2 = dotVector3(deltaR[T], deltaR[T]); + double delta = dotVector3(deltaR[T], deltaR[BD]); delta *= -1.0/rT2; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[P][ii] = positions[particle2][ii] + deltaR[T][ii]*delta; deltaR[AP][ii] = positions[particle1][ii] - deltaR[P][ii]; deltaR[CP][ii] = positions[particle3][ii] - deltaR[P][ii]; } - double rAp2 = dotVector3( deltaR[AP], deltaR[AP] ); - double rCp2 = dotVector3( deltaR[CP], deltaR[CP] ); - if( rAp2 <= 0.0 && rCp2 <= 0.0 ){ + double rAp2 = dotVector3(deltaR[AP], deltaR[AP]); + double rCp2 = dotVector3(deltaR[CP], deltaR[CP]); + if (rAp2 <= 0.0 && rCp2 <= 0.0) { } - crossProductVector3( deltaR[CP], deltaR[AP], deltaR[M] ); + crossProductVector3(deltaR[CP], deltaR[AP], deltaR[M]); - double rm = dotVector3( deltaR[M], deltaR[M] ); - rm = sqrt( rm ); - if( rm < 0.000001 ){ + double rm = dotVector3(deltaR[M], deltaR[M]); + rm = sqrt(rm); + if (rm < 0.000001) { rm = 0.000001; } - double dot = dotVector3( deltaR[AP], deltaR[CP] ); - double cosine = dot/sqrt( rAp2*rCp2 ); + double dot = dotVector3(deltaR[AP], deltaR[CP]); + double cosine = dot/sqrt(rAp2*rCp2); double dEdR; double energyTerm; - getPrefactorsGivenInPlaneAngleCosine( cosine, idealInPlaneAngle, quadraticK, cubicK, - quarticK, penticK, sexticK, &dEdR, &energyTerm ); + getPrefactorsGivenInPlaneAngleCosine(cosine, idealInPlaneAngle, quadraticK, cubicK, + quarticK, penticK, sexticK, &dEdR, &energyTerm); double termA = -dEdR/(rAp2*rm); double termC = dEdR/(rCp2*rm); - crossProductVector3( deltaR[AP], deltaR[M], deltaR[APxM] ); - crossProductVector3( deltaR[CP], deltaR[M], deltaR[CPxM] ); + crossProductVector3(deltaR[AP], deltaR[M], deltaR[APxM]); + crossProductVector3(deltaR[CP], deltaR[M], deltaR[CPxM]); // forces will be gathered here enum { dA, dB, dC, dD, LastDIndex }; double forceTerm[LastDIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forceTerm[dA][ii] = deltaR[APxM][ii]*termA; forceTerm[dC][ii] = deltaR[CPxM][ii]*termC; - forceTerm[dB][ii] = -1.0*( forceTerm[dA][ii] + forceTerm[dC][ii] ); + forceTerm[dB][ii] = -1.0*(forceTerm[dA][ii] + forceTerm[dC][ii]); } - double pTrT2 = dotVector3( forceTerm[dB], deltaR[T] ); + double pTrT2 = dotVector3(forceTerm[dB], deltaR[T]); pTrT2 /= rT2; - crossProductVector3( deltaR[CD], forceTerm[dB], deltaR[CDxdB] ); - crossProductVector3( forceTerm[dB], deltaR[AD], deltaR[dBxAD] ); + crossProductVector3(deltaR[CD], forceTerm[dB], deltaR[CDxdB]); + crossProductVector3(forceTerm[dB], deltaR[AD], deltaR[dBxAD]); - if( fabs( pTrT2 ) > 1.0e-08 ){ + if (fabs(pTrT2) > 1.0e-08) { double delta2 = delta*2.0; - crossProductVector3( deltaR[BD], deltaR[CD], deltaR[BDxCD] ); - crossProductVector3( deltaR[T], deltaR[CD], deltaR[TxCD] ); - crossProductVector3( deltaR[AD], deltaR[BD], deltaR[ADxBD] ); - crossProductVector3( deltaR[AD], deltaR[T], deltaR[ADxT] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[BD], deltaR[CD], deltaR[BDxCD]); + crossProductVector3(deltaR[T], deltaR[CD], deltaR[TxCD] ); + crossProductVector3(deltaR[AD], deltaR[BD], deltaR[ADxBD]); + crossProductVector3(deltaR[AD], deltaR[T], deltaR[ADxT] ); + for (int ii = 0; ii < 3; ii++) { double term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii]; forceTerm[dA][ii] += delta*deltaR[CDxdB][ii] + term*pTrT2; @@ -222,15 +222,15 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po term = deltaR[ADxBD][ii] + delta2*deltaR[ADxT][ii]; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii] + term*pTrT2; - forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); + forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]); } } else { - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { forceTerm[dA][ii] += delta*deltaR[CDxdB][ii]; forceTerm[dC][ii] += delta*deltaR[dBxAD][ii]; - forceTerm[dD][ii] = -( forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii] ); + forceTerm[dD][ii] = -(forceTerm[dA][ii] + forceTerm[dB][ii] + forceTerm[dC][ii]); } } @@ -256,47 +256,47 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po } -static void computeAmoebaInPlaneAngleForces( Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, - std::vector& expectedForces, double* expectedEnergy ) { +static void computeAmoebaInPlaneAngleForces(Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaInPlaneAngleForce.getNumAngles(); ii++ ){ + for (int ii = 0; ii < amoebaInPlaneAngleForce.getNumAngles(); ii++) { computeAmoebaInPlaneAngleForce(ii, positions, amoebaInPlaneAngleForce, expectedForces, expectedEnergy); } } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, - double tolerance, const std::string& idString) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaInPlaneAngleForce& amoebaInPlaneAngleForce, + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaInPlaneAngleForces( context, amoebaInPlaneAngleForce, expectedForces, &expectedEnergy ); + computeAmoebaInPlaneAngleForces(context, amoebaInPlaneAngleForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } void testOneAngle() { System system; int numberOfParticles = 4; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -318,7 +318,7 @@ void testOneAngle() { amoebaInPlaneAngleForce->setAmoebaGlobalInPlaneAngleSextic(sexticK); system.addForce(amoebaInPlaneAngleForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector positions(numberOfParticles); @@ -328,7 +328,7 @@ void testOneAngle() { positions[3] = Vec3(1, 1, 1); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle" ); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle"); // Try changing the angle parameters and make sure it's still correct. @@ -336,14 +336,14 @@ void testOneAngle() { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle" ); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaInPlaneAngleForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle" ); + compareWithExpectedForceAndEnergy(context, *amoebaInPlaneAngleForce, TOL, "testOneInPlaneAngle"); } int main(int argc, char* argv[]) { diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp index 700c53db3..b6ac6f524 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaMultipoleForce.cpp @@ -65,24 +65,24 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu // box double boxDimension = 0.6; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); int numberOfParticles = 8; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 1.4024714e+01 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(1.4024714e+01); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); - std::vector pmeGridDimension( 3 ); + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); std::vector nitrogenMolecularDipole(3); std::vector nitrogenMolecularQuadrupole(9); @@ -103,8 +103,8 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu // first N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03 ); + system.addParticle(1.4007000e+01); + amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to first N @@ -124,165 +124,165 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 2.4549167e-06; - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9e-01, 2.8135002e-01, 4.96e-04 ); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9e-01, 2.8135002e-01, 4.96e-04); // second N - system.addParticle( 1.4007000e+01 ); - amoebaMultipoleForce->addMultipole( -5.796e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9e-01, 3.1996314e-01, 1.073e-03 ); + system.addParticle( 1.4007000e+01); + amoebaMultipoleForce->addMultipole( -5.796e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9e-01, 3.1996314e-01, 1.073e-03); // 3 H attached to second N - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9e-01, 2.8135002e-01, 4.96e-04 ); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9e-01, 2.8135002e-01, 4.96e-04 ); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9e-01, 2.8135002e-01, 4.96e-04); // covalent maps std::vector< int > covalentMap; covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(0), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(0, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(1, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(1), covalentMap ); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(1, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 2, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(0), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(3, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(1), covalentMap ); + covalentMap.push_back(1); + covalentMap.push_back(2); + amoebaMultipoleForce->setCovalentMap(3, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 0 ); - covalentMap.push_back( 1 ); - covalentMap.push_back( 2 ); - covalentMap.push_back( 3 ); - amoebaMultipoleForce->setCovalentMap( 3, static_cast(4), covalentMap ); + covalentMap.push_back(0); + covalentMap.push_back(1); + covalentMap.push_back(2); + covalentMap.push_back(3); + amoebaMultipoleForce->setCovalentMap(3, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(0), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 4, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(4, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(5, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(1), covalentMap ); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 5, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(5, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(6, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 6, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(6, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(0), covalentMap ); + covalentMap.push_back(4); + amoebaMultipoleForce->setCovalentMap(7, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(1), covalentMap ); + covalentMap.push_back(5); + covalentMap.push_back(6); + amoebaMultipoleForce->setCovalentMap(7, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 4 ); - covalentMap.push_back( 5 ); - covalentMap.push_back( 6 ); - covalentMap.push_back( 7 ); - amoebaMultipoleForce->setCovalentMap( 7, static_cast(4), covalentMap ); + covalentMap.push_back(4); + covalentMap.push_back(5); + covalentMap.push_back(6); + covalentMap.push_back(7); + amoebaMultipoleForce->setCovalentMap(7, static_cast(4), covalentMap); system.addForce(amoebaMultipoleForce); } static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy) { std::vector positions(context.getSystem().getNumParticles()); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -292,39 +292,39 @@ static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& // compare forces and energies -static void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, +static void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, const std::vector& expectedForces, - const std::vector& forces, double tolerance ) { - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); + const std::vector& forces, double tolerance) { + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // compare relative differences in force norms and energies -static void compareForceNormsEnergy( std::string& testName, double expectedEnergy, double energy, +static void compareForceNormsEnergy(std::string& testName, double expectedEnergy, double energy, std::vector& expectedForces, - const std::vector& forces, double tolerance ) { - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - double expectedNorm = sqrt( expectedForces[ii][0]*expectedForces[ii][0] + + const std::vector& forces, double tolerance) { + for (unsigned int ii = 0; ii < forces.size(); ii++) { + double expectedNorm = sqrt(expectedForces[ii][0]*expectedForces[ii][0] + expectedForces[ii][1]*expectedForces[ii][1] + - expectedForces[ii][2]*expectedForces[ii][2] ); + expectedForces[ii][2]*expectedForces[ii][2]); - double norm = sqrt( forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2] ); - double absDiff = fabs( norm - expectedNorm ); - double relDiff = 2.0*absDiff/(fabs( norm ) + fabs( expectedNorm ) + 1.0e-08); + double norm = sqrt(forces[ii][0]*forces[ii][0] + forces[ii][1]*forces[ii][1] + forces[ii][2]*forces[ii][2]); + double absDiff = fabs(norm - expectedNorm); + double relDiff = 2.0*absDiff/(fabs(norm) + fabs(expectedNorm) + 1.0e-08); - if( relDiff > tolerance && absDiff > 0.001 ){ + if (relDiff > tolerance && absDiff > 0.001) { std::stringstream details; details << testName << "Relative difference in norms " << relDiff << " larger than allowed tolerance at particle=" << ii; details << ": norms=" << norm << " expected norm=" << expectedNorm; throwException(__FILE__, __LINE__, details.str()); } } - double energyAbsDiff = fabs( expectedEnergy - energy ); - double energyRelDiff = 2.0*energyAbsDiff/( fabs( expectedEnergy ) + fabs( energy ) + 1.0e-08 ); - if( energyRelDiff > tolerance ){ + double energyAbsDiff = fabs(expectedEnergy - energy); + double energyRelDiff = 2.0*energyAbsDiff/(fabs(expectedEnergy) + fabs(energy) + 1.0e-08); + if (energyRelDiff > tolerance) { std::stringstream details; details << testName << "Relative difference in energies " << energyRelDiff << " larger than allowed tolerance."; details << "Energies=" << energy << " expected energy=" << expectedEnergy; @@ -355,22 +355,22 @@ static void testMultipoleAmmoniaDirectPolarization() { double expectedEnergy = -1.7428832e+01; - expectedForces[0] = Vec3( -3.5574000e+02, -7.3919340e+00, 3.8989934e+01 ); - expectedForces[1] = Vec3( 3.0368045e+01, -8.7325694e+00, 6.9731151e+00 ); - expectedForces[2] = Vec3( 3.2358980e+01, 1.0234924e+01, 4.7203694e-01 ); - expectedForces[3] = Vec3( 2.1439022e+01, 5.8998414e+00, -3.8355239e+01 ); - expectedForces[4] = Vec3( -1.8052760e+02, -1.0618455e+00, -7.0030146e+01 ); - expectedForces[5] = Vec3( 4.2411304e+01, -1.6569222e+01, 1.9047581e+00 ); - expectedForces[6] = Vec3( 3.6823677e+02, 7.7839986e-01, 5.8404590e+01 ); - expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00 ); + expectedForces[0] = Vec3( -3.5574000e+02, -7.3919340e+00, 3.8989934e+01); + expectedForces[1] = Vec3( 3.0368045e+01, -8.7325694e+00, 6.9731151e+00); + expectedForces[2] = Vec3( 3.2358980e+01, 1.0234924e+01, 4.7203694e-01); + expectedForces[3] = Vec3( 2.1439022e+01, 5.8998414e+00, -3.8355239e+01); + expectedForces[4] = Vec3( -1.8052760e+02, -1.0618455e+00, -7.0030146e+01); + expectedForces[5] = Vec3( 4.2411304e+01, -1.6569222e+01, 1.9047581e+00); + expectedForces[6] = Vec3( 3.6823677e+02, 7.7839986e-01, 5.8404590e+01); + expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test multipole mutual polarization for system comprised of two ammonia molecules; no cutoff -static void testMultipoleAmmoniaMutualPolarization( ) { +static void testMultipoleAmmoniaMutualPolarization() { std::string testName = "testMultipoleAmmoniaMutualPolarization"; @@ -391,17 +391,17 @@ static void testMultipoleAmmoniaMutualPolarization( ) { double expectedEnergy = -1.7790449e+01; - expectedForces[0] = Vec3( -3.7523158e+02, -7.9806295e+00, 3.7464051e+01 ); - expectedForces[1] = Vec3( 3.1352410e+01, -9.4055551e+00, 8.5230415e+00 ); - expectedForces[2] = Vec3( 3.3504923e+01, 1.1029935e+01, 1.5052263e+00 ); - expectedForces[3] = Vec3( 2.3295507e+01, 6.3698827e+00, -4.0403553e+01 ); - expectedForces[4] = Vec3( -1.9379275e+02, -1.0903937e+00, -7.3461740e+01 ); - expectedForces[5] = Vec3( 4.3278067e+01, -1.6906589e+01, 1.5721909e+00 ); - expectedForces[6] = Vec3( 3.9529983e+02, 7.9661172e-01, 6.3499055e+01 ); - expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00 ); + expectedForces[0] = Vec3( -3.7523158e+02, -7.9806295e+00, 3.7464051e+01); + expectedForces[1] = Vec3( 3.1352410e+01, -9.4055551e+00, 8.5230415e+00); + expectedForces[2] = Vec3( 3.3504923e+01, 1.1029935e+01, 1.5052263e+00); + expectedForces[3] = Vec3( 2.3295507e+01, 6.3698827e+00, -4.0403553e+01); + expectedForces[4] = Vec3( -1.9379275e+02, -1.0903937e+00, -7.3461740e+01); + expectedForces[5] = Vec3( 4.3278067e+01, -1.6906589e+01, 1.5721909e+00); + expectedForces[6] = Vec3( 3.9529983e+02, 7.9661172e-01, 6.3499055e+01); + expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); // Try changing the particle parameters and make sure it's still correct. @@ -423,7 +423,7 @@ static void testMultipoleAmmoniaMutualPolarization( ) { bool exceptionThrown = false; try { // This should throw an exception. - compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance ); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); for (int i = 0; i < numberOfParticles; i++) ASSERT_EQUAL_VEC(state1.getForces()[i], state2.getForces()[i], tolerance); } @@ -433,15 +433,15 @@ static void testMultipoleAmmoniaMutualPolarization( ) { ASSERT(exceptionThrown); amoebaMultipoleForce->updateParametersInContext(context); state1 = context.getState(State::Forces | State::Energy); - compareForcesEnergy( testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance ); + compareForcesEnergy(testName, state2.getPotentialEnergy(), state1.getPotentialEnergy(), state2.getForces(), state1.getForces(), tolerance); } // setup for box of 4 water molecules -- used to test PME -static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, +static void setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, AmoebaMultipoleForce::PolarizationType polarizationType, double cutoff, int inputPmeGridDimension, std::vector& forces, - double& energy){ + double& energy) { // beginning of Multipole setup @@ -450,29 +450,29 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond // box dimensions double boxDimension = 1.8643; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 12; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); - - std::vector pmeGridDimension( 3 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); + + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5995000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5995000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -508,44 +508,44 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps std::vector< int > covalentMap; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(0), covalentMap ); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(4), covalentMap ); + covalentMap.push_back(jj); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(0), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(0), covalentMap ); + covalentMap.push_back(jj); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(0), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(1), covalentMap ); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); + covalentMap.push_back(jj+1); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(1), covalentMap); } @@ -555,36 +555,36 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond // addBond: particle1, particle2, length, quadraticK - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaBondForce->addBond( jj, jj+1, 0.0000000e+00, 0.0000000e+00 ); - amoebaBondForce->addBond( jj, jj+2, 0.0000000e+00, 0.0000000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaBondForce->addBond(jj, jj+1, 0.0000000e+00, 0.0000000e+00); + amoebaBondForce->addBond(jj, jj+2, 0.0000000e+00, 0.0000000e+00); } - amoebaBondForce->setAmoebaGlobalBondCubic( -2.5500000e+01 ); - amoebaBondForce->setAmoebaGlobalBondQuartic( 3.7931250e+02 ); + amoebaBondForce->setAmoebaGlobalBondCubic(-2.5500000e+01); + amoebaBondForce->setAmoebaGlobalBondQuartic(3.7931250e+02); system.addForce(amoebaBondForce); std::vector positions(numberOfParticles); - positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03 ); - positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02 ); - positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01 ); - positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01 ); - positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01 ); - positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01 ); - positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01 ); - positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01 ); - positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01 ); - positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01 ); - positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01 ); - positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01 ); + positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03); + positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02); + positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01); + positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); + positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); + positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); + positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); + positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); + positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); + positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); + positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); + positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); system.addForce(amoebaMultipoleForce); std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -594,7 +594,7 @@ static void setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::Nonbond // test multipole direct polarization using PME for box of water -static void testMultipoleWaterPMEDirectPolarization( ) { +static void testMultipoleWaterPMEDirectPolarization() { std::string testName = "testMultipoleWaterDirectPolarization"; @@ -604,32 +604,32 @@ static void testMultipoleWaterPMEDirectPolarization( ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, forces, energy ); + setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, + cutoff, inputPmeGridDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.4585115e-01; - expectedForces[0] = Vec3( -1.2396731e+00, -2.4231698e+01, 8.3348523e+00 ); - expectedForces[1] = Vec3( -3.3737276e+00, 9.9304523e+00, -6.3917827e+00 ); - expectedForces[2] = Vec3( 4.4062247e+00, 1.9518971e+01, -4.6552873e+00 ); - expectedForces[3] = Vec3( -1.3128824e+00, -1.2887339e+00, -1.4473147e+00 ); - expectedForces[4] = Vec3( 2.1137034e+00, 3.9457973e-01, 2.9269129e-01 ); - expectedForces[5] = Vec3( 1.0271174e+00, 1.2039367e+00, 1.2112214e+00 ); - expectedForces[6] = Vec3( -3.2082903e+00, 1.4979371e+01, -1.0274832e+00 ); - expectedForces[7] = Vec3( -1.1880320e+00, -1.5177166e+01, 2.5525509e+00 ); - expectedForces[8] = Vec3( 4.3607105e+00, -7.0253274e+00, 2.9522580e-01 ); - expectedForces[9] = Vec3( -3.0175134e+00, 1.3607102e+00, 6.6883370e+00 ); - expectedForces[10] = Vec3( 9.2036949e-01, -1.4717629e+00, -3.3362339e+00 ); - expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00 ); + expectedForces[0] = Vec3( -1.2396731e+00, -2.4231698e+01, 8.3348523e+00); + expectedForces[1] = Vec3( -3.3737276e+00, 9.9304523e+00, -6.3917827e+00); + expectedForces[2] = Vec3( 4.4062247e+00, 1.9518971e+01, -4.6552873e+00); + expectedForces[3] = Vec3( -1.3128824e+00, -1.2887339e+00, -1.4473147e+00); + expectedForces[4] = Vec3( 2.1137034e+00, 3.9457973e-01, 2.9269129e-01); + expectedForces[5] = Vec3( 1.0271174e+00, 1.2039367e+00, 1.2112214e+00); + expectedForces[6] = Vec3( -3.2082903e+00, 1.4979371e+01, -1.0274832e+00); + expectedForces[7] = Vec3( -1.1880320e+00, -1.5177166e+01, 2.5525509e+00); + expectedForces[8] = Vec3( 4.3607105e+00, -7.0253274e+00, 2.9522580e-01); + expectedForces[9] = Vec3( -3.0175134e+00, 1.3607102e+00, 6.6883370e+00); + expectedForces[10] = Vec3( 9.2036949e-01, -1.4717629e+00, -3.3362339e+00); + expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00); double tolerance = 1.0e-03; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test multipole mutual polarization using PME for box of water -static void testMultipoleWaterPMEMutualPolarization( ) { +static void testMultipoleWaterPMEMutualPolarization() { std::string testName = "testMultipoleWaterMutualPolarization"; @@ -639,32 +639,32 @@ static void testMultipoleWaterPMEMutualPolarization( ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, forces, energy ); + setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 6.5029855e-01; - expectedForces[0] = Vec3( -1.2367386e+00, -2.4197036e+01, 8.3256759e+00 ); - expectedForces[1] = Vec3( -3.3825187e+00, 9.9387618e+00, -6.4200475e+00 ); - expectedForces[2] = Vec3( 4.4108644e+00, 1.9486127e+01, -4.6530661e+00 ); - expectedForces[3] = Vec3( -1.3129168e+00, -1.2947383e+00, -1.4438198e+00 ); - expectedForces[4] = Vec3( 2.1144837e+00, 3.9590305e-01, 2.9040889e-01 ); - expectedForces[5] = Vec3( 1.0287222e+00, 1.2100201e+00, 1.2103068e+00 ); - expectedForces[6] = Vec3( -3.2017550e+00, 1.4995985e+01, -1.1036504e+00 ); - expectedForces[7] = Vec3( -1.2065398e+00, -1.5192899e+01, 2.6233368e+00 ); - expectedForces[8] = Vec3( 4.3698604e+00, -7.0550315e+00, 3.4204565e-01 ); - expectedForces[9] = Vec3( -3.0082825e+00, 1.3575082e+00, 6.6901032e+00 ); - expectedForces[10] = Vec3( 9.1775539e-01, -1.4651882e+00, -3.3322516e+00 ); - expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00 ); + expectedForces[0] = Vec3( -1.2367386e+00, -2.4197036e+01, 8.3256759e+00); + expectedForces[1] = Vec3( -3.3825187e+00, 9.9387618e+00, -6.4200475e+00); + expectedForces[2] = Vec3( 4.4108644e+00, 1.9486127e+01, -4.6530661e+00); + expectedForces[3] = Vec3( -1.3129168e+00, -1.2947383e+00, -1.4438198e+00); + expectedForces[4] = Vec3( 2.1144837e+00, 3.9590305e-01, 2.9040889e-01); + expectedForces[5] = Vec3( 1.0287222e+00, 1.2100201e+00, 1.2103068e+00); + expectedForces[6] = Vec3( -3.2017550e+00, 1.4995985e+01, -1.1036504e+00); + expectedForces[7] = Vec3( -1.2065398e+00, -1.5192899e+01, 2.6233368e+00); + expectedForces[8] = Vec3( 4.3698604e+00, -7.0550315e+00, 3.4204565e-01); + expectedForces[9] = Vec3( -3.0082825e+00, 1.3575082e+00, 6.6901032e+00); + expectedForces[10] = Vec3( 9.1775539e-01, -1.4651882e+00, -3.3322516e+00); + expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00); double tolerance = 1.0e-03; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // check validation of traceless/symmetric quadrupole tensor -static void testQuadrupoleValidation( ){ +static void testQuadrupoleValidation() { std::string testName = "checkQuadrupoleValidation"; @@ -677,29 +677,29 @@ static void testQuadrupoleValidation( ){ System system; double boxDimension = 1.8643; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; std::vector expectedForces(numberOfParticles); - amoebaMultipoleForce->setNonbondedMethod( AmoebaMultipoleForce::PME ); - amoebaMultipoleForce->setPolarizationType( AmoebaMultipoleForce::Direct ); - amoebaMultipoleForce->setCutoffDistance( 0.7 ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); - - std::vector pmeGridDimensions( 3 ); + amoebaMultipoleForce->setNonbondedMethod(AmoebaMultipoleForce::PME); + amoebaMultipoleForce->setPolarizationType(AmoebaMultipoleForce::Direct); + amoebaMultipoleForce->setCutoffDistance(0.7); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); + + std::vector pmeGridDimensions(3); pmeGridDimensions[0] = pmeGridDimensions[1] = pmeGridDimensions[2] = pmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimensions ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimensions); - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5995000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5995000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -735,44 +735,44 @@ static void testQuadrupoleValidation( ){ hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps /* std::vector< int > covalentMap; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(0), covalentMap ); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(4), covalentMap ); + covalentMap.push_back(jj); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(0), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(0), covalentMap ); + covalentMap.push_back(jj); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(0), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(1), covalentMap ); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); + covalentMap.push_back(jj+1); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(1), covalentMap); } */ @@ -780,36 +780,36 @@ static void testQuadrupoleValidation( ){ // addBond: particle1, particle2, length, quadraticK - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaBondForce->addBond( jj, jj+1, 0.0000000e+00, 0.0000000e+00 ); - amoebaBondForce->addBond( jj, jj+2, 0.0000000e+00, 0.0000000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaBondForce->addBond(jj, jj+1, 0.0000000e+00, 0.0000000e+00); + amoebaBondForce->addBond(jj, jj+2, 0.0000000e+00, 0.0000000e+00); } - amoebaBondForce->setAmoebaGlobalBondCubic( -2.5500000e+01 ); - amoebaBondForce->setAmoebaGlobalBondQuartic( 3.7931250e+02 ); + amoebaBondForce->setAmoebaGlobalBondCubic(-2.5500000e+01); + amoebaBondForce->setAmoebaGlobalBondQuartic(3.7931250e+02); system.addForce(amoebaBondForce); std::vector positions(numberOfParticles); - positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03 ); - positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02 ); - positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01 ); - positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01 ); - positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01 ); - positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01 ); - positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01 ); - positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01 ); - positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01 ); - positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01 ); - positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01 ); - positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01 ); + positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03); + positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02); + positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01); + positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); + positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); + positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); + positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); + positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); + positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); + positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); + positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); + positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); system.addForce(amoebaMultipoleForce); std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); @@ -817,8 +817,8 @@ static void testQuadrupoleValidation( ){ try { oxygenMolecularQuadrupole[4] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -833,8 +833,8 @@ static void testQuadrupoleValidation( ){ try { oxygenMolecularQuadrupole[1] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -847,8 +847,8 @@ static void testQuadrupoleValidation( ){ try { oxygenMolecularQuadrupole[2] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -861,8 +861,8 @@ static void testQuadrupoleValidation( ){ try { oxygenMolecularQuadrupole[5] += 0.1; - amoebaMultipoleForce->setMultipoleParameters( 0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); + amoebaMultipoleForce->setMultipoleParameters(0, -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, 1, 2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); State state = context.getState(State::Forces | State::Energy); std::stringstream buffer; buffer << "Exception not thrown for quadrupole tensor w/ nonzero trace."; @@ -878,10 +878,10 @@ static void testQuadrupoleValidation( ){ // this method does too much; I tried passing the context ptr back to // the tests methods, but the tests would seg fault w/ a bad_alloc error -static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, +static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, AmoebaMultipoleForce::PolarizationType polarizationType, double cutoff, int inputPmeGridDimension, std::string testName, - std::vector& forces, double& energy ){ + std::vector& forces, double& energy) { // beginning of Multipole setup @@ -890,10 +890,10 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: // box dimensions double boxDimensions[3] = { 6.7538, 7.2977, 7.4897 }; - Vec3 a( boxDimensions[0], 0.0, 0.0 ); - Vec3 b( 0.0, boxDimensions[1], 0.0 ); - Vec3 c( 0.0, 0.0, boxDimensions[2] ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimensions[0], 0.0, 0.0); + Vec3 b(0.0, boxDimensions[1], 0.0); + Vec3 c(0.0, 0.0, boxDimensions[2]); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; @@ -901,22 +901,22 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: int numberOfWaters = 2; int numberOfIons = numberOfParticles - numberOfWaters*3; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-05 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-05); - std::vector pmeGridDimension( 3 ); + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); // 2 ions - system.addParticle( 3.5453000e+01 ); - system.addParticle( 2.2990000e+01 ); + system.addParticle(3.5453000e+01 ); + system.addParticle(2.2990000e+01); std::vector ionDipole(3); std::vector ionQuadrupole(9); @@ -934,15 +934,15 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: ionQuadrupole[6] = 0.0000000e+00; ionQuadrupole[7] = 0.0000000e+00; ionQuadrupole[8] = 0.0000000e+00; - amoebaMultipoleForce->addMultipole( -1.0000000e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.9000000e-01, 3.9842202e-01, 4.0000000e-03 ); - amoebaMultipoleForce->addMultipole( 1.0000000e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.9000000e-01, 2.2209062e-01, 1.2000000e-04 ); + amoebaMultipoleForce->addMultipole( -1.0000000e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.9000000e-01, 3.9842202e-01, 4.0000000e-03); + amoebaMultipoleForce->addMultipole( 1.0000000e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.9000000e-01, 2.2209062e-01, 1.2000000e-04); // waters - for( unsigned int jj = 2; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5999000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5999000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -978,52 +978,52 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 2; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps std::vector< int > covalentMap; covalentMap.resize(0); - covalentMap.push_back( 0 ); - amoebaMultipoleForce->setCovalentMap( 0, static_cast(4), covalentMap ); + covalentMap.push_back(0); + amoebaMultipoleForce->setCovalentMap(0, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( 1 ); - amoebaMultipoleForce->setCovalentMap( 1, static_cast(4), covalentMap ); + covalentMap.push_back(1); + amoebaMultipoleForce->setCovalentMap(1, static_cast(4), covalentMap); - for( unsigned int jj = 2; jj < numberOfParticles; jj += 3 ){ + for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(0), covalentMap ); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(4), covalentMap ); + covalentMap.push_back(jj); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(0), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(0), covalentMap ); + covalentMap.push_back(jj); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(0), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(1), covalentMap ); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); + covalentMap.push_back(jj+1); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(1), covalentMap); } @@ -1033,32 +1033,32 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: // addBond: particle1, particle2, length, quadraticK - for( unsigned int jj = 2; jj < numberOfParticles; jj += 3 ){ - amoebaBondForce->addBond( jj, jj+1, 0.0000000e+00, 0.0000000e+00 ); - amoebaBondForce->addBond( jj, jj+2, 0.0000000e+00, 0.0000000e+00 ); + for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { + amoebaBondForce->addBond(jj, jj+1, 0.0000000e+00, 0.0000000e+00); + amoebaBondForce->addBond(jj, jj+2, 0.0000000e+00, 0.0000000e+00); } - amoebaBondForce->setAmoebaGlobalBondCubic( -2.5500000e+01 ); - amoebaBondForce->setAmoebaGlobalBondQuartic( 3.7931250e+02 ); + amoebaBondForce->setAmoebaGlobalBondCubic(-2.5500000e+01); + amoebaBondForce->setAmoebaGlobalBondQuartic(3.7931250e+02); system.addForce(amoebaBondForce); std::vector positions(numberOfParticles); - positions[0] = Vec3( -1.4364000e+00, -1.2848000e+00, 5.1940000e-01 ); - positions[1] = Vec3( -3.2644000e+00, 2.3620000e+00, 1.3643000e+00 ); - positions[2] = Vec3( -2.3780000e+00, 1.8976000e+00, -1.5921000e+00 ); - positions[3] = Vec3( -2.3485183e+00, 1.8296632e+00, -1.5310146e+00 ); - positions[4] = Vec3( -2.3784362e+00, 1.8623910e+00, -1.6814092e+00 ); - positions[5] = Vec3( -2.1821000e+00, -1.0808000e+00, 2.9547000e+00 ); - positions[6] = Vec3( -2.1198155e+00, -1.0925202e+00, 2.8825940e+00 ); - positions[7] = Vec3( -2.1537255e+00, -1.0076218e+00, 3.0099797e+00 ); + positions[0] = Vec3( -1.4364000e+00, -1.2848000e+00, 5.1940000e-01); + positions[1] = Vec3( -3.2644000e+00, 2.3620000e+00, 1.3643000e+00); + positions[2] = Vec3( -2.3780000e+00, 1.8976000e+00, -1.5921000e+00); + positions[3] = Vec3( -2.3485183e+00, 1.8296632e+00, -1.5310146e+00); + positions[4] = Vec3( -2.3784362e+00, 1.8623910e+00, -1.6814092e+00); + positions[5] = Vec3( -2.1821000e+00, -1.0808000e+00, 2.9547000e+00); + positions[6] = Vec3( -2.1198155e+00, -1.0925202e+00, 2.8825940e+00); + positions[7] = Vec3( -2.1537255e+00, -1.0076218e+00, 3.0099797e+00); system.addForce(amoebaMultipoleForce); std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context = Context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context = Context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); @@ -1072,7 +1072,7 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce:: // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEDirectPolarization( ) { +static void testMultipoleIonsAndWaterPMEDirectPolarization() { std::string testName = "testMultipoleIonsAndWaterDirectPolarization"; @@ -1083,30 +1083,30 @@ static void testMultipoleIonsAndWaterPMEDirectPolarization( ) { std::vector forces; double energy; - setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, - cutoff, inputPmeGridDimension, testName, forces, energy ); + setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Direct, + cutoff, inputPmeGridDimension, testName, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -4.6859568e+01; - expectedForces[0] = Vec3( -9.1266563e+00, 1.5193632e+01, -4.0047974e+00 ); - expectedForces[1] = Vec3( -1.0497973e+00, 1.4622548e+01, 1.1789324e+01 ); - expectedForces[2] = Vec3( -3.2564644e+00, 6.5325105e+00, -2.9698616e+00 ); - expectedForces[3] = Vec3( 3.0687040e+00, -8.4253665e-01, -3.4081010e+00 ); - expectedForces[4] = Vec3( 1.1407201e+00, -3.1491550e+00, -1.1326031e+00 ); - expectedForces[5] = Vec3( -6.1046529e+00, 9.5686061e-01, 1.1506333e-01 ); - expectedForces[6] = Vec3( 1.9275403e+00, -5.6007439e-01, -4.8387346e+00 ); - expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00 ); + expectedForces[0] = Vec3( -9.1266563e+00, 1.5193632e+01, -4.0047974e+00); + expectedForces[1] = Vec3( -1.0497973e+00, 1.4622548e+01, 1.1789324e+01); + expectedForces[2] = Vec3( -3.2564644e+00, 6.5325105e+00, -2.9698616e+00); + expectedForces[3] = Vec3( 3.0687040e+00, -8.4253665e-01, -3.4081010e+00); + expectedForces[4] = Vec3( 1.1407201e+00, -3.1491550e+00, -1.1326031e+00); + expectedForces[5] = Vec3( -6.1046529e+00, 9.5686061e-01, 1.1506333e-01); + expectedForces[6] = Vec3( 1.9275403e+00, -5.6007439e-01, -4.8387346e+00); + expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00); double tolerance = 5.0e-04; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test multipole mutual polarization using PME for system comprised of 2 ions and 2 waters -static void testMultipoleIonsAndWaterPMEMutualPolarization( ) { +static void testMultipoleIonsAndWaterPMEMutualPolarization() { std::string testName = "testMultipoleIonsAndWaterMutualPolarization"; @@ -1119,38 +1119,38 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization( ) { std::vector inputGrid; - setupAndGetForcesEnergyMultipoleIonsAndWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, forces, energy ); + setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, testName, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = -4.6859424e+01; - expectedForces[0] = Vec3( -9.1272358e+00, 1.5191516e+01, -4.0058826e+00 ); - expectedForces[1] = Vec3( -1.0497156e+00, 1.4622425e+01, 1.1789420e+01 ); - expectedForces[2] = Vec3( -3.2560478e+00, 6.5289712e+00, -2.9779483e+00 ); - expectedForces[3] = Vec3( 3.0672153e+00, -8.4407797e-01, -3.4094884e+00 ); - expectedForces[4] = Vec3( 1.1382586e+00, -3.1512949e+00, -1.1387028e+00 ); - expectedForces[5] = Vec3( -6.1050295e+00, 9.5345692e-01, 1.1488832e-01 ); - expectedForces[6] = Vec3( 1.9319945e+00, -5.5747599e-01, -4.8469044e+00 ); - expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00 ); + expectedForces[0] = Vec3( -9.1272358e+00, 1.5191516e+01, -4.0058826e+00); + expectedForces[1] = Vec3( -1.0497156e+00, 1.4622425e+01, 1.1789420e+01); + expectedForces[2] = Vec3( -3.2560478e+00, 6.5289712e+00, -2.9779483e+00); + expectedForces[3] = Vec3( 3.0672153e+00, -8.4407797e-01, -3.4094884e+00); + expectedForces[4] = Vec3( 1.1382586e+00, -3.1512949e+00, -1.1387028e+00); + expectedForces[5] = Vec3( -6.1050295e+00, 9.5345692e-01, 1.1488832e-01); + expectedForces[6] = Vec3( 1.9319945e+00, -5.5747599e-01, -4.8469044e+00); + expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00); //double tolerance = 1.0e-03; - //compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + //compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); double tolerance = 5.0e-04; - compareForceNormsEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // setup for box of 216 water molecules -- used to test PME -static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, +static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::NonbondedMethod nonbondedMethod, AmoebaMultipoleForce::PolarizationType polarizationType, double cutoff, int inputPmeGridDimension, std::string& testName, std::vector& forces, double& energy, std::vector< double >& outputMultipoleMoments, std::vector< Vec3 >& inputGrid, - std::vector< double >& outputGridPotential ){ + std::vector< double >& outputGridPotential) { // beginning of Multipole setup @@ -1159,29 +1159,29 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No // box dimensions double boxDimension = 1.8643; - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); AmoebaMultipoleForce* amoebaMultipoleForce = new AmoebaMultipoleForce();; int numberOfParticles = 648; - amoebaMultipoleForce->setNonbondedMethod( nonbondedMethod ); - amoebaMultipoleForce->setPolarizationType( polarizationType ); - amoebaMultipoleForce->setCutoffDistance( cutoff ); - amoebaMultipoleForce->setMutualInducedTargetEpsilon( 1.0e-06 ); - amoebaMultipoleForce->setMutualInducedMaxIterations( 500 ); - amoebaMultipoleForce->setAEwald( 5.4459052e+00 ); - amoebaMultipoleForce->setEwaldErrorTolerance( 1.0e-04 ); - - std::vector pmeGridDimension( 3 ); + amoebaMultipoleForce->setNonbondedMethod(nonbondedMethod); + amoebaMultipoleForce->setPolarizationType(polarizationType); + amoebaMultipoleForce->setCutoffDistance(cutoff); + amoebaMultipoleForce->setMutualInducedTargetEpsilon(1.0e-06); + amoebaMultipoleForce->setMutualInducedMaxIterations(500); + amoebaMultipoleForce->setAEwald(5.4459052e+00); + amoebaMultipoleForce->setEwaldErrorTolerance(1.0e-04); + + std::vector pmeGridDimension(3); pmeGridDimension[0] = pmeGridDimension[1] = pmeGridDimension[2] = inputPmeGridDimension; - amoebaMultipoleForce->setPmeGridDimensions( pmeGridDimension ); + amoebaMultipoleForce->setPmeGridDimensions(pmeGridDimension); - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - system.addParticle( 1.5995000e+01 ); - system.addParticle( 1.0080000e+00 ); - system.addParticle( 1.0080000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + system.addParticle(1.5995000e+01); + system.addParticle(1.0080000e+00); + system.addParticle(1.0080000e+00); } std::vector oxygenMolecularDipole(3); @@ -1217,44 +1217,44 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No hydrogenMolecularQuadrupole[7] = 0.0000000e+00; hydrogenMolecularQuadrupole[8] = 1.3452570e-04; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaMultipoleForce->addMultipole( -5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps std::vector< int > covalentMap; - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(0), covalentMap ); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - covalentMap.push_back( jj+1 ); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(4), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(4), covalentMap ); + covalentMap.push_back(jj); + covalentMap.push_back(jj+1); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(4), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(4), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(0), covalentMap ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(0), covalentMap ); + covalentMap.push_back(jj); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(0), covalentMap); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(0), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+2 ); - amoebaMultipoleForce->setCovalentMap( jj+1, static_cast(1), covalentMap ); + covalentMap.push_back(jj+2); + amoebaMultipoleForce->setCovalentMap(jj+1, static_cast(1), covalentMap); covalentMap.resize(0); - covalentMap.push_back( jj+1 ); - amoebaMultipoleForce->setCovalentMap( jj+2, static_cast(1), covalentMap ); + covalentMap.push_back(jj+1); + amoebaMultipoleForce->setCovalentMap(jj+2, static_cast(1), covalentMap); } system.addForce(amoebaMultipoleForce); @@ -1265,678 +1265,678 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No // addBond: particle1, particle2, length, quadraticK - for( unsigned int jj = 0; jj < numberOfParticles; jj += 3 ){ - amoebaBondForce->addBond( jj, jj+1, 0.0000000e+00, 0.0000000e+00 ); - amoebaBondForce->addBond( jj, jj+2, 0.0000000e+00, 0.0000000e+00 ); + for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { + amoebaBondForce->addBond(jj, jj+1, 0.0000000e+00, 0.0000000e+00); + amoebaBondForce->addBond(jj, jj+2, 0.0000000e+00, 0.0000000e+00); } - amoebaBondForce->setAmoebaGlobalBondCubic( 0.0 ); - amoebaBondForce->setAmoebaGlobalBondQuartic( 0.0 ); + amoebaBondForce->setAmoebaGlobalBondCubic(0.0); + amoebaBondForce->setAmoebaGlobalBondQuartic(0.0); system.addForce(amoebaBondForce); static std::vector positions; // Static to work around bug in Visual Studio that makes compilation very very slow. positions.resize(numberOfParticles); - positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02 ); - positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02 ); - positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02 ); - positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01 ); - positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01 ); - positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01 ); - positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01 ); - positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01 ); - positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01 ); - positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01 ); - positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01 ); - positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01 ); - positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01 ); - positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01 ); - positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01 ); - positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01 ); - positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01 ); - positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01 ); - positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01 ); - positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01 ); - positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01 ); - positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01 ); - positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01 ); - positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01 ); - positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01 ); - positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01 ); - positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02 ); - positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02 ); - positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01 ); - positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01 ); - positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01 ); - positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01 ); - positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01 ); - positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01 ); - positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01 ); - positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01 ); - positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01 ); - positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01 ); - positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01 ); - positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01 ); - positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01 ); - positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01 ); - positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01 ); - positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01 ); - positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01 ); - positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01 ); - positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01 ); - positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01 ); - positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01 ); - positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01 ); - positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01 ); - positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01 ); - positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01 ); - positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01 ); - positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01 ); - positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01 ); - positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01 ); - positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01 ); - positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01 ); - positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01 ); - positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01 ); - positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01 ); - positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01 ); - positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02 ); - positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02 ); - positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01 ); - positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02 ); - positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02 ); - positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01 ); - positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01 ); - positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01 ); - positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01 ); - positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01 ); - positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01 ); - positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01 ); - positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01 ); - positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02 ); - positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01 ); - positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01 ); - positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01 ); - positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01 ); - positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02 ); - positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01 ); - positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02 ); - positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01 ); - positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01 ); - positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01 ); - positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01 ); - positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01 ); - positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01 ); - positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01 ); - positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01 ); - positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01 ); - positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01 ); - positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01 ); - positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01 ); - positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01 ); - positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01 ); - positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01 ); - positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01 ); - positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01 ); - positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01 ); - positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01 ); - positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01 ); - positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01 ); - positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01 ); - positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01 ); - positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01 ); - positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01 ); - positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01 ); - positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01 ); - positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02 ); - positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02 ); - positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01 ); - positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01 ); - positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01 ); - positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01 ); - positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01 ); - positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01 ); - positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01 ); - positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01 ); - positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01 ); - positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01 ); - positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01 ); - positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02 ); - positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01 ); - positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01 ); - positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01 ); - positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01 ); - positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01 ); - positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01 ); - positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01 ); - positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01 ); - positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01 ); - positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01 ); - positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01 ); - positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01 ); - positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01 ); - positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01 ); - positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01 ); - positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01 ); - positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01 ); - positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01 ); - positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01 ); - positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01 ); - positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01 ); - positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01 ); - positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01 ); - positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01 ); - positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01 ); - positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01 ); - positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01 ); - positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01 ); - positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01 ); - positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01 ); - positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01 ); - positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02 ); - positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02 ); - positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02 ); - positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01 ); - positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02 ); - positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02 ); - positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01 ); - positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01 ); - positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01 ); - positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01 ); - positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01 ); - positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01 ); - positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01 ); - positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01 ); - positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01 ); - positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01 ); - positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01 ); - positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01 ); - positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01 ); - positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01 ); - positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01 ); - positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01 ); - positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01 ); - positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01 ); - positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01 ); - positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01 ); - positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01 ); - positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01 ); - positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01 ); - positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01 ); - positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02 ); - positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01 ); - positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03 ); - positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01 ); - positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01 ); - positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01 ); - positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01 ); - positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01 ); - positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01 ); - positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01 ); - positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01 ); - positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01 ); - positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01 ); - positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01 ); - positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01 ); - positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02 ); - positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01 ); - positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02 ); - positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01 ); - positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01 ); - positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01 ); - positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01 ); - positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01 ); - positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01 ); - positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01 ); - positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01 ); - positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01 ); - positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01 ); - positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01 ); - positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01 ); - positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01 ); - positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01 ); - positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01 ); - positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01 ); - positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01 ); - positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01 ); - positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01 ); - positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01 ); - positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01 ); - positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02 ); - positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01 ); - positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02 ); - positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01 ); - positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01 ); - positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01 ); - positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01 ); - positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01 ); - positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01 ); - positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01 ); - positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01 ); - positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01 ); - positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01 ); - positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01 ); - positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01 ); - positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01 ); - positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01 ); - positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01 ); - positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02 ); - positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01 ); - positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02 ); - positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01 ); - positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01 ); - positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01 ); - positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01 ); - positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01 ); - positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01 ); - positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01 ); - positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01 ); - positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01 ); - positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01 ); - positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01 ); - positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01 ); - positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01 ); - positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01 ); - positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01 ); - positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01 ); - positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01 ); - positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01 ); - positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03 ); - positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03 ); - positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02 ); - positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01 ); - positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01 ); - positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01 ); - positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01 ); - positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01 ); - positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01 ); - positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01 ); - positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01 ); - positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01 ); - positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01 ); - positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01 ); - positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01 ); - positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01 ); - positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01 ); - positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01 ); - positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01 ); - positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01 ); - positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01 ); - positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01 ); - positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01 ); - positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01 ); - positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02 ); - positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01 ); - positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02 ); - positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01 ); - positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01 ); - positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01 ); - positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01 ); - positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02 ); - positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02 ); - positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01 ); - positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01 ); - positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01 ); - positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01 ); - positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01 ); - positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01 ); - positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01 ); - positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01 ); - positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01 ); - positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01 ); - positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01 ); - positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01 ); - positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01 ); - positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01 ); - positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01 ); - positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01 ); - positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01 ); - positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01 ); - positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02 ); - positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01 ); - positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02 ); - positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01 ); - positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01 ); - positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01 ); - positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01 ); - positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01 ); - positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01 ); - positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01 ); - positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01 ); - positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01 ); - positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02 ); - positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02 ); - positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02 ); - positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01 ); - positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01 ); - positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01 ); - positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01 ); - positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01 ); - positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01 ); - positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01 ); - positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01 ); - positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01 ); - positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01 ); - positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01 ); - positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01 ); - positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02 ); - positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02 ); - positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02 ); - positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01 ); - positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01 ); - positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01 ); - positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01 ); - positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01 ); - positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01 ); - positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01 ); - positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01 ); - positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01 ); - positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01 ); - positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01 ); - positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01 ); - positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01 ); - positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01 ); - positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01 ); - positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01 ); - positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01 ); - positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01 ); - positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01 ); - positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02 ); - positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01 ); - positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01 ); - positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02 ); - positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01 ); - positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01 ); - positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01 ); - positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01 ); - positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01 ); - positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01 ); - positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01 ); - positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01 ); - positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01 ); - positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01 ); - positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02 ); - positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02 ); - positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02 ); - positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01 ); - positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01 ); - positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01 ); - positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01 ); - positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01 ); - positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01 ); - positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01 ); - positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01 ); - positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01 ); - positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01 ); - positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01 ); - positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01 ); - positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01 ); - positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01 ); - positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01 ); - positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01 ); - positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01 ); - positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01 ); - positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01 ); - positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01 ); - positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01 ); - positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01 ); - positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01 ); - positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01 ); - positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02 ); - positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01 ); - positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03 ); - positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01 ); - positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01 ); - positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01 ); - positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01 ); - positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01 ); - positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01 ); - positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03 ); - positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02 ); - positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03 ); - positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01 ); - positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01 ); - positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01 ); - positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01 ); - positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01 ); - positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01 ); - positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01 ); - positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01 ); - positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01 ); - positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01 ); - positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01 ); - positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01 ); - positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01 ); - positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01 ); - positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01 ); - positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01 ); - positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01 ); - positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01 ); - positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01 ); - positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01 ); - positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01 ); - positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01 ); - positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01 ); - positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01 ); - positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02 ); - positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02 ); - positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01 ); - positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01 ); - positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01 ); - positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01 ); - positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01 ); - positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01 ); - positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01 ); - positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01 ); - positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01 ); - positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01 ); - positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01 ); - positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01 ); - positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01 ); - positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01 ); - positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01 ); - positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01 ); - positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01 ); - positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01 ); - positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01 ); - positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01 ); - positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01 ); - positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01 ); - positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01 ); - positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01 ); - positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01 ); - positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01 ); - positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01 ); - positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01 ); - positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02 ); - positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03 ); - positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01 ); - positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01 ); - positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01 ); - positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01 ); - positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01 ); - positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01 ); - positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01 ); - positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01 ); - positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01 ); - positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01 ); - positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01 ); - positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01 ); - positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02 ); - positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01 ); - positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01 ); - positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01 ); - positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01 ); - positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01 ); - positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01 ); - positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01 ); - positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01 ); - positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01 ); - positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01 ); - positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01 ); - positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01 ); - positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01 ); - positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01 ); - positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01 ); - positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01 ); - positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01 ); - positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01 ); - positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01 ); - positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01 ); - positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01 ); - positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01 ); - positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01 ); - positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01 ); - positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01 ); - positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01 ); - positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01 ); - positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01 ); - positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01 ); - positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01 ); - positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01 ); - positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01 ); - positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01 ); - positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01 ); - positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01 ); - positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01 ); - positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01 ); - positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01 ); - positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01 ); - positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01 ); - positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01 ); - positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01 ); - positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01 ); - positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01 ); - positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01 ); - positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01 ); - positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01 ); - positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01 ); - positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01 ); - positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01 ); - positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01 ); - positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01 ); - positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01 ); - positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01 ); - positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01 ); - positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01 ); - positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01 ); - positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01 ); - positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01 ); - positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01 ); - positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01 ); - positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01 ); - positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01 ); - positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01 ); - positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01 ); - positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01 ); - positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02 ); - positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01 ); - positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02 ); - positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01 ); - positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01 ); - positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02 ); - positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02 ); - positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02 ); - positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02 ); - positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01 ); - positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01 ); - positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01 ); - positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01 ); - positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02 ); - positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02 ); - positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01 ); - positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01 ); - positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01 ); - positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01 ); - positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01 ); - positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01 ); - positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01 ); - positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01 ); - positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01 ); - positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02 ); - positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02 ); - positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02 ); - positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02 ); - positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02 ); - positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01 ); - positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01 ); - positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01 ); - positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01 ); - positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01 ); - positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01 ); - positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01 ); - positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01 ); - positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01 ); - positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01 ); - positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01 ); - positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01 ); - positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01 ); - positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01 ); - positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01 ); - positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01 ); - positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01 ); - positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01 ); - positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01 ); - positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01 ); - positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01 ); - positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01 ); - positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01 ); - positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01 ); - positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01 ); - positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01 ); - positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01 ); - positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01 ); - positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01 ); - positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01 ); - positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01 ); - positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01 ); - positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01 ); - positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01 ); - positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01 ); - positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01 ); - positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01 ); - positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01 ); - positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01 ); - positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01 ); - positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01 ); - positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01 ); - positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01 ); - positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01 ); - positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01 ); - positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01 ); - positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01 ); - positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01 ); - positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01 ); - positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01 ); - positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01 ); - positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01 ); - positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01 ); - positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01 ); - positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01 ); - positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01 ); - positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01 ); - positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01 ); - positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01 ); - positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01 ); - positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01 ); - positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01 ); - positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01 ); - positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01 ); - positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01 ); - positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01 ); - positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01 ); + positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); + positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); + positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); + positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); + positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); + positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); + positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01); + positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01); + positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01); + positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); + positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); + positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); + positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); + positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); + positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); + positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01); + positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01); + positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01); + positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01); + positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01); + positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01); + positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01); + positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01); + positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); + positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01); + positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01); + positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02); + positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02); + positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01); + positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01); + positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); + positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); + positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); + positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); + positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01); + positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); + positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); + positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); + positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01); + positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); + positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); + positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); + positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); + positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); + positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); + positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); + positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); + positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); + positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01); + positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01); + positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01); + positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01); + positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01); + positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01); + positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); + positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); + positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); + positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01); + positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01); + positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01); + positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); + positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); + positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); + positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02); + positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02); + positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01); + positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02); + positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02); + positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01); + positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01); + positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01); + positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01); + positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); + positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); + positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); + positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01); + positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02); + positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01); + positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); + positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); + positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); + positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); + positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); + positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); + positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01); + positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); + positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); + positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); + positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); + positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); + positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); + positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); + positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); + positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01); + positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01); + positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01); + positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); + positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); + positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); + positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); + positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); + positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); + positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01); + positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01); + positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01); + positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); + positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); + positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); + positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); + positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); + positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); + positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); + positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); + positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); + positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01); + positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01); + positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01); + positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01); + positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01); + positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01); + positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); + positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); + positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); + positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01); + positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02); + positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01); + positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01); + positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01); + positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01); + positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); + positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); + positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); + positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01); + positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01); + positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01); + positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01); + positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01); + positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01); + positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01); + positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01); + positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01); + positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); + positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); + positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); + positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); + positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); + positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); + positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); + positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); + positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); + positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01); + positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01); + positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01); + positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01); + positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01); + positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01); + positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02); + positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02); + positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); + positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); + positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); + positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); + positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); + positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); + positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); + positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); + positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); + positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); + positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); + positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01); + positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); + positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01); + positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01); + positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01); + positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); + positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); + positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); + positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01); + positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01); + positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01); + positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); + positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); + positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); + positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01); + positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01); + positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01); + positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02); + positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01); + positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03); + positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01); + positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01); + positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01); + positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); + positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); + positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); + positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); + positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01); + positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); + positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01); + positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01); + positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01); + positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); + positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); + positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); + positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); + positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); + positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); + positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01); + positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01); + positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01); + positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); + positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); + positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); + positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01); + positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01); + positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01); + positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); + positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); + positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); + positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); + positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01); + positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01); + positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); + positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); + positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); + positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); + positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); + positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); + positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01); + positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01); + positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01); + positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01); + positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01); + positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01); + positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); + positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); + positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); + positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01); + positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01); + positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01); + positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01); + positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01); + positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01); + positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); + positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); + positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); + positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01); + positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01); + positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01); + positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); + positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); + positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); + positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); + positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); + positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); + positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01); + positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01); + positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); + positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01); + positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01); + positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01); + positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01); + positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01); + positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01); + positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); + positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); + positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); + positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01); + positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01); + positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01); + positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); + positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); + positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); + positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); + positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); + positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); + positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); + positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); + positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); + positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01); + positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01); + positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01); + positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01); + positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01); + positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01); + positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01); + positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01); + positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01); + positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02); + positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01); + positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02); + positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01); + positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01); + positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01); + positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); + positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); + positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); + positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01); + positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); + positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01); + positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01); + positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01); + positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01); + positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01); + positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01); + positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01); + positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); + positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); + positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); + positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); + positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); + positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); + positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01); + positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01); + positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01); + positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02); + positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01); + positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02); + positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); + positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); + positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); + positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01); + positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01); + positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01); + positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01); + positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01); + positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01); + positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02); + positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02); + positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02); + positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01); + positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01); + positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01); + positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01); + positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01); + positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01); + positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01); + positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01); + positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01); + positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); + positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); + positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); + positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); + positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); + positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); + positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01); + positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01); + positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01); + positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); + positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); + positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); + positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01); + positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01); + positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01); + positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); + positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); + positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); + positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); + positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); + positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); + positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01); + positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01); + positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01); + positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01); + positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02); + positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01); + positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01); + positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02); + positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01); + positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01); + positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01); + positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01); + positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01); + positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01); + positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01); + positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); + positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); + positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); + positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); + positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); + positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); + positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); + positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); + positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); + positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); + positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); + positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); + positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01); + positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01); + positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01); + positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01); + positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01); + positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01); + positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); + positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); + positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); + positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01); + positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01); + positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01); + positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); + positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); + positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); + positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); + positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); + positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); + positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); + positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); + positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); + positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); + positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); + positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01); + positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); + positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); + positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); + positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); + positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); + positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); + positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01); + positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01); + positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01); + positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); + positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); + positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); + positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01); + positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01); + positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01); + positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); + positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); + positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); + positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01); + positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01); + positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01); + positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); + positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); + positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); + positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01); + positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01); + positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01); + positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); + positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); + positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); + positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02); + positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); + positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01); + positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); + positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); + positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); + positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); + positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); + positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); + positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01); + positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01); + positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01); + positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01); + positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01); + positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01); + positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); + positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); + positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); + positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01); + positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01); + positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01); + positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01); + positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01); + positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01); + positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01); + positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01); + positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01); + positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); + positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); + positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); + positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); + positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); + positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); + positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); + positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); + positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); + positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); + positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); + positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); + positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01); + positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01); + positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01); + positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01); + positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01); + positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02); + positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01); + positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01); + positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01); + positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); + positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); + positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); + positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01); + positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01); + positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01); + positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01); + positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01); + positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01); + positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01); + positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01); + positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01); + positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01); + positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01); + positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01); + positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01); + positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01); + positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01); + positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); + positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); + positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); + positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); + positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); + positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); + positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01); + positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01); + positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01); + positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01); + positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01); + positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01); + positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); + positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); + positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); + positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); + positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); + positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); + positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); + positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); + positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); + positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); + positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); + positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); + positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); + positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); + positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); + positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); + positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); + positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); + positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); + positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); + positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); + positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); + positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); + positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); + positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01); + positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01); + positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01); + positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01); + positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01); + positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01); + positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01); + positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01); + positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01); + positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); + positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); + positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); + positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01); + positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01); + positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02); + positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02); + positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02); + positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02); + positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01); + positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01); + positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01); + positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); + positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); + positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); + positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01); + positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01); + positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); + positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01); + positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01); + positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01); + positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01); + positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01); + positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01); + positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); + positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02); + positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); + positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02); + positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02); + positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01); + positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01); + positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01); + positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01); + positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); + positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); + positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); + positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); + positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); + positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); + positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01); + positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01); + positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01); + positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01); + positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01); + positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01); + positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01); + positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01); + positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01); + positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); + positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); + positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); + positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01); + positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01); + positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01); + positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); + positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); + positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); + positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); + positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); + positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); + positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01); + positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01); + positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01); + positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); + positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); + positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); + positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01); + positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01); + positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01); + positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01); + positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01); + positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01); + positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); + positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); + positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); + positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); + positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); + positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); + positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01); + positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01); + positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01); + positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); + positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); + positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); + positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); + positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); + positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); + positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01); + positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01); + positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01); + positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); + positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); + positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); + positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01); + positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01); + positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01); std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); - if( testName == "testSystemMultipoleMoments" ){ - amoebaMultipoleForce->getSystemMultipoleMoments(context, outputMultipoleMoments ); - } else if( testName == "testMultipoleGridPotential" ){ - amoebaMultipoleForce->getElectrostaticPotential( inputGrid, context, outputGridPotential ); + if (testName == "testSystemMultipoleMoments") { + amoebaMultipoleForce->getSystemMultipoleMoments(context, outputMultipoleMoments); + } else if (testName == "testMultipoleGridPotential") { + amoebaMultipoleForce->getElectrostaticPotential(inputGrid, context, outputGridPotential); } else { State state = context.getState(State::Forces | State::Energy); forces = state.getForces(); @@ -1948,7 +1948,7 @@ static void setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::No // test multipole mutual polarization using PME for box of water -static void testPMEMutualPolarizationLargeWater( ) { +static void testPMEMutualPolarizationLargeWater() { std::string testName = "testPMEMutualPolarizationLargeWater"; @@ -1961,665 +1961,665 @@ static void testPMEMutualPolarizationLargeWater( ) { std::vector< Vec3 > inputGrid; std::vector< double > outputGridPotential; - setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential ); + setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, testName, + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential); static std::vector expectedForces; // Static to work around bug in Visual Studio that makes compilation very very slow. expectedForces.resize(numberOfParticles); double expectedEnergy = -1.3268930e+04; - expectedForces[0] = Vec3( -5.2764003e+02, 6.5154502e+02, 7.8683284e+02 ); - expectedForces[1] = Vec3( 3.3391292e+02, -1.1162521e+03, -2.9173021e+02 ); - expectedForces[2] = Vec3( 9.4613310e+01, -5.8988099e+01, -6.2871010e+02 ); - expectedForces[3] = Vec3( -1.6179658e+03, 1.8222798e+02, -1.0373083e+02 ); - expectedForces[4] = Vec3( 1.0177962e+03, 1.7118957e+02, 4.0084976e+02 ); - expectedForces[5] = Vec3( 3.0582540e+02, -5.5215191e+02, 4.8287747e+01 ); - expectedForces[6] = Vec3( -5.4931641e+01, -6.7689368e+02, -1.2260977e+03 ); - expectedForces[7] = Vec3( -2.9961754e+02, 1.3602079e+03, -2.2087612e+02 ); - expectedForces[8] = Vec3( -3.1788045e+02, -1.3540025e+02, 1.1250958e+03 ); - expectedForces[9] = Vec3( 1.0275111e+03, 1.9279625e+02, -6.0872252e+02 ); - expectedForces[10] = Vec3( -5.7512410e+02, -5.6280482e+01, 7.5039261e+02 ); - expectedForces[11] = Vec3( -4.7291981e+02, -3.5875411e+01, 5.2335135e+00 ); - expectedForces[12] = Vec3( -1.5619899e+02, -1.3743370e+02, 1.3587339e+03 ); - expectedForces[13] = Vec3( -4.7423876e+02, 1.0032873e+02, -2.0875847e+02 ); - expectedForces[14] = Vec3( 7.5621178e+02, 3.7979419e+01, -4.1221012e+02 ); - expectedForces[15] = Vec3( 6.7318876e+02, 4.9937148e+02, 1.1665351e+03 ); - expectedForces[16] = Vec3( -7.0858091e+01, 8.4758233e+01, -1.3126942e+03 ); - expectedForces[17] = Vec3( -1.0636296e+03, -1.6254851e+02, -1.0982809e+02 ); - expectedForces[18] = Vec3( -1.0249489e+03, 6.7073895e+02, -2.0754278e+02 ); - expectedForces[19] = Vec3( 5.6396078e+02, -1.1702137e+03, 1.5324295e+02 ); - expectedForces[20] = Vec3( 6.1635144e+02, 5.6122242e+02, -7.9410893e+01 ); - expectedForces[21] = Vec3( -1.5785582e+02, -1.0857764e+03, -1.1010131e+03 ); - expectedForces[22] = Vec3( 2.3733181e+01, 2.0158373e+02, 3.2583783e+02 ); - expectedForces[23] = Vec3( 1.8855396e+02, 1.2408889e+03, 4.5759149e+02 ); - expectedForces[24] = Vec3( 9.3643408e+02, -6.1331107e+01, -3.8601431e+02 ); - expectedForces[25] = Vec3( -3.1972504e+02, -1.5783340e+02, -1.3838003e+02 ); - expectedForces[26] = Vec3( -5.1178039e+02, -2.5998898e+02, 6.1021975e+02 ); - expectedForces[27] = Vec3( 9.1836250e+02, -4.3288112e+02, -9.5579501e+02 ); - expectedForces[28] = Vec3( -9.3325184e+02, 6.2859013e+01, 5.0743198e+02 ); - expectedForces[29] = Vec3( 3.1839963e+02, 5.4102155e+02, 1.1261345e+03 ); - expectedForces[30] = Vec3( 7.3842640e+02, 1.0907054e+02, -2.1126612e+02 ); - expectedForces[31] = Vec3( -1.8470175e+02, -4.0377182e+01, 1.2464073e+02 ); - expectedForces[32] = Vec3( -5.8931386e+02, -3.5021489e+02, -7.2769901e+01 ); - expectedForces[33] = Vec3( 1.4804452e+02, -1.2138869e+02, -1.2423820e+03 ); - expectedForces[34] = Vec3( -2.4850935e+02, 2.3113218e+01, 1.4041979e+02 ); - expectedForces[35] = Vec3( 1.3188525e+02, -6.1243481e+02, 6.4886373e+02 ); - expectedForces[36] = Vec3( 5.0217683e+02, 9.2857480e+02, -7.2500648e+02 ); - expectedForces[37] = Vec3( 9.9446320e+01, -3.0337270e+02, 8.0439741e+02 ); - expectedForces[38] = Vec3( -1.7167491e+02, -9.3911948e+02, 5.6412500e+01 ); - expectedForces[39] = Vec3( -6.6143649e+02, 1.0876882e+03, 3.3801466e+02 ); - expectedForces[40] = Vec3( 5.6748150e+02, -2.2459572e+02, 3.8360728e+02 ); - expectedForces[41] = Vec3( 7.7688834e+02, -6.7341171e+02, -6.4292796e+02 ); - expectedForces[42] = Vec3( 1.0253263e+02, -1.3212797e+03, 9.3279892e+02 ); - expectedForces[43] = Vec3( 1.5424247e+02, -1.0197346e+01, -8.0230728e+02 ); - expectedForces[44] = Vec3( -6.6499384e+02, 1.2534353e+03, -1.6748341e+02 ); - expectedForces[45] = Vec3( -1.9282945e+02, 5.1764789e+02, 1.5108154e+03 ); - expectedForces[46] = Vec3( -4.9204245e+02, 8.8664089e+02, -8.8381078e+02 ); - expectedForces[47] = Vec3( 1.3207641e+01, -5.7765859e+02, -3.5921690e+02 ); - expectedForces[48] = Vec3( 4.1691955e+02, -1.1292452e+03, -6.2339128e+02 ); - expectedForces[49] = Vec3( 4.8613761e+02, 6.8325845e+02, 2.3424652e+02 ); - expectedForces[50] = Vec3( 3.1827501e+01, 6.8442319e+02, -5.8685438e+02 ); - expectedForces[51] = Vec3( 1.1834790e+03, -1.3418299e+03, 5.6280882e+02 ); - expectedForces[52] = Vec3( -5.8629616e+02, -6.9100489e+01, -9.7784543e+02 ); - expectedForces[53] = Vec3( -4.0294748e+02, 5.0669032e+02, 5.3893512e+02 ); - expectedForces[54] = Vec3( 6.3555947e+01, -9.0345643e+02, 7.2235587e+02 ); - expectedForces[55] = Vec3( 4.9353706e+02, 4.3952680e+02, -1.5413911e+02 ); - expectedForces[56] = Vec3( -3.4663273e+02, 8.4708544e+02, -8.8983178e+01 ); - expectedForces[57] = Vec3( 1.5746383e+03, 5.8209931e+02, 3.6645765e+02 ); - expectedForces[58] = Vec3( -4.0076588e+02, -1.2311235e+02, -1.6226002e+02 ); - expectedForces[59] = Vec3( -3.3837369e+02, -5.3890252e+02, -5.5997831e+02 ); - expectedForces[60] = Vec3( 8.6512912e+02, -1.0775827e+03, -3.6920406e+02 ); - expectedForces[61] = Vec3( 1.0588621e+01, 4.4531974e+02, 1.1838800e+02 ); - expectedForces[62] = Vec3( -7.0505255e+02, 1.5737739e+02, 3.0134165e+02 ); - expectedForces[63] = Vec3( -1.2833932e+03, 5.1206074e+02, -9.3423828e+01 ); - expectedForces[64] = Vec3( 2.0863538e+02, -6.7108922e+02, 3.5777952e+02 ); - expectedForces[65] = Vec3( 4.9710436e+02, -6.8550896e+01, -2.7502680e+02 ); - expectedForces[66] = Vec3( 4.0388289e+02, 1.0051571e+03, -2.3823633e+02 ); - expectedForces[67] = Vec3( -3.3895858e+02, -6.7577709e+02, 3.1521120e+02 ); - expectedForces[68] = Vec3( -4.8763670e+02, -2.9427128e+02, 2.9500438e+02 ); - expectedForces[69] = Vec3( -8.4080783e+02, -1.7777886e+02, 6.5087880e+02 ); - expectedForces[70] = Vec3( 2.1136356e+02, 6.6812142e+01, -5.5437438e+02 ); - expectedForces[71] = Vec3( -1.3829189e+01, 7.0936421e+02, -5.0847380e+02 ); - expectedForces[72] = Vec3( -1.5684247e+03, 1.6837339e+02, -4.6044105e+02 ); - expectedForces[73] = Vec3( 9.9163605e+02, -4.1397181e+02, -3.9624142e+02 ); - expectedForces[74] = Vec3( 6.7355000e+02, 5.7652252e+02, 1.0565003e+03 ); - expectedForces[75] = Vec3( -1.3722105e+03, -1.4035644e+03, 2.7882380e+02 ); - expectedForces[76] = Vec3( 5.2187588e+02, 3.9602986e+02, -2.2564009e+02 ); - expectedForces[77] = Vec3( 2.6381283e+02, 4.2945748e+02, 1.8339201e+02 ); - expectedForces[78] = Vec3( 5.3099327e+02, 1.7312849e+03, 3.5385638e+01 ); - expectedForces[79] = Vec3( -2.1320977e+02, -1.1795453e+03, -5.1691859e+02 ); - expectedForces[80] = Vec3( -7.1445218e+02, -5.8918750e+02, 7.6494816e+02 ); - expectedForces[81] = Vec3( 1.0849545e+03, 6.5058603e+02, -5.6051049e+02 ); - expectedForces[82] = Vec3( -4.6986151e+02, -3.3868080e+02, 7.9000645e+02 ); - expectedForces[83] = Vec3( -3.8404718e+02, -4.4915037e+02, -4.2069600e+02 ); - expectedForces[84] = Vec3( -3.0678477e+02, -7.2558567e+02, 2.0276275e+02 ); - expectedForces[85] = Vec3( 6.2969625e+01, 3.4257826e+02, -6.8348290e+02 ); - expectedForces[86] = Vec3( 3.1042613e+02, 9.6563445e+01, -1.8788848e+02 ); - expectedForces[87] = Vec3( 2.4427535e+01, 5.8460648e+02, -1.3720684e+03 ); - expectedForces[88] = Vec3( -4.9904469e+02, -9.1309605e+02, 1.4350031e+02 ); - expectedForces[89] = Vec3( -4.0910847e+01, 5.2845046e+01, 2.7341591e+02 ); - expectedForces[90] = Vec3( -4.5190765e+02, 2.2820859e+02, -1.1052181e+03 ); - expectedForces[91] = Vec3( 9.1626336e+01, -1.0496400e+03, 1.0216011e+02 ); - expectedForces[92] = Vec3( -1.2592678e+02, -4.4050520e+01, 1.0764584e+03 ); - expectedForces[93] = Vec3( 8.4216135e+02, 1.7603150e+02, 1.3698861e+03 ); - expectedForces[94] = Vec3( 1.2583734e+02, 3.4343971e+02, -7.3070182e+02 ); - expectedForces[95] = Vec3( -4.5597370e+02, -6.8170738e+02, -5.2258658e+02 ); - expectedForces[96] = Vec3( 1.3295639e+03, 2.5031118e+02, -3.5171095e+02 ); - expectedForces[97] = Vec3( -2.0136001e+02, -2.2978012e+02, 2.1122610e+02 ); - expectedForces[98] = Vec3( -1.1279722e+03, -9.9794730e+02, -1.1321006e+02 ); - expectedForces[99] = Vec3( 2.9553179e+02, -2.0727600e+02, -1.8912317e+03 ); - expectedForces[100] = Vec3( -9.3777487e+02, 4.3417972e+02, 5.7436670e+02 ); - expectedForces[101] = Vec3( 3.1120364e+02, -4.3241206e+00, 5.6666340e+02 ); - expectedForces[102] = Vec3( -6.6764840e+02, -2.3563274e+02, 9.9017992e+02 ); - expectedForces[103] = Vec3( 8.2857598e+02, 1.9030059e+02, -2.4295780e+02 ); - expectedForces[104] = Vec3( -2.6709334e+02, 7.3284851e+01, -3.9157038e+02 ); - expectedForces[105] = Vec3( 6.6235629e+02, -8.4502811e+02, -5.3670716e+02 ); - expectedForces[106] = Vec3( 3.8449086e+02, 8.0775263e+02, 5.2003911e+02 ); - expectedForces[107] = Vec3( -3.4338589e+02, 1.7870086e+02, -6.1047615e+01 ); - expectedForces[108] = Vec3( 4.3523975e+02, 2.8776092e+02, -1.5333067e+03 ); - expectedForces[109] = Vec3( 1.9214022e+01, -9.9449061e+01, 3.9153169e+02 ); - expectedForces[110] = Vec3( -7.7525496e+02, 7.7309387e+01, 7.8886699e+02 ); - expectedForces[111] = Vec3( -1.1510224e+03, -2.8207337e+02, 1.4866455e+03 ); - expectedForces[112] = Vec3( 1.1281316e+03, -3.0961130e+02, -1.3894255e+02 ); - expectedForces[113] = Vec3( -2.4829062e+02, 5.9466066e+02, -9.0749265e+02 ); - expectedForces[114] = Vec3( -1.6228531e+02, -4.1281378e+02, -1.4860946e+03 ); - expectedForces[115] = Vec3( -2.9071192e+02, 7.5335271e+02, 6.5205720e+02 ); - expectedForces[116] = Vec3( 3.2042337e+02, -4.0237231e+02, 1.0068554e+03 ); - expectedForces[117] = Vec3( -1.4081272e+03, -5.5227579e+02, 2.8376428e+02 ); - expectedForces[118] = Vec3( 9.6978276e+02, -9.6232683e+02, 2.3399918e+02 ); - expectedForces[119] = Vec3( 2.0781312e+02, 9.0531947e+01, 8.3513783e+01 ); - expectedForces[120] = Vec3( 2.9200105e+02, 1.0746865e+03, -6.0773727e+02 ); - expectedForces[121] = Vec3( -8.7546167e+02, 3.1969683e+02, 8.1033199e+01 ); - expectedForces[122] = Vec3( -5.3422658e+01, -3.8456585e+02, 1.4595003e+02 ); - expectedForces[123] = Vec3( -9.5134908e+01, 8.6818098e+02, -1.3111403e+03 ); - expectedForces[124] = Vec3( -7.2576830e+02, 6.3811172e+01, 7.0993488e+02 ); - expectedForces[125] = Vec3( 5.6200572e+02, -1.0972338e+03, -3.5278717e+02 ); - expectedForces[126] = Vec3( -1.6903718e+02, 2.6804112e+02, -8.9811032e+02 ); - expectedForces[127] = Vec3( 7.0934165e+02, -3.2328700e+02, 1.0037562e+02 ); - expectedForces[128] = Vec3( -2.5937738e+00, -3.3758145e+02, 3.6354335e+02 ); - expectedForces[129] = Vec3( -1.1993601e+03, 1.1618922e+02, -1.1329865e+03 ); - expectedForces[130] = Vec3( 8.3480845e+02, 5.2646427e+02, 9.1816763e+01 ); - expectedForces[131] = Vec3( 1.9407174e+02, 7.3877492e+00, 8.8648162e+02 ); - expectedForces[132] = Vec3( -1.0820540e+03, 2.7482390e+02, -1.4876848e+03 ); - expectedForces[133] = Vec3( 9.5717027e+02, -4.7758356e+02, 4.0692835e+02 ); - expectedForces[134] = Vec3( 2.4979896e+02, 7.1530552e+02, 6.5834243e+02 ); - expectedForces[135] = Vec3( -2.7549874e+02, 1.6613806e+03, -5.0628865e+02 ); - expectedForces[136] = Vec3( -1.5960544e+02, -4.5920421e+02, 9.4068762e+02 ); - expectedForces[137] = Vec3( 6.9764295e+01, -4.4024430e+02, -2.3545402e+02 ); - expectedForces[138] = Vec3( 2.0207569e+03, -2.6846158e+02, 3.3977998e+02 ); - expectedForces[139] = Vec3( -9.9905342e+02, 9.5155462e+02, 8.3259854e+01 ); - expectedForces[140] = Vec3( -8.0836255e+02, -6.3005196e+02, 1.2603525e+02 ); - expectedForces[141] = Vec3( 5.2279913e+02, 1.5356061e+03, -1.4399009e+02 ); - expectedForces[142] = Vec3( -1.3088783e+02, -9.0861449e+02, 9.7040422e+02 ); - expectedForces[143] = Vec3( 2.8006682e+01, -1.1783245e+03, -3.7285390e+02 ); - expectedForces[144] = Vec3( 6.1040927e+01, 2.1747286e+01, 9.0366011e+02 ); - expectedForces[145] = Vec3( 7.0396235e+02, -2.3865001e+02, -6.8794682e+02 ); - expectedForces[146] = Vec3( -5.1132933e+02, 7.7102556e+02, -4.7805042e+02 ); - expectedForces[147] = Vec3( 6.2879945e+02, -6.9758821e+02, 1.0983043e+03 ); - expectedForces[148] = Vec3( -9.2449123e+02, 5.0248042e+02, -2.0065211e+02 ); - expectedForces[149] = Vec3( -3.9485154e+02, 3.4679511e+02, -7.3889603e+02 ); - expectedForces[150] = Vec3( 4.9834751e+02, -1.0117501e+03, 1.2510946e+03 ); - expectedForces[151] = Vec3( -1.4942699e+02, -7.4362790e+01, -6.8008427e+02 ); - expectedForces[152] = Vec3( -1.8353666e+02, 5.1697483e+02, -8.4397292e+01 ); - expectedForces[153] = Vec3( 7.0253008e+02, -1.5361338e+02, 8.6830836e+02 ); - expectedForces[154] = Vec3( -4.1108898e+02, -6.8181350e+02, -5.6516951e+02 ); - expectedForces[155] = Vec3( 3.9294374e+02, 3.7294948e+02, -4.9795080e+02 ); - expectedForces[156] = Vec3( -7.3716758e+02, -5.5465931e+02, -9.3434525e+02 ); - expectedForces[157] = Vec3( 1.8240105e+02, 1.5494359e+02, 1.3626243e+02 ); - expectedForces[158] = Vec3( 9.3172059e+02, 1.4431275e+02, 6.6916065e+02 ); - expectedForces[159] = Vec3( 7.3399513e+01, -3.6000187e+02, 1.9853052e+03 ); - expectedForces[160] = Vec3( -2.4842520e+02, -4.0819514e+02, -8.0624794e+02 ); - expectedForces[161] = Vec3( 4.3585911e+02, -2.6521764e+02, -6.7985842e+02 ); - expectedForces[162] = Vec3( -8.2255783e+02, 1.1430906e+03, 1.2991183e+03 ); - expectedForces[163] = Vec3( 5.6437196e+02, -1.5391213e+02, -5.0013503e+02 ); - expectedForces[164] = Vec3( 3.8485296e+02, -1.1754088e+02, -1.4315511e+03 ); - expectedForces[165] = Vec3( 9.8205241e+02, 1.3278205e+01, 3.0367584e+02 ); - expectedForces[166] = Vec3( -3.2909916e+02, 4.5169387e+01, -3.2019488e+02 ); - expectedForces[167] = Vec3( -4.2382795e+02, -8.1938351e+02, -1.5360675e+02 ); - expectedForces[168] = Vec3( 9.1689997e+02, 1.4443113e+03, -1.8886795e+02 ); - expectedForces[169] = Vec3( -1.2161000e+03, -2.3826187e+02, 3.4004889e+02 ); - expectedForces[170] = Vec3( -2.2837927e+02, -9.8334152e+02, 3.0313790e+02 ); - expectedForces[171] = Vec3( 5.2598040e+02, -1.2766936e+03, 8.1247934e+01 ); - expectedForces[172] = Vec3( -6.7839687e+01, 6.9220160e+02, 3.1975320e+02 ); - expectedForces[173] = Vec3( -4.8519844e+02, 4.3008979e+02, -7.6788762e+02 ); - expectedForces[174] = Vec3( 3.9550092e+01, 1.0900122e+03, 5.0955281e+02 ); - expectedForces[175] = Vec3( -6.3000735e+02, -7.2335263e+02, -2.2590661e+02 ); - expectedForces[176] = Vec3( 1.5048762e+02, -4.0086126e+02, -1.2159849e+02 ); - expectedForces[177] = Vec3( -7.1939527e+02, -1.0640815e+03, -3.1826393e+02 ); - expectedForces[178] = Vec3( 7.7492135e+02, 1.0620129e+02, 3.6733165e+02 ); - expectedForces[179] = Vec3( -3.5466457e+02, 7.0081887e+02, 2.2629152e+02 ); - expectedForces[180] = Vec3( 3.0338275e+02, -1.1243396e+02, -1.3408996e+03 ); - expectedForces[181] = Vec3( 9.0394088e+00, 4.8818819e+02, 7.3781403e+02 ); - expectedForces[182] = Vec3( -5.6111982e+01, -2.5224925e+02, 3.0344460e+02 ); - expectedForces[183] = Vec3( -7.4693225e+02, 1.1370727e+03, 9.3958175e+02 ); - expectedForces[184] = Vec3( 3.1310327e+02, -1.2133761e+03, 2.6768166e+02 ); - expectedForces[185] = Vec3( 6.0706899e+02, 9.8403362e+01, -5.0781782e+02 ); - expectedForces[186] = Vec3( -6.2721609e+02, 1.7751567e+02, 2.6230643e+02 ); - expectedForces[187] = Vec3( 3.5425475e+02, -3.3336896e+02, 2.9529930e+02 ); - expectedForces[188] = Vec3( 4.7499029e+02, 4.5552354e+02, -2.4939310e+02 ); - expectedForces[189] = Vec3( 1.1556321e+02, 2.5995186e+02, -8.4171376e+02 ); - expectedForces[190] = Vec3( -4.5095184e+02, -1.6639362e+01, 4.2956175e+02 ); - expectedForces[191] = Vec3( -7.5904218e+01, 3.9416063e+02, 4.2573815e+02 ); - expectedForces[192] = Vec3( 2.3041013e+02, -1.2883920e+03, -5.1943189e+02 ); - expectedForces[193] = Vec3( 8.6086944e+01, 1.8626094e+02, 3.7641641e+02 ); - expectedForces[194] = Vec3( -5.9266805e+02, 4.4766229e+02, -4.5835497e+02 ); - expectedForces[195] = Vec3( 3.9368476e+02, 1.1050329e+03, -1.3906133e+03 ); - expectedForces[196] = Vec3( -1.2912212e+03, -2.9660534e+02, 3.9659215e+02 ); - expectedForces[197] = Vec3( -2.4803663e+01, -2.7945607e+02, 3.5315630e+02 ); - expectedForces[198] = Vec3( 1.4147479e+02, 3.2766723e+02, 1.1137899e+03 ); - expectedForces[199] = Vec3( 7.8383167e+01, 2.2385715e+00, -1.0346820e+03 ); - expectedForces[200] = Vec3( -2.9231551e+02, -5.4648720e+02, -6.5500265e+02 ); - expectedForces[201] = Vec3( 1.3708284e+03, -1.0716376e+03, 4.5781190e+02 ); - expectedForces[202] = Vec3( -7.5533654e+02, 6.5396686e+02, -4.2683276e+02 ); - expectedForces[203] = Vec3( -6.5558825e+02, 3.1164131e+02, 2.6323555e+02 ); - expectedForces[204] = Vec3( 1.3173432e+03, 1.3775889e+03, 1.2933072e+02 ); - expectedForces[205] = Vec3( -4.0922505e+02, -7.5709333e+02, -3.4967434e+02 ); - expectedForces[206] = Vec3( 4.2270572e+01, -7.4393359e+02, 5.2985443e+02 ); - expectedForces[207] = Vec3( -1.5327880e+03, 7.3186706e+02, -2.3440058e+02 ); - expectedForces[208] = Vec3( 1.4650210e+03, 2.8661572e+02, -2.4233049e+02 ); - expectedForces[209] = Vec3( 8.4124688e+02, -3.4020518e+02, -3.1773592e+01 ); - expectedForces[210] = Vec3( -1.1480436e+03, -7.4089732e+02, -4.8883682e+02 ); - expectedForces[211] = Vec3( 3.5682075e+02, 2.1918110e+01, -1.2558000e+02 ); - expectedForces[212] = Vec3( 1.6505256e+02, 7.9867933e+02, 9.9760760e+02 ); - expectedForces[213] = Vec3( 1.2477725e+03, -8.8687803e+02, -8.2498529e+02 ); - expectedForces[214] = Vec3( 1.7357042e+02, 2.0185456e+02, 8.0965301e+02 ); - expectedForces[215] = Vec3( -9.0937500e+02, 5.5968713e+01, 1.7581913e+02 ); - expectedForces[216] = Vec3( 1.3030711e+03, -8.2642443e+02, 1.6679926e+02 ); - expectedForces[217] = Vec3( -8.4295510e+02, 2.0237547e+01, 4.0163431e+02 ); - expectedForces[218] = Vec3( -3.2088719e+02, 3.0824476e+02, 9.9166532e+01 ); - expectedForces[219] = Vec3( 1.4585495e+03, -4.1497503e+01, -2.2539636e+02 ); - expectedForces[220] = Vec3( -2.6148433e+02, 1.7592075e+02, 2.0638296e+02 ); - expectedForces[221] = Vec3( -9.2100962e+02, 2.6090225e+02, -8.4461867e+02 ); - expectedForces[222] = Vec3( -9.0597287e+02, -4.8246138e+02, -1.8012972e+03 ); - expectedForces[223] = Vec3( -1.1775667e+02, 1.7275816e+02, 1.1286513e+03 ); - expectedForces[224] = Vec3( 1.0682239e+03, 8.0853797e+02, 2.5601774e+02 ); - expectedForces[225] = Vec3( -1.6637330e+02, 7.6165466e+02, -5.9394315e+02 ); - expectedForces[226] = Vec3( 2.6206832e+02, -1.5011747e+02, 5.4532792e+02 ); - expectedForces[227] = Vec3( -2.6474701e+02, -1.4218144e+02, 1.1099125e+02 ); - expectedForces[228] = Vec3( -9.7365994e+02, -5.5282012e+02, -6.3158992e+02 ); - expectedForces[229] = Vec3( 1.1482718e+03, 1.4958662e+02, -5.6523355e+02 ); - expectedForces[230] = Vec3( 4.4084982e+02, 7.9662251e+02, 4.9732039e+02 ); - expectedForces[231] = Vec3( -4.8746806e+02, -1.5522005e+03, 1.0133483e+03 ); - expectedForces[232] = Vec3( 1.1332903e+03, 1.2836176e+03, -2.0897082e+02 ); - expectedForces[233] = Vec3( -7.9973372e+01, 6.3066961e+02, -5.8656505e+02 ); - expectedForces[234] = Vec3( -8.3714021e+02, -1.5385924e+03, 1.0179672e+03 ); - expectedForces[235] = Vec3( 3.5358323e+02, 9.3554369e+02, 1.6565605e+02 ); - expectedForces[236] = Vec3( 1.7532341e+02, 3.0381323e+01, -1.2538424e+03 ); - expectedForces[237] = Vec3( -1.0437301e+03, -4.4804918e+02, 1.5276435e+03 ); - expectedForces[238] = Vec3( 8.5470872e+02, 1.0725550e+03, -9.7359443e+01 ); - expectedForces[239] = Vec3( 1.8192015e+02, -7.6967211e+01, -8.6054596e+02 ); - expectedForces[240] = Vec3( 1.5910180e+03, -7.9601605e+02, -8.4030326e+02 ); - expectedForces[241] = Vec3( -6.4638370e+02, 4.0538540e+02, 2.3396878e+01 ); - expectedForces[242] = Vec3( -5.2648918e+02, 1.3689201e+02, 9.3014716e+02 ); - expectedForces[243] = Vec3( 2.2248997e+02, -6.3647370e+02, -8.3913128e+02 ); - expectedForces[244] = Vec3( -7.5759832e+02, 4.7985429e+01, 5.8577833e+02 ); - expectedForces[245] = Vec3( 1.2983550e+02, 4.4401985e+02, 2.3556259e+02 ); - expectedForces[246] = Vec3( 7.8075637e+02, 9.9893821e+02, 7.3511307e+02 ); - expectedForces[247] = Vec3( -8.6411159e+02, 2.3812628e+02, 1.9007971e+02 ); - expectedForces[248] = Vec3( 2.0762263e+02, -7.0123789e+02, -4.8175733e+02 ); - expectedForces[249] = Vec3( -8.2749187e+02, -7.8772346e+02, -9.8536337e+02 ); - expectedForces[250] = Vec3( 8.3905893e+01, -2.8770518e+02, 6.0690561e+02 ); - expectedForces[251] = Vec3( 7.2280803e+02, 4.9294103e+02, -1.2915033e+02 ); - expectedForces[252] = Vec3( -1.3615809e+03, -1.8564754e+02, -4.2172817e+02 ); - expectedForces[253] = Vec3( 9.2102155e+02, 5.4063967e+02, -2.7291760e+02 ); - expectedForces[254] = Vec3( 7.0204283e+02, -3.0338605e+02, 6.6795953e+02 ); - expectedForces[255] = Vec3( -7.2261285e+00, 3.2570478e+02, 5.9010590e+02 ); - expectedForces[256] = Vec3( -8.3167819e+02, 3.0568475e+02, -9.9230441e+02 ); - expectedForces[257] = Vec3( 2.1074297e+02, -4.0099946e+01, -1.2770634e+02 ); - expectedForces[258] = Vec3( 1.1218559e+03, -8.8304672e+02, 1.0217945e+03 ); - expectedForces[259] = Vec3( -4.4730264e+01, 5.3616918e+02, -3.2704110e+02 ); - expectedForces[260] = Vec3( -1.1106141e+03, 3.3541536e+02, -1.0552986e+02 ); - expectedForces[261] = Vec3( -9.3728497e+01, 4.7397796e+01, -1.1294332e+03 ); - expectedForces[262] = Vec3( 5.1424956e+01, 4.0854995e+02, 5.6832607e+02 ); - expectedForces[263] = Vec3( 1.4286074e+02, 2.9172921e+01, 5.1355833e+02 ); - expectedForces[264] = Vec3( -4.4318133e+02, -9.5478293e+02, -1.8067439e+03 ); - expectedForces[265] = Vec3( -2.8083245e+02, 8.1414586e+02, 6.6089404e+02 ); - expectedForces[266] = Vec3( 1.0434876e+02, 3.0664078e+02, 1.3658532e+03 ); - expectedForces[267] = Vec3( 1.2999089e+03, 5.6746563e+02, 1.2200612e+03 ); - expectedForces[268] = Vec3( -5.9546942e+02, 3.6897149e+02, -8.3331437e+02 ); - expectedForces[269] = Vec3( -1.1094881e+03, -5.1903335e+02, -3.5729033e+02 ); - expectedForces[270] = Vec3( 4.1873464e+02, 6.9788983e+02, -1.3191929e+03 ); - expectedForces[271] = Vec3( -1.0086080e+02, 3.3114447e+02, 6.3419860e+02 ); - expectedForces[272] = Vec3( -2.8783906e+02, -8.8308011e+02, -5.4816768e+01 ); - expectedForces[273] = Vec3( 1.0254638e+03, 2.8710026e+02, -1.9779676e+02 ); - expectedForces[274] = Vec3( -3.5906548e+02, -5.5531449e+02, -6.0205492e+01 ); - expectedForces[275] = Vec3( -3.9578349e+02, 5.9217272e+01, 1.0735648e+02 ); - expectedForces[276] = Vec3( -8.7298871e+02, -1.5584711e+02, 9.2571354e+02 ); - expectedForces[277] = Vec3( 4.1520558e+02, 5.6442126e+02, -1.8142289e+02 ); - expectedForces[278] = Vec3( 6.5423421e+02, -4.1631573e+02, 1.0996479e+02 ); - expectedForces[279] = Vec3( -8.0063899e+01, -1.2880940e+03, 2.9304469e+02 ); - expectedForces[280] = Vec3( -9.5930841e+02, 5.8293485e+02, -1.1632205e+03 ); - expectedForces[281] = Vec3( 6.3492338e+02, 2.5550931e+02, 1.7380517e+02 ); - expectedForces[282] = Vec3( -1.9188175e+02, 1.0257290e+03, -8.6438702e+02 ); - expectedForces[283] = Vec3( 4.0063530e+01, -5.1808902e+02, 4.9556015e+02 ); - expectedForces[284] = Vec3( 5.8250018e+02, -2.5030700e+02, 1.1762860e+03 ); - expectedForces[285] = Vec3( -4.3195459e+02, 7.4733530e+02, -1.3002210e+03 ); - expectedForces[286] = Vec3( 2.7567334e+01, -5.1662654e+02, 3.3258050e+02 ); - expectedForces[287] = Vec3( 6.1700857e+02, 3.0016354e+02, 9.5519139e+02 ); - expectedForces[288] = Vec3( 7.7553094e+02, 8.6453551e+02, -1.0122996e+03 ); - expectedForces[289] = Vec3( -2.6730796e+02, -7.7560875e+02, 4.3195620e+02 ); - expectedForces[290] = Vec3( -8.5982146e+02, 1.6692057e+02, 4.3838169e+02 ); - expectedForces[291] = Vec3( 1.2945126e+03, 6.3231748e+02, -8.3020592e+02 ); - expectedForces[292] = Vec3( -6.9510729e+02, -3.1930013e+02, -1.3919425e+01 ); - expectedForces[293] = Vec3( -4.1154200e+02, -3.3562358e+02, 6.3292682e+02 ); - expectedForces[294] = Vec3( -4.0919783e+02, -3.8282298e+02, -4.9125465e+02 ); - expectedForces[295] = Vec3( 6.3932145e+02, -1.8769713e+01, 9.9241332e+01 ); - expectedForces[296] = Vec3( 8.6847663e+01, 8.7234739e+02, 2.7124112e+02 ); - expectedForces[297] = Vec3( -1.0307576e+03, -6.2447562e+02, -1.5796976e+03 ); - expectedForces[298] = Vec3( 6.2464595e+02, 1.0608165e+03, 3.1422521e+01 ); - expectedForces[299] = Vec3( 3.7767184e+02, 4.1170186e+02, 1.0696495e+03 ); - expectedForces[300] = Vec3( 1.0578030e+02, -1.9544726e+03, -4.6243957e+02 ); - expectedForces[301] = Vec3( -3.1074896e+02, 8.6738333e+02, -2.0241448e+02 ); - expectedForces[302] = Vec3( -2.7350519e+02, 6.9945273e+02, 7.8755130e+02 ); - expectedForces[303] = Vec3( 7.8083070e+02, 6.5199614e+02, -6.6698950e+02 ); - expectedForces[304] = Vec3( 1.3647451e+02, -4.2490411e+02, 1.3236061e+01 ); - expectedForces[305] = Vec3( -1.1048984e+03, 3.7582184e+02, -6.4718844e+01 ); - expectedForces[306] = Vec3( 1.5976050e+03, -8.9091819e+02, 9.7113419e+02 ); - expectedForces[307] = Vec3( -4.5545384e+01, 8.8683300e+02, -6.5927739e+01 ); - expectedForces[308] = Vec3( -1.3883497e+03, -4.6171498e+02, -2.9117829e+02 ); - expectedForces[309] = Vec3( -6.6661140e+02, -8.1394964e+02, 1.2397900e+03 ); - expectedForces[310] = Vec3( -2.5293546e+02, 1.8568554e+02, -6.8919479e+02 ); - expectedForces[311] = Vec3( 5.2052057e+02, 1.0288555e+03, 3.1435700e+02 ); - expectedForces[312] = Vec3( -2.4245555e+02, -1.1100993e+03, -1.6937710e+03 ); - expectedForces[313] = Vec3( 1.6647470e+02, 9.5272347e+02, 9.2528380e+02 ); - expectedForces[314] = Vec3( 8.6946518e+02, -1.6295251e+02, 5.7452409e+02 ); - expectedForces[315] = Vec3( 1.4059831e+02, 5.6780959e+02, -4.6024149e+02 ); - expectedForces[316] = Vec3( 2.3327811e+02, -2.2376697e+02, 1.3399582e+01 ); - expectedForces[317] = Vec3( -2.6583612e+01, -4.5801841e+02, 2.9595361e+01 ); - expectedForces[318] = Vec3( 1.2361796e+03, -1.9473934e+02, -2.6179421e+02 ); - expectedForces[319] = Vec3( -4.2330105e+02, 5.0768290e+02, 6.8352494e+02 ); - expectedForces[320] = Vec3( -2.0826312e+02, 1.4720747e+02, -9.8828425e-01 ); - expectedForces[321] = Vec3( -7.3226106e+02, -1.5366771e+01, 2.7882968e+02 ); - expectedForces[322] = Vec3( 4.2634684e+02, -6.2926647e+02, 3.6300784e+02 ); - expectedForces[323] = Vec3( 1.7826269e+02, 1.0038378e+02, -4.2408556e+02 ); - expectedForces[324] = Vec3( -1.1690005e+03, 2.1777241e+02, 9.1980300e+02 ); - expectedForces[325] = Vec3( 5.6841370e+02, -2.6614377e+02, -6.4968364e+01 ); - expectedForces[326] = Vec3( 3.5710749e+02, 1.3228373e+02, -3.6567433e+02 ); - expectedForces[327] = Vec3( 8.1957745e+02, 7.3903486e+02, 3.9487193e+02 ); - expectedForces[328] = Vec3( -8.5354740e+02, 8.9297958e+01, 9.0615539e+01 ); - expectedForces[329] = Vec3( -2.3935807e+02, -2.2950021e+02, -4.6193868e+01 ); - expectedForces[330] = Vec3( 8.6120406e+01, 1.4046499e+03, -1.5899345e+02 ); - expectedForces[331] = Vec3( 4.6319634e+02, -4.6309406e+02, -2.2891416e+02 ); - expectedForces[332] = Vec3( -4.2592255e+02, -2.6503000e+02, 6.1788141e+02 ); - expectedForces[333] = Vec3( -2.4468457e+02, -7.7827760e+02, 4.2470013e+02 ); - expectedForces[334] = Vec3( 2.6006448e+02, 7.6289112e+01, -4.3430411e+02 ); - expectedForces[335] = Vec3( -2.5268926e+02, 7.7381529e+02, -5.0896414e+02 ); - expectedForces[336] = Vec3( 1.0414844e+03, -6.1885512e+02, 1.4495539e+03 ); - expectedForces[337] = Vec3( -5.9522011e+01, 1.3607073e+03, -7.3705640e+01 ); - expectedForces[338] = Vec3( -5.9857094e+02, -2.7213045e+02, -9.7516268e+02 ); - expectedForces[339] = Vec3( 9.2852178e+02, 3.0121600e+02, -7.4982031e+00 ); - expectedForces[340] = Vec3( -1.0201472e+03, 1.6269359e+02, 1.9280960e+02 ); - expectedForces[341] = Vec3( -1.8744984e+02, -4.9790658e+02, 4.2841303e+02 ); - expectedForces[342] = Vec3( -1.0893114e+03, -4.6044565e+02, -2.0537532e+02 ); - expectedForces[343] = Vec3( 5.1068148e+02, -3.0889884e+02, 1.7703226e+01 ); - expectedForces[344] = Vec3( 2.0128423e+02, 5.0813056e+02, -5.0941772e+01 ); - expectedForces[345] = Vec3( -6.0195519e+02, 1.1710803e+03, -5.8271481e+02 ); - expectedForces[346] = Vec3( 1.3898239e+02, -3.2598252e+02, 1.0877023e+03 ); - expectedForces[347] = Vec3( 3.1630812e+02, -8.9974673e+02, 9.6573268e+01 ); - expectedForces[348] = Vec3( -5.5334313e+01, -1.1529065e+03, -2.1949997e+02 ); - expectedForces[349] = Vec3( -4.4904784e+02, 2.4036076e+02, 4.1328142e+02 ); - expectedForces[350] = Vec3( 1.0611611e+03, 4.1620143e+02, 9.1677657e+01 ); - expectedForces[351] = Vec3( 1.3489840e+03, 9.9500659e+02, -4.5894902e+01 ); - expectedForces[352] = Vec3( -9.8051252e+01, -9.0794586e+02, -8.9918421e+02 ); - expectedForces[353] = Vec3( -3.5567408e+02, -7.2914902e+01, 4.7977644e+01 ); - expectedForces[354] = Vec3( -1.5976501e+03, -1.2202674e+03, 7.2159213e+02 ); - expectedForces[355] = Vec3( 1.7391266e+02, 1.0197773e+03, -9.1284547e+02 ); - expectedForces[356] = Vec3( 7.8937287e+02, 1.1964969e+02, -3.8520683e+02 ); - expectedForces[357] = Vec3( 2.8170878e+02, 1.0377979e+03, -5.0609230e+02 ); - expectedForces[358] = Vec3( -4.0852118e+01, -4.3087314e+02, 4.1855459e+01 ); - expectedForces[359] = Vec3( -3.2767902e+02, -7.8083477e+02, 1.1111190e+03 ); - expectedForces[360] = Vec3( -1.0691030e+03, 3.1877408e+02, -7.9684323e+02 ); - expectedForces[361] = Vec3( 7.7603235e+02, 3.6577850e+02, -1.9093841e+02 ); - expectedForces[362] = Vec3( -4.7607360e+02, -5.1710653e+02, 7.2740737e+02 ); - expectedForces[363] = Vec3( 9.3461900e+02, 7.9988609e+01, -5.8055314e+02 ); - expectedForces[364] = Vec3( -9.8128918e+02, -2.6706371e+02, -3.5178135e+01 ); - expectedForces[365] = Vec3( -6.5196668e+02, 8.7618054e+02, 3.3040412e+02 ); - expectedForces[366] = Vec3( 5.5458970e+02, -1.1281839e+03, -8.2774754e+02 ); - expectedForces[367] = Vec3( 1.8491757e+02, -5.1421593e+01, 4.7068191e+02 ); - expectedForces[368] = Vec3( -4.3945944e+02, 8.2740025e+02, -2.1736033e+01 ); - expectedForces[369] = Vec3( -2.5609394e+02, -6.7141305e+02, -3.2964376e+02 ); - expectedForces[370] = Vec3( 1.4932730e+02, 2.2746635e+02, -3.7606156e+01 ); - expectedForces[371] = Vec3( 3.0873674e+02, 5.9974800e+02, 4.2207331e+02 ); - expectedForces[372] = Vec3( -3.8828932e+02, -2.1491002e+02, 1.5266506e+03 ); - expectedForces[373] = Vec3( 4.4495676e+02, 6.4708482e+02, -9.2222368e+02 ); - expectedForces[374] = Vec3( -4.8420767e+01, -4.3781484e+02, -5.0107314e+02 ); - expectedForces[375] = Vec3( 5.7593719e+02, -1.8140066e+03, -4.0189721e+02 ); - expectedForces[376] = Vec3( -5.1276233e+02, 6.6981030e+02, 3.9050744e+02 ); - expectedForces[377] = Vec3( 4.0809391e+02, 1.1596412e+03, -4.1325341e+02 ); - expectedForces[378] = Vec3( 1.4975560e+03, 1.7852942e+02, -7.6514466e+02 ); - expectedForces[379] = Vec3( -2.2890988e+02, 2.6128742e+02, 3.8545036e+02 ); - expectedForces[380] = Vec3( -3.8899762e+02, -2.5609958e+02, 2.0655882e+02 ); - expectedForces[381] = Vec3( -1.9500869e+02, -1.0947633e+03, -9.1786660e+02 ); - expectedForces[382] = Vec3( 8.6146884e+02, 2.5767444e+02, 3.6801549e+02 ); - expectedForces[383] = Vec3( -2.0008562e+02, 2.1549793e+02, 2.5175877e+02 ); - expectedForces[384] = Vec3( -5.6491749e+02, 5.4714989e+02, 3.1934114e+02 ); - expectedForces[385] = Vec3( 1.7665111e+02, -4.5297277e+02, 2.2387580e+02 ); - expectedForces[386] = Vec3( 6.2697664e+02, 1.1271358e+02, 2.9498078e+00 ); - expectedForces[387] = Vec3( -2.1918090e+03, -7.8914005e+01, 1.0632280e+03 ); - expectedForces[388] = Vec3( 7.5750278e+02, -5.0217666e+02, -1.3057335e+02 ); - expectedForces[389] = Vec3( 1.0621096e+03, 1.6022661e+01, -1.1645539e+03 ); - expectedForces[390] = Vec3( -4.7808938e+02, -1.2425496e+03, -1.5543074e+02 ); - expectedForces[391] = Vec3( -3.4676860e+02, 8.5391303e+02, 3.5351618e+01 ); - expectedForces[392] = Vec3( 5.4017203e+02, 8.6467815e+01, 1.1898140e+02 ); - expectedForces[393] = Vec3( -1.8873828e+01, 2.2133074e+02, -1.3378739e+03 ); - expectedForces[394] = Vec3( 7.5888012e+01, -1.6517743e+01, 1.1817186e+02 ); - expectedForces[395] = Vec3( 1.1912944e+02, -1.6083226e+02, 7.8733940e+02 ); - expectedForces[396] = Vec3( -1.2400005e+03, -3.9434827e+02, 1.4071802e+02 ); - expectedForces[397] = Vec3( 9.6249284e+02, 1.1394516e+02, -3.4977717e+02 ); - expectedForces[398] = Vec3( 2.4187486e+02, 1.3373651e+02, 6.5894105e+01 ); - expectedForces[399] = Vec3( 8.8628445e+02, 7.8083892e+01, -1.0288922e+03 ); - expectedForces[400] = Vec3( -9.4613057e+02, -1.9076053e+02, 6.7506442e+02 ); - expectedForces[401] = Vec3( -6.2746897e+02, 2.9376858e+02, 9.2767458e+02 ); - expectedForces[402] = Vec3( 5.5409175e+01, -1.2583442e+03, 7.1728490e+02 ); - expectedForces[403] = Vec3( -2.9076856e+02, 7.5539656e+02, 7.0121763e+00 ); - expectedForces[404] = Vec3( 2.6220897e+02, -9.5606102e+01, -7.7725998e+02 ); - expectedForces[405] = Vec3( -8.6582014e+02, 9.5597761e+02, 1.5941783e+02 ); - expectedForces[406] = Vec3( -1.6910265e+02, -7.2646192e+02, -3.5476587e+02 ); - expectedForces[407] = Vec3( 9.7629076e+02, -8.3969437e+01, 2.5523637e+02 ); - expectedForces[408] = Vec3( -4.9553396e+01, 6.3557270e+02, -7.5908312e+02 ); - expectedForces[409] = Vec3( 3.3210227e+01, 1.5198340e+02, 7.0322192e+02 ); - expectedForces[410] = Vec3( -2.6532687e+01, -4.1589199e+02, 4.2771258e+02 ); - expectedForces[411] = Vec3( 1.1412630e+03, -2.7366656e+02, 9.8419548e+02 ); - expectedForces[412] = Vec3( -3.7239786e+02, 7.2244667e+01, -9.9502150e+02 ); - expectedForces[413] = Vec3( -4.6476941e+02, -6.1433607e+01, -2.5459288e+02 ); - expectedForces[414] = Vec3( 9.7028883e+02, 5.5981848e+02, 8.4425262e+02 ); - expectedForces[415] = Vec3( 7.2811577e+01, 2.2872709e+02, -1.3822700e+03 ); - expectedForces[416] = Vec3( -1.0105821e+03, -2.8444698e+02, -7.2506392e+02 ); - expectedForces[417] = Vec3( 1.0027865e+03, 6.0924816e+02, -5.7818592e+01 ); - expectedForces[418] = Vec3( -3.4173955e+02, -1.1932310e+02, -2.9495449e+01 ); - expectedForces[419] = Vec3( -2.7281265e+02, -1.8869212e+02, 1.9643932e+02 ); - expectedForces[420] = Vec3( -7.4036328e+02, -4.8733524e+02, 1.5862094e+03 ); - expectedForces[421] = Vec3( 5.6387864e+02, 3.0991659e+02, -8.6746725e+02 ); - expectedForces[422] = Vec3( 6.2954421e-01, 4.9665567e+02, -1.0114913e+03 ); - expectedForces[423] = Vec3( 8.9668630e+02, -1.0121499e+03, -1.1520006e+03 ); - expectedForces[424] = Vec3( -2.5699741e+02, 3.3243520e+02, 7.6038873e+02 ); - expectedForces[425] = Vec3( -1.2755484e+03, -2.7786159e+01, 3.0900583e+02 ); - expectedForces[426] = Vec3( -1.2587339e+03, -8.6851333e+02, 1.6295957e+02 ); - expectedForces[427] = Vec3( 6.4923970e+02, 4.4600015e+02, 3.3033348e+02 ); - expectedForces[428] = Vec3( 5.8905637e+02, -1.1589062e+02, -1.8168184e+02 ); - expectedForces[429] = Vec3( -1.1223714e+03, 3.0322406e+01, 8.7272053e+02 ); - expectedForces[430] = Vec3( 3.0982625e+02, 3.1418220e+02, -3.9301742e+02 ); - expectedForces[431] = Vec3( 2.4213933e+02, -7.2382572e+02, -1.0155346e+03 ); - expectedForces[432] = Vec3( 1.1479692e+03, -1.6837721e+03, 1.0545407e+02 ); - expectedForces[433] = Vec3( -8.2496264e+02, 6.0540594e+02, 1.3979931e+02 ); - expectedForces[434] = Vec3( -6.8171514e+02, 4.0392791e+02, -3.4712316e+02 ); - expectedForces[435] = Vec3( -1.5568889e+02, -1.4652975e+03, 5.1518148e+01 ); - expectedForces[436] = Vec3( 5.6573856e+02, 3.5494119e+02, -3.3796345e+02 ); - expectedForces[437] = Vec3( -1.3938679e+02, 4.2296152e+02, -2.0539863e+02 ); - expectedForces[438] = Vec3( 8.9203493e+01, 2.8764597e+02, -7.3273496e+02 ); - expectedForces[439] = Vec3( 4.3114292e+02, 9.4778082e+01, 1.8894761e+02 ); - expectedForces[440] = Vec3( -2.2798193e+01, -4.5460891e+01, 9.8310963e+01 ); - expectedForces[441] = Vec3( -2.1793579e+02, -1.0807542e+03, -2.3470465e+01 ); - expectedForces[442] = Vec3( 1.3881360e+02, 3.9806903e+02, 4.1089741e+01 ); - expectedForces[443] = Vec3( -4.5604974e+02, 4.8515999e+02, -6.6025174e+02 ); - expectedForces[444] = Vec3( 3.6437700e+02, -8.1622511e+02, -9.6454258e+02 ); - expectedForces[445] = Vec3( 3.1998690e+02, -3.3342314e+02, 1.2441763e+03 ); - expectedForces[446] = Vec3( 3.0822409e+01, 2.0596612e+02, 2.0937122e+02 ); - expectedForces[447] = Vec3( -8.4938718e+02, -1.1366483e+03, -1.3638049e+02 ); - expectedForces[448] = Vec3( -5.5232451e+01, 4.7335097e+02, -5.4433565e+02 ); - expectedForces[449] = Vec3( 6.5928852e+02, 1.7488804e+02, 6.7879378e+02 ); - expectedForces[450] = Vec3( -9.4572079e+02, 1.9162420e+02, 4.7935043e+02 ); - expectedForces[451] = Vec3( 2.5029547e+02, 3.6606767e+01, -9.3423713e+01 ); - expectedForces[452] = Vec3( 1.6543841e+02, -1.1892943e+02, -5.8737050e+02 ); - expectedForces[453] = Vec3( -9.8495219e+02, -1.6882428e+03, -4.0576035e+02 ); - expectedForces[454] = Vec3( 7.9182557e+02, 5.3997699e+02, 3.3231603e+02 ); - expectedForces[455] = Vec3( 1.8277090e+01, 1.4623150e+03, -9.4985721e+01 ); - expectedForces[456] = Vec3( -1.0471948e+03, 4.6746395e+02, -1.5020000e+03 ); - expectedForces[457] = Vec3( 7.2055316e+02, -5.4467216e+02, 4.0459421e+02 ); - expectedForces[458] = Vec3( 7.5475531e+01, 4.9532870e+02, 1.3002474e+03 ); - expectedForces[459] = Vec3( 6.3589773e+02, -2.1402397e+02, -1.4147509e+03 ); - expectedForces[460] = Vec3( 2.8391861e+02, -8.0142885e+01, 5.6445225e+02 ); - expectedForces[461] = Vec3( -8.2442674e+02, 5.3520687e+02, 1.1406667e+03 ); - expectedForces[462] = Vec3( -5.7988771e+02, -3.3512887e+02, 4.5461752e+02 ); - expectedForces[463] = Vec3( 4.5746059e+02, 3.1029926e+02, -5.0060176e+02 ); - expectedForces[464] = Vec3( 7.7747136e+02, 4.2131732e+02, 5.5836239e+02 ); - expectedForces[465] = Vec3( -1.2315491e+03, 9.4066088e+02, 9.6145313e+02 ); - expectedForces[466] = Vec3( 7.9043841e+02, -2.2172613e+02, -2.6508587e+02 ); - expectedForces[467] = Vec3( 7.8197894e+02, -3.1383822e+02, 2.5444013e+02 ); - expectedForces[468] = Vec3( -7.1139498e+01, -7.1203189e+01, -4.6845544e+02 ); - expectedForces[469] = Vec3( -8.9774100e+01, 1.4389287e+02, 9.8957451e+01 ); - expectedForces[470] = Vec3( 3.0397922e+02, -2.8247850e+01, 4.4896034e+02 ); - expectedForces[471] = Vec3( -9.7808367e+02, 1.0170553e+03, 8.1594649e+02 ); - expectedForces[472] = Vec3( 1.8933676e+02, -8.8053046e+02, 6.8784042e+01 ); - expectedForces[473] = Vec3( 5.1636668e+02, 1.2970985e+02, -8.9380858e+02 ); - expectedForces[474] = Vec3( -5.8549608e+02, -1.8351156e+02, -5.8043066e+02 ); - expectedForces[475] = Vec3( 2.7877663e+02, -3.6576715e+02, 3.5497095e+02 ); - expectedForces[476] = Vec3( 3.0642370e+02, 5.3438407e+02, 1.9409584e+02 ); - expectedForces[477] = Vec3( -4.8523805e+02, 1.2253320e+03, 9.6414379e+02 ); - expectedForces[478] = Vec3( -1.5213013e+02, -2.0017205e+02, -6.6602643e+02 ); - expectedForces[479] = Vec3( 4.6435225e+02, -4.1945066e+02, -8.6774270e+01 ); - expectedForces[480] = Vec3( 2.4946889e+02, -1.0456281e+03, 4.7404434e+02 ); - expectedForces[481] = Vec3( -3.0813505e+01, 2.8598938e+02, 7.7374350e+01 ); - expectedForces[482] = Vec3( -2.4538851e+02, 3.8306987e+02, -5.0235520e+02 ); - expectedForces[483] = Vec3( 4.0348805e+01, 1.3050360e+03, -6.8725580e+02 ); - expectedForces[484] = Vec3( -1.1095514e+02, -2.7711572e+02, 2.6929959e+02 ); - expectedForces[485] = Vec3( -6.8071081e+01, -3.4398150e+02, 2.5209743e+02 ); - expectedForces[486] = Vec3( 2.1534786e+03, 1.3249493e+01, 7.4171165e+01 ); - expectedForces[487] = Vec3( -7.2618755e+02, -3.2914219e+02, 2.5917332e+02 ); - expectedForces[488] = Vec3( -1.0231949e+03, 7.2426062e+02, 1.9111862e+02 ); - expectedForces[489] = Vec3( 1.1408866e+03, 6.7858353e+02, -2.1410916e+02 ); - expectedForces[490] = Vec3( -4.5559047e+02, -1.3597950e+02, -3.2284091e+02 ); - expectedForces[491] = Vec3( -8.5558133e+02, -7.1748324e+01, 5.3332261e+02 ); - expectedForces[492] = Vec3( -7.1393886e+02, -1.1275222e+03, -6.2147584e+02 ); - expectedForces[493] = Vec3( 4.4029614e+02, 1.0518224e+02, 4.6519788e+02 ); - expectedForces[494] = Vec3( -3.5770378e+02, 1.0311834e+03, 2.2141802e+02 ); - expectedForces[495] = Vec3( -2.6023787e+02, 1.0070248e+03, -1.1113552e+03 ); - expectedForces[496] = Vec3( -3.4950242e+02, 2.8418846e+01, 1.2865161e+03 ); - expectedForces[497] = Vec3( 1.5030225e+02, -7.7257505e+02, 8.7232628e+02 ); - expectedForces[498] = Vec3( -1.7416695e+02, 9.9945569e+02, -1.6742483e+02 ); - expectedForces[499] = Vec3( 2.0837481e+02, -1.9388709e+02, 9.7409815e+01 ); - expectedForces[500] = Vec3( -1.0129845e+02, -6.8652976e+02, 8.4930186e+02 ); - expectedForces[501] = Vec3( 1.2276099e+03, 1.6531986e+02, 3.6342506e+02 ); - expectedForces[502] = Vec3( -1.9998077e+02, -2.6164759e+02, -1.6601933e+02 ); - expectedForces[503] = Vec3( -4.0356327e+02, 4.0549152e+02, 2.9710052e+02 ); - expectedForces[504] = Vec3( -7.3045150e+02, -1.6677706e+03, -9.8671765e+02 ); - expectedForces[505] = Vec3( -2.1441879e+02, 1.4962605e+03, 5.6350856e+02 ); - expectedForces[506] = Vec3( 7.1102593e+02, 5.9407971e+02, 9.5452239e+02 ); - expectedForces[507] = Vec3( 3.2291041e+02, 1.3943261e+03, -1.8477432e+03 ); - expectedForces[508] = Vec3( -1.7778104e+02, 2.8034575e+02, 1.1385089e+03 ); - expectedForces[509] = Vec3( -2.4943297e+02, -9.0965773e+02, 5.2737490e+02 ); - expectedForces[510] = Vec3( -3.8318508e+02, 1.3999092e+03, -5.9960180e+02 ); - expectedForces[511] = Vec3( 2.6930065e+01, -3.6603454e+02, 1.0460530e+03 ); - expectedForces[512] = Vec3( -1.8964668e+02, -1.1663184e+03, -2.8438291e+02 ); - expectedForces[513] = Vec3( -9.4679273e+02, 8.7408257e+01, -2.5740702e+02 ); - expectedForces[514] = Vec3( 1.6558849e+02, 3.3561310e+02, 3.8532718e+02 ); - expectedForces[515] = Vec3( 4.0403504e+02, -8.5545173e+02, 4.0647038e+02 ); - expectedForces[516] = Vec3( 8.3825526e+02, 5.0343638e+01, -3.9171626e+02 ); - expectedForces[517] = Vec3( -4.0069871e+02, -6.4140295e+02, 7.5218861e+01 ); - expectedForces[518] = Vec3( -6.5213072e+02, 4.1689581e+02, -8.9280241e+01 ); - expectedForces[519] = Vec3( 4.0832996e+02, -3.4272605e+02, -9.2740030e+02 ); - expectedForces[520] = Vec3( -2.1128040e+01, -7.3467005e+02, 6.5449252e+02 ); - expectedForces[521] = Vec3( -2.8042421e+02, 3.3193211e+02, 5.1272473e+02 ); - expectedForces[522] = Vec3( -1.2057322e+03, 3.3276609e+02, 6.8838073e+02 ); - expectedForces[523] = Vec3( 8.9270663e+02, 1.3914748e+02, -8.7213182e+02 ); - expectedForces[524] = Vec3( 8.8063936e+02, -2.4952564e+02, -8.3942753e+01 ); - expectedForces[525] = Vec3( 3.6527919e+02, 3.3758036e+02, -1.3449147e+03 ); - expectedForces[526] = Vec3( 7.1836993e+01, -3.9380031e+01, 4.7169292e+02 ); - expectedForces[527] = Vec3( -7.2114939e+01, -1.3679457e+02, 3.9080695e+02 ); - expectedForces[528] = Vec3( 1.1465645e+02, -4.4994719e+02, -3.4180224e+02 ); - expectedForces[529] = Vec3( -6.0950292e+01, 4.2825716e+02, -1.4233246e+02 ); - expectedForces[530] = Vec3( -1.9112828e+02, -2.8511065e+00, 2.6894050e+02 ); - expectedForces[531] = Vec3( 4.4955085e+02, 2.0459389e+02, 8.9486972e+02 ); - expectedForces[532] = Vec3( 6.6339624e+01, -4.2734850e+01, -4.8004048e+02 ); - expectedForces[533] = Vec3( -5.0521801e+02, -1.6330265e+02, -6.2374206e+02 ); - expectedForces[534] = Vec3( -1.1019306e+03, -4.5760347e+02, 4.6134602e+01 ); - expectedForces[535] = Vec3( 4.9278700e+02, 8.0495847e+02, -5.7470233e+01 ); - expectedForces[536] = Vec3( 9.9361557e+02, -2.4453172e+02, -3.7696369e+02 ); - expectedForces[537] = Vec3( -1.1168499e+03, -2.1108925e+02, -4.1233970e+02 ); - expectedForces[538] = Vec3( 5.6559058e+02, -2.8153614e+02, 3.0539700e+02 ); - expectedForces[539] = Vec3( 4.0805303e+02, 2.8796083e+02, -3.0009135e+01 ); - expectedForces[540] = Vec3( -8.5249075e+02, -1.0560038e+03, -6.5111795e+02 ); - expectedForces[541] = Vec3( 8.4653565e+02, 2.0615416e+02, -1.5085906e+02 ); - expectedForces[542] = Vec3( -2.8200251e+02, 6.6950966e+02, 5.9661450e+02 ); - expectedForces[543] = Vec3( -9.3339994e+01, 8.7084190e+02, -7.8375352e+02 ); - expectedForces[544] = Vec3( 1.4187243e+02, 1.2829809e+02, 8.0626841e+02 ); - expectedForces[545] = Vec3( 1.5403073e+02, -4.5932125e+02, -8.3051878e+00 ); - expectedForces[546] = Vec3( 1.3919197e+03, 5.4728737e+02, -1.0548033e+03 ); - expectedForces[547] = Vec3( -2.7215065e+02, 1.5112718e+02, 6.7366542e+02 ); - expectedForces[548] = Vec3( -7.8677637e+02, -2.6895175e+02, 4.3374996e+02 ); - expectedForces[549] = Vec3( 6.6014864e+02, -1.1474704e+03, -3.7199889e+02 ); - expectedForces[550] = Vec3( -5.8741315e+02, 2.6286109e+02, 1.9036264e+02 ); - expectedForces[551] = Vec3( 1.4325969e+02, 7.8928381e+02, 3.6304214e+02 ); - expectedForces[552] = Vec3( -9.6661866e+02, -1.0462801e+03, -6.3261994e+02 ); - expectedForces[553] = Vec3( 5.5171916e+02, 2.8672800e+02, 2.7240662e+02 ); - expectedForces[554] = Vec3( 1.1625052e+03, 7.7864110e+02, -5.2588322e+02 ); - expectedForces[555] = Vec3( 1.7042269e+03, -5.8973225e+02, 1.4814500e+02 ); - expectedForces[556] = Vec3( -7.7324022e+02, 2.9167426e+02, -1.0262563e+02 ); - expectedForces[557] = Vec3( -5.4655014e+02, -8.4339654e+01, 9.7375629e+02 ); - expectedForces[558] = Vec3( -6.9618127e+02, -1.6878530e+02, 7.1078501e+02 ); - expectedForces[559] = Vec3( 6.9623995e+02, -3.7038954e+01, 2.2671528e+02 ); - expectedForces[560] = Vec3( -7.1025694e+01, -1.8643963e+02, -8.0181026e+02 ); - expectedForces[561] = Vec3( -1.4598467e+02, 1.7170707e+03, -4.3305456e+02 ); - expectedForces[562] = Vec3( 7.9582463e+02, -5.9551245e+02, 8.3485625e+01 ); - expectedForces[563] = Vec3( -4.6812643e+02, -3.4598874e+02, -3.6753356e+01 ); - expectedForces[564] = Vec3( -1.8586268e+02, 3.1377143e+02, -1.6616022e+03 ); - expectedForces[565] = Vec3( 7.4400496e+02, 5.5058789e+02, 7.5374599e+02 ); - expectedForces[566] = Vec3( -6.3347529e+02, -3.1407006e+02, 8.2964691e+02 ); - expectedForces[567] = Vec3( -4.2499528e+02, 9.4575975e+02, -6.6700103e+02 ); - expectedForces[568] = Vec3( -9.2637696e+02, -6.6301622e+02, 3.9913705e+02 ); - expectedForces[569] = Vec3( 5.0588430e+02, -8.1942697e+01, 4.2128365e+02 ); - expectedForces[570] = Vec3( 2.7165158e+02, 2.7387902e+02, 1.0850277e+03 ); - expectedForces[571] = Vec3( -6.8391471e+00, -1.2886307e+02, -5.3501450e+02 ); - expectedForces[572] = Vec3( -2.9936240e+02, -2.2085475e+02, -6.9670281e+01 ); - expectedForces[573] = Vec3( 1.6853422e+02, 4.8410887e+02, 1.0517406e+03 ); - expectedForces[574] = Vec3( -4.9287521e+02, 1.6557733e+01, -3.4008916e+02 ); - expectedForces[575] = Vec3( 1.1132397e+02, -9.8734894e+02, -1.1154151e+02 ); - expectedForces[576] = Vec3( 3.8645582e+02, 4.3709361e+02, 1.4861132e+03 ); - expectedForces[577] = Vec3( -1.0169967e+03, -3.5279110e+02, -5.4860861e+02 ); - expectedForces[578] = Vec3( 2.8875246e+02, 5.3726711e+01, -5.9395936e+02 ); - expectedForces[579] = Vec3( 1.5169994e+03, 8.7535209e+01, 1.0103159e+03 ); - expectedForces[580] = Vec3( -1.9439968e+02, -7.9639200e+02, -1.0439069e+03 ); - expectedForces[581] = Vec3( -8.7374025e+02, 2.0597360e+02, 1.0218319e+02 ); - expectedForces[582] = Vec3( 6.4275846e+02, -6.2671529e+02, 8.9274592e+02 ); - expectedForces[583] = Vec3( -5.4449356e+01, 7.2615928e+02, -9.1355057e+02 ); - expectedForces[584] = Vec3( -2.7242606e+02, 3.9376960e+02, -4.7692581e+01 ); - expectedForces[585] = Vec3( 2.6578654e+02, -6.7385441e+02, -1.5306127e+03 ); - expectedForces[586] = Vec3( 5.1049761e+02, 7.3430855e+02, 6.1178168e+02 ); - expectedForces[587] = Vec3( -3.3593193e+02, 3.5079666e+01, 9.7444298e+02 ); - expectedForces[588] = Vec3( -7.8227654e+01, -1.1050481e+03, 1.4161574e+03 ); - expectedForces[589] = Vec3( -7.6753407e+02, 9.7291633e+02, 1.9943116e+02 ); - expectedForces[590] = Vec3( 2.9274184e+02, -2.5706985e+01, -5.8944290e+02 ); - expectedForces[591] = Vec3( -1.2502829e+03, 2.2304820e+02, -8.8573767e+02 ); - expectedForces[592] = Vec3( 1.2218682e+02, -8.2110835e+02, 3.4276058e+02 ); - expectedForces[593] = Vec3( 8.9529566e+02, -1.8417573e+02, 8.4717919e+02 ); - expectedForces[594] = Vec3( -4.6475772e+01, -1.5493620e+03, 4.8004365e+02 ); - expectedForces[595] = Vec3( 6.7104033e+02, 4.7267915e+02, -6.2630817e+02 ); - expectedForces[596] = Vec3( -2.2771561e+02, 2.7463551e+02, -2.9704610e+00 ); - expectedForces[597] = Vec3( 1.7757815e+02, -1.8906761e+03, -1.6656886e+02 ); - expectedForces[598] = Vec3( -7.4745588e+01, 1.0353962e+03, 4.2924498e+02 ); - expectedForces[599] = Vec3( -5.5648197e+02, 7.7838572e+02, -4.1677346e+02 ); - expectedForces[600] = Vec3( -5.2972489e+02, 1.1967117e+02, 1.0565388e+03 ); - expectedForces[601] = Vec3( 7.8379665e+02, -4.1803420e+02, 2.0308387e+02 ); - expectedForces[602] = Vec3( 1.2705528e+02, 1.1663435e+02, -7.6514830e+02 ); - expectedForces[603] = Vec3( -1.5203094e+03, -8.5825144e+01, -2.3039380e+02 ); - expectedForces[604] = Vec3( 5.2063739e+02, -1.7259834e+02, -2.9854160e+01 ); - expectedForces[605] = Vec3( 4.7448961e+02, 2.8282389e+02, 3.4257463e+01 ); - expectedForces[606] = Vec3( 1.4519531e+03, -1.2031444e+03, -6.7084095e+02 ); - expectedForces[607] = Vec3( -7.5308994e+02, -3.2117501e+02, 5.7700017e+02 ); - expectedForces[608] = Vec3( -1.7643179e+02, 8.5655779e+02, -2.6285482e+02 ); - expectedForces[609] = Vec3( -1.3868959e+03, -1.6195505e+01, -1.3783528e+03 ); - expectedForces[610] = Vec3( 2.8034476e+02, -4.2360778e+02, 4.5904202e+02 ); - expectedForces[611] = Vec3( 1.0938532e+03, 6.2455629e+02, -1.0108636e+02 ); - expectedForces[612] = Vec3( 9.1439974e+01, -7.2813810e+02, 1.0197075e+03 ); - expectedForces[613] = Vec3( 1.4048294e+02, 2.5667744e+02, -5.1914694e+02 ); - expectedForces[614] = Vec3( -2.5604629e+01, 2.9915218e+01, -5.1582702e+02 ); - expectedForces[615] = Vec3( 2.0331673e+02, 1.5538650e+02, -1.1836865e+03 ); - expectedForces[616] = Vec3( -2.3788957e+02, -1.1872269e+02, 9.7052698e+02 ); - expectedForces[617] = Vec3( -3.2419551e+01, -1.8828745e+02, 4.3037423e+02 ); - expectedForces[618] = Vec3( -4.8585762e+02, 1.4114027e+02, 1.6021114e+02 ); - expectedForces[619] = Vec3( 2.8744134e+02, -5.7197623e+02, -1.8323508e+02 ); - expectedForces[620] = Vec3( 2.3652930e+02, -1.5448350e+01, 2.1721186e+01 ); - expectedForces[621] = Vec3( 1.1684581e+03, 2.2790484e+02, 2.7798348e+02 ); - expectedForces[622] = Vec3( -4.6823976e+02, -6.1804544e+02, 2.7193441e+02 ); - expectedForces[623] = Vec3( -5.8173089e+02, 4.4573870e+02, -6.0699430e+02 ); - expectedForces[624] = Vec3( 7.9759250e+02, 1.8480473e+03, -5.1434277e+02 ); - expectedForces[625] = Vec3( -1.0945975e+03, -6.0402685e+02, 1.5843017e+02 ); - expectedForces[626] = Vec3( 1.2334392e+02, -9.5602838e+02, 7.8137824e+02 ); - expectedForces[627] = Vec3( -8.5863208e+02, -5.7413454e+02, 1.7014217e+02 ); - expectedForces[628] = Vec3( -1.2232569e+02, 6.0505774e+02, -1.6806693e+02 ); - expectedForces[629] = Vec3( 6.1488135e+02, 4.1603705e+02, 2.1121948e+02 ); - expectedForces[630] = Vec3( 2.1858899e+02, 1.2961013e+03, 4.8534041e+02 ); - expectedForces[631] = Vec3( 2.1292701e+02, -4.1049165e+02, 3.9057142e+00 ); - expectedForces[632] = Vec3( -6.3342469e+02, -8.7529004e+02, 6.1928550e+01 ); - expectedForces[633] = Vec3( -7.3207079e+02, -1.3874807e+03, 8.6303032e+02 ); - expectedForces[634] = Vec3( 6.6660351e+02, 9.5813895e+02, -1.4555416e+02 ); - expectedForces[635] = Vec3( 4.1800653e+02, 2.4677420e+02, -1.1424272e+03 ); - expectedForces[636] = Vec3( 8.3570430e+02, -1.5342969e+03, -1.2510269e+03 ); - expectedForces[637] = Vec3( -3.0635229e+02, 1.2465088e+03, -1.9679529e+01 ); - expectedForces[638] = Vec3( -6.5317178e+02, -1.6432929e+02, 9.2427724e+02 ); - expectedForces[639] = Vec3( 1.5665680e+03, 9.8040004e+01, 1.0786497e+02 ); - expectedForces[640] = Vec3( -4.6590380e+02, -3.7603795e+02, -9.4955273e+02 ); - expectedForces[641] = Vec3( -8.7572108e+02, 5.1750570e+02, -1.2268062e+02 ); - expectedForces[642] = Vec3( 1.1575067e+03, -2.2857204e+02, -2.3816900e+02 ); - expectedForces[643] = Vec3( -2.6229644e+02, 3.1069110e+02, -1.2098536e+02 ); - expectedForces[644] = Vec3( -1.8195659e+02, -3.8984698e+02, 6.4622752e+02 ); - expectedForces[645] = Vec3( 1.0756277e+03, 2.7459106e+01, 1.0850508e+03 ); - expectedForces[646] = Vec3( -6.4620310e+02, 2.5885783e+02, -2.0567224e+02 ); - expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02 ); + expectedForces[0] = Vec3( -5.2764003e+02, 6.5154502e+02, 7.8683284e+02); + expectedForces[1] = Vec3( 3.3391292e+02, -1.1162521e+03, -2.9173021e+02); + expectedForces[2] = Vec3( 9.4613310e+01, -5.8988099e+01, -6.2871010e+02); + expectedForces[3] = Vec3( -1.6179658e+03, 1.8222798e+02, -1.0373083e+02); + expectedForces[4] = Vec3( 1.0177962e+03, 1.7118957e+02, 4.0084976e+02); + expectedForces[5] = Vec3( 3.0582540e+02, -5.5215191e+02, 4.8287747e+01); + expectedForces[6] = Vec3( -5.4931641e+01, -6.7689368e+02, -1.2260977e+03); + expectedForces[7] = Vec3( -2.9961754e+02, 1.3602079e+03, -2.2087612e+02); + expectedForces[8] = Vec3( -3.1788045e+02, -1.3540025e+02, 1.1250958e+03); + expectedForces[9] = Vec3( 1.0275111e+03, 1.9279625e+02, -6.0872252e+02); + expectedForces[10] = Vec3( -5.7512410e+02, -5.6280482e+01, 7.5039261e+02); + expectedForces[11] = Vec3( -4.7291981e+02, -3.5875411e+01, 5.2335135e+00); + expectedForces[12] = Vec3( -1.5619899e+02, -1.3743370e+02, 1.3587339e+03); + expectedForces[13] = Vec3( -4.7423876e+02, 1.0032873e+02, -2.0875847e+02); + expectedForces[14] = Vec3( 7.5621178e+02, 3.7979419e+01, -4.1221012e+02); + expectedForces[15] = Vec3( 6.7318876e+02, 4.9937148e+02, 1.1665351e+03); + expectedForces[16] = Vec3( -7.0858091e+01, 8.4758233e+01, -1.3126942e+03); + expectedForces[17] = Vec3( -1.0636296e+03, -1.6254851e+02, -1.0982809e+02); + expectedForces[18] = Vec3( -1.0249489e+03, 6.7073895e+02, -2.0754278e+02); + expectedForces[19] = Vec3( 5.6396078e+02, -1.1702137e+03, 1.5324295e+02); + expectedForces[20] = Vec3( 6.1635144e+02, 5.6122242e+02, -7.9410893e+01); + expectedForces[21] = Vec3( -1.5785582e+02, -1.0857764e+03, -1.1010131e+03); + expectedForces[22] = Vec3( 2.3733181e+01, 2.0158373e+02, 3.2583783e+02); + expectedForces[23] = Vec3( 1.8855396e+02, 1.2408889e+03, 4.5759149e+02); + expectedForces[24] = Vec3( 9.3643408e+02, -6.1331107e+01, -3.8601431e+02); + expectedForces[25] = Vec3( -3.1972504e+02, -1.5783340e+02, -1.3838003e+02); + expectedForces[26] = Vec3( -5.1178039e+02, -2.5998898e+02, 6.1021975e+02); + expectedForces[27] = Vec3( 9.1836250e+02, -4.3288112e+02, -9.5579501e+02); + expectedForces[28] = Vec3( -9.3325184e+02, 6.2859013e+01, 5.0743198e+02); + expectedForces[29] = Vec3( 3.1839963e+02, 5.4102155e+02, 1.1261345e+03); + expectedForces[30] = Vec3( 7.3842640e+02, 1.0907054e+02, -2.1126612e+02); + expectedForces[31] = Vec3( -1.8470175e+02, -4.0377182e+01, 1.2464073e+02); + expectedForces[32] = Vec3( -5.8931386e+02, -3.5021489e+02, -7.2769901e+01); + expectedForces[33] = Vec3( 1.4804452e+02, -1.2138869e+02, -1.2423820e+03); + expectedForces[34] = Vec3( -2.4850935e+02, 2.3113218e+01, 1.4041979e+02); + expectedForces[35] = Vec3( 1.3188525e+02, -6.1243481e+02, 6.4886373e+02); + expectedForces[36] = Vec3( 5.0217683e+02, 9.2857480e+02, -7.2500648e+02); + expectedForces[37] = Vec3( 9.9446320e+01, -3.0337270e+02, 8.0439741e+02); + expectedForces[38] = Vec3( -1.7167491e+02, -9.3911948e+02, 5.6412500e+01); + expectedForces[39] = Vec3( -6.6143649e+02, 1.0876882e+03, 3.3801466e+02); + expectedForces[40] = Vec3( 5.6748150e+02, -2.2459572e+02, 3.8360728e+02); + expectedForces[41] = Vec3( 7.7688834e+02, -6.7341171e+02, -6.4292796e+02); + expectedForces[42] = Vec3( 1.0253263e+02, -1.3212797e+03, 9.3279892e+02); + expectedForces[43] = Vec3( 1.5424247e+02, -1.0197346e+01, -8.0230728e+02); + expectedForces[44] = Vec3( -6.6499384e+02, 1.2534353e+03, -1.6748341e+02); + expectedForces[45] = Vec3( -1.9282945e+02, 5.1764789e+02, 1.5108154e+03); + expectedForces[46] = Vec3( -4.9204245e+02, 8.8664089e+02, -8.8381078e+02); + expectedForces[47] = Vec3( 1.3207641e+01, -5.7765859e+02, -3.5921690e+02); + expectedForces[48] = Vec3( 4.1691955e+02, -1.1292452e+03, -6.2339128e+02); + expectedForces[49] = Vec3( 4.8613761e+02, 6.8325845e+02, 2.3424652e+02); + expectedForces[50] = Vec3( 3.1827501e+01, 6.8442319e+02, -5.8685438e+02); + expectedForces[51] = Vec3( 1.1834790e+03, -1.3418299e+03, 5.6280882e+02); + expectedForces[52] = Vec3( -5.8629616e+02, -6.9100489e+01, -9.7784543e+02); + expectedForces[53] = Vec3( -4.0294748e+02, 5.0669032e+02, 5.3893512e+02); + expectedForces[54] = Vec3( 6.3555947e+01, -9.0345643e+02, 7.2235587e+02); + expectedForces[55] = Vec3( 4.9353706e+02, 4.3952680e+02, -1.5413911e+02); + expectedForces[56] = Vec3( -3.4663273e+02, 8.4708544e+02, -8.8983178e+01); + expectedForces[57] = Vec3( 1.5746383e+03, 5.8209931e+02, 3.6645765e+02); + expectedForces[58] = Vec3( -4.0076588e+02, -1.2311235e+02, -1.6226002e+02); + expectedForces[59] = Vec3( -3.3837369e+02, -5.3890252e+02, -5.5997831e+02); + expectedForces[60] = Vec3( 8.6512912e+02, -1.0775827e+03, -3.6920406e+02); + expectedForces[61] = Vec3( 1.0588621e+01, 4.4531974e+02, 1.1838800e+02); + expectedForces[62] = Vec3( -7.0505255e+02, 1.5737739e+02, 3.0134165e+02); + expectedForces[63] = Vec3( -1.2833932e+03, 5.1206074e+02, -9.3423828e+01); + expectedForces[64] = Vec3( 2.0863538e+02, -6.7108922e+02, 3.5777952e+02); + expectedForces[65] = Vec3( 4.9710436e+02, -6.8550896e+01, -2.7502680e+02); + expectedForces[66] = Vec3( 4.0388289e+02, 1.0051571e+03, -2.3823633e+02); + expectedForces[67] = Vec3( -3.3895858e+02, -6.7577709e+02, 3.1521120e+02); + expectedForces[68] = Vec3( -4.8763670e+02, -2.9427128e+02, 2.9500438e+02); + expectedForces[69] = Vec3( -8.4080783e+02, -1.7777886e+02, 6.5087880e+02); + expectedForces[70] = Vec3( 2.1136356e+02, 6.6812142e+01, -5.5437438e+02); + expectedForces[71] = Vec3( -1.3829189e+01, 7.0936421e+02, -5.0847380e+02); + expectedForces[72] = Vec3( -1.5684247e+03, 1.6837339e+02, -4.6044105e+02); + expectedForces[73] = Vec3( 9.9163605e+02, -4.1397181e+02, -3.9624142e+02); + expectedForces[74] = Vec3( 6.7355000e+02, 5.7652252e+02, 1.0565003e+03); + expectedForces[75] = Vec3( -1.3722105e+03, -1.4035644e+03, 2.7882380e+02); + expectedForces[76] = Vec3( 5.2187588e+02, 3.9602986e+02, -2.2564009e+02); + expectedForces[77] = Vec3( 2.6381283e+02, 4.2945748e+02, 1.8339201e+02); + expectedForces[78] = Vec3( 5.3099327e+02, 1.7312849e+03, 3.5385638e+01); + expectedForces[79] = Vec3( -2.1320977e+02, -1.1795453e+03, -5.1691859e+02); + expectedForces[80] = Vec3( -7.1445218e+02, -5.8918750e+02, 7.6494816e+02); + expectedForces[81] = Vec3( 1.0849545e+03, 6.5058603e+02, -5.6051049e+02); + expectedForces[82] = Vec3( -4.6986151e+02, -3.3868080e+02, 7.9000645e+02); + expectedForces[83] = Vec3( -3.8404718e+02, -4.4915037e+02, -4.2069600e+02); + expectedForces[84] = Vec3( -3.0678477e+02, -7.2558567e+02, 2.0276275e+02); + expectedForces[85] = Vec3( 6.2969625e+01, 3.4257826e+02, -6.8348290e+02); + expectedForces[86] = Vec3( 3.1042613e+02, 9.6563445e+01, -1.8788848e+02); + expectedForces[87] = Vec3( 2.4427535e+01, 5.8460648e+02, -1.3720684e+03); + expectedForces[88] = Vec3( -4.9904469e+02, -9.1309605e+02, 1.4350031e+02); + expectedForces[89] = Vec3( -4.0910847e+01, 5.2845046e+01, 2.7341591e+02); + expectedForces[90] = Vec3( -4.5190765e+02, 2.2820859e+02, -1.1052181e+03); + expectedForces[91] = Vec3( 9.1626336e+01, -1.0496400e+03, 1.0216011e+02); + expectedForces[92] = Vec3( -1.2592678e+02, -4.4050520e+01, 1.0764584e+03); + expectedForces[93] = Vec3( 8.4216135e+02, 1.7603150e+02, 1.3698861e+03); + expectedForces[94] = Vec3( 1.2583734e+02, 3.4343971e+02, -7.3070182e+02); + expectedForces[95] = Vec3( -4.5597370e+02, -6.8170738e+02, -5.2258658e+02); + expectedForces[96] = Vec3( 1.3295639e+03, 2.5031118e+02, -3.5171095e+02); + expectedForces[97] = Vec3( -2.0136001e+02, -2.2978012e+02, 2.1122610e+02); + expectedForces[98] = Vec3( -1.1279722e+03, -9.9794730e+02, -1.1321006e+02); + expectedForces[99] = Vec3( 2.9553179e+02, -2.0727600e+02, -1.8912317e+03); + expectedForces[100] = Vec3( -9.3777487e+02, 4.3417972e+02, 5.7436670e+02); + expectedForces[101] = Vec3( 3.1120364e+02, -4.3241206e+00, 5.6666340e+02); + expectedForces[102] = Vec3( -6.6764840e+02, -2.3563274e+02, 9.9017992e+02); + expectedForces[103] = Vec3( 8.2857598e+02, 1.9030059e+02, -2.4295780e+02); + expectedForces[104] = Vec3( -2.6709334e+02, 7.3284851e+01, -3.9157038e+02); + expectedForces[105] = Vec3( 6.6235629e+02, -8.4502811e+02, -5.3670716e+02); + expectedForces[106] = Vec3( 3.8449086e+02, 8.0775263e+02, 5.2003911e+02); + expectedForces[107] = Vec3( -3.4338589e+02, 1.7870086e+02, -6.1047615e+01); + expectedForces[108] = Vec3( 4.3523975e+02, 2.8776092e+02, -1.5333067e+03); + expectedForces[109] = Vec3( 1.9214022e+01, -9.9449061e+01, 3.9153169e+02); + expectedForces[110] = Vec3( -7.7525496e+02, 7.7309387e+01, 7.8886699e+02); + expectedForces[111] = Vec3( -1.1510224e+03, -2.8207337e+02, 1.4866455e+03); + expectedForces[112] = Vec3( 1.1281316e+03, -3.0961130e+02, -1.3894255e+02); + expectedForces[113] = Vec3( -2.4829062e+02, 5.9466066e+02, -9.0749265e+02); + expectedForces[114] = Vec3( -1.6228531e+02, -4.1281378e+02, -1.4860946e+03); + expectedForces[115] = Vec3( -2.9071192e+02, 7.5335271e+02, 6.5205720e+02); + expectedForces[116] = Vec3( 3.2042337e+02, -4.0237231e+02, 1.0068554e+03); + expectedForces[117] = Vec3( -1.4081272e+03, -5.5227579e+02, 2.8376428e+02); + expectedForces[118] = Vec3( 9.6978276e+02, -9.6232683e+02, 2.3399918e+02); + expectedForces[119] = Vec3( 2.0781312e+02, 9.0531947e+01, 8.3513783e+01); + expectedForces[120] = Vec3( 2.9200105e+02, 1.0746865e+03, -6.0773727e+02); + expectedForces[121] = Vec3( -8.7546167e+02, 3.1969683e+02, 8.1033199e+01); + expectedForces[122] = Vec3( -5.3422658e+01, -3.8456585e+02, 1.4595003e+02); + expectedForces[123] = Vec3( -9.5134908e+01, 8.6818098e+02, -1.3111403e+03); + expectedForces[124] = Vec3( -7.2576830e+02, 6.3811172e+01, 7.0993488e+02); + expectedForces[125] = Vec3( 5.6200572e+02, -1.0972338e+03, -3.5278717e+02); + expectedForces[126] = Vec3( -1.6903718e+02, 2.6804112e+02, -8.9811032e+02); + expectedForces[127] = Vec3( 7.0934165e+02, -3.2328700e+02, 1.0037562e+02); + expectedForces[128] = Vec3( -2.5937738e+00, -3.3758145e+02, 3.6354335e+02); + expectedForces[129] = Vec3( -1.1993601e+03, 1.1618922e+02, -1.1329865e+03); + expectedForces[130] = Vec3( 8.3480845e+02, 5.2646427e+02, 9.1816763e+01); + expectedForces[131] = Vec3( 1.9407174e+02, 7.3877492e+00, 8.8648162e+02); + expectedForces[132] = Vec3( -1.0820540e+03, 2.7482390e+02, -1.4876848e+03); + expectedForces[133] = Vec3( 9.5717027e+02, -4.7758356e+02, 4.0692835e+02); + expectedForces[134] = Vec3( 2.4979896e+02, 7.1530552e+02, 6.5834243e+02); + expectedForces[135] = Vec3( -2.7549874e+02, 1.6613806e+03, -5.0628865e+02); + expectedForces[136] = Vec3( -1.5960544e+02, -4.5920421e+02, 9.4068762e+02); + expectedForces[137] = Vec3( 6.9764295e+01, -4.4024430e+02, -2.3545402e+02); + expectedForces[138] = Vec3( 2.0207569e+03, -2.6846158e+02, 3.3977998e+02); + expectedForces[139] = Vec3( -9.9905342e+02, 9.5155462e+02, 8.3259854e+01); + expectedForces[140] = Vec3( -8.0836255e+02, -6.3005196e+02, 1.2603525e+02); + expectedForces[141] = Vec3( 5.2279913e+02, 1.5356061e+03, -1.4399009e+02); + expectedForces[142] = Vec3( -1.3088783e+02, -9.0861449e+02, 9.7040422e+02); + expectedForces[143] = Vec3( 2.8006682e+01, -1.1783245e+03, -3.7285390e+02); + expectedForces[144] = Vec3( 6.1040927e+01, 2.1747286e+01, 9.0366011e+02); + expectedForces[145] = Vec3( 7.0396235e+02, -2.3865001e+02, -6.8794682e+02); + expectedForces[146] = Vec3( -5.1132933e+02, 7.7102556e+02, -4.7805042e+02); + expectedForces[147] = Vec3( 6.2879945e+02, -6.9758821e+02, 1.0983043e+03); + expectedForces[148] = Vec3( -9.2449123e+02, 5.0248042e+02, -2.0065211e+02); + expectedForces[149] = Vec3( -3.9485154e+02, 3.4679511e+02, -7.3889603e+02); + expectedForces[150] = Vec3( 4.9834751e+02, -1.0117501e+03, 1.2510946e+03); + expectedForces[151] = Vec3( -1.4942699e+02, -7.4362790e+01, -6.8008427e+02); + expectedForces[152] = Vec3( -1.8353666e+02, 5.1697483e+02, -8.4397292e+01); + expectedForces[153] = Vec3( 7.0253008e+02, -1.5361338e+02, 8.6830836e+02); + expectedForces[154] = Vec3( -4.1108898e+02, -6.8181350e+02, -5.6516951e+02); + expectedForces[155] = Vec3( 3.9294374e+02, 3.7294948e+02, -4.9795080e+02); + expectedForces[156] = Vec3( -7.3716758e+02, -5.5465931e+02, -9.3434525e+02); + expectedForces[157] = Vec3( 1.8240105e+02, 1.5494359e+02, 1.3626243e+02); + expectedForces[158] = Vec3( 9.3172059e+02, 1.4431275e+02, 6.6916065e+02); + expectedForces[159] = Vec3( 7.3399513e+01, -3.6000187e+02, 1.9853052e+03); + expectedForces[160] = Vec3( -2.4842520e+02, -4.0819514e+02, -8.0624794e+02); + expectedForces[161] = Vec3( 4.3585911e+02, -2.6521764e+02, -6.7985842e+02); + expectedForces[162] = Vec3( -8.2255783e+02, 1.1430906e+03, 1.2991183e+03); + expectedForces[163] = Vec3( 5.6437196e+02, -1.5391213e+02, -5.0013503e+02); + expectedForces[164] = Vec3( 3.8485296e+02, -1.1754088e+02, -1.4315511e+03); + expectedForces[165] = Vec3( 9.8205241e+02, 1.3278205e+01, 3.0367584e+02); + expectedForces[166] = Vec3( -3.2909916e+02, 4.5169387e+01, -3.2019488e+02); + expectedForces[167] = Vec3( -4.2382795e+02, -8.1938351e+02, -1.5360675e+02); + expectedForces[168] = Vec3( 9.1689997e+02, 1.4443113e+03, -1.8886795e+02); + expectedForces[169] = Vec3( -1.2161000e+03, -2.3826187e+02, 3.4004889e+02); + expectedForces[170] = Vec3( -2.2837927e+02, -9.8334152e+02, 3.0313790e+02); + expectedForces[171] = Vec3( 5.2598040e+02, -1.2766936e+03, 8.1247934e+01); + expectedForces[172] = Vec3( -6.7839687e+01, 6.9220160e+02, 3.1975320e+02); + expectedForces[173] = Vec3( -4.8519844e+02, 4.3008979e+02, -7.6788762e+02); + expectedForces[174] = Vec3( 3.9550092e+01, 1.0900122e+03, 5.0955281e+02); + expectedForces[175] = Vec3( -6.3000735e+02, -7.2335263e+02, -2.2590661e+02); + expectedForces[176] = Vec3( 1.5048762e+02, -4.0086126e+02, -1.2159849e+02); + expectedForces[177] = Vec3( -7.1939527e+02, -1.0640815e+03, -3.1826393e+02); + expectedForces[178] = Vec3( 7.7492135e+02, 1.0620129e+02, 3.6733165e+02); + expectedForces[179] = Vec3( -3.5466457e+02, 7.0081887e+02, 2.2629152e+02); + expectedForces[180] = Vec3( 3.0338275e+02, -1.1243396e+02, -1.3408996e+03); + expectedForces[181] = Vec3( 9.0394088e+00, 4.8818819e+02, 7.3781403e+02); + expectedForces[182] = Vec3( -5.6111982e+01, -2.5224925e+02, 3.0344460e+02); + expectedForces[183] = Vec3( -7.4693225e+02, 1.1370727e+03, 9.3958175e+02); + expectedForces[184] = Vec3( 3.1310327e+02, -1.2133761e+03, 2.6768166e+02); + expectedForces[185] = Vec3( 6.0706899e+02, 9.8403362e+01, -5.0781782e+02); + expectedForces[186] = Vec3( -6.2721609e+02, 1.7751567e+02, 2.6230643e+02); + expectedForces[187] = Vec3( 3.5425475e+02, -3.3336896e+02, 2.9529930e+02); + expectedForces[188] = Vec3( 4.7499029e+02, 4.5552354e+02, -2.4939310e+02); + expectedForces[189] = Vec3( 1.1556321e+02, 2.5995186e+02, -8.4171376e+02); + expectedForces[190] = Vec3( -4.5095184e+02, -1.6639362e+01, 4.2956175e+02); + expectedForces[191] = Vec3( -7.5904218e+01, 3.9416063e+02, 4.2573815e+02); + expectedForces[192] = Vec3( 2.3041013e+02, -1.2883920e+03, -5.1943189e+02); + expectedForces[193] = Vec3( 8.6086944e+01, 1.8626094e+02, 3.7641641e+02); + expectedForces[194] = Vec3( -5.9266805e+02, 4.4766229e+02, -4.5835497e+02); + expectedForces[195] = Vec3( 3.9368476e+02, 1.1050329e+03, -1.3906133e+03); + expectedForces[196] = Vec3( -1.2912212e+03, -2.9660534e+02, 3.9659215e+02); + expectedForces[197] = Vec3( -2.4803663e+01, -2.7945607e+02, 3.5315630e+02); + expectedForces[198] = Vec3( 1.4147479e+02, 3.2766723e+02, 1.1137899e+03); + expectedForces[199] = Vec3( 7.8383167e+01, 2.2385715e+00, -1.0346820e+03); + expectedForces[200] = Vec3( -2.9231551e+02, -5.4648720e+02, -6.5500265e+02); + expectedForces[201] = Vec3( 1.3708284e+03, -1.0716376e+03, 4.5781190e+02); + expectedForces[202] = Vec3( -7.5533654e+02, 6.5396686e+02, -4.2683276e+02); + expectedForces[203] = Vec3( -6.5558825e+02, 3.1164131e+02, 2.6323555e+02); + expectedForces[204] = Vec3( 1.3173432e+03, 1.3775889e+03, 1.2933072e+02); + expectedForces[205] = Vec3( -4.0922505e+02, -7.5709333e+02, -3.4967434e+02); + expectedForces[206] = Vec3( 4.2270572e+01, -7.4393359e+02, 5.2985443e+02); + expectedForces[207] = Vec3( -1.5327880e+03, 7.3186706e+02, -2.3440058e+02); + expectedForces[208] = Vec3( 1.4650210e+03, 2.8661572e+02, -2.4233049e+02); + expectedForces[209] = Vec3( 8.4124688e+02, -3.4020518e+02, -3.1773592e+01); + expectedForces[210] = Vec3( -1.1480436e+03, -7.4089732e+02, -4.8883682e+02); + expectedForces[211] = Vec3( 3.5682075e+02, 2.1918110e+01, -1.2558000e+02); + expectedForces[212] = Vec3( 1.6505256e+02, 7.9867933e+02, 9.9760760e+02); + expectedForces[213] = Vec3( 1.2477725e+03, -8.8687803e+02, -8.2498529e+02); + expectedForces[214] = Vec3( 1.7357042e+02, 2.0185456e+02, 8.0965301e+02); + expectedForces[215] = Vec3( -9.0937500e+02, 5.5968713e+01, 1.7581913e+02); + expectedForces[216] = Vec3( 1.3030711e+03, -8.2642443e+02, 1.6679926e+02); + expectedForces[217] = Vec3( -8.4295510e+02, 2.0237547e+01, 4.0163431e+02); + expectedForces[218] = Vec3( -3.2088719e+02, 3.0824476e+02, 9.9166532e+01); + expectedForces[219] = Vec3( 1.4585495e+03, -4.1497503e+01, -2.2539636e+02); + expectedForces[220] = Vec3( -2.6148433e+02, 1.7592075e+02, 2.0638296e+02); + expectedForces[221] = Vec3( -9.2100962e+02, 2.6090225e+02, -8.4461867e+02); + expectedForces[222] = Vec3( -9.0597287e+02, -4.8246138e+02, -1.8012972e+03); + expectedForces[223] = Vec3( -1.1775667e+02, 1.7275816e+02, 1.1286513e+03); + expectedForces[224] = Vec3( 1.0682239e+03, 8.0853797e+02, 2.5601774e+02); + expectedForces[225] = Vec3( -1.6637330e+02, 7.6165466e+02, -5.9394315e+02); + expectedForces[226] = Vec3( 2.6206832e+02, -1.5011747e+02, 5.4532792e+02); + expectedForces[227] = Vec3( -2.6474701e+02, -1.4218144e+02, 1.1099125e+02); + expectedForces[228] = Vec3( -9.7365994e+02, -5.5282012e+02, -6.3158992e+02); + expectedForces[229] = Vec3( 1.1482718e+03, 1.4958662e+02, -5.6523355e+02); + expectedForces[230] = Vec3( 4.4084982e+02, 7.9662251e+02, 4.9732039e+02); + expectedForces[231] = Vec3( -4.8746806e+02, -1.5522005e+03, 1.0133483e+03); + expectedForces[232] = Vec3( 1.1332903e+03, 1.2836176e+03, -2.0897082e+02); + expectedForces[233] = Vec3( -7.9973372e+01, 6.3066961e+02, -5.8656505e+02); + expectedForces[234] = Vec3( -8.3714021e+02, -1.5385924e+03, 1.0179672e+03); + expectedForces[235] = Vec3( 3.5358323e+02, 9.3554369e+02, 1.6565605e+02); + expectedForces[236] = Vec3( 1.7532341e+02, 3.0381323e+01, -1.2538424e+03); + expectedForces[237] = Vec3( -1.0437301e+03, -4.4804918e+02, 1.5276435e+03); + expectedForces[238] = Vec3( 8.5470872e+02, 1.0725550e+03, -9.7359443e+01); + expectedForces[239] = Vec3( 1.8192015e+02, -7.6967211e+01, -8.6054596e+02); + expectedForces[240] = Vec3( 1.5910180e+03, -7.9601605e+02, -8.4030326e+02); + expectedForces[241] = Vec3( -6.4638370e+02, 4.0538540e+02, 2.3396878e+01); + expectedForces[242] = Vec3( -5.2648918e+02, 1.3689201e+02, 9.3014716e+02); + expectedForces[243] = Vec3( 2.2248997e+02, -6.3647370e+02, -8.3913128e+02); + expectedForces[244] = Vec3( -7.5759832e+02, 4.7985429e+01, 5.8577833e+02); + expectedForces[245] = Vec3( 1.2983550e+02, 4.4401985e+02, 2.3556259e+02); + expectedForces[246] = Vec3( 7.8075637e+02, 9.9893821e+02, 7.3511307e+02); + expectedForces[247] = Vec3( -8.6411159e+02, 2.3812628e+02, 1.9007971e+02); + expectedForces[248] = Vec3( 2.0762263e+02, -7.0123789e+02, -4.8175733e+02); + expectedForces[249] = Vec3( -8.2749187e+02, -7.8772346e+02, -9.8536337e+02); + expectedForces[250] = Vec3( 8.3905893e+01, -2.8770518e+02, 6.0690561e+02); + expectedForces[251] = Vec3( 7.2280803e+02, 4.9294103e+02, -1.2915033e+02); + expectedForces[252] = Vec3( -1.3615809e+03, -1.8564754e+02, -4.2172817e+02); + expectedForces[253] = Vec3( 9.2102155e+02, 5.4063967e+02, -2.7291760e+02); + expectedForces[254] = Vec3( 7.0204283e+02, -3.0338605e+02, 6.6795953e+02); + expectedForces[255] = Vec3( -7.2261285e+00, 3.2570478e+02, 5.9010590e+02); + expectedForces[256] = Vec3( -8.3167819e+02, 3.0568475e+02, -9.9230441e+02); + expectedForces[257] = Vec3( 2.1074297e+02, -4.0099946e+01, -1.2770634e+02); + expectedForces[258] = Vec3( 1.1218559e+03, -8.8304672e+02, 1.0217945e+03); + expectedForces[259] = Vec3( -4.4730264e+01, 5.3616918e+02, -3.2704110e+02); + expectedForces[260] = Vec3( -1.1106141e+03, 3.3541536e+02, -1.0552986e+02); + expectedForces[261] = Vec3( -9.3728497e+01, 4.7397796e+01, -1.1294332e+03); + expectedForces[262] = Vec3( 5.1424956e+01, 4.0854995e+02, 5.6832607e+02); + expectedForces[263] = Vec3( 1.4286074e+02, 2.9172921e+01, 5.1355833e+02); + expectedForces[264] = Vec3( -4.4318133e+02, -9.5478293e+02, -1.8067439e+03); + expectedForces[265] = Vec3( -2.8083245e+02, 8.1414586e+02, 6.6089404e+02); + expectedForces[266] = Vec3( 1.0434876e+02, 3.0664078e+02, 1.3658532e+03); + expectedForces[267] = Vec3( 1.2999089e+03, 5.6746563e+02, 1.2200612e+03); + expectedForces[268] = Vec3( -5.9546942e+02, 3.6897149e+02, -8.3331437e+02); + expectedForces[269] = Vec3( -1.1094881e+03, -5.1903335e+02, -3.5729033e+02); + expectedForces[270] = Vec3( 4.1873464e+02, 6.9788983e+02, -1.3191929e+03); + expectedForces[271] = Vec3( -1.0086080e+02, 3.3114447e+02, 6.3419860e+02); + expectedForces[272] = Vec3( -2.8783906e+02, -8.8308011e+02, -5.4816768e+01); + expectedForces[273] = Vec3( 1.0254638e+03, 2.8710026e+02, -1.9779676e+02); + expectedForces[274] = Vec3( -3.5906548e+02, -5.5531449e+02, -6.0205492e+01); + expectedForces[275] = Vec3( -3.9578349e+02, 5.9217272e+01, 1.0735648e+02); + expectedForces[276] = Vec3( -8.7298871e+02, -1.5584711e+02, 9.2571354e+02); + expectedForces[277] = Vec3( 4.1520558e+02, 5.6442126e+02, -1.8142289e+02); + expectedForces[278] = Vec3( 6.5423421e+02, -4.1631573e+02, 1.0996479e+02); + expectedForces[279] = Vec3( -8.0063899e+01, -1.2880940e+03, 2.9304469e+02); + expectedForces[280] = Vec3( -9.5930841e+02, 5.8293485e+02, -1.1632205e+03); + expectedForces[281] = Vec3( 6.3492338e+02, 2.5550931e+02, 1.7380517e+02); + expectedForces[282] = Vec3( -1.9188175e+02, 1.0257290e+03, -8.6438702e+02); + expectedForces[283] = Vec3( 4.0063530e+01, -5.1808902e+02, 4.9556015e+02); + expectedForces[284] = Vec3( 5.8250018e+02, -2.5030700e+02, 1.1762860e+03); + expectedForces[285] = Vec3( -4.3195459e+02, 7.4733530e+02, -1.3002210e+03); + expectedForces[286] = Vec3( 2.7567334e+01, -5.1662654e+02, 3.3258050e+02); + expectedForces[287] = Vec3( 6.1700857e+02, 3.0016354e+02, 9.5519139e+02); + expectedForces[288] = Vec3( 7.7553094e+02, 8.6453551e+02, -1.0122996e+03); + expectedForces[289] = Vec3( -2.6730796e+02, -7.7560875e+02, 4.3195620e+02); + expectedForces[290] = Vec3( -8.5982146e+02, 1.6692057e+02, 4.3838169e+02); + expectedForces[291] = Vec3( 1.2945126e+03, 6.3231748e+02, -8.3020592e+02); + expectedForces[292] = Vec3( -6.9510729e+02, -3.1930013e+02, -1.3919425e+01); + expectedForces[293] = Vec3( -4.1154200e+02, -3.3562358e+02, 6.3292682e+02); + expectedForces[294] = Vec3( -4.0919783e+02, -3.8282298e+02, -4.9125465e+02); + expectedForces[295] = Vec3( 6.3932145e+02, -1.8769713e+01, 9.9241332e+01); + expectedForces[296] = Vec3( 8.6847663e+01, 8.7234739e+02, 2.7124112e+02); + expectedForces[297] = Vec3( -1.0307576e+03, -6.2447562e+02, -1.5796976e+03); + expectedForces[298] = Vec3( 6.2464595e+02, 1.0608165e+03, 3.1422521e+01); + expectedForces[299] = Vec3( 3.7767184e+02, 4.1170186e+02, 1.0696495e+03); + expectedForces[300] = Vec3( 1.0578030e+02, -1.9544726e+03, -4.6243957e+02); + expectedForces[301] = Vec3( -3.1074896e+02, 8.6738333e+02, -2.0241448e+02); + expectedForces[302] = Vec3( -2.7350519e+02, 6.9945273e+02, 7.8755130e+02); + expectedForces[303] = Vec3( 7.8083070e+02, 6.5199614e+02, -6.6698950e+02); + expectedForces[304] = Vec3( 1.3647451e+02, -4.2490411e+02, 1.3236061e+01); + expectedForces[305] = Vec3( -1.1048984e+03, 3.7582184e+02, -6.4718844e+01); + expectedForces[306] = Vec3( 1.5976050e+03, -8.9091819e+02, 9.7113419e+02); + expectedForces[307] = Vec3( -4.5545384e+01, 8.8683300e+02, -6.5927739e+01); + expectedForces[308] = Vec3( -1.3883497e+03, -4.6171498e+02, -2.9117829e+02); + expectedForces[309] = Vec3( -6.6661140e+02, -8.1394964e+02, 1.2397900e+03); + expectedForces[310] = Vec3( -2.5293546e+02, 1.8568554e+02, -6.8919479e+02); + expectedForces[311] = Vec3( 5.2052057e+02, 1.0288555e+03, 3.1435700e+02); + expectedForces[312] = Vec3( -2.4245555e+02, -1.1100993e+03, -1.6937710e+03); + expectedForces[313] = Vec3( 1.6647470e+02, 9.5272347e+02, 9.2528380e+02); + expectedForces[314] = Vec3( 8.6946518e+02, -1.6295251e+02, 5.7452409e+02); + expectedForces[315] = Vec3( 1.4059831e+02, 5.6780959e+02, -4.6024149e+02); + expectedForces[316] = Vec3( 2.3327811e+02, -2.2376697e+02, 1.3399582e+01); + expectedForces[317] = Vec3( -2.6583612e+01, -4.5801841e+02, 2.9595361e+01); + expectedForces[318] = Vec3( 1.2361796e+03, -1.9473934e+02, -2.6179421e+02); + expectedForces[319] = Vec3( -4.2330105e+02, 5.0768290e+02, 6.8352494e+02); + expectedForces[320] = Vec3( -2.0826312e+02, 1.4720747e+02, -9.8828425e-01); + expectedForces[321] = Vec3( -7.3226106e+02, -1.5366771e+01, 2.7882968e+02); + expectedForces[322] = Vec3( 4.2634684e+02, -6.2926647e+02, 3.6300784e+02); + expectedForces[323] = Vec3( 1.7826269e+02, 1.0038378e+02, -4.2408556e+02); + expectedForces[324] = Vec3( -1.1690005e+03, 2.1777241e+02, 9.1980300e+02); + expectedForces[325] = Vec3( 5.6841370e+02, -2.6614377e+02, -6.4968364e+01); + expectedForces[326] = Vec3( 3.5710749e+02, 1.3228373e+02, -3.6567433e+02); + expectedForces[327] = Vec3( 8.1957745e+02, 7.3903486e+02, 3.9487193e+02); + expectedForces[328] = Vec3( -8.5354740e+02, 8.9297958e+01, 9.0615539e+01); + expectedForces[329] = Vec3( -2.3935807e+02, -2.2950021e+02, -4.6193868e+01); + expectedForces[330] = Vec3( 8.6120406e+01, 1.4046499e+03, -1.5899345e+02); + expectedForces[331] = Vec3( 4.6319634e+02, -4.6309406e+02, -2.2891416e+02); + expectedForces[332] = Vec3( -4.2592255e+02, -2.6503000e+02, 6.1788141e+02); + expectedForces[333] = Vec3( -2.4468457e+02, -7.7827760e+02, 4.2470013e+02); + expectedForces[334] = Vec3( 2.6006448e+02, 7.6289112e+01, -4.3430411e+02); + expectedForces[335] = Vec3( -2.5268926e+02, 7.7381529e+02, -5.0896414e+02); + expectedForces[336] = Vec3( 1.0414844e+03, -6.1885512e+02, 1.4495539e+03); + expectedForces[337] = Vec3( -5.9522011e+01, 1.3607073e+03, -7.3705640e+01); + expectedForces[338] = Vec3( -5.9857094e+02, -2.7213045e+02, -9.7516268e+02); + expectedForces[339] = Vec3( 9.2852178e+02, 3.0121600e+02, -7.4982031e+00); + expectedForces[340] = Vec3( -1.0201472e+03, 1.6269359e+02, 1.9280960e+02); + expectedForces[341] = Vec3( -1.8744984e+02, -4.9790658e+02, 4.2841303e+02); + expectedForces[342] = Vec3( -1.0893114e+03, -4.6044565e+02, -2.0537532e+02); + expectedForces[343] = Vec3( 5.1068148e+02, -3.0889884e+02, 1.7703226e+01); + expectedForces[344] = Vec3( 2.0128423e+02, 5.0813056e+02, -5.0941772e+01); + expectedForces[345] = Vec3( -6.0195519e+02, 1.1710803e+03, -5.8271481e+02); + expectedForces[346] = Vec3( 1.3898239e+02, -3.2598252e+02, 1.0877023e+03); + expectedForces[347] = Vec3( 3.1630812e+02, -8.9974673e+02, 9.6573268e+01); + expectedForces[348] = Vec3( -5.5334313e+01, -1.1529065e+03, -2.1949997e+02); + expectedForces[349] = Vec3( -4.4904784e+02, 2.4036076e+02, 4.1328142e+02); + expectedForces[350] = Vec3( 1.0611611e+03, 4.1620143e+02, 9.1677657e+01); + expectedForces[351] = Vec3( 1.3489840e+03, 9.9500659e+02, -4.5894902e+01); + expectedForces[352] = Vec3( -9.8051252e+01, -9.0794586e+02, -8.9918421e+02); + expectedForces[353] = Vec3( -3.5567408e+02, -7.2914902e+01, 4.7977644e+01); + expectedForces[354] = Vec3( -1.5976501e+03, -1.2202674e+03, 7.2159213e+02); + expectedForces[355] = Vec3( 1.7391266e+02, 1.0197773e+03, -9.1284547e+02); + expectedForces[356] = Vec3( 7.8937287e+02, 1.1964969e+02, -3.8520683e+02); + expectedForces[357] = Vec3( 2.8170878e+02, 1.0377979e+03, -5.0609230e+02); + expectedForces[358] = Vec3( -4.0852118e+01, -4.3087314e+02, 4.1855459e+01); + expectedForces[359] = Vec3( -3.2767902e+02, -7.8083477e+02, 1.1111190e+03); + expectedForces[360] = Vec3( -1.0691030e+03, 3.1877408e+02, -7.9684323e+02); + expectedForces[361] = Vec3( 7.7603235e+02, 3.6577850e+02, -1.9093841e+02); + expectedForces[362] = Vec3( -4.7607360e+02, -5.1710653e+02, 7.2740737e+02); + expectedForces[363] = Vec3( 9.3461900e+02, 7.9988609e+01, -5.8055314e+02); + expectedForces[364] = Vec3( -9.8128918e+02, -2.6706371e+02, -3.5178135e+01); + expectedForces[365] = Vec3( -6.5196668e+02, 8.7618054e+02, 3.3040412e+02); + expectedForces[366] = Vec3( 5.5458970e+02, -1.1281839e+03, -8.2774754e+02); + expectedForces[367] = Vec3( 1.8491757e+02, -5.1421593e+01, 4.7068191e+02); + expectedForces[368] = Vec3( -4.3945944e+02, 8.2740025e+02, -2.1736033e+01); + expectedForces[369] = Vec3( -2.5609394e+02, -6.7141305e+02, -3.2964376e+02); + expectedForces[370] = Vec3( 1.4932730e+02, 2.2746635e+02, -3.7606156e+01); + expectedForces[371] = Vec3( 3.0873674e+02, 5.9974800e+02, 4.2207331e+02); + expectedForces[372] = Vec3( -3.8828932e+02, -2.1491002e+02, 1.5266506e+03); + expectedForces[373] = Vec3( 4.4495676e+02, 6.4708482e+02, -9.2222368e+02); + expectedForces[374] = Vec3( -4.8420767e+01, -4.3781484e+02, -5.0107314e+02); + expectedForces[375] = Vec3( 5.7593719e+02, -1.8140066e+03, -4.0189721e+02); + expectedForces[376] = Vec3( -5.1276233e+02, 6.6981030e+02, 3.9050744e+02); + expectedForces[377] = Vec3( 4.0809391e+02, 1.1596412e+03, -4.1325341e+02); + expectedForces[378] = Vec3( 1.4975560e+03, 1.7852942e+02, -7.6514466e+02); + expectedForces[379] = Vec3( -2.2890988e+02, 2.6128742e+02, 3.8545036e+02); + expectedForces[380] = Vec3( -3.8899762e+02, -2.5609958e+02, 2.0655882e+02); + expectedForces[381] = Vec3( -1.9500869e+02, -1.0947633e+03, -9.1786660e+02); + expectedForces[382] = Vec3( 8.6146884e+02, 2.5767444e+02, 3.6801549e+02); + expectedForces[383] = Vec3( -2.0008562e+02, 2.1549793e+02, 2.5175877e+02); + expectedForces[384] = Vec3( -5.6491749e+02, 5.4714989e+02, 3.1934114e+02); + expectedForces[385] = Vec3( 1.7665111e+02, -4.5297277e+02, 2.2387580e+02); + expectedForces[386] = Vec3( 6.2697664e+02, 1.1271358e+02, 2.9498078e+00); + expectedForces[387] = Vec3( -2.1918090e+03, -7.8914005e+01, 1.0632280e+03); + expectedForces[388] = Vec3( 7.5750278e+02, -5.0217666e+02, -1.3057335e+02); + expectedForces[389] = Vec3( 1.0621096e+03, 1.6022661e+01, -1.1645539e+03); + expectedForces[390] = Vec3( -4.7808938e+02, -1.2425496e+03, -1.5543074e+02); + expectedForces[391] = Vec3( -3.4676860e+02, 8.5391303e+02, 3.5351618e+01); + expectedForces[392] = Vec3( 5.4017203e+02, 8.6467815e+01, 1.1898140e+02); + expectedForces[393] = Vec3( -1.8873828e+01, 2.2133074e+02, -1.3378739e+03); + expectedForces[394] = Vec3( 7.5888012e+01, -1.6517743e+01, 1.1817186e+02); + expectedForces[395] = Vec3( 1.1912944e+02, -1.6083226e+02, 7.8733940e+02); + expectedForces[396] = Vec3( -1.2400005e+03, -3.9434827e+02, 1.4071802e+02); + expectedForces[397] = Vec3( 9.6249284e+02, 1.1394516e+02, -3.4977717e+02); + expectedForces[398] = Vec3( 2.4187486e+02, 1.3373651e+02, 6.5894105e+01); + expectedForces[399] = Vec3( 8.8628445e+02, 7.8083892e+01, -1.0288922e+03); + expectedForces[400] = Vec3( -9.4613057e+02, -1.9076053e+02, 6.7506442e+02); + expectedForces[401] = Vec3( -6.2746897e+02, 2.9376858e+02, 9.2767458e+02); + expectedForces[402] = Vec3( 5.5409175e+01, -1.2583442e+03, 7.1728490e+02); + expectedForces[403] = Vec3( -2.9076856e+02, 7.5539656e+02, 7.0121763e+00); + expectedForces[404] = Vec3( 2.6220897e+02, -9.5606102e+01, -7.7725998e+02); + expectedForces[405] = Vec3( -8.6582014e+02, 9.5597761e+02, 1.5941783e+02); + expectedForces[406] = Vec3( -1.6910265e+02, -7.2646192e+02, -3.5476587e+02); + expectedForces[407] = Vec3( 9.7629076e+02, -8.3969437e+01, 2.5523637e+02); + expectedForces[408] = Vec3( -4.9553396e+01, 6.3557270e+02, -7.5908312e+02); + expectedForces[409] = Vec3( 3.3210227e+01, 1.5198340e+02, 7.0322192e+02); + expectedForces[410] = Vec3( -2.6532687e+01, -4.1589199e+02, 4.2771258e+02); + expectedForces[411] = Vec3( 1.1412630e+03, -2.7366656e+02, 9.8419548e+02); + expectedForces[412] = Vec3( -3.7239786e+02, 7.2244667e+01, -9.9502150e+02); + expectedForces[413] = Vec3( -4.6476941e+02, -6.1433607e+01, -2.5459288e+02); + expectedForces[414] = Vec3( 9.7028883e+02, 5.5981848e+02, 8.4425262e+02); + expectedForces[415] = Vec3( 7.2811577e+01, 2.2872709e+02, -1.3822700e+03); + expectedForces[416] = Vec3( -1.0105821e+03, -2.8444698e+02, -7.2506392e+02); + expectedForces[417] = Vec3( 1.0027865e+03, 6.0924816e+02, -5.7818592e+01); + expectedForces[418] = Vec3( -3.4173955e+02, -1.1932310e+02, -2.9495449e+01); + expectedForces[419] = Vec3( -2.7281265e+02, -1.8869212e+02, 1.9643932e+02); + expectedForces[420] = Vec3( -7.4036328e+02, -4.8733524e+02, 1.5862094e+03); + expectedForces[421] = Vec3( 5.6387864e+02, 3.0991659e+02, -8.6746725e+02); + expectedForces[422] = Vec3( 6.2954421e-01, 4.9665567e+02, -1.0114913e+03); + expectedForces[423] = Vec3( 8.9668630e+02, -1.0121499e+03, -1.1520006e+03); + expectedForces[424] = Vec3( -2.5699741e+02, 3.3243520e+02, 7.6038873e+02); + expectedForces[425] = Vec3( -1.2755484e+03, -2.7786159e+01, 3.0900583e+02); + expectedForces[426] = Vec3( -1.2587339e+03, -8.6851333e+02, 1.6295957e+02); + expectedForces[427] = Vec3( 6.4923970e+02, 4.4600015e+02, 3.3033348e+02); + expectedForces[428] = Vec3( 5.8905637e+02, -1.1589062e+02, -1.8168184e+02); + expectedForces[429] = Vec3( -1.1223714e+03, 3.0322406e+01, 8.7272053e+02); + expectedForces[430] = Vec3( 3.0982625e+02, 3.1418220e+02, -3.9301742e+02); + expectedForces[431] = Vec3( 2.4213933e+02, -7.2382572e+02, -1.0155346e+03); + expectedForces[432] = Vec3( 1.1479692e+03, -1.6837721e+03, 1.0545407e+02); + expectedForces[433] = Vec3( -8.2496264e+02, 6.0540594e+02, 1.3979931e+02); + expectedForces[434] = Vec3( -6.8171514e+02, 4.0392791e+02, -3.4712316e+02); + expectedForces[435] = Vec3( -1.5568889e+02, -1.4652975e+03, 5.1518148e+01); + expectedForces[436] = Vec3( 5.6573856e+02, 3.5494119e+02, -3.3796345e+02); + expectedForces[437] = Vec3( -1.3938679e+02, 4.2296152e+02, -2.0539863e+02); + expectedForces[438] = Vec3( 8.9203493e+01, 2.8764597e+02, -7.3273496e+02); + expectedForces[439] = Vec3( 4.3114292e+02, 9.4778082e+01, 1.8894761e+02); + expectedForces[440] = Vec3( -2.2798193e+01, -4.5460891e+01, 9.8310963e+01); + expectedForces[441] = Vec3( -2.1793579e+02, -1.0807542e+03, -2.3470465e+01); + expectedForces[442] = Vec3( 1.3881360e+02, 3.9806903e+02, 4.1089741e+01); + expectedForces[443] = Vec3( -4.5604974e+02, 4.8515999e+02, -6.6025174e+02); + expectedForces[444] = Vec3( 3.6437700e+02, -8.1622511e+02, -9.6454258e+02); + expectedForces[445] = Vec3( 3.1998690e+02, -3.3342314e+02, 1.2441763e+03); + expectedForces[446] = Vec3( 3.0822409e+01, 2.0596612e+02, 2.0937122e+02); + expectedForces[447] = Vec3( -8.4938718e+02, -1.1366483e+03, -1.3638049e+02); + expectedForces[448] = Vec3( -5.5232451e+01, 4.7335097e+02, -5.4433565e+02); + expectedForces[449] = Vec3( 6.5928852e+02, 1.7488804e+02, 6.7879378e+02); + expectedForces[450] = Vec3( -9.4572079e+02, 1.9162420e+02, 4.7935043e+02); + expectedForces[451] = Vec3( 2.5029547e+02, 3.6606767e+01, -9.3423713e+01); + expectedForces[452] = Vec3( 1.6543841e+02, -1.1892943e+02, -5.8737050e+02); + expectedForces[453] = Vec3( -9.8495219e+02, -1.6882428e+03, -4.0576035e+02); + expectedForces[454] = Vec3( 7.9182557e+02, 5.3997699e+02, 3.3231603e+02); + expectedForces[455] = Vec3( 1.8277090e+01, 1.4623150e+03, -9.4985721e+01); + expectedForces[456] = Vec3( -1.0471948e+03, 4.6746395e+02, -1.5020000e+03); + expectedForces[457] = Vec3( 7.2055316e+02, -5.4467216e+02, 4.0459421e+02); + expectedForces[458] = Vec3( 7.5475531e+01, 4.9532870e+02, 1.3002474e+03); + expectedForces[459] = Vec3( 6.3589773e+02, -2.1402397e+02, -1.4147509e+03); + expectedForces[460] = Vec3( 2.8391861e+02, -8.0142885e+01, 5.6445225e+02); + expectedForces[461] = Vec3( -8.2442674e+02, 5.3520687e+02, 1.1406667e+03); + expectedForces[462] = Vec3( -5.7988771e+02, -3.3512887e+02, 4.5461752e+02); + expectedForces[463] = Vec3( 4.5746059e+02, 3.1029926e+02, -5.0060176e+02); + expectedForces[464] = Vec3( 7.7747136e+02, 4.2131732e+02, 5.5836239e+02); + expectedForces[465] = Vec3( -1.2315491e+03, 9.4066088e+02, 9.6145313e+02); + expectedForces[466] = Vec3( 7.9043841e+02, -2.2172613e+02, -2.6508587e+02); + expectedForces[467] = Vec3( 7.8197894e+02, -3.1383822e+02, 2.5444013e+02); + expectedForces[468] = Vec3( -7.1139498e+01, -7.1203189e+01, -4.6845544e+02); + expectedForces[469] = Vec3( -8.9774100e+01, 1.4389287e+02, 9.8957451e+01); + expectedForces[470] = Vec3( 3.0397922e+02, -2.8247850e+01, 4.4896034e+02); + expectedForces[471] = Vec3( -9.7808367e+02, 1.0170553e+03, 8.1594649e+02); + expectedForces[472] = Vec3( 1.8933676e+02, -8.8053046e+02, 6.8784042e+01); + expectedForces[473] = Vec3( 5.1636668e+02, 1.2970985e+02, -8.9380858e+02); + expectedForces[474] = Vec3( -5.8549608e+02, -1.8351156e+02, -5.8043066e+02); + expectedForces[475] = Vec3( 2.7877663e+02, -3.6576715e+02, 3.5497095e+02); + expectedForces[476] = Vec3( 3.0642370e+02, 5.3438407e+02, 1.9409584e+02); + expectedForces[477] = Vec3( -4.8523805e+02, 1.2253320e+03, 9.6414379e+02); + expectedForces[478] = Vec3( -1.5213013e+02, -2.0017205e+02, -6.6602643e+02); + expectedForces[479] = Vec3( 4.6435225e+02, -4.1945066e+02, -8.6774270e+01); + expectedForces[480] = Vec3( 2.4946889e+02, -1.0456281e+03, 4.7404434e+02); + expectedForces[481] = Vec3( -3.0813505e+01, 2.8598938e+02, 7.7374350e+01); + expectedForces[482] = Vec3( -2.4538851e+02, 3.8306987e+02, -5.0235520e+02); + expectedForces[483] = Vec3( 4.0348805e+01, 1.3050360e+03, -6.8725580e+02); + expectedForces[484] = Vec3( -1.1095514e+02, -2.7711572e+02, 2.6929959e+02); + expectedForces[485] = Vec3( -6.8071081e+01, -3.4398150e+02, 2.5209743e+02); + expectedForces[486] = Vec3( 2.1534786e+03, 1.3249493e+01, 7.4171165e+01); + expectedForces[487] = Vec3( -7.2618755e+02, -3.2914219e+02, 2.5917332e+02); + expectedForces[488] = Vec3( -1.0231949e+03, 7.2426062e+02, 1.9111862e+02); + expectedForces[489] = Vec3( 1.1408866e+03, 6.7858353e+02, -2.1410916e+02); + expectedForces[490] = Vec3( -4.5559047e+02, -1.3597950e+02, -3.2284091e+02); + expectedForces[491] = Vec3( -8.5558133e+02, -7.1748324e+01, 5.3332261e+02); + expectedForces[492] = Vec3( -7.1393886e+02, -1.1275222e+03, -6.2147584e+02); + expectedForces[493] = Vec3( 4.4029614e+02, 1.0518224e+02, 4.6519788e+02); + expectedForces[494] = Vec3( -3.5770378e+02, 1.0311834e+03, 2.2141802e+02); + expectedForces[495] = Vec3( -2.6023787e+02, 1.0070248e+03, -1.1113552e+03); + expectedForces[496] = Vec3( -3.4950242e+02, 2.8418846e+01, 1.2865161e+03); + expectedForces[497] = Vec3( 1.5030225e+02, -7.7257505e+02, 8.7232628e+02); + expectedForces[498] = Vec3( -1.7416695e+02, 9.9945569e+02, -1.6742483e+02); + expectedForces[499] = Vec3( 2.0837481e+02, -1.9388709e+02, 9.7409815e+01); + expectedForces[500] = Vec3( -1.0129845e+02, -6.8652976e+02, 8.4930186e+02); + expectedForces[501] = Vec3( 1.2276099e+03, 1.6531986e+02, 3.6342506e+02); + expectedForces[502] = Vec3( -1.9998077e+02, -2.6164759e+02, -1.6601933e+02); + expectedForces[503] = Vec3( -4.0356327e+02, 4.0549152e+02, 2.9710052e+02); + expectedForces[504] = Vec3( -7.3045150e+02, -1.6677706e+03, -9.8671765e+02); + expectedForces[505] = Vec3( -2.1441879e+02, 1.4962605e+03, 5.6350856e+02); + expectedForces[506] = Vec3( 7.1102593e+02, 5.9407971e+02, 9.5452239e+02); + expectedForces[507] = Vec3( 3.2291041e+02, 1.3943261e+03, -1.8477432e+03); + expectedForces[508] = Vec3( -1.7778104e+02, 2.8034575e+02, 1.1385089e+03); + expectedForces[509] = Vec3( -2.4943297e+02, -9.0965773e+02, 5.2737490e+02); + expectedForces[510] = Vec3( -3.8318508e+02, 1.3999092e+03, -5.9960180e+02); + expectedForces[511] = Vec3( 2.6930065e+01, -3.6603454e+02, 1.0460530e+03); + expectedForces[512] = Vec3( -1.8964668e+02, -1.1663184e+03, -2.8438291e+02); + expectedForces[513] = Vec3( -9.4679273e+02, 8.7408257e+01, -2.5740702e+02); + expectedForces[514] = Vec3( 1.6558849e+02, 3.3561310e+02, 3.8532718e+02); + expectedForces[515] = Vec3( 4.0403504e+02, -8.5545173e+02, 4.0647038e+02); + expectedForces[516] = Vec3( 8.3825526e+02, 5.0343638e+01, -3.9171626e+02); + expectedForces[517] = Vec3( -4.0069871e+02, -6.4140295e+02, 7.5218861e+01); + expectedForces[518] = Vec3( -6.5213072e+02, 4.1689581e+02, -8.9280241e+01); + expectedForces[519] = Vec3( 4.0832996e+02, -3.4272605e+02, -9.2740030e+02); + expectedForces[520] = Vec3( -2.1128040e+01, -7.3467005e+02, 6.5449252e+02); + expectedForces[521] = Vec3( -2.8042421e+02, 3.3193211e+02, 5.1272473e+02); + expectedForces[522] = Vec3( -1.2057322e+03, 3.3276609e+02, 6.8838073e+02); + expectedForces[523] = Vec3( 8.9270663e+02, 1.3914748e+02, -8.7213182e+02); + expectedForces[524] = Vec3( 8.8063936e+02, -2.4952564e+02, -8.3942753e+01); + expectedForces[525] = Vec3( 3.6527919e+02, 3.3758036e+02, -1.3449147e+03); + expectedForces[526] = Vec3( 7.1836993e+01, -3.9380031e+01, 4.7169292e+02); + expectedForces[527] = Vec3( -7.2114939e+01, -1.3679457e+02, 3.9080695e+02); + expectedForces[528] = Vec3( 1.1465645e+02, -4.4994719e+02, -3.4180224e+02); + expectedForces[529] = Vec3( -6.0950292e+01, 4.2825716e+02, -1.4233246e+02); + expectedForces[530] = Vec3( -1.9112828e+02, -2.8511065e+00, 2.6894050e+02); + expectedForces[531] = Vec3( 4.4955085e+02, 2.0459389e+02, 8.9486972e+02); + expectedForces[532] = Vec3( 6.6339624e+01, -4.2734850e+01, -4.8004048e+02); + expectedForces[533] = Vec3( -5.0521801e+02, -1.6330265e+02, -6.2374206e+02); + expectedForces[534] = Vec3( -1.1019306e+03, -4.5760347e+02, 4.6134602e+01); + expectedForces[535] = Vec3( 4.9278700e+02, 8.0495847e+02, -5.7470233e+01); + expectedForces[536] = Vec3( 9.9361557e+02, -2.4453172e+02, -3.7696369e+02); + expectedForces[537] = Vec3( -1.1168499e+03, -2.1108925e+02, -4.1233970e+02); + expectedForces[538] = Vec3( 5.6559058e+02, -2.8153614e+02, 3.0539700e+02); + expectedForces[539] = Vec3( 4.0805303e+02, 2.8796083e+02, -3.0009135e+01); + expectedForces[540] = Vec3( -8.5249075e+02, -1.0560038e+03, -6.5111795e+02); + expectedForces[541] = Vec3( 8.4653565e+02, 2.0615416e+02, -1.5085906e+02); + expectedForces[542] = Vec3( -2.8200251e+02, 6.6950966e+02, 5.9661450e+02); + expectedForces[543] = Vec3( -9.3339994e+01, 8.7084190e+02, -7.8375352e+02); + expectedForces[544] = Vec3( 1.4187243e+02, 1.2829809e+02, 8.0626841e+02); + expectedForces[545] = Vec3( 1.5403073e+02, -4.5932125e+02, -8.3051878e+00); + expectedForces[546] = Vec3( 1.3919197e+03, 5.4728737e+02, -1.0548033e+03); + expectedForces[547] = Vec3( -2.7215065e+02, 1.5112718e+02, 6.7366542e+02); + expectedForces[548] = Vec3( -7.8677637e+02, -2.6895175e+02, 4.3374996e+02); + expectedForces[549] = Vec3( 6.6014864e+02, -1.1474704e+03, -3.7199889e+02); + expectedForces[550] = Vec3( -5.8741315e+02, 2.6286109e+02, 1.9036264e+02); + expectedForces[551] = Vec3( 1.4325969e+02, 7.8928381e+02, 3.6304214e+02); + expectedForces[552] = Vec3( -9.6661866e+02, -1.0462801e+03, -6.3261994e+02); + expectedForces[553] = Vec3( 5.5171916e+02, 2.8672800e+02, 2.7240662e+02); + expectedForces[554] = Vec3( 1.1625052e+03, 7.7864110e+02, -5.2588322e+02); + expectedForces[555] = Vec3( 1.7042269e+03, -5.8973225e+02, 1.4814500e+02); + expectedForces[556] = Vec3( -7.7324022e+02, 2.9167426e+02, -1.0262563e+02); + expectedForces[557] = Vec3( -5.4655014e+02, -8.4339654e+01, 9.7375629e+02); + expectedForces[558] = Vec3( -6.9618127e+02, -1.6878530e+02, 7.1078501e+02); + expectedForces[559] = Vec3( 6.9623995e+02, -3.7038954e+01, 2.2671528e+02); + expectedForces[560] = Vec3( -7.1025694e+01, -1.8643963e+02, -8.0181026e+02); + expectedForces[561] = Vec3( -1.4598467e+02, 1.7170707e+03, -4.3305456e+02); + expectedForces[562] = Vec3( 7.9582463e+02, -5.9551245e+02, 8.3485625e+01); + expectedForces[563] = Vec3( -4.6812643e+02, -3.4598874e+02, -3.6753356e+01); + expectedForces[564] = Vec3( -1.8586268e+02, 3.1377143e+02, -1.6616022e+03); + expectedForces[565] = Vec3( 7.4400496e+02, 5.5058789e+02, 7.5374599e+02); + expectedForces[566] = Vec3( -6.3347529e+02, -3.1407006e+02, 8.2964691e+02); + expectedForces[567] = Vec3( -4.2499528e+02, 9.4575975e+02, -6.6700103e+02); + expectedForces[568] = Vec3( -9.2637696e+02, -6.6301622e+02, 3.9913705e+02); + expectedForces[569] = Vec3( 5.0588430e+02, -8.1942697e+01, 4.2128365e+02); + expectedForces[570] = Vec3( 2.7165158e+02, 2.7387902e+02, 1.0850277e+03); + expectedForces[571] = Vec3( -6.8391471e+00, -1.2886307e+02, -5.3501450e+02); + expectedForces[572] = Vec3( -2.9936240e+02, -2.2085475e+02, -6.9670281e+01); + expectedForces[573] = Vec3( 1.6853422e+02, 4.8410887e+02, 1.0517406e+03); + expectedForces[574] = Vec3( -4.9287521e+02, 1.6557733e+01, -3.4008916e+02); + expectedForces[575] = Vec3( 1.1132397e+02, -9.8734894e+02, -1.1154151e+02); + expectedForces[576] = Vec3( 3.8645582e+02, 4.3709361e+02, 1.4861132e+03); + expectedForces[577] = Vec3( -1.0169967e+03, -3.5279110e+02, -5.4860861e+02); + expectedForces[578] = Vec3( 2.8875246e+02, 5.3726711e+01, -5.9395936e+02); + expectedForces[579] = Vec3( 1.5169994e+03, 8.7535209e+01, 1.0103159e+03); + expectedForces[580] = Vec3( -1.9439968e+02, -7.9639200e+02, -1.0439069e+03); + expectedForces[581] = Vec3( -8.7374025e+02, 2.0597360e+02, 1.0218319e+02); + expectedForces[582] = Vec3( 6.4275846e+02, -6.2671529e+02, 8.9274592e+02); + expectedForces[583] = Vec3( -5.4449356e+01, 7.2615928e+02, -9.1355057e+02); + expectedForces[584] = Vec3( -2.7242606e+02, 3.9376960e+02, -4.7692581e+01); + expectedForces[585] = Vec3( 2.6578654e+02, -6.7385441e+02, -1.5306127e+03); + expectedForces[586] = Vec3( 5.1049761e+02, 7.3430855e+02, 6.1178168e+02); + expectedForces[587] = Vec3( -3.3593193e+02, 3.5079666e+01, 9.7444298e+02); + expectedForces[588] = Vec3( -7.8227654e+01, -1.1050481e+03, 1.4161574e+03); + expectedForces[589] = Vec3( -7.6753407e+02, 9.7291633e+02, 1.9943116e+02); + expectedForces[590] = Vec3( 2.9274184e+02, -2.5706985e+01, -5.8944290e+02); + expectedForces[591] = Vec3( -1.2502829e+03, 2.2304820e+02, -8.8573767e+02); + expectedForces[592] = Vec3( 1.2218682e+02, -8.2110835e+02, 3.4276058e+02); + expectedForces[593] = Vec3( 8.9529566e+02, -1.8417573e+02, 8.4717919e+02); + expectedForces[594] = Vec3( -4.6475772e+01, -1.5493620e+03, 4.8004365e+02); + expectedForces[595] = Vec3( 6.7104033e+02, 4.7267915e+02, -6.2630817e+02); + expectedForces[596] = Vec3( -2.2771561e+02, 2.7463551e+02, -2.9704610e+00); + expectedForces[597] = Vec3( 1.7757815e+02, -1.8906761e+03, -1.6656886e+02); + expectedForces[598] = Vec3( -7.4745588e+01, 1.0353962e+03, 4.2924498e+02); + expectedForces[599] = Vec3( -5.5648197e+02, 7.7838572e+02, -4.1677346e+02); + expectedForces[600] = Vec3( -5.2972489e+02, 1.1967117e+02, 1.0565388e+03); + expectedForces[601] = Vec3( 7.8379665e+02, -4.1803420e+02, 2.0308387e+02); + expectedForces[602] = Vec3( 1.2705528e+02, 1.1663435e+02, -7.6514830e+02); + expectedForces[603] = Vec3( -1.5203094e+03, -8.5825144e+01, -2.3039380e+02); + expectedForces[604] = Vec3( 5.2063739e+02, -1.7259834e+02, -2.9854160e+01); + expectedForces[605] = Vec3( 4.7448961e+02, 2.8282389e+02, 3.4257463e+01); + expectedForces[606] = Vec3( 1.4519531e+03, -1.2031444e+03, -6.7084095e+02); + expectedForces[607] = Vec3( -7.5308994e+02, -3.2117501e+02, 5.7700017e+02); + expectedForces[608] = Vec3( -1.7643179e+02, 8.5655779e+02, -2.6285482e+02); + expectedForces[609] = Vec3( -1.3868959e+03, -1.6195505e+01, -1.3783528e+03); + expectedForces[610] = Vec3( 2.8034476e+02, -4.2360778e+02, 4.5904202e+02); + expectedForces[611] = Vec3( 1.0938532e+03, 6.2455629e+02, -1.0108636e+02); + expectedForces[612] = Vec3( 9.1439974e+01, -7.2813810e+02, 1.0197075e+03); + expectedForces[613] = Vec3( 1.4048294e+02, 2.5667744e+02, -5.1914694e+02); + expectedForces[614] = Vec3( -2.5604629e+01, 2.9915218e+01, -5.1582702e+02); + expectedForces[615] = Vec3( 2.0331673e+02, 1.5538650e+02, -1.1836865e+03); + expectedForces[616] = Vec3( -2.3788957e+02, -1.1872269e+02, 9.7052698e+02); + expectedForces[617] = Vec3( -3.2419551e+01, -1.8828745e+02, 4.3037423e+02); + expectedForces[618] = Vec3( -4.8585762e+02, 1.4114027e+02, 1.6021114e+02); + expectedForces[619] = Vec3( 2.8744134e+02, -5.7197623e+02, -1.8323508e+02); + expectedForces[620] = Vec3( 2.3652930e+02, -1.5448350e+01, 2.1721186e+01); + expectedForces[621] = Vec3( 1.1684581e+03, 2.2790484e+02, 2.7798348e+02); + expectedForces[622] = Vec3( -4.6823976e+02, -6.1804544e+02, 2.7193441e+02); + expectedForces[623] = Vec3( -5.8173089e+02, 4.4573870e+02, -6.0699430e+02); + expectedForces[624] = Vec3( 7.9759250e+02, 1.8480473e+03, -5.1434277e+02); + expectedForces[625] = Vec3( -1.0945975e+03, -6.0402685e+02, 1.5843017e+02); + expectedForces[626] = Vec3( 1.2334392e+02, -9.5602838e+02, 7.8137824e+02); + expectedForces[627] = Vec3( -8.5863208e+02, -5.7413454e+02, 1.7014217e+02); + expectedForces[628] = Vec3( -1.2232569e+02, 6.0505774e+02, -1.6806693e+02); + expectedForces[629] = Vec3( 6.1488135e+02, 4.1603705e+02, 2.1121948e+02); + expectedForces[630] = Vec3( 2.1858899e+02, 1.2961013e+03, 4.8534041e+02); + expectedForces[631] = Vec3( 2.1292701e+02, -4.1049165e+02, 3.9057142e+00); + expectedForces[632] = Vec3( -6.3342469e+02, -8.7529004e+02, 6.1928550e+01); + expectedForces[633] = Vec3( -7.3207079e+02, -1.3874807e+03, 8.6303032e+02); + expectedForces[634] = Vec3( 6.6660351e+02, 9.5813895e+02, -1.4555416e+02); + expectedForces[635] = Vec3( 4.1800653e+02, 2.4677420e+02, -1.1424272e+03); + expectedForces[636] = Vec3( 8.3570430e+02, -1.5342969e+03, -1.2510269e+03); + expectedForces[637] = Vec3( -3.0635229e+02, 1.2465088e+03, -1.9679529e+01); + expectedForces[638] = Vec3( -6.5317178e+02, -1.6432929e+02, 9.2427724e+02); + expectedForces[639] = Vec3( 1.5665680e+03, 9.8040004e+01, 1.0786497e+02); + expectedForces[640] = Vec3( -4.6590380e+02, -3.7603795e+02, -9.4955273e+02); + expectedForces[641] = Vec3( -8.7572108e+02, 5.1750570e+02, -1.2268062e+02); + expectedForces[642] = Vec3( 1.1575067e+03, -2.2857204e+02, -2.3816900e+02); + expectedForces[643] = Vec3( -2.6229644e+02, 3.1069110e+02, -1.2098536e+02); + expectedForces[644] = Vec3( -1.8195659e+02, -3.8984698e+02, 6.4622752e+02); + expectedForces[645] = Vec3( 1.0756277e+03, 2.7459106e+01, 1.0850508e+03); + expectedForces[646] = Vec3( -6.4620310e+02, 2.5885783e+02, -2.0567224e+02); + expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } @@ -2659,7 +2659,7 @@ static void testParticleInducedDipoles() { // test computation of system multipole moments -static void testSystemMultipoleMoments( ) { +static void testSystemMultipoleMoments() { std::string testName = "testSystemMultipoleMoments"; @@ -2673,9 +2673,9 @@ static void testSystemMultipoleMoments( ) { std::vector< Vec3 > inputGrid; std::vector< double > outputGridPotential; - setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, - cutoff, inputPmeGridDimension, testName, - forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential ); + setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + cutoff, inputPmeGridDimension, testName, + forces, energy, outputMultipoleMoments, inputGrid, outputGridPotential); std::vector tinkerMoments(4); @@ -2694,14 +2694,14 @@ static void testSystemMultipoleMoments( ) { // tinkerMoments[12] = 4.3292490e-02; double tolerance = 1.0e-04; - for( unsigned int ii = 0; ii < tinkerMoments.size(); ii++ ){ + for (unsigned int ii = 0; ii < tinkerMoments.size(); ii++) { double difference; - if( fabs( tinkerMoments[ii] ) > 0.0 ){ - difference = fabs( outputMultipoleMoments[ii] - tinkerMoments[ii] )/fabs( tinkerMoments[ii] ); + if (fabs(tinkerMoments[ii]) > 0.0) { + difference = fabs(outputMultipoleMoments[ii] - tinkerMoments[ii])/fabs(tinkerMoments[ii]); } else { - difference = fabs( outputMultipoleMoments[ii] - tinkerMoments[ii] ); + difference = fabs(outputMultipoleMoments[ii] - tinkerMoments[ii]); } - if( difference > tolerance ){ + if (difference > tolerance) { std::stringstream details; details << testName << "Multipole moment " << ii << " does not agree w/ TINKER computed moments: OpenMM=" << outputMultipoleMoments[ii]; details << " TINKER=" << tinkerMoments[ii] << " difference=" << difference; @@ -2714,7 +2714,7 @@ static void testSystemMultipoleMoments( ) { // test computation of multipole potential on a grid -static void testMultipoleGridPotential( ) { +static void testMultipoleGridPotential() { std::string testName = "testMultipoleGridPotential"; @@ -2730,40 +2730,40 @@ static void testMultipoleGridPotential( ) { int gridSize = 27; std::vector inputGrid(gridSize); - inputGrid[0] = Vec3( -1.0318535e+00, -1.0224502e+00, -1.0202836e+00); - inputGrid[1] = Vec3( -1.0318535e+00, -1.0224502e+00, -3.4032700e-02); - inputGrid[2] = Vec3( -1.0318535e+00, -1.0224502e+00, 9.5221820e-01); - inputGrid[3] = Vec3( -1.0318535e+00, -3.0961200e-02, -1.0202836e+00); - inputGrid[4] = Vec3( -1.0318535e+00, -3.0961200e-02, -3.4032700e-02); - inputGrid[5] = Vec3( -1.0318535e+00, -3.0961200e-02, 9.5221820e-01); - inputGrid[6] = Vec3( -1.0318535e+00, 9.6052780e-01, -1.0202836e+00); - inputGrid[7] = Vec3( -1.0318535e+00, 9.6052780e-01, -3.4032700e-02); - inputGrid[8] = Vec3( -1.0318535e+00, 9.6052780e-01, 9.5221820e-01); - inputGrid[9] = Vec3( -3.3969000e-02, -1.0224502e+00, -1.0202836e+00); - inputGrid[10] = Vec3( -3.3969000e-02, -1.0224502e+00, -3.4032700e-02); - inputGrid[11] = Vec3( -3.3969000e-02, -1.0224502e+00, 9.5221820e-01); - inputGrid[12] = Vec3( -3.3969000e-02, -3.0961200e-02, -1.0202836e+00); - inputGrid[13] = Vec3( -3.3969000e-02, -3.0961200e-02, -3.4032700e-02); - inputGrid[14] = Vec3( -3.3969000e-02, -3.0961200e-02, 9.5221820e-01); - inputGrid[15] = Vec3( -3.3969000e-02, 9.6052780e-01, -1.0202836e+00); - inputGrid[16] = Vec3( -3.3969000e-02, 9.6052780e-01, -3.4032700e-02); - inputGrid[17] = Vec3( -3.3969000e-02, 9.6052780e-01, 9.5221820e-01); - inputGrid[18] = Vec3( 9.6391550e-01, -1.0224502e+00, -1.0202836e+00); - inputGrid[19] = Vec3( 9.6391550e-01, -1.0224502e+00, -3.4032700e-02); - inputGrid[20] = Vec3( 9.6391550e-01, -1.0224502e+00, 9.5221820e-01); - inputGrid[21] = Vec3( 9.6391550e-01, -3.0961200e-02, -1.0202836e+00); - inputGrid[22] = Vec3( 9.6391550e-01, -3.0961200e-02, -3.4032700e-02); - inputGrid[23] = Vec3( 9.6391550e-01, -3.0961200e-02, 9.5221820e-01); - inputGrid[24] = Vec3( 9.6391550e-01, 9.6052780e-01, -1.0202836e+00); - inputGrid[25] = Vec3( 9.6391550e-01, 9.6052780e-01, -3.4032700e-02); - inputGrid[26] = Vec3( 9.6391550e-01, 9.6052780e-01, 9.5221820e-01); + inputGrid[0] = Vec3(-1.0318535e+00, -1.0224502e+00, -1.0202836e+00); + inputGrid[1] = Vec3(-1.0318535e+00, -1.0224502e+00, -3.4032700e-02); + inputGrid[2] = Vec3(-1.0318535e+00, -1.0224502e+00, 9.5221820e-01); + inputGrid[3] = Vec3(-1.0318535e+00, -3.0961200e-02, -1.0202836e+00); + inputGrid[4] = Vec3(-1.0318535e+00, -3.0961200e-02, -3.4032700e-02); + inputGrid[5] = Vec3(-1.0318535e+00, -3.0961200e-02, 9.5221820e-01); + inputGrid[6] = Vec3(-1.0318535e+00, 9.6052780e-01, -1.0202836e+00); + inputGrid[7] = Vec3(-1.0318535e+00, 9.6052780e-01, -3.4032700e-02); + inputGrid[8] = Vec3(-1.0318535e+00, 9.6052780e-01, 9.5221820e-01); + inputGrid[9] = Vec3(-3.3969000e-02, -1.0224502e+00, -1.0202836e+00); + inputGrid[10] = Vec3(-3.3969000e-02, -1.0224502e+00, -3.4032700e-02); + inputGrid[11] = Vec3(-3.3969000e-02, -1.0224502e+00, 9.5221820e-01); + inputGrid[12] = Vec3(-3.3969000e-02, -3.0961200e-02, -1.0202836e+00); + inputGrid[13] = Vec3(-3.3969000e-02, -3.0961200e-02, -3.4032700e-02); + inputGrid[14] = Vec3(-3.3969000e-02, -3.0961200e-02, 9.5221820e-01); + inputGrid[15] = Vec3(-3.3969000e-02, 9.6052780e-01, -1.0202836e+00); + inputGrid[16] = Vec3(-3.3969000e-02, 9.6052780e-01, -3.4032700e-02); + inputGrid[17] = Vec3(-3.3969000e-02, 9.6052780e-01, 9.5221820e-01); + inputGrid[18] = Vec3( 9.6391550e-01, -1.0224502e+00, -1.0202836e+00); + inputGrid[19] = Vec3( 9.6391550e-01, -1.0224502e+00, -3.4032700e-02); + inputGrid[20] = Vec3( 9.6391550e-01, -1.0224502e+00, 9.5221820e-01); + inputGrid[21] = Vec3( 9.6391550e-01, -3.0961200e-02, -1.0202836e+00); + inputGrid[22] = Vec3( 9.6391550e-01, -3.0961200e-02, -3.4032700e-02); + inputGrid[23] = Vec3( 9.6391550e-01, -3.0961200e-02, 9.5221820e-01); + inputGrid[24] = Vec3( 9.6391550e-01, 9.6052780e-01, -1.0202836e+00); + inputGrid[25] = Vec3( 9.6391550e-01, 9.6052780e-01, -3.4032700e-02); + inputGrid[26] = Vec3( 9.6391550e-01, 9.6052780e-01, 9.5221820e-01); std::vector outputGridPotential; std::vector< double > outputMultipoleMoments; - setupAndGetForcesEnergyMultipoleLargeWater( AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, + setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::PME, AmoebaMultipoleForce::Mutual, cutoff, inputPmeGridDimension, testName, forces, energy, - outputMultipoleMoments, inputGrid, outputGridPotential ); + outputMultipoleMoments, inputGrid, outputGridPotential); // TINKER computed grid values @@ -2798,10 +2798,9 @@ static void testMultipoleGridPotential( ) { tinkerGridPotential[26] = 1.3960144e+02; double tolerance = 4.0e-04; - for( unsigned int ii = 0; ii < gridSize; ii++ ){ - double difference = fabs( (outputGridPotential[ii] - tinkerGridPotential[ii] )/tinkerGridPotential[ii] ); - //(void) fprintf( stderr, "Grid: %2d %15.7e %15.7e %15.7e\n", ii, difference, outputGridPotential[ii], tinkerGridPotential[ii] ); - if( difference > tolerance ){ + for (unsigned int ii = 0; ii < gridSize; ii++) { + double difference = fabs((outputGridPotential[ii] - tinkerGridPotential[ii])/tinkerGridPotential[ii]); + if (difference > tolerance) { std::stringstream details; details << testName << " potential for grid point " << ii << " does not agree w/ TINKER computed value: OpenMM=" << outputGridPotential[ii]; details << " TINKER=" << tinkerGridPotential[ii] << " difference=" << difference; diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp index 687560c88..c03f2ef81 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaOutOfPlaneBendForce.cpp @@ -63,7 +63,7 @@ const double TOL = 1e-3; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -72,13 +72,13 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& positions, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& forces, double* energy ) { + std::vector& forces, double* energy) { double kAngleCubic = amoebaOutOfPlaneBendForce.getAmoebaGlobalOutOfPlaneBendCubic(); @@ -88,7 +88,7 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& int particle1, particle2, particle3, particle4; double kAngleQuadratic; - amoebaOutOfPlaneBendForce.getOutOfPlaneBendParameters(bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic ); + amoebaOutOfPlaneBendForce.getOutOfPlaneBendParameters(bondIndex, particle1, particle2, particle3, particle4, kAngleQuadratic); enum { A, B, C, D, LastAtomIndex }; enum { AB, CB, DB, AD, CD, LastDeltaIndex }; @@ -99,7 +99,7 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& // and various intermediate terms double deltaR[LastDeltaIndex][6]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AB][ii] = positions[particle1][ii] - positions[particle2][ii]; deltaR[CB][ii] = positions[particle3][ii] - positions[particle2][ii]; deltaR[DB][ii] = positions[particle4][ii] - positions[particle2][ii]; @@ -107,25 +107,25 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& deltaR[CD][ii] = positions[particle3][ii] - positions[particle4][ii]; } - double rDB2 = dotVector3( deltaR[DB], deltaR[DB] ); - double rAD2 = dotVector3( deltaR[AD], deltaR[AD] ); - double rCD2 = dotVector3( deltaR[CD], deltaR[CD] ); + double rDB2 = dotVector3(deltaR[DB], deltaR[DB]); + double rAD2 = dotVector3(deltaR[AD], deltaR[AD]); + double rCD2 = dotVector3(deltaR[CD], deltaR[CD]); double tempVector[3]; - crossProductVector3( deltaR[CB], deltaR[DB], tempVector ); - double eE = dotVector3( deltaR[AB], tempVector ); - double dot = dotVector3( deltaR[AD], deltaR[CD] ); + crossProductVector3(deltaR[CB], deltaR[DB], tempVector); + double eE = dotVector3(deltaR[AB], tempVector ); + double dot = dotVector3(deltaR[AD], deltaR[CD]); double cc = rAD2*rCD2 - dot*dot; - if( rDB2 <= 0.0 || cc == 0.0 ){ + if (rDB2 <= 0.0 || cc == 0.0) { return; } double bkk2 = rDB2 - eE*eE/cc; double cosine = sqrt(bkk2/rDB2); double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0; - } else if( cosine <= -1.0 ){ + } else if (cosine <= -1.0) { angle = PI_M; } else { angle = RADIAN*acos(cosine); @@ -143,23 +143,23 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& double dEdCos; dEdCos = dEdDt/sqrt(cc*bkk2); - if( eE > 0.0 ){ + if (eE > 0.0) { dEdCos *= -1.0; } double term = eE/cc; double dccd[LastAtomIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { dccd[A][ii] = (deltaR[AD][ii]*rCD2 - deltaR[CD][ii]*dot)*term; dccd[C][ii] = (deltaR[CD][ii]*rAD2 - deltaR[AD][ii]*dot)*term; dccd[D][ii] = -1.0*(dccd[A][ii] + dccd[C][ii]); } double deed[LastAtomIndex][3]; - crossProductVector3( deltaR[DB], deltaR[CB], deed[A] ); - crossProductVector3( deltaR[AB], deltaR[DB], deed[C] ); - crossProductVector3( deltaR[CB], deltaR[AB], deed[D] ); + crossProductVector3(deltaR[DB], deltaR[CB], deed[A]); + crossProductVector3(deltaR[AB], deltaR[DB], deed[C]); + crossProductVector3(deltaR[CB], deltaR[AB], deed[D]); term = eE/rDB2; deed[D][0] += deltaR[DB][0]*term; @@ -171,24 +171,24 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& // forces // calculate forces for atoms a, c, d - // the force for b is then -( a+ c + d) + // the force for b is then -(a+ c + d) double subForce[LastAtomIndex][3]; - for( int jj = 0; jj < LastAtomIndex; jj++ ){ + for (int jj = 0; jj < LastAtomIndex; jj++) { // A, C, D - for( int ii = 0; ii < 3; ii++ ){ - subForce[jj][ii] = dEdCos*( dccd[jj][ii] + deed[jj][ii] ); + for (int ii = 0; ii < 3; ii++) { + subForce[jj][ii] = dEdCos*(dccd[jj][ii] + deed[jj][ii]); } - if( jj == 0 )jj++; // skip B + if (jj == 0)jj++; // skip B // now compute B - if( jj == 3 ){ - for( int ii = 0; ii < 3; ii++ ){ + if (jj == 3) { + for (int ii = 0; ii < 3; ii++) { subForce[1][ii] = -1.0*(subForce[0][ii] + subForce[2][ii] + subForce[3][ii]); } } @@ -225,47 +225,47 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& return; } -static void computeAmoebaOutOfPlaneBendForces( Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - std::vector& expectedForces, double* expectedEnergy ) { +static void computeAmoebaOutOfPlaneBendForces(Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaOutOfPlaneBendForce.getNumOutOfPlaneBends(); ii++ ){ + for (int ii = 0; ii < amoebaOutOfPlaneBendForce.getNumOutOfPlaneBends(); ii++) { computeAmoebaOutOfPlaneBendForce(ii, positions, amoebaOutOfPlaneBendForce, expectedForces, expectedEnergy); } } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, - double tolerance, const std::string& idString) { +void compareWithExpectedForceAndEnergy(Context& context, AmoebaOutOfPlaneBendForce& amoebaOutOfPlaneBendForce, + double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaOutOfPlaneBendForces( context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy ); + computeAmoebaOutOfPlaneBendForces(context, amoebaOutOfPlaneBendForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } -void testOneOutOfPlaneBend( ) { +void testOneOutOfPlaneBend() { System system; int numberOfParticles = 4; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -273,27 +273,27 @@ void testOneOutOfPlaneBend( ) { AmoebaOutOfPlaneBendForce* amoebaOutOfPlaneBendForce = new AmoebaOutOfPlaneBendForce(); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07 ); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); double kOutOfPlaneBend = 0.328682196E-01; - amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend ); + amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend); system.addForce(amoebaOutOfPlaneBendForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector positions(numberOfParticles); - positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); - positions[1] = Vec3( 0.269130000E+02, 0.266390000E+02, 0.353100000E+01 ); + positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01); + positions[1] = Vec3(0.269130000E+02, 0.266390000E+02, 0.353100000E+01); - positions[2] = Vec3( 0.278860000E+02, 0.264630000E+02, 0.426300000E+01 ); - positions[3] = Vec3( 0.245568230E+02, 0.250215290E+02, 0.796852800E+01 ); + positions[2] = Vec3(0.278860000E+02, 0.264630000E+02, 0.426300000E+01); + positions[3] = Vec3(0.245568230E+02, 0.250215290E+02, 0.796852800E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); // Try changing the bend parameters and make sure it's still correct. @@ -301,21 +301,21 @@ void testOneOutOfPlaneBend( ) { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaOutOfPlaneBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); } -void testOneOutOfPlaneBend2(int setId ) { +void testOneOutOfPlaneBend2(int setId) { System system; int numberOfParticles = 4; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -323,10 +323,10 @@ void testOneOutOfPlaneBend2(int setId ) { AmoebaOutOfPlaneBendForce* amoebaOutOfPlaneBendForce = new AmoebaOutOfPlaneBendForce(); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06 ); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07 ); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); /* 285 441 442 443 444 0.328682196E-01 286 441 442 444 443 0.164493407E-01 @@ -346,103 +346,103 @@ void testOneOutOfPlaneBend2(int setId ) { */ std::map coordinates; - coordinates[440] = Vec3( 0.893800000E+01, 0.439800000E+01, 0.343100000E+01 ); - coordinates[441] = Vec3( 0.779100000E+01, 0.614600000E+01, 0.390100000E+01 ); - coordinates[442] = Vec3( 0.915400000E+01, 0.683900000E+01, 0.389400000E+01 ); - coordinates[443] = Vec3( 0.101770000E+02, 0.619000000E+01, 0.379900000E+01 ); - coordinates[444] = Vec3( 0.921000000E+01, 0.813800000E+01, 0.398600000E+01 ); - coordinates[445] = Vec3( 0.708500000E+01, 0.672900000E+01, 0.332700000E+01 ); - coordinates[446] = Vec3( 0.744300000E+01, 0.605200000E+01, 0.491900000E+01 ); - coordinates[447] = Vec3( 0.100820000E+02, 0.859300000E+01, 0.398200000E+01 ); - coordinates[448] = Vec3( 0.838000000E+01, 0.866100000E+01, 0.406000000E+01 ); + coordinates[440] = Vec3( 0.893800000E+01, 0.439800000E+01, 0.343100000E+01); + coordinates[441] = Vec3( 0.779100000E+01, 0.614600000E+01, 0.390100000E+01); + coordinates[442] = Vec3( 0.915400000E+01, 0.683900000E+01, 0.389400000E+01); + coordinates[443] = Vec3( 0.101770000E+02, 0.619000000E+01, 0.379900000E+01); + coordinates[444] = Vec3( 0.921000000E+01, 0.813800000E+01, 0.398600000E+01); + coordinates[445] = Vec3( 0.708500000E+01, 0.672900000E+01, 0.332700000E+01); + coordinates[446] = Vec3( 0.744300000E+01, 0.605200000E+01, 0.491900000E+01); + coordinates[447] = Vec3( 0.100820000E+02, 0.859300000E+01, 0.398200000E+01); + coordinates[448] = Vec3( 0.838000000E+01, 0.866100000E+01, 0.406000000E+01); double kOutOfPlaneBend = 0.328682196E-01; std::vector particleIndices; - if( setId == 1 ){ - particleIndices.push_back( 441 ); - particleIndices.push_back( 442 ); - particleIndices.push_back( 443 ); - particleIndices.push_back( 444 ); + if (setId == 1) { + particleIndices.push_back(441); + particleIndices.push_back(442); + particleIndices.push_back(443); + particleIndices.push_back(444); kOutOfPlaneBend = 0.328682196E-01; - } else if( setId == 2 ){ - particleIndices.push_back( 441 ); - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 443 ); + } else if (setId == 2) { + particleIndices.push_back(441); + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(443); kOutOfPlaneBend = 0.164493407E-01; - } else if( setId == 3 ){ - particleIndices.push_back( 443 ); - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 441 ); + } else if (setId == 3) { + particleIndices.push_back(443); + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(441); kOutOfPlaneBend = 0.636650407E-02; - } else if( setId == 4 ){ - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 447 ); - particleIndices.push_back( 448 ); + } else if (setId == 4) { + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(447); + particleIndices.push_back(448); kOutOfPlaneBend = 0.392956472E-02; - } else if( setId == 5 ){ - particleIndices.push_back( 442 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 448 ); - particleIndices.push_back( 447 ); + } else if (setId == 5) { + particleIndices.push_back(442); + particleIndices.push_back(444); + particleIndices.push_back(448); + particleIndices.push_back(447); kOutOfPlaneBend = 0.392956472E-02; - } else if( setId == 6 ){ - particleIndices.push_back( 447 ); - particleIndices.push_back( 444 ); - particleIndices.push_back( 448 ); - particleIndices.push_back( 442 ); + } else if (setId == 6) { + particleIndices.push_back(447); + particleIndices.push_back(444); + particleIndices.push_back(448); + particleIndices.push_back(442); kOutOfPlaneBend = 0.214755281E-01; } else { std::stringstream buffer; buffer << "Set id " << setId << " not recognized."; - throw OpenMMException( buffer.str() ); + throw OpenMMException(buffer.str()); } - amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend ); + amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend); system.addForce(amoebaOutOfPlaneBendForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector positions(numberOfParticles); - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - if( coordinates.find( particleIndices[ii] ) == coordinates.end() ){ + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + if (coordinates.find(particleIndices[ii]) == coordinates.end()) { std::stringstream buffer; buffer << "Coordinates " << particleIndices[ii] << " not loaded."; - throw OpenMMException( buffer.str() ); + throw OpenMMException(buffer.str()); } positions[ii] = coordinates[particleIndices[ii]]; } context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); + compareWithExpectedForceAndEnergy(context, *amoebaOutOfPlaneBendForce, TOL, "testOneOutOfPlaneBend"); static int iter = 0; static std::map totalForces; static double totalEnergy; - if( iter == 0 ){ - - totalForces[441] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[442] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[443] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[444] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[445] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[446] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[447] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[448] = Vec3( 0.0, 0.0, 0.0 ); - totalForces[449] = Vec3( 0.0, 0.0, 0.0 ); + if (iter == 0) { + + totalForces[441] = Vec3( 0.0, 0.0, 0.0); + totalForces[442] = Vec3( 0.0, 0.0, 0.0); + totalForces[443] = Vec3( 0.0, 0.0, 0.0); + totalForces[444] = Vec3( 0.0, 0.0, 0.0); + totalForces[445] = Vec3( 0.0, 0.0, 0.0); + totalForces[446] = Vec3( 0.0, 0.0, 0.0); + totalForces[447] = Vec3( 0.0, 0.0, 0.0); + totalForces[448] = Vec3( 0.0, 0.0, 0.0); + totalForces[449] = Vec3( 0.0, 0.0, 0.0); totalEnergy = 0.0; } iter++; std::vector forces; - forces.resize( numberOfParticles ); + forces.resize(numberOfParticles); double energy; - computeAmoebaOutOfPlaneBendForce( 0, positions, *amoebaOutOfPlaneBendForce, forces, &energy); + computeAmoebaOutOfPlaneBendForce(0, positions, *amoebaOutOfPlaneBendForce, forces, &energy); totalEnergy += energy; - for( unsigned int ii = 0; ii < numberOfParticles; ii++ ){ - for( unsigned int jj = 0; jj < 3; jj++ ){ + for (unsigned int ii = 0; ii < numberOfParticles; ii++) { + for (unsigned int jj = 0; jj < 3; jj++) { totalForces[particleIndices[ii]][jj] += forces[ii][jj]; } } diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp index 836423530..0d8dee5cb 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaPiTorsionForce.cpp @@ -63,7 +63,7 @@ const double TOL = 1e-5; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -72,7 +72,7 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } @@ -91,16 +91,16 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit enum { A, B, C, D, E, F, LastAtomIndex }; double d[LastAtomIndex][3]; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AD][ii] = positions[particle1][ii] - positions[particle4][ii]; deltaR[BD][ii] = positions[particle2][ii] - positions[particle4][ii]; deltaR[EC][ii] = positions[particle5][ii] - positions[particle3][ii]; deltaR[FC][ii] = positions[particle6][ii] - positions[particle3][ii]; } - crossProductVector3( deltaR[AD], deltaR[BD], deltaR[P] ); - crossProductVector3( deltaR[EC], deltaR[FC], deltaR[Q] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[AD], deltaR[BD], deltaR[P]); + crossProductVector3(deltaR[EC], deltaR[FC], deltaR[Q]); + for (int ii = 0; ii < 3; ii++) { deltaR[CP][ii] = -deltaR[P][ii]; deltaR[DC][ii] = positions[particle4][ii] - positions[particle3][ii]; deltaR[QD][ii] = deltaR[Q][ii]; @@ -108,25 +108,25 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit deltaR[P][ii] += positions[particle3][ii]; deltaR[Q][ii] += positions[particle4][ii]; } - crossProductVector3( deltaR[CP], deltaR[DC], deltaR[T] ); - crossProductVector3( deltaR[DC], deltaR[QD], deltaR[U] ); - crossProductVector3( deltaR[T], deltaR[U], deltaR[TU] ); + crossProductVector3(deltaR[CP], deltaR[DC], deltaR[T] ); + crossProductVector3(deltaR[DC], deltaR[QD], deltaR[U] ); + crossProductVector3(deltaR[T], deltaR[U], deltaR[TU]); - double rT2 = dotVector3( deltaR[T], deltaR[T] ); - double rU2 = dotVector3( deltaR[U], deltaR[U] ); - double rTrU = sqrt( rT2*rU2 ); - if( rTrU <= 0.0 ){ + double rT2 = dotVector3(deltaR[T], deltaR[T]); + double rU2 = dotVector3(deltaR[U], deltaR[U]); + double rTrU = sqrt(rT2*rU2); + if (rTrU <= 0.0) { return; } - double rDC = dotVector3( deltaR[DC], deltaR[DC] ); - rDC = sqrt( rDC ); + double rDC = dotVector3(deltaR[DC], deltaR[DC]); + rDC = sqrt(rDC); - double cosine = dotVector3( deltaR[T], deltaR[U] ); + double cosine = dotVector3(deltaR[T], deltaR[U]); cosine /= rTrU; - double sine = dotVector3( deltaR[DC], deltaR[TU] ); - sine /= ( rDC*rTrU ); + double sine = dotVector3(deltaR[DC], deltaR[TU]); + sine /= (rDC*rTrU); double cosine2 = cosine*cosine - sine*sine; double sine2 = 2.0*cosine*sine; @@ -136,37 +136,37 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit double dedphi = kTorsion*dphi2; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[DP][ii] = positions[particle4][ii] - deltaR[P][ii]; deltaR[QC][ii] = deltaR[Q][ii] - positions[particle3][ii]; } - double factorT = dedphi/( rDC*rT2 ); - double factorU = -dedphi/( rDC*rU2 ); + double factorT = dedphi/(rDC*rT2); + double factorU = -dedphi/(rDC*rU2); - crossProductVector3( deltaR[T], deltaR[DC], deltaR[dT] ); - crossProductVector3( deltaR[U], deltaR[DC], deltaR[dU] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[T], deltaR[DC], deltaR[dT] ); + crossProductVector3(deltaR[U], deltaR[DC], deltaR[dU] ); + for (int ii = 0; ii < 3; ii++) { deltaR[dT][ii] *= factorT; deltaR[dU][ii] *= factorU; } - crossProductVector3( deltaR[dT], deltaR[DC], deltaR[dP] ); - crossProductVector3( deltaR[dU], deltaR[DC], deltaR[dQ] ); + crossProductVector3(deltaR[dT], deltaR[DC], deltaR[dP] ); + crossProductVector3(deltaR[dU], deltaR[DC], deltaR[dQ] ); - crossProductVector3( deltaR[DP], deltaR[dT], deltaR[dC1] ); - crossProductVector3( deltaR[dU], deltaR[QD], deltaR[dC2] ); + crossProductVector3(deltaR[DP], deltaR[dT], deltaR[dC1] ); + crossProductVector3(deltaR[dU], deltaR[QD], deltaR[dC2] ); - crossProductVector3( deltaR[dT], deltaR[CP], deltaR[dD1] ); - crossProductVector3( deltaR[QC], deltaR[dU], deltaR[dD2] ); + crossProductVector3(deltaR[dT], deltaR[CP], deltaR[dD1] ); + crossProductVector3(deltaR[QC], deltaR[dU], deltaR[dD2] ); - crossProductVector3( deltaR[BD], deltaR[dP], d[A] ); - crossProductVector3( deltaR[dP], deltaR[AD], d[B] ); + crossProductVector3(deltaR[BD], deltaR[dP], d[A] ); + crossProductVector3(deltaR[dP], deltaR[AD], d[B] ); - crossProductVector3( deltaR[FC], deltaR[dQ], d[E] ); - crossProductVector3( deltaR[dQ], deltaR[EC], d[F] ); + crossProductVector3(deltaR[FC], deltaR[dQ], d[E] ); + crossProductVector3(deltaR[dQ], deltaR[EC], d[F] ); - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { d[C][ii] = deltaR[dC1][ii] + deltaR[dC2][ii] + deltaR[dP][ii] - d[E][ii] - d[F][ii]; d[D][ii] = deltaR[dD1][ii] + deltaR[dD2][ii] + deltaR[dQ][ii] - d[A][ii] - d[B][ii]; } @@ -204,48 +204,48 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit return; } -static void computeAmoebaPiTorsionForces( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, - std::vector& expectedForces, double* expectedEnergy ) { +static void computeAmoebaPiTorsionForces(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, + std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++ ){ + for (int ii = 0; ii < amoebaPiTorsionForce.getNumPiTorsions(); ii++) { computeAmoebaPiTorsionForce(ii, positions, amoebaPiTorsionForce, expectedForces, expectedEnergy); } } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, +void compareWithExpectedForceAndEnergy(Context& context, AmoebaPiTorsionForce& amoebaPiTorsionForce, double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaPiTorsionForces( context, amoebaPiTorsionForce, expectedForces, &expectedEnergy ); + computeAmoebaPiTorsionForces(context, amoebaPiTorsionForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } void testOnePiTorsion() { System system; int numberOfParticles = 6; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -254,23 +254,23 @@ void testOnePiTorsion() { AmoebaPiTorsionForce* amoebaPiTorsionForce = new AmoebaPiTorsionForce(); double kTorsion = 6.85; - amoebaPiTorsionForce->addPiTorsion(0, 1, 2, 3, 4, 5, kTorsion ); + amoebaPiTorsionForce->addPiTorsion(0, 1, 2, 3, 4, 5, kTorsion); system.addForce(amoebaPiTorsionForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector positions(numberOfParticles); - positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); - positions[1] = Vec3( 0.278860000E+02, 0.264630000E+02, 0.426300000E+01 ); - positions[2] = Vec3( 0.269130000E+02, 0.266390000E+02, 0.353100000E+01 ); + positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01); + positions[1] = Vec3(0.278860000E+02, 0.264630000E+02, 0.426300000E+01); + positions[2] = Vec3(0.269130000E+02, 0.266390000E+02, 0.353100000E+01); - positions[3] = Vec3( 0.245568230E+02, 0.250215290E+02, 0.796852800E+01 ); - positions[4] = Vec3( 0.261000000E+02, 0.292530000E+02, 0.520200000E+01 ); - positions[5] = Vec3( 0.254124630E+02, 0.234691880E+02, 0.773335400E+01 ); + positions[3] = Vec3(0.245568230E+02, 0.250215290E+02, 0.796852800E+01); + positions[4] = Vec3(0.261000000E+02, 0.292530000E+02, 0.520200000E+01); + positions[5] = Vec3(0.254124630E+02, 0.234691880E+02, 0.773335400E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); // Try changing the torsion parameters and make sure it's still correct. @@ -278,14 +278,14 @@ void testOnePiTorsion() { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaPiTorsionForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion" ); + compareWithExpectedForceAndEnergy(context, *amoebaPiTorsionForce, TOL, "testOnePiTorsion"); } int main(int argc, char* argv[]) { diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp index fd8725cfe..c87c54f41 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaStretchBendForce.cpp @@ -64,7 +64,7 @@ const double DegreesToRadians = PI_M/180.0; --------------------------------------------------------------------------------------- */ -static void crossProductVector3( double* vectorX, double* vectorY, double* vectorZ ){ +static void crossProductVector3(double* vectorX, double* vectorY, double* vectorZ) { vectorZ[0] = vectorX[1]*vectorY[2] - vectorX[2]*vectorY[1]; vectorZ[1] = vectorX[2]*vectorY[0] - vectorX[0]*vectorY[2]; @@ -73,7 +73,7 @@ static void crossProductVector3( double* vectorX, double* vectorY, double* vecto return; } -static double dotVector3( double* vectorX, double* vectorY ){ +static double dotVector3(double* vectorX, double* vectorY) { return vectorX[0]*vectorY[0] + vectorX[1]*vectorY[1] + vectorX[2]*vectorY[2]; } @@ -97,31 +97,31 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos double deltaR[LastDeltaIndex][3]; double rAB2 = 0.0; double rCB2 = 0.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { deltaR[AB][ii] = positions[particle1][ii] - positions[particle2][ii]; rAB2 += deltaR[AB][ii]*deltaR[AB][ii]; deltaR[CB][ii] = positions[particle3][ii] - positions[particle2][ii]; rCB2 += deltaR[CB][ii]*deltaR[CB][ii]; } - double rAB = sqrt( rAB2 ); - double rCB = sqrt( rCB2 ); + double rAB = sqrt(rAB2); + double rCB = sqrt(rCB2); - crossProductVector3( deltaR[CB], deltaR[AB], deltaR[CBxAB] ); - double rP = dotVector3( deltaR[CBxAB], deltaR[CBxAB] ); - rP = sqrt( rP ); + crossProductVector3(deltaR[CB], deltaR[AB], deltaR[CBxAB]); + double rP = dotVector3(deltaR[CBxAB], deltaR[CBxAB]); + rP = sqrt(rP); - if( rP <= 0.0 ){ + if (rP <= 0.0) { return; } - double dot = dotVector3( deltaR[CB], deltaR[AB] ); + double dot = dotVector3(deltaR[CB], deltaR[AB]); double cosine = dot/(rAB*rCB); double angle; - if( cosine >= 1.0 ){ + if (cosine >= 1.0) { angle = 0.0; } - else if( cosine <= -1.0 ){ + else if (cosine <= -1.0) { angle = PI_M; } else { @@ -133,9 +133,9 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos // P = CBxAB - crossProductVector3( deltaR[AB], deltaR[CBxAB], deltaR[ABxP] ); - crossProductVector3( deltaR[CB], deltaR[CBxAB], deltaR[CBxP] ); - for( int ii = 0; ii < 3; ii++ ){ + crossProductVector3(deltaR[AB], deltaR[CBxAB], deltaR[ABxP]); + crossProductVector3(deltaR[CB], deltaR[CBxAB], deltaR[CBxP]); + for (int ii = 0; ii < 3; ii++) { deltaR[ABxP][ii] *= termA; deltaR[CBxP][ii] *= termC; } @@ -153,14 +153,14 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos // forces // calculate forces for atoms a, b, c - // the force for b is then -( a + c) + // the force for b is then -(a + c) double subForce[LastAtomIndex][3]; double dt = angle - angleStretchBend; - for( int jj = 0; jj < 3; jj++ ){ + for (int jj = 0; jj < 3; jj++) { subForce[A][jj] = kStretchBend*dt*termA*deltaR[AB][jj] + drkk*deltaR[ABxP][jj]; subForce[C][jj] = k2StretchBend*dt*termC*deltaR[CB][jj] + drkk*deltaR[CBxP][jj]; - subForce[B][jj] = -( subForce[A][jj] + subForce[C][jj] ); + subForce[B][jj] = -(subForce[A][jj] + subForce[C][jj]); } // --------------------------------------------------------------------------------------- @@ -182,47 +182,47 @@ static void computeAmoebaStretchBendForce(int bondIndex, std::vector& pos *energy += dt*drkk; } -static void computeAmoebaStretchBendForces( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, +static void computeAmoebaStretchBendForces(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, std::vector& expectedForces, double* expectedEnergy) { // get positions and zero forces State state = context.getState(State::Positions); std::vector positions = state.getPositions(); - expectedForces.resize( positions.size() ); + expectedForces.resize(positions.size()); - for( unsigned int ii = 0; ii < expectedForces.size(); ii++ ){ + for (unsigned int ii = 0; ii < expectedForces.size(); ii++) { expectedForces[ii][0] = expectedForces[ii][1] = expectedForces[ii][2] = 0.0; } // calculates forces/energy *expectedEnergy = 0.0; - for( int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++ ){ - computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy ); + for (int ii = 0; ii < amoebaStretchBendForce.getNumStretchBends(); ii++) { + computeAmoebaStretchBendForce(ii, positions, amoebaStretchBendForce, expectedForces, expectedEnergy); } } -void compareWithExpectedForceAndEnergy( Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, +void compareWithExpectedForceAndEnergy(Context& context, AmoebaStretchBendForce& amoebaStretchBendForce, double tolerance, const std::string& idString) { std::vector expectedForces; double expectedEnergy; - computeAmoebaStretchBendForces( context, amoebaStretchBendForce, expectedForces, &expectedEnergy ); + computeAmoebaStretchBendForces(context, amoebaStretchBendForce, expectedForces, &expectedEnergy); State state = context.getState(State::Forces | State::Energy); const std::vector forces = state.getForces(); - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } void testOneStretchBend() { System system; int numberOfParticles = 3; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } @@ -236,19 +236,19 @@ void testOneStretchBend() { //double kStretchBend = 0.750491578E-01; double kStretchBend = 1.0; - amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend ); + amoebaStretchBendForce->addStretchBend(0, 1, 2, abLength, cbLength, angleStretchBend, kStretchBend, kStretchBend); system.addForce(amoebaStretchBendForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); std::vector positions(numberOfParticles); - positions[0] = Vec3( 0.262660000E+02, 0.254130000E+02, 0.284200000E+01 ); - positions[1] = Vec3( 0.273400000E+02, 0.244300000E+02, 0.261400000E+01 ); - positions[2] = Vec3( 0.269573220E+02, 0.236108860E+02, 0.216376800E+01 ); + positions[0] = Vec3(0.262660000E+02, 0.254130000E+02, 0.284200000E+01); + positions[1] = Vec3(0.273400000E+02, 0.244300000E+02, 0.261400000E+01); + positions[2] = Vec3(0.269573220E+02, 0.236108860E+02, 0.216376800E+01); context.setPositions(positions); - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend" ); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend"); // Try changing the stretch-bend parameters and make sure it's still correct. @@ -256,14 +256,14 @@ void testOneStretchBend() { bool exceptionThrown = false; try { // This should throw an exception. - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend" ); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend"); } catch (std::exception ex) { exceptionThrown = true; } ASSERT(exceptionThrown); amoebaStretchBendForce->updateParametersInContext(context); - compareWithExpectedForceAndEnergy( context, *amoebaStretchBendForce, TOL, "testOneStretchBend" ); + compareWithExpectedForceAndEnergy(context, *amoebaStretchBendForce, TOL, "testOneStretchBend"); } int main(int argc, char* argv[]) { diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp index 556783682..088ae02f2 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaTorsionTorsionForce.cpp @@ -48,7 +48,7 @@ extern "C" void registerAmoebaCudaKernelFactories(); const double TOL = 1e-4; -TorsionTorsionGrid& getTorsionGrid( int gridIndex ) { +TorsionTorsionGrid& getTorsionGrid(int gridIndex) { static double grid[4][625][6] = { { @@ -2558,22 +2558,22 @@ TorsionTorsionGrid& getTorsionGrid( int gridIndex ) { // static std::vector< std::vector< std::vector > > TorsionTorsionGrid static std::vector grids; - if( grids.size() == 0 ){ + if (grids.size() == 0) { grids.resize(4); - for( int ii = 0; ii < 4; ii++ ){ - grids[ii].resize( 25 ); - for( int jj = 0; jj < 25; jj++ ){ + for (int ii = 0; ii < 4; ii++) { + grids[ii].resize(25); + for (int jj = 0; jj < 25; jj++) { grids[ii][jj].resize(25); - for( int kk = 0; kk < 25; kk++ ){ + for (int kk = 0; kk < 25; kk++) { grids[ii][jj][kk].resize(6); } } int index = 0; - for( int jj = 0; jj < 25; jj++ ){ - for( int kk = 0; kk < 25; kk++ ){ + for (int jj = 0; jj < 25; jj++) { + for (int kk = 0; kk < 25; kk++) { int jjIndex = static_cast(((grid[ii][index][0] + 180.0)/15.0)+1.0e-05); int kkIndex = static_cast(((grid[ii][index][1] + 180.0)/15.0)+1.0e-05); - for( int ll = 0; ll < 6; ll++ ){ + for (int ll = 0; ll < 6; ll++) { grids[ii][kk][jj][ll] = grid[ii][index][ll]; } index++; @@ -2588,7 +2588,7 @@ void testTorsionTorsion(int systemId) { System system; int numberOfParticles = 6; - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { system.addParticle(1.0); } LangevinIntegrator integrator(0.0, 0.1, 0.01); @@ -2600,71 +2600,71 @@ void testTorsionTorsion(int systemId) { std::vector positions(numberOfParticles); std::vector expectedForces(numberOfParticles); double expectedEnergy; - if( systemId == 0 ){ + if (systemId == 0) { // villin: 2 19 20 21 38 25 grid=2 chiralCheckAtomIndex = 5; gridIndex = 2; - positions[0] = Vec3( -0.422792800E+01, -0.110605910E+02, -0.508156700E+01 ); - positions[1] = Vec3( -0.447153100E+01, -0.978627900E+01, -0.466405800E+01 ); - positions[2] = Vec3( -0.531878400E+01, -0.940508600E+01, -0.352283100E+01 ); - positions[3] = Vec3( -0.679606000E+01, -0.974353100E+01, -0.382975700E+01 ); - positions[4] = Vec3( -0.760612300E+01, -0.992590200E+01, -0.275088400E+01 ); - positions[5] = Vec3( -0.516893900E+01, -0.788347000E+01, -0.316943000E+01 ); + positions[0] = Vec3(-0.422792800E+01, -0.110605910E+02, -0.508156700E+01); + positions[1] = Vec3(-0.447153100E+01, -0.978627900E+01, -0.466405800E+01); + positions[2] = Vec3(-0.531878400E+01, -0.940508600E+01, -0.352283100E+01); + positions[3] = Vec3(-0.679606000E+01, -0.974353100E+01, -0.382975700E+01); + positions[4] = Vec3(-0.760612300E+01, -0.992590200E+01, -0.275088400E+01); + positions[5] = Vec3(-0.516893900E+01, -0.788347000E+01, -0.316943000E+01); - expectedForces[0] = Vec3( 0.906091624E+00, -0.529814945E-01, 0.690384140E+00 ); - expectedForces[1] = Vec3( -0.124550232E+01, -0.999341692E+00, -0.590867130E+00 ); - expectedForces[2] = Vec3( 0.534419689E+00, 0.612404926E-01, 0.547380310E-01 ); - expectedForces[3] = Vec3( -5.732010432E-01, 2.645718463E+00, -1.585204274E-01 ); - expectedForces[4] = Vec3( 3.781920539E-01, -1.654635768E+00, 4.265386268E-03 ); - expectedForces[5] = Vec3( 0.0, 0.0, 0.0 ); + expectedForces[0] = Vec3( 0.906091624E+00, -0.529814945E-01, 0.690384140E+00); + expectedForces[1] = Vec3(-0.124550232E+01, -0.999341692E+00, -0.590867130E+00); + expectedForces[2] = Vec3( 0.534419689E+00, 0.612404926E-01, 0.547380310E-01); + expectedForces[3] = Vec3(-5.732010432E-01, 2.645718463E+00, -1.585204274E-01); + expectedForces[4] = Vec3( 3.781920539E-01, -1.654635768E+00, 4.265386268E-03); + expectedForces[5] = Vec3( 0.0, 0.0, 0.0); expectedEnergy = -2.699654759E+00; - } else if( systemId == 1 ){ + } else if (systemId == 1) { // villin: 158 176 177 178 183 -1 0 chiralCheckAtomIndex = -1; gridIndex = 0; - positions[0] = Vec3( -0.105946640E+02, -0.917797000E+00, 0.105486310E+02 ); - positions[1] = Vec3( -0.115059090E+02, -0.141876700E+01, 0.966933200E+01 ); - positions[2] = Vec3( -0.128314660E+02, -0.876338000E+00, 0.942959800E+01 ); - positions[3] = Vec3( -0.130879850E+02, -0.760280000E-01, 0.814732200E+01 ); - positions[4] = Vec3( -0.120888080E+02, 0.112050000E-01, 0.722704500E+01 ); - positions[5] = Vec3( 0.0, 0.0, 0.0 ); + positions[0] = Vec3(-0.105946640E+02, -0.917797000E+00, 0.105486310E+02); + positions[1] = Vec3(-0.115059090E+02, -0.141876700E+01, 0.966933200E+01); + positions[2] = Vec3(-0.128314660E+02, -0.876338000E+00, 0.942959800E+01); + positions[3] = Vec3(-0.130879850E+02, -0.760280000E-01, 0.814732200E+01); + positions[4] = Vec3(-0.120888080E+02, 0.112050000E-01, 0.722704500E+01); + positions[5] = Vec3( 0.0, 0.0, 0.0); - expectedForces[0] = Vec3( 4.165851130E-01, 6.608242922E-01, -8.082168261E-01 ); - expectedForces[1] = Vec3( -6.024659721E-01, -8.878744406E-01, 1.322274444E+00 ); - expectedForces[2] = Vec3( 3.196925118E-02, -3.137497848E-01, -8.207984001E-01 ); - expectedForces[3] = Vec3( 3.842205941E-02, 2.602732089E-01, 1.547586195E-01 ); - expectedForces[4] = Vec3( 1.154895485E-01, 2.805267242E-01, 1.519821623E-01 ); - expectedForces[5] = Vec3( 0.0, 0.0, 0.0 ); + expectedForces[0] = Vec3( 4.165851130E-01, 6.608242922E-01, -8.082168261E-01); + expectedForces[1] = Vec3(-6.024659721E-01, -8.878744406E-01, 1.322274444E+00); + expectedForces[2] = Vec3( 3.196925118E-02, -3.137497848E-01, -8.207984001E-01); + expectedForces[3] = Vec3( 3.842205941E-02, 2.602732089E-01, 1.547586195E-01); + expectedForces[4] = Vec3( 1.154895485E-01, 2.805267242E-01, 1.519821623E-01); + expectedForces[5] = Vec3( 0.0, 0.0, 0.0); expectedEnergy = -3.372536909E+00; } - amoebaTorsionTorsionForce->addTorsionTorsion( 0, 1, 2, 3, 4, chiralCheckAtomIndex, 0 ); - amoebaTorsionTorsionForce->setTorsionTorsionGrid( 0, getTorsionGrid( gridIndex ) ); + amoebaTorsionTorsionForce->addTorsionTorsion(0, 1, 2, 3, 4, chiralCheckAtomIndex, 0); + amoebaTorsionTorsionForce->setTorsionTorsionGrid(0, getTorsionGrid(gridIndex)); system.addForce(amoebaTorsionTorsionForce); - Context context(system, integrator, Platform::getPlatformByName( "CUDA")); + Context context(system, integrator, Platform::getPlatformByName("CUDA")); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); std::vector forces = state.getForces(); const double conversion = -1.0; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ + for (unsigned int ii = 0; ii < forces.size(); ii++) { forces[ii][0] *= conversion; forces[ii][1] *= conversion; forces[ii][2] *= conversion; } double tolerance = 1.0e-03; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); } diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp index d1e0248b7..5594b8e8d 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaAmoebaVdwForce.cpp @@ -63,15 +63,15 @@ void testVdw() { int numberOfParticles = 6; AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce(); std::string sigmaCombiningRule = std::string("CUBIC-MEAN"); - amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule ); + amoebaVdwForce->setSigmaCombiningRule(sigmaCombiningRule); std::string epsilonCombiningRule = std::string("HHG"); - amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule ); - for( int ii = 0; ii < numberOfParticles; ii++ ){ + amoebaVdwForce->setEpsilonCombiningRule(epsilonCombiningRule); + for (int ii = 0; ii < numberOfParticles; ii++) { int indexIV; double mass, sigma, epsilon, reduction; std::vector< int > exclusions; - if( ii == 0 || ii == 3 ){ + if (ii == 0 || ii == 3) { mass = 16.0; indexIV = ii; sigma = 1.70250E+00; @@ -87,18 +87,18 @@ void testVdw() { // exclusions - if( ii < 3 ){ - exclusions.push_back ( 0 ); - exclusions.push_back ( 1 ); - exclusions.push_back ( 2 ); + if (ii < 3) { + exclusions.push_back (0); + exclusions.push_back (1); + exclusions.push_back (2); } else { - exclusions.push_back ( 3 ); - exclusions.push_back ( 4 ); - exclusions.push_back ( 5 ); + exclusions.push_back (3); + exclusions.push_back (4); + exclusions.push_back (5); } system.addParticle(mass); - amoebaVdwForce->addParticle( indexIV, sigma, epsilon, reduction ); - amoebaVdwForce->setParticleExclusions( ii, exclusions ); + amoebaVdwForce->addParticle(indexIV, sigma, epsilon, reduction); + amoebaVdwForce->setParticleExclusions(ii, exclusions); } LangevinIntegrator integrator(0.0, 0.1, 0.01); @@ -106,25 +106,25 @@ void testVdw() { std::vector expectedForces(numberOfParticles); double expectedEnergy; - positions[0] = Vec3( -0.254893450E+02, -0.876646600E+01, 0.174761600E+01 ); - positions[1] = Vec3( -0.263489690E+02, -0.907798000E+01, 0.205385100E+01 ); - positions[2] = Vec3( -0.252491680E+02, -0.949411200E+01, 0.115017600E+01 ); - positions[3] = Vec3( 0.172827200E+01, 0.195873090E+02, 0.100059800E+01 ); - positions[4] = Vec3( 0.129370700E+01, 0.190112810E+02, 0.169576300E+01 ); - positions[5] = Vec3( 0.256122300E+01, 0.191601930E+02, 0.854382000E+00 ); + positions[0] = Vec3(-0.254893450E+02, -0.876646600E+01, 0.174761600E+01); + positions[1] = Vec3(-0.263489690E+02, -0.907798000E+01, 0.205385100E+01); + positions[2] = Vec3(-0.252491680E+02, -0.949411200E+01, 0.115017600E+01); + positions[3] = Vec3( 0.172827200E+01, 0.195873090E+02, 0.100059800E+01); + positions[4] = Vec3( 0.129370700E+01, 0.190112810E+02, 0.169576300E+01); + positions[5] = Vec3( 0.256122300E+01, 0.191601930E+02, 0.854382000E+00); double offset = 27.0; - for( int ii = 0; ii < 3; ii++ ){ + for (int ii = 0; ii < 3; ii++) { positions[ii][0] += offset; positions[ii][1] += offset; } - expectedForces[0] = Vec3( -0.729561040E+03, 0.425828484E+04, -0.769114213E+03 ); - expectedForces[1] = Vec3( 0.181000041E+02, 0.328216639E+02, -0.126210511E+02 ); - expectedForces[2] = Vec3( -0.943743014E+00, 0.199728310E+02, 0.884567842E+00 ); - expectedForces[3] = Vec3( 0.615734500E+01, -0.747350431E+03, 0.264726489E+03 ); - expectedForces[4] = Vec3( 0.735772031E+03, -0.353310112E+04, 0.490066356E+03 ); - expectedForces[5] = Vec3( -0.295245970E+02, -0.306277797E+02, 0.260578506E+02 ); + expectedForces[0] = Vec3( -0.729561040E+03, 0.425828484E+04, -0.769114213E+03); + expectedForces[1] = Vec3( 0.181000041E+02, 0.328216639E+02, -0.126210511E+02); + expectedForces[2] = Vec3( -0.943743014E+00, 0.199728310E+02, 0.884567842E+00); + expectedForces[3] = Vec3( 0.615734500E+01, -0.747350431E+03, 0.264726489E+03); + expectedForces[4] = Vec3( 0.735772031E+03, -0.353310112E+04, 0.490066356E+03); + expectedForces[5] = Vec3( -0.295245970E+02, -0.306277797E+02, 0.260578506E+02); expectedEnergy = 0.740688488E+03; @@ -132,38 +132,38 @@ void testVdw() { std::string platformName; #define AngstromToNm 0.1 #define CalToJoule 4.184 - for( int ii = 0; ii < numberOfParticles; ii++ ){ + for (int ii = 0; ii < numberOfParticles; ii++) { positions[ii][0] *= AngstromToNm; positions[ii][1] *= AngstromToNm; positions[ii][2] *= AngstromToNm; } - for( int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++ ){ + for (int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++) { int indexIV; double sigma, epsilon, reduction; - amoebaVdwForce->getParticleParameters( ii, indexIV, sigma, epsilon, reduction ); + amoebaVdwForce->getParticleParameters(ii, indexIV, sigma, epsilon, reduction); sigma *= AngstromToNm; epsilon *= CalToJoule; - amoebaVdwForce->setParticleParameters( ii, indexIV, sigma, epsilon, reduction ); + amoebaVdwForce->setParticleParameters(ii, indexIV, sigma, epsilon, reduction); } platformName = "CUDA"; - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); std::vector forces = state.getForces(); const double conversion = -AngstromToNm/CalToJoule; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ + for (unsigned int ii = 0; ii < forces.size(); ii++) { forces[ii][0] *= conversion; forces[ii][1] *= conversion; forces[ii][2] *= conversion; } expectedEnergy *= CalToJoule; double tolerance = 1.0e-03; - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC( expectedForces[ii], forces[ii], tolerance ); + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC(expectedForces[ii], forces[ii], tolerance); } - ASSERT_EQUAL_TOL( expectedEnergy, state.getPotentialEnergy(), tolerance ); + ASSERT_EQUAL_TOL(expectedEnergy, state.getPotentialEnergy(), tolerance); // Try changing the particle parameters and make sure it's still correct. @@ -195,133 +195,133 @@ void testVdw() { ASSERT_EQUAL_TOL(state1.getPotentialEnergy(), state2.getPotentialEnergy(), tolerance); } -void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, - double boxDimension, std::vector& forces, double& energy){ +void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, + double boxDimension, std::vector& forces, double& energy) { // beginning of Vdw setup System system; AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce();; int numberOfParticles = 8; - amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule ); - amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule ); - amoebaVdwForce->setCutoff( cutoff ); - if( boxDimension > 0.0 ){ - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + amoebaVdwForce->setSigmaCombiningRule(sigmaCombiningRule); + amoebaVdwForce->setEpsilonCombiningRule(epsilonCombiningRule); + amoebaVdwForce->setCutoff(cutoff); + if (boxDimension > 0.0) { + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); - amoebaVdwForce->setUseDispersionCorrection( 1 ); + amoebaVdwForce->setUseDispersionCorrection(1); } else { amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff); - amoebaVdwForce->setUseDispersionCorrection( 0 ); + amoebaVdwForce->setUseDispersionCorrection(0); } // addParticle: ivIndex, radius, epsilon, reductionFactor - system.addParticle( 1.4007000e+01 ); - amoebaVdwForce->addParticle( 0, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 ); + system.addParticle( 1.4007000e+01); + amoebaVdwForce->addParticle(0, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.4007000e+01 ); - amoebaVdwForce->addParticle( 4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00 ); + system.addParticle( 1.4007000e+01); + amoebaVdwForce->addParticle(4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( 4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); // ParticleExclusions std::vector< int > exclusions; exclusions.resize(0); - exclusions.push_back( 0 ); - exclusions.push_back( 1 ); - exclusions.push_back( 2 ); - exclusions.push_back( 3 ); - amoebaVdwForce->setParticleExclusions( 0, exclusions ); + exclusions.push_back(0); + exclusions.push_back(1); + exclusions.push_back(2); + exclusions.push_back(3); + amoebaVdwForce->setParticleExclusions(0, exclusions); exclusions.resize(0); - exclusions.push_back( 1 ); - exclusions.push_back( 0 ); - exclusions.push_back( 2 ); - exclusions.push_back( 3 ); - amoebaVdwForce->setParticleExclusions( 1, exclusions ); + exclusions.push_back(1); + exclusions.push_back(0); + exclusions.push_back(2); + exclusions.push_back(3); + amoebaVdwForce->setParticleExclusions(1, exclusions); exclusions.resize(0); - exclusions.push_back( 2 ); - exclusions.push_back( 0 ); - exclusions.push_back( 1 ); - exclusions.push_back( 3 ); - amoebaVdwForce->setParticleExclusions( 2, exclusions ); + exclusions.push_back(2); + exclusions.push_back(0); + exclusions.push_back(1); + exclusions.push_back(3); + amoebaVdwForce->setParticleExclusions(2, exclusions); exclusions.resize(0); - exclusions.push_back( 3 ); - exclusions.push_back( 0 ); - exclusions.push_back( 1 ); - exclusions.push_back( 2 ); - amoebaVdwForce->setParticleExclusions( 3, exclusions ); + exclusions.push_back(3); + exclusions.push_back(0); + exclusions.push_back(1); + exclusions.push_back(2); + amoebaVdwForce->setParticleExclusions(3, exclusions); exclusions.resize(0); - exclusions.push_back( 4 ); - exclusions.push_back( 5 ); - exclusions.push_back( 6 ); - exclusions.push_back( 7 ); - amoebaVdwForce->setParticleExclusions( 4, exclusions ); + exclusions.push_back(4); + exclusions.push_back(5); + exclusions.push_back(6); + exclusions.push_back(7); + amoebaVdwForce->setParticleExclusions(4, exclusions); exclusions.resize(0); - exclusions.push_back( 5 ); - exclusions.push_back( 4 ); - exclusions.push_back( 6 ); - exclusions.push_back( 7 ); - amoebaVdwForce->setParticleExclusions( 5, exclusions ); + exclusions.push_back(5); + exclusions.push_back(4); + exclusions.push_back(6); + exclusions.push_back(7); + amoebaVdwForce->setParticleExclusions(5, exclusions); exclusions.resize(0); - exclusions.push_back( 6 ); - exclusions.push_back( 4 ); - exclusions.push_back( 5 ); - exclusions.push_back( 7 ); - amoebaVdwForce->setParticleExclusions( 6, exclusions ); + exclusions.push_back(6); + exclusions.push_back(4); + exclusions.push_back(5); + exclusions.push_back(7); + amoebaVdwForce->setParticleExclusions(6, exclusions); exclusions.resize(0); - exclusions.push_back( 7 ); - exclusions.push_back( 4 ); - exclusions.push_back( 5 ); - exclusions.push_back( 6 ); - amoebaVdwForce->setParticleExclusions( 7, exclusions ); + exclusions.push_back(7); + exclusions.push_back(4); + exclusions.push_back(5); + exclusions.push_back(6); + amoebaVdwForce->setParticleExclusions(7, exclusions); // end of Vdw setup std::vector positions(numberOfParticles); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); system.addForce(amoebaVdwForce); std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -329,13 +329,13 @@ void setupAndGetForcesEnergyVdwAmmonia( const std::string& sigmaCombiningRule, c energy = state.getPotentialEnergy(); } -void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, - std::vector& expectedForces, - std::vector& forces, double tolerance) { - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); +void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, + std::vector& expectedForces, + std::vector& forces, double tolerance) { + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // test VDW w/ sigmaRule=CubicMean and epsilonRule=HHG @@ -350,22 +350,22 @@ void testVdwAmmoniaCubicMeanHhg() { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.8012258e+00; - expectedForces[0] = Vec3( 2.9265247e+02, -1.4507808e-02, -6.9562123e+00 ); - expectedForces[1] = Vec3( -2.2451693e+00, 4.8143073e-01, -2.0041494e-01 ); - expectedForces[2] = Vec3( -2.2440698e+00, -4.7905450e-01, -2.0125284e-01 ); - expectedForces[3] = Vec3( -1.0840394e+00, -5.8531253e-04, 2.6934135e-01 ); - expectedForces[4] = Vec3( -5.6305662e+01, 1.4733908e-03, -1.8083306e-01 ); - expectedForces[5] = Vec3( 1.6750145e+00, -3.2448374e-01, -1.8030914e-01 ); - expectedForces[6] = Vec3( -2.3412420e+02, 1.0754069e-02, 7.6287492e+00 ); - expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01 ); + expectedForces[0] = Vec3( 2.9265247e+02, -1.4507808e-02, -6.9562123e+00); + expectedForces[1] = Vec3( -2.2451693e+00, 4.8143073e-01, -2.0041494e-01); + expectedForces[2] = Vec3( -2.2440698e+00, -4.7905450e-01, -2.0125284e-01); + expectedForces[3] = Vec3( -1.0840394e+00, -5.8531253e-04, 2.6934135e-01); + expectedForces[4] = Vec3( -5.6305662e+01, 1.4733908e-03, -1.8083306e-01); + expectedForces[5] = Vec3( 1.6750145e+00, -3.2448374e-01, -1.8030914e-01); + expectedForces[6] = Vec3( -2.3412420e+02, 1.0754069e-02, 7.6287492e+00); + expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test VDW w/ sigmaRule=Arithmetic and epsilonRule=Arithmetic @@ -380,27 +380,27 @@ void testVdwAmmoniaArithmeticArithmetic() { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy ); + setupAndGetForcesEnergyVdwAmmonia("ARITHMETIC", "ARITHMETIC", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.2252403e+00; - expectedForces[0] = Vec3( 3.0603839e+02, -1.5550310e-02, -7.2661707e+00 ); - expectedForces[1] = Vec3( -2.7801357e+00, 5.8805051e-01, -2.5907269e-01 ); - expectedForces[2] = Vec3( -2.7753968e+00, -5.8440732e-01, -2.5969111e-01 ); - expectedForces[3] = Vec3( -2.2496416e+00, -1.1797440e-03, 5.5501757e-01 ); - expectedForces[4] = Vec3( -5.5077629e+01, 8.3417114e-04, -3.3668921e-01 ); - expectedForces[5] = Vec3( 2.3752452e+00, -4.6788669e-01, -2.4907764e-01 ); - expectedForces[6] = Vec3( -2.4790697e+02, 1.1419770e-02, 8.0629999e+00 ); - expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01 ); + expectedForces[0] = Vec3( 3.0603839e+02, -1.5550310e-02, -7.2661707e+00); + expectedForces[1] = Vec3( -2.7801357e+00, 5.8805051e-01, -2.5907269e-01); + expectedForces[2] = Vec3( -2.7753968e+00, -5.8440732e-01, -2.5969111e-01); + expectedForces[3] = Vec3( -2.2496416e+00, -1.1797440e-03, 5.5501757e-01); + expectedForces[4] = Vec3( -5.5077629e+01, 8.3417114e-04, -3.3668921e-01); + expectedForces[5] = Vec3( 2.3752452e+00, -4.6788669e-01, -2.4907764e-01); + expectedForces[6] = Vec3( -2.4790697e+02, 1.1419770e-02, 8.0629999e+00); + expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test VDW w/ sigmaRule=Geometric and epsilonRule=Geometric -void testVdwAmmoniaGeometricGeometric( ) { +void testVdwAmmoniaGeometricGeometric() { std::string testName = "testVdwAmmoniaGeometricGeometric"; @@ -409,25 +409,25 @@ void testVdwAmmoniaGeometricGeometric( ) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy ); + setupAndGetForcesEnergyVdwAmmonia("GEOMETRIC", "GEOMETRIC", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 2.5249914e+00; - expectedForces[0] = Vec3( 2.1169631e+02, -1.0710925e-02, -4.3728025e+00 ); - expectedForces[1] = Vec3( -2.2585621e+00, 4.8409995e-01, -2.0188344e-01 ); - expectedForces[2] = Vec3( -2.2551351e+00, -4.8124855e-01, -2.0246986e-01 ); - expectedForces[3] = Vec3( -1.7178028e+00, -9.0851787e-04, 4.2466975e-01 ); - expectedForces[4] = Vec3( -4.8302147e+01, 9.6603376e-04, -5.7972068e-01 ); - expectedForces[5] = Vec3( 1.8100634e+00, -3.5214093e-01, -1.9357207e-01 ); - expectedForces[6] = Vec3( -1.6078365e+02, 7.2117601e-03, 5.3180261e+00 ); - expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01 ); + expectedForces[0] = Vec3( 2.1169631e+02, -1.0710925e-02, -4.3728025e+00); + expectedForces[1] = Vec3( -2.2585621e+00, 4.8409995e-01, -2.0188344e-01); + expectedForces[2] = Vec3( -2.2551351e+00, -4.8124855e-01, -2.0246986e-01); + expectedForces[3] = Vec3( -1.7178028e+00, -9.0851787e-04, 4.2466975e-01); + expectedForces[4] = Vec3( -4.8302147e+01, 9.6603376e-04, -5.7972068e-01); + expectedForces[5] = Vec3( 1.8100634e+00, -3.5214093e-01, -1.9357207e-01); + expectedForces[6] = Vec3( -1.6078365e+02, 7.2117601e-03, 5.3180261e+00); + expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } -void testVdwAmmoniaCubicMeanHarmonic( ) { +void testVdwAmmoniaCubicMeanHarmonic() { std::string testName = "testVdwAmmoniaCubicMeanHarmonic"; @@ -436,29 +436,29 @@ void testVdwAmmoniaCubicMeanHarmonic( ) { double cutoff = 9000000.0; std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HARMONIC", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 4.1369069e+00; - expectedForces[0] = Vec3( 2.5854436e+02, -1.2779529e-02, -5.9041148e+00 ); - expectedForces[1] = Vec3( -2.0832419e+00, 4.4915831e-01, -1.8266000e-01 ); - expectedForces[2] = Vec3( -2.0823991e+00, -4.4699804e-01, -1.8347141e-01 ); - expectedForces[3] = Vec3( -9.5914714e-01, -5.2162026e-04, 2.3873165e-01 ); - expectedForces[4] = Vec3( -5.3724787e+01, 1.4838241e-03, -2.8089191e-01 ); - expectedForces[5] = Vec3( 1.5074325e+00, -2.9016397e-01, -1.6385118e-01 ); - expectedForces[6] = Vec3( -2.0271029e+02, 9.2367947e-03, 6.6389988e+00 ); - expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01 ); + expectedForces[0] = Vec3( 2.5854436e+02, -1.2779529e-02, -5.9041148e+00); + expectedForces[1] = Vec3( -2.0832419e+00, 4.4915831e-01, -1.8266000e-01); + expectedForces[2] = Vec3( -2.0823991e+00, -4.4699804e-01, -1.8347141e-01); + expectedForces[3] = Vec3( -9.5914714e-01, -5.2162026e-04, 2.3873165e-01); + expectedForces[4] = Vec3( -5.3724787e+01, 1.4838241e-03, -2.8089191e-01); + expectedForces[5] = Vec3( 1.5074325e+00, -2.9016397e-01, -1.6385118e-01); + expectedForces[6] = Vec3( -2.0271029e+02, 9.2367947e-03, 6.6389988e+00); + expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test w/ cutoff=0.25 nm; single ixn between two particles (0 and 6); force nonzero on // particle 4 due to reduction applied to NH // the distance between 0 and 6 is ~ 0.235 so the ixn is in the tapered region -void testVdwTaper( ) { +void testVdwTaper() { std::string testName = "testVdwTaper"; @@ -468,27 +468,27 @@ void testVdwTaper( ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 3.5478444e+00; - expectedForces[0] = Vec3( 5.6710779e+02, -2.7391004e-02, -1.7867730e+01 ); - expectedForces[1] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[2] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[4] = Vec3( -5.1039701e+01, 2.4651903e-03, 1.6080957e+00 ); - expectedForces[5] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01 ); - expectedForces[7] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); + expectedForces[0] = Vec3( 5.6710779e+02, -2.7391004e-02, -1.7867730e+01); + expectedForces[1] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[2] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[4] = Vec3( -5.1039701e+01, 2.4651903e-03, 1.6080957e+00); + expectedForces[5] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01); + expectedForces[7] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // test PBC -void testVdwPBC( ) { +void testVdwPBC() { std::string testName = "testVdwPBC"; @@ -498,78 +498,78 @@ void testVdwPBC( ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwAmmonia( "CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy ); + setupAndGetForcesEnergyVdwAmmonia("CUBIC-MEAN", "HHG", cutoff, boxDimension, forces, energy); std::vector expectedForces(numberOfParticles); double expectedEnergy = 1.4949141e+01; - expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01 ); - expectedForces[1] = Vec3( -2.5622586e+02, -4.6524265e+01, 2.4281465e+01 ); - expectedForces[2] = Vec3( -2.7538705e+02, 5.1831690e+01, 2.7367710e+01 ); - expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00 ); - expectedForces[4] = Vec3( 3.0883034e+02, -5.8876974e+00, -5.8286122e+01 ); - expectedForces[5] = Vec3( 1.1319359e+02, -3.2047069e-01, 1.6181231e+00 ); - expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01 ); - expectedForces[7] = Vec3( 1.1112638e+02, 3.7829857e-01, 1.5187587e+00 ); + expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01); + expectedForces[1] = Vec3( -2.5622586e+02, -4.6524265e+01, 2.4281465e+01); + expectedForces[2] = Vec3( -2.7538705e+02, 5.1831690e+01, 2.7367710e+01); + expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[4] = Vec3( 3.0883034e+02, -5.8876974e+00, -5.8286122e+01); + expectedForces[5] = Vec3( 1.1319359e+02, -3.2047069e-01, 1.6181231e+00); + expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01); + expectedForces[7] = Vec3( 1.1112638e+02, 3.7829857e-01, 1.5187587e+00); // tolerance is higher here due to interpolation used in setting tapering coefficients; // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); } // create box of 216 water molecules -void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, - double boxDimension, int includeVdwDispersionCorrection, - std::vector& forces, double& energy ){ +void setupAndGetForcesEnergyVdwWater(const std::string& sigmaCombiningRule, const std::string& epsilonCombiningRule, double cutoff, + double boxDimension, int includeVdwDispersionCorrection, + std::vector& forces, double& energy) { // beginning of Vdw setup System system; AmoebaVdwForce* amoebaVdwForce = new AmoebaVdwForce();; int numberOfParticles = 648; - amoebaVdwForce->setSigmaCombiningRule( sigmaCombiningRule ); - amoebaVdwForce->setEpsilonCombiningRule( epsilonCombiningRule ); - amoebaVdwForce->setCutoff( cutoff ); - if( boxDimension > 0.0 ){ - Vec3 a( boxDimension, 0.0, 0.0 ); - Vec3 b( 0.0, boxDimension, 0.0 ); - Vec3 c( 0.0, 0.0, boxDimension ); - system.setDefaultPeriodicBoxVectors( a, b, c ); + amoebaVdwForce->setSigmaCombiningRule(sigmaCombiningRule); + amoebaVdwForce->setEpsilonCombiningRule(epsilonCombiningRule); + amoebaVdwForce->setCutoff(cutoff); + if (boxDimension > 0.0) { + Vec3 a(boxDimension, 0.0, 0.0); + Vec3 b(0.0, boxDimension, 0.0); + Vec3 c(0.0, 0.0, boxDimension); + system.setDefaultPeriodicBoxVectors(a, b, c); amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); - amoebaVdwForce->setUseDispersionCorrection( includeVdwDispersionCorrection ); + amoebaVdwForce->setUseDispersionCorrection(includeVdwDispersionCorrection); } else { amoebaVdwForce->setNonbondedMethod(AmoebaVdwForce::NoCutoff); - amoebaVdwForce->setUseDispersionCorrection( 0 ); + amoebaVdwForce->setUseDispersionCorrection(0); } // addParticle: ivIndex, radius, epsilon, reductionFactor int classIndex = 0; - for( unsigned int ii = 0; ii < numberOfParticles; ii += 3 ){ + for (unsigned int ii = 0; ii < numberOfParticles; ii += 3) { - system.addParticle( 1.5995000e+01 ); - amoebaVdwForce->addParticle( ii, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00 ); + system.addParticle( 1.5995000e+01); + amoebaVdwForce->addParticle(ii, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaVdwForce->addParticle( ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01 ); + system.addParticle( 1.0080000e+00); + amoebaVdwForce->addParticle(ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01); } // exclusions std::vector< int > exclusions(3); - for( unsigned int ii = 0; ii < numberOfParticles; ii += 3 ){ + for (unsigned int ii = 0; ii < numberOfParticles; ii += 3) { exclusions[0] = ii; exclusions[1] = ii+1; exclusions[2] = ii+2; - amoebaVdwForce->setParticleExclusions( ii, exclusions ); - amoebaVdwForce->setParticleExclusions( ii+1, exclusions ); - amoebaVdwForce->setParticleExclusions( ii+2, exclusions ); + amoebaVdwForce->setParticleExclusions(ii, exclusions); + amoebaVdwForce->setParticleExclusions(ii+1, exclusions); + amoebaVdwForce->setParticleExclusions(ii+2, exclusions); } // end of Vdw setup @@ -578,661 +578,661 @@ void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, con std::vector positions(numberOfParticles); - positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02 ); - positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02 ); - positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02 ); - positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01 ); - positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01 ); - positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01 ); - positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01 ); - positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01 ); - positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01 ); - positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01 ); - positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01 ); - positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01 ); - positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01 ); - positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01 ); - positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01 ); - positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01 ); - positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01 ); - positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01 ); - positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01 ); - positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01 ); - positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01 ); - positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01 ); - positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01 ); - positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01 ); - positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01 ); - positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01 ); - positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02 ); - positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02 ); - positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01 ); - positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01 ); - positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01 ); - positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01 ); - positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01 ); - positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01 ); - positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01 ); - positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01 ); - positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01 ); - positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01 ); - positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01 ); - positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01 ); - positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01 ); - positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01 ); - positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01 ); - positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01 ); - positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01 ); - positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01 ); - positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01 ); - positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01 ); - positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01 ); - positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01 ); - positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01 ); - positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01 ); - positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01 ); - positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01 ); - positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01 ); - positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01 ); - positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01 ); - positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01 ); - positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01 ); - positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01 ); - positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01 ); - positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01 ); - positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01 ); - positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02 ); - positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02 ); - positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01 ); - positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02 ); - positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02 ); - positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01 ); - positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01 ); - positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01 ); - positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01 ); - positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01 ); - positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01 ); - positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01 ); - positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01 ); - positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02 ); - positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01 ); - positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01 ); - positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01 ); - positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01 ); - positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02 ); - positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01 ); - positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02 ); - positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01 ); - positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01 ); - positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01 ); - positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01 ); - positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01 ); - positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01 ); - positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01 ); - positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01 ); - positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01 ); - positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01 ); - positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01 ); - positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01 ); - positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01 ); - positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01 ); - positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01 ); - positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01 ); - positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01 ); - positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01 ); - positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01 ); - positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01 ); - positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01 ); - positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01 ); - positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01 ); - positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01 ); - positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01 ); - positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01 ); - positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01 ); - positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02 ); - positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02 ); - positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01 ); - positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01 ); - positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01 ); - positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01 ); - positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01 ); - positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01 ); - positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01 ); - positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01 ); - positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01 ); - positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01 ); - positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01 ); - positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02 ); - positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01 ); - positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01 ); - positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01 ); - positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01 ); - positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01 ); - positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01 ); - positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01 ); - positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01 ); - positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01 ); - positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01 ); - positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01 ); - positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01 ); - positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01 ); - positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01 ); - positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01 ); - positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01 ); - positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01 ); - positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01 ); - positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01 ); - positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01 ); - positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01 ); - positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01 ); - positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01 ); - positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01 ); - positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01 ); - positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01 ); - positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01 ); - positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01 ); - positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01 ); - positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01 ); - positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01 ); - positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02 ); - positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02 ); - positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02 ); - positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01 ); - positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02 ); - positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02 ); - positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01 ); - positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01 ); - positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01 ); - positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01 ); - positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01 ); - positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01 ); - positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01 ); - positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01 ); - positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01 ); - positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01 ); - positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01 ); - positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01 ); - positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01 ); - positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01 ); - positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01 ); - positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01 ); - positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01 ); - positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01 ); - positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01 ); - positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01 ); - positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01 ); - positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01 ); - positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01 ); - positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01 ); - positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02 ); - positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01 ); - positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03 ); - positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01 ); - positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01 ); - positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01 ); - positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01 ); - positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01 ); - positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01 ); - positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01 ); - positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01 ); - positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01 ); - positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01 ); - positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01 ); - positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01 ); - positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02 ); - positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01 ); - positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02 ); - positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01 ); - positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01 ); - positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01 ); - positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01 ); - positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01 ); - positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01 ); - positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01 ); - positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01 ); - positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01 ); - positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01 ); - positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01 ); - positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01 ); - positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01 ); - positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01 ); - positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01 ); - positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01 ); - positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01 ); - positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01 ); - positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01 ); - positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01 ); - positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01 ); - positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02 ); - positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01 ); - positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02 ); - positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01 ); - positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01 ); - positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01 ); - positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01 ); - positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01 ); - positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01 ); - positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01 ); - positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01 ); - positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01 ); - positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01 ); - positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01 ); - positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01 ); - positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01 ); - positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01 ); - positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01 ); - positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02 ); - positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01 ); - positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02 ); - positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01 ); - positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01 ); - positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01 ); - positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01 ); - positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01 ); - positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01 ); - positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01 ); - positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01 ); - positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01 ); - positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01 ); - positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01 ); - positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01 ); - positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01 ); - positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01 ); - positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01 ); - positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01 ); - positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01 ); - positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01 ); - positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03 ); - positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03 ); - positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02 ); - positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01 ); - positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01 ); - positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01 ); - positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01 ); - positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01 ); - positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01 ); - positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01 ); - positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01 ); - positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01 ); - positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01 ); - positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01 ); - positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01 ); - positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01 ); - positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01 ); - positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01 ); - positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01 ); - positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01 ); - positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01 ); - positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01 ); - positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01 ); - positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01 ); - positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02 ); - positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01 ); - positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02 ); - positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01 ); - positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01 ); - positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01 ); - positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01 ); - positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02 ); - positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02 ); - positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01 ); - positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01 ); - positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01 ); - positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01 ); - positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01 ); - positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01 ); - positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01 ); - positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01 ); - positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01 ); - positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01 ); - positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01 ); - positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01 ); - positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01 ); - positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01 ); - positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01 ); - positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01 ); - positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01 ); - positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01 ); - positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02 ); - positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01 ); - positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02 ); - positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01 ); - positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01 ); - positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01 ); - positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01 ); - positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01 ); - positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01 ); - positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01 ); - positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01 ); - positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01 ); - positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02 ); - positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02 ); - positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02 ); - positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01 ); - positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01 ); - positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01 ); - positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01 ); - positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01 ); - positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01 ); - positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01 ); - positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01 ); - positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01 ); - positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01 ); - positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01 ); - positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01 ); - positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02 ); - positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02 ); - positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02 ); - positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01 ); - positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01 ); - positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01 ); - positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01 ); - positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01 ); - positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01 ); - positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01 ); - positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01 ); - positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01 ); - positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01 ); - positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01 ); - positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01 ); - positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01 ); - positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01 ); - positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01 ); - positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01 ); - positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01 ); - positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01 ); - positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01 ); - positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02 ); - positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01 ); - positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01 ); - positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02 ); - positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01 ); - positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01 ); - positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01 ); - positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01 ); - positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01 ); - positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01 ); - positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01 ); - positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01 ); - positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01 ); - positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01 ); - positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02 ); - positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02 ); - positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02 ); - positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01 ); - positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01 ); - positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01 ); - positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01 ); - positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01 ); - positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01 ); - positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01 ); - positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01 ); - positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01 ); - positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01 ); - positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01 ); - positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01 ); - positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01 ); - positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01 ); - positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01 ); - positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01 ); - positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01 ); - positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01 ); - positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01 ); - positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01 ); - positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01 ); - positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01 ); - positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01 ); - positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01 ); - positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02 ); - positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01 ); - positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03 ); - positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01 ); - positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01 ); - positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01 ); - positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01 ); - positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01 ); - positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01 ); - positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03 ); - positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02 ); - positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03 ); - positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01 ); - positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01 ); - positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01 ); - positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01 ); - positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01 ); - positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01 ); - positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01 ); - positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01 ); - positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01 ); - positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01 ); - positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01 ); - positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01 ); - positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01 ); - positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01 ); - positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01 ); - positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01 ); - positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01 ); - positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01 ); - positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01 ); - positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01 ); - positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01 ); - positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01 ); - positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01 ); - positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01 ); - positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02 ); - positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02 ); - positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01 ); - positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01 ); - positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01 ); - positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01 ); - positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01 ); - positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01 ); - positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01 ); - positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01 ); - positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01 ); - positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01 ); - positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01 ); - positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01 ); - positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01 ); - positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01 ); - positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01 ); - positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01 ); - positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01 ); - positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01 ); - positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01 ); - positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01 ); - positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01 ); - positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01 ); - positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01 ); - positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01 ); - positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01 ); - positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01 ); - positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01 ); - positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01 ); - positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02 ); - positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03 ); - positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01 ); - positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01 ); - positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01 ); - positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01 ); - positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01 ); - positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01 ); - positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01 ); - positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01 ); - positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01 ); - positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01 ); - positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01 ); - positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01 ); - positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02 ); - positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01 ); - positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01 ); - positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01 ); - positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01 ); - positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01 ); - positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01 ); - positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01 ); - positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01 ); - positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01 ); - positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01 ); - positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01 ); - positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01 ); - positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01 ); - positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01 ); - positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01 ); - positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01 ); - positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01 ); - positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01 ); - positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01 ); - positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01 ); - positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01 ); - positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01 ); - positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01 ); - positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01 ); - positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01 ); - positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01 ); - positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01 ); - positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01 ); - positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01 ); - positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01 ); - positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01 ); - positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01 ); - positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01 ); - positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01 ); - positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01 ); - positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01 ); - positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01 ); - positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01 ); - positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01 ); - positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01 ); - positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01 ); - positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01 ); - positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01 ); - positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01 ); - positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01 ); - positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01 ); - positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01 ); - positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01 ); - positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01 ); - positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01 ); - positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01 ); - positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01 ); - positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01 ); - positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01 ); - positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01 ); - positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01 ); - positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01 ); - positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01 ); - positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01 ); - positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01 ); - positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01 ); - positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01 ); - positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01 ); - positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01 ); - positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01 ); - positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01 ); - positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02 ); - positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01 ); - positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02 ); - positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01 ); - positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01 ); - positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02 ); - positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02 ); - positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02 ); - positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02 ); - positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01 ); - positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01 ); - positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01 ); - positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01 ); - positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02 ); - positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02 ); - positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01 ); - positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01 ); - positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01 ); - positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01 ); - positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01 ); - positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01 ); - positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01 ); - positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01 ); - positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01 ); - positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02 ); - positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02 ); - positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02 ); - positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02 ); - positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02 ); - positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01 ); - positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01 ); - positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01 ); - positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01 ); - positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01 ); - positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01 ); - positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01 ); - positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01 ); - positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01 ); - positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01 ); - positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01 ); - positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01 ); - positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01 ); - positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01 ); - positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01 ); - positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01 ); - positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01 ); - positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01 ); - positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01 ); - positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01 ); - positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01 ); - positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01 ); - positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01 ); - positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01 ); - positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01 ); - positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01 ); - positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01 ); - positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01 ); - positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01 ); - positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01 ); - positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01 ); - positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01 ); - positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01 ); - positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01 ); - positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01 ); - positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01 ); - positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01 ); - positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01 ); - positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01 ); - positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01 ); - positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01 ); - positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01 ); - positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01 ); - positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01 ); - positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01 ); - positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01 ); - positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01 ); - positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01 ); - positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01 ); - positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01 ); - positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01 ); - positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01 ); - positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01 ); - positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01 ); - positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01 ); - positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01 ); - positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01 ); - positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01 ); - positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01 ); - positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01 ); - positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01 ); - positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01 ); - positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01 ); - positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01 ); - positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01 ); - positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01 ); - positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01 ); + positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); + positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); + positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); + positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); + positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); + positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); + positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01); + positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01); + positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01); + positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); + positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); + positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); + positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); + positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); + positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); + positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01); + positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01); + positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01); + positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01); + positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01); + positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01); + positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01); + positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01); + positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); + positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01); + positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01); + positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02); + positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02); + positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01); + positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01); + positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); + positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); + positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); + positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); + positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01); + positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); + positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); + positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); + positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01); + positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); + positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); + positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); + positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); + positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); + positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); + positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); + positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); + positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); + positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01); + positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01); + positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01); + positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01); + positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01); + positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01); + positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); + positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); + positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); + positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01); + positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01); + positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01); + positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); + positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); + positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); + positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02); + positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02); + positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01); + positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02); + positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02); + positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01); + positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01); + positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01); + positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01); + positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); + positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); + positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); + positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01); + positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02); + positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01); + positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); + positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); + positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); + positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); + positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); + positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); + positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01); + positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); + positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); + positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); + positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); + positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); + positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); + positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); + positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); + positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01); + positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01); + positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01); + positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); + positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); + positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); + positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); + positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); + positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); + positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01); + positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01); + positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01); + positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); + positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); + positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); + positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); + positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); + positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); + positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); + positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); + positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); + positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01); + positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01); + positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01); + positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01); + positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01); + positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01); + positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); + positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); + positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); + positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01); + positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02); + positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01); + positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01); + positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01); + positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01); + positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); + positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); + positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); + positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01); + positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01); + positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01); + positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01); + positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01); + positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01); + positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01); + positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01); + positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01); + positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); + positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); + positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); + positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); + positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); + positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); + positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); + positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); + positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); + positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01); + positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01); + positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01); + positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01); + positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01); + positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01); + positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02); + positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02); + positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); + positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); + positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); + positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); + positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); + positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); + positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); + positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); + positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); + positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); + positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); + positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01); + positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); + positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01); + positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01); + positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01); + positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); + positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); + positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); + positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01); + positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01); + positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01); + positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); + positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); + positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); + positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01); + positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01); + positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01); + positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02); + positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01); + positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03); + positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01); + positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01); + positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01); + positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); + positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); + positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); + positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); + positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01); + positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); + positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01); + positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01); + positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01); + positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); + positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); + positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); + positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); + positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); + positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); + positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01); + positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01); + positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01); + positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); + positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); + positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); + positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01); + positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01); + positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01); + positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); + positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); + positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); + positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); + positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01); + positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01); + positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); + positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); + positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); + positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); + positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); + positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); + positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01); + positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01); + positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01); + positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01); + positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01); + positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01); + positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); + positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); + positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); + positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01); + positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01); + positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01); + positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01); + positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01); + positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01); + positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); + positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); + positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); + positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01); + positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01); + positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01); + positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); + positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); + positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); + positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); + positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); + positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); + positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01); + positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01); + positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); + positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01); + positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01); + positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01); + positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01); + positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01); + positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01); + positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); + positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); + positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); + positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01); + positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01); + positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01); + positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); + positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); + positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); + positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); + positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); + positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); + positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); + positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); + positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); + positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01); + positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01); + positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01); + positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01); + positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01); + positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01); + positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01); + positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01); + positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01); + positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02); + positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01); + positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02); + positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01); + positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01); + positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01); + positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); + positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); + positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); + positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01); + positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); + positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01); + positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01); + positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01); + positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01); + positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01); + positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01); + positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01); + positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); + positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); + positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); + positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); + positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); + positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); + positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01); + positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01); + positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01); + positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02); + positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01); + positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02); + positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); + positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); + positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); + positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01); + positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01); + positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01); + positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01); + positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01); + positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01); + positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02); + positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02); + positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02); + positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01); + positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01); + positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01); + positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01); + positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01); + positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01); + positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01); + positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01); + positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01); + positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); + positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); + positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); + positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); + positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); + positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); + positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01); + positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01); + positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01); + positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); + positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); + positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); + positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01); + positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01); + positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01); + positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); + positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); + positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); + positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); + positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); + positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); + positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01); + positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01); + positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01); + positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01); + positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02); + positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01); + positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01); + positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02); + positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01); + positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01); + positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01); + positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01); + positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01); + positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01); + positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01); + positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); + positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); + positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); + positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); + positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); + positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); + positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); + positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); + positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); + positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); + positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); + positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); + positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01); + positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01); + positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01); + positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01); + positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01); + positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01); + positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); + positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); + positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); + positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01); + positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01); + positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01); + positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); + positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); + positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); + positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); + positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); + positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); + positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); + positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); + positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); + positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); + positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); + positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01); + positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); + positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); + positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); + positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); + positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); + positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); + positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01); + positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01); + positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01); + positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); + positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); + positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); + positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01); + positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01); + positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01); + positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); + positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); + positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); + positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01); + positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01); + positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01); + positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); + positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); + positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); + positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01); + positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01); + positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01); + positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); + positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); + positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); + positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02); + positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); + positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01); + positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); + positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); + positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); + positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); + positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); + positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); + positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01); + positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01); + positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01); + positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01); + positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01); + positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01); + positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); + positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); + positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); + positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01); + positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01); + positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01); + positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01); + positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01); + positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01); + positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01); + positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01); + positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01); + positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); + positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); + positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); + positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); + positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); + positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); + positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); + positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); + positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); + positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); + positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); + positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); + positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01); + positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01); + positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01); + positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01); + positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01); + positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02); + positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01); + positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01); + positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01); + positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); + positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); + positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); + positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01); + positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01); + positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01); + positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01); + positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01); + positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01); + positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01); + positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01); + positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01); + positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01); + positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01); + positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01); + positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01); + positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01); + positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01); + positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); + positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); + positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); + positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); + positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); + positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); + positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01); + positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01); + positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01); + positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01); + positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01); + positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01); + positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); + positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); + positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); + positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); + positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); + positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); + positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); + positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); + positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); + positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); + positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); + positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); + positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); + positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); + positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); + positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); + positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); + positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); + positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); + positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); + positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); + positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); + positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); + positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); + positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01); + positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01); + positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01); + positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01); + positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01); + positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01); + positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01); + positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01); + positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01); + positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); + positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); + positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); + positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01); + positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01); + positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02); + positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02); + positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02); + positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02); + positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01); + positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01); + positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01); + positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); + positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); + positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); + positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01); + positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01); + positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); + positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01); + positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01); + positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01); + positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01); + positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01); + positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01); + positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); + positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02); + positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); + positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02); + positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02); + positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01); + positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01); + positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01); + positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01); + positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); + positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); + positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); + positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); + positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); + positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); + positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01); + positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01); + positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01); + positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01); + positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01); + positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01); + positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01); + positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01); + positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01); + positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); + positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); + positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); + positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01); + positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01); + positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01); + positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); + positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); + positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); + positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); + positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); + positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); + positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01); + positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01); + positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01); + positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); + positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); + positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); + positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01); + positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01); + positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01); + positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01); + positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01); + positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01); + positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); + positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); + positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); + positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); + positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); + positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); + positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01); + positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01); + positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01); + positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); + positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); + positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); + positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); + positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); + positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); + positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01); + positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01); + positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01); + positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); + positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); + positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); + positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01); + positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01); + positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01); system.addForce(amoebaVdwForce); std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -1242,11 +1242,11 @@ void setupAndGetForcesEnergyVdwWater( const std::string& sigmaCombiningRule, con // test employing box of 216 water molecules w/ and w/o dispersion correction -void testVdwWater( int includeVdwDispersionCorrection ) { +void testVdwWater(int includeVdwDispersionCorrection) { std::string testName; - if( includeVdwDispersionCorrection ){ + if (includeVdwDispersionCorrection) { testName = "testVdwWaterWithDispersionCorrection"; } else { testName = "testVdwWater"; @@ -1258,697 +1258,697 @@ void testVdwWater( int includeVdwDispersionCorrection ) { std::vector forces; double energy; - setupAndGetForcesEnergyVdwWater( "CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy ); + setupAndGetForcesEnergyVdwWater("CUBIC-MEAN", "HHG", cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy); std::vector expectedForces(numberOfParticles); // initialize expected energy and forces double expectedEnergy; - if( includeVdwDispersionCorrection ){ + if (includeVdwDispersionCorrection) { expectedEnergy = 4.0108819792e+03; } else { expectedEnergy = 4.0349101e+03; } - expectedForces[0] = Vec3( 2.3025909e+02, -1.0422757e+01, -2.1413965e+02 ); - expectedForces[1] = Vec3( 1.1261936e+02, 5.5882575e+02, 9.6539143e+01 ); - expectedForces[2] = Vec3( -8.8436857e+01, -4.4737313e+01, 2.5242022e+02 ); - expectedForces[3] = Vec3( 6.3548886e+02, -1.9582636e+02, -1.2229882e+02 ); - expectedForces[4] = Vec3( -3.9513809e+02, -1.3738635e+02, -1.2488717e+02 ); - expectedForces[5] = Vec3( 6.8771170e+00, 9.1574345e+01, -1.3865672e+00 ); - expectedForces[6] = Vec3( 3.6928792e+02, -7.1025648e+01, 5.2550320e+02 ); - expectedForces[7] = Vec3( 1.5531325e+02, -7.9256260e+02, 3.8119809e+02 ); - expectedForces[8] = Vec3( 1.5408049e+02, 1.4633285e+02, -5.4573735e+02 ); - expectedForces[9] = Vec3( -3.2549641e+02, 2.8613802e+01, 1.8082150e+02 ); - expectedForces[10] = Vec3( 1.9968249e+02, -7.7742415e+01, -4.2188467e+02 ); - expectedForces[11] = Vec3( 4.6645952e+01, 2.1362909e+01, 5.7120135e+01 ); - expectedForces[12] = Vec3( 4.2971265e+01, -4.2927865e+01, -7.6319121e+02 ); - expectedForces[13] = Vec3( 2.1889551e+02, -5.1806784e+01, 7.6637073e+01 ); - expectedForces[14] = Vec3( -3.0028991e+02, 9.0479382e+01, 1.3199449e+02 ); - expectedForces[15] = Vec3( -1.8041801e+00, -1.2176813e+03, -5.9679371e+02 ); - expectedForces[16] = Vec3( -1.4773339e+02, -1.2582057e+02, 8.4242040e+02 ); - expectedForces[17] = Vec3( 6.8633312e+02, -2.4864325e+01, 1.0675519e+01 ); - expectedForces[18] = Vec3( 4.8211733e+02, -2.2044742e+02, 1.8105309e+02 ); - expectedForces[19] = Vec3( -2.1956736e+02, 5.4786741e+02, -1.4827263e+02 ); - expectedForces[20] = Vec3( -1.0476100e+02, -1.6922280e+02, 8.3220473e+01 ); - expectedForces[21] = Vec3( 5.5455350e+01, 1.7851224e+02, 6.0598643e+02 ); - expectedForces[22] = Vec3( 7.1915871e+00, -1.6455057e+01, -6.3929797e+00 ); - expectedForces[23] = Vec3( -2.4371864e+02, -7.0765288e+02, -1.7820148e+02 ); - expectedForces[24] = Vec3( -4.3715367e+02, 2.8707226e+02, 2.2558361e+02 ); - expectedForces[25] = Vec3( 2.3735557e+00, -4.2064130e+00, 2.5933632e+01 ); - expectedForces[26] = Vec3( 1.0192415e+02, 5.3205842e+01, -2.0158900e+02 ); - expectedForces[27] = Vec3( -5.1276812e+02, 2.4860179e+02, 2.5150125e+02 ); - expectedForces[28] = Vec3( 3.9608987e+02, -4.0544816e+01, -2.1579831e+02 ); - expectedForces[29] = Vec3( -2.5926005e+02, -1.1691294e+02, -4.7278417e+02 ); - expectedForces[30] = Vec3( -1.1036158e+02, 3.3229287e+01, 8.8351491e+01 ); - expectedForces[31] = Vec3( -4.1178603e+00, 1.2957632e+00, 1.2617868e+00 ); - expectedForces[32] = Vec3( 1.9401524e+02, 1.0030314e+02, 3.0386141e+01 ); - expectedForces[33] = Vec3( 1.0870981e+02, 2.1865882e+02, 6.7672725e+02 ); - expectedForces[34] = Vec3( 3.6812338e+01, -2.9347382e-01, 1.2959790e+01 ); - expectedForces[35] = Vec3( -5.5738560e+01, 2.2268442e+02, -1.4911862e+02 ); - expectedForces[36] = Vec3( -1.6659719e+02, 8.1941190e+01, 7.8132996e+01 ); - expectedForces[37] = Vec3( -1.1985659e+02, 7.1891763e+01, -3.2559738e+02 ); - expectedForces[38] = Vec3( 1.4441653e+02, 4.1824194e+02, 3.4293255e+01 ); - expectedForces[39] = Vec3( 1.1307312e+02, -3.4981802e+02, -1.0676819e+02 ); - expectedForces[40] = Vec3( -1.2857487e+02, -4.0798950e+01, -1.7800009e+02 ); - expectedForces[41] = Vec3( -4.1244991e+02, 2.3439565e+02, 3.8546709e+02 ); - expectedForces[42] = Vec3( 2.1799653e+02, 2.9397348e+02, -3.8955146e+02 ); - expectedForces[43] = Vec3( -9.4254462e+01, 5.0157547e+01, 1.3707146e+02 ); - expectedForces[44] = Vec3( 8.0520929e+02, -1.0228045e+03, -4.5813594e+01 ); - expectedForces[45] = Vec3( 5.3451125e+02, -7.0725115e+02, -2.3828883e+02 ); - expectedForces[46] = Vec3( 3.6991801e+02, -1.0410466e+03, 8.4889413e+02 ); - expectedForces[47] = Vec3( 5.8096458e+01, 2.3859368e+02, 7.3104979e+01 ); - expectedForces[48] = Vec3( -1.3230378e+03, 7.1827816e+02, 9.4372946e+02 ); - expectedForces[49] = Vec3( -4.2398413e+02, -3.6766481e+02, -1.6666711e+02 ); - expectedForces[50] = Vec3( 8.6374766e+00, -2.7870227e+02, 3.0621233e+02 ); - expectedForces[51] = Vec3( -2.4404981e+02, 1.0510491e+03, -3.5202340e+02 ); - expectedForces[52] = Vec3( 1.7461155e+02, 1.3419948e+02, 5.0279733e+02 ); - expectedForces[53] = Vec3( 9.7089193e+01, -1.4826120e+02, -2.3426711e+02 ); - expectedForces[54] = Vec3( -1.0647432e+02, 2.3266543e+02, -3.5025025e+02 ); - expectedForces[55] = Vec3( -1.9951717e+02, -1.0804258e+02, 6.2114265e+01 ); - expectedForces[56] = Vec3( 2.5354284e+02, -3.5074926e+02, -2.9176946e+01 ); - expectedForces[57] = Vec3( -8.8328002e+02, -1.8937053e+02, 2.0772189e+02 ); - expectedForces[58] = Vec3( 4.5809698e+01, -1.8636513e+00, 1.6742910e+01 ); - expectedForces[59] = Vec3( 8.6670673e+01, 1.2653519e+02, 2.0046372e+02 ); - expectedForces[60] = Vec3( -9.6142275e+02, 1.1800289e+03, 1.0064471e+02 ); - expectedForces[61] = Vec3( -6.9751453e+01, -1.9324691e+02, 2.2638891e+01 ); - expectedForces[62] = Vec3( 1.3671815e+02, 1.0129231e+01, -6.1136892e+01 ); - expectedForces[63] = Vec3( 7.6032938e+02, -1.9779542e+02, -2.5706161e+01 ); - expectedForces[64] = Vec3( -9.8966607e+00, 3.6294058e+02, -2.3247376e+02 ); - expectedForces[65] = Vec3( -1.3142673e+02, 9.9368000e+00, 1.4225069e+02 ); - expectedForces[66] = Vec3( 5.2691625e+01, -4.0618331e+02, -1.0942115e+02 ); - expectedForces[67] = Vec3( 5.8137742e+01, 2.1942441e+02, -1.7191686e+02 ); - expectedForces[68] = Vec3( 1.2480778e+02, 2.4086799e+01, -1.9588545e+02 ); - expectedForces[69] = Vec3( 2.4577512e+02, -2.3516051e+01, 2.3764379e+02 ); - expectedForces[70] = Vec3( 4.2298797e+01, 8.6807583e+01, 2.9276129e+02 ); - expectedForces[71] = Vec3( 3.0309915e+01, -3.4686002e+02, 1.0849989e+02 ); - expectedForces[72] = Vec3( 5.5170999e+02, -1.5797913e+02, 9.8379834e+01 ); - expectedForces[73] = Vec3( -5.3706921e+02, 2.2236470e+02, 2.7548665e+02 ); - expectedForces[74] = Vec3( -2.7734936e+02, -4.2949693e+02, -8.2303469e+02 ); - expectedForces[75] = Vec3( 1.1749001e+03, 9.2734627e+02, -2.6342291e+02 ); - expectedForces[76] = Vec3( -1.2345216e+02, -6.6220297e+01, 1.1022778e+02 ); - expectedForces[77] = Vec3( -4.4861284e+01, -7.4560959e+01, -8.0791275e+01 ); - expectedForces[78] = Vec3( 1.7692476e+01, -9.9067626e+02, -3.3083363e+02 ); - expectedForces[79] = Vec3( 6.4276566e+01, 5.1865608e+02, 4.1241764e+02 ); - expectedForces[80] = Vec3( 6.5867999e+02, 2.0995465e+02, -5.0989840e+02 ); - expectedForces[81] = Vec3( -5.2826435e+02, -1.3719887e+02, 1.9730314e+02 ); - expectedForces[82] = Vec3( 2.3329314e+02, 5.1589944e+01, -3.3942818e+02 ); - expectedForces[83] = Vec3( -2.5756193e+00, 1.3788257e+02, 1.3074778e+02 ); - expectedForces[84] = Vec3( -2.8925811e+01, 8.8185346e+01, 1.1547804e+02 ); - expectedForces[85] = Vec3( -3.3582542e+01, -1.3079843e+02, 3.4774799e+02 ); - expectedForces[86] = Vec3( -5.9585326e+01, -3.7973755e+01, 1.0206767e+01 ); - expectedForces[87] = Vec3( -7.1691223e+01, -1.9547311e+02, 9.3856472e+02 ); - expectedForces[88] = Vec3( 1.4832977e+02, 4.2005795e+02, 2.7235044e+01 ); - expectedForces[89] = Vec3( 8.6221698e+00, -1.3935906e+01, -2.5473157e+00 ); - expectedForces[90] = Vec3( 3.0044348e+02, 3.4320406e+02, 2.5305998e+02 ); - expectedForces[91] = Vec3( -1.6694013e+02, 7.4645776e+02, 3.3266168e+01 ); - expectedForces[92] = Vec3( 1.6931562e+02, -2.3972286e+01, -3.0802865e+02 ); - expectedForces[93] = Vec3( -2.5931152e+02, -9.7825375e+01, -5.5598386e+02 ); - expectedForces[94] = Vec3( -7.8473519e+01, -2.6244561e+02, 2.9622027e+02 ); - expectedForces[95] = Vec3( 1.5788473e+02, 2.9806605e+02, 1.8283700e+02 ); - expectedForces[96] = Vec3( -4.2033208e+02, 4.8745845e+02, 9.7957219e+01 ); - expectedForces[97] = Vec3( 1.3261733e+00, 3.7143158e+00, -1.8329960e+00 ); - expectedForces[98] = Vec3( 7.4741051e+02, 1.0482696e+03, 1.7182445e+02 ); - expectedForces[99] = Vec3( 2.0366606e+02, 1.1586652e+02, 1.5482927e+03 ); - expectedForces[100] = Vec3( 5.7569884e+02, -2.2068597e+02, -1.9305186e+02 ); - expectedForces[101] = Vec3( -2.4259775e+02, -6.1359858e+01, -7.5753918e+01 ); - expectedForces[102] = Vec3( 2.4382837e+02, 1.3660693e+01, -2.8717824e+02 ); - expectedForces[103] = Vec3( -4.1914381e+02, -1.4506334e+02, 7.7692658e+01 ); - expectedForces[104] = Vec3( 9.5422158e+01, -1.4261849e+01, 1.0122453e+02 ); - expectedForces[105] = Vec3( -6.1222151e+02, 6.1398147e+01, 3.2961693e+02 ); - expectedForces[106] = Vec3( -2.7982116e+02, -3.7564793e+02, -2.4318658e+02 ); - expectedForces[107] = Vec3( 8.2892383e+01, 1.1992522e+01, 2.4802899e+01 ); - expectedForces[108] = Vec3( -3.3626753e+02, -7.8892295e+01, 8.1184535e+02 ); - expectedForces[109] = Vec3( -4.6396103e+01, 3.1165111e+01, -3.5184949e+01 ); - expectedForces[110] = Vec3( 4.6295297e+02, -8.0135823e+01, -3.2963637e+02 ); - expectedForces[111] = Vec3( 5.5325945e+02, 3.8213691e+02, -5.9449911e+02 ); - expectedForces[112] = Vec3( -6.1770559e+02, 2.2322880e+02, -2.1022934e+01 ); - expectedForces[113] = Vec3( 2.3716825e+02, -3.8085281e+02, 4.9618193e+02 ); - expectedForces[114] = Vec3( 2.9972570e+02, 3.3773759e+02, 3.4933501e+02 ); - expectedForces[115] = Vec3( 1.9913039e+02, -3.2035626e+02, -9.7987777e+01 ); - expectedForces[116] = Vec3( -2.3506456e+02, 4.0030561e+02, -6.2604809e+02 ); - expectedForces[117] = Vec3( 6.0408777e+02, 5.6271523e+02, -5.8742635e+02 ); - expectedForces[118] = Vec3( -5.0707285e+02, 7.8511351e+02, -1.7561830e+02 ); - expectedForces[119] = Vec3( 5.6759945e+00, 6.9735233e+00, -9.8853787e+00 ); - expectedForces[120] = Vec3( 1.1918531e+02, -5.6200785e+02, 3.2333502e+02 ); - expectedForces[121] = Vec3( 5.1801315e+02, -3.4460898e+02, 1.1488242e+02 ); - expectedForces[122] = Vec3( 7.5859703e+00, 6.9528951e+01, -6.2437444e+00 ); - expectedForces[123] = Vec3( 1.1990899e+03, -1.2507886e+01, 1.1906562e+03 ); - expectedForces[124] = Vec3( 2.6001536e+02, -9.5041373e+01, -4.2547252e+02 ); - expectedForces[125] = Vec3( -3.5601586e+01, 9.1460220e+02, 6.2306102e+02 ); - expectedForces[126] = Vec3( -3.8254176e+01, 2.4796243e+02, 3.0638741e+02 ); - expectedForces[127] = Vec3( -3.8798311e+02, 1.2532794e+02, -3.1926601e+01 ); - expectedForces[128] = Vec3( 5.7672682e+01, 1.7487900e+02, -1.0319581e+02 ); - expectedForces[129] = Vec3( 4.4276215e+02, -1.5517993e+02, 3.8122873e+02 ); - expectedForces[130] = Vec3( -2.8119980e+02, -2.6530936e+02, 4.3545814e+01 ); - expectedForces[131] = Vec3( 5.9375768e+00, 1.6335780e+01, -3.6204644e+02 ); - expectedForces[132] = Vec3( 5.9733834e+02, -2.9843602e+02, 1.0541092e+03 ); - expectedForces[133] = Vec3( -3.4568461e+02, 2.2794808e+02, -8.4675886e+01 ); - expectedForces[134] = Vec3( -6.7882706e+01, -4.5016799e+02, -1.9387646e+02 ); - expectedForces[135] = Vec3( 5.6125478e+02, -1.1741092e+03, 1.4214256e+02 ); - expectedForces[136] = Vec3( 1.2766648e+02, 1.2519441e+02, -4.4359129e+02 ); - expectedForces[137] = Vec3( -2.7235507e+01, -1.0871423e+01, 3.2406976e+01 ); - expectedForces[138] = Vec3( -1.2110689e+03, 1.3038667e+02, -7.5331947e+02 ); - expectedForces[139] = Vec3( 3.2504988e+02, -7.1577942e+02, -2.4351454e+02 ); - expectedForces[140] = Vec3( 2.6466925e+02, 3.6878498e+02, -6.2044711e+01 ); - expectedForces[141] = Vec3( -6.2647276e+02, -4.7112562e+02, -6.1885184e+01 ); - expectedForces[142] = Vec3( 3.0996699e+01, 3.1033732e+02, -5.7493337e+02 ); - expectedForces[143] = Vec3( 2.4664962e+01, 7.8306665e+02, 3.7907751e+02 ); - expectedForces[144] = Vec3( -1.9847551e+02, -3.0052499e+02, -6.5192951e+01 ); - expectedForces[145] = Vec3( -5.0686773e+02, 1.1972933e+02, 3.6202910e+02 ); - expectedForces[146] = Vec3( 4.0004521e+02, -4.3205645e+02, 2.8583074e+02 ); - expectedForces[147] = Vec3( -2.9447542e+01, 6.3434099e+02, -6.5189179e+02 ); - expectedForces[148] = Vec3( 4.1588516e+02, -1.5534873e+02, -1.1031323e+01 ); - expectedForces[149] = Vec3( 1.2761543e+01, -5.6871456e+01, 2.8032565e+02 ); - expectedForces[150] = Vec3( -4.7527199e+01, 6.2549647e+02, -8.5007589e+02 ); - expectedForces[151] = Vec3( 1.6598949e+01, 1.1210199e+02, 2.0667266e+02 ); - expectedForces[152] = Vec3( -2.4012423e+00, -6.1728962e+01, -1.5057977e+01 ); - expectedForces[153] = Vec3( -3.6934056e+02, 2.3087063e+02, -3.3268511e+02 ); - expectedForces[154] = Vec3( 1.2658460e+02, 4.1809355e+02, 1.9550635e+02 ); - expectedForces[155] = Vec3( -1.9528152e+02, -1.9035919e+02, 1.4986704e+02 ); - expectedForces[156] = Vec3( -5.9608803e+00, 2.7258190e+02, 5.5318395e+02 ); - expectedForces[157] = Vec3( -1.0545084e+01, -1.8397001e+00, -3.3615498e+00 ); - expectedForces[158] = Vec3( -4.0827462e+02, -6.4070993e+01, -2.6614992e+02 ); - expectedForces[159] = Vec3( -1.5773827e+02, 4.7708702e+02, -9.9622711e+02 ); - expectedForces[160] = Vec3( 8.3896122e+01, 2.5959601e+02, 1.7728081e+02 ); - expectedForces[161] = Vec3( -2.4859055e+02, 8.1617294e+01, 2.7905586e+02 ); - expectedForces[162] = Vec3( 1.3694593e+02, -6.2640483e+02, -2.5308878e+02 ); - expectedForces[163] = Vec3( -1.5156337e+02, 1.1567379e+02, 1.8384602e+02 ); - expectedForces[164] = Vec3( -1.4794785e+02, -8.0381965e+01, 9.4028021e+02 ); - expectedForces[165] = Vec3( -3.5851252e+02, 2.6066489e+02, -4.1225343e+01 ); - expectedForces[166] = Vec3( 1.0820389e+02, -8.3485138e+01, 9.5047812e+01 ); - expectedForces[167] = Vec3( 2.0019411e+02, 5.0864719e+02, -4.8662239e+01 ); - expectedForces[168] = Vec3( -3.0716707e+02, -9.8820762e+02, 1.3660536e+01 ); - expectedForces[169] = Vec3( 8.5788590e+02, -1.0335921e+02, -2.2197815e+02 ); - expectedForces[170] = Vec3( 9.8072705e+00, 6.6224870e+02, -1.1594055e+02 ); - expectedForces[171] = Vec3( -3.6572453e+01, 2.4062731e+02, 1.7831682e+02 ); - expectedForces[172] = Vec3( -2.1274187e+00, -2.5471785e+02, -2.5813525e+02 ); - expectedForces[173] = Vec3( 3.4763673e+02, -2.0753062e+02, 7.5125390e+02 ); - expectedForces[174] = Vec3( 2.9010685e+01, -4.1894498e+02, -6.3847846e+02 ); - expectedForces[175] = Vec3( 3.0255245e+02, 2.5945698e+02, 2.3530662e+01 ); - expectedForces[176] = Vec3( -2.0827676e+01, 2.2568888e+01, 1.0890440e+01 ); - expectedForces[177] = Vec3( 2.2415739e+02, 3.5720682e+02, -8.7208211e+01 ); - expectedForces[178] = Vec3( -2.9808276e+02, 7.0108444e+01, -1.5361211e+02 ); - expectedForces[179] = Vec3( 2.3882234e+02, -2.6764176e+02, -1.7847229e+01 ); - expectedForces[180] = Vec3( -4.7380966e+02, 5.2547306e+01, 7.4446526e+02 ); - expectedForces[181] = Vec3( 4.2804072e+00, -2.2456284e+02, -2.0288206e+02 ); - expectedForces[182] = Vec3( 2.5474630e+00, 2.5211778e+01, 1.2675317e+01 ); - expectedForces[183] = Vec3( -1.4519676e+02, -1.7268277e+02, -8.4750014e+02 ); - expectedForces[184] = Vec3( -1.6850633e+02, 9.5223081e+02, -2.5415253e+02 ); - expectedForces[185] = Vec3( -2.1600185e+02, -1.6313340e+02, 1.8746411e+02 ); - expectedForces[186] = Vec3( 4.5719348e+01, -5.8877840e+01, -1.1199622e+02 ); - expectedForces[187] = Vec3( -9.0377199e+01, 2.2045926e+02, -3.2532356e+02 ); - expectedForces[188] = Vec3( -1.4523032e+02, -2.2127499e+02, 1.1526636e+02 ); - expectedForces[189] = Vec3( 1.9857975e+02, -1.8170037e+02, 3.2016150e+02 ); - expectedForces[190] = Vec3( 1.5659789e+02, 5.2984420e+01, -1.0121553e+02 ); - expectedForces[191] = Vec3( 1.3925504e+01, -1.1627739e+02, 1.7106106e+00 ); - expectedForces[192] = Vec3( 1.7560737e+01, 3.1275548e+02, 1.4568181e+02 ); - expectedForces[193] = Vec3( 8.5129168e-01, 3.2688468e+01, -2.0471785e+02 ); - expectedForces[194] = Vec3( 2.5640904e+02, -1.8345358e+02, 3.3082812e+02 ); - expectedForces[195] = Vec3( 1.5159266e+02, -7.9091822e+02, 7.6475475e+02 ); - expectedForces[196] = Vec3( 7.8546101e+02, 1.7887845e+02, -7.4508377e+01 ); - expectedForces[197] = Vec3( 6.9010029e+00, 2.1336674e+01, -7.8256484e+01 ); - expectedForces[198] = Vec3( -3.4033432e+01, -1.6471994e+02, -2.8721884e+02 ); - expectedForces[199] = Vec3( -1.2248359e+02, 5.3002993e+01, 3.5296174e+02 ); - expectedForces[200] = Vec3( 1.7497881e+02, 1.1744848e+02, 1.8127502e+02 ); - expectedForces[201] = Vec3( -1.1710882e+03, 8.7114752e+02, -1.3353036e+02 ); - expectedForces[202] = Vec3( 2.7510368e+02, -1.9393814e+02, 2.6671453e+02 ); - expectedForces[203] = Vec3( 7.3421287e+01, -3.8409917e+01, -1.0910368e+02 ); - expectedForces[204] = Vec3( -8.7394869e+02, -1.2323430e+03, -1.3693068e+02 ); - expectedForces[205] = Vec3( 2.5439149e+02, 2.4002077e+02, 3.0231859e+02 ); - expectedForces[206] = Vec3( -9.8167431e+01, 3.1515278e+02, -2.5512038e+02 ); - expectedForces[207] = Vec3( 2.7501189e+02, -4.9189774e+02, 4.5827877e+02 ); - expectedForces[208] = Vec3( -8.2333908e+02, -7.0609881e+02, 2.9188070e+02 ); - expectedForces[209] = Vec3( -2.9200330e+02, 1.9955124e+02, -7.9227826e+00 ); - expectedForces[210] = Vec3( 8.0151971e+02, 3.8996996e+02, -1.9508756e+02 ); - expectedForces[211] = Vec3( -6.2168096e+01, 2.4323951e+01, 9.8845638e+01 ); - expectedForces[212] = Vec3( 2.2980428e+01, -6.2829693e+02, -7.5253154e+02 ); - expectedForces[213] = Vec3( -5.7502634e+02, 8.2310635e+02, 3.7934867e+02 ); - expectedForces[214] = Vec3( -8.9168889e+01, 5.0052167e+01, -8.6850564e+01 ); - expectedForces[215] = Vec3( 2.7414821e+02, -5.9725191e+01, -3.7278778e+00 ); - expectedForces[216] = Vec3( -5.3230933e+02, 4.7698725e+02, -2.5857751e+02 ); - expectedForces[217] = Vec3( 2.1615644e+02, 6.0001233e+01, -1.1880182e+02 ); - expectedForces[218] = Vec3( 2.9837823e+01, -3.9275454e+01, -4.3913571e+01 ); - expectedForces[219] = Vec3( -5.6516561e+02, -1.6539113e+02, 3.3185872e+02 ); - expectedForces[220] = Vec3( -1.5484833e+01, -1.0085566e+01, -2.8199778e+01 ); - expectedForces[221] = Vec3( 6.4295337e+02, -2.7398997e+02, 8.2320867e+02 ); - expectedForces[222] = Vec3( 3.3816540e+02, -1.8492046e+02, 8.6215770e+02 ); - expectedForces[223] = Vec3( 2.4367872e+02, 8.9527142e+01, -5.9973680e+02 ); - expectedForces[224] = Vec3( -6.1601439e+02, -5.3093862e+02, 4.1696221e+01 ); - expectedForces[225] = Vec3( 2.2521478e+02, -2.9234267e+02, 2.9760244e+02 ); - expectedForces[226] = Vec3( -1.2672295e+02, 2.5753736e+01, -1.6216252e+02 ); - expectedForces[227] = Vec3( 1.1136724e+02, 4.3446676e+00, -1.4045447e+01 ); - expectedForces[228] = Vec3( 3.5554849e+02, 7.7446255e+00, 5.8722356e+02 ); - expectedForces[229] = Vec3( -7.8313952e+02, -5.9206053e+01, 5.1181391e+02 ); - expectedForces[230] = Vec3( -9.5647729e+01, -4.6045792e+02, -3.1515210e+02 ); - expectedForces[231] = Vec3( 8.7273284e+01, 8.0310279e+02, -1.2212040e+03 ); - expectedForces[232] = Vec3( -9.0853819e+02, -7.6005570e+02, 1.8578569e+02 ); - expectedForces[233] = Vec3( 1.2061615e+02, -3.2834560e+02, 5.1291192e+01 ); - expectedForces[234] = Vec3( 6.0149262e+02, 1.6081852e+03, -1.0922015e+03 ); - expectedForces[235] = Vec3( -5.8087260e+01, -2.6676779e+02, -1.5006920e+02 ); - expectedForces[236] = Vec3( -1.0997771e+01, 1.3012815e+02, 5.8615633e+02 ); - expectedForces[237] = Vec3( 4.9821503e+02, -9.5783644e+01, -6.5708073e+02 ); - expectedForces[238] = Vec3( -4.9394992e+02, -7.0445435e+02, -1.5540228e+02 ); - expectedForces[239] = Vec3( 1.5710340e+01, 1.9170336e+02, 4.6707393e+02 ); - expectedForces[240] = Vec3( -1.2599557e+03, 5.6104975e+02, 6.5853210e+02 ); - expectedForces[241] = Vec3( 1.3032986e+01, -2.7481865e+01, 8.0373029e+00 ); - expectedForces[242] = Vec3( 1.4371505e+02, -5.2615293e+01, -3.7929456e+02 ); - expectedForces[243] = Vec3( 6.0025739e+01, 1.4474905e+02, 3.6414330e+02 ); - expectedForces[244] = Vec3( 4.5364033e+02, 7.0785823e+01, -2.9279112e+02 ); - expectedForces[245] = Vec3( -9.7012956e+01, -8.2545229e+01, -5.4567106e+01 ); - expectedForces[246] = Vec3( -3.6449281e+02, -5.6669832e+02, -3.5196038e+02 ); - expectedForces[247] = Vec3( 2.6571354e+02, -2.5051716e+02, -4.7199161e+01 ); - expectedForces[248] = Vec3( -4.7285701e+01, 1.7950093e+02, 8.0633971e+01 ); - expectedForces[249] = Vec3( 1.8035439e+02, 4.6977540e+02, 2.2589769e+02 ); - expectedForces[250] = Vec3( 5.9853399e+01, 1.5477006e+02, -1.7011806e+02 ); - expectedForces[251] = Vec3( -2.6084741e+02, -2.0538756e+02, 1.0269002e+02 ); - expectedForces[252] = Vec3( 4.0221722e+02, -1.0368371e+02, -1.3842460e+01 ); - expectedForces[253] = Vec3( -4.4264447e+02, -3.0334810e+02, 1.6740779e+02 ); - expectedForces[254] = Vec3( -1.7373662e+02, 1.5020202e+02, -3.3761418e+02 ); - expectedForces[255] = Vec3( 4.7508953e+01, -5.4028784e+02, -3.6291329e+01 ); - expectedForces[256] = Vec3( 5.4807168e+02, -2.0293664e+02, 5.5114363e+02 ); - expectedForces[257] = Vec3( -4.9787370e+01, 4.5106329e+01, -5.7524550e+01 ); - expectedForces[258] = Vec3( -5.1584935e+02, 1.5014186e+02, -6.6369834e+02 ); - expectedForces[259] = Vec3( -6.0140298e+01, -9.4127280e+01, 8.7495796e+01 ); - expectedForces[260] = Vec3( 8.0619588e+02, -2.1066454e+02, -5.9371508e+01 ); - expectedForces[261] = Vec3( 1.2817429e+02, -2.7044116e+02, 5.3213275e+02 ); - expectedForces[262] = Vec3( -4.1467442e-01, -1.3641138e+02, -8.5576287e+01 ); - expectedForces[263] = Vec3( -5.6508528e+01, 2.4091504e+01, -7.9236147e+01 ); - expectedForces[264] = Vec3( 1.4123799e+02, 2.1326444e+02, 1.9141445e+02 ); - expectedForces[265] = Vec3( 1.6579721e+02, -3.2221503e+02, -1.5197776e+02 ); - expectedForces[266] = Vec3( -2.5871222e+02, -2.6345996e+02, -1.1149413e+03 ); - expectedForces[267] = Vec3( -1.2859743e+02, -3.9214753e+02, -6.5874862e+02 ); - expectedForces[268] = Vec3( 1.7237157e+02, -2.8729010e+02, 3.2000889e+02 ); - expectedForces[269] = Vec3( 6.6312203e+02, 3.5683926e+02, 9.7235616e+01 ); - expectedForces[270] = Vec3( -1.1860349e+02, -4.3528895e+02, 1.1598672e+03 ); - expectedForces[271] = Vec3( 7.7135123e+01, -2.1671305e+02, -2.3088548e+02 ); - expectedForces[272] = Vec3( 7.2863708e+01, 5.2065158e+02, 1.5704752e+02 ); - expectedForces[273] = Vec3( -3.6727477e+02, -6.0885463e+01, 4.1193960e+01 ); - expectedForces[274] = Vec3( 5.4858881e+01, 1.6886577e+02, -1.1662392e+01 ); - expectedForces[275] = Vec3( 3.2070061e+01, -1.6138709e+01, -7.6648912e+00 ); - expectedForces[276] = Vec3( 2.5695892e+02, 7.7719531e+01, -8.3154765e+02 ); - expectedForces[277] = Vec3( -3.3460202e+01, -1.3077348e+02, 3.6110539e+01 ); - expectedForces[278] = Vec3( -4.1360402e+02, 2.7754335e+02, -1.1139467e+02 ); - expectedForces[279] = Vec3( 1.0012775e+02, 1.4365237e+03, 2.6972544e+02 ); - expectedForces[280] = Vec3( 7.8750024e+02, -2.3376123e+02, 9.5969232e+02 ); - expectedForces[281] = Vec3( -2.2493912e+02, -1.1444344e+01, -6.3713547e+01 ); - expectedForces[282] = Vec3( -9.4211966e+01, -3.9286586e+02, -7.0932607e+01 ); - expectedForces[283] = Vec3( 1.6192138e+02, 2.3010404e+02, -2.1511498e+02 ); - expectedForces[284] = Vec3( -4.9644702e+02, -1.1894844e+01, -4.7458477e+02 ); - expectedForces[285] = Vec3( -1.0151600e+02, -4.2789293e+02, 5.2698223e+02 ); - expectedForces[286] = Vec3( 1.1350409e+01, 1.5126445e+02, -5.2740587e+01 ); - expectedForces[287] = Vec3( -4.7715521e+02, -3.6476152e+02, -5.4346958e+02 ); - expectedForces[288] = Vec3( -9.4019721e+01, -2.4758228e+02, 4.2219712e+02 ); - expectedForces[289] = Vec3( 3.1525053e+01, 3.7927245e+02, -2.4577041e+02 ); - expectedForces[290] = Vec3( 4.4004025e+02, -9.4883983e+01, -6.9075632e+01 ); - expectedForces[291] = Vec3( -2.6553328e+02, -2.7059185e+02, 3.1145935e+02 ); - expectedForces[292] = Vec3( 1.1199463e+02, 9.0805870e+01, 8.0258804e+01 ); - expectedForces[293] = Vec3( 7.8056273e+01, -3.5931761e+01, -1.9249727e+02 ); - expectedForces[294] = Vec3( -1.2443366e+01, -1.4631721e+02, 7.9733561e+01 ); - expectedForces[295] = Vec3( -3.2866900e+02, 1.1527926e+02, -9.3135590e+01 ); - expectedForces[296] = Vec3( 7.5078643e+01, -7.2653837e+02, -1.0830908e+02 ); - expectedForces[297] = Vec3( 1.0361037e+02, 1.5478274e+02, 1.1293089e+03 ); - expectedForces[298] = Vec3( -2.4014663e+02, -5.6771824e+02, 1.5441974e+02 ); - expectedForces[299] = Vec3( -6.8441034e+01, -1.1226846e+02, -5.4497343e+02 ); - expectedForces[300] = Vec3( 2.9803689e+02, 1.0649462e+03, 2.5408768e+02 ); - expectedForces[301] = Vec3( 5.6356599e+01, -2.3035579e+02, 7.6928758e+01 ); - expectedForces[302] = Vec3( 1.0229494e+02, -1.9615696e+02, -3.2600199e+02 ); - expectedForces[303] = Vec3( -7.0312065e+01, -3.1170055e+02, 5.6453888e+02 ); - expectedForces[304] = Vec3( -7.0752582e+01, 1.2273280e+02, -1.6740503e+01 ); - expectedForces[305] = Vec3( 6.8972998e+02, -2.8067032e+02, 6.6502848e+01 ); - expectedForces[306] = Vec3( -8.8407472e+02, 3.7818347e+02, -1.2141945e+03 ); - expectedForces[307] = Vec3( -1.0445122e+02, -4.4818836e+02, -9.5227168e+00 ); - expectedForces[308] = Vec3( 8.3015802e+02, 5.0941309e+02, 3.2593793e+01 ); - expectedForces[309] = Vec3( 7.6887033e+02, 4.3490548e+02, -1.0826101e+03 ); - expectedForces[310] = Vec3( 1.4352949e+02, -3.9479802e+01, 1.7718790e+02 ); - expectedForces[311] = Vec3( -2.5204642e+02, -3.3888239e+02, -2.7365802e+02 ); - expectedForces[312] = Vec3( -4.4783121e+02, 4.4465580e+02, 9.2506336e+02 ); - expectedForces[313] = Vec3( -3.3390337e+01, -5.0097602e+02, -3.6812516e+02 ); - expectedForces[314] = Vec3( -4.1862341e+02, 1.9519764e+02, -2.4571211e+02 ); - expectedForces[315] = Vec3( -1.4176845e+02, -3.3767798e+01, 1.7800248e+02 ); - expectedForces[316] = Vec3( -4.7411046e+01, 2.3841278e+01, -1.5183689e+01 ); - expectedForces[317] = Vec3( 1.6723204e+01, 1.4145797e+02, -1.6930384e+01 ); - expectedForces[318] = Vec3( -8.4841167e+02, -2.1282818e+02, 8.1614626e+01 ); - expectedForces[319] = Vec3( 6.5941519e+00, -1.1472179e+02, -2.3181002e+02 ); - expectedForces[320] = Vec3( 2.2464095e+01, -5.7606215e+00, 5.2865780e+00 ); - expectedForces[321] = Vec3( 3.8063827e+02, 2.4597014e+02, -4.1947008e+01 ); - expectedForces[322] = Vec3( -3.1531672e+02, 3.5038104e+02, -3.2724191e+02 ); - expectedForces[323] = Vec3( 7.4741163e+01, 7.2296536e+01, 3.1768919e+02 ); - expectedForces[324] = Vec3( 7.9578966e+02, -1.5345175e+02, -7.1301288e+02 ); - expectedForces[325] = Vec3( -3.1387318e+01, 1.7528515e+01, -3.4100670e+01 ); - expectedForces[326] = Vec3( 9.3853572e-01, 6.8496077e+00, 1.2234894e+01 ); - expectedForces[327] = Vec3( -1.3099690e+02, -4.0135958e+02, -4.3248135e+02 ); - expectedForces[328] = Vec3( 4.3988113e+02, -1.5944416e+02, 5.4620163e+01 ); - expectedForces[329] = Vec3( 1.3509243e+01, 3.6990268e+00, -2.6251838e-01 ); - expectedForces[330] = Vec3( -8.7459998e+01, -6.4319025e+02, 2.2863360e+02 ); - expectedForces[331] = Vec3( -3.5181606e+02, 3.1131978e+02, 2.8037788e+02 ); - expectedForces[332] = Vec3( 1.9545884e+02, 4.3994512e+01, -2.5158598e+02 ); - expectedForces[333] = Vec3( 1.8100917e+00, 1.9534738e+02, 1.7181161e+02 ); - expectedForces[334] = Vec3( -1.1846876e+02, 1.5368782e+02, 2.2261016e+02 ); - expectedForces[335] = Vec3( 1.4866155e+02, -4.7983795e+02, 3.0361323e+02 ); - expectedForces[336] = Vec3( -7.7242468e+02, 2.0736079e+02, -8.6661236e+02 ); - expectedForces[337] = Vec3( -7.9875679e+00, -9.0946585e+02, -7.1617627e+01 ); - expectedForces[338] = Vec3( 2.2543457e+02, 2.0215639e+02, 4.4285374e+02 ); - expectedForces[339] = Vec3( -2.6252013e+02, -1.0336519e+02, -2.6630451e+02 ); - expectedForces[340] = Vec3( 5.0907589e+02, -1.2491931e+02, -4.3015857e+01 ); - expectedForces[341] = Vec3( -6.0362692e+01, 1.0025664e+02, -9.3389235e+01 ); - expectedForces[342] = Vec3( 5.8779874e+02, 3.7600030e+02, 2.5345454e+02 ); - expectedForces[343] = Vec3( -1.3661048e+02, 1.6498482e+02, -2.6789925e+01 ); - expectedForces[344] = Vec3( 4.9840419e+01, -1.2136315e+02, 2.5455320e+01 ); - expectedForces[345] = Vec3( 2.3324807e+02, -3.6601512e+02, 5.6798114e+01 ); - expectedForces[346] = Vec3( 5.5853546e+01, -4.9035168e+00, -5.8726331e+02 ); - expectedForces[347] = Vec3( -3.8918158e+01, 3.0380495e+02, 1.0944883e+01 ); - expectedForces[348] = Vec3( -2.6092065e+02, 4.3443036e+02, -1.3673862e+02 ); - expectedForces[349] = Vec3( 1.5195166e+02, 1.1879426e+01, -1.1429493e+02 ); - expectedForces[350] = Vec3( -8.5687107e+02, -1.7938881e+02, 4.5576455e+00 ); - expectedForces[351] = Vec3( -1.0117388e+03, -3.2686610e+02, 2.9733049e+02 ); - expectedForces[352] = Vec3( -2.3946369e+02, 4.9753786e+02, 7.2681440e+02 ); - expectedForces[353] = Vec3( 3.9085837e+01, 7.4391931e+00, 3.4179196e+00 ); - expectedForces[354] = Vec3( 1.0462977e+03, 4.3639578e+02, -5.7349371e+02 ); - expectedForces[355] = Vec3( 1.2715333e+02, -5.7907885e+02, 5.7463165e+02 ); - expectedForces[356] = Vec3( -1.5968981e+02, 2.2295605e+01, 6.3554487e+01 ); - expectedForces[357] = Vec3( -1.9666111e+02, -2.0286725e+02, -8.3590992e+01 ); - expectedForces[358] = Vec3( 5.9985006e+00, 2.9764307e+01, 3.1304672e+01 ); - expectedForces[359] = Vec3( 1.0409792e+02, 4.3974987e+02, -9.1530162e+02 ); - expectedForces[360] = Vec3( 2.9538724e+02, 1.4353710e+02, 2.1558768e+02 ); - expectedForces[361] = Vec3( -3.7974445e+02, -9.0749144e+01, 1.4531502e+02 ); - expectedForces[362] = Vec3( 3.7089093e+02, 2.2523397e+02, -2.9760698e+02 ); - expectedForces[363] = Vec3( -7.6884906e+01, -2.7486958e+02, 3.5671043e+02 ); - expectedForces[364] = Vec3( 4.3400097e+02, 2.2275226e+02, 5.9201087e+01 ); - expectedForces[365] = Vec3( 2.1177620e+02, -6.4990517e+02, -1.8431623e+02 ); - expectedForces[366] = Vec3( -8.2234148e+01, 4.9900036e+02, 3.0906858e+02 ); - expectedForces[367] = Vec3( -1.4784097e+02, 1.3442463e+02, -2.6811487e+02 ); - expectedForces[368] = Vec3( 2.2289541e+02, -4.1933983e+02, 1.3646246e+01 ); - expectedForces[369] = Vec3( -2.1199481e+02, 6.2103281e+01, 1.6049768e+02 ); - expectedForces[370] = Vec3( -2.9429845e+01, -1.3944740e+01, 1.6000003e+01 ); - expectedForces[371] = Vec3( -1.5093250e+02, -1.9541345e+02, -1.5879844e+02 ); - expectedForces[372] = Vec3( 2.2218133e+02, 7.5740668e+01, -7.0754853e+02 ); - expectedForces[373] = Vec3( -4.7529615e+02, -3.5259490e+02, 3.8025744e+02 ); - expectedForces[374] = Vec3( 4.9308495e+01, 1.2206152e+02, 4.2704595e+01 ); - expectedForces[375] = Vec3( -3.6408113e+02, 9.5905960e+02, 3.3861668e+02 ); - expectedForces[376] = Vec3( 1.5324093e+02, -1.4375341e+02, -9.1369900e+01 ); - expectedForces[377] = Vec3( -3.5343609e+02, -4.4662438e+02, 3.1741831e+02 ); - expectedForces[378] = Vec3( -8.2721281e+02, -6.4969313e+01, 4.1869320e+02 ); - expectedForces[379] = Vec3( -8.7419096e+00, -4.6278343e+01, -3.0259942e+01 ); - expectedForces[380] = Vec3( 1.6814871e+01, 4.5462601e+01, -3.5204538e+01 ); - expectedForces[381] = Vec3( 1.9043143e+02, 5.1101135e+02, 2.9970918e+02 ); - expectedForces[382] = Vec3( -4.3547560e+02, -7.7495770e+01, -8.2311440e+01 ); - expectedForces[383] = Vec3( 1.3206505e+02, 4.0993476e+01, 1.5150623e+01 ); - expectedForces[384] = Vec3( 4.6163268e+01, -2.7722119e+01, -2.2996255e+02 ); - expectedForces[385] = Vec3( -4.7033552e+01, 1.5721545e+02, -9.2562636e+01 ); - expectedForces[386] = Vec3( -2.4164903e+02, -1.4771464e+02, -5.1675638e+01 ); - expectedForces[387] = Vec3( 1.3445564e+03, 3.5387081e+02, -3.7402713e+02 ); - expectedForces[388] = Vec3( -2.6290280e+02, 2.5025510e+02, 3.0570707e+01 ); - expectedForces[389] = Vec3( -4.4624214e+02, -2.4919412e+02, 1.1336564e+03 ); - expectedForces[390] = Vec3( 3.1188483e+02, 6.4836125e+02, 4.5477683e+01 ); - expectedForces[391] = Vec3( 2.5570674e+02, -2.7101115e+02, -1.2579817e+02 ); - expectedForces[392] = Vec3( -3.4941759e+02, -3.2508734e+01, -5.6131515e+01 ); - expectedForces[393] = Vec3( -1.2734301e+02, -2.0417657e+02, 5.7738004e+02 ); - expectedForces[394] = Vec3( 5.0435795e+01, -9.5203527e+01, -4.1237509e+00 ); - expectedForces[395] = Vec3( -6.8258463e+01, 1.7475914e+02, -1.6422294e+02 ); - expectedForces[396] = Vec3( 2.6455575e+02, 2.6880230e+02, -1.6607620e+01 ); - expectedForces[397] = Vec3( -3.5968167e+02, 6.6092937e+01, 1.5915445e+02 ); - expectedForces[398] = Vec3( 8.4092494e-01, -5.9896731e+01, -2.1856007e+01 ); - expectedForces[399] = Vec3( -1.9237984e+02, -1.6506355e+02, 1.3370845e+02 ); - expectedForces[400] = Vec3( 4.7023043e+02, 1.2931257e+02, -1.7013618e+02 ); - expectedForces[401] = Vec3( 9.4928843e+01, -3.1613892e+02, -4.6973091e+02 ); - expectedForces[402] = Vec3( -2.9180818e+02, 6.5496755e+02, -2.9430870e+02 ); - expectedForces[403] = Vec3( 1.6670668e+02, -2.4693913e+02, -8.8775735e+01 ); - expectedForces[404] = Vec3( -1.4218604e+02, 2.3173349e+02, 3.9869740e+02 ); - expectedForces[405] = Vec3( 4.3469431e+02, -2.4686568e+02, -2.6838523e+02 ); - expectedForces[406] = Vec3( 1.0671130e+02, 3.9710106e+02, 2.6478100e+02 ); - expectedForces[407] = Vec3( -4.4281099e+02, -3.2746126e+01, -2.0719929e+02 ); - expectedForces[408] = Vec3( 1.1864952e+01, -1.5901568e+02, 1.1865945e+01 ); - expectedForces[409] = Vec3( -6.0546863e+01, -1.3488005e+02, -2.9223986e+02 ); - expectedForces[410] = Vec3( 2.5845942e+01, 1.7545933e+02, -1.4590654e+02 ); - expectedForces[411] = Vec3( -3.0776460e+02, 2.7351986e+02, -2.0386483e+02 ); - expectedForces[412] = Vec3( 1.7301558e+02, 8.3012339e+01, 7.6018513e+02 ); - expectedForces[413] = Vec3( 1.2893147e+02, -3.9937475e+00, 1.4197628e+01 ); - expectedForces[414] = Vec3( -3.9803615e+02, -4.4825663e+02, 2.8616211e+01 ); - expectedForces[415] = Vec3( -2.3586809e+02, -8.9306136e+01, 7.5265669e+02 ); - expectedForces[416] = Vec3( 8.3814512e+02, -9.5563706e+00, 2.8738759e+02 ); - expectedForces[417] = Vec3( -3.8269399e+02, -2.3650170e+02, 1.7330415e+01 ); - expectedForces[418] = Vec3( 7.2310675e+00, 2.4731653e+01, 1.9491126e+01 ); - expectedForces[419] = Vec3( 8.4485111e+01, 9.0560261e+01, -1.4261777e+01 ); - expectedForces[420] = Vec3( 2.1829925e+02, -8.3951651e+01, -7.8910117e+02 ); - expectedForces[421] = Vec3( -2.4228018e+02, -5.7097512e+01, 2.6447829e+02 ); - expectedForces[422] = Vec3( 6.9666665e+01, -4.7313678e+02, 4.5559673e+02 ); - expectedForces[423] = Vec3( 1.0108369e+02, 4.6568610e+02, 2.5612541e+02 ); - expectedForces[424] = Vec3( 7.2334238e+01, -1.5660040e+02, -2.6278686e+02 ); - expectedForces[425] = Vec3( 1.0749954e+03, 2.4395658e+02, -8.7308262e+01 ); - expectedForces[426] = Vec3( 5.4983082e+02, 5.6528577e+02, -3.0489991e+02 ); - expectedForces[427] = Vec3( -2.1210132e+02, -1.5871954e+02, -1.6936452e+02 ); - expectedForces[428] = Vec3( -9.5473983e+01, 7.4879276e+01, 5.5720204e+01 ); - expectedForces[429] = Vec3( 5.6417182e+02, -1.3478250e+02, -4.8006673e+01 ); - expectedForces[430] = Vec3( -1.0055266e+02, -8.3811289e+01, 6.5259748e+01 ); - expectedForces[431] = Vec3( 3.0553989e+01, 4.0927300e+02, 6.2242246e+02 ); - expectedForces[432] = Vec3( -6.0956353e+02, 9.0301312e+02, -1.4063582e+01 ); - expectedForces[433] = Vec3( 3.2774559e+02, -1.0849473e+02, -8.8877712e+01 ); - expectedForces[434] = Vec3( 2.1371643e+02, -7.2067980e+01, 2.4803863e+02 ); - expectedForces[435] = Vec3( -9.0636479e+01, 1.0673514e+03, 1.3005625e+02 ); - expectedForces[436] = Vec3( -3.5058624e+02, -1.4968284e+02, 1.4340635e+02 ); - expectedForces[437] = Vec3( 3.4640813e+01, -4.8035225e+01, 4.4066226e+01 ); - expectedForces[438] = Vec3( -2.3414523e+02, -9.1359130e+01, 2.8535427e+02 ); - expectedForces[439] = Vec3( -2.7156547e+02, -6.3426763e+01, 1.6968017e+01 ); - expectedForces[440] = Vec3( -2.8751166e+00, 4.3192169e+00, -2.1401359e+00 ); - expectedForces[441] = Vec3( -2.0241419e+01, 4.2856138e+02, 7.3204868e+01 ); - expectedForces[442] = Vec3( -4.2166169e+01, -2.2454013e+01, -5.4998450e+01 ); - expectedForces[443] = Vec3( 2.6442026e+02, -1.1670567e+02, 2.8879291e+02 ); - expectedForces[444] = Vec3( -4.9762729e+02, 4.7320314e+02, 3.2506251e+02 ); - expectedForces[445] = Vec3( -3.0994232e+02, 3.6728867e+02, -6.8793662e+02 ); - expectedForces[446] = Vec3( -5.6328374e+00, -2.3284824e+00, 1.9650486e+01 ); - expectedForces[447] = Vec3( 4.0145354e+02, 7.0143762e+02, 1.3039041e+02 ); - expectedForces[448] = Vec3( 1.3270713e+02, -3.3050447e+02, 2.8630784e+02 ); - expectedForces[449] = Vec3( -3.8904836e+02, -4.6125118e+01, -3.8815388e+02 ); - expectedForces[450] = Vec3( 4.6293066e+02, -2.4970158e+02, -5.7231818e+01 ); - expectedForces[451] = Vec3( -4.7707142e+00, 1.7120822e-01, 4.5081299e+00 ); - expectedForces[452] = Vec3( 3.5968818e+01, -1.1892248e+01, 1.2184792e+02 ); - expectedForces[453] = Vec3( 4.4939172e+02, 4.8377647e+02, 3.0529778e+02 ); - expectedForces[454] = Vec3( -2.9071570e+02, -9.0611613e+01, -2.5190431e+02 ); - expectedForces[455] = Vec3( -1.4344537e+02, -1.3061997e+03, 3.8343947e+02 ); - expectedForces[456] = Vec3( 4.1580940e+02, -3.6864043e+02, 6.6384066e+02 ); - expectedForces[457] = Vec3( -3.4869949e+02, 3.3262427e+02, -8.3156358e+01 ); - expectedForces[458] = Vec3( -5.8565457e+00, -5.1879987e+02, -7.2717213e+02 ); - expectedForces[459] = Vec3( -1.0514593e+02, -2.6844396e+02, 3.0849659e+02 ); - expectedForces[460] = Vec3( -1.2562153e+02, 6.5438031e+01, -2.3521687e+02 ); - expectedForces[461] = Vec3( 8.3330016e+02, -6.7961048e+02, -7.2442064e+02 ); - expectedForces[462] = Vec3( -1.3328298e+02, 1.6143544e+02, -3.2000493e+02 ); - expectedForces[463] = Vec3( -1.1035002e+02, -8.6040775e+01, 2.0953986e+02 ); - expectedForces[464] = Vec3( -2.7702219e+02, -1.2156319e+02, -3.8897654e+02 ); - expectedForces[465] = Vec3( 3.6277432e+02, -7.0422679e+02, -8.2487472e+02 ); - expectedForces[466] = Vec3( -2.3947587e+02, -4.3625964e+00, 4.8716989e+01 ); - expectedForces[467] = Vec3( -2.6210552e+02, 9.9730213e+01, -2.4465307e+02 ); - expectedForces[468] = Vec3( -4.1344138e+01, -3.8636310e+01, -1.0720610e+01 ); - expectedForces[469] = Vec3( 2.3928584e+01, -1.3030908e+01, -1.7631168e+01 ); - expectedForces[470] = Vec3( -1.1873594e+02, -3.3905287e+00, -8.4575994e+01 ); - expectedForces[471] = Vec3( 4.3384846e+02, -4.8660929e+02, -2.4015737e+02 ); - expectedForces[472] = Vec3( 3.8974922e+01, 2.4401913e+02, -1.2060132e+02 ); - expectedForces[473] = Vec3( -4.2239647e+02, -8.6924630e+01, 5.7884013e+02 ); - expectedForces[474] = Vec3( 1.7222431e+02, -1.9292167e+01, 4.4184770e+01 ); - expectedForces[475] = Vec3( -4.8871102e+01, 1.8185057e+02, -1.3144294e+02 ); - expectedForces[476] = Vec3( -1.1467881e+02, -1.8387284e+02, -2.6935761e+01 ); - expectedForces[477] = Vec3( 4.4415601e+02, -8.6415426e+02, -2.2765803e+02 ); - expectedForces[478] = Vec3( 2.0893474e+02, 1.3529112e+02, 2.4108004e+02 ); - expectedForces[479] = Vec3( -1.2802570e+01, -4.7089261e+00, -7.0024810e+00 ); - expectedForces[480] = Vec3( -1.0878354e+02, 4.5030357e+02, -3.9086153e+02 ); - expectedForces[481] = Vec3( -3.7659745e+01, -4.9295745e+01, -6.0028516e+01 ); - expectedForces[482] = Vec3( 1.8851809e+02, -1.6863914e+02, 1.2031505e+02 ); - expectedForces[483] = Vec3( 2.2040686e+02, -1.1953187e+03, 2.9106238e+02 ); - expectedForces[484] = Vec3( -1.1642847e+01, 5.6739977e+01, 3.7532413e+00 ); - expectedForces[485] = Vec3( 3.5013234e+00, 2.8236323e+01, -1.1738866e+01 ); - expectedForces[486] = Vec3( -2.0051506e+03, -5.3138994e+02, 4.0428126e+02 ); - expectedForces[487] = Vec3( 1.6887843e+02, 1.1687735e+02, -9.6232177e+01 ); - expectedForces[488] = Vec3( 2.5030722e+02, -3.6662537e+02, -5.8595505e+01 ); - expectedForces[489] = Vec3( -1.5924273e+01, -2.1761920e+02, -3.4885425e+01 ); - expectedForces[490] = Vec3( 1.0423157e+02, 4.0767827e+01, 1.4036192e+02 ); - expectedForces[491] = Vec3( 5.0090776e+02, -5.0455702e+01, -4.2524815e+02 ); - expectedForces[492] = Vec3( 3.8037844e+02, 5.7460724e+02, 2.1243310e+02 ); - expectedForces[493] = Vec3( -1.1487653e+02, 3.3550952e+01, -5.7050397e+01 ); - expectedForces[494] = Vec3( 1.8425697e+02, -2.7223857e+02, -2.9384020e+01 ); - expectedForces[495] = Vec3( -1.1115514e+02, -4.4519957e+02, -3.3628896e+02 ); - expectedForces[496] = Vec3( 3.8865823e+02, -2.1372852e+02, -7.8979988e+02 ); - expectedForces[497] = Vec3( -3.1740258e+02, 4.4824683e+02, -5.0382680e+02 ); - expectedForces[498] = Vec3( 1.5521684e+02, -1.5278429e+02, -1.8418006e+02 ); - expectedForces[499] = Vec3( -2.2213191e+01, 7.1015095e+00, 1.0308820e+01 ); - expectedForces[500] = Vec3( 3.0011560e+01, 2.4584541e+02, -5.3231694e+02 ); - expectedForces[501] = Vec3( -8.4865171e+02, -2.0279022e+02, -6.8435095e+02 ); - expectedForces[502] = Vec3( 7.0477549e+00, 2.7626774e+01, -1.6246047e+01 ); - expectedForces[503] = Vec3( -7.1309648e+01, -1.6054218e+02, -3.1621746e+01 ); - expectedForces[504] = Vec3( 3.6317856e+02, 1.9055487e+02, 3.9196046e+01 ); - expectedForces[505] = Vec3( 1.4643265e+02, -1.2295335e+03, -2.2268806e+01 ); - expectedForces[506] = Vec3( -3.6638240e+02, -6.5310612e+00, -6.8077013e+02 ); - expectedForces[507] = Vec3( 1.9107813e+02, -6.2176534e+02, 5.1826941e+02 ); - expectedForces[508] = Vec3( 1.7226933e+02, -3.8939126e+02, -7.4174355e+02 ); - expectedForces[509] = Vec3( 1.3541890e+02, 4.1350561e+02, -2.6155396e+02 ); - expectedForces[510] = Vec3( 1.6452609e+02, -4.1963597e+02, 1.6322800e+02 ); - expectedForces[511] = Vec3( 9.1248387e+01, -1.3380408e+01, -5.1326806e+02 ); - expectedForces[512] = Vec3( 1.2420564e+02, 8.9492432e+02, 2.8660661e+02 ); - expectedForces[513] = Vec3( 4.5609859e+02, 3.4252036e+01, -2.3830457e+02 ); - expectedForces[514] = Vec3( -8.8282131e+01, -1.4512876e+02, -4.5703642e+01 ); - expectedForces[515] = Vec3( -6.9194714e+01, 5.5053415e+02, -3.9527911e+02 ); - expectedForces[516] = Vec3( -1.5570798e+02, 4.1650792e-02, 3.0224667e+02 ); - expectedForces[517] = Vec3( 9.2007640e+01, 3.6378499e+02, -2.2069415e+01 ); - expectedForces[518] = Vec3( 2.7996922e+02, -2.0932322e+02, 6.2987796e+01 ); - expectedForces[519] = Vec3( -7.4985282e+01, 1.3508916e+02, 1.1453750e+02 ); - expectedForces[520] = Vec3( 1.2149786e+01, 4.2161047e+02, -2.9521571e+02 ); - expectedForces[521] = Vec3( 1.9419524e+01, -8.6619683e+01, -9.4040609e+01 ); - expectedForces[522] = Vec3( 3.5495800e+01, 6.4028894e+01, 1.2320699e+02 ); - expectedForces[523] = Vec3( -5.6501302e+02, -1.2497462e+02, 8.1633096e+02 ); - expectedForces[524] = Vec3( -3.1775230e+02, 1.6467221e+02, -4.8242287e+01 ); - expectedForces[525] = Vec3( -1.8325245e+02, -1.0751941e+02, 6.2172117e+02 ); - expectedForces[526] = Vec3( 1.8164299e+00, 8.0654784e-01, -1.4484741e+01 ); - expectedForces[527] = Vec3( 2.6686986e+00, 1.5933475e+01, -6.8843007e+01 ); - expectedForces[528] = Vec3( -1.3208642e+02, -1.2281791e+02, 7.8417959e+01 ); - expectedForces[529] = Vec3( -4.8078193e+01, -1.5140963e+02, 8.3605002e+01 ); - expectedForces[530] = Vec3( 8.5925332e+01, 1.9959621e+01, -5.9034655e+01 ); - expectedForces[531] = Vec3( -3.1311626e+00, -3.4009931e+01, -1.5895685e+02 ); - expectedForces[532] = Vec3( -9.9694666e+01, 1.0296874e+00, 1.0482739e+02 ); - expectedForces[533] = Vec3( 2.8954747e+02, 1.2018666e+02, 2.2155006e+02 ); - expectedForces[534] = Vec3( 3.2588176e+02, 3.6622498e+01, 3.5801460e+02 ); - expectedForces[535] = Vec3( -6.5985617e+01, -3.5501709e+02, 6.8149810e+01 ); - expectedForces[536] = Vec3( -4.7632753e+02, 2.7936656e+02, 1.5548558e+02 ); - expectedForces[537] = Vec3( 4.7724904e+02, 2.1647106e+02, 1.2003317e+02 ); - expectedForces[538] = Vec3( -1.6225405e+02, 1.4264998e+02, -1.0113321e+02 ); - expectedForces[539] = Vec3( -3.2540487e+01, -7.5643223e+01, 1.6054148e+01 ); - expectedForces[540] = Vec3( 4.3311991e+02, 5.8082595e+02, 1.9354276e+02 ); - expectedForces[541] = Vec3( -3.4924430e+02, -7.0056069e+01, 1.0274560e+02 ); - expectedForces[542] = Vec3( 1.9441645e+02, -2.0017354e+02, -2.3280717e+02 ); - expectedForces[543] = Vec3( -4.1530380e+01, -5.6394351e+02, 2.4472509e+02 ); - expectedForces[544] = Vec3( -1.6193396e+01, -8.0431396e+01, -2.9094018e+02 ); - expectedForces[545] = Vec3( -1.9414773e+01, 4.6180982e+01, 3.3123072e+01 ); - expectedForces[546] = Vec3( -3.9314039e+02, -3.9874866e+02, 4.5308571e+02 ); - expectedForces[547] = Vec3( -7.1897482e+01, -1.1940445e+02, -2.7405931e+02 ); - expectedForces[548] = Vec3( 3.0646396e+02, 6.1235747e+01, -1.5253270e+02 ); - expectedForces[549] = Vec3( -3.2480464e+02, 4.3056561e+02, 3.2532485e+01 ); - expectedForces[550] = Vec3( 1.2818655e+02, 7.4294994e-01, -5.7650521e+00 ); - expectedForces[551] = Vec3( -1.7481437e+02, -2.6203225e+02, -9.6793481e+01 ); - expectedForces[552] = Vec3( 1.9259110e+02, 3.0171883e+02, 5.2403235e+02 ); - expectedForces[553] = Vec3( -7.8132123e+01, -7.6569340e+00, -1.1140240e+02 ); - expectedForces[554] = Vec3( -5.2504673e+02, -4.3700574e+02, 4.3321261e+02 ); - expectedForces[555] = Vec3( -9.9785283e+02, 2.7139143e+02, -4.1723547e+02 ); - expectedForces[556] = Vec3( 2.7115933e+02, -8.7444541e+01, 1.0745103e+02 ); - expectedForces[557] = Vec3( 1.4348018e+02, 1.4013343e+02, -4.0305733e+02 ); - expectedForces[558] = Vec3( 4.9491010e+02, 4.3040089e+02, -3.5558583e+02 ); - expectedForces[559] = Vec3( -1.8510736e+02, 6.7129731e+01, -2.1324364e+02 ); - expectedForces[560] = Vec3( 8.4478090e+01, 4.0986269e+01, 4.1401094e+02 ); - expectedForces[561] = Vec3( 4.4188419e+01, -8.6520108e+02, 6.8555821e+02 ); - expectedForces[562] = Vec3( -4.5036974e+02, 2.2379481e+02, 6.2457971e+01 ); - expectedForces[563] = Vec3( 2.4325836e+02, 6.9725116e+01, 3.6266296e+01 ); - expectedForces[564] = Vec3( 1.5611925e+02, -2.4471023e+02, 4.7857332e+02 ); - expectedForces[565] = Vec3( -3.5692822e+02, -2.7248961e+02, -1.8165146e+02 ); - expectedForces[566] = Vec3( 4.3093388e+02, 1.6944839e+02, -4.4177741e+02 ); - expectedForces[567] = Vec3( 5.2118711e+02, -1.5252783e+02, -1.6964047e+02 ); - expectedForces[568] = Vec3( 1.3899083e+03, 3.8363654e+02, -6.4623177e+02 ); - expectedForces[569] = Vec3( -1.4984858e+02, 4.5097170e+01, -5.0257768e+01 ); - expectedForces[570] = Vec3( -8.1979709e+01, -4.1632909e+01, -5.1367825e+02 ); - expectedForces[571] = Vec3( -7.8645235e+00, 1.8105470e+01, 9.2902759e+01 ); - expectedForces[572] = Vec3( 1.2725548e+02, 1.3926229e+02, -4.3752260e+01 ); - expectedForces[573] = Vec3( -2.7817289e+01, -8.0900345e+01, -4.3178498e+02 ); - expectedForces[574] = Vec3( 2.2115263e+02, -7.8807799e+01, 8.8367391e+01 ); - expectedForces[575] = Vec3( -1.2756938e+02, 4.2170937e+02, -6.8418245e+01 ); - expectedForces[576] = Vec3( 8.8370341e+01, -1.4671130e+02, -5.6211071e+02 ); - expectedForces[577] = Vec3( 6.7701453e+02, 2.1228010e+02, 2.3047236e+02 ); - expectedForces[578] = Vec3( -1.2694819e+02, -7.2734890e+00, 1.1007893e+02 ); - expectedForces[579] = Vec3( -6.8945756e+02, 1.7359485e+02, -2.5607776e+02 ); - expectedForces[580] = Vec3( 6.7323923e+00, 3.1574487e+02, 5.9741152e+02 ); - expectedForces[581] = Vec3( 2.1214031e+02, -4.7565197e+01, -9.6896159e+01 ); - expectedForces[582] = Vec3( -3.4876562e+02, 5.8335489e+01, -1.7058451e+02 ); - expectedForces[583] = Vec3( -1.6516914e+02, -3.8913162e+02, 5.8832025e+02 ); - expectedForces[584] = Vec3( 4.7753612e+01, -6.6792213e+01, -4.6492749e+01 ); - expectedForces[585] = Vec3( -4.7166578e+02, 7.1811831e+02, 7.0620222e+02 ); - expectedForces[586] = Vec3( -3.0570577e+02, -1.7681907e+02, -2.1227370e+02 ); - expectedForces[587] = Vec3( 1.8122997e+02, -6.8318737e+01, -3.4853368e+02 ); - expectedForces[588] = Vec3( 7.5752093e+01, 3.9702196e+02, -9.0196404e+02 ); - expectedForces[589] = Vec3( 5.1185528e+02, -7.7747186e+02, -3.3969581e+02 ); - expectedForces[590] = Vec3( -3.1187606e+01, 5.9593198e+01, 7.7918649e+01 ); - expectedForces[591] = Vec3( 2.2741676e+02, 2.1705631e+02, 3.9920149e+02 ); - expectedForces[592] = Vec3( 7.0516894e+01, 3.3389665e+02, -6.8443760e+00 ); - expectedForces[593] = Vec3( -9.9645406e+02, 2.8574127e+02, -8.0946834e+02 ); - expectedForces[594] = Vec3( 1.0930460e+02, 1.5869363e+03, -4.0704089e+02 ); - expectedForces[595] = Vec3( -3.0341438e+02, -5.7494385e+00, 2.9655509e+02 ); - expectedForces[596] = Vec3( 8.7955203e+01, -7.6811348e+01, -6.9558652e+01 ); - expectedForces[597] = Vec3( -9.4378353e+01, 3.6253070e+02, 9.0703343e-01 ); - expectedForces[598] = Vec3( -4.7595525e+01, -6.9148379e+02, -4.6737971e+02 ); - expectedForces[599] = Vec3( 2.2339987e+02, -2.5503335e+02, 2.8552040e+02 ); - expectedForces[600] = Vec3( 1.0309072e+02, -2.1298204e+02, -4.3393283e+02 ); - expectedForces[601] = Vec3( -2.4581477e+02, 2.5126386e+02, -1.8679710e+02 ); - expectedForces[602] = Vec3( 7.7926618e+00, -2.4947558e+01, 1.5962011e+02 ); - expectedForces[603] = Vec3( 7.0099476e+02, 5.9496129e+01, 2.0314640e+02 ); - expectedForces[604] = Vec3( -5.2583810e+01, 3.1237489e+01, -4.0902937e+00 ); - expectedForces[605] = Vec3( -5.4435871e+01, -7.7056693e+01, -1.5137215e+01 ); - expectedForces[606] = Vec3( -7.8684074e+02, 8.1673860e+02, 5.0192222e+02 ); - expectedForces[607] = Vec3( 2.9859285e+02, 1.9661708e+02, -1.9940993e+02 ); - expectedForces[608] = Vec3( -9.9358476e-01, -3.4789219e+02, 1.7693106e+02 ); - expectedForces[609] = Vec3( 6.7880927e+02, 7.2768533e+01, 1.1973248e+03 ); - expectedForces[610] = Vec3( -1.2072838e+00, 1.1770157e+02, -8.6765918e+01 ); - expectedForces[611] = Vec3( -4.3236695e+02, -2.8583002e+02, 1.3459508e+02 ); - expectedForces[612] = Vec3( -6.1894609e+01, 4.4705141e+02, -2.3264215e+02 ); - expectedForces[613] = Vec3( -2.6948720e+01, -2.7688230e+01, 4.6300601e+01 ); - expectedForces[614] = Vec3( 4.3954815e+01, 6.1244278e+01, 1.0727211e+02 ); - expectedForces[615] = Vec3( -2.2049132e+02, -9.7233594e+01, 8.3807949e+01 ); - expectedForces[616] = Vec3( 2.8631226e+02, -1.3478640e+02, -5.0675977e+02 ); - expectedForces[617] = Vec3( -1.1458029e+01, 6.3762007e+01, -4.9643140e+01 ); - expectedForces[618] = Vec3( 7.7363305e+01, 1.1936816e+02, 3.9692323e+01 ); - expectedForces[619] = Vec3( -8.4199858e+01, 2.3567494e+02, 7.2885200e+01 ); - expectedForces[620] = Vec3( -7.4500104e+00, 3.5567340e+00, -2.2676267e+01 ); - expectedForces[621] = Vec3( -7.9200057e+02, 3.2245192e+01, 1.1829644e+01 ); - expectedForces[622] = Vec3( 3.9959336e+02, 2.2447865e+02, -3.1413233e+02 ); - expectedForces[623] = Vec3( 1.5810527e+02, -2.2341997e+02, 2.3388212e+02 ); - expectedForces[624] = Vec3( -2.9248657e+02, -1.0806250e+03, -6.1268035e+01 ); - expectedForces[625] = Vec3( 6.5061442e+02, 1.2244756e+02, -1.1976147e+02 ); - expectedForces[626] = Vec3( -1.7787710e+02, 3.7279354e+02, -3.7911745e+02 ); - expectedForces[627] = Vec3( 3.7145927e+02, -2.5203732e+02, -2.2889342e+02 ); - expectedForces[628] = Vec3( 1.9440281e+02, -2.3076142e+02, 7.2945279e+01 ); - expectedForces[629] = Vec3( -2.3603693e+02, -1.1987203e+02, -1.2000208e+02 ); - expectedForces[630] = Vec3( -8.4811726e+01, -6.4500846e+02, -5.1257210e+02 ); - expectedForces[631] = Vec3( -1.6183393e+01, 1.3980655e+01, -2.3189702e+00 ); - expectedForces[632] = Vec3( 1.3526098e+02, 1.3800365e+02, -9.4360476e+01 ); - expectedForces[633] = Vec3( 2.0983514e+01, 5.1156494e+02, -4.3526557e+01 ); - expectedForces[634] = Vec3( -2.8666500e+02, -5.8235691e+02, -8.7425194e+01 ); - expectedForces[635] = Vec3( -1.7183604e+02, 1.0002944e+01, 6.5855812e+02 ); - expectedForces[636] = Vec3( -2.1735465e+02, 9.4664675e+02, 8.9132890e+02 ); - expectedForces[637] = Vec3( 6.3759184e+01, -5.2436201e+02, 1.2455578e+02 ); - expectedForces[638] = Vec3( 3.2176621e+02, 1.8182348e+02, -4.4863340e+02 ); - expectedForces[639] = Vec3( -8.4308252e+02, -1.6268681e+02, 5.8113352e+02 ); - expectedForces[640] = Vec3( 6.1223389e+01, 3.6767423e+02, 5.9071999e+02 ); - expectedForces[641] = Vec3( 2.2546928e+02, -2.2022805e+02, 8.3027103e+01 ); - expectedForces[642] = Vec3( -4.0385190e+02, 2.0141033e+02, 2.7296512e+01 ); - expectedForces[643] = Vec3( 8.4204485e+01, -7.1102294e+01, 5.7642677e+01 ); - expectedForces[644] = Vec3( 6.1859901e+01, 1.4828523e+02, -2.6764016e+02 ); - expectedForces[645] = Vec3( -6.7249932e+02, -8.4613525e+01, -3.9792609e+02 ); - expectedForces[646] = Vec3( 9.9116485e+01, -3.7714583e+01, -5.3966332e+01 ); - expectedForces[647] = Vec3( 2.0868628e+02, 2.9747206e+02, 3.3931416e+02 ); + expectedForces[0] = Vec3( 2.3025909e+02, -1.0422757e+01, -2.1413965e+02); + expectedForces[1] = Vec3( 1.1261936e+02, 5.5882575e+02, 9.6539143e+01); + expectedForces[2] = Vec3( -8.8436857e+01, -4.4737313e+01, 2.5242022e+02); + expectedForces[3] = Vec3( 6.3548886e+02, -1.9582636e+02, -1.2229882e+02); + expectedForces[4] = Vec3( -3.9513809e+02, -1.3738635e+02, -1.2488717e+02); + expectedForces[5] = Vec3( 6.8771170e+00, 9.1574345e+01, -1.3865672e+00); + expectedForces[6] = Vec3( 3.6928792e+02, -7.1025648e+01, 5.2550320e+02); + expectedForces[7] = Vec3( 1.5531325e+02, -7.9256260e+02, 3.8119809e+02); + expectedForces[8] = Vec3( 1.5408049e+02, 1.4633285e+02, -5.4573735e+02); + expectedForces[9] = Vec3( -3.2549641e+02, 2.8613802e+01, 1.8082150e+02); + expectedForces[10] = Vec3( 1.9968249e+02, -7.7742415e+01, -4.2188467e+02); + expectedForces[11] = Vec3( 4.6645952e+01, 2.1362909e+01, 5.7120135e+01); + expectedForces[12] = Vec3( 4.2971265e+01, -4.2927865e+01, -7.6319121e+02); + expectedForces[13] = Vec3( 2.1889551e+02, -5.1806784e+01, 7.6637073e+01); + expectedForces[14] = Vec3( -3.0028991e+02, 9.0479382e+01, 1.3199449e+02); + expectedForces[15] = Vec3( -1.8041801e+00, -1.2176813e+03, -5.9679371e+02); + expectedForces[16] = Vec3( -1.4773339e+02, -1.2582057e+02, 8.4242040e+02); + expectedForces[17] = Vec3( 6.8633312e+02, -2.4864325e+01, 1.0675519e+01); + expectedForces[18] = Vec3( 4.8211733e+02, -2.2044742e+02, 1.8105309e+02); + expectedForces[19] = Vec3( -2.1956736e+02, 5.4786741e+02, -1.4827263e+02); + expectedForces[20] = Vec3( -1.0476100e+02, -1.6922280e+02, 8.3220473e+01); + expectedForces[21] = Vec3( 5.5455350e+01, 1.7851224e+02, 6.0598643e+02); + expectedForces[22] = Vec3( 7.1915871e+00, -1.6455057e+01, -6.3929797e+00); + expectedForces[23] = Vec3( -2.4371864e+02, -7.0765288e+02, -1.7820148e+02); + expectedForces[24] = Vec3( -4.3715367e+02, 2.8707226e+02, 2.2558361e+02); + expectedForces[25] = Vec3( 2.3735557e+00, -4.2064130e+00, 2.5933632e+01); + expectedForces[26] = Vec3( 1.0192415e+02, 5.3205842e+01, -2.0158900e+02); + expectedForces[27] = Vec3( -5.1276812e+02, 2.4860179e+02, 2.5150125e+02); + expectedForces[28] = Vec3( 3.9608987e+02, -4.0544816e+01, -2.1579831e+02); + expectedForces[29] = Vec3( -2.5926005e+02, -1.1691294e+02, -4.7278417e+02); + expectedForces[30] = Vec3( -1.1036158e+02, 3.3229287e+01, 8.8351491e+01); + expectedForces[31] = Vec3( -4.1178603e+00, 1.2957632e+00, 1.2617868e+00); + expectedForces[32] = Vec3( 1.9401524e+02, 1.0030314e+02, 3.0386141e+01); + expectedForces[33] = Vec3( 1.0870981e+02, 2.1865882e+02, 6.7672725e+02); + expectedForces[34] = Vec3( 3.6812338e+01, -2.9347382e-01, 1.2959790e+01); + expectedForces[35] = Vec3( -5.5738560e+01, 2.2268442e+02, -1.4911862e+02); + expectedForces[36] = Vec3( -1.6659719e+02, 8.1941190e+01, 7.8132996e+01); + expectedForces[37] = Vec3( -1.1985659e+02, 7.1891763e+01, -3.2559738e+02); + expectedForces[38] = Vec3( 1.4441653e+02, 4.1824194e+02, 3.4293255e+01); + expectedForces[39] = Vec3( 1.1307312e+02, -3.4981802e+02, -1.0676819e+02); + expectedForces[40] = Vec3( -1.2857487e+02, -4.0798950e+01, -1.7800009e+02); + expectedForces[41] = Vec3( -4.1244991e+02, 2.3439565e+02, 3.8546709e+02); + expectedForces[42] = Vec3( 2.1799653e+02, 2.9397348e+02, -3.8955146e+02); + expectedForces[43] = Vec3( -9.4254462e+01, 5.0157547e+01, 1.3707146e+02); + expectedForces[44] = Vec3( 8.0520929e+02, -1.0228045e+03, -4.5813594e+01); + expectedForces[45] = Vec3( 5.3451125e+02, -7.0725115e+02, -2.3828883e+02); + expectedForces[46] = Vec3( 3.6991801e+02, -1.0410466e+03, 8.4889413e+02); + expectedForces[47] = Vec3( 5.8096458e+01, 2.3859368e+02, 7.3104979e+01); + expectedForces[48] = Vec3( -1.3230378e+03, 7.1827816e+02, 9.4372946e+02); + expectedForces[49] = Vec3( -4.2398413e+02, -3.6766481e+02, -1.6666711e+02); + expectedForces[50] = Vec3( 8.6374766e+00, -2.7870227e+02, 3.0621233e+02); + expectedForces[51] = Vec3( -2.4404981e+02, 1.0510491e+03, -3.5202340e+02); + expectedForces[52] = Vec3( 1.7461155e+02, 1.3419948e+02, 5.0279733e+02); + expectedForces[53] = Vec3( 9.7089193e+01, -1.4826120e+02, -2.3426711e+02); + expectedForces[54] = Vec3( -1.0647432e+02, 2.3266543e+02, -3.5025025e+02); + expectedForces[55] = Vec3( -1.9951717e+02, -1.0804258e+02, 6.2114265e+01); + expectedForces[56] = Vec3( 2.5354284e+02, -3.5074926e+02, -2.9176946e+01); + expectedForces[57] = Vec3( -8.8328002e+02, -1.8937053e+02, 2.0772189e+02); + expectedForces[58] = Vec3( 4.5809698e+01, -1.8636513e+00, 1.6742910e+01); + expectedForces[59] = Vec3( 8.6670673e+01, 1.2653519e+02, 2.0046372e+02); + expectedForces[60] = Vec3( -9.6142275e+02, 1.1800289e+03, 1.0064471e+02); + expectedForces[61] = Vec3( -6.9751453e+01, -1.9324691e+02, 2.2638891e+01); + expectedForces[62] = Vec3( 1.3671815e+02, 1.0129231e+01, -6.1136892e+01); + expectedForces[63] = Vec3( 7.6032938e+02, -1.9779542e+02, -2.5706161e+01); + expectedForces[64] = Vec3( -9.8966607e+00, 3.6294058e+02, -2.3247376e+02); + expectedForces[65] = Vec3( -1.3142673e+02, 9.9368000e+00, 1.4225069e+02); + expectedForces[66] = Vec3( 5.2691625e+01, -4.0618331e+02, -1.0942115e+02); + expectedForces[67] = Vec3( 5.8137742e+01, 2.1942441e+02, -1.7191686e+02); + expectedForces[68] = Vec3( 1.2480778e+02, 2.4086799e+01, -1.9588545e+02); + expectedForces[69] = Vec3( 2.4577512e+02, -2.3516051e+01, 2.3764379e+02); + expectedForces[70] = Vec3( 4.2298797e+01, 8.6807583e+01, 2.9276129e+02); + expectedForces[71] = Vec3( 3.0309915e+01, -3.4686002e+02, 1.0849989e+02); + expectedForces[72] = Vec3( 5.5170999e+02, -1.5797913e+02, 9.8379834e+01); + expectedForces[73] = Vec3( -5.3706921e+02, 2.2236470e+02, 2.7548665e+02); + expectedForces[74] = Vec3( -2.7734936e+02, -4.2949693e+02, -8.2303469e+02); + expectedForces[75] = Vec3( 1.1749001e+03, 9.2734627e+02, -2.6342291e+02); + expectedForces[76] = Vec3( -1.2345216e+02, -6.6220297e+01, 1.1022778e+02); + expectedForces[77] = Vec3( -4.4861284e+01, -7.4560959e+01, -8.0791275e+01); + expectedForces[78] = Vec3( 1.7692476e+01, -9.9067626e+02, -3.3083363e+02); + expectedForces[79] = Vec3( 6.4276566e+01, 5.1865608e+02, 4.1241764e+02); + expectedForces[80] = Vec3( 6.5867999e+02, 2.0995465e+02, -5.0989840e+02); + expectedForces[81] = Vec3( -5.2826435e+02, -1.3719887e+02, 1.9730314e+02); + expectedForces[82] = Vec3( 2.3329314e+02, 5.1589944e+01, -3.3942818e+02); + expectedForces[83] = Vec3( -2.5756193e+00, 1.3788257e+02, 1.3074778e+02); + expectedForces[84] = Vec3( -2.8925811e+01, 8.8185346e+01, 1.1547804e+02); + expectedForces[85] = Vec3( -3.3582542e+01, -1.3079843e+02, 3.4774799e+02); + expectedForces[86] = Vec3( -5.9585326e+01, -3.7973755e+01, 1.0206767e+01); + expectedForces[87] = Vec3( -7.1691223e+01, -1.9547311e+02, 9.3856472e+02); + expectedForces[88] = Vec3( 1.4832977e+02, 4.2005795e+02, 2.7235044e+01); + expectedForces[89] = Vec3( 8.6221698e+00, -1.3935906e+01, -2.5473157e+00); + expectedForces[90] = Vec3( 3.0044348e+02, 3.4320406e+02, 2.5305998e+02); + expectedForces[91] = Vec3( -1.6694013e+02, 7.4645776e+02, 3.3266168e+01); + expectedForces[92] = Vec3( 1.6931562e+02, -2.3972286e+01, -3.0802865e+02); + expectedForces[93] = Vec3( -2.5931152e+02, -9.7825375e+01, -5.5598386e+02); + expectedForces[94] = Vec3( -7.8473519e+01, -2.6244561e+02, 2.9622027e+02); + expectedForces[95] = Vec3( 1.5788473e+02, 2.9806605e+02, 1.8283700e+02); + expectedForces[96] = Vec3( -4.2033208e+02, 4.8745845e+02, 9.7957219e+01); + expectedForces[97] = Vec3( 1.3261733e+00, 3.7143158e+00, -1.8329960e+00); + expectedForces[98] = Vec3( 7.4741051e+02, 1.0482696e+03, 1.7182445e+02); + expectedForces[99] = Vec3( 2.0366606e+02, 1.1586652e+02, 1.5482927e+03); + expectedForces[100] = Vec3( 5.7569884e+02, -2.2068597e+02, -1.9305186e+02); + expectedForces[101] = Vec3( -2.4259775e+02, -6.1359858e+01, -7.5753918e+01); + expectedForces[102] = Vec3( 2.4382837e+02, 1.3660693e+01, -2.8717824e+02); + expectedForces[103] = Vec3( -4.1914381e+02, -1.4506334e+02, 7.7692658e+01); + expectedForces[104] = Vec3( 9.5422158e+01, -1.4261849e+01, 1.0122453e+02); + expectedForces[105] = Vec3( -6.1222151e+02, 6.1398147e+01, 3.2961693e+02); + expectedForces[106] = Vec3( -2.7982116e+02, -3.7564793e+02, -2.4318658e+02); + expectedForces[107] = Vec3( 8.2892383e+01, 1.1992522e+01, 2.4802899e+01); + expectedForces[108] = Vec3( -3.3626753e+02, -7.8892295e+01, 8.1184535e+02); + expectedForces[109] = Vec3( -4.6396103e+01, 3.1165111e+01, -3.5184949e+01); + expectedForces[110] = Vec3( 4.6295297e+02, -8.0135823e+01, -3.2963637e+02); + expectedForces[111] = Vec3( 5.5325945e+02, 3.8213691e+02, -5.9449911e+02); + expectedForces[112] = Vec3( -6.1770559e+02, 2.2322880e+02, -2.1022934e+01); + expectedForces[113] = Vec3( 2.3716825e+02, -3.8085281e+02, 4.9618193e+02); + expectedForces[114] = Vec3( 2.9972570e+02, 3.3773759e+02, 3.4933501e+02); + expectedForces[115] = Vec3( 1.9913039e+02, -3.2035626e+02, -9.7987777e+01); + expectedForces[116] = Vec3( -2.3506456e+02, 4.0030561e+02, -6.2604809e+02); + expectedForces[117] = Vec3( 6.0408777e+02, 5.6271523e+02, -5.8742635e+02); + expectedForces[118] = Vec3( -5.0707285e+02, 7.8511351e+02, -1.7561830e+02); + expectedForces[119] = Vec3( 5.6759945e+00, 6.9735233e+00, -9.8853787e+00); + expectedForces[120] = Vec3( 1.1918531e+02, -5.6200785e+02, 3.2333502e+02); + expectedForces[121] = Vec3( 5.1801315e+02, -3.4460898e+02, 1.1488242e+02); + expectedForces[122] = Vec3( 7.5859703e+00, 6.9528951e+01, -6.2437444e+00); + expectedForces[123] = Vec3( 1.1990899e+03, -1.2507886e+01, 1.1906562e+03); + expectedForces[124] = Vec3( 2.6001536e+02, -9.5041373e+01, -4.2547252e+02); + expectedForces[125] = Vec3( -3.5601586e+01, 9.1460220e+02, 6.2306102e+02); + expectedForces[126] = Vec3( -3.8254176e+01, 2.4796243e+02, 3.0638741e+02); + expectedForces[127] = Vec3( -3.8798311e+02, 1.2532794e+02, -3.1926601e+01); + expectedForces[128] = Vec3( 5.7672682e+01, 1.7487900e+02, -1.0319581e+02); + expectedForces[129] = Vec3( 4.4276215e+02, -1.5517993e+02, 3.8122873e+02); + expectedForces[130] = Vec3( -2.8119980e+02, -2.6530936e+02, 4.3545814e+01); + expectedForces[131] = Vec3( 5.9375768e+00, 1.6335780e+01, -3.6204644e+02); + expectedForces[132] = Vec3( 5.9733834e+02, -2.9843602e+02, 1.0541092e+03); + expectedForces[133] = Vec3( -3.4568461e+02, 2.2794808e+02, -8.4675886e+01); + expectedForces[134] = Vec3( -6.7882706e+01, -4.5016799e+02, -1.9387646e+02); + expectedForces[135] = Vec3( 5.6125478e+02, -1.1741092e+03, 1.4214256e+02); + expectedForces[136] = Vec3( 1.2766648e+02, 1.2519441e+02, -4.4359129e+02); + expectedForces[137] = Vec3( -2.7235507e+01, -1.0871423e+01, 3.2406976e+01); + expectedForces[138] = Vec3( -1.2110689e+03, 1.3038667e+02, -7.5331947e+02); + expectedForces[139] = Vec3( 3.2504988e+02, -7.1577942e+02, -2.4351454e+02); + expectedForces[140] = Vec3( 2.6466925e+02, 3.6878498e+02, -6.2044711e+01); + expectedForces[141] = Vec3( -6.2647276e+02, -4.7112562e+02, -6.1885184e+01); + expectedForces[142] = Vec3( 3.0996699e+01, 3.1033732e+02, -5.7493337e+02); + expectedForces[143] = Vec3( 2.4664962e+01, 7.8306665e+02, 3.7907751e+02); + expectedForces[144] = Vec3( -1.9847551e+02, -3.0052499e+02, -6.5192951e+01); + expectedForces[145] = Vec3( -5.0686773e+02, 1.1972933e+02, 3.6202910e+02); + expectedForces[146] = Vec3( 4.0004521e+02, -4.3205645e+02, 2.8583074e+02); + expectedForces[147] = Vec3( -2.9447542e+01, 6.3434099e+02, -6.5189179e+02); + expectedForces[148] = Vec3( 4.1588516e+02, -1.5534873e+02, -1.1031323e+01); + expectedForces[149] = Vec3( 1.2761543e+01, -5.6871456e+01, 2.8032565e+02); + expectedForces[150] = Vec3( -4.7527199e+01, 6.2549647e+02, -8.5007589e+02); + expectedForces[151] = Vec3( 1.6598949e+01, 1.1210199e+02, 2.0667266e+02); + expectedForces[152] = Vec3( -2.4012423e+00, -6.1728962e+01, -1.5057977e+01); + expectedForces[153] = Vec3( -3.6934056e+02, 2.3087063e+02, -3.3268511e+02); + expectedForces[154] = Vec3( 1.2658460e+02, 4.1809355e+02, 1.9550635e+02); + expectedForces[155] = Vec3( -1.9528152e+02, -1.9035919e+02, 1.4986704e+02); + expectedForces[156] = Vec3( -5.9608803e+00, 2.7258190e+02, 5.5318395e+02); + expectedForces[157] = Vec3( -1.0545084e+01, -1.8397001e+00, -3.3615498e+00); + expectedForces[158] = Vec3( -4.0827462e+02, -6.4070993e+01, -2.6614992e+02); + expectedForces[159] = Vec3( -1.5773827e+02, 4.7708702e+02, -9.9622711e+02); + expectedForces[160] = Vec3( 8.3896122e+01, 2.5959601e+02, 1.7728081e+02); + expectedForces[161] = Vec3( -2.4859055e+02, 8.1617294e+01, 2.7905586e+02); + expectedForces[162] = Vec3( 1.3694593e+02, -6.2640483e+02, -2.5308878e+02); + expectedForces[163] = Vec3( -1.5156337e+02, 1.1567379e+02, 1.8384602e+02); + expectedForces[164] = Vec3( -1.4794785e+02, -8.0381965e+01, 9.4028021e+02); + expectedForces[165] = Vec3( -3.5851252e+02, 2.6066489e+02, -4.1225343e+01); + expectedForces[166] = Vec3( 1.0820389e+02, -8.3485138e+01, 9.5047812e+01); + expectedForces[167] = Vec3( 2.0019411e+02, 5.0864719e+02, -4.8662239e+01); + expectedForces[168] = Vec3( -3.0716707e+02, -9.8820762e+02, 1.3660536e+01); + expectedForces[169] = Vec3( 8.5788590e+02, -1.0335921e+02, -2.2197815e+02); + expectedForces[170] = Vec3( 9.8072705e+00, 6.6224870e+02, -1.1594055e+02); + expectedForces[171] = Vec3( -3.6572453e+01, 2.4062731e+02, 1.7831682e+02); + expectedForces[172] = Vec3( -2.1274187e+00, -2.5471785e+02, -2.5813525e+02); + expectedForces[173] = Vec3( 3.4763673e+02, -2.0753062e+02, 7.5125390e+02); + expectedForces[174] = Vec3( 2.9010685e+01, -4.1894498e+02, -6.3847846e+02); + expectedForces[175] = Vec3( 3.0255245e+02, 2.5945698e+02, 2.3530662e+01); + expectedForces[176] = Vec3( -2.0827676e+01, 2.2568888e+01, 1.0890440e+01); + expectedForces[177] = Vec3( 2.2415739e+02, 3.5720682e+02, -8.7208211e+01); + expectedForces[178] = Vec3( -2.9808276e+02, 7.0108444e+01, -1.5361211e+02); + expectedForces[179] = Vec3( 2.3882234e+02, -2.6764176e+02, -1.7847229e+01); + expectedForces[180] = Vec3( -4.7380966e+02, 5.2547306e+01, 7.4446526e+02); + expectedForces[181] = Vec3( 4.2804072e+00, -2.2456284e+02, -2.0288206e+02); + expectedForces[182] = Vec3( 2.5474630e+00, 2.5211778e+01, 1.2675317e+01); + expectedForces[183] = Vec3( -1.4519676e+02, -1.7268277e+02, -8.4750014e+02); + expectedForces[184] = Vec3( -1.6850633e+02, 9.5223081e+02, -2.5415253e+02); + expectedForces[185] = Vec3( -2.1600185e+02, -1.6313340e+02, 1.8746411e+02); + expectedForces[186] = Vec3( 4.5719348e+01, -5.8877840e+01, -1.1199622e+02); + expectedForces[187] = Vec3( -9.0377199e+01, 2.2045926e+02, -3.2532356e+02); + expectedForces[188] = Vec3( -1.4523032e+02, -2.2127499e+02, 1.1526636e+02); + expectedForces[189] = Vec3( 1.9857975e+02, -1.8170037e+02, 3.2016150e+02); + expectedForces[190] = Vec3( 1.5659789e+02, 5.2984420e+01, -1.0121553e+02); + expectedForces[191] = Vec3( 1.3925504e+01, -1.1627739e+02, 1.7106106e+00); + expectedForces[192] = Vec3( 1.7560737e+01, 3.1275548e+02, 1.4568181e+02); + expectedForces[193] = Vec3( 8.5129168e-01, 3.2688468e+01, -2.0471785e+02); + expectedForces[194] = Vec3( 2.5640904e+02, -1.8345358e+02, 3.3082812e+02); + expectedForces[195] = Vec3( 1.5159266e+02, -7.9091822e+02, 7.6475475e+02); + expectedForces[196] = Vec3( 7.8546101e+02, 1.7887845e+02, -7.4508377e+01); + expectedForces[197] = Vec3( 6.9010029e+00, 2.1336674e+01, -7.8256484e+01); + expectedForces[198] = Vec3( -3.4033432e+01, -1.6471994e+02, -2.8721884e+02); + expectedForces[199] = Vec3( -1.2248359e+02, 5.3002993e+01, 3.5296174e+02); + expectedForces[200] = Vec3( 1.7497881e+02, 1.1744848e+02, 1.8127502e+02); + expectedForces[201] = Vec3( -1.1710882e+03, 8.7114752e+02, -1.3353036e+02); + expectedForces[202] = Vec3( 2.7510368e+02, -1.9393814e+02, 2.6671453e+02); + expectedForces[203] = Vec3( 7.3421287e+01, -3.8409917e+01, -1.0910368e+02); + expectedForces[204] = Vec3( -8.7394869e+02, -1.2323430e+03, -1.3693068e+02); + expectedForces[205] = Vec3( 2.5439149e+02, 2.4002077e+02, 3.0231859e+02); + expectedForces[206] = Vec3( -9.8167431e+01, 3.1515278e+02, -2.5512038e+02); + expectedForces[207] = Vec3( 2.7501189e+02, -4.9189774e+02, 4.5827877e+02); + expectedForces[208] = Vec3( -8.2333908e+02, -7.0609881e+02, 2.9188070e+02); + expectedForces[209] = Vec3( -2.9200330e+02, 1.9955124e+02, -7.9227826e+00); + expectedForces[210] = Vec3( 8.0151971e+02, 3.8996996e+02, -1.9508756e+02); + expectedForces[211] = Vec3( -6.2168096e+01, 2.4323951e+01, 9.8845638e+01); + expectedForces[212] = Vec3( 2.2980428e+01, -6.2829693e+02, -7.5253154e+02); + expectedForces[213] = Vec3( -5.7502634e+02, 8.2310635e+02, 3.7934867e+02); + expectedForces[214] = Vec3( -8.9168889e+01, 5.0052167e+01, -8.6850564e+01); + expectedForces[215] = Vec3( 2.7414821e+02, -5.9725191e+01, -3.7278778e+00); + expectedForces[216] = Vec3( -5.3230933e+02, 4.7698725e+02, -2.5857751e+02); + expectedForces[217] = Vec3( 2.1615644e+02, 6.0001233e+01, -1.1880182e+02); + expectedForces[218] = Vec3( 2.9837823e+01, -3.9275454e+01, -4.3913571e+01); + expectedForces[219] = Vec3( -5.6516561e+02, -1.6539113e+02, 3.3185872e+02); + expectedForces[220] = Vec3( -1.5484833e+01, -1.0085566e+01, -2.8199778e+01); + expectedForces[221] = Vec3( 6.4295337e+02, -2.7398997e+02, 8.2320867e+02); + expectedForces[222] = Vec3( 3.3816540e+02, -1.8492046e+02, 8.6215770e+02); + expectedForces[223] = Vec3( 2.4367872e+02, 8.9527142e+01, -5.9973680e+02); + expectedForces[224] = Vec3( -6.1601439e+02, -5.3093862e+02, 4.1696221e+01); + expectedForces[225] = Vec3( 2.2521478e+02, -2.9234267e+02, 2.9760244e+02); + expectedForces[226] = Vec3( -1.2672295e+02, 2.5753736e+01, -1.6216252e+02); + expectedForces[227] = Vec3( 1.1136724e+02, 4.3446676e+00, -1.4045447e+01); + expectedForces[228] = Vec3( 3.5554849e+02, 7.7446255e+00, 5.8722356e+02); + expectedForces[229] = Vec3( -7.8313952e+02, -5.9206053e+01, 5.1181391e+02); + expectedForces[230] = Vec3( -9.5647729e+01, -4.6045792e+02, -3.1515210e+02); + expectedForces[231] = Vec3( 8.7273284e+01, 8.0310279e+02, -1.2212040e+03); + expectedForces[232] = Vec3( -9.0853819e+02, -7.6005570e+02, 1.8578569e+02); + expectedForces[233] = Vec3( 1.2061615e+02, -3.2834560e+02, 5.1291192e+01); + expectedForces[234] = Vec3( 6.0149262e+02, 1.6081852e+03, -1.0922015e+03); + expectedForces[235] = Vec3( -5.8087260e+01, -2.6676779e+02, -1.5006920e+02); + expectedForces[236] = Vec3( -1.0997771e+01, 1.3012815e+02, 5.8615633e+02); + expectedForces[237] = Vec3( 4.9821503e+02, -9.5783644e+01, -6.5708073e+02); + expectedForces[238] = Vec3( -4.9394992e+02, -7.0445435e+02, -1.5540228e+02); + expectedForces[239] = Vec3( 1.5710340e+01, 1.9170336e+02, 4.6707393e+02); + expectedForces[240] = Vec3( -1.2599557e+03, 5.6104975e+02, 6.5853210e+02); + expectedForces[241] = Vec3( 1.3032986e+01, -2.7481865e+01, 8.0373029e+00); + expectedForces[242] = Vec3( 1.4371505e+02, -5.2615293e+01, -3.7929456e+02); + expectedForces[243] = Vec3( 6.0025739e+01, 1.4474905e+02, 3.6414330e+02); + expectedForces[244] = Vec3( 4.5364033e+02, 7.0785823e+01, -2.9279112e+02); + expectedForces[245] = Vec3( -9.7012956e+01, -8.2545229e+01, -5.4567106e+01); + expectedForces[246] = Vec3( -3.6449281e+02, -5.6669832e+02, -3.5196038e+02); + expectedForces[247] = Vec3( 2.6571354e+02, -2.5051716e+02, -4.7199161e+01); + expectedForces[248] = Vec3( -4.7285701e+01, 1.7950093e+02, 8.0633971e+01); + expectedForces[249] = Vec3( 1.8035439e+02, 4.6977540e+02, 2.2589769e+02); + expectedForces[250] = Vec3( 5.9853399e+01, 1.5477006e+02, -1.7011806e+02); + expectedForces[251] = Vec3( -2.6084741e+02, -2.0538756e+02, 1.0269002e+02); + expectedForces[252] = Vec3( 4.0221722e+02, -1.0368371e+02, -1.3842460e+01); + expectedForces[253] = Vec3( -4.4264447e+02, -3.0334810e+02, 1.6740779e+02); + expectedForces[254] = Vec3( -1.7373662e+02, 1.5020202e+02, -3.3761418e+02); + expectedForces[255] = Vec3( 4.7508953e+01, -5.4028784e+02, -3.6291329e+01); + expectedForces[256] = Vec3( 5.4807168e+02, -2.0293664e+02, 5.5114363e+02); + expectedForces[257] = Vec3( -4.9787370e+01, 4.5106329e+01, -5.7524550e+01); + expectedForces[258] = Vec3( -5.1584935e+02, 1.5014186e+02, -6.6369834e+02); + expectedForces[259] = Vec3( -6.0140298e+01, -9.4127280e+01, 8.7495796e+01); + expectedForces[260] = Vec3( 8.0619588e+02, -2.1066454e+02, -5.9371508e+01); + expectedForces[261] = Vec3( 1.2817429e+02, -2.7044116e+02, 5.3213275e+02); + expectedForces[262] = Vec3( -4.1467442e-01, -1.3641138e+02, -8.5576287e+01); + expectedForces[263] = Vec3( -5.6508528e+01, 2.4091504e+01, -7.9236147e+01); + expectedForces[264] = Vec3( 1.4123799e+02, 2.1326444e+02, 1.9141445e+02); + expectedForces[265] = Vec3( 1.6579721e+02, -3.2221503e+02, -1.5197776e+02); + expectedForces[266] = Vec3( -2.5871222e+02, -2.6345996e+02, -1.1149413e+03); + expectedForces[267] = Vec3( -1.2859743e+02, -3.9214753e+02, -6.5874862e+02); + expectedForces[268] = Vec3( 1.7237157e+02, -2.8729010e+02, 3.2000889e+02); + expectedForces[269] = Vec3( 6.6312203e+02, 3.5683926e+02, 9.7235616e+01); + expectedForces[270] = Vec3( -1.1860349e+02, -4.3528895e+02, 1.1598672e+03); + expectedForces[271] = Vec3( 7.7135123e+01, -2.1671305e+02, -2.3088548e+02); + expectedForces[272] = Vec3( 7.2863708e+01, 5.2065158e+02, 1.5704752e+02); + expectedForces[273] = Vec3( -3.6727477e+02, -6.0885463e+01, 4.1193960e+01); + expectedForces[274] = Vec3( 5.4858881e+01, 1.6886577e+02, -1.1662392e+01); + expectedForces[275] = Vec3( 3.2070061e+01, -1.6138709e+01, -7.6648912e+00); + expectedForces[276] = Vec3( 2.5695892e+02, 7.7719531e+01, -8.3154765e+02); + expectedForces[277] = Vec3( -3.3460202e+01, -1.3077348e+02, 3.6110539e+01); + expectedForces[278] = Vec3( -4.1360402e+02, 2.7754335e+02, -1.1139467e+02); + expectedForces[279] = Vec3( 1.0012775e+02, 1.4365237e+03, 2.6972544e+02); + expectedForces[280] = Vec3( 7.8750024e+02, -2.3376123e+02, 9.5969232e+02); + expectedForces[281] = Vec3( -2.2493912e+02, -1.1444344e+01, -6.3713547e+01); + expectedForces[282] = Vec3( -9.4211966e+01, -3.9286586e+02, -7.0932607e+01); + expectedForces[283] = Vec3( 1.6192138e+02, 2.3010404e+02, -2.1511498e+02); + expectedForces[284] = Vec3( -4.9644702e+02, -1.1894844e+01, -4.7458477e+02); + expectedForces[285] = Vec3( -1.0151600e+02, -4.2789293e+02, 5.2698223e+02); + expectedForces[286] = Vec3( 1.1350409e+01, 1.5126445e+02, -5.2740587e+01); + expectedForces[287] = Vec3( -4.7715521e+02, -3.6476152e+02, -5.4346958e+02); + expectedForces[288] = Vec3( -9.4019721e+01, -2.4758228e+02, 4.2219712e+02); + expectedForces[289] = Vec3( 3.1525053e+01, 3.7927245e+02, -2.4577041e+02); + expectedForces[290] = Vec3( 4.4004025e+02, -9.4883983e+01, -6.9075632e+01); + expectedForces[291] = Vec3( -2.6553328e+02, -2.7059185e+02, 3.1145935e+02); + expectedForces[292] = Vec3( 1.1199463e+02, 9.0805870e+01, 8.0258804e+01); + expectedForces[293] = Vec3( 7.8056273e+01, -3.5931761e+01, -1.9249727e+02); + expectedForces[294] = Vec3( -1.2443366e+01, -1.4631721e+02, 7.9733561e+01); + expectedForces[295] = Vec3( -3.2866900e+02, 1.1527926e+02, -9.3135590e+01); + expectedForces[296] = Vec3( 7.5078643e+01, -7.2653837e+02, -1.0830908e+02); + expectedForces[297] = Vec3( 1.0361037e+02, 1.5478274e+02, 1.1293089e+03); + expectedForces[298] = Vec3( -2.4014663e+02, -5.6771824e+02, 1.5441974e+02); + expectedForces[299] = Vec3( -6.8441034e+01, -1.1226846e+02, -5.4497343e+02); + expectedForces[300] = Vec3( 2.9803689e+02, 1.0649462e+03, 2.5408768e+02); + expectedForces[301] = Vec3( 5.6356599e+01, -2.3035579e+02, 7.6928758e+01); + expectedForces[302] = Vec3( 1.0229494e+02, -1.9615696e+02, -3.2600199e+02); + expectedForces[303] = Vec3( -7.0312065e+01, -3.1170055e+02, 5.6453888e+02); + expectedForces[304] = Vec3( -7.0752582e+01, 1.2273280e+02, -1.6740503e+01); + expectedForces[305] = Vec3( 6.8972998e+02, -2.8067032e+02, 6.6502848e+01); + expectedForces[306] = Vec3( -8.8407472e+02, 3.7818347e+02, -1.2141945e+03); + expectedForces[307] = Vec3( -1.0445122e+02, -4.4818836e+02, -9.5227168e+00); + expectedForces[308] = Vec3( 8.3015802e+02, 5.0941309e+02, 3.2593793e+01); + expectedForces[309] = Vec3( 7.6887033e+02, 4.3490548e+02, -1.0826101e+03); + expectedForces[310] = Vec3( 1.4352949e+02, -3.9479802e+01, 1.7718790e+02); + expectedForces[311] = Vec3( -2.5204642e+02, -3.3888239e+02, -2.7365802e+02); + expectedForces[312] = Vec3( -4.4783121e+02, 4.4465580e+02, 9.2506336e+02); + expectedForces[313] = Vec3( -3.3390337e+01, -5.0097602e+02, -3.6812516e+02); + expectedForces[314] = Vec3( -4.1862341e+02, 1.9519764e+02, -2.4571211e+02); + expectedForces[315] = Vec3( -1.4176845e+02, -3.3767798e+01, 1.7800248e+02); + expectedForces[316] = Vec3( -4.7411046e+01, 2.3841278e+01, -1.5183689e+01); + expectedForces[317] = Vec3( 1.6723204e+01, 1.4145797e+02, -1.6930384e+01); + expectedForces[318] = Vec3( -8.4841167e+02, -2.1282818e+02, 8.1614626e+01); + expectedForces[319] = Vec3( 6.5941519e+00, -1.1472179e+02, -2.3181002e+02); + expectedForces[320] = Vec3( 2.2464095e+01, -5.7606215e+00, 5.2865780e+00); + expectedForces[321] = Vec3( 3.8063827e+02, 2.4597014e+02, -4.1947008e+01); + expectedForces[322] = Vec3( -3.1531672e+02, 3.5038104e+02, -3.2724191e+02); + expectedForces[323] = Vec3( 7.4741163e+01, 7.2296536e+01, 3.1768919e+02); + expectedForces[324] = Vec3( 7.9578966e+02, -1.5345175e+02, -7.1301288e+02); + expectedForces[325] = Vec3( -3.1387318e+01, 1.7528515e+01, -3.4100670e+01); + expectedForces[326] = Vec3( 9.3853572e-01, 6.8496077e+00, 1.2234894e+01); + expectedForces[327] = Vec3( -1.3099690e+02, -4.0135958e+02, -4.3248135e+02); + expectedForces[328] = Vec3( 4.3988113e+02, -1.5944416e+02, 5.4620163e+01); + expectedForces[329] = Vec3( 1.3509243e+01, 3.6990268e+00, -2.6251838e-01); + expectedForces[330] = Vec3( -8.7459998e+01, -6.4319025e+02, 2.2863360e+02); + expectedForces[331] = Vec3( -3.5181606e+02, 3.1131978e+02, 2.8037788e+02); + expectedForces[332] = Vec3( 1.9545884e+02, 4.3994512e+01, -2.5158598e+02); + expectedForces[333] = Vec3( 1.8100917e+00, 1.9534738e+02, 1.7181161e+02); + expectedForces[334] = Vec3( -1.1846876e+02, 1.5368782e+02, 2.2261016e+02); + expectedForces[335] = Vec3( 1.4866155e+02, -4.7983795e+02, 3.0361323e+02); + expectedForces[336] = Vec3( -7.7242468e+02, 2.0736079e+02, -8.6661236e+02); + expectedForces[337] = Vec3( -7.9875679e+00, -9.0946585e+02, -7.1617627e+01); + expectedForces[338] = Vec3( 2.2543457e+02, 2.0215639e+02, 4.4285374e+02); + expectedForces[339] = Vec3( -2.6252013e+02, -1.0336519e+02, -2.6630451e+02); + expectedForces[340] = Vec3( 5.0907589e+02, -1.2491931e+02, -4.3015857e+01); + expectedForces[341] = Vec3( -6.0362692e+01, 1.0025664e+02, -9.3389235e+01); + expectedForces[342] = Vec3( 5.8779874e+02, 3.7600030e+02, 2.5345454e+02); + expectedForces[343] = Vec3( -1.3661048e+02, 1.6498482e+02, -2.6789925e+01); + expectedForces[344] = Vec3( 4.9840419e+01, -1.2136315e+02, 2.5455320e+01); + expectedForces[345] = Vec3( 2.3324807e+02, -3.6601512e+02, 5.6798114e+01); + expectedForces[346] = Vec3( 5.5853546e+01, -4.9035168e+00, -5.8726331e+02); + expectedForces[347] = Vec3( -3.8918158e+01, 3.0380495e+02, 1.0944883e+01); + expectedForces[348] = Vec3( -2.6092065e+02, 4.3443036e+02, -1.3673862e+02); + expectedForces[349] = Vec3( 1.5195166e+02, 1.1879426e+01, -1.1429493e+02); + expectedForces[350] = Vec3( -8.5687107e+02, -1.7938881e+02, 4.5576455e+00); + expectedForces[351] = Vec3( -1.0117388e+03, -3.2686610e+02, 2.9733049e+02); + expectedForces[352] = Vec3( -2.3946369e+02, 4.9753786e+02, 7.2681440e+02); + expectedForces[353] = Vec3( 3.9085837e+01, 7.4391931e+00, 3.4179196e+00); + expectedForces[354] = Vec3( 1.0462977e+03, 4.3639578e+02, -5.7349371e+02); + expectedForces[355] = Vec3( 1.2715333e+02, -5.7907885e+02, 5.7463165e+02); + expectedForces[356] = Vec3( -1.5968981e+02, 2.2295605e+01, 6.3554487e+01); + expectedForces[357] = Vec3( -1.9666111e+02, -2.0286725e+02, -8.3590992e+01); + expectedForces[358] = Vec3( 5.9985006e+00, 2.9764307e+01, 3.1304672e+01); + expectedForces[359] = Vec3( 1.0409792e+02, 4.3974987e+02, -9.1530162e+02); + expectedForces[360] = Vec3( 2.9538724e+02, 1.4353710e+02, 2.1558768e+02); + expectedForces[361] = Vec3( -3.7974445e+02, -9.0749144e+01, 1.4531502e+02); + expectedForces[362] = Vec3( 3.7089093e+02, 2.2523397e+02, -2.9760698e+02); + expectedForces[363] = Vec3( -7.6884906e+01, -2.7486958e+02, 3.5671043e+02); + expectedForces[364] = Vec3( 4.3400097e+02, 2.2275226e+02, 5.9201087e+01); + expectedForces[365] = Vec3( 2.1177620e+02, -6.4990517e+02, -1.8431623e+02); + expectedForces[366] = Vec3( -8.2234148e+01, 4.9900036e+02, 3.0906858e+02); + expectedForces[367] = Vec3( -1.4784097e+02, 1.3442463e+02, -2.6811487e+02); + expectedForces[368] = Vec3( 2.2289541e+02, -4.1933983e+02, 1.3646246e+01); + expectedForces[369] = Vec3( -2.1199481e+02, 6.2103281e+01, 1.6049768e+02); + expectedForces[370] = Vec3( -2.9429845e+01, -1.3944740e+01, 1.6000003e+01); + expectedForces[371] = Vec3( -1.5093250e+02, -1.9541345e+02, -1.5879844e+02); + expectedForces[372] = Vec3( 2.2218133e+02, 7.5740668e+01, -7.0754853e+02); + expectedForces[373] = Vec3( -4.7529615e+02, -3.5259490e+02, 3.8025744e+02); + expectedForces[374] = Vec3( 4.9308495e+01, 1.2206152e+02, 4.2704595e+01); + expectedForces[375] = Vec3( -3.6408113e+02, 9.5905960e+02, 3.3861668e+02); + expectedForces[376] = Vec3( 1.5324093e+02, -1.4375341e+02, -9.1369900e+01); + expectedForces[377] = Vec3( -3.5343609e+02, -4.4662438e+02, 3.1741831e+02); + expectedForces[378] = Vec3( -8.2721281e+02, -6.4969313e+01, 4.1869320e+02); + expectedForces[379] = Vec3( -8.7419096e+00, -4.6278343e+01, -3.0259942e+01); + expectedForces[380] = Vec3( 1.6814871e+01, 4.5462601e+01, -3.5204538e+01); + expectedForces[381] = Vec3( 1.9043143e+02, 5.1101135e+02, 2.9970918e+02); + expectedForces[382] = Vec3( -4.3547560e+02, -7.7495770e+01, -8.2311440e+01); + expectedForces[383] = Vec3( 1.3206505e+02, 4.0993476e+01, 1.5150623e+01); + expectedForces[384] = Vec3( 4.6163268e+01, -2.7722119e+01, -2.2996255e+02); + expectedForces[385] = Vec3( -4.7033552e+01, 1.5721545e+02, -9.2562636e+01); + expectedForces[386] = Vec3( -2.4164903e+02, -1.4771464e+02, -5.1675638e+01); + expectedForces[387] = Vec3( 1.3445564e+03, 3.5387081e+02, -3.7402713e+02); + expectedForces[388] = Vec3( -2.6290280e+02, 2.5025510e+02, 3.0570707e+01); + expectedForces[389] = Vec3( -4.4624214e+02, -2.4919412e+02, 1.1336564e+03); + expectedForces[390] = Vec3( 3.1188483e+02, 6.4836125e+02, 4.5477683e+01); + expectedForces[391] = Vec3( 2.5570674e+02, -2.7101115e+02, -1.2579817e+02); + expectedForces[392] = Vec3( -3.4941759e+02, -3.2508734e+01, -5.6131515e+01); + expectedForces[393] = Vec3( -1.2734301e+02, -2.0417657e+02, 5.7738004e+02); + expectedForces[394] = Vec3( 5.0435795e+01, -9.5203527e+01, -4.1237509e+00); + expectedForces[395] = Vec3( -6.8258463e+01, 1.7475914e+02, -1.6422294e+02); + expectedForces[396] = Vec3( 2.6455575e+02, 2.6880230e+02, -1.6607620e+01); + expectedForces[397] = Vec3( -3.5968167e+02, 6.6092937e+01, 1.5915445e+02); + expectedForces[398] = Vec3( 8.4092494e-01, -5.9896731e+01, -2.1856007e+01); + expectedForces[399] = Vec3( -1.9237984e+02, -1.6506355e+02, 1.3370845e+02); + expectedForces[400] = Vec3( 4.7023043e+02, 1.2931257e+02, -1.7013618e+02); + expectedForces[401] = Vec3( 9.4928843e+01, -3.1613892e+02, -4.6973091e+02); + expectedForces[402] = Vec3( -2.9180818e+02, 6.5496755e+02, -2.9430870e+02); + expectedForces[403] = Vec3( 1.6670668e+02, -2.4693913e+02, -8.8775735e+01); + expectedForces[404] = Vec3( -1.4218604e+02, 2.3173349e+02, 3.9869740e+02); + expectedForces[405] = Vec3( 4.3469431e+02, -2.4686568e+02, -2.6838523e+02); + expectedForces[406] = Vec3( 1.0671130e+02, 3.9710106e+02, 2.6478100e+02); + expectedForces[407] = Vec3( -4.4281099e+02, -3.2746126e+01, -2.0719929e+02); + expectedForces[408] = Vec3( 1.1864952e+01, -1.5901568e+02, 1.1865945e+01); + expectedForces[409] = Vec3( -6.0546863e+01, -1.3488005e+02, -2.9223986e+02); + expectedForces[410] = Vec3( 2.5845942e+01, 1.7545933e+02, -1.4590654e+02); + expectedForces[411] = Vec3( -3.0776460e+02, 2.7351986e+02, -2.0386483e+02); + expectedForces[412] = Vec3( 1.7301558e+02, 8.3012339e+01, 7.6018513e+02); + expectedForces[413] = Vec3( 1.2893147e+02, -3.9937475e+00, 1.4197628e+01); + expectedForces[414] = Vec3( -3.9803615e+02, -4.4825663e+02, 2.8616211e+01); + expectedForces[415] = Vec3( -2.3586809e+02, -8.9306136e+01, 7.5265669e+02); + expectedForces[416] = Vec3( 8.3814512e+02, -9.5563706e+00, 2.8738759e+02); + expectedForces[417] = Vec3( -3.8269399e+02, -2.3650170e+02, 1.7330415e+01); + expectedForces[418] = Vec3( 7.2310675e+00, 2.4731653e+01, 1.9491126e+01); + expectedForces[419] = Vec3( 8.4485111e+01, 9.0560261e+01, -1.4261777e+01); + expectedForces[420] = Vec3( 2.1829925e+02, -8.3951651e+01, -7.8910117e+02); + expectedForces[421] = Vec3( -2.4228018e+02, -5.7097512e+01, 2.6447829e+02); + expectedForces[422] = Vec3( 6.9666665e+01, -4.7313678e+02, 4.5559673e+02); + expectedForces[423] = Vec3( 1.0108369e+02, 4.6568610e+02, 2.5612541e+02); + expectedForces[424] = Vec3( 7.2334238e+01, -1.5660040e+02, -2.6278686e+02); + expectedForces[425] = Vec3( 1.0749954e+03, 2.4395658e+02, -8.7308262e+01); + expectedForces[426] = Vec3( 5.4983082e+02, 5.6528577e+02, -3.0489991e+02); + expectedForces[427] = Vec3( -2.1210132e+02, -1.5871954e+02, -1.6936452e+02); + expectedForces[428] = Vec3( -9.5473983e+01, 7.4879276e+01, 5.5720204e+01); + expectedForces[429] = Vec3( 5.6417182e+02, -1.3478250e+02, -4.8006673e+01); + expectedForces[430] = Vec3( -1.0055266e+02, -8.3811289e+01, 6.5259748e+01); + expectedForces[431] = Vec3( 3.0553989e+01, 4.0927300e+02, 6.2242246e+02); + expectedForces[432] = Vec3( -6.0956353e+02, 9.0301312e+02, -1.4063582e+01); + expectedForces[433] = Vec3( 3.2774559e+02, -1.0849473e+02, -8.8877712e+01); + expectedForces[434] = Vec3( 2.1371643e+02, -7.2067980e+01, 2.4803863e+02); + expectedForces[435] = Vec3( -9.0636479e+01, 1.0673514e+03, 1.3005625e+02); + expectedForces[436] = Vec3( -3.5058624e+02, -1.4968284e+02, 1.4340635e+02); + expectedForces[437] = Vec3( 3.4640813e+01, -4.8035225e+01, 4.4066226e+01); + expectedForces[438] = Vec3( -2.3414523e+02, -9.1359130e+01, 2.8535427e+02); + expectedForces[439] = Vec3( -2.7156547e+02, -6.3426763e+01, 1.6968017e+01); + expectedForces[440] = Vec3( -2.8751166e+00, 4.3192169e+00, -2.1401359e+00); + expectedForces[441] = Vec3( -2.0241419e+01, 4.2856138e+02, 7.3204868e+01); + expectedForces[442] = Vec3( -4.2166169e+01, -2.2454013e+01, -5.4998450e+01); + expectedForces[443] = Vec3( 2.6442026e+02, -1.1670567e+02, 2.8879291e+02); + expectedForces[444] = Vec3( -4.9762729e+02, 4.7320314e+02, 3.2506251e+02); + expectedForces[445] = Vec3( -3.0994232e+02, 3.6728867e+02, -6.8793662e+02); + expectedForces[446] = Vec3( -5.6328374e+00, -2.3284824e+00, 1.9650486e+01); + expectedForces[447] = Vec3( 4.0145354e+02, 7.0143762e+02, 1.3039041e+02); + expectedForces[448] = Vec3( 1.3270713e+02, -3.3050447e+02, 2.8630784e+02); + expectedForces[449] = Vec3( -3.8904836e+02, -4.6125118e+01, -3.8815388e+02); + expectedForces[450] = Vec3( 4.6293066e+02, -2.4970158e+02, -5.7231818e+01); + expectedForces[451] = Vec3( -4.7707142e+00, 1.7120822e-01, 4.5081299e+00); + expectedForces[452] = Vec3( 3.5968818e+01, -1.1892248e+01, 1.2184792e+02); + expectedForces[453] = Vec3( 4.4939172e+02, 4.8377647e+02, 3.0529778e+02); + expectedForces[454] = Vec3( -2.9071570e+02, -9.0611613e+01, -2.5190431e+02); + expectedForces[455] = Vec3( -1.4344537e+02, -1.3061997e+03, 3.8343947e+02); + expectedForces[456] = Vec3( 4.1580940e+02, -3.6864043e+02, 6.6384066e+02); + expectedForces[457] = Vec3( -3.4869949e+02, 3.3262427e+02, -8.3156358e+01); + expectedForces[458] = Vec3( -5.8565457e+00, -5.1879987e+02, -7.2717213e+02); + expectedForces[459] = Vec3( -1.0514593e+02, -2.6844396e+02, 3.0849659e+02); + expectedForces[460] = Vec3( -1.2562153e+02, 6.5438031e+01, -2.3521687e+02); + expectedForces[461] = Vec3( 8.3330016e+02, -6.7961048e+02, -7.2442064e+02); + expectedForces[462] = Vec3( -1.3328298e+02, 1.6143544e+02, -3.2000493e+02); + expectedForces[463] = Vec3( -1.1035002e+02, -8.6040775e+01, 2.0953986e+02); + expectedForces[464] = Vec3( -2.7702219e+02, -1.2156319e+02, -3.8897654e+02); + expectedForces[465] = Vec3( 3.6277432e+02, -7.0422679e+02, -8.2487472e+02); + expectedForces[466] = Vec3( -2.3947587e+02, -4.3625964e+00, 4.8716989e+01); + expectedForces[467] = Vec3( -2.6210552e+02, 9.9730213e+01, -2.4465307e+02); + expectedForces[468] = Vec3( -4.1344138e+01, -3.8636310e+01, -1.0720610e+01); + expectedForces[469] = Vec3( 2.3928584e+01, -1.3030908e+01, -1.7631168e+01); + expectedForces[470] = Vec3( -1.1873594e+02, -3.3905287e+00, -8.4575994e+01); + expectedForces[471] = Vec3( 4.3384846e+02, -4.8660929e+02, -2.4015737e+02); + expectedForces[472] = Vec3( 3.8974922e+01, 2.4401913e+02, -1.2060132e+02); + expectedForces[473] = Vec3( -4.2239647e+02, -8.6924630e+01, 5.7884013e+02); + expectedForces[474] = Vec3( 1.7222431e+02, -1.9292167e+01, 4.4184770e+01); + expectedForces[475] = Vec3( -4.8871102e+01, 1.8185057e+02, -1.3144294e+02); + expectedForces[476] = Vec3( -1.1467881e+02, -1.8387284e+02, -2.6935761e+01); + expectedForces[477] = Vec3( 4.4415601e+02, -8.6415426e+02, -2.2765803e+02); + expectedForces[478] = Vec3( 2.0893474e+02, 1.3529112e+02, 2.4108004e+02); + expectedForces[479] = Vec3( -1.2802570e+01, -4.7089261e+00, -7.0024810e+00); + expectedForces[480] = Vec3( -1.0878354e+02, 4.5030357e+02, -3.9086153e+02); + expectedForces[481] = Vec3( -3.7659745e+01, -4.9295745e+01, -6.0028516e+01); + expectedForces[482] = Vec3( 1.8851809e+02, -1.6863914e+02, 1.2031505e+02); + expectedForces[483] = Vec3( 2.2040686e+02, -1.1953187e+03, 2.9106238e+02); + expectedForces[484] = Vec3( -1.1642847e+01, 5.6739977e+01, 3.7532413e+00); + expectedForces[485] = Vec3( 3.5013234e+00, 2.8236323e+01, -1.1738866e+01); + expectedForces[486] = Vec3( -2.0051506e+03, -5.3138994e+02, 4.0428126e+02); + expectedForces[487] = Vec3( 1.6887843e+02, 1.1687735e+02, -9.6232177e+01); + expectedForces[488] = Vec3( 2.5030722e+02, -3.6662537e+02, -5.8595505e+01); + expectedForces[489] = Vec3( -1.5924273e+01, -2.1761920e+02, -3.4885425e+01); + expectedForces[490] = Vec3( 1.0423157e+02, 4.0767827e+01, 1.4036192e+02); + expectedForces[491] = Vec3( 5.0090776e+02, -5.0455702e+01, -4.2524815e+02); + expectedForces[492] = Vec3( 3.8037844e+02, 5.7460724e+02, 2.1243310e+02); + expectedForces[493] = Vec3( -1.1487653e+02, 3.3550952e+01, -5.7050397e+01); + expectedForces[494] = Vec3( 1.8425697e+02, -2.7223857e+02, -2.9384020e+01); + expectedForces[495] = Vec3( -1.1115514e+02, -4.4519957e+02, -3.3628896e+02); + expectedForces[496] = Vec3( 3.8865823e+02, -2.1372852e+02, -7.8979988e+02); + expectedForces[497] = Vec3( -3.1740258e+02, 4.4824683e+02, -5.0382680e+02); + expectedForces[498] = Vec3( 1.5521684e+02, -1.5278429e+02, -1.8418006e+02); + expectedForces[499] = Vec3( -2.2213191e+01, 7.1015095e+00, 1.0308820e+01); + expectedForces[500] = Vec3( 3.0011560e+01, 2.4584541e+02, -5.3231694e+02); + expectedForces[501] = Vec3( -8.4865171e+02, -2.0279022e+02, -6.8435095e+02); + expectedForces[502] = Vec3( 7.0477549e+00, 2.7626774e+01, -1.6246047e+01); + expectedForces[503] = Vec3( -7.1309648e+01, -1.6054218e+02, -3.1621746e+01); + expectedForces[504] = Vec3( 3.6317856e+02, 1.9055487e+02, 3.9196046e+01); + expectedForces[505] = Vec3( 1.4643265e+02, -1.2295335e+03, -2.2268806e+01); + expectedForces[506] = Vec3( -3.6638240e+02, -6.5310612e+00, -6.8077013e+02); + expectedForces[507] = Vec3( 1.9107813e+02, -6.2176534e+02, 5.1826941e+02); + expectedForces[508] = Vec3( 1.7226933e+02, -3.8939126e+02, -7.4174355e+02); + expectedForces[509] = Vec3( 1.3541890e+02, 4.1350561e+02, -2.6155396e+02); + expectedForces[510] = Vec3( 1.6452609e+02, -4.1963597e+02, 1.6322800e+02); + expectedForces[511] = Vec3( 9.1248387e+01, -1.3380408e+01, -5.1326806e+02); + expectedForces[512] = Vec3( 1.2420564e+02, 8.9492432e+02, 2.8660661e+02); + expectedForces[513] = Vec3( 4.5609859e+02, 3.4252036e+01, -2.3830457e+02); + expectedForces[514] = Vec3( -8.8282131e+01, -1.4512876e+02, -4.5703642e+01); + expectedForces[515] = Vec3( -6.9194714e+01, 5.5053415e+02, -3.9527911e+02); + expectedForces[516] = Vec3( -1.5570798e+02, 4.1650792e-02, 3.0224667e+02); + expectedForces[517] = Vec3( 9.2007640e+01, 3.6378499e+02, -2.2069415e+01); + expectedForces[518] = Vec3( 2.7996922e+02, -2.0932322e+02, 6.2987796e+01); + expectedForces[519] = Vec3( -7.4985282e+01, 1.3508916e+02, 1.1453750e+02); + expectedForces[520] = Vec3( 1.2149786e+01, 4.2161047e+02, -2.9521571e+02); + expectedForces[521] = Vec3( 1.9419524e+01, -8.6619683e+01, -9.4040609e+01); + expectedForces[522] = Vec3( 3.5495800e+01, 6.4028894e+01, 1.2320699e+02); + expectedForces[523] = Vec3( -5.6501302e+02, -1.2497462e+02, 8.1633096e+02); + expectedForces[524] = Vec3( -3.1775230e+02, 1.6467221e+02, -4.8242287e+01); + expectedForces[525] = Vec3( -1.8325245e+02, -1.0751941e+02, 6.2172117e+02); + expectedForces[526] = Vec3( 1.8164299e+00, 8.0654784e-01, -1.4484741e+01); + expectedForces[527] = Vec3( 2.6686986e+00, 1.5933475e+01, -6.8843007e+01); + expectedForces[528] = Vec3( -1.3208642e+02, -1.2281791e+02, 7.8417959e+01); + expectedForces[529] = Vec3( -4.8078193e+01, -1.5140963e+02, 8.3605002e+01); + expectedForces[530] = Vec3( 8.5925332e+01, 1.9959621e+01, -5.9034655e+01); + expectedForces[531] = Vec3( -3.1311626e+00, -3.4009931e+01, -1.5895685e+02); + expectedForces[532] = Vec3( -9.9694666e+01, 1.0296874e+00, 1.0482739e+02); + expectedForces[533] = Vec3( 2.8954747e+02, 1.2018666e+02, 2.2155006e+02); + expectedForces[534] = Vec3( 3.2588176e+02, 3.6622498e+01, 3.5801460e+02); + expectedForces[535] = Vec3( -6.5985617e+01, -3.5501709e+02, 6.8149810e+01); + expectedForces[536] = Vec3( -4.7632753e+02, 2.7936656e+02, 1.5548558e+02); + expectedForces[537] = Vec3( 4.7724904e+02, 2.1647106e+02, 1.2003317e+02); + expectedForces[538] = Vec3( -1.6225405e+02, 1.4264998e+02, -1.0113321e+02); + expectedForces[539] = Vec3( -3.2540487e+01, -7.5643223e+01, 1.6054148e+01); + expectedForces[540] = Vec3( 4.3311991e+02, 5.8082595e+02, 1.9354276e+02); + expectedForces[541] = Vec3( -3.4924430e+02, -7.0056069e+01, 1.0274560e+02); + expectedForces[542] = Vec3( 1.9441645e+02, -2.0017354e+02, -2.3280717e+02); + expectedForces[543] = Vec3( -4.1530380e+01, -5.6394351e+02, 2.4472509e+02); + expectedForces[544] = Vec3( -1.6193396e+01, -8.0431396e+01, -2.9094018e+02); + expectedForces[545] = Vec3( -1.9414773e+01, 4.6180982e+01, 3.3123072e+01); + expectedForces[546] = Vec3( -3.9314039e+02, -3.9874866e+02, 4.5308571e+02); + expectedForces[547] = Vec3( -7.1897482e+01, -1.1940445e+02, -2.7405931e+02); + expectedForces[548] = Vec3( 3.0646396e+02, 6.1235747e+01, -1.5253270e+02); + expectedForces[549] = Vec3( -3.2480464e+02, 4.3056561e+02, 3.2532485e+01); + expectedForces[550] = Vec3( 1.2818655e+02, 7.4294994e-01, -5.7650521e+00); + expectedForces[551] = Vec3( -1.7481437e+02, -2.6203225e+02, -9.6793481e+01); + expectedForces[552] = Vec3( 1.9259110e+02, 3.0171883e+02, 5.2403235e+02); + expectedForces[553] = Vec3( -7.8132123e+01, -7.6569340e+00, -1.1140240e+02); + expectedForces[554] = Vec3( -5.2504673e+02, -4.3700574e+02, 4.3321261e+02); + expectedForces[555] = Vec3( -9.9785283e+02, 2.7139143e+02, -4.1723547e+02); + expectedForces[556] = Vec3( 2.7115933e+02, -8.7444541e+01, 1.0745103e+02); + expectedForces[557] = Vec3( 1.4348018e+02, 1.4013343e+02, -4.0305733e+02); + expectedForces[558] = Vec3( 4.9491010e+02, 4.3040089e+02, -3.5558583e+02); + expectedForces[559] = Vec3( -1.8510736e+02, 6.7129731e+01, -2.1324364e+02); + expectedForces[560] = Vec3( 8.4478090e+01, 4.0986269e+01, 4.1401094e+02); + expectedForces[561] = Vec3( 4.4188419e+01, -8.6520108e+02, 6.8555821e+02); + expectedForces[562] = Vec3( -4.5036974e+02, 2.2379481e+02, 6.2457971e+01); + expectedForces[563] = Vec3( 2.4325836e+02, 6.9725116e+01, 3.6266296e+01); + expectedForces[564] = Vec3( 1.5611925e+02, -2.4471023e+02, 4.7857332e+02); + expectedForces[565] = Vec3( -3.5692822e+02, -2.7248961e+02, -1.8165146e+02); + expectedForces[566] = Vec3( 4.3093388e+02, 1.6944839e+02, -4.4177741e+02); + expectedForces[567] = Vec3( 5.2118711e+02, -1.5252783e+02, -1.6964047e+02); + expectedForces[568] = Vec3( 1.3899083e+03, 3.8363654e+02, -6.4623177e+02); + expectedForces[569] = Vec3( -1.4984858e+02, 4.5097170e+01, -5.0257768e+01); + expectedForces[570] = Vec3( -8.1979709e+01, -4.1632909e+01, -5.1367825e+02); + expectedForces[571] = Vec3( -7.8645235e+00, 1.8105470e+01, 9.2902759e+01); + expectedForces[572] = Vec3( 1.2725548e+02, 1.3926229e+02, -4.3752260e+01); + expectedForces[573] = Vec3( -2.7817289e+01, -8.0900345e+01, -4.3178498e+02); + expectedForces[574] = Vec3( 2.2115263e+02, -7.8807799e+01, 8.8367391e+01); + expectedForces[575] = Vec3( -1.2756938e+02, 4.2170937e+02, -6.8418245e+01); + expectedForces[576] = Vec3( 8.8370341e+01, -1.4671130e+02, -5.6211071e+02); + expectedForces[577] = Vec3( 6.7701453e+02, 2.1228010e+02, 2.3047236e+02); + expectedForces[578] = Vec3( -1.2694819e+02, -7.2734890e+00, 1.1007893e+02); + expectedForces[579] = Vec3( -6.8945756e+02, 1.7359485e+02, -2.5607776e+02); + expectedForces[580] = Vec3( 6.7323923e+00, 3.1574487e+02, 5.9741152e+02); + expectedForces[581] = Vec3( 2.1214031e+02, -4.7565197e+01, -9.6896159e+01); + expectedForces[582] = Vec3( -3.4876562e+02, 5.8335489e+01, -1.7058451e+02); + expectedForces[583] = Vec3( -1.6516914e+02, -3.8913162e+02, 5.8832025e+02); + expectedForces[584] = Vec3( 4.7753612e+01, -6.6792213e+01, -4.6492749e+01); + expectedForces[585] = Vec3( -4.7166578e+02, 7.1811831e+02, 7.0620222e+02); + expectedForces[586] = Vec3( -3.0570577e+02, -1.7681907e+02, -2.1227370e+02); + expectedForces[587] = Vec3( 1.8122997e+02, -6.8318737e+01, -3.4853368e+02); + expectedForces[588] = Vec3( 7.5752093e+01, 3.9702196e+02, -9.0196404e+02); + expectedForces[589] = Vec3( 5.1185528e+02, -7.7747186e+02, -3.3969581e+02); + expectedForces[590] = Vec3( -3.1187606e+01, 5.9593198e+01, 7.7918649e+01); + expectedForces[591] = Vec3( 2.2741676e+02, 2.1705631e+02, 3.9920149e+02); + expectedForces[592] = Vec3( 7.0516894e+01, 3.3389665e+02, -6.8443760e+00); + expectedForces[593] = Vec3( -9.9645406e+02, 2.8574127e+02, -8.0946834e+02); + expectedForces[594] = Vec3( 1.0930460e+02, 1.5869363e+03, -4.0704089e+02); + expectedForces[595] = Vec3( -3.0341438e+02, -5.7494385e+00, 2.9655509e+02); + expectedForces[596] = Vec3( 8.7955203e+01, -7.6811348e+01, -6.9558652e+01); + expectedForces[597] = Vec3( -9.4378353e+01, 3.6253070e+02, 9.0703343e-01); + expectedForces[598] = Vec3( -4.7595525e+01, -6.9148379e+02, -4.6737971e+02); + expectedForces[599] = Vec3( 2.2339987e+02, -2.5503335e+02, 2.8552040e+02); + expectedForces[600] = Vec3( 1.0309072e+02, -2.1298204e+02, -4.3393283e+02); + expectedForces[601] = Vec3( -2.4581477e+02, 2.5126386e+02, -1.8679710e+02); + expectedForces[602] = Vec3( 7.7926618e+00, -2.4947558e+01, 1.5962011e+02); + expectedForces[603] = Vec3( 7.0099476e+02, 5.9496129e+01, 2.0314640e+02); + expectedForces[604] = Vec3( -5.2583810e+01, 3.1237489e+01, -4.0902937e+00); + expectedForces[605] = Vec3( -5.4435871e+01, -7.7056693e+01, -1.5137215e+01); + expectedForces[606] = Vec3( -7.8684074e+02, 8.1673860e+02, 5.0192222e+02); + expectedForces[607] = Vec3( 2.9859285e+02, 1.9661708e+02, -1.9940993e+02); + expectedForces[608] = Vec3( -9.9358476e-01, -3.4789219e+02, 1.7693106e+02); + expectedForces[609] = Vec3( 6.7880927e+02, 7.2768533e+01, 1.1973248e+03); + expectedForces[610] = Vec3( -1.2072838e+00, 1.1770157e+02, -8.6765918e+01); + expectedForces[611] = Vec3( -4.3236695e+02, -2.8583002e+02, 1.3459508e+02); + expectedForces[612] = Vec3( -6.1894609e+01, 4.4705141e+02, -2.3264215e+02); + expectedForces[613] = Vec3( -2.6948720e+01, -2.7688230e+01, 4.6300601e+01); + expectedForces[614] = Vec3( 4.3954815e+01, 6.1244278e+01, 1.0727211e+02); + expectedForces[615] = Vec3( -2.2049132e+02, -9.7233594e+01, 8.3807949e+01); + expectedForces[616] = Vec3( 2.8631226e+02, -1.3478640e+02, -5.0675977e+02); + expectedForces[617] = Vec3( -1.1458029e+01, 6.3762007e+01, -4.9643140e+01); + expectedForces[618] = Vec3( 7.7363305e+01, 1.1936816e+02, 3.9692323e+01); + expectedForces[619] = Vec3( -8.4199858e+01, 2.3567494e+02, 7.2885200e+01); + expectedForces[620] = Vec3( -7.4500104e+00, 3.5567340e+00, -2.2676267e+01); + expectedForces[621] = Vec3( -7.9200057e+02, 3.2245192e+01, 1.1829644e+01); + expectedForces[622] = Vec3( 3.9959336e+02, 2.2447865e+02, -3.1413233e+02); + expectedForces[623] = Vec3( 1.5810527e+02, -2.2341997e+02, 2.3388212e+02); + expectedForces[624] = Vec3( -2.9248657e+02, -1.0806250e+03, -6.1268035e+01); + expectedForces[625] = Vec3( 6.5061442e+02, 1.2244756e+02, -1.1976147e+02); + expectedForces[626] = Vec3( -1.7787710e+02, 3.7279354e+02, -3.7911745e+02); + expectedForces[627] = Vec3( 3.7145927e+02, -2.5203732e+02, -2.2889342e+02); + expectedForces[628] = Vec3( 1.9440281e+02, -2.3076142e+02, 7.2945279e+01); + expectedForces[629] = Vec3( -2.3603693e+02, -1.1987203e+02, -1.2000208e+02); + expectedForces[630] = Vec3( -8.4811726e+01, -6.4500846e+02, -5.1257210e+02); + expectedForces[631] = Vec3( -1.6183393e+01, 1.3980655e+01, -2.3189702e+00); + expectedForces[632] = Vec3( 1.3526098e+02, 1.3800365e+02, -9.4360476e+01); + expectedForces[633] = Vec3( 2.0983514e+01, 5.1156494e+02, -4.3526557e+01); + expectedForces[634] = Vec3( -2.8666500e+02, -5.8235691e+02, -8.7425194e+01); + expectedForces[635] = Vec3( -1.7183604e+02, 1.0002944e+01, 6.5855812e+02); + expectedForces[636] = Vec3( -2.1735465e+02, 9.4664675e+02, 8.9132890e+02); + expectedForces[637] = Vec3( 6.3759184e+01, -5.2436201e+02, 1.2455578e+02); + expectedForces[638] = Vec3( 3.2176621e+02, 1.8182348e+02, -4.4863340e+02); + expectedForces[639] = Vec3( -8.4308252e+02, -1.6268681e+02, 5.8113352e+02); + expectedForces[640] = Vec3( 6.1223389e+01, 3.6767423e+02, 5.9071999e+02); + expectedForces[641] = Vec3( 2.2546928e+02, -2.2022805e+02, 8.3027103e+01); + expectedForces[642] = Vec3( -4.0385190e+02, 2.0141033e+02, 2.7296512e+01); + expectedForces[643] = Vec3( 8.4204485e+01, -7.1102294e+01, 5.7642677e+01); + expectedForces[644] = Vec3( 6.1859901e+01, 1.4828523e+02, -2.6764016e+02); + expectedForces[645] = Vec3( -6.7249932e+02, -8.4613525e+01, -3.9792609e+02); + expectedForces[646] = Vec3( 9.9116485e+01, -3.7714583e+01, -5.3966332e+01); + expectedForces[647] = Vec3( 2.0868628e+02, 2.9747206e+02, 3.3931416e+02); // tolerance is higher here due to interpolation used in setting tapering coefficients; // if tapering turned off, then absolute difference < 2.0e-05 double tolerance = 5.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); // test sigma/epsilon rules for dispersion correction - if( includeVdwDispersionCorrection ){ + if (includeVdwDispersionCorrection) { std::vector sigmaRules; std::vector epsilonRules; std::vector expectedEnergies; - sigmaRules.push_back( "ARITHMETIC" ); - epsilonRules.push_back( "ARITHMETIC" ); - expectedEnergies.push_back( 6.2137988e+03 ); + sigmaRules.push_back("ARITHMETIC"); + epsilonRules.push_back("ARITHMETIC"); + expectedEnergies.push_back(6.2137988e+03); - sigmaRules.push_back( "GEOMETRIC" ); - epsilonRules.push_back( "GEOMETRIC" ); - expectedEnergies.push_back( 3.6358216e+03 ); + sigmaRules.push_back("GEOMETRIC"); + epsilonRules.push_back("GEOMETRIC"); + expectedEnergies.push_back( 3.6358216e+03); - sigmaRules.push_back( "CUBIC-MEAN" ); - epsilonRules.push_back( "HARMONIC" ); - expectedEnergies.push_back( 3.2774624e+03 ); + sigmaRules.push_back("CUBIC-MEAN"); + epsilonRules.push_back("HARMONIC"); + expectedEnergies.push_back(3.2774624e+03); - for( unsigned int ii = 0; ii < sigmaRules.size(); ii++ ){ - setupAndGetForcesEnergyVdwWater( sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy ); + for (unsigned int ii = 0; ii < sigmaRules.size(); ii++) { + setupAndGetForcesEnergyVdwWater(sigmaRules[ii], epsilonRules[ii], cutoff, boxDimension, includeVdwDispersionCorrection, forces, energy); testName = "testVdwWaterWithDispersionCorrection_" + sigmaRules[ii] + '_' + epsilonRules[ii]; - ASSERT_EQUAL_TOL_MOD( expectedEnergies[ii], energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergies[ii], energy, tolerance, testName); } } @@ -2050,13 +2050,13 @@ int main(int argc, char* argv[]) { // tests based on box of water int includeVdwDispersionCorrection = 0; - testVdwWater( includeVdwDispersionCorrection); + testVdwWater(includeVdwDispersionCorrection); // includes tests for various combinations of sigma/epsilon rules // when computing vdw dispersion correction includeVdwDispersionCorrection = 1; - testVdwWater( includeVdwDispersionCorrection); + testVdwWater(includeVdwDispersionCorrection); // test triclinic boxes diff --git a/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp b/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp index 97c61ea8d..33dd54a0d 100644 --- a/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/cuda/tests/TestCudaWcaDispersionForce.cpp @@ -54,13 +54,13 @@ const double TOL = 1e-4; extern "C" void registerAmoebaCudaKernelFactories(); -void compareForcesEnergy( std::string& testName, double expectedEnergy, double energy, - const std::vector& expectedForces, - const std::vector& forces, double tolerance) { - for( unsigned int ii = 0; ii < forces.size(); ii++ ){ - ASSERT_EQUAL_VEC_MOD( expectedForces[ii], forces[ii], tolerance, testName ); +void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, + const std::vector& expectedForces, + const std::vector& forces, double tolerance) { + for (unsigned int ii = 0; ii < forces.size(); ii++) { + ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); } - ASSERT_EQUAL_TOL_MOD( expectedEnergy, energy, tolerance, testName ); + ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); } // test Wca dispersion @@ -76,48 +76,48 @@ void testWcaDispersionAmmonia() { System system; AmoebaWcaDispersionForce* amoebaWcaDispersionForce = new AmoebaWcaDispersionForce();; - amoebaWcaDispersionForce->setEpso( 4.6024000e-01 ); - amoebaWcaDispersionForce->setEpsh( 5.6484000e-02 ); - amoebaWcaDispersionForce->setRmino( 1.7025000e-01 ); - amoebaWcaDispersionForce->setRminh( 1.3275000e-01 ); - amoebaWcaDispersionForce->setDispoff( 2.6000000e-02 ); - amoebaWcaDispersionForce->setAwater( 3.3428000e+01 ); - amoebaWcaDispersionForce->setSlevy( 1.0000000e+00 ); - amoebaWcaDispersionForce->setShctd( 8.1000000e-01 ); + amoebaWcaDispersionForce->setEpso( 4.6024000e-01); + amoebaWcaDispersionForce->setEpsh( 5.6484000e-02); + amoebaWcaDispersionForce->setRmino( 1.7025000e-01); + amoebaWcaDispersionForce->setRminh( 1.3275000e-01); + amoebaWcaDispersionForce->setDispoff(2.6000000e-02); + amoebaWcaDispersionForce->setAwater( 3.3428000e+01); + amoebaWcaDispersionForce->setSlevy( 1.0000000e+00); + amoebaWcaDispersionForce->setShctd( 8.1000000e-01); // addParticle: radius, epsilon - for( unsigned int ii = 0; ii < 2; ii++ ){ - system.addParticle( 1.4007000e+01 ); - amoebaWcaDispersionForce->addParticle( 1.8550000e-01, 4.3932000e-01 ); + for (unsigned int ii = 0; ii < 2; ii++) { + system.addParticle( 1.4007000e+01); + amoebaWcaDispersionForce->addParticle( 1.8550000e-01, 4.3932000e-01); - system.addParticle( 1.0080000e+00 ); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02 ); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); - system.addParticle( 1.0080000e+00 ); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02 ); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); - system.addParticle( 1.0080000e+00 ); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02 ); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); } std::vector positions(numberOfParticles); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03 ); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02 ); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02 ); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02 ); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03 ); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02 ); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02 ); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02 ); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); system.addForce(amoebaWcaDispersionForce); std::string platformName; platformName = "CUDA"; LangevinIntegrator integrator(0.0, 0.1, 0.01); - Context context(system, integrator, Platform::getPlatformByName( platformName ) ); + Context context(system, integrator, Platform::getPlatformByName(platformName)); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -129,17 +129,17 @@ void testWcaDispersionAmmonia() { std::vector expectedForces(numberOfParticles); double expectedEnergy = -2.6981209e+01; - expectedForces[0] = Vec3( 4.7839388e+00, -7.3510133e-04, -5.0382764e-01 ); - expectedForces[1] = Vec3( 1.4657758e+00, 1.2431003e+00, -6.7075886e-01 ); - expectedForces[2] = Vec3( 1.4563936e+00, -1.2399917e+00, -6.7443841e-01 ); - expectedForces[3] = Vec3( 2.1116744e+00, -2.7407512e-03, 1.3271245e+00 ); - expectedForces[4] = Vec3( -4.7528440e+00, -1.5148066e-03, 1.2653813e+00 ); - expectedForces[5] = Vec3( -1.1875619e+00, -1.2866678e+00, -3.9109060e-01 ); - expectedForces[6] = Vec3( -2.6885679e+00, -4.3038639e-04, 3.3763583e-02 ); - expectedForces[7] = Vec3( -1.1888087e+00, 1.2889802e+00, -3.8615387e-01 ); + expectedForces[0] = Vec3( 4.7839388e+00, -7.3510133e-04, -5.0382764e-01); + expectedForces[1] = Vec3( 1.4657758e+00, 1.2431003e+00, -6.7075886e-01); + expectedForces[2] = Vec3( 1.4563936e+00, -1.2399917e+00, -6.7443841e-01); + expectedForces[3] = Vec3( 2.1116744e+00, -2.7407512e-03, 1.3271245e+00); + expectedForces[4] = Vec3( -4.7528440e+00, -1.5148066e-03, 1.2653813e+00); + expectedForces[5] = Vec3( -1.1875619e+00, -1.2866678e+00, -3.9109060e-01); + expectedForces[6] = Vec3( -2.6885679e+00, -4.3038639e-04, 3.3763583e-02); + expectedForces[7] = Vec3( -1.1888087e+00, 1.2889802e+00, -3.8615387e-01); double tolerance = 1.0e-04; - compareForcesEnergy( testName, expectedEnergy, energy, expectedForces, forces, tolerance ); + compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); // Try changing the particle parameters and make sure it's still correct. diff --git a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp index 5adaba8b9..0a77654ee 100644 --- a/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp +++ b/plugins/amoeba/platforms/reference/src/AmoebaReferenceKernels.cpp @@ -99,7 +99,7 @@ void ReferenceCalcAmoebaBondForceKernel::initialize(const System& system, const particle1.push_back(particle1Index); particle2.push_back(particle2Index); - length.push_back( static_cast(lengthValue)); + length.push_back(static_cast(lengthValue)); kQuadratic.push_back(static_cast(kValue)); } globalBondCubic = static_cast(force.getAmoebaGlobalBondCubic()); @@ -153,7 +153,7 @@ void ReferenceCalcAmoebaAngleForceKernel::initialize(const System& system, const particle1.push_back(particle1Index); particle2.push_back(particle2Index); particle3.push_back(particle3Index); - angle.push_back( static_cast(angleValue)); + angle.push_back(static_cast(angleValue)); kQuadratic.push_back(static_cast(k)); } globalAngleCubic = static_cast(force.getAmoebaGlobalAngleCubic()); @@ -206,8 +206,8 @@ void ReferenceCalcAmoebaInPlaneAngleForceKernel::initialize(const System& system particle2.push_back(particle2Index); particle3.push_back(particle3Index); particle4.push_back(particle4Index); - angle.push_back( static_cast(angleValue)); - kQuadratic.push_back( static_cast(k)); + angle.push_back(static_cast(angleValue)); + kQuadratic.push_back(static_cast(k)); } globalInPlaneAngleCubic = static_cast(force.getAmoebaGlobalInPlaneAngleCubic()); globalInPlaneAngleQuartic = static_cast(force.getAmoebaGlobalInPlaneAngleQuartic()); @@ -314,9 +314,9 @@ void ReferenceCalcAmoebaStretchBendForceKernel::initialize(const System& system, particle3.push_back(particle3Index); lengthABParameters.push_back(static_cast(lengthAB)); lengthCBParameters.push_back(static_cast(lengthCB)); - angleParameters.push_back( static_cast(angle)); - k1Parameters.push_back( static_cast(k1)); - k2Parameters.push_back( static_cast(k2)); + angleParameters.push_back(static_cast(angle)); + k1Parameters.push_back(static_cast(k1)); + k2Parameters.push_back(static_cast(k2)); } } @@ -1043,14 +1043,14 @@ void ReferenceCalcAmoebaWcaDispersionForceKernel::initialize(const System& syste totalMaximumDispersionEnergy = static_cast(AmoebaWcaDispersionForceImpl::getTotalMaximumDispersionEnergy(force)); - epso = static_cast(force.getEpso() ); - epsh = static_cast(force.getEpsh() ); - rmino = static_cast(force.getRmino() ); - rminh = static_cast(force.getRminh() ); + epso = static_cast(force.getEpso()); + epsh = static_cast(force.getEpsh()); + rmino = static_cast(force.getRmino()); + rminh = static_cast(force.getRminh()); awater = static_cast(force.getAwater()); - shctd = static_cast(force.getShctd() ); + shctd = static_cast(force.getShctd()); dispoff = static_cast(force.getDispoff()); - slevy = static_cast(force.getSlevy() ); + slevy = static_cast(force.getSlevy()); } double ReferenceCalcAmoebaWcaDispersionForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) { diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp index cd4dd6ed7..0eeed6459 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceInPlaneAngleForce.cpp @@ -210,9 +210,9 @@ RealOpenMM AmoebaReferenceInPlaneAngleForce::calculateAngleIxn(const RealVec& po RealOpenMM delta2 = delta*two; AmoebaReferenceForce::getCrossProduct(deltaR[BD], deltaR[CD], deltaR[BDxCD]); - AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[CD], deltaR[TxCD] ); + AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[CD], deltaR[TxCD]); AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[BD], deltaR[ADxBD]); - AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[T], deltaR[ADxT] ); + AmoebaReferenceForce::getCrossProduct(deltaR[AD], deltaR[T], deltaR[ADxT]); for (int ii = 0; ii < 3; ii++) { RealOpenMM term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp index 459766435..59a52e178 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceOutOfPlaneBendForce.cpp @@ -91,7 +91,7 @@ RealOpenMM AmoebaReferenceOutOfPlaneBendForce::calculateOutOfPlaneBendIxn(const std::vector tempVector(3); AmoebaReferenceForce::getCrossProduct(deltaR[CB], deltaR[DB], tempVector); - RealOpenMM eE = AmoebaReferenceForce::getDotProduct3(deltaR[AB], tempVector ); + RealOpenMM eE = AmoebaReferenceForce::getDotProduct3(deltaR[AB], tempVector); RealOpenMM dot = AmoebaReferenceForce::getDotProduct3(deltaR[AD], deltaR[CD]); RealOpenMM cc = rAD2*rCD2 - dot*dot; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp index e46680087..5a58bb299 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferencePiTorsionForce.cpp @@ -88,8 +88,8 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn(const RealVec& p deltaR[P][ii] += positionAtomC[ii]; deltaR[Q][ii] += positionAtomD[ii]; } - AmoebaReferenceForce::getCrossProduct(deltaR[CP], deltaR[DC], deltaR[T] ); - AmoebaReferenceForce::getCrossProduct(deltaR[DC], deltaR[QD], deltaR[U] ); + AmoebaReferenceForce::getCrossProduct(deltaR[CP], deltaR[DC], deltaR[T]); + AmoebaReferenceForce::getCrossProduct(deltaR[DC], deltaR[QD], deltaR[U]); AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[U], deltaR[TU]); RealOpenMM rT2 = AmoebaReferenceForce::getNormSquared3(deltaR[T]); @@ -123,27 +123,27 @@ RealOpenMM AmoebaReferencePiTorsionForce::calculatePiTorsionIxn(const RealVec& p RealOpenMM factorT = dedphi/(rDC*rT2); RealOpenMM factorU = -dedphi/(rDC*rU2); - AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[DC], deltaR[dT] ); - AmoebaReferenceForce::getCrossProduct(deltaR[U], deltaR[DC], deltaR[dU] ); + AmoebaReferenceForce::getCrossProduct(deltaR[T], deltaR[DC], deltaR[dT]); + AmoebaReferenceForce::getCrossProduct(deltaR[U], deltaR[DC], deltaR[dU]); for (int ii = 0; ii < 3; ii++) { deltaR[dT][ii] *= factorT; deltaR[dU][ii] *= factorU; } - AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[DC], deltaR[dP] ); - AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[DC], deltaR[dQ] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[DC], deltaR[dP] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[DC], deltaR[dQ] ); - AmoebaReferenceForce::getCrossProduct(deltaR[DP], deltaR[dT], deltaR[dC1] ); - AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[QD], deltaR[dC2] ); + AmoebaReferenceForce::getCrossProduct(deltaR[DP], deltaR[dT], deltaR[dC1]); + AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[QD], deltaR[dC2]); - AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[CP], deltaR[dD1] ); - AmoebaReferenceForce::getCrossProduct(deltaR[QC], deltaR[dU], deltaR[dD2] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[CP], deltaR[dD1]); + AmoebaReferenceForce::getCrossProduct(deltaR[QC], deltaR[dU], deltaR[dD2]); - AmoebaReferenceForce::getCrossProduct(deltaR[BD], deltaR[dP], d[A] ); - AmoebaReferenceForce::getCrossProduct(deltaR[dP], deltaR[AD], d[B] ); + AmoebaReferenceForce::getCrossProduct(deltaR[BD], deltaR[dP], d[A] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dP], deltaR[AD], d[B] ); - AmoebaReferenceForce::getCrossProduct(deltaR[FC], deltaR[dQ], d[E] ); - AmoebaReferenceForce::getCrossProduct(deltaR[dQ], deltaR[EC], d[F] ); + AmoebaReferenceForce::getCrossProduct(deltaR[FC], deltaR[dQ], d[E] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dQ], deltaR[EC], d[F] ); for (int ii = 0; ii < 3; ii++) { d[C][ii] = deltaR[dC1][ii] + deltaR[dC2][ii] + deltaR[dP][ii] - d[E][ii] - d[F][ii]; diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp index 1775b9ae6..cefef15c6 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceTorsionTorsionForce.cpp @@ -478,7 +478,7 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn(const AmoebaReferenceForce::getCrossProduct(deltaR[CA], deltaR[dT], d[B]); AmoebaReferenceForce::getCrossProduct(deltaR[dU], deltaR[DC], tmp[0]); - AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[BA], d[C] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dT], deltaR[BA], d[C]); AmoebaReferenceForce::getCrossProduct(deltaR[DB], deltaR[dU], tmp[1]); d[B][0] += tmp[0][0]; @@ -507,12 +507,12 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn(const // dB2 - AmoebaReferenceForce::getCrossProduct(deltaR[dU2], deltaR[DC], tmp[0] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dU2], deltaR[DC], tmp[0]); // dC2 - AmoebaReferenceForce::getCrossProduct(deltaR[DB], deltaR[dU2], tmp[1] ); - AmoebaReferenceForce::getCrossProduct(deltaR[dV2], deltaR[ED], tmp[2] ); + AmoebaReferenceForce::getCrossProduct(deltaR[DB], deltaR[dU2], tmp[1]); + AmoebaReferenceForce::getCrossProduct(deltaR[dV2], deltaR[ED], tmp[2]); d[B][0] += tmp[0][0]; d[B][1] += tmp[0][1]; @@ -524,8 +524,8 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn(const // dD2 - AmoebaReferenceForce::getCrossProduct(deltaR[dU2], deltaR[CB], tmp[0] ); - AmoebaReferenceForce::getCrossProduct(deltaR[EC], deltaR[dV2], tmp[1] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dU2], deltaR[CB], tmp[0]); + AmoebaReferenceForce::getCrossProduct(deltaR[EC], deltaR[dV2], tmp[1]); d[D][0] += tmp[0][0] + tmp[1][0]; d[D][1] += tmp[0][1] + tmp[1][1]; @@ -533,7 +533,7 @@ RealOpenMM AmoebaReferenceTorsionTorsionForce::calculateTorsionTorsionIxn(const // dE - AmoebaReferenceForce::getCrossProduct(deltaR[dV2], deltaR[DC], d[E] ); + AmoebaReferenceForce::getCrossProduct(deltaR[dV2], deltaR[DC], d[E]); // --------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h index 49985d5c4..69c2fdfe7 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceVdwForce.h @@ -252,8 +252,8 @@ private: CombiningFunction _combineEpsilons; RealOpenMM arithmeticEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const; RealOpenMM geometricEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const; - RealOpenMM harmonicEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ) const; - RealOpenMM hhgEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ) const; + RealOpenMM harmonicEpsilonCombiningRule(RealOpenMM epsilonI, RealOpenMM epsilonJ) const; + RealOpenMM hhgEpsilonCombiningRule( RealOpenMM epsilonI, RealOpenMM epsilonJ) const; /**--------------------------------------------------------------------------------------- diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp index f93af0950..8c0abc28f 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaAngleForce.cpp @@ -101,7 +101,7 @@ static void getPrefactorsGivenAngleCosine(double cosine, double idealAngle, doub 3.0*cubicK* deltaIdeal + 4.0*quarticK*deltaIdeal2 + 5.0*penticK* deltaIdeal3 + - 6.0*sexticK* deltaIdeal4 ); + 6.0*sexticK* deltaIdeal4 ); *dEdR *= RADIAN*quadraticK*deltaIdeal; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp index 2fa66f55c..e3e74abb9 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaGeneralizedKirkwoodForce.cpp @@ -90,7 +90,7 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce // first N system.addParticle(1.4007000e+01); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); + amoebaMultipoleForce->addMultipole(-5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to first N @@ -113,23 +113,23 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce system.addParticle(1.0080000e+00); system.addParticle(1.0080000e+00); system.addParticle(1.0080000e+00); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); // second N - system.addParticle( 1.4007000e+01); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); + system.addParticle( 1.4007000e+01); + amoebaMultipoleForce->addMultipole(-5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to second N - system.addParticle( 1.0080000e+00); - system.addParticle( 1.0080000e+00); - system.addParticle( 1.0080000e+00); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole( 1.9320000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); // covalent maps @@ -260,17 +260,17 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce // GK force - amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01); - amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); + amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01); + amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm(includeCavityTerm); // addParticle: charge, radius, scalingFactor for (unsigned int ii = 0; ii < 2; ii++) { - amoebaGeneralizedKirkwoodForce->addParticle( -5.7960000e-01, 1.5965000e-01, 6.9000000e-01); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); - amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle(-5.7960000e-01, 1.5965000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); + amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); } system.addForce(amoebaGeneralizedKirkwoodForce); } @@ -278,14 +278,14 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy) { std::vector positions(context.getSystem().getNumParticles()); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3(-1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3(-2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3(-6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3(-2.0426290e-01, -8.1231400e-02, 4.1033500e-02); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -5744,8 +5744,8 @@ static void setupAndGetForcesEnergyMultipoleVillin(AmoebaMultipoleForce::Polariz // GK force AmoebaGeneralizedKirkwoodForce* amoebaGeneralizedKirkwoodForce = new AmoebaGeneralizedKirkwoodForce(); - amoebaGeneralizedKirkwoodForce->setSolventDielectric( 7.8300000e+01); - amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); + amoebaGeneralizedKirkwoodForce->setSolventDielectric(7.8300000e+01); + amoebaGeneralizedKirkwoodForce->setSoluteDielectric( 1.0000000e+00); amoebaGeneralizedKirkwoodForce->setIncludeCavityTerm(includeCavityTerm); // addParticle: charge, radius, scalingFactor @@ -7039,14 +7039,14 @@ static void testGeneralizedKirkwoodAmmoniaDirectPolarization() { double expectedEnergy = -7.6636680e+01; - expectedForces[0] = Vec3( -6.9252994e+02, -8.9085133e+00, 9.6489739e+01); - expectedForces[1] = Vec3( 1.5593797e+02, -6.0331931e+01, 1.5104507e+01); - expectedForces[2] = Vec3( 1.5870088e+02, 6.1702809e+01, 6.7708985e+00); - expectedForces[3] = Vec3( 1.4089885e+02, 7.5870617e+00, -1.1362294e+02); - expectedForces[4] = Vec3( -1.8916205e+02, 2.1465549e-01, -4.3433152e+02); - expectedForces[5] = Vec3( 1.0208290e+01, 6.2676753e+01, 1.4987953e+02); - expectedForces[6] = Vec3( 4.0621859e+02, 1.8962203e-01, 1.3021956e+02); - expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02); + expectedForces[0] = Vec3(-6.9252994e+02, -8.9085133e+00, 9.6489739e+01); + expectedForces[1] = Vec3( 1.5593797e+02, -6.0331931e+01, 1.5104507e+01); + expectedForces[2] = Vec3( 1.5870088e+02, 6.1702809e+01, 6.7708985e+00); + expectedForces[3] = Vec3( 1.4089885e+02, 7.5870617e+00, -1.1362294e+02); + expectedForces[4] = Vec3(-1.8916205e+02, 2.1465549e-01, -4.3433152e+02); + expectedForces[5] = Vec3( 1.0208290e+01, 6.2676753e+01, 1.4987953e+02); + expectedForces[6] = Vec3( 4.0621859e+02, 1.8962203e-01, 1.3021956e+02); + expectedForces[7] = Vec3( 9.7274235e+00, -6.3130458e+01, 1.4949024e+02); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -7072,14 +7072,14 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarization() { double expectedEnergy = -7.8018875e+01; - expectedForces[0] = Vec3( -7.6820301e+02, -1.0102760e+01, 1.0094389e+02); - expectedForces[1] = Vec3( 1.7037307e+02, -7.5621857e+01, 2.3320365e+01); - expectedForces[2] = Vec3( 1.7353828e+02, 7.7199741e+01, 1.3965379e+01); - expectedForces[3] = Vec3( 1.5045244e+02, 8.5784569e+00, -1.3377619e+02); - expectedForces[4] = Vec3( -2.1811615e+02, -1.6818022e-01, -4.6103163e+02); - expectedForces[5] = Vec3( 6.2091942e+00, 7.6748687e+01, 1.5883463e+02); - expectedForces[6] = Vec3( 4.8035662e+02, 4.9704902e-01, 1.3948083e+02); - expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02); + expectedForces[0] = Vec3(-7.6820301e+02, -1.0102760e+01, 1.0094389e+02); + expectedForces[1] = Vec3( 1.7037307e+02, -7.5621857e+01, 2.3320365e+01); + expectedForces[2] = Vec3( 1.7353828e+02, 7.7199741e+01, 1.3965379e+01); + expectedForces[3] = Vec3( 1.5045244e+02, 8.5784569e+00, -1.3377619e+02); + expectedForces[4] = Vec3(-2.1811615e+02, -1.6818022e-01, -4.6103163e+02); + expectedForces[5] = Vec3( 6.2091942e+00, 7.6748687e+01, 1.5883463e+02); + expectedForces[6] = Vec3( 4.8035662e+02, 4.9704902e-01, 1.3948083e+02); + expectedForces[7] = Vec3( 5.3895456e+00, -7.7131137e+01, 1.5826273e+02); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -7108,14 +7108,14 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm() { double expectedEnergy = -6.0434582e+01; - expectedForces[0] = Vec3( -7.8323218e+02, -1.0097644e+01, 1.0256890e+02); - expectedForces[1] = Vec3( 1.7078480e+02, -7.1896701e+01, 2.0840172e+01); - expectedForces[2] = Vec3( 1.7394089e+02, 7.3488594e+01, 1.1484648e+01); - expectedForces[3] = Vec3( 1.5169364e+02, 8.5611299e+00, -1.2968050e+02); - expectedForces[4] = Vec3( -2.1669693e+02, -1.5926823e-01, -4.6636274e+02); - expectedForces[5] = Vec3( 8.7397444e+00, 7.3330990e+01, 1.6016898e+02); - expectedForces[6] = Vec3( 4.8684950e+02, 4.8937161e-01, 1.4137061e+02); - expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02); + expectedForces[0] = Vec3(-7.8323218e+02, -1.0097644e+01, 1.0256890e+02); + expectedForces[1] = Vec3( 1.7078480e+02, -7.1896701e+01, 2.0840172e+01); + expectedForces[2] = Vec3( 1.7394089e+02, 7.3488594e+01, 1.1484648e+01); + expectedForces[3] = Vec3( 1.5169364e+02, 8.5611299e+00, -1.2968050e+02); + expectedForces[4] = Vec3(-2.1669693e+02, -1.5926823e-01, -4.6636274e+02); + expectedForces[5] = Vec3( 8.7397444e+00, 7.3330990e+01, 1.6016898e+02); + expectedForces[6] = Vec3( 4.8684950e+02, 4.8937161e-01, 1.4137061e+02); + expectedForces[7] = Vec3( 7.9205382e+00, -7.3716473e+01, 1.5960993e+02); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp index 0499ca7e9..4fda1bfcb 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaInPlaneAngleForce.cpp @@ -99,18 +99,18 @@ static void getPrefactorsGivenInPlaneAngleCosine(double cosine, double idealInPl // deltaIdeal = r - r_0 - *dEdR = (2.0 + + *dEdR = (2.0 + 3.0*cubicK* deltaIdeal + 4.0*quarticK*deltaIdeal2 + 5.0*penticK* deltaIdeal3 + - 6.0*sexticK* deltaIdeal4 ); + 6.0*sexticK* deltaIdeal4 ); *dEdR *= RADIAN*quadraticK*deltaIdeal; - *energyTerm = 1.0f + cubicK* deltaIdeal + - quarticK*deltaIdeal2 + - penticK* deltaIdeal3 + + *energyTerm = 1.0f + cubicK* deltaIdeal + + quarticK*deltaIdeal2 + + penticK* deltaIdeal3 + sexticK* deltaIdeal4; *energyTerm *= quadraticK*deltaIdeal2; @@ -215,9 +215,9 @@ static void computeAmoebaInPlaneAngleForce(int bondIndex, std::vector& po double delta2 = delta*2.0; crossProductVector3(deltaR[BD], deltaR[CD], deltaR[BDxCD]); - crossProductVector3(deltaR[T], deltaR[CD], deltaR[TxCD] ); + crossProductVector3(deltaR[T], deltaR[CD], deltaR[TxCD]); crossProductVector3(deltaR[AD], deltaR[BD], deltaR[ADxBD]); - crossProductVector3(deltaR[AD], deltaR[T], deltaR[ADxT] ); + crossProductVector3(deltaR[AD], deltaR[T], deltaR[ADxT]); for (int ii = 0; ii < 3; ii++) { double term = deltaR[BDxCD][ii] + delta2*deltaR[TxCD][ii]; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp index aa8c791eb..f3f4abf3e 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaMultipoleForce.cpp @@ -105,7 +105,7 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu // first N system.addParticle(1.4007000e+01); - amoebaMultipoleForce->addMultipole( -5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); + amoebaMultipoleForce->addMultipole(-5.7960000e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 1, 2, 3, 3.9000000e-01, 3.1996314e-01, 1.0730000e-03); // 3 H attached to first N @@ -128,23 +128,23 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu system.addParticle(1.0080000e+00); system.addParticle(1.0080000e+00); system.addParticle(1.0080000e+00); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 2, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 3, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 0, 1, 2, 3.9e-01, 2.8135002e-01, 4.96e-04); // second N - system.addParticle( 1.4007000e+01); - amoebaMultipoleForce->addMultipole( -5.796e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9e-01, 3.1996314e-01, 1.073e-03); + system.addParticle( 1.4007000e+01); + amoebaMultipoleForce->addMultipole(-5.796e-01, nitrogenMolecularDipole, nitrogenMolecularQuadrupole, 2, 5, 6, 7, 3.9e-01, 3.1996314e-01, 1.073e-03); // 3 H attached to second N - system.addParticle( 1.0080000e+00); - system.addParticle( 1.0080000e+00); - system.addParticle( 1.0080000e+00); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); - amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9e-01, 2.8135002e-01, 4.96e-04); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 6, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 7, 3.9e-01, 2.8135002e-01, 4.96e-04); + amoebaMultipoleForce->addMultipole( 1.932e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 2, 4, 5, 6, 3.9e-01, 2.8135002e-01, 4.96e-04); // covalent maps @@ -276,14 +276,14 @@ static void setupMultipoleAmmonia(System& system, AmoebaMultipoleForce* amoebaMu static void getForcesEnergyMultipoleAmmonia(Context& context, std::vector& forces, double& energy) { std::vector positions(context.getSystem().getNumParticles()); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3(-1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3(-2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3(-6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3(-2.0426290e-01, -8.1231400e-02, 4.1033500e-02); context.setPositions(positions); State state = context.getState(State::Forces | State::Energy); @@ -357,14 +357,14 @@ static void testMultipoleAmmoniaDirectPolarization() { double expectedEnergy = -1.7428832e+01; - expectedForces[0] = Vec3( -3.5574000e+02, -7.3919340e+00, 3.8989934e+01); - expectedForces[1] = Vec3( 3.0368045e+01, -8.7325694e+00, 6.9731151e+00); - expectedForces[2] = Vec3( 3.2358980e+01, 1.0234924e+01, 4.7203694e-01); - expectedForces[3] = Vec3( 2.1439022e+01, 5.8998414e+00, -3.8355239e+01); - expectedForces[4] = Vec3( -1.8052760e+02, -1.0618455e+00, -7.0030146e+01); - expectedForces[5] = Vec3( 4.2411304e+01, -1.6569222e+01, 1.9047581e+00); - expectedForces[6] = Vec3( 3.6823677e+02, 7.7839986e-01, 5.8404590e+01); - expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00); + expectedForces[0] = Vec3(-3.5574000e+02, -7.3919340e+00, 3.8989934e+01); + expectedForces[1] = Vec3( 3.0368045e+01, -8.7325694e+00, 6.9731151e+00); + expectedForces[2] = Vec3( 3.2358980e+01, 1.0234924e+01, 4.7203694e-01); + expectedForces[3] = Vec3( 2.1439022e+01, 5.8998414e+00, -3.8355239e+01); + expectedForces[4] = Vec3(-1.8052760e+02, -1.0618455e+00, -7.0030146e+01); + expectedForces[5] = Vec3( 4.2411304e+01, -1.6569222e+01, 1.9047581e+00); + expectedForces[6] = Vec3( 3.6823677e+02, 7.7839986e-01, 5.8404590e+01); + expectedForces[7] = Vec3( 4.1453480e+01, 1.6842405e+01, 1.6409513e+00); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -395,14 +395,14 @@ static void testMultipoleAmmoniaMutualPolarization() { double expectedEnergy = -1.7790449e+01; - expectedForces[0] = Vec3( -3.7523158e+02, -7.9806295e+00, 3.7464051e+01); - expectedForces[1] = Vec3( 3.1352410e+01, -9.4055551e+00, 8.5230415e+00); - expectedForces[2] = Vec3( 3.3504923e+01, 1.1029935e+01, 1.5052263e+00); - expectedForces[3] = Vec3( 2.3295507e+01, 6.3698827e+00, -4.0403553e+01); - expectedForces[4] = Vec3( -1.9379275e+02, -1.0903937e+00, -7.3461740e+01); - expectedForces[5] = Vec3( 4.3278067e+01, -1.6906589e+01, 1.5721909e+00); - expectedForces[6] = Vec3( 3.9529983e+02, 7.9661172e-01, 6.3499055e+01); - expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00); + expectedForces[0] = Vec3(-3.7523158e+02, -7.9806295e+00, 3.7464051e+01); + expectedForces[1] = Vec3( 3.1352410e+01, -9.4055551e+00, 8.5230415e+00); + expectedForces[2] = Vec3( 3.3504923e+01, 1.1029935e+01, 1.5052263e+00); + expectedForces[3] = Vec3( 2.3295507e+01, 6.3698827e+00, -4.0403553e+01); + expectedForces[4] = Vec3(-1.9379275e+02, -1.0903937e+00, -7.3461740e+01); + expectedForces[5] = Vec3( 4.3278067e+01, -1.6906589e+01, 1.5721909e+00); + expectedForces[6] = Vec3( 3.9529983e+02, 7.9661172e-01, 6.3499055e+01); + expectedForces[7] = Vec3( 4.2293601e+01, 1.7186738e+01, 1.3017270e+00); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -513,10 +513,10 @@ static void setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::Nonbonde for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps @@ -553,18 +553,18 @@ static void setupAndGetForcesEnergyMultipoleWater(AmoebaMultipoleForce::Nonbonde std::vector positions(numberOfParticles); - positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03); - positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02); - positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01); - positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); - positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); - positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); - positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); - positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); - positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); - positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); - positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); - positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); + positions[0] = Vec3(-8.7387270e-01, 5.3220410e-01, 7.4214000e-03); + positions[1] = Vec3(-9.6050090e-01, 5.1173410e-01, -2.2202700e-02); + positions[2] = Vec3(-8.5985900e-01, 4.9658230e-01, 1.0283390e-01); + positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); + positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); + positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); + positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); + positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); + positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); + positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); + positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); + positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); system.addForce(amoebaMultipoleForce); ASSERT(amoebaMultipoleForce->usesPeriodicBoundaryConditions()); @@ -599,18 +599,18 @@ static void testMultipoleWaterPMEDirectPolarization() { double expectedEnergy = 6.4585115e-01; - expectedForces[0] = Vec3( -1.2396731e+00, -2.4231698e+01, 8.3348523e+00); - expectedForces[1] = Vec3( -3.3737276e+00, 9.9304523e+00, -6.3917827e+00); - expectedForces[2] = Vec3( 4.4062247e+00, 1.9518971e+01, -4.6552873e+00); - expectedForces[3] = Vec3( -1.3128824e+00, -1.2887339e+00, -1.4473147e+00); - expectedForces[4] = Vec3( 2.1137034e+00, 3.9457973e-01, 2.9269129e-01); - expectedForces[5] = Vec3( 1.0271174e+00, 1.2039367e+00, 1.2112214e+00); - expectedForces[6] = Vec3( -3.2082903e+00, 1.4979371e+01, -1.0274832e+00); - expectedForces[7] = Vec3( -1.1880320e+00, -1.5177166e+01, 2.5525509e+00); - expectedForces[8] = Vec3( 4.3607105e+00, -7.0253274e+00, 2.9522580e-01); - expectedForces[9] = Vec3( -3.0175134e+00, 1.3607102e+00, 6.6883370e+00); - expectedForces[10] = Vec3( 9.2036949e-01, -1.4717629e+00, -3.3362339e+00); - expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00); + expectedForces[0] = Vec3(-1.2396731e+00, -2.4231698e+01, 8.3348523e+00); + expectedForces[1] = Vec3(-3.3737276e+00, 9.9304523e+00, -6.3917827e+00); + expectedForces[2] = Vec3( 4.4062247e+00, 1.9518971e+01, -4.6552873e+00); + expectedForces[3] = Vec3(-1.3128824e+00, -1.2887339e+00, -1.4473147e+00); + expectedForces[4] = Vec3( 2.1137034e+00, 3.9457973e-01, 2.9269129e-01); + expectedForces[5] = Vec3( 1.0271174e+00, 1.2039367e+00, 1.2112214e+00); + expectedForces[6] = Vec3(-3.2082903e+00, 1.4979371e+01, -1.0274832e+00); + expectedForces[7] = Vec3(-1.1880320e+00, -1.5177166e+01, 2.5525509e+00); + expectedForces[8] = Vec3( 4.3607105e+00, -7.0253274e+00, 2.9522580e-01); + expectedForces[9] = Vec3(-3.0175134e+00, 1.3607102e+00, 6.6883370e+00); + expectedForces[10] = Vec3( 9.2036949e-01, -1.4717629e+00, -3.3362339e+00); + expectedForces[11] = Vec3( 1.2523841e+00, -1.9794292e+00, -3.4670129e+00); double tolerance = 1.0e-03; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -634,18 +634,18 @@ static void testMultipoleWaterPMEMutualPolarization() { double expectedEnergy = 6.5029855e-01; - expectedForces[0] = Vec3( -1.2367386e+00, -2.4197036e+01, 8.3256759e+00); - expectedForces[1] = Vec3( -3.3825187e+00, 9.9387618e+00, -6.4200475e+00); - expectedForces[2] = Vec3( 4.4108644e+00, 1.9486127e+01, -4.6530661e+00); - expectedForces[3] = Vec3( -1.3129168e+00, -1.2947383e+00, -1.4438198e+00); - expectedForces[4] = Vec3( 2.1144837e+00, 3.9590305e-01, 2.9040889e-01); - expectedForces[5] = Vec3( 1.0287222e+00, 1.2100201e+00, 1.2103068e+00); - expectedForces[6] = Vec3( -3.2017550e+00, 1.4995985e+01, -1.1036504e+00); - expectedForces[7] = Vec3( -1.2065398e+00, -1.5192899e+01, 2.6233368e+00); - expectedForces[8] = Vec3( 4.3698604e+00, -7.0550315e+00, 3.4204565e-01); - expectedForces[9] = Vec3( -3.0082825e+00, 1.3575082e+00, 6.6901032e+00); - expectedForces[10] = Vec3( 9.1775539e-01, -1.4651882e+00, -3.3322516e+00); - expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00); + expectedForces[0] = Vec3(-1.2367386e+00, -2.4197036e+01, 8.3256759e+00); + expectedForces[1] = Vec3(-3.3825187e+00, 9.9387618e+00, -6.4200475e+00); + expectedForces[2] = Vec3( 4.4108644e+00, 1.9486127e+01, -4.6530661e+00); + expectedForces[3] = Vec3(-1.3129168e+00, -1.2947383e+00, -1.4438198e+00); + expectedForces[4] = Vec3( 2.1144837e+00, 3.9590305e-01, 2.9040889e-01); + expectedForces[5] = Vec3( 1.0287222e+00, 1.2100201e+00, 1.2103068e+00); + expectedForces[6] = Vec3(-3.2017550e+00, 1.4995985e+01, -1.1036504e+00); + expectedForces[7] = Vec3(-1.2065398e+00, -1.5192899e+01, 2.6233368e+00); + expectedForces[8] = Vec3( 4.3698604e+00, -7.0550315e+00, 3.4204565e-01); + expectedForces[9] = Vec3(-3.0082825e+00, 1.3575082e+00, 6.6901032e+00); + expectedForces[10] = Vec3( 9.1775539e-01, -1.4651882e+00, -3.3322516e+00); + expectedForces[11] = Vec3( 1.2467701e+00, -1.9832979e+00, -3.4684052e+00); double tolerance = 1.0e-03; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -726,27 +726,27 @@ static void testQuadrupoleValidation() { for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } std::vector positions(numberOfParticles); - positions[0] = Vec3( -8.7387270e-01, 5.3220410e-01, 7.4214000e-03); - positions[1] = Vec3( -9.6050090e-01, 5.1173410e-01, -2.2202700e-02); - positions[2] = Vec3( -8.5985900e-01, 4.9658230e-01, 1.0283390e-01); - positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); - positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); - positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); - positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); - positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); - positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); - positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); - positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); - positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); + positions[0] = Vec3(-8.7387270e-01, 5.3220410e-01, 7.4214000e-03); + positions[1] = Vec3(-9.6050090e-01, 5.1173410e-01, -2.2202700e-02); + positions[2] = Vec3(-8.5985900e-01, 4.9658230e-01, 1.0283390e-01); + positions[3] = Vec3( 9.1767100e-02, -7.8956650e-01, 4.3804200e-01); + positions[4] = Vec3( 1.2333420e-01, -7.0267430e-01, 4.2611550e-01); + positions[5] = Vec3( 1.7267090e-01, -8.2320810e-01, 4.8124750e-01); + positions[6] = Vec3( 8.6290110e-01, 6.2153500e-02, 4.1280850e-01); + positions[7] = Vec3( 8.6385200e-01, 1.2684730e-01, 3.3887060e-01); + positions[8] = Vec3( 9.5063550e-01, 5.3173300e-02, 4.4799160e-01); + positions[9] = Vec3( 5.0844930e-01, 2.8684740e-01, -6.9293750e-01); + positions[10] = Vec3( 6.0459330e-01, 3.0620510e-01, -7.0100130e-01); + positions[11] = Vec3( 5.0590640e-01, 1.8880920e-01, -6.8813470e-01); system.addForce(amoebaMultipoleForce); @@ -863,7 +863,7 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::N // 2 ions - system.addParticle(3.5453000e+01 ); + system.addParticle(3.5453000e+01); system.addParticle(2.2990000e+01); std::vector ionDipole(3); @@ -882,8 +882,8 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::N ionQuadrupole[6] = 0.0000000e+00; ionQuadrupole[7] = 0.0000000e+00; ionQuadrupole[8] = 0.0000000e+00; - amoebaMultipoleForce->addMultipole( -1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 3.9842202e-01, 4.00e-03); - amoebaMultipoleForce->addMultipole( 1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 2.2209062e-01, 1.20e-04); + amoebaMultipoleForce->addMultipole(-1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 3.9842202e-01, 4.00e-03); + amoebaMultipoleForce->addMultipole( 1.0e+00, ionDipole, ionQuadrupole, 5, -1, -1, -1, 3.90e-01, 2.2209062e-01, 1.20e-04); // waters @@ -928,11 +928,11 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::N for (unsigned int jj = 2; jj < numberOfParticles; jj += 3) { amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps @@ -977,14 +977,14 @@ static void setupAndGetForcesEnergyMultipoleIonsAndWater(AmoebaMultipoleForce::N std::vector positions(numberOfParticles); - positions[0] = Vec3( -1.4364000e+00, -1.2848000e+00, 5.1940000e-01); - positions[1] = Vec3( -3.2644000e+00, 2.3620000e+00, 1.3643000e+00); - positions[2] = Vec3( -2.3780000e+00, 1.8976000e+00, -1.5921000e+00); - positions[3] = Vec3( -2.3485183e+00, 1.8296632e+00, -1.5310146e+00); - positions[4] = Vec3( -2.3784362e+00, 1.8623910e+00, -1.6814092e+00); - positions[5] = Vec3( -2.1821000e+00, -1.0808000e+00, 2.9547000e+00); - positions[6] = Vec3( -2.1198155e+00, -1.0925202e+00, 2.8825940e+00); - positions[7] = Vec3( -2.1537255e+00, -1.0076218e+00, 3.0099797e+00); + positions[0] = Vec3(-1.4364000e+00, -1.2848000e+00, 5.1940000e-01); + positions[1] = Vec3(-3.2644000e+00, 2.3620000e+00, 1.3643000e+00); + positions[2] = Vec3(-2.3780000e+00, 1.8976000e+00, -1.5921000e+00); + positions[3] = Vec3(-2.3485183e+00, 1.8296632e+00, -1.5310146e+00); + positions[4] = Vec3(-2.3784362e+00, 1.8623910e+00, -1.6814092e+00); + positions[5] = Vec3(-2.1821000e+00, -1.0808000e+00, 2.9547000e+00); + positions[6] = Vec3(-2.1198155e+00, -1.0925202e+00, 2.8825940e+00); + positions[7] = Vec3(-2.1537255e+00, -1.0076218e+00, 3.0099797e+00); system.addForce(amoebaMultipoleForce); @@ -1023,14 +1023,14 @@ static void testMultipoleIonsAndWaterPMEDirectPolarization() { double expectedEnergy = -4.6859568e+01; - expectedForces[0] = Vec3( -9.1266563e+00, 1.5193632e+01, -4.0047974e+00); - expectedForces[1] = Vec3( -1.0497973e+00, 1.4622548e+01, 1.1789324e+01); - expectedForces[2] = Vec3( -3.2564644e+00, 6.5325105e+00, -2.9698616e+00); - expectedForces[3] = Vec3( 3.0687040e+00, -8.4253665e-01, -3.4081010e+00); - expectedForces[4] = Vec3( 1.1407201e+00, -3.1491550e+00, -1.1326031e+00); - expectedForces[5] = Vec3( -6.1046529e+00, 9.5686061e-01, 1.1506333e-01); - expectedForces[6] = Vec3( 1.9275403e+00, -5.6007439e-01, -4.8387346e+00); - expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00); + expectedForces[0] = Vec3(-9.1266563e+00, 1.5193632e+01, -4.0047974e+00); + expectedForces[1] = Vec3(-1.0497973e+00, 1.4622548e+01, 1.1789324e+01); + expectedForces[2] = Vec3(-3.2564644e+00, 6.5325105e+00, -2.9698616e+00); + expectedForces[3] = Vec3( 3.0687040e+00, -8.4253665e-01, -3.4081010e+00); + expectedForces[4] = Vec3( 1.1407201e+00, -3.1491550e+00, -1.1326031e+00); + expectedForces[5] = Vec3(-6.1046529e+00, 9.5686061e-01, 1.1506333e-01); + expectedForces[6] = Vec3( 1.9275403e+00, -5.6007439e-01, -4.8387346e+00); + expectedForces[7] = Vec3( 4.0644209e+00, -3.3666305e+00, -1.7022384e+00); double tolerance = 5.0e-04; compareForceNormsEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -1059,14 +1059,14 @@ static void testMultipoleIonsAndWaterPMEMutualPolarization() { double expectedEnergy = -4.6859424e+01; - expectedForces[0] = Vec3( -9.1272358e+00, 1.5191516e+01, -4.0058826e+00); - expectedForces[1] = Vec3( -1.0497156e+00, 1.4622425e+01, 1.1789420e+01); - expectedForces[2] = Vec3( -3.2560478e+00, 6.5289712e+00, -2.9779483e+00); - expectedForces[3] = Vec3( 3.0672153e+00, -8.4407797e-01, -3.4094884e+00); - expectedForces[4] = Vec3( 1.1382586e+00, -3.1512949e+00, -1.1387028e+00); - expectedForces[5] = Vec3( -6.1050295e+00, 9.5345692e-01, 1.1488832e-01); - expectedForces[6] = Vec3( 1.9319945e+00, -5.5747599e-01, -4.8469044e+00); - expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00); + expectedForces[0] = Vec3(-9.1272358e+00, 1.5191516e+01, -4.0058826e+00); + expectedForces[1] = Vec3(-1.0497156e+00, 1.4622425e+01, 1.1789420e+01); + expectedForces[2] = Vec3(-3.2560478e+00, 6.5289712e+00, -2.9779483e+00); + expectedForces[3] = Vec3( 3.0672153e+00, -8.4407797e-01, -3.4094884e+00); + expectedForces[4] = Vec3( 1.1382586e+00, -3.1512949e+00, -1.1387028e+00); + expectedForces[5] = Vec3(-6.1050295e+00, 9.5345692e-01, 1.1488832e-01); + expectedForces[6] = Vec3( 1.9319945e+00, -5.5747599e-01, -4.8469044e+00); + expectedForces[7] = Vec3( 4.0622614e+00, -3.3687594e+00, -1.6986575e+00); //double tolerance = 1.0e-03; //compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -1152,11 +1152,11 @@ static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::Non for (unsigned int jj = 0; jj < numberOfParticles; jj += 3) { amoebaMultipoleForce->addMultipole(-5.1966000e-01, oxygenMolecularDipole, oxygenMolecularQuadrupole, 1, jj+1, jj+2, -1, - 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); - amoebaMultipoleForce->addMultipole( 2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, - 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + 3.9000000e-01, 3.0698765e-01, 8.3700000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+2, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); + amoebaMultipoleForce->addMultipole(2.5983000e-01, hydrogenMolecularDipole, hydrogenMolecularQuadrupole, 0, jj, jj+1, -1, + 3.9000000e-01, 2.8135002e-01, 4.9600000e-04); } // CovalentMaps @@ -1195,654 +1195,654 @@ static void setupAndGetForcesEnergyMultipoleLargeWater(AmoebaMultipoleForce::Non static std::vector positions; // Static to work around bug in Visual Studio that makes compilation very very slow. positions.resize(numberOfParticles); - positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); - positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); - positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); - positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); - positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); - positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); - positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01); - positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01); - positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01); - positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); - positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); - positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); - positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); - positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); - positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); - positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01); - positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01); - positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01); - positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01); - positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01); - positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01); - positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01); - positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01); - positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); - positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01); - positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01); - positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02); - positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02); - positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01); - positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01); - positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); - positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); - positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); - positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); - positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01); - positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); - positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); - positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); - positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01); - positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); - positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); - positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); - positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); - positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); - positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); - positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); - positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); - positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); - positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01); - positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01); - positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01); - positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01); - positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01); - positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01); - positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); - positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); - positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); - positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01); - positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01); - positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01); - positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); - positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); - positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); - positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02); - positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02); - positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01); - positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02); - positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02); - positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01); - positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01); - positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01); - positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01); - positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); - positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); - positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); - positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01); - positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02); - positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01); - positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); - positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); - positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); - positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); - positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); - positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); - positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01); - positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); - positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); - positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); - positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); - positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); - positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); - positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); - positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); - positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01); - positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01); - positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01); - positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); - positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); - positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); - positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); - positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); - positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); - positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01); - positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01); - positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01); - positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); - positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); - positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); - positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); - positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); - positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); - positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); - positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); - positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); - positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01); - positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01); - positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01); - positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01); - positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01); - positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01); - positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); - positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); - positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); - positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01); - positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02); - positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01); - positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01); - positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01); - positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01); - positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); - positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); - positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); - positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01); - positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01); - positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01); - positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01); - positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01); - positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01); - positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01); - positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01); - positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01); - positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); - positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); - positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); - positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); - positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); - positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); - positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); - positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); - positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); - positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01); - positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01); - positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01); - positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01); - positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01); - positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01); - positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02); - positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02); - positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); - positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); - positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); - positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); - positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); - positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); - positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); - positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); - positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); - positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); - positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); - positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01); - positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); - positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01); - positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01); - positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01); - positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); - positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); - positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); - positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01); - positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01); - positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01); - positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); - positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); - positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); - positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01); - positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01); - positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01); - positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02); - positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01); - positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03); - positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01); - positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01); - positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01); - positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); - positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); - positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); - positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); - positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01); - positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); - positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01); - positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01); - positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01); - positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); - positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); - positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); - positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); - positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); - positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); - positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01); - positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01); - positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01); - positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); - positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); - positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); - positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01); - positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01); - positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01); - positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); - positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); - positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); - positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); - positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01); - positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01); - positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); - positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); - positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); - positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); - positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); - positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); - positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01); - positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01); - positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01); - positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01); - positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01); - positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01); - positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); - positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); - positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); - positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01); - positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01); - positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01); - positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01); - positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01); - positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01); - positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); - positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); - positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); - positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01); - positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01); - positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01); - positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); - positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); - positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); - positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); - positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); - positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); - positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01); - positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01); - positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); - positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01); - positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01); - positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01); - positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01); - positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01); - positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01); - positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); - positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); - positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); - positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01); - positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01); - positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01); - positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); - positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); - positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); - positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); - positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); - positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); - positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); - positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); - positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); - positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01); - positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01); - positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01); - positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01); - positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01); - positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01); - positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01); - positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01); - positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01); - positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02); - positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01); - positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02); - positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01); - positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01); - positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01); - positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); - positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); - positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); - positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01); - positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); - positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01); - positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01); - positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01); - positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01); - positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01); - positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01); - positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01); - positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); - positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); - positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); - positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); - positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); - positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); - positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01); - positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01); - positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01); - positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02); - positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01); - positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02); - positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); - positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); - positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); - positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01); - positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01); - positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01); - positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01); - positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01); - positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01); - positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02); - positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02); - positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02); - positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01); - positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01); - positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01); - positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01); - positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01); - positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01); - positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01); - positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01); - positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01); - positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); - positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); - positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); - positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); - positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); - positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); - positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01); - positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01); - positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01); - positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); - positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); - positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); - positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01); - positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01); - positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01); - positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); - positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); - positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); - positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); - positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); - positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); - positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01); - positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01); - positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01); - positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01); - positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02); - positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01); - positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01); - positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02); - positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01); - positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01); - positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01); - positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01); - positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01); - positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01); - positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01); - positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); - positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); - positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); - positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); - positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); - positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); - positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); - positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); - positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); - positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); - positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); - positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); - positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01); - positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01); - positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01); - positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01); - positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01); - positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01); - positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); - positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); - positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); - positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01); - positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01); - positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01); - positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); - positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); - positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); - positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); - positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); - positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); - positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); - positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); - positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); - positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); - positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); - positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01); - positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); - positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); - positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); - positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); - positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); - positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); - positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01); - positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01); - positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01); - positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); - positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); - positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); - positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01); - positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01); - positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01); - positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); - positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); - positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); - positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01); - positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01); - positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01); - positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); - positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); - positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); - positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01); - positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01); - positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01); - positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); - positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); - positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); - positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02); - positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); - positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01); - positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); - positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); - positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); - positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); - positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); - positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); - positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01); - positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01); - positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01); - positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01); - positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01); - positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01); - positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); - positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); - positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); - positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01); - positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01); - positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01); - positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01); - positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01); - positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01); - positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01); - positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01); - positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01); - positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); - positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); - positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); - positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); - positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); - positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); - positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); - positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); - positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); - positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); - positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); - positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); - positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01); - positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01); - positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01); - positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01); - positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01); - positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02); - positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01); - positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01); - positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01); - positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); - positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); - positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); - positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01); - positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01); - positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01); - positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01); - positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01); - positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01); - positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01); - positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01); - positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01); - positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01); - positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01); - positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01); - positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01); - positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01); - positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01); - positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); - positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); - positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); - positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); - positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); - positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); - positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01); - positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01); - positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01); - positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01); - positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01); - positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01); - positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); - positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); - positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); - positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); - positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); - positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); - positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); - positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); - positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); - positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); - positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); - positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); - positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); - positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); - positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); - positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); - positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); - positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); - positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); - positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); - positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); - positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); - positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); - positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); - positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01); - positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01); - positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01); - positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01); - positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01); - positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01); - positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01); - positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01); - positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01); - positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); - positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); - positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); - positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01); - positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01); - positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02); - positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02); - positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02); - positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02); - positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01); - positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01); - positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01); - positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); - positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); - positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); - positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01); - positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01); - positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); - positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01); - positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01); - positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01); - positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01); - positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01); - positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01); - positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); - positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02); - positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); - positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02); - positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02); - positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01); - positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01); - positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01); - positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01); - positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); - positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); - positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); - positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); - positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); - positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); - positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01); - positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01); - positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01); - positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01); - positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01); - positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01); - positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01); - positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01); - positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01); - positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); - positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); - positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); - positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01); - positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01); - positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01); - positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); - positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); - positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); - positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); - positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); - positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); - positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01); - positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01); - positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01); - positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); - positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); - positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); - positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01); - positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01); - positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01); - positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01); - positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01); - positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01); - positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); - positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); - positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); - positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); - positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); - positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); - positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01); - positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01); - positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01); - positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); - positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); - positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); - positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); - positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); - positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); - positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01); - positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01); - positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01); - positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); - positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); - positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); - positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01); - positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01); - positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01); + positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); + positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); + positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); + positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); + positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); + positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); + positions[6] = Vec3(-6.5763670e-01, -2.5260000e-02, 8.1046320e-01); + positions[7] = Vec3(-6.6454990e-01, 6.8992500e-02, 7.8963560e-01); + positions[8] = Vec3(-6.6845370e-01, -4.0076000e-02, 9.1037470e-01); + positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); + positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); + positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); + positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); + positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); + positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); + positions[15] = Vec3(-4.6646340e-01, -8.5021310e-01, -2.6526210e-01); + positions[16] = Vec3(-4.5053590e-01, -8.3883300e-01, -3.6069710e-01); + positions[17] = Vec3(-5.5653260e-01, -8.7510810e-01, -2.5955820e-01); + positions[18] = Vec3(-7.7550740e-01, -4.6613180e-01, 4.9045930e-01); + positions[19] = Vec3(-7.3577510e-01, -5.4400590e-01, 5.3107060e-01); + positions[20] = Vec3(-7.0755520e-01, -4.1773140e-01, 4.4037930e-01); + positions[21] = Vec3(-2.8190600e-02, 7.4872450e-01, -7.6855300e-01); + positions[22] = Vec3(-7.9443300e-02, 7.4463600e-01, -6.8256160e-01); + positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); + positions[24] = Vec3(-3.7112750e-01, -2.2624390e-01, -1.9170030e-01); + positions[25] = Vec3(-4.4236150e-01, -2.4258640e-01, -2.4723220e-01); + positions[26] = Vec3(-4.0233380e-01, -2.2106530e-01, -9.7227800e-02); + positions[27] = Vec3(-5.8120030e-01, -5.6157220e-01, 8.3549400e-02); + positions[28] = Vec3(-6.6764500e-01, -5.7119710e-01, 1.2970660e-01); + positions[29] = Vec3(-5.1434340e-01, -5.5317060e-01, 1.5597670e-01); + positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); + positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); + positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); + positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); + positions[34] = Vec3(-6.4546800e-02, 4.4539620e-01, -6.0008300e-01); + positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); + positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); + positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); + positions[38] = Vec3(-3.9569500e-02, 5.9419720e-01, 5.6714930e-01); + positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); + positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); + positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); + positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); + positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); + positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); + positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); + positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); + positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); + positions[48] = Vec3(-8.7750980e-01, 6.9408570e-01, -6.1784650e-01); + positions[49] = Vec3(-8.2179580e-01, 7.3187880e-01, -5.4705510e-01); + positions[50] = Vec3(-9.0362240e-01, 7.7367480e-01, -6.6488210e-01); + positions[51] = Vec3(-6.9406820e-01, 2.2491740e-01, 7.1940890e-01); + positions[52] = Vec3(-7.3674620e-01, 2.2091000e-01, 6.3486690e-01); + positions[53] = Vec3(-7.4149900e-01, 2.8970280e-01, 7.7200060e-01); + positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); + positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); + positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); + positions[57] = Vec3(-2.2024800e-01, -3.1071870e-01, 9.1706370e-01); + positions[58] = Vec3(-2.3195790e-01, -4.0722320e-01, 9.2465160e-01); + positions[59] = Vec3(-2.8015290e-01, -2.9349640e-01, 8.4209880e-01); + positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); + positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); + positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); + positions[63] = Vec3(-9.0804840e-01, -6.2437310e-01, -8.8188300e-02); + positions[64] = Vec3(-8.6732940e-01, -7.0428590e-01, -4.8030200e-02); + positions[65] = Vec3(-8.3644480e-01, -5.8139450e-01, -1.3828190e-01); + positions[66] = Vec3(-8.6567760e-01, -8.6537570e-01, 5.6295900e-02); + positions[67] = Vec3(-8.1778220e-01, -9.4654890e-01, 8.4163600e-02); + positions[68] = Vec3(-9.4534460e-01, -8.6858770e-01, 1.0560810e-01); + positions[69] = Vec3(-5.7716930e-01, -2.6316670e-01, -4.5880740e-01); + positions[70] = Vec3(-5.4569620e-01, -3.1693230e-01, -5.2720970e-01); + positions[71] = Vec3(-5.5496000e-01, -1.7071220e-01, -4.7392400e-01); + positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); + positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); + positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); + positions[75] = Vec3(-2.3769060e-01, -6.2523350e-01, 1.2921080e-01); + positions[76] = Vec3(-1.8309420e-01, -6.2163180e-01, 4.8693900e-02); + positions[77] = Vec3(-2.3929030e-01, -5.3708810e-01, 1.6453540e-01); + positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); + positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); + positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); + positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); + positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); + positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); + positions[84] = Vec3(-2.5059100e-02, 8.6314620e-01, 2.2861410e-01); + positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); + positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); + positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); + positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); + positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); + positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); + positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); + positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); + positions[93] = Vec3(-7.9443650e-01, 1.7601300e-01, 4.6436790e-01); + positions[94] = Vec3(-7.9212150e-01, 2.3533020e-01, 3.8657500e-01); + positions[95] = Vec3(-8.7057070e-01, 1.1288830e-01, 4.4595260e-01); + positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); + positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); + positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); + positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); + positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); + positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); + positions[102] = Vec3(-8.4248740e-01, 3.5007110e-01, -4.4389740e-01); + positions[103] = Vec3(-7.5693800e-01, 3.9510690e-01, -4.4710480e-01); + positions[104] = Vec3(-8.6984880e-01, 3.5457480e-01, -5.3702920e-01); + positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); + positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); + positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); + positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); + positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); + positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); + positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); + positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); + positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); + positions[114] = Vec3(-4.4116790e-01, -4.7749880e-01, 3.0876830e-01); + positions[115] = Vec3(-5.0645290e-01, -4.1075220e-01, 3.1159470e-01); + positions[116] = Vec3(-4.6594720e-01, -5.2568230e-01, 3.8755370e-01); + positions[117] = Vec3(-9.1937480e-01, -5.8400000e-05, -2.5359570e-01); + positions[118] = Vec3(-8.5894750e-01, -7.0402500e-02, -2.2230370e-01); + positions[119] = Vec3(-8.7441760e-01, 8.3170500e-02, -2.3447490e-01); + positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); + positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); + positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); + positions[123] = Vec3(-4.6831090e-01, -6.1465890e-01, -1.6794620e-01); + positions[124] = Vec3(-4.8688540e-01, -5.9611250e-01, -7.4636500e-02); + positions[125] = Vec3(-4.9162010e-01, -7.0497770e-01, -1.8127910e-01); + positions[126] = Vec3(-3.1791800e-01, -5.4450000e-03, -3.6397680e-01); + positions[127] = Vec3(-2.2253910e-01, -2.4457600e-02, -3.5240990e-01); + positions[128] = Vec3(-3.6044390e-01, -3.5065000e-02, -2.8414310e-01); + positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); + positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); + positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); + positions[132] = Vec3(-1.4119340e-01, 4.1653970e-01, -2.7320250e-01); + positions[133] = Vec3(-5.2065100e-02, 3.6979030e-01, -2.6662970e-01); + positions[134] = Vec3(-1.3834110e-01, 4.7690560e-01, -1.9435870e-01); + positions[135] = Vec3(-7.6602450e-01, -2.1216400e-01, -1.9516640e-01); + positions[136] = Vec3(-8.0191290e-01, -2.8391260e-01, -1.3557910e-01); + positions[137] = Vec3(-7.4415500e-01, -2.6044280e-01, -2.8169590e-01); + positions[138] = Vec3(-1.3600310e-01, 1.9674000e-01, 2.0349610e-01); + positions[139] = Vec3(-1.6201050e-01, 2.8693750e-01, 2.3123820e-01); + positions[140] = Vec3(-2.1785650e-01, 1.4514420e-01, 1.9201990e-01); + positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); + positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); + positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); + positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); + positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); + positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); + positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); + positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); + positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); + positions[150] = Vec3(-7.2845180e-01, -3.4650580e-01, 7.5973620e-01); + positions[151] = Vec3(-7.6073760e-01, -3.6974690e-01, 6.7323450e-01); + positions[152] = Vec3(-7.1326740e-01, -2.4916760e-01, 7.5651020e-01); + positions[153] = Vec3(-3.0896820e-01, -3.8029640e-01, 6.5520670e-01); + positions[154] = Vec3(-3.5019560e-01, -4.5571260e-01, 6.1040330e-01); + positions[155] = Vec3(-2.8479430e-01, -3.2175460e-01, 5.7933340e-01); + positions[156] = Vec3(-6.2826700e-02, -6.4315900e-02, -6.8812300e-02); + positions[157] = Vec3(-7.4971500e-02, 1.9900000e-02, -1.8191100e-02); + positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); + positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); + positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); + positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); + positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); + positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); + positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); + positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); + positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); + positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); + positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); + positions[169] = Vec3(-7.1641800e-02, 4.1848500e-02, 8.7065260e-01); + positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); + positions[171] = Vec3(-3.1486750e-01, -1.9966860e-01, -5.7954700e-01); + positions[172] = Vec3(-3.2321140e-01, -1.4613590e-01, -5.0133480e-01); + positions[173] = Vec3(-3.4769180e-01, -1.4810900e-01, -6.5567720e-01); + positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); + positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); + positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); + positions[177] = Vec3(-1.5721060e-01, -2.0015580e-01, 4.8442010e-01); + positions[178] = Vec3(-7.4675400e-02, -2.0952300e-01, 5.3560160e-01); + positions[179] = Vec3(-1.8522760e-01, -1.0781560e-01, 5.0024110e-01); + positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); + positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); + positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); + positions[183] = Vec3(-6.3383580e-01, 5.7282910e-01, -1.7429980e-01); + positions[184] = Vec3(-6.0668100e-01, 4.7712900e-01, -1.7677570e-01); + positions[185] = Vec3(-5.6638740e-01, 6.1288510e-01, -2.2951390e-01); + positions[186] = Vec3(-2.0998170e-01, -2.7747820e-01, 7.0579400e-02); + positions[187] = Vec3(-1.4055440e-01, -3.0201380e-01, 1.3644740e-01); + positions[188] = Vec3(-1.6881700e-01, -2.1818660e-01, 6.9733000e-03); + positions[189] = Vec3(-7.6400000e-04, 5.6326380e-01, 1.4175360e-01); + positions[190] = Vec3(-7.3688000e-02, 5.0031150e-01, 1.5514670e-01); + positions[191] = Vec3(-2.5553000e-02, 6.4733770e-01, 1.7711800e-01); + positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); + positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); + positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); + positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); + positions[196] = Vec3(-4.9643600e-02, -2.7156660e-01, 8.9962920e-01); + positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); + positions[198] = Vec3(-5.9039370e-01, -3.5975630e-01, -7.1984370e-01); + positions[199] = Vec3(-5.3914870e-01, -4.0214860e-01, -7.8361060e-01); + positions[200] = Vec3(-6.8562580e-01, -3.9051900e-01, -7.4071320e-01); + positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); + positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); + positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); + positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); + positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); + positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); + positions[207] = Vec3(-6.9841710e-01, 8.5211760e-01, 4.9956020e-01); + positions[208] = Vec3(-6.3194850e-01, 9.0336360e-01, 4.5467020e-01); + positions[209] = Vec3(-6.7863830e-01, 7.5666570e-01, 5.1268950e-01); + positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); + positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); + positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); + positions[213] = Vec3(-2.3686380e-01, 4.4018650e-01, 2.7494630e-01); + positions[214] = Vec3(-2.1006750e-01, 4.1932880e-01, 3.6593160e-01); + positions[215] = Vec3(-3.2910900e-01, 4.6299420e-01, 2.7725190e-01); + positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); + positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); + positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); + positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); + positions[220] = Vec3(-1.0515300e-02, 1.4450010e-01, 4.8531790e-01); + positions[221] = Vec3(-3.6861400e-02, 1.5333190e-01, 3.3364650e-01); + positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); + positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); + positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); + positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); + positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); + positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); + positions[228] = Vec3(-1.9830990e-01, -6.8678560e-01, -7.6648560e-01); + positions[229] = Vec3(-1.1489950e-01, -6.8356660e-01, -8.2028210e-01); + positions[230] = Vec3(-2.0935090e-01, -5.9618710e-01, -7.3178710e-01); + positions[231] = Vec3(-4.3741650e-01, -7.8889500e-01, 1.7785560e-01); + positions[232] = Vec3(-3.6424030e-01, -7.2995610e-01, 1.5380490e-01); + positions[233] = Vec3(-5.0710310e-01, -7.4066850e-01, 1.3917790e-01); + positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); + positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); + positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); + positions[237] = Vec3(-9.1377180e-01, 9.0412110e-01, -8.0577110e-01); + positions[238] = Vec3(-8.6299150e-01, 9.8552780e-01, -7.9463610e-01); + positions[239] = Vec3(-9.1270510e-01, 8.7715830e-01, -9.0107170e-01); + positions[240] = Vec3(-5.6874630e-01, -3.9330600e-02, 5.3540210e-01); + positions[241] = Vec3(-6.0667690e-01, 3.6619200e-02, 4.9922460e-01); + positions[242] = Vec3(-5.8307630e-01, -4.4694300e-02, 6.3380260e-01); + positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); + positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); + positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); + positions[246] = Vec3(-5.3437690e-01, -9.0689060e-01, -7.7012560e-01); + positions[247] = Vec3(-6.0761130e-01, -8.5593580e-01, -8.0463440e-01); + positions[248] = Vec3(-5.5313680e-01, -9.9745020e-01, -8.0224750e-01); + positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); + positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); + positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); + positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); + positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); + positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); + positions[255] = Vec3(-2.3461000e-03, 8.8439120e-01, -3.5703750e-01); + positions[256] = Vec3(-4.5869800e-02, 9.2025060e-01, -4.4264850e-01); + positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); + positions[258] = Vec3(-1.6677150e-01, -9.0353490e-01, -5.6323410e-01); + positions[259] = Vec3(-1.5077930e-01, -8.7448310e-01, -6.5150250e-01); + positions[260] = Vec3(-2.5054260e-01, -8.5746520e-01, -5.4471400e-01); + positions[261] = Vec3(-1.0245710e-01, -4.1390500e-01, 2.9240710e-01); + positions[262] = Vec3(-1.6375100e-01, -3.5806090e-01, 3.3803800e-01); + positions[263] = Vec3(-3.4371600e-02, -4.4188880e-01, 3.6032470e-01); + positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); + positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); + positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); + positions[267] = Vec3(-5.2597410e-01, 5.0741940e-01, 2.8142130e-01); + positions[268] = Vec3(-5.3172740e-01, 5.6506650e-01, 2.0013640e-01); + positions[269] = Vec3(-5.9533220e-01, 4.4193270e-01, 2.6673520e-01); + positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); + positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); + positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); + positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); + positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); + positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); + positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); + positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); + positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); + positions[279] = Vec3(-8.5624140e-01, -3.3540460e-01, -5.3955060e-01); + positions[280] = Vec3(-8.9833150e-01, -3.2177130e-01, -6.2636700e-01); + positions[281] = Vec3(-7.6568080e-01, -3.0076830e-01, -5.3672910e-01); + positions[282] = Vec3(-4.0866080e-01, -7.0070860e-01, 9.2586930e-01); + positions[283] = Vec3(-4.5043520e-01, -7.7640050e-01, 9.7012510e-01); + positions[284] = Vec3(-3.2086210e-01, -6.9414110e-01, 9.6526100e-01); + positions[285] = Vec3(-2.9612090e-01, 2.9021400e-01, -4.6137730e-01); + positions[286] = Vec3(-3.0085180e-01, 1.9752840e-01, -4.3159520e-01); + positions[287] = Vec3(-2.4502340e-01, 3.3756140e-01, -3.9070450e-01); + positions[288] = Vec3(-8.4956240e-01, -3.3051010e-01, 4.2215900e-02); + positions[289] = Vec3(-8.2077940e-01, -3.9086690e-01, 1.1548590e-01); + positions[290] = Vec3(-9.3822180e-01, -3.1618550e-01, 5.2894000e-02); + positions[291] = Vec3(-8.6464030e-01, 7.5345250e-01, 1.9545370e-01); + positions[292] = Vec3(-9.2073720e-01, 6.7584430e-01, 1.8998460e-01); + positions[293] = Vec3(-8.9310500e-01, 7.8515510e-01, 2.8077440e-01); + positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); + positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); + positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); + positions[297] = Vec3(-3.0166400e-02, 3.6028840e-01, -9.2023940e-01); + positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); + positions[299] = Vec3(-1.2837900e-02, 3.5198820e-01, -8.2331230e-01); + positions[300] = Vec3(-7.6094250e-01, -7.4142570e-01, -7.6415170e-01); + positions[301] = Vec3(-7.5826150e-01, -6.8315050e-01, -8.4024930e-01); + positions[302] = Vec3(-7.8169550e-01, -6.8557300e-01, -6.8728990e-01); + positions[303] = Vec3(-7.1618050e-01, -8.6617600e-02, -7.8297100e-01); + positions[304] = Vec3(-6.9164460e-01, -1.6643810e-01, -7.3660090e-01); + positions[305] = Vec3(-8.1169890e-01, -8.6541300e-02, -7.7380060e-01); + positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); + positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); + positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); + positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); + positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); + positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); + positions[312] = Vec3(-2.2829370e-01, 4.6661410e-01, 7.7985190e-01); + positions[313] = Vec3(-2.4730820e-01, 5.6404020e-01, 7.8763210e-01); + positions[314] = Vec3(-1.7899690e-01, 4.3324110e-01, 8.5622400e-01); + positions[315] = Vec3(-5.1323270e-01, -2.6480150e-01, 7.2113100e-02); + positions[316] = Vec3(-4.4180310e-01, -2.8480730e-01, 1.4166490e-01); + positions[317] = Vec3(-5.5826690e-01, -3.4508980e-01, 5.6782300e-02); + positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); + positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); + positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); + positions[321] = Vec3(-8.6077820e-01, -8.3187420e-01, 3.5264550e-01); + positions[322] = Vec3(-7.9919290e-01, -8.9965630e-01, 3.8875110e-01); + positions[323] = Vec3(-8.4377450e-01, -8.2428940e-01, 2.5657630e-01); + positions[324] = Vec3(-6.9407750e-01, 8.5240530e-01, -4.8975260e-01); + positions[325] = Vec3(-6.0369970e-01, 8.2005830e-01, -4.7948010e-01); + positions[326] = Vec3(-6.8257340e-01, 9.0158170e-01, -5.7057020e-01); + positions[327] = Vec3(-8.6181560e-01, 2.1174420e-01, 3.2775000e-02); + positions[328] = Vec3(-9.5070390e-01, 2.5868190e-01, 2.6787700e-02); + positions[329] = Vec3(-8.8015990e-01, 1.3696510e-01, 9.1486900e-02); + positions[330] = Vec3(-6.7034530e-01, -7.0959980e-01, 5.7197940e-01); + positions[331] = Vec3(-6.3447070e-01, -7.7970770e-01, 5.1435410e-01); + positions[332] = Vec3(-7.1147280e-01, -7.6230200e-01, 6.4084900e-01); + positions[333] = Vec3(-4.2433970e-01, 1.6353470e-01, -7.5364040e-01); + positions[334] = Vec3(-3.3715920e-01, 1.3734360e-01, -7.8660110e-01); + positions[335] = Vec3(-4.5203330e-01, 2.3873860e-01, -8.1607320e-01); + positions[336] = Vec3(-4.2091960e-01, -8.1633330e-01, -5.3063920e-01); + positions[337] = Vec3(-4.2728590e-01, -7.1806470e-01, -5.4109270e-01); + positions[338] = Vec3(-4.5013260e-01, -8.3810340e-01, -6.1998700e-01); + positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); + positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); + positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); + positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); + positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); + positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); + positions[345] = Vec3(-3.5029200e-02, -7.9917400e-02, -3.4468400e-01); + positions[346] = Vec3(-6.3903800e-02, -6.0213300e-02, -2.5206780e-01); + positions[347] = Vec3(-4.6785200e-02, -1.7349570e-01, -3.5772680e-01); + positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); + positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); + positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); + positions[351] = Vec3(-7.3742490e-01, -8.7628820e-01, -2.6411710e-01); + positions[352] = Vec3(-7.3220480e-01, -9.1540050e-01, -3.5104230e-01); + positions[353] = Vec3(-7.9968040e-01, -9.2863850e-01, -2.1682500e-01); + positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); + positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); + positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); + positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); + positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); + positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); + positions[360] = Vec3(-5.0181950e-01, 6.8138390e-01, -8.8794760e-01); + positions[361] = Vec3(-4.0469720e-01, 6.5541180e-01, -8.8475300e-01); + positions[362] = Vec3(-5.4953810e-01, 6.3245150e-01, -8.1669610e-01); + positions[363] = Vec3(-3.5708340e-01, 8.1787480e-01, 1.0372050e-01); + positions[364] = Vec3(-4.3575160e-01, 7.6657380e-01, 8.8357500e-02); + positions[365] = Vec3(-3.8126100e-01, 9.1312250e-01, 1.2894930e-01); + positions[366] = Vec3(-1.0889180e-01, 6.4289110e-01, -1.1000150e-01); + positions[367] = Vec3(-9.5792300e-02, 6.5121590e-01, -1.2915400e-02); + positions[368] = Vec3(-1.4253020e-01, 7.3532640e-01, -1.2649680e-01); + positions[369] = Vec3(-8.0675190e-01, 3.8993580e-01, -9.3061890e-01); + positions[370] = Vec3(-8.4285770e-01, 4.7693320e-01, -9.5868770e-01); + positions[371] = Vec3(-7.4065520e-01, 4.1059110e-01, -8.6270860e-01); + positions[372] = Vec3(-7.3221050e-01, -8.3486000e-02, 1.8651540e-01); + positions[373] = Vec3(-6.6332990e-01, -2.5838100e-02, 1.5155080e-01); + positions[374] = Vec3(-7.5939010e-01, -1.4675440e-01, 1.1813700e-01); + positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); + positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); + positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); + positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); + positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); + positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); + positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); + positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); + positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); + positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); + positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); + positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); + positions[387] = Vec3(-4.9931530e-01, -8.6556710e-01, 4.1410020e-01); + positions[388] = Vec3(-4.0971070e-01, -9.0364250e-01, 4.1539320e-01); + positions[389] = Vec3(-5.0187830e-01, -8.1863570e-01, 3.2854240e-01); + positions[390] = Vec3(-9.2923250e-01, -9.5140200e-02, 7.7175180e-01); + positions[391] = Vec3(-1.0068535e+00, -4.9193300e-02, 8.1361050e-01); + positions[392] = Vec3(-8.5382270e-01, -3.5167000e-02, 7.7988780e-01); + positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); + positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); + positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); + positions[396] = Vec3(-4.3869270e-01, 7.1030180e-01, -3.4435510e-01); + positions[397] = Vec3(-3.5798370e-01, 6.6801330e-01, -3.8293170e-01); + positions[398] = Vec3(-3.9584820e-01, 7.8582280e-01, -3.0015890e-01); + positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); + positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); + positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); + positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); + positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); + positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); + positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); + positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); + positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); + positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); + positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); + positions[410] = Vec3(-1.4581300e-02, 7.7868400e-02, -4.8044320e-01); + positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); + positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); + positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); + positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); + positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); + positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); + positions[417] = Vec3(-7.2074000e-03, -2.1935180e-01, -6.7044710e-01); + positions[418] = Vec3(-7.9916200e-02, -2.2604130e-01, -7.3330810e-01); + positions[419] = Vec3(-3.2871000e-03, -2.9557560e-01, -6.1702790e-01); + positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); + positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); + positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); + positions[423] = Vec3(-3.1753700e-01, 3.7248900e-02, 5.0846140e-01); + positions[424] = Vec3(-3.3276340e-01, 1.2794660e-01, 5.4135580e-01); + positions[425] = Vec3(-4.0442920e-01, -2.1535000e-03, 5.2164500e-01); + positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); + positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); + positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); + positions[429] = Vec3(-5.0985980e-01, 6.5271910e-01, 5.1660950e-01); + positions[430] = Vec3(-4.1891080e-01, 6.9500010e-01, 5.0933000e-01); + positions[431] = Vec3(-5.2072650e-01, 6.0609800e-01, 4.2889530e-01); + positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); + positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); + positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); + positions[435] = Vec3(-4.2632820e-01, -5.4538160e-01, -5.2698140e-01); + positions[436] = Vec3(-3.4047810e-01, -5.2088280e-01, -5.5637760e-01); + positions[437] = Vec3(-4.9107950e-01, -5.2513960e-01, -5.9520410e-01); + positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); + positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); + positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); + positions[441] = Vec3(-3.0889500e-02, -5.4040860e-01, -7.7446500e-02); + positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); + positions[443] = Vec3(-1.0937030e-01, -5.1212170e-01, -1.2642620e-01); + positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); + positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); + positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); + positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); + positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); + positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); + positions[450] = Vec3(-2.7264270e-01, 8.2117820e-01, 4.0979220e-01); + positions[451] = Vec3(-1.8893860e-01, 7.8611730e-01, 4.4435560e-01); + positions[452] = Vec3(-2.7256440e-01, 8.1557060e-01, 3.0746650e-01); + positions[453] = Vec3(-2.3667600e-01, 7.0807760e-01, 9.0055470e-01); + positions[454] = Vec3(-1.7087350e-01, 7.0278860e-01, 9.7330650e-01); + positions[455] = Vec3(-2.2325560e-01, 8.0596230e-01, 8.7050690e-01); + positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); + positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); + positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); + positions[459] = Vec3(-6.9432470e-01, 5.5588670e-01, -7.2750070e-01); + positions[460] = Vec3(-6.8524660e-01, 5.1427650e-01, -6.4407660e-01); + positions[461] = Vec3(-7.7219850e-01, 6.0882800e-01, -7.1352640e-01); + positions[462] = Vec3(-6.5544400e-01, 5.6801890e-01, 7.6654940e-01); + positions[463] = Vec3(-5.9853210e-01, 5.8150060e-01, 6.8630620e-01); + positions[464] = Vec3(-6.0728400e-01, 6.2604000e-01, 8.2970960e-01); + positions[465] = Vec3(-1.7725100e-01, -7.5128040e-01, 4.8288320e-01); + positions[466] = Vec3(-1.1106490e-01, -7.1604590e-01, 4.2681180e-01); + positions[467] = Vec3(-1.2808000e-01, -8.2063050e-01, 5.2385060e-01); + positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); + positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); + positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); + positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); + positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); + positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); + positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); + positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); + positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); + positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); + positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); + positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); + positions[480] = Vec3(-5.0297400e-01, 3.8595440e-01, -9.1329410e-01); + positions[481] = Vec3(-4.2761710e-01, 4.4573350e-01, -8.9961960e-01); + positions[482] = Vec3(-5.7109730e-01, 4.3620760e-01, -9.6075240e-01); + positions[483] = Vec3(-5.7912630e-01, 3.1473530e-01, -1.3174480e-01); + positions[484] = Vec3(-6.4359930e-01, 2.3775370e-01, -1.3815260e-01); + positions[485] = Vec3(-5.1910350e-01, 2.9841740e-01, -5.0386200e-02); + positions[486] = Vec3(-2.3287450e-01, -4.5325250e-01, -2.6295780e-01); + positions[487] = Vec3(-3.1705790e-01, -5.0582880e-01, -2.5755610e-01); + positions[488] = Vec3(-2.4988940e-01, -3.6717760e-01, -2.2456790e-01); + positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); + positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); + positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); + positions[492] = Vec3(-1.7342650e-01, -4.4833620e-01, -6.2689720e-01); + positions[493] = Vec3(-1.2120170e-01, -4.7044370e-01, -5.5178260e-01); + positions[494] = Vec3(-2.1756220e-01, -3.7095040e-01, -5.9046920e-01); + positions[495] = Vec3(-9.7909800e-02, 4.1047140e-01, 5.5154950e-01); + positions[496] = Vec3(-1.5085520e-01, 4.3078300e-01, 6.2923170e-01); + positions[497] = Vec3(-2.2121000e-02, 3.5854830e-01, 5.8628920e-01); + positions[498] = Vec3(-2.9249090e-01, 4.2502460e-01, -7.0552100e-01); + positions[499] = Vec3(-2.3858950e-01, 3.8279980e-01, -7.7129020e-01); + positions[500] = Vec3(-2.8537830e-01, 3.6194940e-01, -6.3036240e-01); + positions[501] = Vec3(-4.1927200e-01, -1.0765570e-01, -8.1010100e-01); + positions[502] = Vec3(-4.5513170e-01, -1.8389200e-01, -8.5055730e-01); + positions[503] = Vec3(-4.6978720e-01, -3.2915400e-02, -8.4249770e-01); + positions[504] = Vec3(-8.3022800e-01, -5.9366610e-01, -5.2440890e-01); + positions[505] = Vec3(-8.3569020e-01, -5.0053960e-01, -5.4596070e-01); + positions[506] = Vec3(-7.7653500e-01, -5.9680800e-01, -4.4872510e-01); + positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); + positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); + positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); + positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); + positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); + positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); + positions[513] = Vec3(-1.7389390e-01, 6.3857050e-01, -4.3802350e-01); + positions[514] = Vec3(-1.0857550e-01, 7.0876020e-01, -4.2023360e-01); + positions[515] = Vec3(-1.6180390e-01, 5.6775180e-01, -3.7084920e-01); + positions[516] = Vec3(-8.3384410e-01, -7.8320210e-01, 7.9714340e-01); + positions[517] = Vec3(-8.6597850e-01, -8.7176550e-01, 7.7689410e-01); + positions[518] = Vec3(-9.1332720e-01, -7.1912210e-01, 7.9807020e-01); + positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); + positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); + positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); + positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); + positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); + positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); + positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); + positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); + positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); + positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); + positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); + positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); + positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); + positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); + positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); + positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); + positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); + positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); + positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); + positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); + positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); + positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); + positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); + positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); + positions[543] = Vec3(-3.2687830e-01, -9.5478000e-03, 2.1684540e-01); + positions[544] = Vec3(-3.2605730e-01, -1.4225700e-02, 3.1463820e-01); + positions[545] = Vec3(-2.7582100e-01, -8.4479800e-02, 1.8809180e-01); + positions[546] = Vec3(-8.3433230e-01, -5.5202940e-01, 2.1864880e-01); + positions[547] = Vec3(-8.2396710e-01, -5.4694370e-01, 3.1266070e-01); + positions[548] = Vec3(-9.3264700e-01, -5.5452020e-01, 1.9359510e-01); + positions[549] = Vec3(-3.7479050e-01, 2.2505660e-01, 7.1205330e-01); + positions[550] = Vec3(-4.7509020e-01, 2.3675960e-01, 7.1906840e-01); + positions[551] = Vec3(-3.3344270e-01, 3.0911900e-01, 7.2096390e-01); + positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); + positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); + positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); + positions[555] = Vec3(-2.3127640e-01, 9.0287820e-01, -1.3411380e-01); + positions[556] = Vec3(-2.8615520e-01, 9.5668910e-01, -1.9830460e-01); + positions[557] = Vec3(-2.9306830e-01, 8.7146310e-01, -6.8234400e-02); + positions[558] = Vec3(-5.4794480e-01, 6.9927600e-02, 4.9211700e-02); + positions[559] = Vec3(-4.8467110e-01, 1.3673600e-02, 9.6662900e-02); + positions[560] = Vec3(-5.5944570e-01, 3.5041600e-02, -4.0422400e-02); + positions[561] = Vec3(-4.0842490e-01, -6.1610810e-01, 5.3013490e-01); + positions[562] = Vec3(-3.5055240e-01, -6.7988460e-01, 4.9398580e-01); + positions[563] = Vec3(-4.6296070e-01, -6.7880320e-01, 5.8633470e-01); + positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); + positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); + positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); + positions[567] = Vec3(-1.6560700e-02, -3.7062430e-01, -3.6569060e-01); + positions[568] = Vec3(-9.0792700e-02, -4.1378610e-01, -3.2720710e-01); + positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); + positions[570] = Vec3(-5.9512760e-01, 1.7073000e-02, -2.2772060e-01); + positions[571] = Vec3(-5.8225940e-01, 7.1421900e-02, -3.0604790e-01); + positions[572] = Vec3(-6.2819960e-01, -6.3276600e-02, -2.6202260e-01); + positions[573] = Vec3(-4.7641750e-01, -4.2323550e-01, 8.9604240e-01); + positions[574] = Vec3(-5.4796980e-01, -4.1341290e-01, 8.3129580e-01); + positions[575] = Vec3(-4.6422920e-01, -5.2061790e-01, 8.9834640e-01); + positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); + positions[577] = Vec3(-6.9252500e-02, -9.1064710e-01, -8.0576000e-02); + positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); + positions[579] = Vec3(-6.0237270e-01, 6.8170090e-01, 6.7672100e-02); + positions[580] = Vec3(-6.3353490e-01, 6.5944010e-01, -1.4737000e-02); + positions[581] = Vec3(-6.7945440e-01, 7.0260310e-01, 1.2553510e-01); + positions[582] = Vec3(-7.9759390e-01, -4.8566970e-01, -8.8075620e-01); + positions[583] = Vec3(-7.6587590e-01, -4.4277470e-01, -9.5861500e-01); + positions[584] = Vec3(-8.8262650e-01, -4.4354590e-01, -8.6497650e-01); + positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); + positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); + positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); + positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); + positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); + positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); + positions[591] = Vec3(-6.9004280e-01, -5.9012070e-01, -2.9270410e-01); + positions[592] = Vec3(-7.1539690e-01, -6.8384200e-01, -2.8572180e-01); + positions[593] = Vec3(-5.9319910e-01, -5.8219810e-01, -2.7391860e-01); + positions[594] = Vec3(-2.0769030e-01, -9.0263320e-01, 8.2559380e-01); + positions[595] = Vec3(-1.2326710e-01, -9.0347650e-01, 7.7889800e-01); + positions[596] = Vec3(-2.4674410e-01, -8.1114260e-01, 8.1400270e-01); + positions[597] = Vec3(-5.9770390e-01, -2.5353030e-01, 3.7815410e-01); + positions[598] = Vec3(-5.7799760e-01, -1.8503970e-01, 4.3781640e-01); + positions[599] = Vec3(-6.3056510e-01, -1.9169960e-01, 3.0646360e-01); + positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); + positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); + positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); + positions[603] = Vec3(-5.7980030e-01, 4.5624440e-01, -4.8053250e-01); + positions[604] = Vec3(-5.0283550e-01, 4.0235700e-01, -4.7629430e-01); + positions[605] = Vec3(-5.5234760e-01, 5.5030960e-01, -4.6445780e-01); + positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); + positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); + positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); + positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); + positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); + positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); + positions[612] = Vec3(-5.8628640e-01, 1.5133800e-02, -5.2805090e-01); + positions[613] = Vec3(-5.0874980e-01, 5.8718200e-02, -5.5884230e-01); + positions[614] = Vec3(-6.4503990e-01, 1.9133400e-02, -6.0165090e-01); + positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); + positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); + positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); + positions[618] = Vec3(-4.1271350e-01, 6.8162960e-01, -6.2517570e-01); + positions[619] = Vec3(-3.4841290e-01, 6.1054470e-01, -6.4194430e-01); + positions[620] = Vec3(-3.5808100e-01, 7.5958210e-01, -6.0333290e-01); + positions[621] = Vec3(-2.3867290e-01, 5.9441400e-02, 9.1386800e-01); + positions[622] = Vec3(-2.9103650e-01, -1.4337800e-02, 9.5259360e-01); + positions[623] = Vec3(-2.8602000e-01, 1.0405050e-01, 8.3648420e-01); + positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); + positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); + positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); + positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); + positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); + positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); + positions[630] = Vec3(-9.1418940e-01, 8.0389630e-01, 7.8826000e-01); + positions[631] = Vec3(-8.3833600e-01, 7.4209380e-01, 7.8290720e-01); + positions[632] = Vec3(-9.9161100e-01, 7.5608500e-01, 8.2971860e-01); + positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); + positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); + positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); + positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); + positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); + positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); + positions[639] = Vec3(-1.1738970e-01, -5.9305270e-01, 7.0381050e-01); + positions[640] = Vec3(-1.5290840e-01, -6.5518590e-01, 6.3431800e-01); + positions[641] = Vec3(-1.6038250e-01, -5.0776740e-01, 6.8496070e-01); + positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); + positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); + positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); + positions[645] = Vec3(-7.5114680e-01, 3.5944460e-01, 2.4369600e-01); + positions[646] = Vec3(-8.1938720e-01, 4.1907000e-01, 2.7265900e-01); + positions[647] = Vec3(-7.8315770e-01, 3.2541650e-01, 1.6165560e-01); std::string platformName; platformName = "Reference"; @@ -1890,654 +1890,654 @@ static void testPMEMutualPolarizationLargeWater() { double expectedEnergy = -1.3268930e+04; - expectedForces[0] = Vec3( -5.2764003e+02, 6.5154502e+02, 7.8683284e+02); - expectedForces[1] = Vec3( 3.3391292e+02, -1.1162521e+03, -2.9173021e+02); - expectedForces[2] = Vec3( 9.4613310e+01, -5.8988099e+01, -6.2871010e+02); - expectedForces[3] = Vec3( -1.6179658e+03, 1.8222798e+02, -1.0373083e+02); - expectedForces[4] = Vec3( 1.0177962e+03, 1.7118957e+02, 4.0084976e+02); - expectedForces[5] = Vec3( 3.0582540e+02, -5.5215191e+02, 4.8287747e+01); - expectedForces[6] = Vec3( -5.4931641e+01, -6.7689368e+02, -1.2260977e+03); - expectedForces[7] = Vec3( -2.9961754e+02, 1.3602079e+03, -2.2087612e+02); - expectedForces[8] = Vec3( -3.1788045e+02, -1.3540025e+02, 1.1250958e+03); - expectedForces[9] = Vec3( 1.0275111e+03, 1.9279625e+02, -6.0872252e+02); - expectedForces[10] = Vec3( -5.7512410e+02, -5.6280482e+01, 7.5039261e+02); - expectedForces[11] = Vec3( -4.7291981e+02, -3.5875411e+01, 5.2335135e+00); - expectedForces[12] = Vec3( -1.5619899e+02, -1.3743370e+02, 1.3587339e+03); - expectedForces[13] = Vec3( -4.7423876e+02, 1.0032873e+02, -2.0875847e+02); - expectedForces[14] = Vec3( 7.5621178e+02, 3.7979419e+01, -4.1221012e+02); - expectedForces[15] = Vec3( 6.7318876e+02, 4.9937148e+02, 1.1665351e+03); - expectedForces[16] = Vec3( -7.0858091e+01, 8.4758233e+01, -1.3126942e+03); - expectedForces[17] = Vec3( -1.0636296e+03, -1.6254851e+02, -1.0982809e+02); - expectedForces[18] = Vec3( -1.0249489e+03, 6.7073895e+02, -2.0754278e+02); - expectedForces[19] = Vec3( 5.6396078e+02, -1.1702137e+03, 1.5324295e+02); - expectedForces[20] = Vec3( 6.1635144e+02, 5.6122242e+02, -7.9410893e+01); - expectedForces[21] = Vec3( -1.5785582e+02, -1.0857764e+03, -1.1010131e+03); - expectedForces[22] = Vec3( 2.3733181e+01, 2.0158373e+02, 3.2583783e+02); - expectedForces[23] = Vec3( 1.8855396e+02, 1.2408889e+03, 4.5759149e+02); - expectedForces[24] = Vec3( 9.3643408e+02, -6.1331107e+01, -3.8601431e+02); - expectedForces[25] = Vec3( -3.1972504e+02, -1.5783340e+02, -1.3838003e+02); - expectedForces[26] = Vec3( -5.1178039e+02, -2.5998898e+02, 6.1021975e+02); - expectedForces[27] = Vec3( 9.1836250e+02, -4.3288112e+02, -9.5579501e+02); - expectedForces[28] = Vec3( -9.3325184e+02, 6.2859013e+01, 5.0743198e+02); - expectedForces[29] = Vec3( 3.1839963e+02, 5.4102155e+02, 1.1261345e+03); - expectedForces[30] = Vec3( 7.3842640e+02, 1.0907054e+02, -2.1126612e+02); - expectedForces[31] = Vec3( -1.8470175e+02, -4.0377182e+01, 1.2464073e+02); - expectedForces[32] = Vec3( -5.8931386e+02, -3.5021489e+02, -7.2769901e+01); - expectedForces[33] = Vec3( 1.4804452e+02, -1.2138869e+02, -1.2423820e+03); - expectedForces[34] = Vec3( -2.4850935e+02, 2.3113218e+01, 1.4041979e+02); - expectedForces[35] = Vec3( 1.3188525e+02, -6.1243481e+02, 6.4886373e+02); - expectedForces[36] = Vec3( 5.0217683e+02, 9.2857480e+02, -7.2500648e+02); - expectedForces[37] = Vec3( 9.9446320e+01, -3.0337270e+02, 8.0439741e+02); - expectedForces[38] = Vec3( -1.7167491e+02, -9.3911948e+02, 5.6412500e+01); - expectedForces[39] = Vec3( -6.6143649e+02, 1.0876882e+03, 3.3801466e+02); - expectedForces[40] = Vec3( 5.6748150e+02, -2.2459572e+02, 3.8360728e+02); - expectedForces[41] = Vec3( 7.7688834e+02, -6.7341171e+02, -6.4292796e+02); - expectedForces[42] = Vec3( 1.0253263e+02, -1.3212797e+03, 9.3279892e+02); - expectedForces[43] = Vec3( 1.5424247e+02, -1.0197346e+01, -8.0230728e+02); - expectedForces[44] = Vec3( -6.6499384e+02, 1.2534353e+03, -1.6748341e+02); - expectedForces[45] = Vec3( -1.9282945e+02, 5.1764789e+02, 1.5108154e+03); - expectedForces[46] = Vec3( -4.9204245e+02, 8.8664089e+02, -8.8381078e+02); - expectedForces[47] = Vec3( 1.3207641e+01, -5.7765859e+02, -3.5921690e+02); - expectedForces[48] = Vec3( 4.1691955e+02, -1.1292452e+03, -6.2339128e+02); - expectedForces[49] = Vec3( 4.8613761e+02, 6.8325845e+02, 2.3424652e+02); - expectedForces[50] = Vec3( 3.1827501e+01, 6.8442319e+02, -5.8685438e+02); - expectedForces[51] = Vec3( 1.1834790e+03, -1.3418299e+03, 5.6280882e+02); - expectedForces[52] = Vec3( -5.8629616e+02, -6.9100489e+01, -9.7784543e+02); - expectedForces[53] = Vec3( -4.0294748e+02, 5.0669032e+02, 5.3893512e+02); - expectedForces[54] = Vec3( 6.3555947e+01, -9.0345643e+02, 7.2235587e+02); - expectedForces[55] = Vec3( 4.9353706e+02, 4.3952680e+02, -1.5413911e+02); - expectedForces[56] = Vec3( -3.4663273e+02, 8.4708544e+02, -8.8983178e+01); - expectedForces[57] = Vec3( 1.5746383e+03, 5.8209931e+02, 3.6645765e+02); - expectedForces[58] = Vec3( -4.0076588e+02, -1.2311235e+02, -1.6226002e+02); - expectedForces[59] = Vec3( -3.3837369e+02, -5.3890252e+02, -5.5997831e+02); - expectedForces[60] = Vec3( 8.6512912e+02, -1.0775827e+03, -3.6920406e+02); - expectedForces[61] = Vec3( 1.0588621e+01, 4.4531974e+02, 1.1838800e+02); - expectedForces[62] = Vec3( -7.0505255e+02, 1.5737739e+02, 3.0134165e+02); - expectedForces[63] = Vec3( -1.2833932e+03, 5.1206074e+02, -9.3423828e+01); - expectedForces[64] = Vec3( 2.0863538e+02, -6.7108922e+02, 3.5777952e+02); - expectedForces[65] = Vec3( 4.9710436e+02, -6.8550896e+01, -2.7502680e+02); - expectedForces[66] = Vec3( 4.0388289e+02, 1.0051571e+03, -2.3823633e+02); - expectedForces[67] = Vec3( -3.3895858e+02, -6.7577709e+02, 3.1521120e+02); - expectedForces[68] = Vec3( -4.8763670e+02, -2.9427128e+02, 2.9500438e+02); - expectedForces[69] = Vec3( -8.4080783e+02, -1.7777886e+02, 6.5087880e+02); - expectedForces[70] = Vec3( 2.1136356e+02, 6.6812142e+01, -5.5437438e+02); - expectedForces[71] = Vec3( -1.3829189e+01, 7.0936421e+02, -5.0847380e+02); - expectedForces[72] = Vec3( -1.5684247e+03, 1.6837339e+02, -4.6044105e+02); - expectedForces[73] = Vec3( 9.9163605e+02, -4.1397181e+02, -3.9624142e+02); - expectedForces[74] = Vec3( 6.7355000e+02, 5.7652252e+02, 1.0565003e+03); - expectedForces[75] = Vec3( -1.3722105e+03, -1.4035644e+03, 2.7882380e+02); - expectedForces[76] = Vec3( 5.2187588e+02, 3.9602986e+02, -2.2564009e+02); - expectedForces[77] = Vec3( 2.6381283e+02, 4.2945748e+02, 1.8339201e+02); - expectedForces[78] = Vec3( 5.3099327e+02, 1.7312849e+03, 3.5385638e+01); - expectedForces[79] = Vec3( -2.1320977e+02, -1.1795453e+03, -5.1691859e+02); - expectedForces[80] = Vec3( -7.1445218e+02, -5.8918750e+02, 7.6494816e+02); - expectedForces[81] = Vec3( 1.0849545e+03, 6.5058603e+02, -5.6051049e+02); - expectedForces[82] = Vec3( -4.6986151e+02, -3.3868080e+02, 7.9000645e+02); - expectedForces[83] = Vec3( -3.8404718e+02, -4.4915037e+02, -4.2069600e+02); - expectedForces[84] = Vec3( -3.0678477e+02, -7.2558567e+02, 2.0276275e+02); - expectedForces[85] = Vec3( 6.2969625e+01, 3.4257826e+02, -6.8348290e+02); - expectedForces[86] = Vec3( 3.1042613e+02, 9.6563445e+01, -1.8788848e+02); - expectedForces[87] = Vec3( 2.4427535e+01, 5.8460648e+02, -1.3720684e+03); - expectedForces[88] = Vec3( -4.9904469e+02, -9.1309605e+02, 1.4350031e+02); - expectedForces[89] = Vec3( -4.0910847e+01, 5.2845046e+01, 2.7341591e+02); - expectedForces[90] = Vec3( -4.5190765e+02, 2.2820859e+02, -1.1052181e+03); - expectedForces[91] = Vec3( 9.1626336e+01, -1.0496400e+03, 1.0216011e+02); - expectedForces[92] = Vec3( -1.2592678e+02, -4.4050520e+01, 1.0764584e+03); - expectedForces[93] = Vec3( 8.4216135e+02, 1.7603150e+02, 1.3698861e+03); - expectedForces[94] = Vec3( 1.2583734e+02, 3.4343971e+02, -7.3070182e+02); - expectedForces[95] = Vec3( -4.5597370e+02, -6.8170738e+02, -5.2258658e+02); - expectedForces[96] = Vec3( 1.3295639e+03, 2.5031118e+02, -3.5171095e+02); - expectedForces[97] = Vec3( -2.0136001e+02, -2.2978012e+02, 2.1122610e+02); - expectedForces[98] = Vec3( -1.1279722e+03, -9.9794730e+02, -1.1321006e+02); - expectedForces[99] = Vec3( 2.9553179e+02, -2.0727600e+02, -1.8912317e+03); - expectedForces[100] = Vec3( -9.3777487e+02, 4.3417972e+02, 5.7436670e+02); - expectedForces[101] = Vec3( 3.1120364e+02, -4.3241206e+00, 5.6666340e+02); - expectedForces[102] = Vec3( -6.6764840e+02, -2.3563274e+02, 9.9017992e+02); - expectedForces[103] = Vec3( 8.2857598e+02, 1.9030059e+02, -2.4295780e+02); - expectedForces[104] = Vec3( -2.6709334e+02, 7.3284851e+01, -3.9157038e+02); - expectedForces[105] = Vec3( 6.6235629e+02, -8.4502811e+02, -5.3670716e+02); - expectedForces[106] = Vec3( 3.8449086e+02, 8.0775263e+02, 5.2003911e+02); - expectedForces[107] = Vec3( -3.4338589e+02, 1.7870086e+02, -6.1047615e+01); - expectedForces[108] = Vec3( 4.3523975e+02, 2.8776092e+02, -1.5333067e+03); - expectedForces[109] = Vec3( 1.9214022e+01, -9.9449061e+01, 3.9153169e+02); - expectedForces[110] = Vec3( -7.7525496e+02, 7.7309387e+01, 7.8886699e+02); - expectedForces[111] = Vec3( -1.1510224e+03, -2.8207337e+02, 1.4866455e+03); - expectedForces[112] = Vec3( 1.1281316e+03, -3.0961130e+02, -1.3894255e+02); - expectedForces[113] = Vec3( -2.4829062e+02, 5.9466066e+02, -9.0749265e+02); - expectedForces[114] = Vec3( -1.6228531e+02, -4.1281378e+02, -1.4860946e+03); - expectedForces[115] = Vec3( -2.9071192e+02, 7.5335271e+02, 6.5205720e+02); - expectedForces[116] = Vec3( 3.2042337e+02, -4.0237231e+02, 1.0068554e+03); - expectedForces[117] = Vec3( -1.4081272e+03, -5.5227579e+02, 2.8376428e+02); - expectedForces[118] = Vec3( 9.6978276e+02, -9.6232683e+02, 2.3399918e+02); - expectedForces[119] = Vec3( 2.0781312e+02, 9.0531947e+01, 8.3513783e+01); - expectedForces[120] = Vec3( 2.9200105e+02, 1.0746865e+03, -6.0773727e+02); - expectedForces[121] = Vec3( -8.7546167e+02, 3.1969683e+02, 8.1033199e+01); - expectedForces[122] = Vec3( -5.3422658e+01, -3.8456585e+02, 1.4595003e+02); - expectedForces[123] = Vec3( -9.5134908e+01, 8.6818098e+02, -1.3111403e+03); - expectedForces[124] = Vec3( -7.2576830e+02, 6.3811172e+01, 7.0993488e+02); - expectedForces[125] = Vec3( 5.6200572e+02, -1.0972338e+03, -3.5278717e+02); - expectedForces[126] = Vec3( -1.6903718e+02, 2.6804112e+02, -8.9811032e+02); - expectedForces[127] = Vec3( 7.0934165e+02, -3.2328700e+02, 1.0037562e+02); - expectedForces[128] = Vec3( -2.5937738e+00, -3.3758145e+02, 3.6354335e+02); - expectedForces[129] = Vec3( -1.1993601e+03, 1.1618922e+02, -1.1329865e+03); - expectedForces[130] = Vec3( 8.3480845e+02, 5.2646427e+02, 9.1816763e+01); - expectedForces[131] = Vec3( 1.9407174e+02, 7.3877492e+00, 8.8648162e+02); - expectedForces[132] = Vec3( -1.0820540e+03, 2.7482390e+02, -1.4876848e+03); - expectedForces[133] = Vec3( 9.5717027e+02, -4.7758356e+02, 4.0692835e+02); - expectedForces[134] = Vec3( 2.4979896e+02, 7.1530552e+02, 6.5834243e+02); - expectedForces[135] = Vec3( -2.7549874e+02, 1.6613806e+03, -5.0628865e+02); - expectedForces[136] = Vec3( -1.5960544e+02, -4.5920421e+02, 9.4068762e+02); - expectedForces[137] = Vec3( 6.9764295e+01, -4.4024430e+02, -2.3545402e+02); - expectedForces[138] = Vec3( 2.0207569e+03, -2.6846158e+02, 3.3977998e+02); - expectedForces[139] = Vec3( -9.9905342e+02, 9.5155462e+02, 8.3259854e+01); - expectedForces[140] = Vec3( -8.0836255e+02, -6.3005196e+02, 1.2603525e+02); - expectedForces[141] = Vec3( 5.2279913e+02, 1.5356061e+03, -1.4399009e+02); - expectedForces[142] = Vec3( -1.3088783e+02, -9.0861449e+02, 9.7040422e+02); - expectedForces[143] = Vec3( 2.8006682e+01, -1.1783245e+03, -3.7285390e+02); - expectedForces[144] = Vec3( 6.1040927e+01, 2.1747286e+01, 9.0366011e+02); - expectedForces[145] = Vec3( 7.0396235e+02, -2.3865001e+02, -6.8794682e+02); - expectedForces[146] = Vec3( -5.1132933e+02, 7.7102556e+02, -4.7805042e+02); - expectedForces[147] = Vec3( 6.2879945e+02, -6.9758821e+02, 1.0983043e+03); - expectedForces[148] = Vec3( -9.2449123e+02, 5.0248042e+02, -2.0065211e+02); - expectedForces[149] = Vec3( -3.9485154e+02, 3.4679511e+02, -7.3889603e+02); - expectedForces[150] = Vec3( 4.9834751e+02, -1.0117501e+03, 1.2510946e+03); - expectedForces[151] = Vec3( -1.4942699e+02, -7.4362790e+01, -6.8008427e+02); - expectedForces[152] = Vec3( -1.8353666e+02, 5.1697483e+02, -8.4397292e+01); - expectedForces[153] = Vec3( 7.0253008e+02, -1.5361338e+02, 8.6830836e+02); - expectedForces[154] = Vec3( -4.1108898e+02, -6.8181350e+02, -5.6516951e+02); - expectedForces[155] = Vec3( 3.9294374e+02, 3.7294948e+02, -4.9795080e+02); - expectedForces[156] = Vec3( -7.3716758e+02, -5.5465931e+02, -9.3434525e+02); - expectedForces[157] = Vec3( 1.8240105e+02, 1.5494359e+02, 1.3626243e+02); - expectedForces[158] = Vec3( 9.3172059e+02, 1.4431275e+02, 6.6916065e+02); - expectedForces[159] = Vec3( 7.3399513e+01, -3.6000187e+02, 1.9853052e+03); - expectedForces[160] = Vec3( -2.4842520e+02, -4.0819514e+02, -8.0624794e+02); - expectedForces[161] = Vec3( 4.3585911e+02, -2.6521764e+02, -6.7985842e+02); - expectedForces[162] = Vec3( -8.2255783e+02, 1.1430906e+03, 1.2991183e+03); - expectedForces[163] = Vec3( 5.6437196e+02, -1.5391213e+02, -5.0013503e+02); - expectedForces[164] = Vec3( 3.8485296e+02, -1.1754088e+02, -1.4315511e+03); - expectedForces[165] = Vec3( 9.8205241e+02, 1.3278205e+01, 3.0367584e+02); - expectedForces[166] = Vec3( -3.2909916e+02, 4.5169387e+01, -3.2019488e+02); - expectedForces[167] = Vec3( -4.2382795e+02, -8.1938351e+02, -1.5360675e+02); - expectedForces[168] = Vec3( 9.1689997e+02, 1.4443113e+03, -1.8886795e+02); - expectedForces[169] = Vec3( -1.2161000e+03, -2.3826187e+02, 3.4004889e+02); - expectedForces[170] = Vec3( -2.2837927e+02, -9.8334152e+02, 3.0313790e+02); - expectedForces[171] = Vec3( 5.2598040e+02, -1.2766936e+03, 8.1247934e+01); - expectedForces[172] = Vec3( -6.7839687e+01, 6.9220160e+02, 3.1975320e+02); - expectedForces[173] = Vec3( -4.8519844e+02, 4.3008979e+02, -7.6788762e+02); - expectedForces[174] = Vec3( 3.9550092e+01, 1.0900122e+03, 5.0955281e+02); - expectedForces[175] = Vec3( -6.3000735e+02, -7.2335263e+02, -2.2590661e+02); - expectedForces[176] = Vec3( 1.5048762e+02, -4.0086126e+02, -1.2159849e+02); - expectedForces[177] = Vec3( -7.1939527e+02, -1.0640815e+03, -3.1826393e+02); - expectedForces[178] = Vec3( 7.7492135e+02, 1.0620129e+02, 3.6733165e+02); - expectedForces[179] = Vec3( -3.5466457e+02, 7.0081887e+02, 2.2629152e+02); - expectedForces[180] = Vec3( 3.0338275e+02, -1.1243396e+02, -1.3408996e+03); - expectedForces[181] = Vec3( 9.0394088e+00, 4.8818819e+02, 7.3781403e+02); - expectedForces[182] = Vec3( -5.6111982e+01, -2.5224925e+02, 3.0344460e+02); - expectedForces[183] = Vec3( -7.4693225e+02, 1.1370727e+03, 9.3958175e+02); - expectedForces[184] = Vec3( 3.1310327e+02, -1.2133761e+03, 2.6768166e+02); - expectedForces[185] = Vec3( 6.0706899e+02, 9.8403362e+01, -5.0781782e+02); - expectedForces[186] = Vec3( -6.2721609e+02, 1.7751567e+02, 2.6230643e+02); - expectedForces[187] = Vec3( 3.5425475e+02, -3.3336896e+02, 2.9529930e+02); - expectedForces[188] = Vec3( 4.7499029e+02, 4.5552354e+02, -2.4939310e+02); - expectedForces[189] = Vec3( 1.1556321e+02, 2.5995186e+02, -8.4171376e+02); - expectedForces[190] = Vec3( -4.5095184e+02, -1.6639362e+01, 4.2956175e+02); - expectedForces[191] = Vec3( -7.5904218e+01, 3.9416063e+02, 4.2573815e+02); - expectedForces[192] = Vec3( 2.3041013e+02, -1.2883920e+03, -5.1943189e+02); - expectedForces[193] = Vec3( 8.6086944e+01, 1.8626094e+02, 3.7641641e+02); - expectedForces[194] = Vec3( -5.9266805e+02, 4.4766229e+02, -4.5835497e+02); - expectedForces[195] = Vec3( 3.9368476e+02, 1.1050329e+03, -1.3906133e+03); - expectedForces[196] = Vec3( -1.2912212e+03, -2.9660534e+02, 3.9659215e+02); - expectedForces[197] = Vec3( -2.4803663e+01, -2.7945607e+02, 3.5315630e+02); - expectedForces[198] = Vec3( 1.4147479e+02, 3.2766723e+02, 1.1137899e+03); - expectedForces[199] = Vec3( 7.8383167e+01, 2.2385715e+00, -1.0346820e+03); - expectedForces[200] = Vec3( -2.9231551e+02, -5.4648720e+02, -6.5500265e+02); - expectedForces[201] = Vec3( 1.3708284e+03, -1.0716376e+03, 4.5781190e+02); - expectedForces[202] = Vec3( -7.5533654e+02, 6.5396686e+02, -4.2683276e+02); - expectedForces[203] = Vec3( -6.5558825e+02, 3.1164131e+02, 2.6323555e+02); - expectedForces[204] = Vec3( 1.3173432e+03, 1.3775889e+03, 1.2933072e+02); - expectedForces[205] = Vec3( -4.0922505e+02, -7.5709333e+02, -3.4967434e+02); - expectedForces[206] = Vec3( 4.2270572e+01, -7.4393359e+02, 5.2985443e+02); - expectedForces[207] = Vec3( -1.5327880e+03, 7.3186706e+02, -2.3440058e+02); - expectedForces[208] = Vec3( 1.4650210e+03, 2.8661572e+02, -2.4233049e+02); - expectedForces[209] = Vec3( 8.4124688e+02, -3.4020518e+02, -3.1773592e+01); - expectedForces[210] = Vec3( -1.1480436e+03, -7.4089732e+02, -4.8883682e+02); - expectedForces[211] = Vec3( 3.5682075e+02, 2.1918110e+01, -1.2558000e+02); - expectedForces[212] = Vec3( 1.6505256e+02, 7.9867933e+02, 9.9760760e+02); - expectedForces[213] = Vec3( 1.2477725e+03, -8.8687803e+02, -8.2498529e+02); - expectedForces[214] = Vec3( 1.7357042e+02, 2.0185456e+02, 8.0965301e+02); - expectedForces[215] = Vec3( -9.0937500e+02, 5.5968713e+01, 1.7581913e+02); - expectedForces[216] = Vec3( 1.3030711e+03, -8.2642443e+02, 1.6679926e+02); - expectedForces[217] = Vec3( -8.4295510e+02, 2.0237547e+01, 4.0163431e+02); - expectedForces[218] = Vec3( -3.2088719e+02, 3.0824476e+02, 9.9166532e+01); - expectedForces[219] = Vec3( 1.4585495e+03, -4.1497503e+01, -2.2539636e+02); - expectedForces[220] = Vec3( -2.6148433e+02, 1.7592075e+02, 2.0638296e+02); - expectedForces[221] = Vec3( -9.2100962e+02, 2.6090225e+02, -8.4461867e+02); - expectedForces[222] = Vec3( -9.0597287e+02, -4.8246138e+02, -1.8012972e+03); - expectedForces[223] = Vec3( -1.1775667e+02, 1.7275816e+02, 1.1286513e+03); - expectedForces[224] = Vec3( 1.0682239e+03, 8.0853797e+02, 2.5601774e+02); - expectedForces[225] = Vec3( -1.6637330e+02, 7.6165466e+02, -5.9394315e+02); - expectedForces[226] = Vec3( 2.6206832e+02, -1.5011747e+02, 5.4532792e+02); - expectedForces[227] = Vec3( -2.6474701e+02, -1.4218144e+02, 1.1099125e+02); - expectedForces[228] = Vec3( -9.7365994e+02, -5.5282012e+02, -6.3158992e+02); - expectedForces[229] = Vec3( 1.1482718e+03, 1.4958662e+02, -5.6523355e+02); - expectedForces[230] = Vec3( 4.4084982e+02, 7.9662251e+02, 4.9732039e+02); - expectedForces[231] = Vec3( -4.8746806e+02, -1.5522005e+03, 1.0133483e+03); - expectedForces[232] = Vec3( 1.1332903e+03, 1.2836176e+03, -2.0897082e+02); - expectedForces[233] = Vec3( -7.9973372e+01, 6.3066961e+02, -5.8656505e+02); - expectedForces[234] = Vec3( -8.3714021e+02, -1.5385924e+03, 1.0179672e+03); - expectedForces[235] = Vec3( 3.5358323e+02, 9.3554369e+02, 1.6565605e+02); - expectedForces[236] = Vec3( 1.7532341e+02, 3.0381323e+01, -1.2538424e+03); - expectedForces[237] = Vec3( -1.0437301e+03, -4.4804918e+02, 1.5276435e+03); - expectedForces[238] = Vec3( 8.5470872e+02, 1.0725550e+03, -9.7359443e+01); - expectedForces[239] = Vec3( 1.8192015e+02, -7.6967211e+01, -8.6054596e+02); - expectedForces[240] = Vec3( 1.5910180e+03, -7.9601605e+02, -8.4030326e+02); - expectedForces[241] = Vec3( -6.4638370e+02, 4.0538540e+02, 2.3396878e+01); - expectedForces[242] = Vec3( -5.2648918e+02, 1.3689201e+02, 9.3014716e+02); - expectedForces[243] = Vec3( 2.2248997e+02, -6.3647370e+02, -8.3913128e+02); - expectedForces[244] = Vec3( -7.5759832e+02, 4.7985429e+01, 5.8577833e+02); - expectedForces[245] = Vec3( 1.2983550e+02, 4.4401985e+02, 2.3556259e+02); - expectedForces[246] = Vec3( 7.8075637e+02, 9.9893821e+02, 7.3511307e+02); - expectedForces[247] = Vec3( -8.6411159e+02, 2.3812628e+02, 1.9007971e+02); - expectedForces[248] = Vec3( 2.0762263e+02, -7.0123789e+02, -4.8175733e+02); - expectedForces[249] = Vec3( -8.2749187e+02, -7.8772346e+02, -9.8536337e+02); - expectedForces[250] = Vec3( 8.3905893e+01, -2.8770518e+02, 6.0690561e+02); - expectedForces[251] = Vec3( 7.2280803e+02, 4.9294103e+02, -1.2915033e+02); - expectedForces[252] = Vec3( -1.3615809e+03, -1.8564754e+02, -4.2172817e+02); - expectedForces[253] = Vec3( 9.2102155e+02, 5.4063967e+02, -2.7291760e+02); - expectedForces[254] = Vec3( 7.0204283e+02, -3.0338605e+02, 6.6795953e+02); - expectedForces[255] = Vec3( -7.2261285e+00, 3.2570478e+02, 5.9010590e+02); - expectedForces[256] = Vec3( -8.3167819e+02, 3.0568475e+02, -9.9230441e+02); - expectedForces[257] = Vec3( 2.1074297e+02, -4.0099946e+01, -1.2770634e+02); - expectedForces[258] = Vec3( 1.1218559e+03, -8.8304672e+02, 1.0217945e+03); - expectedForces[259] = Vec3( -4.4730264e+01, 5.3616918e+02, -3.2704110e+02); - expectedForces[260] = Vec3( -1.1106141e+03, 3.3541536e+02, -1.0552986e+02); - expectedForces[261] = Vec3( -9.3728497e+01, 4.7397796e+01, -1.1294332e+03); - expectedForces[262] = Vec3( 5.1424956e+01, 4.0854995e+02, 5.6832607e+02); - expectedForces[263] = Vec3( 1.4286074e+02, 2.9172921e+01, 5.1355833e+02); - expectedForces[264] = Vec3( -4.4318133e+02, -9.5478293e+02, -1.8067439e+03); - expectedForces[265] = Vec3( -2.8083245e+02, 8.1414586e+02, 6.6089404e+02); - expectedForces[266] = Vec3( 1.0434876e+02, 3.0664078e+02, 1.3658532e+03); - expectedForces[267] = Vec3( 1.2999089e+03, 5.6746563e+02, 1.2200612e+03); - expectedForces[268] = Vec3( -5.9546942e+02, 3.6897149e+02, -8.3331437e+02); - expectedForces[269] = Vec3( -1.1094881e+03, -5.1903335e+02, -3.5729033e+02); - expectedForces[270] = Vec3( 4.1873464e+02, 6.9788983e+02, -1.3191929e+03); - expectedForces[271] = Vec3( -1.0086080e+02, 3.3114447e+02, 6.3419860e+02); - expectedForces[272] = Vec3( -2.8783906e+02, -8.8308011e+02, -5.4816768e+01); - expectedForces[273] = Vec3( 1.0254638e+03, 2.8710026e+02, -1.9779676e+02); - expectedForces[274] = Vec3( -3.5906548e+02, -5.5531449e+02, -6.0205492e+01); - expectedForces[275] = Vec3( -3.9578349e+02, 5.9217272e+01, 1.0735648e+02); - expectedForces[276] = Vec3( -8.7298871e+02, -1.5584711e+02, 9.2571354e+02); - expectedForces[277] = Vec3( 4.1520558e+02, 5.6442126e+02, -1.8142289e+02); - expectedForces[278] = Vec3( 6.5423421e+02, -4.1631573e+02, 1.0996479e+02); - expectedForces[279] = Vec3( -8.0063899e+01, -1.2880940e+03, 2.9304469e+02); - expectedForces[280] = Vec3( -9.5930841e+02, 5.8293485e+02, -1.1632205e+03); - expectedForces[281] = Vec3( 6.3492338e+02, 2.5550931e+02, 1.7380517e+02); - expectedForces[282] = Vec3( -1.9188175e+02, 1.0257290e+03, -8.6438702e+02); - expectedForces[283] = Vec3( 4.0063530e+01, -5.1808902e+02, 4.9556015e+02); - expectedForces[284] = Vec3( 5.8250018e+02, -2.5030700e+02, 1.1762860e+03); - expectedForces[285] = Vec3( -4.3195459e+02, 7.4733530e+02, -1.3002210e+03); - expectedForces[286] = Vec3( 2.7567334e+01, -5.1662654e+02, 3.3258050e+02); - expectedForces[287] = Vec3( 6.1700857e+02, 3.0016354e+02, 9.5519139e+02); - expectedForces[288] = Vec3( 7.7553094e+02, 8.6453551e+02, -1.0122996e+03); - expectedForces[289] = Vec3( -2.6730796e+02, -7.7560875e+02, 4.3195620e+02); - expectedForces[290] = Vec3( -8.5982146e+02, 1.6692057e+02, 4.3838169e+02); - expectedForces[291] = Vec3( 1.2945126e+03, 6.3231748e+02, -8.3020592e+02); - expectedForces[292] = Vec3( -6.9510729e+02, -3.1930013e+02, -1.3919425e+01); - expectedForces[293] = Vec3( -4.1154200e+02, -3.3562358e+02, 6.3292682e+02); - expectedForces[294] = Vec3( -4.0919783e+02, -3.8282298e+02, -4.9125465e+02); - expectedForces[295] = Vec3( 6.3932145e+02, -1.8769713e+01, 9.9241332e+01); - expectedForces[296] = Vec3( 8.6847663e+01, 8.7234739e+02, 2.7124112e+02); - expectedForces[297] = Vec3( -1.0307576e+03, -6.2447562e+02, -1.5796976e+03); - expectedForces[298] = Vec3( 6.2464595e+02, 1.0608165e+03, 3.1422521e+01); - expectedForces[299] = Vec3( 3.7767184e+02, 4.1170186e+02, 1.0696495e+03); - expectedForces[300] = Vec3( 1.0578030e+02, -1.9544726e+03, -4.6243957e+02); - expectedForces[301] = Vec3( -3.1074896e+02, 8.6738333e+02, -2.0241448e+02); - expectedForces[302] = Vec3( -2.7350519e+02, 6.9945273e+02, 7.8755130e+02); - expectedForces[303] = Vec3( 7.8083070e+02, 6.5199614e+02, -6.6698950e+02); - expectedForces[304] = Vec3( 1.3647451e+02, -4.2490411e+02, 1.3236061e+01); - expectedForces[305] = Vec3( -1.1048984e+03, 3.7582184e+02, -6.4718844e+01); - expectedForces[306] = Vec3( 1.5976050e+03, -8.9091819e+02, 9.7113419e+02); - expectedForces[307] = Vec3( -4.5545384e+01, 8.8683300e+02, -6.5927739e+01); - expectedForces[308] = Vec3( -1.3883497e+03, -4.6171498e+02, -2.9117829e+02); - expectedForces[309] = Vec3( -6.6661140e+02, -8.1394964e+02, 1.2397900e+03); - expectedForces[310] = Vec3( -2.5293546e+02, 1.8568554e+02, -6.8919479e+02); - expectedForces[311] = Vec3( 5.2052057e+02, 1.0288555e+03, 3.1435700e+02); - expectedForces[312] = Vec3( -2.4245555e+02, -1.1100993e+03, -1.6937710e+03); - expectedForces[313] = Vec3( 1.6647470e+02, 9.5272347e+02, 9.2528380e+02); - expectedForces[314] = Vec3( 8.6946518e+02, -1.6295251e+02, 5.7452409e+02); - expectedForces[315] = Vec3( 1.4059831e+02, 5.6780959e+02, -4.6024149e+02); - expectedForces[316] = Vec3( 2.3327811e+02, -2.2376697e+02, 1.3399582e+01); - expectedForces[317] = Vec3( -2.6583612e+01, -4.5801841e+02, 2.9595361e+01); - expectedForces[318] = Vec3( 1.2361796e+03, -1.9473934e+02, -2.6179421e+02); - expectedForces[319] = Vec3( -4.2330105e+02, 5.0768290e+02, 6.8352494e+02); - expectedForces[320] = Vec3( -2.0826312e+02, 1.4720747e+02, -9.8828425e-01); - expectedForces[321] = Vec3( -7.3226106e+02, -1.5366771e+01, 2.7882968e+02); - expectedForces[322] = Vec3( 4.2634684e+02, -6.2926647e+02, 3.6300784e+02); - expectedForces[323] = Vec3( 1.7826269e+02, 1.0038378e+02, -4.2408556e+02); - expectedForces[324] = Vec3( -1.1690005e+03, 2.1777241e+02, 9.1980300e+02); - expectedForces[325] = Vec3( 5.6841370e+02, -2.6614377e+02, -6.4968364e+01); - expectedForces[326] = Vec3( 3.5710749e+02, 1.3228373e+02, -3.6567433e+02); - expectedForces[327] = Vec3( 8.1957745e+02, 7.3903486e+02, 3.9487193e+02); - expectedForces[328] = Vec3( -8.5354740e+02, 8.9297958e+01, 9.0615539e+01); - expectedForces[329] = Vec3( -2.3935807e+02, -2.2950021e+02, -4.6193868e+01); - expectedForces[330] = Vec3( 8.6120406e+01, 1.4046499e+03, -1.5899345e+02); - expectedForces[331] = Vec3( 4.6319634e+02, -4.6309406e+02, -2.2891416e+02); - expectedForces[332] = Vec3( -4.2592255e+02, -2.6503000e+02, 6.1788141e+02); - expectedForces[333] = Vec3( -2.4468457e+02, -7.7827760e+02, 4.2470013e+02); - expectedForces[334] = Vec3( 2.6006448e+02, 7.6289112e+01, -4.3430411e+02); - expectedForces[335] = Vec3( -2.5268926e+02, 7.7381529e+02, -5.0896414e+02); - expectedForces[336] = Vec3( 1.0414844e+03, -6.1885512e+02, 1.4495539e+03); - expectedForces[337] = Vec3( -5.9522011e+01, 1.3607073e+03, -7.3705640e+01); - expectedForces[338] = Vec3( -5.9857094e+02, -2.7213045e+02, -9.7516268e+02); - expectedForces[339] = Vec3( 9.2852178e+02, 3.0121600e+02, -7.4982031e+00); - expectedForces[340] = Vec3( -1.0201472e+03, 1.6269359e+02, 1.9280960e+02); - expectedForces[341] = Vec3( -1.8744984e+02, -4.9790658e+02, 4.2841303e+02); - expectedForces[342] = Vec3( -1.0893114e+03, -4.6044565e+02, -2.0537532e+02); - expectedForces[343] = Vec3( 5.1068148e+02, -3.0889884e+02, 1.7703226e+01); - expectedForces[344] = Vec3( 2.0128423e+02, 5.0813056e+02, -5.0941772e+01); - expectedForces[345] = Vec3( -6.0195519e+02, 1.1710803e+03, -5.8271481e+02); - expectedForces[346] = Vec3( 1.3898239e+02, -3.2598252e+02, 1.0877023e+03); - expectedForces[347] = Vec3( 3.1630812e+02, -8.9974673e+02, 9.6573268e+01); - expectedForces[348] = Vec3( -5.5334313e+01, -1.1529065e+03, -2.1949997e+02); - expectedForces[349] = Vec3( -4.4904784e+02, 2.4036076e+02, 4.1328142e+02); - expectedForces[350] = Vec3( 1.0611611e+03, 4.1620143e+02, 9.1677657e+01); - expectedForces[351] = Vec3( 1.3489840e+03, 9.9500659e+02, -4.5894902e+01); - expectedForces[352] = Vec3( -9.8051252e+01, -9.0794586e+02, -8.9918421e+02); - expectedForces[353] = Vec3( -3.5567408e+02, -7.2914902e+01, 4.7977644e+01); - expectedForces[354] = Vec3( -1.5976501e+03, -1.2202674e+03, 7.2159213e+02); - expectedForces[355] = Vec3( 1.7391266e+02, 1.0197773e+03, -9.1284547e+02); - expectedForces[356] = Vec3( 7.8937287e+02, 1.1964969e+02, -3.8520683e+02); - expectedForces[357] = Vec3( 2.8170878e+02, 1.0377979e+03, -5.0609230e+02); - expectedForces[358] = Vec3( -4.0852118e+01, -4.3087314e+02, 4.1855459e+01); - expectedForces[359] = Vec3( -3.2767902e+02, -7.8083477e+02, 1.1111190e+03); - expectedForces[360] = Vec3( -1.0691030e+03, 3.1877408e+02, -7.9684323e+02); - expectedForces[361] = Vec3( 7.7603235e+02, 3.6577850e+02, -1.9093841e+02); - expectedForces[362] = Vec3( -4.7607360e+02, -5.1710653e+02, 7.2740737e+02); - expectedForces[363] = Vec3( 9.3461900e+02, 7.9988609e+01, -5.8055314e+02); - expectedForces[364] = Vec3( -9.8128918e+02, -2.6706371e+02, -3.5178135e+01); - expectedForces[365] = Vec3( -6.5196668e+02, 8.7618054e+02, 3.3040412e+02); - expectedForces[366] = Vec3( 5.5458970e+02, -1.1281839e+03, -8.2774754e+02); - expectedForces[367] = Vec3( 1.8491757e+02, -5.1421593e+01, 4.7068191e+02); - expectedForces[368] = Vec3( -4.3945944e+02, 8.2740025e+02, -2.1736033e+01); - expectedForces[369] = Vec3( -2.5609394e+02, -6.7141305e+02, -3.2964376e+02); - expectedForces[370] = Vec3( 1.4932730e+02, 2.2746635e+02, -3.7606156e+01); - expectedForces[371] = Vec3( 3.0873674e+02, 5.9974800e+02, 4.2207331e+02); - expectedForces[372] = Vec3( -3.8828932e+02, -2.1491002e+02, 1.5266506e+03); - expectedForces[373] = Vec3( 4.4495676e+02, 6.4708482e+02, -9.2222368e+02); - expectedForces[374] = Vec3( -4.8420767e+01, -4.3781484e+02, -5.0107314e+02); - expectedForces[375] = Vec3( 5.7593719e+02, -1.8140066e+03, -4.0189721e+02); - expectedForces[376] = Vec3( -5.1276233e+02, 6.6981030e+02, 3.9050744e+02); - expectedForces[377] = Vec3( 4.0809391e+02, 1.1596412e+03, -4.1325341e+02); - expectedForces[378] = Vec3( 1.4975560e+03, 1.7852942e+02, -7.6514466e+02); - expectedForces[379] = Vec3( -2.2890988e+02, 2.6128742e+02, 3.8545036e+02); - expectedForces[380] = Vec3( -3.8899762e+02, -2.5609958e+02, 2.0655882e+02); - expectedForces[381] = Vec3( -1.9500869e+02, -1.0947633e+03, -9.1786660e+02); - expectedForces[382] = Vec3( 8.6146884e+02, 2.5767444e+02, 3.6801549e+02); - expectedForces[383] = Vec3( -2.0008562e+02, 2.1549793e+02, 2.5175877e+02); - expectedForces[384] = Vec3( -5.6491749e+02, 5.4714989e+02, 3.1934114e+02); - expectedForces[385] = Vec3( 1.7665111e+02, -4.5297277e+02, 2.2387580e+02); - expectedForces[386] = Vec3( 6.2697664e+02, 1.1271358e+02, 2.9498078e+00); - expectedForces[387] = Vec3( -2.1918090e+03, -7.8914005e+01, 1.0632280e+03); - expectedForces[388] = Vec3( 7.5750278e+02, -5.0217666e+02, -1.3057335e+02); - expectedForces[389] = Vec3( 1.0621096e+03, 1.6022661e+01, -1.1645539e+03); - expectedForces[390] = Vec3( -4.7808938e+02, -1.2425496e+03, -1.5543074e+02); - expectedForces[391] = Vec3( -3.4676860e+02, 8.5391303e+02, 3.5351618e+01); - expectedForces[392] = Vec3( 5.4017203e+02, 8.6467815e+01, 1.1898140e+02); - expectedForces[393] = Vec3( -1.8873828e+01, 2.2133074e+02, -1.3378739e+03); - expectedForces[394] = Vec3( 7.5888012e+01, -1.6517743e+01, 1.1817186e+02); - expectedForces[395] = Vec3( 1.1912944e+02, -1.6083226e+02, 7.8733940e+02); - expectedForces[396] = Vec3( -1.2400005e+03, -3.9434827e+02, 1.4071802e+02); - expectedForces[397] = Vec3( 9.6249284e+02, 1.1394516e+02, -3.4977717e+02); - expectedForces[398] = Vec3( 2.4187486e+02, 1.3373651e+02, 6.5894105e+01); - expectedForces[399] = Vec3( 8.8628445e+02, 7.8083892e+01, -1.0288922e+03); - expectedForces[400] = Vec3( -9.4613057e+02, -1.9076053e+02, 6.7506442e+02); - expectedForces[401] = Vec3( -6.2746897e+02, 2.9376858e+02, 9.2767458e+02); - expectedForces[402] = Vec3( 5.5409175e+01, -1.2583442e+03, 7.1728490e+02); - expectedForces[403] = Vec3( -2.9076856e+02, 7.5539656e+02, 7.0121763e+00); - expectedForces[404] = Vec3( 2.6220897e+02, -9.5606102e+01, -7.7725998e+02); - expectedForces[405] = Vec3( -8.6582014e+02, 9.5597761e+02, 1.5941783e+02); - expectedForces[406] = Vec3( -1.6910265e+02, -7.2646192e+02, -3.5476587e+02); - expectedForces[407] = Vec3( 9.7629076e+02, -8.3969437e+01, 2.5523637e+02); - expectedForces[408] = Vec3( -4.9553396e+01, 6.3557270e+02, -7.5908312e+02); - expectedForces[409] = Vec3( 3.3210227e+01, 1.5198340e+02, 7.0322192e+02); - expectedForces[410] = Vec3( -2.6532687e+01, -4.1589199e+02, 4.2771258e+02); - expectedForces[411] = Vec3( 1.1412630e+03, -2.7366656e+02, 9.8419548e+02); - expectedForces[412] = Vec3( -3.7239786e+02, 7.2244667e+01, -9.9502150e+02); - expectedForces[413] = Vec3( -4.6476941e+02, -6.1433607e+01, -2.5459288e+02); - expectedForces[414] = Vec3( 9.7028883e+02, 5.5981848e+02, 8.4425262e+02); - expectedForces[415] = Vec3( 7.2811577e+01, 2.2872709e+02, -1.3822700e+03); - expectedForces[416] = Vec3( -1.0105821e+03, -2.8444698e+02, -7.2506392e+02); - expectedForces[417] = Vec3( 1.0027865e+03, 6.0924816e+02, -5.7818592e+01); - expectedForces[418] = Vec3( -3.4173955e+02, -1.1932310e+02, -2.9495449e+01); - expectedForces[419] = Vec3( -2.7281265e+02, -1.8869212e+02, 1.9643932e+02); - expectedForces[420] = Vec3( -7.4036328e+02, -4.8733524e+02, 1.5862094e+03); - expectedForces[421] = Vec3( 5.6387864e+02, 3.0991659e+02, -8.6746725e+02); - expectedForces[422] = Vec3( 6.2954421e-01, 4.9665567e+02, -1.0114913e+03); - expectedForces[423] = Vec3( 8.9668630e+02, -1.0121499e+03, -1.1520006e+03); - expectedForces[424] = Vec3( -2.5699741e+02, 3.3243520e+02, 7.6038873e+02); - expectedForces[425] = Vec3( -1.2755484e+03, -2.7786159e+01, 3.0900583e+02); - expectedForces[426] = Vec3( -1.2587339e+03, -8.6851333e+02, 1.6295957e+02); - expectedForces[427] = Vec3( 6.4923970e+02, 4.4600015e+02, 3.3033348e+02); - expectedForces[428] = Vec3( 5.8905637e+02, -1.1589062e+02, -1.8168184e+02); - expectedForces[429] = Vec3( -1.1223714e+03, 3.0322406e+01, 8.7272053e+02); - expectedForces[430] = Vec3( 3.0982625e+02, 3.1418220e+02, -3.9301742e+02); - expectedForces[431] = Vec3( 2.4213933e+02, -7.2382572e+02, -1.0155346e+03); - expectedForces[432] = Vec3( 1.1479692e+03, -1.6837721e+03, 1.0545407e+02); - expectedForces[433] = Vec3( -8.2496264e+02, 6.0540594e+02, 1.3979931e+02); - expectedForces[434] = Vec3( -6.8171514e+02, 4.0392791e+02, -3.4712316e+02); - expectedForces[435] = Vec3( -1.5568889e+02, -1.4652975e+03, 5.1518148e+01); - expectedForces[436] = Vec3( 5.6573856e+02, 3.5494119e+02, -3.3796345e+02); - expectedForces[437] = Vec3( -1.3938679e+02, 4.2296152e+02, -2.0539863e+02); - expectedForces[438] = Vec3( 8.9203493e+01, 2.8764597e+02, -7.3273496e+02); - expectedForces[439] = Vec3( 4.3114292e+02, 9.4778082e+01, 1.8894761e+02); - expectedForces[440] = Vec3( -2.2798193e+01, -4.5460891e+01, 9.8310963e+01); - expectedForces[441] = Vec3( -2.1793579e+02, -1.0807542e+03, -2.3470465e+01); - expectedForces[442] = Vec3( 1.3881360e+02, 3.9806903e+02, 4.1089741e+01); - expectedForces[443] = Vec3( -4.5604974e+02, 4.8515999e+02, -6.6025174e+02); - expectedForces[444] = Vec3( 3.6437700e+02, -8.1622511e+02, -9.6454258e+02); - expectedForces[445] = Vec3( 3.1998690e+02, -3.3342314e+02, 1.2441763e+03); - expectedForces[446] = Vec3( 3.0822409e+01, 2.0596612e+02, 2.0937122e+02); - expectedForces[447] = Vec3( -8.4938718e+02, -1.1366483e+03, -1.3638049e+02); - expectedForces[448] = Vec3( -5.5232451e+01, 4.7335097e+02, -5.4433565e+02); - expectedForces[449] = Vec3( 6.5928852e+02, 1.7488804e+02, 6.7879378e+02); - expectedForces[450] = Vec3( -9.4572079e+02, 1.9162420e+02, 4.7935043e+02); - expectedForces[451] = Vec3( 2.5029547e+02, 3.6606767e+01, -9.3423713e+01); - expectedForces[452] = Vec3( 1.6543841e+02, -1.1892943e+02, -5.8737050e+02); - expectedForces[453] = Vec3( -9.8495219e+02, -1.6882428e+03, -4.0576035e+02); - expectedForces[454] = Vec3( 7.9182557e+02, 5.3997699e+02, 3.3231603e+02); - expectedForces[455] = Vec3( 1.8277090e+01, 1.4623150e+03, -9.4985721e+01); - expectedForces[456] = Vec3( -1.0471948e+03, 4.6746395e+02, -1.5020000e+03); - expectedForces[457] = Vec3( 7.2055316e+02, -5.4467216e+02, 4.0459421e+02); - expectedForces[458] = Vec3( 7.5475531e+01, 4.9532870e+02, 1.3002474e+03); - expectedForces[459] = Vec3( 6.3589773e+02, -2.1402397e+02, -1.4147509e+03); - expectedForces[460] = Vec3( 2.8391861e+02, -8.0142885e+01, 5.6445225e+02); - expectedForces[461] = Vec3( -8.2442674e+02, 5.3520687e+02, 1.1406667e+03); - expectedForces[462] = Vec3( -5.7988771e+02, -3.3512887e+02, 4.5461752e+02); - expectedForces[463] = Vec3( 4.5746059e+02, 3.1029926e+02, -5.0060176e+02); - expectedForces[464] = Vec3( 7.7747136e+02, 4.2131732e+02, 5.5836239e+02); - expectedForces[465] = Vec3( -1.2315491e+03, 9.4066088e+02, 9.6145313e+02); - expectedForces[466] = Vec3( 7.9043841e+02, -2.2172613e+02, -2.6508587e+02); - expectedForces[467] = Vec3( 7.8197894e+02, -3.1383822e+02, 2.5444013e+02); - expectedForces[468] = Vec3( -7.1139498e+01, -7.1203189e+01, -4.6845544e+02); - expectedForces[469] = Vec3( -8.9774100e+01, 1.4389287e+02, 9.8957451e+01); - expectedForces[470] = Vec3( 3.0397922e+02, -2.8247850e+01, 4.4896034e+02); - expectedForces[471] = Vec3( -9.7808367e+02, 1.0170553e+03, 8.1594649e+02); - expectedForces[472] = Vec3( 1.8933676e+02, -8.8053046e+02, 6.8784042e+01); - expectedForces[473] = Vec3( 5.1636668e+02, 1.2970985e+02, -8.9380858e+02); - expectedForces[474] = Vec3( -5.8549608e+02, -1.8351156e+02, -5.8043066e+02); - expectedForces[475] = Vec3( 2.7877663e+02, -3.6576715e+02, 3.5497095e+02); - expectedForces[476] = Vec3( 3.0642370e+02, 5.3438407e+02, 1.9409584e+02); - expectedForces[477] = Vec3( -4.8523805e+02, 1.2253320e+03, 9.6414379e+02); - expectedForces[478] = Vec3( -1.5213013e+02, -2.0017205e+02, -6.6602643e+02); - expectedForces[479] = Vec3( 4.6435225e+02, -4.1945066e+02, -8.6774270e+01); - expectedForces[480] = Vec3( 2.4946889e+02, -1.0456281e+03, 4.7404434e+02); - expectedForces[481] = Vec3( -3.0813505e+01, 2.8598938e+02, 7.7374350e+01); - expectedForces[482] = Vec3( -2.4538851e+02, 3.8306987e+02, -5.0235520e+02); - expectedForces[483] = Vec3( 4.0348805e+01, 1.3050360e+03, -6.8725580e+02); - expectedForces[484] = Vec3( -1.1095514e+02, -2.7711572e+02, 2.6929959e+02); - expectedForces[485] = Vec3( -6.8071081e+01, -3.4398150e+02, 2.5209743e+02); - expectedForces[486] = Vec3( 2.1534786e+03, 1.3249493e+01, 7.4171165e+01); - expectedForces[487] = Vec3( -7.2618755e+02, -3.2914219e+02, 2.5917332e+02); - expectedForces[488] = Vec3( -1.0231949e+03, 7.2426062e+02, 1.9111862e+02); - expectedForces[489] = Vec3( 1.1408866e+03, 6.7858353e+02, -2.1410916e+02); - expectedForces[490] = Vec3( -4.5559047e+02, -1.3597950e+02, -3.2284091e+02); - expectedForces[491] = Vec3( -8.5558133e+02, -7.1748324e+01, 5.3332261e+02); - expectedForces[492] = Vec3( -7.1393886e+02, -1.1275222e+03, -6.2147584e+02); - expectedForces[493] = Vec3( 4.4029614e+02, 1.0518224e+02, 4.6519788e+02); - expectedForces[494] = Vec3( -3.5770378e+02, 1.0311834e+03, 2.2141802e+02); - expectedForces[495] = Vec3( -2.6023787e+02, 1.0070248e+03, -1.1113552e+03); - expectedForces[496] = Vec3( -3.4950242e+02, 2.8418846e+01, 1.2865161e+03); - expectedForces[497] = Vec3( 1.5030225e+02, -7.7257505e+02, 8.7232628e+02); - expectedForces[498] = Vec3( -1.7416695e+02, 9.9945569e+02, -1.6742483e+02); - expectedForces[499] = Vec3( 2.0837481e+02, -1.9388709e+02, 9.7409815e+01); - expectedForces[500] = Vec3( -1.0129845e+02, -6.8652976e+02, 8.4930186e+02); - expectedForces[501] = Vec3( 1.2276099e+03, 1.6531986e+02, 3.6342506e+02); - expectedForces[502] = Vec3( -1.9998077e+02, -2.6164759e+02, -1.6601933e+02); - expectedForces[503] = Vec3( -4.0356327e+02, 4.0549152e+02, 2.9710052e+02); - expectedForces[504] = Vec3( -7.3045150e+02, -1.6677706e+03, -9.8671765e+02); - expectedForces[505] = Vec3( -2.1441879e+02, 1.4962605e+03, 5.6350856e+02); - expectedForces[506] = Vec3( 7.1102593e+02, 5.9407971e+02, 9.5452239e+02); - expectedForces[507] = Vec3( 3.2291041e+02, 1.3943261e+03, -1.8477432e+03); - expectedForces[508] = Vec3( -1.7778104e+02, 2.8034575e+02, 1.1385089e+03); - expectedForces[509] = Vec3( -2.4943297e+02, -9.0965773e+02, 5.2737490e+02); - expectedForces[510] = Vec3( -3.8318508e+02, 1.3999092e+03, -5.9960180e+02); - expectedForces[511] = Vec3( 2.6930065e+01, -3.6603454e+02, 1.0460530e+03); - expectedForces[512] = Vec3( -1.8964668e+02, -1.1663184e+03, -2.8438291e+02); - expectedForces[513] = Vec3( -9.4679273e+02, 8.7408257e+01, -2.5740702e+02); - expectedForces[514] = Vec3( 1.6558849e+02, 3.3561310e+02, 3.8532718e+02); - expectedForces[515] = Vec3( 4.0403504e+02, -8.5545173e+02, 4.0647038e+02); - expectedForces[516] = Vec3( 8.3825526e+02, 5.0343638e+01, -3.9171626e+02); - expectedForces[517] = Vec3( -4.0069871e+02, -6.4140295e+02, 7.5218861e+01); - expectedForces[518] = Vec3( -6.5213072e+02, 4.1689581e+02, -8.9280241e+01); - expectedForces[519] = Vec3( 4.0832996e+02, -3.4272605e+02, -9.2740030e+02); - expectedForces[520] = Vec3( -2.1128040e+01, -7.3467005e+02, 6.5449252e+02); - expectedForces[521] = Vec3( -2.8042421e+02, 3.3193211e+02, 5.1272473e+02); - expectedForces[522] = Vec3( -1.2057322e+03, 3.3276609e+02, 6.8838073e+02); - expectedForces[523] = Vec3( 8.9270663e+02, 1.3914748e+02, -8.7213182e+02); - expectedForces[524] = Vec3( 8.8063936e+02, -2.4952564e+02, -8.3942753e+01); - expectedForces[525] = Vec3( 3.6527919e+02, 3.3758036e+02, -1.3449147e+03); - expectedForces[526] = Vec3( 7.1836993e+01, -3.9380031e+01, 4.7169292e+02); - expectedForces[527] = Vec3( -7.2114939e+01, -1.3679457e+02, 3.9080695e+02); - expectedForces[528] = Vec3( 1.1465645e+02, -4.4994719e+02, -3.4180224e+02); - expectedForces[529] = Vec3( -6.0950292e+01, 4.2825716e+02, -1.4233246e+02); - expectedForces[530] = Vec3( -1.9112828e+02, -2.8511065e+00, 2.6894050e+02); - expectedForces[531] = Vec3( 4.4955085e+02, 2.0459389e+02, 8.9486972e+02); - expectedForces[532] = Vec3( 6.6339624e+01, -4.2734850e+01, -4.8004048e+02); - expectedForces[533] = Vec3( -5.0521801e+02, -1.6330265e+02, -6.2374206e+02); - expectedForces[534] = Vec3( -1.1019306e+03, -4.5760347e+02, 4.6134602e+01); - expectedForces[535] = Vec3( 4.9278700e+02, 8.0495847e+02, -5.7470233e+01); - expectedForces[536] = Vec3( 9.9361557e+02, -2.4453172e+02, -3.7696369e+02); - expectedForces[537] = Vec3( -1.1168499e+03, -2.1108925e+02, -4.1233970e+02); - expectedForces[538] = Vec3( 5.6559058e+02, -2.8153614e+02, 3.0539700e+02); - expectedForces[539] = Vec3( 4.0805303e+02, 2.8796083e+02, -3.0009135e+01); - expectedForces[540] = Vec3( -8.5249075e+02, -1.0560038e+03, -6.5111795e+02); - expectedForces[541] = Vec3( 8.4653565e+02, 2.0615416e+02, -1.5085906e+02); - expectedForces[542] = Vec3( -2.8200251e+02, 6.6950966e+02, 5.9661450e+02); - expectedForces[543] = Vec3( -9.3339994e+01, 8.7084190e+02, -7.8375352e+02); - expectedForces[544] = Vec3( 1.4187243e+02, 1.2829809e+02, 8.0626841e+02); - expectedForces[545] = Vec3( 1.5403073e+02, -4.5932125e+02, -8.3051878e+00); - expectedForces[546] = Vec3( 1.3919197e+03, 5.4728737e+02, -1.0548033e+03); - expectedForces[547] = Vec3( -2.7215065e+02, 1.5112718e+02, 6.7366542e+02); - expectedForces[548] = Vec3( -7.8677637e+02, -2.6895175e+02, 4.3374996e+02); - expectedForces[549] = Vec3( 6.6014864e+02, -1.1474704e+03, -3.7199889e+02); - expectedForces[550] = Vec3( -5.8741315e+02, 2.6286109e+02, 1.9036264e+02); - expectedForces[551] = Vec3( 1.4325969e+02, 7.8928381e+02, 3.6304214e+02); - expectedForces[552] = Vec3( -9.6661866e+02, -1.0462801e+03, -6.3261994e+02); - expectedForces[553] = Vec3( 5.5171916e+02, 2.8672800e+02, 2.7240662e+02); - expectedForces[554] = Vec3( 1.1625052e+03, 7.7864110e+02, -5.2588322e+02); - expectedForces[555] = Vec3( 1.7042269e+03, -5.8973225e+02, 1.4814500e+02); - expectedForces[556] = Vec3( -7.7324022e+02, 2.9167426e+02, -1.0262563e+02); - expectedForces[557] = Vec3( -5.4655014e+02, -8.4339654e+01, 9.7375629e+02); - expectedForces[558] = Vec3( -6.9618127e+02, -1.6878530e+02, 7.1078501e+02); - expectedForces[559] = Vec3( 6.9623995e+02, -3.7038954e+01, 2.2671528e+02); - expectedForces[560] = Vec3( -7.1025694e+01, -1.8643963e+02, -8.0181026e+02); - expectedForces[561] = Vec3( -1.4598467e+02, 1.7170707e+03, -4.3305456e+02); - expectedForces[562] = Vec3( 7.9582463e+02, -5.9551245e+02, 8.3485625e+01); - expectedForces[563] = Vec3( -4.6812643e+02, -3.4598874e+02, -3.6753356e+01); - expectedForces[564] = Vec3( -1.8586268e+02, 3.1377143e+02, -1.6616022e+03); - expectedForces[565] = Vec3( 7.4400496e+02, 5.5058789e+02, 7.5374599e+02); - expectedForces[566] = Vec3( -6.3347529e+02, -3.1407006e+02, 8.2964691e+02); - expectedForces[567] = Vec3( -4.2499528e+02, 9.4575975e+02, -6.6700103e+02); - expectedForces[568] = Vec3( -9.2637696e+02, -6.6301622e+02, 3.9913705e+02); - expectedForces[569] = Vec3( 5.0588430e+02, -8.1942697e+01, 4.2128365e+02); - expectedForces[570] = Vec3( 2.7165158e+02, 2.7387902e+02, 1.0850277e+03); - expectedForces[571] = Vec3( -6.8391471e+00, -1.2886307e+02, -5.3501450e+02); - expectedForces[572] = Vec3( -2.9936240e+02, -2.2085475e+02, -6.9670281e+01); - expectedForces[573] = Vec3( 1.6853422e+02, 4.8410887e+02, 1.0517406e+03); - expectedForces[574] = Vec3( -4.9287521e+02, 1.6557733e+01, -3.4008916e+02); - expectedForces[575] = Vec3( 1.1132397e+02, -9.8734894e+02, -1.1154151e+02); - expectedForces[576] = Vec3( 3.8645582e+02, 4.3709361e+02, 1.4861132e+03); - expectedForces[577] = Vec3( -1.0169967e+03, -3.5279110e+02, -5.4860861e+02); - expectedForces[578] = Vec3( 2.8875246e+02, 5.3726711e+01, -5.9395936e+02); - expectedForces[579] = Vec3( 1.5169994e+03, 8.7535209e+01, 1.0103159e+03); - expectedForces[580] = Vec3( -1.9439968e+02, -7.9639200e+02, -1.0439069e+03); - expectedForces[581] = Vec3( -8.7374025e+02, 2.0597360e+02, 1.0218319e+02); - expectedForces[582] = Vec3( 6.4275846e+02, -6.2671529e+02, 8.9274592e+02); - expectedForces[583] = Vec3( -5.4449356e+01, 7.2615928e+02, -9.1355057e+02); - expectedForces[584] = Vec3( -2.7242606e+02, 3.9376960e+02, -4.7692581e+01); - expectedForces[585] = Vec3( 2.6578654e+02, -6.7385441e+02, -1.5306127e+03); - expectedForces[586] = Vec3( 5.1049761e+02, 7.3430855e+02, 6.1178168e+02); - expectedForces[587] = Vec3( -3.3593193e+02, 3.5079666e+01, 9.7444298e+02); - expectedForces[588] = Vec3( -7.8227654e+01, -1.1050481e+03, 1.4161574e+03); - expectedForces[589] = Vec3( -7.6753407e+02, 9.7291633e+02, 1.9943116e+02); - expectedForces[590] = Vec3( 2.9274184e+02, -2.5706985e+01, -5.8944290e+02); - expectedForces[591] = Vec3( -1.2502829e+03, 2.2304820e+02, -8.8573767e+02); - expectedForces[592] = Vec3( 1.2218682e+02, -8.2110835e+02, 3.4276058e+02); - expectedForces[593] = Vec3( 8.9529566e+02, -1.8417573e+02, 8.4717919e+02); - expectedForces[594] = Vec3( -4.6475772e+01, -1.5493620e+03, 4.8004365e+02); - expectedForces[595] = Vec3( 6.7104033e+02, 4.7267915e+02, -6.2630817e+02); - expectedForces[596] = Vec3( -2.2771561e+02, 2.7463551e+02, -2.9704610e+00); - expectedForces[597] = Vec3( 1.7757815e+02, -1.8906761e+03, -1.6656886e+02); - expectedForces[598] = Vec3( -7.4745588e+01, 1.0353962e+03, 4.2924498e+02); - expectedForces[599] = Vec3( -5.5648197e+02, 7.7838572e+02, -4.1677346e+02); - expectedForces[600] = Vec3( -5.2972489e+02, 1.1967117e+02, 1.0565388e+03); - expectedForces[601] = Vec3( 7.8379665e+02, -4.1803420e+02, 2.0308387e+02); - expectedForces[602] = Vec3( 1.2705528e+02, 1.1663435e+02, -7.6514830e+02); - expectedForces[603] = Vec3( -1.5203094e+03, -8.5825144e+01, -2.3039380e+02); - expectedForces[604] = Vec3( 5.2063739e+02, -1.7259834e+02, -2.9854160e+01); - expectedForces[605] = Vec3( 4.7448961e+02, 2.8282389e+02, 3.4257463e+01); - expectedForces[606] = Vec3( 1.4519531e+03, -1.2031444e+03, -6.7084095e+02); - expectedForces[607] = Vec3( -7.5308994e+02, -3.2117501e+02, 5.7700017e+02); - expectedForces[608] = Vec3( -1.7643179e+02, 8.5655779e+02, -2.6285482e+02); - expectedForces[609] = Vec3( -1.3868959e+03, -1.6195505e+01, -1.3783528e+03); - expectedForces[610] = Vec3( 2.8034476e+02, -4.2360778e+02, 4.5904202e+02); - expectedForces[611] = Vec3( 1.0938532e+03, 6.2455629e+02, -1.0108636e+02); - expectedForces[612] = Vec3( 9.1439974e+01, -7.2813810e+02, 1.0197075e+03); - expectedForces[613] = Vec3( 1.4048294e+02, 2.5667744e+02, -5.1914694e+02); - expectedForces[614] = Vec3( -2.5604629e+01, 2.9915218e+01, -5.1582702e+02); - expectedForces[615] = Vec3( 2.0331673e+02, 1.5538650e+02, -1.1836865e+03); - expectedForces[616] = Vec3( -2.3788957e+02, -1.1872269e+02, 9.7052698e+02); - expectedForces[617] = Vec3( -3.2419551e+01, -1.8828745e+02, 4.3037423e+02); - expectedForces[618] = Vec3( -4.8585762e+02, 1.4114027e+02, 1.6021114e+02); - expectedForces[619] = Vec3( 2.8744134e+02, -5.7197623e+02, -1.8323508e+02); - expectedForces[620] = Vec3( 2.3652930e+02, -1.5448350e+01, 2.1721186e+01); - expectedForces[621] = Vec3( 1.1684581e+03, 2.2790484e+02, 2.7798348e+02); - expectedForces[622] = Vec3( -4.6823976e+02, -6.1804544e+02, 2.7193441e+02); - expectedForces[623] = Vec3( -5.8173089e+02, 4.4573870e+02, -6.0699430e+02); - expectedForces[624] = Vec3( 7.9759250e+02, 1.8480473e+03, -5.1434277e+02); - expectedForces[625] = Vec3( -1.0945975e+03, -6.0402685e+02, 1.5843017e+02); - expectedForces[626] = Vec3( 1.2334392e+02, -9.5602838e+02, 7.8137824e+02); - expectedForces[627] = Vec3( -8.5863208e+02, -5.7413454e+02, 1.7014217e+02); - expectedForces[628] = Vec3( -1.2232569e+02, 6.0505774e+02, -1.6806693e+02); - expectedForces[629] = Vec3( 6.1488135e+02, 4.1603705e+02, 2.1121948e+02); - expectedForces[630] = Vec3( 2.1858899e+02, 1.2961013e+03, 4.8534041e+02); - expectedForces[631] = Vec3( 2.1292701e+02, -4.1049165e+02, 3.9057142e+00); - expectedForces[632] = Vec3( -6.3342469e+02, -8.7529004e+02, 6.1928550e+01); - expectedForces[633] = Vec3( -7.3207079e+02, -1.3874807e+03, 8.6303032e+02); - expectedForces[634] = Vec3( 6.6660351e+02, 9.5813895e+02, -1.4555416e+02); - expectedForces[635] = Vec3( 4.1800653e+02, 2.4677420e+02, -1.1424272e+03); - expectedForces[636] = Vec3( 8.3570430e+02, -1.5342969e+03, -1.2510269e+03); - expectedForces[637] = Vec3( -3.0635229e+02, 1.2465088e+03, -1.9679529e+01); - expectedForces[638] = Vec3( -6.5317178e+02, -1.6432929e+02, 9.2427724e+02); - expectedForces[639] = Vec3( 1.5665680e+03, 9.8040004e+01, 1.0786497e+02); - expectedForces[640] = Vec3( -4.6590380e+02, -3.7603795e+02, -9.4955273e+02); - expectedForces[641] = Vec3( -8.7572108e+02, 5.1750570e+02, -1.2268062e+02); - expectedForces[642] = Vec3( 1.1575067e+03, -2.2857204e+02, -2.3816900e+02); - expectedForces[643] = Vec3( -2.6229644e+02, 3.1069110e+02, -1.2098536e+02); - expectedForces[644] = Vec3( -1.8195659e+02, -3.8984698e+02, 6.4622752e+02); - expectedForces[645] = Vec3( 1.0756277e+03, 2.7459106e+01, 1.0850508e+03); - expectedForces[646] = Vec3( -6.4620310e+02, 2.5885783e+02, -2.0567224e+02); - expectedForces[647] = Vec3( -4.7388806e+02, -5.5561844e+02, -8.5019295e+02); + expectedForces[0] = Vec3(-5.2764003e+02, 6.5154502e+02, 7.8683284e+02); + expectedForces[1] = Vec3( 3.3391292e+02, -1.1162521e+03, -2.9173021e+02); + expectedForces[2] = Vec3( 9.4613310e+01, -5.8988099e+01, -6.2871010e+02); + expectedForces[3] = Vec3(-1.6179658e+03, 1.8222798e+02, -1.0373083e+02); + expectedForces[4] = Vec3( 1.0177962e+03, 1.7118957e+02, 4.0084976e+02); + expectedForces[5] = Vec3( 3.0582540e+02, -5.5215191e+02, 4.8287747e+01); + expectedForces[6] = Vec3(-5.4931641e+01, -6.7689368e+02, -1.2260977e+03); + expectedForces[7] = Vec3(-2.9961754e+02, 1.3602079e+03, -2.2087612e+02); + expectedForces[8] = Vec3(-3.1788045e+02, -1.3540025e+02, 1.1250958e+03); + expectedForces[9] = Vec3( 1.0275111e+03, 1.9279625e+02, -6.0872252e+02); + expectedForces[10] = Vec3(-5.7512410e+02, -5.6280482e+01, 7.5039261e+02); + expectedForces[11] = Vec3(-4.7291981e+02, -3.5875411e+01, 5.2335135e+00); + expectedForces[12] = Vec3(-1.5619899e+02, -1.3743370e+02, 1.3587339e+03); + expectedForces[13] = Vec3(-4.7423876e+02, 1.0032873e+02, -2.0875847e+02); + expectedForces[14] = Vec3( 7.5621178e+02, 3.7979419e+01, -4.1221012e+02); + expectedForces[15] = Vec3( 6.7318876e+02, 4.9937148e+02, 1.1665351e+03); + expectedForces[16] = Vec3(-7.0858091e+01, 8.4758233e+01, -1.3126942e+03); + expectedForces[17] = Vec3(-1.0636296e+03, -1.6254851e+02, -1.0982809e+02); + expectedForces[18] = Vec3(-1.0249489e+03, 6.7073895e+02, -2.0754278e+02); + expectedForces[19] = Vec3( 5.6396078e+02, -1.1702137e+03, 1.5324295e+02); + expectedForces[20] = Vec3( 6.1635144e+02, 5.6122242e+02, -7.9410893e+01); + expectedForces[21] = Vec3(-1.5785582e+02, -1.0857764e+03, -1.1010131e+03); + expectedForces[22] = Vec3( 2.3733181e+01, 2.0158373e+02, 3.2583783e+02); + expectedForces[23] = Vec3( 1.8855396e+02, 1.2408889e+03, 4.5759149e+02); + expectedForces[24] = Vec3( 9.3643408e+02, -6.1331107e+01, -3.8601431e+02); + expectedForces[25] = Vec3(-3.1972504e+02, -1.5783340e+02, -1.3838003e+02); + expectedForces[26] = Vec3(-5.1178039e+02, -2.5998898e+02, 6.1021975e+02); + expectedForces[27] = Vec3( 9.1836250e+02, -4.3288112e+02, -9.5579501e+02); + expectedForces[28] = Vec3(-9.3325184e+02, 6.2859013e+01, 5.0743198e+02); + expectedForces[29] = Vec3( 3.1839963e+02, 5.4102155e+02, 1.1261345e+03); + expectedForces[30] = Vec3( 7.3842640e+02, 1.0907054e+02, -2.1126612e+02); + expectedForces[31] = Vec3(-1.8470175e+02, -4.0377182e+01, 1.2464073e+02); + expectedForces[32] = Vec3(-5.8931386e+02, -3.5021489e+02, -7.2769901e+01); + expectedForces[33] = Vec3( 1.4804452e+02, -1.2138869e+02, -1.2423820e+03); + expectedForces[34] = Vec3(-2.4850935e+02, 2.3113218e+01, 1.4041979e+02); + expectedForces[35] = Vec3( 1.3188525e+02, -6.1243481e+02, 6.4886373e+02); + expectedForces[36] = Vec3( 5.0217683e+02, 9.2857480e+02, -7.2500648e+02); + expectedForces[37] = Vec3( 9.9446320e+01, -3.0337270e+02, 8.0439741e+02); + expectedForces[38] = Vec3(-1.7167491e+02, -9.3911948e+02, 5.6412500e+01); + expectedForces[39] = Vec3(-6.6143649e+02, 1.0876882e+03, 3.3801466e+02); + expectedForces[40] = Vec3( 5.6748150e+02, -2.2459572e+02, 3.8360728e+02); + expectedForces[41] = Vec3( 7.7688834e+02, -6.7341171e+02, -6.4292796e+02); + expectedForces[42] = Vec3( 1.0253263e+02, -1.3212797e+03, 9.3279892e+02); + expectedForces[43] = Vec3( 1.5424247e+02, -1.0197346e+01, -8.0230728e+02); + expectedForces[44] = Vec3(-6.6499384e+02, 1.2534353e+03, -1.6748341e+02); + expectedForces[45] = Vec3(-1.9282945e+02, 5.1764789e+02, 1.5108154e+03); + expectedForces[46] = Vec3(-4.9204245e+02, 8.8664089e+02, -8.8381078e+02); + expectedForces[47] = Vec3( 1.3207641e+01, -5.7765859e+02, -3.5921690e+02); + expectedForces[48] = Vec3( 4.1691955e+02, -1.1292452e+03, -6.2339128e+02); + expectedForces[49] = Vec3( 4.8613761e+02, 6.8325845e+02, 2.3424652e+02); + expectedForces[50] = Vec3( 3.1827501e+01, 6.8442319e+02, -5.8685438e+02); + expectedForces[51] = Vec3( 1.1834790e+03, -1.3418299e+03, 5.6280882e+02); + expectedForces[52] = Vec3(-5.8629616e+02, -6.9100489e+01, -9.7784543e+02); + expectedForces[53] = Vec3(-4.0294748e+02, 5.0669032e+02, 5.3893512e+02); + expectedForces[54] = Vec3( 6.3555947e+01, -9.0345643e+02, 7.2235587e+02); + expectedForces[55] = Vec3( 4.9353706e+02, 4.3952680e+02, -1.5413911e+02); + expectedForces[56] = Vec3(-3.4663273e+02, 8.4708544e+02, -8.8983178e+01); + expectedForces[57] = Vec3( 1.5746383e+03, 5.8209931e+02, 3.6645765e+02); + expectedForces[58] = Vec3(-4.0076588e+02, -1.2311235e+02, -1.6226002e+02); + expectedForces[59] = Vec3(-3.3837369e+02, -5.3890252e+02, -5.5997831e+02); + expectedForces[60] = Vec3( 8.6512912e+02, -1.0775827e+03, -3.6920406e+02); + expectedForces[61] = Vec3( 1.0588621e+01, 4.4531974e+02, 1.1838800e+02); + expectedForces[62] = Vec3(-7.0505255e+02, 1.5737739e+02, 3.0134165e+02); + expectedForces[63] = Vec3(-1.2833932e+03, 5.1206074e+02, -9.3423828e+01); + expectedForces[64] = Vec3( 2.0863538e+02, -6.7108922e+02, 3.5777952e+02); + expectedForces[65] = Vec3( 4.9710436e+02, -6.8550896e+01, -2.7502680e+02); + expectedForces[66] = Vec3( 4.0388289e+02, 1.0051571e+03, -2.3823633e+02); + expectedForces[67] = Vec3(-3.3895858e+02, -6.7577709e+02, 3.1521120e+02); + expectedForces[68] = Vec3(-4.8763670e+02, -2.9427128e+02, 2.9500438e+02); + expectedForces[69] = Vec3(-8.4080783e+02, -1.7777886e+02, 6.5087880e+02); + expectedForces[70] = Vec3( 2.1136356e+02, 6.6812142e+01, -5.5437438e+02); + expectedForces[71] = Vec3(-1.3829189e+01, 7.0936421e+02, -5.0847380e+02); + expectedForces[72] = Vec3(-1.5684247e+03, 1.6837339e+02, -4.6044105e+02); + expectedForces[73] = Vec3( 9.9163605e+02, -4.1397181e+02, -3.9624142e+02); + expectedForces[74] = Vec3( 6.7355000e+02, 5.7652252e+02, 1.0565003e+03); + expectedForces[75] = Vec3(-1.3722105e+03, -1.4035644e+03, 2.7882380e+02); + expectedForces[76] = Vec3( 5.2187588e+02, 3.9602986e+02, -2.2564009e+02); + expectedForces[77] = Vec3( 2.6381283e+02, 4.2945748e+02, 1.8339201e+02); + expectedForces[78] = Vec3( 5.3099327e+02, 1.7312849e+03, 3.5385638e+01); + expectedForces[79] = Vec3(-2.1320977e+02, -1.1795453e+03, -5.1691859e+02); + expectedForces[80] = Vec3(-7.1445218e+02, -5.8918750e+02, 7.6494816e+02); + expectedForces[81] = Vec3( 1.0849545e+03, 6.5058603e+02, -5.6051049e+02); + expectedForces[82] = Vec3(-4.6986151e+02, -3.3868080e+02, 7.9000645e+02); + expectedForces[83] = Vec3(-3.8404718e+02, -4.4915037e+02, -4.2069600e+02); + expectedForces[84] = Vec3(-3.0678477e+02, -7.2558567e+02, 2.0276275e+02); + expectedForces[85] = Vec3( 6.2969625e+01, 3.4257826e+02, -6.8348290e+02); + expectedForces[86] = Vec3( 3.1042613e+02, 9.6563445e+01, -1.8788848e+02); + expectedForces[87] = Vec3( 2.4427535e+01, 5.8460648e+02, -1.3720684e+03); + expectedForces[88] = Vec3(-4.9904469e+02, -9.1309605e+02, 1.4350031e+02); + expectedForces[89] = Vec3(-4.0910847e+01, 5.2845046e+01, 2.7341591e+02); + expectedForces[90] = Vec3(-4.5190765e+02, 2.2820859e+02, -1.1052181e+03); + expectedForces[91] = Vec3( 9.1626336e+01, -1.0496400e+03, 1.0216011e+02); + expectedForces[92] = Vec3(-1.2592678e+02, -4.4050520e+01, 1.0764584e+03); + expectedForces[93] = Vec3( 8.4216135e+02, 1.7603150e+02, 1.3698861e+03); + expectedForces[94] = Vec3( 1.2583734e+02, 3.4343971e+02, -7.3070182e+02); + expectedForces[95] = Vec3(-4.5597370e+02, -6.8170738e+02, -5.2258658e+02); + expectedForces[96] = Vec3( 1.3295639e+03, 2.5031118e+02, -3.5171095e+02); + expectedForces[97] = Vec3(-2.0136001e+02, -2.2978012e+02, 2.1122610e+02); + expectedForces[98] = Vec3(-1.1279722e+03, -9.9794730e+02, -1.1321006e+02); + expectedForces[99] = Vec3( 2.9553179e+02, -2.0727600e+02, -1.8912317e+03); + expectedForces[100] = Vec3(-9.3777487e+02, 4.3417972e+02, 5.7436670e+02); + expectedForces[101] = Vec3( 3.1120364e+02, -4.3241206e+00, 5.6666340e+02); + expectedForces[102] = Vec3(-6.6764840e+02, -2.3563274e+02, 9.9017992e+02); + expectedForces[103] = Vec3( 8.2857598e+02, 1.9030059e+02, -2.4295780e+02); + expectedForces[104] = Vec3(-2.6709334e+02, 7.3284851e+01, -3.9157038e+02); + expectedForces[105] = Vec3( 6.6235629e+02, -8.4502811e+02, -5.3670716e+02); + expectedForces[106] = Vec3( 3.8449086e+02, 8.0775263e+02, 5.2003911e+02); + expectedForces[107] = Vec3(-3.4338589e+02, 1.7870086e+02, -6.1047615e+01); + expectedForces[108] = Vec3( 4.3523975e+02, 2.8776092e+02, -1.5333067e+03); + expectedForces[109] = Vec3( 1.9214022e+01, -9.9449061e+01, 3.9153169e+02); + expectedForces[110] = Vec3(-7.7525496e+02, 7.7309387e+01, 7.8886699e+02); + expectedForces[111] = Vec3(-1.1510224e+03, -2.8207337e+02, 1.4866455e+03); + expectedForces[112] = Vec3( 1.1281316e+03, -3.0961130e+02, -1.3894255e+02); + expectedForces[113] = Vec3(-2.4829062e+02, 5.9466066e+02, -9.0749265e+02); + expectedForces[114] = Vec3(-1.6228531e+02, -4.1281378e+02, -1.4860946e+03); + expectedForces[115] = Vec3(-2.9071192e+02, 7.5335271e+02, 6.5205720e+02); + expectedForces[116] = Vec3( 3.2042337e+02, -4.0237231e+02, 1.0068554e+03); + expectedForces[117] = Vec3(-1.4081272e+03, -5.5227579e+02, 2.8376428e+02); + expectedForces[118] = Vec3( 9.6978276e+02, -9.6232683e+02, 2.3399918e+02); + expectedForces[119] = Vec3( 2.0781312e+02, 9.0531947e+01, 8.3513783e+01); + expectedForces[120] = Vec3( 2.9200105e+02, 1.0746865e+03, -6.0773727e+02); + expectedForces[121] = Vec3(-8.7546167e+02, 3.1969683e+02, 8.1033199e+01); + expectedForces[122] = Vec3(-5.3422658e+01, -3.8456585e+02, 1.4595003e+02); + expectedForces[123] = Vec3(-9.5134908e+01, 8.6818098e+02, -1.3111403e+03); + expectedForces[124] = Vec3(-7.2576830e+02, 6.3811172e+01, 7.0993488e+02); + expectedForces[125] = Vec3( 5.6200572e+02, -1.0972338e+03, -3.5278717e+02); + expectedForces[126] = Vec3(-1.6903718e+02, 2.6804112e+02, -8.9811032e+02); + expectedForces[127] = Vec3( 7.0934165e+02, -3.2328700e+02, 1.0037562e+02); + expectedForces[128] = Vec3(-2.5937738e+00, -3.3758145e+02, 3.6354335e+02); + expectedForces[129] = Vec3(-1.1993601e+03, 1.1618922e+02, -1.1329865e+03); + expectedForces[130] = Vec3( 8.3480845e+02, 5.2646427e+02, 9.1816763e+01); + expectedForces[131] = Vec3( 1.9407174e+02, 7.3877492e+00, 8.8648162e+02); + expectedForces[132] = Vec3(-1.0820540e+03, 2.7482390e+02, -1.4876848e+03); + expectedForces[133] = Vec3( 9.5717027e+02, -4.7758356e+02, 4.0692835e+02); + expectedForces[134] = Vec3( 2.4979896e+02, 7.1530552e+02, 6.5834243e+02); + expectedForces[135] = Vec3(-2.7549874e+02, 1.6613806e+03, -5.0628865e+02); + expectedForces[136] = Vec3(-1.5960544e+02, -4.5920421e+02, 9.4068762e+02); + expectedForces[137] = Vec3( 6.9764295e+01, -4.4024430e+02, -2.3545402e+02); + expectedForces[138] = Vec3( 2.0207569e+03, -2.6846158e+02, 3.3977998e+02); + expectedForces[139] = Vec3(-9.9905342e+02, 9.5155462e+02, 8.3259854e+01); + expectedForces[140] = Vec3(-8.0836255e+02, -6.3005196e+02, 1.2603525e+02); + expectedForces[141] = Vec3( 5.2279913e+02, 1.5356061e+03, -1.4399009e+02); + expectedForces[142] = Vec3(-1.3088783e+02, -9.0861449e+02, 9.7040422e+02); + expectedForces[143] = Vec3( 2.8006682e+01, -1.1783245e+03, -3.7285390e+02); + expectedForces[144] = Vec3( 6.1040927e+01, 2.1747286e+01, 9.0366011e+02); + expectedForces[145] = Vec3( 7.0396235e+02, -2.3865001e+02, -6.8794682e+02); + expectedForces[146] = Vec3(-5.1132933e+02, 7.7102556e+02, -4.7805042e+02); + expectedForces[147] = Vec3( 6.2879945e+02, -6.9758821e+02, 1.0983043e+03); + expectedForces[148] = Vec3(-9.2449123e+02, 5.0248042e+02, -2.0065211e+02); + expectedForces[149] = Vec3(-3.9485154e+02, 3.4679511e+02, -7.3889603e+02); + expectedForces[150] = Vec3( 4.9834751e+02, -1.0117501e+03, 1.2510946e+03); + expectedForces[151] = Vec3(-1.4942699e+02, -7.4362790e+01, -6.8008427e+02); + expectedForces[152] = Vec3(-1.8353666e+02, 5.1697483e+02, -8.4397292e+01); + expectedForces[153] = Vec3( 7.0253008e+02, -1.5361338e+02, 8.6830836e+02); + expectedForces[154] = Vec3(-4.1108898e+02, -6.8181350e+02, -5.6516951e+02); + expectedForces[155] = Vec3( 3.9294374e+02, 3.7294948e+02, -4.9795080e+02); + expectedForces[156] = Vec3(-7.3716758e+02, -5.5465931e+02, -9.3434525e+02); + expectedForces[157] = Vec3( 1.8240105e+02, 1.5494359e+02, 1.3626243e+02); + expectedForces[158] = Vec3( 9.3172059e+02, 1.4431275e+02, 6.6916065e+02); + expectedForces[159] = Vec3( 7.3399513e+01, -3.6000187e+02, 1.9853052e+03); + expectedForces[160] = Vec3(-2.4842520e+02, -4.0819514e+02, -8.0624794e+02); + expectedForces[161] = Vec3( 4.3585911e+02, -2.6521764e+02, -6.7985842e+02); + expectedForces[162] = Vec3(-8.2255783e+02, 1.1430906e+03, 1.2991183e+03); + expectedForces[163] = Vec3( 5.6437196e+02, -1.5391213e+02, -5.0013503e+02); + expectedForces[164] = Vec3( 3.8485296e+02, -1.1754088e+02, -1.4315511e+03); + expectedForces[165] = Vec3( 9.8205241e+02, 1.3278205e+01, 3.0367584e+02); + expectedForces[166] = Vec3(-3.2909916e+02, 4.5169387e+01, -3.2019488e+02); + expectedForces[167] = Vec3(-4.2382795e+02, -8.1938351e+02, -1.5360675e+02); + expectedForces[168] = Vec3( 9.1689997e+02, 1.4443113e+03, -1.8886795e+02); + expectedForces[169] = Vec3(-1.2161000e+03, -2.3826187e+02, 3.4004889e+02); + expectedForces[170] = Vec3(-2.2837927e+02, -9.8334152e+02, 3.0313790e+02); + expectedForces[171] = Vec3( 5.2598040e+02, -1.2766936e+03, 8.1247934e+01); + expectedForces[172] = Vec3(-6.7839687e+01, 6.9220160e+02, 3.1975320e+02); + expectedForces[173] = Vec3(-4.8519844e+02, 4.3008979e+02, -7.6788762e+02); + expectedForces[174] = Vec3( 3.9550092e+01, 1.0900122e+03, 5.0955281e+02); + expectedForces[175] = Vec3(-6.3000735e+02, -7.2335263e+02, -2.2590661e+02); + expectedForces[176] = Vec3( 1.5048762e+02, -4.0086126e+02, -1.2159849e+02); + expectedForces[177] = Vec3(-7.1939527e+02, -1.0640815e+03, -3.1826393e+02); + expectedForces[178] = Vec3( 7.7492135e+02, 1.0620129e+02, 3.6733165e+02); + expectedForces[179] = Vec3(-3.5466457e+02, 7.0081887e+02, 2.2629152e+02); + expectedForces[180] = Vec3( 3.0338275e+02, -1.1243396e+02, -1.3408996e+03); + expectedForces[181] = Vec3( 9.0394088e+00, 4.8818819e+02, 7.3781403e+02); + expectedForces[182] = Vec3(-5.6111982e+01, -2.5224925e+02, 3.0344460e+02); + expectedForces[183] = Vec3(-7.4693225e+02, 1.1370727e+03, 9.3958175e+02); + expectedForces[184] = Vec3( 3.1310327e+02, -1.2133761e+03, 2.6768166e+02); + expectedForces[185] = Vec3( 6.0706899e+02, 9.8403362e+01, -5.0781782e+02); + expectedForces[186] = Vec3(-6.2721609e+02, 1.7751567e+02, 2.6230643e+02); + expectedForces[187] = Vec3( 3.5425475e+02, -3.3336896e+02, 2.9529930e+02); + expectedForces[188] = Vec3( 4.7499029e+02, 4.5552354e+02, -2.4939310e+02); + expectedForces[189] = Vec3( 1.1556321e+02, 2.5995186e+02, -8.4171376e+02); + expectedForces[190] = Vec3(-4.5095184e+02, -1.6639362e+01, 4.2956175e+02); + expectedForces[191] = Vec3(-7.5904218e+01, 3.9416063e+02, 4.2573815e+02); + expectedForces[192] = Vec3( 2.3041013e+02, -1.2883920e+03, -5.1943189e+02); + expectedForces[193] = Vec3( 8.6086944e+01, 1.8626094e+02, 3.7641641e+02); + expectedForces[194] = Vec3(-5.9266805e+02, 4.4766229e+02, -4.5835497e+02); + expectedForces[195] = Vec3( 3.9368476e+02, 1.1050329e+03, -1.3906133e+03); + expectedForces[196] = Vec3(-1.2912212e+03, -2.9660534e+02, 3.9659215e+02); + expectedForces[197] = Vec3(-2.4803663e+01, -2.7945607e+02, 3.5315630e+02); + expectedForces[198] = Vec3( 1.4147479e+02, 3.2766723e+02, 1.1137899e+03); + expectedForces[199] = Vec3( 7.8383167e+01, 2.2385715e+00, -1.0346820e+03); + expectedForces[200] = Vec3(-2.9231551e+02, -5.4648720e+02, -6.5500265e+02); + expectedForces[201] = Vec3( 1.3708284e+03, -1.0716376e+03, 4.5781190e+02); + expectedForces[202] = Vec3(-7.5533654e+02, 6.5396686e+02, -4.2683276e+02); + expectedForces[203] = Vec3(-6.5558825e+02, 3.1164131e+02, 2.6323555e+02); + expectedForces[204] = Vec3( 1.3173432e+03, 1.3775889e+03, 1.2933072e+02); + expectedForces[205] = Vec3(-4.0922505e+02, -7.5709333e+02, -3.4967434e+02); + expectedForces[206] = Vec3( 4.2270572e+01, -7.4393359e+02, 5.2985443e+02); + expectedForces[207] = Vec3(-1.5327880e+03, 7.3186706e+02, -2.3440058e+02); + expectedForces[208] = Vec3( 1.4650210e+03, 2.8661572e+02, -2.4233049e+02); + expectedForces[209] = Vec3( 8.4124688e+02, -3.4020518e+02, -3.1773592e+01); + expectedForces[210] = Vec3(-1.1480436e+03, -7.4089732e+02, -4.8883682e+02); + expectedForces[211] = Vec3( 3.5682075e+02, 2.1918110e+01, -1.2558000e+02); + expectedForces[212] = Vec3( 1.6505256e+02, 7.9867933e+02, 9.9760760e+02); + expectedForces[213] = Vec3( 1.2477725e+03, -8.8687803e+02, -8.2498529e+02); + expectedForces[214] = Vec3( 1.7357042e+02, 2.0185456e+02, 8.0965301e+02); + expectedForces[215] = Vec3(-9.0937500e+02, 5.5968713e+01, 1.7581913e+02); + expectedForces[216] = Vec3( 1.3030711e+03, -8.2642443e+02, 1.6679926e+02); + expectedForces[217] = Vec3(-8.4295510e+02, 2.0237547e+01, 4.0163431e+02); + expectedForces[218] = Vec3(-3.2088719e+02, 3.0824476e+02, 9.9166532e+01); + expectedForces[219] = Vec3( 1.4585495e+03, -4.1497503e+01, -2.2539636e+02); + expectedForces[220] = Vec3(-2.6148433e+02, 1.7592075e+02, 2.0638296e+02); + expectedForces[221] = Vec3(-9.2100962e+02, 2.6090225e+02, -8.4461867e+02); + expectedForces[222] = Vec3(-9.0597287e+02, -4.8246138e+02, -1.8012972e+03); + expectedForces[223] = Vec3(-1.1775667e+02, 1.7275816e+02, 1.1286513e+03); + expectedForces[224] = Vec3( 1.0682239e+03, 8.0853797e+02, 2.5601774e+02); + expectedForces[225] = Vec3(-1.6637330e+02, 7.6165466e+02, -5.9394315e+02); + expectedForces[226] = Vec3( 2.6206832e+02, -1.5011747e+02, 5.4532792e+02); + expectedForces[227] = Vec3(-2.6474701e+02, -1.4218144e+02, 1.1099125e+02); + expectedForces[228] = Vec3(-9.7365994e+02, -5.5282012e+02, -6.3158992e+02); + expectedForces[229] = Vec3( 1.1482718e+03, 1.4958662e+02, -5.6523355e+02); + expectedForces[230] = Vec3( 4.4084982e+02, 7.9662251e+02, 4.9732039e+02); + expectedForces[231] = Vec3(-4.8746806e+02, -1.5522005e+03, 1.0133483e+03); + expectedForces[232] = Vec3( 1.1332903e+03, 1.2836176e+03, -2.0897082e+02); + expectedForces[233] = Vec3(-7.9973372e+01, 6.3066961e+02, -5.8656505e+02); + expectedForces[234] = Vec3(-8.3714021e+02, -1.5385924e+03, 1.0179672e+03); + expectedForces[235] = Vec3( 3.5358323e+02, 9.3554369e+02, 1.6565605e+02); + expectedForces[236] = Vec3( 1.7532341e+02, 3.0381323e+01, -1.2538424e+03); + expectedForces[237] = Vec3(-1.0437301e+03, -4.4804918e+02, 1.5276435e+03); + expectedForces[238] = Vec3( 8.5470872e+02, 1.0725550e+03, -9.7359443e+01); + expectedForces[239] = Vec3( 1.8192015e+02, -7.6967211e+01, -8.6054596e+02); + expectedForces[240] = Vec3( 1.5910180e+03, -7.9601605e+02, -8.4030326e+02); + expectedForces[241] = Vec3(-6.4638370e+02, 4.0538540e+02, 2.3396878e+01); + expectedForces[242] = Vec3(-5.2648918e+02, 1.3689201e+02, 9.3014716e+02); + expectedForces[243] = Vec3( 2.2248997e+02, -6.3647370e+02, -8.3913128e+02); + expectedForces[244] = Vec3(-7.5759832e+02, 4.7985429e+01, 5.8577833e+02); + expectedForces[245] = Vec3( 1.2983550e+02, 4.4401985e+02, 2.3556259e+02); + expectedForces[246] = Vec3( 7.8075637e+02, 9.9893821e+02, 7.3511307e+02); + expectedForces[247] = Vec3(-8.6411159e+02, 2.3812628e+02, 1.9007971e+02); + expectedForces[248] = Vec3( 2.0762263e+02, -7.0123789e+02, -4.8175733e+02); + expectedForces[249] = Vec3(-8.2749187e+02, -7.8772346e+02, -9.8536337e+02); + expectedForces[250] = Vec3( 8.3905893e+01, -2.8770518e+02, 6.0690561e+02); + expectedForces[251] = Vec3( 7.2280803e+02, 4.9294103e+02, -1.2915033e+02); + expectedForces[252] = Vec3(-1.3615809e+03, -1.8564754e+02, -4.2172817e+02); + expectedForces[253] = Vec3( 9.2102155e+02, 5.4063967e+02, -2.7291760e+02); + expectedForces[254] = Vec3( 7.0204283e+02, -3.0338605e+02, 6.6795953e+02); + expectedForces[255] = Vec3(-7.2261285e+00, 3.2570478e+02, 5.9010590e+02); + expectedForces[256] = Vec3(-8.3167819e+02, 3.0568475e+02, -9.9230441e+02); + expectedForces[257] = Vec3( 2.1074297e+02, -4.0099946e+01, -1.2770634e+02); + expectedForces[258] = Vec3( 1.1218559e+03, -8.8304672e+02, 1.0217945e+03); + expectedForces[259] = Vec3(-4.4730264e+01, 5.3616918e+02, -3.2704110e+02); + expectedForces[260] = Vec3(-1.1106141e+03, 3.3541536e+02, -1.0552986e+02); + expectedForces[261] = Vec3(-9.3728497e+01, 4.7397796e+01, -1.1294332e+03); + expectedForces[262] = Vec3( 5.1424956e+01, 4.0854995e+02, 5.6832607e+02); + expectedForces[263] = Vec3( 1.4286074e+02, 2.9172921e+01, 5.1355833e+02); + expectedForces[264] = Vec3(-4.4318133e+02, -9.5478293e+02, -1.8067439e+03); + expectedForces[265] = Vec3(-2.8083245e+02, 8.1414586e+02, 6.6089404e+02); + expectedForces[266] = Vec3( 1.0434876e+02, 3.0664078e+02, 1.3658532e+03); + expectedForces[267] = Vec3( 1.2999089e+03, 5.6746563e+02, 1.2200612e+03); + expectedForces[268] = Vec3(-5.9546942e+02, 3.6897149e+02, -8.3331437e+02); + expectedForces[269] = Vec3(-1.1094881e+03, -5.1903335e+02, -3.5729033e+02); + expectedForces[270] = Vec3( 4.1873464e+02, 6.9788983e+02, -1.3191929e+03); + expectedForces[271] = Vec3(-1.0086080e+02, 3.3114447e+02, 6.3419860e+02); + expectedForces[272] = Vec3(-2.8783906e+02, -8.8308011e+02, -5.4816768e+01); + expectedForces[273] = Vec3( 1.0254638e+03, 2.8710026e+02, -1.9779676e+02); + expectedForces[274] = Vec3(-3.5906548e+02, -5.5531449e+02, -6.0205492e+01); + expectedForces[275] = Vec3(-3.9578349e+02, 5.9217272e+01, 1.0735648e+02); + expectedForces[276] = Vec3(-8.7298871e+02, -1.5584711e+02, 9.2571354e+02); + expectedForces[277] = Vec3( 4.1520558e+02, 5.6442126e+02, -1.8142289e+02); + expectedForces[278] = Vec3( 6.5423421e+02, -4.1631573e+02, 1.0996479e+02); + expectedForces[279] = Vec3(-8.0063899e+01, -1.2880940e+03, 2.9304469e+02); + expectedForces[280] = Vec3(-9.5930841e+02, 5.8293485e+02, -1.1632205e+03); + expectedForces[281] = Vec3( 6.3492338e+02, 2.5550931e+02, 1.7380517e+02); + expectedForces[282] = Vec3(-1.9188175e+02, 1.0257290e+03, -8.6438702e+02); + expectedForces[283] = Vec3( 4.0063530e+01, -5.1808902e+02, 4.9556015e+02); + expectedForces[284] = Vec3( 5.8250018e+02, -2.5030700e+02, 1.1762860e+03); + expectedForces[285] = Vec3(-4.3195459e+02, 7.4733530e+02, -1.3002210e+03); + expectedForces[286] = Vec3( 2.7567334e+01, -5.1662654e+02, 3.3258050e+02); + expectedForces[287] = Vec3( 6.1700857e+02, 3.0016354e+02, 9.5519139e+02); + expectedForces[288] = Vec3( 7.7553094e+02, 8.6453551e+02, -1.0122996e+03); + expectedForces[289] = Vec3(-2.6730796e+02, -7.7560875e+02, 4.3195620e+02); + expectedForces[290] = Vec3(-8.5982146e+02, 1.6692057e+02, 4.3838169e+02); + expectedForces[291] = Vec3( 1.2945126e+03, 6.3231748e+02, -8.3020592e+02); + expectedForces[292] = Vec3(-6.9510729e+02, -3.1930013e+02, -1.3919425e+01); + expectedForces[293] = Vec3(-4.1154200e+02, -3.3562358e+02, 6.3292682e+02); + expectedForces[294] = Vec3(-4.0919783e+02, -3.8282298e+02, -4.9125465e+02); + expectedForces[295] = Vec3( 6.3932145e+02, -1.8769713e+01, 9.9241332e+01); + expectedForces[296] = Vec3( 8.6847663e+01, 8.7234739e+02, 2.7124112e+02); + expectedForces[297] = Vec3(-1.0307576e+03, -6.2447562e+02, -1.5796976e+03); + expectedForces[298] = Vec3( 6.2464595e+02, 1.0608165e+03, 3.1422521e+01); + expectedForces[299] = Vec3( 3.7767184e+02, 4.1170186e+02, 1.0696495e+03); + expectedForces[300] = Vec3( 1.0578030e+02, -1.9544726e+03, -4.6243957e+02); + expectedForces[301] = Vec3(-3.1074896e+02, 8.6738333e+02, -2.0241448e+02); + expectedForces[302] = Vec3(-2.7350519e+02, 6.9945273e+02, 7.8755130e+02); + expectedForces[303] = Vec3( 7.8083070e+02, 6.5199614e+02, -6.6698950e+02); + expectedForces[304] = Vec3( 1.3647451e+02, -4.2490411e+02, 1.3236061e+01); + expectedForces[305] = Vec3(-1.1048984e+03, 3.7582184e+02, -6.4718844e+01); + expectedForces[306] = Vec3( 1.5976050e+03, -8.9091819e+02, 9.7113419e+02); + expectedForces[307] = Vec3(-4.5545384e+01, 8.8683300e+02, -6.5927739e+01); + expectedForces[308] = Vec3(-1.3883497e+03, -4.6171498e+02, -2.9117829e+02); + expectedForces[309] = Vec3(-6.6661140e+02, -8.1394964e+02, 1.2397900e+03); + expectedForces[310] = Vec3(-2.5293546e+02, 1.8568554e+02, -6.8919479e+02); + expectedForces[311] = Vec3( 5.2052057e+02, 1.0288555e+03, 3.1435700e+02); + expectedForces[312] = Vec3(-2.4245555e+02, -1.1100993e+03, -1.6937710e+03); + expectedForces[313] = Vec3( 1.6647470e+02, 9.5272347e+02, 9.2528380e+02); + expectedForces[314] = Vec3( 8.6946518e+02, -1.6295251e+02, 5.7452409e+02); + expectedForces[315] = Vec3( 1.4059831e+02, 5.6780959e+02, -4.6024149e+02); + expectedForces[316] = Vec3( 2.3327811e+02, -2.2376697e+02, 1.3399582e+01); + expectedForces[317] = Vec3(-2.6583612e+01, -4.5801841e+02, 2.9595361e+01); + expectedForces[318] = Vec3( 1.2361796e+03, -1.9473934e+02, -2.6179421e+02); + expectedForces[319] = Vec3(-4.2330105e+02, 5.0768290e+02, 6.8352494e+02); + expectedForces[320] = Vec3(-2.0826312e+02, 1.4720747e+02, -9.8828425e-01); + expectedForces[321] = Vec3(-7.3226106e+02, -1.5366771e+01, 2.7882968e+02); + expectedForces[322] = Vec3( 4.2634684e+02, -6.2926647e+02, 3.6300784e+02); + expectedForces[323] = Vec3( 1.7826269e+02, 1.0038378e+02, -4.2408556e+02); + expectedForces[324] = Vec3(-1.1690005e+03, 2.1777241e+02, 9.1980300e+02); + expectedForces[325] = Vec3( 5.6841370e+02, -2.6614377e+02, -6.4968364e+01); + expectedForces[326] = Vec3( 3.5710749e+02, 1.3228373e+02, -3.6567433e+02); + expectedForces[327] = Vec3( 8.1957745e+02, 7.3903486e+02, 3.9487193e+02); + expectedForces[328] = Vec3(-8.5354740e+02, 8.9297958e+01, 9.0615539e+01); + expectedForces[329] = Vec3(-2.3935807e+02, -2.2950021e+02, -4.6193868e+01); + expectedForces[330] = Vec3( 8.6120406e+01, 1.4046499e+03, -1.5899345e+02); + expectedForces[331] = Vec3( 4.6319634e+02, -4.6309406e+02, -2.2891416e+02); + expectedForces[332] = Vec3(-4.2592255e+02, -2.6503000e+02, 6.1788141e+02); + expectedForces[333] = Vec3(-2.4468457e+02, -7.7827760e+02, 4.2470013e+02); + expectedForces[334] = Vec3( 2.6006448e+02, 7.6289112e+01, -4.3430411e+02); + expectedForces[335] = Vec3(-2.5268926e+02, 7.7381529e+02, -5.0896414e+02); + expectedForces[336] = Vec3( 1.0414844e+03, -6.1885512e+02, 1.4495539e+03); + expectedForces[337] = Vec3(-5.9522011e+01, 1.3607073e+03, -7.3705640e+01); + expectedForces[338] = Vec3(-5.9857094e+02, -2.7213045e+02, -9.7516268e+02); + expectedForces[339] = Vec3( 9.2852178e+02, 3.0121600e+02, -7.4982031e+00); + expectedForces[340] = Vec3(-1.0201472e+03, 1.6269359e+02, 1.9280960e+02); + expectedForces[341] = Vec3(-1.8744984e+02, -4.9790658e+02, 4.2841303e+02); + expectedForces[342] = Vec3(-1.0893114e+03, -4.6044565e+02, -2.0537532e+02); + expectedForces[343] = Vec3( 5.1068148e+02, -3.0889884e+02, 1.7703226e+01); + expectedForces[344] = Vec3( 2.0128423e+02, 5.0813056e+02, -5.0941772e+01); + expectedForces[345] = Vec3(-6.0195519e+02, 1.1710803e+03, -5.8271481e+02); + expectedForces[346] = Vec3( 1.3898239e+02, -3.2598252e+02, 1.0877023e+03); + expectedForces[347] = Vec3( 3.1630812e+02, -8.9974673e+02, 9.6573268e+01); + expectedForces[348] = Vec3(-5.5334313e+01, -1.1529065e+03, -2.1949997e+02); + expectedForces[349] = Vec3(-4.4904784e+02, 2.4036076e+02, 4.1328142e+02); + expectedForces[350] = Vec3( 1.0611611e+03, 4.1620143e+02, 9.1677657e+01); + expectedForces[351] = Vec3( 1.3489840e+03, 9.9500659e+02, -4.5894902e+01); + expectedForces[352] = Vec3(-9.8051252e+01, -9.0794586e+02, -8.9918421e+02); + expectedForces[353] = Vec3(-3.5567408e+02, -7.2914902e+01, 4.7977644e+01); + expectedForces[354] = Vec3(-1.5976501e+03, -1.2202674e+03, 7.2159213e+02); + expectedForces[355] = Vec3( 1.7391266e+02, 1.0197773e+03, -9.1284547e+02); + expectedForces[356] = Vec3( 7.8937287e+02, 1.1964969e+02, -3.8520683e+02); + expectedForces[357] = Vec3( 2.8170878e+02, 1.0377979e+03, -5.0609230e+02); + expectedForces[358] = Vec3(-4.0852118e+01, -4.3087314e+02, 4.1855459e+01); + expectedForces[359] = Vec3(-3.2767902e+02, -7.8083477e+02, 1.1111190e+03); + expectedForces[360] = Vec3(-1.0691030e+03, 3.1877408e+02, -7.9684323e+02); + expectedForces[361] = Vec3( 7.7603235e+02, 3.6577850e+02, -1.9093841e+02); + expectedForces[362] = Vec3(-4.7607360e+02, -5.1710653e+02, 7.2740737e+02); + expectedForces[363] = Vec3( 9.3461900e+02, 7.9988609e+01, -5.8055314e+02); + expectedForces[364] = Vec3(-9.8128918e+02, -2.6706371e+02, -3.5178135e+01); + expectedForces[365] = Vec3(-6.5196668e+02, 8.7618054e+02, 3.3040412e+02); + expectedForces[366] = Vec3( 5.5458970e+02, -1.1281839e+03, -8.2774754e+02); + expectedForces[367] = Vec3( 1.8491757e+02, -5.1421593e+01, 4.7068191e+02); + expectedForces[368] = Vec3(-4.3945944e+02, 8.2740025e+02, -2.1736033e+01); + expectedForces[369] = Vec3(-2.5609394e+02, -6.7141305e+02, -3.2964376e+02); + expectedForces[370] = Vec3( 1.4932730e+02, 2.2746635e+02, -3.7606156e+01); + expectedForces[371] = Vec3( 3.0873674e+02, 5.9974800e+02, 4.2207331e+02); + expectedForces[372] = Vec3(-3.8828932e+02, -2.1491002e+02, 1.5266506e+03); + expectedForces[373] = Vec3( 4.4495676e+02, 6.4708482e+02, -9.2222368e+02); + expectedForces[374] = Vec3(-4.8420767e+01, -4.3781484e+02, -5.0107314e+02); + expectedForces[375] = Vec3( 5.7593719e+02, -1.8140066e+03, -4.0189721e+02); + expectedForces[376] = Vec3(-5.1276233e+02, 6.6981030e+02, 3.9050744e+02); + expectedForces[377] = Vec3( 4.0809391e+02, 1.1596412e+03, -4.1325341e+02); + expectedForces[378] = Vec3( 1.4975560e+03, 1.7852942e+02, -7.6514466e+02); + expectedForces[379] = Vec3(-2.2890988e+02, 2.6128742e+02, 3.8545036e+02); + expectedForces[380] = Vec3(-3.8899762e+02, -2.5609958e+02, 2.0655882e+02); + expectedForces[381] = Vec3(-1.9500869e+02, -1.0947633e+03, -9.1786660e+02); + expectedForces[382] = Vec3( 8.6146884e+02, 2.5767444e+02, 3.6801549e+02); + expectedForces[383] = Vec3(-2.0008562e+02, 2.1549793e+02, 2.5175877e+02); + expectedForces[384] = Vec3(-5.6491749e+02, 5.4714989e+02, 3.1934114e+02); + expectedForces[385] = Vec3( 1.7665111e+02, -4.5297277e+02, 2.2387580e+02); + expectedForces[386] = Vec3( 6.2697664e+02, 1.1271358e+02, 2.9498078e+00); + expectedForces[387] = Vec3(-2.1918090e+03, -7.8914005e+01, 1.0632280e+03); + expectedForces[388] = Vec3( 7.5750278e+02, -5.0217666e+02, -1.3057335e+02); + expectedForces[389] = Vec3( 1.0621096e+03, 1.6022661e+01, -1.1645539e+03); + expectedForces[390] = Vec3(-4.7808938e+02, -1.2425496e+03, -1.5543074e+02); + expectedForces[391] = Vec3(-3.4676860e+02, 8.5391303e+02, 3.5351618e+01); + expectedForces[392] = Vec3( 5.4017203e+02, 8.6467815e+01, 1.1898140e+02); + expectedForces[393] = Vec3(-1.8873828e+01, 2.2133074e+02, -1.3378739e+03); + expectedForces[394] = Vec3( 7.5888012e+01, -1.6517743e+01, 1.1817186e+02); + expectedForces[395] = Vec3( 1.1912944e+02, -1.6083226e+02, 7.8733940e+02); + expectedForces[396] = Vec3(-1.2400005e+03, -3.9434827e+02, 1.4071802e+02); + expectedForces[397] = Vec3( 9.6249284e+02, 1.1394516e+02, -3.4977717e+02); + expectedForces[398] = Vec3( 2.4187486e+02, 1.3373651e+02, 6.5894105e+01); + expectedForces[399] = Vec3( 8.8628445e+02, 7.8083892e+01, -1.0288922e+03); + expectedForces[400] = Vec3(-9.4613057e+02, -1.9076053e+02, 6.7506442e+02); + expectedForces[401] = Vec3(-6.2746897e+02, 2.9376858e+02, 9.2767458e+02); + expectedForces[402] = Vec3( 5.5409175e+01, -1.2583442e+03, 7.1728490e+02); + expectedForces[403] = Vec3(-2.9076856e+02, 7.5539656e+02, 7.0121763e+00); + expectedForces[404] = Vec3( 2.6220897e+02, -9.5606102e+01, -7.7725998e+02); + expectedForces[405] = Vec3(-8.6582014e+02, 9.5597761e+02, 1.5941783e+02); + expectedForces[406] = Vec3(-1.6910265e+02, -7.2646192e+02, -3.5476587e+02); + expectedForces[407] = Vec3( 9.7629076e+02, -8.3969437e+01, 2.5523637e+02); + expectedForces[408] = Vec3(-4.9553396e+01, 6.3557270e+02, -7.5908312e+02); + expectedForces[409] = Vec3( 3.3210227e+01, 1.5198340e+02, 7.0322192e+02); + expectedForces[410] = Vec3(-2.6532687e+01, -4.1589199e+02, 4.2771258e+02); + expectedForces[411] = Vec3( 1.1412630e+03, -2.7366656e+02, 9.8419548e+02); + expectedForces[412] = Vec3(-3.7239786e+02, 7.2244667e+01, -9.9502150e+02); + expectedForces[413] = Vec3(-4.6476941e+02, -6.1433607e+01, -2.5459288e+02); + expectedForces[414] = Vec3( 9.7028883e+02, 5.5981848e+02, 8.4425262e+02); + expectedForces[415] = Vec3( 7.2811577e+01, 2.2872709e+02, -1.3822700e+03); + expectedForces[416] = Vec3(-1.0105821e+03, -2.8444698e+02, -7.2506392e+02); + expectedForces[417] = Vec3( 1.0027865e+03, 6.0924816e+02, -5.7818592e+01); + expectedForces[418] = Vec3(-3.4173955e+02, -1.1932310e+02, -2.9495449e+01); + expectedForces[419] = Vec3(-2.7281265e+02, -1.8869212e+02, 1.9643932e+02); + expectedForces[420] = Vec3(-7.4036328e+02, -4.8733524e+02, 1.5862094e+03); + expectedForces[421] = Vec3( 5.6387864e+02, 3.0991659e+02, -8.6746725e+02); + expectedForces[422] = Vec3( 6.2954421e-01, 4.9665567e+02, -1.0114913e+03); + expectedForces[423] = Vec3( 8.9668630e+02, -1.0121499e+03, -1.1520006e+03); + expectedForces[424] = Vec3(-2.5699741e+02, 3.3243520e+02, 7.6038873e+02); + expectedForces[425] = Vec3(-1.2755484e+03, -2.7786159e+01, 3.0900583e+02); + expectedForces[426] = Vec3(-1.2587339e+03, -8.6851333e+02, 1.6295957e+02); + expectedForces[427] = Vec3( 6.4923970e+02, 4.4600015e+02, 3.3033348e+02); + expectedForces[428] = Vec3( 5.8905637e+02, -1.1589062e+02, -1.8168184e+02); + expectedForces[429] = Vec3(-1.1223714e+03, 3.0322406e+01, 8.7272053e+02); + expectedForces[430] = Vec3( 3.0982625e+02, 3.1418220e+02, -3.9301742e+02); + expectedForces[431] = Vec3( 2.4213933e+02, -7.2382572e+02, -1.0155346e+03); + expectedForces[432] = Vec3( 1.1479692e+03, -1.6837721e+03, 1.0545407e+02); + expectedForces[433] = Vec3(-8.2496264e+02, 6.0540594e+02, 1.3979931e+02); + expectedForces[434] = Vec3(-6.8171514e+02, 4.0392791e+02, -3.4712316e+02); + expectedForces[435] = Vec3(-1.5568889e+02, -1.4652975e+03, 5.1518148e+01); + expectedForces[436] = Vec3( 5.6573856e+02, 3.5494119e+02, -3.3796345e+02); + expectedForces[437] = Vec3(-1.3938679e+02, 4.2296152e+02, -2.0539863e+02); + expectedForces[438] = Vec3( 8.9203493e+01, 2.8764597e+02, -7.3273496e+02); + expectedForces[439] = Vec3( 4.3114292e+02, 9.4778082e+01, 1.8894761e+02); + expectedForces[440] = Vec3(-2.2798193e+01, -4.5460891e+01, 9.8310963e+01); + expectedForces[441] = Vec3(-2.1793579e+02, -1.0807542e+03, -2.3470465e+01); + expectedForces[442] = Vec3( 1.3881360e+02, 3.9806903e+02, 4.1089741e+01); + expectedForces[443] = Vec3(-4.5604974e+02, 4.8515999e+02, -6.6025174e+02); + expectedForces[444] = Vec3( 3.6437700e+02, -8.1622511e+02, -9.6454258e+02); + expectedForces[445] = Vec3( 3.1998690e+02, -3.3342314e+02, 1.2441763e+03); + expectedForces[446] = Vec3( 3.0822409e+01, 2.0596612e+02, 2.0937122e+02); + expectedForces[447] = Vec3(-8.4938718e+02, -1.1366483e+03, -1.3638049e+02); + expectedForces[448] = Vec3(-5.5232451e+01, 4.7335097e+02, -5.4433565e+02); + expectedForces[449] = Vec3( 6.5928852e+02, 1.7488804e+02, 6.7879378e+02); + expectedForces[450] = Vec3(-9.4572079e+02, 1.9162420e+02, 4.7935043e+02); + expectedForces[451] = Vec3( 2.5029547e+02, 3.6606767e+01, -9.3423713e+01); + expectedForces[452] = Vec3( 1.6543841e+02, -1.1892943e+02, -5.8737050e+02); + expectedForces[453] = Vec3(-9.8495219e+02, -1.6882428e+03, -4.0576035e+02); + expectedForces[454] = Vec3( 7.9182557e+02, 5.3997699e+02, 3.3231603e+02); + expectedForces[455] = Vec3( 1.8277090e+01, 1.4623150e+03, -9.4985721e+01); + expectedForces[456] = Vec3(-1.0471948e+03, 4.6746395e+02, -1.5020000e+03); + expectedForces[457] = Vec3( 7.2055316e+02, -5.4467216e+02, 4.0459421e+02); + expectedForces[458] = Vec3( 7.5475531e+01, 4.9532870e+02, 1.3002474e+03); + expectedForces[459] = Vec3( 6.3589773e+02, -2.1402397e+02, -1.4147509e+03); + expectedForces[460] = Vec3( 2.8391861e+02, -8.0142885e+01, 5.6445225e+02); + expectedForces[461] = Vec3(-8.2442674e+02, 5.3520687e+02, 1.1406667e+03); + expectedForces[462] = Vec3(-5.7988771e+02, -3.3512887e+02, 4.5461752e+02); + expectedForces[463] = Vec3( 4.5746059e+02, 3.1029926e+02, -5.0060176e+02); + expectedForces[464] = Vec3( 7.7747136e+02, 4.2131732e+02, 5.5836239e+02); + expectedForces[465] = Vec3(-1.2315491e+03, 9.4066088e+02, 9.6145313e+02); + expectedForces[466] = Vec3( 7.9043841e+02, -2.2172613e+02, -2.6508587e+02); + expectedForces[467] = Vec3( 7.8197894e+02, -3.1383822e+02, 2.5444013e+02); + expectedForces[468] = Vec3(-7.1139498e+01, -7.1203189e+01, -4.6845544e+02); + expectedForces[469] = Vec3(-8.9774100e+01, 1.4389287e+02, 9.8957451e+01); + expectedForces[470] = Vec3( 3.0397922e+02, -2.8247850e+01, 4.4896034e+02); + expectedForces[471] = Vec3(-9.7808367e+02, 1.0170553e+03, 8.1594649e+02); + expectedForces[472] = Vec3( 1.8933676e+02, -8.8053046e+02, 6.8784042e+01); + expectedForces[473] = Vec3( 5.1636668e+02, 1.2970985e+02, -8.9380858e+02); + expectedForces[474] = Vec3(-5.8549608e+02, -1.8351156e+02, -5.8043066e+02); + expectedForces[475] = Vec3( 2.7877663e+02, -3.6576715e+02, 3.5497095e+02); + expectedForces[476] = Vec3( 3.0642370e+02, 5.3438407e+02, 1.9409584e+02); + expectedForces[477] = Vec3(-4.8523805e+02, 1.2253320e+03, 9.6414379e+02); + expectedForces[478] = Vec3(-1.5213013e+02, -2.0017205e+02, -6.6602643e+02); + expectedForces[479] = Vec3( 4.6435225e+02, -4.1945066e+02, -8.6774270e+01); + expectedForces[480] = Vec3( 2.4946889e+02, -1.0456281e+03, 4.7404434e+02); + expectedForces[481] = Vec3(-3.0813505e+01, 2.8598938e+02, 7.7374350e+01); + expectedForces[482] = Vec3(-2.4538851e+02, 3.8306987e+02, -5.0235520e+02); + expectedForces[483] = Vec3( 4.0348805e+01, 1.3050360e+03, -6.8725580e+02); + expectedForces[484] = Vec3(-1.1095514e+02, -2.7711572e+02, 2.6929959e+02); + expectedForces[485] = Vec3(-6.8071081e+01, -3.4398150e+02, 2.5209743e+02); + expectedForces[486] = Vec3( 2.1534786e+03, 1.3249493e+01, 7.4171165e+01); + expectedForces[487] = Vec3(-7.2618755e+02, -3.2914219e+02, 2.5917332e+02); + expectedForces[488] = Vec3(-1.0231949e+03, 7.2426062e+02, 1.9111862e+02); + expectedForces[489] = Vec3( 1.1408866e+03, 6.7858353e+02, -2.1410916e+02); + expectedForces[490] = Vec3(-4.5559047e+02, -1.3597950e+02, -3.2284091e+02); + expectedForces[491] = Vec3(-8.5558133e+02, -7.1748324e+01, 5.3332261e+02); + expectedForces[492] = Vec3(-7.1393886e+02, -1.1275222e+03, -6.2147584e+02); + expectedForces[493] = Vec3( 4.4029614e+02, 1.0518224e+02, 4.6519788e+02); + expectedForces[494] = Vec3(-3.5770378e+02, 1.0311834e+03, 2.2141802e+02); + expectedForces[495] = Vec3(-2.6023787e+02, 1.0070248e+03, -1.1113552e+03); + expectedForces[496] = Vec3(-3.4950242e+02, 2.8418846e+01, 1.2865161e+03); + expectedForces[497] = Vec3( 1.5030225e+02, -7.7257505e+02, 8.7232628e+02); + expectedForces[498] = Vec3(-1.7416695e+02, 9.9945569e+02, -1.6742483e+02); + expectedForces[499] = Vec3( 2.0837481e+02, -1.9388709e+02, 9.7409815e+01); + expectedForces[500] = Vec3(-1.0129845e+02, -6.8652976e+02, 8.4930186e+02); + expectedForces[501] = Vec3( 1.2276099e+03, 1.6531986e+02, 3.6342506e+02); + expectedForces[502] = Vec3(-1.9998077e+02, -2.6164759e+02, -1.6601933e+02); + expectedForces[503] = Vec3(-4.0356327e+02, 4.0549152e+02, 2.9710052e+02); + expectedForces[504] = Vec3(-7.3045150e+02, -1.6677706e+03, -9.8671765e+02); + expectedForces[505] = Vec3(-2.1441879e+02, 1.4962605e+03, 5.6350856e+02); + expectedForces[506] = Vec3( 7.1102593e+02, 5.9407971e+02, 9.5452239e+02); + expectedForces[507] = Vec3( 3.2291041e+02, 1.3943261e+03, -1.8477432e+03); + expectedForces[508] = Vec3(-1.7778104e+02, 2.8034575e+02, 1.1385089e+03); + expectedForces[509] = Vec3(-2.4943297e+02, -9.0965773e+02, 5.2737490e+02); + expectedForces[510] = Vec3(-3.8318508e+02, 1.3999092e+03, -5.9960180e+02); + expectedForces[511] = Vec3( 2.6930065e+01, -3.6603454e+02, 1.0460530e+03); + expectedForces[512] = Vec3(-1.8964668e+02, -1.1663184e+03, -2.8438291e+02); + expectedForces[513] = Vec3(-9.4679273e+02, 8.7408257e+01, -2.5740702e+02); + expectedForces[514] = Vec3( 1.6558849e+02, 3.3561310e+02, 3.8532718e+02); + expectedForces[515] = Vec3( 4.0403504e+02, -8.5545173e+02, 4.0647038e+02); + expectedForces[516] = Vec3( 8.3825526e+02, 5.0343638e+01, -3.9171626e+02); + expectedForces[517] = Vec3(-4.0069871e+02, -6.4140295e+02, 7.5218861e+01); + expectedForces[518] = Vec3(-6.5213072e+02, 4.1689581e+02, -8.9280241e+01); + expectedForces[519] = Vec3( 4.0832996e+02, -3.4272605e+02, -9.2740030e+02); + expectedForces[520] = Vec3(-2.1128040e+01, -7.3467005e+02, 6.5449252e+02); + expectedForces[521] = Vec3(-2.8042421e+02, 3.3193211e+02, 5.1272473e+02); + expectedForces[522] = Vec3(-1.2057322e+03, 3.3276609e+02, 6.8838073e+02); + expectedForces[523] = Vec3( 8.9270663e+02, 1.3914748e+02, -8.7213182e+02); + expectedForces[524] = Vec3( 8.8063936e+02, -2.4952564e+02, -8.3942753e+01); + expectedForces[525] = Vec3( 3.6527919e+02, 3.3758036e+02, -1.3449147e+03); + expectedForces[526] = Vec3( 7.1836993e+01, -3.9380031e+01, 4.7169292e+02); + expectedForces[527] = Vec3(-7.2114939e+01, -1.3679457e+02, 3.9080695e+02); + expectedForces[528] = Vec3( 1.1465645e+02, -4.4994719e+02, -3.4180224e+02); + expectedForces[529] = Vec3(-6.0950292e+01, 4.2825716e+02, -1.4233246e+02); + expectedForces[530] = Vec3(-1.9112828e+02, -2.8511065e+00, 2.6894050e+02); + expectedForces[531] = Vec3( 4.4955085e+02, 2.0459389e+02, 8.9486972e+02); + expectedForces[532] = Vec3( 6.6339624e+01, -4.2734850e+01, -4.8004048e+02); + expectedForces[533] = Vec3(-5.0521801e+02, -1.6330265e+02, -6.2374206e+02); + expectedForces[534] = Vec3(-1.1019306e+03, -4.5760347e+02, 4.6134602e+01); + expectedForces[535] = Vec3( 4.9278700e+02, 8.0495847e+02, -5.7470233e+01); + expectedForces[536] = Vec3( 9.9361557e+02, -2.4453172e+02, -3.7696369e+02); + expectedForces[537] = Vec3(-1.1168499e+03, -2.1108925e+02, -4.1233970e+02); + expectedForces[538] = Vec3( 5.6559058e+02, -2.8153614e+02, 3.0539700e+02); + expectedForces[539] = Vec3( 4.0805303e+02, 2.8796083e+02, -3.0009135e+01); + expectedForces[540] = Vec3(-8.5249075e+02, -1.0560038e+03, -6.5111795e+02); + expectedForces[541] = Vec3( 8.4653565e+02, 2.0615416e+02, -1.5085906e+02); + expectedForces[542] = Vec3(-2.8200251e+02, 6.6950966e+02, 5.9661450e+02); + expectedForces[543] = Vec3(-9.3339994e+01, 8.7084190e+02, -7.8375352e+02); + expectedForces[544] = Vec3( 1.4187243e+02, 1.2829809e+02, 8.0626841e+02); + expectedForces[545] = Vec3( 1.5403073e+02, -4.5932125e+02, -8.3051878e+00); + expectedForces[546] = Vec3( 1.3919197e+03, 5.4728737e+02, -1.0548033e+03); + expectedForces[547] = Vec3(-2.7215065e+02, 1.5112718e+02, 6.7366542e+02); + expectedForces[548] = Vec3(-7.8677637e+02, -2.6895175e+02, 4.3374996e+02); + expectedForces[549] = Vec3( 6.6014864e+02, -1.1474704e+03, -3.7199889e+02); + expectedForces[550] = Vec3(-5.8741315e+02, 2.6286109e+02, 1.9036264e+02); + expectedForces[551] = Vec3( 1.4325969e+02, 7.8928381e+02, 3.6304214e+02); + expectedForces[552] = Vec3(-9.6661866e+02, -1.0462801e+03, -6.3261994e+02); + expectedForces[553] = Vec3( 5.5171916e+02, 2.8672800e+02, 2.7240662e+02); + expectedForces[554] = Vec3( 1.1625052e+03, 7.7864110e+02, -5.2588322e+02); + expectedForces[555] = Vec3( 1.7042269e+03, -5.8973225e+02, 1.4814500e+02); + expectedForces[556] = Vec3(-7.7324022e+02, 2.9167426e+02, -1.0262563e+02); + expectedForces[557] = Vec3(-5.4655014e+02, -8.4339654e+01, 9.7375629e+02); + expectedForces[558] = Vec3(-6.9618127e+02, -1.6878530e+02, 7.1078501e+02); + expectedForces[559] = Vec3( 6.9623995e+02, -3.7038954e+01, 2.2671528e+02); + expectedForces[560] = Vec3(-7.1025694e+01, -1.8643963e+02, -8.0181026e+02); + expectedForces[561] = Vec3(-1.4598467e+02, 1.7170707e+03, -4.3305456e+02); + expectedForces[562] = Vec3( 7.9582463e+02, -5.9551245e+02, 8.3485625e+01); + expectedForces[563] = Vec3(-4.6812643e+02, -3.4598874e+02, -3.6753356e+01); + expectedForces[564] = Vec3(-1.8586268e+02, 3.1377143e+02, -1.6616022e+03); + expectedForces[565] = Vec3( 7.4400496e+02, 5.5058789e+02, 7.5374599e+02); + expectedForces[566] = Vec3(-6.3347529e+02, -3.1407006e+02, 8.2964691e+02); + expectedForces[567] = Vec3(-4.2499528e+02, 9.4575975e+02, -6.6700103e+02); + expectedForces[568] = Vec3(-9.2637696e+02, -6.6301622e+02, 3.9913705e+02); + expectedForces[569] = Vec3( 5.0588430e+02, -8.1942697e+01, 4.2128365e+02); + expectedForces[570] = Vec3( 2.7165158e+02, 2.7387902e+02, 1.0850277e+03); + expectedForces[571] = Vec3(-6.8391471e+00, -1.2886307e+02, -5.3501450e+02); + expectedForces[572] = Vec3(-2.9936240e+02, -2.2085475e+02, -6.9670281e+01); + expectedForces[573] = Vec3( 1.6853422e+02, 4.8410887e+02, 1.0517406e+03); + expectedForces[574] = Vec3(-4.9287521e+02, 1.6557733e+01, -3.4008916e+02); + expectedForces[575] = Vec3( 1.1132397e+02, -9.8734894e+02, -1.1154151e+02); + expectedForces[576] = Vec3( 3.8645582e+02, 4.3709361e+02, 1.4861132e+03); + expectedForces[577] = Vec3(-1.0169967e+03, -3.5279110e+02, -5.4860861e+02); + expectedForces[578] = Vec3( 2.8875246e+02, 5.3726711e+01, -5.9395936e+02); + expectedForces[579] = Vec3( 1.5169994e+03, 8.7535209e+01, 1.0103159e+03); + expectedForces[580] = Vec3(-1.9439968e+02, -7.9639200e+02, -1.0439069e+03); + expectedForces[581] = Vec3(-8.7374025e+02, 2.0597360e+02, 1.0218319e+02); + expectedForces[582] = Vec3( 6.4275846e+02, -6.2671529e+02, 8.9274592e+02); + expectedForces[583] = Vec3(-5.4449356e+01, 7.2615928e+02, -9.1355057e+02); + expectedForces[584] = Vec3(-2.7242606e+02, 3.9376960e+02, -4.7692581e+01); + expectedForces[585] = Vec3( 2.6578654e+02, -6.7385441e+02, -1.5306127e+03); + expectedForces[586] = Vec3( 5.1049761e+02, 7.3430855e+02, 6.1178168e+02); + expectedForces[587] = Vec3(-3.3593193e+02, 3.5079666e+01, 9.7444298e+02); + expectedForces[588] = Vec3(-7.8227654e+01, -1.1050481e+03, 1.4161574e+03); + expectedForces[589] = Vec3(-7.6753407e+02, 9.7291633e+02, 1.9943116e+02); + expectedForces[590] = Vec3( 2.9274184e+02, -2.5706985e+01, -5.8944290e+02); + expectedForces[591] = Vec3(-1.2502829e+03, 2.2304820e+02, -8.8573767e+02); + expectedForces[592] = Vec3( 1.2218682e+02, -8.2110835e+02, 3.4276058e+02); + expectedForces[593] = Vec3( 8.9529566e+02, -1.8417573e+02, 8.4717919e+02); + expectedForces[594] = Vec3(-4.6475772e+01, -1.5493620e+03, 4.8004365e+02); + expectedForces[595] = Vec3( 6.7104033e+02, 4.7267915e+02, -6.2630817e+02); + expectedForces[596] = Vec3(-2.2771561e+02, 2.7463551e+02, -2.9704610e+00); + expectedForces[597] = Vec3( 1.7757815e+02, -1.8906761e+03, -1.6656886e+02); + expectedForces[598] = Vec3(-7.4745588e+01, 1.0353962e+03, 4.2924498e+02); + expectedForces[599] = Vec3(-5.5648197e+02, 7.7838572e+02, -4.1677346e+02); + expectedForces[600] = Vec3(-5.2972489e+02, 1.1967117e+02, 1.0565388e+03); + expectedForces[601] = Vec3( 7.8379665e+02, -4.1803420e+02, 2.0308387e+02); + expectedForces[602] = Vec3( 1.2705528e+02, 1.1663435e+02, -7.6514830e+02); + expectedForces[603] = Vec3(-1.5203094e+03, -8.5825144e+01, -2.3039380e+02); + expectedForces[604] = Vec3( 5.2063739e+02, -1.7259834e+02, -2.9854160e+01); + expectedForces[605] = Vec3( 4.7448961e+02, 2.8282389e+02, 3.4257463e+01); + expectedForces[606] = Vec3( 1.4519531e+03, -1.2031444e+03, -6.7084095e+02); + expectedForces[607] = Vec3(-7.5308994e+02, -3.2117501e+02, 5.7700017e+02); + expectedForces[608] = Vec3(-1.7643179e+02, 8.5655779e+02, -2.6285482e+02); + expectedForces[609] = Vec3(-1.3868959e+03, -1.6195505e+01, -1.3783528e+03); + expectedForces[610] = Vec3( 2.8034476e+02, -4.2360778e+02, 4.5904202e+02); + expectedForces[611] = Vec3( 1.0938532e+03, 6.2455629e+02, -1.0108636e+02); + expectedForces[612] = Vec3( 9.1439974e+01, -7.2813810e+02, 1.0197075e+03); + expectedForces[613] = Vec3( 1.4048294e+02, 2.5667744e+02, -5.1914694e+02); + expectedForces[614] = Vec3(-2.5604629e+01, 2.9915218e+01, -5.1582702e+02); + expectedForces[615] = Vec3( 2.0331673e+02, 1.5538650e+02, -1.1836865e+03); + expectedForces[616] = Vec3(-2.3788957e+02, -1.1872269e+02, 9.7052698e+02); + expectedForces[617] = Vec3(-3.2419551e+01, -1.8828745e+02, 4.3037423e+02); + expectedForces[618] = Vec3(-4.8585762e+02, 1.4114027e+02, 1.6021114e+02); + expectedForces[619] = Vec3( 2.8744134e+02, -5.7197623e+02, -1.8323508e+02); + expectedForces[620] = Vec3( 2.3652930e+02, -1.5448350e+01, 2.1721186e+01); + expectedForces[621] = Vec3( 1.1684581e+03, 2.2790484e+02, 2.7798348e+02); + expectedForces[622] = Vec3(-4.6823976e+02, -6.1804544e+02, 2.7193441e+02); + expectedForces[623] = Vec3(-5.8173089e+02, 4.4573870e+02, -6.0699430e+02); + expectedForces[624] = Vec3( 7.9759250e+02, 1.8480473e+03, -5.1434277e+02); + expectedForces[625] = Vec3(-1.0945975e+03, -6.0402685e+02, 1.5843017e+02); + expectedForces[626] = Vec3( 1.2334392e+02, -9.5602838e+02, 7.8137824e+02); + expectedForces[627] = Vec3(-8.5863208e+02, -5.7413454e+02, 1.7014217e+02); + expectedForces[628] = Vec3(-1.2232569e+02, 6.0505774e+02, -1.6806693e+02); + expectedForces[629] = Vec3( 6.1488135e+02, 4.1603705e+02, 2.1121948e+02); + expectedForces[630] = Vec3( 2.1858899e+02, 1.2961013e+03, 4.8534041e+02); + expectedForces[631] = Vec3( 2.1292701e+02, -4.1049165e+02, 3.9057142e+00); + expectedForces[632] = Vec3(-6.3342469e+02, -8.7529004e+02, 6.1928550e+01); + expectedForces[633] = Vec3(-7.3207079e+02, -1.3874807e+03, 8.6303032e+02); + expectedForces[634] = Vec3( 6.6660351e+02, 9.5813895e+02, -1.4555416e+02); + expectedForces[635] = Vec3( 4.1800653e+02, 2.4677420e+02, -1.1424272e+03); + expectedForces[636] = Vec3( 8.3570430e+02, -1.5342969e+03, -1.2510269e+03); + expectedForces[637] = Vec3(-3.0635229e+02, 1.2465088e+03, -1.9679529e+01); + expectedForces[638] = Vec3(-6.5317178e+02, -1.6432929e+02, 9.2427724e+02); + expectedForces[639] = Vec3( 1.5665680e+03, 9.8040004e+01, 1.0786497e+02); + expectedForces[640] = Vec3(-4.6590380e+02, -3.7603795e+02, -9.4955273e+02); + expectedForces[641] = Vec3(-8.7572108e+02, 5.1750570e+02, -1.2268062e+02); + expectedForces[642] = Vec3( 1.1575067e+03, -2.2857204e+02, -2.3816900e+02); + expectedForces[643] = Vec3(-2.6229644e+02, 3.1069110e+02, -1.2098536e+02); + expectedForces[644] = Vec3(-1.8195659e+02, -3.8984698e+02, 6.4622752e+02); + expectedForces[645] = Vec3( 1.0756277e+03, 2.7459106e+01, 1.0850508e+03); + expectedForces[646] = Vec3(-6.4620310e+02, 2.5885783e+02, -2.0567224e+02); + expectedForces[647] = Vec3(-4.7388806e+02, -5.5561844e+02, -8.5019295e+02); double tolerance = 1.0e-03; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp index 1eaacf700..c95eeebcf 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaOutOfPlaneBendForce.cpp @@ -114,7 +114,7 @@ static void computeAmoebaOutOfPlaneBendForce(int bondIndex, std::vector& double tempVector[3]; crossProductVector3(deltaR[CB], deltaR[DB], tempVector); - double eE = dotVector3(deltaR[AB], tempVector ); + double eE = dotVector3(deltaR[AB], tempVector); double dot = dotVector3(deltaR[AD], deltaR[CD]); double cc = rAD2*rCD2 - dot*dot; @@ -277,10 +277,10 @@ void testOneOutOfPlaneBend() { AmoebaOutOfPlaneBendForce* amoebaOutOfPlaneBendForce = new AmoebaOutOfPlaneBendForce(); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic(0.5600000E-04); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic(-0.7000000E-06); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); double kOutOfPlaneBend = 0.328682196E-01; amoebaOutOfPlaneBendForce->addOutOfPlaneBend(0, 1, 2, 3, kOutOfPlaneBend); @@ -329,10 +329,10 @@ void testOneOutOfPlaneBend2(int setId) { AmoebaOutOfPlaneBendForce* amoebaOutOfPlaneBendForce = new AmoebaOutOfPlaneBendForce(); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic( 0.5600000E-04); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic( -0.7000000E-06); - amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendCubic( -0.1400000E-01); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendQuartic(0.5600000E-04); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendPentic(-0.7000000E-06); + amoebaOutOfPlaneBendForce->setAmoebaGlobalOutOfPlaneBendSextic( 0.2200000E-07); /* 285 441 442 443 444 0.328682196E-01 286 441 442 444 443 0.164493407E-01 @@ -352,15 +352,15 @@ void testOneOutOfPlaneBend2(int setId) { */ std::map coordinates; - coordinates[440] = Vec3( 0.893800000E+01, 0.439800000E+01, 0.343100000E+01); - coordinates[441] = Vec3( 0.779100000E+01, 0.614600000E+01, 0.390100000E+01); - coordinates[442] = Vec3( 0.915400000E+01, 0.683900000E+01, 0.389400000E+01); - coordinates[443] = Vec3( 0.101770000E+02, 0.619000000E+01, 0.379900000E+01); - coordinates[444] = Vec3( 0.921000000E+01, 0.813800000E+01, 0.398600000E+01); - coordinates[445] = Vec3( 0.708500000E+01, 0.672900000E+01, 0.332700000E+01); - coordinates[446] = Vec3( 0.744300000E+01, 0.605200000E+01, 0.491900000E+01); - coordinates[447] = Vec3( 0.100820000E+02, 0.859300000E+01, 0.398200000E+01); - coordinates[448] = Vec3( 0.838000000E+01, 0.866100000E+01, 0.406000000E+01); + coordinates[440] = Vec3(0.893800000E+01, 0.439800000E+01, 0.343100000E+01); + coordinates[441] = Vec3(0.779100000E+01, 0.614600000E+01, 0.390100000E+01); + coordinates[442] = Vec3(0.915400000E+01, 0.683900000E+01, 0.389400000E+01); + coordinates[443] = Vec3(0.101770000E+02, 0.619000000E+01, 0.379900000E+01); + coordinates[444] = Vec3(0.921000000E+01, 0.813800000E+01, 0.398600000E+01); + coordinates[445] = Vec3(0.708500000E+01, 0.672900000E+01, 0.332700000E+01); + coordinates[446] = Vec3(0.744300000E+01, 0.605200000E+01, 0.491900000E+01); + coordinates[447] = Vec3(0.100820000E+02, 0.859300000E+01, 0.398200000E+01); + coordinates[448] = Vec3(0.838000000E+01, 0.866100000E+01, 0.406000000E+01); double kOutOfPlaneBend = 0.328682196E-01; std::vector particleIndices; @@ -435,15 +435,15 @@ void testOneOutOfPlaneBend2(int setId) { static double totalEnergy; if (iter == 0) { - totalForces[441] = Vec3( 0.0, 0.0, 0.0); - totalForces[442] = Vec3( 0.0, 0.0, 0.0); - totalForces[443] = Vec3( 0.0, 0.0, 0.0); - totalForces[444] = Vec3( 0.0, 0.0, 0.0); - totalForces[445] = Vec3( 0.0, 0.0, 0.0); - totalForces[446] = Vec3( 0.0, 0.0, 0.0); - totalForces[447] = Vec3( 0.0, 0.0, 0.0); - totalForces[448] = Vec3( 0.0, 0.0, 0.0); - totalForces[449] = Vec3( 0.0, 0.0, 0.0); + totalForces[441] = Vec3(0.0, 0.0, 0.0); + totalForces[442] = Vec3(0.0, 0.0, 0.0); + totalForces[443] = Vec3(0.0, 0.0, 0.0); + totalForces[444] = Vec3(0.0, 0.0, 0.0); + totalForces[445] = Vec3(0.0, 0.0, 0.0); + totalForces[446] = Vec3(0.0, 0.0, 0.0); + totalForces[447] = Vec3(0.0, 0.0, 0.0); + totalForces[448] = Vec3(0.0, 0.0, 0.0); + totalForces[449] = Vec3(0.0, 0.0, 0.0); totalEnergy = 0.0; } iter++; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp index a8ea989b4..282e73a0f 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaPiTorsionForce.cpp @@ -108,8 +108,8 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit deltaR[P][ii] += positions[particle3][ii]; deltaR[Q][ii] += positions[particle4][ii]; } - crossProductVector3(deltaR[CP], deltaR[DC], deltaR[T] ); - crossProductVector3(deltaR[DC], deltaR[QD], deltaR[U] ); + crossProductVector3(deltaR[CP], deltaR[DC], deltaR[T]); + crossProductVector3(deltaR[DC], deltaR[QD], deltaR[U]); crossProductVector3(deltaR[T], deltaR[U], deltaR[TU]); double rT2 = dotVector3(deltaR[T], deltaR[T]); @@ -144,27 +144,27 @@ static void computeAmoebaPiTorsionForce(int bondIndex, std::vector& posit double factorT = dedphi/(rDC*rT2); double factorU = -dedphi/(rDC*rU2); - crossProductVector3(deltaR[T], deltaR[DC], deltaR[dT] ); - crossProductVector3(deltaR[U], deltaR[DC], deltaR[dU] ); + crossProductVector3(deltaR[T], deltaR[DC], deltaR[dT]); + crossProductVector3(deltaR[U], deltaR[DC], deltaR[dU]); for (int ii = 0; ii < 3; ii++) { deltaR[dT][ii] *= factorT; deltaR[dU][ii] *= factorU; } - crossProductVector3(deltaR[dT], deltaR[DC], deltaR[dP] ); - crossProductVector3(deltaR[dU], deltaR[DC], deltaR[dQ] ); + crossProductVector3(deltaR[dT], deltaR[DC], deltaR[dP] ); + crossProductVector3(deltaR[dU], deltaR[DC], deltaR[dQ] ); - crossProductVector3(deltaR[DP], deltaR[dT], deltaR[dC1] ); - crossProductVector3(deltaR[dU], deltaR[QD], deltaR[dC2] ); + crossProductVector3(deltaR[DP], deltaR[dT], deltaR[dC1]); + crossProductVector3(deltaR[dU], deltaR[QD], deltaR[dC2]); - crossProductVector3(deltaR[dT], deltaR[CP], deltaR[dD1] ); - crossProductVector3(deltaR[QC], deltaR[dU], deltaR[dD2] ); + crossProductVector3(deltaR[dT], deltaR[CP], deltaR[dD1]); + crossProductVector3(deltaR[QC], deltaR[dU], deltaR[dD2]); - crossProductVector3(deltaR[BD], deltaR[dP], d[A] ); - crossProductVector3(deltaR[dP], deltaR[AD], d[B] ); + crossProductVector3(deltaR[BD], deltaR[dP], d[A] ); + crossProductVector3(deltaR[dP], deltaR[AD], d[B] ); - crossProductVector3(deltaR[FC], deltaR[dQ], d[E] ); - crossProductVector3(deltaR[dQ], deltaR[EC], d[F] ); + crossProductVector3(deltaR[FC], deltaR[dQ], d[E] ); + crossProductVector3(deltaR[dQ], deltaR[EC], d[F] ); for (int ii = 0; ii < 3; ii++) { d[C][ii] = deltaR[dC1][ii] + deltaR[dC2][ii] + deltaR[dP][ii] - d[E][ii] - d[F][ii]; diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp index 604b45ffe..817b8122a 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaTorsionTorsionForce.cpp @@ -2611,12 +2611,12 @@ void testTorsionTorsion(int systemId, bool includeDerivs) { positions[4] = Vec3(-0.760612300E+01, -0.992590200E+01, -0.275088400E+01); positions[5] = Vec3(-0.516893900E+01, -0.788347000E+01, -0.316943000E+01); - expectedForces[0] = Vec3( 0.906091624E+00, -0.529814945E-01, 0.690384140E+00); + expectedForces[0] = Vec3(0.906091624E+00, -0.529814945E-01, 0.690384140E+00); expectedForces[1] = Vec3(-0.124550232E+01, -0.999341692E+00, -0.590867130E+00); - expectedForces[2] = Vec3( 0.534419689E+00, 0.612404926E-01, 0.547380310E-01); + expectedForces[2] = Vec3(0.534419689E+00, 0.612404926E-01, 0.547380310E-01); expectedForces[3] = Vec3(-5.732010432E-01, 2.645718463E+00, -1.585204274E-01); - expectedForces[4] = Vec3( 3.781920539E-01, -1.654635768E+00, 4.265386268E-03); - expectedForces[5] = Vec3( 0.0, 0.0, 0.0); + expectedForces[4] = Vec3(3.781920539E-01, -1.654635768E+00, 4.265386268E-03); + expectedForces[5] = Vec3(0.0, 0.0, 0.0); expectedEnergy = -2.699654759E+00; @@ -2632,14 +2632,14 @@ void testTorsionTorsion(int systemId, bool includeDerivs) { positions[2] = Vec3(-0.128314660E+02, -0.876338000E+00, 0.942959800E+01); positions[3] = Vec3(-0.130879850E+02, -0.760280000E-01, 0.814732200E+01); positions[4] = Vec3(-0.120888080E+02, 0.112050000E-01, 0.722704500E+01); - positions[5] = Vec3( 0.0, 0.0, 0.0); + positions[5] = Vec3(0.0, 0.0, 0.0); - expectedForces[0] = Vec3( 4.165851130E-01, 6.608242922E-01, -8.082168261E-01); + expectedForces[0] = Vec3(4.165851130E-01, 6.608242922E-01, -8.082168261E-01); expectedForces[1] = Vec3(-6.024659721E-01, -8.878744406E-01, 1.322274444E+00); - expectedForces[2] = Vec3( 3.196925118E-02, -3.137497848E-01, -8.207984001E-01); - expectedForces[3] = Vec3( 3.842205941E-02, 2.602732089E-01, 1.547586195E-01); - expectedForces[4] = Vec3( 1.154895485E-01, 2.805267242E-01, 1.519821623E-01); - expectedForces[5] = Vec3( 0.0, 0.0, 0.0); + expectedForces[2] = Vec3(3.196925118E-02, -3.137497848E-01, -8.207984001E-01); + expectedForces[3] = Vec3(3.842205941E-02, 2.602732089E-01, 1.547586195E-01); + expectedForces[4] = Vec3(1.154895485E-01, 2.805267242E-01, 1.519821623E-01); + expectedForces[5] = Vec3(0.0, 0.0, 0.0); expectedEnergy = -3.372536909E+00; } diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp index 73bfa84b5..f7cbc9870 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceAmoebaVdwForce.cpp @@ -111,9 +111,9 @@ void testVdw() { positions[0] = Vec3(-0.254893450E+02, -0.876646600E+01, 0.174761600E+01); positions[1] = Vec3(-0.263489690E+02, -0.907798000E+01, 0.205385100E+01); positions[2] = Vec3(-0.252491680E+02, -0.949411200E+01, 0.115017600E+01); - positions[3] = Vec3( 0.172827200E+01, 0.195873090E+02, 0.100059800E+01); - positions[4] = Vec3( 0.129370700E+01, 0.190112810E+02, 0.169576300E+01); - positions[5] = Vec3( 0.256122300E+01, 0.191601930E+02, 0.854382000E+00); + positions[3] = Vec3(0.172827200E+01, 0.195873090E+02, 0.100059800E+01); + positions[4] = Vec3(0.129370700E+01, 0.190112810E+02, 0.169576300E+01); + positions[5] = Vec3(0.256122300E+01, 0.191601930E+02, 0.854382000E+00); double offset = 27.0; for (int ii = 0; ii < 3; ii++) { @@ -121,12 +121,12 @@ void testVdw() { positions[ii][1] += offset; } - expectedForces[0] = Vec3( -0.729561040E+03, 0.425828484E+04, -0.769114213E+03); - expectedForces[1] = Vec3( 0.181000041E+02, 0.328216639E+02, -0.126210511E+02); - expectedForces[2] = Vec3( -0.943743014E+00, 0.199728310E+02, 0.884567842E+00); - expectedForces[3] = Vec3( 0.615734500E+01, -0.747350431E+03, 0.264726489E+03); - expectedForces[4] = Vec3( 0.735772031E+03, -0.353310112E+04, 0.490066356E+03); - expectedForces[5] = Vec3( -0.295245970E+02, -0.306277797E+02, 0.260578506E+02); + expectedForces[0] = Vec3(-0.729561040E+03, 0.425828484E+04, -0.769114213E+03); + expectedForces[1] = Vec3( 0.181000041E+02, 0.328216639E+02, -0.126210511E+02); + expectedForces[2] = Vec3(-0.943743014E+00, 0.199728310E+02, 0.884567842E+00); + expectedForces[3] = Vec3( 0.615734500E+01, -0.747350431E+03, 0.264726489E+03); + expectedForces[4] = Vec3( 0.735772031E+03, -0.353310112E+04, 0.490066356E+03); + expectedForces[5] = Vec3(-0.295245970E+02, -0.306277797E+02, 0.260578506E+02); expectedEnergy = 0.740688488E+03; @@ -224,28 +224,28 @@ void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, co // addParticle: ivIndex, radius, epsilon, reductionFactor - system.addParticle( 1.4007000e+01); + system.addParticle( 1.4007000e+01); amoebaVdwForce->addParticle(0, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(0, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.4007000e+01); + system.addParticle( 1.4007000e+01); amoebaVdwForce->addParticle(4, 1.8550000e-01, 4.3932000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(4, 1.3500000e-01, 8.3680000e-02, 9.1000000e-01); // ParticleExclusions @@ -311,14 +311,14 @@ void setupAndGetForcesEnergyVdwAmmonia(const std::string& sigmaCombiningRule, co std::vector positions(numberOfParticles); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3(-1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3(-2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3(-6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3(-2.0426290e-01, -8.1231400e-02, 4.1033500e-02); system.addForce(amoebaVdwForce); @@ -366,14 +366,14 @@ void testVdwAmmoniaCubicMeanHhg() { double expectedEnergy = 4.8012258e+00; - expectedForces[0] = Vec3( 2.9265247e+02, -1.4507808e-02, -6.9562123e+00); - expectedForces[1] = Vec3( -2.2451693e+00, 4.8143073e-01, -2.0041494e-01); - expectedForces[2] = Vec3( -2.2440698e+00, -4.7905450e-01, -2.0125284e-01); - expectedForces[3] = Vec3( -1.0840394e+00, -5.8531253e-04, 2.6934135e-01); - expectedForces[4] = Vec3( -5.6305662e+01, 1.4733908e-03, -1.8083306e-01); - expectedForces[5] = Vec3( 1.6750145e+00, -3.2448374e-01, -1.8030914e-01); - expectedForces[6] = Vec3( -2.3412420e+02, 1.0754069e-02, 7.6287492e+00); - expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01); + expectedForces[0] = Vec3( 2.9265247e+02, -1.4507808e-02, -6.9562123e+00); + expectedForces[1] = Vec3(-2.2451693e+00, 4.8143073e-01, -2.0041494e-01); + expectedForces[2] = Vec3(-2.2440698e+00, -4.7905450e-01, -2.0125284e-01); + expectedForces[3] = Vec3(-1.0840394e+00, -5.8531253e-04, 2.6934135e-01); + expectedForces[4] = Vec3(-5.6305662e+01, 1.4733908e-03, -1.8083306e-01); + expectedForces[5] = Vec3( 1.6750145e+00, -3.2448374e-01, -1.8030914e-01); + expectedForces[6] = Vec3(-2.3412420e+02, 1.0754069e-02, 7.6287492e+00); + expectedForces[7] = Vec3( 1.6756544e+00, 3.2497316e-01, -1.7906832e-01); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -396,14 +396,14 @@ void testVdwAmmoniaArithmeticArithmetic() { double expectedEnergy = 4.2252403e+00; - expectedForces[0] = Vec3( 3.0603839e+02, -1.5550310e-02, -7.2661707e+00); - expectedForces[1] = Vec3( -2.7801357e+00, 5.8805051e-01, -2.5907269e-01); - expectedForces[2] = Vec3( -2.7753968e+00, -5.8440732e-01, -2.5969111e-01); - expectedForces[3] = Vec3( -2.2496416e+00, -1.1797440e-03, 5.5501757e-01); - expectedForces[4] = Vec3( -5.5077629e+01, 8.3417114e-04, -3.3668921e-01); - expectedForces[5] = Vec3( 2.3752452e+00, -4.6788669e-01, -2.4907764e-01); - expectedForces[6] = Vec3( -2.4790697e+02, 1.1419770e-02, 8.0629999e+00); - expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01); + expectedForces[0] = Vec3( 3.0603839e+02, -1.5550310e-02, -7.2661707e+00); + expectedForces[1] = Vec3(-2.7801357e+00, 5.8805051e-01, -2.5907269e-01); + expectedForces[2] = Vec3(-2.7753968e+00, -5.8440732e-01, -2.5969111e-01); + expectedForces[3] = Vec3(-2.2496416e+00, -1.1797440e-03, 5.5501757e-01); + expectedForces[4] = Vec3(-5.5077629e+01, 8.3417114e-04, -3.3668921e-01); + expectedForces[5] = Vec3( 2.3752452e+00, -4.6788669e-01, -2.4907764e-01); + expectedForces[6] = Vec3(-2.4790697e+02, 1.1419770e-02, 8.0629999e+00); + expectedForces[7] = Vec3( 2.3761408e+00, 4.6871961e-01, -2.4731607e-01); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -425,14 +425,14 @@ void testVdwAmmoniaGeometricGeometric() { double expectedEnergy = 2.5249914e+00; - expectedForces[0] = Vec3( 2.1169631e+02, -1.0710925e-02, -4.3728025e+00); - expectedForces[1] = Vec3( -2.2585621e+00, 4.8409995e-01, -2.0188344e-01); - expectedForces[2] = Vec3( -2.2551351e+00, -4.8124855e-01, -2.0246986e-01); - expectedForces[3] = Vec3( -1.7178028e+00, -9.0851787e-04, 4.2466975e-01); - expectedForces[4] = Vec3( -4.8302147e+01, 9.6603376e-04, -5.7972068e-01); - expectedForces[5] = Vec3( 1.8100634e+00, -3.5214093e-01, -1.9357207e-01); - expectedForces[6] = Vec3( -1.6078365e+02, 7.2117601e-03, 5.3180261e+00); - expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01); + expectedForces[0] = Vec3( 2.1169631e+02, -1.0710925e-02, -4.3728025e+00); + expectedForces[1] = Vec3(-2.2585621e+00, 4.8409995e-01, -2.0188344e-01); + expectedForces[2] = Vec3(-2.2551351e+00, -4.8124855e-01, -2.0246986e-01); + expectedForces[3] = Vec3(-1.7178028e+00, -9.0851787e-04, 4.2466975e-01); + expectedForces[4] = Vec3(-4.8302147e+01, 9.6603376e-04, -5.7972068e-01); + expectedForces[5] = Vec3( 1.8100634e+00, -3.5214093e-01, -1.9357207e-01); + expectedForces[6] = Vec3(-1.6078365e+02, 7.2117601e-03, 5.3180261e+00); + expectedForces[7] = Vec3( 1.8109211e+00, 3.5273117e-01, -1.9224723e-01); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -452,14 +452,14 @@ void testVdwAmmoniaCubicMeanHarmonic() { double expectedEnergy = 4.1369069e+00; - expectedForces[0] = Vec3( 2.5854436e+02, -1.2779529e-02, -5.9041148e+00); - expectedForces[1] = Vec3( -2.0832419e+00, 4.4915831e-01, -1.8266000e-01); - expectedForces[2] = Vec3( -2.0823991e+00, -4.4699804e-01, -1.8347141e-01); - expectedForces[3] = Vec3( -9.5914714e-01, -5.2162026e-04, 2.3873165e-01); - expectedForces[4] = Vec3( -5.3724787e+01, 1.4838241e-03, -2.8089191e-01); - expectedForces[5] = Vec3( 1.5074325e+00, -2.9016397e-01, -1.6385118e-01); - expectedForces[6] = Vec3( -2.0271029e+02, 9.2367947e-03, 6.6389988e+00); - expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01); + expectedForces[0] = Vec3( 2.5854436e+02, -1.2779529e-02, -5.9041148e+00); + expectedForces[1] = Vec3(-2.0832419e+00, 4.4915831e-01, -1.8266000e-01); + expectedForces[2] = Vec3(-2.0823991e+00, -4.4699804e-01, -1.8347141e-01); + expectedForces[3] = Vec3(-9.5914714e-01, -5.2162026e-04, 2.3873165e-01); + expectedForces[4] = Vec3(-5.3724787e+01, 1.4838241e-03, -2.8089191e-01); + expectedForces[5] = Vec3( 1.5074325e+00, -2.9016397e-01, -1.6385118e-01); + expectedForces[6] = Vec3(-2.0271029e+02, 9.2367947e-03, 6.6389988e+00); + expectedForces[7] = Vec3( 1.5080748e+00, 2.9058422e-01, -1.6274118e-01); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -484,14 +484,14 @@ void testVdwTaper() { double expectedEnergy = 3.5478444e+00; - expectedForces[0] = Vec3( 5.6710779e+02, -2.7391004e-02, -1.7867730e+01); - expectedForces[1] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); - expectedForces[2] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); - expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); - expectedForces[4] = Vec3( -5.1039701e+01, 2.4651903e-03, 1.6080957e+00); - expectedForces[5] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); - expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01); - expectedForces[7] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[0] = Vec3( 5.6710779e+02, -2.7391004e-02, -1.7867730e+01); + expectedForces[1] = Vec3(-0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[2] = Vec3(-0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[3] = Vec3(-0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[4] = Vec3(-5.1039701e+01, 2.4651903e-03, 1.6080957e+00); + expectedForces[5] = Vec3(-0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[6] = Vec3(-5.1606809e+02, 2.4925813e-02, 1.6259634e+01); + expectedForces[7] = Vec3(-0.0000000e+00, -0.0000000e+00, -0.0000000e+00); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); @@ -514,14 +514,14 @@ void testVdwPBC() { double expectedEnergy = 1.4949141e+01; - expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01); - expectedForces[1] = Vec3( -2.5622586e+02, -4.6524265e+01, 2.4281465e+01); - expectedForces[2] = Vec3( -2.7538705e+02, 5.1831690e+01, 2.7367710e+01); - expectedForces[3] = Vec3( -0.0000000e+00, -0.0000000e+00, -0.0000000e+00); - expectedForces[4] = Vec3( 3.0883034e+02, -5.8876974e+00, -5.8286122e+01); - expectedForces[5] = Vec3( 1.1319359e+02, -3.2047069e-01, 1.6181231e+00); - expectedForces[6] = Vec3( -5.1606809e+02, 2.4925813e-02, 1.6259634e+01); - expectedForces[7] = Vec3( 1.1112638e+02, 3.7829857e-01, 1.5187587e+00); + expectedForces[0] = Vec3( 5.1453069e+02, 4.9751912e-01, -1.2759570e+01); + expectedForces[1] = Vec3(-2.5622586e+02, -4.6524265e+01, 2.4281465e+01); + expectedForces[2] = Vec3(-2.7538705e+02, 5.1831690e+01, 2.7367710e+01); + expectedForces[3] = Vec3(-0.0000000e+00, -0.0000000e+00, -0.0000000e+00); + expectedForces[4] = Vec3( 3.0883034e+02, -5.8876974e+00, -5.8286122e+01); + expectedForces[5] = Vec3( 1.1319359e+02, -3.2047069e-01, 1.6181231e+00); + expectedForces[6] = Vec3(-5.1606809e+02, 2.4925813e-02, 1.6259634e+01); + expectedForces[7] = Vec3( 1.1112638e+02, 3.7829857e-01, 1.5187587e+00); // tolerance is higher here due to interpolation used in setting tapering coefficients; // if tapering turned off, then absolute difference < 2.0e-05 @@ -562,13 +562,13 @@ void setupAndGetForcesEnergyVdwWater(const std::string& sigmaCombiningRule, cons int classIndex = 0; for (int ii = 0; ii < numberOfParticles; ii += 3) { - system.addParticle( 1.5995000e+01); + system.addParticle( 1.5995000e+01); amoebaVdwForce->addParticle(ii, 1.7025000e-01, 4.6024000e-01, 0.0000000e+00); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01); - system.addParticle( 1.0080000e+00); + system.addParticle( 1.0080000e+00); amoebaVdwForce->addParticle(ii, 1.3275000e-01, 5.6484000e-02, 9.1000000e-01); } @@ -590,654 +590,654 @@ void setupAndGetForcesEnergyVdwWater(const std::string& sigmaCombiningRule, cons std::vector positions(numberOfParticles); - positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); - positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); - positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); - positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); - positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); - positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); - positions[6] = Vec3( -6.5763670e-01, -2.5260000e-02, 8.1046320e-01); - positions[7] = Vec3( -6.6454990e-01, 6.8992500e-02, 7.8963560e-01); - positions[8] = Vec3( -6.6845370e-01, -4.0076000e-02, 9.1037470e-01); - positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); - positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); - positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); - positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); - positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); - positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); - positions[15] = Vec3( -4.6646340e-01, -8.5021310e-01, -2.6526210e-01); - positions[16] = Vec3( -4.5053590e-01, -8.3883300e-01, -3.6069710e-01); - positions[17] = Vec3( -5.5653260e-01, -8.7510810e-01, -2.5955820e-01); - positions[18] = Vec3( -7.7550740e-01, -4.6613180e-01, 4.9045930e-01); - positions[19] = Vec3( -7.3577510e-01, -5.4400590e-01, 5.3107060e-01); - positions[20] = Vec3( -7.0755520e-01, -4.1773140e-01, 4.4037930e-01); - positions[21] = Vec3( -2.8190600e-02, 7.4872450e-01, -7.6855300e-01); - positions[22] = Vec3( -7.9443300e-02, 7.4463600e-01, -6.8256160e-01); - positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); - positions[24] = Vec3( -3.7112750e-01, -2.2624390e-01, -1.9170030e-01); - positions[25] = Vec3( -4.4236150e-01, -2.4258640e-01, -2.4723220e-01); - positions[26] = Vec3( -4.0233380e-01, -2.2106530e-01, -9.7227800e-02); - positions[27] = Vec3( -5.8120030e-01, -5.6157220e-01, 8.3549400e-02); - positions[28] = Vec3( -6.6764500e-01, -5.7119710e-01, 1.2970660e-01); - positions[29] = Vec3( -5.1434340e-01, -5.5317060e-01, 1.5597670e-01); - positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); - positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); - positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); - positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); - positions[34] = Vec3( -6.4546800e-02, 4.4539620e-01, -6.0008300e-01); - positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); - positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); - positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); - positions[38] = Vec3( -3.9569500e-02, 5.9419720e-01, 5.6714930e-01); - positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); - positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); - positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); - positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); - positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); - positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); - positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); - positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); - positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); - positions[48] = Vec3( -8.7750980e-01, 6.9408570e-01, -6.1784650e-01); - positions[49] = Vec3( -8.2179580e-01, 7.3187880e-01, -5.4705510e-01); - positions[50] = Vec3( -9.0362240e-01, 7.7367480e-01, -6.6488210e-01); - positions[51] = Vec3( -6.9406820e-01, 2.2491740e-01, 7.1940890e-01); - positions[52] = Vec3( -7.3674620e-01, 2.2091000e-01, 6.3486690e-01); - positions[53] = Vec3( -7.4149900e-01, 2.8970280e-01, 7.7200060e-01); - positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); - positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); - positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); - positions[57] = Vec3( -2.2024800e-01, -3.1071870e-01, 9.1706370e-01); - positions[58] = Vec3( -2.3195790e-01, -4.0722320e-01, 9.2465160e-01); - positions[59] = Vec3( -2.8015290e-01, -2.9349640e-01, 8.4209880e-01); - positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); - positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); - positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); - positions[63] = Vec3( -9.0804840e-01, -6.2437310e-01, -8.8188300e-02); - positions[64] = Vec3( -8.6732940e-01, -7.0428590e-01, -4.8030200e-02); - positions[65] = Vec3( -8.3644480e-01, -5.8139450e-01, -1.3828190e-01); - positions[66] = Vec3( -8.6567760e-01, -8.6537570e-01, 5.6295900e-02); - positions[67] = Vec3( -8.1778220e-01, -9.4654890e-01, 8.4163600e-02); - positions[68] = Vec3( -9.4534460e-01, -8.6858770e-01, 1.0560810e-01); - positions[69] = Vec3( -5.7716930e-01, -2.6316670e-01, -4.5880740e-01); - positions[70] = Vec3( -5.4569620e-01, -3.1693230e-01, -5.2720970e-01); - positions[71] = Vec3( -5.5496000e-01, -1.7071220e-01, -4.7392400e-01); - positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); - positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); - positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); - positions[75] = Vec3( -2.3769060e-01, -6.2523350e-01, 1.2921080e-01); - positions[76] = Vec3( -1.8309420e-01, -6.2163180e-01, 4.8693900e-02); - positions[77] = Vec3( -2.3929030e-01, -5.3708810e-01, 1.6453540e-01); - positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); - positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); - positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); - positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); - positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); - positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); - positions[84] = Vec3( -2.5059100e-02, 8.6314620e-01, 2.2861410e-01); - positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); - positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); - positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); - positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); - positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); - positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); - positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); - positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); - positions[93] = Vec3( -7.9443650e-01, 1.7601300e-01, 4.6436790e-01); - positions[94] = Vec3( -7.9212150e-01, 2.3533020e-01, 3.8657500e-01); - positions[95] = Vec3( -8.7057070e-01, 1.1288830e-01, 4.4595260e-01); - positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); - positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); - positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); - positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); - positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); - positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); - positions[102] = Vec3( -8.4248740e-01, 3.5007110e-01, -4.4389740e-01); - positions[103] = Vec3( -7.5693800e-01, 3.9510690e-01, -4.4710480e-01); - positions[104] = Vec3( -8.6984880e-01, 3.5457480e-01, -5.3702920e-01); - positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); - positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); - positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); - positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); - positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); - positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); - positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); - positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); - positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); - positions[114] = Vec3( -4.4116790e-01, -4.7749880e-01, 3.0876830e-01); - positions[115] = Vec3( -5.0645290e-01, -4.1075220e-01, 3.1159470e-01); - positions[116] = Vec3( -4.6594720e-01, -5.2568230e-01, 3.8755370e-01); - positions[117] = Vec3( -9.1937480e-01, -5.8400000e-05, -2.5359570e-01); - positions[118] = Vec3( -8.5894750e-01, -7.0402500e-02, -2.2230370e-01); - positions[119] = Vec3( -8.7441760e-01, 8.3170500e-02, -2.3447490e-01); - positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); - positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); - positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); - positions[123] = Vec3( -4.6831090e-01, -6.1465890e-01, -1.6794620e-01); - positions[124] = Vec3( -4.8688540e-01, -5.9611250e-01, -7.4636500e-02); - positions[125] = Vec3( -4.9162010e-01, -7.0497770e-01, -1.8127910e-01); - positions[126] = Vec3( -3.1791800e-01, -5.4450000e-03, -3.6397680e-01); - positions[127] = Vec3( -2.2253910e-01, -2.4457600e-02, -3.5240990e-01); - positions[128] = Vec3( -3.6044390e-01, -3.5065000e-02, -2.8414310e-01); - positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); - positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); - positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); - positions[132] = Vec3( -1.4119340e-01, 4.1653970e-01, -2.7320250e-01); - positions[133] = Vec3( -5.2065100e-02, 3.6979030e-01, -2.6662970e-01); - positions[134] = Vec3( -1.3834110e-01, 4.7690560e-01, -1.9435870e-01); - positions[135] = Vec3( -7.6602450e-01, -2.1216400e-01, -1.9516640e-01); - positions[136] = Vec3( -8.0191290e-01, -2.8391260e-01, -1.3557910e-01); - positions[137] = Vec3( -7.4415500e-01, -2.6044280e-01, -2.8169590e-01); - positions[138] = Vec3( -1.3600310e-01, 1.9674000e-01, 2.0349610e-01); - positions[139] = Vec3( -1.6201050e-01, 2.8693750e-01, 2.3123820e-01); - positions[140] = Vec3( -2.1785650e-01, 1.4514420e-01, 1.9201990e-01); - positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); - positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); - positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); - positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); - positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); - positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); - positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); - positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); - positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); - positions[150] = Vec3( -7.2845180e-01, -3.4650580e-01, 7.5973620e-01); - positions[151] = Vec3( -7.6073760e-01, -3.6974690e-01, 6.7323450e-01); - positions[152] = Vec3( -7.1326740e-01, -2.4916760e-01, 7.5651020e-01); - positions[153] = Vec3( -3.0896820e-01, -3.8029640e-01, 6.5520670e-01); - positions[154] = Vec3( -3.5019560e-01, -4.5571260e-01, 6.1040330e-01); - positions[155] = Vec3( -2.8479430e-01, -3.2175460e-01, 5.7933340e-01); - positions[156] = Vec3( -6.2826700e-02, -6.4315900e-02, -6.8812300e-02); - positions[157] = Vec3( -7.4971500e-02, 1.9900000e-02, -1.8191100e-02); - positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); - positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); - positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); - positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); - positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); - positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); - positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); - positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); - positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); - positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); - positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); - positions[169] = Vec3( -7.1641800e-02, 4.1848500e-02, 8.7065260e-01); - positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); - positions[171] = Vec3( -3.1486750e-01, -1.9966860e-01, -5.7954700e-01); - positions[172] = Vec3( -3.2321140e-01, -1.4613590e-01, -5.0133480e-01); - positions[173] = Vec3( -3.4769180e-01, -1.4810900e-01, -6.5567720e-01); - positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); - positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); - positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); - positions[177] = Vec3( -1.5721060e-01, -2.0015580e-01, 4.8442010e-01); - positions[178] = Vec3( -7.4675400e-02, -2.0952300e-01, 5.3560160e-01); - positions[179] = Vec3( -1.8522760e-01, -1.0781560e-01, 5.0024110e-01); - positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); - positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); - positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); - positions[183] = Vec3( -6.3383580e-01, 5.7282910e-01, -1.7429980e-01); - positions[184] = Vec3( -6.0668100e-01, 4.7712900e-01, -1.7677570e-01); - positions[185] = Vec3( -5.6638740e-01, 6.1288510e-01, -2.2951390e-01); - positions[186] = Vec3( -2.0998170e-01, -2.7747820e-01, 7.0579400e-02); - positions[187] = Vec3( -1.4055440e-01, -3.0201380e-01, 1.3644740e-01); - positions[188] = Vec3( -1.6881700e-01, -2.1818660e-01, 6.9733000e-03); - positions[189] = Vec3( -7.6400000e-04, 5.6326380e-01, 1.4175360e-01); - positions[190] = Vec3( -7.3688000e-02, 5.0031150e-01, 1.5514670e-01); - positions[191] = Vec3( -2.5553000e-02, 6.4733770e-01, 1.7711800e-01); - positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); - positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); - positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); - positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); - positions[196] = Vec3( -4.9643600e-02, -2.7156660e-01, 8.9962920e-01); - positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); - positions[198] = Vec3( -5.9039370e-01, -3.5975630e-01, -7.1984370e-01); - positions[199] = Vec3( -5.3914870e-01, -4.0214860e-01, -7.8361060e-01); - positions[200] = Vec3( -6.8562580e-01, -3.9051900e-01, -7.4071320e-01); - positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); - positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); - positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); - positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); - positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); - positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); - positions[207] = Vec3( -6.9841710e-01, 8.5211760e-01, 4.9956020e-01); - positions[208] = Vec3( -6.3194850e-01, 9.0336360e-01, 4.5467020e-01); - positions[209] = Vec3( -6.7863830e-01, 7.5666570e-01, 5.1268950e-01); - positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); - positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); - positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); - positions[213] = Vec3( -2.3686380e-01, 4.4018650e-01, 2.7494630e-01); - positions[214] = Vec3( -2.1006750e-01, 4.1932880e-01, 3.6593160e-01); - positions[215] = Vec3( -3.2910900e-01, 4.6299420e-01, 2.7725190e-01); - positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); - positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); - positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); - positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); - positions[220] = Vec3( -1.0515300e-02, 1.4450010e-01, 4.8531790e-01); - positions[221] = Vec3( -3.6861400e-02, 1.5333190e-01, 3.3364650e-01); - positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); - positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); - positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); - positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); - positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); - positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); - positions[228] = Vec3( -1.9830990e-01, -6.8678560e-01, -7.6648560e-01); - positions[229] = Vec3( -1.1489950e-01, -6.8356660e-01, -8.2028210e-01); - positions[230] = Vec3( -2.0935090e-01, -5.9618710e-01, -7.3178710e-01); - positions[231] = Vec3( -4.3741650e-01, -7.8889500e-01, 1.7785560e-01); - positions[232] = Vec3( -3.6424030e-01, -7.2995610e-01, 1.5380490e-01); - positions[233] = Vec3( -5.0710310e-01, -7.4066850e-01, 1.3917790e-01); - positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); - positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); - positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); - positions[237] = Vec3( -9.1377180e-01, 9.0412110e-01, -8.0577110e-01); - positions[238] = Vec3( -8.6299150e-01, 9.8552780e-01, -7.9463610e-01); - positions[239] = Vec3( -9.1270510e-01, 8.7715830e-01, -9.0107170e-01); - positions[240] = Vec3( -5.6874630e-01, -3.9330600e-02, 5.3540210e-01); - positions[241] = Vec3( -6.0667690e-01, 3.6619200e-02, 4.9922460e-01); - positions[242] = Vec3( -5.8307630e-01, -4.4694300e-02, 6.3380260e-01); - positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); - positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); - positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); - positions[246] = Vec3( -5.3437690e-01, -9.0689060e-01, -7.7012560e-01); - positions[247] = Vec3( -6.0761130e-01, -8.5593580e-01, -8.0463440e-01); - positions[248] = Vec3( -5.5313680e-01, -9.9745020e-01, -8.0224750e-01); - positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); - positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); - positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); - positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); - positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); - positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); - positions[255] = Vec3( -2.3461000e-03, 8.8439120e-01, -3.5703750e-01); - positions[256] = Vec3( -4.5869800e-02, 9.2025060e-01, -4.4264850e-01); - positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); - positions[258] = Vec3( -1.6677150e-01, -9.0353490e-01, -5.6323410e-01); - positions[259] = Vec3( -1.5077930e-01, -8.7448310e-01, -6.5150250e-01); - positions[260] = Vec3( -2.5054260e-01, -8.5746520e-01, -5.4471400e-01); - positions[261] = Vec3( -1.0245710e-01, -4.1390500e-01, 2.9240710e-01); - positions[262] = Vec3( -1.6375100e-01, -3.5806090e-01, 3.3803800e-01); - positions[263] = Vec3( -3.4371600e-02, -4.4188880e-01, 3.6032470e-01); - positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); - positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); - positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); - positions[267] = Vec3( -5.2597410e-01, 5.0741940e-01, 2.8142130e-01); - positions[268] = Vec3( -5.3172740e-01, 5.6506650e-01, 2.0013640e-01); - positions[269] = Vec3( -5.9533220e-01, 4.4193270e-01, 2.6673520e-01); - positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); - positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); - positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); - positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); - positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); - positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); - positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); - positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); - positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); - positions[279] = Vec3( -8.5624140e-01, -3.3540460e-01, -5.3955060e-01); - positions[280] = Vec3( -8.9833150e-01, -3.2177130e-01, -6.2636700e-01); - positions[281] = Vec3( -7.6568080e-01, -3.0076830e-01, -5.3672910e-01); - positions[282] = Vec3( -4.0866080e-01, -7.0070860e-01, 9.2586930e-01); - positions[283] = Vec3( -4.5043520e-01, -7.7640050e-01, 9.7012510e-01); - positions[284] = Vec3( -3.2086210e-01, -6.9414110e-01, 9.6526100e-01); - positions[285] = Vec3( -2.9612090e-01, 2.9021400e-01, -4.6137730e-01); - positions[286] = Vec3( -3.0085180e-01, 1.9752840e-01, -4.3159520e-01); - positions[287] = Vec3( -2.4502340e-01, 3.3756140e-01, -3.9070450e-01); - positions[288] = Vec3( -8.4956240e-01, -3.3051010e-01, 4.2215900e-02); - positions[289] = Vec3( -8.2077940e-01, -3.9086690e-01, 1.1548590e-01); - positions[290] = Vec3( -9.3822180e-01, -3.1618550e-01, 5.2894000e-02); - positions[291] = Vec3( -8.6464030e-01, 7.5345250e-01, 1.9545370e-01); - positions[292] = Vec3( -9.2073720e-01, 6.7584430e-01, 1.8998460e-01); - positions[293] = Vec3( -8.9310500e-01, 7.8515510e-01, 2.8077440e-01); - positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); - positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); - positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); - positions[297] = Vec3( -3.0166400e-02, 3.6028840e-01, -9.2023940e-01); - positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); - positions[299] = Vec3( -1.2837900e-02, 3.5198820e-01, -8.2331230e-01); - positions[300] = Vec3( -7.6094250e-01, -7.4142570e-01, -7.6415170e-01); - positions[301] = Vec3( -7.5826150e-01, -6.8315050e-01, -8.4024930e-01); - positions[302] = Vec3( -7.8169550e-01, -6.8557300e-01, -6.8728990e-01); - positions[303] = Vec3( -7.1618050e-01, -8.6617600e-02, -7.8297100e-01); - positions[304] = Vec3( -6.9164460e-01, -1.6643810e-01, -7.3660090e-01); - positions[305] = Vec3( -8.1169890e-01, -8.6541300e-02, -7.7380060e-01); - positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); - positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); - positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); - positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); - positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); - positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); - positions[312] = Vec3( -2.2829370e-01, 4.6661410e-01, 7.7985190e-01); - positions[313] = Vec3( -2.4730820e-01, 5.6404020e-01, 7.8763210e-01); - positions[314] = Vec3( -1.7899690e-01, 4.3324110e-01, 8.5622400e-01); - positions[315] = Vec3( -5.1323270e-01, -2.6480150e-01, 7.2113100e-02); - positions[316] = Vec3( -4.4180310e-01, -2.8480730e-01, 1.4166490e-01); - positions[317] = Vec3( -5.5826690e-01, -3.4508980e-01, 5.6782300e-02); - positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); - positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); - positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); - positions[321] = Vec3( -8.6077820e-01, -8.3187420e-01, 3.5264550e-01); - positions[322] = Vec3( -7.9919290e-01, -8.9965630e-01, 3.8875110e-01); - positions[323] = Vec3( -8.4377450e-01, -8.2428940e-01, 2.5657630e-01); - positions[324] = Vec3( -6.9407750e-01, 8.5240530e-01, -4.8975260e-01); - positions[325] = Vec3( -6.0369970e-01, 8.2005830e-01, -4.7948010e-01); - positions[326] = Vec3( -6.8257340e-01, 9.0158170e-01, -5.7057020e-01); - positions[327] = Vec3( -8.6181560e-01, 2.1174420e-01, 3.2775000e-02); - positions[328] = Vec3( -9.5070390e-01, 2.5868190e-01, 2.6787700e-02); - positions[329] = Vec3( -8.8015990e-01, 1.3696510e-01, 9.1486900e-02); - positions[330] = Vec3( -6.7034530e-01, -7.0959980e-01, 5.7197940e-01); - positions[331] = Vec3( -6.3447070e-01, -7.7970770e-01, 5.1435410e-01); - positions[332] = Vec3( -7.1147280e-01, -7.6230200e-01, 6.4084900e-01); - positions[333] = Vec3( -4.2433970e-01, 1.6353470e-01, -7.5364040e-01); - positions[334] = Vec3( -3.3715920e-01, 1.3734360e-01, -7.8660110e-01); - positions[335] = Vec3( -4.5203330e-01, 2.3873860e-01, -8.1607320e-01); - positions[336] = Vec3( -4.2091960e-01, -8.1633330e-01, -5.3063920e-01); - positions[337] = Vec3( -4.2728590e-01, -7.1806470e-01, -5.4109270e-01); - positions[338] = Vec3( -4.5013260e-01, -8.3810340e-01, -6.1998700e-01); - positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); - positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); - positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); - positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); - positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); - positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); - positions[345] = Vec3( -3.5029200e-02, -7.9917400e-02, -3.4468400e-01); - positions[346] = Vec3( -6.3903800e-02, -6.0213300e-02, -2.5206780e-01); - positions[347] = Vec3( -4.6785200e-02, -1.7349570e-01, -3.5772680e-01); - positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); - positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); - positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); - positions[351] = Vec3( -7.3742490e-01, -8.7628820e-01, -2.6411710e-01); - positions[352] = Vec3( -7.3220480e-01, -9.1540050e-01, -3.5104230e-01); - positions[353] = Vec3( -7.9968040e-01, -9.2863850e-01, -2.1682500e-01); - positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); - positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); - positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); - positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); - positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); - positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); - positions[360] = Vec3( -5.0181950e-01, 6.8138390e-01, -8.8794760e-01); - positions[361] = Vec3( -4.0469720e-01, 6.5541180e-01, -8.8475300e-01); - positions[362] = Vec3( -5.4953810e-01, 6.3245150e-01, -8.1669610e-01); - positions[363] = Vec3( -3.5708340e-01, 8.1787480e-01, 1.0372050e-01); - positions[364] = Vec3( -4.3575160e-01, 7.6657380e-01, 8.8357500e-02); - positions[365] = Vec3( -3.8126100e-01, 9.1312250e-01, 1.2894930e-01); - positions[366] = Vec3( -1.0889180e-01, 6.4289110e-01, -1.1000150e-01); - positions[367] = Vec3( -9.5792300e-02, 6.5121590e-01, -1.2915400e-02); - positions[368] = Vec3( -1.4253020e-01, 7.3532640e-01, -1.2649680e-01); - positions[369] = Vec3( -8.0675190e-01, 3.8993580e-01, -9.3061890e-01); - positions[370] = Vec3( -8.4285770e-01, 4.7693320e-01, -9.5868770e-01); - positions[371] = Vec3( -7.4065520e-01, 4.1059110e-01, -8.6270860e-01); - positions[372] = Vec3( -7.3221050e-01, -8.3486000e-02, 1.8651540e-01); - positions[373] = Vec3( -6.6332990e-01, -2.5838100e-02, 1.5155080e-01); - positions[374] = Vec3( -7.5939010e-01, -1.4675440e-01, 1.1813700e-01); - positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); - positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); - positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); - positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); - positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); - positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); - positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); - positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); - positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); - positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); - positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); - positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); - positions[387] = Vec3( -4.9931530e-01, -8.6556710e-01, 4.1410020e-01); - positions[388] = Vec3( -4.0971070e-01, -9.0364250e-01, 4.1539320e-01); - positions[389] = Vec3( -5.0187830e-01, -8.1863570e-01, 3.2854240e-01); - positions[390] = Vec3( -9.2923250e-01, -9.5140200e-02, 7.7175180e-01); - positions[391] = Vec3( -1.0068535e+00, -4.9193300e-02, 8.1361050e-01); - positions[392] = Vec3( -8.5382270e-01, -3.5167000e-02, 7.7988780e-01); - positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); - positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); - positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); - positions[396] = Vec3( -4.3869270e-01, 7.1030180e-01, -3.4435510e-01); - positions[397] = Vec3( -3.5798370e-01, 6.6801330e-01, -3.8293170e-01); - positions[398] = Vec3( -3.9584820e-01, 7.8582280e-01, -3.0015890e-01); - positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); - positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); - positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); - positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); - positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); - positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); - positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); - positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); - positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); - positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); - positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); - positions[410] = Vec3( -1.4581300e-02, 7.7868400e-02, -4.8044320e-01); - positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); - positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); - positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); - positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); - positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); - positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); - positions[417] = Vec3( -7.2074000e-03, -2.1935180e-01, -6.7044710e-01); - positions[418] = Vec3( -7.9916200e-02, -2.2604130e-01, -7.3330810e-01); - positions[419] = Vec3( -3.2871000e-03, -2.9557560e-01, -6.1702790e-01); - positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); - positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); - positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); - positions[423] = Vec3( -3.1753700e-01, 3.7248900e-02, 5.0846140e-01); - positions[424] = Vec3( -3.3276340e-01, 1.2794660e-01, 5.4135580e-01); - positions[425] = Vec3( -4.0442920e-01, -2.1535000e-03, 5.2164500e-01); - positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); - positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); - positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); - positions[429] = Vec3( -5.0985980e-01, 6.5271910e-01, 5.1660950e-01); - positions[430] = Vec3( -4.1891080e-01, 6.9500010e-01, 5.0933000e-01); - positions[431] = Vec3( -5.2072650e-01, 6.0609800e-01, 4.2889530e-01); - positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); - positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); - positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); - positions[435] = Vec3( -4.2632820e-01, -5.4538160e-01, -5.2698140e-01); - positions[436] = Vec3( -3.4047810e-01, -5.2088280e-01, -5.5637760e-01); - positions[437] = Vec3( -4.9107950e-01, -5.2513960e-01, -5.9520410e-01); - positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); - positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); - positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); - positions[441] = Vec3( -3.0889500e-02, -5.4040860e-01, -7.7446500e-02); - positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); - positions[443] = Vec3( -1.0937030e-01, -5.1212170e-01, -1.2642620e-01); - positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); - positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); - positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); - positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); - positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); - positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); - positions[450] = Vec3( -2.7264270e-01, 8.2117820e-01, 4.0979220e-01); - positions[451] = Vec3( -1.8893860e-01, 7.8611730e-01, 4.4435560e-01); - positions[452] = Vec3( -2.7256440e-01, 8.1557060e-01, 3.0746650e-01); - positions[453] = Vec3( -2.3667600e-01, 7.0807760e-01, 9.0055470e-01); - positions[454] = Vec3( -1.7087350e-01, 7.0278860e-01, 9.7330650e-01); - positions[455] = Vec3( -2.2325560e-01, 8.0596230e-01, 8.7050690e-01); - positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); - positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); - positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); - positions[459] = Vec3( -6.9432470e-01, 5.5588670e-01, -7.2750070e-01); - positions[460] = Vec3( -6.8524660e-01, 5.1427650e-01, -6.4407660e-01); - positions[461] = Vec3( -7.7219850e-01, 6.0882800e-01, -7.1352640e-01); - positions[462] = Vec3( -6.5544400e-01, 5.6801890e-01, 7.6654940e-01); - positions[463] = Vec3( -5.9853210e-01, 5.8150060e-01, 6.8630620e-01); - positions[464] = Vec3( -6.0728400e-01, 6.2604000e-01, 8.2970960e-01); - positions[465] = Vec3( -1.7725100e-01, -7.5128040e-01, 4.8288320e-01); - positions[466] = Vec3( -1.1106490e-01, -7.1604590e-01, 4.2681180e-01); - positions[467] = Vec3( -1.2808000e-01, -8.2063050e-01, 5.2385060e-01); - positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); - positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); - positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); - positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); - positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); - positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); - positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); - positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); - positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); - positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); - positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); - positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); - positions[480] = Vec3( -5.0297400e-01, 3.8595440e-01, -9.1329410e-01); - positions[481] = Vec3( -4.2761710e-01, 4.4573350e-01, -8.9961960e-01); - positions[482] = Vec3( -5.7109730e-01, 4.3620760e-01, -9.6075240e-01); - positions[483] = Vec3( -5.7912630e-01, 3.1473530e-01, -1.3174480e-01); - positions[484] = Vec3( -6.4359930e-01, 2.3775370e-01, -1.3815260e-01); - positions[485] = Vec3( -5.1910350e-01, 2.9841740e-01, -5.0386200e-02); - positions[486] = Vec3( -2.3287450e-01, -4.5325250e-01, -2.6295780e-01); - positions[487] = Vec3( -3.1705790e-01, -5.0582880e-01, -2.5755610e-01); - positions[488] = Vec3( -2.4988940e-01, -3.6717760e-01, -2.2456790e-01); - positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); - positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); - positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); - positions[492] = Vec3( -1.7342650e-01, -4.4833620e-01, -6.2689720e-01); - positions[493] = Vec3( -1.2120170e-01, -4.7044370e-01, -5.5178260e-01); - positions[494] = Vec3( -2.1756220e-01, -3.7095040e-01, -5.9046920e-01); - positions[495] = Vec3( -9.7909800e-02, 4.1047140e-01, 5.5154950e-01); - positions[496] = Vec3( -1.5085520e-01, 4.3078300e-01, 6.2923170e-01); - positions[497] = Vec3( -2.2121000e-02, 3.5854830e-01, 5.8628920e-01); - positions[498] = Vec3( -2.9249090e-01, 4.2502460e-01, -7.0552100e-01); - positions[499] = Vec3( -2.3858950e-01, 3.8279980e-01, -7.7129020e-01); - positions[500] = Vec3( -2.8537830e-01, 3.6194940e-01, -6.3036240e-01); - positions[501] = Vec3( -4.1927200e-01, -1.0765570e-01, -8.1010100e-01); - positions[502] = Vec3( -4.5513170e-01, -1.8389200e-01, -8.5055730e-01); - positions[503] = Vec3( -4.6978720e-01, -3.2915400e-02, -8.4249770e-01); - positions[504] = Vec3( -8.3022800e-01, -5.9366610e-01, -5.2440890e-01); - positions[505] = Vec3( -8.3569020e-01, -5.0053960e-01, -5.4596070e-01); - positions[506] = Vec3( -7.7653500e-01, -5.9680800e-01, -4.4872510e-01); - positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); - positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); - positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); - positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); - positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); - positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); - positions[513] = Vec3( -1.7389390e-01, 6.3857050e-01, -4.3802350e-01); - positions[514] = Vec3( -1.0857550e-01, 7.0876020e-01, -4.2023360e-01); - positions[515] = Vec3( -1.6180390e-01, 5.6775180e-01, -3.7084920e-01); - positions[516] = Vec3( -8.3384410e-01, -7.8320210e-01, 7.9714340e-01); - positions[517] = Vec3( -8.6597850e-01, -8.7176550e-01, 7.7689410e-01); - positions[518] = Vec3( -9.1332720e-01, -7.1912210e-01, 7.9807020e-01); - positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); - positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); - positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); - positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); - positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); - positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); - positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); - positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); - positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); - positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); - positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); - positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); - positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); - positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); - positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); - positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); - positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); - positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); - positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); - positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); - positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); - positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); - positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); - positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); - positions[543] = Vec3( -3.2687830e-01, -9.5478000e-03, 2.1684540e-01); - positions[544] = Vec3( -3.2605730e-01, -1.4225700e-02, 3.1463820e-01); - positions[545] = Vec3( -2.7582100e-01, -8.4479800e-02, 1.8809180e-01); - positions[546] = Vec3( -8.3433230e-01, -5.5202940e-01, 2.1864880e-01); - positions[547] = Vec3( -8.2396710e-01, -5.4694370e-01, 3.1266070e-01); - positions[548] = Vec3( -9.3264700e-01, -5.5452020e-01, 1.9359510e-01); - positions[549] = Vec3( -3.7479050e-01, 2.2505660e-01, 7.1205330e-01); - positions[550] = Vec3( -4.7509020e-01, 2.3675960e-01, 7.1906840e-01); - positions[551] = Vec3( -3.3344270e-01, 3.0911900e-01, 7.2096390e-01); - positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); - positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); - positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); - positions[555] = Vec3( -2.3127640e-01, 9.0287820e-01, -1.3411380e-01); - positions[556] = Vec3( -2.8615520e-01, 9.5668910e-01, -1.9830460e-01); - positions[557] = Vec3( -2.9306830e-01, 8.7146310e-01, -6.8234400e-02); - positions[558] = Vec3( -5.4794480e-01, 6.9927600e-02, 4.9211700e-02); - positions[559] = Vec3( -4.8467110e-01, 1.3673600e-02, 9.6662900e-02); - positions[560] = Vec3( -5.5944570e-01, 3.5041600e-02, -4.0422400e-02); - positions[561] = Vec3( -4.0842490e-01, -6.1610810e-01, 5.3013490e-01); - positions[562] = Vec3( -3.5055240e-01, -6.7988460e-01, 4.9398580e-01); - positions[563] = Vec3( -4.6296070e-01, -6.7880320e-01, 5.8633470e-01); - positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); - positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); - positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); - positions[567] = Vec3( -1.6560700e-02, -3.7062430e-01, -3.6569060e-01); - positions[568] = Vec3( -9.0792700e-02, -4.1378610e-01, -3.2720710e-01); - positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); - positions[570] = Vec3( -5.9512760e-01, 1.7073000e-02, -2.2772060e-01); - positions[571] = Vec3( -5.8225940e-01, 7.1421900e-02, -3.0604790e-01); - positions[572] = Vec3( -6.2819960e-01, -6.3276600e-02, -2.6202260e-01); - positions[573] = Vec3( -4.7641750e-01, -4.2323550e-01, 8.9604240e-01); - positions[574] = Vec3( -5.4796980e-01, -4.1341290e-01, 8.3129580e-01); - positions[575] = Vec3( -4.6422920e-01, -5.2061790e-01, 8.9834640e-01); - positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); - positions[577] = Vec3( -6.9252500e-02, -9.1064710e-01, -8.0576000e-02); - positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); - positions[579] = Vec3( -6.0237270e-01, 6.8170090e-01, 6.7672100e-02); - positions[580] = Vec3( -6.3353490e-01, 6.5944010e-01, -1.4737000e-02); - positions[581] = Vec3( -6.7945440e-01, 7.0260310e-01, 1.2553510e-01); - positions[582] = Vec3( -7.9759390e-01, -4.8566970e-01, -8.8075620e-01); - positions[583] = Vec3( -7.6587590e-01, -4.4277470e-01, -9.5861500e-01); - positions[584] = Vec3( -8.8262650e-01, -4.4354590e-01, -8.6497650e-01); - positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); - positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); - positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); - positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); - positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); - positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); - positions[591] = Vec3( -6.9004280e-01, -5.9012070e-01, -2.9270410e-01); - positions[592] = Vec3( -7.1539690e-01, -6.8384200e-01, -2.8572180e-01); - positions[593] = Vec3( -5.9319910e-01, -5.8219810e-01, -2.7391860e-01); - positions[594] = Vec3( -2.0769030e-01, -9.0263320e-01, 8.2559380e-01); - positions[595] = Vec3( -1.2326710e-01, -9.0347650e-01, 7.7889800e-01); - positions[596] = Vec3( -2.4674410e-01, -8.1114260e-01, 8.1400270e-01); - positions[597] = Vec3( -5.9770390e-01, -2.5353030e-01, 3.7815410e-01); - positions[598] = Vec3( -5.7799760e-01, -1.8503970e-01, 4.3781640e-01); - positions[599] = Vec3( -6.3056510e-01, -1.9169960e-01, 3.0646360e-01); - positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); - positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); - positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); - positions[603] = Vec3( -5.7980030e-01, 4.5624440e-01, -4.8053250e-01); - positions[604] = Vec3( -5.0283550e-01, 4.0235700e-01, -4.7629430e-01); - positions[605] = Vec3( -5.5234760e-01, 5.5030960e-01, -4.6445780e-01); - positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); - positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); - positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); - positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); - positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); - positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); - positions[612] = Vec3( -5.8628640e-01, 1.5133800e-02, -5.2805090e-01); - positions[613] = Vec3( -5.0874980e-01, 5.8718200e-02, -5.5884230e-01); - positions[614] = Vec3( -6.4503990e-01, 1.9133400e-02, -6.0165090e-01); - positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); - positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); - positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); - positions[618] = Vec3( -4.1271350e-01, 6.8162960e-01, -6.2517570e-01); - positions[619] = Vec3( -3.4841290e-01, 6.1054470e-01, -6.4194430e-01); - positions[620] = Vec3( -3.5808100e-01, 7.5958210e-01, -6.0333290e-01); - positions[621] = Vec3( -2.3867290e-01, 5.9441400e-02, 9.1386800e-01); - positions[622] = Vec3( -2.9103650e-01, -1.4337800e-02, 9.5259360e-01); - positions[623] = Vec3( -2.8602000e-01, 1.0405050e-01, 8.3648420e-01); - positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); - positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); - positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); - positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); - positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); - positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); - positions[630] = Vec3( -9.1418940e-01, 8.0389630e-01, 7.8826000e-01); - positions[631] = Vec3( -8.3833600e-01, 7.4209380e-01, 7.8290720e-01); - positions[632] = Vec3( -9.9161100e-01, 7.5608500e-01, 8.2971860e-01); - positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); - positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); - positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); - positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); - positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); - positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); - positions[639] = Vec3( -1.1738970e-01, -5.9305270e-01, 7.0381050e-01); - positions[640] = Vec3( -1.5290840e-01, -6.5518590e-01, 6.3431800e-01); - positions[641] = Vec3( -1.6038250e-01, -5.0776740e-01, 6.8496070e-01); - positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); - positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); - positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); - positions[645] = Vec3( -7.5114680e-01, 3.5944460e-01, 2.4369600e-01); - positions[646] = Vec3( -8.1938720e-01, 4.1907000e-01, 2.7265900e-01); - positions[647] = Vec3( -7.8315770e-01, 3.2541650e-01, 1.6165560e-01); + positions[0] = Vec3( 8.0394300e-01, 5.8680350e-01, 4.9277700e-02); + positions[1] = Vec3( 7.5814940e-01, 5.0226660e-01, 4.0375900e-02); + positions[2] = Vec3( 8.2870560e-01, 6.0624400e-01, -3.9707400e-02); + positions[3] = Vec3( 1.1484000e-02, -8.8765990e-01, 6.4458520e-01); + positions[4] = Vec3( 9.5892500e-02, -8.4464940e-01, 6.4052470e-01); + positions[5] = Vec3( 2.4723500e-02, -9.7944710e-01, 6.1378930e-01); + positions[6] = Vec3(-6.5763670e-01, -2.5260000e-02, 8.1046320e-01); + positions[7] = Vec3(-6.6454990e-01, 6.8992500e-02, 7.8963560e-01); + positions[8] = Vec3(-6.6845370e-01, -4.0076000e-02, 9.1037470e-01); + positions[9] = Vec3( 6.5831270e-01, 8.5501500e-02, -6.6685290e-01); + positions[10] = Vec3( 6.2600580e-01, 8.8732600e-02, -5.7651320e-01); + positions[11] = Vec3( 6.1694860e-01, 5.3229000e-03, -7.0543230e-01); + positions[12] = Vec3( 5.4954790e-01, 6.4357640e-01, 1.8420070e-01); + positions[13] = Vec3( 4.7740750e-01, 6.5609280e-01, 1.2079650e-01); + positions[14] = Vec3( 6.2544340e-01, 6.3485600e-01, 1.2346110e-01); + positions[15] = Vec3(-4.6646340e-01, -8.5021310e-01, -2.6526210e-01); + positions[16] = Vec3(-4.5053590e-01, -8.3883300e-01, -3.6069710e-01); + positions[17] = Vec3(-5.5653260e-01, -8.7510810e-01, -2.5955820e-01); + positions[18] = Vec3(-7.7550740e-01, -4.6613180e-01, 4.9045930e-01); + positions[19] = Vec3(-7.3577510e-01, -5.4400590e-01, 5.3107060e-01); + positions[20] = Vec3(-7.0755520e-01, -4.1773140e-01, 4.4037930e-01); + positions[21] = Vec3(-2.8190600e-02, 7.4872450e-01, -7.6855300e-01); + positions[22] = Vec3(-7.9443300e-02, 7.4463600e-01, -6.8256160e-01); + positions[23] = Vec3( 1.7033100e-02, 8.3813000e-01, -7.6365310e-01); + positions[24] = Vec3(-3.7112750e-01, -2.2624390e-01, -1.9170030e-01); + positions[25] = Vec3(-4.4236150e-01, -2.4258640e-01, -2.4723220e-01); + positions[26] = Vec3(-4.0233380e-01, -2.2106530e-01, -9.7227800e-02); + positions[27] = Vec3(-5.8120030e-01, -5.6157220e-01, 8.3549400e-02); + positions[28] = Vec3(-6.6764500e-01, -5.7119710e-01, 1.2970660e-01); + positions[29] = Vec3(-5.1434340e-01, -5.5317060e-01, 1.5597670e-01); + positions[30] = Vec3( 8.5281410e-01, 4.9997870e-01, 3.4439320e-01); + positions[31] = Vec3( 8.8661040e-01, 4.7595500e-01, 4.3409810e-01); + positions[32] = Vec3( 7.6829200e-01, 4.5403270e-01, 3.3783460e-01); + positions[33] = Vec3( 6.2913000e-03, 3.9622090e-01, -6.4448110e-01); + positions[34] = Vec3(-6.4546800e-02, 4.4539620e-01, -6.0008300e-01); + positions[35] = Vec3( 7.0262000e-03, 3.1229330e-01, -5.9892730e-01); + positions[36] = Vec3( 1.6883500e-02, 6.5824910e-01, 6.0982750e-01); + positions[37] = Vec3( 2.9114400e-02, 6.3714540e-01, 7.0403040e-01); + positions[38] = Vec3(-3.9569500e-02, 5.9419720e-01, 5.6714930e-01); + positions[39] = Vec3( 3.7393550e-01, 6.2909200e-01, 8.1318410e-01); + positions[40] = Vec3( 4.1500630e-01, 6.1010560e-01, 9.0110400e-01); + positions[41] = Vec3( 4.3953600e-01, 5.9208230e-01, 7.5268270e-01); + positions[42] = Vec3( 3.2500410e-01, 4.5615770e-01, -2.5643980e-01); + positions[43] = Vec3( 3.7432790e-01, 4.5313140e-01, -3.3754880e-01); + positions[44] = Vec3( 2.6987370e-01, 5.3785040e-01, -2.4860760e-01); + positions[45] = Vec3( 5.6184630e-01, 5.2015900e-01, 6.3763990e-01); + positions[46] = Vec3( 5.6189080e-01, 5.6140190e-01, 5.5312940e-01); + positions[47] = Vec3( 5.4901540e-01, 4.2688810e-01, 6.2109450e-01); + positions[48] = Vec3(-8.7750980e-01, 6.9408570e-01, -6.1784650e-01); + positions[49] = Vec3(-8.2179580e-01, 7.3187880e-01, -5.4705510e-01); + positions[50] = Vec3(-9.0362240e-01, 7.7367480e-01, -6.6488210e-01); + positions[51] = Vec3(-6.9406820e-01, 2.2491740e-01, 7.1940890e-01); + positions[52] = Vec3(-7.3674620e-01, 2.2091000e-01, 6.3486690e-01); + positions[53] = Vec3(-7.4149900e-01, 2.8970280e-01, 7.7200060e-01); + positions[54] = Vec3( 4.8285280e-01, -1.8445100e-02, 3.1521130e-01); + positions[55] = Vec3( 5.5574910e-01, 2.4338500e-02, 2.7236750e-01); + positions[56] = Vec3( 4.1347360e-01, 5.0063500e-02, 3.2371450e-01); + positions[57] = Vec3(-2.2024800e-01, -3.1071870e-01, 9.1706370e-01); + positions[58] = Vec3(-2.3195790e-01, -4.0722320e-01, 9.2465160e-01); + positions[59] = Vec3(-2.8015290e-01, -2.9349640e-01, 8.4209880e-01); + positions[60] = Vec3( 1.6893780e-01, 6.6734280e-01, -2.4352040e-01); + positions[61] = Vec3( 1.9716270e-01, 7.5186390e-01, -2.0536790e-01); + positions[62] = Vec3( 8.7430700e-02, 6.4225300e-01, -1.9539020e-01); + positions[63] = Vec3(-9.0804840e-01, -6.2437310e-01, -8.8188300e-02); + positions[64] = Vec3(-8.6732940e-01, -7.0428590e-01, -4.8030200e-02); + positions[65] = Vec3(-8.3644480e-01, -5.8139450e-01, -1.3828190e-01); + positions[66] = Vec3(-8.6567760e-01, -8.6537570e-01, 5.6295900e-02); + positions[67] = Vec3(-8.1778220e-01, -9.4654890e-01, 8.4163600e-02); + positions[68] = Vec3(-9.4534460e-01, -8.6858770e-01, 1.0560810e-01); + positions[69] = Vec3(-5.7716930e-01, -2.6316670e-01, -4.5880740e-01); + positions[70] = Vec3(-5.4569620e-01, -3.1693230e-01, -5.2720970e-01); + positions[71] = Vec3(-5.5496000e-01, -1.7071220e-01, -4.7392400e-01); + positions[72] = Vec3( 7.2367810e-01, -8.4678300e-01, -6.9502250e-01); + positions[73] = Vec3( 7.9899670e-01, -8.9648580e-01, -7.2759260e-01); + positions[74] = Vec3( 7.5075030e-01, -8.1725850e-01, -6.0600380e-01); + positions[75] = Vec3(-2.3769060e-01, -6.2523350e-01, 1.2921080e-01); + positions[76] = Vec3(-1.8309420e-01, -6.2163180e-01, 4.8693900e-02); + positions[77] = Vec3(-2.3929030e-01, -5.3708810e-01, 1.6453540e-01); + positions[78] = Vec3( 8.3347800e-02, -5.0189060e-01, 5.4317800e-01); + positions[79] = Vec3( 1.0917180e-01, -5.7641330e-01, 4.8632230e-01); + positions[80] = Vec3( 1.4837200e-02, -5.5084220e-01, 5.9546910e-01); + positions[81] = Vec3( 7.4250070e-01, -2.7418580e-01, 8.3795900e-02); + positions[82] = Vec3( 6.8666720e-01, -2.4554090e-01, 1.6206940e-01); + positions[83] = Vec3( 7.1516850e-01, -3.6419530e-01, 7.2493400e-02); + positions[84] = Vec3(-2.5059100e-02, 8.6314620e-01, 2.2861410e-01); + positions[85] = Vec3( 9.6445000e-03, 9.0720400e-01, 1.4964290e-01); + positions[86] = Vec3( 4.5097900e-02, 8.7155360e-01, 2.9051950e-01); + positions[87] = Vec3( 4.7779490e-01, 9.0242640e-01, 8.2515620e-01); + positions[88] = Vec3( 4.3957480e-01, 8.0786830e-01, 8.2489220e-01); + positions[89] = Vec3( 4.6833310e-01, 9.2867710e-01, 9.1788160e-01); + positions[90] = Vec3( 8.2204140e-01, 9.0145630e-01, -2.5081510e-01); + positions[91] = Vec3( 8.5191840e-01, 8.1397830e-01, -2.2168590e-01); + positions[92] = Vec3( 7.6397810e-01, 9.2011290e-01, -1.8137750e-01); + positions[93] = Vec3(-7.9443650e-01, 1.7601300e-01, 4.6436790e-01); + positions[94] = Vec3(-7.9212150e-01, 2.3533020e-01, 3.8657500e-01); + positions[95] = Vec3(-8.7057070e-01, 1.1288830e-01, 4.4595260e-01); + positions[96] = Vec3( 3.2425690e-01, 3.8214720e-01, -8.2471120e-01); + positions[97] = Vec3( 2.8321830e-01, 4.2912450e-01, -7.4875880e-01); + positions[98] = Vec3( 2.7681870e-01, 2.9837230e-01, -8.2620080e-01); + positions[99] = Vec3( 7.5575820e-01, -8.9620900e-01, 2.3680670e-01); + positions[100] = Vec3( 6.6600420e-01, -8.7027760e-01, 2.7104280e-01); + positions[101] = Vec3( 8.1544110e-01, -9.1190240e-01, 3.1149610e-01); + positions[102] = Vec3(-8.4248740e-01, 3.5007110e-01, -4.4389740e-01); + positions[103] = Vec3(-7.5693800e-01, 3.9510690e-01, -4.4710480e-01); + positions[104] = Vec3(-8.6984880e-01, 3.5457480e-01, -5.3702920e-01); + positions[105] = Vec3( 3.8837250e-01, -4.8496240e-01, 6.5322550e-01); + positions[106] = Vec3( 4.1237110e-01, -4.0401080e-01, 7.0255980e-01); + positions[107] = Vec3( 3.0065040e-01, -4.6399160e-01, 6.0513040e-01); + positions[108] = Vec3( 6.2063930e-01, -5.0831230e-01, 4.9540430e-01); + positions[109] = Vec3( 6.8959700e-01, -5.3506820e-01, 5.6328860e-01); + positions[110] = Vec3( 5.3663630e-01, -5.1121830e-01, 5.4640900e-01); + positions[111] = Vec3( 7.0354670e-01, -5.1748580e-01, -7.3878700e-02); + positions[112] = Vec3( 7.8529450e-01, -5.6535940e-01, -9.5943500e-02); + positions[113] = Vec3( 6.7807440e-01, -4.7921810e-01, -1.6187590e-01); + positions[114] = Vec3(-4.4116790e-01, -4.7749880e-01, 3.0876830e-01); + positions[115] = Vec3(-5.0645290e-01, -4.1075220e-01, 3.1159470e-01); + positions[116] = Vec3(-4.6594720e-01, -5.2568230e-01, 3.8755370e-01); + positions[117] = Vec3(-9.1937480e-01, -5.8400000e-05, -2.5359570e-01); + positions[118] = Vec3(-8.5894750e-01, -7.0402500e-02, -2.2230370e-01); + positions[119] = Vec3(-8.7441760e-01, 8.3170500e-02, -2.3447490e-01); + positions[120] = Vec3( 5.0867290e-01, 2.3568780e-01, 5.5935510e-01); + positions[121] = Vec3( 4.1446460e-01, 2.6088930e-01, 5.8683440e-01); + positions[122] = Vec3( 5.1853820e-01, 1.4937830e-01, 5.8561390e-01); + positions[123] = Vec3(-4.6831090e-01, -6.1465890e-01, -1.6794620e-01); + positions[124] = Vec3(-4.8688540e-01, -5.9611250e-01, -7.4636500e-02); + positions[125] = Vec3(-4.9162010e-01, -7.0497770e-01, -1.8127910e-01); + positions[126] = Vec3(-3.1791800e-01, -5.4450000e-03, -3.6397680e-01); + positions[127] = Vec3(-2.2253910e-01, -2.4457600e-02, -3.5240990e-01); + positions[128] = Vec3(-3.6044390e-01, -3.5065000e-02, -2.8414310e-01); + positions[129] = Vec3( 1.0461140e-01, 2.6758700e-01, -2.2684050e-01); + positions[130] = Vec3( 1.8426490e-01, 3.2453330e-01, -2.3574350e-01); + positions[131] = Vec3( 1.0569370e-01, 2.3628020e-01, -1.3834830e-01); + positions[132] = Vec3(-1.4119340e-01, 4.1653970e-01, -2.7320250e-01); + positions[133] = Vec3(-5.2065100e-02, 3.6979030e-01, -2.6662970e-01); + positions[134] = Vec3(-1.3834110e-01, 4.7690560e-01, -1.9435870e-01); + positions[135] = Vec3(-7.6602450e-01, -2.1216400e-01, -1.9516640e-01); + positions[136] = Vec3(-8.0191290e-01, -2.8391260e-01, -1.3557910e-01); + positions[137] = Vec3(-7.4415500e-01, -2.6044280e-01, -2.8169590e-01); + positions[138] = Vec3(-1.3600310e-01, 1.9674000e-01, 2.0349610e-01); + positions[139] = Vec3(-1.6201050e-01, 2.8693750e-01, 2.3123820e-01); + positions[140] = Vec3(-2.1785650e-01, 1.4514420e-01, 1.9201990e-01); + positions[141] = Vec3( 6.2897820e-01, -4.2302590e-01, -7.6557210e-01); + positions[142] = Vec3( 6.2334100e-01, -4.4471660e-01, -6.7174140e-01); + positions[143] = Vec3( 6.3346670e-01, -5.0696850e-01, -8.0495300e-01); + positions[144] = Vec3( 9.1588260e-01, -3.9845200e-02, 3.5189180e-01); + positions[145] = Vec3( 9.8891550e-01, -4.4673900e-02, 2.9156120e-01); + positions[146] = Vec3( 8.4126090e-01, -2.2841000e-03, 2.9707980e-01); + positions[147] = Vec3( 4.8470900e-01, -8.2561400e-02, 6.0082980e-01); + positions[148] = Vec3( 3.9021850e-01, -6.2932500e-02, 6.0195610e-01); + positions[149] = Vec3( 5.0563070e-01, -7.9866200e-02, 5.0777230e-01); + positions[150] = Vec3(-7.2845180e-01, -3.4650580e-01, 7.5973620e-01); + positions[151] = Vec3(-7.6073760e-01, -3.6974690e-01, 6.7323450e-01); + positions[152] = Vec3(-7.1326740e-01, -2.4916760e-01, 7.5651020e-01); + positions[153] = Vec3(-3.0896820e-01, -3.8029640e-01, 6.5520670e-01); + positions[154] = Vec3(-3.5019560e-01, -4.5571260e-01, 6.1040330e-01); + positions[155] = Vec3(-2.8479430e-01, -3.2175460e-01, 5.7933340e-01); + positions[156] = Vec3(-6.2826700e-02, -6.4315900e-02, -6.8812300e-02); + positions[157] = Vec3(-7.4971500e-02, 1.9900000e-02, -1.8191100e-02); + positions[158] = Vec3( 3.2478400e-02, -8.8932300e-02, -5.6413600e-02); + positions[159] = Vec3( 1.1667520e-01, -6.6784990e-01, 1.1452860e-01); + positions[160] = Vec3( 6.5194200e-02, -7.3080350e-01, 6.5294000e-02); + positions[161] = Vec3( 1.6133150e-01, -6.1778770e-01, 4.7196600e-02); + positions[162] = Vec3( 8.8627400e-02, -7.1850240e-01, 3.7581390e-01); + positions[163] = Vec3( 1.2356120e-01, -8.0690930e-01, 3.7094210e-01); + positions[164] = Vec3( 9.2028600e-02, -6.8313750e-01, 2.8412340e-01); + positions[165] = Vec3( 2.1347270e-01, 8.4107000e-03, 6.0413030e-01); + positions[166] = Vec3( 1.8845570e-01, 4.3251500e-02, 5.1600410e-01); + positions[167] = Vec3( 1.6789670e-01, -7.6656800e-02, 6.0793520e-01); + positions[168] = Vec3( 1.8425700e-02, 3.0164400e-02, 8.4213210e-01); + positions[169] = Vec3(-7.1641800e-02, 4.1848500e-02, 8.7065260e-01); + positions[170] = Vec3( 4.4510400e-02, -6.2982500e-02, 8.6373290e-01); + positions[171] = Vec3(-3.1486750e-01, -1.9966860e-01, -5.7954700e-01); + positions[172] = Vec3(-3.2321140e-01, -1.4613590e-01, -5.0133480e-01); + positions[173] = Vec3(-3.4769180e-01, -1.4810900e-01, -6.5567720e-01); + positions[174] = Vec3( 2.2013690e-01, -4.8207100e-02, -6.6169910e-01); + positions[175] = Vec3( 1.3676160e-01, -9.4600100e-02, -6.4525960e-01); + positions[176] = Vec3( 2.7051720e-01, -1.2158460e-01, -6.9535940e-01); + positions[177] = Vec3(-1.5721060e-01, -2.0015580e-01, 4.8442010e-01); + positions[178] = Vec3(-7.4675400e-02, -2.0952300e-01, 5.3560160e-01); + positions[179] = Vec3(-1.8522760e-01, -1.0781560e-01, 5.0024110e-01); + positions[180] = Vec3( 5.4002730e-01, 6.3800500e-01, -8.0040500e-01); + positions[181] = Vec3( 5.0366070e-01, 7.1545920e-01, -7.5257350e-01); + positions[182] = Vec3( 5.1480770e-01, 5.5941670e-01, -7.4903220e-01); + positions[183] = Vec3(-6.3383580e-01, 5.7282910e-01, -1.7429980e-01); + positions[184] = Vec3(-6.0668100e-01, 4.7712900e-01, -1.7677570e-01); + positions[185] = Vec3(-5.6638740e-01, 6.1288510e-01, -2.2951390e-01); + positions[186] = Vec3(-2.0998170e-01, -2.7747820e-01, 7.0579400e-02); + positions[187] = Vec3(-1.4055440e-01, -3.0201380e-01, 1.3644740e-01); + positions[188] = Vec3(-1.6881700e-01, -2.1818660e-01, 6.9733000e-03); + positions[189] = Vec3(-7.6400000e-04, 5.6326380e-01, 1.4175360e-01); + positions[190] = Vec3(-7.3688000e-02, 5.0031150e-01, 1.5514670e-01); + positions[191] = Vec3(-2.5553000e-02, 6.4733770e-01, 1.7711800e-01); + positions[192] = Vec3( 3.9595890e-01, -1.9078420e-01, -1.9708050e-01); + positions[193] = Vec3( 4.3887020e-01, -1.5694200e-01, -1.1582060e-01); + positions[194] = Vec3( 3.7635540e-01, -1.1834040e-01, -2.5323660e-01); + positions[195] = Vec3( 3.9638900e-02, -2.4093090e-01, 8.9424300e-01); + positions[196] = Vec3(-4.9643600e-02, -2.7156660e-01, 8.9962920e-01); + positions[197] = Vec3( 8.4318200e-02, -2.7149840e-01, 9.7721820e-01); + positions[198] = Vec3(-5.9039370e-01, -3.5975630e-01, -7.1984370e-01); + positions[199] = Vec3(-5.3914870e-01, -4.0214860e-01, -7.8361060e-01); + positions[200] = Vec3(-6.8562580e-01, -3.9051900e-01, -7.4071320e-01); + positions[201] = Vec3( 4.7759800e-01, 3.2863960e-01, -5.4274200e-02); + positions[202] = Vec3( 4.5034450e-01, 3.6680450e-01, -1.4201230e-01); + positions[203] = Vec3( 4.3083410e-01, 3.8043410e-01, 1.5118500e-02); + positions[204] = Vec3( 1.8100450e-01, 1.6674000e-01, -8.4907090e-01); + positions[205] = Vec3( 1.0479500e-01, 1.5721720e-01, -9.0737790e-01); + positions[206] = Vec3( 1.7365410e-01, 9.7140100e-02, -7.7842430e-01); + positions[207] = Vec3(-6.9841710e-01, 8.5211760e-01, 4.9956020e-01); + positions[208] = Vec3(-6.3194850e-01, 9.0336360e-01, 4.5467020e-01); + positions[209] = Vec3(-6.7863830e-01, 7.5666570e-01, 5.1268950e-01); + positions[210] = Vec3( 8.0356880e-01, -7.6669620e-01, 5.6240980e-01); + positions[211] = Vec3( 8.9444390e-01, -7.9421520e-01, 5.4379860e-01); + positions[212] = Vec3( 8.0061200e-01, -7.1151420e-01, 6.3743510e-01); + positions[213] = Vec3(-2.3686380e-01, 4.4018650e-01, 2.7494630e-01); + positions[214] = Vec3(-2.1006750e-01, 4.1932880e-01, 3.6593160e-01); + positions[215] = Vec3(-3.2910900e-01, 4.6299420e-01, 2.7725190e-01); + positions[216] = Vec3( 7.3324180e-01, 9.1021100e-02, 8.6347740e-01); + positions[217] = Vec3( 6.4934460e-01, 5.3444800e-02, 8.7843600e-01); + positions[218] = Vec3( 7.1407590e-01, 1.8691830e-01, 8.6323690e-01); + positions[219] = Vec3( 3.6906600e-02, 1.4742360e-01, 4.0082880e-01); + positions[220] = Vec3(-1.0515300e-02, 1.4450010e-01, 4.8531790e-01); + positions[221] = Vec3(-3.6861400e-02, 1.5333190e-01, 3.3364650e-01); + positions[222] = Vec3( 5.7666790e-01, -9.2075640e-01, 5.7305300e-01); + positions[223] = Vec3( 5.4452540e-01, -9.3954290e-01, 6.5798160e-01); + positions[224] = Vec3( 6.7020160e-01, -8.8052280e-01, 5.6852240e-01); + positions[225] = Vec3( 4.1616300e-01, -2.3723450e-01, 7.8105700e-02); + positions[226] = Vec3( 4.4947640e-01, -2.2465620e-01, 1.6469280e-01); + positions[227] = Vec3( 3.6093380e-01, -3.1332780e-01, 7.1125100e-02); + positions[228] = Vec3(-1.9830990e-01, -6.8678560e-01, -7.6648560e-01); + positions[229] = Vec3(-1.1489950e-01, -6.8356660e-01, -8.2028210e-01); + positions[230] = Vec3(-2.0935090e-01, -5.9618710e-01, -7.3178710e-01); + positions[231] = Vec3(-4.3741650e-01, -7.8889500e-01, 1.7785560e-01); + positions[232] = Vec3(-3.6424030e-01, -7.2995610e-01, 1.5380490e-01); + positions[233] = Vec3(-5.0710310e-01, -7.4066850e-01, 1.3917790e-01); + positions[234] = Vec3( 5.1605280e-01, 6.8521860e-01, 4.5545030e-01); + positions[235] = Vec3( 5.3920960e-01, 7.6750670e-01, 4.8965960e-01); + positions[236] = Vec3( 5.4441350e-01, 6.8153880e-01, 3.6305340e-01); + positions[237] = Vec3(-9.1377180e-01, 9.0412110e-01, -8.0577110e-01); + positions[238] = Vec3(-8.6299150e-01, 9.8552780e-01, -7.9463610e-01); + positions[239] = Vec3(-9.1270510e-01, 8.7715830e-01, -9.0107170e-01); + positions[240] = Vec3(-5.6874630e-01, -3.9330600e-02, 5.3540210e-01); + positions[241] = Vec3(-6.0667690e-01, 3.6619200e-02, 4.9922460e-01); + positions[242] = Vec3(-5.8307630e-01, -4.4694300e-02, 6.3380260e-01); + positions[243] = Vec3( 1.0312020e-01, 2.2809180e-01, 5.7525600e-02); + positions[244] = Vec3( 1.8161800e-02, 2.2164820e-01, 1.0293620e-01); + positions[245] = Vec3( 1.4691520e-01, 3.0734480e-01, 9.4432600e-02); + positions[246] = Vec3(-5.3437690e-01, -9.0689060e-01, -7.7012560e-01); + positions[247] = Vec3(-6.0761130e-01, -8.5593580e-01, -8.0463440e-01); + positions[248] = Vec3(-5.5313680e-01, -9.9745020e-01, -8.0224750e-01); + positions[249] = Vec3( 1.7436730e-01, -4.6935620e-01, -7.7408150e-01); + positions[250] = Vec3( 1.3315640e-01, -4.6856170e-01, -6.8363440e-01); + positions[251] = Vec3( 2.3486700e-01, -3.9970620e-01, -7.7872930e-01); + positions[252] = Vec3( 5.0382310e-01, 8.6391330e-01, -6.1751380e-01); + positions[253] = Vec3( 5.7851670e-01, 9.1774780e-01, -6.3741940e-01); + positions[254] = Vec3( 5.2100060e-01, 8.2278060e-01, -5.3449130e-01); + positions[255] = Vec3(-2.3461000e-03, 8.8439120e-01, -3.5703750e-01); + positions[256] = Vec3(-4.5869800e-02, 9.2025060e-01, -4.4264850e-01); + positions[257] = Vec3( 7.7568300e-02, 8.3812640e-01, -3.7824790e-01); + positions[258] = Vec3(-1.6677150e-01, -9.0353490e-01, -5.6323410e-01); + positions[259] = Vec3(-1.5077930e-01, -8.7448310e-01, -6.5150250e-01); + positions[260] = Vec3(-2.5054260e-01, -8.5746520e-01, -5.4471400e-01); + positions[261] = Vec3(-1.0245710e-01, -4.1390500e-01, 2.9240710e-01); + positions[262] = Vec3(-1.6375100e-01, -3.5806090e-01, 3.3803800e-01); + positions[263] = Vec3(-3.4371600e-02, -4.4188880e-01, 3.6032470e-01); + positions[264] = Vec3( 6.7721230e-01, -9.2755000e-01, -6.1695000e-03); + positions[265] = Vec3( 6.3209610e-01, -8.4066740e-01, 1.5854000e-03); + positions[266] = Vec3( 7.2195780e-01, -9.3506790e-01, 7.6821700e-02); + positions[267] = Vec3(-5.2597410e-01, 5.0741940e-01, 2.8142130e-01); + positions[268] = Vec3(-5.3172740e-01, 5.6506650e-01, 2.0013640e-01); + positions[269] = Vec3(-5.9533220e-01, 4.4193270e-01, 2.6673520e-01); + positions[270] = Vec3( 4.3852700e-02, -7.1092730e-01, -3.0056810e-01); + positions[271] = Vec3( 1.2232900e-02, -6.7601300e-01, -2.1679320e-01); + positions[272] = Vec3( 3.0039200e-02, -8.0474130e-01, -3.0050550e-01); + positions[273] = Vec3( 4.7537430e-01, 6.7956000e-03, -8.8926760e-01); + positions[274] = Vec3( 4.4972180e-01, -8.1937800e-02, -8.5037740e-01); + positions[275] = Vec3( 3.9238110e-01, 5.4650000e-02, -9.0978500e-01); + positions[276] = Vec3( 8.4526190e-01, -3.2384610e-01, 4.4702430e-01); + positions[277] = Vec3( 8.5335920e-01, -2.3860050e-01, 4.1507690e-01); + positions[278] = Vec3( 9.3799800e-01, -3.6222940e-01, 4.5249690e-01); + positions[279] = Vec3(-8.5624140e-01, -3.3540460e-01, -5.3955060e-01); + positions[280] = Vec3(-8.9833150e-01, -3.2177130e-01, -6.2636700e-01); + positions[281] = Vec3(-7.6568080e-01, -3.0076830e-01, -5.3672910e-01); + positions[282] = Vec3(-4.0866080e-01, -7.0070860e-01, 9.2586930e-01); + positions[283] = Vec3(-4.5043520e-01, -7.7640050e-01, 9.7012510e-01); + positions[284] = Vec3(-3.2086210e-01, -6.9414110e-01, 9.6526100e-01); + positions[285] = Vec3(-2.9612090e-01, 2.9021400e-01, -4.6137730e-01); + positions[286] = Vec3(-3.0085180e-01, 1.9752840e-01, -4.3159520e-01); + positions[287] = Vec3(-2.4502340e-01, 3.3756140e-01, -3.9070450e-01); + positions[288] = Vec3(-8.4956240e-01, -3.3051010e-01, 4.2215900e-02); + positions[289] = Vec3(-8.2077940e-01, -3.9086690e-01, 1.1548590e-01); + positions[290] = Vec3(-9.3822180e-01, -3.1618550e-01, 5.2894000e-02); + positions[291] = Vec3(-8.6464030e-01, 7.5345250e-01, 1.9545370e-01); + positions[292] = Vec3(-9.2073720e-01, 6.7584430e-01, 1.8998460e-01); + positions[293] = Vec3(-8.9310500e-01, 7.8515510e-01, 2.8077440e-01); + positions[294] = Vec3( 5.3248170e-01, 6.8435100e-02, -1.1431070e-01); + positions[295] = Vec3( 6.1630600e-01, 5.7417300e-02, -6.9794300e-02); + positions[296] = Vec3( 4.9275030e-01, 1.5234490e-01, -7.9235100e-02); + positions[297] = Vec3(-3.0166400e-02, 3.6028840e-01, -9.2023940e-01); + positions[298] = Vec3( 2.5390700e-02, 4.3355180e-01, -9.4581010e-01); + positions[299] = Vec3(-1.2837900e-02, 3.5198820e-01, -8.2331230e-01); + positions[300] = Vec3(-7.6094250e-01, -7.4142570e-01, -7.6415170e-01); + positions[301] = Vec3(-7.5826150e-01, -6.8315050e-01, -8.4024930e-01); + positions[302] = Vec3(-7.8169550e-01, -6.8557300e-01, -6.8728990e-01); + positions[303] = Vec3(-7.1618050e-01, -8.6617600e-02, -7.8297100e-01); + positions[304] = Vec3(-6.9164460e-01, -1.6643810e-01, -7.3660090e-01); + positions[305] = Vec3(-8.1169890e-01, -8.6541300e-02, -7.7380060e-01); + positions[306] = Vec3( 8.6280550e-01, -2.8731190e-01, -7.5013210e-01); + positions[307] = Vec3( 8.4297110e-01, -2.0142080e-01, -7.9688520e-01); + positions[308] = Vec3( 7.7553640e-01, -3.3421630e-01, -7.5754400e-01); + positions[309] = Vec3( 2.9607200e-02, -6.7251560e-01, -9.1368960e-01); + positions[310] = Vec3( 1.0909000e-03, -6.2708430e-01, -9.9528360e-01); + positions[311] = Vec3( 8.0161300e-02, -5.9814710e-01, -8.7106130e-01); + positions[312] = Vec3(-2.2829370e-01, 4.6661410e-01, 7.7985190e-01); + positions[313] = Vec3(-2.4730820e-01, 5.6404020e-01, 7.8763210e-01); + positions[314] = Vec3(-1.7899690e-01, 4.3324110e-01, 8.5622400e-01); + positions[315] = Vec3(-5.1323270e-01, -2.6480150e-01, 7.2113100e-02); + positions[316] = Vec3(-4.4180310e-01, -2.8480730e-01, 1.4166490e-01); + positions[317] = Vec3(-5.5826690e-01, -3.4508980e-01, 5.6782300e-02); + positions[318] = Vec3( 3.5970320e-01, -7.1101700e-01, -8.5706800e-01); + positions[319] = Vec3( 3.5573750e-01, -6.6123030e-01, -7.7069560e-01); + positions[320] = Vec3( 2.9308100e-01, -6.7738800e-01, -9.1162920e-01); + positions[321] = Vec3(-8.6077820e-01, -8.3187420e-01, 3.5264550e-01); + positions[322] = Vec3(-7.9919290e-01, -8.9965630e-01, 3.8875110e-01); + positions[323] = Vec3(-8.4377450e-01, -8.2428940e-01, 2.5657630e-01); + positions[324] = Vec3(-6.9407750e-01, 8.5240530e-01, -4.8975260e-01); + positions[325] = Vec3(-6.0369970e-01, 8.2005830e-01, -4.7948010e-01); + positions[326] = Vec3(-6.8257340e-01, 9.0158170e-01, -5.7057020e-01); + positions[327] = Vec3(-8.6181560e-01, 2.1174420e-01, 3.2775000e-02); + positions[328] = Vec3(-9.5070390e-01, 2.5868190e-01, 2.6787700e-02); + positions[329] = Vec3(-8.8015990e-01, 1.3696510e-01, 9.1486900e-02); + positions[330] = Vec3(-6.7034530e-01, -7.0959980e-01, 5.7197940e-01); + positions[331] = Vec3(-6.3447070e-01, -7.7970770e-01, 5.1435410e-01); + positions[332] = Vec3(-7.1147280e-01, -7.6230200e-01, 6.4084900e-01); + positions[333] = Vec3(-4.2433970e-01, 1.6353470e-01, -7.5364040e-01); + positions[334] = Vec3(-3.3715920e-01, 1.3734360e-01, -7.8660110e-01); + positions[335] = Vec3(-4.5203330e-01, 2.3873860e-01, -8.1607320e-01); + positions[336] = Vec3(-4.2091960e-01, -8.1633330e-01, -5.3063920e-01); + positions[337] = Vec3(-4.2728590e-01, -7.1806470e-01, -5.4109270e-01); + positions[338] = Vec3(-4.5013260e-01, -8.3810340e-01, -6.1998700e-01); + positions[339] = Vec3( 6.0367930e-01, 3.3084920e-01, -8.4465460e-01); + positions[340] = Vec3( 5.0455880e-01, 3.3698360e-01, -8.4011240e-01); + positions[341] = Vec3( 6.2487550e-01, 2.4834360e-01, -8.0607210e-01); + positions[342] = Vec3( 1.8546120e-01, -6.3282200e-02, 5.1304500e-02); + positions[343] = Vec3( 2.8101390e-01, -7.7771500e-02, 5.1163200e-02); + positions[344] = Vec3( 1.7127760e-01, 2.0996700e-02, 9.0574100e-02); + positions[345] = Vec3(-3.5029200e-02, -7.9917400e-02, -3.4468400e-01); + positions[346] = Vec3(-6.3903800e-02, -6.0213300e-02, -2.5206780e-01); + positions[347] = Vec3(-4.6785200e-02, -1.7349570e-01, -3.5772680e-01); + positions[348] = Vec3( 2.5567190e-01, 6.2355480e-01, 4.2852620e-01); + positions[349] = Vec3( 1.9093710e-01, 6.4505930e-01, 4.9102940e-01); + positions[350] = Vec3( 3.4540670e-01, 6.4937420e-01, 4.5902510e-01); + positions[351] = Vec3(-7.3742490e-01, -8.7628820e-01, -2.6411710e-01); + positions[352] = Vec3(-7.3220480e-01, -9.1540050e-01, -3.5104230e-01); + positions[353] = Vec3(-7.9968040e-01, -9.2863850e-01, -2.1682500e-01); + positions[354] = Vec3( 5.1017210e-01, -2.7173980e-01, 7.9174500e-01); + positions[355] = Vec3( 5.1045830e-01, -2.0746280e-01, 7.2138780e-01); + positions[356] = Vec3( 5.9967910e-01, -3.0815350e-01, 7.9296320e-01); + positions[357] = Vec3( 6.1703300e-02, -6.0490320e-01, -5.4304490e-01); + positions[358] = Vec3( 6.5202000e-03, -6.6388800e-01, -5.9525970e-01); + positions[359] = Vec3( 6.2525700e-02, -6.3466150e-01, -4.5175130e-01); + positions[360] = Vec3(-5.0181950e-01, 6.8138390e-01, -8.8794760e-01); + positions[361] = Vec3(-4.0469720e-01, 6.5541180e-01, -8.8475300e-01); + positions[362] = Vec3(-5.4953810e-01, 6.3245150e-01, -8.1669610e-01); + positions[363] = Vec3(-3.5708340e-01, 8.1787480e-01, 1.0372050e-01); + positions[364] = Vec3(-4.3575160e-01, 7.6657380e-01, 8.8357500e-02); + positions[365] = Vec3(-3.8126100e-01, 9.1312250e-01, 1.2894930e-01); + positions[366] = Vec3(-1.0889180e-01, 6.4289110e-01, -1.1000150e-01); + positions[367] = Vec3(-9.5792300e-02, 6.5121590e-01, -1.2915400e-02); + positions[368] = Vec3(-1.4253020e-01, 7.3532640e-01, -1.2649680e-01); + positions[369] = Vec3(-8.0675190e-01, 3.8993580e-01, -9.3061890e-01); + positions[370] = Vec3(-8.4285770e-01, 4.7693320e-01, -9.5868770e-01); + positions[371] = Vec3(-7.4065520e-01, 4.1059110e-01, -8.6270860e-01); + positions[372] = Vec3(-7.3221050e-01, -8.3486000e-02, 1.8651540e-01); + positions[373] = Vec3(-6.6332990e-01, -2.5838100e-02, 1.5155080e-01); + positions[374] = Vec3(-7.5939010e-01, -1.4675440e-01, 1.1813700e-01); + positions[375] = Vec3( 6.1370510e-01, -3.7510720e-01, -2.9444790e-01); + positions[376] = Vec3( 5.3141590e-01, -3.1971250e-01, -2.8369080e-01); + positions[377] = Vec3( 6.7472620e-01, -3.0544670e-01, -3.2680390e-01); + positions[378] = Vec3( 2.8333090e-01, 7.0116700e-01, 6.3582400e-02); + positions[379] = Vec3( 2.3304950e-01, 7.8436370e-01, 8.8113000e-02); + positions[380] = Vec3( 2.1603670e-01, 6.3345680e-01, 4.3706900e-02); + positions[381] = Vec3( 3.4046290e-01, -5.8425160e-01, -5.8383960e-01); + positions[382] = Vec3( 4.2396660e-01, -5.6867730e-01, -5.4787780e-01); + positions[383] = Vec3( 2.7987870e-01, -5.6273080e-01, -5.1485370e-01); + positions[384] = Vec3( 4.8651200e-01, 3.9384650e-01, -5.0852640e-01); + positions[385] = Vec3( 4.8954070e-01, 2.9830160e-01, -5.1540010e-01); + positions[386] = Vec3( 5.7513360e-01, 4.2777280e-01, -4.8094980e-01); + positions[387] = Vec3(-4.9931530e-01, -8.6556710e-01, 4.1410020e-01); + positions[388] = Vec3(-4.0971070e-01, -9.0364250e-01, 4.1539320e-01); + positions[389] = Vec3(-5.0187830e-01, -8.1863570e-01, 3.2854240e-01); + positions[390] = Vec3(-9.2923250e-01, -9.5140200e-02, 7.7175180e-01); + positions[391] = Vec3(-1.0068535e+00, -4.9193300e-02, 8.1361050e-01); + positions[392] = Vec3(-8.5382270e-01, -3.5167000e-02, 7.7988780e-01); + positions[393] = Vec3( 5.8200510e-01, -2.7347380e-01, 3.2175080e-01); + positions[394] = Vec3( 5.9114530e-01, -2.1232990e-01, 3.9188270e-01); + positions[395] = Vec3( 6.2697690e-01, -3.5436570e-01, 3.5518080e-01); + positions[396] = Vec3(-4.3869270e-01, 7.1030180e-01, -3.4435510e-01); + positions[397] = Vec3(-3.5798370e-01, 6.6801330e-01, -3.8293170e-01); + positions[398] = Vec3(-3.9584820e-01, 7.8582280e-01, -3.0015890e-01); + positions[399] = Vec3( 3.0315060e-01, 2.0553140e-01, 3.3518590e-01); + positions[400] = Vec3( 2.0466680e-01, 2.0029920e-01, 3.3800050e-01); + positions[401] = Vec3( 3.1784090e-01, 2.6138240e-01, 4.0966770e-01); + positions[402] = Vec3( 7.3144120e-01, 1.1861840e-01, 2.1872590e-01); + positions[403] = Vec3( 6.9245610e-01, 2.0755440e-01, 2.3848660e-01); + positions[404] = Vec3( 7.4250960e-01, 1.1063670e-01, 1.1673060e-01); + positions[405] = Vec3( 3.0774670e-01, -6.7782260e-01, -6.9330000e-02); + positions[406] = Vec3( 3.0161020e-01, -7.5652530e-01, -1.2627210e-01); + positions[407] = Vec3( 3.7612340e-01, -6.9199170e-01, -2.0688000e-03); + positions[408] = Vec3( 4.8241200e-02, 1.4991530e-01, -4.8562930e-01); + positions[409] = Vec3( 7.0825700e-02, 1.7883510e-01, -4.0076820e-01); + positions[410] = Vec3(-1.4581300e-02, 7.7868400e-02, -4.8044320e-01); + positions[411] = Vec3( 2.6566210e-01, -4.7972300e-02, -3.9240060e-01); + positions[412] = Vec3( 2.5708940e-01, -2.6958700e-02, -4.8906580e-01); + positions[413] = Vec3( 1.8079360e-01, -1.7099600e-02, -3.5945650e-01); + positions[414] = Vec3( 7.3593670e-01, 3.2192010e-01, 6.3185000e-03); + positions[415] = Vec3( 7.5313070e-01, 3.1236830e-01, -9.0780600e-02); + positions[416] = Vec3( 6.4125230e-01, 3.3242850e-01, 5.3072000e-03); + positions[417] = Vec3(-7.2074000e-03, -2.1935180e-01, -6.7044710e-01); + positions[418] = Vec3(-7.9916200e-02, -2.2604130e-01, -7.3330810e-01); + positions[419] = Vec3(-3.2871000e-03, -2.9557560e-01, -6.1702790e-01); + positions[420] = Vec3( 8.0182800e-01, 3.3340310e-01, -2.5836160e-01); + positions[421] = Vec3( 8.9266890e-01, 3.1760310e-01, -2.9990300e-01); + positions[422] = Vec3( 7.7135080e-01, 4.0881250e-01, -3.1490320e-01); + positions[423] = Vec3(-3.1753700e-01, 3.7248900e-02, 5.0846140e-01); + positions[424] = Vec3(-3.3276340e-01, 1.2794660e-01, 5.4135580e-01); + positions[425] = Vec3(-4.0442920e-01, -2.1535000e-03, 5.2164500e-01); + positions[426] = Vec3( 7.7089090e-01, -1.7749490e-01, -4.1090550e-01); + positions[427] = Vec3( 8.0919970e-01, -9.9267700e-02, -3.6080690e-01); + positions[428] = Vec3( 8.4794900e-01, -2.2265030e-01, -4.4286640e-01); + positions[429] = Vec3(-5.0985980e-01, 6.5271910e-01, 5.1660950e-01); + positions[430] = Vec3(-4.1891080e-01, 6.9500010e-01, 5.0933000e-01); + positions[431] = Vec3(-5.2072650e-01, 6.0609800e-01, 4.2889530e-01); + positions[432] = Vec3( 8.8931480e-01, -1.5854900e-02, -7.9057690e-01); + positions[433] = Vec3( 8.4049130e-01, 2.2454500e-02, -7.1223150e-01); + positions[434] = Vec3( 8.6392620e-01, 4.6002000e-02, -8.5696830e-01); + positions[435] = Vec3(-4.2632820e-01, -5.4538160e-01, -5.2698140e-01); + positions[436] = Vec3(-3.4047810e-01, -5.2088280e-01, -5.5637760e-01); + positions[437] = Vec3(-4.9107950e-01, -5.2513960e-01, -5.9520410e-01); + positions[438] = Vec3( 8.8830700e-01, 7.8506050e-01, 4.7420010e-01); + positions[439] = Vec3( 9.6737760e-01, 8.0796480e-01, 5.2210120e-01); + positions[440] = Vec3( 8.3449840e-01, 7.2694370e-01, 5.2968560e-01); + positions[441] = Vec3(-3.0889500e-02, -5.4040860e-01, -7.7446500e-02); + positions[442] = Vec3( 2.4910200e-02, -4.7046460e-01, -5.3187100e-02); + positions[443] = Vec3(-1.0937030e-01, -5.1212170e-01, -1.2642620e-01); + positions[444] = Vec3( 5.0722190e-01, -8.0898340e-01, 3.3208510e-01); + positions[445] = Vec3( 5.1254280e-01, -8.4333670e-01, 4.2962250e-01); + positions[446] = Vec3( 4.8459280e-01, -7.1548850e-01, 3.3664280e-01); + positions[447] = Vec3( 7.0974400e-02, -8.6268490e-01, -7.2122900e-01); + positions[448] = Vec3( 8.8211100e-02, -8.1266230e-01, -7.9698760e-01); + positions[449] = Vec3( 1.4856180e-01, -8.7440360e-01, -6.6601020e-01); + positions[450] = Vec3(-2.7264270e-01, 8.2117820e-01, 4.0979220e-01); + positions[451] = Vec3(-1.8893860e-01, 7.8611730e-01, 4.4435560e-01); + positions[452] = Vec3(-2.7256440e-01, 8.1557060e-01, 3.0746650e-01); + positions[453] = Vec3(-2.3667600e-01, 7.0807760e-01, 9.0055470e-01); + positions[454] = Vec3(-1.7087350e-01, 7.0278860e-01, 9.7330650e-01); + positions[455] = Vec3(-2.2325560e-01, 8.0596230e-01, 8.7050690e-01); + positions[456] = Vec3( 6.0904540e-01, -5.3471490e-01, -5.1588800e-01); + positions[457] = Vec3( 6.6627390e-01, -6.1177680e-01, -4.9309950e-01); + positions[458] = Vec3( 6.1303950e-01, -4.7414890e-01, -4.3691960e-01); + positions[459] = Vec3(-6.9432470e-01, 5.5588670e-01, -7.2750070e-01); + positions[460] = Vec3(-6.8524660e-01, 5.1427650e-01, -6.4407660e-01); + positions[461] = Vec3(-7.7219850e-01, 6.0882800e-01, -7.1352640e-01); + positions[462] = Vec3(-6.5544400e-01, 5.6801890e-01, 7.6654940e-01); + positions[463] = Vec3(-5.9853210e-01, 5.8150060e-01, 6.8630620e-01); + positions[464] = Vec3(-6.0728400e-01, 6.2604000e-01, 8.2970960e-01); + positions[465] = Vec3(-1.7725100e-01, -7.5128040e-01, 4.8288320e-01); + positions[466] = Vec3(-1.1106490e-01, -7.1604590e-01, 4.2681180e-01); + positions[467] = Vec3(-1.2808000e-01, -8.2063050e-01, 5.2385060e-01); + positions[468] = Vec3( 5.0880810e-01, -1.7782370e-01, -5.5526690e-01); + positions[469] = Vec3( 4.7579150e-01, -1.6757400e-01, -4.6732050e-01); + positions[470] = Vec3( 6.0010540e-01, -1.6566020e-01, -5.4639700e-01); + positions[471] = Vec3( 7.9737120e-01, -5.3326000e-03, -2.2789800e-02); + positions[472] = Vec3( 7.5436910e-01, -9.2537600e-02, -2.7176000e-03); + positions[473] = Vec3( 8.4035540e-01, -2.5845500e-02, -1.0913300e-01); + positions[474] = Vec3( 2.4805290e-01, -4.5182680e-01, -2.5649240e-01); + positions[475] = Vec3( 2.6536400e-01, -5.1313010e-01, -1.8699050e-01); + positions[476] = Vec3( 2.8661880e-01, -3.6531040e-01, -2.2184290e-01); + positions[477] = Vec3( 8.9407190e-01, 6.4140150e-01, -2.2838520e-01); + positions[478] = Vec3( 8.6394270e-01, 5.7649930e-01, -2.9124340e-01); + positions[479] = Vec3( 9.8698980e-01, 6.3685520e-01, -2.2087390e-01); + positions[480] = Vec3(-5.0297400e-01, 3.8595440e-01, -9.1329410e-01); + positions[481] = Vec3(-4.2761710e-01, 4.4573350e-01, -8.9961960e-01); + positions[482] = Vec3(-5.7109730e-01, 4.3620760e-01, -9.6075240e-01); + positions[483] = Vec3(-5.7912630e-01, 3.1473530e-01, -1.3174480e-01); + positions[484] = Vec3(-6.4359930e-01, 2.3775370e-01, -1.3815260e-01); + positions[485] = Vec3(-5.1910350e-01, 2.9841740e-01, -5.0386200e-02); + positions[486] = Vec3(-2.3287450e-01, -4.5325250e-01, -2.6295780e-01); + positions[487] = Vec3(-3.1705790e-01, -5.0582880e-01, -2.5755610e-01); + positions[488] = Vec3(-2.4988940e-01, -3.6717760e-01, -2.2456790e-01); + positions[489] = Vec3( 7.3902040e-01, 6.0596960e-01, 8.7531410e-01); + positions[490] = Vec3( 6.8510920e-01, 5.6584400e-01, 8.0394270e-01); + positions[491] = Vec3( 6.7885220e-01, 6.2492120e-01, 9.4854880e-01); + positions[492] = Vec3(-1.7342650e-01, -4.4833620e-01, -6.2689720e-01); + positions[493] = Vec3(-1.2120170e-01, -4.7044370e-01, -5.5178260e-01); + positions[494] = Vec3(-2.1756220e-01, -3.7095040e-01, -5.9046920e-01); + positions[495] = Vec3(-9.7909800e-02, 4.1047140e-01, 5.5154950e-01); + positions[496] = Vec3(-1.5085520e-01, 4.3078300e-01, 6.2923170e-01); + positions[497] = Vec3(-2.2121000e-02, 3.5854830e-01, 5.8628920e-01); + positions[498] = Vec3(-2.9249090e-01, 4.2502460e-01, -7.0552100e-01); + positions[499] = Vec3(-2.3858950e-01, 3.8279980e-01, -7.7129020e-01); + positions[500] = Vec3(-2.8537830e-01, 3.6194940e-01, -6.3036240e-01); + positions[501] = Vec3(-4.1927200e-01, -1.0765570e-01, -8.1010100e-01); + positions[502] = Vec3(-4.5513170e-01, -1.8389200e-01, -8.5055730e-01); + positions[503] = Vec3(-4.6978720e-01, -3.2915400e-02, -8.4249770e-01); + positions[504] = Vec3(-8.3022800e-01, -5.9366610e-01, -5.2440890e-01); + positions[505] = Vec3(-8.3569020e-01, -5.0053960e-01, -5.4596070e-01); + positions[506] = Vec3(-7.7653500e-01, -5.9680800e-01, -4.4872510e-01); + positions[507] = Vec3( 4.7451900e-02, 2.4985900e-01, 7.1027380e-01); + positions[508] = Vec3( 5.2750000e-03, 2.6682820e-01, 8.0047760e-01); + positions[509] = Vec3( 9.2790500e-02, 1.6390540e-01, 7.2751450e-01); + positions[510] = Vec3( 9.8318300e-02, -2.4834430e-01, 6.2217110e-01); + positions[511] = Vec3( 7.1376800e-02, -2.3868900e-01, 7.1029050e-01); + positions[512] = Vec3( 1.0725160e-01, -3.3946690e-01, 5.9525570e-01); + positions[513] = Vec3(-1.7389390e-01, 6.3857050e-01, -4.3802350e-01); + positions[514] = Vec3(-1.0857550e-01, 7.0876020e-01, -4.2023360e-01); + positions[515] = Vec3(-1.6180390e-01, 5.6775180e-01, -3.7084920e-01); + positions[516] = Vec3(-8.3384410e-01, -7.8320210e-01, 7.9714340e-01); + positions[517] = Vec3(-8.6597850e-01, -8.7176550e-01, 7.7689410e-01); + positions[518] = Vec3(-9.1332720e-01, -7.1912210e-01, 7.9807020e-01); + positions[519] = Vec3( 3.0122650e-01, 4.4099240e-01, 1.7747380e-01); + positions[520] = Vec3( 3.0879580e-01, 3.5962220e-01, 2.2668340e-01); + positions[521] = Vec3( 2.9198270e-01, 5.0655710e-01, 2.4655760e-01); + positions[522] = Vec3( 3.8346200e-01, -2.8443150e-01, -8.3961770e-01); + positions[523] = Vec3( 4.1227770e-01, -2.9408340e-01, -9.3409110e-01); + positions[524] = Vec3( 4.5498420e-01, -3.3552520e-01, -7.8643110e-01); + positions[525] = Vec3( 5.4535540e-01, 1.2249720e-01, -4.0869350e-01); + positions[526] = Vec3( 6.0755050e-01, 1.6343320e-01, -3.4805580e-01); + positions[527] = Vec3( 4.8362230e-01, 8.8573600e-02, -3.4405000e-01); + positions[528] = Vec3( 1.3637990e-01, -3.3186850e-01, 1.0338270e-01); + positions[529] = Vec3( 1.5761460e-01, -2.5187340e-01, 1.5683210e-01); + positions[530] = Vec3( 7.8556700e-02, -3.8461200e-01, 1.6118390e-01); + positions[531] = Vec3( 8.4245020e-01, 3.8084570e-01, -6.9184990e-01); + positions[532] = Vec3( 9.0750590e-01, 3.9283710e-01, -7.7288830e-01); + positions[533] = Vec3( 7.5053500e-01, 3.8878480e-01, -7.2751780e-01); + positions[534] = Vec3( 2.7768360e-01, -8.5899240e-01, -5.3138620e-01); + positions[535] = Vec3( 2.8386750e-01, -7.7018020e-01, -5.6323660e-01); + positions[536] = Vec3( 3.4891330e-01, -9.1242960e-01, -5.6853820e-01); + positions[537] = Vec3( 2.6823810e-01, -7.8504070e-01, 6.9926380e-01); + positions[538] = Vec3( 3.3824260e-01, -8.3764610e-01, 7.3839250e-01); + positions[539] = Vec3( 3.0089590e-01, -6.9098950e-01, 7.0290360e-01); + positions[540] = Vec3( 9.5946000e-02, 5.9757730e-01, 8.8417370e-01); + positions[541] = Vec3( 1.9084960e-01, 5.8892180e-01, 8.6811780e-01); + positions[542] = Vec3( 7.0090900e-02, 6.3001980e-01, 9.7622150e-01); + positions[543] = Vec3(-3.2687830e-01, -9.5478000e-03, 2.1684540e-01); + positions[544] = Vec3(-3.2605730e-01, -1.4225700e-02, 3.1463820e-01); + positions[545] = Vec3(-2.7582100e-01, -8.4479800e-02, 1.8809180e-01); + positions[546] = Vec3(-8.3433230e-01, -5.5202940e-01, 2.1864880e-01); + positions[547] = Vec3(-8.2396710e-01, -5.4694370e-01, 3.1266070e-01); + positions[548] = Vec3(-9.3264700e-01, -5.5452020e-01, 1.9359510e-01); + positions[549] = Vec3(-3.7479050e-01, 2.2505660e-01, 7.1205330e-01); + positions[550] = Vec3(-4.7509020e-01, 2.3675960e-01, 7.1906840e-01); + positions[551] = Vec3(-3.3344270e-01, 3.0911900e-01, 7.2096390e-01); + positions[552] = Vec3( 5.4909720e-01, -6.8048160e-01, 7.2400200e-02); + positions[553] = Vec3( 6.0527360e-01, -6.6696760e-01, 1.5170900e-01); + positions[554] = Vec3( 5.8614280e-01, -6.1178520e-01, 1.7524700e-02); + positions[555] = Vec3(-2.3127640e-01, 9.0287820e-01, -1.3411380e-01); + positions[556] = Vec3(-2.8615520e-01, 9.5668910e-01, -1.9830460e-01); + positions[557] = Vec3(-2.9306830e-01, 8.7146310e-01, -6.8234400e-02); + positions[558] = Vec3(-5.4794480e-01, 6.9927600e-02, 4.9211700e-02); + positions[559] = Vec3(-4.8467110e-01, 1.3673600e-02, 9.6662900e-02); + positions[560] = Vec3(-5.5944570e-01, 3.5041600e-02, -4.0422400e-02); + positions[561] = Vec3(-4.0842490e-01, -6.1610810e-01, 5.3013490e-01); + positions[562] = Vec3(-3.5055240e-01, -6.7988460e-01, 4.9398580e-01); + positions[563] = Vec3(-4.6296070e-01, -6.7880320e-01, 5.8633470e-01); + positions[564] = Vec3( 4.6585780e-01, 7.8746100e-01, -1.2817710e-01); + positions[565] = Vec3( 5.3858490e-01, 8.3094890e-01, -7.7410200e-02); + positions[566] = Vec3( 4.0552000e-01, 7.4979180e-01, -6.1891900e-02); + positions[567] = Vec3(-1.6560700e-02, -3.7062430e-01, -3.6569060e-01); + positions[568] = Vec3(-9.0792700e-02, -4.1378610e-01, -3.2720710e-01); + positions[569] = Vec3( 5.1374900e-02, -4.3774530e-01, -3.4403280e-01); + positions[570] = Vec3(-5.9512760e-01, 1.7073000e-02, -2.2772060e-01); + positions[571] = Vec3(-5.8225940e-01, 7.1421900e-02, -3.0604790e-01); + positions[572] = Vec3(-6.2819960e-01, -6.3276600e-02, -2.6202260e-01); + positions[573] = Vec3(-4.7641750e-01, -4.2323550e-01, 8.9604240e-01); + positions[574] = Vec3(-5.4796980e-01, -4.1341290e-01, 8.3129580e-01); + positions[575] = Vec3(-4.6422920e-01, -5.2061790e-01, 8.9834640e-01); + positions[576] = Vec3( 1.4489300e-02, -8.9340740e-01, -3.4831200e-02); + positions[577] = Vec3(-6.9252500e-02, -9.1064710e-01, -8.0576000e-02); + positions[578] = Vec3( 8.8146500e-02, -9.1521790e-01, -9.6184600e-02); + positions[579] = Vec3(-6.0237270e-01, 6.8170090e-01, 6.7672100e-02); + positions[580] = Vec3(-6.3353490e-01, 6.5944010e-01, -1.4737000e-02); + positions[581] = Vec3(-6.7945440e-01, 7.0260310e-01, 1.2553510e-01); + positions[582] = Vec3(-7.9759390e-01, -4.8566970e-01, -8.8075620e-01); + positions[583] = Vec3(-7.6587590e-01, -4.4277470e-01, -9.5861500e-01); + positions[584] = Vec3(-8.8262650e-01, -4.4354590e-01, -8.6497650e-01); + positions[585] = Vec3( 6.0913180e-01, 7.5063640e-01, -3.7944500e-01); + positions[586] = Vec3( 6.8958950e-01, 8.0236210e-01, -3.5044320e-01); + positions[587] = Vec3( 5.5351750e-01, 7.5362410e-01, -2.9669720e-01); + positions[588] = Vec3( 7.4485800e-01, 5.3041050e-01, -4.4708420e-01); + positions[589] = Vec3( 7.0182180e-01, 6.1806940e-01, -4.3652910e-01); + positions[590] = Vec3( 8.0156580e-01, 5.2857300e-01, -5.2411300e-01); + positions[591] = Vec3(-6.9004280e-01, -5.9012070e-01, -2.9270410e-01); + positions[592] = Vec3(-7.1539690e-01, -6.8384200e-01, -2.8572180e-01); + positions[593] = Vec3(-5.9319910e-01, -5.8219810e-01, -2.7391860e-01); + positions[594] = Vec3(-2.0769030e-01, -9.0263320e-01, 8.2559380e-01); + positions[595] = Vec3(-1.2326710e-01, -9.0347650e-01, 7.7889800e-01); + positions[596] = Vec3(-2.4674410e-01, -8.1114260e-01, 8.1400270e-01); + positions[597] = Vec3(-5.9770390e-01, -2.5353030e-01, 3.7815410e-01); + positions[598] = Vec3(-5.7799760e-01, -1.8503970e-01, 4.3781640e-01); + positions[599] = Vec3(-6.3056510e-01, -1.9169960e-01, 3.0646360e-01); + positions[600] = Vec3( 2.5756560e-01, -9.0983610e-01, -2.2681580e-01); + positions[601] = Vec3( 3.3909840e-01, -9.6122750e-01, -2.1952540e-01); + positions[602] = Vec3( 2.5286730e-01, -8.8095350e-01, -3.1936560e-01); + positions[603] = Vec3(-5.7980030e-01, 4.5624440e-01, -4.8053250e-01); + positions[604] = Vec3(-5.0283550e-01, 4.0235700e-01, -4.7629430e-01); + positions[605] = Vec3(-5.5234760e-01, 5.5030960e-01, -4.6445780e-01); + positions[606] = Vec3( 2.6417710e-01, 3.6149920e-01, 5.5726940e-01); + positions[607] = Vec3( 1.8510390e-01, 3.4649300e-01, 6.1450570e-01); + positions[608] = Vec3( 2.5328370e-01, 4.4988030e-01, 5.1753010e-01); + positions[609] = Vec3( 8.0108540e-01, -7.3935090e-01, -4.6186460e-01); + positions[610] = Vec3( 8.1693510e-01, -7.9012220e-01, -3.8198140e-01); + positions[611] = Vec3( 8.8304810e-01, -6.9238110e-01, -4.8097940e-01); + positions[612] = Vec3(-5.8628640e-01, 1.5133800e-02, -5.2805090e-01); + positions[613] = Vec3(-5.0874980e-01, 5.8718200e-02, -5.5884230e-01); + positions[614] = Vec3(-6.4503990e-01, 1.9133400e-02, -6.0165090e-01); + positions[615] = Vec3( 7.6453220e-01, -5.9994620e-01, 2.8797170e-01); + positions[616] = Vec3( 7.0859250e-01, -5.4012040e-01, 3.3515640e-01); + positions[617] = Vec3( 7.9449730e-01, -6.7260900e-01, 3.4844210e-01); + positions[618] = Vec3(-4.1271350e-01, 6.8162960e-01, -6.2517570e-01); + positions[619] = Vec3(-3.4841290e-01, 6.1054470e-01, -6.4194430e-01); + positions[620] = Vec3(-3.5808100e-01, 7.5958210e-01, -6.0333290e-01); + positions[621] = Vec3(-2.3867290e-01, 5.9441400e-02, 9.1386800e-01); + positions[622] = Vec3(-2.9103650e-01, -1.4337800e-02, 9.5259360e-01); + positions[623] = Vec3(-2.8602000e-01, 1.0405050e-01, 8.3648420e-01); + positions[624] = Vec3( 6.2908620e-01, -6.6369160e-01, -8.8313160e-01); + positions[625] = Vec3( 5.3309000e-01, -6.6824080e-01, -8.8386380e-01); + positions[626] = Vec3( 6.6687380e-01, -7.2037270e-01, -8.1674370e-01); + positions[627] = Vec3( 2.5101170e-01, -8.8838680e-01, 2.2900940e-01); + positions[628] = Vec3( 2.4302200e-01, -8.1686710e-01, 1.6969450e-01); + positions[629] = Vec3( 3.4457660e-01, -8.9596990e-01, 2.4839760e-01); + positions[630] = Vec3(-9.1418940e-01, 8.0389630e-01, 7.8826000e-01); + positions[631] = Vec3(-8.3833600e-01, 7.4209380e-01, 7.8290720e-01); + positions[632] = Vec3(-9.9161100e-01, 7.5608500e-01, 8.2971860e-01); + positions[633] = Vec3( 7.9708930e-01, -3.2882190e-01, 7.1789600e-01); + positions[634] = Vec3( 8.5609970e-01, -2.5716920e-01, 7.4938090e-01); + positions[635] = Vec3( 7.9853320e-01, -3.2248890e-01, 6.2155040e-01); + positions[636] = Vec3( 7.9743030e-01, -6.0061740e-01, 7.6822330e-01); + positions[637] = Vec3( 8.2105340e-01, -5.0895770e-01, 7.5902860e-01); + positions[638] = Vec3( 7.2970170e-01, -6.0508550e-01, 8.3860140e-01); + positions[639] = Vec3(-1.1738970e-01, -5.9305270e-01, 7.0381050e-01); + positions[640] = Vec3(-1.5290840e-01, -6.5518590e-01, 6.3431800e-01); + positions[641] = Vec3(-1.6038250e-01, -5.0776740e-01, 6.8496070e-01); + positions[642] = Vec3( 5.8567050e-01, 3.6131160e-01, 3.0656670e-01); + positions[643] = Vec3( 5.1450330e-01, 4.2381370e-01, 2.6162660e-01); + positions[644] = Vec3( 5.3597340e-01, 3.2574600e-01, 3.8272470e-01); + positions[645] = Vec3(-7.5114680e-01, 3.5944460e-01, 2.4369600e-01); + positions[646] = Vec3(-8.1938720e-01, 4.1907000e-01, 2.7265900e-01); + positions[647] = Vec3(-7.8315770e-01, 3.2541650e-01, 1.6165560e-01); system.addForce(amoebaVdwForce); @@ -1284,654 +1284,654 @@ void testVdwWater(int includeVdwDispersionCorrection) { expectedEnergy = 4.0349101e+03; } - expectedForces[0] = Vec3( 2.3025909e+02, -1.0422757e+01, -2.1413965e+02); - expectedForces[1] = Vec3( 1.1261936e+02, 5.5882575e+02, 9.6539143e+01); - expectedForces[2] = Vec3( -8.8436857e+01, -4.4737313e+01, 2.5242022e+02); - expectedForces[3] = Vec3( 6.3548886e+02, -1.9582636e+02, -1.2229882e+02); - expectedForces[4] = Vec3( -3.9513809e+02, -1.3738635e+02, -1.2488717e+02); - expectedForces[5] = Vec3( 6.8771170e+00, 9.1574345e+01, -1.3865672e+00); - expectedForces[6] = Vec3( 3.6928792e+02, -7.1025648e+01, 5.2550320e+02); - expectedForces[7] = Vec3( 1.5531325e+02, -7.9256260e+02, 3.8119809e+02); - expectedForces[8] = Vec3( 1.5408049e+02, 1.4633285e+02, -5.4573735e+02); - expectedForces[9] = Vec3( -3.2549641e+02, 2.8613802e+01, 1.8082150e+02); - expectedForces[10] = Vec3( 1.9968249e+02, -7.7742415e+01, -4.2188467e+02); - expectedForces[11] = Vec3( 4.6645952e+01, 2.1362909e+01, 5.7120135e+01); - expectedForces[12] = Vec3( 4.2971265e+01, -4.2927865e+01, -7.6319121e+02); - expectedForces[13] = Vec3( 2.1889551e+02, -5.1806784e+01, 7.6637073e+01); - expectedForces[14] = Vec3( -3.0028991e+02, 9.0479382e+01, 1.3199449e+02); - expectedForces[15] = Vec3( -1.8041801e+00, -1.2176813e+03, -5.9679371e+02); - expectedForces[16] = Vec3( -1.4773339e+02, -1.2582057e+02, 8.4242040e+02); - expectedForces[17] = Vec3( 6.8633312e+02, -2.4864325e+01, 1.0675519e+01); - expectedForces[18] = Vec3( 4.8211733e+02, -2.2044742e+02, 1.8105309e+02); - expectedForces[19] = Vec3( -2.1956736e+02, 5.4786741e+02, -1.4827263e+02); - expectedForces[20] = Vec3( -1.0476100e+02, -1.6922280e+02, 8.3220473e+01); - expectedForces[21] = Vec3( 5.5455350e+01, 1.7851224e+02, 6.0598643e+02); - expectedForces[22] = Vec3( 7.1915871e+00, -1.6455057e+01, -6.3929797e+00); - expectedForces[23] = Vec3( -2.4371864e+02, -7.0765288e+02, -1.7820148e+02); - expectedForces[24] = Vec3( -4.3715367e+02, 2.8707226e+02, 2.2558361e+02); - expectedForces[25] = Vec3( 2.3735557e+00, -4.2064130e+00, 2.5933632e+01); - expectedForces[26] = Vec3( 1.0192415e+02, 5.3205842e+01, -2.0158900e+02); - expectedForces[27] = Vec3( -5.1276812e+02, 2.4860179e+02, 2.5150125e+02); - expectedForces[28] = Vec3( 3.9608987e+02, -4.0544816e+01, -2.1579831e+02); - expectedForces[29] = Vec3( -2.5926005e+02, -1.1691294e+02, -4.7278417e+02); - expectedForces[30] = Vec3( -1.1036158e+02, 3.3229287e+01, 8.8351491e+01); - expectedForces[31] = Vec3( -4.1178603e+00, 1.2957632e+00, 1.2617868e+00); - expectedForces[32] = Vec3( 1.9401524e+02, 1.0030314e+02, 3.0386141e+01); - expectedForces[33] = Vec3( 1.0870981e+02, 2.1865882e+02, 6.7672725e+02); - expectedForces[34] = Vec3( 3.6812338e+01, -2.9347382e-01, 1.2959790e+01); - expectedForces[35] = Vec3( -5.5738560e+01, 2.2268442e+02, -1.4911862e+02); - expectedForces[36] = Vec3( -1.6659719e+02, 8.1941190e+01, 7.8132996e+01); - expectedForces[37] = Vec3( -1.1985659e+02, 7.1891763e+01, -3.2559738e+02); - expectedForces[38] = Vec3( 1.4441653e+02, 4.1824194e+02, 3.4293255e+01); - expectedForces[39] = Vec3( 1.1307312e+02, -3.4981802e+02, -1.0676819e+02); - expectedForces[40] = Vec3( -1.2857487e+02, -4.0798950e+01, -1.7800009e+02); - expectedForces[41] = Vec3( -4.1244991e+02, 2.3439565e+02, 3.8546709e+02); - expectedForces[42] = Vec3( 2.1799653e+02, 2.9397348e+02, -3.8955146e+02); - expectedForces[43] = Vec3( -9.4254462e+01, 5.0157547e+01, 1.3707146e+02); - expectedForces[44] = Vec3( 8.0520929e+02, -1.0228045e+03, -4.5813594e+01); - expectedForces[45] = Vec3( 5.3451125e+02, -7.0725115e+02, -2.3828883e+02); - expectedForces[46] = Vec3( 3.6991801e+02, -1.0410466e+03, 8.4889413e+02); - expectedForces[47] = Vec3( 5.8096458e+01, 2.3859368e+02, 7.3104979e+01); - expectedForces[48] = Vec3( -1.3230378e+03, 7.1827816e+02, 9.4372946e+02); - expectedForces[49] = Vec3( -4.2398413e+02, -3.6766481e+02, -1.6666711e+02); - expectedForces[50] = Vec3( 8.6374766e+00, -2.7870227e+02, 3.0621233e+02); - expectedForces[51] = Vec3( -2.4404981e+02, 1.0510491e+03, -3.5202340e+02); - expectedForces[52] = Vec3( 1.7461155e+02, 1.3419948e+02, 5.0279733e+02); - expectedForces[53] = Vec3( 9.7089193e+01, -1.4826120e+02, -2.3426711e+02); - expectedForces[54] = Vec3( -1.0647432e+02, 2.3266543e+02, -3.5025025e+02); - expectedForces[55] = Vec3( -1.9951717e+02, -1.0804258e+02, 6.2114265e+01); - expectedForces[56] = Vec3( 2.5354284e+02, -3.5074926e+02, -2.9176946e+01); - expectedForces[57] = Vec3( -8.8328002e+02, -1.8937053e+02, 2.0772189e+02); - expectedForces[58] = Vec3( 4.5809698e+01, -1.8636513e+00, 1.6742910e+01); - expectedForces[59] = Vec3( 8.6670673e+01, 1.2653519e+02, 2.0046372e+02); - expectedForces[60] = Vec3( -9.6142275e+02, 1.1800289e+03, 1.0064471e+02); - expectedForces[61] = Vec3( -6.9751453e+01, -1.9324691e+02, 2.2638891e+01); - expectedForces[62] = Vec3( 1.3671815e+02, 1.0129231e+01, -6.1136892e+01); - expectedForces[63] = Vec3( 7.6032938e+02, -1.9779542e+02, -2.5706161e+01); - expectedForces[64] = Vec3( -9.8966607e+00, 3.6294058e+02, -2.3247376e+02); - expectedForces[65] = Vec3( -1.3142673e+02, 9.9368000e+00, 1.4225069e+02); - expectedForces[66] = Vec3( 5.2691625e+01, -4.0618331e+02, -1.0942115e+02); - expectedForces[67] = Vec3( 5.8137742e+01, 2.1942441e+02, -1.7191686e+02); - expectedForces[68] = Vec3( 1.2480778e+02, 2.4086799e+01, -1.9588545e+02); - expectedForces[69] = Vec3( 2.4577512e+02, -2.3516051e+01, 2.3764379e+02); - expectedForces[70] = Vec3( 4.2298797e+01, 8.6807583e+01, 2.9276129e+02); - expectedForces[71] = Vec3( 3.0309915e+01, -3.4686002e+02, 1.0849989e+02); - expectedForces[72] = Vec3( 5.5170999e+02, -1.5797913e+02, 9.8379834e+01); - expectedForces[73] = Vec3( -5.3706921e+02, 2.2236470e+02, 2.7548665e+02); - expectedForces[74] = Vec3( -2.7734936e+02, -4.2949693e+02, -8.2303469e+02); - expectedForces[75] = Vec3( 1.1749001e+03, 9.2734627e+02, -2.6342291e+02); - expectedForces[76] = Vec3( -1.2345216e+02, -6.6220297e+01, 1.1022778e+02); - expectedForces[77] = Vec3( -4.4861284e+01, -7.4560959e+01, -8.0791275e+01); - expectedForces[78] = Vec3( 1.7692476e+01, -9.9067626e+02, -3.3083363e+02); - expectedForces[79] = Vec3( 6.4276566e+01, 5.1865608e+02, 4.1241764e+02); - expectedForces[80] = Vec3( 6.5867999e+02, 2.0995465e+02, -5.0989840e+02); - expectedForces[81] = Vec3( -5.2826435e+02, -1.3719887e+02, 1.9730314e+02); - expectedForces[82] = Vec3( 2.3329314e+02, 5.1589944e+01, -3.3942818e+02); - expectedForces[83] = Vec3( -2.5756193e+00, 1.3788257e+02, 1.3074778e+02); - expectedForces[84] = Vec3( -2.8925811e+01, 8.8185346e+01, 1.1547804e+02); - expectedForces[85] = Vec3( -3.3582542e+01, -1.3079843e+02, 3.4774799e+02); - expectedForces[86] = Vec3( -5.9585326e+01, -3.7973755e+01, 1.0206767e+01); - expectedForces[87] = Vec3( -7.1691223e+01, -1.9547311e+02, 9.3856472e+02); - expectedForces[88] = Vec3( 1.4832977e+02, 4.2005795e+02, 2.7235044e+01); - expectedForces[89] = Vec3( 8.6221698e+00, -1.3935906e+01, -2.5473157e+00); - expectedForces[90] = Vec3( 3.0044348e+02, 3.4320406e+02, 2.5305998e+02); - expectedForces[91] = Vec3( -1.6694013e+02, 7.4645776e+02, 3.3266168e+01); - expectedForces[92] = Vec3( 1.6931562e+02, -2.3972286e+01, -3.0802865e+02); - expectedForces[93] = Vec3( -2.5931152e+02, -9.7825375e+01, -5.5598386e+02); - expectedForces[94] = Vec3( -7.8473519e+01, -2.6244561e+02, 2.9622027e+02); - expectedForces[95] = Vec3( 1.5788473e+02, 2.9806605e+02, 1.8283700e+02); - expectedForces[96] = Vec3( -4.2033208e+02, 4.8745845e+02, 9.7957219e+01); - expectedForces[97] = Vec3( 1.3261733e+00, 3.7143158e+00, -1.8329960e+00); - expectedForces[98] = Vec3( 7.4741051e+02, 1.0482696e+03, 1.7182445e+02); - expectedForces[99] = Vec3( 2.0366606e+02, 1.1586652e+02, 1.5482927e+03); - expectedForces[100] = Vec3( 5.7569884e+02, -2.2068597e+02, -1.9305186e+02); - expectedForces[101] = Vec3( -2.4259775e+02, -6.1359858e+01, -7.5753918e+01); - expectedForces[102] = Vec3( 2.4382837e+02, 1.3660693e+01, -2.8717824e+02); - expectedForces[103] = Vec3( -4.1914381e+02, -1.4506334e+02, 7.7692658e+01); - expectedForces[104] = Vec3( 9.5422158e+01, -1.4261849e+01, 1.0122453e+02); - expectedForces[105] = Vec3( -6.1222151e+02, 6.1398147e+01, 3.2961693e+02); - expectedForces[106] = Vec3( -2.7982116e+02, -3.7564793e+02, -2.4318658e+02); - expectedForces[107] = Vec3( 8.2892383e+01, 1.1992522e+01, 2.4802899e+01); - expectedForces[108] = Vec3( -3.3626753e+02, -7.8892295e+01, 8.1184535e+02); - expectedForces[109] = Vec3( -4.6396103e+01, 3.1165111e+01, -3.5184949e+01); - expectedForces[110] = Vec3( 4.6295297e+02, -8.0135823e+01, -3.2963637e+02); - expectedForces[111] = Vec3( 5.5325945e+02, 3.8213691e+02, -5.9449911e+02); - expectedForces[112] = Vec3( -6.1770559e+02, 2.2322880e+02, -2.1022934e+01); - expectedForces[113] = Vec3( 2.3716825e+02, -3.8085281e+02, 4.9618193e+02); - expectedForces[114] = Vec3( 2.9972570e+02, 3.3773759e+02, 3.4933501e+02); - expectedForces[115] = Vec3( 1.9913039e+02, -3.2035626e+02, -9.7987777e+01); - expectedForces[116] = Vec3( -2.3506456e+02, 4.0030561e+02, -6.2604809e+02); - expectedForces[117] = Vec3( 6.0408777e+02, 5.6271523e+02, -5.8742635e+02); - expectedForces[118] = Vec3( -5.0707285e+02, 7.8511351e+02, -1.7561830e+02); - expectedForces[119] = Vec3( 5.6759945e+00, 6.9735233e+00, -9.8853787e+00); - expectedForces[120] = Vec3( 1.1918531e+02, -5.6200785e+02, 3.2333502e+02); - expectedForces[121] = Vec3( 5.1801315e+02, -3.4460898e+02, 1.1488242e+02); - expectedForces[122] = Vec3( 7.5859703e+00, 6.9528951e+01, -6.2437444e+00); - expectedForces[123] = Vec3( 1.1990899e+03, -1.2507886e+01, 1.1906562e+03); - expectedForces[124] = Vec3( 2.6001536e+02, -9.5041373e+01, -4.2547252e+02); - expectedForces[125] = Vec3( -3.5601586e+01, 9.1460220e+02, 6.2306102e+02); - expectedForces[126] = Vec3( -3.8254176e+01, 2.4796243e+02, 3.0638741e+02); - expectedForces[127] = Vec3( -3.8798311e+02, 1.2532794e+02, -3.1926601e+01); - expectedForces[128] = Vec3( 5.7672682e+01, 1.7487900e+02, -1.0319581e+02); - expectedForces[129] = Vec3( 4.4276215e+02, -1.5517993e+02, 3.8122873e+02); - expectedForces[130] = Vec3( -2.8119980e+02, -2.6530936e+02, 4.3545814e+01); - expectedForces[131] = Vec3( 5.9375768e+00, 1.6335780e+01, -3.6204644e+02); - expectedForces[132] = Vec3( 5.9733834e+02, -2.9843602e+02, 1.0541092e+03); - expectedForces[133] = Vec3( -3.4568461e+02, 2.2794808e+02, -8.4675886e+01); - expectedForces[134] = Vec3( -6.7882706e+01, -4.5016799e+02, -1.9387646e+02); - expectedForces[135] = Vec3( 5.6125478e+02, -1.1741092e+03, 1.4214256e+02); - expectedForces[136] = Vec3( 1.2766648e+02, 1.2519441e+02, -4.4359129e+02); - expectedForces[137] = Vec3( -2.7235507e+01, -1.0871423e+01, 3.2406976e+01); - expectedForces[138] = Vec3( -1.2110689e+03, 1.3038667e+02, -7.5331947e+02); - expectedForces[139] = Vec3( 3.2504988e+02, -7.1577942e+02, -2.4351454e+02); - expectedForces[140] = Vec3( 2.6466925e+02, 3.6878498e+02, -6.2044711e+01); - expectedForces[141] = Vec3( -6.2647276e+02, -4.7112562e+02, -6.1885184e+01); - expectedForces[142] = Vec3( 3.0996699e+01, 3.1033732e+02, -5.7493337e+02); - expectedForces[143] = Vec3( 2.4664962e+01, 7.8306665e+02, 3.7907751e+02); - expectedForces[144] = Vec3( -1.9847551e+02, -3.0052499e+02, -6.5192951e+01); - expectedForces[145] = Vec3( -5.0686773e+02, 1.1972933e+02, 3.6202910e+02); - expectedForces[146] = Vec3( 4.0004521e+02, -4.3205645e+02, 2.8583074e+02); - expectedForces[147] = Vec3( -2.9447542e+01, 6.3434099e+02, -6.5189179e+02); - expectedForces[148] = Vec3( 4.1588516e+02, -1.5534873e+02, -1.1031323e+01); - expectedForces[149] = Vec3( 1.2761543e+01, -5.6871456e+01, 2.8032565e+02); - expectedForces[150] = Vec3( -4.7527199e+01, 6.2549647e+02, -8.5007589e+02); - expectedForces[151] = Vec3( 1.6598949e+01, 1.1210199e+02, 2.0667266e+02); - expectedForces[152] = Vec3( -2.4012423e+00, -6.1728962e+01, -1.5057977e+01); - expectedForces[153] = Vec3( -3.6934056e+02, 2.3087063e+02, -3.3268511e+02); - expectedForces[154] = Vec3( 1.2658460e+02, 4.1809355e+02, 1.9550635e+02); - expectedForces[155] = Vec3( -1.9528152e+02, -1.9035919e+02, 1.4986704e+02); - expectedForces[156] = Vec3( -5.9608803e+00, 2.7258190e+02, 5.5318395e+02); - expectedForces[157] = Vec3( -1.0545084e+01, -1.8397001e+00, -3.3615498e+00); - expectedForces[158] = Vec3( -4.0827462e+02, -6.4070993e+01, -2.6614992e+02); - expectedForces[159] = Vec3( -1.5773827e+02, 4.7708702e+02, -9.9622711e+02); - expectedForces[160] = Vec3( 8.3896122e+01, 2.5959601e+02, 1.7728081e+02); - expectedForces[161] = Vec3( -2.4859055e+02, 8.1617294e+01, 2.7905586e+02); - expectedForces[162] = Vec3( 1.3694593e+02, -6.2640483e+02, -2.5308878e+02); - expectedForces[163] = Vec3( -1.5156337e+02, 1.1567379e+02, 1.8384602e+02); - expectedForces[164] = Vec3( -1.4794785e+02, -8.0381965e+01, 9.4028021e+02); - expectedForces[165] = Vec3( -3.5851252e+02, 2.6066489e+02, -4.1225343e+01); - expectedForces[166] = Vec3( 1.0820389e+02, -8.3485138e+01, 9.5047812e+01); - expectedForces[167] = Vec3( 2.0019411e+02, 5.0864719e+02, -4.8662239e+01); - expectedForces[168] = Vec3( -3.0716707e+02, -9.8820762e+02, 1.3660536e+01); - expectedForces[169] = Vec3( 8.5788590e+02, -1.0335921e+02, -2.2197815e+02); - expectedForces[170] = Vec3( 9.8072705e+00, 6.6224870e+02, -1.1594055e+02); - expectedForces[171] = Vec3( -3.6572453e+01, 2.4062731e+02, 1.7831682e+02); - expectedForces[172] = Vec3( -2.1274187e+00, -2.5471785e+02, -2.5813525e+02); - expectedForces[173] = Vec3( 3.4763673e+02, -2.0753062e+02, 7.5125390e+02); - expectedForces[174] = Vec3( 2.9010685e+01, -4.1894498e+02, -6.3847846e+02); - expectedForces[175] = Vec3( 3.0255245e+02, 2.5945698e+02, 2.3530662e+01); - expectedForces[176] = Vec3( -2.0827676e+01, 2.2568888e+01, 1.0890440e+01); - expectedForces[177] = Vec3( 2.2415739e+02, 3.5720682e+02, -8.7208211e+01); - expectedForces[178] = Vec3( -2.9808276e+02, 7.0108444e+01, -1.5361211e+02); - expectedForces[179] = Vec3( 2.3882234e+02, -2.6764176e+02, -1.7847229e+01); - expectedForces[180] = Vec3( -4.7380966e+02, 5.2547306e+01, 7.4446526e+02); - expectedForces[181] = Vec3( 4.2804072e+00, -2.2456284e+02, -2.0288206e+02); - expectedForces[182] = Vec3( 2.5474630e+00, 2.5211778e+01, 1.2675317e+01); - expectedForces[183] = Vec3( -1.4519676e+02, -1.7268277e+02, -8.4750014e+02); - expectedForces[184] = Vec3( -1.6850633e+02, 9.5223081e+02, -2.5415253e+02); - expectedForces[185] = Vec3( -2.1600185e+02, -1.6313340e+02, 1.8746411e+02); - expectedForces[186] = Vec3( 4.5719348e+01, -5.8877840e+01, -1.1199622e+02); - expectedForces[187] = Vec3( -9.0377199e+01, 2.2045926e+02, -3.2532356e+02); - expectedForces[188] = Vec3( -1.4523032e+02, -2.2127499e+02, 1.1526636e+02); - expectedForces[189] = Vec3( 1.9857975e+02, -1.8170037e+02, 3.2016150e+02); - expectedForces[190] = Vec3( 1.5659789e+02, 5.2984420e+01, -1.0121553e+02); - expectedForces[191] = Vec3( 1.3925504e+01, -1.1627739e+02, 1.7106106e+00); - expectedForces[192] = Vec3( 1.7560737e+01, 3.1275548e+02, 1.4568181e+02); - expectedForces[193] = Vec3( 8.5129168e-01, 3.2688468e+01, -2.0471785e+02); - expectedForces[194] = Vec3( 2.5640904e+02, -1.8345358e+02, 3.3082812e+02); - expectedForces[195] = Vec3( 1.5159266e+02, -7.9091822e+02, 7.6475475e+02); - expectedForces[196] = Vec3( 7.8546101e+02, 1.7887845e+02, -7.4508377e+01); - expectedForces[197] = Vec3( 6.9010029e+00, 2.1336674e+01, -7.8256484e+01); - expectedForces[198] = Vec3( -3.4033432e+01, -1.6471994e+02, -2.8721884e+02); - expectedForces[199] = Vec3( -1.2248359e+02, 5.3002993e+01, 3.5296174e+02); - expectedForces[200] = Vec3( 1.7497881e+02, 1.1744848e+02, 1.8127502e+02); - expectedForces[201] = Vec3( -1.1710882e+03, 8.7114752e+02, -1.3353036e+02); - expectedForces[202] = Vec3( 2.7510368e+02, -1.9393814e+02, 2.6671453e+02); - expectedForces[203] = Vec3( 7.3421287e+01, -3.8409917e+01, -1.0910368e+02); - expectedForces[204] = Vec3( -8.7394869e+02, -1.2323430e+03, -1.3693068e+02); - expectedForces[205] = Vec3( 2.5439149e+02, 2.4002077e+02, 3.0231859e+02); - expectedForces[206] = Vec3( -9.8167431e+01, 3.1515278e+02, -2.5512038e+02); - expectedForces[207] = Vec3( 2.7501189e+02, -4.9189774e+02, 4.5827877e+02); - expectedForces[208] = Vec3( -8.2333908e+02, -7.0609881e+02, 2.9188070e+02); - expectedForces[209] = Vec3( -2.9200330e+02, 1.9955124e+02, -7.9227826e+00); - expectedForces[210] = Vec3( 8.0151971e+02, 3.8996996e+02, -1.9508756e+02); - expectedForces[211] = Vec3( -6.2168096e+01, 2.4323951e+01, 9.8845638e+01); - expectedForces[212] = Vec3( 2.2980428e+01, -6.2829693e+02, -7.5253154e+02); - expectedForces[213] = Vec3( -5.7502634e+02, 8.2310635e+02, 3.7934867e+02); - expectedForces[214] = Vec3( -8.9168889e+01, 5.0052167e+01, -8.6850564e+01); - expectedForces[215] = Vec3( 2.7414821e+02, -5.9725191e+01, -3.7278778e+00); - expectedForces[216] = Vec3( -5.3230933e+02, 4.7698725e+02, -2.5857751e+02); - expectedForces[217] = Vec3( 2.1615644e+02, 6.0001233e+01, -1.1880182e+02); - expectedForces[218] = Vec3( 2.9837823e+01, -3.9275454e+01, -4.3913571e+01); - expectedForces[219] = Vec3( -5.6516561e+02, -1.6539113e+02, 3.3185872e+02); - expectedForces[220] = Vec3( -1.5484833e+01, -1.0085566e+01, -2.8199778e+01); - expectedForces[221] = Vec3( 6.4295337e+02, -2.7398997e+02, 8.2320867e+02); - expectedForces[222] = Vec3( 3.3816540e+02, -1.8492046e+02, 8.6215770e+02); - expectedForces[223] = Vec3( 2.4367872e+02, 8.9527142e+01, -5.9973680e+02); - expectedForces[224] = Vec3( -6.1601439e+02, -5.3093862e+02, 4.1696221e+01); - expectedForces[225] = Vec3( 2.2521478e+02, -2.9234267e+02, 2.9760244e+02); - expectedForces[226] = Vec3( -1.2672295e+02, 2.5753736e+01, -1.6216252e+02); - expectedForces[227] = Vec3( 1.1136724e+02, 4.3446676e+00, -1.4045447e+01); - expectedForces[228] = Vec3( 3.5554849e+02, 7.7446255e+00, 5.8722356e+02); - expectedForces[229] = Vec3( -7.8313952e+02, -5.9206053e+01, 5.1181391e+02); - expectedForces[230] = Vec3( -9.5647729e+01, -4.6045792e+02, -3.1515210e+02); - expectedForces[231] = Vec3( 8.7273284e+01, 8.0310279e+02, -1.2212040e+03); - expectedForces[232] = Vec3( -9.0853819e+02, -7.6005570e+02, 1.8578569e+02); - expectedForces[233] = Vec3( 1.2061615e+02, -3.2834560e+02, 5.1291192e+01); - expectedForces[234] = Vec3( 6.0149262e+02, 1.6081852e+03, -1.0922015e+03); - expectedForces[235] = Vec3( -5.8087260e+01, -2.6676779e+02, -1.5006920e+02); - expectedForces[236] = Vec3( -1.0997771e+01, 1.3012815e+02, 5.8615633e+02); - expectedForces[237] = Vec3( 4.9821503e+02, -9.5783644e+01, -6.5708073e+02); - expectedForces[238] = Vec3( -4.9394992e+02, -7.0445435e+02, -1.5540228e+02); - expectedForces[239] = Vec3( 1.5710340e+01, 1.9170336e+02, 4.6707393e+02); - expectedForces[240] = Vec3( -1.2599557e+03, 5.6104975e+02, 6.5853210e+02); - expectedForces[241] = Vec3( 1.3032986e+01, -2.7481865e+01, 8.0373029e+00); - expectedForces[242] = Vec3( 1.4371505e+02, -5.2615293e+01, -3.7929456e+02); - expectedForces[243] = Vec3( 6.0025739e+01, 1.4474905e+02, 3.6414330e+02); - expectedForces[244] = Vec3( 4.5364033e+02, 7.0785823e+01, -2.9279112e+02); - expectedForces[245] = Vec3( -9.7012956e+01, -8.2545229e+01, -5.4567106e+01); - expectedForces[246] = Vec3( -3.6449281e+02, -5.6669832e+02, -3.5196038e+02); - expectedForces[247] = Vec3( 2.6571354e+02, -2.5051716e+02, -4.7199161e+01); - expectedForces[248] = Vec3( -4.7285701e+01, 1.7950093e+02, 8.0633971e+01); - expectedForces[249] = Vec3( 1.8035439e+02, 4.6977540e+02, 2.2589769e+02); - expectedForces[250] = Vec3( 5.9853399e+01, 1.5477006e+02, -1.7011806e+02); - expectedForces[251] = Vec3( -2.6084741e+02, -2.0538756e+02, 1.0269002e+02); - expectedForces[252] = Vec3( 4.0221722e+02, -1.0368371e+02, -1.3842460e+01); - expectedForces[253] = Vec3( -4.4264447e+02, -3.0334810e+02, 1.6740779e+02); - expectedForces[254] = Vec3( -1.7373662e+02, 1.5020202e+02, -3.3761418e+02); - expectedForces[255] = Vec3( 4.7508953e+01, -5.4028784e+02, -3.6291329e+01); - expectedForces[256] = Vec3( 5.4807168e+02, -2.0293664e+02, 5.5114363e+02); - expectedForces[257] = Vec3( -4.9787370e+01, 4.5106329e+01, -5.7524550e+01); - expectedForces[258] = Vec3( -5.1584935e+02, 1.5014186e+02, -6.6369834e+02); - expectedForces[259] = Vec3( -6.0140298e+01, -9.4127280e+01, 8.7495796e+01); - expectedForces[260] = Vec3( 8.0619588e+02, -2.1066454e+02, -5.9371508e+01); - expectedForces[261] = Vec3( 1.2817429e+02, -2.7044116e+02, 5.3213275e+02); - expectedForces[262] = Vec3( -4.1467442e-01, -1.3641138e+02, -8.5576287e+01); - expectedForces[263] = Vec3( -5.6508528e+01, 2.4091504e+01, -7.9236147e+01); - expectedForces[264] = Vec3( 1.4123799e+02, 2.1326444e+02, 1.9141445e+02); - expectedForces[265] = Vec3( 1.6579721e+02, -3.2221503e+02, -1.5197776e+02); - expectedForces[266] = Vec3( -2.5871222e+02, -2.6345996e+02, -1.1149413e+03); - expectedForces[267] = Vec3( -1.2859743e+02, -3.9214753e+02, -6.5874862e+02); - expectedForces[268] = Vec3( 1.7237157e+02, -2.8729010e+02, 3.2000889e+02); - expectedForces[269] = Vec3( 6.6312203e+02, 3.5683926e+02, 9.7235616e+01); - expectedForces[270] = Vec3( -1.1860349e+02, -4.3528895e+02, 1.1598672e+03); - expectedForces[271] = Vec3( 7.7135123e+01, -2.1671305e+02, -2.3088548e+02); - expectedForces[272] = Vec3( 7.2863708e+01, 5.2065158e+02, 1.5704752e+02); - expectedForces[273] = Vec3( -3.6727477e+02, -6.0885463e+01, 4.1193960e+01); - expectedForces[274] = Vec3( 5.4858881e+01, 1.6886577e+02, -1.1662392e+01); - expectedForces[275] = Vec3( 3.2070061e+01, -1.6138709e+01, -7.6648912e+00); - expectedForces[276] = Vec3( 2.5695892e+02, 7.7719531e+01, -8.3154765e+02); - expectedForces[277] = Vec3( -3.3460202e+01, -1.3077348e+02, 3.6110539e+01); - expectedForces[278] = Vec3( -4.1360402e+02, 2.7754335e+02, -1.1139467e+02); - expectedForces[279] = Vec3( 1.0012775e+02, 1.4365237e+03, 2.6972544e+02); - expectedForces[280] = Vec3( 7.8750024e+02, -2.3376123e+02, 9.5969232e+02); - expectedForces[281] = Vec3( -2.2493912e+02, -1.1444344e+01, -6.3713547e+01); - expectedForces[282] = Vec3( -9.4211966e+01, -3.9286586e+02, -7.0932607e+01); - expectedForces[283] = Vec3( 1.6192138e+02, 2.3010404e+02, -2.1511498e+02); - expectedForces[284] = Vec3( -4.9644702e+02, -1.1894844e+01, -4.7458477e+02); - expectedForces[285] = Vec3( -1.0151600e+02, -4.2789293e+02, 5.2698223e+02); - expectedForces[286] = Vec3( 1.1350409e+01, 1.5126445e+02, -5.2740587e+01); - expectedForces[287] = Vec3( -4.7715521e+02, -3.6476152e+02, -5.4346958e+02); - expectedForces[288] = Vec3( -9.4019721e+01, -2.4758228e+02, 4.2219712e+02); - expectedForces[289] = Vec3( 3.1525053e+01, 3.7927245e+02, -2.4577041e+02); - expectedForces[290] = Vec3( 4.4004025e+02, -9.4883983e+01, -6.9075632e+01); - expectedForces[291] = Vec3( -2.6553328e+02, -2.7059185e+02, 3.1145935e+02); - expectedForces[292] = Vec3( 1.1199463e+02, 9.0805870e+01, 8.0258804e+01); - expectedForces[293] = Vec3( 7.8056273e+01, -3.5931761e+01, -1.9249727e+02); - expectedForces[294] = Vec3( -1.2443366e+01, -1.4631721e+02, 7.9733561e+01); - expectedForces[295] = Vec3( -3.2866900e+02, 1.1527926e+02, -9.3135590e+01); - expectedForces[296] = Vec3( 7.5078643e+01, -7.2653837e+02, -1.0830908e+02); - expectedForces[297] = Vec3( 1.0361037e+02, 1.5478274e+02, 1.1293089e+03); - expectedForces[298] = Vec3( -2.4014663e+02, -5.6771824e+02, 1.5441974e+02); - expectedForces[299] = Vec3( -6.8441034e+01, -1.1226846e+02, -5.4497343e+02); - expectedForces[300] = Vec3( 2.9803689e+02, 1.0649462e+03, 2.5408768e+02); - expectedForces[301] = Vec3( 5.6356599e+01, -2.3035579e+02, 7.6928758e+01); - expectedForces[302] = Vec3( 1.0229494e+02, -1.9615696e+02, -3.2600199e+02); - expectedForces[303] = Vec3( -7.0312065e+01, -3.1170055e+02, 5.6453888e+02); - expectedForces[304] = Vec3( -7.0752582e+01, 1.2273280e+02, -1.6740503e+01); - expectedForces[305] = Vec3( 6.8972998e+02, -2.8067032e+02, 6.6502848e+01); - expectedForces[306] = Vec3( -8.8407472e+02, 3.7818347e+02, -1.2141945e+03); - expectedForces[307] = Vec3( -1.0445122e+02, -4.4818836e+02, -9.5227168e+00); - expectedForces[308] = Vec3( 8.3015802e+02, 5.0941309e+02, 3.2593793e+01); - expectedForces[309] = Vec3( 7.6887033e+02, 4.3490548e+02, -1.0826101e+03); - expectedForces[310] = Vec3( 1.4352949e+02, -3.9479802e+01, 1.7718790e+02); - expectedForces[311] = Vec3( -2.5204642e+02, -3.3888239e+02, -2.7365802e+02); - expectedForces[312] = Vec3( -4.4783121e+02, 4.4465580e+02, 9.2506336e+02); - expectedForces[313] = Vec3( -3.3390337e+01, -5.0097602e+02, -3.6812516e+02); - expectedForces[314] = Vec3( -4.1862341e+02, 1.9519764e+02, -2.4571211e+02); - expectedForces[315] = Vec3( -1.4176845e+02, -3.3767798e+01, 1.7800248e+02); - expectedForces[316] = Vec3( -4.7411046e+01, 2.3841278e+01, -1.5183689e+01); - expectedForces[317] = Vec3( 1.6723204e+01, 1.4145797e+02, -1.6930384e+01); - expectedForces[318] = Vec3( -8.4841167e+02, -2.1282818e+02, 8.1614626e+01); - expectedForces[319] = Vec3( 6.5941519e+00, -1.1472179e+02, -2.3181002e+02); - expectedForces[320] = Vec3( 2.2464095e+01, -5.7606215e+00, 5.2865780e+00); - expectedForces[321] = Vec3( 3.8063827e+02, 2.4597014e+02, -4.1947008e+01); - expectedForces[322] = Vec3( -3.1531672e+02, 3.5038104e+02, -3.2724191e+02); - expectedForces[323] = Vec3( 7.4741163e+01, 7.2296536e+01, 3.1768919e+02); - expectedForces[324] = Vec3( 7.9578966e+02, -1.5345175e+02, -7.1301288e+02); - expectedForces[325] = Vec3( -3.1387318e+01, 1.7528515e+01, -3.4100670e+01); - expectedForces[326] = Vec3( 9.3853572e-01, 6.8496077e+00, 1.2234894e+01); - expectedForces[327] = Vec3( -1.3099690e+02, -4.0135958e+02, -4.3248135e+02); - expectedForces[328] = Vec3( 4.3988113e+02, -1.5944416e+02, 5.4620163e+01); - expectedForces[329] = Vec3( 1.3509243e+01, 3.6990268e+00, -2.6251838e-01); - expectedForces[330] = Vec3( -8.7459998e+01, -6.4319025e+02, 2.2863360e+02); - expectedForces[331] = Vec3( -3.5181606e+02, 3.1131978e+02, 2.8037788e+02); - expectedForces[332] = Vec3( 1.9545884e+02, 4.3994512e+01, -2.5158598e+02); - expectedForces[333] = Vec3( 1.8100917e+00, 1.9534738e+02, 1.7181161e+02); - expectedForces[334] = Vec3( -1.1846876e+02, 1.5368782e+02, 2.2261016e+02); - expectedForces[335] = Vec3( 1.4866155e+02, -4.7983795e+02, 3.0361323e+02); - expectedForces[336] = Vec3( -7.7242468e+02, 2.0736079e+02, -8.6661236e+02); - expectedForces[337] = Vec3( -7.9875679e+00, -9.0946585e+02, -7.1617627e+01); - expectedForces[338] = Vec3( 2.2543457e+02, 2.0215639e+02, 4.4285374e+02); - expectedForces[339] = Vec3( -2.6252013e+02, -1.0336519e+02, -2.6630451e+02); - expectedForces[340] = Vec3( 5.0907589e+02, -1.2491931e+02, -4.3015857e+01); - expectedForces[341] = Vec3( -6.0362692e+01, 1.0025664e+02, -9.3389235e+01); - expectedForces[342] = Vec3( 5.8779874e+02, 3.7600030e+02, 2.5345454e+02); - expectedForces[343] = Vec3( -1.3661048e+02, 1.6498482e+02, -2.6789925e+01); - expectedForces[344] = Vec3( 4.9840419e+01, -1.2136315e+02, 2.5455320e+01); - expectedForces[345] = Vec3( 2.3324807e+02, -3.6601512e+02, 5.6798114e+01); - expectedForces[346] = Vec3( 5.5853546e+01, -4.9035168e+00, -5.8726331e+02); - expectedForces[347] = Vec3( -3.8918158e+01, 3.0380495e+02, 1.0944883e+01); - expectedForces[348] = Vec3( -2.6092065e+02, 4.3443036e+02, -1.3673862e+02); - expectedForces[349] = Vec3( 1.5195166e+02, 1.1879426e+01, -1.1429493e+02); - expectedForces[350] = Vec3( -8.5687107e+02, -1.7938881e+02, 4.5576455e+00); - expectedForces[351] = Vec3( -1.0117388e+03, -3.2686610e+02, 2.9733049e+02); - expectedForces[352] = Vec3( -2.3946369e+02, 4.9753786e+02, 7.2681440e+02); - expectedForces[353] = Vec3( 3.9085837e+01, 7.4391931e+00, 3.4179196e+00); - expectedForces[354] = Vec3( 1.0462977e+03, 4.3639578e+02, -5.7349371e+02); - expectedForces[355] = Vec3( 1.2715333e+02, -5.7907885e+02, 5.7463165e+02); - expectedForces[356] = Vec3( -1.5968981e+02, 2.2295605e+01, 6.3554487e+01); - expectedForces[357] = Vec3( -1.9666111e+02, -2.0286725e+02, -8.3590992e+01); - expectedForces[358] = Vec3( 5.9985006e+00, 2.9764307e+01, 3.1304672e+01); - expectedForces[359] = Vec3( 1.0409792e+02, 4.3974987e+02, -9.1530162e+02); - expectedForces[360] = Vec3( 2.9538724e+02, 1.4353710e+02, 2.1558768e+02); - expectedForces[361] = Vec3( -3.7974445e+02, -9.0749144e+01, 1.4531502e+02); - expectedForces[362] = Vec3( 3.7089093e+02, 2.2523397e+02, -2.9760698e+02); - expectedForces[363] = Vec3( -7.6884906e+01, -2.7486958e+02, 3.5671043e+02); - expectedForces[364] = Vec3( 4.3400097e+02, 2.2275226e+02, 5.9201087e+01); - expectedForces[365] = Vec3( 2.1177620e+02, -6.4990517e+02, -1.8431623e+02); - expectedForces[366] = Vec3( -8.2234148e+01, 4.9900036e+02, 3.0906858e+02); - expectedForces[367] = Vec3( -1.4784097e+02, 1.3442463e+02, -2.6811487e+02); - expectedForces[368] = Vec3( 2.2289541e+02, -4.1933983e+02, 1.3646246e+01); - expectedForces[369] = Vec3( -2.1199481e+02, 6.2103281e+01, 1.6049768e+02); - expectedForces[370] = Vec3( -2.9429845e+01, -1.3944740e+01, 1.6000003e+01); - expectedForces[371] = Vec3( -1.5093250e+02, -1.9541345e+02, -1.5879844e+02); - expectedForces[372] = Vec3( 2.2218133e+02, 7.5740668e+01, -7.0754853e+02); - expectedForces[373] = Vec3( -4.7529615e+02, -3.5259490e+02, 3.8025744e+02); - expectedForces[374] = Vec3( 4.9308495e+01, 1.2206152e+02, 4.2704595e+01); - expectedForces[375] = Vec3( -3.6408113e+02, 9.5905960e+02, 3.3861668e+02); - expectedForces[376] = Vec3( 1.5324093e+02, -1.4375341e+02, -9.1369900e+01); - expectedForces[377] = Vec3( -3.5343609e+02, -4.4662438e+02, 3.1741831e+02); - expectedForces[378] = Vec3( -8.2721281e+02, -6.4969313e+01, 4.1869320e+02); - expectedForces[379] = Vec3( -8.7419096e+00, -4.6278343e+01, -3.0259942e+01); - expectedForces[380] = Vec3( 1.6814871e+01, 4.5462601e+01, -3.5204538e+01); - expectedForces[381] = Vec3( 1.9043143e+02, 5.1101135e+02, 2.9970918e+02); - expectedForces[382] = Vec3( -4.3547560e+02, -7.7495770e+01, -8.2311440e+01); - expectedForces[383] = Vec3( 1.3206505e+02, 4.0993476e+01, 1.5150623e+01); - expectedForces[384] = Vec3( 4.6163268e+01, -2.7722119e+01, -2.2996255e+02); - expectedForces[385] = Vec3( -4.7033552e+01, 1.5721545e+02, -9.2562636e+01); - expectedForces[386] = Vec3( -2.4164903e+02, -1.4771464e+02, -5.1675638e+01); - expectedForces[387] = Vec3( 1.3445564e+03, 3.5387081e+02, -3.7402713e+02); - expectedForces[388] = Vec3( -2.6290280e+02, 2.5025510e+02, 3.0570707e+01); - expectedForces[389] = Vec3( -4.4624214e+02, -2.4919412e+02, 1.1336564e+03); - expectedForces[390] = Vec3( 3.1188483e+02, 6.4836125e+02, 4.5477683e+01); - expectedForces[391] = Vec3( 2.5570674e+02, -2.7101115e+02, -1.2579817e+02); - expectedForces[392] = Vec3( -3.4941759e+02, -3.2508734e+01, -5.6131515e+01); - expectedForces[393] = Vec3( -1.2734301e+02, -2.0417657e+02, 5.7738004e+02); - expectedForces[394] = Vec3( 5.0435795e+01, -9.5203527e+01, -4.1237509e+00); - expectedForces[395] = Vec3( -6.8258463e+01, 1.7475914e+02, -1.6422294e+02); - expectedForces[396] = Vec3( 2.6455575e+02, 2.6880230e+02, -1.6607620e+01); - expectedForces[397] = Vec3( -3.5968167e+02, 6.6092937e+01, 1.5915445e+02); - expectedForces[398] = Vec3( 8.4092494e-01, -5.9896731e+01, -2.1856007e+01); - expectedForces[399] = Vec3( -1.9237984e+02, -1.6506355e+02, 1.3370845e+02); - expectedForces[400] = Vec3( 4.7023043e+02, 1.2931257e+02, -1.7013618e+02); - expectedForces[401] = Vec3( 9.4928843e+01, -3.1613892e+02, -4.6973091e+02); - expectedForces[402] = Vec3( -2.9180818e+02, 6.5496755e+02, -2.9430870e+02); - expectedForces[403] = Vec3( 1.6670668e+02, -2.4693913e+02, -8.8775735e+01); - expectedForces[404] = Vec3( -1.4218604e+02, 2.3173349e+02, 3.9869740e+02); - expectedForces[405] = Vec3( 4.3469431e+02, -2.4686568e+02, -2.6838523e+02); - expectedForces[406] = Vec3( 1.0671130e+02, 3.9710106e+02, 2.6478100e+02); - expectedForces[407] = Vec3( -4.4281099e+02, -3.2746126e+01, -2.0719929e+02); - expectedForces[408] = Vec3( 1.1864952e+01, -1.5901568e+02, 1.1865945e+01); - expectedForces[409] = Vec3( -6.0546863e+01, -1.3488005e+02, -2.9223986e+02); - expectedForces[410] = Vec3( 2.5845942e+01, 1.7545933e+02, -1.4590654e+02); - expectedForces[411] = Vec3( -3.0776460e+02, 2.7351986e+02, -2.0386483e+02); - expectedForces[412] = Vec3( 1.7301558e+02, 8.3012339e+01, 7.6018513e+02); - expectedForces[413] = Vec3( 1.2893147e+02, -3.9937475e+00, 1.4197628e+01); - expectedForces[414] = Vec3( -3.9803615e+02, -4.4825663e+02, 2.8616211e+01); - expectedForces[415] = Vec3( -2.3586809e+02, -8.9306136e+01, 7.5265669e+02); - expectedForces[416] = Vec3( 8.3814512e+02, -9.5563706e+00, 2.8738759e+02); - expectedForces[417] = Vec3( -3.8269399e+02, -2.3650170e+02, 1.7330415e+01); - expectedForces[418] = Vec3( 7.2310675e+00, 2.4731653e+01, 1.9491126e+01); - expectedForces[419] = Vec3( 8.4485111e+01, 9.0560261e+01, -1.4261777e+01); - expectedForces[420] = Vec3( 2.1829925e+02, -8.3951651e+01, -7.8910117e+02); - expectedForces[421] = Vec3( -2.4228018e+02, -5.7097512e+01, 2.6447829e+02); - expectedForces[422] = Vec3( 6.9666665e+01, -4.7313678e+02, 4.5559673e+02); - expectedForces[423] = Vec3( 1.0108369e+02, 4.6568610e+02, 2.5612541e+02); - expectedForces[424] = Vec3( 7.2334238e+01, -1.5660040e+02, -2.6278686e+02); - expectedForces[425] = Vec3( 1.0749954e+03, 2.4395658e+02, -8.7308262e+01); - expectedForces[426] = Vec3( 5.4983082e+02, 5.6528577e+02, -3.0489991e+02); - expectedForces[427] = Vec3( -2.1210132e+02, -1.5871954e+02, -1.6936452e+02); - expectedForces[428] = Vec3( -9.5473983e+01, 7.4879276e+01, 5.5720204e+01); - expectedForces[429] = Vec3( 5.6417182e+02, -1.3478250e+02, -4.8006673e+01); - expectedForces[430] = Vec3( -1.0055266e+02, -8.3811289e+01, 6.5259748e+01); - expectedForces[431] = Vec3( 3.0553989e+01, 4.0927300e+02, 6.2242246e+02); - expectedForces[432] = Vec3( -6.0956353e+02, 9.0301312e+02, -1.4063582e+01); - expectedForces[433] = Vec3( 3.2774559e+02, -1.0849473e+02, -8.8877712e+01); - expectedForces[434] = Vec3( 2.1371643e+02, -7.2067980e+01, 2.4803863e+02); - expectedForces[435] = Vec3( -9.0636479e+01, 1.0673514e+03, 1.3005625e+02); - expectedForces[436] = Vec3( -3.5058624e+02, -1.4968284e+02, 1.4340635e+02); - expectedForces[437] = Vec3( 3.4640813e+01, -4.8035225e+01, 4.4066226e+01); - expectedForces[438] = Vec3( -2.3414523e+02, -9.1359130e+01, 2.8535427e+02); - expectedForces[439] = Vec3( -2.7156547e+02, -6.3426763e+01, 1.6968017e+01); - expectedForces[440] = Vec3( -2.8751166e+00, 4.3192169e+00, -2.1401359e+00); - expectedForces[441] = Vec3( -2.0241419e+01, 4.2856138e+02, 7.3204868e+01); - expectedForces[442] = Vec3( -4.2166169e+01, -2.2454013e+01, -5.4998450e+01); - expectedForces[443] = Vec3( 2.6442026e+02, -1.1670567e+02, 2.8879291e+02); - expectedForces[444] = Vec3( -4.9762729e+02, 4.7320314e+02, 3.2506251e+02); - expectedForces[445] = Vec3( -3.0994232e+02, 3.6728867e+02, -6.8793662e+02); - expectedForces[446] = Vec3( -5.6328374e+00, -2.3284824e+00, 1.9650486e+01); - expectedForces[447] = Vec3( 4.0145354e+02, 7.0143762e+02, 1.3039041e+02); - expectedForces[448] = Vec3( 1.3270713e+02, -3.3050447e+02, 2.8630784e+02); - expectedForces[449] = Vec3( -3.8904836e+02, -4.6125118e+01, -3.8815388e+02); - expectedForces[450] = Vec3( 4.6293066e+02, -2.4970158e+02, -5.7231818e+01); - expectedForces[451] = Vec3( -4.7707142e+00, 1.7120822e-01, 4.5081299e+00); - expectedForces[452] = Vec3( 3.5968818e+01, -1.1892248e+01, 1.2184792e+02); - expectedForces[453] = Vec3( 4.4939172e+02, 4.8377647e+02, 3.0529778e+02); - expectedForces[454] = Vec3( -2.9071570e+02, -9.0611613e+01, -2.5190431e+02); - expectedForces[455] = Vec3( -1.4344537e+02, -1.3061997e+03, 3.8343947e+02); - expectedForces[456] = Vec3( 4.1580940e+02, -3.6864043e+02, 6.6384066e+02); - expectedForces[457] = Vec3( -3.4869949e+02, 3.3262427e+02, -8.3156358e+01); - expectedForces[458] = Vec3( -5.8565457e+00, -5.1879987e+02, -7.2717213e+02); - expectedForces[459] = Vec3( -1.0514593e+02, -2.6844396e+02, 3.0849659e+02); - expectedForces[460] = Vec3( -1.2562153e+02, 6.5438031e+01, -2.3521687e+02); - expectedForces[461] = Vec3( 8.3330016e+02, -6.7961048e+02, -7.2442064e+02); - expectedForces[462] = Vec3( -1.3328298e+02, 1.6143544e+02, -3.2000493e+02); - expectedForces[463] = Vec3( -1.1035002e+02, -8.6040775e+01, 2.0953986e+02); - expectedForces[464] = Vec3( -2.7702219e+02, -1.2156319e+02, -3.8897654e+02); - expectedForces[465] = Vec3( 3.6277432e+02, -7.0422679e+02, -8.2487472e+02); - expectedForces[466] = Vec3( -2.3947587e+02, -4.3625964e+00, 4.8716989e+01); - expectedForces[467] = Vec3( -2.6210552e+02, 9.9730213e+01, -2.4465307e+02); - expectedForces[468] = Vec3( -4.1344138e+01, -3.8636310e+01, -1.0720610e+01); - expectedForces[469] = Vec3( 2.3928584e+01, -1.3030908e+01, -1.7631168e+01); - expectedForces[470] = Vec3( -1.1873594e+02, -3.3905287e+00, -8.4575994e+01); - expectedForces[471] = Vec3( 4.3384846e+02, -4.8660929e+02, -2.4015737e+02); - expectedForces[472] = Vec3( 3.8974922e+01, 2.4401913e+02, -1.2060132e+02); - expectedForces[473] = Vec3( -4.2239647e+02, -8.6924630e+01, 5.7884013e+02); - expectedForces[474] = Vec3( 1.7222431e+02, -1.9292167e+01, 4.4184770e+01); - expectedForces[475] = Vec3( -4.8871102e+01, 1.8185057e+02, -1.3144294e+02); - expectedForces[476] = Vec3( -1.1467881e+02, -1.8387284e+02, -2.6935761e+01); - expectedForces[477] = Vec3( 4.4415601e+02, -8.6415426e+02, -2.2765803e+02); - expectedForces[478] = Vec3( 2.0893474e+02, 1.3529112e+02, 2.4108004e+02); - expectedForces[479] = Vec3( -1.2802570e+01, -4.7089261e+00, -7.0024810e+00); - expectedForces[480] = Vec3( -1.0878354e+02, 4.5030357e+02, -3.9086153e+02); - expectedForces[481] = Vec3( -3.7659745e+01, -4.9295745e+01, -6.0028516e+01); - expectedForces[482] = Vec3( 1.8851809e+02, -1.6863914e+02, 1.2031505e+02); - expectedForces[483] = Vec3( 2.2040686e+02, -1.1953187e+03, 2.9106238e+02); - expectedForces[484] = Vec3( -1.1642847e+01, 5.6739977e+01, 3.7532413e+00); - expectedForces[485] = Vec3( 3.5013234e+00, 2.8236323e+01, -1.1738866e+01); - expectedForces[486] = Vec3( -2.0051506e+03, -5.3138994e+02, 4.0428126e+02); - expectedForces[487] = Vec3( 1.6887843e+02, 1.1687735e+02, -9.6232177e+01); - expectedForces[488] = Vec3( 2.5030722e+02, -3.6662537e+02, -5.8595505e+01); - expectedForces[489] = Vec3( -1.5924273e+01, -2.1761920e+02, -3.4885425e+01); - expectedForces[490] = Vec3( 1.0423157e+02, 4.0767827e+01, 1.4036192e+02); - expectedForces[491] = Vec3( 5.0090776e+02, -5.0455702e+01, -4.2524815e+02); - expectedForces[492] = Vec3( 3.8037844e+02, 5.7460724e+02, 2.1243310e+02); - expectedForces[493] = Vec3( -1.1487653e+02, 3.3550952e+01, -5.7050397e+01); - expectedForces[494] = Vec3( 1.8425697e+02, -2.7223857e+02, -2.9384020e+01); - expectedForces[495] = Vec3( -1.1115514e+02, -4.4519957e+02, -3.3628896e+02); - expectedForces[496] = Vec3( 3.8865823e+02, -2.1372852e+02, -7.8979988e+02); - expectedForces[497] = Vec3( -3.1740258e+02, 4.4824683e+02, -5.0382680e+02); - expectedForces[498] = Vec3( 1.5521684e+02, -1.5278429e+02, -1.8418006e+02); - expectedForces[499] = Vec3( -2.2213191e+01, 7.1015095e+00, 1.0308820e+01); - expectedForces[500] = Vec3( 3.0011560e+01, 2.4584541e+02, -5.3231694e+02); - expectedForces[501] = Vec3( -8.4865171e+02, -2.0279022e+02, -6.8435095e+02); - expectedForces[502] = Vec3( 7.0477549e+00, 2.7626774e+01, -1.6246047e+01); - expectedForces[503] = Vec3( -7.1309648e+01, -1.6054218e+02, -3.1621746e+01); - expectedForces[504] = Vec3( 3.6317856e+02, 1.9055487e+02, 3.9196046e+01); - expectedForces[505] = Vec3( 1.4643265e+02, -1.2295335e+03, -2.2268806e+01); - expectedForces[506] = Vec3( -3.6638240e+02, -6.5310612e+00, -6.8077013e+02); - expectedForces[507] = Vec3( 1.9107813e+02, -6.2176534e+02, 5.1826941e+02); - expectedForces[508] = Vec3( 1.7226933e+02, -3.8939126e+02, -7.4174355e+02); - expectedForces[509] = Vec3( 1.3541890e+02, 4.1350561e+02, -2.6155396e+02); - expectedForces[510] = Vec3( 1.6452609e+02, -4.1963597e+02, 1.6322800e+02); - expectedForces[511] = Vec3( 9.1248387e+01, -1.3380408e+01, -5.1326806e+02); - expectedForces[512] = Vec3( 1.2420564e+02, 8.9492432e+02, 2.8660661e+02); - expectedForces[513] = Vec3( 4.5609859e+02, 3.4252036e+01, -2.3830457e+02); - expectedForces[514] = Vec3( -8.8282131e+01, -1.4512876e+02, -4.5703642e+01); - expectedForces[515] = Vec3( -6.9194714e+01, 5.5053415e+02, -3.9527911e+02); - expectedForces[516] = Vec3( -1.5570798e+02, 4.1650792e-02, 3.0224667e+02); - expectedForces[517] = Vec3( 9.2007640e+01, 3.6378499e+02, -2.2069415e+01); - expectedForces[518] = Vec3( 2.7996922e+02, -2.0932322e+02, 6.2987796e+01); - expectedForces[519] = Vec3( -7.4985282e+01, 1.3508916e+02, 1.1453750e+02); - expectedForces[520] = Vec3( 1.2149786e+01, 4.2161047e+02, -2.9521571e+02); - expectedForces[521] = Vec3( 1.9419524e+01, -8.6619683e+01, -9.4040609e+01); - expectedForces[522] = Vec3( 3.5495800e+01, 6.4028894e+01, 1.2320699e+02); - expectedForces[523] = Vec3( -5.6501302e+02, -1.2497462e+02, 8.1633096e+02); - expectedForces[524] = Vec3( -3.1775230e+02, 1.6467221e+02, -4.8242287e+01); - expectedForces[525] = Vec3( -1.8325245e+02, -1.0751941e+02, 6.2172117e+02); - expectedForces[526] = Vec3( 1.8164299e+00, 8.0654784e-01, -1.4484741e+01); - expectedForces[527] = Vec3( 2.6686986e+00, 1.5933475e+01, -6.8843007e+01); - expectedForces[528] = Vec3( -1.3208642e+02, -1.2281791e+02, 7.8417959e+01); - expectedForces[529] = Vec3( -4.8078193e+01, -1.5140963e+02, 8.3605002e+01); - expectedForces[530] = Vec3( 8.5925332e+01, 1.9959621e+01, -5.9034655e+01); - expectedForces[531] = Vec3( -3.1311626e+00, -3.4009931e+01, -1.5895685e+02); - expectedForces[532] = Vec3( -9.9694666e+01, 1.0296874e+00, 1.0482739e+02); - expectedForces[533] = Vec3( 2.8954747e+02, 1.2018666e+02, 2.2155006e+02); - expectedForces[534] = Vec3( 3.2588176e+02, 3.6622498e+01, 3.5801460e+02); - expectedForces[535] = Vec3( -6.5985617e+01, -3.5501709e+02, 6.8149810e+01); - expectedForces[536] = Vec3( -4.7632753e+02, 2.7936656e+02, 1.5548558e+02); - expectedForces[537] = Vec3( 4.7724904e+02, 2.1647106e+02, 1.2003317e+02); - expectedForces[538] = Vec3( -1.6225405e+02, 1.4264998e+02, -1.0113321e+02); - expectedForces[539] = Vec3( -3.2540487e+01, -7.5643223e+01, 1.6054148e+01); - expectedForces[540] = Vec3( 4.3311991e+02, 5.8082595e+02, 1.9354276e+02); - expectedForces[541] = Vec3( -3.4924430e+02, -7.0056069e+01, 1.0274560e+02); - expectedForces[542] = Vec3( 1.9441645e+02, -2.0017354e+02, -2.3280717e+02); - expectedForces[543] = Vec3( -4.1530380e+01, -5.6394351e+02, 2.4472509e+02); - expectedForces[544] = Vec3( -1.6193396e+01, -8.0431396e+01, -2.9094018e+02); - expectedForces[545] = Vec3( -1.9414773e+01, 4.6180982e+01, 3.3123072e+01); - expectedForces[546] = Vec3( -3.9314039e+02, -3.9874866e+02, 4.5308571e+02); - expectedForces[547] = Vec3( -7.1897482e+01, -1.1940445e+02, -2.7405931e+02); - expectedForces[548] = Vec3( 3.0646396e+02, 6.1235747e+01, -1.5253270e+02); - expectedForces[549] = Vec3( -3.2480464e+02, 4.3056561e+02, 3.2532485e+01); - expectedForces[550] = Vec3( 1.2818655e+02, 7.4294994e-01, -5.7650521e+00); - expectedForces[551] = Vec3( -1.7481437e+02, -2.6203225e+02, -9.6793481e+01); - expectedForces[552] = Vec3( 1.9259110e+02, 3.0171883e+02, 5.2403235e+02); - expectedForces[553] = Vec3( -7.8132123e+01, -7.6569340e+00, -1.1140240e+02); - expectedForces[554] = Vec3( -5.2504673e+02, -4.3700574e+02, 4.3321261e+02); - expectedForces[555] = Vec3( -9.9785283e+02, 2.7139143e+02, -4.1723547e+02); - expectedForces[556] = Vec3( 2.7115933e+02, -8.7444541e+01, 1.0745103e+02); - expectedForces[557] = Vec3( 1.4348018e+02, 1.4013343e+02, -4.0305733e+02); - expectedForces[558] = Vec3( 4.9491010e+02, 4.3040089e+02, -3.5558583e+02); - expectedForces[559] = Vec3( -1.8510736e+02, 6.7129731e+01, -2.1324364e+02); - expectedForces[560] = Vec3( 8.4478090e+01, 4.0986269e+01, 4.1401094e+02); - expectedForces[561] = Vec3( 4.4188419e+01, -8.6520108e+02, 6.8555821e+02); - expectedForces[562] = Vec3( -4.5036974e+02, 2.2379481e+02, 6.2457971e+01); - expectedForces[563] = Vec3( 2.4325836e+02, 6.9725116e+01, 3.6266296e+01); - expectedForces[564] = Vec3( 1.5611925e+02, -2.4471023e+02, 4.7857332e+02); - expectedForces[565] = Vec3( -3.5692822e+02, -2.7248961e+02, -1.8165146e+02); - expectedForces[566] = Vec3( 4.3093388e+02, 1.6944839e+02, -4.4177741e+02); - expectedForces[567] = Vec3( 5.2118711e+02, -1.5252783e+02, -1.6964047e+02); - expectedForces[568] = Vec3( 1.3899083e+03, 3.8363654e+02, -6.4623177e+02); - expectedForces[569] = Vec3( -1.4984858e+02, 4.5097170e+01, -5.0257768e+01); - expectedForces[570] = Vec3( -8.1979709e+01, -4.1632909e+01, -5.1367825e+02); - expectedForces[571] = Vec3( -7.8645235e+00, 1.8105470e+01, 9.2902759e+01); - expectedForces[572] = Vec3( 1.2725548e+02, 1.3926229e+02, -4.3752260e+01); - expectedForces[573] = Vec3( -2.7817289e+01, -8.0900345e+01, -4.3178498e+02); - expectedForces[574] = Vec3( 2.2115263e+02, -7.8807799e+01, 8.8367391e+01); - expectedForces[575] = Vec3( -1.2756938e+02, 4.2170937e+02, -6.8418245e+01); - expectedForces[576] = Vec3( 8.8370341e+01, -1.4671130e+02, -5.6211071e+02); - expectedForces[577] = Vec3( 6.7701453e+02, 2.1228010e+02, 2.3047236e+02); - expectedForces[578] = Vec3( -1.2694819e+02, -7.2734890e+00, 1.1007893e+02); - expectedForces[579] = Vec3( -6.8945756e+02, 1.7359485e+02, -2.5607776e+02); - expectedForces[580] = Vec3( 6.7323923e+00, 3.1574487e+02, 5.9741152e+02); - expectedForces[581] = Vec3( 2.1214031e+02, -4.7565197e+01, -9.6896159e+01); - expectedForces[582] = Vec3( -3.4876562e+02, 5.8335489e+01, -1.7058451e+02); - expectedForces[583] = Vec3( -1.6516914e+02, -3.8913162e+02, 5.8832025e+02); - expectedForces[584] = Vec3( 4.7753612e+01, -6.6792213e+01, -4.6492749e+01); - expectedForces[585] = Vec3( -4.7166578e+02, 7.1811831e+02, 7.0620222e+02); - expectedForces[586] = Vec3( -3.0570577e+02, -1.7681907e+02, -2.1227370e+02); - expectedForces[587] = Vec3( 1.8122997e+02, -6.8318737e+01, -3.4853368e+02); - expectedForces[588] = Vec3( 7.5752093e+01, 3.9702196e+02, -9.0196404e+02); - expectedForces[589] = Vec3( 5.1185528e+02, -7.7747186e+02, -3.3969581e+02); - expectedForces[590] = Vec3( -3.1187606e+01, 5.9593198e+01, 7.7918649e+01); - expectedForces[591] = Vec3( 2.2741676e+02, 2.1705631e+02, 3.9920149e+02); - expectedForces[592] = Vec3( 7.0516894e+01, 3.3389665e+02, -6.8443760e+00); - expectedForces[593] = Vec3( -9.9645406e+02, 2.8574127e+02, -8.0946834e+02); - expectedForces[594] = Vec3( 1.0930460e+02, 1.5869363e+03, -4.0704089e+02); - expectedForces[595] = Vec3( -3.0341438e+02, -5.7494385e+00, 2.9655509e+02); - expectedForces[596] = Vec3( 8.7955203e+01, -7.6811348e+01, -6.9558652e+01); - expectedForces[597] = Vec3( -9.4378353e+01, 3.6253070e+02, 9.0703343e-01); - expectedForces[598] = Vec3( -4.7595525e+01, -6.9148379e+02, -4.6737971e+02); - expectedForces[599] = Vec3( 2.2339987e+02, -2.5503335e+02, 2.8552040e+02); - expectedForces[600] = Vec3( 1.0309072e+02, -2.1298204e+02, -4.3393283e+02); - expectedForces[601] = Vec3( -2.4581477e+02, 2.5126386e+02, -1.8679710e+02); - expectedForces[602] = Vec3( 7.7926618e+00, -2.4947558e+01, 1.5962011e+02); - expectedForces[603] = Vec3( 7.0099476e+02, 5.9496129e+01, 2.0314640e+02); - expectedForces[604] = Vec3( -5.2583810e+01, 3.1237489e+01, -4.0902937e+00); - expectedForces[605] = Vec3( -5.4435871e+01, -7.7056693e+01, -1.5137215e+01); - expectedForces[606] = Vec3( -7.8684074e+02, 8.1673860e+02, 5.0192222e+02); - expectedForces[607] = Vec3( 2.9859285e+02, 1.9661708e+02, -1.9940993e+02); - expectedForces[608] = Vec3( -9.9358476e-01, -3.4789219e+02, 1.7693106e+02); - expectedForces[609] = Vec3( 6.7880927e+02, 7.2768533e+01, 1.1973248e+03); - expectedForces[610] = Vec3( -1.2072838e+00, 1.1770157e+02, -8.6765918e+01); - expectedForces[611] = Vec3( -4.3236695e+02, -2.8583002e+02, 1.3459508e+02); - expectedForces[612] = Vec3( -6.1894609e+01, 4.4705141e+02, -2.3264215e+02); - expectedForces[613] = Vec3( -2.6948720e+01, -2.7688230e+01, 4.6300601e+01); - expectedForces[614] = Vec3( 4.3954815e+01, 6.1244278e+01, 1.0727211e+02); - expectedForces[615] = Vec3( -2.2049132e+02, -9.7233594e+01, 8.3807949e+01); - expectedForces[616] = Vec3( 2.8631226e+02, -1.3478640e+02, -5.0675977e+02); - expectedForces[617] = Vec3( -1.1458029e+01, 6.3762007e+01, -4.9643140e+01); - expectedForces[618] = Vec3( 7.7363305e+01, 1.1936816e+02, 3.9692323e+01); - expectedForces[619] = Vec3( -8.4199858e+01, 2.3567494e+02, 7.2885200e+01); - expectedForces[620] = Vec3( -7.4500104e+00, 3.5567340e+00, -2.2676267e+01); - expectedForces[621] = Vec3( -7.9200057e+02, 3.2245192e+01, 1.1829644e+01); - expectedForces[622] = Vec3( 3.9959336e+02, 2.2447865e+02, -3.1413233e+02); - expectedForces[623] = Vec3( 1.5810527e+02, -2.2341997e+02, 2.3388212e+02); - expectedForces[624] = Vec3( -2.9248657e+02, -1.0806250e+03, -6.1268035e+01); - expectedForces[625] = Vec3( 6.5061442e+02, 1.2244756e+02, -1.1976147e+02); - expectedForces[626] = Vec3( -1.7787710e+02, 3.7279354e+02, -3.7911745e+02); - expectedForces[627] = Vec3( 3.7145927e+02, -2.5203732e+02, -2.2889342e+02); - expectedForces[628] = Vec3( 1.9440281e+02, -2.3076142e+02, 7.2945279e+01); - expectedForces[629] = Vec3( -2.3603693e+02, -1.1987203e+02, -1.2000208e+02); - expectedForces[630] = Vec3( -8.4811726e+01, -6.4500846e+02, -5.1257210e+02); - expectedForces[631] = Vec3( -1.6183393e+01, 1.3980655e+01, -2.3189702e+00); - expectedForces[632] = Vec3( 1.3526098e+02, 1.3800365e+02, -9.4360476e+01); - expectedForces[633] = Vec3( 2.0983514e+01, 5.1156494e+02, -4.3526557e+01); - expectedForces[634] = Vec3( -2.8666500e+02, -5.8235691e+02, -8.7425194e+01); - expectedForces[635] = Vec3( -1.7183604e+02, 1.0002944e+01, 6.5855812e+02); - expectedForces[636] = Vec3( -2.1735465e+02, 9.4664675e+02, 8.9132890e+02); - expectedForces[637] = Vec3( 6.3759184e+01, -5.2436201e+02, 1.2455578e+02); - expectedForces[638] = Vec3( 3.2176621e+02, 1.8182348e+02, -4.4863340e+02); - expectedForces[639] = Vec3( -8.4308252e+02, -1.6268681e+02, 5.8113352e+02); - expectedForces[640] = Vec3( 6.1223389e+01, 3.6767423e+02, 5.9071999e+02); - expectedForces[641] = Vec3( 2.2546928e+02, -2.2022805e+02, 8.3027103e+01); - expectedForces[642] = Vec3( -4.0385190e+02, 2.0141033e+02, 2.7296512e+01); - expectedForces[643] = Vec3( 8.4204485e+01, -7.1102294e+01, 5.7642677e+01); - expectedForces[644] = Vec3( 6.1859901e+01, 1.4828523e+02, -2.6764016e+02); - expectedForces[645] = Vec3( -6.7249932e+02, -8.4613525e+01, -3.9792609e+02); - expectedForces[646] = Vec3( 9.9116485e+01, -3.7714583e+01, -5.3966332e+01); - expectedForces[647] = Vec3( 2.0868628e+02, 2.9747206e+02, 3.3931416e+02); + expectedForces[0] = Vec3( 2.3025909e+02, -1.0422757e+01, -2.1413965e+02); + expectedForces[1] = Vec3( 1.1261936e+02, 5.5882575e+02, 9.6539143e+01); + expectedForces[2] = Vec3(-8.8436857e+01, -4.4737313e+01, 2.5242022e+02); + expectedForces[3] = Vec3( 6.3548886e+02, -1.9582636e+02, -1.2229882e+02); + expectedForces[4] = Vec3(-3.9513809e+02, -1.3738635e+02, -1.2488717e+02); + expectedForces[5] = Vec3( 6.8771170e+00, 9.1574345e+01, -1.3865672e+00); + expectedForces[6] = Vec3( 3.6928792e+02, -7.1025648e+01, 5.2550320e+02); + expectedForces[7] = Vec3( 1.5531325e+02, -7.9256260e+02, 3.8119809e+02); + expectedForces[8] = Vec3( 1.5408049e+02, 1.4633285e+02, -5.4573735e+02); + expectedForces[9] = Vec3(-3.2549641e+02, 2.8613802e+01, 1.8082150e+02); + expectedForces[10] = Vec3( 1.9968249e+02, -7.7742415e+01, -4.2188467e+02); + expectedForces[11] = Vec3( 4.6645952e+01, 2.1362909e+01, 5.7120135e+01); + expectedForces[12] = Vec3( 4.2971265e+01, -4.2927865e+01, -7.6319121e+02); + expectedForces[13] = Vec3( 2.1889551e+02, -5.1806784e+01, 7.6637073e+01); + expectedForces[14] = Vec3(-3.0028991e+02, 9.0479382e+01, 1.3199449e+02); + expectedForces[15] = Vec3(-1.8041801e+00, -1.2176813e+03, -5.9679371e+02); + expectedForces[16] = Vec3(-1.4773339e+02, -1.2582057e+02, 8.4242040e+02); + expectedForces[17] = Vec3( 6.8633312e+02, -2.4864325e+01, 1.0675519e+01); + expectedForces[18] = Vec3( 4.8211733e+02, -2.2044742e+02, 1.8105309e+02); + expectedForces[19] = Vec3(-2.1956736e+02, 5.4786741e+02, -1.4827263e+02); + expectedForces[20] = Vec3(-1.0476100e+02, -1.6922280e+02, 8.3220473e+01); + expectedForces[21] = Vec3( 5.5455350e+01, 1.7851224e+02, 6.0598643e+02); + expectedForces[22] = Vec3( 7.1915871e+00, -1.6455057e+01, -6.3929797e+00); + expectedForces[23] = Vec3(-2.4371864e+02, -7.0765288e+02, -1.7820148e+02); + expectedForces[24] = Vec3(-4.3715367e+02, 2.8707226e+02, 2.2558361e+02); + expectedForces[25] = Vec3( 2.3735557e+00, -4.2064130e+00, 2.5933632e+01); + expectedForces[26] = Vec3( 1.0192415e+02, 5.3205842e+01, -2.0158900e+02); + expectedForces[27] = Vec3(-5.1276812e+02, 2.4860179e+02, 2.5150125e+02); + expectedForces[28] = Vec3( 3.9608987e+02, -4.0544816e+01, -2.1579831e+02); + expectedForces[29] = Vec3(-2.5926005e+02, -1.1691294e+02, -4.7278417e+02); + expectedForces[30] = Vec3(-1.1036158e+02, 3.3229287e+01, 8.8351491e+01); + expectedForces[31] = Vec3(-4.1178603e+00, 1.2957632e+00, 1.2617868e+00); + expectedForces[32] = Vec3( 1.9401524e+02, 1.0030314e+02, 3.0386141e+01); + expectedForces[33] = Vec3( 1.0870981e+02, 2.1865882e+02, 6.7672725e+02); + expectedForces[34] = Vec3( 3.6812338e+01, -2.9347382e-01, 1.2959790e+01); + expectedForces[35] = Vec3(-5.5738560e+01, 2.2268442e+02, -1.4911862e+02); + expectedForces[36] = Vec3(-1.6659719e+02, 8.1941190e+01, 7.8132996e+01); + expectedForces[37] = Vec3(-1.1985659e+02, 7.1891763e+01, -3.2559738e+02); + expectedForces[38] = Vec3( 1.4441653e+02, 4.1824194e+02, 3.4293255e+01); + expectedForces[39] = Vec3( 1.1307312e+02, -3.4981802e+02, -1.0676819e+02); + expectedForces[40] = Vec3(-1.2857487e+02, -4.0798950e+01, -1.7800009e+02); + expectedForces[41] = Vec3(-4.1244991e+02, 2.3439565e+02, 3.8546709e+02); + expectedForces[42] = Vec3( 2.1799653e+02, 2.9397348e+02, -3.8955146e+02); + expectedForces[43] = Vec3(-9.4254462e+01, 5.0157547e+01, 1.3707146e+02); + expectedForces[44] = Vec3( 8.0520929e+02, -1.0228045e+03, -4.5813594e+01); + expectedForces[45] = Vec3( 5.3451125e+02, -7.0725115e+02, -2.3828883e+02); + expectedForces[46] = Vec3( 3.6991801e+02, -1.0410466e+03, 8.4889413e+02); + expectedForces[47] = Vec3( 5.8096458e+01, 2.3859368e+02, 7.3104979e+01); + expectedForces[48] = Vec3(-1.3230378e+03, 7.1827816e+02, 9.4372946e+02); + expectedForces[49] = Vec3(-4.2398413e+02, -3.6766481e+02, -1.6666711e+02); + expectedForces[50] = Vec3( 8.6374766e+00, -2.7870227e+02, 3.0621233e+02); + expectedForces[51] = Vec3(-2.4404981e+02, 1.0510491e+03, -3.5202340e+02); + expectedForces[52] = Vec3( 1.7461155e+02, 1.3419948e+02, 5.0279733e+02); + expectedForces[53] = Vec3( 9.7089193e+01, -1.4826120e+02, -2.3426711e+02); + expectedForces[54] = Vec3(-1.0647432e+02, 2.3266543e+02, -3.5025025e+02); + expectedForces[55] = Vec3(-1.9951717e+02, -1.0804258e+02, 6.2114265e+01); + expectedForces[56] = Vec3( 2.5354284e+02, -3.5074926e+02, -2.9176946e+01); + expectedForces[57] = Vec3(-8.8328002e+02, -1.8937053e+02, 2.0772189e+02); + expectedForces[58] = Vec3( 4.5809698e+01, -1.8636513e+00, 1.6742910e+01); + expectedForces[59] = Vec3( 8.6670673e+01, 1.2653519e+02, 2.0046372e+02); + expectedForces[60] = Vec3(-9.6142275e+02, 1.1800289e+03, 1.0064471e+02); + expectedForces[61] = Vec3(-6.9751453e+01, -1.9324691e+02, 2.2638891e+01); + expectedForces[62] = Vec3( 1.3671815e+02, 1.0129231e+01, -6.1136892e+01); + expectedForces[63] = Vec3( 7.6032938e+02, -1.9779542e+02, -2.5706161e+01); + expectedForces[64] = Vec3(-9.8966607e+00, 3.6294058e+02, -2.3247376e+02); + expectedForces[65] = Vec3(-1.3142673e+02, 9.9368000e+00, 1.4225069e+02); + expectedForces[66] = Vec3( 5.2691625e+01, -4.0618331e+02, -1.0942115e+02); + expectedForces[67] = Vec3( 5.8137742e+01, 2.1942441e+02, -1.7191686e+02); + expectedForces[68] = Vec3( 1.2480778e+02, 2.4086799e+01, -1.9588545e+02); + expectedForces[69] = Vec3( 2.4577512e+02, -2.3516051e+01, 2.3764379e+02); + expectedForces[70] = Vec3( 4.2298797e+01, 8.6807583e+01, 2.9276129e+02); + expectedForces[71] = Vec3( 3.0309915e+01, -3.4686002e+02, 1.0849989e+02); + expectedForces[72] = Vec3( 5.5170999e+02, -1.5797913e+02, 9.8379834e+01); + expectedForces[73] = Vec3(-5.3706921e+02, 2.2236470e+02, 2.7548665e+02); + expectedForces[74] = Vec3(-2.7734936e+02, -4.2949693e+02, -8.2303469e+02); + expectedForces[75] = Vec3( 1.1749001e+03, 9.2734627e+02, -2.6342291e+02); + expectedForces[76] = Vec3(-1.2345216e+02, -6.6220297e+01, 1.1022778e+02); + expectedForces[77] = Vec3(-4.4861284e+01, -7.4560959e+01, -8.0791275e+01); + expectedForces[78] = Vec3( 1.7692476e+01, -9.9067626e+02, -3.3083363e+02); + expectedForces[79] = Vec3( 6.4276566e+01, 5.1865608e+02, 4.1241764e+02); + expectedForces[80] = Vec3( 6.5867999e+02, 2.0995465e+02, -5.0989840e+02); + expectedForces[81] = Vec3(-5.2826435e+02, -1.3719887e+02, 1.9730314e+02); + expectedForces[82] = Vec3( 2.3329314e+02, 5.1589944e+01, -3.3942818e+02); + expectedForces[83] = Vec3(-2.5756193e+00, 1.3788257e+02, 1.3074778e+02); + expectedForces[84] = Vec3(-2.8925811e+01, 8.8185346e+01, 1.1547804e+02); + expectedForces[85] = Vec3(-3.3582542e+01, -1.3079843e+02, 3.4774799e+02); + expectedForces[86] = Vec3(-5.9585326e+01, -3.7973755e+01, 1.0206767e+01); + expectedForces[87] = Vec3(-7.1691223e+01, -1.9547311e+02, 9.3856472e+02); + expectedForces[88] = Vec3( 1.4832977e+02, 4.2005795e+02, 2.7235044e+01); + expectedForces[89] = Vec3( 8.6221698e+00, -1.3935906e+01, -2.5473157e+00); + expectedForces[90] = Vec3( 3.0044348e+02, 3.4320406e+02, 2.5305998e+02); + expectedForces[91] = Vec3(-1.6694013e+02, 7.4645776e+02, 3.3266168e+01); + expectedForces[92] = Vec3( 1.6931562e+02, -2.3972286e+01, -3.0802865e+02); + expectedForces[93] = Vec3(-2.5931152e+02, -9.7825375e+01, -5.5598386e+02); + expectedForces[94] = Vec3(-7.8473519e+01, -2.6244561e+02, 2.9622027e+02); + expectedForces[95] = Vec3( 1.5788473e+02, 2.9806605e+02, 1.8283700e+02); + expectedForces[96] = Vec3(-4.2033208e+02, 4.8745845e+02, 9.7957219e+01); + expectedForces[97] = Vec3( 1.3261733e+00, 3.7143158e+00, -1.8329960e+00); + expectedForces[98] = Vec3( 7.4741051e+02, 1.0482696e+03, 1.7182445e+02); + expectedForces[99] = Vec3( 2.0366606e+02, 1.1586652e+02, 1.5482927e+03); + expectedForces[100] = Vec3( 5.7569884e+02, -2.2068597e+02, -1.9305186e+02); + expectedForces[101] = Vec3(-2.4259775e+02, -6.1359858e+01, -7.5753918e+01); + expectedForces[102] = Vec3( 2.4382837e+02, 1.3660693e+01, -2.8717824e+02); + expectedForces[103] = Vec3(-4.1914381e+02, -1.4506334e+02, 7.7692658e+01); + expectedForces[104] = Vec3( 9.5422158e+01, -1.4261849e+01, 1.0122453e+02); + expectedForces[105] = Vec3(-6.1222151e+02, 6.1398147e+01, 3.2961693e+02); + expectedForces[106] = Vec3(-2.7982116e+02, -3.7564793e+02, -2.4318658e+02); + expectedForces[107] = Vec3( 8.2892383e+01, 1.1992522e+01, 2.4802899e+01); + expectedForces[108] = Vec3(-3.3626753e+02, -7.8892295e+01, 8.1184535e+02); + expectedForces[109] = Vec3(-4.6396103e+01, 3.1165111e+01, -3.5184949e+01); + expectedForces[110] = Vec3( 4.6295297e+02, -8.0135823e+01, -3.2963637e+02); + expectedForces[111] = Vec3( 5.5325945e+02, 3.8213691e+02, -5.9449911e+02); + expectedForces[112] = Vec3(-6.1770559e+02, 2.2322880e+02, -2.1022934e+01); + expectedForces[113] = Vec3( 2.3716825e+02, -3.8085281e+02, 4.9618193e+02); + expectedForces[114] = Vec3( 2.9972570e+02, 3.3773759e+02, 3.4933501e+02); + expectedForces[115] = Vec3( 1.9913039e+02, -3.2035626e+02, -9.7987777e+01); + expectedForces[116] = Vec3(-2.3506456e+02, 4.0030561e+02, -6.2604809e+02); + expectedForces[117] = Vec3( 6.0408777e+02, 5.6271523e+02, -5.8742635e+02); + expectedForces[118] = Vec3(-5.0707285e+02, 7.8511351e+02, -1.7561830e+02); + expectedForces[119] = Vec3( 5.6759945e+00, 6.9735233e+00, -9.8853787e+00); + expectedForces[120] = Vec3( 1.1918531e+02, -5.6200785e+02, 3.2333502e+02); + expectedForces[121] = Vec3( 5.1801315e+02, -3.4460898e+02, 1.1488242e+02); + expectedForces[122] = Vec3( 7.5859703e+00, 6.9528951e+01, -6.2437444e+00); + expectedForces[123] = Vec3( 1.1990899e+03, -1.2507886e+01, 1.1906562e+03); + expectedForces[124] = Vec3( 2.6001536e+02, -9.5041373e+01, -4.2547252e+02); + expectedForces[125] = Vec3(-3.5601586e+01, 9.1460220e+02, 6.2306102e+02); + expectedForces[126] = Vec3(-3.8254176e+01, 2.4796243e+02, 3.0638741e+02); + expectedForces[127] = Vec3(-3.8798311e+02, 1.2532794e+02, -3.1926601e+01); + expectedForces[128] = Vec3( 5.7672682e+01, 1.7487900e+02, -1.0319581e+02); + expectedForces[129] = Vec3( 4.4276215e+02, -1.5517993e+02, 3.8122873e+02); + expectedForces[130] = Vec3(-2.8119980e+02, -2.6530936e+02, 4.3545814e+01); + expectedForces[131] = Vec3( 5.9375768e+00, 1.6335780e+01, -3.6204644e+02); + expectedForces[132] = Vec3( 5.9733834e+02, -2.9843602e+02, 1.0541092e+03); + expectedForces[133] = Vec3(-3.4568461e+02, 2.2794808e+02, -8.4675886e+01); + expectedForces[134] = Vec3(-6.7882706e+01, -4.5016799e+02, -1.9387646e+02); + expectedForces[135] = Vec3( 5.6125478e+02, -1.1741092e+03, 1.4214256e+02); + expectedForces[136] = Vec3( 1.2766648e+02, 1.2519441e+02, -4.4359129e+02); + expectedForces[137] = Vec3(-2.7235507e+01, -1.0871423e+01, 3.2406976e+01); + expectedForces[138] = Vec3(-1.2110689e+03, 1.3038667e+02, -7.5331947e+02); + expectedForces[139] = Vec3( 3.2504988e+02, -7.1577942e+02, -2.4351454e+02); + expectedForces[140] = Vec3( 2.6466925e+02, 3.6878498e+02, -6.2044711e+01); + expectedForces[141] = Vec3(-6.2647276e+02, -4.7112562e+02, -6.1885184e+01); + expectedForces[142] = Vec3( 3.0996699e+01, 3.1033732e+02, -5.7493337e+02); + expectedForces[143] = Vec3( 2.4664962e+01, 7.8306665e+02, 3.7907751e+02); + expectedForces[144] = Vec3(-1.9847551e+02, -3.0052499e+02, -6.5192951e+01); + expectedForces[145] = Vec3(-5.0686773e+02, 1.1972933e+02, 3.6202910e+02); + expectedForces[146] = Vec3( 4.0004521e+02, -4.3205645e+02, 2.8583074e+02); + expectedForces[147] = Vec3(-2.9447542e+01, 6.3434099e+02, -6.5189179e+02); + expectedForces[148] = Vec3( 4.1588516e+02, -1.5534873e+02, -1.1031323e+01); + expectedForces[149] = Vec3( 1.2761543e+01, -5.6871456e+01, 2.8032565e+02); + expectedForces[150] = Vec3(-4.7527199e+01, 6.2549647e+02, -8.5007589e+02); + expectedForces[151] = Vec3( 1.6598949e+01, 1.1210199e+02, 2.0667266e+02); + expectedForces[152] = Vec3(-2.4012423e+00, -6.1728962e+01, -1.5057977e+01); + expectedForces[153] = Vec3(-3.6934056e+02, 2.3087063e+02, -3.3268511e+02); + expectedForces[154] = Vec3( 1.2658460e+02, 4.1809355e+02, 1.9550635e+02); + expectedForces[155] = Vec3(-1.9528152e+02, -1.9035919e+02, 1.4986704e+02); + expectedForces[156] = Vec3(-5.9608803e+00, 2.7258190e+02, 5.5318395e+02); + expectedForces[157] = Vec3(-1.0545084e+01, -1.8397001e+00, -3.3615498e+00); + expectedForces[158] = Vec3(-4.0827462e+02, -6.4070993e+01, -2.6614992e+02); + expectedForces[159] = Vec3(-1.5773827e+02, 4.7708702e+02, -9.9622711e+02); + expectedForces[160] = Vec3( 8.3896122e+01, 2.5959601e+02, 1.7728081e+02); + expectedForces[161] = Vec3(-2.4859055e+02, 8.1617294e+01, 2.7905586e+02); + expectedForces[162] = Vec3( 1.3694593e+02, -6.2640483e+02, -2.5308878e+02); + expectedForces[163] = Vec3(-1.5156337e+02, 1.1567379e+02, 1.8384602e+02); + expectedForces[164] = Vec3(-1.4794785e+02, -8.0381965e+01, 9.4028021e+02); + expectedForces[165] = Vec3(-3.5851252e+02, 2.6066489e+02, -4.1225343e+01); + expectedForces[166] = Vec3( 1.0820389e+02, -8.3485138e+01, 9.5047812e+01); + expectedForces[167] = Vec3( 2.0019411e+02, 5.0864719e+02, -4.8662239e+01); + expectedForces[168] = Vec3(-3.0716707e+02, -9.8820762e+02, 1.3660536e+01); + expectedForces[169] = Vec3( 8.5788590e+02, -1.0335921e+02, -2.2197815e+02); + expectedForces[170] = Vec3( 9.8072705e+00, 6.6224870e+02, -1.1594055e+02); + expectedForces[171] = Vec3(-3.6572453e+01, 2.4062731e+02, 1.7831682e+02); + expectedForces[172] = Vec3(-2.1274187e+00, -2.5471785e+02, -2.5813525e+02); + expectedForces[173] = Vec3( 3.4763673e+02, -2.0753062e+02, 7.5125390e+02); + expectedForces[174] = Vec3( 2.9010685e+01, -4.1894498e+02, -6.3847846e+02); + expectedForces[175] = Vec3( 3.0255245e+02, 2.5945698e+02, 2.3530662e+01); + expectedForces[176] = Vec3(-2.0827676e+01, 2.2568888e+01, 1.0890440e+01); + expectedForces[177] = Vec3( 2.2415739e+02, 3.5720682e+02, -8.7208211e+01); + expectedForces[178] = Vec3(-2.9808276e+02, 7.0108444e+01, -1.5361211e+02); + expectedForces[179] = Vec3( 2.3882234e+02, -2.6764176e+02, -1.7847229e+01); + expectedForces[180] = Vec3(-4.7380966e+02, 5.2547306e+01, 7.4446526e+02); + expectedForces[181] = Vec3( 4.2804072e+00, -2.2456284e+02, -2.0288206e+02); + expectedForces[182] = Vec3( 2.5474630e+00, 2.5211778e+01, 1.2675317e+01); + expectedForces[183] = Vec3(-1.4519676e+02, -1.7268277e+02, -8.4750014e+02); + expectedForces[184] = Vec3(-1.6850633e+02, 9.5223081e+02, -2.5415253e+02); + expectedForces[185] = Vec3(-2.1600185e+02, -1.6313340e+02, 1.8746411e+02); + expectedForces[186] = Vec3( 4.5719348e+01, -5.8877840e+01, -1.1199622e+02); + expectedForces[187] = Vec3(-9.0377199e+01, 2.2045926e+02, -3.2532356e+02); + expectedForces[188] = Vec3(-1.4523032e+02, -2.2127499e+02, 1.1526636e+02); + expectedForces[189] = Vec3( 1.9857975e+02, -1.8170037e+02, 3.2016150e+02); + expectedForces[190] = Vec3( 1.5659789e+02, 5.2984420e+01, -1.0121553e+02); + expectedForces[191] = Vec3( 1.3925504e+01, -1.1627739e+02, 1.7106106e+00); + expectedForces[192] = Vec3( 1.7560737e+01, 3.1275548e+02, 1.4568181e+02); + expectedForces[193] = Vec3( 8.5129168e-01, 3.2688468e+01, -2.0471785e+02); + expectedForces[194] = Vec3( 2.5640904e+02, -1.8345358e+02, 3.3082812e+02); + expectedForces[195] = Vec3( 1.5159266e+02, -7.9091822e+02, 7.6475475e+02); + expectedForces[196] = Vec3( 7.8546101e+02, 1.7887845e+02, -7.4508377e+01); + expectedForces[197] = Vec3( 6.9010029e+00, 2.1336674e+01, -7.8256484e+01); + expectedForces[198] = Vec3(-3.4033432e+01, -1.6471994e+02, -2.8721884e+02); + expectedForces[199] = Vec3(-1.2248359e+02, 5.3002993e+01, 3.5296174e+02); + expectedForces[200] = Vec3( 1.7497881e+02, 1.1744848e+02, 1.8127502e+02); + expectedForces[201] = Vec3(-1.1710882e+03, 8.7114752e+02, -1.3353036e+02); + expectedForces[202] = Vec3( 2.7510368e+02, -1.9393814e+02, 2.6671453e+02); + expectedForces[203] = Vec3( 7.3421287e+01, -3.8409917e+01, -1.0910368e+02); + expectedForces[204] = Vec3(-8.7394869e+02, -1.2323430e+03, -1.3693068e+02); + expectedForces[205] = Vec3( 2.5439149e+02, 2.4002077e+02, 3.0231859e+02); + expectedForces[206] = Vec3(-9.8167431e+01, 3.1515278e+02, -2.5512038e+02); + expectedForces[207] = Vec3( 2.7501189e+02, -4.9189774e+02, 4.5827877e+02); + expectedForces[208] = Vec3(-8.2333908e+02, -7.0609881e+02, 2.9188070e+02); + expectedForces[209] = Vec3(-2.9200330e+02, 1.9955124e+02, -7.9227826e+00); + expectedForces[210] = Vec3( 8.0151971e+02, 3.8996996e+02, -1.9508756e+02); + expectedForces[211] = Vec3(-6.2168096e+01, 2.4323951e+01, 9.8845638e+01); + expectedForces[212] = Vec3( 2.2980428e+01, -6.2829693e+02, -7.5253154e+02); + expectedForces[213] = Vec3(-5.7502634e+02, 8.2310635e+02, 3.7934867e+02); + expectedForces[214] = Vec3(-8.9168889e+01, 5.0052167e+01, -8.6850564e+01); + expectedForces[215] = Vec3( 2.7414821e+02, -5.9725191e+01, -3.7278778e+00); + expectedForces[216] = Vec3(-5.3230933e+02, 4.7698725e+02, -2.5857751e+02); + expectedForces[217] = Vec3( 2.1615644e+02, 6.0001233e+01, -1.1880182e+02); + expectedForces[218] = Vec3( 2.9837823e+01, -3.9275454e+01, -4.3913571e+01); + expectedForces[219] = Vec3(-5.6516561e+02, -1.6539113e+02, 3.3185872e+02); + expectedForces[220] = Vec3(-1.5484833e+01, -1.0085566e+01, -2.8199778e+01); + expectedForces[221] = Vec3( 6.4295337e+02, -2.7398997e+02, 8.2320867e+02); + expectedForces[222] = Vec3( 3.3816540e+02, -1.8492046e+02, 8.6215770e+02); + expectedForces[223] = Vec3( 2.4367872e+02, 8.9527142e+01, -5.9973680e+02); + expectedForces[224] = Vec3(-6.1601439e+02, -5.3093862e+02, 4.1696221e+01); + expectedForces[225] = Vec3( 2.2521478e+02, -2.9234267e+02, 2.9760244e+02); + expectedForces[226] = Vec3(-1.2672295e+02, 2.5753736e+01, -1.6216252e+02); + expectedForces[227] = Vec3( 1.1136724e+02, 4.3446676e+00, -1.4045447e+01); + expectedForces[228] = Vec3( 3.5554849e+02, 7.7446255e+00, 5.8722356e+02); + expectedForces[229] = Vec3(-7.8313952e+02, -5.9206053e+01, 5.1181391e+02); + expectedForces[230] = Vec3(-9.5647729e+01, -4.6045792e+02, -3.1515210e+02); + expectedForces[231] = Vec3( 8.7273284e+01, 8.0310279e+02, -1.2212040e+03); + expectedForces[232] = Vec3(-9.0853819e+02, -7.6005570e+02, 1.8578569e+02); + expectedForces[233] = Vec3( 1.2061615e+02, -3.2834560e+02, 5.1291192e+01); + expectedForces[234] = Vec3( 6.0149262e+02, 1.6081852e+03, -1.0922015e+03); + expectedForces[235] = Vec3(-5.8087260e+01, -2.6676779e+02, -1.5006920e+02); + expectedForces[236] = Vec3(-1.0997771e+01, 1.3012815e+02, 5.8615633e+02); + expectedForces[237] = Vec3( 4.9821503e+02, -9.5783644e+01, -6.5708073e+02); + expectedForces[238] = Vec3(-4.9394992e+02, -7.0445435e+02, -1.5540228e+02); + expectedForces[239] = Vec3( 1.5710340e+01, 1.9170336e+02, 4.6707393e+02); + expectedForces[240] = Vec3(-1.2599557e+03, 5.6104975e+02, 6.5853210e+02); + expectedForces[241] = Vec3( 1.3032986e+01, -2.7481865e+01, 8.0373029e+00); + expectedForces[242] = Vec3( 1.4371505e+02, -5.2615293e+01, -3.7929456e+02); + expectedForces[243] = Vec3( 6.0025739e+01, 1.4474905e+02, 3.6414330e+02); + expectedForces[244] = Vec3( 4.5364033e+02, 7.0785823e+01, -2.9279112e+02); + expectedForces[245] = Vec3(-9.7012956e+01, -8.2545229e+01, -5.4567106e+01); + expectedForces[246] = Vec3(-3.6449281e+02, -5.6669832e+02, -3.5196038e+02); + expectedForces[247] = Vec3( 2.6571354e+02, -2.5051716e+02, -4.7199161e+01); + expectedForces[248] = Vec3(-4.7285701e+01, 1.7950093e+02, 8.0633971e+01); + expectedForces[249] = Vec3( 1.8035439e+02, 4.6977540e+02, 2.2589769e+02); + expectedForces[250] = Vec3( 5.9853399e+01, 1.5477006e+02, -1.7011806e+02); + expectedForces[251] = Vec3(-2.6084741e+02, -2.0538756e+02, 1.0269002e+02); + expectedForces[252] = Vec3( 4.0221722e+02, -1.0368371e+02, -1.3842460e+01); + expectedForces[253] = Vec3(-4.4264447e+02, -3.0334810e+02, 1.6740779e+02); + expectedForces[254] = Vec3(-1.7373662e+02, 1.5020202e+02, -3.3761418e+02); + expectedForces[255] = Vec3( 4.7508953e+01, -5.4028784e+02, -3.6291329e+01); + expectedForces[256] = Vec3( 5.4807168e+02, -2.0293664e+02, 5.5114363e+02); + expectedForces[257] = Vec3(-4.9787370e+01, 4.5106329e+01, -5.7524550e+01); + expectedForces[258] = Vec3(-5.1584935e+02, 1.5014186e+02, -6.6369834e+02); + expectedForces[259] = Vec3(-6.0140298e+01, -9.4127280e+01, 8.7495796e+01); + expectedForces[260] = Vec3( 8.0619588e+02, -2.1066454e+02, -5.9371508e+01); + expectedForces[261] = Vec3( 1.2817429e+02, -2.7044116e+02, 5.3213275e+02); + expectedForces[262] = Vec3(-4.1467442e-01, -1.3641138e+02, -8.5576287e+01); + expectedForces[263] = Vec3(-5.6508528e+01, 2.4091504e+01, -7.9236147e+01); + expectedForces[264] = Vec3( 1.4123799e+02, 2.1326444e+02, 1.9141445e+02); + expectedForces[265] = Vec3( 1.6579721e+02, -3.2221503e+02, -1.5197776e+02); + expectedForces[266] = Vec3(-2.5871222e+02, -2.6345996e+02, -1.1149413e+03); + expectedForces[267] = Vec3(-1.2859743e+02, -3.9214753e+02, -6.5874862e+02); + expectedForces[268] = Vec3( 1.7237157e+02, -2.8729010e+02, 3.2000889e+02); + expectedForces[269] = Vec3( 6.6312203e+02, 3.5683926e+02, 9.7235616e+01); + expectedForces[270] = Vec3(-1.1860349e+02, -4.3528895e+02, 1.1598672e+03); + expectedForces[271] = Vec3( 7.7135123e+01, -2.1671305e+02, -2.3088548e+02); + expectedForces[272] = Vec3( 7.2863708e+01, 5.2065158e+02, 1.5704752e+02); + expectedForces[273] = Vec3(-3.6727477e+02, -6.0885463e+01, 4.1193960e+01); + expectedForces[274] = Vec3( 5.4858881e+01, 1.6886577e+02, -1.1662392e+01); + expectedForces[275] = Vec3( 3.2070061e+01, -1.6138709e+01, -7.6648912e+00); + expectedForces[276] = Vec3( 2.5695892e+02, 7.7719531e+01, -8.3154765e+02); + expectedForces[277] = Vec3(-3.3460202e+01, -1.3077348e+02, 3.6110539e+01); + expectedForces[278] = Vec3(-4.1360402e+02, 2.7754335e+02, -1.1139467e+02); + expectedForces[279] = Vec3( 1.0012775e+02, 1.4365237e+03, 2.6972544e+02); + expectedForces[280] = Vec3( 7.8750024e+02, -2.3376123e+02, 9.5969232e+02); + expectedForces[281] = Vec3(-2.2493912e+02, -1.1444344e+01, -6.3713547e+01); + expectedForces[282] = Vec3(-9.4211966e+01, -3.9286586e+02, -7.0932607e+01); + expectedForces[283] = Vec3( 1.6192138e+02, 2.3010404e+02, -2.1511498e+02); + expectedForces[284] = Vec3(-4.9644702e+02, -1.1894844e+01, -4.7458477e+02); + expectedForces[285] = Vec3(-1.0151600e+02, -4.2789293e+02, 5.2698223e+02); + expectedForces[286] = Vec3( 1.1350409e+01, 1.5126445e+02, -5.2740587e+01); + expectedForces[287] = Vec3(-4.7715521e+02, -3.6476152e+02, -5.4346958e+02); + expectedForces[288] = Vec3(-9.4019721e+01, -2.4758228e+02, 4.2219712e+02); + expectedForces[289] = Vec3( 3.1525053e+01, 3.7927245e+02, -2.4577041e+02); + expectedForces[290] = Vec3( 4.4004025e+02, -9.4883983e+01, -6.9075632e+01); + expectedForces[291] = Vec3(-2.6553328e+02, -2.7059185e+02, 3.1145935e+02); + expectedForces[292] = Vec3( 1.1199463e+02, 9.0805870e+01, 8.0258804e+01); + expectedForces[293] = Vec3( 7.8056273e+01, -3.5931761e+01, -1.9249727e+02); + expectedForces[294] = Vec3(-1.2443366e+01, -1.4631721e+02, 7.9733561e+01); + expectedForces[295] = Vec3(-3.2866900e+02, 1.1527926e+02, -9.3135590e+01); + expectedForces[296] = Vec3( 7.5078643e+01, -7.2653837e+02, -1.0830908e+02); + expectedForces[297] = Vec3( 1.0361037e+02, 1.5478274e+02, 1.1293089e+03); + expectedForces[298] = Vec3(-2.4014663e+02, -5.6771824e+02, 1.5441974e+02); + expectedForces[299] = Vec3(-6.8441034e+01, -1.1226846e+02, -5.4497343e+02); + expectedForces[300] = Vec3( 2.9803689e+02, 1.0649462e+03, 2.5408768e+02); + expectedForces[301] = Vec3( 5.6356599e+01, -2.3035579e+02, 7.6928758e+01); + expectedForces[302] = Vec3( 1.0229494e+02, -1.9615696e+02, -3.2600199e+02); + expectedForces[303] = Vec3(-7.0312065e+01, -3.1170055e+02, 5.6453888e+02); + expectedForces[304] = Vec3(-7.0752582e+01, 1.2273280e+02, -1.6740503e+01); + expectedForces[305] = Vec3( 6.8972998e+02, -2.8067032e+02, 6.6502848e+01); + expectedForces[306] = Vec3(-8.8407472e+02, 3.7818347e+02, -1.2141945e+03); + expectedForces[307] = Vec3(-1.0445122e+02, -4.4818836e+02, -9.5227168e+00); + expectedForces[308] = Vec3( 8.3015802e+02, 5.0941309e+02, 3.2593793e+01); + expectedForces[309] = Vec3( 7.6887033e+02, 4.3490548e+02, -1.0826101e+03); + expectedForces[310] = Vec3( 1.4352949e+02, -3.9479802e+01, 1.7718790e+02); + expectedForces[311] = Vec3(-2.5204642e+02, -3.3888239e+02, -2.7365802e+02); + expectedForces[312] = Vec3(-4.4783121e+02, 4.4465580e+02, 9.2506336e+02); + expectedForces[313] = Vec3(-3.3390337e+01, -5.0097602e+02, -3.6812516e+02); + expectedForces[314] = Vec3(-4.1862341e+02, 1.9519764e+02, -2.4571211e+02); + expectedForces[315] = Vec3(-1.4176845e+02, -3.3767798e+01, 1.7800248e+02); + expectedForces[316] = Vec3(-4.7411046e+01, 2.3841278e+01, -1.5183689e+01); + expectedForces[317] = Vec3( 1.6723204e+01, 1.4145797e+02, -1.6930384e+01); + expectedForces[318] = Vec3(-8.4841167e+02, -2.1282818e+02, 8.1614626e+01); + expectedForces[319] = Vec3( 6.5941519e+00, -1.1472179e+02, -2.3181002e+02); + expectedForces[320] = Vec3( 2.2464095e+01, -5.7606215e+00, 5.2865780e+00); + expectedForces[321] = Vec3( 3.8063827e+02, 2.4597014e+02, -4.1947008e+01); + expectedForces[322] = Vec3(-3.1531672e+02, 3.5038104e+02, -3.2724191e+02); + expectedForces[323] = Vec3( 7.4741163e+01, 7.2296536e+01, 3.1768919e+02); + expectedForces[324] = Vec3( 7.9578966e+02, -1.5345175e+02, -7.1301288e+02); + expectedForces[325] = Vec3(-3.1387318e+01, 1.7528515e+01, -3.4100670e+01); + expectedForces[326] = Vec3( 9.3853572e-01, 6.8496077e+00, 1.2234894e+01); + expectedForces[327] = Vec3(-1.3099690e+02, -4.0135958e+02, -4.3248135e+02); + expectedForces[328] = Vec3( 4.3988113e+02, -1.5944416e+02, 5.4620163e+01); + expectedForces[329] = Vec3( 1.3509243e+01, 3.6990268e+00, -2.6251838e-01); + expectedForces[330] = Vec3(-8.7459998e+01, -6.4319025e+02, 2.2863360e+02); + expectedForces[331] = Vec3(-3.5181606e+02, 3.1131978e+02, 2.8037788e+02); + expectedForces[332] = Vec3( 1.9545884e+02, 4.3994512e+01, -2.5158598e+02); + expectedForces[333] = Vec3( 1.8100917e+00, 1.9534738e+02, 1.7181161e+02); + expectedForces[334] = Vec3(-1.1846876e+02, 1.5368782e+02, 2.2261016e+02); + expectedForces[335] = Vec3( 1.4866155e+02, -4.7983795e+02, 3.0361323e+02); + expectedForces[336] = Vec3(-7.7242468e+02, 2.0736079e+02, -8.6661236e+02); + expectedForces[337] = Vec3(-7.9875679e+00, -9.0946585e+02, -7.1617627e+01); + expectedForces[338] = Vec3( 2.2543457e+02, 2.0215639e+02, 4.4285374e+02); + expectedForces[339] = Vec3(-2.6252013e+02, -1.0336519e+02, -2.6630451e+02); + expectedForces[340] = Vec3( 5.0907589e+02, -1.2491931e+02, -4.3015857e+01); + expectedForces[341] = Vec3(-6.0362692e+01, 1.0025664e+02, -9.3389235e+01); + expectedForces[342] = Vec3( 5.8779874e+02, 3.7600030e+02, 2.5345454e+02); + expectedForces[343] = Vec3(-1.3661048e+02, 1.6498482e+02, -2.6789925e+01); + expectedForces[344] = Vec3( 4.9840419e+01, -1.2136315e+02, 2.5455320e+01); + expectedForces[345] = Vec3( 2.3324807e+02, -3.6601512e+02, 5.6798114e+01); + expectedForces[346] = Vec3( 5.5853546e+01, -4.9035168e+00, -5.8726331e+02); + expectedForces[347] = Vec3(-3.8918158e+01, 3.0380495e+02, 1.0944883e+01); + expectedForces[348] = Vec3(-2.6092065e+02, 4.3443036e+02, -1.3673862e+02); + expectedForces[349] = Vec3( 1.5195166e+02, 1.1879426e+01, -1.1429493e+02); + expectedForces[350] = Vec3(-8.5687107e+02, -1.7938881e+02, 4.5576455e+00); + expectedForces[351] = Vec3(-1.0117388e+03, -3.2686610e+02, 2.9733049e+02); + expectedForces[352] = Vec3(-2.3946369e+02, 4.9753786e+02, 7.2681440e+02); + expectedForces[353] = Vec3( 3.9085837e+01, 7.4391931e+00, 3.4179196e+00); + expectedForces[354] = Vec3( 1.0462977e+03, 4.3639578e+02, -5.7349371e+02); + expectedForces[355] = Vec3( 1.2715333e+02, -5.7907885e+02, 5.7463165e+02); + expectedForces[356] = Vec3(-1.5968981e+02, 2.2295605e+01, 6.3554487e+01); + expectedForces[357] = Vec3(-1.9666111e+02, -2.0286725e+02, -8.3590992e+01); + expectedForces[358] = Vec3( 5.9985006e+00, 2.9764307e+01, 3.1304672e+01); + expectedForces[359] = Vec3( 1.0409792e+02, 4.3974987e+02, -9.1530162e+02); + expectedForces[360] = Vec3( 2.9538724e+02, 1.4353710e+02, 2.1558768e+02); + expectedForces[361] = Vec3(-3.7974445e+02, -9.0749144e+01, 1.4531502e+02); + expectedForces[362] = Vec3( 3.7089093e+02, 2.2523397e+02, -2.9760698e+02); + expectedForces[363] = Vec3(-7.6884906e+01, -2.7486958e+02, 3.5671043e+02); + expectedForces[364] = Vec3( 4.3400097e+02, 2.2275226e+02, 5.9201087e+01); + expectedForces[365] = Vec3( 2.1177620e+02, -6.4990517e+02, -1.8431623e+02); + expectedForces[366] = Vec3(-8.2234148e+01, 4.9900036e+02, 3.0906858e+02); + expectedForces[367] = Vec3(-1.4784097e+02, 1.3442463e+02, -2.6811487e+02); + expectedForces[368] = Vec3( 2.2289541e+02, -4.1933983e+02, 1.3646246e+01); + expectedForces[369] = Vec3(-2.1199481e+02, 6.2103281e+01, 1.6049768e+02); + expectedForces[370] = Vec3(-2.9429845e+01, -1.3944740e+01, 1.6000003e+01); + expectedForces[371] = Vec3(-1.5093250e+02, -1.9541345e+02, -1.5879844e+02); + expectedForces[372] = Vec3( 2.2218133e+02, 7.5740668e+01, -7.0754853e+02); + expectedForces[373] = Vec3(-4.7529615e+02, -3.5259490e+02, 3.8025744e+02); + expectedForces[374] = Vec3( 4.9308495e+01, 1.2206152e+02, 4.2704595e+01); + expectedForces[375] = Vec3(-3.6408113e+02, 9.5905960e+02, 3.3861668e+02); + expectedForces[376] = Vec3( 1.5324093e+02, -1.4375341e+02, -9.1369900e+01); + expectedForces[377] = Vec3(-3.5343609e+02, -4.4662438e+02, 3.1741831e+02); + expectedForces[378] = Vec3(-8.2721281e+02, -6.4969313e+01, 4.1869320e+02); + expectedForces[379] = Vec3(-8.7419096e+00, -4.6278343e+01, -3.0259942e+01); + expectedForces[380] = Vec3( 1.6814871e+01, 4.5462601e+01, -3.5204538e+01); + expectedForces[381] = Vec3( 1.9043143e+02, 5.1101135e+02, 2.9970918e+02); + expectedForces[382] = Vec3(-4.3547560e+02, -7.7495770e+01, -8.2311440e+01); + expectedForces[383] = Vec3( 1.3206505e+02, 4.0993476e+01, 1.5150623e+01); + expectedForces[384] = Vec3( 4.6163268e+01, -2.7722119e+01, -2.2996255e+02); + expectedForces[385] = Vec3(-4.7033552e+01, 1.5721545e+02, -9.2562636e+01); + expectedForces[386] = Vec3(-2.4164903e+02, -1.4771464e+02, -5.1675638e+01); + expectedForces[387] = Vec3( 1.3445564e+03, 3.5387081e+02, -3.7402713e+02); + expectedForces[388] = Vec3(-2.6290280e+02, 2.5025510e+02, 3.0570707e+01); + expectedForces[389] = Vec3(-4.4624214e+02, -2.4919412e+02, 1.1336564e+03); + expectedForces[390] = Vec3( 3.1188483e+02, 6.4836125e+02, 4.5477683e+01); + expectedForces[391] = Vec3( 2.5570674e+02, -2.7101115e+02, -1.2579817e+02); + expectedForces[392] = Vec3(-3.4941759e+02, -3.2508734e+01, -5.6131515e+01); + expectedForces[393] = Vec3(-1.2734301e+02, -2.0417657e+02, 5.7738004e+02); + expectedForces[394] = Vec3( 5.0435795e+01, -9.5203527e+01, -4.1237509e+00); + expectedForces[395] = Vec3(-6.8258463e+01, 1.7475914e+02, -1.6422294e+02); + expectedForces[396] = Vec3( 2.6455575e+02, 2.6880230e+02, -1.6607620e+01); + expectedForces[397] = Vec3(-3.5968167e+02, 6.6092937e+01, 1.5915445e+02); + expectedForces[398] = Vec3( 8.4092494e-01, -5.9896731e+01, -2.1856007e+01); + expectedForces[399] = Vec3(-1.9237984e+02, -1.6506355e+02, 1.3370845e+02); + expectedForces[400] = Vec3( 4.7023043e+02, 1.2931257e+02, -1.7013618e+02); + expectedForces[401] = Vec3( 9.4928843e+01, -3.1613892e+02, -4.6973091e+02); + expectedForces[402] = Vec3(-2.9180818e+02, 6.5496755e+02, -2.9430870e+02); + expectedForces[403] = Vec3( 1.6670668e+02, -2.4693913e+02, -8.8775735e+01); + expectedForces[404] = Vec3(-1.4218604e+02, 2.3173349e+02, 3.9869740e+02); + expectedForces[405] = Vec3( 4.3469431e+02, -2.4686568e+02, -2.6838523e+02); + expectedForces[406] = Vec3( 1.0671130e+02, 3.9710106e+02, 2.6478100e+02); + expectedForces[407] = Vec3(-4.4281099e+02, -3.2746126e+01, -2.0719929e+02); + expectedForces[408] = Vec3( 1.1864952e+01, -1.5901568e+02, 1.1865945e+01); + expectedForces[409] = Vec3(-6.0546863e+01, -1.3488005e+02, -2.9223986e+02); + expectedForces[410] = Vec3( 2.5845942e+01, 1.7545933e+02, -1.4590654e+02); + expectedForces[411] = Vec3(-3.0776460e+02, 2.7351986e+02, -2.0386483e+02); + expectedForces[412] = Vec3( 1.7301558e+02, 8.3012339e+01, 7.6018513e+02); + expectedForces[413] = Vec3( 1.2893147e+02, -3.9937475e+00, 1.4197628e+01); + expectedForces[414] = Vec3(-3.9803615e+02, -4.4825663e+02, 2.8616211e+01); + expectedForces[415] = Vec3(-2.3586809e+02, -8.9306136e+01, 7.5265669e+02); + expectedForces[416] = Vec3( 8.3814512e+02, -9.5563706e+00, 2.8738759e+02); + expectedForces[417] = Vec3(-3.8269399e+02, -2.3650170e+02, 1.7330415e+01); + expectedForces[418] = Vec3( 7.2310675e+00, 2.4731653e+01, 1.9491126e+01); + expectedForces[419] = Vec3( 8.4485111e+01, 9.0560261e+01, -1.4261777e+01); + expectedForces[420] = Vec3( 2.1829925e+02, -8.3951651e+01, -7.8910117e+02); + expectedForces[421] = Vec3(-2.4228018e+02, -5.7097512e+01, 2.6447829e+02); + expectedForces[422] = Vec3( 6.9666665e+01, -4.7313678e+02, 4.5559673e+02); + expectedForces[423] = Vec3( 1.0108369e+02, 4.6568610e+02, 2.5612541e+02); + expectedForces[424] = Vec3( 7.2334238e+01, -1.5660040e+02, -2.6278686e+02); + expectedForces[425] = Vec3( 1.0749954e+03, 2.4395658e+02, -8.7308262e+01); + expectedForces[426] = Vec3( 5.4983082e+02, 5.6528577e+02, -3.0489991e+02); + expectedForces[427] = Vec3(-2.1210132e+02, -1.5871954e+02, -1.6936452e+02); + expectedForces[428] = Vec3(-9.5473983e+01, 7.4879276e+01, 5.5720204e+01); + expectedForces[429] = Vec3( 5.6417182e+02, -1.3478250e+02, -4.8006673e+01); + expectedForces[430] = Vec3(-1.0055266e+02, -8.3811289e+01, 6.5259748e+01); + expectedForces[431] = Vec3( 3.0553989e+01, 4.0927300e+02, 6.2242246e+02); + expectedForces[432] = Vec3(-6.0956353e+02, 9.0301312e+02, -1.4063582e+01); + expectedForces[433] = Vec3( 3.2774559e+02, -1.0849473e+02, -8.8877712e+01); + expectedForces[434] = Vec3( 2.1371643e+02, -7.2067980e+01, 2.4803863e+02); + expectedForces[435] = Vec3(-9.0636479e+01, 1.0673514e+03, 1.3005625e+02); + expectedForces[436] = Vec3(-3.5058624e+02, -1.4968284e+02, 1.4340635e+02); + expectedForces[437] = Vec3( 3.4640813e+01, -4.8035225e+01, 4.4066226e+01); + expectedForces[438] = Vec3(-2.3414523e+02, -9.1359130e+01, 2.8535427e+02); + expectedForces[439] = Vec3(-2.7156547e+02, -6.3426763e+01, 1.6968017e+01); + expectedForces[440] = Vec3(-2.8751166e+00, 4.3192169e+00, -2.1401359e+00); + expectedForces[441] = Vec3(-2.0241419e+01, 4.2856138e+02, 7.3204868e+01); + expectedForces[442] = Vec3(-4.2166169e+01, -2.2454013e+01, -5.4998450e+01); + expectedForces[443] = Vec3( 2.6442026e+02, -1.1670567e+02, 2.8879291e+02); + expectedForces[444] = Vec3(-4.9762729e+02, 4.7320314e+02, 3.2506251e+02); + expectedForces[445] = Vec3(-3.0994232e+02, 3.6728867e+02, -6.8793662e+02); + expectedForces[446] = Vec3(-5.6328374e+00, -2.3284824e+00, 1.9650486e+01); + expectedForces[447] = Vec3( 4.0145354e+02, 7.0143762e+02, 1.3039041e+02); + expectedForces[448] = Vec3( 1.3270713e+02, -3.3050447e+02, 2.8630784e+02); + expectedForces[449] = Vec3(-3.8904836e+02, -4.6125118e+01, -3.8815388e+02); + expectedForces[450] = Vec3( 4.6293066e+02, -2.4970158e+02, -5.7231818e+01); + expectedForces[451] = Vec3(-4.7707142e+00, 1.7120822e-01, 4.5081299e+00); + expectedForces[452] = Vec3( 3.5968818e+01, -1.1892248e+01, 1.2184792e+02); + expectedForces[453] = Vec3( 4.4939172e+02, 4.8377647e+02, 3.0529778e+02); + expectedForces[454] = Vec3(-2.9071570e+02, -9.0611613e+01, -2.5190431e+02); + expectedForces[455] = Vec3(-1.4344537e+02, -1.3061997e+03, 3.8343947e+02); + expectedForces[456] = Vec3( 4.1580940e+02, -3.6864043e+02, 6.6384066e+02); + expectedForces[457] = Vec3(-3.4869949e+02, 3.3262427e+02, -8.3156358e+01); + expectedForces[458] = Vec3(-5.8565457e+00, -5.1879987e+02, -7.2717213e+02); + expectedForces[459] = Vec3(-1.0514593e+02, -2.6844396e+02, 3.0849659e+02); + expectedForces[460] = Vec3(-1.2562153e+02, 6.5438031e+01, -2.3521687e+02); + expectedForces[461] = Vec3( 8.3330016e+02, -6.7961048e+02, -7.2442064e+02); + expectedForces[462] = Vec3(-1.3328298e+02, 1.6143544e+02, -3.2000493e+02); + expectedForces[463] = Vec3(-1.1035002e+02, -8.6040775e+01, 2.0953986e+02); + expectedForces[464] = Vec3(-2.7702219e+02, -1.2156319e+02, -3.8897654e+02); + expectedForces[465] = Vec3( 3.6277432e+02, -7.0422679e+02, -8.2487472e+02); + expectedForces[466] = Vec3(-2.3947587e+02, -4.3625964e+00, 4.8716989e+01); + expectedForces[467] = Vec3(-2.6210552e+02, 9.9730213e+01, -2.4465307e+02); + expectedForces[468] = Vec3(-4.1344138e+01, -3.8636310e+01, -1.0720610e+01); + expectedForces[469] = Vec3( 2.3928584e+01, -1.3030908e+01, -1.7631168e+01); + expectedForces[470] = Vec3(-1.1873594e+02, -3.3905287e+00, -8.4575994e+01); + expectedForces[471] = Vec3( 4.3384846e+02, -4.8660929e+02, -2.4015737e+02); + expectedForces[472] = Vec3( 3.8974922e+01, 2.4401913e+02, -1.2060132e+02); + expectedForces[473] = Vec3(-4.2239647e+02, -8.6924630e+01, 5.7884013e+02); + expectedForces[474] = Vec3( 1.7222431e+02, -1.9292167e+01, 4.4184770e+01); + expectedForces[475] = Vec3(-4.8871102e+01, 1.8185057e+02, -1.3144294e+02); + expectedForces[476] = Vec3(-1.1467881e+02, -1.8387284e+02, -2.6935761e+01); + expectedForces[477] = Vec3( 4.4415601e+02, -8.6415426e+02, -2.2765803e+02); + expectedForces[478] = Vec3( 2.0893474e+02, 1.3529112e+02, 2.4108004e+02); + expectedForces[479] = Vec3(-1.2802570e+01, -4.7089261e+00, -7.0024810e+00); + expectedForces[480] = Vec3(-1.0878354e+02, 4.5030357e+02, -3.9086153e+02); + expectedForces[481] = Vec3(-3.7659745e+01, -4.9295745e+01, -6.0028516e+01); + expectedForces[482] = Vec3( 1.8851809e+02, -1.6863914e+02, 1.2031505e+02); + expectedForces[483] = Vec3( 2.2040686e+02, -1.1953187e+03, 2.9106238e+02); + expectedForces[484] = Vec3(-1.1642847e+01, 5.6739977e+01, 3.7532413e+00); + expectedForces[485] = Vec3( 3.5013234e+00, 2.8236323e+01, -1.1738866e+01); + expectedForces[486] = Vec3(-2.0051506e+03, -5.3138994e+02, 4.0428126e+02); + expectedForces[487] = Vec3( 1.6887843e+02, 1.1687735e+02, -9.6232177e+01); + expectedForces[488] = Vec3( 2.5030722e+02, -3.6662537e+02, -5.8595505e+01); + expectedForces[489] = Vec3(-1.5924273e+01, -2.1761920e+02, -3.4885425e+01); + expectedForces[490] = Vec3( 1.0423157e+02, 4.0767827e+01, 1.4036192e+02); + expectedForces[491] = Vec3( 5.0090776e+02, -5.0455702e+01, -4.2524815e+02); + expectedForces[492] = Vec3( 3.8037844e+02, 5.7460724e+02, 2.1243310e+02); + expectedForces[493] = Vec3(-1.1487653e+02, 3.3550952e+01, -5.7050397e+01); + expectedForces[494] = Vec3( 1.8425697e+02, -2.7223857e+02, -2.9384020e+01); + expectedForces[495] = Vec3(-1.1115514e+02, -4.4519957e+02, -3.3628896e+02); + expectedForces[496] = Vec3( 3.8865823e+02, -2.1372852e+02, -7.8979988e+02); + expectedForces[497] = Vec3(-3.1740258e+02, 4.4824683e+02, -5.0382680e+02); + expectedForces[498] = Vec3( 1.5521684e+02, -1.5278429e+02, -1.8418006e+02); + expectedForces[499] = Vec3(-2.2213191e+01, 7.1015095e+00, 1.0308820e+01); + expectedForces[500] = Vec3( 3.0011560e+01, 2.4584541e+02, -5.3231694e+02); + expectedForces[501] = Vec3(-8.4865171e+02, -2.0279022e+02, -6.8435095e+02); + expectedForces[502] = Vec3( 7.0477549e+00, 2.7626774e+01, -1.6246047e+01); + expectedForces[503] = Vec3(-7.1309648e+01, -1.6054218e+02, -3.1621746e+01); + expectedForces[504] = Vec3( 3.6317856e+02, 1.9055487e+02, 3.9196046e+01); + expectedForces[505] = Vec3( 1.4643265e+02, -1.2295335e+03, -2.2268806e+01); + expectedForces[506] = Vec3(-3.6638240e+02, -6.5310612e+00, -6.8077013e+02); + expectedForces[507] = Vec3( 1.9107813e+02, -6.2176534e+02, 5.1826941e+02); + expectedForces[508] = Vec3( 1.7226933e+02, -3.8939126e+02, -7.4174355e+02); + expectedForces[509] = Vec3( 1.3541890e+02, 4.1350561e+02, -2.6155396e+02); + expectedForces[510] = Vec3( 1.6452609e+02, -4.1963597e+02, 1.6322800e+02); + expectedForces[511] = Vec3( 9.1248387e+01, -1.3380408e+01, -5.1326806e+02); + expectedForces[512] = Vec3( 1.2420564e+02, 8.9492432e+02, 2.8660661e+02); + expectedForces[513] = Vec3( 4.5609859e+02, 3.4252036e+01, -2.3830457e+02); + expectedForces[514] = Vec3(-8.8282131e+01, -1.4512876e+02, -4.5703642e+01); + expectedForces[515] = Vec3(-6.9194714e+01, 5.5053415e+02, -3.9527911e+02); + expectedForces[516] = Vec3(-1.5570798e+02, 4.1650792e-02, 3.0224667e+02); + expectedForces[517] = Vec3( 9.2007640e+01, 3.6378499e+02, -2.2069415e+01); + expectedForces[518] = Vec3( 2.7996922e+02, -2.0932322e+02, 6.2987796e+01); + expectedForces[519] = Vec3(-7.4985282e+01, 1.3508916e+02, 1.1453750e+02); + expectedForces[520] = Vec3( 1.2149786e+01, 4.2161047e+02, -2.9521571e+02); + expectedForces[521] = Vec3( 1.9419524e+01, -8.6619683e+01, -9.4040609e+01); + expectedForces[522] = Vec3( 3.5495800e+01, 6.4028894e+01, 1.2320699e+02); + expectedForces[523] = Vec3(-5.6501302e+02, -1.2497462e+02, 8.1633096e+02); + expectedForces[524] = Vec3(-3.1775230e+02, 1.6467221e+02, -4.8242287e+01); + expectedForces[525] = Vec3(-1.8325245e+02, -1.0751941e+02, 6.2172117e+02); + expectedForces[526] = Vec3( 1.8164299e+00, 8.0654784e-01, -1.4484741e+01); + expectedForces[527] = Vec3( 2.6686986e+00, 1.5933475e+01, -6.8843007e+01); + expectedForces[528] = Vec3(-1.3208642e+02, -1.2281791e+02, 7.8417959e+01); + expectedForces[529] = Vec3(-4.8078193e+01, -1.5140963e+02, 8.3605002e+01); + expectedForces[530] = Vec3( 8.5925332e+01, 1.9959621e+01, -5.9034655e+01); + expectedForces[531] = Vec3(-3.1311626e+00, -3.4009931e+01, -1.5895685e+02); + expectedForces[532] = Vec3(-9.9694666e+01, 1.0296874e+00, 1.0482739e+02); + expectedForces[533] = Vec3( 2.8954747e+02, 1.2018666e+02, 2.2155006e+02); + expectedForces[534] = Vec3( 3.2588176e+02, 3.6622498e+01, 3.5801460e+02); + expectedForces[535] = Vec3(-6.5985617e+01, -3.5501709e+02, 6.8149810e+01); + expectedForces[536] = Vec3(-4.7632753e+02, 2.7936656e+02, 1.5548558e+02); + expectedForces[537] = Vec3( 4.7724904e+02, 2.1647106e+02, 1.2003317e+02); + expectedForces[538] = Vec3(-1.6225405e+02, 1.4264998e+02, -1.0113321e+02); + expectedForces[539] = Vec3(-3.2540487e+01, -7.5643223e+01, 1.6054148e+01); + expectedForces[540] = Vec3( 4.3311991e+02, 5.8082595e+02, 1.9354276e+02); + expectedForces[541] = Vec3(-3.4924430e+02, -7.0056069e+01, 1.0274560e+02); + expectedForces[542] = Vec3( 1.9441645e+02, -2.0017354e+02, -2.3280717e+02); + expectedForces[543] = Vec3(-4.1530380e+01, -5.6394351e+02, 2.4472509e+02); + expectedForces[544] = Vec3(-1.6193396e+01, -8.0431396e+01, -2.9094018e+02); + expectedForces[545] = Vec3(-1.9414773e+01, 4.6180982e+01, 3.3123072e+01); + expectedForces[546] = Vec3(-3.9314039e+02, -3.9874866e+02, 4.5308571e+02); + expectedForces[547] = Vec3(-7.1897482e+01, -1.1940445e+02, -2.7405931e+02); + expectedForces[548] = Vec3( 3.0646396e+02, 6.1235747e+01, -1.5253270e+02); + expectedForces[549] = Vec3(-3.2480464e+02, 4.3056561e+02, 3.2532485e+01); + expectedForces[550] = Vec3( 1.2818655e+02, 7.4294994e-01, -5.7650521e+00); + expectedForces[551] = Vec3(-1.7481437e+02, -2.6203225e+02, -9.6793481e+01); + expectedForces[552] = Vec3( 1.9259110e+02, 3.0171883e+02, 5.2403235e+02); + expectedForces[553] = Vec3(-7.8132123e+01, -7.6569340e+00, -1.1140240e+02); + expectedForces[554] = Vec3(-5.2504673e+02, -4.3700574e+02, 4.3321261e+02); + expectedForces[555] = Vec3(-9.9785283e+02, 2.7139143e+02, -4.1723547e+02); + expectedForces[556] = Vec3( 2.7115933e+02, -8.7444541e+01, 1.0745103e+02); + expectedForces[557] = Vec3( 1.4348018e+02, 1.4013343e+02, -4.0305733e+02); + expectedForces[558] = Vec3( 4.9491010e+02, 4.3040089e+02, -3.5558583e+02); + expectedForces[559] = Vec3(-1.8510736e+02, 6.7129731e+01, -2.1324364e+02); + expectedForces[560] = Vec3( 8.4478090e+01, 4.0986269e+01, 4.1401094e+02); + expectedForces[561] = Vec3( 4.4188419e+01, -8.6520108e+02, 6.8555821e+02); + expectedForces[562] = Vec3(-4.5036974e+02, 2.2379481e+02, 6.2457971e+01); + expectedForces[563] = Vec3( 2.4325836e+02, 6.9725116e+01, 3.6266296e+01); + expectedForces[564] = Vec3( 1.5611925e+02, -2.4471023e+02, 4.7857332e+02); + expectedForces[565] = Vec3(-3.5692822e+02, -2.7248961e+02, -1.8165146e+02); + expectedForces[566] = Vec3( 4.3093388e+02, 1.6944839e+02, -4.4177741e+02); + expectedForces[567] = Vec3( 5.2118711e+02, -1.5252783e+02, -1.6964047e+02); + expectedForces[568] = Vec3( 1.3899083e+03, 3.8363654e+02, -6.4623177e+02); + expectedForces[569] = Vec3(-1.4984858e+02, 4.5097170e+01, -5.0257768e+01); + expectedForces[570] = Vec3(-8.1979709e+01, -4.1632909e+01, -5.1367825e+02); + expectedForces[571] = Vec3(-7.8645235e+00, 1.8105470e+01, 9.2902759e+01); + expectedForces[572] = Vec3( 1.2725548e+02, 1.3926229e+02, -4.3752260e+01); + expectedForces[573] = Vec3(-2.7817289e+01, -8.0900345e+01, -4.3178498e+02); + expectedForces[574] = Vec3( 2.2115263e+02, -7.8807799e+01, 8.8367391e+01); + expectedForces[575] = Vec3(-1.2756938e+02, 4.2170937e+02, -6.8418245e+01); + expectedForces[576] = Vec3( 8.8370341e+01, -1.4671130e+02, -5.6211071e+02); + expectedForces[577] = Vec3( 6.7701453e+02, 2.1228010e+02, 2.3047236e+02); + expectedForces[578] = Vec3(-1.2694819e+02, -7.2734890e+00, 1.1007893e+02); + expectedForces[579] = Vec3(-6.8945756e+02, 1.7359485e+02, -2.5607776e+02); + expectedForces[580] = Vec3( 6.7323923e+00, 3.1574487e+02, 5.9741152e+02); + expectedForces[581] = Vec3( 2.1214031e+02, -4.7565197e+01, -9.6896159e+01); + expectedForces[582] = Vec3(-3.4876562e+02, 5.8335489e+01, -1.7058451e+02); + expectedForces[583] = Vec3(-1.6516914e+02, -3.8913162e+02, 5.8832025e+02); + expectedForces[584] = Vec3( 4.7753612e+01, -6.6792213e+01, -4.6492749e+01); + expectedForces[585] = Vec3(-4.7166578e+02, 7.1811831e+02, 7.0620222e+02); + expectedForces[586] = Vec3(-3.0570577e+02, -1.7681907e+02, -2.1227370e+02); + expectedForces[587] = Vec3( 1.8122997e+02, -6.8318737e+01, -3.4853368e+02); + expectedForces[588] = Vec3( 7.5752093e+01, 3.9702196e+02, -9.0196404e+02); + expectedForces[589] = Vec3( 5.1185528e+02, -7.7747186e+02, -3.3969581e+02); + expectedForces[590] = Vec3(-3.1187606e+01, 5.9593198e+01, 7.7918649e+01); + expectedForces[591] = Vec3( 2.2741676e+02, 2.1705631e+02, 3.9920149e+02); + expectedForces[592] = Vec3( 7.0516894e+01, 3.3389665e+02, -6.8443760e+00); + expectedForces[593] = Vec3(-9.9645406e+02, 2.8574127e+02, -8.0946834e+02); + expectedForces[594] = Vec3( 1.0930460e+02, 1.5869363e+03, -4.0704089e+02); + expectedForces[595] = Vec3(-3.0341438e+02, -5.7494385e+00, 2.9655509e+02); + expectedForces[596] = Vec3( 8.7955203e+01, -7.6811348e+01, -6.9558652e+01); + expectedForces[597] = Vec3(-9.4378353e+01, 3.6253070e+02, 9.0703343e-01); + expectedForces[598] = Vec3(-4.7595525e+01, -6.9148379e+02, -4.6737971e+02); + expectedForces[599] = Vec3( 2.2339987e+02, -2.5503335e+02, 2.8552040e+02); + expectedForces[600] = Vec3( 1.0309072e+02, -2.1298204e+02, -4.3393283e+02); + expectedForces[601] = Vec3(-2.4581477e+02, 2.5126386e+02, -1.8679710e+02); + expectedForces[602] = Vec3( 7.7926618e+00, -2.4947558e+01, 1.5962011e+02); + expectedForces[603] = Vec3( 7.0099476e+02, 5.9496129e+01, 2.0314640e+02); + expectedForces[604] = Vec3(-5.2583810e+01, 3.1237489e+01, -4.0902937e+00); + expectedForces[605] = Vec3(-5.4435871e+01, -7.7056693e+01, -1.5137215e+01); + expectedForces[606] = Vec3(-7.8684074e+02, 8.1673860e+02, 5.0192222e+02); + expectedForces[607] = Vec3( 2.9859285e+02, 1.9661708e+02, -1.9940993e+02); + expectedForces[608] = Vec3(-9.9358476e-01, -3.4789219e+02, 1.7693106e+02); + expectedForces[609] = Vec3( 6.7880927e+02, 7.2768533e+01, 1.1973248e+03); + expectedForces[610] = Vec3(-1.2072838e+00, 1.1770157e+02, -8.6765918e+01); + expectedForces[611] = Vec3(-4.3236695e+02, -2.8583002e+02, 1.3459508e+02); + expectedForces[612] = Vec3(-6.1894609e+01, 4.4705141e+02, -2.3264215e+02); + expectedForces[613] = Vec3(-2.6948720e+01, -2.7688230e+01, 4.6300601e+01); + expectedForces[614] = Vec3( 4.3954815e+01, 6.1244278e+01, 1.0727211e+02); + expectedForces[615] = Vec3(-2.2049132e+02, -9.7233594e+01, 8.3807949e+01); + expectedForces[616] = Vec3( 2.8631226e+02, -1.3478640e+02, -5.0675977e+02); + expectedForces[617] = Vec3(-1.1458029e+01, 6.3762007e+01, -4.9643140e+01); + expectedForces[618] = Vec3( 7.7363305e+01, 1.1936816e+02, 3.9692323e+01); + expectedForces[619] = Vec3(-8.4199858e+01, 2.3567494e+02, 7.2885200e+01); + expectedForces[620] = Vec3(-7.4500104e+00, 3.5567340e+00, -2.2676267e+01); + expectedForces[621] = Vec3(-7.9200057e+02, 3.2245192e+01, 1.1829644e+01); + expectedForces[622] = Vec3( 3.9959336e+02, 2.2447865e+02, -3.1413233e+02); + expectedForces[623] = Vec3( 1.5810527e+02, -2.2341997e+02, 2.3388212e+02); + expectedForces[624] = Vec3(-2.9248657e+02, -1.0806250e+03, -6.1268035e+01); + expectedForces[625] = Vec3( 6.5061442e+02, 1.2244756e+02, -1.1976147e+02); + expectedForces[626] = Vec3(-1.7787710e+02, 3.7279354e+02, -3.7911745e+02); + expectedForces[627] = Vec3( 3.7145927e+02, -2.5203732e+02, -2.2889342e+02); + expectedForces[628] = Vec3( 1.9440281e+02, -2.3076142e+02, 7.2945279e+01); + expectedForces[629] = Vec3(-2.3603693e+02, -1.1987203e+02, -1.2000208e+02); + expectedForces[630] = Vec3(-8.4811726e+01, -6.4500846e+02, -5.1257210e+02); + expectedForces[631] = Vec3(-1.6183393e+01, 1.3980655e+01, -2.3189702e+00); + expectedForces[632] = Vec3( 1.3526098e+02, 1.3800365e+02, -9.4360476e+01); + expectedForces[633] = Vec3( 2.0983514e+01, 5.1156494e+02, -4.3526557e+01); + expectedForces[634] = Vec3(-2.8666500e+02, -5.8235691e+02, -8.7425194e+01); + expectedForces[635] = Vec3(-1.7183604e+02, 1.0002944e+01, 6.5855812e+02); + expectedForces[636] = Vec3(-2.1735465e+02, 9.4664675e+02, 8.9132890e+02); + expectedForces[637] = Vec3( 6.3759184e+01, -5.2436201e+02, 1.2455578e+02); + expectedForces[638] = Vec3( 3.2176621e+02, 1.8182348e+02, -4.4863340e+02); + expectedForces[639] = Vec3(-8.4308252e+02, -1.6268681e+02, 5.8113352e+02); + expectedForces[640] = Vec3( 6.1223389e+01, 3.6767423e+02, 5.9071999e+02); + expectedForces[641] = Vec3( 2.2546928e+02, -2.2022805e+02, 8.3027103e+01); + expectedForces[642] = Vec3(-4.0385190e+02, 2.0141033e+02, 2.7296512e+01); + expectedForces[643] = Vec3( 8.4204485e+01, -7.1102294e+01, 5.7642677e+01); + expectedForces[644] = Vec3( 6.1859901e+01, 1.4828523e+02, -2.6764016e+02); + expectedForces[645] = Vec3(-6.7249932e+02, -8.4613525e+01, -3.9792609e+02); + expectedForces[646] = Vec3( 9.9116485e+01, -3.7714583e+01, -5.3966332e+01); + expectedForces[647] = Vec3( 2.0868628e+02, 2.9747206e+02, 3.3931416e+02); // tolerance is higher here due to interpolation used in setting tapering coefficients; // if tapering turned off, then absolute difference < 2.0e-05 @@ -1953,7 +1953,7 @@ void testVdwWater(int includeVdwDispersionCorrection) { sigmaRules.push_back("GEOMETRIC"); epsilonRules.push_back("GEOMETRIC"); - expectedEnergies.push_back( 3.6358216e+03); + expectedEnergies.push_back(3.6358216e+03); sigmaRules.push_back("CUBIC-MEAN"); epsilonRules.push_back("HARMONIC"); diff --git a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp index 8cdbbc4d8..41769682c 100644 --- a/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp +++ b/plugins/amoeba/platforms/reference/tests/TestReferenceWcaDispersionForce.cpp @@ -79,41 +79,41 @@ void testWcaDispersionAmmonia(FILE* log) { System system; AmoebaWcaDispersionForce* amoebaWcaDispersionForce = new AmoebaWcaDispersionForce();; - amoebaWcaDispersionForce->setEpso( 4.6024000e-01); - amoebaWcaDispersionForce->setEpsh( 5.6484000e-02); - amoebaWcaDispersionForce->setRmino( 1.7025000e-01); - amoebaWcaDispersionForce->setRminh( 1.3275000e-01); + amoebaWcaDispersionForce->setEpso( 4.6024000e-01); + amoebaWcaDispersionForce->setEpsh( 5.6484000e-02); + amoebaWcaDispersionForce->setRmino( 1.7025000e-01); + amoebaWcaDispersionForce->setRminh( 1.3275000e-01); amoebaWcaDispersionForce->setDispoff(2.6000000e-02); - amoebaWcaDispersionForce->setAwater( 3.3428000e+01); - amoebaWcaDispersionForce->setSlevy( 1.0000000e+00); - amoebaWcaDispersionForce->setShctd( 8.1000000e-01); + amoebaWcaDispersionForce->setAwater(3.3428000e+01); + amoebaWcaDispersionForce->setSlevy( 1.0000000e+00); + amoebaWcaDispersionForce->setShctd( 8.1000000e-01); // addParticle: radius, epsilon for (unsigned int ii = 0; ii < 2; ii++) { - system.addParticle( 1.4007000e+01); - amoebaWcaDispersionForce->addParticle( 1.8550000e-01, 4.3932000e-01); + system.addParticle( 1.4007000e+01); + amoebaWcaDispersionForce->addParticle( 1.8550000e-01, 4.3932000e-01); - system.addParticle( 1.0080000e+00); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); - system.addParticle( 1.0080000e+00); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); - system.addParticle( 1.0080000e+00); - amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); + system.addParticle( 1.0080000e+00); + amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02); } std::vector positions(numberOfParticles); - positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); - positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); - positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); - positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); - positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); - positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); - positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); - positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); + positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); + positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); + positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); + positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); + positions[4] = Vec3(-1.6743680e-01, 1.5900000e-05, -6.6149000e-03); + positions[5] = Vec3(-2.0428260e-01, 8.1071500e-02, 4.1343900e-02); + positions[6] = Vec3(-6.7308300e-02, 1.2800000e-05, 1.0623300e-02); + positions[7] = Vec3(-2.0426290e-01, -8.1231400e-02, 4.1033500e-02); system.addForce(amoebaWcaDispersionForce); ASSERT(!amoebaWcaDispersionForce->usesPeriodicBoundaryConditions()); @@ -134,14 +134,14 @@ void testWcaDispersionAmmonia(FILE* log) { std::vector expectedForces(numberOfParticles); double expectedEnergy = -2.6981209e+01; - expectedForces[0] = Vec3( 4.7839388e+00, -7.3510133e-04, -5.0382764e-01); - expectedForces[1] = Vec3( 1.4657758e+00, 1.2431003e+00, -6.7075886e-01); - expectedForces[2] = Vec3( 1.4563936e+00, -1.2399917e+00, -6.7443841e-01); - expectedForces[3] = Vec3( 2.1116744e+00, -2.7407512e-03, 1.3271245e+00); - expectedForces[4] = Vec3( -4.7528440e+00, -1.5148066e-03, 1.2653813e+00); - expectedForces[5] = Vec3( -1.1875619e+00, -1.2866678e+00, -3.9109060e-01); - expectedForces[6] = Vec3( -2.6885679e+00, -4.3038639e-04, 3.3763583e-02); - expectedForces[7] = Vec3( -1.1888087e+00, 1.2889802e+00, -3.8615387e-01); + expectedForces[0] = Vec3( 4.7839388e+00, -7.3510133e-04, -5.0382764e-01); + expectedForces[1] = Vec3( 1.4657758e+00, 1.2431003e+00, -6.7075886e-01); + expectedForces[2] = Vec3( 1.4563936e+00, -1.2399917e+00, -6.7443841e-01); + expectedForces[3] = Vec3( 2.1116744e+00, -2.7407512e-03, 1.3271245e+00); + expectedForces[4] = Vec3(-4.7528440e+00, -1.5148066e-03, 1.2653813e+00); + expectedForces[5] = Vec3(-1.1875619e+00, -1.2866678e+00, -3.9109060e-01); + expectedForces[6] = Vec3(-2.6885679e+00, -4.3038639e-04, 3.3763583e-02); + expectedForces[7] = Vec3(-1.1888087e+00, 1.2889802e+00, -3.8615387e-01); double tolerance = 1.0e-04; compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance, log); diff --git a/plugins/amoeba/serialization/src/AmoebaAngleForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaAngleForceProxy.cpp index 0029cf721..7648518f1 100644 --- a/plugins/amoeba/serialization/src/AmoebaAngleForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaAngleForceProxy.cpp @@ -66,13 +66,13 @@ void* AmoebaAngleForceProxy::deserialize(const SerializationNode& node) const { AmoebaAngleForce* force = new AmoebaAngleForce(); try { - force->setAmoebaGlobalAngleCubic(node.getDoubleProperty( "cubic")); + force->setAmoebaGlobalAngleCubic(node.getDoubleProperty("cubic")); force->setAmoebaGlobalAngleQuartic(node.getDoubleProperty("quartic")); - force->setAmoebaGlobalAnglePentic(node.getDoubleProperty( "pentic")); - force->setAmoebaGlobalAngleSextic(node.getDoubleProperty( "sextic")); + force->setAmoebaGlobalAnglePentic(node.getDoubleProperty("pentic")); + force->setAmoebaGlobalAngleSextic(node.getDoubleProperty("sextic")); const SerializationNode& bonds = node.getChildNode("Angles"); - for ( unsigned int ii = 0; ii < bonds.getChildren().size(); ii++) { + for (unsigned int ii = 0; ii < bonds.getChildren().size(); ii++) { const SerializationNode& bond = bonds.getChildren()[ii]; force->addAngle(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getIntProperty("p3"), bond.getDoubleProperty("d"), bond.getDoubleProperty("k")); } diff --git a/plugins/amoeba/serialization/src/AmoebaBondForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaBondForceProxy.cpp index b0a45a190..8bfdf7d4a 100644 --- a/plugins/amoeba/serialization/src/AmoebaBondForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaBondForceProxy.cpp @@ -65,7 +65,7 @@ void* AmoebaBondForceProxy::deserialize(const SerializationNode& node) const { force->setAmoebaGlobalBondCubic(node.getDoubleProperty("cubic")); force->setAmoebaGlobalBondQuartic(node.getDoubleProperty("quartic")); const SerializationNode& bonds = node.getChildNode("Bonds"); - for ( unsigned int ii = 0; ii < (int) bonds.getChildren().size(); ii++) { + for (unsigned int ii = 0; ii < (int) bonds.getChildren().size(); ii++) { const SerializationNode& bond = bonds.getChildren()[ii]; force->addBond(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getDoubleProperty("d"), bond.getDoubleProperty("k")); } diff --git a/plugins/amoeba/serialization/src/AmoebaGeneralizedKirkwoodForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaGeneralizedKirkwoodForceProxy.cpp index 15f051b37..e64c8f75b 100644 --- a/plugins/amoeba/serialization/src/AmoebaGeneralizedKirkwoodForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaGeneralizedKirkwoodForceProxy.cpp @@ -45,17 +45,17 @@ void AmoebaGeneralizedKirkwoodForceProxy::serialize(const void* object, Serializ node.setIntProperty("version", 1); const AmoebaGeneralizedKirkwoodForce& force = *reinterpret_cast(object); - node.setDoubleProperty("GeneralizedKirkwoodSolventDielectric", force.getSolventDielectric() ); - node.setDoubleProperty("GeneralizedKirkwoodSoluteDielectric", force.getSoluteDielectric() ); - //node.setDoubleProperty("GeneralizedKirkwoodDielectricOffset", force.getDielectricOffset() ); - node.setDoubleProperty("GeneralizedKirkwoodProbeRadius", force.getProbeRadius() ); - node.setDoubleProperty("GeneralizedKirkwoodSurfaceAreaFactor", force.getSurfaceAreaFactor() ); - node.setIntProperty( "GeneralizedKirkwoodIncludeCavityTerm", force.getIncludeCavityTerm() ); + node.setDoubleProperty("GeneralizedKirkwoodSolventDielectric", force.getSolventDielectric()); + node.setDoubleProperty("GeneralizedKirkwoodSoluteDielectric", force.getSoluteDielectric()); + //node.setDoubleProperty("GeneralizedKirkwoodDielectricOffset", force.getDielectricOffset()); + node.setDoubleProperty("GeneralizedKirkwoodProbeRadius", force.getProbeRadius()); + node.setDoubleProperty("GeneralizedKirkwoodSurfaceAreaFactor", force.getSurfaceAreaFactor()); + node.setIntProperty( "GeneralizedKirkwoodIncludeCavityTerm", force.getIncludeCavityTerm()); SerializationNode& particles = node.createChildNode("GeneralizedKirkwoodParticles"); for (unsigned int ii = 0; ii < static_cast(force.getNumParticles()); ii++) { double radius, charge, scalingFactor; - force.getParticleParameters( ii, charge, radius, scalingFactor ); + force.getParticleParameters(ii, charge, radius, scalingFactor); particles.createChildNode("Particle").setDoubleProperty("charge", charge).setDoubleProperty("radius", radius).setDoubleProperty("scaleFactor", scalingFactor); } @@ -67,17 +67,17 @@ void* AmoebaGeneralizedKirkwoodForceProxy::deserialize(const SerializationNode& AmoebaGeneralizedKirkwoodForce* force = new AmoebaGeneralizedKirkwoodForce(); try { - force->setSolventDielectric( node.getDoubleProperty( "GeneralizedKirkwoodSolventDielectric" ) ); - force->setSoluteDielectric( node.getDoubleProperty( "GeneralizedKirkwoodSoluteDielectric" ) ); - //force->setDielectricOffset( node.getDoubleProperty( "GeneralizedKirkwoodDielectricOffset" ) ); - force->setProbeRadius( node.getDoubleProperty( "GeneralizedKirkwoodProbeRadius" ) ); - force->setSurfaceAreaFactor( node.getDoubleProperty( "GeneralizedKirkwoodSurfaceAreaFactor" ) ); - force->setIncludeCavityTerm( node.getIntProperty( "GeneralizedKirkwoodIncludeCavityTerm" ) ); + force->setSolventDielectric( node.getDoubleProperty("GeneralizedKirkwoodSolventDielectric")); + force->setSoluteDielectric( node.getDoubleProperty("GeneralizedKirkwoodSoluteDielectric")); + //force->setDielectricOffset( node.getDoubleProperty("GeneralizedKirkwoodDielectricOffset")); + force->setProbeRadius( node.getDoubleProperty("GeneralizedKirkwoodProbeRadius")); + force->setSurfaceAreaFactor( node.getDoubleProperty("GeneralizedKirkwoodSurfaceAreaFactor")); + force->setIncludeCavityTerm( node.getIntProperty( "GeneralizedKirkwoodIncludeCavityTerm")); const SerializationNode& particles = node.getChildNode("GeneralizedKirkwoodParticles"); for (unsigned int ii = 0; ii < particles.getChildren().size(); ii++) { const SerializationNode& particle = particles.getChildren()[ii]; - force->addParticle( particle.getDoubleProperty("charge"), particle.getDoubleProperty("radius"), particle.getDoubleProperty("scaleFactor")); + force->addParticle(particle.getDoubleProperty("charge"), particle.getDoubleProperty("radius"), particle.getDoubleProperty("scaleFactor")); } } catch (...) { diff --git a/plugins/amoeba/serialization/src/AmoebaInPlaneAngleForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaInPlaneAngleForceProxy.cpp index 3bd42fdcb..9363a3f0c 100644 --- a/plugins/amoeba/serialization/src/AmoebaInPlaneAngleForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaInPlaneAngleForceProxy.cpp @@ -52,7 +52,7 @@ void AmoebaInPlaneAngleForceProxy::serialize(const void* object, SerializationNo node.setDoubleProperty("sextic", force.getAmoebaGlobalInPlaneAngleSextic()); SerializationNode& bonds = node.createChildNode("InPlaneAngles"); - for ( unsigned int ii = 0; ii < static_cast(force.getNumAngles()); ii++) { + for (unsigned int ii = 0; ii < static_cast(force.getNumAngles()); ii++) { int particle1, particle2, particle3, particle4; double distance, k; force.getAngleParameters(ii, particle1, particle2, particle3, particle4, distance, k); @@ -66,10 +66,10 @@ void* AmoebaInPlaneAngleForceProxy::deserialize(const SerializationNode& node) c AmoebaInPlaneAngleForce* force = new AmoebaInPlaneAngleForce(); try { - force->setAmoebaGlobalInPlaneAngleCubic( node.getDoubleProperty("cubic")); + force->setAmoebaGlobalInPlaneAngleCubic( node.getDoubleProperty("cubic")); force->setAmoebaGlobalInPlaneAngleQuartic(node.getDoubleProperty("quartic")); - force->setAmoebaGlobalInPlaneAnglePentic( node.getDoubleProperty("pentic")); - force->setAmoebaGlobalInPlaneAngleSextic( node.getDoubleProperty("sextic")); + force->setAmoebaGlobalInPlaneAnglePentic(node.getDoubleProperty("pentic")); + force->setAmoebaGlobalInPlaneAngleSextic(node.getDoubleProperty("sextic")); const SerializationNode& bonds = node.getChildNode("InPlaneAngles"); for (unsigned int ii = 0; ii < bonds.getChildren().size(); ii++) { diff --git a/plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp index 25e5688b9..609741fe8 100644 --- a/plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaMultipoleForceProxy.cpp @@ -41,29 +41,29 @@ using namespace std; AmoebaMultipoleForceProxy::AmoebaMultipoleForceProxy() : SerializationProxy("AmoebaMultipoleForce") { } -static void getCovalentTypes( std::vector& covalentTypes ){ +static void getCovalentTypes(std::vector& covalentTypes) { - covalentTypes.push_back( "Covalent12" ); - covalentTypes.push_back( "Covalent13" ); - covalentTypes.push_back( "Covalent14" ); - covalentTypes.push_back( "Covalent15" ); + covalentTypes.push_back("Covalent12"); + covalentTypes.push_back("Covalent13"); + covalentTypes.push_back("Covalent14"); + covalentTypes.push_back("Covalent15"); - covalentTypes.push_back( "PolarizationCovalent11" ); - covalentTypes.push_back( "PolarizationCovalent12" ); - covalentTypes.push_back( "PolarizationCovalent13" ); - covalentTypes.push_back( "PolarizationCovalent14" ); + covalentTypes.push_back("PolarizationCovalent11"); + covalentTypes.push_back("PolarizationCovalent12"); + covalentTypes.push_back("PolarizationCovalent13"); + covalentTypes.push_back("PolarizationCovalent14"); } -static void addCovalentMap( SerializationNode& particleExclusions, int particleIndex, std::string mapName, std::vector< int > covalentMap ){ +static void addCovalentMap(SerializationNode& particleExclusions, int particleIndex, std::string mapName, std::vector< int > covalentMap) { SerializationNode& map = particleExclusions.createChildNode(mapName); for (unsigned int ii = 0; ii < covalentMap.size(); ii++) { - map.createChildNode("Cv").setIntProperty( "v", covalentMap[ii] ); + map.createChildNode("Cv").setIntProperty("v", covalentMap[ii]); } } -void loadCovalentMap( const SerializationNode& map, std::vector< int >& covalentMap ){ +void loadCovalentMap(const SerializationNode& map, std::vector< int >& covalentMap) { for (unsigned int ii = 0; ii < map.getChildren().size(); ii++) { - covalentMap.push_back( map.getChildren()[ii].getIntProperty( "v" ) ); + covalentMap.push_back(map.getChildren()[ii].getIntProperty("v")); } } @@ -84,12 +84,12 @@ void AmoebaMultipoleForceProxy::serialize(const void* object, SerializationNode& node.setDoubleProperty("ewaldErrorTolerance", force.getEwaldErrorTolerance()); std::vector gridDimensions; - force.getPmeGridDimensions( gridDimensions ); + force.getPmeGridDimensions(gridDimensions); SerializationNode& gridDimensionsNode = node.createChildNode("MultipoleParticleGridDimension"); - gridDimensionsNode.setIntProperty( "d0", gridDimensions[0] ).setIntProperty( "d1", gridDimensions[1] ).setIntProperty( "d2", gridDimensions[2] ); + gridDimensionsNode.setIntProperty("d0", gridDimensions[0]).setIntProperty("d1", gridDimensions[1]).setIntProperty("d2", gridDimensions[2]); std::vector covalentTypes; - getCovalentTypes( covalentTypes ); + getCovalentTypes(covalentTypes); SerializationNode& particles = node.createChildNode("MultipoleParticles"); for (unsigned int ii = 0; ii < static_cast(force.getNumMultipoles()); ii++) { @@ -100,25 +100,25 @@ void AmoebaMultipoleForceProxy::serialize(const void* object, SerializationNode& std::vector molecularDipole; std::vector molecularQuadrupole; - force.getMultipoleParameters( ii, charge, molecularDipole, molecularQuadrupole, - axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity ); + force.getMultipoleParameters(ii, charge, molecularDipole, molecularQuadrupole, + axisType, multipoleAtomZ, multipoleAtomX, multipoleAtomY, thole, dampingFactor, polarity); SerializationNode& particle = particles.createChildNode("Particle"); particle.setIntProperty("axisType", axisType).setIntProperty("multipoleAtomZ", multipoleAtomZ).setIntProperty("multipoleAtomX", multipoleAtomX).setIntProperty("multipoleAtomY", multipoleAtomY); particle.setDoubleProperty("charge", charge).setDoubleProperty("thole", thole).setDoubleProperty("damp", dampingFactor).setDoubleProperty("polarity", polarity); SerializationNode& dipole = particle.createChildNode("Dipole"); - dipole.setDoubleProperty( "d0", molecularDipole[0] ).setDoubleProperty( "d1", molecularDipole[1] ).setDoubleProperty( "d2", molecularDipole[2] ); + dipole.setDoubleProperty("d0", molecularDipole[0]).setDoubleProperty("d1", molecularDipole[1]).setDoubleProperty("d2", molecularDipole[2]); SerializationNode& quadrupole = particle.createChildNode("Quadrupole"); - quadrupole.setDoubleProperty( "q0", molecularQuadrupole[0] ).setDoubleProperty( "q1", molecularQuadrupole[1] ).setDoubleProperty( "q2", molecularQuadrupole[2] ); - quadrupole.setDoubleProperty( "q3", molecularQuadrupole[3] ).setDoubleProperty( "q4", molecularQuadrupole[4] ).setDoubleProperty( "q5", molecularQuadrupole[5] ); - quadrupole.setDoubleProperty( "q6", molecularQuadrupole[6] ).setDoubleProperty( "q7", molecularQuadrupole[7] ).setDoubleProperty( "q8", molecularQuadrupole[8] ); + quadrupole.setDoubleProperty("q0", molecularQuadrupole[0]).setDoubleProperty("q1", molecularQuadrupole[1]).setDoubleProperty("q2", molecularQuadrupole[2]); + quadrupole.setDoubleProperty("q3", molecularQuadrupole[3]).setDoubleProperty("q4", molecularQuadrupole[4]).setDoubleProperty("q5", molecularQuadrupole[5]); + quadrupole.setDoubleProperty("q6", molecularQuadrupole[6]).setDoubleProperty("q7", molecularQuadrupole[7]).setDoubleProperty("q8", molecularQuadrupole[8]); for (unsigned int jj = 0; jj < covalentTypes.size(); jj++) { std::vector< int > covalentMap; - force.getCovalentMap(ii, static_cast(jj), covalentMap ); - addCovalentMap( particle, ii, covalentTypes[jj], covalentMap ); + force.getCovalentMap(ii, static_cast(jj), covalentMap); + addCovalentMap(particle, ii, covalentTypes[jj], covalentMap); } } } @@ -130,54 +130,54 @@ void* AmoebaMultipoleForceProxy::deserialize(const SerializationNode& node) cons try { - force->setNonbondedMethod( static_cast(node.getIntProperty( "nonbondedMethod" )) ); - if( node.getIntProperty("version") == 2 ){ - force->setPolarizationType( static_cast(node.getIntProperty( "polarizationType" )) ); + force->setNonbondedMethod(static_cast(node.getIntProperty("nonbondedMethod"))); + if (node.getIntProperty("version") == 2) { + force->setPolarizationType(static_cast(node.getIntProperty("polarizationType"))); } - //force->setPmeBSplineOrder( node.getIntProperty( "pmeBSplineOrder" ) ); - //force->setMutualInducedIterationMethod( static_cast(node.getIntProperty( "mutualInducedIterationMethod" ) ) ); - force->setMutualInducedMaxIterations( node.getIntProperty( "mutualInducedMaxIterations" ) ); + //force->setPmeBSplineOrder(node.getIntProperty("pmeBSplineOrder")); + //force->setMutualInducedIterationMethod(static_cast(node.getIntProperty("mutualInducedIterationMethod"))); + force->setMutualInducedMaxIterations(node.getIntProperty("mutualInducedMaxIterations")); - force->setCutoffDistance( node.getDoubleProperty( "cutoffDistance" ) ); - force->setAEwald( node.getDoubleProperty( "aEwald" ) ); - force->setMutualInducedTargetEpsilon( node.getDoubleProperty( "mutualInducedTargetEpsilon" ) ); - //force->setElectricConstant( node.getDoubleProperty( "electricConstant" ) ); - force->setEwaldErrorTolerance( node.getDoubleProperty( "ewaldErrorTolerance" ) ); + force->setCutoffDistance(node.getDoubleProperty("cutoffDistance")); + force->setAEwald(node.getDoubleProperty("aEwald")); + force->setMutualInducedTargetEpsilon(node.getDoubleProperty("mutualInducedTargetEpsilon")); + //force->setElectricConstant(node.getDoubleProperty("electricConstant")); + force->setEwaldErrorTolerance(node.getDoubleProperty("ewaldErrorTolerance")); std::vector gridDimensions; const SerializationNode& gridDimensionsNode = node.getChildNode("MultipoleParticleGridDimension"); - gridDimensions.push_back( gridDimensionsNode.getIntProperty( "d0" )); - gridDimensions.push_back( gridDimensionsNode.getIntProperty( "d1" )); - gridDimensions.push_back( gridDimensionsNode.getIntProperty( "d2" )); - force->setPmeGridDimensions( gridDimensions ); + gridDimensions.push_back(gridDimensionsNode.getIntProperty("d0")); + gridDimensions.push_back(gridDimensionsNode.getIntProperty("d1")); + gridDimensions.push_back(gridDimensionsNode.getIntProperty("d2")); + force->setPmeGridDimensions(gridDimensions); std::vector covalentTypes; - getCovalentTypes( covalentTypes ); + getCovalentTypes(covalentTypes); const SerializationNode& particles = node.getChildNode("MultipoleParticles"); - for ( unsigned int ii = 0; ii < particles.getChildren().size(); ii++) { + for (unsigned int ii = 0; ii < particles.getChildren().size(); ii++) { const SerializationNode& particle = particles.getChildren()[ii]; std::vector molecularDipole; const SerializationNode& dipole = particle.getChildNode("Dipole"); - molecularDipole.push_back( dipole.getDoubleProperty( "d0" ) ); - molecularDipole.push_back( dipole.getDoubleProperty( "d1" ) ); - molecularDipole.push_back( dipole.getDoubleProperty( "d2" ) ); + molecularDipole.push_back(dipole.getDoubleProperty("d0")); + molecularDipole.push_back(dipole.getDoubleProperty("d1")); + molecularDipole.push_back(dipole.getDoubleProperty("d2")); std::vector molecularQuadrupole; const SerializationNode& quadrupole = particle.getChildNode("Quadrupole"); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q0" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q1" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q2" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q3" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q4" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q5" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q6" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q7" ) ); - molecularQuadrupole.push_back( quadrupole.getDoubleProperty( "q8" ) ); - - force->addMultipole( particle.getDoubleProperty("charge"), molecularDipole, molecularQuadrupole, + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q0")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q1")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q2")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q3")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q4")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q5")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q6")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q7")); + molecularQuadrupole.push_back(quadrupole.getDoubleProperty("q8")); + + force->addMultipole(particle.getDoubleProperty("charge"), molecularDipole, molecularQuadrupole, particle.getIntProperty("axisType"), particle.getIntProperty("multipoleAtomZ"), particle.getIntProperty("multipoleAtomX"), @@ -189,8 +189,8 @@ void* AmoebaMultipoleForceProxy::deserialize(const SerializationNode& node) cons for (unsigned int jj = 0; jj < covalentTypes.size(); jj++) { std::vector< int > covalentMap; - loadCovalentMap( particle.getChildNode(covalentTypes[jj]), covalentMap ); - force->setCovalentMap( ii, static_cast(jj), covalentMap ); + loadCovalentMap(particle.getChildNode(covalentTypes[jj]), covalentMap); + force->setCovalentMap(ii, static_cast(jj), covalentMap); } } diff --git a/plugins/amoeba/serialization/src/AmoebaOutOfPlaneBendForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaOutOfPlaneBendForceProxy.cpp index 01691973a..9fca74327 100644 --- a/plugins/amoeba/serialization/src/AmoebaOutOfPlaneBendForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaOutOfPlaneBendForceProxy.cpp @@ -64,10 +64,10 @@ void* AmoebaOutOfPlaneBendForceProxy::deserialize(const SerializationNode& node) AmoebaOutOfPlaneBendForce* force = new AmoebaOutOfPlaneBendForce(); try { - force->setAmoebaGlobalOutOfPlaneBendCubic(node.getDoubleProperty( "cubic")); + force->setAmoebaGlobalOutOfPlaneBendCubic(node.getDoubleProperty("cubic")); force->setAmoebaGlobalOutOfPlaneBendQuartic(node.getDoubleProperty("quartic")); - force->setAmoebaGlobalOutOfPlaneBendPentic(node.getDoubleProperty( "pentic")); - force->setAmoebaGlobalOutOfPlaneBendSextic(node.getDoubleProperty( "sextic")); + force->setAmoebaGlobalOutOfPlaneBendPentic(node.getDoubleProperty("pentic")); + force->setAmoebaGlobalOutOfPlaneBendSextic(node.getDoubleProperty("sextic")); const SerializationNode& bonds = node.getChildNode("OutOfPlaneBend"); for (unsigned int ii = 0; ii < bonds.getChildren().size(); ii++) { diff --git a/plugins/amoeba/serialization/src/AmoebaPiTorsionForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaPiTorsionForceProxy.cpp index cba39d63d..2e01fc040 100644 --- a/plugins/amoeba/serialization/src/AmoebaPiTorsionForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaPiTorsionForceProxy.cpp @@ -45,7 +45,7 @@ void AmoebaPiTorsionForceProxy::serialize(const void* object, SerializationNode& node.setIntProperty("version", 1); const AmoebaPiTorsionForce& force = *reinterpret_cast(object); SerializationNode& bonds = node.createChildNode("PiTorsion"); - for ( unsigned int ii = 0; ii < static_cast(force.getNumPiTorsions()); ii++) { + for (unsigned int ii = 0; ii < static_cast(force.getNumPiTorsions()); ii++) { int particle1, particle2, particle3, particle4, particle5, particle6; double k; force.getPiTorsionParameters(ii, particle1, particle2, particle3, particle4, particle5, particle6, k); diff --git a/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp index 5d91bb783..d084129e1 100644 --- a/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaStretchBendForceProxy.cpp @@ -60,7 +60,7 @@ void* AmoebaStretchBendForceProxy::deserialize(const SerializationNode& node) co AmoebaStretchBendForce* force = new AmoebaStretchBendForce(); try { const SerializationNode& bonds = node.getChildNode("StretchBendAngles"); - for ( unsigned int ii = 0; ii < (int) bonds.getChildren().size(); ii++) { + for (unsigned int ii = 0; ii < (int) bonds.getChildren().size(); ii++) { const SerializationNode& bond = bonds.getChildren()[ii]; force->addStretchBend(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getIntProperty("p3"), bond.getDoubleProperty("dAB"), bond.getDoubleProperty("dCB"), bond.getDoubleProperty("angle"), bond.getDoubleProperty("k1"), bond.getDoubleProperty("k2")); diff --git a/plugins/amoeba/serialization/src/AmoebaTorsionTorsionForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaTorsionTorsionForceProxy.cpp index 7c9e77d4e..ecefb51b5 100644 --- a/plugins/amoeba/serialization/src/AmoebaTorsionTorsionForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaTorsionTorsionForceProxy.cpp @@ -41,23 +41,23 @@ using namespace std; AmoebaTorsionTorsionForceProxy::AmoebaTorsionTorsionForceProxy() : SerializationProxy("AmoebaTorsionTorsionForce") { } -static void loadGrid( const SerializationNode& grid, std::vector< std::vector< std::vector > >& gridVector ){ +static void loadGrid(const SerializationNode& grid, std::vector< std::vector< std::vector > >& gridVector) { const std::vector& gridSerializationRows = grid.getChildren(); - gridVector.resize( gridSerializationRows.size() ); + gridVector.resize(gridSerializationRows.size()); - for( unsigned int ii = 0; ii < gridSerializationRows.size(); ii++) { + for (unsigned int ii = 0; ii < gridSerializationRows.size(); ii++) { const std::vector& gridSerializationColumns = gridSerializationRows[ii].getChildren(); - gridVector[ii].resize( gridSerializationColumns.size() ); - for( unsigned int jj = 0; jj < gridSerializationColumns.size(); jj++) { + gridVector[ii].resize(gridSerializationColumns.size()); + for (unsigned int jj = 0; jj < gridSerializationColumns.size(); jj++) { const SerializationNode& gridSerializationColumnNode = gridSerializationColumns[jj]; - gridVector[ii][jj].resize( 6 ); - gridVector[ii][jj][0] = gridSerializationColumnNode.getDoubleProperty( "x" ); - gridVector[ii][jj][1] = gridSerializationColumnNode.getDoubleProperty( "y" ); - gridVector[ii][jj][2] = gridSerializationColumnNode.getDoubleProperty( "f" ); - gridVector[ii][jj][3] = gridSerializationColumnNode.getDoubleProperty( "fx" ); - gridVector[ii][jj][4] = gridSerializationColumnNode.getDoubleProperty( "fy" ); - gridVector[ii][jj][5] = gridSerializationColumnNode.getDoubleProperty( "fxy" ); + gridVector[ii][jj].resize(6); + gridVector[ii][jj][0] = gridSerializationColumnNode.getDoubleProperty("x"); + gridVector[ii][jj][1] = gridSerializationColumnNode.getDoubleProperty("y"); + gridVector[ii][jj][2] = gridSerializationColumnNode.getDoubleProperty("f"); + gridVector[ii][jj][3] = gridSerializationColumnNode.getDoubleProperty("fx"); + gridVector[ii][jj][4] = gridSerializationColumnNode.getDoubleProperty("fy"); + gridVector[ii][jj][5] = gridSerializationColumnNode.getDoubleProperty("fxy"); } } } @@ -78,28 +78,28 @@ void AmoebaTorsionTorsionForceProxy::serialize(const void* object, Serialization SerializationNode& grids = node.createChildNode("TorsionTorsionGrids"); for (unsigned int kk = 0; kk < static_cast(force.getNumTorsionTorsionGrids()); kk++) { - const std::vector< std::vector< std::vector > > grid = force.getTorsionTorsionGrid( kk ); + const std::vector< std::vector< std::vector > > grid = force.getTorsionTorsionGrid(kk); unsigned int gridCount = 0; unsigned int gridYsize = grid[0].size(); - for ( unsigned int ii = 0; ii < grid.size(); ii++) { + for (unsigned int ii = 0; ii < grid.size(); ii++) { gridCount += grid[ii].size(); } SerializationNode& gridNode = grids.createChildNode("TorsionTorsionGrid"); - for ( unsigned int ii = 0; ii < grid.size(); ii++) { + for (unsigned int ii = 0; ii < grid.size(); ii++) { SerializationNode& gridSerializationRow = gridNode.createChildNode("RowNode"); - gridSerializationRow.setIntProperty("dim", ii ); - for ( unsigned int jj = 0; jj < grid[ii].size(); jj++) { + gridSerializationRow.setIntProperty("dim", ii); + for (unsigned int jj = 0; jj < grid[ii].size(); jj++) { SerializationNode& gridSerializationColumnNode = gridSerializationRow.createChildNode("ColumnNode"); - gridSerializationColumnNode.setIntProperty("dim", jj ); + gridSerializationColumnNode.setIntProperty("dim", jj); unsigned int index = 0; - gridSerializationColumnNode.setDoubleProperty("x", grid[ii][jj][index++] ); - gridSerializationColumnNode.setDoubleProperty("y", grid[ii][jj][index++] ); - gridSerializationColumnNode.setDoubleProperty("f", grid[ii][jj][index++] ); - gridSerializationColumnNode.setDoubleProperty("fx", grid[ii][jj][index++] ); - gridSerializationColumnNode.setDoubleProperty("fy", grid[ii][jj][index++] ); - gridSerializationColumnNode.setDoubleProperty("fxy", grid[ii][jj][index++] ); + gridSerializationColumnNode.setDoubleProperty("x", grid[ii][jj][index++]); + gridSerializationColumnNode.setDoubleProperty("y", grid[ii][jj][index++]); + gridSerializationColumnNode.setDoubleProperty("f", grid[ii][jj][index++]); + gridSerializationColumnNode.setDoubleProperty("fx", grid[ii][jj][index++]); + gridSerializationColumnNode.setDoubleProperty("fy", grid[ii][jj][index++]); + gridSerializationColumnNode.setDoubleProperty("fxy", grid[ii][jj][index++]); } } } @@ -108,8 +108,8 @@ void AmoebaTorsionTorsionForceProxy::serialize(const void* object, Serialization for (unsigned int ii = 0; ii < static_cast(force.getNumTorsionTorsions()); ii++) { int particle1, particle2, particle3, particle4, particle5; int chiralCheckAtomIndex, gridIndex; - force.getTorsionTorsionParameters(ii, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex ); - bonds.createChildNode("TorsionTorsion").setIntProperty("p1", particle1).setIntProperty("p2", particle2).setIntProperty("p3", particle3).setIntProperty("p4", particle4).setIntProperty("p5", particle5).setIntProperty("chiralCheckAtomIndex", chiralCheckAtomIndex).setIntProperty("gridIndex", gridIndex ); + force.getTorsionTorsionParameters(ii, particle1, particle2, particle3, particle4, particle5, chiralCheckAtomIndex, gridIndex); + bonds.createChildNode("TorsionTorsion").setIntProperty("p1", particle1).setIntProperty("p2", particle2).setIntProperty("p3", particle3).setIntProperty("p4", particle4).setIntProperty("p5", particle5).setIntProperty("chiralCheckAtomIndex", chiralCheckAtomIndex).setIntProperty("gridIndex", gridIndex); } } @@ -124,10 +124,10 @@ void* AmoebaTorsionTorsionForceProxy::deserialize(const SerializationNode& node) const SerializationNode& grids = node.getChildNode("TorsionTorsionGrids"); const std::vector& gridList = grids.getChildren(); - for( unsigned int ii = 0; ii < gridList.size(); ii++) { + for (unsigned int ii = 0; ii < gridList.size(); ii++) { std::vector< std::vector< std::vector > > gridVector; - loadGrid( gridList[ii], gridVector ); - force->setTorsionTorsionGrid( ii, gridVector ); + loadGrid(gridList[ii], gridVector); + force->setTorsionTorsionGrid(ii, gridVector); } const SerializationNode& bonds = node.getChildNode("TorsionTorsion"); diff --git a/plugins/amoeba/serialization/src/AmoebaVdwForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaVdwForceProxy.cpp index 613f2330a..80d0a5075 100644 --- a/plugins/amoeba/serialization/src/AmoebaVdwForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaVdwForceProxy.cpp @@ -56,17 +56,17 @@ void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node) int ivIndex; double sigma, epsilon, reductionFactor; - force.getParticleParameters( ii, ivIndex, sigma, epsilon, reductionFactor ); + force.getParticleParameters(ii, ivIndex, sigma, epsilon, reductionFactor); SerializationNode& particle = particles.createChildNode("Particle"); particle.setIntProperty("ivIndex", ivIndex).setDoubleProperty("sigma", sigma).setDoubleProperty("epsilon", epsilon).setDoubleProperty("reductionFactor", reductionFactor); std::vector< int > exclusions; - force.getParticleExclusions( ii, exclusions ); + force.getParticleExclusions(ii, exclusions); SerializationNode& particleExclusions = particle.createChildNode("ParticleExclusions"); for (unsigned int jj = 0; jj < exclusions.size(); jj++) { - particleExclusions.createChildNode( "excl" ).setIntProperty( "index", exclusions[jj] ); + particleExclusions.createChildNode("excl").setIntProperty("index", exclusions[jj]); } } } @@ -77,9 +77,9 @@ void* AmoebaVdwForceProxy::deserialize(const SerializationNode& node) const { AmoebaVdwForce* force = new AmoebaVdwForce(); try { - force->setSigmaCombiningRule(node.getStringProperty( "SigmaCombiningRule" ) ); - force->setEpsilonCombiningRule(node.getStringProperty( "EpsilonCombiningRule" ) ); - force->setCutoff(node.getDoubleProperty( "VdwCutoff" ) ); + force->setSigmaCombiningRule(node.getStringProperty("SigmaCombiningRule")); + force->setEpsilonCombiningRule(node.getStringProperty("EpsilonCombiningRule")); + force->setCutoff(node.getDoubleProperty("VdwCutoff")); force->setNonbondedMethod((AmoebaVdwForce::NonbondedMethod) node.getIntProperty("method")); const SerializationNode& particles = node.getChildNode("VdwParticles"); @@ -92,9 +92,9 @@ void* AmoebaVdwForceProxy::deserialize(const SerializationNode& node) const { const SerializationNode& particleExclusions = particle.getChildNode("ParticleExclusions"); std::vector< int > exclusions; for (unsigned int jj = 0; jj < particleExclusions.getChildren().size(); jj++) { - exclusions.push_back( particleExclusions.getChildren()[jj].getIntProperty("index") ); + exclusions.push_back(particleExclusions.getChildren()[jj].getIntProperty("index")); } - force->setParticleExclusions( ii, exclusions ); + force->setParticleExclusions(ii, exclusions); } } diff --git a/plugins/amoeba/serialization/src/AmoebaWcaDispersionForceProxy.cpp b/plugins/amoeba/serialization/src/AmoebaWcaDispersionForceProxy.cpp index a326ce49d..5fe68d24a 100644 --- a/plugins/amoeba/serialization/src/AmoebaWcaDispersionForceProxy.cpp +++ b/plugins/amoeba/serialization/src/AmoebaWcaDispersionForceProxy.cpp @@ -56,7 +56,7 @@ void AmoebaWcaDispersionForceProxy::serialize(const void* object, SerializationN SerializationNode& particles = node.createChildNode("WcaDispersionParticles"); for (unsigned int ii = 0; ii < static_cast(force.getNumParticles()); ii++) { double radius, epsilon; - force.getParticleParameters( ii, radius, epsilon ); + force.getParticleParameters(ii, radius, epsilon); particles.createChildNode("Particle").setDoubleProperty("radius", radius).setDoubleProperty("epsilon", epsilon); } @@ -69,21 +69,21 @@ void* AmoebaWcaDispersionForceProxy::deserialize(const SerializationNode& node) try { - force->setEpso( node.getDoubleProperty( "Epso" ) ); - force->setEpsh( node.getDoubleProperty( "Epsh" ) ); - force->setRmino( node.getDoubleProperty( "Rmino" ) ); - force->setRminh( node.getDoubleProperty( "Rminh" ) ); + force->setEpso( node.getDoubleProperty("Epso")); + force->setEpsh( node.getDoubleProperty("Epsh")); + force->setRmino( node.getDoubleProperty("Rmino")); + force->setRminh( node.getDoubleProperty("Rminh")); - force->setAwater( node.getDoubleProperty( "Awater" ) ); - force->setShctd( node.getDoubleProperty( "Shctd" ) ); - force->setDispoff( node.getDoubleProperty( "Dispoff" ) ); - force->setSlevy( node.getDoubleProperty( "Slevy" ) ); + force->setAwater( node.getDoubleProperty("Awater")); + force->setShctd( node.getDoubleProperty("Shctd")); + force->setDispoff(node.getDoubleProperty("Dispoff")); + force->setSlevy( node.getDoubleProperty("Slevy")); const SerializationNode& particles = node.getChildNode("WcaDispersionParticles"); for (unsigned int ii = 0; ii < particles.getChildren().size(); ii++) { const SerializationNode& particle = particles.getChildren()[ii]; - force->addParticle( particle.getDoubleProperty("radius"), particle.getDoubleProperty("epsilon")); + force->addParticle(particle.getDoubleProperty("radius"), particle.getDoubleProperty("epsilon")); } } diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaAngleForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaAngleForce.cpp index a35622725..aaadc9f9e 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaAngleForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaAngleForce.cpp @@ -45,10 +45,10 @@ void testSerialization() { // Create a Force. AmoebaAngleForce force1; - force1.setAmoebaGlobalAngleCubic( 12.3 ); - force1.setAmoebaGlobalAngleQuartic( 98.7 ); - force1.setAmoebaGlobalAnglePentic( 91.7 ); - force1.setAmoebaGlobalAngleSextic( 93.7 ); + force1.setAmoebaGlobalAngleCubic(12.3); + force1.setAmoebaGlobalAngleQuartic(98.7); + force1.setAmoebaGlobalAnglePentic(91.7); + force1.setAmoebaGlobalAngleSextic(93.7); force1.addAngle(0, 1, 3, 1.0, 2.0); force1.addAngle(0, 2, 3, 2.0, 2.1); force1.addAngle(2, 3, 5, 3.0, 2.2); diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaBondForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaBondForce.cpp index 1215f6e2f..e892b6353 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaBondForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaBondForce.cpp @@ -45,8 +45,8 @@ void testSerialization() { // Create a Force. AmoebaBondForce force1; - force1.setAmoebaGlobalBondCubic( 12.3 ); - force1.setAmoebaGlobalBondQuartic( 98.7 ); + force1.setAmoebaGlobalBondCubic(12.3); + force1.setAmoebaGlobalBondQuartic(98.7); force1.addBond(0, 1, 1.0, 2.0); force1.addBond(0, 2, 2.0, 2.1); force1.addBond(2, 3, 3.0, 2.2); diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp index 475303e59..7fe4294c3 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaGeneralizedKirkwoodForce.cpp @@ -45,12 +45,12 @@ void testSerialization() { // Create a Force. AmoebaGeneralizedKirkwoodForce force1; - force1.setSolventDielectric( 80.0 ); - force1.setSoluteDielectric( 1.0 ); - //force1.setDielectricOffset( 0.09 ); - force1.setProbeRadius( 1.40 ); - force1.setSurfaceAreaFactor( 0.888 ); - force1.setIncludeCavityTerm( 1 ); + force1.setSolventDielectric( 80.0); + force1.setSoluteDielectric( 1.0); + //force1.setDielectricOffset( 0.09); + force1.setProbeRadius( 1.40); + force1.setSurfaceAreaFactor( 0.888); + force1.setIncludeCavityTerm( 1); force1.addParticle(1.0, 2.0, 0.9); force1.addParticle(-1.1,2.1, 0.8); @@ -77,8 +77,8 @@ void testSerialization() { double radius1, charge1, scaleFactor1; double radius2, charge2, scaleFactor2; - force1.getParticleParameters( ii, charge1, radius1, scaleFactor1 ); - force2.getParticleParameters( ii, charge2, radius2, scaleFactor2 ); + force1.getParticleParameters(ii, charge1, radius1, scaleFactor1); + force2.getParticleParameters(ii, charge2, radius2, scaleFactor2); ASSERT_EQUAL(charge1, charge2); ASSERT_EQUAL(radius1, radius2); diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaInPlaneAngleForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaInPlaneAngleForce.cpp index 65e12aabb..c1a97e1a3 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaInPlaneAngleForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaInPlaneAngleForce.cpp @@ -46,10 +46,10 @@ void testSerialization() { AmoebaInPlaneAngleForce force1; - force1.setAmoebaGlobalInPlaneAngleCubic( 12.3 ); - force1.setAmoebaGlobalInPlaneAngleQuartic( 98.7 ); - force1.setAmoebaGlobalInPlaneAnglePentic( 91.7 ); - force1.setAmoebaGlobalInPlaneAngleSextic( 93.7 ); + force1.setAmoebaGlobalInPlaneAngleCubic(12.3); + force1.setAmoebaGlobalInPlaneAngleQuartic(98.7); + force1.setAmoebaGlobalInPlaneAnglePentic(91.7); + force1.setAmoebaGlobalInPlaneAngleSextic(93.7); force1.addAngle(0, 1, 3, 4, 1.0, 2.0); force1.addAngle(0, 2, 3, 5, 2.0, 2.1); @@ -71,7 +71,7 @@ void testSerialization() { ASSERT_EQUAL(force1.getAmoebaGlobalInPlaneAngleSextic(), force2.getAmoebaGlobalInPlaneAngleSextic()); ASSERT_EQUAL(force1.getNumAngles(), force2.getNumAngles()); - for ( unsigned int ii = 0; ii < static_cast(force1.getNumAngles()); ii++) { + for (unsigned int ii = 0; ii < static_cast(force1.getNumAngles()); ii++) { int a1, a2, a3, a4, b1, b2, b3, b4; double da, db, ka, kb; force1.getAngleParameters(ii, a1, a2, a3, a4, da, ka); diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp index 35f28a34e..4c8cd0dad 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaMultipoleForce.cpp @@ -42,56 +42,56 @@ using namespace std; extern "C" void registerAmoebaSerializationProxies(); -static void getCovalentTypes( std::vector& covalentTypes ){ +static void getCovalentTypes(std::vector& covalentTypes) { - covalentTypes.push_back( "Covalent12" ); - covalentTypes.push_back( "Covalent13" ); - covalentTypes.push_back( "Covalent14" ); - covalentTypes.push_back( "Covalent15" ); + covalentTypes.push_back("Covalent12"); + covalentTypes.push_back("Covalent13"); + covalentTypes.push_back("Covalent14"); + covalentTypes.push_back("Covalent15"); - covalentTypes.push_back( "PolarizationCovalent11" ); - covalentTypes.push_back( "PolarizationCovalent12" ); - covalentTypes.push_back( "PolarizationCovalent13" ); - covalentTypes.push_back( "PolarizationCovalent14" ); + covalentTypes.push_back("PolarizationCovalent11"); + covalentTypes.push_back("PolarizationCovalent12"); + covalentTypes.push_back("PolarizationCovalent13"); + covalentTypes.push_back("PolarizationCovalent14"); } void testSerialization() { // Create a Force. AmoebaMultipoleForce force1; - force1.setNonbondedMethod( AmoebaMultipoleForce::NoCutoff ); - force1.setCutoffDistance( 0.9 ); - force1.setAEwald( 0.544 ); - //force1.setPmeBSplineOrder( 4 ); + force1.setNonbondedMethod(AmoebaMultipoleForce::NoCutoff); + force1.setCutoffDistance(0.9); + force1.setAEwald(0.544); + //force1.setPmeBSplineOrder(4); std::vector gridDimension; - gridDimension.push_back( 64 ); - gridDimension.push_back( 63 ); - gridDimension.push_back( 61 ); - force1.setPmeGridDimensions( gridDimension ); - //force1.setMutualInducedIterationMethod( AmoebaMultipoleForce::SOR ); - force1.setMutualInducedMaxIterations( 200 ); - force1.setMutualInducedTargetEpsilon( 1.0e-05 ); - //force1.setElectricConstant( 138.93 ); - force1.setEwaldErrorTolerance( 1.0e-05 ); + gridDimension.push_back(64); + gridDimension.push_back(63); + gridDimension.push_back(61); + force1.setPmeGridDimensions(gridDimension); + //force1.setMutualInducedIterationMethod(AmoebaMultipoleForce::SOR); + force1.setMutualInducedMaxIterations(200); + force1.setMutualInducedTargetEpsilon(1.0e-05); + //force1.setElectricConstant(138.93); + force1.setEwaldErrorTolerance(1.0e-05); std::vector covalentTypes; - getCovalentTypes( covalentTypes ); + getCovalentTypes(covalentTypes); - for( unsigned int ii = 0; ii < 3; ii++ ){ + for (unsigned int ii = 0; ii < 3; ii++) { std::vector molecularDipole; std::vector molecularQuadrupole; - molecularDipole.push_back( 0.1 ); molecularDipole.push_back( rand() ); molecularDipole.push_back( rand() ); - for( unsigned int jj = 0; jj < 9; jj++ ){ - molecularQuadrupole.push_back( static_cast(rand()) ); + molecularDipole.push_back(0.1); molecularDipole.push_back(rand()); molecularDipole.push_back(rand()); + for (unsigned int jj = 0; jj < 9; jj++) { + molecularQuadrupole.push_back(static_cast(rand())); } - force1.addMultipole( static_cast(ii+1), molecularDipole, molecularQuadrupole, AmoebaMultipoleForce::Bisector, - ii+1, ii+2, ii+3, static_cast(rand()), static_cast(rand()), static_cast(rand()) ); + force1.addMultipole(static_cast(ii+1), molecularDipole, molecularQuadrupole, AmoebaMultipoleForce::Bisector, + ii+1, ii+2, ii+3, static_cast(rand()), static_cast(rand()), static_cast(rand())); - for( unsigned int jj = 0; jj < covalentTypes.size(); jj++ ){ + for (unsigned int jj = 0; jj < covalentTypes.size(); jj++) { std::vector< int > covalentMap; - covalentMap.push_back( ii*jj ); covalentMap.push_back( rand() ); covalentMap.push_back( rand() ); - force1.setCovalentMap( ii, static_cast(jj), covalentMap); + covalentMap.push_back(ii*jj); covalentMap.push_back(rand()); covalentMap.push_back(rand()); + force1.setCovalentMap(ii, static_cast(jj), covalentMap); } } @@ -118,10 +118,10 @@ void testSerialization() { std::vector gridDimension1; std::vector gridDimension2; - force1.getPmeGridDimensions( gridDimension1 ); - force2.getPmeGridDimensions( gridDimension2 ); + force1.getPmeGridDimensions(gridDimension1); + force2.getPmeGridDimensions(gridDimension2); ASSERT_EQUAL(gridDimension1.size(), gridDimension2.size()); - for( unsigned int jj = 0; jj < gridDimension1.size(); jj++ ){ + for (unsigned int jj = 0; jj < gridDimension1.size(); jj++) { ASSERT_EQUAL(gridDimension1[jj], gridDimension2[jj]); } @@ -140,11 +140,11 @@ void testSerialization() { std::vector molecularDipole2; std::vector molecularQuadrupole2; - force1.getMultipoleParameters( ii, charge1, molecularDipole1, molecularQuadrupole1, axisType1, multipoleAtomZ1, multipoleAtomX1, multipoleAtomY1, - thole1, dampingFactor1, polarity1 ); + force1.getMultipoleParameters(ii, charge1, molecularDipole1, molecularQuadrupole1, axisType1, multipoleAtomZ1, multipoleAtomX1, multipoleAtomY1, + thole1, dampingFactor1, polarity1); - force2.getMultipoleParameters( ii, charge2, molecularDipole2, molecularQuadrupole2, axisType2, multipoleAtomZ2, multipoleAtomX2, multipoleAtomY2, - thole2, dampingFactor2, polarity2 ); + force2.getMultipoleParameters(ii, charge2, molecularDipole2, molecularQuadrupole2, axisType2, multipoleAtomZ2, multipoleAtomX2, multipoleAtomY2, + thole2, dampingFactor2, polarity2); ASSERT_EQUAL(charge1, charge2); ASSERT_EQUAL(axisType1, axisType2); @@ -155,25 +155,25 @@ void testSerialization() { ASSERT_EQUAL(dampingFactor1, dampingFactor2); ASSERT_EQUAL(polarity1, polarity2); - ASSERT_EQUAL(molecularDipole1.size(), molecularDipole2.size() ); - ASSERT_EQUAL(molecularDipole1.size(), 3 ); + ASSERT_EQUAL(molecularDipole1.size(), molecularDipole2.size()); + ASSERT_EQUAL(molecularDipole1.size(), 3); for (unsigned int jj = 0; jj < molecularDipole1.size(); jj++) { - ASSERT_EQUAL(molecularDipole1[jj], molecularDipole2[jj] ); + ASSERT_EQUAL(molecularDipole1[jj], molecularDipole2[jj]); } - ASSERT_EQUAL(molecularQuadrupole1.size(), molecularQuadrupole2.size() ); - ASSERT_EQUAL(molecularQuadrupole1.size(), 9 ); + ASSERT_EQUAL(molecularQuadrupole1.size(), molecularQuadrupole2.size()); + ASSERT_EQUAL(molecularQuadrupole1.size(), 9); for (unsigned int jj = 0; jj < molecularQuadrupole1.size(); jj++) { - ASSERT_EQUAL(molecularQuadrupole1[jj], molecularQuadrupole2[jj] ); + ASSERT_EQUAL(molecularQuadrupole1[jj], molecularQuadrupole2[jj]); } for (unsigned int jj = 0; jj < covalentTypes.size(); jj++) { std::vector covalentMap1; std::vector covalentMap2; - force1.getCovalentMap( ii, static_cast(jj), covalentMap1 ); - force2.getCovalentMap( ii, static_cast(jj), covalentMap2 ); - ASSERT_EQUAL(covalentMap1.size(), covalentMap2.size() ); + force1.getCovalentMap(ii, static_cast(jj), covalentMap1); + force2.getCovalentMap(ii, static_cast(jj), covalentMap2); + ASSERT_EQUAL(covalentMap1.size(), covalentMap2.size()); for (unsigned int kk = 0; kk < covalentMap1.size(); kk++) { - ASSERT_EQUAL(covalentMap1[kk], covalentMap2[kk] ); + ASSERT_EQUAL(covalentMap1[kk], covalentMap2[kk]); } } } diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaOutOfPlaneBendForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaOutOfPlaneBendForce.cpp index e0c9f72b1..cdbbf6a35 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaOutOfPlaneBendForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaOutOfPlaneBendForce.cpp @@ -46,10 +46,10 @@ void testSerialization() { AmoebaOutOfPlaneBendForce force1; - force1.setAmoebaGlobalOutOfPlaneBendCubic( 12.3 ); - force1.setAmoebaGlobalOutOfPlaneBendQuartic( 98.7 ); - force1.setAmoebaGlobalOutOfPlaneBendPentic( 91.7 ); - force1.setAmoebaGlobalOutOfPlaneBendSextic( 93.7 ); + force1.setAmoebaGlobalOutOfPlaneBendCubic(12.3); + force1.setAmoebaGlobalOutOfPlaneBendQuartic(98.7); + force1.setAmoebaGlobalOutOfPlaneBendPentic(91.7); + force1.setAmoebaGlobalOutOfPlaneBendSextic(93.7); force1.addOutOfPlaneBend(0, 1, 3, 4, 2.0); force1.addOutOfPlaneBend(0, 2, 3, 5, 2.1); diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp index a70812b77..3bbc0b569 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaTorsionTorsionForce.cpp @@ -42,27 +42,27 @@ using namespace std; extern "C" void registerAmoebaSerializationProxies(); -static void loadTorsionTorsionGrid( std::vector< std::vector< std::vector > >& gridVector ){ +static void loadTorsionTorsionGrid(std::vector< std::vector< std::vector > >& gridVector) { static const int gridSize = 25; - gridVector.resize( gridSize ); - for( unsigned int ii = 0; ii < gridSize; ii++ ){ - gridVector[ii].resize( gridSize ); - for( unsigned int jj = 0; jj < gridSize; jj++ ){ - gridVector[ii][jj].resize( 6 ); - for( unsigned int kk = 0; kk < 6; kk++ ){ + gridVector.resize(gridSize); + for (unsigned int ii = 0; ii < gridSize; ii++) { + gridVector[ii].resize(gridSize); + for (unsigned int jj = 0; jj < gridSize; jj++) { + gridVector[ii][jj].resize(6); + for (unsigned int kk = 0; kk < 6; kk++) { gridVector[ii][jj][0] = -180.0 + 15.0*static_cast(ii); gridVector[ii][jj][1] = -180.0 + 15.0*static_cast(jj); - gridVector[ii][jj][2] = static_cast( rand()); - gridVector[ii][jj][3] = static_cast( rand()); - gridVector[ii][jj][4] = static_cast( rand()); - gridVector[ii][jj][5] = static_cast( rand()); + gridVector[ii][jj][2] = static_cast(rand()); + gridVector[ii][jj][3] = static_cast(rand()); + gridVector[ii][jj][4] = static_cast(rand()); + gridVector[ii][jj][5] = static_cast(rand()); } } } } -static void compareGrids( const std::vector< std::vector< std::vector > >& grid1, const std::vector< std::vector< std::vector > >& grid2 ) { +static void compareGrids(const std::vector< std::vector< std::vector > >& grid1, const std::vector< std::vector< std::vector > >& grid2) { ASSERT_EQUAL(grid1.size(), grid2.size()); for (unsigned int ii = 0; ii < grid1.size(); ii++) { @@ -81,13 +81,13 @@ void testSerialization() { AmoebaTorsionTorsionForce force1; - for( unsigned int ii = 0; ii < 5; ii++ ){ + for (unsigned int ii = 0; ii < 5; ii++) { std::vector< std::vector< std::vector > > gridVector; - loadTorsionTorsionGrid( gridVector ); - force1.setTorsionTorsionGrid( ii, gridVector ); + loadTorsionTorsionGrid(gridVector); + force1.setTorsionTorsionGrid(ii, gridVector); } - for( unsigned int ii = 0; ii < 5; ii++ ){ - force1.addTorsionTorsion( ii, ii+1,ii+3, ii+4, ii+5, ( (ii % 2 ) ? 1 : 0), (ii % 4) ); + for (unsigned int ii = 0; ii < 5; ii++) { + force1.addTorsionTorsion(ii, ii+1,ii+3, ii+4, ii+5, ((ii % 2) ? 1 : 0), (ii % 4)); } // Serialize and then deserialize it. @@ -104,8 +104,8 @@ void testSerialization() { int a1, a2, a3, a4, a5, aChiral, aGridIndex, b1, b2, b3, b4, b5, bChiral, bGridIndex; - force1.getTorsionTorsionParameters( ii, a1, a2, a3, a4, a5, aChiral, aGridIndex); - force2.getTorsionTorsionParameters( ii, b1, b2, b3, b4, b5, bChiral, bGridIndex); + force1.getTorsionTorsionParameters(ii, a1, a2, a3, a4, a5, aChiral, aGridIndex); + force2.getTorsionTorsionParameters(ii, b1, b2, b3, b4, b5, bChiral, bGridIndex); ASSERT_EQUAL(a1, b1); ASSERT_EQUAL(a2, b2); @@ -113,14 +113,14 @@ void testSerialization() { ASSERT_EQUAL(a4, b4); ASSERT_EQUAL(a5, b5); ASSERT_EQUAL(aChiral, bChiral); - ASSERT_EQUAL(aGridIndex, bGridIndex ); + ASSERT_EQUAL(aGridIndex, bGridIndex); } ASSERT_EQUAL(force1.getNumTorsionTorsionGrids(), force2.getNumTorsionTorsionGrids()); for (unsigned int ii = 0; ii < static_cast(force1.getNumTorsionTorsionGrids()); ii++) { - const std::vector< std::vector< std::vector > >& grid1 = force1.getTorsionTorsionGrid( ii ); - const std::vector< std::vector< std::vector > >& grid2 = force2.getTorsionTorsionGrid( ii ); - compareGrids(grid1, grid2 ); + const std::vector< std::vector< std::vector > >& grid1 = force1.getTorsionTorsionGrid(ii); + const std::vector< std::vector< std::vector > >& grid2 = force2.getTorsionTorsionGrid(ii); + compareGrids(grid1, grid2); } } diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp index b63f74d96..f34bac6c4 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaVdwForce.cpp @@ -45,20 +45,20 @@ void testSerialization() { // Create a Force. AmoebaVdwForce force1; - force1.setSigmaCombiningRule( "GEOMETRIC" ); - force1.setEpsilonCombiningRule( "GEOMETRIC" ); - force1.setCutoff( 0.9 ); + force1.setSigmaCombiningRule("GEOMETRIC"); + force1.setEpsilonCombiningRule("GEOMETRIC"); + force1.setCutoff(0.9); force1.setNonbondedMethod(AmoebaVdwForce::CutoffPeriodic); force1.addParticle(0, 1.0, 2.0, 0.9); force1.addParticle(1, 1.1, 2.1, 0.9); force1.addParticle(2, 1.3, 4.1, 0.9); - for( unsigned int ii = 0; ii < 3; ii++ ){ + for (unsigned int ii = 0; ii < 3; ii++) { std::vector< int > exclusions; - exclusions.push_back( ii ); - exclusions.push_back( ii + 1 ); - exclusions.push_back( ii + 10 ); - force1.setParticleExclusions( ii, exclusions ); + exclusions.push_back(ii); + exclusions.push_back(ii + 1); + exclusions.push_back(ii + 10); + force1.setParticleExclusions(ii, exclusions); } // Serialize and then deserialize it. @@ -85,10 +85,10 @@ void testSerialization() { double sigma1, epsilon1, reductionFactor1; double sigma2, epsilon2, reductionFactor2; - force1.getParticleParameters( ii, ivIndex1, sigma1, epsilon1, reductionFactor1 ); - force2.getParticleParameters( ii, ivIndex2, sigma2, epsilon2, reductionFactor2 ); + force1.getParticleParameters(ii, ivIndex1, sigma1, epsilon1, reductionFactor1); + force2.getParticleParameters(ii, ivIndex2, sigma2, epsilon2, reductionFactor2); - ASSERT_EQUAL(ivIndex1, ivIndex2 ); + ASSERT_EQUAL(ivIndex1, ivIndex2); ASSERT_EQUAL(sigma1, sigma2); ASSERT_EQUAL(epsilon1, epsilon2); ASSERT_EQUAL(reductionFactor1, reductionFactor2); @@ -98,14 +98,14 @@ void testSerialization() { std::vector< int > exclusions1; std::vector< int > exclusions2; - force1.getParticleExclusions( ii, exclusions1 ); - force2.getParticleExclusions( ii, exclusions2 ); + force1.getParticleExclusions(ii, exclusions1); + force2.getParticleExclusions(ii, exclusions2); ASSERT_EQUAL(exclusions1.size(), exclusions2.size()); for (unsigned int jj = 0; jj < exclusions1.size(); jj++) { int hit = 0; for (unsigned int kk = 0; kk < exclusions2.size(); kk++) { - if( exclusions2[jj] == exclusions1[kk] )hit++; + if (exclusions2[jj] == exclusions1[kk])hit++; } ASSERT_EQUAL(hit, 1); } diff --git a/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp b/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp index b52a95291..dd4d1dece 100644 --- a/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp +++ b/plugins/amoeba/serialization/tests/TestSerializeAmoebaWcaDispersionForce.cpp @@ -45,14 +45,14 @@ void testSerialization() { // Create a Force. AmoebaWcaDispersionForce force1; - force1.setEpso( 1.0 ); - force1.setEpsh( 1.1 ); - force1.setRmino( 1.2 ); - force1.setRminh( 1.3 ); - force1.setAwater( 1.4 ); - force1.setShctd( 1.5 ); - force1.setDispoff( 1.6 ); - force1.setSlevy( 1.7 ); + force1.setEpso( 1.0); + force1.setEpsh( 1.1); + force1.setRmino( 1.2); + force1.setRminh( 1.3); + force1.setAwater( 1.4); + force1.setShctd( 1.5); + force1.setDispoff(1.6); + force1.setSlevy( 1.7); force1.addParticle(1.0, 2.0); force1.addParticle(1.1, 2.1); @@ -83,8 +83,8 @@ void testSerialization() { double radius1, epsilon1; double radius2, epsilon2; - force1.getParticleParameters( ii, radius1, epsilon1 ); - force2.getParticleParameters( ii, radius2, epsilon2 ); + force1.getParticleParameters(ii, radius1, epsilon1); + force2.getParticleParameters(ii, radius2, epsilon2); ASSERT_EQUAL(radius1, radius2); ASSERT_EQUAL(epsilon1, epsilon2); diff --git a/plugins/amoeba/wrappers/generateAmoebaWrappers.py b/plugins/amoeba/wrappers/generateAmoebaWrappers.py index bd37f3c60..ce860e2f3 100644 --- a/plugins/amoeba/wrappers/generateAmoebaWrappers.py +++ b/plugins/amoeba/wrappers/generateAmoebaWrappers.py @@ -327,7 +327,7 @@ extern "C" { /* OpenMM_3D_DoubleArray */ OPENMM_EXPORT_AMOEBA OpenMM_3D_DoubleArray* OpenMM_3D_DoubleArray_create(int size1, int size2, int size3); OPENMM_EXPORT_AMOEBA void OpenMM_3D_DoubleArray_set(OpenMM_3D_DoubleArray* array, int index1, int index2, OpenMM_DoubleArray* values); -OPENMM_EXPORT_AMOEBA void OpenMM_3D_DoubleArray_destroy( OpenMM_3D_DoubleArray* array);""", file=self.out) +OPENMM_EXPORT_AMOEBA void OpenMM_3D_DoubleArray_destroy(OpenMM_3D_DoubleArray* array);""", file=self.out) self.writeClasses() @@ -586,29 +586,29 @@ OPENMM_EXPORT_AMOEBA int OpenMM_2D_IntArray_getSize(const OpenMM_2D_IntArray* ar OPENMM_EXPORT_AMOEBA void OpenMM_2D_IntArray_resize(OpenMM_2D_IntArray* array, int size) { reinterpret_cast >*>(array)->resize(size); } -OPENMM_EXPORT_AMOEBA void OpenMM_2D_IntArray_append(OpenMM_2D_IntArray* array, int index1, int value ) { +OPENMM_EXPORT_AMOEBA void OpenMM_2D_IntArray_append(OpenMM_2D_IntArray* array, int index1, int value) { vector >* array2DInt = reinterpret_cast >*>(array); - if( array2DInt->size() <= index1 ){ - array2DInt->resize( index1+1 ); + if (array2DInt->size() <= index1) { + array2DInt->resize(index1+1); } - (*array2DInt)[index1].push_back( value ); + (*array2DInt)[index1].push_back(value); } OPENMM_EXPORT_AMOEBA void OpenMM_2D_IntArray_set(OpenMM_2D_IntArray* array, int index1, int index2, int value) { vector >* array2DInt = reinterpret_cast >*>(array); - if( array2DInt->size() <= index1 ){ - array2DInt->resize( index1+1 ); + if (array2DInt->size() <= index1) { + array2DInt->resize(index1+1); } - if( array2DInt[index1].size() <= index2 ){ - array2DInt[index1].resize( index2+1 ); + if (array2DInt[index1].size() <= index2) { + array2DInt[index1].resize(index2+1); } (*array2DInt)[index1][index2] = value; } OPENMM_EXPORT_AMOEBA void OpenMM_2D_IntArray_get(const OpenMM_2D_IntArray* array, int index1, int index2, int* value) { const vector >* array2DInt = reinterpret_cast >*>(array); - if ( array2DInt->size() <= index1 ) + if (array2DInt->size() <= index1) throw OpenMMException("OpenMM_2D_IntArray_get: first index out of range."); - if ( (*array2DInt)[index1].size() <= index2 ) + if ((*array2DInt)[index1].size() <= index2) throw OpenMMException("OpenMM_2D_IntArray_get: second index out of range."); *value = (*array2DInt)[index1][index2]; } @@ -618,9 +618,9 @@ OPENMM_EXPORT_AMOEBA OpenMM_3D_DoubleArray* OpenMM_3D_DoubleArray_create(int siz int ii, jj; std::vector< std::vector< std::vector > >* v3D_Array = new std::vector > >(size1); - for( ii = 0; ii < size1; ii++ ){ + for (ii = 0; ii < size1; ii++) { (*v3D_Array)[ii].resize(size2); - for( jj = 0; jj < size2; jj++ ){ + for (jj = 0; jj < size2; jj++) { (*v3D_Array)[ii][jj].resize(size3); } } @@ -631,12 +631,12 @@ OPENMM_EXPORT_AMOEBA void OpenMM_3D_DoubleArray_set(OpenMM_3D_DoubleArray* array unsigned int ii; std::vector< std::vector< std::vector > >* v3D_Array = reinterpret_cast > >*>(array); std::vector * value_array = reinterpret_cast *>(values); - for( ii = 0; ii < (*value_array).size(); ii++ ){ + for (ii = 0; ii < (*value_array).size(); ii++) { (*v3D_Array)[index1][index2][ii] = (*value_array)[ii]; } } -OPENMM_EXPORT_AMOEBA void OpenMM_3D_DoubleArray_destroy( OpenMM_3D_DoubleArray* array) { +OPENMM_EXPORT_AMOEBA void OpenMM_3D_DoubleArray_destroy(OpenMM_3D_DoubleArray* array) { delete reinterpret_cast > >*>(array); }""", file=self.out) -- GitLab From e18eb785ed5bccbd659a3f9815251d3cd7df1cb4 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 23 Feb 2015 16:58:16 -0800 Subject: [PATCH 287/338] Avoid throwing exceptions internally when serializing States --- openmmapi/include/openmm/State.h | 4 + openmmapi/src/State.cpp | 3 + serialization/src/StateProxy.cpp | 135 ++++++++------------- serialization/tests/TestSerializeState.cpp | 59 ++++++++- 4 files changed, 109 insertions(+), 92 deletions(-) diff --git a/openmmapi/include/openmm/State.h b/openmmapi/include/openmm/State.h index be669a3a2..fda10d856 100644 --- a/openmmapi/include/openmm/State.h +++ b/openmmapi/include/openmm/State.h @@ -108,6 +108,10 @@ public: * Get a map containing the values of all parameters. If this State does not contain parameters, this will throw an exception. */ const std::map& getParameters() const; + /** + * Get which data types are stored in this State. The return value is a sum of DataType flags. + */ + int getDataTypes() const; private: State(double time); void setPositions(const std::vector& pos); diff --git a/openmmapi/src/State.cpp b/openmmapi/src/State.cpp index 5f226021b..75faddb15 100644 --- a/openmmapi/src/State.cpp +++ b/openmmapi/src/State.cpp @@ -76,6 +76,9 @@ const map& State::getParameters() const { throw OpenMMException("Invoked getParameters() on a State which does not contain parameters."); return parameters; } +int State::getDataTypes() const { + return types; +} State::State(double time) : types(0), time(time), ke(0), pe(0) { } State::State() : types(0), time(0.0), ke(0), pe(0) { diff --git a/serialization/src/StateProxy.cpp b/serialization/src/StateProxy.cpp index 1a799ab50..0fca5d9f1 100644 --- a/serialization/src/StateProxy.cpp +++ b/serialization/src/StateProxy.cpp @@ -50,7 +50,7 @@ void StateProxy::serialize(const void* object, SerializationNode& node) const { boxVectorsNode.createChildNode("A").setDoubleProperty("x", a[0]).setDoubleProperty("y", a[1]).setDoubleProperty("z", a[2]); boxVectorsNode.createChildNode("B").setDoubleProperty("x", b[0]).setDoubleProperty("y", b[1]).setDoubleProperty("z", b[2]); boxVectorsNode.createChildNode("C").setDoubleProperty("x", c[0]).setDoubleProperty("y", c[1]).setDoubleProperty("z", c[2]); - try { + if ((s.getDataTypes()&State::Parameters) != 0) { s.getParameters(); SerializationNode& parametersNode = node.createChildNode("Parameters"); map stateParams = s.getParameters(); @@ -58,46 +58,36 @@ void StateProxy::serialize(const void* object, SerializationNode& node) const { for (it = stateParams.begin(); it!=stateParams.end();it++) { parametersNode.setDoubleProperty(it->first, it->second); } - } catch (const OpenMMException &) { - // do nothing } - try { + if ((s.getDataTypes()&State::Energy) != 0) { s.getPotentialEnergy(); SerializationNode& energiesNode = node.createChildNode("Energies"); energiesNode.setDoubleProperty("PotentialEnergy", s.getPotentialEnergy()); energiesNode.setDoubleProperty("KineticEnergy", s.getKineticEnergy()); - } catch (const OpenMMException &) { - // do nothing } - try { + if ((s.getDataTypes()&State::Positions) != 0) { s.getPositions(); SerializationNode& positionsNode = node.createChildNode("Positions"); vector statePositions = s.getPositions(); for (int i=0; i stateVelocities = s.getVelocities(); for (int i=0; i stateForces = s.getForces(); for (int i=0; i outStateParams; - try { - const SerializationNode& parametersNode = node.getChildNode("Parameters"); - // inStateParams is really a pair, where string is the name and double is the value - // but we want to avoid casting a string to a double and instead use the built in routines, - map inStateParams = parametersNode.getProperties(); - for (map::const_iterator pit = inStateParams.begin(); pit != inStateParams.end(); pit++) { - outStateParams[pit->first] = parametersNode.getDoubleProperty(pit->first); + vector arraySizes; + State::StateBuilder builder(outTime); + const vector& children = node.getChildren(); + for (int j = 0; j < (int) children.size(); j++) { + const SerializationNode& child = children[j]; + if (child.getName() == "Parameters") { + map outStateParams; + // inStateParams is really a pair, where string is the name and double is the value + // but we want to avoid casting a string to a double and instead use the built in routines, + map inStateParams = child.getProperties(); + for (map::const_iterator pit = inStateParams.begin(); pit != inStateParams.end(); pit++) { + outStateParams[pit->first] = child.getDoubleProperty(pit->first); + } + builder.setParameters(outStateParams); } - types = types | State::Parameters; - } catch (const OpenMMException &) { - // do nothing - } - double potentialEnergy; - double kineticEnergy; - try { - const SerializationNode& energiesNode = node.getChildNode("Energies"); - potentialEnergy = energiesNode.getDoubleProperty("PotentialEnergy"); - kineticEnergy = energiesNode.getDoubleProperty("KineticEnergy"); - types = types | State::Energy; - } catch (const OpenMMException &) { - // do nothing - } - vector outPositions; - vector outVelocities; - vector outForces; - try { - const SerializationNode& positionsNode = node.getChildNode("Positions"); - for (int i = 0; i < (int) positionsNode.getChildren().size(); i++) { - const SerializationNode& particle = positionsNode.getChildren()[i]; - outPositions.push_back(Vec3(particle.getDoubleProperty("x"),particle.getDoubleProperty("y"),particle.getDoubleProperty("z"))); + else if (child.getName() == "Energies") { + double potentialEnergy = child.getDoubleProperty("PotentialEnergy"); + double kineticEnergy = child.getDoubleProperty("KineticEnergy"); + builder.setEnergy(kineticEnergy, potentialEnergy); } - types = types | State::Positions; - } catch (const OpenMMException &) { - // do nothing - } - try { - const SerializationNode& velocitiesNode = node.getChildNode("Velocities"); - for (int i = 0; i < (int) velocitiesNode.getChildren().size(); i++) { - const SerializationNode& particle = velocitiesNode.getChildren()[i]; - outVelocities.push_back(Vec3(particle.getDoubleProperty("x"),particle.getDoubleProperty("y"),particle.getDoubleProperty("z"))); + else if (child.getName() == "Positions") { + vector outPositions; + for (int i = 0; i < (int) child.getChildren().size(); i++) { + const SerializationNode& particle = child.getChildren()[i]; + outPositions.push_back(Vec3(particle.getDoubleProperty("x"),particle.getDoubleProperty("y"),particle.getDoubleProperty("z"))); + } + builder.setPositions(outPositions); + arraySizes.push_back(outPositions.size()); } - types = types | State::Velocities; - } catch (const OpenMMException &) { - // do nothing - } - try { - const SerializationNode& forcesNode = node.getChildNode("Forces"); - for (int i = 0; i < (int) forcesNode.getChildren().size(); i++) { - const SerializationNode& particle = forcesNode.getChildren()[i]; - outForces.push_back(Vec3(particle.getDoubleProperty("x"),particle.getDoubleProperty("y"),particle.getDoubleProperty("z"))); + else if (child.getName() == "Velocities") { + vector outVelocities; + for (int i = 0; i < (int) child.getChildren().size(); i++) { + const SerializationNode& particle = child.getChildren()[i]; + outVelocities.push_back(Vec3(particle.getDoubleProperty("x"),particle.getDoubleProperty("y"),particle.getDoubleProperty("z"))); + } + builder.setVelocities(outVelocities); + arraySizes.push_back(outVelocities.size()); + } + else if (child.getName() == "Forces") { + vector outForces; + for (int i = 0; i < (int) child.getChildren().size(); i++) { + const SerializationNode& particle = child.getChildren()[i]; + outForces.push_back(Vec3(particle.getDoubleProperty("x"),particle.getDoubleProperty("y"),particle.getDoubleProperty("z"))); + } + builder.setForces(outForces); + arraySizes.push_back(outForces.size()); } - types = types | State::Forces; - } catch (const OpenMMException &) { - // do nothing - } - vector arraySizes; - State::StateBuilder builder(outTime); - if (types & State::Positions) { - builder.setPositions(outPositions); - arraySizes.push_back(outPositions.size()); - } - if (types & State::Velocities) { - builder.setVelocities(outVelocities); - arraySizes.push_back(outVelocities.size()); - } - if (types & State::Forces) { - builder.setForces(outForces); - arraySizes.push_back(outForces.size()); - } - if (types & State::Energy) { - builder.setEnergy(kineticEnergy, potentialEnergy); - } - if (types & State::Parameters) { - builder.setParameters(outStateParams); } - for (int i = 1; i < arraySizes.size(); i++) { if (arraySizes[i] != arraySizes[i-1]) { throw(OpenMMException("State Deserialization Particle Size Mismatch, check number of particles in Forces, Velocities, Positions!")); diff --git a/serialization/tests/TestSerializeState.cpp b/serialization/tests/TestSerializeState.cpp index 017085385..1c936fc76 100644 --- a/serialization/tests/TestSerializeState.cpp +++ b/serialization/tests/TestSerializeState.cpp @@ -66,8 +66,8 @@ void testSerialization() { system.addForce(nonbonded); system.addForce(new AndersenThermostat(393.3, 19.3)); system.addForce(new MonteCarloBarostat(25, 393.3, 25)); - Integrator *intg = new LangevinIntegrator(300,79,0.002); - Context *ctxt = new Context(system, *intg); + LangevinIntegrator intg(300,79,0.002); + Context context(system, intg); // Set positions, velocities, forces vector positions; @@ -79,11 +79,11 @@ void testSerialization() { velocities.push_back(Vec3( ((float) rand()/(float) RAND_MAX)*6.2, ((float) rand()/(float) RAND_MAX)*6.2, ((float) rand()/(float) RAND_MAX)*6.2)); } - ctxt->setPositions(positions); - ctxt->setVelocities(velocities); + context.setPositions(positions); + context.setVelocities(velocities); // Serialize and then deserialize it. - State s1 = ctxt->getState(State::Positions | State::Velocities | State::Forces | State::Energy | State::Parameters); + State s1 = context.getState(State::Positions | State::Velocities | State::Forces | State::Energy | State::Parameters); stringstream buffer; XmlSerializer::serialize(&s1, "State", buffer); @@ -132,6 +132,55 @@ void testSerialization() { assert((it1->first).compare(it2->first) == 0); ASSERT_EQUAL(it1->second, it2->second); } + delete copy; + + // Now create a series of States that include only one type of information. Verify + // that serialization works correctly for them. + + for (int types = 1; types <= 16; types *= 2) { + State s3 = context.getState(types); + stringstream buffer2; + XmlSerializer::serialize(&s3, "State", buffer2); + copy = XmlSerializer::deserialize(buffer2); + int foundTypes = 0; + try { + copy->getPositions(); + foundTypes += State::Positions; + } + catch (...) { + // Ignore + } + try { + copy->getVelocities(); + foundTypes += State::Velocities; + } + catch (...) { + // Ignore + } + try { + copy->getForces(); + foundTypes += State::Forces; + } + catch (...) { + // Ignore + } + try { + copy->getPotentialEnergy(); + foundTypes += State::Energy; + } + catch (...) { + // Ignore + } + try { + copy->getParameters(); + foundTypes += State::Parameters; + } + catch (...) { + // Ignore + } + delete copy; + ASSERT_EQUAL(types, foundTypes); + } } int main() { -- GitLab From aa7bd1cf520fb75d7e8fbbf52609bd0dcdc91ed2 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 24 Feb 2015 13:12:36 -0800 Subject: [PATCH 288/338] Fixed problems running in PNaCl --- openmmapi/src/Context.cpp | 33 ++------------------- platforms/cpu/src/CpuKernels.cpp | 9 +++--- platforms/cpu/src/CpuNonbondedForce.cpp | 2 +- platforms/cpu/tests/TestCpuNeighborList.cpp | 2 +- 4 files changed, 9 insertions(+), 37 deletions(-) diff --git a/openmmapi/src/Context.cpp b/openmmapi/src/Context.cpp index 5fe99ce88..67e694139 100644 --- a/openmmapi/src/Context.cpp +++ b/openmmapi/src/Context.cpp @@ -143,42 +143,15 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const { } void Context::setState(const State& state) { - // Determine what information the state contains. - - bool hasPositions = false, hasVelocities = false, hasParameters = false; - try { - state.getPositions(); - hasPositions = true; - } - catch (OpenMMException& ex) { - // The State does not include positions. - } - try { - state.getVelocities(); - hasVelocities = true; - } - catch (OpenMMException& ex) { - // The State does not include velocities. - } - try { - state.getParameters(); - hasParameters = true; - } - catch (OpenMMException& ex) { - // The State does not include parameters. - } - - // Copy it over. - setTime(state.getTime()); Vec3 a, b, c; state.getPeriodicBoxVectors(a, b, c); setPeriodicBoxVectors(a, b, c); - if (hasPositions) + if ((state.getDataTypes()&State::Positions) != 0) setPositions(state.getPositions()); - if (hasVelocities) + if ((state.getDataTypes()&State::Velocities) != 0) setVelocities(state.getVelocities()); - if (hasParameters) + if ((state.getDataTypes()&State::Parameters) != 0) for (map::const_iterator iter = state.getParameters().begin(); iter != state.getParameters().end(); ++iter) setParameter(iter->first, iter->second); } diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 1564a8ae7..41397c923 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -508,13 +508,12 @@ double CpuCalcNonbondedForceKernel::execute(ContextImpl& context, bool includeFo if (nonbondedMethod == PME) { // If available, use the optimized PME implementation. - try { + vector kernelNames; + kernelNames.push_back("CalcPmeReciprocalForce"); + useOptimizedPme = getPlatform().supportsKernels(kernelNames); + if (useOptimizedPme) { optimizedPme = getPlatform().createKernel(CalcPmeReciprocalForceKernel::Name(), context); optimizedPme.getAs().initialize(gridSize[0], gridSize[1], gridSize[2], numParticles, ewaldAlpha); - useOptimizedPme = true; - } - catch (OpenMMException& ex) { - // The CPU PME plugin isn't available. } } } diff --git a/platforms/cpu/src/CpuNonbondedForce.cpp b/platforms/cpu/src/CpuNonbondedForce.cpp index 107c8da99..6488cad92 100644 --- a/platforms/cpu/src/CpuNonbondedForce.cpp +++ b/platforms/cpu/src/CpuNonbondedForce.cpp @@ -216,7 +216,7 @@ void CpuNonbondedForce::calculateReciprocalIxn(int numberOfAtoms, float* posq, c // setup reciprocal box - float recipBoxSize[3] = { TWO_PI / periodicBoxVectors[0][0], TWO_PI / periodicBoxVectors[1][1], TWO_PI / periodicBoxVectors[2][2]}; + float recipBoxSize[3] = {(float) (TWO_PI/periodicBoxVectors[0][0]), (float) (TWO_PI/periodicBoxVectors[1][1]), (float) (TWO_PI/periodicBoxVectors[2][2])}; // setup K-vectors diff --git a/platforms/cpu/tests/TestCpuNeighborList.cpp b/platforms/cpu/tests/TestCpuNeighborList.cpp index 9d2a1ac0c..62c68084b 100644 --- a/platforms/cpu/tests/TestCpuNeighborList.cpp +++ b/platforms/cpu/tests/TestCpuNeighborList.cpp @@ -62,7 +62,7 @@ void testNeighborList(bool periodic, bool triclinic) { boxVectors[1] = RealVec(0, 15, 0); boxVectors[2] = RealVec(0, 0, 22); } - const float boxSize[3] = {boxVectors[0][0], boxVectors[1][1], boxVectors[2][2]}; + const float boxSize[3] = {(float) boxVectors[0][0], (float) boxVectors[1][1], (float) boxVectors[2][2]}; const int blockSize = 8; OpenMM_SFMT::SFMT sfmt; init_gen_rand(0, sfmt); -- GitLab From d51ad3c382d17600dfa7201e1e289f9bd137c8be Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 24 Feb 2015 17:08:47 -0800 Subject: [PATCH 289/338] Optimizations to PNaCl vectors --- .../include/openmm/internal/vectorize_pnacl.h | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/openmmapi/include/openmm/internal/vectorize_pnacl.h b/openmmapi/include/openmm/internal/vectorize_pnacl.h index 300d2c22d..7352039d4 100644 --- a/openmmapi/include/openmm/internal/vectorize_pnacl.h +++ b/openmmapi/include/openmm/internal/vectorize_pnacl.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2013-2014 Stanford University and the Authors. * + * Portions copyright (c) 2013-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -217,28 +217,8 @@ inline ivec4::operator fvec4() const { // Functions that operate on fvec4s. -static inline fvec4 floor(const fvec4& v) { - return fvec4(std::floor(v[0]), std::floor(v[1]), std::floor(v[2]), std::floor(v[3])); -} - -static inline fvec4 ceil(const fvec4& v) { - return fvec4(std::ceil(v[0]), std::ceil(v[1]), std::ceil(v[2]), std::ceil(v[3])); -} - -static inline fvec4 round(const fvec4& v) { - return fvec4(std::round(v[0]), std::round(v[1]), std::round(v[2]), std::round(v[3])); -} - -static inline fvec4 min(const fvec4& v1, const fvec4& v2) { - return fvec4(std::min(v1[0], v2[0]), std::min(v1[1], v2[1]), std::min(v1[2], v2[2]), std::min(v1[3], v2[3])); -} - -static inline fvec4 max(const fvec4& v1, const fvec4& v2) { - return fvec4(std::max(v1[0], v2[0]), std::max(v1[1], v2[1]), std::max(v1[2], v2[2]), std::max(v1[3], v2[3])); -} - static inline fvec4 abs(const fvec4& v) { - return fvec4(std::abs(v[0]), std::abs(v[1]), std::abs(v[2]), std::abs(v[3])); + return v&(__m128) ivec4(0x7FFFFFFF); } static inline fvec4 sqrt(const fvec4& v) { @@ -252,7 +232,8 @@ static inline float dot3(const fvec4& v1, const fvec4& v2) { static inline float dot4(const fvec4& v1, const fvec4& v2) { fvec4 r = v1*v2; - return r[0]+r[1]+r[2]+r[3]; + fvec4 temp = __builtin_shufflevector(r.val, r.val, 0, 1, -1, -1)+__builtin_shufflevector(r.val, r.val, 2, 3, -1, -1); + return temp[0]+temp[1]; } static inline fvec4 cross(const fvec4& v1, const fvec4& v2) { @@ -287,7 +268,8 @@ static inline ivec4 abs(const ivec4& v) { } static inline bool any(const __m128i& v) { - return (v[0] || v[1] || v[2] || v[3]); + ivec4 temp = __builtin_shufflevector(v, v, 0, 1, -1, -1) | __builtin_shufflevector(v, v, 2, 3, -1, -1); + return (temp[0] || temp[1]); } // Mathematical operators involving a scalar and a vector. @@ -311,7 +293,33 @@ static inline fvec4 operator/(float v1, const fvec4& v2) { // Operations for blending fvec4s based on an ivec4. static inline fvec4 blend(const fvec4& v1, const fvec4& v2, const __m128i& mask) { - return fvec4(mask[0] ? v2[0] : v1[0], mask[1] ? v2[1] : v1[1], mask[2] ? v2[2] : v1[2], mask[3] ? v2[3] : v1[3]); + return (__m128) ((mask&(__m128i)v2) + ((ivec4(0xFFFFFFFF)-ivec4(mask))&(__m128i)v1)); +} + +// These are at the end since they involve other functions defined above. + +static inline fvec4 min(const fvec4& v1, const fvec4& v2) { + return blend(v1, v2, v1 > v2); +} + +static inline fvec4 max(const fvec4& v1, const fvec4& v2) { + return blend(v1, v2, v1 < v2); +} + +static inline fvec4 round(const fvec4& v) { + fvec4 shift(0x1.0p23f); + fvec4 absResult = (abs(v)+shift)-shift; + return (__m128) ((ivec4(0x80000000)&(__m128i)v) + (ivec4(0x7FFFFFFF)&(__m128i)absResult)); +} + +static inline fvec4 floor(const fvec4& v) { + fvec4 rounded = round(v); + return rounded + blend(0.0f, -1.0f, rounded>v); +} + +static inline fvec4 ceil(const fvec4& v) { + fvec4 rounded = round(v); + return rounded + blend(0.0f, 1.0f, rounded Date: Wed, 25 Feb 2015 15:23:31 -0800 Subject: [PATCH 290/338] Further improvements to PNaCl vectors --- .../include/openmm/internal/vectorize_pnacl.h | 76 ++++++++++++------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/openmmapi/include/openmm/internal/vectorize_pnacl.h b/openmmapi/include/openmm/internal/vectorize_pnacl.h index 7352039d4..97f366327 100644 --- a/openmmapi/include/openmm/internal/vectorize_pnacl.h +++ b/openmmapi/include/openmm/internal/vectorize_pnacl.h @@ -109,24 +109,12 @@ public: fvec4 operator|(const fvec4& other) const { return (fvec4) (((__m128i)val)|((__m128i)other.val)); } - fvec4 operator==(const fvec4& other) const { - return (val==other.val); - } - fvec4 operator!=(const fvec4& other) const { - return (val!=other.val); - } - fvec4 operator>(const fvec4& other) const { - return (val>other.val); - } - fvec4 operator<(const fvec4& other) const { - return (val=(const fvec4& other) const { - return (val>=other.val); - } - fvec4 operator<=(const fvec4& other) const { - return (val<=other.val); - } + ivec4 operator==(const fvec4& other) const; + ivec4 operator!=(const fvec4& other) const; + ivec4 operator>(const fvec4& other) const; + ivec4 operator<(const fvec4& other) const; + ivec4 operator>=(const fvec4& other) const; + ivec4 operator<=(const fvec4& other) const; operator ivec4() const; }; @@ -207,6 +195,30 @@ public: // Conversion operators. +inline ivec4 fvec4::operator==(const fvec4& other) const { + return (__m128i) (val==other.val); +} + +inline ivec4 fvec4::operator!=(const fvec4& other) const { + return (__m128i) (val!=other.val); +} + +inline ivec4 fvec4::operator>(const fvec4& other) const { + return (__m128i) (val>other.val); +} + +inline ivec4 fvec4::operator<(const fvec4& other) const { + return (__m128i) (val=(const fvec4& other) const { + return (__m128i) (val>=other.val); +} + +inline ivec4 fvec4::operator<=(const fvec4& other) const { + return (__m128i) (val<=other.val); +} + inline fvec4::operator ivec4() const { return __builtin_convertvector(val, __m128i); } @@ -221,10 +233,6 @@ static inline fvec4 abs(const fvec4& v) { return v&(__m128) ivec4(0x7FFFFFFF); } -static inline fvec4 sqrt(const fvec4& v) { - return fvec4(std::sqrt(v[0]), std::sqrt(v[1]), std::sqrt(v[2]), std::sqrt(v[3])); -} - static inline float dot3(const fvec4& v1, const fvec4& v2) { fvec4 r = v1*v2; return r[0]+r[1]+r[2]; @@ -313,13 +321,29 @@ static inline fvec4 round(const fvec4& v) { } static inline fvec4 floor(const fvec4& v) { - fvec4 rounded = round(v); - return rounded + blend(0.0f, -1.0f, rounded>v); + fvec4 truncated = __builtin_convertvector(__builtin_convertvector(v.val, __m128i), __m128); + return truncated + blend(0.0f, -1.0f, truncated>v); } static inline fvec4 ceil(const fvec4& v) { - fvec4 rounded = round(v); - return rounded + blend(0.0f, 1.0f, rounded>ivec4(1).val); + fvec4 y = (__m128) i; + + // Perform three iterations of Newton refinement. + + fvec4 x2 = 0.5f*v; + y *= 1.5f-x2*y*y; + y *= 1.5f-x2*y*y; + y *= 1.5f-x2*y*y; + return y*v; } #endif /*OPENMM_VECTORIZE_PNACL_H_*/ -- GitLab From 4662beda0f833082d080943a26e968f770e15260 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 27 Feb 2015 11:43:36 -0800 Subject: [PATCH 291/338] Updated version number to 6.3 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 05a9b9f37..5102c6dc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,10 +164,10 @@ ENDIF (NOT CMAKE_CXX_FLAGS_RELEASE) SET(OPENMM_LIBRARY_NAME OpenMM) SET(OPENMM_MAJOR_VERSION 6) -SET(OPENMM_MINOR_VERSION 2) +SET(OPENMM_MINOR_VERSION 3) SET(OPENMM_BUILD_VERSION 0) -SET(OPENMM_COPYRIGHT_YEARS "2008-2014") +SET(OPENMM_COPYRIGHT_YEARS "2008-2015") # underbar separated list of dotted authors, no spaces or commas SET(OPENMM_AUTHORS "Peter.Eastman") -- GitLab From 8bcc9b3d39a116ce082f4aa85f241b4a6452ee02 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 27 Feb 2015 14:23:27 -0800 Subject: [PATCH 292/338] PdbStructure handles byte streams correctly in Python 3 --- wrappers/python/simtk/openmm/app/internal/pdbstructure.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py index 6e94306e7..ddf79bec1 100644 --- a/wrappers/python/simtk/openmm/app/internal/pdbstructure.py +++ b/wrappers/python/simtk/openmm/app/internal/pdbstructure.py @@ -150,6 +150,8 @@ class PdbStructure(object): self._reset_residue_numbers() # Read one line at a time for pdb_line in input_stream: + if not isinstance(pdb_line, str): + pdb_line = pdb_line.decode('utf-8') # Look for atoms if (pdb_line.find("ATOM ") == 0) or (pdb_line.find("HETATM") == 0): self._add_atom(Atom(pdb_line, self)) -- GitLab From 9fee45f98aeafba814f218ec1fa56f974a8e1c33 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 27 Feb 2015 14:32:36 -0800 Subject: [PATCH 293/338] Added test for binary PDB streams --- wrappers/python/tests/TestPdbFile.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wrappers/python/tests/TestPdbFile.py b/wrappers/python/tests/TestPdbFile.py index 5c9ad3a9d..63d8aa0a9 100644 --- a/wrappers/python/tests/TestPdbFile.py +++ b/wrappers/python/tests/TestPdbFile.py @@ -60,6 +60,12 @@ class TestPdbFile(unittest.TestCase): self.assertEqual(atom1.name, atom2.name) self.assertEqual(atom1.residue.name, atom2.residue.name) + def test_BinaryStream(self): + """Test reading a stream that was opened in binary mode.""" + pdb = PDBFile(open('systems/triclinic.pdb', 'rb')) + self.assertEqual(len(pdb.positions), 8) + + def assertVecAlmostEqual(self, p1, p2, tol=1e-7): unit = p1.unit p1 = p1.value_in_unit(unit) -- GitLab From 36cdbc8d34c3534c7a006f2a270fc7771742f529 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 3 Mar 2015 11:01:33 -0800 Subject: [PATCH 294/338] Fixed exception in addExtraParticles() --- wrappers/python/simtk/openmm/app/modeller.py | 2 +- wrappers/python/tests/TestModeller.py | 21 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/modeller.py b/wrappers/python/simtk/openmm/app/modeller.py index fff6c81e2..b59157233 100644 --- a/wrappers/python/simtk/openmm/app/modeller.py +++ b/wrappers/python/simtk/openmm/app/modeller.py @@ -924,7 +924,7 @@ class Modeller(object): # extra points. template = None - residueNoEP = Residue(residue.name, residue.index, residue.chain) + residueNoEP = Residue(residue.name, residue.index, residue.chain, residue.id) residueNoEP._atoms = [atom for atom in residue.atoms() if atom.element is not None] if signature in forcefield._templateSignatures: for t in forcefield._templateSignatures[signature]: diff --git a/wrappers/python/tests/TestModeller.py b/wrappers/python/tests/TestModeller.py index 2a256dcfa..def41c64e 100644 --- a/wrappers/python/tests/TestModeller.py +++ b/wrappers/python/tests/TestModeller.py @@ -886,6 +886,27 @@ class TestModeller(unittest.TestCase): validate_equivalence(self, topology_LYN, topology_after) + + def test_addExtraParticles(self): + """Test addExtraParticles().""" + + # Create a box of water. + + ff1 = ForceField('tip3p.xml') + modeller = Modeller(Topology(), []*nanometers) + modeller.addSolvent(ff1, 'tip3p', boxSize=Vec3(2,2,2)*nanometers) + + # Now convert the water to TIP4P. + + ff2 = ForceField('tip4pew.xml') + modeller.addExtraParticles(ff2) + for residue in modeller.topology.residues(): + atoms = list(residue.atoms()) + self.assertEqual(4, len(atoms)) + ep = [atom for atom in atoms if atom.element is None] + self.assertEqual(1, len(ep)) + + def assertVecAlmostEqual(self, p1, p2, tol=1e-7): scale = max(1.0, norm(p1),) for i in range(3): -- GitLab From 6dc44c0eae850801f89cbec1e78108091ef5fe5c Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 3 Mar 2015 16:21:06 -0800 Subject: [PATCH 295/338] Added keepIds flag to PDBFile.writeFile() --- wrappers/python/simtk/openmm/app/pdbfile.py | 28 +++++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/pdbfile.py b/wrappers/python/simtk/openmm/app/pdbfile.py index 4c449be5b..79074298e 100644 --- a/wrappers/python/simtk/openmm/app/pdbfile.py +++ b/wrappers/python/simtk/openmm/app/pdbfile.py @@ -229,16 +229,19 @@ class PDBFile(object): map[atom.attrib[id]] = name @staticmethod - def writeFile(topology, positions, file=sys.stdout, modelIndex=None): + def writeFile(topology, positions, file=sys.stdout, keepIds=False): """Write a PDB file containing a single model. Parameters: - topology (Topology) The Topology defining the model to write - positions (list) The list of atomic positions to write - file (file=stdout) A file to write to + - keepIds (bool=False) If True, keep the residue and chain IDs specified in the Topology rather than generating + new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of + the PDB format. Otherwise, the output file will be invalid. """ PDBFile.writeHeader(topology, file) - PDBFile.writeModel(topology, positions, file) + PDBFile.writeModel(topology, positions, file, keepIds=keepIds) PDBFile.writeFooter(topology, file) @staticmethod @@ -262,7 +265,7 @@ class PDBFile(object): print >>file, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P 1 1 " % (a_length, b_length, c_length, alpha, beta, gamma) @staticmethod - def writeModel(topology, positions, file=sys.stdout, modelIndex=None): + def writeModel(topology, positions, file=sys.stdout, modelIndex=None, keepIds=False): """Write out a model to a PDB file. Parameters: @@ -270,6 +273,9 @@ class PDBFile(object): - positions (list) The list of atomic positions to write - file (file=stdout) A file to write the model to - modelIndex (int=None) If not None, the model will be surrounded by MODEL/ENDMDL records with this index + - keepIds (bool=False) If True, keep the residue and chain IDs specified in the Topology rather than generating + new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of + the PDB format. Otherwise, the output file will be invalid. """ if len(list(topology.atoms())) != len(positions): raise ValueError('The number of positions must match the number of atoms') @@ -284,13 +290,20 @@ class PDBFile(object): if modelIndex is not None: print >>file, "MODEL %4d" % modelIndex for (chainIndex, chain) in enumerate(topology.chains()): - chainName = chr(ord('A')+chainIndex%26) + if keepIds: + chainName = chain.id + else: + chainName = chr(ord('A')+chainIndex%26) residues = list(chain.residues()) for (resIndex, res) in enumerate(residues): if len(res.name) > 3: resName = res.name[:3] else: resName = res.name + if keepIds: + resId = res.id + else: + resId = "%4d" % ((resIndex+1)%10000) for atom in res.atoms(): if len(atom.name) < 4 and atom.name[:1].isalpha() and (atom.element is None or len(atom.element.symbol) < 2): atomName = ' '+atom.name @@ -303,16 +316,15 @@ class PDBFile(object): symbol = atom.element.symbol else: symbol = ' ' - line = "ATOM %5d %-4s %3s %s%4d %s%s%s 1.00 0.00 %2s " % ( - atomIndex%100000, atomName, resName, chainName, - (resIndex+1)%10000, _format_83(coords[0]), + line = "ATOM %5d %-4s %3s %s%4s %s%s%s 1.00 0.00 %2s " % ( + atomIndex%100000, atomName, resName, chainName, resId, _format_83(coords[0]), _format_83(coords[1]), _format_83(coords[2]), symbol) assert len(line) == 80, 'Fixed width overflow detected' print >>file, line posIndex += 1 atomIndex += 1 if resIndex == len(residues)-1: - print >>file, "TER %5d %3s %s%4d" % (atomIndex, resName, chainName, resIndex+1) + print >>file, "TER %5d %3s %s%4s" % (atomIndex, resName, chainName, resId) atomIndex += 1 if modelIndex is not None: print >>file, "ENDMDL" -- GitLab From e5ffa90545643887fb8cdc705ff44a9b8bb0b0d4 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 26 Feb 2015 12:04:24 -0500 Subject: [PATCH 296/338] Have the CHARMM parsers use the Topology API additions. --- wrappers/python/simtk/openmm/app/charmmpsffile.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/charmmpsffile.py b/wrappers/python/simtk/openmm/app/charmmpsffile.py index fa45470ac..32f6636bd 100644 --- a/wrappers/python/simtk/openmm/app/charmmpsffile.py +++ b/wrappers/python/simtk/openmm/app/charmmpsffile.py @@ -777,11 +777,12 @@ class CharmmPsfFile(object): # Add each chain (separate 'system's) and residue for atom in self.atom_list: if atom.system != last_chain: - chain = topology.addChain() + chain = topology.addChain(atom.system) last_chain = atom.system if atom.residue.idx != last_residue: last_residue = atom.residue.idx - residue = topology.addResidue(atom.residue.resname, chain) + residue = topology.addResidue(atom.residue.resname, chain, + str(atom.residue.idx)) if atom.type is not None: # This is the most reliable way of determining the element atomic_num = atom.type.atomic_number -- GitLab From 84bc63a1137ec25cfde65a98f7ae72fb6355d85c Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 5 Mar 2015 10:08:56 -0500 Subject: [PATCH 297/338] prmtop files can have %COMMENT sections in them between the %FLAG and %FORMAT flags. This can cause a KeyError when trying to look up the format of the current section when it's reading the %COMMENT line (before any Format has been assigned). --- wrappers/python/simtk/openmm/app/internal/amber_file_parser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 16459f131..6a8145ccd 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -135,6 +135,8 @@ class PrmtopLoader(object): format = format[index0+1:index1] m = FORMAT_RE_PATTERN.search(format) self._raw_format[self._flags[-1]] = (format, m.group(1), m.group(2), m.group(3), m.group(4)) + elif line.startswith('%COMMENT'): + continue elif self._flags \ and 'TITLE'==self._flags[-1] \ and not self._raw_data['TITLE']: -- GitLab From 0a0e3ba360c67b2ca181b33b9f3a0536171b351e Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 5 Mar 2015 10:37:14 -0500 Subject: [PATCH 298/338] Add a %COMMENT to this prmtop file to test that it's parsed correctly. --- wrappers/python/tests/systems/Mg_water.prmtop | 1 + 1 file changed, 1 insertion(+) diff --git a/wrappers/python/tests/systems/Mg_water.prmtop b/wrappers/python/tests/systems/Mg_water.prmtop index c7cd98962..41b6b7e46 100644 --- a/wrappers/python/tests/systems/Mg_water.prmtop +++ b/wrappers/python/tests/systems/Mg_water.prmtop @@ -1802,6 +1802,7 @@ WAT WAT 2.54487941E+01 1.27063907E+02 5.94825035E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 %FLAG LENNARD_JONES_CCOEF +%COMMENT This is the r^-4 term in the 12-6-4 LJ potential %FORMAT(5E16.8) 0.00000000E+00 1.32908847E+02 0000000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 -- GitLab From 62f7c44c1d2352fbc5dc550ac3578a8dd8bfade2 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 6 Mar 2015 10:14:09 -0800 Subject: [PATCH 299/338] Load balancing between GPUs forces the neighbor list to be rebuilt --- .../cuda/include/CudaNonbondedUtilities.h | 2 +- platforms/cuda/src/CudaNonbondedUtilities.cpp | 7 ++-- .../cuda/src/kernels/findInteractingBlocks.cu | 4 +-- .../opencl/src/OpenCLNonbondedUtilities.cpp | 3 ++ .../opencl/src/OpenCLParallelKernels.cpp | 36 ++++++++++--------- .../src/kernels/findInteractingBlocks.cl | 4 +-- 6 files changed, 32 insertions(+), 24 deletions(-) diff --git a/platforms/cuda/include/CudaNonbondedUtilities.h b/platforms/cuda/include/CudaNonbondedUtilities.h index d8d5e9038..8597f9a36 100644 --- a/platforms/cuda/include/CudaNonbondedUtilities.h +++ b/platforms/cuda/include/CudaNonbondedUtilities.h @@ -278,7 +278,7 @@ private: std::string kernelSource; std::map kernelDefines; double cutoff; - bool useCutoff, usePeriodic, anyExclusions, usePadding; + bool useCutoff, usePeriodic, anyExclusions, usePadding, forceRebuildNeighborList; int startTileIndex, numTiles, startBlockIndex, numBlocks, maxTiles, numForceThreadBlocks, forceThreadBlockSize, nonbondedForceGroup, numAtoms; }; diff --git a/platforms/cuda/src/CudaNonbondedUtilities.cpp b/platforms/cuda/src/CudaNonbondedUtilities.cpp index 9a5e3f805..244cddc98 100644 --- a/platforms/cuda/src/CudaNonbondedUtilities.cpp +++ b/platforms/cuda/src/CudaNonbondedUtilities.cpp @@ -65,7 +65,7 @@ private: CudaNonbondedUtilities::CudaNonbondedUtilities(CudaContext& context) : context(context), cutoff(-1.0), useCutoff(false), anyExclusions(false), usePadding(true), exclusionIndices(NULL), exclusionRowIndices(NULL), exclusionTiles(NULL), exclusions(NULL), interactingTiles(NULL), interactingAtoms(NULL), interactionCount(NULL), blockCenter(NULL), blockBoundingBox(NULL), sortedBlocks(NULL), sortedBlockCenter(NULL), sortedBlockBoundingBox(NULL), - oldPositions(NULL), rebuildNeighborList(NULL), blockSorter(NULL), nonbondedForceGroup(0) { + oldPositions(NULL), rebuildNeighborList(NULL), blockSorter(NULL), nonbondedForceGroup(0), forceRebuildNeighborList(true) { // Decide how many thread blocks to use. string errorMessage = "Error initializing nonbonded utilities"; @@ -322,6 +322,7 @@ void CudaNonbondedUtilities::initialize(const System& system) { sortBoxDataArgs.push_back(&oldPositions->getDevicePointer()); sortBoxDataArgs.push_back(&interactionCount->getDevicePointer()); sortBoxDataArgs.push_back(&rebuildNeighborList->getDevicePointer()); + sortBoxDataArgs.push_back(&forceRebuildNeighborList); findInteractingBlocksKernel = context.getKernel(interactingBlocksProgram, "findBlocksWithInteractions"); findInteractingBlocksArgs.push_back(context.getPeriodicBoxSizePointer()); findInteractingBlocksArgs.push_back(context.getInvPeriodicBoxSizePointer()); @@ -363,6 +364,7 @@ void CudaNonbondedUtilities::prepareInteractions() { blockSorter->sort(*sortedBlocks); context.executeKernel(sortBoxDataKernel, &sortBoxDataArgs[0], context.getNumAtoms()); context.executeKernel(findInteractingBlocksKernel, &findInteractingBlocksArgs[0], context.getNumAtoms(), 256); + forceRebuildNeighborList = false; } void CudaNonbondedUtilities::computeInteractions() { @@ -419,8 +421,9 @@ void CudaNonbondedUtilities::setAtomBlockRange(double startFraction, double endF startBlockIndex = (int) (startFraction*numAtomBlocks); numBlocks = (int) (endFraction*numAtomBlocks)-startBlockIndex; int totalTiles = context.getNumAtomBlocks()*(context.getNumAtomBlocks()+1)/2; - startTileIndex = (int) (startFraction*totalTiles);; + startTileIndex = (int) (startFraction*totalTiles); numTiles = (int) (endFraction*totalTiles)-startTileIndex; + forceRebuildNeighborList = true; } CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source, vector& params, vector& arguments, bool useExclusions, bool isSymmetric) { diff --git a/platforms/cuda/src/kernels/findInteractingBlocks.cu b/platforms/cuda/src/kernels/findInteractingBlocks.cu index 34822f0c8..93228e448 100644 --- a/platforms/cuda/src/kernels/findInteractingBlocks.cu +++ b/platforms/cuda/src/kernels/findInteractingBlocks.cu @@ -43,7 +43,7 @@ extern "C" __global__ void findBlockBounds(int numAtoms, real4 periodicBoxSize, extern "C" __global__ void sortBoxData(const real2* __restrict__ sortedBlock, const real4* __restrict__ blockCenter, const real4* __restrict__ blockBoundingBox, real4* __restrict__ sortedBlockCenter, real4* __restrict__ sortedBlockBoundingBox, const real4* __restrict__ posq, const real4* __restrict__ oldPositions, - unsigned int* __restrict__ interactionCount, int* __restrict__ rebuildNeighborList) { + unsigned int* __restrict__ interactionCount, int* __restrict__ rebuildNeighborList, bool forceRebuild) { for (int i = threadIdx.x+blockIdx.x*blockDim.x; i < NUM_BLOCKS; i += blockDim.x*gridDim.x) { int index = (int) sortedBlock[i].y; sortedBlockCenter[i] = blockCenter[index]; @@ -52,7 +52,7 @@ extern "C" __global__ void sortBoxData(const real2* __restrict__ sortedBlock, co // Also check whether any atom has moved enough so that we really need to rebuild the neighbor list. - bool rebuild = false; + bool rebuild = forceRebuild; for (int i = threadIdx.x+blockIdx.x*blockDim.x; i < NUM_ATOMS; i += blockDim.x*gridDim.x) { real4 delta = oldPositions[i]-posq[i]; if (delta.x*delta.x + delta.y*delta.y + delta.z*delta.z > 0.25f*PADDING*PADDING) diff --git a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp index 643298cc2..23886045a 100644 --- a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp +++ b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp @@ -340,6 +340,7 @@ void OpenCLNonbondedUtilities::initialize(const System& system) { sortBoxDataKernel.setArg(6, oldPositions->getDeviceBuffer()); sortBoxDataKernel.setArg(7, interactionCount->getDeviceBuffer()); sortBoxDataKernel.setArg(8, rebuildNeighborList->getDeviceBuffer()); + sortBoxDataKernel.setArg(9, true); findInteractingBlocksKernel = cl::Kernel(interactingBlocksProgram, "findBlocksWithInteractions"); findInteractingBlocksKernel.setArg(5, interactionCount->getDeviceBuffer()); findInteractingBlocksKernel.setArg(6, interactingTiles->getDeviceBuffer()); @@ -406,6 +407,7 @@ void OpenCLNonbondedUtilities::prepareInteractions() { context.executeKernel(sortBoxDataKernel, context.getNumAtoms()); setPeriodicBoxArgs(context, findInteractingBlocksKernel, 0); context.executeKernel(findInteractingBlocksKernel, context.getNumAtoms(), interactingBlocksThreadBlockSize); + sortBoxDataKernel.setArg(9, false); } void OpenCLNonbondedUtilities::computeInteractions() { @@ -474,6 +476,7 @@ void OpenCLNonbondedUtilities::setAtomBlockRange(double startFraction, double en forceKernel.setArg(6, numTiles); findInteractingBlocksKernel.setArg(10, startBlockIndex); findInteractingBlocksKernel.setArg(11, numBlocks); + sortBoxDataKernel.setArg(9, true); } } diff --git a/platforms/opencl/src/OpenCLParallelKernels.cpp b/platforms/opencl/src/OpenCLParallelKernels.cpp index 0e03ca5cb..473400af2 100644 --- a/platforms/opencl/src/OpenCLParallelKernels.cpp +++ b/platforms/opencl/src/OpenCLParallelKernels.cpp @@ -177,23 +177,25 @@ double OpenCLParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& c // Balance work between the contexts by transferring a little nonbonded work from the context that // finished last to the one that finished first. - int firstIndex = 0, lastIndex = 0; - for (int i = 0; i < (int) completionTimes.size(); i++) { - if (completionTimes[i] < completionTimes[firstIndex]) - firstIndex = i; - if (completionTimes[i] > completionTimes[lastIndex]) - lastIndex = i; - } - double fractionToTransfer = min(0.001, contextNonbondedFractions[lastIndex]); - contextNonbondedFractions[firstIndex] += fractionToTransfer; - contextNonbondedFractions[lastIndex] -= fractionToTransfer; - double startFraction = 0.0; - for (int i = 0; i < (int) contextNonbondedFractions.size(); i++) { - double endFraction = startFraction+contextNonbondedFractions[i]; - if (i == contextNonbondedFractions.size()-1) - endFraction = 1.0; // Avoid roundoff error - data.contexts[i]->getNonbondedUtilities().setAtomBlockRange(startFraction, endFraction); - startFraction = endFraction; + if (cl.getComputeForceCount() < 200) { + int firstIndex = 0, lastIndex = 0; + for (int i = 0; i < (int) completionTimes.size(); i++) { + if (completionTimes[i] < completionTimes[firstIndex]) + firstIndex = i; + if (completionTimes[i] > completionTimes[lastIndex]) + lastIndex = i; + } + double fractionToTransfer = min(0.001, contextNonbondedFractions[lastIndex]); + contextNonbondedFractions[firstIndex] += fractionToTransfer; + contextNonbondedFractions[lastIndex] -= fractionToTransfer; + double startFraction = 0.0; + for (int i = 0; i < (int) contextNonbondedFractions.size(); i++) { + double endFraction = startFraction+contextNonbondedFractions[i]; + if (i == contextNonbondedFractions.size()-1) + endFraction = 1.0; // Avoid roundoff error + data.contexts[i]->getNonbondedUtilities().setAtomBlockRange(startFraction, endFraction); + startFraction = endFraction; + } } } return energy; diff --git a/platforms/opencl/src/kernels/findInteractingBlocks.cl b/platforms/opencl/src/kernels/findInteractingBlocks.cl index 044db4d2f..bb56c1e74 100644 --- a/platforms/opencl/src/kernels/findInteractingBlocks.cl +++ b/platforms/opencl/src/kernels/findInteractingBlocks.cl @@ -44,7 +44,7 @@ __kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeri __kernel void sortBoxData(__global const real2* restrict sortedBlock, __global const real4* restrict blockCenter, __global const real4* restrict blockBoundingBox, __global real4* restrict sortedBlockCenter, __global real4* restrict sortedBlockBoundingBox, __global const real4* restrict posq, __global const real4* restrict oldPositions, - __global unsigned int* restrict interactionCount, __global int* restrict rebuildNeighborList) { + __global unsigned int* restrict interactionCount, __global int* restrict rebuildNeighborList, int forceRebuild) { for (int i = get_global_id(0); i < NUM_BLOCKS; i += get_global_size(0)) { int index = (int) sortedBlock[i].y; sortedBlockCenter[i] = blockCenter[index]; @@ -53,7 +53,7 @@ __kernel void sortBoxData(__global const real2* restrict sortedBlock, __global c // Also check whether any atom has moved enough so that we really need to rebuild the neighbor list. - bool rebuild = false; + bool rebuild = forceRebuild; for (int i = get_global_id(0); i < NUM_ATOMS; i += get_global_size(0)) { real4 delta = oldPositions[i]-posq[i]; if (delta.x*delta.x + delta.y*delta.y + delta.z*delta.z > 0.25f*PADDING*PADDING) -- GitLab From bd666c270a642f4e80ac6f0cc42742ccb925e725 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 6 Mar 2015 12:25:47 -0800 Subject: [PATCH 300/338] For multi-GPU, exceeding the size of the neighbor list causes the forces to be marked as invalid --- olla/include/openmm/kernels.h | 4 ++- openmmapi/src/ContextImpl.cpp | 16 +++++---- platforms/cpu/include/CpuKernels.h | 4 ++- platforms/cpu/src/CpuKernels.cpp | 4 +-- platforms/cuda/include/CudaKernels.h | 4 ++- platforms/cuda/include/CudaParallelKernels.h | 5 ++- platforms/cuda/src/CudaKernels.cpp | 2 +- platforms/cuda/src/CudaNonbondedUtilities.cpp | 2 +- platforms/cuda/src/CudaParallelKernels.cpp | 36 ++++++++++++------- platforms/opencl/include/OpenCLKernels.h | 4 ++- .../opencl/include/OpenCLParallelKernels.h | 5 ++- platforms/opencl/src/OpenCLKernels.cpp | 2 +- .../opencl/src/OpenCLNonbondedUtilities.cpp | 2 +- .../opencl/src/OpenCLParallelKernels.cpp | 33 +++++++++++------ .../reference/include/ReferenceKernels.h | 4 ++- platforms/reference/src/ReferenceKernels.cpp | 2 +- 16 files changed, 85 insertions(+), 44 deletions(-) diff --git a/olla/include/openmm/kernels.h b/olla/include/openmm/kernels.h index 62b2f0dda..f7cd2773e 100644 --- a/olla/include/openmm/kernels.h +++ b/olla/include/openmm/kernels.h @@ -103,11 +103,13 @@ public: * @param includeForce true if forces should be computed * @param includeEnergy true if potential energy should be computed * @param groups a set of bit flags for which force groups to include + * @param valid the method may set this to false to indicate the results are invalid and the force/energy + * calculation should be repeated * @return the potential energy of the system. This value is added to all values returned by ForceImpls' * calcForcesAndEnergy() methods. That is, each force kernel may either return its contribution to the * energy directly, or add it to an internal buffer so that it will be included here. */ - virtual double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) = 0; + virtual double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid) = 0; }; /** diff --git a/openmmapi/src/ContextImpl.cpp b/openmmapi/src/ContextImpl.cpp index dfc98328e..f300fe82b 100644 --- a/openmmapi/src/ContextImpl.cpp +++ b/openmmapi/src/ContextImpl.cpp @@ -260,12 +260,16 @@ double ContextImpl::calcForcesAndEnergy(bool includeForces, bool includeEnergy, throw OpenMMException("Particle positions have not been set"); lastForceGroups = groups; CalcForcesAndEnergyKernel& kernel = initializeForcesKernel.getAs(); - double energy = 0.0; - kernel.beginComputation(*this, includeForces, includeEnergy, groups); - for (int i = 0; i < (int) forceImpls.size(); ++i) - energy += forceImpls[i]->calcForcesAndEnergy(*this, includeForces, includeEnergy, groups); - energy += kernel.finishComputation(*this, includeForces, includeEnergy, groups); - return energy; + while (true) { + double energy = 0.0; + kernel.beginComputation(*this, includeForces, includeEnergy, groups); + for (int i = 0; i < (int) forceImpls.size(); ++i) + energy += forceImpls[i]->calcForcesAndEnergy(*this, includeForces, includeEnergy, groups); + bool valid = true; + energy += kernel.finishComputation(*this, includeForces, includeEnergy, groups, valid); + if (valid) + return energy; + } } int ContextImpl::getLastForceGroups() const { diff --git a/platforms/cpu/include/CpuKernels.h b/platforms/cpu/include/CpuKernels.h index ef5356961..36106da1e 100644 --- a/platforms/cpu/include/CpuKernels.h +++ b/platforms/cpu/include/CpuKernels.h @@ -80,11 +80,13 @@ public: * @param includeForce true if forces should be computed * @param includeEnergy true if potential energy should be computed * @param groups a set of bit flags for which force groups to include + * @param valid the method may set this to false to indicate the results are invalid and the force/energy + * calculation should be repeated * @return the potential energy of the system. This value is added to all values returned by ForceImpls' * calcForcesAndEnergy() methods. That is, each force kernel may either return its contribution to the * energy directly, or add it to an internal buffer so that it will be included here. */ - double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups); + double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid); private: CpuPlatform::PlatformData& data; Kernel referenceKernel; diff --git a/platforms/cpu/src/CpuKernels.cpp b/platforms/cpu/src/CpuKernels.cpp index 41397c923..a8bd8f973 100644 --- a/platforms/cpu/src/CpuKernels.cpp +++ b/platforms/cpu/src/CpuKernels.cpp @@ -231,13 +231,13 @@ void CpuCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool i throw OpenMMException("Particle coordinate is nan"); } -double CpuCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { +double CpuCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid) { // Sum the forces from all the threads. SumForceTask task(context.getSystem().getNumParticles(), extractForces(context), data); data.threads.execute(task); data.threads.waitForThreads(); - return referenceKernel.getAs().finishComputation(context, includeForce, includeEnergy, groups); + return referenceKernel.getAs().finishComputation(context, includeForce, includeEnergy, groups, valid); } CpuCalcPeriodicTorsionForceKernel::~CpuCalcPeriodicTorsionForceKernel() { diff --git a/platforms/cuda/include/CudaKernels.h b/platforms/cuda/include/CudaKernels.h index 4650ae9ff..2d97a82a6 100644 --- a/platforms/cuda/include/CudaKernels.h +++ b/platforms/cuda/include/CudaKernels.h @@ -92,11 +92,13 @@ public: * @param includeForce true if forces should be computed * @param includeEnergy true if potential energy should be computed * @param groups a set of bit flags for which force groups to include + * @param valid the method may set this to false to indicate the results are invalid and the force/energy + * calculation should be repeated * @return the potential energy of the system. This value is added to all values returned by ForceImpls' * calcForcesAndEnergy() methods. That is, each force kernel may either return its contribution to the * energy directly, or add it to an internal buffer so that it will be included here. */ - double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups); + double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid); private: CudaContext& cu; }; diff --git a/platforms/cuda/include/CudaParallelKernels.h b/platforms/cuda/include/CudaParallelKernels.h index 94fe2a7eb..e43299a8a 100644 --- a/platforms/cuda/include/CudaParallelKernels.h +++ b/platforms/cuda/include/CudaParallelKernels.h @@ -69,11 +69,13 @@ public: * @param includeForce true if forces should be computed * @param includeEnergy true if potential energy should be computed * @param groups a set of bit flags for which force groups to include + * @param valid the method may set this to false to indicate the results are invalid and the force/energy + * calculation should be repeated * @return the potential energy of the system. This value is added to all values returned by ForceImpls' * calcForcesAndEnergy() methods. That is, each force kernel may either return its contribution to the * energy directly, or add it to an internal buffer so that it will be included here. */ - double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups); + double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid); private: class BeginComputationTask; class FinishComputationTask; @@ -81,6 +83,7 @@ private: std::vector kernels; std::vector completionTimes; std::vector contextNonbondedFractions; + std::vector tileCounts; CudaArray* contextForces; void* pinnedPositionBuffer; long long* pinnedForceBuffer; diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index f9d71aa5b..9dab83c75 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -104,7 +104,7 @@ void CudaCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool nb.prepareInteractions(); } -double CudaCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) { +double CudaCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForces, bool includeEnergy, int groups, bool& valid) { cu.getBondedUtilities().computeInteractions(groups); if ((groups&(1< -double CudaParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { +double CudaParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid) { for (int i = 0; i < (int) data.contexts.size(); i++) { CudaContext& cu = *data.contexts[i]; CudaContext::WorkThread& thread = cu.getWorkThread(); - thread.addTask(new FinishComputationTask(context, cu, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceBuffer, *contextForces)); + thread.addTask(new FinishComputationTask(context, cu, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceBuffer, *contextForces, valid)); } data.syncContexts(); + if (data.contexts[0]->getNonbondedUtilities().getUsePeriodic()) { + for (int i = 0; i < (int) tileCounts.size(); i++) + if (tileCounts[i] > data.contexts[i]->getNonbondedUtilities().getInteractingTiles().getSize()) { + valid = false; + data.contexts[i]->getNonbondedUtilities().updateNeighborListSize(); + } + } double energy = 0.0; for (int i = 0; i < (int) data.contextEnergy.size(); i++) energy += data.contextEnergy[i]; - if (includeForce) { + if (includeForce && valid) { // Sum the forces from all devices. CudaContext& cu = *data.contexts[0]; diff --git a/platforms/opencl/include/OpenCLKernels.h b/platforms/opencl/include/OpenCLKernels.h index d62647150..5331c9188 100644 --- a/platforms/opencl/include/OpenCLKernels.h +++ b/platforms/opencl/include/OpenCLKernels.h @@ -71,11 +71,13 @@ public: * @param includeForce true if forces should be computed * @param includeEnergy true if potential energy should be computed * @param groups a set of bit flags for which force groups to include + * @param valid the method may set this to false to indicate the results are invalid and the force/energy + * calculation should be repeated * @return the potential energy of the system. This value is added to all values returned by ForceImpls' * calcForcesAndEnergy() methods. That is, each force kernel may either return its contribution to the * energy directly, or add it to an internal buffer so that it will be included here. */ - double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups); + double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid); private: OpenCLContext& cl; }; diff --git a/platforms/opencl/include/OpenCLParallelKernels.h b/platforms/opencl/include/OpenCLParallelKernels.h index dd4d5fe82..e626ec3f0 100644 --- a/platforms/opencl/include/OpenCLParallelKernels.h +++ b/platforms/opencl/include/OpenCLParallelKernels.h @@ -69,11 +69,13 @@ public: * @param includeForce true if forces should be computed * @param includeEnergy true if potential energy should be computed * @param groups a set of bit flags for which force groups to include + * @param valid the method may set this to false to indicate the results are invalid and the force/energy + * calculation should be repeated * @return the potential energy of the system. This value is added to all values returned by ForceImpls' * calcForcesAndEnergy() methods. That is, each force kernel may either return its contribution to the * energy directly, or add it to an internal buffer so that it will be included here. */ - double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups); + double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid); private: class BeginComputationTask; class FinishComputationTask; @@ -81,6 +83,7 @@ private: std::vector kernels; std::vector completionTimes; std::vector contextNonbondedFractions; + std::vector tileCounts; OpenCLArray* contextForces; cl::Buffer* pinnedPositionBuffer; cl::Buffer* pinnedForceBuffer; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 4a7eb329e..13cde63b3 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -127,7 +127,7 @@ void OpenCLCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, boo nb.prepareInteractions(); } -double OpenCLCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) { +double OpenCLCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForces, bool includeEnergy, int groups, bool& valid) { cl.getBondedUtilities().computeInteractions(groups); if ((groups&(1< 0) cl.getQueue().enqueueWriteBuffer(cl.getPosq().getDeviceBuffer(), CL_FALSE, 0, cl.getPaddedNumAtoms()*cl.getPosq().getElementSize(), pinnedMemory); kernel.beginComputation(context, includeForce, includeEnergy, groups); + if (cl.getNonbondedUtilities().getUsePeriodic()) + cl.getNonbondedUtilities().getInteractionCount().download(&numTiles, false); } private: ContextImpl& context; @@ -71,19 +73,20 @@ private: bool includeForce, includeEnergy; int groups; void* pinnedMemory; + int& numTiles; }; class OpenCLParallelCalcForcesAndEnergyKernel::FinishComputationTask : public OpenCLContext::WorkTask { public: FinishComputationTask(ContextImpl& context, OpenCLContext& cl, OpenCLCalcForcesAndEnergyKernel& kernel, - bool includeForce, bool includeEnergy, int groups, double& energy, long long& completionTime, void* pinnedMemory) : + bool includeForce, bool includeEnergy, int groups, double& energy, long long& completionTime, void* pinnedMemory, bool& valid) : context(context), cl(cl), kernel(kernel), includeForce(includeForce), includeEnergy(includeEnergy), groups(groups), energy(energy), - completionTime(completionTime), pinnedMemory(pinnedMemory) { + completionTime(completionTime), pinnedMemory(pinnedMemory), valid(valid) { } void execute() { // Execute the kernel, then download forces. - energy += kernel.finishComputation(context, includeForce, includeEnergy, groups); + energy += kernel.finishComputation(context, includeForce, includeEnergy, groups, valid); if (includeForce) { if (cl.getContextIndex() > 0) { int numAtoms = cl.getPaddedNumAtoms(); @@ -105,11 +108,12 @@ private: double& energy; long long& completionTime; void* pinnedMemory; + bool& valid; }; OpenCLParallelCalcForcesAndEnergyKernel::OpenCLParallelCalcForcesAndEnergyKernel(string name, const Platform& platform, OpenCLPlatform::PlatformData& data) : - CalcForcesAndEnergyKernel(name, platform), data(data), completionTimes(data.contexts.size()), contextNonbondedFractions(data.contexts.size()), contextForces(NULL), - pinnedPositionBuffer(NULL), pinnedPositionMemory(NULL), pinnedForceBuffer(NULL), pinnedForceMemory(NULL) { + CalcForcesAndEnergyKernel(name, platform), data(data), completionTimes(data.contexts.size()), contextNonbondedFractions(data.contexts.size()), + tileCounts(data.contexts.size()), contextForces(NULL), pinnedPositionBuffer(NULL), pinnedPositionMemory(NULL), pinnedForceBuffer(NULL), pinnedForceMemory(NULL) { for (int i = 0; i < (int) data.contexts.size(); i++) kernels.push_back(Kernel(new OpenCLCalcForcesAndEnergyKernel(name, platform, *data.contexts[i]))); } @@ -150,21 +154,28 @@ void OpenCLParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& cont data.contextEnergy[i] = 0.0; OpenCLContext& cl = *data.contexts[i]; OpenCLContext::WorkThread& thread = cl.getWorkThread(); - thread.addTask(new BeginComputationTask(context, cl, getKernel(i), includeForce, includeEnergy, groups, pinnedPositionMemory)); + thread.addTask(new BeginComputationTask(context, cl, getKernel(i), includeForce, includeEnergy, groups, pinnedPositionMemory, tileCounts[i])); } } -double OpenCLParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { +double OpenCLParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid) { for (int i = 0; i < (int) data.contexts.size(); i++) { OpenCLContext& cl = *data.contexts[i]; OpenCLContext::WorkThread& thread = cl.getWorkThread(); - thread.addTask(new FinishComputationTask(context, cl, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceMemory)); + thread.addTask(new FinishComputationTask(context, cl, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceMemory, valid)); } data.syncContexts(); + if (data.contexts[0]->getNonbondedUtilities().getUsePeriodic()) { + for (int i = 0; i < (int) tileCounts.size(); i++) + if (tileCounts[i] > data.contexts[i]->getNonbondedUtilities().getInteractingTiles().getSize()) { + valid = false; + data.contexts[i]->getNonbondedUtilities().updateNeighborListSize(); + } + } double energy = 0.0; for (int i = 0; i < (int) data.contextEnergy.size(); i++) energy += data.contextEnergy[i]; - if (includeForce) { + if (includeForce && valid) { // Sum the forces from all devices. OpenCLContext& cl = *data.contexts[0]; diff --git a/platforms/reference/include/ReferenceKernels.h b/platforms/reference/include/ReferenceKernels.h index c380a9b85..8c047f86d 100644 --- a/platforms/reference/include/ReferenceKernels.h +++ b/platforms/reference/include/ReferenceKernels.h @@ -89,11 +89,13 @@ public: * @param includeForce true if forces should be computed * @param includeEnergy true if potential energy should be computed * @param groups a set of bit flags for which force groups to include + * @param valid the method may set this to false to indicate the results are invalid and the force/energy + * calculation should be repeated * @return the potential energy of the system. This value is added to all values returned by ForceImpls' * calcForcesAndEnergy() methods. That is, each force kernel may either return its contribution to the * energy directly, or add it to an internal buffer so that it will be included here. */ - double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups); + double finishComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups, bool& valid); private: std::vector savedForces; }; diff --git a/platforms/reference/src/ReferenceKernels.cpp b/platforms/reference/src/ReferenceKernels.cpp index c895833dc..834cfd104 100644 --- a/platforms/reference/src/ReferenceKernels.cpp +++ b/platforms/reference/src/ReferenceKernels.cpp @@ -197,7 +197,7 @@ void ReferenceCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, savedForces = forceData; } -double ReferenceCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) { +double ReferenceCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, bool includeForces, bool includeEnergy, int groups, bool& valid) { if (!includeForces) extractForces(context) = savedForces; // Restore the forces so computing the energy doesn't overwrite the forces with incorrect values. else -- GitLab From 84c9bcdbe7166f17b95a513a96a06d36840f51b9 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 6 Mar 2015 14:25:48 -0800 Subject: [PATCH 301/338] Cleanup and simplification to reference AMOEBA multipole force --- .../AmoebaReferenceMultipoleForce.cpp | 363 ++++-------------- .../AmoebaReferenceMultipoleForce.h | 42 -- 2 files changed, 81 insertions(+), 324 deletions(-) diff --git a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp index 4fc481e68..895c595c0 100644 --- a/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp +++ b/plugins/amoeba/platforms/reference/src/SimTKReference/AmoebaReferenceMultipoleForce.cpp @@ -95,8 +95,6 @@ void AmoebaReferenceMultipoleForce::initialize() _uScale[index++] = 1.0; _uScale[index++] = 1.0; _uScale[index++] = 1.0; - - return; } AmoebaReferenceMultipoleForce::NonbondedMethod AmoebaReferenceMultipoleForce::getNonbondedMethod() const @@ -288,7 +286,6 @@ void AmoebaReferenceMultipoleForce::copyRealVecVector(const vector& particlePositions, @@ -354,8 +351,6 @@ void AmoebaReferenceMultipoleForce::checkChiralCenterAtParticle(MultipoleParticl particleI.quadrupole[QXY] *= -1.0; // pole(6,i) && pole(8,i) particleI.quadrupole[QYZ] *= -1.0; // pole(10,i) && pole(12,i) } - return; - } void AmoebaReferenceMultipoleForce::checkChiral(vector& particleData, @@ -373,7 +368,6 @@ void AmoebaReferenceMultipoleForce::checkChiral(vector& p particleData[multipoleAtomYs[ii]]); } } - return; } void AmoebaReferenceMultipoleForce::applyRotationMatrixToParticle( MultipoleParticleData& particleI, @@ -497,9 +491,6 @@ void AmoebaReferenceMultipoleForce::applyRotationMatrixToParticle( Multipol particleI.quadrupole[QYY] = rPole[1][1]; particleI.quadrupole[QYZ] = rPole[1][2]; particleI.quadrupole[QZZ] = rPole[2][2]; - - return; - } void AmoebaReferenceMultipoleForce::applyRotationMatrix(vector& particleData, @@ -515,8 +506,6 @@ void AmoebaReferenceMultipoleForce::applyRotationMatrix(vector -1 ? &particleData[multipoleAtomYs[ii]] : NULL, axisTypes[ii]); } } - - return; } void AmoebaReferenceMultipoleForce::getAndScaleInverseRs(RealOpenMM dampI, RealOpenMM dampJ, @@ -551,7 +540,6 @@ void AmoebaReferenceMultipoleForce::getAndScaleInverseRs(RealOpenMM dampI, RealO } } } - return; } void AmoebaReferenceMultipoleForce::calculateFixedMultipoleFieldPairIxn(const MultipoleParticleData& particleI, @@ -559,7 +547,8 @@ void AmoebaReferenceMultipoleForce::calculateFixedMultipoleFieldPairIxn(const Mu RealOpenMM dScale, RealOpenMM pScale) { - if (particleI.particleIndex == particleJ.particleIndex)return; + if (particleI.particleIndex == particleJ.particleIndex) + return; RealVec deltaR = particleJ.position - particleI.position; RealOpenMM r = SQRT(deltaR.dot(deltaR)); @@ -605,8 +594,6 @@ void AmoebaReferenceMultipoleForce::calculateFixedMultipoleFieldPairIxn(const Mu particleIndex = particleJ.particleIndex; _fixedMultipoleField[particleIndex] += field*dScale; _fixedMultipoleFieldPolar[particleIndex] += field*pScale; - - return; } void AmoebaReferenceMultipoleForce::calculateFixedMultipoleField(const vector& particleData) @@ -632,7 +619,6 @@ void AmoebaReferenceMultipoleForce::calculateFixedMultipoleField(const vector& updateInducedDipoleFields) @@ -647,8 +633,6 @@ void AmoebaReferenceMultipoleForce::initializeInducedDipoles(vector& updateInducedDipoleFields) { - if (particleI.particleIndex == particleJ.particleIndex)return; + if (particleI.particleIndex == particleJ.particleIndex) + return; RealVec deltaR = particleJ.position - particleI.position; RealOpenMM r = SQRT(deltaR.dot(deltaR)); @@ -689,8 +672,6 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipolePairIxns(const Multipo calculateInducedDipolePairIxn(particleI.particleIndex, particleJ.particleIndex, rr3, rr5, deltaR, *updateInducedDipoleFields[ii].inducedDipoles, updateInducedDipoleFields[ii].inducedDipoleField); } - return; - } void AmoebaReferenceMultipoleForce::calculateInducedDipoleFields(const vector& particleData, vector& updateInducedDipoleFields) { @@ -705,7 +686,6 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipoleFields(const vector& particleData, @@ -777,8 +757,6 @@ void AmoebaReferenceMultipoleForce::convergeInduceDipolesBySOR(const vector& particleData, vector& updateInducedDipoleField) { @@ -921,8 +899,6 @@ void AmoebaReferenceMultipoleForce::calculateInducedDipoles(const vector& particleData, @@ -1523,7 +1496,6 @@ void AmoebaReferenceMultipoleForce::mapTorqueToForce(vector& particleData, @@ -1601,8 +1573,6 @@ void AmoebaReferenceMultipoleForce::setup(const vector& particlePositio message << " eps=" << getMutualInducedDipoleEpsilon(); throw OpenMMException(message.str()); } - - return; } RealOpenMM AmoebaReferenceMultipoleForce::calculateForceAndEnergy(const vector& particlePositions, @@ -1772,8 +1742,6 @@ void AmoebaReferenceMultipoleForce::calculateAmoebaSystemMultipoleMoments(const for (unsigned int ii = 4; ii < 13; ii++) { outputMultipoleMoments[ii] *= 100.0*debye; } - - return; } RealOpenMM AmoebaReferenceMultipoleForce::calculateElectrostaticPotentialForParticleGridPoint(const MultipoleParticleData& particleI, const RealVec& gridPoint) const @@ -1847,8 +1815,6 @@ void AmoebaReferenceMultipoleForce::calculateElectrostaticPotential(const vector for (unsigned int ii = 0; ii < grid.size(); ii++) { potential[ii] *= term; } - - return; } AmoebaReferenceMultipoleForce::UpdateInducedDipoleFieldStruct::UpdateInducedDipoleFieldStruct(vector& inputFixed_E_Field, vector& inputInducedDipoles) : @@ -2143,8 +2109,6 @@ void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateFixedMultipoleFi if (particleI.particleIndex != particleJ.particleIndex) { _gkField[particleJ.particleIndex] += fjd; } - - return; } void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateInducedDipolePairGkIxn(const MultipoleParticleData& particleI, @@ -2218,8 +2182,6 @@ void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateInducedDipolePai outputFields[jIndex][1] += _fd*duis.dot(guy); outputFields[jIndex][2] += _fd*duis.dot(guz); } - - return; } void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateInducedDipolePairIxns(const MultipoleParticleData& particleI, @@ -2234,8 +2196,6 @@ void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateInducedDipolePai for (unsigned int ii = 2; ii < updateInducedDipoleFields.size(); ii++) { calculateInducedDipolePairGkIxn(particleI, particleJ, *updateInducedDipoleFields[ii].inducedDipoles, updateInducedDipoleFields[ii].inducedDipoleField); } - - return; } void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateInducedDipoles(const vector& particleData) @@ -2282,8 +2242,6 @@ void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateInducedDipoles(c updateInducedDipoleField.push_back(UpdateInducedDipoleFieldStruct(gkFieldPolar, _inducedDipolePolarS)); convergeInduceDipolesByDIIS(particleData, updateInducedDipoleField); - - return; } RealOpenMM AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateKirkwoodPairIxn(const MultipoleParticleData& particleI, @@ -3816,8 +3774,6 @@ void AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateGrycukChainRuleP forces[iIndex] -= deltaR*de; forces[jIndex] += deltaR*de; - - return; } RealOpenMM AmoebaReferenceGeneralizedKirkwoodMultipoleForce::calculateCavityTermEnergyAndForces(vector& dBorn) const @@ -4556,8 +4512,6 @@ void AmoebaReferencePmeMultipoleForce::getPmeGridDimensions(vector& pmeGrid pmeGridDimensions[0] = _pmeGridDimensions[0]; pmeGridDimensions[1] = _pmeGridDimensions[1]; pmeGridDimensions[2] = _pmeGridDimensions[2]; - - return; }; void AmoebaReferencePmeMultipoleForce::setPmeGridDimensions(vector& pmeGridDimensions) @@ -4565,7 +4519,8 @@ void AmoebaReferencePmeMultipoleForce::setPmeGridDimensions(vector& pmeGrid if ((pmeGridDimensions[0] == _pmeGridDimensions[0]) && (pmeGridDimensions[1] == _pmeGridDimensions[1]) && - (pmeGridDimensions[2] == _pmeGridDimensions[2]))return; + (pmeGridDimensions[2] == _pmeGridDimensions[2])) + return; if (_fftplan) { fftpack_destroy(_fftplan); @@ -4626,21 +4581,16 @@ void AmoebaReferencePmeMultipoleForce::resizePmeArrays() _phid.resize(10*_numParticles); _phip.resize(10*_numParticles); _phidp.resize(20*_numParticles); - _pmeAtomRange.resize(_totalGridSize + 1); - _pmeAtomGridIndex.resize(_numParticles); - - return; } void AmoebaReferencePmeMultipoleForce::initializePmeGrid() { - if (_pmeGrid == NULL)return; - //memset(_pmeGrid, 0, sizeof(t_complex)*_totalGridSize); + if (_pmeGrid == NULL) + return; for (int jj = 0; jj < _totalGridSize; jj++) { _pmeGrid[jj].re = _pmeGrid[jj].im = 0.0; } - return; } void AmoebaReferencePmeMultipoleForce::getPeriodicDelta(RealVec& deltaR) const @@ -4692,8 +4642,6 @@ void AmoebaReferencePmeMultipoleForce::getDampedInverseDistances(const Multipole dampedPInverseDistances[1] = 3.0*(1.0-dampedPScale[1])/r5; dampedPInverseDistances[2] = 15.0*(1.0-dampedPScale[2])/r7; } - - return; } void AmoebaReferencePmeMultipoleForce::initializeBSplineModuli() @@ -4786,8 +4734,6 @@ void AmoebaReferencePmeMultipoleForce::initializeBSplineModuli() _pmeBsplineModuli[dim][i-1] = _pmeBsplineModuli[dim][i-1]*(zeta*zeta); } } - - return; } void AmoebaReferencePmeMultipoleForce::calculateFixedMultipoleFieldPairIxn(const MultipoleParticleData& particleI, @@ -4797,13 +4743,15 @@ void AmoebaReferencePmeMultipoleForce::calculateFixedMultipoleFieldPairIxn(const // compute the real space portion of the Ewald summation - if (particleI.particleIndex == particleJ.particleIndex)return; + if (particleI.particleIndex == particleJ.particleIndex) + return; RealVec deltaR = particleJ.position - particleI.position; getPeriodicDelta(deltaR); RealOpenMM r2 = deltaR.dot(deltaR); - if (r2 > _cutoffDistanceSquared)return; + if (r2 > _cutoffDistanceSquared) + return; RealOpenMM r = SQRT(r2); @@ -4875,8 +4823,6 @@ void AmoebaReferencePmeMultipoleForce::calculateFixedMultipoleFieldPairIxn(const _fixedMultipoleFieldPolar[iIndex] += fim - fip; _fixedMultipoleFieldPolar[jIndex] += fjm - fjp; - - return; } void AmoebaReferencePmeMultipoleForce::calculateFixedMultipoleField(const vector& particleData) @@ -4886,8 +4832,6 @@ void AmoebaReferencePmeMultipoleForce::calculateFixedMultipoleField(const vector resizePmeArrays(); computeAmoebaBsplines(particleData); - sort(_pmeAtomGridIndex.begin(), _pmeAtomGridIndex.end(), compareInt2); - findAmoebaAtomRangeForGrid(particleData); initializePmeGrid(); spreadFixedMultipolesOntoGrid(particleData); fftpack_exec_3d(_fftplan, FFTPACK_FORWARD, _pmeGrid, _pmeGrid); @@ -4909,8 +4853,6 @@ void AmoebaReferencePmeMultipoleForce::calculateFixedMultipoleField(const vector // include direct space fixed multipole fields this->AmoebaReferenceMultipoleForce::calculateFixedMultipoleField(particleData); - - return; } #define ARRAY(x,y) array[(x)-1+((y)-1)*AMOEBA_PME_ORDER] @@ -4987,8 +4929,6 @@ void AmoebaReferencePmeMultipoleForce::computeBSplinePoint(vector& for (int i = 1; i <= AMOEBA_PME_ORDER; i++) { thetai[i-1] = RealOpenMM4(ARRAY(AMOEBA_PME_ORDER,i), ARRAY(AMOEBA_PME_ORDER-1,i), ARRAY(AMOEBA_PME_ORDER-2,i), ARRAY(AMOEBA_PME_ORDER-3,i)); } - - return; } /** @@ -4996,7 +4936,6 @@ void AmoebaReferencePmeMultipoleForce::computeBSplinePoint(vector& */ void AmoebaReferencePmeMultipoleForce::computeAmoebaBsplines(const vector& particleData) { - // get the B-spline coefficients for each multipole site for (unsigned int ii = 0; ii < _numParticles; ii++) { @@ -5021,102 +4960,7 @@ void AmoebaReferencePmeMultipoleForce::computeAmoebaBsplines(const vector& particleData) -{ - - int last; - int start = 0; - last = (start == 0 ? -1 : _pmeAtomGridIndex[start-1][1]); - for (unsigned int ii = start; ii < _numParticles; ++ii) { - int2 atomData = _pmeAtomGridIndex[ii]; - int gridIndex = atomData[1]; - if (gridIndex != last) - { - for (int jj = last+1; jj <= gridIndex; ++jj) { - _pmeAtomRange[jj] = ii; - } - last = gridIndex; - } - } - - // Fill in values beyond the last atom. - - for (int j = last+1; j <= _totalGridSize; ++j) { - _pmeAtomRange[j] = _numParticles; - } - - // The grid index won't be needed again. Reuse that component to hold the z index, thus saving - // some work in the multipole spreading. - - for (unsigned int ii = 0; ii < _numParticles; ii++) { - - RealOpenMM posz = particleData[_pmeAtomGridIndex[ii][0]].position[2]; - posz -= FLOOR(posz*_recipBoxVectors[2][2])*_periodicBoxVectors[2][2]; - RealOpenMM w = posz*_recipBoxVectors[2][2]; - RealOpenMM fr = _pmeGridDimensions[2]*(w-(int)(w+0.5)+0.5); - int z = (static_cast(fr)) - AMOEBA_PME_ORDER + 1; - _pmeAtomGridIndex[ii][1] = z; - } - - return; -} - -void AmoebaReferencePmeMultipoleForce::getGridPointGivenGridIndex(int gridIndex, IntVec& gridPoint) const -{ - - gridPoint[0] = gridIndex/(_pmeGridDimensions[1]*_pmeGridDimensions[2]); - int remainder = gridIndex-gridPoint[0]*_pmeGridDimensions[1]*_pmeGridDimensions[2]; - gridPoint[1] = remainder/_pmeGridDimensions[2]; - gridPoint[2] = remainder-gridPoint[1]*_pmeGridDimensions[2]; - - return; -} - -RealOpenMM AmoebaReferencePmeMultipoleForce::computeFixedMultipolesGridValue(const int2& particleGridIndices, - int ix, int iy, const IntVec& gridPoint) const -{ - - RealOpenMM gridValue = 0.0; - for (int i = _pmeAtomRange[particleGridIndices[0]]; i < _pmeAtomRange[particleGridIndices[1]+1]; ++i) { - int2 atomData = _pmeAtomGridIndex[i]; - int atomIndex = atomData[0]; - int z = atomData[1]; - int iz = gridPoint[2]-z+(gridPoint[2] >= z ? 0 : _pmeGridDimensions[2]); - if (iz >= _pmeGridDimensions[2]) { - iz -= _pmeGridDimensions[2]; - } - - RealOpenMM atomCharge = _transformed[atomIndex].charge; - RealVec atomDipole = RealVec(_transformed[atomIndex].dipole[0], - _transformed[atomIndex].dipole[1], - _transformed[atomIndex].dipole[2]); - - RealOpenMM atomQuadrupoleXX = _transformed[atomIndex].quadrupole[QXX]; - RealOpenMM atomQuadrupoleXY = _transformed[atomIndex].quadrupole[QXY]; - RealOpenMM atomQuadrupoleXZ = _transformed[atomIndex].quadrupole[QXZ]; - RealOpenMM atomQuadrupoleYY = _transformed[atomIndex].quadrupole[QYY]; - RealOpenMM atomQuadrupoleYZ = _transformed[atomIndex].quadrupole[QYZ]; - RealOpenMM atomQuadrupoleZZ = _transformed[atomIndex].quadrupole[QZZ]; - - RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix]; - RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy]; - RealOpenMM4 v = _thetai[2][atomIndex*AMOEBA_PME_ORDER+iz]; - RealOpenMM term0 = atomCharge*u[0]*v[0] + atomDipole[1]*u[1]*v[0] + atomDipole[2]*u[0]*v[1] + atomQuadrupoleYY*u[2]*v[0] + atomQuadrupoleZZ*u[0]*v[2] + atomQuadrupoleYZ*u[1]*v[1]; - RealOpenMM term1 = atomDipole[0]*u[0]*v[0] + atomQuadrupoleXY*u[1]*v[0] + atomQuadrupoleXZ*u[0]*v[1]; - RealOpenMM term2 = atomQuadrupoleXX * u[0] * v[0]; - gridValue += term0*t[0] + term1*t[1] + term2*t[2]; } - return gridValue; } void AmoebaReferencePmeMultipoleForce::transformMultipolesToFractionalCoordinates(const vector& particleData) { @@ -5200,38 +5044,44 @@ void AmoebaReferencePmeMultipoleForce::spreadFixedMultipolesOntoGrid(const vecto transformMultipolesToFractionalCoordinates(particleData); - for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) { - - IntVec gridPoint; - getGridPointGivenGridIndex(gridIndex, gridPoint); - - RealOpenMM result = 0.0; - for (int ix = 0; ix < AMOEBA_PME_ORDER; ++ix) - { - int x = gridPoint[0]-ix+(gridPoint[0] >= ix ? 0 : _pmeGridDimensions[0]); - for (int iy = 0; iy < AMOEBA_PME_ORDER; ++iy) - { - int y = gridPoint[1]-iy+(gridPoint[1] >= iy ? 0 : _pmeGridDimensions[1]); - int z1 = gridPoint[2]-AMOEBA_PME_ORDER+1; - z1 += (z1 >= 0 ? 0 : _pmeGridDimensions[2]); - int z2 = (z1 < gridPoint[2] ? gridPoint[2] : _pmeGridDimensions[2]-1); - - int2 particleGridIndices; - particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z1; - particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z2; - result += computeFixedMultipolesGridValue(particleGridIndices, ix, iy, gridPoint); - - if (z1 > gridPoint[2]) { + // Clear the grid. + + for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) + _pmeGrid[gridIndex] = t_complex(0, 0); + + // Loop over atoms and spread them on the grid. + + for (int atomIndex = 0; atomIndex < _numParticles; atomIndex++) { + RealOpenMM atomCharge = _transformed[atomIndex].charge; + RealVec atomDipole = RealVec(_transformed[atomIndex].dipole[0], + _transformed[atomIndex].dipole[1], + _transformed[atomIndex].dipole[2]); - particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]; - particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+gridPoint[2]; - result += computeFixedMultipolesGridValue(particleGridIndices, ix, iy, gridPoint); + RealOpenMM atomQuadrupoleXX = _transformed[atomIndex].quadrupole[QXX]; + RealOpenMM atomQuadrupoleXY = _transformed[atomIndex].quadrupole[QXY]; + RealOpenMM atomQuadrupoleXZ = _transformed[atomIndex].quadrupole[QXZ]; + RealOpenMM atomQuadrupoleYY = _transformed[atomIndex].quadrupole[QYY]; + RealOpenMM atomQuadrupoleYZ = _transformed[atomIndex].quadrupole[QYZ]; + RealOpenMM atomQuadrupoleZZ = _transformed[atomIndex].quadrupole[QZZ]; + IntVec& gridPoint = _iGrid[atomIndex]; + for (int ix = 0; ix < AMOEBA_PME_ORDER; ix++) { + int x = (gridPoint[0]+ix) % _pmeGridDimensions[0]; + for (int iy = 0; iy < AMOEBA_PME_ORDER; iy++) { + int y = (gridPoint[1]+iy) % _pmeGridDimensions[1]; + for (int iz = 0; iz < AMOEBA_PME_ORDER; iz++) { + int z = (gridPoint[2]+iz) % _pmeGridDimensions[2]; + RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix]; + RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy]; + RealOpenMM4 v = _thetai[2][atomIndex*AMOEBA_PME_ORDER+iz]; + RealOpenMM term0 = atomCharge*u[0]*v[0] + atomDipole[1]*u[1]*v[0] + atomDipole[2]*u[0]*v[1] + atomQuadrupoleYY*u[2]*v[0] + atomQuadrupoleZZ*u[0]*v[2] + atomQuadrupoleYZ*u[1]*v[1]; + RealOpenMM term1 = atomDipole[0]*u[0]*v[0] + atomQuadrupoleXY*u[1]*v[0] + atomQuadrupoleXZ*u[0]*v[1]; + RealOpenMM term2 = atomQuadrupoleXX * u[0] * v[0]; + t_complex& gridValue = _pmeGrid[x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z]; + gridValue.re += term0*t[0] + term1*t[1] + term2*t[2]; } } } - _pmeGrid[gridIndex].re = result; } - return; } void AmoebaReferencePmeMultipoleForce::performAmoebaReciprocalConvolution() @@ -5381,92 +5231,53 @@ void AmoebaReferencePmeMultipoleForce::computeFixedPotentialFromGrid() } } -t_complex AmoebaReferencePmeMultipoleForce::computeInducedDipoleGridValue(const int2& particleGridIndices, const RealVec* cartToFrac, int ix, int iy, - const IntVec& gridPoint, - const vector& inputInducedDipole, - const vector& inputInducedDipolePolar) const -{ - +void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector& inputInducedDipole, + const vector& inputInducedDipolePolar) { + // Create the matrix to convert from Cartesian to fractional coordinates. - // loop over particles contributing to this grid point + RealVec cartToFrac[3]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + cartToFrac[j][i] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; - t_complex gridValue; - gridValue.re = gridValue.im = 0.0; + // Clear the grid. - for (int i = _pmeAtomRange[particleGridIndices[0]]; i < _pmeAtomRange[particleGridIndices[1]+1]; ++i) { - int2 atomData = _pmeAtomGridIndex[i]; - int atomIndex = atomData[0]; - int z = atomData[1]; - int iz = gridPoint[2]-z+(gridPoint[2] >= z ? 0 : _pmeGridDimensions[2]); - if (iz >= _pmeGridDimensions[2]) { - iz -= _pmeGridDimensions[2]; - } + for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) + _pmeGrid[gridIndex] = t_complex(0, 0); + + // Loop over atoms and spread them on the grid. + + for (int atomIndex = 0; atomIndex < _numParticles; atomIndex++) { RealVec inducedDipole = RealVec(inputInducedDipole[atomIndex][0]*cartToFrac[0][0] + inputInducedDipole[atomIndex][1]*cartToFrac[0][1] + inputInducedDipole[atomIndex][2]*cartToFrac[0][2], inputInducedDipole[atomIndex][0]*cartToFrac[1][0] + inputInducedDipole[atomIndex][1]*cartToFrac[1][1] + inputInducedDipole[atomIndex][2]*cartToFrac[1][2], inputInducedDipole[atomIndex][0]*cartToFrac[2][0] + inputInducedDipole[atomIndex][1]*cartToFrac[2][1] + inputInducedDipole[atomIndex][2]*cartToFrac[2][2]); RealVec inducedDipolePolar = RealVec(inputInducedDipolePolar[atomIndex][0]*cartToFrac[0][0] + inputInducedDipolePolar[atomIndex][1]*cartToFrac[0][1] + inputInducedDipolePolar[atomIndex][2]*cartToFrac[0][2], inputInducedDipolePolar[atomIndex][0]*cartToFrac[1][0] + inputInducedDipolePolar[atomIndex][1]*cartToFrac[1][1] + inputInducedDipolePolar[atomIndex][2]*cartToFrac[1][2], inputInducedDipolePolar[atomIndex][0]*cartToFrac[2][0] + inputInducedDipolePolar[atomIndex][1]*cartToFrac[2][1] + inputInducedDipolePolar[atomIndex][2]*cartToFrac[2][2]); - - RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix]; - RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy]; - RealOpenMM4 v = _thetai[2][atomIndex*AMOEBA_PME_ORDER+iz]; - - RealOpenMM term01 = inducedDipole[1]*u[1]*v[0] + inducedDipole[2]*u[0]*v[1]; - RealOpenMM term11 = inducedDipole[0]*u[0]*v[0]; - RealOpenMM term02 = inducedDipolePolar[1]*u[1]*v[0] + inducedDipolePolar[2]*u[0]*v[1]; - RealOpenMM term12 = inducedDipolePolar[0]*u[0]*v[0]; - - gridValue.re += term01*t[0] + term11*t[1]; - gridValue.im += term02*t[0] + term12*t[1]; - - } - return gridValue; -} - -void AmoebaReferencePmeMultipoleForce::spreadInducedDipolesOnGrid(const vector& inputInducedDipole, - const vector& inputInducedDipolePolar) -{ - RealVec cartToFrac[3]; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - cartToFrac[j][i] = _pmeGridDimensions[j]*_recipBoxVectors[i][j]; - - for (int gridIndex = 0; gridIndex < _totalGridSize; gridIndex++) - { - IntVec gridPoint; - getGridPointGivenGridIndex(gridIndex, gridPoint); - - t_complex gridValue; - gridValue.re = gridValue.im = 0.0; - - for (int ix = 0; ix < AMOEBA_PME_ORDER; ++ix) - { - int x = gridPoint[0]-ix+(gridPoint[0] >= ix ? 0 : _pmeGridDimensions[0]); - for (int iy = 0; iy < AMOEBA_PME_ORDER; ++iy) - { - int y = gridPoint[1]-iy+(gridPoint[1] >= iy ? 0 : _pmeGridDimensions[1]); - int z1 = gridPoint[2]-AMOEBA_PME_ORDER+1; - z1 += (z1 >= 0 ? 0 : _pmeGridDimensions[2]); - int z2 = (z1 < gridPoint[2] ? gridPoint[2] : _pmeGridDimensions[2]-1); - - int2 particleGridIndices; - particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z1; - particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z2; - gridValue += computeInducedDipoleGridValue(particleGridIndices, cartToFrac, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar); - - if (z1 > gridPoint[2]) - { - particleGridIndices[0] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]; - particleGridIndices[1] = x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+gridPoint[2]; - gridValue += computeInducedDipoleGridValue(particleGridIndices, cartToFrac, ix, iy, gridPoint, inputInducedDipole, inputInducedDipolePolar); + IntVec& gridPoint = _iGrid[atomIndex]; + for (int ix = 0; ix < AMOEBA_PME_ORDER; ix++) { + int x = (gridPoint[0]+ix) % _pmeGridDimensions[0]; + for (int iy = 0; iy < AMOEBA_PME_ORDER; iy++) { + int y = (gridPoint[1]+iy) % _pmeGridDimensions[1]; + for (int iz = 0; iz < AMOEBA_PME_ORDER; iz++) { + int z = (gridPoint[2]+iz) % _pmeGridDimensions[2]; + + RealOpenMM4 t = _thetai[0][atomIndex*AMOEBA_PME_ORDER+ix]; + RealOpenMM4 u = _thetai[1][atomIndex*AMOEBA_PME_ORDER+iy]; + RealOpenMM4 v = _thetai[2][atomIndex*AMOEBA_PME_ORDER+iz]; + + RealOpenMM term01 = inducedDipole[1]*u[1]*v[0] + inducedDipole[2]*u[0]*v[1]; + RealOpenMM term11 = inducedDipole[0]*u[0]*v[0]; + RealOpenMM term02 = inducedDipolePolar[1]*u[1]*v[0] + inducedDipolePolar[2]*u[0]*v[1]; + RealOpenMM term12 = inducedDipolePolar[0]*u[0]*v[0]; + + t_complex& gridValue = _pmeGrid[x*_pmeGridDimensions[1]*_pmeGridDimensions[2]+y*_pmeGridDimensions[2]+z]; + gridValue.re += term01*t[0] + term11*t[1]; + gridValue.im += term02*t[0] + term12*t[1]; } } } - _pmeGrid[gridIndex] = gridValue; } - - return; } void AmoebaReferencePmeMultipoleForce::computeInducedPotentialFromGrid() @@ -5669,7 +5480,6 @@ void AmoebaReferencePmeMultipoleForce::computeInducedPotentialFromGrid() _phidp[20*m+18] = tuv012; _phidp[20*m+19] = tuv111; } - return; } RealOpenMM AmoebaReferencePmeMultipoleForce::computeReciprocalSpaceFixedMultipoleForceAndEnergy(const vector& particleData, @@ -5874,7 +5684,6 @@ void AmoebaReferencePmeMultipoleForce::recordFixedMultipoleField() _fixedMultipoleField[i][1] = -(_phi[20*i+1]*fracToCart[1][0] + _phi[20*i+2]*fracToCart[1][1] + _phi[20*i+3]*fracToCart[1][2]); _fixedMultipoleField[i][2] = -(_phi[20*i+1]*fracToCart[2][0] + _phi[20*i+2]*fracToCart[2][1] + _phi[20*i+3]*fracToCart[2][2]); } - return; } void AmoebaReferencePmeMultipoleForce::initializeInducedDipoles(vector& updateInducedDipoleFields) @@ -5882,7 +5691,6 @@ void AmoebaReferencePmeMultipoleForce::initializeInducedDipoles(vectorAmoebaReferenceMultipoleForce::initializeInducedDipoles(updateInducedDipoleFields); calculateReciprocalSpaceInducedDipoleField(updateInducedDipoleFields); - return; } void AmoebaReferencePmeMultipoleForce::recordInducedDipoleField(vector& field, vector& fieldPolar) @@ -5901,7 +5709,6 @@ void AmoebaReferencePmeMultipoleForce::recordInducedDipoleField(vector& fieldPolar[i][1] -= _phip[10*i+1]*fracToCart[1][0] + _phip[10*i+2]*fracToCart[1][1] + _phip[10*i+3]*fracToCart[1][2]; fieldPolar[i][2] -= _phip[10*i+1]*fracToCart[2][0] + _phip[10*i+2]*fracToCart[2][1] + _phip[10*i+3]*fracToCart[2][2]; } - return; } void AmoebaReferencePmeMultipoleForce::calculateReciprocalSpaceInducedDipoleField(vector& updateInducedDipoleFields) @@ -5948,8 +5755,6 @@ void AmoebaReferencePmeMultipoleForce::calculateInducedDipoleFields(const vector field[jj] += inducedDipoles[jj]*term; } } - - return; } void AmoebaReferencePmeMultipoleForce::calculateDirectInducedDipolePairIxn(unsigned int iIndex, unsigned int jIndex, @@ -5968,8 +5773,6 @@ void AmoebaReferencePmeMultipoleForce::calculateDirectInducedDipolePairIxn(unsig dur = inducedDipole[iIndex].dot(delta); field[jIndex] += delta*(dur*preFactor2) + inducedDipole[iIndex]*preFactor1; - - return; } void AmoebaReferencePmeMultipoleForce::calculateDirectInducedDipolePairIxns(const MultipoleParticleData& particleI, @@ -5987,7 +5790,8 @@ void AmoebaReferencePmeMultipoleForce::calculateDirectInducedDipolePairIxns(cons getPeriodicDelta(deltaR); RealOpenMM r2 = deltaR.dot(deltaR); - if (r2 > _cutoffDistanceSquared)return; + if (r2 > _cutoffDistanceSquared) + return; RealOpenMM r = SQRT(r2); @@ -6039,13 +5843,10 @@ void AmoebaReferencePmeMultipoleForce::calculateDirectInducedDipolePairIxns(cons *updateInducedDipoleFields[ii].inducedDipoles, updateInducedDipoleFields[ii].inducedDipoleField); } - - return; } RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector& particleData) const { - RealOpenMM cii = 0.0; RealOpenMM dii = 0.0; RealOpenMM qii = 0.0; @@ -6074,7 +5875,6 @@ RealOpenMM AmoebaReferencePmeMultipoleForce::calculatePmeSelfEnergy(const vector void AmoebaReferencePmeMultipoleForce::calculatePmeSelfTorque(const vector& particleData, vector& torques) const { - RealOpenMM term = (2.0/3.0)*(_electric/_dielectric)*(_alphaEwald*_alphaEwald*_alphaEwald)/SQRT_PI; for (unsigned int ii = 0; ii < _numParticles; ii++) { @@ -6085,7 +5885,6 @@ void AmoebaReferencePmeMultipoleForce::calculatePmeSelfTorque(const vector _phid; std::vector _phip; std::vector _phidp; - std::vector _pmeAtomRange; - std::vector _pmeAtomGridIndex; std::vector _pmeBsplineTheta; std::vector _pmeBsplineDtheta; @@ -1439,31 +1437,6 @@ private: */ void computeAmoebaBsplines(const std::vector& particleData); - /** - * For each grid point, find the range of sorted atoms associated with that point. - * - * @param particleData vector of particle positions and parameters (charge, labFrame dipoles, quadrupoles, ...) - */ - void findAmoebaAtomRangeForGrid(const vector& particleData); - - /** - * Get grid point given grid index. - * - * @param gridIndex input grid index - * @param gridPoint output grid point - */ - void getGridPointGivenGridIndex(int gridIndex, IntVec& gridPoint) const; - - /** - * Compute induced dipole grid value. - * - * @param particleGridIndices particle grid indices - * @param ix x-dimension offset value - * @param iy y-dimension offset value - * @param gridPoint grid point for which value is to be computed - */ - RealOpenMM computeFixedMultipolesGridValue(const int2& particleGridIndices, int ix, int iy, const IntVec& gridPoint) const; - /** * Transform multipoles from cartesian coordinates to fractional coordinates. */ @@ -1559,21 +1532,6 @@ private: */ void initializeInducedDipoles(std::vector& updateInducedDipoleFields); - /** - * Compute induced dipole grid value. - * - * @param atomIndices indices of first and last atom contiputing to grid point value - * @param cartToFrac transformation matrix from Cartesian to fractional coordinates - * @param ix x-dimension offset value - * @param iy y-dimension offset value - * @param gridPoint grid point for which value is to be computed - * @param inputInducedDipole induced dipole value - * @param inputInducedDipolePolar induced dipole polar value - */ - t_complex computeInducedDipoleGridValue(const int2& atomIndices, const RealVec* cartToFrac, int ix, int iy, const IntVec& gridPoint, - const std::vector& inputInducedDipole, - const std::vector& inputInducedDipolePolar) const; - /** * Spread induced dipoles onto grid. * -- GitLab From f7ef2dd001984e3be35498e41f8f8106ee0e25fa Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 10 Mar 2015 10:43:20 -0700 Subject: [PATCH 302/338] More bug fixes to multi-GPU --- platforms/cuda/src/CudaNonbondedUtilities.cpp | 17 +--------------- platforms/cuda/src/CudaParallelKernels.cpp | 20 +++++++++---------- .../opencl/src/OpenCLNonbondedUtilities.cpp | 18 +---------------- .../opencl/src/OpenCLParallelKernels.cpp | 20 +++++++++---------- 4 files changed, 20 insertions(+), 55 deletions(-) diff --git a/platforms/cuda/src/CudaNonbondedUtilities.cpp b/platforms/cuda/src/CudaNonbondedUtilities.cpp index 57d9a35d8..b4ae6e875 100644 --- a/platforms/cuda/src/CudaNonbondedUtilities.cpp +++ b/platforms/cuda/src/CudaNonbondedUtilities.cpp @@ -264,14 +264,6 @@ void CudaNonbondedUtilities::initialize(const System& system) { sortedBlockCenter = new CudaArray(context, numAtomBlocks+1, 4*elementSize, "sortedBlockCenter"); sortedBlockBoundingBox = new CudaArray(context, numAtomBlocks+1, 4*elementSize, "sortedBlockBoundingBox"); oldPositions = new CudaArray(context, numAtoms, 4*elementSize, "oldPositions"); - if (context.getUseDoublePrecision()) { - vector oldPositionsVec(numAtoms, make_double4(1e30, 1e30, 1e30, 0)); - oldPositions->upload(oldPositionsVec); - } - else { - vector oldPositionsVec(numAtoms, make_float4(1e30f, 1e30f, 1e30f, 0)); - oldPositions->upload(oldPositionsVec); - } rebuildNeighborList = CudaArray::create(context, 1, "rebuildNeighborList"); blockSorter = new CudaSort(context, new BlockSortTrait(context.getUseDoublePrecision()), numAtomBlocks); vector count(1, 0); @@ -402,14 +394,7 @@ void CudaNonbondedUtilities::updateNeighborListSize() { if (forceArgs.size() > 0) forceArgs[17] = &interactingAtoms->getDevicePointer(); findInteractingBlocksArgs[7] = &interactingAtoms->getDevicePointer(); - if (context.getUseDoublePrecision()) { - vector oldPositionsVec(numAtoms, make_double4(1e30, 1e30, 1e30, 0)); - oldPositions->upload(oldPositionsVec); - } - else { - vector oldPositionsVec(numAtoms, make_float4(1e30f, 1e30f, 1e30f, 0)); - oldPositions->upload(oldPositionsVec); - } + forceRebuildNeighborList = true; } void CudaNonbondedUtilities::setUsePadding(bool padding) { diff --git a/platforms/cuda/src/CudaParallelKernels.cpp b/platforms/cuda/src/CudaParallelKernels.cpp index b5d5ec7f1..eae23836b 100644 --- a/platforms/cuda/src/CudaParallelKernels.cpp +++ b/platforms/cuda/src/CudaParallelKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2011-2013 Stanford University and the Authors. * + * Portions copyright (c) 2011-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -93,9 +93,9 @@ private: class CudaParallelCalcForcesAndEnergyKernel::FinishComputationTask : public CudaContext::WorkTask { public: FinishComputationTask(ContextImpl& context, CudaContext& cu, CudaCalcForcesAndEnergyKernel& kernel, - bool includeForce, bool includeEnergy, int groups, double& energy, long long& completionTime, long long* pinnedMemory, CudaArray& contextForces, bool& valid) : + bool includeForce, bool includeEnergy, int groups, double& energy, long long& completionTime, long long* pinnedMemory, CudaArray& contextForces, bool& valid, int& numTiles) : context(context), cu(cu), kernel(kernel), includeForce(includeForce), includeEnergy(includeEnergy), groups(groups), energy(energy), - completionTime(completionTime), pinnedMemory(pinnedMemory), contextForces(contextForces), valid(valid) { + completionTime(completionTime), pinnedMemory(pinnedMemory), contextForces(contextForces), valid(valid), numTiles(numTiles) { } void execute() { // Execute the kernel, then download forces. @@ -120,6 +120,10 @@ public: cu.getForce().download(&pinnedMemory[(cu.getContextIndex()-1)*numAtoms*3]); } } + if (cu.getNonbondedUtilities().getUsePeriodic() && numTiles > cu.getNonbondedUtilities().getInteractingTiles().getSize()) { + valid = false; + cu.getNonbondedUtilities().updateNeighborListSize(); + } } private: ContextImpl& context; @@ -132,6 +136,7 @@ private: long long* pinnedMemory; CudaArray& contextForces; bool& valid; + int& numTiles; }; CudaParallelCalcForcesAndEnergyKernel::CudaParallelCalcForcesAndEnergyKernel(string name, const Platform& platform, CudaPlatform::PlatformData& data) : @@ -201,16 +206,9 @@ double CudaParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& con for (int i = 0; i < (int) data.contexts.size(); i++) { CudaContext& cu = *data.contexts[i]; CudaContext::WorkThread& thread = cu.getWorkThread(); - thread.addTask(new FinishComputationTask(context, cu, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceBuffer, *contextForces, valid)); + thread.addTask(new FinishComputationTask(context, cu, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceBuffer, *contextForces, valid, tileCounts[i])); } data.syncContexts(); - if (data.contexts[0]->getNonbondedUtilities().getUsePeriodic()) { - for (int i = 0; i < (int) tileCounts.size(); i++) - if (tileCounts[i] > data.contexts[i]->getNonbondedUtilities().getInteractingTiles().getSize()) { - valid = false; - data.contexts[i]->getNonbondedUtilities().updateNeighborListSize(); - } - } double energy = 0.0; for (int i = 0; i < (int) data.contextEnergy.size(); i++) energy += data.contextEnergy[i]; diff --git a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp index cf703f10b..de53dac7a 100644 --- a/platforms/opencl/src/OpenCLNonbondedUtilities.cpp +++ b/platforms/opencl/src/OpenCLNonbondedUtilities.cpp @@ -282,14 +282,6 @@ void OpenCLNonbondedUtilities::initialize(const System& system) { sortedBlockCenter = new OpenCLArray(context, numAtomBlocks+1, 4*elementSize, "sortedBlockCenter"); sortedBlockBoundingBox = new OpenCLArray(context, numAtomBlocks+1, 4*elementSize, "sortedBlockBoundingBox"); oldPositions = new OpenCLArray(context, numAtoms, 4*elementSize, "oldPositions"); - if (context.getUseDoublePrecision()) { - vector oldPositionsVec(numAtoms, mm_double4(1e30, 1e30, 1e30, 0)); - oldPositions->upload(oldPositionsVec); - } - else { - vector oldPositionsVec(numAtoms, mm_float4(1e30f, 1e30f, 1e30f, 0)); - oldPositions->upload(oldPositionsVec); - } rebuildNeighborList = OpenCLArray::create(context, 1, "rebuildNeighborList"); blockSorter = new OpenCLSort(context, new BlockSortTrait(context.getUseDoublePrecision()), numAtomBlocks); vector count(1, 0); @@ -447,15 +439,7 @@ void OpenCLNonbondedUtilities::updateNeighborListSize() { findInteractingBlocksKernel.setArg(6, interactingTiles->getDeviceBuffer()); findInteractingBlocksKernel.setArg(7, interactingAtoms->getDeviceBuffer()); findInteractingBlocksKernel.setArg(9, maxTiles); - int numAtoms = context.getNumAtoms(); - if (context.getUseDoublePrecision()) { - vector oldPositionsVec(numAtoms, mm_double4(1e30, 1e30, 1e30, 0)); - oldPositions->upload(oldPositionsVec); - } - else { - vector oldPositionsVec(numAtoms, mm_float4(1e30f, 1e30f, 1e30f, 0)); - oldPositions->upload(oldPositionsVec); - } + sortBoxDataKernel.setArg(9, true); } void OpenCLNonbondedUtilities::setUsePadding(bool padding) { diff --git a/platforms/opencl/src/OpenCLParallelKernels.cpp b/platforms/opencl/src/OpenCLParallelKernels.cpp index c4a5e8ea8..b81a3f48c 100644 --- a/platforms/opencl/src/OpenCLParallelKernels.cpp +++ b/platforms/opencl/src/OpenCLParallelKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2011-2013 Stanford University and the Authors. * + * Portions copyright (c) 2011-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -79,9 +79,9 @@ private: class OpenCLParallelCalcForcesAndEnergyKernel::FinishComputationTask : public OpenCLContext::WorkTask { public: FinishComputationTask(ContextImpl& context, OpenCLContext& cl, OpenCLCalcForcesAndEnergyKernel& kernel, - bool includeForce, bool includeEnergy, int groups, double& energy, long long& completionTime, void* pinnedMemory, bool& valid) : + bool includeForce, bool includeEnergy, int groups, double& energy, long long& completionTime, void* pinnedMemory, bool& valid, int& numTiles) : context(context), cl(cl), kernel(kernel), includeForce(includeForce), includeEnergy(includeEnergy), groups(groups), energy(energy), - completionTime(completionTime), pinnedMemory(pinnedMemory), valid(valid) { + completionTime(completionTime), pinnedMemory(pinnedMemory), valid(valid), numTiles(numTiles) { } void execute() { // Execute the kernel, then download forces. @@ -98,6 +98,10 @@ public: cl.getQueue().finish(); } completionTime = getTime(); + if (cl.getNonbondedUtilities().getUsePeriodic() && numTiles > cl.getNonbondedUtilities().getInteractingTiles().getSize()) { + valid = false; + cl.getNonbondedUtilities().updateNeighborListSize(); + } } private: ContextImpl& context; @@ -109,6 +113,7 @@ private: long long& completionTime; void* pinnedMemory; bool& valid; + int& numTiles; }; OpenCLParallelCalcForcesAndEnergyKernel::OpenCLParallelCalcForcesAndEnergyKernel(string name, const Platform& platform, OpenCLPlatform::PlatformData& data) : @@ -162,16 +167,9 @@ double OpenCLParallelCalcForcesAndEnergyKernel::finishComputation(ContextImpl& c for (int i = 0; i < (int) data.contexts.size(); i++) { OpenCLContext& cl = *data.contexts[i]; OpenCLContext::WorkThread& thread = cl.getWorkThread(); - thread.addTask(new FinishComputationTask(context, cl, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceMemory, valid)); + thread.addTask(new FinishComputationTask(context, cl, getKernel(i), includeForce, includeEnergy, groups, data.contextEnergy[i], completionTimes[i], pinnedForceMemory, valid, tileCounts[i])); } data.syncContexts(); - if (data.contexts[0]->getNonbondedUtilities().getUsePeriodic()) { - for (int i = 0; i < (int) tileCounts.size(); i++) - if (tileCounts[i] > data.contexts[i]->getNonbondedUtilities().getInteractingTiles().getSize()) { - valid = false; - data.contexts[i]->getNonbondedUtilities().updateNeighborListSize(); - } - } double energy = 0.0; for (int i = 0; i < (int) data.contextEnergy.size(); i++) energy += data.contextEnergy[i]; -- GitLab From 9d3a655b1f4bb263ee22bbc415a39ff30c9f02f8 Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 10 Mar 2015 13:54:18 -0700 Subject: [PATCH 303/338] Fixed a performance regression in multi-GPU on CUDA --- examples/benchmark.py | 9 ++++++--- platforms/cuda/include/CudaParallelKernels.h | 2 +- platforms/cuda/src/CudaParallelKernels.cpp | 14 +++++++++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/benchmark.py b/examples/benchmark.py index 650f3848d..629162509 100644 --- a/examples/benchmark.py +++ b/examples/benchmark.py @@ -6,9 +6,9 @@ import sys from datetime import datetime from optparse import OptionParser -def timeIntegration(context, steps): +def timeIntegration(context, steps, initialSteps): """Integrate a Context for a specified number of steps, then return how many seconds it took.""" - context.getIntegrator().step(5) # Make sure everything is fully initialized + context.getIntegrator().step(initialSteps) # Make sure everything is fully initialized context.getState(getEnergy=True) start = datetime.now() context.getIntegrator().step(steps) @@ -79,11 +79,14 @@ def runOneTest(testName, options): system = ff.createSystem(pdb.topology, nonbondedMethod=method, nonbondedCutoff=cutoff, constraints=constraints, hydrogenMass=hydrogenMass) print('Step Size: %g fs' % dt.value_in_unit(unit.femtoseconds)) properties = {} + initialSteps = 5 if options.device is not None: if platform.getName() == 'CUDA': properties['CudaDeviceIndex'] = options.device elif platform.getName() == 'OpenCL': properties['OpenCLDeviceIndex'] = options.device + if ',' in options.device or ' ' in options.device: + initialSteps = 250 if options.precision is not None: if platform.getName() == 'CUDA': properties['CudaPrecision'] = options.precision @@ -102,7 +105,7 @@ def runOneTest(testName, options): context.setVelocitiesToTemperature(300*unit.kelvin) steps = 20 while True: - time = timeIntegration(context, steps) + time = timeIntegration(context, steps, initialSteps) if time >= 0.5*options.seconds: break if time < 0.5: diff --git a/platforms/cuda/include/CudaParallelKernels.h b/platforms/cuda/include/CudaParallelKernels.h index e43299a8a..6c2498b9b 100644 --- a/platforms/cuda/include/CudaParallelKernels.h +++ b/platforms/cuda/include/CudaParallelKernels.h @@ -83,7 +83,7 @@ private: std::vector kernels; std::vector completionTimes; std::vector contextNonbondedFractions; - std::vector tileCounts; + int* tileCounts; CudaArray* contextForces; void* pinnedPositionBuffer; long long* pinnedForceBuffer; diff --git a/platforms/cuda/src/CudaParallelKernels.cpp b/platforms/cuda/src/CudaParallelKernels.cpp index eae23836b..6c024cea8 100644 --- a/platforms/cuda/src/CudaParallelKernels.cpp +++ b/platforms/cuda/src/CudaParallelKernels.cpp @@ -99,7 +99,7 @@ public: } void execute() { // Execute the kernel, then download forces. - + energy += kernel.finishComputation(context, includeForce, includeEnergy, groups, valid); if (cu.getComputeForceCount() < 200) { // Record timing information for load balancing. Since this takes time, only do it at the start of the simulation. @@ -141,7 +141,7 @@ private: CudaParallelCalcForcesAndEnergyKernel::CudaParallelCalcForcesAndEnergyKernel(string name, const Platform& platform, CudaPlatform::PlatformData& data) : CalcForcesAndEnergyKernel(name, platform), data(data), completionTimes(data.contexts.size()), contextNonbondedFractions(data.contexts.size()), - tileCounts(data.contexts.size()), contextForces(NULL), pinnedPositionBuffer(NULL), pinnedForceBuffer(NULL) { + tileCounts(NULL), contextForces(NULL), pinnedPositionBuffer(NULL), pinnedForceBuffer(NULL) { for (int i = 0; i < (int) data.contexts.size(); i++) kernels.push_back(Kernel(new CudaCalcForcesAndEnergyKernel(name, platform, *data.contexts[i]))); } @@ -156,6 +156,8 @@ CudaParallelCalcForcesAndEnergyKernel::~CudaParallelCalcForcesAndEnergyKernel() cuMemFreeHost(pinnedForceBuffer); cuEventDestroy(event); cuStreamDestroy(peerCopyStream); + if (tileCounts != NULL) + cuMemFreeHost(tileCounts); } void CudaParallelCalcForcesAndEnergyKernel::initialize(const System& system) { @@ -163,12 +165,14 @@ void CudaParallelCalcForcesAndEnergyKernel::initialize(const System& system) { cu.setAsCurrent(); CUmodule module = cu.createModule(CudaKernelSources::parallel); sumKernel = cu.getKernel(module, "sumForces"); - for (int i = 0; i < (int) kernels.size(); i++) + int numContexts = data.contexts.size(); + for (int i = 0; i < numContexts; i++) getKernel(i).initialize(system); - for (int i = 0; i < (int) contextNonbondedFractions.size(); i++) - contextNonbondedFractions[i] = 1/(double) contextNonbondedFractions.size(); + for (int i = 0; i < numContexts; i++) + contextNonbondedFractions[i] = 1/(double) numContexts; CHECK_RESULT(cuEventCreate(&event, 0), "Error creating event"); CHECK_RESULT(cuStreamCreate(&peerCopyStream, CU_STREAM_NON_BLOCKING), "Error creating stream"); + CHECK_RESULT(cuMemHostAlloc((void**) &tileCounts, numContexts*sizeof(int), 0), "Error creating tile count buffer"); } void CudaParallelCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool includeForce, bool includeEnergy, int groups) { -- GitLab From af74717d3cb376e362a57bc39d980418ed92ce30 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Sat, 14 Mar 2015 11:45:32 -0400 Subject: [PATCH 304/338] Fix bug in dcd box vector writing. --- wrappers/python/simtk/openmm/app/dcdfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index ba9007366..d9479ddc1 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -112,8 +112,8 @@ class DCDFile(object): file.seek(0, os.SEEK_END) boxVectors = self._topology.getPeriodicBoxVectors() if boxVectors is not None: - if getPeriodicBoxVectors is not None: - boxVectors = getPeriodicBoxVectors + if periodicBoxVectors is not None: + boxVectors = periodicBoxVectors elif unitCellDimensions is not None: if is_quantity(unitCellDimensions): unitCellDimensions = unitCellDimensions.value_in_unit(nanometers) -- GitLab From 427f09355b50c322ad53d5e43a53c1315eb87334 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Sat, 14 Mar 2015 11:54:00 -0400 Subject: [PATCH 305/338] Fix more bugs --- wrappers/python/simtk/openmm/app/dcdfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index d9479ddc1..b5cf1a2a6 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -37,6 +37,8 @@ import time import struct import math from simtk.unit import picoseconds, nanometers, angstroms, is_quantity, norm +from simtk.openmm import Vec3 +from simtk.openmm.app.internal.unitcell import computeLengthsAndAngles class DCDFile(object): """DCDFile provides methods for creating DCD files. -- GitLab From 5061f42d3d6e54ad81bf6c8dd344f765e6340253 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Sat, 14 Mar 2015 11:57:18 -0400 Subject: [PATCH 306/338] Fix last bug. --- wrappers/python/simtk/openmm/app/dcdfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index b5cf1a2a6..c55bb675b 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -121,9 +121,9 @@ class DCDFile(object): unitCellDimensions = unitCellDimensions.value_in_unit(nanometers) boxVectors = (Vec3(unitCellDimensions[0], 0, 0), Vec3(0, unitCellDimensions[1], 0), Vec3(0, 0, unitCellDimensions[2]))*nanometers (a_length, b_length, c_length, alpha, beta, gamma) = computeLengthsAndAngles(boxVectors) - a_length = a_length.value_in_unit(angstroms) - b_length = b_length.value_in_unit(angstroms) - c_length = c_length.value_in_unit(angstroms) + a_length = a_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. + b_length = b_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here..value_in_unit(angstroms) + c_length = c_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. angle1 = math.sin(math.pi/2-gamma) angle2 = math.sin(math.pi/2-beta) angle3 = math.sin(math.pi/2-alpha) -- GitLab From 4c2be2fdb833242f37fe7ec58d4bf26943073eb5 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Sat, 14 Mar 2015 11:58:20 -0400 Subject: [PATCH 307/338] Fix extra text in comment. --- wrappers/python/simtk/openmm/app/dcdfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index c55bb675b..e72f534d4 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -122,7 +122,7 @@ class DCDFile(object): boxVectors = (Vec3(unitCellDimensions[0], 0, 0), Vec3(0, unitCellDimensions[1], 0), Vec3(0, 0, unitCellDimensions[2]))*nanometers (a_length, b_length, c_length, alpha, beta, gamma) = computeLengthsAndAngles(boxVectors) a_length = a_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. - b_length = b_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here..value_in_unit(angstroms) + b_length = b_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. c_length = c_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. angle1 = math.sin(math.pi/2-gamma) angle2 = math.sin(math.pi/2-beta) -- GitLab From c212839eb8fe78b24401404f3be5f328d828a336 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Sat, 14 Mar 2015 11:59:43 -0400 Subject: [PATCH 308/338] Fix manual unit conversion bug. --- wrappers/python/simtk/openmm/app/dcdfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/dcdfile.py b/wrappers/python/simtk/openmm/app/dcdfile.py index e72f534d4..6d9898056 100644 --- a/wrappers/python/simtk/openmm/app/dcdfile.py +++ b/wrappers/python/simtk/openmm/app/dcdfile.py @@ -121,9 +121,9 @@ class DCDFile(object): unitCellDimensions = unitCellDimensions.value_in_unit(nanometers) boxVectors = (Vec3(unitCellDimensions[0], 0, 0), Vec3(0, unitCellDimensions[1], 0), Vec3(0, 0, unitCellDimensions[2]))*nanometers (a_length, b_length, c_length, alpha, beta, gamma) = computeLengthsAndAngles(boxVectors) - a_length = a_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. - b_length = b_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. - c_length = c_length / 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. + a_length = a_length * 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. + b_length = b_length * 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. + c_length = c_length * 10. # computeLengthsAndAngles returns unitless nanometers, but need angstroms here. angle1 = math.sin(math.pi/2-gamma) angle2 = math.sin(math.pi/2-beta) angle3 = math.sin(math.pi/2-alpha) -- GitLab From 875c973fb21ded221da226c12292bf037c3b4f3d Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Sat, 14 Mar 2015 12:09:55 -0400 Subject: [PATCH 309/338] Added test. --- wrappers/python/tests/TestAmberPrmtopFile.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/wrappers/python/tests/TestAmberPrmtopFile.py b/wrappers/python/tests/TestAmberPrmtopFile.py index 529c95eb6..83cb2f6b4 100644 --- a/wrappers/python/tests/TestAmberPrmtopFile.py +++ b/wrappers/python/tests/TestAmberPrmtopFile.py @@ -275,5 +275,25 @@ class TestAmberPrmtopFile(unittest.TestCase): diff = norm(f1-f2) self.assertTrue(diff < 0.1 or diff/norm(f1) < 1e-4) + def test_with_dcd_reporter(self): + """Check that an amber simulation like the docs example works with a DCD reporter.""" + + temperature = 50*kelvin + + prmtop = prmtop4 # Mg + water + inpcrd = inpcrd4 # Mg + water + system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) + system.addForce(MonteCarloBarostat(1.0 * atmospheres, temperature, 1)) + + integrator = LangevinIntegrator(temperature, 1.0 / picosecond, 0.0001 * picoseconds) + + simulation = Simulation(prmtop.topology, system, integrator) + simulation.context.setPositions(inpcrd.positions) + simulation.context.setPeriodicBoxVectors(*inpcrd.boxVectors) + + simulation.reporters.append(DCDReporter('output.dcd', 1)) # This is an explicit test for the bugs in issue #850 + simulation.step(5) + + if __name__ == '__main__': unittest.main() -- GitLab From 9fe6cd749aa0e5cc2b5df7d4ce5aaef4f3c639e6 Mon Sep 17 00:00:00 2001 From: kyleabeauchamp Date: Sat, 14 Mar 2015 12:12:48 -0400 Subject: [PATCH 310/338] Amber DCD test uses tempfile now. --- wrappers/python/tests/TestAmberPrmtopFile.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wrappers/python/tests/TestAmberPrmtopFile.py b/wrappers/python/tests/TestAmberPrmtopFile.py index 83cb2f6b4..5c32bd636 100644 --- a/wrappers/python/tests/TestAmberPrmtopFile.py +++ b/wrappers/python/tests/TestAmberPrmtopFile.py @@ -1,4 +1,6 @@ import unittest +import os +import tempfile from validateConstraints import * from simtk.openmm.app import * from simtk.openmm import * @@ -291,8 +293,10 @@ class TestAmberPrmtopFile(unittest.TestCase): simulation.context.setPositions(inpcrd.positions) simulation.context.setPeriodicBoxVectors(*inpcrd.boxVectors) - simulation.reporters.append(DCDReporter('output.dcd', 1)) # This is an explicit test for the bugs in issue #850 + fname = tempfile.mktemp(suffix='.dcd') + simulation.reporters.append(DCDReporter(fname, 1)) # This is an explicit test for the bugs in issue #850 simulation.step(5) + os.remove(fname) if __name__ == '__main__': -- GitLab From 62581e9c31e27c7d26519ef45cd5370fdac38e46 Mon Sep 17 00:00:00 2001 From: "John Chodera (MSKCC)" Date: Sat, 14 Mar 2015 13:48:38 -0700 Subject: [PATCH 311/338] Modified travis logic to only fail if retested tests fail. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index feb3a76d3..008faff02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,8 +23,8 @@ script: - sudo make PythonInstall - # Run the testInstallation script - python -m simtk.testInstallation - - # run all of the tests - - ctest -j2 -V + - # run all of the tests, making sure failures at this stage don't cause travis failures + - ctest -j2 -V || true - # get a list of all of the failed tests into this stupid ctest format - python -c 'fn = "Testing/Temporary/LastTestsFailed.log"; import os; os.path.exists(fn) or exit(0); l = [line.split(":")[0] for line in open(fn)]; triplets = zip(l, l, [","]*len(l)); print "".join(",".join(t) for t in triplets)' > FailedTests.log - # rerun all of the failed tests -- GitLab From 53e7cadc018008dabfeea931f93bc8b39825bc84 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Mon, 16 Mar 2015 10:04:27 -0400 Subject: [PATCH 312/338] Fix very subtle bug in Amber prmtop with NBFIX Some topology files have some of the nonbonded pairs in the Lennard-Jones matrix pointing to a 0 entry in the HBOND_ACOEF and HBOND_BCOEF arrays. This commit simply skips over those entries, having previously checked that all entries in the 10-12 sections are 0. There is actually an example of this already in the test suite (see ff14ipq.parm7), but this fortuitously did not cause any difference in those test results. The reason this bug is not evident in that test case is because the A- and B-coefficients pulled when the index was -1 (later decremented to -2) was also coincidentally 0. However, if this was not the case (as it does not *have* to be), then who knows what could happen. This also adds more of a check against 10-12 topology files. ParmEd actually supports using the 10-12 potential in OpenMM when specified in the Amber prmtop, but it is sufficiently rare that it is not worth porting to OpenMM, IMO. --- .../simtk/openmm/app/internal/amber_file_parser.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 6a8145ccd..730a02743 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -305,6 +305,10 @@ class PrmtopLoader(object): return self._nonbondTerms except AttributeError: pass + # Check if there are any non-zero HBOND terms + for x, y in zip(self._raw_data['HBOND_ACOEF'], self._raw_data['HBOND_BCOEF']): + if float(x) or float(y): + raise Exception('10-12 interactions are not supported') self._nonbondTerms=[] lengthConversionFactor = units.angstrom.conversion_factor_to(units.nanometer) energyConversionFactor = units.kilocalorie_per_mole.conversion_factor_to(units.kilojoule_per_mole) @@ -333,6 +337,7 @@ class PrmtopLoader(object): for i in range(numTypes): for j in range(numTypes): index = int(self._raw_data['NONBONDED_PARM_INDEX'][numTypes*i+j]) - 1 + if index < 0: continue rij = type_parameters[i][0] + type_parameters[j][0] wdij = sqrt(type_parameters[i][1] * type_parameters[j][1]) a = float(self._raw_data['LENNARD_JONES_ACOEF'][index]) @@ -477,6 +482,7 @@ class PrmtopLoader(object): typ1 = atomTypeIndexes[iAtom] - 1 typ2 = atomTypeIndexes[lAtom] - 1 idx = nbidx[numTypes*typ1+typ2] - 1 + if idx < 0: continue a = parm_acoef[idx] b = parm_bcoef[idx] try: @@ -870,6 +876,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode for i in range(numTypes): for j in range(numTypes): idx = nbidx[numTypes*i+j] - 1 + if idx < 0: continue acoef[i+numTypes*j] = sqrt(parm_acoef[idx]) * afac bcoef[i+numTypes*j] = parm_bcoef[idx] * bfac if has_1264: @@ -878,6 +885,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode for i in range(numTypes): for j in range(numTypes): idx = nbidx[numTypes*i+j] - 1 + if idx < 0: continue ccoef[i+numTypes*j] = parm_ccoef[idx] * cfac cforce = mm.CustomNonbondedForce('(a/r6)^2-b/r6-c/r^4; r6=r^6;' 'a=acoef(type1, type2);' @@ -911,6 +919,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode for i in range(numTypes): for j in range(numTypes): idx = nbidx[numTypes*i+j] - 1 + if idx < 0: continue ccoef[i+numTypes*j] = parm_ccoef[idx] * cfac cforce = mm.CustomNonbondedForce('-c/r^4; c=ccoef(type1, type2)') cforce.addTabulatedFunction('ccoef', -- GitLab From 474bbf7a7519783c11684108e49d64b2006406c1 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 16 Mar 2015 16:13:17 -0700 Subject: [PATCH 313/338] Added updateParametersInContext() to CMAPTorsionForce, and implemented in reference platform --- olla/include/openmm/kernels.h | 9 ++- openmmapi/include/openmm/CMAPTorsionForce.h | 13 +++- .../openmm/internal/CMAPTorsionForceImpl.h | 3 +- openmmapi/src/CMAPTorsionForce.cpp | 5 +- openmmapi/src/CMAPTorsionForceImpl.cpp | 8 ++- platforms/cuda/include/CudaKernels.h | 9 ++- platforms/cuda/include/CudaParallelKernels.h | 9 ++- platforms/cuda/src/CudaKernels.cpp | 3 + platforms/cuda/src/CudaParallelKernels.cpp | 5 ++ platforms/opencl/include/OpenCLKernels.h | 9 ++- .../opencl/include/OpenCLParallelKernels.h | 9 ++- platforms/opencl/src/OpenCLKernels.cpp | 3 + .../opencl/src/OpenCLParallelKernels.cpp | 5 ++ .../reference/include/ReferenceKernels.h | 9 ++- platforms/reference/src/ReferenceKernels.cpp | 36 ++++++++++- .../tests/TestReferenceCMAPTorsionForce.cpp | 62 ++++++++++++++++++- 16 files changed, 183 insertions(+), 14 deletions(-) diff --git a/olla/include/openmm/kernels.h b/olla/include/openmm/kernels.h index f7cd2773e..484448586 100644 --- a/olla/include/openmm/kernels.h +++ b/olla/include/openmm/kernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2012 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -494,6 +494,13 @@ public: * @return the potential energy due to the force */ virtual double execute(ContextImpl& context, bool includeForces, bool includeEnergy) = 0; + /** + * Copy changed parameters over to a context. + * + * @param context the context to copy parameters to + * @param force the CMAPTorsionForce to copy the parameters from + */ + virtual void copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) = 0; }; /** diff --git a/openmmapi/include/openmm/CMAPTorsionForce.h b/openmmapi/include/openmm/CMAPTorsionForce.h index 1288f4773..494b0b351 100644 --- a/openmmapi/include/openmm/CMAPTorsionForce.h +++ b/openmmapi/include/openmm/CMAPTorsionForce.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -148,6 +148,17 @@ public: * @param b4 the index of the fourth particle forming the second torsion */ void setTorsionParameters(int index, int map, int a1, int a2, int a3, int a4, int b1, int b2, int b3, int b4); + /** + * Update the map and torsion parameters in a Context to match those stored in this Force object. This method provides + * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. + * Simply call setMapParameters() and setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() + * to copy them over to the Context. + * + * The only information that can be updated with this method is the energy values for a map, and the map index + * for a torsion. The size of a map and the set of particles involved in a torsion cannot be changed. Also, + * new bonds and torsions cannot be added. + */ + void updateParametersInContext(Context& context); /** * Returns whether or not this force makes use of periodic boundary * conditions. diff --git a/openmmapi/include/openmm/internal/CMAPTorsionForceImpl.h b/openmmapi/include/openmm/internal/CMAPTorsionForceImpl.h index c3b976c99..c342541b3 100644 --- a/openmmapi/include/openmm/internal/CMAPTorsionForceImpl.h +++ b/openmmapi/include/openmm/internal/CMAPTorsionForceImpl.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2010 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -60,6 +60,7 @@ public: return std::map(); // This force field doesn't define any parameters. } std::vector getKernelNames(); + void updateParametersInContext(ContextImpl& context); /** * Given the energy values for a map, compute the spline coefficients at each point of the map. */ diff --git a/openmmapi/src/CMAPTorsionForce.cpp b/openmmapi/src/CMAPTorsionForce.cpp index 9ea149323..6afd0ba5d 100644 --- a/openmmapi/src/CMAPTorsionForce.cpp +++ b/openmmapi/src/CMAPTorsionForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -96,3 +96,6 @@ ForceImpl* CMAPTorsionForce::createImpl() const { return new CMAPTorsionForceImpl(*this); } +void CMAPTorsionForce::updateParametersInContext(Context& context) { + dynamic_cast(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); +} diff --git a/openmmapi/src/CMAPTorsionForceImpl.cpp b/openmmapi/src/CMAPTorsionForceImpl.cpp index 249dac206..48910ab09 100644 --- a/openmmapi/src/CMAPTorsionForceImpl.cpp +++ b/openmmapi/src/CMAPTorsionForceImpl.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -154,4 +154,8 @@ void CMAPTorsionForceImpl::calcMapDerivatives(int size, const vector& en } } } -} \ No newline at end of file +} + +void CMAPTorsionForceImpl::updateParametersInContext(ContextImpl& context) { + kernel.getAs().copyParametersToContext(context, owner); +} diff --git a/platforms/cuda/include/CudaKernels.h b/platforms/cuda/include/CudaKernels.h index 2d97a82a6..93cda1a6c 100644 --- a/platforms/cuda/include/CudaKernels.h +++ b/platforms/cuda/include/CudaKernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -520,6 +520,13 @@ public: * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); + /** + * Copy changed parameters over to a context. + * + * @param context the context to copy parameters to + * @param force the CMAPTorsionForce to copy the parameters from + */ + void copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force); private: int numTorsions; bool hasInitializedKernel; diff --git a/platforms/cuda/include/CudaParallelKernels.h b/platforms/cuda/include/CudaParallelKernels.h index 6c2498b9b..f80cca43d 100644 --- a/platforms/cuda/include/CudaParallelKernels.h +++ b/platforms/cuda/include/CudaParallelKernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2011-2013 Stanford University and the Authors. * + * Portions copyright (c) 2011-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -345,6 +345,13 @@ public: * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); + /** + * Copy changed parameters over to a context. + * + * @param context the context to copy parameters to + * @param force the CMAPTorsionForce to copy the parameters from + */ + void copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force); private: class Task; CudaPlatform::PlatformData& data; diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 9dab83c75..007a8ff29 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1166,6 +1166,9 @@ double CudaCalcCMAPTorsionForceKernel::execute(ContextImpl& context, bool includ return 0.0; } +void CudaCalcCMAPTorsionForceKernel::copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) { +} + class CudaCustomTorsionForceInfo : public CudaForceInfo { public: CudaCustomTorsionForceInfo(const CustomTorsionForce& force) : force(force) { diff --git a/platforms/cuda/src/CudaParallelKernels.cpp b/platforms/cuda/src/CudaParallelKernels.cpp index 6c024cea8..97c03a1c4 100644 --- a/platforms/cuda/src/CudaParallelKernels.cpp +++ b/platforms/cuda/src/CudaParallelKernels.cpp @@ -536,6 +536,11 @@ double CudaParallelCalcCMAPTorsionForceKernel::execute(ContextImpl& context, boo return 0.0; } +void CudaParallelCalcCMAPTorsionForceKernel::copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) { + for (int i = 0; i < (int) kernels.size(); i++) + getKernel(i).copyParametersToContext(context, force); +} + class CudaParallelCalcCustomTorsionForceKernel::Task : public CudaContext::WorkTask { public: Task(ContextImpl& context, CudaCalcCustomTorsionForceKernel& kernel, bool includeForce, diff --git a/platforms/opencl/include/OpenCLKernels.h b/platforms/opencl/include/OpenCLKernels.h index 5331c9188..08d5955fe 100644 --- a/platforms/opencl/include/OpenCLKernels.h +++ b/platforms/opencl/include/OpenCLKernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -498,6 +498,13 @@ public: * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); + /** + * Copy changed parameters over to a context. + * + * @param context the context to copy parameters to + * @param force the CMAPTorsionForce to copy the parameters from + */ + void copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force); private: int numTorsions; bool hasInitializedKernel; diff --git a/platforms/opencl/include/OpenCLParallelKernels.h b/platforms/opencl/include/OpenCLParallelKernels.h index e626ec3f0..b1de99942 100644 --- a/platforms/opencl/include/OpenCLParallelKernels.h +++ b/platforms/opencl/include/OpenCLParallelKernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2011-2013 Stanford University and the Authors. * + * Portions copyright (c) 2011-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -344,6 +344,13 @@ public: * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); + /** + * Copy changed parameters over to a context. + * + * @param context the context to copy parameters to + * @param force the CMAPTorsionForce to copy the parameters from + */ + void copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force); private: class Task; OpenCLPlatform::PlatformData& data; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 13cde63b3..88dd22d85 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1164,6 +1164,9 @@ double OpenCLCalcCMAPTorsionForceKernel::execute(ContextImpl& context, bool incl return 0.0; } +void OpenCLCalcCMAPTorsionForceKernel::copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) { +} + class OpenCLCustomTorsionForceInfo : public OpenCLForceInfo { public: OpenCLCustomTorsionForceInfo(const CustomTorsionForce& force) : OpenCLForceInfo(0), force(force) { diff --git a/platforms/opencl/src/OpenCLParallelKernels.cpp b/platforms/opencl/src/OpenCLParallelKernels.cpp index b81a3f48c..1e5b5226e 100644 --- a/platforms/opencl/src/OpenCLParallelKernels.cpp +++ b/platforms/opencl/src/OpenCLParallelKernels.cpp @@ -492,6 +492,11 @@ double OpenCLParallelCalcCMAPTorsionForceKernel::execute(ContextImpl& context, b return 0.0; } +void OpenCLParallelCalcCMAPTorsionForceKernel::copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) { + for (int i = 0; i < (int) kernels.size(); i++) + getKernel(i).copyParametersToContext(context, force); +} + class OpenCLParallelCalcCustomTorsionForceKernel::Task : public OpenCLContext::WorkTask { public: Task(ContextImpl& context, OpenCLCalcCustomTorsionForceKernel& kernel, bool includeForce, diff --git a/platforms/reference/include/ReferenceKernels.h b/platforms/reference/include/ReferenceKernels.h index 8c047f86d..e064fd76d 100644 --- a/platforms/reference/include/ReferenceKernels.h +++ b/platforms/reference/include/ReferenceKernels.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -493,6 +493,13 @@ public: * @return the potential energy due to the force */ double execute(ContextImpl& context, bool includeForces, bool includeEnergy); + /** + * Copy changed parameters over to a context. + * + * @param context the context to copy parameters to + * @param force the CMAPTorsionForce to copy the parameters from + */ + void copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force); private: std::vector > > coeff; std::vector torsionMaps; diff --git a/platforms/reference/src/ReferenceKernels.cpp b/platforms/reference/src/ReferenceKernels.cpp index 834cfd104..41fcbf417 100644 --- a/platforms/reference/src/ReferenceKernels.cpp +++ b/platforms/reference/src/ReferenceKernels.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2008-2013 Stanford University and the Authors. * + * Portions copyright (c) 2008-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -710,6 +710,40 @@ double ReferenceCalcCMAPTorsionForceKernel::execute(ContextImpl& context, bool i return totalEnergy; } +void ReferenceCalcCMAPTorsionForceKernel::copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) { + int numMaps = force.getNumMaps(); + int numTorsions = force.getNumTorsions(); + if (coeff.size() != numMaps) + throw OpenMMException("updateParametersInContext: The number of maps has changed"); + if (torsionMaps.size() != numTorsions) + throw OpenMMException("updateParametersInContext: The number of CMAP torsions has changed"); + + // Update the maps. + + vector energy; + vector > c; + for (int i = 0; i < numMaps; i++) { + int size; + force.getMapParameters(i, size, energy); + if (coeff[i].size() != size*size) + throw OpenMMException("updateParametersInContext: The size of a map has changed"); + CMAPTorsionForceImpl::calcMapDerivatives(size, energy, c); + for (int j = 0; j < size*size; j++) + for (int k = 0; k < 16; k++) + coeff[i][j][k] = c[j][k]; + } + + // Update the indices. + + for (int i = 0; i < numTorsions; i++) { + int index[8]; + force.getTorsionParameters(i, torsionMaps[i], index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7]); + for (int j = 0; j < 8; j++) + if (index[j] != torsionIndices[i][j]) + throw OpenMMException("updateParametersInContext: The set of particles in a CMAP torsion has changed"); + } +} + ReferenceCalcCustomTorsionForceKernel::~ReferenceCalcCustomTorsionForceKernel() { disposeIntArray(torsionIndexArray, numTorsions); disposeRealArray(torsionParamArray, numTorsions); diff --git a/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp b/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp index f88e51d94..f0e722365 100644 --- a/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp +++ b/platforms/reference/tests/TestReferenceCMAPTorsionForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -48,6 +48,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testCMAPTorsions() { @@ -56,7 +58,6 @@ void testCMAPTorsions() { // Create two systems: one with a pair of periodic torsions, and one with a CMAP torsion // that approximates the same force. - ReferencePlatform platform; System system1; for (int i = 0; i < 5; i++) system1.addParticle(1.0); @@ -108,9 +109,66 @@ void testCMAPTorsions() { } } +void testChangingParameters() { + // Create a system with two maps and one torsion. + + const int mapSize = 8; + System system; + for (int i = 0; i < 5; i++) + system.addParticle(1.0); + CMAPTorsionForce* cmap = new CMAPTorsionForce(); + vector mapEnergy1(mapSize*mapSize); + vector mapEnergy2(mapSize*mapSize); + for (int i = 0; i < mapSize; i++) { + double angle1 = i*2*M_PI/mapSize; + double energy1 = cos(angle1); + for (int j = 0; j < mapSize; j++) { + double angle2 = j*2*M_PI/mapSize; + double energy2 = 10*sin(angle2); + mapEnergy1[i+j*mapSize] = energy1+energy2; + mapEnergy2[i+j*mapSize] = energy1-energy2; + } + } + cmap->addMap(mapSize, mapEnergy1); + cmap->addMap(mapSize, mapEnergy2); + cmap->addTorsion(0, 0, 1, 2, 3, 1, 2, 3, 4); + system.addForce(cmap); + + // Set particle positions so angle1=0 and angle2=PI/4. + + vector positions(5); + positions[0] = Vec3(0, 0, 1); + positions[1] = Vec3(0, 0, 0); + positions[2] = Vec3(1, 0, 0); + positions[3] = Vec3(1, 0, 1); + positions[4] = Vec3(0.5, -0.5, 1); + VerletIntegrator integrator(0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + + // Check that the energy is correct. + + double energy = context.getState(State::Energy).getPotentialEnergy(); + ASSERT_EQUAL_TOL(1+10*sin(M_PI/4), energy, 1e-5); + + // Modify the parameters. + + cmap->setTorsionParameters(0, 1, 0, 1, 2, 3, 1, 2, 3, 4); + for (int i = 0; i < mapSize*mapSize; i++) + mapEnergy2[i] *= 2.0; + cmap->setMapParameters(1, mapSize, mapEnergy2); + cmap->updateParametersInContext(context); + + // See if the results are correct. + + energy = context.getState(State::Energy).getPotentialEnergy(); + ASSERT_EQUAL_TOL(2-20*sin(M_PI/4), energy, 1e-5); +} + int main() { try { testCMAPTorsions(); + testChangingParameters(); } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From 6dc2f9a8cec35c7590cd69893818ef6748f2bcc8 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 16 Mar 2015 17:09:17 -0700 Subject: [PATCH 314/338] CUDA and OpenCL implementations of CMAPTorsionForce::updateParametersInContext() --- platforms/cuda/include/CudaKernels.h | 1 + platforms/cuda/src/CudaKernels.cpp | 42 ++++++++++++- .../cuda/tests/TestCudaCMAPTorsionForce.cpp | 59 ++++++++++++++++++- platforms/opencl/include/OpenCLKernels.h | 1 + platforms/opencl/src/OpenCLKernels.cpp | 42 ++++++++++++- .../tests/TestOpenCLCMAPTorsionForce.cpp | 59 ++++++++++++++++++- 6 files changed, 200 insertions(+), 4 deletions(-) diff --git a/platforms/cuda/include/CudaKernels.h b/platforms/cuda/include/CudaKernels.h index 93cda1a6c..fba24700f 100644 --- a/platforms/cuda/include/CudaKernels.h +++ b/platforms/cuda/include/CudaKernels.h @@ -532,6 +532,7 @@ private: bool hasInitializedKernel; CudaContext& cu; const System& system; + std::vector mapPositionsVec; CudaArray* coefficients; CudaArray* mapPositions; CudaArray* torsionMaps; diff --git a/platforms/cuda/src/CudaKernels.cpp b/platforms/cuda/src/CudaKernels.cpp index 007a8ff29..9ca628c0d 100644 --- a/platforms/cuda/src/CudaKernels.cpp +++ b/platforms/cuda/src/CudaKernels.cpp @@ -1127,7 +1127,7 @@ void CudaCalcCMAPTorsionForceKernel::initialize(const System& system, const CMAP return; int numMaps = force.getNumMaps(); vector coeffVec; - vector mapPositionsVec(numMaps); + mapPositionsVec.resize(numMaps); vector energy; vector > c; int currentPosition = 0; @@ -1167,6 +1167,46 @@ double CudaCalcCMAPTorsionForceKernel::execute(ContextImpl& context, bool includ } void CudaCalcCMAPTorsionForceKernel::copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) { + int numMaps = force.getNumMaps(); + int numContexts = cu.getPlatformData().contexts.size(); + int startIndex = cu.getContextIndex()*force.getNumTorsions()/numContexts; + int endIndex = (cu.getContextIndex()+1)*force.getNumTorsions()/numContexts; + numTorsions = endIndex-startIndex; + if (mapPositions->getSize() != numMaps) + throw OpenMMException("updateParametersInContext: The number of maps has changed"); + if (torsionMaps->getSize() != numTorsions) + throw OpenMMException("updateParametersInContext: The number of CMAP torsions has changed"); + + // Update the maps. + + vector coeffVec; + vector energy; + vector > c; + int currentPosition = 0; + for (int i = 0; i < numMaps; i++) { + int size; + force.getMapParameters(i, size, energy); + if (size != mapPositionsVec[i].y) + throw OpenMMException("updateParametersInContext: The size of a map has changed"); + CMAPTorsionForceImpl::calcMapDerivatives(size, energy, c); + currentPosition += 4*size*size; + for (int j = 0; j < size*size; j++) { + coeffVec.push_back(make_float4((float) c[j][0], (float) c[j][1], (float) c[j][2], (float) c[j][3])); + coeffVec.push_back(make_float4((float) c[j][4], (float) c[j][5], (float) c[j][6], (float) c[j][7])); + coeffVec.push_back(make_float4((float) c[j][8], (float) c[j][9], (float) c[j][10], (float) c[j][11])); + coeffVec.push_back(make_float4((float) c[j][12], (float) c[j][13], (float) c[j][14], (float) c[j][15])); + } + } + coefficients->upload(coeffVec); + + // Update the indices. + + vector torsionMapsVec(numTorsions); + for (int i = 0; i < numTorsions; i++) { + int index[8]; + force.getTorsionParameters(i, torsionMapsVec[i], index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7]); + } + torsionMaps->upload(torsionMapsVec); } class CudaCustomTorsionForceInfo : public CudaForceInfo { diff --git a/platforms/cuda/tests/TestCudaCMAPTorsionForce.cpp b/platforms/cuda/tests/TestCudaCMAPTorsionForce.cpp index 8f5aecc71..6a95ade0f 100644 --- a/platforms/cuda/tests/TestCudaCMAPTorsionForce.cpp +++ b/platforms/cuda/tests/TestCudaCMAPTorsionForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010-2012 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -105,11 +105,68 @@ void testCMAPTorsions() { } } +void testChangingParameters() { + // Create a system with two maps and one torsion. + + const int mapSize = 8; + System system; + for (int i = 0; i < 5; i++) + system.addParticle(1.0); + CMAPTorsionForce* cmap = new CMAPTorsionForce(); + vector mapEnergy1(mapSize*mapSize); + vector mapEnergy2(mapSize*mapSize); + for (int i = 0; i < mapSize; i++) { + double angle1 = i*2*M_PI/mapSize; + double energy1 = cos(angle1); + for (int j = 0; j < mapSize; j++) { + double angle2 = j*2*M_PI/mapSize; + double energy2 = 10*sin(angle2); + mapEnergy1[i+j*mapSize] = energy1+energy2; + mapEnergy2[i+j*mapSize] = energy1-energy2; + } + } + cmap->addMap(mapSize, mapEnergy1); + cmap->addMap(mapSize, mapEnergy2); + cmap->addTorsion(0, 0, 1, 2, 3, 1, 2, 3, 4); + system.addForce(cmap); + + // Set particle positions so angle1=0 and angle2=PI/4. + + vector positions(5); + positions[0] = Vec3(0, 0, 1); + positions[1] = Vec3(0, 0, 0); + positions[2] = Vec3(1, 0, 0); + positions[3] = Vec3(1, 0, 1); + positions[4] = Vec3(0.5, -0.5, 1); + VerletIntegrator integrator(0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + + // Check that the energy is correct. + + double energy = context.getState(State::Energy).getPotentialEnergy(); + ASSERT_EQUAL_TOL(1+10*sin(M_PI/4), energy, 1e-5); + + // Modify the parameters. + + cmap->setTorsionParameters(0, 1, 0, 1, 2, 3, 1, 2, 3, 4); + for (int i = 0; i < mapSize*mapSize; i++) + mapEnergy2[i] *= 2.0; + cmap->setMapParameters(1, mapSize, mapEnergy2); + cmap->updateParametersInContext(context); + + // See if the results are correct. + + energy = context.getState(State::Energy).getPotentialEnergy(); + ASSERT_EQUAL_TOL(2-20*sin(M_PI/4), energy, 1e-5); +} + int main(int argc, char* argv[]) { try { if (argc > 1) platform.setPropertyDefaultValue("CudaPrecision", string(argv[1])); testCMAPTorsions(); + testChangingParameters(); } catch(const exception& e) { cout << "exception: " << e.what() << endl; diff --git a/platforms/opencl/include/OpenCLKernels.h b/platforms/opencl/include/OpenCLKernels.h index 08d5955fe..72f4f0072 100644 --- a/platforms/opencl/include/OpenCLKernels.h +++ b/platforms/opencl/include/OpenCLKernels.h @@ -510,6 +510,7 @@ private: bool hasInitializedKernel; OpenCLContext& cl; const System& system; + std::vector mapPositionsVec; OpenCLArray* coefficients; OpenCLArray* mapPositions; OpenCLArray* torsionMaps; diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 88dd22d85..216e0bbf4 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1125,7 +1125,7 @@ void OpenCLCalcCMAPTorsionForceKernel::initialize(const System& system, const CM return; int numMaps = force.getNumMaps(); vector coeffVec; - vector mapPositionsVec(numMaps); + mapPositionsVec.resize(numMaps); vector energy; vector > c; int currentPosition = 0; @@ -1165,6 +1165,46 @@ double OpenCLCalcCMAPTorsionForceKernel::execute(ContextImpl& context, bool incl } void OpenCLCalcCMAPTorsionForceKernel::copyParametersToContext(ContextImpl& context, const CMAPTorsionForce& force) { + int numMaps = force.getNumMaps(); + int numContexts = cl.getPlatformData().contexts.size(); + int startIndex = cl.getContextIndex()*force.getNumTorsions()/numContexts; + int endIndex = (cl.getContextIndex()+1)*force.getNumTorsions()/numContexts; + numTorsions = endIndex-startIndex; + if (mapPositions->getSize() != numMaps) + throw OpenMMException("updateParametersInContext: The number of maps has changed"); + if (torsionMaps->getSize() != numTorsions) + throw OpenMMException("updateParametersInContext: The number of CMAP torsions has changed"); + + // Update the maps. + + vector coeffVec; + vector energy; + vector > c; + int currentPosition = 0; + for (int i = 0; i < numMaps; i++) { + int size; + force.getMapParameters(i, size, energy); + if (size != mapPositionsVec[i].y) + throw OpenMMException("updateParametersInContext: The size of a map has changed"); + CMAPTorsionForceImpl::calcMapDerivatives(size, energy, c); + currentPosition += 4*size*size; + for (int j = 0; j < size*size; j++) { + coeffVec.push_back(mm_float4((float) c[j][0], (float) c[j][1], (float) c[j][2], (float) c[j][3])); + coeffVec.push_back(mm_float4((float) c[j][4], (float) c[j][5], (float) c[j][6], (float) c[j][7])); + coeffVec.push_back(mm_float4((float) c[j][8], (float) c[j][9], (float) c[j][10], (float) c[j][11])); + coeffVec.push_back(mm_float4((float) c[j][12], (float) c[j][13], (float) c[j][14], (float) c[j][15])); + } + } + coefficients->upload(coeffVec); + + // Update the indices. + + vector torsionMapsVec(numTorsions); + for (int i = 0; i < numTorsions; i++) { + int index[8]; + force.getTorsionParameters(i, torsionMapsVec[i], index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7]); + } + torsionMaps->upload(torsionMapsVec); } class OpenCLCustomTorsionForceInfo : public OpenCLForceInfo { diff --git a/platforms/opencl/tests/TestOpenCLCMAPTorsionForce.cpp b/platforms/opencl/tests/TestOpenCLCMAPTorsionForce.cpp index 78e357252..10deec857 100644 --- a/platforms/opencl/tests/TestOpenCLCMAPTorsionForce.cpp +++ b/platforms/opencl/tests/TestOpenCLCMAPTorsionForce.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -105,11 +105,68 @@ void testCMAPTorsions() { } } +void testChangingParameters() { + // Create a system with two maps and one torsion. + + const int mapSize = 8; + System system; + for (int i = 0; i < 5; i++) + system.addParticle(1.0); + CMAPTorsionForce* cmap = new CMAPTorsionForce(); + vector mapEnergy1(mapSize*mapSize); + vector mapEnergy2(mapSize*mapSize); + for (int i = 0; i < mapSize; i++) { + double angle1 = i*2*M_PI/mapSize; + double energy1 = cos(angle1); + for (int j = 0; j < mapSize; j++) { + double angle2 = j*2*M_PI/mapSize; + double energy2 = 10*sin(angle2); + mapEnergy1[i+j*mapSize] = energy1+energy2; + mapEnergy2[i+j*mapSize] = energy1-energy2; + } + } + cmap->addMap(mapSize, mapEnergy1); + cmap->addMap(mapSize, mapEnergy2); + cmap->addTorsion(0, 0, 1, 2, 3, 1, 2, 3, 4); + system.addForce(cmap); + + // Set particle positions so angle1=0 and angle2=PI/4. + + vector positions(5); + positions[0] = Vec3(0, 0, 1); + positions[1] = Vec3(0, 0, 0); + positions[2] = Vec3(1, 0, 0); + positions[3] = Vec3(1, 0, 1); + positions[4] = Vec3(0.5, -0.5, 1); + VerletIntegrator integrator(0.01); + Context context(system, integrator, platform); + context.setPositions(positions); + + // Check that the energy is correct. + + double energy = context.getState(State::Energy).getPotentialEnergy(); + ASSERT_EQUAL_TOL(1+10*sin(M_PI/4), energy, 1e-5); + + // Modify the parameters. + + cmap->setTorsionParameters(0, 1, 0, 1, 2, 3, 1, 2, 3, 4); + for (int i = 0; i < mapSize*mapSize; i++) + mapEnergy2[i] *= 2.0; + cmap->setMapParameters(1, mapSize, mapEnergy2); + cmap->updateParametersInContext(context); + + // See if the results are correct. + + energy = context.getState(State::Energy).getPotentialEnergy(); + ASSERT_EQUAL_TOL(2-20*sin(M_PI/4), energy, 1e-5); +} + int main(int argc, char* argv[]) { try { if (argc > 1) platform.setPropertyDefaultValue("OpenCLPrecision", string(argv[1])); testCMAPTorsions(); + testChangingParameters(); } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From e4ccca2ed69059fc330dd2a0b006c12bc8d27ec3 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 19 Mar 2015 11:47:12 -0400 Subject: [PATCH 315/338] Very simple change to get ~20% performance improvement in reading Amber prmtop files. --- .../openmm/app/internal/amber_file_parser.py | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 730a02743..8e7245d0b 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -122,21 +122,22 @@ class PrmtopLoader(object): with open(inFilename, 'r') as fIn: for line in fIn: - if line.startswith('%VERSION'): - tag, self._prmtopVersion = line.rstrip().split(None, 1) - elif line.startswith('%FLAG'): - tag, flag = line.rstrip().split(None, 1) - self._flags.append(flag) - self._raw_data[flag] = [] - elif line.startswith('%FORMAT'): - format = line.rstrip() - index0=format.index('(') - index1=format.index(')') - format = format[index0+1:index1] - m = FORMAT_RE_PATTERN.search(format) - self._raw_format[self._flags[-1]] = (format, m.group(1), m.group(2), m.group(3), m.group(4)) - elif line.startswith('%COMMENT'): - continue + if line[0] == '%': + if line.startswith('%VERSION'): + tag, self._prmtopVersion = line.rstrip().split(None, 1) + elif line.startswith('%FLAG'): + tag, flag = line.rstrip().split(None, 1) + self._flags.append(flag) + self._raw_data[flag] = [] + elif line.startswith('%FORMAT'): + format = line.rstrip() + index0=format.index('(') + index1=format.index(')') + format = format[index0+1:index1] + m = FORMAT_RE_PATTERN.search(format) + self._raw_format[self._flags[-1]] = (format, m.group(1), m.group(2), int(m.group(3)), m.group(4)) + elif line.startswith('%COMMENT'): + continue elif self._flags \ and 'TITLE'==self._flags[-1] \ and not self._raw_data['TITLE']: @@ -144,8 +145,7 @@ class PrmtopLoader(object): else: flag=self._flags[-1] (format, numItems, itemType, - itemLength, itemPrecision) = self._getFormat(flag) - iLength=int(itemLength) + iLength, itemPrecision) = self._getFormat(flag) line = line.rstrip() for index in range(0, len(line), iLength): item = line[index:index+iLength] -- GitLab From eb215a4d2fb578de17dfb57e722aa6d9c929c32d Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 19 Mar 2015 12:53:22 -0400 Subject: [PATCH 316/338] Fix AmberPrmtopFile's handling of HAngles when gaff is used. Adds a test for it as well. --- .../simtk/openmm/app/amberprmtopfile.py | 5 +- .../openmm/app/internal/amber_file_parser.py | 19 +- wrappers/python/tests/TestAmberPrmtopFile.py | 19 + wrappers/python/tests/systems/gaffwat.parm7 | 6118 +++++++++++++++++ 4 files changed, 6151 insertions(+), 10 deletions(-) create mode 100644 wrappers/python/tests/systems/gaffwat.parm7 diff --git a/wrappers/python/simtk/openmm/app/amberprmtopfile.py b/wrappers/python/simtk/openmm/app/amberprmtopfile.py index 04c05c062..c7c854a80 100644 --- a/wrappers/python/simtk/openmm/app/amberprmtopfile.py +++ b/wrappers/python/simtk/openmm/app/amberprmtopfile.py @@ -73,9 +73,8 @@ class AmberPrmtopFile(object): def __init__(self, file): """Load a prmtop file.""" - top = Topology() ## The Topology read from the prmtop file - self.topology = top + self.topology = top = Topology() self.elements = [] # Load the prmtop file @@ -229,7 +228,7 @@ class AmberPrmtopFile(object): elif implicitSolvent is None: implicitSolventKappa = 0.0 - sys = amber_file_parser.readAmberSystem(prmtop_loader=self._prmtop, shake=constraintString, + sys = amber_file_parser.readAmberSystem(self.topology, prmtop_loader=self._prmtop, shake=constraintString, nonbondedCutoff=nonbondedCutoff, nonbondedMethod=methodMap[nonbondedMethod], flexibleConstraints=False, gbmodel=implicitString, soluteDielectric=soluteDielectric, solventDielectric=solventDielectric, implicitSolventKappa=implicitSolventKappa, diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index 8e7245d0b..bc84e63e0 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -651,7 +651,7 @@ class PrmtopLoader(object): # AMBER System builder (based on, but not identical to, systemManager from 'zander') #============================================================================================= -def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmodel=None, +def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=None, gbmodel=None, soluteDielectric=1.0, solventDielectric=78.5, implicitSolventKappa=0.0*(1/units.nanometer), nonbondedCutoff=None, nonbondedMethod='NoCutoff', scee=None, scnb=None, mm=None, verbose=False, @@ -659,6 +659,9 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode """ Create an OpenMM System from an Amber prmtop file. + REQUIRED ARGUMENT + topology (forcefield.Topology) The topology for the system that is about + to be created ARGUMENTS (specify one or the other, but not both) prmtop_filename (String) - name of Amber prmtop file (new-style only) prmtop_loader (PrmtopLoader) - the loaded prmtop file @@ -739,7 +742,7 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode system.addParticle(mass) # Add constraints. - isWater = [prmtop.getResidueLabel(i) in ('WAT', 'TP4', 'TP5', 'T4E') for i in range(prmtop.getNumAtoms())] + isWater = [prmtop.getResidueLabel(i) in ('WAT', 'HOH', 'TP4', 'TP5', 'T4E') for i in range(prmtop.getNumAtoms())] if shake in ('h-bonds', 'all-bonds', 'h-angles'): for (iAtom, jAtom, k, rMin) in prmtop.getBondsWithH(): system.addConstraint(iAtom, jAtom, rMin) @@ -774,13 +777,15 @@ def readAmberSystem(prmtop_filename=None, prmtop_loader=None, shake=None, gbmode distance = c[2].value_in_unit(units.nanometer) atomConstraints[c[0]].append((c[1], distance)) atomConstraints[c[1]].append((c[0], distance)) + topatoms = list(topology.atoms()) for (iAtom, jAtom, kAtom, k, aMin) in prmtop.getAngles(): if shake == 'h-angles': - type1 = prmtop.getAtomType(iAtom) - type2 = prmtop.getAtomType(jAtom) - type3 = prmtop.getAtomType(kAtom) - numH = len([type for type in (type1, type3) if type.startswith('H')]) - constrained = (numH == 2 or (numH == 1 and type2.startswith('O'))) + atomI = topatoms[iAtom] + atomJ = topatoms[jAtom] + atomK = topatoms[kAtom] + numH = ((atomI.element.atomic_number == 1) + (atomJ.element.atomic_number == 1) + + (atomK.element.atomic_number == 1)) + constrained = (numH == 2 or (numH == 1 and atomK.element is elem.oxygen)) else: constrained = False if constrained: diff --git a/wrappers/python/tests/TestAmberPrmtopFile.py b/wrappers/python/tests/TestAmberPrmtopFile.py index 5c32bd636..45803b04e 100644 --- a/wrappers/python/tests/TestAmberPrmtopFile.py +++ b/wrappers/python/tests/TestAmberPrmtopFile.py @@ -12,6 +12,7 @@ prmtop2 = AmberPrmtopFile('systems/alanine-dipeptide-implicit.prmtop') prmtop3 = AmberPrmtopFile('systems/ff14ipq.parm7') prmtop4 = AmberPrmtopFile('systems/Mg_water.prmtop') prmtop5 = AmberPrmtopFile('systems/tz2.truncoct.parm7') +prmtop6 = AmberPrmtopFile('systems/gaffwat.parm7') inpcrd3 = AmberInpcrdFile('systems/ff14ipq.rst7') inpcrd4 = AmberInpcrdFile('systems/Mg_water.inpcrd') @@ -200,6 +201,24 @@ class TestAmberPrmtopFile(unittest.TestCase): # Amber using this force field. self.assertAlmostEqual(-7042.3903307/ene, 1, places=3) + def test_HAngle(self): + """ Test that HAngle constraints are properly handled for all hydrogens """ + system = prmtop6.createSystem(nonbondedMethod=PME, + nonbondedCutoff=1*nanometers, + constraints=HBonds) + self.assertEqual(system.getForce(0).getNumBonds(), 0) + self.assertEqual(system.getNumParticles(), 3000) + self.assertEqual(system.getNumConstraints(), 2000) + self.assertEqual(system.getForce(1).getNumAngles(), 1000) + + system = prmtop6.createSystem(nonbondedMethod=PME, + nonbondedCutoff=1*nanometers, + constraints=HAngles) + self.assertEqual(system.getForce(0).getNumBonds(), 0) + self.assertEqual(system.getNumParticles(), 3000) + self.assertEqual(system.getNumConstraints(), 3000) + self.assertEqual(system.getForce(1).getNumAngles(), 0) + def test_LJ1264(self): """Test prmtop with 12-6-4 vdW potential implemented""" system = prmtop4.createSystem(nonbondedMethod=PME, diff --git a/wrappers/python/tests/systems/gaffwat.parm7 b/wrappers/python/tests/systems/gaffwat.parm7 new file mode 100644 index 000000000..3eeb9eb84 --- /dev/null +++ b/wrappers/python/tests/systems/gaffwat.parm7 @@ -0,0 +1,6118 @@ +%VERSION VERSION_STAMP = V0001.000 DATE = 03/15/15 13:23:58 +%FLAG TITLE +%FORMAT(20a4) +default_name +%FLAG POINTERS +%FORMAT(10I8) + 3000 2 2000 0 1000 0 0 0 0 0 + 4000 1000 0 0 0 1 1 0 2 0 + 0 0 0 0 0 0 0 1 3 0 + 0 +%FLAG ATOM_NAME +%FORMAT(20a4) +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 +H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 +H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 O1 H1 H2 +%FLAG CHARGE +%FORMAT(5E16.8) + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 + -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 + 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 -1.43045055E+01 + 7.15225275E+00 7.15225275E+00 -1.43045055E+01 7.15225275E+00 7.15225275E+00 +%FLAG ATOMIC_NUMBER +%FORMAT(10I8) + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 + 8 1 1 8 1 1 8 1 1 8 + 1 1 8 1 1 8 1 1 8 1 + 1 8 1 1 8 1 1 8 1 1 +%FLAG MASS +%FORMAT(5E16.8) + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 + 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 + 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 1.60000000E+01 + 1.00800000E+00 1.00800000E+00 1.60000000E+01 1.00800000E+00 1.00800000E+00 +%FLAG ATOM_TYPE_INDEX +%FORMAT(10I8) + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 + 1 2 2 1 2 2 1 2 2 1 + 2 2 1 2 2 1 2 2 1 2 + 2 1 2 2 1 2 2 1 2 2 +%FLAG NUMBER_EXCLUDED_ATOMS +%FORMAT(10I8) + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 + 2 1 1 2 1 1 2 1 1 2 + 1 1 2 1 1 2 1 1 2 1 + 1 2 1 1 2 1 1 2 1 1 +%FLAG NONBONDED_PARM_INDEX +%FORMAT(10I8) + 1 2 2 3 +%FLAG RESIDUE_LABEL +%FORMAT(20a4) +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL MOL +%FLAG RESIDUE_POINTER +%FORMAT(10I8) + 1 4 7 10 13 16 19 22 25 28 + 31 34 37 40 43 46 49 52 55 58 + 61 64 67 70 73 76 79 82 85 88 + 91 94 97 100 103 106 109 112 115 118 + 121 124 127 130 133 136 139 142 145 148 + 151 154 157 160 163 166 169 172 175 178 + 181 184 187 190 193 196 199 202 205 208 + 211 214 217 220 223 226 229 232 235 238 + 241 244 247 250 253 256 259 262 265 268 + 271 274 277 280 283 286 289 292 295 298 + 301 304 307 310 313 316 319 322 325 328 + 331 334 337 340 343 346 349 352 355 358 + 361 364 367 370 373 376 379 382 385 388 + 391 394 397 400 403 406 409 412 415 418 + 421 424 427 430 433 436 439 442 445 448 + 451 454 457 460 463 466 469 472 475 478 + 481 484 487 490 493 496 499 502 505 508 + 511 514 517 520 523 526 529 532 535 538 + 541 544 547 550 553 556 559 562 565 568 + 571 574 577 580 583 586 589 592 595 598 + 601 604 607 610 613 616 619 622 625 628 + 631 634 637 640 643 646 649 652 655 658 + 661 664 667 670 673 676 679 682 685 688 + 691 694 697 700 703 706 709 712 715 718 + 721 724 727 730 733 736 739 742 745 748 + 751 754 757 760 763 766 769 772 775 778 + 781 784 787 790 793 796 799 802 805 808 + 811 814 817 820 823 826 829 832 835 838 + 841 844 847 850 853 856 859 862 865 868 + 871 874 877 880 883 886 889 892 895 898 + 901 904 907 910 913 916 919 922 925 928 + 931 934 937 940 943 946 949 952 955 958 + 961 964 967 970 973 976 979 982 985 988 + 991 994 997 1000 1003 1006 1009 1012 1015 1018 + 1021 1024 1027 1030 1033 1036 1039 1042 1045 1048 + 1051 1054 1057 1060 1063 1066 1069 1072 1075 1078 + 1081 1084 1087 1090 1093 1096 1099 1102 1105 1108 + 1111 1114 1117 1120 1123 1126 1129 1132 1135 1138 + 1141 1144 1147 1150 1153 1156 1159 1162 1165 1168 + 1171 1174 1177 1180 1183 1186 1189 1192 1195 1198 + 1201 1204 1207 1210 1213 1216 1219 1222 1225 1228 + 1231 1234 1237 1240 1243 1246 1249 1252 1255 1258 + 1261 1264 1267 1270 1273 1276 1279 1282 1285 1288 + 1291 1294 1297 1300 1303 1306 1309 1312 1315 1318 + 1321 1324 1327 1330 1333 1336 1339 1342 1345 1348 + 1351 1354 1357 1360 1363 1366 1369 1372 1375 1378 + 1381 1384 1387 1390 1393 1396 1399 1402 1405 1408 + 1411 1414 1417 1420 1423 1426 1429 1432 1435 1438 + 1441 1444 1447 1450 1453 1456 1459 1462 1465 1468 + 1471 1474 1477 1480 1483 1486 1489 1492 1495 1498 + 1501 1504 1507 1510 1513 1516 1519 1522 1525 1528 + 1531 1534 1537 1540 1543 1546 1549 1552 1555 1558 + 1561 1564 1567 1570 1573 1576 1579 1582 1585 1588 + 1591 1594 1597 1600 1603 1606 1609 1612 1615 1618 + 1621 1624 1627 1630 1633 1636 1639 1642 1645 1648 + 1651 1654 1657 1660 1663 1666 1669 1672 1675 1678 + 1681 1684 1687 1690 1693 1696 1699 1702 1705 1708 + 1711 1714 1717 1720 1723 1726 1729 1732 1735 1738 + 1741 1744 1747 1750 1753 1756 1759 1762 1765 1768 + 1771 1774 1777 1780 1783 1786 1789 1792 1795 1798 + 1801 1804 1807 1810 1813 1816 1819 1822 1825 1828 + 1831 1834 1837 1840 1843 1846 1849 1852 1855 1858 + 1861 1864 1867 1870 1873 1876 1879 1882 1885 1888 + 1891 1894 1897 1900 1903 1906 1909 1912 1915 1918 + 1921 1924 1927 1930 1933 1936 1939 1942 1945 1948 + 1951 1954 1957 1960 1963 1966 1969 1972 1975 1978 + 1981 1984 1987 1990 1993 1996 1999 2002 2005 2008 + 2011 2014 2017 2020 2023 2026 2029 2032 2035 2038 + 2041 2044 2047 2050 2053 2056 2059 2062 2065 2068 + 2071 2074 2077 2080 2083 2086 2089 2092 2095 2098 + 2101 2104 2107 2110 2113 2116 2119 2122 2125 2128 + 2131 2134 2137 2140 2143 2146 2149 2152 2155 2158 + 2161 2164 2167 2170 2173 2176 2179 2182 2185 2188 + 2191 2194 2197 2200 2203 2206 2209 2212 2215 2218 + 2221 2224 2227 2230 2233 2236 2239 2242 2245 2248 + 2251 2254 2257 2260 2263 2266 2269 2272 2275 2278 + 2281 2284 2287 2290 2293 2296 2299 2302 2305 2308 + 2311 2314 2317 2320 2323 2326 2329 2332 2335 2338 + 2341 2344 2347 2350 2353 2356 2359 2362 2365 2368 + 2371 2374 2377 2380 2383 2386 2389 2392 2395 2398 + 2401 2404 2407 2410 2413 2416 2419 2422 2425 2428 + 2431 2434 2437 2440 2443 2446 2449 2452 2455 2458 + 2461 2464 2467 2470 2473 2476 2479 2482 2485 2488 + 2491 2494 2497 2500 2503 2506 2509 2512 2515 2518 + 2521 2524 2527 2530 2533 2536 2539 2542 2545 2548 + 2551 2554 2557 2560 2563 2566 2569 2572 2575 2578 + 2581 2584 2587 2590 2593 2596 2599 2602 2605 2608 + 2611 2614 2617 2620 2623 2626 2629 2632 2635 2638 + 2641 2644 2647 2650 2653 2656 2659 2662 2665 2668 + 2671 2674 2677 2680 2683 2686 2689 2692 2695 2698 + 2701 2704 2707 2710 2713 2716 2719 2722 2725 2728 + 2731 2734 2737 2740 2743 2746 2749 2752 2755 2758 + 2761 2764 2767 2770 2773 2776 2779 2782 2785 2788 + 2791 2794 2797 2800 2803 2806 2809 2812 2815 2818 + 2821 2824 2827 2830 2833 2836 2839 2842 2845 2848 + 2851 2854 2857 2860 2863 2866 2869 2872 2875 2878 + 2881 2884 2887 2890 2893 2896 2899 2902 2905 2908 + 2911 2914 2917 2920 2923 2926 2929 2932 2935 2938 + 2941 2944 2947 2950 2953 2956 2959 2962 2965 2968 + 2971 2974 2977 2980 2983 2986 2989 2992 2995 2998 +%FLAG BOND_FORCE_CONSTANT +%FORMAT(5E16.8) + 3.69600000E+02 +%FLAG BOND_EQUIL_VALUE +%FORMAT(5E16.8) + 9.74000000E-01 +%FLAG ANGLE_FORCE_CONSTANT +%FORMAT(5E16.8) + 4.19300000E+01 +%FLAG ANGLE_EQUIL_VALUE +%FORMAT(5E16.8) + 1.82910584E+00 +%FLAG DIHEDRAL_FORCE_CONSTANT +%FORMAT(5E16.8) + +%FLAG DIHEDRAL_PERIODICITY +%FORMAT(5E16.8) + +%FLAG DIHEDRAL_PHASE +%FORMAT(5E16.8) + +%FLAG SCEE_SCALE_FACTOR +%FORMAT(5E16.8) + +%FLAG SCNB_SCALE_FACTOR +%FORMAT(5E16.8) + +%FLAG SOLTY +%FORMAT(5E16.8) + 0.00000000E+00 0.00000000E+00 +%FLAG LENNARD_JONES_ACOEF +%FORMAT(5E16.8) + 5.81803229E+05 0.00000000E+00 0.00000000E+00 +%FLAG LENNARD_JONES_BCOEF +%FORMAT(5E16.8) + 6.99746810E+02 0.00000000E+00 0.00000000E+00 +%FLAG BONDS_INC_HYDROGEN +%FORMAT(10I8) + 0 3 1 0 6 1 9 12 1 9 + 15 1 18 21 1 18 24 1 27 30 + 1 27 33 1 36 39 1 36 42 1 + 45 48 1 45 51 1 54 57 1 54 + 60 1 63 66 1 63 69 1 72 75 + 1 72 78 1 81 84 1 81 87 1 + 90 93 1 90 96 1 99 102 1 99 + 105 1 108 111 1 108 114 1 117 120 + 1 117 123 1 126 129 1 126 132 1 + 135 138 1 135 141 1 144 147 1 144 + 150 1 153 156 1 153 159 1 162 165 + 1 162 168 1 171 174 1 171 177 1 + 180 183 1 180 186 1 189 192 1 189 + 195 1 198 201 1 198 204 1 207 210 + 1 207 213 1 216 219 1 216 222 1 + 225 228 1 225 231 1 234 237 1 234 + 240 1 243 246 1 243 249 1 252 255 + 1 252 258 1 261 264 1 261 267 1 + 270 273 1 270 276 1 279 282 1 279 + 285 1 288 291 1 288 294 1 297 300 + 1 297 303 1 306 309 1 306 312 1 + 315 318 1 315 321 1 324 327 1 324 + 330 1 333 336 1 333 339 1 342 345 + 1 342 348 1 351 354 1 351 357 1 + 360 363 1 360 366 1 369 372 1 369 + 375 1 378 381 1 378 384 1 387 390 + 1 387 393 1 396 399 1 396 402 1 + 405 408 1 405 411 1 414 417 1 414 + 420 1 423 426 1 423 429 1 432 435 + 1 432 438 1 441 444 1 441 447 1 + 450 453 1 450 456 1 459 462 1 459 + 465 1 468 471 1 468 474 1 477 480 + 1 477 483 1 486 489 1 486 492 1 + 495 498 1 495 501 1 504 507 1 504 + 510 1 513 516 1 513 519 1 522 525 + 1 522 528 1 531 534 1 531 537 1 + 540 543 1 540 546 1 549 552 1 549 + 555 1 558 561 1 558 564 1 567 570 + 1 567 573 1 576 579 1 576 582 1 + 585 588 1 585 591 1 594 597 1 594 + 600 1 603 606 1 603 609 1 612 615 + 1 612 618 1 621 624 1 621 627 1 + 630 633 1 630 636 1 639 642 1 639 + 645 1 648 651 1 648 654 1 657 660 + 1 657 663 1 666 669 1 666 672 1 + 675 678 1 675 681 1 684 687 1 684 + 690 1 693 696 1 693 699 1 702 705 + 1 702 708 1 711 714 1 711 717 1 + 720 723 1 720 726 1 729 732 1 729 + 735 1 738 741 1 738 744 1 747 750 + 1 747 753 1 756 759 1 756 762 1 + 765 768 1 765 771 1 774 777 1 774 + 780 1 783 786 1 783 789 1 792 795 + 1 792 798 1 801 804 1 801 807 1 + 810 813 1 810 816 1 819 822 1 819 + 825 1 828 831 1 828 834 1 837 840 + 1 837 843 1 846 849 1 846 852 1 + 855 858 1 855 861 1 864 867 1 864 + 870 1 873 876 1 873 879 1 882 885 + 1 882 888 1 891 894 1 891 897 1 + 900 903 1 900 906 1 909 912 1 909 + 915 1 918 921 1 918 924 1 927 930 + 1 927 933 1 936 939 1 936 942 1 + 945 948 1 945 951 1 954 957 1 954 + 960 1 963 966 1 963 969 1 972 975 + 1 972 978 1 981 984 1 981 987 1 + 990 993 1 990 996 1 999 1002 1 999 + 1005 1 1008 1011 1 1008 1014 1 1017 1020 + 1 1017 1023 1 1026 1029 1 1026 1032 1 + 1035 1038 1 1035 1041 1 1044 1047 1 1044 + 1050 1 1053 1056 1 1053 1059 1 1062 1065 + 1 1062 1068 1 1071 1074 1 1071 1077 1 + 1080 1083 1 1080 1086 1 1089 1092 1 1089 + 1095 1 1098 1101 1 1098 1104 1 1107 1110 + 1 1107 1113 1 1116 1119 1 1116 1122 1 + 1125 1128 1 1125 1131 1 1134 1137 1 1134 + 1140 1 1143 1146 1 1143 1149 1 1152 1155 + 1 1152 1158 1 1161 1164 1 1161 1167 1 + 1170 1173 1 1170 1176 1 1179 1182 1 1179 + 1185 1 1188 1191 1 1188 1194 1 1197 1200 + 1 1197 1203 1 1206 1209 1 1206 1212 1 + 1215 1218 1 1215 1221 1 1224 1227 1 1224 + 1230 1 1233 1236 1 1233 1239 1 1242 1245 + 1 1242 1248 1 1251 1254 1 1251 1257 1 + 1260 1263 1 1260 1266 1 1269 1272 1 1269 + 1275 1 1278 1281 1 1278 1284 1 1287 1290 + 1 1287 1293 1 1296 1299 1 1296 1302 1 + 1305 1308 1 1305 1311 1 1314 1317 1 1314 + 1320 1 1323 1326 1 1323 1329 1 1332 1335 + 1 1332 1338 1 1341 1344 1 1341 1347 1 + 1350 1353 1 1350 1356 1 1359 1362 1 1359 + 1365 1 1368 1371 1 1368 1374 1 1377 1380 + 1 1377 1383 1 1386 1389 1 1386 1392 1 + 1395 1398 1 1395 1401 1 1404 1407 1 1404 + 1410 1 1413 1416 1 1413 1419 1 1422 1425 + 1 1422 1428 1 1431 1434 1 1431 1437 1 + 1440 1443 1 1440 1446 1 1449 1452 1 1449 + 1455 1 1458 1461 1 1458 1464 1 1467 1470 + 1 1467 1473 1 1476 1479 1 1476 1482 1 + 1485 1488 1 1485 1491 1 1494 1497 1 1494 + 1500 1 1503 1506 1 1503 1509 1 1512 1515 + 1 1512 1518 1 1521 1524 1 1521 1527 1 + 1530 1533 1 1530 1536 1 1539 1542 1 1539 + 1545 1 1548 1551 1 1548 1554 1 1557 1560 + 1 1557 1563 1 1566 1569 1 1566 1572 1 + 1575 1578 1 1575 1581 1 1584 1587 1 1584 + 1590 1 1593 1596 1 1593 1599 1 1602 1605 + 1 1602 1608 1 1611 1614 1 1611 1617 1 + 1620 1623 1 1620 1626 1 1629 1632 1 1629 + 1635 1 1638 1641 1 1638 1644 1 1647 1650 + 1 1647 1653 1 1656 1659 1 1656 1662 1 + 1665 1668 1 1665 1671 1 1674 1677 1 1674 + 1680 1 1683 1686 1 1683 1689 1 1692 1695 + 1 1692 1698 1 1701 1704 1 1701 1707 1 + 1710 1713 1 1710 1716 1 1719 1722 1 1719 + 1725 1 1728 1731 1 1728 1734 1 1737 1740 + 1 1737 1743 1 1746 1749 1 1746 1752 1 + 1755 1758 1 1755 1761 1 1764 1767 1 1764 + 1770 1 1773 1776 1 1773 1779 1 1782 1785 + 1 1782 1788 1 1791 1794 1 1791 1797 1 + 1800 1803 1 1800 1806 1 1809 1812 1 1809 + 1815 1 1818 1821 1 1818 1824 1 1827 1830 + 1 1827 1833 1 1836 1839 1 1836 1842 1 + 1845 1848 1 1845 1851 1 1854 1857 1 1854 + 1860 1 1863 1866 1 1863 1869 1 1872 1875 + 1 1872 1878 1 1881 1884 1 1881 1887 1 + 1890 1893 1 1890 1896 1 1899 1902 1 1899 + 1905 1 1908 1911 1 1908 1914 1 1917 1920 + 1 1917 1923 1 1926 1929 1 1926 1932 1 + 1935 1938 1 1935 1941 1 1944 1947 1 1944 + 1950 1 1953 1956 1 1953 1959 1 1962 1965 + 1 1962 1968 1 1971 1974 1 1971 1977 1 + 1980 1983 1 1980 1986 1 1989 1992 1 1989 + 1995 1 1998 2001 1 1998 2004 1 2007 2010 + 1 2007 2013 1 2016 2019 1 2016 2022 1 + 2025 2028 1 2025 2031 1 2034 2037 1 2034 + 2040 1 2043 2046 1 2043 2049 1 2052 2055 + 1 2052 2058 1 2061 2064 1 2061 2067 1 + 2070 2073 1 2070 2076 1 2079 2082 1 2079 + 2085 1 2088 2091 1 2088 2094 1 2097 2100 + 1 2097 2103 1 2106 2109 1 2106 2112 1 + 2115 2118 1 2115 2121 1 2124 2127 1 2124 + 2130 1 2133 2136 1 2133 2139 1 2142 2145 + 1 2142 2148 1 2151 2154 1 2151 2157 1 + 2160 2163 1 2160 2166 1 2169 2172 1 2169 + 2175 1 2178 2181 1 2178 2184 1 2187 2190 + 1 2187 2193 1 2196 2199 1 2196 2202 1 + 2205 2208 1 2205 2211 1 2214 2217 1 2214 + 2220 1 2223 2226 1 2223 2229 1 2232 2235 + 1 2232 2238 1 2241 2244 1 2241 2247 1 + 2250 2253 1 2250 2256 1 2259 2262 1 2259 + 2265 1 2268 2271 1 2268 2274 1 2277 2280 + 1 2277 2283 1 2286 2289 1 2286 2292 1 + 2295 2298 1 2295 2301 1 2304 2307 1 2304 + 2310 1 2313 2316 1 2313 2319 1 2322 2325 + 1 2322 2328 1 2331 2334 1 2331 2337 1 + 2340 2343 1 2340 2346 1 2349 2352 1 2349 + 2355 1 2358 2361 1 2358 2364 1 2367 2370 + 1 2367 2373 1 2376 2379 1 2376 2382 1 + 2385 2388 1 2385 2391 1 2394 2397 1 2394 + 2400 1 2403 2406 1 2403 2409 1 2412 2415 + 1 2412 2418 1 2421 2424 1 2421 2427 1 + 2430 2433 1 2430 2436 1 2439 2442 1 2439 + 2445 1 2448 2451 1 2448 2454 1 2457 2460 + 1 2457 2463 1 2466 2469 1 2466 2472 1 + 2475 2478 1 2475 2481 1 2484 2487 1 2484 + 2490 1 2493 2496 1 2493 2499 1 2502 2505 + 1 2502 2508 1 2511 2514 1 2511 2517 1 + 2520 2523 1 2520 2526 1 2529 2532 1 2529 + 2535 1 2538 2541 1 2538 2544 1 2547 2550 + 1 2547 2553 1 2556 2559 1 2556 2562 1 + 2565 2568 1 2565 2571 1 2574 2577 1 2574 + 2580 1 2583 2586 1 2583 2589 1 2592 2595 + 1 2592 2598 1 2601 2604 1 2601 2607 1 + 2610 2613 1 2610 2616 1 2619 2622 1 2619 + 2625 1 2628 2631 1 2628 2634 1 2637 2640 + 1 2637 2643 1 2646 2649 1 2646 2652 1 + 2655 2658 1 2655 2661 1 2664 2667 1 2664 + 2670 1 2673 2676 1 2673 2679 1 2682 2685 + 1 2682 2688 1 2691 2694 1 2691 2697 1 + 2700 2703 1 2700 2706 1 2709 2712 1 2709 + 2715 1 2718 2721 1 2718 2724 1 2727 2730 + 1 2727 2733 1 2736 2739 1 2736 2742 1 + 2745 2748 1 2745 2751 1 2754 2757 1 2754 + 2760 1 2763 2766 1 2763 2769 1 2772 2775 + 1 2772 2778 1 2781 2784 1 2781 2787 1 + 2790 2793 1 2790 2796 1 2799 2802 1 2799 + 2805 1 2808 2811 1 2808 2814 1 2817 2820 + 1 2817 2823 1 2826 2829 1 2826 2832 1 + 2835 2838 1 2835 2841 1 2844 2847 1 2844 + 2850 1 2853 2856 1 2853 2859 1 2862 2865 + 1 2862 2868 1 2871 2874 1 2871 2877 1 + 2880 2883 1 2880 2886 1 2889 2892 1 2889 + 2895 1 2898 2901 1 2898 2904 1 2907 2910 + 1 2907 2913 1 2916 2919 1 2916 2922 1 + 2925 2928 1 2925 2931 1 2934 2937 1 2934 + 2940 1 2943 2946 1 2943 2949 1 2952 2955 + 1 2952 2958 1 2961 2964 1 2961 2967 1 + 2970 2973 1 2970 2976 1 2979 2982 1 2979 + 2985 1 2988 2991 1 2988 2994 1 2997 3000 + 1 2997 3003 1 3006 3009 1 3006 3012 1 + 3015 3018 1 3015 3021 1 3024 3027 1 3024 + 3030 1 3033 3036 1 3033 3039 1 3042 3045 + 1 3042 3048 1 3051 3054 1 3051 3057 1 + 3060 3063 1 3060 3066 1 3069 3072 1 3069 + 3075 1 3078 3081 1 3078 3084 1 3087 3090 + 1 3087 3093 1 3096 3099 1 3096 3102 1 + 3105 3108 1 3105 3111 1 3114 3117 1 3114 + 3120 1 3123 3126 1 3123 3129 1 3132 3135 + 1 3132 3138 1 3141 3144 1 3141 3147 1 + 3150 3153 1 3150 3156 1 3159 3162 1 3159 + 3165 1 3168 3171 1 3168 3174 1 3177 3180 + 1 3177 3183 1 3186 3189 1 3186 3192 1 + 3195 3198 1 3195 3201 1 3204 3207 1 3204 + 3210 1 3213 3216 1 3213 3219 1 3222 3225 + 1 3222 3228 1 3231 3234 1 3231 3237 1 + 3240 3243 1 3240 3246 1 3249 3252 1 3249 + 3255 1 3258 3261 1 3258 3264 1 3267 3270 + 1 3267 3273 1 3276 3279 1 3276 3282 1 + 3285 3288 1 3285 3291 1 3294 3297 1 3294 + 3300 1 3303 3306 1 3303 3309 1 3312 3315 + 1 3312 3318 1 3321 3324 1 3321 3327 1 + 3330 3333 1 3330 3336 1 3339 3342 1 3339 + 3345 1 3348 3351 1 3348 3354 1 3357 3360 + 1 3357 3363 1 3366 3369 1 3366 3372 1 + 3375 3378 1 3375 3381 1 3384 3387 1 3384 + 3390 1 3393 3396 1 3393 3399 1 3402 3405 + 1 3402 3408 1 3411 3414 1 3411 3417 1 + 3420 3423 1 3420 3426 1 3429 3432 1 3429 + 3435 1 3438 3441 1 3438 3444 1 3447 3450 + 1 3447 3453 1 3456 3459 1 3456 3462 1 + 3465 3468 1 3465 3471 1 3474 3477 1 3474 + 3480 1 3483 3486 1 3483 3489 1 3492 3495 + 1 3492 3498 1 3501 3504 1 3501 3507 1 + 3510 3513 1 3510 3516 1 3519 3522 1 3519 + 3525 1 3528 3531 1 3528 3534 1 3537 3540 + 1 3537 3543 1 3546 3549 1 3546 3552 1 + 3555 3558 1 3555 3561 1 3564 3567 1 3564 + 3570 1 3573 3576 1 3573 3579 1 3582 3585 + 1 3582 3588 1 3591 3594 1 3591 3597 1 + 3600 3603 1 3600 3606 1 3609 3612 1 3609 + 3615 1 3618 3621 1 3618 3624 1 3627 3630 + 1 3627 3633 1 3636 3639 1 3636 3642 1 + 3645 3648 1 3645 3651 1 3654 3657 1 3654 + 3660 1 3663 3666 1 3663 3669 1 3672 3675 + 1 3672 3678 1 3681 3684 1 3681 3687 1 + 3690 3693 1 3690 3696 1 3699 3702 1 3699 + 3705 1 3708 3711 1 3708 3714 1 3717 3720 + 1 3717 3723 1 3726 3729 1 3726 3732 1 + 3735 3738 1 3735 3741 1 3744 3747 1 3744 + 3750 1 3753 3756 1 3753 3759 1 3762 3765 + 1 3762 3768 1 3771 3774 1 3771 3777 1 + 3780 3783 1 3780 3786 1 3789 3792 1 3789 + 3795 1 3798 3801 1 3798 3804 1 3807 3810 + 1 3807 3813 1 3816 3819 1 3816 3822 1 + 3825 3828 1 3825 3831 1 3834 3837 1 3834 + 3840 1 3843 3846 1 3843 3849 1 3852 3855 + 1 3852 3858 1 3861 3864 1 3861 3867 1 + 3870 3873 1 3870 3876 1 3879 3882 1 3879 + 3885 1 3888 3891 1 3888 3894 1 3897 3900 + 1 3897 3903 1 3906 3909 1 3906 3912 1 + 3915 3918 1 3915 3921 1 3924 3927 1 3924 + 3930 1 3933 3936 1 3933 3939 1 3942 3945 + 1 3942 3948 1 3951 3954 1 3951 3957 1 + 3960 3963 1 3960 3966 1 3969 3972 1 3969 + 3975 1 3978 3981 1 3978 3984 1 3987 3990 + 1 3987 3993 1 3996 3999 1 3996 4002 1 + 4005 4008 1 4005 4011 1 4014 4017 1 4014 + 4020 1 4023 4026 1 4023 4029 1 4032 4035 + 1 4032 4038 1 4041 4044 1 4041 4047 1 + 4050 4053 1 4050 4056 1 4059 4062 1 4059 + 4065 1 4068 4071 1 4068 4074 1 4077 4080 + 1 4077 4083 1 4086 4089 1 4086 4092 1 + 4095 4098 1 4095 4101 1 4104 4107 1 4104 + 4110 1 4113 4116 1 4113 4119 1 4122 4125 + 1 4122 4128 1 4131 4134 1 4131 4137 1 + 4140 4143 1 4140 4146 1 4149 4152 1 4149 + 4155 1 4158 4161 1 4158 4164 1 4167 4170 + 1 4167 4173 1 4176 4179 1 4176 4182 1 + 4185 4188 1 4185 4191 1 4194 4197 1 4194 + 4200 1 4203 4206 1 4203 4209 1 4212 4215 + 1 4212 4218 1 4221 4224 1 4221 4227 1 + 4230 4233 1 4230 4236 1 4239 4242 1 4239 + 4245 1 4248 4251 1 4248 4254 1 4257 4260 + 1 4257 4263 1 4266 4269 1 4266 4272 1 + 4275 4278 1 4275 4281 1 4284 4287 1 4284 + 4290 1 4293 4296 1 4293 4299 1 4302 4305 + 1 4302 4308 1 4311 4314 1 4311 4317 1 + 4320 4323 1 4320 4326 1 4329 4332 1 4329 + 4335 1 4338 4341 1 4338 4344 1 4347 4350 + 1 4347 4353 1 4356 4359 1 4356 4362 1 + 4365 4368 1 4365 4371 1 4374 4377 1 4374 + 4380 1 4383 4386 1 4383 4389 1 4392 4395 + 1 4392 4398 1 4401 4404 1 4401 4407 1 + 4410 4413 1 4410 4416 1 4419 4422 1 4419 + 4425 1 4428 4431 1 4428 4434 1 4437 4440 + 1 4437 4443 1 4446 4449 1 4446 4452 1 + 4455 4458 1 4455 4461 1 4464 4467 1 4464 + 4470 1 4473 4476 1 4473 4479 1 4482 4485 + 1 4482 4488 1 4491 4494 1 4491 4497 1 + 4500 4503 1 4500 4506 1 4509 4512 1 4509 + 4515 1 4518 4521 1 4518 4524 1 4527 4530 + 1 4527 4533 1 4536 4539 1 4536 4542 1 + 4545 4548 1 4545 4551 1 4554 4557 1 4554 + 4560 1 4563 4566 1 4563 4569 1 4572 4575 + 1 4572 4578 1 4581 4584 1 4581 4587 1 + 4590 4593 1 4590 4596 1 4599 4602 1 4599 + 4605 1 4608 4611 1 4608 4614 1 4617 4620 + 1 4617 4623 1 4626 4629 1 4626 4632 1 + 4635 4638 1 4635 4641 1 4644 4647 1 4644 + 4650 1 4653 4656 1 4653 4659 1 4662 4665 + 1 4662 4668 1 4671 4674 1 4671 4677 1 + 4680 4683 1 4680 4686 1 4689 4692 1 4689 + 4695 1 4698 4701 1 4698 4704 1 4707 4710 + 1 4707 4713 1 4716 4719 1 4716 4722 1 + 4725 4728 1 4725 4731 1 4734 4737 1 4734 + 4740 1 4743 4746 1 4743 4749 1 4752 4755 + 1 4752 4758 1 4761 4764 1 4761 4767 1 + 4770 4773 1 4770 4776 1 4779 4782 1 4779 + 4785 1 4788 4791 1 4788 4794 1 4797 4800 + 1 4797 4803 1 4806 4809 1 4806 4812 1 + 4815 4818 1 4815 4821 1 4824 4827 1 4824 + 4830 1 4833 4836 1 4833 4839 1 4842 4845 + 1 4842 4848 1 4851 4854 1 4851 4857 1 + 4860 4863 1 4860 4866 1 4869 4872 1 4869 + 4875 1 4878 4881 1 4878 4884 1 4887 4890 + 1 4887 4893 1 4896 4899 1 4896 4902 1 + 4905 4908 1 4905 4911 1 4914 4917 1 4914 + 4920 1 4923 4926 1 4923 4929 1 4932 4935 + 1 4932 4938 1 4941 4944 1 4941 4947 1 + 4950 4953 1 4950 4956 1 4959 4962 1 4959 + 4965 1 4968 4971 1 4968 4974 1 4977 4980 + 1 4977 4983 1 4986 4989 1 4986 4992 1 + 4995 4998 1 4995 5001 1 5004 5007 1 5004 + 5010 1 5013 5016 1 5013 5019 1 5022 5025 + 1 5022 5028 1 5031 5034 1 5031 5037 1 + 5040 5043 1 5040 5046 1 5049 5052 1 5049 + 5055 1 5058 5061 1 5058 5064 1 5067 5070 + 1 5067 5073 1 5076 5079 1 5076 5082 1 + 5085 5088 1 5085 5091 1 5094 5097 1 5094 + 5100 1 5103 5106 1 5103 5109 1 5112 5115 + 1 5112 5118 1 5121 5124 1 5121 5127 1 + 5130 5133 1 5130 5136 1 5139 5142 1 5139 + 5145 1 5148 5151 1 5148 5154 1 5157 5160 + 1 5157 5163 1 5166 5169 1 5166 5172 1 + 5175 5178 1 5175 5181 1 5184 5187 1 5184 + 5190 1 5193 5196 1 5193 5199 1 5202 5205 + 1 5202 5208 1 5211 5214 1 5211 5217 1 + 5220 5223 1 5220 5226 1 5229 5232 1 5229 + 5235 1 5238 5241 1 5238 5244 1 5247 5250 + 1 5247 5253 1 5256 5259 1 5256 5262 1 + 5265 5268 1 5265 5271 1 5274 5277 1 5274 + 5280 1 5283 5286 1 5283 5289 1 5292 5295 + 1 5292 5298 1 5301 5304 1 5301 5307 1 + 5310 5313 1 5310 5316 1 5319 5322 1 5319 + 5325 1 5328 5331 1 5328 5334 1 5337 5340 + 1 5337 5343 1 5346 5349 1 5346 5352 1 + 5355 5358 1 5355 5361 1 5364 5367 1 5364 + 5370 1 5373 5376 1 5373 5379 1 5382 5385 + 1 5382 5388 1 5391 5394 1 5391 5397 1 + 5400 5403 1 5400 5406 1 5409 5412 1 5409 + 5415 1 5418 5421 1 5418 5424 1 5427 5430 + 1 5427 5433 1 5436 5439 1 5436 5442 1 + 5445 5448 1 5445 5451 1 5454 5457 1 5454 + 5460 1 5463 5466 1 5463 5469 1 5472 5475 + 1 5472 5478 1 5481 5484 1 5481 5487 1 + 5490 5493 1 5490 5496 1 5499 5502 1 5499 + 5505 1 5508 5511 1 5508 5514 1 5517 5520 + 1 5517 5523 1 5526 5529 1 5526 5532 1 + 5535 5538 1 5535 5541 1 5544 5547 1 5544 + 5550 1 5553 5556 1 5553 5559 1 5562 5565 + 1 5562 5568 1 5571 5574 1 5571 5577 1 + 5580 5583 1 5580 5586 1 5589 5592 1 5589 + 5595 1 5598 5601 1 5598 5604 1 5607 5610 + 1 5607 5613 1 5616 5619 1 5616 5622 1 + 5625 5628 1 5625 5631 1 5634 5637 1 5634 + 5640 1 5643 5646 1 5643 5649 1 5652 5655 + 1 5652 5658 1 5661 5664 1 5661 5667 1 + 5670 5673 1 5670 5676 1 5679 5682 1 5679 + 5685 1 5688 5691 1 5688 5694 1 5697 5700 + 1 5697 5703 1 5706 5709 1 5706 5712 1 + 5715 5718 1 5715 5721 1 5724 5727 1 5724 + 5730 1 5733 5736 1 5733 5739 1 5742 5745 + 1 5742 5748 1 5751 5754 1 5751 5757 1 + 5760 5763 1 5760 5766 1 5769 5772 1 5769 + 5775 1 5778 5781 1 5778 5784 1 5787 5790 + 1 5787 5793 1 5796 5799 1 5796 5802 1 + 5805 5808 1 5805 5811 1 5814 5817 1 5814 + 5820 1 5823 5826 1 5823 5829 1 5832 5835 + 1 5832 5838 1 5841 5844 1 5841 5847 1 + 5850 5853 1 5850 5856 1 5859 5862 1 5859 + 5865 1 5868 5871 1 5868 5874 1 5877 5880 + 1 5877 5883 1 5886 5889 1 5886 5892 1 + 5895 5898 1 5895 5901 1 5904 5907 1 5904 + 5910 1 5913 5916 1 5913 5919 1 5922 5925 + 1 5922 5928 1 5931 5934 1 5931 5937 1 + 5940 5943 1 5940 5946 1 5949 5952 1 5949 + 5955 1 5958 5961 1 5958 5964 1 5967 5970 + 1 5967 5973 1 5976 5979 1 5976 5982 1 + 5985 5988 1 5985 5991 1 5994 5997 1 5994 + 6000 1 6003 6006 1 6003 6009 1 6012 6015 + 1 6012 6018 1 6021 6024 1 6021 6027 1 + 6030 6033 1 6030 6036 1 6039 6042 1 6039 + 6045 1 6048 6051 1 6048 6054 1 6057 6060 + 1 6057 6063 1 6066 6069 1 6066 6072 1 + 6075 6078 1 6075 6081 1 6084 6087 1 6084 + 6090 1 6093 6096 1 6093 6099 1 6102 6105 + 1 6102 6108 1 6111 6114 1 6111 6117 1 + 6120 6123 1 6120 6126 1 6129 6132 1 6129 + 6135 1 6138 6141 1 6138 6144 1 6147 6150 + 1 6147 6153 1 6156 6159 1 6156 6162 1 + 6165 6168 1 6165 6171 1 6174 6177 1 6174 + 6180 1 6183 6186 1 6183 6189 1 6192 6195 + 1 6192 6198 1 6201 6204 1 6201 6207 1 + 6210 6213 1 6210 6216 1 6219 6222 1 6219 + 6225 1 6228 6231 1 6228 6234 1 6237 6240 + 1 6237 6243 1 6246 6249 1 6246 6252 1 + 6255 6258 1 6255 6261 1 6264 6267 1 6264 + 6270 1 6273 6276 1 6273 6279 1 6282 6285 + 1 6282 6288 1 6291 6294 1 6291 6297 1 + 6300 6303 1 6300 6306 1 6309 6312 1 6309 + 6315 1 6318 6321 1 6318 6324 1 6327 6330 + 1 6327 6333 1 6336 6339 1 6336 6342 1 + 6345 6348 1 6345 6351 1 6354 6357 1 6354 + 6360 1 6363 6366 1 6363 6369 1 6372 6375 + 1 6372 6378 1 6381 6384 1 6381 6387 1 + 6390 6393 1 6390 6396 1 6399 6402 1 6399 + 6405 1 6408 6411 1 6408 6414 1 6417 6420 + 1 6417 6423 1 6426 6429 1 6426 6432 1 + 6435 6438 1 6435 6441 1 6444 6447 1 6444 + 6450 1 6453 6456 1 6453 6459 1 6462 6465 + 1 6462 6468 1 6471 6474 1 6471 6477 1 + 6480 6483 1 6480 6486 1 6489 6492 1 6489 + 6495 1 6498 6501 1 6498 6504 1 6507 6510 + 1 6507 6513 1 6516 6519 1 6516 6522 1 + 6525 6528 1 6525 6531 1 6534 6537 1 6534 + 6540 1 6543 6546 1 6543 6549 1 6552 6555 + 1 6552 6558 1 6561 6564 1 6561 6567 1 + 6570 6573 1 6570 6576 1 6579 6582 1 6579 + 6585 1 6588 6591 1 6588 6594 1 6597 6600 + 1 6597 6603 1 6606 6609 1 6606 6612 1 + 6615 6618 1 6615 6621 1 6624 6627 1 6624 + 6630 1 6633 6636 1 6633 6639 1 6642 6645 + 1 6642 6648 1 6651 6654 1 6651 6657 1 + 6660 6663 1 6660 6666 1 6669 6672 1 6669 + 6675 1 6678 6681 1 6678 6684 1 6687 6690 + 1 6687 6693 1 6696 6699 1 6696 6702 1 + 6705 6708 1 6705 6711 1 6714 6717 1 6714 + 6720 1 6723 6726 1 6723 6729 1 6732 6735 + 1 6732 6738 1 6741 6744 1 6741 6747 1 + 6750 6753 1 6750 6756 1 6759 6762 1 6759 + 6765 1 6768 6771 1 6768 6774 1 6777 6780 + 1 6777 6783 1 6786 6789 1 6786 6792 1 + 6795 6798 1 6795 6801 1 6804 6807 1 6804 + 6810 1 6813 6816 1 6813 6819 1 6822 6825 + 1 6822 6828 1 6831 6834 1 6831 6837 1 + 6840 6843 1 6840 6846 1 6849 6852 1 6849 + 6855 1 6858 6861 1 6858 6864 1 6867 6870 + 1 6867 6873 1 6876 6879 1 6876 6882 1 + 6885 6888 1 6885 6891 1 6894 6897 1 6894 + 6900 1 6903 6906 1 6903 6909 1 6912 6915 + 1 6912 6918 1 6921 6924 1 6921 6927 1 + 6930 6933 1 6930 6936 1 6939 6942 1 6939 + 6945 1 6948 6951 1 6948 6954 1 6957 6960 + 1 6957 6963 1 6966 6969 1 6966 6972 1 + 6975 6978 1 6975 6981 1 6984 6987 1 6984 + 6990 1 6993 6996 1 6993 6999 1 7002 7005 + 1 7002 7008 1 7011 7014 1 7011 7017 1 + 7020 7023 1 7020 7026 1 7029 7032 1 7029 + 7035 1 7038 7041 1 7038 7044 1 7047 7050 + 1 7047 7053 1 7056 7059 1 7056 7062 1 + 7065 7068 1 7065 7071 1 7074 7077 1 7074 + 7080 1 7083 7086 1 7083 7089 1 7092 7095 + 1 7092 7098 1 7101 7104 1 7101 7107 1 + 7110 7113 1 7110 7116 1 7119 7122 1 7119 + 7125 1 7128 7131 1 7128 7134 1 7137 7140 + 1 7137 7143 1 7146 7149 1 7146 7152 1 + 7155 7158 1 7155 7161 1 7164 7167 1 7164 + 7170 1 7173 7176 1 7173 7179 1 7182 7185 + 1 7182 7188 1 7191 7194 1 7191 7197 1 + 7200 7203 1 7200 7206 1 7209 7212 1 7209 + 7215 1 7218 7221 1 7218 7224 1 7227 7230 + 1 7227 7233 1 7236 7239 1 7236 7242 1 + 7245 7248 1 7245 7251 1 7254 7257 1 7254 + 7260 1 7263 7266 1 7263 7269 1 7272 7275 + 1 7272 7278 1 7281 7284 1 7281 7287 1 + 7290 7293 1 7290 7296 1 7299 7302 1 7299 + 7305 1 7308 7311 1 7308 7314 1 7317 7320 + 1 7317 7323 1 7326 7329 1 7326 7332 1 + 7335 7338 1 7335 7341 1 7344 7347 1 7344 + 7350 1 7353 7356 1 7353 7359 1 7362 7365 + 1 7362 7368 1 7371 7374 1 7371 7377 1 + 7380 7383 1 7380 7386 1 7389 7392 1 7389 + 7395 1 7398 7401 1 7398 7404 1 7407 7410 + 1 7407 7413 1 7416 7419 1 7416 7422 1 + 7425 7428 1 7425 7431 1 7434 7437 1 7434 + 7440 1 7443 7446 1 7443 7449 1 7452 7455 + 1 7452 7458 1 7461 7464 1 7461 7467 1 + 7470 7473 1 7470 7476 1 7479 7482 1 7479 + 7485 1 7488 7491 1 7488 7494 1 7497 7500 + 1 7497 7503 1 7506 7509 1 7506 7512 1 + 7515 7518 1 7515 7521 1 7524 7527 1 7524 + 7530 1 7533 7536 1 7533 7539 1 7542 7545 + 1 7542 7548 1 7551 7554 1 7551 7557 1 + 7560 7563 1 7560 7566 1 7569 7572 1 7569 + 7575 1 7578 7581 1 7578 7584 1 7587 7590 + 1 7587 7593 1 7596 7599 1 7596 7602 1 + 7605 7608 1 7605 7611 1 7614 7617 1 7614 + 7620 1 7623 7626 1 7623 7629 1 7632 7635 + 1 7632 7638 1 7641 7644 1 7641 7647 1 + 7650 7653 1 7650 7656 1 7659 7662 1 7659 + 7665 1 7668 7671 1 7668 7674 1 7677 7680 + 1 7677 7683 1 7686 7689 1 7686 7692 1 + 7695 7698 1 7695 7701 1 7704 7707 1 7704 + 7710 1 7713 7716 1 7713 7719 1 7722 7725 + 1 7722 7728 1 7731 7734 1 7731 7737 1 + 7740 7743 1 7740 7746 1 7749 7752 1 7749 + 7755 1 7758 7761 1 7758 7764 1 7767 7770 + 1 7767 7773 1 7776 7779 1 7776 7782 1 + 7785 7788 1 7785 7791 1 7794 7797 1 7794 + 7800 1 7803 7806 1 7803 7809 1 7812 7815 + 1 7812 7818 1 7821 7824 1 7821 7827 1 + 7830 7833 1 7830 7836 1 7839 7842 1 7839 + 7845 1 7848 7851 1 7848 7854 1 7857 7860 + 1 7857 7863 1 7866 7869 1 7866 7872 1 + 7875 7878 1 7875 7881 1 7884 7887 1 7884 + 7890 1 7893 7896 1 7893 7899 1 7902 7905 + 1 7902 7908 1 7911 7914 1 7911 7917 1 + 7920 7923 1 7920 7926 1 7929 7932 1 7929 + 7935 1 7938 7941 1 7938 7944 1 7947 7950 + 1 7947 7953 1 7956 7959 1 7956 7962 1 + 7965 7968 1 7965 7971 1 7974 7977 1 7974 + 7980 1 7983 7986 1 7983 7989 1 7992 7995 + 1 7992 7998 1 8001 8004 1 8001 8007 1 + 8010 8013 1 8010 8016 1 8019 8022 1 8019 + 8025 1 8028 8031 1 8028 8034 1 8037 8040 + 1 8037 8043 1 8046 8049 1 8046 8052 1 + 8055 8058 1 8055 8061 1 8064 8067 1 8064 + 8070 1 8073 8076 1 8073 8079 1 8082 8085 + 1 8082 8088 1 8091 8094 1 8091 8097 1 + 8100 8103 1 8100 8106 1 8109 8112 1 8109 + 8115 1 8118 8121 1 8118 8124 1 8127 8130 + 1 8127 8133 1 8136 8139 1 8136 8142 1 + 8145 8148 1 8145 8151 1 8154 8157 1 8154 + 8160 1 8163 8166 1 8163 8169 1 8172 8175 + 1 8172 8178 1 8181 8184 1 8181 8187 1 + 8190 8193 1 8190 8196 1 8199 8202 1 8199 + 8205 1 8208 8211 1 8208 8214 1 8217 8220 + 1 8217 8223 1 8226 8229 1 8226 8232 1 + 8235 8238 1 8235 8241 1 8244 8247 1 8244 + 8250 1 8253 8256 1 8253 8259 1 8262 8265 + 1 8262 8268 1 8271 8274 1 8271 8277 1 + 8280 8283 1 8280 8286 1 8289 8292 1 8289 + 8295 1 8298 8301 1 8298 8304 1 8307 8310 + 1 8307 8313 1 8316 8319 1 8316 8322 1 + 8325 8328 1 8325 8331 1 8334 8337 1 8334 + 8340 1 8343 8346 1 8343 8349 1 8352 8355 + 1 8352 8358 1 8361 8364 1 8361 8367 1 + 8370 8373 1 8370 8376 1 8379 8382 1 8379 + 8385 1 8388 8391 1 8388 8394 1 8397 8400 + 1 8397 8403 1 8406 8409 1 8406 8412 1 + 8415 8418 1 8415 8421 1 8424 8427 1 8424 + 8430 1 8433 8436 1 8433 8439 1 8442 8445 + 1 8442 8448 1 8451 8454 1 8451 8457 1 + 8460 8463 1 8460 8466 1 8469 8472 1 8469 + 8475 1 8478 8481 1 8478 8484 1 8487 8490 + 1 8487 8493 1 8496 8499 1 8496 8502 1 + 8505 8508 1 8505 8511 1 8514 8517 1 8514 + 8520 1 8523 8526 1 8523 8529 1 8532 8535 + 1 8532 8538 1 8541 8544 1 8541 8547 1 + 8550 8553 1 8550 8556 1 8559 8562 1 8559 + 8565 1 8568 8571 1 8568 8574 1 8577 8580 + 1 8577 8583 1 8586 8589 1 8586 8592 1 + 8595 8598 1 8595 8601 1 8604 8607 1 8604 + 8610 1 8613 8616 1 8613 8619 1 8622 8625 + 1 8622 8628 1 8631 8634 1 8631 8637 1 + 8640 8643 1 8640 8646 1 8649 8652 1 8649 + 8655 1 8658 8661 1 8658 8664 1 8667 8670 + 1 8667 8673 1 8676 8679 1 8676 8682 1 + 8685 8688 1 8685 8691 1 8694 8697 1 8694 + 8700 1 8703 8706 1 8703 8709 1 8712 8715 + 1 8712 8718 1 8721 8724 1 8721 8727 1 + 8730 8733 1 8730 8736 1 8739 8742 1 8739 + 8745 1 8748 8751 1 8748 8754 1 8757 8760 + 1 8757 8763 1 8766 8769 1 8766 8772 1 + 8775 8778 1 8775 8781 1 8784 8787 1 8784 + 8790 1 8793 8796 1 8793 8799 1 8802 8805 + 1 8802 8808 1 8811 8814 1 8811 8817 1 + 8820 8823 1 8820 8826 1 8829 8832 1 8829 + 8835 1 8838 8841 1 8838 8844 1 8847 8850 + 1 8847 8853 1 8856 8859 1 8856 8862 1 + 8865 8868 1 8865 8871 1 8874 8877 1 8874 + 8880 1 8883 8886 1 8883 8889 1 8892 8895 + 1 8892 8898 1 8901 8904 1 8901 8907 1 + 8910 8913 1 8910 8916 1 8919 8922 1 8919 + 8925 1 8928 8931 1 8928 8934 1 8937 8940 + 1 8937 8943 1 8946 8949 1 8946 8952 1 + 8955 8958 1 8955 8961 1 8964 8967 1 8964 + 8970 1 8973 8976 1 8973 8979 1 8982 8985 + 1 8982 8988 1 8991 8994 1 8991 8997 1 +%FLAG BONDS_WITHOUT_HYDROGEN +%FORMAT(10I8) + +%FLAG ANGLES_INC_HYDROGEN +%FORMAT(10I8) + 3 0 6 1 12 9 15 1 21 18 + 24 1 30 27 33 1 39 36 42 1 + 48 45 51 1 57 54 60 1 66 63 + 69 1 75 72 78 1 84 81 87 1 + 93 90 96 1 102 99 105 1 111 108 + 114 1 120 117 123 1 129 126 132 1 + 138 135 141 1 147 144 150 1 156 153 + 159 1 165 162 168 1 174 171 177 1 + 183 180 186 1 192 189 195 1 201 198 + 204 1 210 207 213 1 219 216 222 1 + 228 225 231 1 237 234 240 1 246 243 + 249 1 255 252 258 1 264 261 267 1 + 273 270 276 1 282 279 285 1 291 288 + 294 1 300 297 303 1 309 306 312 1 + 318 315 321 1 327 324 330 1 336 333 + 339 1 345 342 348 1 354 351 357 1 + 363 360 366 1 372 369 375 1 381 378 + 384 1 390 387 393 1 399 396 402 1 + 408 405 411 1 417 414 420 1 426 423 + 429 1 435 432 438 1 444 441 447 1 + 453 450 456 1 462 459 465 1 471 468 + 474 1 480 477 483 1 489 486 492 1 + 498 495 501 1 507 504 510 1 516 513 + 519 1 525 522 528 1 534 531 537 1 + 543 540 546 1 552 549 555 1 561 558 + 564 1 570 567 573 1 579 576 582 1 + 588 585 591 1 597 594 600 1 606 603 + 609 1 615 612 618 1 624 621 627 1 + 633 630 636 1 642 639 645 1 651 648 + 654 1 660 657 663 1 669 666 672 1 + 678 675 681 1 687 684 690 1 696 693 + 699 1 705 702 708 1 714 711 717 1 + 723 720 726 1 732 729 735 1 741 738 + 744 1 750 747 753 1 759 756 762 1 + 768 765 771 1 777 774 780 1 786 783 + 789 1 795 792 798 1 804 801 807 1 + 813 810 816 1 822 819 825 1 831 828 + 834 1 840 837 843 1 849 846 852 1 + 858 855 861 1 867 864 870 1 876 873 + 879 1 885 882 888 1 894 891 897 1 + 903 900 906 1 912 909 915 1 921 918 + 924 1 930 927 933 1 939 936 942 1 + 948 945 951 1 957 954 960 1 966 963 + 969 1 975 972 978 1 984 981 987 1 + 993 990 996 1 1002 999 1005 1 1011 1008 + 1014 1 1020 1017 1023 1 1029 1026 1032 1 + 1038 1035 1041 1 1047 1044 1050 1 1056 1053 + 1059 1 1065 1062 1068 1 1074 1071 1077 1 + 1083 1080 1086 1 1092 1089 1095 1 1101 1098 + 1104 1 1110 1107 1113 1 1119 1116 1122 1 + 1128 1125 1131 1 1137 1134 1140 1 1146 1143 + 1149 1 1155 1152 1158 1 1164 1161 1167 1 + 1173 1170 1176 1 1182 1179 1185 1 1191 1188 + 1194 1 1200 1197 1203 1 1209 1206 1212 1 + 1218 1215 1221 1 1227 1224 1230 1 1236 1233 + 1239 1 1245 1242 1248 1 1254 1251 1257 1 + 1263 1260 1266 1 1272 1269 1275 1 1281 1278 + 1284 1 1290 1287 1293 1 1299 1296 1302 1 + 1308 1305 1311 1 1317 1314 1320 1 1326 1323 + 1329 1 1335 1332 1338 1 1344 1341 1347 1 + 1353 1350 1356 1 1362 1359 1365 1 1371 1368 + 1374 1 1380 1377 1383 1 1389 1386 1392 1 + 1398 1395 1401 1 1407 1404 1410 1 1416 1413 + 1419 1 1425 1422 1428 1 1434 1431 1437 1 + 1443 1440 1446 1 1452 1449 1455 1 1461 1458 + 1464 1 1470 1467 1473 1 1479 1476 1482 1 + 1488 1485 1491 1 1497 1494 1500 1 1506 1503 + 1509 1 1515 1512 1518 1 1524 1521 1527 1 + 1533 1530 1536 1 1542 1539 1545 1 1551 1548 + 1554 1 1560 1557 1563 1 1569 1566 1572 1 + 1578 1575 1581 1 1587 1584 1590 1 1596 1593 + 1599 1 1605 1602 1608 1 1614 1611 1617 1 + 1623 1620 1626 1 1632 1629 1635 1 1641 1638 + 1644 1 1650 1647 1653 1 1659 1656 1662 1 + 1668 1665 1671 1 1677 1674 1680 1 1686 1683 + 1689 1 1695 1692 1698 1 1704 1701 1707 1 + 1713 1710 1716 1 1722 1719 1725 1 1731 1728 + 1734 1 1740 1737 1743 1 1749 1746 1752 1 + 1758 1755 1761 1 1767 1764 1770 1 1776 1773 + 1779 1 1785 1782 1788 1 1794 1791 1797 1 + 1803 1800 1806 1 1812 1809 1815 1 1821 1818 + 1824 1 1830 1827 1833 1 1839 1836 1842 1 + 1848 1845 1851 1 1857 1854 1860 1 1866 1863 + 1869 1 1875 1872 1878 1 1884 1881 1887 1 + 1893 1890 1896 1 1902 1899 1905 1 1911 1908 + 1914 1 1920 1917 1923 1 1929 1926 1932 1 + 1938 1935 1941 1 1947 1944 1950 1 1956 1953 + 1959 1 1965 1962 1968 1 1974 1971 1977 1 + 1983 1980 1986 1 1992 1989 1995 1 2001 1998 + 2004 1 2010 2007 2013 1 2019 2016 2022 1 + 2028 2025 2031 1 2037 2034 2040 1 2046 2043 + 2049 1 2055 2052 2058 1 2064 2061 2067 1 + 2073 2070 2076 1 2082 2079 2085 1 2091 2088 + 2094 1 2100 2097 2103 1 2109 2106 2112 1 + 2118 2115 2121 1 2127 2124 2130 1 2136 2133 + 2139 1 2145 2142 2148 1 2154 2151 2157 1 + 2163 2160 2166 1 2172 2169 2175 1 2181 2178 + 2184 1 2190 2187 2193 1 2199 2196 2202 1 + 2208 2205 2211 1 2217 2214 2220 1 2226 2223 + 2229 1 2235 2232 2238 1 2244 2241 2247 1 + 2253 2250 2256 1 2262 2259 2265 1 2271 2268 + 2274 1 2280 2277 2283 1 2289 2286 2292 1 + 2298 2295 2301 1 2307 2304 2310 1 2316 2313 + 2319 1 2325 2322 2328 1 2334 2331 2337 1 + 2343 2340 2346 1 2352 2349 2355 1 2361 2358 + 2364 1 2370 2367 2373 1 2379 2376 2382 1 + 2388 2385 2391 1 2397 2394 2400 1 2406 2403 + 2409 1 2415 2412 2418 1 2424 2421 2427 1 + 2433 2430 2436 1 2442 2439 2445 1 2451 2448 + 2454 1 2460 2457 2463 1 2469 2466 2472 1 + 2478 2475 2481 1 2487 2484 2490 1 2496 2493 + 2499 1 2505 2502 2508 1 2514 2511 2517 1 + 2523 2520 2526 1 2532 2529 2535 1 2541 2538 + 2544 1 2550 2547 2553 1 2559 2556 2562 1 + 2568 2565 2571 1 2577 2574 2580 1 2586 2583 + 2589 1 2595 2592 2598 1 2604 2601 2607 1 + 2613 2610 2616 1 2622 2619 2625 1 2631 2628 + 2634 1 2640 2637 2643 1 2649 2646 2652 1 + 2658 2655 2661 1 2667 2664 2670 1 2676 2673 + 2679 1 2685 2682 2688 1 2694 2691 2697 1 + 2703 2700 2706 1 2712 2709 2715 1 2721 2718 + 2724 1 2730 2727 2733 1 2739 2736 2742 1 + 2748 2745 2751 1 2757 2754 2760 1 2766 2763 + 2769 1 2775 2772 2778 1 2784 2781 2787 1 + 2793 2790 2796 1 2802 2799 2805 1 2811 2808 + 2814 1 2820 2817 2823 1 2829 2826 2832 1 + 2838 2835 2841 1 2847 2844 2850 1 2856 2853 + 2859 1 2865 2862 2868 1 2874 2871 2877 1 + 2883 2880 2886 1 2892 2889 2895 1 2901 2898 + 2904 1 2910 2907 2913 1 2919 2916 2922 1 + 2928 2925 2931 1 2937 2934 2940 1 2946 2943 + 2949 1 2955 2952 2958 1 2964 2961 2967 1 + 2973 2970 2976 1 2982 2979 2985 1 2991 2988 + 2994 1 3000 2997 3003 1 3009 3006 3012 1 + 3018 3015 3021 1 3027 3024 3030 1 3036 3033 + 3039 1 3045 3042 3048 1 3054 3051 3057 1 + 3063 3060 3066 1 3072 3069 3075 1 3081 3078 + 3084 1 3090 3087 3093 1 3099 3096 3102 1 + 3108 3105 3111 1 3117 3114 3120 1 3126 3123 + 3129 1 3135 3132 3138 1 3144 3141 3147 1 + 3153 3150 3156 1 3162 3159 3165 1 3171 3168 + 3174 1 3180 3177 3183 1 3189 3186 3192 1 + 3198 3195 3201 1 3207 3204 3210 1 3216 3213 + 3219 1 3225 3222 3228 1 3234 3231 3237 1 + 3243 3240 3246 1 3252 3249 3255 1 3261 3258 + 3264 1 3270 3267 3273 1 3279 3276 3282 1 + 3288 3285 3291 1 3297 3294 3300 1 3306 3303 + 3309 1 3315 3312 3318 1 3324 3321 3327 1 + 3333 3330 3336 1 3342 3339 3345 1 3351 3348 + 3354 1 3360 3357 3363 1 3369 3366 3372 1 + 3378 3375 3381 1 3387 3384 3390 1 3396 3393 + 3399 1 3405 3402 3408 1 3414 3411 3417 1 + 3423 3420 3426 1 3432 3429 3435 1 3441 3438 + 3444 1 3450 3447 3453 1 3459 3456 3462 1 + 3468 3465 3471 1 3477 3474 3480 1 3486 3483 + 3489 1 3495 3492 3498 1 3504 3501 3507 1 + 3513 3510 3516 1 3522 3519 3525 1 3531 3528 + 3534 1 3540 3537 3543 1 3549 3546 3552 1 + 3558 3555 3561 1 3567 3564 3570 1 3576 3573 + 3579 1 3585 3582 3588 1 3594 3591 3597 1 + 3603 3600 3606 1 3612 3609 3615 1 3621 3618 + 3624 1 3630 3627 3633 1 3639 3636 3642 1 + 3648 3645 3651 1 3657 3654 3660 1 3666 3663 + 3669 1 3675 3672 3678 1 3684 3681 3687 1 + 3693 3690 3696 1 3702 3699 3705 1 3711 3708 + 3714 1 3720 3717 3723 1 3729 3726 3732 1 + 3738 3735 3741 1 3747 3744 3750 1 3756 3753 + 3759 1 3765 3762 3768 1 3774 3771 3777 1 + 3783 3780 3786 1 3792 3789 3795 1 3801 3798 + 3804 1 3810 3807 3813 1 3819 3816 3822 1 + 3828 3825 3831 1 3837 3834 3840 1 3846 3843 + 3849 1 3855 3852 3858 1 3864 3861 3867 1 + 3873 3870 3876 1 3882 3879 3885 1 3891 3888 + 3894 1 3900 3897 3903 1 3909 3906 3912 1 + 3918 3915 3921 1 3927 3924 3930 1 3936 3933 + 3939 1 3945 3942 3948 1 3954 3951 3957 1 + 3963 3960 3966 1 3972 3969 3975 1 3981 3978 + 3984 1 3990 3987 3993 1 3999 3996 4002 1 + 4008 4005 4011 1 4017 4014 4020 1 4026 4023 + 4029 1 4035 4032 4038 1 4044 4041 4047 1 + 4053 4050 4056 1 4062 4059 4065 1 4071 4068 + 4074 1 4080 4077 4083 1 4089 4086 4092 1 + 4098 4095 4101 1 4107 4104 4110 1 4116 4113 + 4119 1 4125 4122 4128 1 4134 4131 4137 1 + 4143 4140 4146 1 4152 4149 4155 1 4161 4158 + 4164 1 4170 4167 4173 1 4179 4176 4182 1 + 4188 4185 4191 1 4197 4194 4200 1 4206 4203 + 4209 1 4215 4212 4218 1 4224 4221 4227 1 + 4233 4230 4236 1 4242 4239 4245 1 4251 4248 + 4254 1 4260 4257 4263 1 4269 4266 4272 1 + 4278 4275 4281 1 4287 4284 4290 1 4296 4293 + 4299 1 4305 4302 4308 1 4314 4311 4317 1 + 4323 4320 4326 1 4332 4329 4335 1 4341 4338 + 4344 1 4350 4347 4353 1 4359 4356 4362 1 + 4368 4365 4371 1 4377 4374 4380 1 4386 4383 + 4389 1 4395 4392 4398 1 4404 4401 4407 1 + 4413 4410 4416 1 4422 4419 4425 1 4431 4428 + 4434 1 4440 4437 4443 1 4449 4446 4452 1 + 4458 4455 4461 1 4467 4464 4470 1 4476 4473 + 4479 1 4485 4482 4488 1 4494 4491 4497 1 + 4503 4500 4506 1 4512 4509 4515 1 4521 4518 + 4524 1 4530 4527 4533 1 4539 4536 4542 1 + 4548 4545 4551 1 4557 4554 4560 1 4566 4563 + 4569 1 4575 4572 4578 1 4584 4581 4587 1 + 4593 4590 4596 1 4602 4599 4605 1 4611 4608 + 4614 1 4620 4617 4623 1 4629 4626 4632 1 + 4638 4635 4641 1 4647 4644 4650 1 4656 4653 + 4659 1 4665 4662 4668 1 4674 4671 4677 1 + 4683 4680 4686 1 4692 4689 4695 1 4701 4698 + 4704 1 4710 4707 4713 1 4719 4716 4722 1 + 4728 4725 4731 1 4737 4734 4740 1 4746 4743 + 4749 1 4755 4752 4758 1 4764 4761 4767 1 + 4773 4770 4776 1 4782 4779 4785 1 4791 4788 + 4794 1 4800 4797 4803 1 4809 4806 4812 1 + 4818 4815 4821 1 4827 4824 4830 1 4836 4833 + 4839 1 4845 4842 4848 1 4854 4851 4857 1 + 4863 4860 4866 1 4872 4869 4875 1 4881 4878 + 4884 1 4890 4887 4893 1 4899 4896 4902 1 + 4908 4905 4911 1 4917 4914 4920 1 4926 4923 + 4929 1 4935 4932 4938 1 4944 4941 4947 1 + 4953 4950 4956 1 4962 4959 4965 1 4971 4968 + 4974 1 4980 4977 4983 1 4989 4986 4992 1 + 4998 4995 5001 1 5007 5004 5010 1 5016 5013 + 5019 1 5025 5022 5028 1 5034 5031 5037 1 + 5043 5040 5046 1 5052 5049 5055 1 5061 5058 + 5064 1 5070 5067 5073 1 5079 5076 5082 1 + 5088 5085 5091 1 5097 5094 5100 1 5106 5103 + 5109 1 5115 5112 5118 1 5124 5121 5127 1 + 5133 5130 5136 1 5142 5139 5145 1 5151 5148 + 5154 1 5160 5157 5163 1 5169 5166 5172 1 + 5178 5175 5181 1 5187 5184 5190 1 5196 5193 + 5199 1 5205 5202 5208 1 5214 5211 5217 1 + 5223 5220 5226 1 5232 5229 5235 1 5241 5238 + 5244 1 5250 5247 5253 1 5259 5256 5262 1 + 5268 5265 5271 1 5277 5274 5280 1 5286 5283 + 5289 1 5295 5292 5298 1 5304 5301 5307 1 + 5313 5310 5316 1 5322 5319 5325 1 5331 5328 + 5334 1 5340 5337 5343 1 5349 5346 5352 1 + 5358 5355 5361 1 5367 5364 5370 1 5376 5373 + 5379 1 5385 5382 5388 1 5394 5391 5397 1 + 5403 5400 5406 1 5412 5409 5415 1 5421 5418 + 5424 1 5430 5427 5433 1 5439 5436 5442 1 + 5448 5445 5451 1 5457 5454 5460 1 5466 5463 + 5469 1 5475 5472 5478 1 5484 5481 5487 1 + 5493 5490 5496 1 5502 5499 5505 1 5511 5508 + 5514 1 5520 5517 5523 1 5529 5526 5532 1 + 5538 5535 5541 1 5547 5544 5550 1 5556 5553 + 5559 1 5565 5562 5568 1 5574 5571 5577 1 + 5583 5580 5586 1 5592 5589 5595 1 5601 5598 + 5604 1 5610 5607 5613 1 5619 5616 5622 1 + 5628 5625 5631 1 5637 5634 5640 1 5646 5643 + 5649 1 5655 5652 5658 1 5664 5661 5667 1 + 5673 5670 5676 1 5682 5679 5685 1 5691 5688 + 5694 1 5700 5697 5703 1 5709 5706 5712 1 + 5718 5715 5721 1 5727 5724 5730 1 5736 5733 + 5739 1 5745 5742 5748 1 5754 5751 5757 1 + 5763 5760 5766 1 5772 5769 5775 1 5781 5778 + 5784 1 5790 5787 5793 1 5799 5796 5802 1 + 5808 5805 5811 1 5817 5814 5820 1 5826 5823 + 5829 1 5835 5832 5838 1 5844 5841 5847 1 + 5853 5850 5856 1 5862 5859 5865 1 5871 5868 + 5874 1 5880 5877 5883 1 5889 5886 5892 1 + 5898 5895 5901 1 5907 5904 5910 1 5916 5913 + 5919 1 5925 5922 5928 1 5934 5931 5937 1 + 5943 5940 5946 1 5952 5949 5955 1 5961 5958 + 5964 1 5970 5967 5973 1 5979 5976 5982 1 + 5988 5985 5991 1 5997 5994 6000 1 6006 6003 + 6009 1 6015 6012 6018 1 6024 6021 6027 1 + 6033 6030 6036 1 6042 6039 6045 1 6051 6048 + 6054 1 6060 6057 6063 1 6069 6066 6072 1 + 6078 6075 6081 1 6087 6084 6090 1 6096 6093 + 6099 1 6105 6102 6108 1 6114 6111 6117 1 + 6123 6120 6126 1 6132 6129 6135 1 6141 6138 + 6144 1 6150 6147 6153 1 6159 6156 6162 1 + 6168 6165 6171 1 6177 6174 6180 1 6186 6183 + 6189 1 6195 6192 6198 1 6204 6201 6207 1 + 6213 6210 6216 1 6222 6219 6225 1 6231 6228 + 6234 1 6240 6237 6243 1 6249 6246 6252 1 + 6258 6255 6261 1 6267 6264 6270 1 6276 6273 + 6279 1 6285 6282 6288 1 6294 6291 6297 1 + 6303 6300 6306 1 6312 6309 6315 1 6321 6318 + 6324 1 6330 6327 6333 1 6339 6336 6342 1 + 6348 6345 6351 1 6357 6354 6360 1 6366 6363 + 6369 1 6375 6372 6378 1 6384 6381 6387 1 + 6393 6390 6396 1 6402 6399 6405 1 6411 6408 + 6414 1 6420 6417 6423 1 6429 6426 6432 1 + 6438 6435 6441 1 6447 6444 6450 1 6456 6453 + 6459 1 6465 6462 6468 1 6474 6471 6477 1 + 6483 6480 6486 1 6492 6489 6495 1 6501 6498 + 6504 1 6510 6507 6513 1 6519 6516 6522 1 + 6528 6525 6531 1 6537 6534 6540 1 6546 6543 + 6549 1 6555 6552 6558 1 6564 6561 6567 1 + 6573 6570 6576 1 6582 6579 6585 1 6591 6588 + 6594 1 6600 6597 6603 1 6609 6606 6612 1 + 6618 6615 6621 1 6627 6624 6630 1 6636 6633 + 6639 1 6645 6642 6648 1 6654 6651 6657 1 + 6663 6660 6666 1 6672 6669 6675 1 6681 6678 + 6684 1 6690 6687 6693 1 6699 6696 6702 1 + 6708 6705 6711 1 6717 6714 6720 1 6726 6723 + 6729 1 6735 6732 6738 1 6744 6741 6747 1 + 6753 6750 6756 1 6762 6759 6765 1 6771 6768 + 6774 1 6780 6777 6783 1 6789 6786 6792 1 + 6798 6795 6801 1 6807 6804 6810 1 6816 6813 + 6819 1 6825 6822 6828 1 6834 6831 6837 1 + 6843 6840 6846 1 6852 6849 6855 1 6861 6858 + 6864 1 6870 6867 6873 1 6879 6876 6882 1 + 6888 6885 6891 1 6897 6894 6900 1 6906 6903 + 6909 1 6915 6912 6918 1 6924 6921 6927 1 + 6933 6930 6936 1 6942 6939 6945 1 6951 6948 + 6954 1 6960 6957 6963 1 6969 6966 6972 1 + 6978 6975 6981 1 6987 6984 6990 1 6996 6993 + 6999 1 7005 7002 7008 1 7014 7011 7017 1 + 7023 7020 7026 1 7032 7029 7035 1 7041 7038 + 7044 1 7050 7047 7053 1 7059 7056 7062 1 + 7068 7065 7071 1 7077 7074 7080 1 7086 7083 + 7089 1 7095 7092 7098 1 7104 7101 7107 1 + 7113 7110 7116 1 7122 7119 7125 1 7131 7128 + 7134 1 7140 7137 7143 1 7149 7146 7152 1 + 7158 7155 7161 1 7167 7164 7170 1 7176 7173 + 7179 1 7185 7182 7188 1 7194 7191 7197 1 + 7203 7200 7206 1 7212 7209 7215 1 7221 7218 + 7224 1 7230 7227 7233 1 7239 7236 7242 1 + 7248 7245 7251 1 7257 7254 7260 1 7266 7263 + 7269 1 7275 7272 7278 1 7284 7281 7287 1 + 7293 7290 7296 1 7302 7299 7305 1 7311 7308 + 7314 1 7320 7317 7323 1 7329 7326 7332 1 + 7338 7335 7341 1 7347 7344 7350 1 7356 7353 + 7359 1 7365 7362 7368 1 7374 7371 7377 1 + 7383 7380 7386 1 7392 7389 7395 1 7401 7398 + 7404 1 7410 7407 7413 1 7419 7416 7422 1 + 7428 7425 7431 1 7437 7434 7440 1 7446 7443 + 7449 1 7455 7452 7458 1 7464 7461 7467 1 + 7473 7470 7476 1 7482 7479 7485 1 7491 7488 + 7494 1 7500 7497 7503 1 7509 7506 7512 1 + 7518 7515 7521 1 7527 7524 7530 1 7536 7533 + 7539 1 7545 7542 7548 1 7554 7551 7557 1 + 7563 7560 7566 1 7572 7569 7575 1 7581 7578 + 7584 1 7590 7587 7593 1 7599 7596 7602 1 + 7608 7605 7611 1 7617 7614 7620 1 7626 7623 + 7629 1 7635 7632 7638 1 7644 7641 7647 1 + 7653 7650 7656 1 7662 7659 7665 1 7671 7668 + 7674 1 7680 7677 7683 1 7689 7686 7692 1 + 7698 7695 7701 1 7707 7704 7710 1 7716 7713 + 7719 1 7725 7722 7728 1 7734 7731 7737 1 + 7743 7740 7746 1 7752 7749 7755 1 7761 7758 + 7764 1 7770 7767 7773 1 7779 7776 7782 1 + 7788 7785 7791 1 7797 7794 7800 1 7806 7803 + 7809 1 7815 7812 7818 1 7824 7821 7827 1 + 7833 7830 7836 1 7842 7839 7845 1 7851 7848 + 7854 1 7860 7857 7863 1 7869 7866 7872 1 + 7878 7875 7881 1 7887 7884 7890 1 7896 7893 + 7899 1 7905 7902 7908 1 7914 7911 7917 1 + 7923 7920 7926 1 7932 7929 7935 1 7941 7938 + 7944 1 7950 7947 7953 1 7959 7956 7962 1 + 7968 7965 7971 1 7977 7974 7980 1 7986 7983 + 7989 1 7995 7992 7998 1 8004 8001 8007 1 + 8013 8010 8016 1 8022 8019 8025 1 8031 8028 + 8034 1 8040 8037 8043 1 8049 8046 8052 1 + 8058 8055 8061 1 8067 8064 8070 1 8076 8073 + 8079 1 8085 8082 8088 1 8094 8091 8097 1 + 8103 8100 8106 1 8112 8109 8115 1 8121 8118 + 8124 1 8130 8127 8133 1 8139 8136 8142 1 + 8148 8145 8151 1 8157 8154 8160 1 8166 8163 + 8169 1 8175 8172 8178 1 8184 8181 8187 1 + 8193 8190 8196 1 8202 8199 8205 1 8211 8208 + 8214 1 8220 8217 8223 1 8229 8226 8232 1 + 8238 8235 8241 1 8247 8244 8250 1 8256 8253 + 8259 1 8265 8262 8268 1 8274 8271 8277 1 + 8283 8280 8286 1 8292 8289 8295 1 8301 8298 + 8304 1 8310 8307 8313 1 8319 8316 8322 1 + 8328 8325 8331 1 8337 8334 8340 1 8346 8343 + 8349 1 8355 8352 8358 1 8364 8361 8367 1 + 8373 8370 8376 1 8382 8379 8385 1 8391 8388 + 8394 1 8400 8397 8403 1 8409 8406 8412 1 + 8418 8415 8421 1 8427 8424 8430 1 8436 8433 + 8439 1 8445 8442 8448 1 8454 8451 8457 1 + 8463 8460 8466 1 8472 8469 8475 1 8481 8478 + 8484 1 8490 8487 8493 1 8499 8496 8502 1 + 8508 8505 8511 1 8517 8514 8520 1 8526 8523 + 8529 1 8535 8532 8538 1 8544 8541 8547 1 + 8553 8550 8556 1 8562 8559 8565 1 8571 8568 + 8574 1 8580 8577 8583 1 8589 8586 8592 1 + 8598 8595 8601 1 8607 8604 8610 1 8616 8613 + 8619 1 8625 8622 8628 1 8634 8631 8637 1 + 8643 8640 8646 1 8652 8649 8655 1 8661 8658 + 8664 1 8670 8667 8673 1 8679 8676 8682 1 + 8688 8685 8691 1 8697 8694 8700 1 8706 8703 + 8709 1 8715 8712 8718 1 8724 8721 8727 1 + 8733 8730 8736 1 8742 8739 8745 1 8751 8748 + 8754 1 8760 8757 8763 1 8769 8766 8772 1 + 8778 8775 8781 1 8787 8784 8790 1 8796 8793 + 8799 1 8805 8802 8808 1 8814 8811 8817 1 + 8823 8820 8826 1 8832 8829 8835 1 8841 8838 + 8844 1 8850 8847 8853 1 8859 8856 8862 1 + 8868 8865 8871 1 8877 8874 8880 1 8886 8883 + 8889 1 8895 8892 8898 1 8904 8901 8907 1 + 8913 8910 8916 1 8922 8919 8925 1 8931 8928 + 8934 1 8940 8937 8943 1 8949 8946 8952 1 + 8958 8955 8961 1 8967 8964 8970 1 8976 8973 + 8979 1 8985 8982 8988 1 8994 8991 8997 1 +%FLAG ANGLES_WITHOUT_HYDROGEN +%FORMAT(10I8) + +%FLAG DIHEDRALS_INC_HYDROGEN +%FORMAT(10I8) + +%FLAG DIHEDRALS_WITHOUT_HYDROGEN +%FORMAT(10I8) + +%FLAG EXCLUDED_ATOMS_LIST +%FORMAT(10I8) + 2 3 3 0 5 6 6 0 8 9 + 9 0 11 12 12 0 14 15 15 0 + 17 18 18 0 20 21 21 0 23 24 + 24 0 26 27 27 0 29 30 30 0 + 32 33 33 0 35 36 36 0 38 39 + 39 0 41 42 42 0 44 45 45 0 + 47 48 48 0 50 51 51 0 53 54 + 54 0 56 57 57 0 59 60 60 0 + 62 63 63 0 65 66 66 0 68 69 + 69 0 71 72 72 0 74 75 75 0 + 77 78 78 0 80 81 81 0 83 84 + 84 0 86 87 87 0 89 90 90 0 + 92 93 93 0 95 96 96 0 98 99 + 99 0 101 102 102 0 104 105 105 0 + 107 108 108 0 110 111 111 0 113 114 + 114 0 116 117 117 0 119 120 120 0 + 122 123 123 0 125 126 126 0 128 129 + 129 0 131 132 132 0 134 135 135 0 + 137 138 138 0 140 141 141 0 143 144 + 144 0 146 147 147 0 149 150 150 0 + 152 153 153 0 155 156 156 0 158 159 + 159 0 161 162 162 0 164 165 165 0 + 167 168 168 0 170 171 171 0 173 174 + 174 0 176 177 177 0 179 180 180 0 + 182 183 183 0 185 186 186 0 188 189 + 189 0 191 192 192 0 194 195 195 0 + 197 198 198 0 200 201 201 0 203 204 + 204 0 206 207 207 0 209 210 210 0 + 212 213 213 0 215 216 216 0 218 219 + 219 0 221 222 222 0 224 225 225 0 + 227 228 228 0 230 231 231 0 233 234 + 234 0 236 237 237 0 239 240 240 0 + 242 243 243 0 245 246 246 0 248 249 + 249 0 251 252 252 0 254 255 255 0 + 257 258 258 0 260 261 261 0 263 264 + 264 0 266 267 267 0 269 270 270 0 + 272 273 273 0 275 276 276 0 278 279 + 279 0 281 282 282 0 284 285 285 0 + 287 288 288 0 290 291 291 0 293 294 + 294 0 296 297 297 0 299 300 300 0 + 302 303 303 0 305 306 306 0 308 309 + 309 0 311 312 312 0 314 315 315 0 + 317 318 318 0 320 321 321 0 323 324 + 324 0 326 327 327 0 329 330 330 0 + 332 333 333 0 335 336 336 0 338 339 + 339 0 341 342 342 0 344 345 345 0 + 347 348 348 0 350 351 351 0 353 354 + 354 0 356 357 357 0 359 360 360 0 + 362 363 363 0 365 366 366 0 368 369 + 369 0 371 372 372 0 374 375 375 0 + 377 378 378 0 380 381 381 0 383 384 + 384 0 386 387 387 0 389 390 390 0 + 392 393 393 0 395 396 396 0 398 399 + 399 0 401 402 402 0 404 405 405 0 + 407 408 408 0 410 411 411 0 413 414 + 414 0 416 417 417 0 419 420 420 0 + 422 423 423 0 425 426 426 0 428 429 + 429 0 431 432 432 0 434 435 435 0 + 437 438 438 0 440 441 441 0 443 444 + 444 0 446 447 447 0 449 450 450 0 + 452 453 453 0 455 456 456 0 458 459 + 459 0 461 462 462 0 464 465 465 0 + 467 468 468 0 470 471 471 0 473 474 + 474 0 476 477 477 0 479 480 480 0 + 482 483 483 0 485 486 486 0 488 489 + 489 0 491 492 492 0 494 495 495 0 + 497 498 498 0 500 501 501 0 503 504 + 504 0 506 507 507 0 509 510 510 0 + 512 513 513 0 515 516 516 0 518 519 + 519 0 521 522 522 0 524 525 525 0 + 527 528 528 0 530 531 531 0 533 534 + 534 0 536 537 537 0 539 540 540 0 + 542 543 543 0 545 546 546 0 548 549 + 549 0 551 552 552 0 554 555 555 0 + 557 558 558 0 560 561 561 0 563 564 + 564 0 566 567 567 0 569 570 570 0 + 572 573 573 0 575 576 576 0 578 579 + 579 0 581 582 582 0 584 585 585 0 + 587 588 588 0 590 591 591 0 593 594 + 594 0 596 597 597 0 599 600 600 0 + 602 603 603 0 605 606 606 0 608 609 + 609 0 611 612 612 0 614 615 615 0 + 617 618 618 0 620 621 621 0 623 624 + 624 0 626 627 627 0 629 630 630 0 + 632 633 633 0 635 636 636 0 638 639 + 639 0 641 642 642 0 644 645 645 0 + 647 648 648 0 650 651 651 0 653 654 + 654 0 656 657 657 0 659 660 660 0 + 662 663 663 0 665 666 666 0 668 669 + 669 0 671 672 672 0 674 675 675 0 + 677 678 678 0 680 681 681 0 683 684 + 684 0 686 687 687 0 689 690 690 0 + 692 693 693 0 695 696 696 0 698 699 + 699 0 701 702 702 0 704 705 705 0 + 707 708 708 0 710 711 711 0 713 714 + 714 0 716 717 717 0 719 720 720 0 + 722 723 723 0 725 726 726 0 728 729 + 729 0 731 732 732 0 734 735 735 0 + 737 738 738 0 740 741 741 0 743 744 + 744 0 746 747 747 0 749 750 750 0 + 752 753 753 0 755 756 756 0 758 759 + 759 0 761 762 762 0 764 765 765 0 + 767 768 768 0 770 771 771 0 773 774 + 774 0 776 777 777 0 779 780 780 0 + 782 783 783 0 785 786 786 0 788 789 + 789 0 791 792 792 0 794 795 795 0 + 797 798 798 0 800 801 801 0 803 804 + 804 0 806 807 807 0 809 810 810 0 + 812 813 813 0 815 816 816 0 818 819 + 819 0 821 822 822 0 824 825 825 0 + 827 828 828 0 830 831 831 0 833 834 + 834 0 836 837 837 0 839 840 840 0 + 842 843 843 0 845 846 846 0 848 849 + 849 0 851 852 852 0 854 855 855 0 + 857 858 858 0 860 861 861 0 863 864 + 864 0 866 867 867 0 869 870 870 0 + 872 873 873 0 875 876 876 0 878 879 + 879 0 881 882 882 0 884 885 885 0 + 887 888 888 0 890 891 891 0 893 894 + 894 0 896 897 897 0 899 900 900 0 + 902 903 903 0 905 906 906 0 908 909 + 909 0 911 912 912 0 914 915 915 0 + 917 918 918 0 920 921 921 0 923 924 + 924 0 926 927 927 0 929 930 930 0 + 932 933 933 0 935 936 936 0 938 939 + 939 0 941 942 942 0 944 945 945 0 + 947 948 948 0 950 951 951 0 953 954 + 954 0 956 957 957 0 959 960 960 0 + 962 963 963 0 965 966 966 0 968 969 + 969 0 971 972 972 0 974 975 975 0 + 977 978 978 0 980 981 981 0 983 984 + 984 0 986 987 987 0 989 990 990 0 + 992 993 993 0 995 996 996 0 998 999 + 999 0 1001 1002 1002 0 1004 1005 1005 0 + 1007 1008 1008 0 1010 1011 1011 0 1013 1014 + 1014 0 1016 1017 1017 0 1019 1020 1020 0 + 1022 1023 1023 0 1025 1026 1026 0 1028 1029 + 1029 0 1031 1032 1032 0 1034 1035 1035 0 + 1037 1038 1038 0 1040 1041 1041 0 1043 1044 + 1044 0 1046 1047 1047 0 1049 1050 1050 0 + 1052 1053 1053 0 1055 1056 1056 0 1058 1059 + 1059 0 1061 1062 1062 0 1064 1065 1065 0 + 1067 1068 1068 0 1070 1071 1071 0 1073 1074 + 1074 0 1076 1077 1077 0 1079 1080 1080 0 + 1082 1083 1083 0 1085 1086 1086 0 1088 1089 + 1089 0 1091 1092 1092 0 1094 1095 1095 0 + 1097 1098 1098 0 1100 1101 1101 0 1103 1104 + 1104 0 1106 1107 1107 0 1109 1110 1110 0 + 1112 1113 1113 0 1115 1116 1116 0 1118 1119 + 1119 0 1121 1122 1122 0 1124 1125 1125 0 + 1127 1128 1128 0 1130 1131 1131 0 1133 1134 + 1134 0 1136 1137 1137 0 1139 1140 1140 0 + 1142 1143 1143 0 1145 1146 1146 0 1148 1149 + 1149 0 1151 1152 1152 0 1154 1155 1155 0 + 1157 1158 1158 0 1160 1161 1161 0 1163 1164 + 1164 0 1166 1167 1167 0 1169 1170 1170 0 + 1172 1173 1173 0 1175 1176 1176 0 1178 1179 + 1179 0 1181 1182 1182 0 1184 1185 1185 0 + 1187 1188 1188 0 1190 1191 1191 0 1193 1194 + 1194 0 1196 1197 1197 0 1199 1200 1200 0 + 1202 1203 1203 0 1205 1206 1206 0 1208 1209 + 1209 0 1211 1212 1212 0 1214 1215 1215 0 + 1217 1218 1218 0 1220 1221 1221 0 1223 1224 + 1224 0 1226 1227 1227 0 1229 1230 1230 0 + 1232 1233 1233 0 1235 1236 1236 0 1238 1239 + 1239 0 1241 1242 1242 0 1244 1245 1245 0 + 1247 1248 1248 0 1250 1251 1251 0 1253 1254 + 1254 0 1256 1257 1257 0 1259 1260 1260 0 + 1262 1263 1263 0 1265 1266 1266 0 1268 1269 + 1269 0 1271 1272 1272 0 1274 1275 1275 0 + 1277 1278 1278 0 1280 1281 1281 0 1283 1284 + 1284 0 1286 1287 1287 0 1289 1290 1290 0 + 1292 1293 1293 0 1295 1296 1296 0 1298 1299 + 1299 0 1301 1302 1302 0 1304 1305 1305 0 + 1307 1308 1308 0 1310 1311 1311 0 1313 1314 + 1314 0 1316 1317 1317 0 1319 1320 1320 0 + 1322 1323 1323 0 1325 1326 1326 0 1328 1329 + 1329 0 1331 1332 1332 0 1334 1335 1335 0 + 1337 1338 1338 0 1340 1341 1341 0 1343 1344 + 1344 0 1346 1347 1347 0 1349 1350 1350 0 + 1352 1353 1353 0 1355 1356 1356 0 1358 1359 + 1359 0 1361 1362 1362 0 1364 1365 1365 0 + 1367 1368 1368 0 1370 1371 1371 0 1373 1374 + 1374 0 1376 1377 1377 0 1379 1380 1380 0 + 1382 1383 1383 0 1385 1386 1386 0 1388 1389 + 1389 0 1391 1392 1392 0 1394 1395 1395 0 + 1397 1398 1398 0 1400 1401 1401 0 1403 1404 + 1404 0 1406 1407 1407 0 1409 1410 1410 0 + 1412 1413 1413 0 1415 1416 1416 0 1418 1419 + 1419 0 1421 1422 1422 0 1424 1425 1425 0 + 1427 1428 1428 0 1430 1431 1431 0 1433 1434 + 1434 0 1436 1437 1437 0 1439 1440 1440 0 + 1442 1443 1443 0 1445 1446 1446 0 1448 1449 + 1449 0 1451 1452 1452 0 1454 1455 1455 0 + 1457 1458 1458 0 1460 1461 1461 0 1463 1464 + 1464 0 1466 1467 1467 0 1469 1470 1470 0 + 1472 1473 1473 0 1475 1476 1476 0 1478 1479 + 1479 0 1481 1482 1482 0 1484 1485 1485 0 + 1487 1488 1488 0 1490 1491 1491 0 1493 1494 + 1494 0 1496 1497 1497 0 1499 1500 1500 0 + 1502 1503 1503 0 1505 1506 1506 0 1508 1509 + 1509 0 1511 1512 1512 0 1514 1515 1515 0 + 1517 1518 1518 0 1520 1521 1521 0 1523 1524 + 1524 0 1526 1527 1527 0 1529 1530 1530 0 + 1532 1533 1533 0 1535 1536 1536 0 1538 1539 + 1539 0 1541 1542 1542 0 1544 1545 1545 0 + 1547 1548 1548 0 1550 1551 1551 0 1553 1554 + 1554 0 1556 1557 1557 0 1559 1560 1560 0 + 1562 1563 1563 0 1565 1566 1566 0 1568 1569 + 1569 0 1571 1572 1572 0 1574 1575 1575 0 + 1577 1578 1578 0 1580 1581 1581 0 1583 1584 + 1584 0 1586 1587 1587 0 1589 1590 1590 0 + 1592 1593 1593 0 1595 1596 1596 0 1598 1599 + 1599 0 1601 1602 1602 0 1604 1605 1605 0 + 1607 1608 1608 0 1610 1611 1611 0 1613 1614 + 1614 0 1616 1617 1617 0 1619 1620 1620 0 + 1622 1623 1623 0 1625 1626 1626 0 1628 1629 + 1629 0 1631 1632 1632 0 1634 1635 1635 0 + 1637 1638 1638 0 1640 1641 1641 0 1643 1644 + 1644 0 1646 1647 1647 0 1649 1650 1650 0 + 1652 1653 1653 0 1655 1656 1656 0 1658 1659 + 1659 0 1661 1662 1662 0 1664 1665 1665 0 + 1667 1668 1668 0 1670 1671 1671 0 1673 1674 + 1674 0 1676 1677 1677 0 1679 1680 1680 0 + 1682 1683 1683 0 1685 1686 1686 0 1688 1689 + 1689 0 1691 1692 1692 0 1694 1695 1695 0 + 1697 1698 1698 0 1700 1701 1701 0 1703 1704 + 1704 0 1706 1707 1707 0 1709 1710 1710 0 + 1712 1713 1713 0 1715 1716 1716 0 1718 1719 + 1719 0 1721 1722 1722 0 1724 1725 1725 0 + 1727 1728 1728 0 1730 1731 1731 0 1733 1734 + 1734 0 1736 1737 1737 0 1739 1740 1740 0 + 1742 1743 1743 0 1745 1746 1746 0 1748 1749 + 1749 0 1751 1752 1752 0 1754 1755 1755 0 + 1757 1758 1758 0 1760 1761 1761 0 1763 1764 + 1764 0 1766 1767 1767 0 1769 1770 1770 0 + 1772 1773 1773 0 1775 1776 1776 0 1778 1779 + 1779 0 1781 1782 1782 0 1784 1785 1785 0 + 1787 1788 1788 0 1790 1791 1791 0 1793 1794 + 1794 0 1796 1797 1797 0 1799 1800 1800 0 + 1802 1803 1803 0 1805 1806 1806 0 1808 1809 + 1809 0 1811 1812 1812 0 1814 1815 1815 0 + 1817 1818 1818 0 1820 1821 1821 0 1823 1824 + 1824 0 1826 1827 1827 0 1829 1830 1830 0 + 1832 1833 1833 0 1835 1836 1836 0 1838 1839 + 1839 0 1841 1842 1842 0 1844 1845 1845 0 + 1847 1848 1848 0 1850 1851 1851 0 1853 1854 + 1854 0 1856 1857 1857 0 1859 1860 1860 0 + 1862 1863 1863 0 1865 1866 1866 0 1868 1869 + 1869 0 1871 1872 1872 0 1874 1875 1875 0 + 1877 1878 1878 0 1880 1881 1881 0 1883 1884 + 1884 0 1886 1887 1887 0 1889 1890 1890 0 + 1892 1893 1893 0 1895 1896 1896 0 1898 1899 + 1899 0 1901 1902 1902 0 1904 1905 1905 0 + 1907 1908 1908 0 1910 1911 1911 0 1913 1914 + 1914 0 1916 1917 1917 0 1919 1920 1920 0 + 1922 1923 1923 0 1925 1926 1926 0 1928 1929 + 1929 0 1931 1932 1932 0 1934 1935 1935 0 + 1937 1938 1938 0 1940 1941 1941 0 1943 1944 + 1944 0 1946 1947 1947 0 1949 1950 1950 0 + 1952 1953 1953 0 1955 1956 1956 0 1958 1959 + 1959 0 1961 1962 1962 0 1964 1965 1965 0 + 1967 1968 1968 0 1970 1971 1971 0 1973 1974 + 1974 0 1976 1977 1977 0 1979 1980 1980 0 + 1982 1983 1983 0 1985 1986 1986 0 1988 1989 + 1989 0 1991 1992 1992 0 1994 1995 1995 0 + 1997 1998 1998 0 2000 2001 2001 0 2003 2004 + 2004 0 2006 2007 2007 0 2009 2010 2010 0 + 2012 2013 2013 0 2015 2016 2016 0 2018 2019 + 2019 0 2021 2022 2022 0 2024 2025 2025 0 + 2027 2028 2028 0 2030 2031 2031 0 2033 2034 + 2034 0 2036 2037 2037 0 2039 2040 2040 0 + 2042 2043 2043 0 2045 2046 2046 0 2048 2049 + 2049 0 2051 2052 2052 0 2054 2055 2055 0 + 2057 2058 2058 0 2060 2061 2061 0 2063 2064 + 2064 0 2066 2067 2067 0 2069 2070 2070 0 + 2072 2073 2073 0 2075 2076 2076 0 2078 2079 + 2079 0 2081 2082 2082 0 2084 2085 2085 0 + 2087 2088 2088 0 2090 2091 2091 0 2093 2094 + 2094 0 2096 2097 2097 0 2099 2100 2100 0 + 2102 2103 2103 0 2105 2106 2106 0 2108 2109 + 2109 0 2111 2112 2112 0 2114 2115 2115 0 + 2117 2118 2118 0 2120 2121 2121 0 2123 2124 + 2124 0 2126 2127 2127 0 2129 2130 2130 0 + 2132 2133 2133 0 2135 2136 2136 0 2138 2139 + 2139 0 2141 2142 2142 0 2144 2145 2145 0 + 2147 2148 2148 0 2150 2151 2151 0 2153 2154 + 2154 0 2156 2157 2157 0 2159 2160 2160 0 + 2162 2163 2163 0 2165 2166 2166 0 2168 2169 + 2169 0 2171 2172 2172 0 2174 2175 2175 0 + 2177 2178 2178 0 2180 2181 2181 0 2183 2184 + 2184 0 2186 2187 2187 0 2189 2190 2190 0 + 2192 2193 2193 0 2195 2196 2196 0 2198 2199 + 2199 0 2201 2202 2202 0 2204 2205 2205 0 + 2207 2208 2208 0 2210 2211 2211 0 2213 2214 + 2214 0 2216 2217 2217 0 2219 2220 2220 0 + 2222 2223 2223 0 2225 2226 2226 0 2228 2229 + 2229 0 2231 2232 2232 0 2234 2235 2235 0 + 2237 2238 2238 0 2240 2241 2241 0 2243 2244 + 2244 0 2246 2247 2247 0 2249 2250 2250 0 + 2252 2253 2253 0 2255 2256 2256 0 2258 2259 + 2259 0 2261 2262 2262 0 2264 2265 2265 0 + 2267 2268 2268 0 2270 2271 2271 0 2273 2274 + 2274 0 2276 2277 2277 0 2279 2280 2280 0 + 2282 2283 2283 0 2285 2286 2286 0 2288 2289 + 2289 0 2291 2292 2292 0 2294 2295 2295 0 + 2297 2298 2298 0 2300 2301 2301 0 2303 2304 + 2304 0 2306 2307 2307 0 2309 2310 2310 0 + 2312 2313 2313 0 2315 2316 2316 0 2318 2319 + 2319 0 2321 2322 2322 0 2324 2325 2325 0 + 2327 2328 2328 0 2330 2331 2331 0 2333 2334 + 2334 0 2336 2337 2337 0 2339 2340 2340 0 + 2342 2343 2343 0 2345 2346 2346 0 2348 2349 + 2349 0 2351 2352 2352 0 2354 2355 2355 0 + 2357 2358 2358 0 2360 2361 2361 0 2363 2364 + 2364 0 2366 2367 2367 0 2369 2370 2370 0 + 2372 2373 2373 0 2375 2376 2376 0 2378 2379 + 2379 0 2381 2382 2382 0 2384 2385 2385 0 + 2387 2388 2388 0 2390 2391 2391 0 2393 2394 + 2394 0 2396 2397 2397 0 2399 2400 2400 0 + 2402 2403 2403 0 2405 2406 2406 0 2408 2409 + 2409 0 2411 2412 2412 0 2414 2415 2415 0 + 2417 2418 2418 0 2420 2421 2421 0 2423 2424 + 2424 0 2426 2427 2427 0 2429 2430 2430 0 + 2432 2433 2433 0 2435 2436 2436 0 2438 2439 + 2439 0 2441 2442 2442 0 2444 2445 2445 0 + 2447 2448 2448 0 2450 2451 2451 0 2453 2454 + 2454 0 2456 2457 2457 0 2459 2460 2460 0 + 2462 2463 2463 0 2465 2466 2466 0 2468 2469 + 2469 0 2471 2472 2472 0 2474 2475 2475 0 + 2477 2478 2478 0 2480 2481 2481 0 2483 2484 + 2484 0 2486 2487 2487 0 2489 2490 2490 0 + 2492 2493 2493 0 2495 2496 2496 0 2498 2499 + 2499 0 2501 2502 2502 0 2504 2505 2505 0 + 2507 2508 2508 0 2510 2511 2511 0 2513 2514 + 2514 0 2516 2517 2517 0 2519 2520 2520 0 + 2522 2523 2523 0 2525 2526 2526 0 2528 2529 + 2529 0 2531 2532 2532 0 2534 2535 2535 0 + 2537 2538 2538 0 2540 2541 2541 0 2543 2544 + 2544 0 2546 2547 2547 0 2549 2550 2550 0 + 2552 2553 2553 0 2555 2556 2556 0 2558 2559 + 2559 0 2561 2562 2562 0 2564 2565 2565 0 + 2567 2568 2568 0 2570 2571 2571 0 2573 2574 + 2574 0 2576 2577 2577 0 2579 2580 2580 0 + 2582 2583 2583 0 2585 2586 2586 0 2588 2589 + 2589 0 2591 2592 2592 0 2594 2595 2595 0 + 2597 2598 2598 0 2600 2601 2601 0 2603 2604 + 2604 0 2606 2607 2607 0 2609 2610 2610 0 + 2612 2613 2613 0 2615 2616 2616 0 2618 2619 + 2619 0 2621 2622 2622 0 2624 2625 2625 0 + 2627 2628 2628 0 2630 2631 2631 0 2633 2634 + 2634 0 2636 2637 2637 0 2639 2640 2640 0 + 2642 2643 2643 0 2645 2646 2646 0 2648 2649 + 2649 0 2651 2652 2652 0 2654 2655 2655 0 + 2657 2658 2658 0 2660 2661 2661 0 2663 2664 + 2664 0 2666 2667 2667 0 2669 2670 2670 0 + 2672 2673 2673 0 2675 2676 2676 0 2678 2679 + 2679 0 2681 2682 2682 0 2684 2685 2685 0 + 2687 2688 2688 0 2690 2691 2691 0 2693 2694 + 2694 0 2696 2697 2697 0 2699 2700 2700 0 + 2702 2703 2703 0 2705 2706 2706 0 2708 2709 + 2709 0 2711 2712 2712 0 2714 2715 2715 0 + 2717 2718 2718 0 2720 2721 2721 0 2723 2724 + 2724 0 2726 2727 2727 0 2729 2730 2730 0 + 2732 2733 2733 0 2735 2736 2736 0 2738 2739 + 2739 0 2741 2742 2742 0 2744 2745 2745 0 + 2747 2748 2748 0 2750 2751 2751 0 2753 2754 + 2754 0 2756 2757 2757 0 2759 2760 2760 0 + 2762 2763 2763 0 2765 2766 2766 0 2768 2769 + 2769 0 2771 2772 2772 0 2774 2775 2775 0 + 2777 2778 2778 0 2780 2781 2781 0 2783 2784 + 2784 0 2786 2787 2787 0 2789 2790 2790 0 + 2792 2793 2793 0 2795 2796 2796 0 2798 2799 + 2799 0 2801 2802 2802 0 2804 2805 2805 0 + 2807 2808 2808 0 2810 2811 2811 0 2813 2814 + 2814 0 2816 2817 2817 0 2819 2820 2820 0 + 2822 2823 2823 0 2825 2826 2826 0 2828 2829 + 2829 0 2831 2832 2832 0 2834 2835 2835 0 + 2837 2838 2838 0 2840 2841 2841 0 2843 2844 + 2844 0 2846 2847 2847 0 2849 2850 2850 0 + 2852 2853 2853 0 2855 2856 2856 0 2858 2859 + 2859 0 2861 2862 2862 0 2864 2865 2865 0 + 2867 2868 2868 0 2870 2871 2871 0 2873 2874 + 2874 0 2876 2877 2877 0 2879 2880 2880 0 + 2882 2883 2883 0 2885 2886 2886 0 2888 2889 + 2889 0 2891 2892 2892 0 2894 2895 2895 0 + 2897 2898 2898 0 2900 2901 2901 0 2903 2904 + 2904 0 2906 2907 2907 0 2909 2910 2910 0 + 2912 2913 2913 0 2915 2916 2916 0 2918 2919 + 2919 0 2921 2922 2922 0 2924 2925 2925 0 + 2927 2928 2928 0 2930 2931 2931 0 2933 2934 + 2934 0 2936 2937 2937 0 2939 2940 2940 0 + 2942 2943 2943 0 2945 2946 2946 0 2948 2949 + 2949 0 2951 2952 2952 0 2954 2955 2955 0 + 2957 2958 2958 0 2960 2961 2961 0 2963 2964 + 2964 0 2966 2967 2967 0 2969 2970 2970 0 + 2972 2973 2973 0 2975 2976 2976 0 2978 2979 + 2979 0 2981 2982 2982 0 2984 2985 2985 0 + 2987 2988 2988 0 2990 2991 2991 0 2993 2994 + 2994 0 2996 2997 2997 0 2999 3000 3000 0 +%FLAG HBOND_ACOEF +%FORMAT(5E16.8) + +%FLAG HBOND_BCOEF +%FORMAT(5E16.8) + +%FLAG HBCUT +%FORMAT(5E16.8) + +%FLAG AMBER_ATOM_TYPE +%FORMAT(20a4) +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho +ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh +ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho oh ho ho +%FLAG TREE_CHAIN_CLASSIFICATION +%FORMAT(20a4) +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA BLA +%FLAG JOIN_ARRAY +%FORMAT(10I8) + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 +%FLAG IROTAT +%FORMAT(10I8) + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 +%FLAG SOLVENT_POINTERS +%FORMAT(3I8) + 1000 1000 1001 +%FLAG ATOMS_PER_MOLECULE +%FORMAT(10I8) + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 +%FLAG BOX_DIMENSIONS +%FORMAT(5E16.8) + 9.00000000E+01 5.84800000E+01 5.84800000E+01 5.84800000E+01 +%FLAG RADIUS_SET +%FORMAT(1a80) +modified Bondi radii (mbondi) +%FLAG RADII +%FORMAT(5E16.8) + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 + 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 + 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 1.50000000E+00 + 8.00000000E-01 8.00000000E-01 1.50000000E+00 8.00000000E-01 8.00000000E-01 +%FLAG SCREEN +%FORMAT(5E16.8) + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 + 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 8.50000000E-01 +%FLAG IPOL +%FORMAT(1I8) + 0 -- GitLab From aba4c054bf1c742bfa9b2eca69d4ff19e06fb5c9 Mon Sep 17 00:00:00 2001 From: Jason Swails Date: Thu, 19 Mar 2015 13:47:20 -0400 Subject: [PATCH 317/338] Fix old behavior. --- .../python/simtk/openmm/app/internal/amber_file_parser.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py index bc84e63e0..5f41c7a1f 100644 --- a/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py +++ b/wrappers/python/simtk/openmm/app/internal/amber_file_parser.py @@ -783,9 +783,8 @@ def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=No atomI = topatoms[iAtom] atomJ = topatoms[jAtom] atomK = topatoms[kAtom] - numH = ((atomI.element.atomic_number == 1) + (atomJ.element.atomic_number == 1) + - (atomK.element.atomic_number == 1)) - constrained = (numH == 2 or (numH == 1 and atomK.element is elem.oxygen)) + numH = ((atomI.element.atomic_number == 1) + (atomK.element.atomic_number == 1)) + constrained = (numH == 2 or (numH == 1 and atomJ.element is elem.oxygen)) else: constrained = False if constrained: -- GitLab From 92727186ad1f25b397b1f8a12447ed345ba1b923 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 19 Mar 2015 12:25:44 -0700 Subject: [PATCH 318/338] Fixed an error in doxygen comments --- openmmapi/include/openmm/CustomAngleForce.h | 2 +- openmmapi/include/openmm/CustomBondForce.h | 2 +- openmmapi/include/openmm/CustomCompoundBondForce.h | 2 +- openmmapi/include/openmm/CustomExternalForce.h | 2 +- openmmapi/include/openmm/CustomGBForce.h | 2 +- openmmapi/include/openmm/CustomHbondForce.h | 2 +- openmmapi/include/openmm/CustomTorsionForce.h | 2 +- openmmapi/include/openmm/GBSAOBCForce.h | 2 +- openmmapi/include/openmm/HarmonicAngleForce.h | 2 +- openmmapi/include/openmm/HarmonicBondForce.h | 2 +- openmmapi/include/openmm/NonbondedForce.h | 2 +- openmmapi/include/openmm/PeriodicTorsionForce.h | 2 +- openmmapi/include/openmm/RBTorsionForce.h | 2 +- plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h | 2 +- plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h | 2 +- .../openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h | 2 +- .../amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h | 2 +- plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h | 2 +- .../amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h | 2 +- plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h | 2 +- .../amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h | 2 +- plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h | 2 +- .../amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/openmmapi/include/openmm/CustomAngleForce.h b/openmmapi/include/openmm/CustomAngleForce.h index 587f0e424..d4e628f84 100644 --- a/openmmapi/include/openmm/CustomAngleForce.h +++ b/openmmapi/include/openmm/CustomAngleForce.h @@ -194,7 +194,7 @@ public: /** * Update the per-angle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * This method has several limitations. The only information it updates is the values of per-angle parameters. diff --git a/openmmapi/include/openmm/CustomBondForce.h b/openmmapi/include/openmm/CustomBondForce.h index 9900eef43..85c224466 100644 --- a/openmmapi/include/openmm/CustomBondForce.h +++ b/openmmapi/include/openmm/CustomBondForce.h @@ -191,7 +191,7 @@ public: /** * Update the per-bond parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * This method has several limitations. The only information it updates is the values of per-bond parameters. diff --git a/openmmapi/include/openmm/CustomCompoundBondForce.h b/openmmapi/include/openmm/CustomCompoundBondForce.h index d75d3d3bb..8a02b3fab 100644 --- a/openmmapi/include/openmm/CustomCompoundBondForce.h +++ b/openmmapi/include/openmm/CustomCompoundBondForce.h @@ -289,7 +289,7 @@ public: /** * Update the per-bond parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * This method has several limitations. The only information it updates is the values of per-bond parameters. diff --git a/openmmapi/include/openmm/CustomExternalForce.h b/openmmapi/include/openmm/CustomExternalForce.h index da7682da4..f79e57d97 100644 --- a/openmmapi/include/openmm/CustomExternalForce.h +++ b/openmmapi/include/openmm/CustomExternalForce.h @@ -191,7 +191,7 @@ public: /** * Update the per-particle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * This method has several limitations. The only information it updates is the values of per-particle parameters. diff --git a/openmmapi/include/openmm/CustomGBForce.h b/openmmapi/include/openmm/CustomGBForce.h index 9f31cffc5..081154916 100644 --- a/openmmapi/include/openmm/CustomGBForce.h +++ b/openmmapi/include/openmm/CustomGBForce.h @@ -515,7 +515,7 @@ public: /** * Update the per-particle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * This method has several limitations. The only information it updates is the values of per-particle parameters. diff --git a/openmmapi/include/openmm/CustomHbondForce.h b/openmmapi/include/openmm/CustomHbondForce.h index c0a1071bd..825904b44 100644 --- a/openmmapi/include/openmm/CustomHbondForce.h +++ b/openmmapi/include/openmm/CustomHbondForce.h @@ -435,7 +435,7 @@ public: * Update the per-donor and per-acceptor parameters in a Context to match those stored in this Force object. This method * provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. * Simply call setDonorParameters() and setAcceptorParameters() to modify this object's parameters, then call - * updateParametersInState() to copy them over to the Context. + * updateParametersInContext() to copy them over to the Context. * * This method has several limitations. The only information it updates is the values of per-donor and per-acceptor parameters. * All other aspects of the Force (the energy function, nonbonded method, cutoff distance, etc.) are unaffected and can only diff --git a/openmmapi/include/openmm/CustomTorsionForce.h b/openmmapi/include/openmm/CustomTorsionForce.h index 2826546e7..0c4e926ef 100644 --- a/openmmapi/include/openmm/CustomTorsionForce.h +++ b/openmmapi/include/openmm/CustomTorsionForce.h @@ -197,7 +197,7 @@ public: /** * Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * This method has several limitations. The only information it updates is the values of per-torsion parameters. diff --git a/openmmapi/include/openmm/GBSAOBCForce.h b/openmmapi/include/openmm/GBSAOBCForce.h index 60f54fa4a..e5cb55827 100644 --- a/openmmapi/include/openmm/GBSAOBCForce.h +++ b/openmmapi/include/openmm/GBSAOBCForce.h @@ -176,7 +176,7 @@ public: * Update the particle parameters in a Context to match those stored in this Force object. This method * provides an efficient method to update certain parameters in an existing Context without needing to * reinitialize it. Simply call setParticleParameters() to modify this object's parameters, then call - * updateParametersInState() to copy them over to the Context. + * updateParametersInContext() to copy them over to the Context. * * The only information this method updates is the values of per-particle parameters. All other aspects * of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be changed diff --git a/openmmapi/include/openmm/HarmonicAngleForce.h b/openmmapi/include/openmm/HarmonicAngleForce.h index 4eb302d45..009e35853 100644 --- a/openmmapi/include/openmm/HarmonicAngleForce.h +++ b/openmmapi/include/openmm/HarmonicAngleForce.h @@ -95,7 +95,7 @@ public: /** * Update the per-angle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-angle parameters. The set of particles involved diff --git a/openmmapi/include/openmm/HarmonicBondForce.h b/openmmapi/include/openmm/HarmonicBondForce.h index 2c2ca4310..a0921ff43 100644 --- a/openmmapi/include/openmm/HarmonicBondForce.h +++ b/openmmapi/include/openmm/HarmonicBondForce.h @@ -92,7 +92,7 @@ public: /** * Update the per-bond parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-bond parameters. The set of particles involved diff --git a/openmmapi/include/openmm/NonbondedForce.h b/openmmapi/include/openmm/NonbondedForce.h index 371acb515..4f0d815ae 100644 --- a/openmmapi/include/openmm/NonbondedForce.h +++ b/openmmapi/include/openmm/NonbondedForce.h @@ -343,7 +343,7 @@ public: * Update the particle and exception parameters in a Context to match those stored in this Force object. This method * provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. * Simply call setParticleParameters() and setExceptionParameters() to modify this object's parameters, then call - * updateParametersInState() to copy them over to the Context. + * updateParametersInContext() to copy them over to the Context. * * This method has several limitations. The only information it updates is the parameters of particles and exceptions. * All other aspects of the Force (the nonbonded method, the cutoff distance, etc.) are unaffected and can only be diff --git a/openmmapi/include/openmm/PeriodicTorsionForce.h b/openmmapi/include/openmm/PeriodicTorsionForce.h index 5e06ad940..1cca5e4f5 100644 --- a/openmmapi/include/openmm/PeriodicTorsionForce.h +++ b/openmmapi/include/openmm/PeriodicTorsionForce.h @@ -101,7 +101,7 @@ public: /** * Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-torsion parameters. The set of particles involved diff --git a/openmmapi/include/openmm/RBTorsionForce.h b/openmmapi/include/openmm/RBTorsionForce.h index 981901541..fe3abf0e8 100644 --- a/openmmapi/include/openmm/RBTorsionForce.h +++ b/openmmapi/include/openmm/RBTorsionForce.h @@ -110,7 +110,7 @@ public: /** * Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setTorsionParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-torsion parameters. The set of particles involved diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h index 17a8061a1..dc778dff2 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaAngleForce.h @@ -159,7 +159,7 @@ public: /** * Update the per-angle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-angle parameters. The set of particles involved diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h index 0ff2b4944..df4cd1309 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaBondForce.h @@ -131,7 +131,7 @@ public: /** * Update the per-bond parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-bond parameters. The set of particles involved diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h index 4ed9564a1..b7db3968b 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaGeneralizedKirkwoodForce.h @@ -156,7 +156,7 @@ public: /** * Update the per-particle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-particle parameters. All other aspects of the Force diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h index 39b23241b..6f4835eb9 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaInPlaneAngleForce.h @@ -164,7 +164,7 @@ public: /** * Update the per-angle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setAngleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-angle parameters. The set of particles involved diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h index 321ea05c1..776ee864d 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaMultipoleForce.h @@ -340,7 +340,7 @@ public: /** * Update the multipole parameters in a Context to match those stored in this Force object. This method * provides an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setMultipoleParameters() to modify this object's parameters, then call updateParametersInState() to + * Simply call setMultipoleParameters() to modify this object's parameters, then call updateParametersInContext() to * copy them over to the Context. * * This method has several limitations. The only information it updates is the parameters of multipoles. diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h index 23d416627..ab4f27129 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaOutOfPlaneBendForce.h @@ -156,7 +156,7 @@ public: /** * Update the per-bend term parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setOutOfPlaneBendParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setOutOfPlaneBendParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-bend term parameters. The set of particles involved diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h index c04ef68b4..efb3e3749 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaPiTorsionForce.h @@ -106,7 +106,7 @@ public: /** * Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setPiTorsionParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setPiTorsionParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-torsion parameters. The set of particles involved diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h index cd45844c0..ab40c5db0 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaStretchBendForce.h @@ -112,7 +112,7 @@ public: /** * Update the per-stretch-bend term parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setStretchBendParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setStretchBendParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-stretch-bend term parameters. The set of particles involved diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h index 0dbc0500f..82421bd28 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaVdwForce.h @@ -205,7 +205,7 @@ public: /** * Update the per-particle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-particle parameters. All other aspects of the Force diff --git a/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h b/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h index acc1fd74e..8a00a9293 100644 --- a/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h +++ b/plugins/amoeba/openmmapi/include/openmm/AmoebaWcaDispersionForce.h @@ -92,7 +92,7 @@ public: /** * Update the per-particle parameters in a Context to match those stored in this Force object. This method provides * an efficient method to update certain parameters in an existing Context without needing to reinitialize it. - * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInState() + * Simply call setParticleParameters() to modify this object's parameters, then call updateParametersInContext() * to copy them over to the Context. * * The only information this method updates is the values of per-particle parameters. All other aspects of the Force -- GitLab From f66c9b61847cfc8ba61e78999139864933c8bc0b Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 19 Mar 2015 13:41:06 -0700 Subject: [PATCH 319/338] Simplification to reference platform tests --- .../tests/TestReferenceAndersenThermostat.cpp | 5 ++--- .../tests/TestReferenceBrownianIntegrator.cpp | 7 ++----- .../tests/TestReferenceCMMotionRemover.cpp | 3 ++- .../tests/TestReferenceCheckpoints.cpp | 4 ++-- .../tests/TestReferenceCustomAngleForce.cpp | 4 ++-- .../tests/TestReferenceCustomBondForce.cpp | 3 ++- .../TestReferenceCustomCompoundBondForce.cpp | 8 ++------ .../TestReferenceCustomExternalForce.cpp | 3 ++- .../tests/TestReferenceCustomGBForce.cpp | 9 ++------- .../tests/TestReferenceCustomHbondForce.cpp | 7 ++----- .../tests/TestReferenceCustomIntegrator.cpp | 14 ++----------- .../TestReferenceCustomManyParticleForce.cpp | 8 ++------ .../TestReferenceCustomNonbondedForce.cpp | 20 ++----------------- .../tests/TestReferenceCustomTorsionForce.cpp | 5 ++--- .../reference/tests/TestReferenceEwald.cpp | 10 ++-------- .../tests/TestReferenceGBSAOBCForce.cpp | 6 ++---- .../tests/TestReferenceGBVIForce.cpp | 5 ++--- .../tests/TestReferenceHarmonicAngleForce.cpp | 3 ++- .../tests/TestReferenceHarmonicBondForce.cpp | 3 ++- .../tests/TestReferenceKineticEnergy.cpp | 3 ++- .../tests/TestReferenceLangevinIntegrator.cpp | 7 ++----- .../TestReferenceLocalEnergyMinimizer.cpp | 5 ++--- ...ReferenceMonteCarloAnisotropicBarostat.cpp | 7 ++----- .../tests/TestReferenceMonteCarloBarostat.cpp | 5 ++--- ...estReferenceMonteCarloMembraneBarostat.cpp | 4 ++-- .../tests/TestReferenceNonbondedForce.cpp | 11 ++-------- .../TestReferencePeriodicTorsionForce.cpp | 3 ++- .../tests/TestReferenceRBTorsionForce.cpp | 3 ++- .../reference/tests/TestReferenceRandom.cpp | 3 ++- .../reference/tests/TestReferenceSettle.cpp | 3 ++- ...estReferenceVariableLangevinIntegrator.cpp | 8 ++------ .../TestReferenceVariableVerletIntegrator.cpp | 7 ++----- .../tests/TestReferenceVerletIntegrator.cpp | 6 ++---- .../tests/TestReferenceVirtualSites.cpp | 8 ++------ 34 files changed, 68 insertions(+), 142 deletions(-) diff --git a/platforms/reference/tests/TestReferenceAndersenThermostat.cpp b/platforms/reference/tests/TestReferenceAndersenThermostat.cpp index 0ca2a70ba..5e61024ce 100644 --- a/platforms/reference/tests/TestReferenceAndersenThermostat.cpp +++ b/platforms/reference/tests/TestReferenceAndersenThermostat.cpp @@ -48,12 +48,13 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + void testTemperature() { const int numParticles = 8; const double temp = 100.0; const double collisionFreq = 10.0; const int numSteps = 5000; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.003); NonbondedForce* forceField = new NonbondedForce(); @@ -94,7 +95,6 @@ void testConstraints() { const double temp = 100.0; const double collisionFreq = 10.0; const int numSteps = 15000; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.004); NonbondedForce* forceField = new NonbondedForce(); @@ -147,7 +147,6 @@ void testRandomSeed() { const int numParticles = 8; const double temp = 100.0; const double collisionFreq = 10.0; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); NonbondedForce* forceField = new NonbondedForce(); diff --git a/platforms/reference/tests/TestReferenceBrownianIntegrator.cpp b/platforms/reference/tests/TestReferenceBrownianIntegrator.cpp index b678d22c2..c50e9ffc2 100644 --- a/platforms/reference/tests/TestReferenceBrownianIntegrator.cpp +++ b/platforms/reference/tests/TestReferenceBrownianIntegrator.cpp @@ -48,10 +48,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSingleBond() { - ReferencePlatform platform; System system; system.addParticle(2.0); system.addParticle(2.0); @@ -88,7 +89,6 @@ void testTemperature() { const int numParticles = 8; const int numBonds = numParticles-1; const double temp = 10.0; - ReferencePlatform platform; System system; BrownianIntegrator integrator(temp, 2.0, 0.01); HarmonicBondForce* forceField = new HarmonicBondForce(); @@ -125,7 +125,6 @@ void testTemperature() { void testConstraints() { const int numParticles = 8; const double temp = 100.0; - ReferencePlatform platform; System system; BrownianIntegrator integrator(temp, 2.0, 0.001); integrator.setConstraintTolerance(1e-5); @@ -165,7 +164,6 @@ void testConstraints() { } void testConstrainedMasslessParticles() { - ReferencePlatform platform; System system; system.addParticle(0.0); system.addParticle(1.0); @@ -200,7 +198,6 @@ void testRandomSeed() { const int numParticles = 8; const double temp = 100.0; const double collisionFreq = 10.0; - ReferencePlatform platform; System system; BrownianIntegrator integrator(temp, 2.0, 0.001); NonbondedForce* forceField = new NonbondedForce(); diff --git a/platforms/reference/tests/TestReferenceCMMotionRemover.cpp b/platforms/reference/tests/TestReferenceCMMotionRemover.cpp index d3656b1ed..7e8403277 100644 --- a/platforms/reference/tests/TestReferenceCMMotionRemover.cpp +++ b/platforms/reference/tests/TestReferenceCMMotionRemover.cpp @@ -49,6 +49,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + Vec3 calcCM(const vector& values, System& system) { Vec3 cm; for (int j = 0; j < system.getNumParticles(); ++j) { @@ -63,7 +65,6 @@ void testMotionRemoval() { const int numParticles = 8; const double temp = 100.0; const double collisionFreq = 10.0; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); HarmonicBondForce* bonds = new HarmonicBondForce(); diff --git a/platforms/reference/tests/TestReferenceCheckpoints.cpp b/platforms/reference/tests/TestReferenceCheckpoints.cpp index a47934ca6..4356494b2 100644 --- a/platforms/reference/tests/TestReferenceCheckpoints.cpp +++ b/platforms/reference/tests/TestReferenceCheckpoints.cpp @@ -48,6 +48,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void compareStates(State& s1, State& s2) { @@ -71,7 +73,6 @@ void testCheckpoint() { const int numParticles = 10; const double boxSize = 3.0; const double temperature = 200.0; - ReferencePlatform platform; System system; system.addForce(new AndersenThermostat(0.0, 100.0)); NonbondedForce* nonbonded = new NonbondedForce(); @@ -125,7 +126,6 @@ void testSetState() { const int numParticles = 10; const double boxSize = 3.0; const double temperature = 200.0; - ReferencePlatform platform; System system; system.addForce(new AndersenThermostat(0.0, 100.0)); NonbondedForce* nonbonded = new NonbondedForce(); diff --git a/platforms/reference/tests/TestReferenceCustomAngleForce.cpp b/platforms/reference/tests/TestReferenceCustomAngleForce.cpp index 179332463..b892397e6 100644 --- a/platforms/reference/tests/TestReferenceCustomAngleForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomAngleForce.cpp @@ -47,11 +47,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testAngles() { - ReferencePlatform platform; - // Create a system using a CustomAngleForce. System customSystem; diff --git a/platforms/reference/tests/TestReferenceCustomBondForce.cpp b/platforms/reference/tests/TestReferenceCustomBondForce.cpp index eaf5e6a20..a50bc3e01 100644 --- a/platforms/reference/tests/TestReferenceCustomBondForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomBondForce.cpp @@ -46,10 +46,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testBonds() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp b/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp index 24514240d..00c109c75 100644 --- a/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp @@ -52,11 +52,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testBond() { - ReferencePlatform platform; - // Create a system using a CustomCompoundBondForce. System customSystem; @@ -147,7 +147,6 @@ void testBond() { } void testPositionDependence() { - ReferencePlatform platform; System customSystem; customSystem.addParticle(1.0); customSystem.addParticle(1.0); @@ -179,7 +178,6 @@ void testContinuous2DFunction() { const double xmax = 1.1; const double ymin = 0.0; const double ymax = 0.9; - ReferencePlatform platform; System system; system.addParticle(1.0); VerletIntegrator integrator(0.01); @@ -227,7 +225,6 @@ void testContinuous3DFunction() { const double ymax = 0.9; const double zmin = 0.2; const double zmax = 1.3; - ReferencePlatform platform; System system; system.addParticle(1.0); VerletIntegrator integrator(0.01); @@ -273,7 +270,6 @@ void testContinuous3DFunction() { void testMultipleBonds() { // Two compound bonds using Urey-Bradley example from API doc - ReferencePlatform platform; System customSystem; customSystem.addParticle(1.0); customSystem.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceCustomExternalForce.cpp b/platforms/reference/tests/TestReferenceCustomExternalForce.cpp index 5c46385af..e9ae2ff39 100644 --- a/platforms/reference/tests/TestReferenceCustomExternalForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomExternalForce.cpp @@ -46,10 +46,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testForce() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceCustomGBForce.cpp b/platforms/reference/tests/TestReferenceCustomGBForce.cpp index c3fa72de7..1997566b3 100644 --- a/platforms/reference/tests/TestReferenceCustomGBForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomGBForce.cpp @@ -51,6 +51,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMethod customMethod) { @@ -58,7 +60,6 @@ void testOBC(GBSAOBCForce::NonbondedMethod obcMethod, CustomGBForce::NonbondedMe const int numParticles = numMolecules*2; const double boxSize = 10.0; const double cutoff = 2.0; - ReferencePlatform platform; // Create two systems: one with a GBSAOBCForce, and one using a CustomGBForce to implement the same interaction. @@ -190,7 +191,6 @@ void testMembrane() { const int numMolecules = 70; const int numParticles = numMolecules*2; const double boxSize = 10.0; - ReferencePlatform platform; // Create a system with an implicit membrane. @@ -280,7 +280,6 @@ void testMembrane() { } void testTabulatedFunction() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -313,7 +312,6 @@ void testTabulatedFunction() { } void testMultipleChainRules() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -341,7 +339,6 @@ void testMultipleChainRules() { } void testPositionDependence() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -405,7 +402,6 @@ void testPositionDependence() { } void testExclusions() { - ReferencePlatform platform; for (int i = 3; i < 4; i++) { System system; system.addParticle(1.0); @@ -817,7 +813,6 @@ void testGBVI(GBVIForce::NonbondedMethod gbviMethod, CustomGBForce::NonbondedMet const int numMolecules = 1; const double boxSize = 10.0; - ReferencePlatform platform; GBVIForce* gbvi = new GBVIForce(); std::vector positions; diff --git a/platforms/reference/tests/TestReferenceCustomHbondForce.cpp b/platforms/reference/tests/TestReferenceCustomHbondForce.cpp index 37215258e..e0dd8c1dd 100644 --- a/platforms/reference/tests/TestReferenceCustomHbondForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomHbondForce.cpp @@ -49,11 +49,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testHbond() { - ReferencePlatform platform; - // Create a system using a CustomHbondForce. System customSystem; @@ -151,7 +151,6 @@ void testHbond() { } void testExclusions() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -178,7 +177,6 @@ void testExclusions() { } void testCutoff() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -206,7 +204,6 @@ void testCutoff() { } void testCustomFunctions() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceCustomIntegrator.cpp b/platforms/reference/tests/TestReferenceCustomIntegrator.cpp index 829a8ed29..0eb6dfa5e 100644 --- a/platforms/reference/tests/TestReferenceCustomIntegrator.cpp +++ b/platforms/reference/tests/TestReferenceCustomIntegrator.cpp @@ -49,13 +49,14 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; /** * Test a simple leapfrog integrator on a single bond. */ void testSingleBond() { - ReferencePlatform platform; System system; system.addParticle(2.0); system.addParticle(2.0); @@ -101,7 +102,6 @@ void testSingleBond() { void testConstraints() { const int numParticles = 8; const double temp = 500.0; - ReferencePlatform platform; System system; CustomIntegrator integrator(0.002); integrator.addPerDofVariable("oldx", 0); @@ -160,7 +160,6 @@ void testConstraints() { */ void testVelocityConstraints() { const int numParticles = 10; - ReferencePlatform platform; System system; CustomIntegrator integrator(0.002); integrator.addPerDofVariable("x1", 0); @@ -236,7 +235,6 @@ void testVelocityConstraints() { } void testConstrainedMasslessParticles() { - ReferencePlatform platform; System system; system.addParticle(0.0); system.addParticle(1.0); @@ -282,7 +280,6 @@ void testWithThermostat() { const double temp = 100.0; const double collisionFreq = 10.0; const int numSteps = 5000; - ReferencePlatform platform; System system; CustomIntegrator integrator(0.003); integrator.addUpdateContextState(); @@ -324,7 +321,6 @@ void testWithThermostat() { * Test a Monte Carlo integrator that uses global variables and depends on energy. */ void testMonteCarlo() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -379,7 +375,6 @@ void testMonteCarlo() { void testSum() { const int numParticles = 200; const double boxSize = 10; - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); NonbondedForce* nb = new NonbondedForce(); @@ -422,7 +417,6 @@ void testSum() { * Test an integrator that both uses and modifies a context parameter. */ void testParameter() { - ReferencePlatform platform; System system; system.addParticle(1.0); AndersenThermostat* thermostat = new AndersenThermostat(0.1, 0.1); @@ -448,7 +442,6 @@ void testRandomDistributions() { const int numParticles = 100; const int numBins = 20; const int numSteps = 100; - ReferencePlatform platform; System system; for (int i = 0; i < numParticles; i++) system.addParticle(1.0); @@ -516,7 +509,6 @@ void testRandomDistributions() { void testPerDofVariables() { const int numParticles = 200; const double boxSize = 10; - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); NonbondedForce* nb = new NonbondedForce(); @@ -571,7 +563,6 @@ void testPerDofVariables() { * Test evaluating force groups separately. */ void testForceGroups() { - ReferencePlatform platform; System system; system.addParticle(2.0); system.addParticle(2.0); @@ -647,7 +638,6 @@ void testForceGroups() { */ void testRespa() { const int numParticles = 8; - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(4, 0, 0), Vec3(0, 4, 0), Vec3(0, 0, 4)); CustomIntegrator integrator(0.002); diff --git a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp index f0967c659..ec3f926a5 100644 --- a/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomManyParticleForce.cpp @@ -51,6 +51,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; Vec3 computeDelta(const Vec3& pos1, const Vec3& pos2, bool periodic, const Vec3* periodicBoxVectors) { @@ -93,7 +95,6 @@ void validateAxilrodTeller(CustomManyParticleForce* force, const vector& p ASSERT(!system.usesPeriodicBoundaryConditions()); } VerletIntegrator integrator(0.001); - ReferencePlatform platform; Context context(system, integrator, platform); context.setPositions(positions); State state1 = context.getState(State::Forces | State::Energy); @@ -155,7 +156,6 @@ void validateStillingerWeber(CustomManyParticleForce* force, const vector& system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); system.addForce(force); VerletIntegrator integrator(0.001); - ReferencePlatform platform; Context context(system, integrator, platform); context.setPositions(positions); State state1 = context.getState(State::Forces | State::Energy); @@ -340,7 +340,6 @@ void testExclusions() { void testAllTerms() { int numParticles = 4; - ReferencePlatform platform; // Create a system with a CustomManyParticleForce. @@ -424,7 +423,6 @@ void testParameters() { } system.addForce(force); VerletIntegrator integrator(0.001); - ReferencePlatform platform; Context context(system, integrator, platform); context.setPositions(positions); @@ -510,7 +508,6 @@ void testTabulatedFunctions() { } system.addForce(force); VerletIntegrator integrator(0.001); - ReferencePlatform platform; Context context(system, integrator, platform); context.setPositions(positions); @@ -562,7 +559,6 @@ void testTypeFilters() { force->setTypeFilter(2, f2); system.addForce(force); VerletIntegrator integrator(0.001); - ReferencePlatform platform; Context context(system, integrator, platform); context.setPositions(positions); diff --git a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp index a4209c6e6..4c460a3e6 100644 --- a/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomNonbondedForce.cpp @@ -53,10 +53,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSimpleExpression() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -79,7 +80,6 @@ void testSimpleExpression() { } void testParameters() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -140,7 +140,6 @@ void testParameters() { } void testExclusions() { - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); CustomNonbondedForce* nonbonded = new CustomNonbondedForce("a*r; a=a1+a2"); @@ -171,7 +170,6 @@ void testExclusions() { } void testCutoff() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -201,7 +199,6 @@ void testCutoff() { } void testPeriodic() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -232,7 +229,6 @@ void testPeriodic() { } void testTriclinic() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -292,7 +288,6 @@ void testTriclinic() { } void testContinuous1DFunction() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -337,7 +332,6 @@ void testContinuous2DFunction() { const double xmax = 1.5; const double ymin = 0.0; const double ymax = 2.1; - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -389,7 +383,6 @@ void testContinuous3DFunction() { const double ymax = 0.7; const double zmin = 0.2; const double zmax = 0.9; - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -439,7 +432,6 @@ void testContinuous3DFunction() { } void testDiscrete1DFunction() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -469,7 +461,6 @@ void testDiscrete1DFunction() { void testDiscrete2DFunction() { const int xsize = 10; const int ysize = 5; - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -503,7 +494,6 @@ void testDiscrete3DFunction() { const int xsize = 8; const int ysize = 5; const int zsize = 6; - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -540,7 +530,6 @@ void testCoulombLennardJones() { const int numMolecules = 300; const int numParticles = numMolecules*2; const double boxSize = 20.0; - ReferencePlatform platform; // Create two systems: one with a NonbondedForce, and one using a CustomNonbondedForce to implement the same interaction. @@ -614,7 +603,6 @@ void testCoulombLennardJones() { } void testSwitchingFunction() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -673,7 +661,6 @@ void testLongRangeCorrection() { int numParticles = gridSize*gridSize*gridSize; double boxSize = gridSize*0.7; double cutoff = boxSize/3; - ReferencePlatform platform; System standardSystem; System customSystem; VerletIntegrator integrator1(0.01); @@ -748,7 +735,6 @@ void testLongRangeCorrection() { void testInteractionGroups() { const int numParticles = 6; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); CustomNonbondedForce* nonbonded = new CustomNonbondedForce("v1+v2"); @@ -790,7 +776,6 @@ void testLargeInteractionGroup() { // Create a large system. - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); for (int i = 0; i < numParticles; i++) @@ -868,7 +853,6 @@ void testInteractionGroupLongRangeCorrection() { const int numParticles = 10; const double boxSize = 10.0; const double cutoff = 0.5; - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); CustomNonbondedForce* nonbonded = new CustomNonbondedForce("c1*c2*r^-4"); diff --git a/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp b/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp index 3ddd6773d..b2dcb3e5b 100644 --- a/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp +++ b/platforms/reference/tests/TestReferenceCustomTorsionForce.cpp @@ -50,11 +50,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testTorsions() { - ReferencePlatform platform; - // Create a system using a CustomTorsionForce. System customSystem; @@ -141,7 +141,6 @@ void testTorsions() { } void testRange() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceEwald.cpp b/platforms/reference/tests/TestReferenceEwald.cpp index 8fe41e63f..25f8b1898 100644 --- a/platforms/reference/tests/TestReferenceEwald.cpp +++ b/platforms/reference/tests/TestReferenceEwald.cpp @@ -48,6 +48,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double EWALD_TOL = 1e-5; const double PME_TOL = 5e-5; @@ -59,9 +61,7 @@ void testEwaldExact() { const double cutoff = 1.0; const double boxSize = 2.82; - ReferencePlatform platform; System system; - for (int i = 0; i < numParticles/2; i++) system.addParticle(22.99); for (int i = 0; i < numParticles/2; i++) @@ -112,7 +112,6 @@ void testEwaldPME() { // Use amorphous NaCl system // The particles are simple charges, no VdW interactions - ReferencePlatform platform; System system; for (int i = 0; i < numParticles/2; i++) system.addParticle(22.99); @@ -217,7 +216,6 @@ void testEwaldPME() { } void testEwald2Ions() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -244,7 +242,6 @@ void testEwald2Ions() { } void testWaterSystem() { - ReferencePlatform platform; System system; static int numParticles = 648; const double boxSize = 1.86206; @@ -305,7 +302,6 @@ void testWaterSystem() { void testTriclinic() { // Create a triclinic box containing eight particles. - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(2.5, 0, 0), Vec3(0.5, 3.0, 0), Vec3(0.7, 0.9, 3.5)); for (int i = 0; i < 8; i++) @@ -373,7 +369,6 @@ void testErrorTolerance(NonbondedForce::NonbondedMethod method) { positions[i] = Vec3(boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt)); } force->setNonbondedMethod(method); - ReferencePlatform platform; // For various values of the cutoff and error tolerance, see if the actual error is reasonable. @@ -425,7 +420,6 @@ void testPMEParameters() { positions[i] = Vec3(boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt), boxWidth*genrand_real2(sfmt)); } force->setNonbondedMethod(NonbondedForce::PME); - ReferencePlatform platform; // Compute the energy with an error tolerance of 1e-3. diff --git a/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp b/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp index d9ff935a1..c50c64f96 100644 --- a/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp +++ b/platforms/reference/tests/TestReferenceGBSAOBCForce.cpp @@ -48,10 +48,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSingleParticle() { - ReferencePlatform platform; System system; system.addParticle(2.0); LangevinIntegrator integrator(0, 0.1, 0.01); @@ -85,7 +86,6 @@ void testSingleParticle() { } void testGlobalSettings() { - ReferencePlatform platform; System system; system.addParticle(2.0); LangevinIntegrator integrator(0, 0.1, 0.01); @@ -114,7 +114,6 @@ void testGlobalSettings() { } void testCutoffAndPeriodic() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -183,7 +182,6 @@ void testCutoffAndPeriodic() { } void testForce() { - ReferencePlatform platform; const int numParticles = 10; System system; LangevinIntegrator integrator(0, 0.1, 0.01); diff --git a/platforms/reference/tests/TestReferenceGBVIForce.cpp b/platforms/reference/tests/TestReferenceGBVIForce.cpp index ed1f782fb..25455faec 100644 --- a/platforms/reference/tests/TestReferenceGBVIForce.cpp +++ b/platforms/reference/tests/TestReferenceGBVIForce.cpp @@ -50,10 +50,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSingleParticle() { - ReferencePlatform platform; System system; system.addParticle(2.0); LangevinIntegrator integrator(0, 0.1, 0.01); @@ -89,8 +90,6 @@ void testSingleParticle() { } void testEnergyEthane(int applyBornRadiiScaling) { - - ReferencePlatform platform; const int numParticles = 8; System system; LangevinIntegrator integrator(0, 0.1, 0.01); diff --git a/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp b/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp index 0d0f7c42c..c8b701725 100644 --- a/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp +++ b/platforms/reference/tests/TestReferenceHarmonicAngleForce.cpp @@ -46,10 +46,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testAngles() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp b/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp index f4bab1069..cccf3c4f3 100644 --- a/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp +++ b/platforms/reference/tests/TestReferenceHarmonicBondForce.cpp @@ -46,10 +46,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testBonds() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceKineticEnergy.cpp b/platforms/reference/tests/TestReferenceKineticEnergy.cpp index c6eb21ece..428a6ed2c 100644 --- a/platforms/reference/tests/TestReferenceKineticEnergy.cpp +++ b/platforms/reference/tests/TestReferenceKineticEnergy.cpp @@ -44,10 +44,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testCalcKE() { - ReferencePlatform platform; System system; for (int i = 0; i < 4; ++i) system.addParticle(i+1); diff --git a/platforms/reference/tests/TestReferenceLangevinIntegrator.cpp b/platforms/reference/tests/TestReferenceLangevinIntegrator.cpp index 61066c1fe..c2ccefe20 100644 --- a/platforms/reference/tests/TestReferenceLangevinIntegrator.cpp +++ b/platforms/reference/tests/TestReferenceLangevinIntegrator.cpp @@ -48,10 +48,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSingleBond() { - ReferencePlatform platform; System system; system.addParticle(2.0); system.addParticle(2.0); @@ -97,7 +98,6 @@ void testSingleBond() { void testTemperature() { const int numParticles = 8; const double temp = 100.0; - ReferencePlatform platform; System system; LangevinIntegrator integrator(temp, 2.0, 0.01); NonbondedForce* forceField = new NonbondedForce(); @@ -132,7 +132,6 @@ void testTemperature() { void testConstraints() { const int numParticles = 8; const double temp = 100.0; - ReferencePlatform platform; System system; LangevinIntegrator integrator(temp, 2.0, 0.01); integrator.setConstraintTolerance(1e-5); @@ -172,7 +171,6 @@ void testConstraints() { } void testConstrainedMasslessParticles() { - ReferencePlatform platform; System system; system.addParticle(0.0); system.addParticle(1.0); @@ -207,7 +205,6 @@ void testRandomSeed() { const int numParticles = 8; const double temp = 100.0; const double collisionFreq = 10.0; - ReferencePlatform platform; System system; LangevinIntegrator integrator(temp, 2.0, 0.01); NonbondedForce* forceField = new NonbondedForce(); diff --git a/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp b/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp index f49bed60b..02c309b94 100644 --- a/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp +++ b/platforms/reference/tests/TestReferenceLocalEnergyMinimizer.cpp @@ -45,6 +45,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + void testHarmonicBonds() { const int numParticles = 10; System system; @@ -64,7 +66,6 @@ void testHarmonicBonds() { // Minimize it and check that all bonds are at their equilibrium distances. VerletIntegrator integrator(0.01); - ReferencePlatform platform; Context context(system, integrator, platform); context.setPositions(positions); LocalEnergyMinimizer::minimize(context, 1e-5); @@ -105,7 +106,6 @@ void testLargeSystem() { // Minimize it and verify that the energy has decreased. - ReferencePlatform platform; VerletIntegrator integrator(0.01); Context context(system, integrator, platform); context.setPositions(positions); @@ -167,7 +167,6 @@ void testVirtualSites() { // Minimize it and verify that the energy has decreased. - ReferencePlatform platform; VerletIntegrator integrator(0.01); Context context(system, integrator, platform); context.setPositions(positions); diff --git a/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp index 02882fcfa..031b8c9f5 100644 --- a/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp +++ b/platforms/reference/tests/TestReferenceMonteCarloAnisotropicBarostat.cpp @@ -51,6 +51,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + void testIdealGas() { const int numParticles = 64; const int frequency = 10; @@ -63,7 +65,6 @@ void testIdealGas() { // Create a gas of noninteracting particles. - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(initialLength, 0, 0), Vec3(0, 0.5*initialLength, 0), Vec3(0, 0, 2*initialLength)); vector positions(numParticles); @@ -124,7 +125,6 @@ void testIdealGasAxis(int axis) { // Create a gas of noninteracting particles. - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(initialLength, 0, 0), Vec3(0, 0.5*initialLength, 0), Vec3(0, 0, 2*initialLength)); vector positions(numParticles); @@ -182,7 +182,6 @@ void testRandomSeed() { const int numParticles = 8; const double temp = 100.0; const double pressure = 1.5; - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(8, 0, 0), Vec3(0, 8, 0), Vec3(0, 0, 8)); VerletIntegrator integrator(0.01); @@ -255,7 +254,6 @@ void testTriclinic() { // Create a gas of noninteracting particles. - ReferencePlatform platform; System system; Vec3 initialBox[3]; initialBox[0] = Vec3(initialLength, 0, 0); @@ -347,7 +345,6 @@ void testEinsteinCrystal() { const double pres3[] = {2.0, 8.0, 15.0}; const double initialVolume = numParticles*BOLTZ*temp/pressureInMD; const double initialLength = std::pow(initialVolume, 1.0/3.0); - ReferencePlatform platform; vector initialPositions(3); vector results; // Run four groups of anisotropic simulations; scaling just x, y, z, then all three. diff --git a/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp index f436114f4..65c513e96 100644 --- a/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp +++ b/platforms/reference/tests/TestReferenceMonteCarloBarostat.cpp @@ -49,8 +49,9 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + void testChangingBoxSize() { - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(4, 0, 0), Vec3(0, 5, 0), Vec3(0, 0, 6)); system.addParticle(1.0); @@ -100,7 +101,6 @@ void testIdealGas() { // Create a gas of noninteracting particles. - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(initialLength, 0, 0), Vec3(0, 0.5*initialLength, 0), Vec3(0, 0, 2*initialLength)); vector positions(numParticles); @@ -148,7 +148,6 @@ void testRandomSeed() { const int numParticles = 8; const double temp = 100.0; const double pressure = 1.5; - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(8, 0, 0), Vec3(0, 8, 0), Vec3(0, 0, 8)); VerletIntegrator integrator(0.01); diff --git a/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp b/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp index cf5c09b3e..93761ba33 100644 --- a/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp +++ b/platforms/reference/tests/TestReferenceMonteCarloMembraneBarostat.cpp @@ -49,6 +49,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + void testIdealGas(MonteCarloMembraneBarostat::XYMode xymode, MonteCarloMembraneBarostat::ZMode zmode) { const int numParticles = 64; const int frequency = 1; @@ -63,7 +65,6 @@ void testIdealGas(MonteCarloMembraneBarostat::XYMode xymode, MonteCarloMembraneB // Create a gas of noninteracting particles. - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(initialLength, 0, 0), Vec3(0, 0.5*initialLength, 0), Vec3(0, 0, 2*initialLength)); vector positions(numParticles); @@ -121,7 +122,6 @@ void testRandomSeed() { const double temp = 100.0; const double pressure = 1.5; const double tension = 0.3; - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(8, 0, 0), Vec3(0, 8, 0), Vec3(0, 0, 8)); VerletIntegrator integrator(0.01); diff --git a/platforms/reference/tests/TestReferenceNonbondedForce.cpp b/platforms/reference/tests/TestReferenceNonbondedForce.cpp index f14be6821..2f3a52e57 100644 --- a/platforms/reference/tests/TestReferenceNonbondedForce.cpp +++ b/platforms/reference/tests/TestReferenceNonbondedForce.cpp @@ -48,10 +48,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testCoulomb() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -76,7 +77,6 @@ void testCoulomb() { } void testLJ() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -103,7 +103,6 @@ void testLJ() { } void testExclusionsAnd14() { - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); NonbondedForce* nonbonded = new NonbondedForce(); @@ -190,7 +189,6 @@ void testExclusionsAnd14() { } void testCutoff() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -229,7 +227,6 @@ void testCutoff() { } void testCutoff14() { - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); NonbondedForce* nonbonded = new NonbondedForce(); @@ -326,7 +323,6 @@ void testCutoff14() { } void testPeriodic() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -363,7 +359,6 @@ void testPeriodic() { } void testTriclinic() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -432,7 +427,6 @@ void testDispersionCorrection() { int numParticles = gridSize*gridSize*gridSize; double boxSize = gridSize*0.7; double cutoff = boxSize/3; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); NonbondedForce* nonbonded = new NonbondedForce(); @@ -496,7 +490,6 @@ void testDispersionCorrection() { } void testSwitchingFunction(NonbondedForce::NonbondedMethod method) { - ReferencePlatform platform; System system; system.setDefaultPeriodicBoxVectors(Vec3(6, 0, 0), Vec3(0, 6, 0), Vec3(0, 0, 6)); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp b/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp index 14bd5f752..ba7580b6c 100644 --- a/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp +++ b/platforms/reference/tests/TestReferencePeriodicTorsionForce.cpp @@ -46,10 +46,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testPeriodicTorsions() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceRBTorsionForce.cpp b/platforms/reference/tests/TestReferenceRBTorsionForce.cpp index 51cbfe899..c7f80b6c9 100644 --- a/platforms/reference/tests/TestReferenceRBTorsionForce.cpp +++ b/platforms/reference/tests/TestReferenceRBTorsionForce.cpp @@ -46,10 +46,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testRBTorsions() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceRandom.cpp b/platforms/reference/tests/TestReferenceRandom.cpp index a547a4e78..6eeed7e0e 100644 --- a/platforms/reference/tests/TestReferenceRandom.cpp +++ b/platforms/reference/tests/TestReferenceRandom.cpp @@ -43,6 +43,8 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + void testGaussian() { const int numValues = 10000000; double mean = 0.0; @@ -74,7 +76,6 @@ void testRandomVelocities() { const int numParticles = 10000; const double temperture = 100.0; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.01); for (int i = 0; i < numParticles; ++i) diff --git a/platforms/reference/tests/TestReferenceSettle.cpp b/platforms/reference/tests/TestReferenceSettle.cpp index ff8c3a872..e63892bd9 100644 --- a/platforms/reference/tests/TestReferenceSettle.cpp +++ b/platforms/reference/tests/TestReferenceSettle.cpp @@ -47,12 +47,13 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + void testConstraints() { const int numMolecules = 10; const int numParticles = numMolecules*3; const int numConstraints = numMolecules*3; const double temp = 100.0; - ReferencePlatform platform; System system; LangevinIntegrator integrator(temp, 2.0, 0.001); integrator.setConstraintTolerance(1e-5); diff --git a/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp b/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp index 7fa226530..d6fa874fc 100644 --- a/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp +++ b/platforms/reference/tests/TestReferenceVariableLangevinIntegrator.cpp @@ -48,10 +48,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSingleBond() { - ReferencePlatform platform; System system; system.addParticle(2.0); system.addParticle(2.0); @@ -97,7 +98,6 @@ void testSingleBond() { void testTemperature() { const int numParticles = 8; const double temp = 100.0; - ReferencePlatform platform; System system; VariableLangevinIntegrator integrator(temp, 5.0, 5e-5); NonbondedForce* forceField = new NonbondedForce(); @@ -133,7 +133,6 @@ void testTemperature() { void testConstraints() { const int numParticles = 8; const double temp = 100.0; - ReferencePlatform platform; System system; VariableLangevinIntegrator integrator(temp, 2.0, 1e-5); integrator.setConstraintTolerance(1e-5); @@ -174,7 +173,6 @@ void testConstraints() { } void testConstrainedMasslessParticles() { - ReferencePlatform platform; System system; system.addParticle(0.0); system.addParticle(1.0); @@ -208,7 +206,6 @@ void testConstrainedMasslessParticles() { void testRandomSeed() { const int numParticles = 8; const double temp = 100.0; - ReferencePlatform platform; System system; VariableLangevinIntegrator integrator(temp, 2.0, 1e-5); NonbondedForce* forceField = new NonbondedForce(); @@ -276,7 +273,6 @@ void testArgonBox() { // Create a box of argon atoms. - ReferencePlatform platform; System system; NonbondedForce* nonbonded = new NonbondedForce(); vector positions; diff --git a/platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp b/platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp index 1acdb88da..120400486 100644 --- a/platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp +++ b/platforms/reference/tests/TestReferenceVariableVerletIntegrator.cpp @@ -48,10 +48,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSingleBond() { - ReferencePlatform platform; System system; system.addParticle(2.0); system.addParticle(2.0); @@ -89,7 +90,6 @@ void testSingleBond() { void testConstraints() { const int numParticles = 8; const double temp = 500.0; - ReferencePlatform platform; System system; VariableVerletIntegrator integrator(1e-5); integrator.setConstraintTolerance(1e-5); @@ -148,7 +148,6 @@ void testConstraints() { void testConstrainedClusters() { const int numParticles = 7; const double temp = 500.0; - ReferencePlatform platform; System system; VariableVerletIntegrator integrator(1e-5); integrator.setConstraintTolerance(1e-5); @@ -211,7 +210,6 @@ void testConstrainedClusters() { } void testConstrainedMasslessParticles() { - ReferencePlatform platform; System system; system.addParticle(0.0); system.addParticle(1.0); @@ -255,7 +253,6 @@ void testArgonBox() { // Create a box of argon atoms. - ReferencePlatform platform; System system; NonbondedForce* nonbonded = new NonbondedForce(); vector positions; diff --git a/platforms/reference/tests/TestReferenceVerletIntegrator.cpp b/platforms/reference/tests/TestReferenceVerletIntegrator.cpp index 7c4723f38..c3eb060e8 100644 --- a/platforms/reference/tests/TestReferenceVerletIntegrator.cpp +++ b/platforms/reference/tests/TestReferenceVerletIntegrator.cpp @@ -48,10 +48,11 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + const double TOL = 1e-5; void testSingleBond() { - ReferencePlatform platform; System system; system.addParticle(2.0); system.addParticle(2.0); @@ -88,7 +89,6 @@ void testSingleBond() { void testConstraints() { const int numParticles = 8; const double temp = 500.0; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.002); integrator.setConstraintTolerance(1e-5); @@ -139,7 +139,6 @@ void testConstraints() { void testConstrainedClusters() { const int numParticles = 7; const double temp = 500.0; - ReferencePlatform platform; System system; VerletIntegrator integrator(0.001); integrator.setConstraintTolerance(1e-5); @@ -201,7 +200,6 @@ void testConstrainedClusters() { } void testConstrainedMasslessParticles() { - ReferencePlatform platform; System system; system.addParticle(0.0); system.addParticle(1.0); diff --git a/platforms/reference/tests/TestReferenceVirtualSites.cpp b/platforms/reference/tests/TestReferenceVirtualSites.cpp index 1424708e7..ff4afab9e 100644 --- a/platforms/reference/tests/TestReferenceVirtualSites.cpp +++ b/platforms/reference/tests/TestReferenceVirtualSites.cpp @@ -50,11 +50,12 @@ using namespace OpenMM; using namespace std; +ReferencePlatform platform; + /** * Check that massless particles are handled correctly. */ void testMasslessParticle() { - ReferencePlatform platform; System system; system.addParticle(0.0); system.addParticle(1.0); @@ -91,7 +92,6 @@ void testMasslessParticle() { * Test a TwoParticleAverageSite virtual site. */ void testTwoParticleAverage() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -128,7 +128,6 @@ void testTwoParticleAverage() { * Test a ThreeParticleAverageSite virtual site. */ void testThreeParticleAverage() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -170,7 +169,6 @@ void testThreeParticleAverage() { * Test an OutOfPlaneSite virtual site. */ void testOutOfPlane() { - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -223,7 +221,6 @@ void testLocalCoordinates() { const Vec3 xWeights(-1.0, 0.5, 0.5); const Vec3 yWeights(0.0, -1.0, 1.0); const Vec3 localPosition(0.4, 0.3, 0.2); - ReferencePlatform platform; System system; system.addParticle(1.0); system.addParticle(1.0); @@ -299,7 +296,6 @@ void testLocalCoordinates() { * when using virtual sites. */ void testConservationLaws() { - ReferencePlatform platform; System system; NonbondedForce* forceField = new NonbondedForce(); system.addForce(forceField); -- GitLab From 558b3636d2187b6ff5eda706ddcdb54de478a020 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Tue, 24 Mar 2015 16:48:19 -0700 Subject: [PATCH 320/338] Fixed a race condition in OpenCL --- platforms/opencl/src/OpenCLKernels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 216e0bbf4..9a4a913d0 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -131,10 +131,10 @@ double OpenCLCalcForcesAndEnergyKernel::finishComputation(ContextImpl& context, cl.getBondedUtilities().computeInteractions(groups); if ((groups&(1<::iterator iter = cl.getPostComputations().begin(); iter != cl.getPostComputations().end(); ++iter) sum += (*iter)->computeForceAndEnergy(includeForces, includeEnergy, groups); + cl.reduceForces(); cl.getIntegrationUtilities().distributeForcesFromVirtualSites(); if (includeEnergy) { OpenCLArray& energyArray = cl.getEnergyBuffer(); -- GitLab From 787869c355c7fae243794f619beff3b730315429 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 25 Mar 2015 14:09:34 -0700 Subject: [PATCH 321/338] Parallelized extraction of inverse matrix for CCMA --- .../cuda/src/CudaIntegrationUtilities.cpp | 182 ++++-------------- .../opencl/src/OpenCLIntegrationUtilities.cpp | 180 ++++------------- .../opencl/tests/TestOpenCLVirtualSites.cpp | 2 +- .../include/ReferenceCCMAAlgorithm.h | 13 +- .../SimTKReference/ReferenceCCMAAlgorithm.cpp | 72 +++++-- .../SimTKReference/ReferenceConstraints.cpp | 2 +- 6 files changed, 145 insertions(+), 306 deletions(-) diff --git a/platforms/cuda/src/CudaIntegrationUtilities.cpp b/platforms/cuda/src/CudaIntegrationUtilities.cpp index e3c94a93a..6deb2565b 100644 --- a/platforms/cuda/src/CudaIntegrationUtilities.cpp +++ b/platforms/cuda/src/CudaIntegrationUtilities.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2014 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -32,6 +32,7 @@ #include "openmm/VirtualSite.h" #include "quern.h" #include "CudaExpressionUtilities.h" +#include "ReferenceCCMAAlgorithm.h" #include #include #include @@ -304,157 +305,54 @@ CudaIntegrationUtilities::CudaIntegrationUtilities(CudaContext& context, const S int numCCMA = (int) ccmaConstraints.size(); if (numCCMA > 0) { - vector > atomConstraints(context.getNumAtoms()); + // Record information needed by ReferenceCCMAAlgorithm. + + vector > refIndices(numCCMA); + vector refDistance(numCCMA); for (int i = 0; i < numCCMA; i++) { - atomConstraints[atom1[ccmaConstraints[i]]].push_back(i); - atomConstraints[atom2[ccmaConstraints[i]]].push_back(i); + int index = ccmaConstraints[i]; + refIndices[i] = make_pair(atom1[index], atom2[index]); + refDistance[i] = distance[index]; } - vector > linkedConstraints(numCCMA); - for (unsigned atom = 0; atom < atomConstraints.size(); atom++) { - for (unsigned i = 0; i < atomConstraints[atom].size(); i++) - for (unsigned j = 0; j < i; j++) { - int c1 = atomConstraints[atom][i]; - int c2 = atomConstraints[atom][j]; - linkedConstraints[c1].push_back(c2); - linkedConstraints[c2].push_back(c1); + vector refMasses(numAtoms); + for (int i = 0; i < numAtoms; ++i) + refMasses[i] = (RealOpenMM) system.getParticleMass(i); + + // Look up angles for CCMA. + + vector angles; + for (int i = 0; i < system.getNumForces(); i++) { + const HarmonicAngleForce* force = dynamic_cast(&system.getForce(i)); + if (force != NULL) { + for (int j = 0; j < force->getNumAngles(); j++) { + int atom1, atom2, atom3; + double angle, k; + force->getAngleParameters(j, atom1, atom2, atom3, angle, k); + angles.push_back(ReferenceCCMAAlgorithm::AngleInfo(atom1, atom2, atom3, (RealOpenMM) angle)); } - } - int maxLinks = 0; - for (unsigned i = 0; i < linkedConstraints.size(); i++) - maxLinks = max(maxLinks, (int) linkedConstraints[i].size()); - int maxAtomConstraints = 0; - for (unsigned i = 0; i < atomConstraints.size(); i++) - maxAtomConstraints = max(maxAtomConstraints, (int) atomConstraints[i].size()); - - // Compute the constraint coupling matrix - - vector > atomAngles(numAtoms); - HarmonicAngleForce const* angleForce = NULL; - for (int i = 0; i < system.getNumForces() && angleForce == NULL; i++) - angleForce = dynamic_cast(&system.getForce(i)); - if (angleForce != NULL) - for (int i = 0; i < angleForce->getNumAngles(); i++) { - int particle1, particle2, particle3; - double angle, k; - angleForce->getAngleParameters(i, particle1, particle2, particle3, angle, k); - atomAngles[particle2].push_back(i); - } - vector > > matrix(numCCMA); - for (int j = 0; j < numCCMA; j++) { - for (int k = 0; k < numCCMA; k++) { - if (j == k) { - matrix[j].push_back(pair(j, 1.0)); - continue; - } - double scale; - int cj = ccmaConstraints[j]; - int ck = ccmaConstraints[k]; - int atomj0 = atom1[cj]; - int atomj1 = atom2[cj]; - int atomk0 = atom1[ck]; - int atomk1 = atom2[ck]; - int atoma, atomb, atomc; - double imj0 = 1.0/system.getParticleMass(atomj0); - double imj1 = 1.0/system.getParticleMass(atomj1); - if (atomj0 == atomk0) { - atoma = atomj1; - atomb = atomj0; - atomc = atomk1; - scale = imj0/(imj0+imj1); - } - else if (atomj1 == atomk1) { - atoma = atomj0; - atomb = atomj1; - atomc = atomk0; - scale = imj1/(imj0+imj1); - } - else if (atomj0 == atomk1) { - atoma = atomj1; - atomb = atomj0; - atomc = atomk0; - scale = imj0/(imj0+imj1); - } - else if (atomj1 == atomk0) { - atoma = atomj0; - atomb = atomj1; - atomc = atomk1; - scale = imj1/(imj0+imj1); - } - else - continue; // These constraints are not connected. - - // Look for a third constraint forming a triangle with these two. - - bool foundConstraint = false; - for (int m = 0; m < numCCMA; m++) { - int other = ccmaConstraints[m]; - if ((atom1[other] == atoma && atom2[other] == atomc) || (atom1[other] == atomc && atom2[other] == atoma)) { - double d1 = distance[cj]; - double d2 = distance[ck]; - double d3 = distance[other]; - matrix[j].push_back(pair(k, scale*(d1*d1+d2*d2-d3*d3)/(2.0*d1*d2))); - foundConstraint = true; - break; - } - } - if (!foundConstraint && angleForce != NULL) { - // We didn't find one, so look for an angle force field term. - - const vector& angleCandidates = atomAngles[atomb]; - for (vector::const_iterator iter = angleCandidates.begin(); iter != angleCandidates.end(); iter++) { - int particle1, particle2, particle3; - double angle, ka; - angleForce->getAngleParameters(*iter, particle1, particle2, particle3, angle, ka); - if ((particle1 == atoma && particle3 == atomc) || (particle3 == atoma && particle1 == atomc)) { - matrix[j].push_back(pair(k, scale*cos(angle))); - break; - } - } - } - } - } - - // Invert it using QR. - - vector matrixRowStart; - vector matrixColIndex; - vector matrixValue; - for (int i = 0; i < numCCMA; i++) { - matrixRowStart.push_back(matrixValue.size()); - for (int j = 0; j < (int) matrix[i].size(); j++) { - pair element = matrix[i][j]; - matrixColIndex.push_back(element.first); - matrixValue.push_back(element.second); } } - matrixRowStart.push_back(matrixValue.size()); - int *qRowStart, *qColIndex, *rRowStart, *rColIndex; - double *qValue, *rValue; - int result = QUERN_compute_qr(numCCMA, numCCMA, &matrixRowStart[0], &matrixColIndex[0], &matrixValue[0], NULL, - &qRowStart, &qColIndex, &qValue, &rRowStart, &rColIndex, &rValue); - vector rhs(numCCMA); - matrix.clear(); - matrix.resize(numCCMA); - for (int i = 0; i < numCCMA; i++) { - // Extract column i of the inverse matrix. - - for (int j = 0; j < numCCMA; j++) - rhs[j] = (i == j ? 1.0 : 0.0); - result = QUERN_multiply_with_q_transpose(numCCMA, qRowStart, qColIndex, qValue, &rhs[0]); - result = QUERN_solve_with_r(numCCMA, rRowStart, rColIndex, rValue, &rhs[0], &rhs[0]); - for (int j = 0; j < numCCMA; j++) { - double value = rhs[j]*distance[ccmaConstraints[i]]/distance[ccmaConstraints[j]]; - if (abs(value) > 0.1) - matrix[j].push_back(pair(i, value)); - } - } - QUERN_free_result(qRowStart, qColIndex, qValue); - QUERN_free_result(rRowStart, rColIndex, rValue); + + // Create a ReferenceCCMAAlgorithm. It will build and invert the constraint matrix for us. + + ReferenceCCMAAlgorithm ccma(numAtoms, numCCMA, refIndices, refDistance, refMasses, angles, 0.1); + vector > > matrix = ccma.getMatrix(); int maxRowElements = 0; for (unsigned i = 0; i < matrix.size(); i++) maxRowElements = max(maxRowElements, (int) matrix[i].size()); maxRowElements++; + // Build the list of constraints for each atom. + + vector > atomConstraints(context.getNumAtoms()); + for (int i = 0; i < numCCMA; i++) { + atomConstraints[atom1[ccmaConstraints[i]]].push_back(i); + atomConstraints[atom2[ccmaConstraints[i]]].push_back(i); + } + int maxAtomConstraints = 0; + for (unsigned i = 0; i < atomConstraints.size(); i++) + maxAtomConstraints = max(maxAtomConstraints, (int) atomConstraints[i].size()); + // Sort the constraints. vector constraintOrder(numCCMA); diff --git a/platforms/opencl/src/OpenCLIntegrationUtilities.cpp b/platforms/opencl/src/OpenCLIntegrationUtilities.cpp index 24be42646..ad588305b 100644 --- a/platforms/opencl/src/OpenCLIntegrationUtilities.cpp +++ b/platforms/opencl/src/OpenCLIntegrationUtilities.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2014 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -32,6 +32,7 @@ #include "openmm/VirtualSite.h" #include "quern.h" #include "OpenCLExpressionUtilities.h" +#include "ReferenceCCMAAlgorithm.h" #include #include #include @@ -323,157 +324,54 @@ OpenCLIntegrationUtilities::OpenCLIntegrationUtilities(OpenCLContext& context, c int numCCMA = (int) ccmaConstraints.size(); if (numCCMA > 0) { - vector > atomConstraints(context.getNumAtoms()); + // Record information needed by ReferenceCCMAAlgorithm. + + vector > refIndices(numCCMA); + vector refDistance(numCCMA); for (int i = 0; i < numCCMA; i++) { - atomConstraints[atom1[ccmaConstraints[i]]].push_back(i); - atomConstraints[atom2[ccmaConstraints[i]]].push_back(i); - } - vector > linkedConstraints(numCCMA); - for (unsigned atom = 0; atom < atomConstraints.size(); atom++) { - for (unsigned i = 0; i < atomConstraints[atom].size(); i++) - for (unsigned j = 0; j < i; j++) { - int c1 = atomConstraints[atom][i]; - int c2 = atomConstraints[atom][j]; - linkedConstraints[c1].push_back(c2); - linkedConstraints[c2].push_back(c1); - } + int index = ccmaConstraints[i]; + refIndices[i] = make_pair(atom1[index], atom2[index]); + refDistance[i] = distance[index]; } - int maxLinks = 0; - for (unsigned i = 0; i < linkedConstraints.size(); i++) - maxLinks = max(maxLinks, (int) linkedConstraints[i].size()); - int maxAtomConstraints = 0; - for (unsigned i = 0; i < atomConstraints.size(); i++) - maxAtomConstraints = max(maxAtomConstraints, (int) atomConstraints[i].size()); - - // Compute the constraint coupling matrix - - vector > atomAngles(numAtoms); - HarmonicAngleForce const* angleForce = NULL; - for (int i = 0; i < system.getNumForces() && angleForce == NULL; i++) - angleForce = dynamic_cast(&system.getForce(i)); - if (angleForce != NULL) - for (int i = 0; i < angleForce->getNumAngles(); i++) { - int particle1, particle2, particle3; - double angle, k; - angleForce->getAngleParameters(i, particle1, particle2, particle3, angle, k); - atomAngles[particle2].push_back(i); - } - vector > > matrix(numCCMA); - for (int j = 0; j < numCCMA; j++) { - for (int k = 0; k < numCCMA; k++) { - if (j == k) { - matrix[j].push_back(pair(j, 1.0)); - continue; - } - double scale; - int cj = ccmaConstraints[j]; - int ck = ccmaConstraints[k]; - int atomj0 = atom1[cj]; - int atomj1 = atom2[cj]; - int atomk0 = atom1[ck]; - int atomk1 = atom2[ck]; - int atoma, atomb, atomc; - double imj0 = 1.0/system.getParticleMass(atomj0); - double imj1 = 1.0/system.getParticleMass(atomj1); - if (atomj0 == atomk0) { - atoma = atomj1; - atomb = atomj0; - atomc = atomk1; - scale = imj0/(imj0+imj1); - } - else if (atomj1 == atomk1) { - atoma = atomj0; - atomb = atomj1; - atomc = atomk0; - scale = imj1/(imj0+imj1); - } - else if (atomj0 == atomk1) { - atoma = atomj1; - atomb = atomj0; - atomc = atomk0; - scale = imj0/(imj0+imj1); - } - else if (atomj1 == atomk0) { - atoma = atomj0; - atomb = atomj1; - atomc = atomk1; - scale = imj1/(imj0+imj1); - } - else - continue; // These constraints are not connected. - - // Look for a third constraint forming a triangle with these two. + vector refMasses(numAtoms); + for (int i = 0; i < numAtoms; ++i) + refMasses[i] = (RealOpenMM) system.getParticleMass(i); - bool foundConstraint = false; - for (int m = 0; m < numCCMA; m++) { - int other = ccmaConstraints[m]; - if ((atom1[other] == atoma && atom2[other] == atomc) || (atom1[other] == atomc && atom2[other] == atoma)) { - double d1 = distance[cj]; - double d2 = distance[ck]; - double d3 = distance[other]; - matrix[j].push_back(pair(k, scale*(d1*d1+d2*d2-d3*d3)/(2.0*d1*d2))); - foundConstraint = true; - break; - } - } - if (!foundConstraint && angleForce != NULL) { - // We didn't find one, so look for an angle force field term. - - const vector& angleCandidates = atomAngles[atomb]; - for (vector::const_iterator iter = angleCandidates.begin(); iter != angleCandidates.end(); iter++) { - int particle1, particle2, particle3; - double angle, ka; - angleForce->getAngleParameters(*iter, particle1, particle2, particle3, angle, ka); - if ((particle1 == atoma && particle3 == atomc) || (particle3 == atoma && particle1 == atomc)) { - matrix[j].push_back(pair(k, scale*cos(angle))); - break; - } - } + // Look up angles for CCMA. + + vector angles; + for (int i = 0; i < system.getNumForces(); i++) { + const HarmonicAngleForce* force = dynamic_cast(&system.getForce(i)); + if (force != NULL) { + for (int j = 0; j < force->getNumAngles(); j++) { + int atom1, atom2, atom3; + double angle, k; + force->getAngleParameters(j, atom1, atom2, atom3, angle, k); + angles.push_back(ReferenceCCMAAlgorithm::AngleInfo(atom1, atom2, atom3, (RealOpenMM) angle)); } } } - - // Invert it using QR. - - vector matrixRowStart; - vector matrixColIndex; - vector matrixValue; - for (int i = 0; i < numCCMA; i++) { - matrixRowStart.push_back(matrixValue.size()); - for (int j = 0; j < (int) matrix[i].size(); j++) { - pair element = matrix[i][j]; - matrixColIndex.push_back(element.first); - matrixValue.push_back(element.second); - } - } - matrixRowStart.push_back(matrixValue.size()); - int *qRowStart, *qColIndex, *rRowStart, *rColIndex; - double *qValue, *rValue; - int result = QUERN_compute_qr(numCCMA, numCCMA, &matrixRowStart[0], &matrixColIndex[0], &matrixValue[0], NULL, - &qRowStart, &qColIndex, &qValue, &rRowStart, &rColIndex, &rValue); - vector rhs(numCCMA); - matrix.clear(); - matrix.resize(numCCMA); - for (int i = 0; i < numCCMA; i++) { - // Extract column i of the inverse matrix. - - for (int j = 0; j < numCCMA; j++) - rhs[j] = (i == j ? 1.0 : 0.0); - result = QUERN_multiply_with_q_transpose(numCCMA, qRowStart, qColIndex, qValue, &rhs[0]); - result = QUERN_solve_with_r(numCCMA, rRowStart, rColIndex, rValue, &rhs[0], &rhs[0]); - for (int j = 0; j < numCCMA; j++) { - double value = rhs[j]*distance[ccmaConstraints[i]]/distance[ccmaConstraints[j]]; - if (abs(value) > 0.1) - matrix[j].push_back(pair(i, value)); - } - } - QUERN_free_result(qRowStart, qColIndex, qValue); - QUERN_free_result(rRowStart, rColIndex, rValue); + + // Create a ReferenceCCMAAlgorithm. It will build and invert the constraint matrix for us. + + ReferenceCCMAAlgorithm ccma(numAtoms, numCCMA, refIndices, refDistance, refMasses, angles, 0.1); + vector > > matrix = ccma.getMatrix(); int maxRowElements = 0; for (unsigned i = 0; i < matrix.size(); i++) maxRowElements = max(maxRowElements, (int) matrix[i].size()); maxRowElements++; + // Build the list of constraints for each atom. + + vector > atomConstraints(context.getNumAtoms()); + for (int i = 0; i < numCCMA; i++) { + atomConstraints[atom1[ccmaConstraints[i]]].push_back(i); + atomConstraints[atom2[ccmaConstraints[i]]].push_back(i); + } + int maxAtomConstraints = 0; + for (unsigned i = 0; i < atomConstraints.size(); i++) + maxAtomConstraints = max(maxAtomConstraints, (int) atomConstraints[i].size()); + // Sort the constraints. vector constraintOrder(numCCMA); diff --git a/platforms/opencl/tests/TestOpenCLVirtualSites.cpp b/platforms/opencl/tests/TestOpenCLVirtualSites.cpp index 6e3550a7e..1bb847379 100644 --- a/platforms/opencl/tests/TestOpenCLVirtualSites.cpp +++ b/platforms/opencl/tests/TestOpenCLVirtualSites.cpp @@ -413,7 +413,7 @@ void testConservationLaws() { if (i == 0) initialAngularMomentum = angularMomentum; else - ASSERT_EQUAL_VEC(initialAngularMomentum, angularMomentum, 0.03); + ASSERT_EQUAL_VEC(initialAngularMomentum, angularMomentum, 0.05); integrator.step(1); } } diff --git a/platforms/reference/include/ReferenceCCMAAlgorithm.h b/platforms/reference/include/ReferenceCCMAAlgorithm.h index ff8021414..17ed2c844 100644 --- a/platforms/reference/include/ReferenceCCMAAlgorithm.h +++ b/platforms/reference/include/ReferenceCCMAAlgorithm.h @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. +/* Portions copyright (c) 2006-2015 Stanford University and Simbios. * Contributors: Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -37,6 +37,7 @@ class OPENMM_EXPORT ReferenceCCMAAlgorithm : public ReferenceConstraintAlgorithm protected: int _maximumNumberOfIterations; + RealOpenMM _elementCutoff; int _numberOfConstraints; std::vector > _atomIndices; @@ -66,8 +67,9 @@ public: * @param distance distances for constraints * @param masses atom masses * @param angles angle force field terms + * @param elementCutoff the cutoff for which elements of the inverse matrix to keep */ - ReferenceCCMAAlgorithm(int numberOfAtoms, int numberOfConstraints, const std::vector >& atomIndices, const std::vector& distance, std::vector& masses, std::vector& angles); + ReferenceCCMAAlgorithm(int numberOfAtoms, int numberOfConstraints, const std::vector >& atomIndices, const std::vector& distance, std::vector& masses, std::vector& angles, RealOpenMM elementCutoff); ~ReferenceCCMAAlgorithm(); @@ -107,6 +109,13 @@ public: */ void applyToVelocities(std::vector& atomCoordinates, std::vector& velocities, std::vector& inverseMasses, RealOpenMM tolerance); + + /** + * Get the inverse constraint matrix. Each element represents one column, and contains a list + * of all non-zero elements in the form (index, value). + */ + const std::vector > >& getMatrix() const; + }; class ReferenceCCMAAlgorithm::AngleInfo diff --git a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp index 714b988f9..732e9057d 100644 --- a/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceCCMAAlgorithm.cpp @@ -1,5 +1,5 @@ -/* Portions copyright (c) 2006-2013 Stanford University and Simbios. +/* Portions copyright (c) 2006-2015 Stanford University and Simbios. * Contributors: Peter Eastman, Pande Group * * Permission is hereby granted, free of charge, to any person obtaining @@ -31,6 +31,7 @@ #include "quern.h" #include "openmm/OpenMMException.h" #include "openmm/Vec3.h" +#include "openmm/internal/ThreadPool.h" #include using std::map; @@ -39,13 +40,51 @@ using std::vector; using std::set; using namespace OpenMM; +// This class extracts columns from the inverse matrix one at a time. It is done in parallel, +// since this can be very slow. + +class ExtractMatrixTask : public ThreadPool::Task { +public: + ExtractMatrixTask(int numConstraints, vector > >& matrix, const vector& distance, RealOpenMM elementCutoff, + const int* qRowStart, const int* qColIndex, const int* rRowStart, const int* rColIndex, const double* qValue, const double* rValue) : + numConstraints(numConstraints), matrix(matrix), distance(distance), elementCutoff(elementCutoff), qRowStart(qRowStart), qColIndex(qColIndex), + rRowStart(rRowStart), rColIndex(rColIndex), qValue(qValue), rValue(rValue) { + } + + void execute(ThreadPool& pool, int threadIndex) { + vector rhs(numConstraints); + for (int i = threadIndex; i < numConstraints; i += pool.getNumThreads()) { + // Extract column i of the inverse matrix. + + for (int j = 0; j < numConstraints; j++) + rhs[j] = (i == j ? 1.0 : 0.0); + QUERN_multiply_with_q_transpose(numConstraints, qRowStart, qColIndex, qValue, &rhs[0]); + QUERN_solve_with_r(numConstraints, rRowStart, rColIndex, rValue, &rhs[0], &rhs[0]); + for (int j = 0; j < numConstraints; j++) { + double value = rhs[j]*distance[j]/distance[i]; + if (FABS((RealOpenMM) value) > elementCutoff) + matrix[i].push_back(pair(j, (RealOpenMM) value)); + } + } + } +private: + int numConstraints; + vector > >& matrix; + const vector& distance; + RealOpenMM elementCutoff; + const int *qRowStart, *qColIndex, *rRowStart, *rColIndex; + const double *qValue, *rValue; +}; + ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms, - int numberOfConstraints, - const vector >& atomIndices, - const vector& distance, - vector& masses, - vector& angles) { + int numberOfConstraints, + const vector >& atomIndices, + const vector& distance, + vector& masses, + vector& angles, + RealOpenMM elementCutoff) { _numberOfConstraints = numberOfConstraints; + _elementCutoff = elementCutoff; _atomIndices = atomIndices; _distance = distance; @@ -157,19 +196,10 @@ ReferenceCCMAAlgorithm::ReferenceCCMAAlgorithm(int numberOfAtoms, &qRowStart, &qColIndex, &qValue, &rRowStart, &rColIndex, &rValue); vector rhs(numberOfConstraints); _matrix.resize(numberOfConstraints); - for (int i = 0; i < numberOfConstraints; i++) { - // Extract column i of the inverse matrix. - - for (int j = 0; j < numberOfConstraints; j++) - rhs[j] = (i == j ? 1.0 : 0.0); - QUERN_multiply_with_q_transpose(numberOfConstraints, qRowStart, qColIndex, qValue, &rhs[0]); - QUERN_solve_with_r(numberOfConstraints, rRowStart, rColIndex, rValue, &rhs[0], &rhs[0]); - for (int j = 0; j < numberOfConstraints; j++) { - double value = rhs[j]*_distance[i]/_distance[j]; - if (FABS((RealOpenMM)value) > 0.02) - _matrix[j].push_back(pair(i, (RealOpenMM) value)); - } - } + ThreadPool threads; + ExtractMatrixTask task(numberOfConstraints, _matrix, _distance, _elementCutoff, qRowStart, qColIndex, rRowStart, rColIndex, qValue, rValue); + threads.execute(task); + threads.waitForThreads(); QUERN_free_result(qRowStart, qColIndex, qValue); QUERN_free_result(rRowStart, rColIndex, rValue); } @@ -290,3 +320,7 @@ void ReferenceCCMAAlgorithm::applyConstraints(vector& atomCoordinates, } } } + +const vector > >& ReferenceCCMAAlgorithm::getMatrix() const { + return _matrix; +} diff --git a/platforms/reference/src/SimTKReference/ReferenceConstraints.cpp b/platforms/reference/src/SimTKReference/ReferenceConstraints.cpp index 410b3ba94..d3b52bda8 100644 --- a/platforms/reference/src/SimTKReference/ReferenceConstraints.cpp +++ b/platforms/reference/src/SimTKReference/ReferenceConstraints.cpp @@ -180,7 +180,7 @@ ReferenceConstraints::ReferenceConstraints(const System& system) : ccma(NULL), s // Create the CCMA object. - ccma = new ReferenceCCMAAlgorithm(numParticles, numCCMA, ccmaIndices, ccmaDistance, masses, angles); + ccma = new ReferenceCCMAAlgorithm(numParticles, numCCMA, ccmaIndices, ccmaDistance, masses, angles, 0.02); } } -- GitLab From 8fc7132051f47bd2dac098fba0a46505f51d24b3 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 30 Mar 2015 15:25:36 -0700 Subject: [PATCH 322/338] Fixed errors using OpenCL with CPU device --- platforms/opencl/src/OpenCLKernels.cpp | 2 +- .../src/kernels/findInteractingBlocks_cpu.cl | 39 +++++++++---------- platforms/opencl/src/kernels/nonbonded_cpu.cl | 15 ++++--- .../opencl/tests/TestOpenCLNonbondedForce.cpp | 6 +-- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 9a4a913d0..90782ad0c 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1882,7 +1882,7 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ pmeUpdateBsplinesKernel.setArg(7, recipBoxVectorsFloat[2]); } cl.executeKernel(pmeUpdateBsplinesKernel, cl.getNumAtoms()); - if (deviceIsCpu) { + if (deviceIsCpu && !cl.getSupports64BitGlobalAtomics()) { setPeriodicBoxSizeArg(cl, pmeSpreadChargeKernel, 5); if (cl.getUseDoublePrecision()) { pmeSpreadChargeKernel.setArg(6, recipBoxVectors[0]); diff --git a/platforms/opencl/src/kernels/findInteractingBlocks_cpu.cl b/platforms/opencl/src/kernels/findInteractingBlocks_cpu.cl index 091fe3edf..05bc74d02 100644 --- a/platforms/opencl/src/kernels/findInteractingBlocks_cpu.cl +++ b/platforms/opencl/src/kernels/findInteractingBlocks_cpu.cl @@ -5,16 +5,15 @@ /** * Find a bounding box for the atoms in each block. */ -__kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, __global const real4* restrict posq, - __global real4* restrict blockCenter, __global real4* restrict blockBoundingBox, __global int* restrict rebuildNeighborList, +__kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + __global const real4* restrict posq, __global real4* restrict blockCenter, __global real4* restrict blockBoundingBox, __global int* restrict rebuildNeighborList, __global real2* restrict sortedBlocks) { int index = get_global_id(0); int base = index*TILE_SIZE; while (base < numAtoms) { real4 pos = posq[base]; #ifdef USE_PERIODIC - pos.xyz -= floor(pos.xyz*invPeriodicBoxSize.xyz)*periodicBoxSize.xyz; - real4 firstPoint = pos; + APPLY_PERIODIC_TO_POS(pos) #endif real4 minPos = pos; real4 maxPos = pos; @@ -22,7 +21,8 @@ __kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeri for (int i = base+1; i < last; i++) { pos = posq[i]; #ifdef USE_PERIODIC - pos.xyz -= floor((pos.xyz-firstPoint.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + real4 center = 0.5f*(maxPos+minPos); + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, center) #endif minPos = min(minPos, pos); maxPos = max(maxPos, pos); @@ -44,7 +44,7 @@ __kernel void findBlockBounds(int numAtoms, real4 periodicBoxSize, real4 invPeri __kernel void sortBoxData(__global const real2* restrict sortedBlock, __global const real4* restrict blockCenter, __global const real4* restrict blockBoundingBox, __global real4* restrict sortedBlockCenter, __global real4* restrict sortedBlockBoundingBox, __global const real4* restrict posq, __global const real4* restrict oldPositions, - __global unsigned int* restrict interactionCount, __global int* restrict rebuildNeighborList) { + __global unsigned int* restrict interactionCount, __global int* restrict rebuildNeighborList, int forceRebuild) { for (int i = get_global_id(0); i < NUM_BLOCKS; i += get_global_size(0)) { int index = (int) sortedBlock[i].y; sortedBlockCenter[i] = blockCenter[index]; @@ -53,7 +53,7 @@ __kernel void sortBoxData(__global const real2* restrict sortedBlock, __global c // Also check whether any atom has moved enough so that we really need to rebuild the neighbor list. - bool rebuild = false; + bool rebuild = forceRebuild; for (int i = get_global_id(0); i < NUM_ATOMS; i += get_global_size(0)) { real4 delta = oldPositions[i]-posq[i]; if (delta.x*delta.x + delta.y*delta.y + delta.z*delta.z > 0.25f*PADDING*PADDING) @@ -70,8 +70,8 @@ __kernel void sortBoxData(__global const real2* restrict sortedBlock, __global c * to global memory. */ void storeInteractionData(unsigned short x, unsigned short* buffer, int* atoms, int* numAtoms, int numValid, __global unsigned int* interactionCount, - __global int* interactingTiles, __global unsigned int* interactingAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, - __global real4* posq, real4 blockCenterX, real4 blockSizeX, unsigned int maxTiles, bool finish) { + __global int* interactingTiles, __global unsigned int* interactingAtoms, real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, + real4 periodicBoxVecY, real4 periodicBoxVecZ, __global const real4* posq, real4 blockCenterX, real4 blockSizeX, unsigned int maxTiles, bool finish) { real4 posBuffer[TILE_SIZE]; const bool singlePeriodicCopy = (0.5f*periodicBoxSize.x-blockSizeX.x >= PADDED_CUTOFF && 0.5f*periodicBoxSize.y-blockSizeX.y >= PADDED_CUTOFF && @@ -83,7 +83,7 @@ void storeInteractionData(unsigned short x, unsigned short* buffer, int* atoms, // The box is small enough that we can just translate all the atoms into a single periodic // box, then skip having to apply periodic boundary conditions later. - pos.xyz -= floor((pos.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, blockCenterX) } #endif posBuffer[i] = pos; @@ -99,14 +99,14 @@ void storeInteractionData(unsigned short x, unsigned short* buffer, int* atoms, real4 pos = posq[atom]; #ifdef USE_PERIODIC if (singlePeriodicCopy) - pos.xyz -= floor((pos.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(pos, blockCenterX) #endif bool interacts = false; #ifdef USE_PERIODIC if (!singlePeriodicCopy) { for (int j = 0; j < TILE_SIZE && !interacts; j++) { real4 delta = pos-posBuffer[j]; - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) interacts = (delta.x*delta.x+delta.y*delta.y+delta.z*delta.z < PADDED_CUTOFF_SQUARED); } } @@ -159,9 +159,10 @@ void storeInteractionData(unsigned short x, unsigned short* buffer, int* atoms, * Compare the bounding boxes for each pair of blocks. If they are sufficiently far apart, * mark them as non-interacting. */ -__kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodicBoxSize, __global unsigned int* restrict interactionCount, - __global int* restrict interactingTiles, __global unsigned int* restrict interactingAtoms, __global const real4* restrict posq, unsigned int maxTiles, unsigned int startBlockIndex, - unsigned int numBlocks, __global real2* restrict sortedBlocks, __global const real4* restrict sortedBlockCenter, __global const real4* restrict sortedBlockBoundingBox, +__kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodicBoxSize, real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, + __global unsigned int* restrict interactionCount, __global int* restrict interactingTiles, __global unsigned int* restrict interactingAtoms, + __global const real4* restrict posq, unsigned int maxTiles, unsigned int startBlockIndex, unsigned int numBlocks, __global real2* restrict sortedBlocks, + __global const real4* restrict sortedBlockCenter, __global const real4* restrict sortedBlockBoundingBox, __global const unsigned int* restrict exclusionIndices, __global const unsigned int* restrict exclusionRowIndices, __global real4* restrict oldPositions, __global const int* restrict rebuildNeighborList) { if (rebuildNeighborList[0] == 0) @@ -204,9 +205,7 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi real4 blockSizeY = sortedBlockBoundingBox[j]; real4 delta = blockCenterX-blockCenterY; #ifdef USE_PERIODIC - delta.x -= floor(delta.x*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - delta.y -= floor(delta.y*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - delta.z -= floor(delta.z*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_DELTA(delta) #endif delta.x = max((real) 0, fabs(delta.x)-blockSizeX.x-blockSizeY.x); delta.y = max((real) 0, fabs(delta.y)-blockSizeX.y-blockSizeY.y); @@ -216,12 +215,12 @@ __kernel void findBlocksWithInteractions(real4 periodicBoxSize, real4 invPeriodi buffer[valuesInBuffer++] = y; if (valuesInBuffer == BUFFER_SIZE) { - storeInteractionData(x, buffer, atoms, &numAtoms, valuesInBuffer, interactionCount, interactingTiles, interactingAtoms, periodicBoxSize, invPeriodicBoxSize, posq, blockCenterX, blockSizeX, maxTiles, false); + storeInteractionData(x, buffer, atoms, &numAtoms, valuesInBuffer, interactionCount, interactingTiles, interactingAtoms, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ, posq, blockCenterX, blockSizeX, maxTiles, false); valuesInBuffer = 0; } } } - storeInteractionData(x, buffer, atoms, &numAtoms, valuesInBuffer, interactionCount, interactingTiles, interactingAtoms, periodicBoxSize, invPeriodicBoxSize, posq, blockCenterX, blockSizeX, maxTiles, true); + storeInteractionData(x, buffer, atoms, &numAtoms, valuesInBuffer, interactionCount, interactingTiles, interactingAtoms, periodicBoxSize, invPeriodicBoxSize, periodicBoxVecX, periodicBoxVecY, periodicBoxVecZ, posq, blockCenterX, blockSizeX, maxTiles, true); } // Record the positions the neighbor list is based on. diff --git a/platforms/opencl/src/kernels/nonbonded_cpu.cl b/platforms/opencl/src/kernels/nonbonded_cpu.cl index 04cc303f5..f99fa1801 100644 --- a/platforms/opencl/src/kernels/nonbonded_cpu.cl +++ b/platforms/opencl/src/kernels/nonbonded_cpu.cl @@ -23,7 +23,8 @@ __kernel void computeNonbonded( __global const ushort2* restrict exclusionTiles, unsigned int startTileIndex, unsigned int numTileIndices #ifdef USE_CUTOFF , __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms #endif PARAMETER_ARGUMENTS) { real energy = 0; @@ -65,7 +66,7 @@ __kernel void computeNonbonded( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF @@ -133,7 +134,7 @@ __kernel void computeNonbonded( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF @@ -291,15 +292,13 @@ __kernel void computeNonbonded( real4 blockCenterX = blockCenter[x]; for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { - localData[tgx].x -= floor((localData[tgx].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[tgx].y -= floor((localData[tgx].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[tgx].z -= floor((localData[tgx].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[tgx], blockCenterX) } for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { unsigned int atom1 = x*TILE_SIZE+tgx; real4 force = 0; real4 posq1 = posq[atom1]; - posq1.xyz -= floor((posq1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) LOAD_ATOM1_PARAMETERS for (unsigned int j = 0; j < TILE_SIZE; j++) { real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); @@ -364,7 +363,7 @@ __kernel void computeNonbonded( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF diff --git a/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp b/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp index 35db6b9ff..16ea4cd0a 100644 --- a/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp +++ b/platforms/opencl/tests/TestOpenCLNonbondedForce.cpp @@ -410,9 +410,9 @@ void testTriclinic() { } else { const Vec3 force = delta*ONE_4PI_EPS0*(-1.0/(distance*distance*distance)+2.0*krf); - ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(1.0/distance+krf*distance*distance-crf), state.getPotentialEnergy(), TOL); - ASSERT_EQUAL_VEC(force, state.getForces()[0], TOL); - ASSERT_EQUAL_VEC(-force, state.getForces()[1], TOL); + ASSERT_EQUAL_TOL(ONE_4PI_EPS0*(1.0/distance+krf*distance*distance-crf), state.getPotentialEnergy(), 1e-4); + ASSERT_EQUAL_VEC(force, state.getForces()[0], 1e-4); + ASSERT_EQUAL_VEC(-force, state.getForces()[1], 1e-4); } } } -- GitLab From 85669a543cf78a5d1ed9d38e10a4f654221fb374 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 1 Apr 2015 11:24:42 -0700 Subject: [PATCH 323/338] More fixes to OpenCL with CPU device --- .../opencl/src/kernels/customManyParticle.cl | 4 ++- platforms/opencl/src/kernels/gbsaObc_cpu.cl | 33 +++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/platforms/opencl/src/kernels/customManyParticle.cl b/platforms/opencl/src/kernels/customManyParticle.cl index 2fe70612b..f6842c3dc 100644 --- a/platforms/opencl/src/kernels/customManyParticle.cl +++ b/platforms/opencl/src/kernels/customManyParticle.cl @@ -227,7 +227,9 @@ __kernel void findNeighbors(real4 periodicBoxSize, real4 invPeriodicBoxSize, rea int start = block2*TILE_SIZE; int included[TILE_SIZE]; int numIncluded = 0; + SYNC_WARPS; positionCache[get_local_id(0)] = posq[start+indexInWarp]; + SYNC_WARPS; if (atom1 < NUM_ATOMS) { for (int j = 0; j < 32; j++) { int atom2 = start+j; @@ -287,7 +289,7 @@ __kernel void computeNeighborStartIndices(__global int* restrict numNeighborsFor unsigned int globalIndex = startAtom+get_local_id(0); posBuffer[get_local_id(0)] = (globalIndex < NUM_ATOMS ? numNeighborsForAtom[globalIndex] : 0); - barrier(CLK_LOCAL_MEM_FENCE); + barrier(CLK_LOCAL_MEM_FENCE); // Perform a parallel prefix sum. diff --git a/platforms/opencl/src/kernels/gbsaObc_cpu.cl b/platforms/opencl/src/kernels/gbsaObc_cpu.cl index d32cfcf16..4d8fe05c0 100644 --- a/platforms/opencl/src/kernels/gbsaObc_cpu.cl +++ b/platforms/opencl/src/kernels/gbsaObc_cpu.cl @@ -20,8 +20,9 @@ __kernel void computeBornSum( #endif __global const real4* restrict posq, __global const float2* restrict global_params, #ifdef USE_CUTOFF - __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, + __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, #else unsigned int numTiles, #endif @@ -62,7 +63,7 @@ __kernel void computeBornSum( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = dot(delta.xyz, delta.xyz); #ifdef USE_CUTOFF @@ -111,7 +112,7 @@ __kernel void computeBornSum( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -253,14 +254,13 @@ __kernel void computeBornSum( real4 blockCenterX = blockCenter[x]; for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { - localData[tgx].x -= floor((localData[tgx].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[tgx].y -= floor((localData[tgx].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[tgx].z -= floor((localData[tgx].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[tgx], blockCenterX) } for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { unsigned int atom1 = x*TILE_SIZE+tgx; real bornSum = 0; real4 posq1 = posq[atom1]; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) float2 params1 = global_params[atom1]; for (unsigned int j = 0; j < TILE_SIZE; j++) { real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); @@ -321,7 +321,7 @@ __kernel void computeBornSum( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; int atom2 = atomIndices[j]; @@ -411,8 +411,9 @@ __kernel void computeGBSAForce1( #endif __global real* restrict energyBuffer, __global const real4* restrict posq, __global const real* restrict global_bornRadii, #ifdef USE_CUTOFF - __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, - unsigned int maxTiles, __global const real4* restrict blockCenter, __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, + __global const int* restrict tiles, __global const unsigned int* restrict interactionCount, real4 periodicBoxSize, real4 invPeriodicBoxSize, + real4 periodicBoxVecX, real4 periodicBoxVecY, real4 periodicBoxVecZ, unsigned int maxTiles, __global const real4* restrict blockCenter, + __global const real4* restrict blockSize, __global const int* restrict interactingAtoms, #else unsigned int numTiles, #endif @@ -452,7 +453,7 @@ __kernel void computeGBSAForce1( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -516,7 +517,7 @@ __kernel void computeGBSAForce1( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; #ifdef USE_CUTOFF @@ -669,15 +670,13 @@ __kernel void computeGBSAForce1( real4 blockCenterX = blockCenter[x]; for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { - localData[tgx].x -= floor((localData[tgx].x-blockCenterX.x)*invPeriodicBoxSize.x+0.5f)*periodicBoxSize.x; - localData[tgx].y -= floor((localData[tgx].y-blockCenterX.y)*invPeriodicBoxSize.y+0.5f)*periodicBoxSize.y; - localData[tgx].z -= floor((localData[tgx].z-blockCenterX.z)*invPeriodicBoxSize.z+0.5f)*periodicBoxSize.z; + APPLY_PERIODIC_TO_POS_WITH_CENTER(localData[tgx], blockCenterX) } for (unsigned int tgx = 0; tgx < TILE_SIZE; tgx++) { unsigned int atom1 = x*TILE_SIZE+tgx; real4 force = 0; real4 posq1 = posq[atom1]; - posq1.xyz -= floor((posq1.xyz-blockCenterX.xyz)*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_POS_WITH_CENTER(posq1, blockCenterX) float bornRadius1 = global_bornRadii[atom1]; for (unsigned int j = 0; j < TILE_SIZE; j++) { real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); @@ -740,7 +739,7 @@ __kernel void computeGBSAForce1( real4 posq2 = (real4) (localData[j].x, localData[j].y, localData[j].z, localData[j].q); real4 delta = (real4) (posq2.xyz - posq1.xyz, 0); #ifdef USE_PERIODIC - delta.xyz -= floor(delta.xyz*invPeriodicBoxSize.xyz+0.5f)*periodicBoxSize.xyz; + APPLY_PERIODIC_TO_DELTA(delta) #endif real r2 = delta.x*delta.x + delta.y*delta.y + delta.z*delta.z; int atom2 = atomIndices[j]; -- GitLab From 4cf4328e1e3ae8f49adbb9aadad4ac86e3478825 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 2 Apr 2015 11:05:49 -0700 Subject: [PATCH 324/338] Fixed a performance regression on AMD GPUs --- platforms/opencl/src/OpenCLSort.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platforms/opencl/src/OpenCLSort.cpp b/platforms/opencl/src/OpenCLSort.cpp index a3fb2ca52..32223d136 100644 --- a/platforms/opencl/src/OpenCLSort.cpp +++ b/platforms/opencl/src/OpenCLSort.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2010-2013 Stanford University and the Authors. * + * Portions copyright (c) 2010-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -59,7 +59,11 @@ OpenCLSort::OpenCLSort(OpenCLContext& context, SortTrait* trait, unsigned int le unsigned int maxRangeSize = std::min(maxGroupSize, (unsigned int) computeRangeKernel.getWorkGroupInfo(context.getDevice())); unsigned int maxPositionsSize = std::min(maxGroupSize, (unsigned int) computeBucketPositionsKernel.getWorkGroupInfo(context.getDevice())); unsigned int maxShortListSize = shortListKernel.getWorkGroupInfo(context.getDevice()); - isShortList = (length <= maxLocalBuffer && length < maxShortListSize); + // On Qualcomm's OpenCL, it's essential to check against maxShortListSize. Otherwise you get a crash. + // But AMD's OpenCL returns an inappropriately small value for it that is much shorter than the actual + // maximum, so including the check hurts performance. For the moment I'm going to just comment it out. + // If we officially support Qualcomm in the future, we'll need to do something better. + isShortList = (length <= maxLocalBuffer/* && length < maxShortListSize*/); for (rangeKernelSize = 1; rangeKernelSize*2 <= maxRangeSize; rangeKernelSize *= 2) ; positionsKernelSize = std::min(rangeKernelSize, maxPositionsSize); -- GitLab From 913c6dc38d2dfad42c79a1165568c54801750f37 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Fri, 3 Apr 2015 14:30:48 -0700 Subject: [PATCH 325/338] OpenCL FFT supports real-to-complex transforms --- platforms/opencl/include/OpenCLFFT3D.h | 16 +++--- platforms/opencl/src/OpenCLFFT3D.cpp | 68 ++++++++++++++---------- platforms/opencl/src/OpenCLKernels.cpp | 2 +- platforms/opencl/src/kernels/fft.cl | 12 ++++- platforms/opencl/src/kernels/pme.cl | 26 ++++----- platforms/opencl/tests/TestOpenCLFFT.cpp | 27 +++++++--- 6 files changed, 92 insertions(+), 59 deletions(-) diff --git a/platforms/opencl/include/OpenCLFFT3D.h b/platforms/opencl/include/OpenCLFFT3D.h index fbec32bb3..57b5068df 100644 --- a/platforms/opencl/include/OpenCLFFT3D.h +++ b/platforms/opencl/include/OpenCLFFT3D.h @@ -9,7 +9,7 @@ * 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. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -40,7 +40,7 @@ namespace OpenMM { * 15, 207–228 (2000). *

* This class places certain restrictions on the allowed dimensions of the grid. First, - * the size of each dimension may have no prime factors other than 2, 3, and 5. You + * the size of each dimension may have no prime factors other than 2, 3, 5, and 7. You * can call findLegalDimension() to determine the smallest size that satisfies this * requirement and is greater than or equal to a specified minimum size. Second, the size * of each dimension must be small enough to compute each 1D transform entirely in local @@ -61,12 +61,14 @@ public: * @param xsize the first dimension of the data sets on which FFTs will be performed * @param ysize the second dimension of the data sets on which FFTs will be performed * @param zsize the third dimension of the data sets on which FFTs will be performed + * @param realToComplex if true, a real-to-complex transform will be done. Otherwise, it is complex-to-complex. */ - OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize); + OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize, bool realToComplex=false); /** * Perform a Fourier transform. The transform cannot be done in-place: the input and output * arrays must be different. Also, the input array is used as workspace, so its contents - * are destroyed. + * are destroyed. This also means that both arrays must be large enough to hold complex values, + * even when performing a real-to-complex transform. * * @param in the data to transform, ordered such that in[x*ysize*zsize + y*zsize + z] contains element (x, y, z) * @param out on exit, this contains the transformed data @@ -75,17 +77,19 @@ public: void execFFT(OpenCLArray& in, OpenCLArray& out, bool forward = true); /** * Get the smallest legal size for a dimension of the grid (that is, a size with no prime - * factors other than 2, 3, and 5). + * factors other than 2, 3, 5, and 7). * * @param minimum the minimum size the return value must be greater than or equal to */ static int findLegalDimension(int minimum); private: - cl::Kernel createKernel(int xsize, int ysize, int zsize, int& threads); + cl::Kernel createKernel(int xsize, int ysize, int zsize, int& threads, int axis, bool forward); int xsize, ysize, zsize; int xthreads, ythreads, zthreads; + bool realToComplex; OpenCLContext& context; cl::Kernel xkernel, ykernel, zkernel; + cl::Kernel invxkernel, invykernel, invzkernel; }; } // namespace OpenMM diff --git a/platforms/opencl/src/OpenCLFFT3D.cpp b/platforms/opencl/src/OpenCLFFT3D.cpp index 7847a06e2..319f092e1 100644 --- a/platforms/opencl/src/OpenCLFFT3D.cpp +++ b/platforms/opencl/src/OpenCLFFT3D.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2012 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -35,25 +35,29 @@ using namespace OpenMM; using namespace std; -OpenCLFFT3D::OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize) : context(context), xsize(xsize), ysize(ysize), zsize(zsize) { - zkernel = createKernel(xsize, ysize, zsize, zthreads); - xkernel = createKernel(ysize, zsize, xsize, xthreads); - ykernel = createKernel(zsize, xsize, ysize, ythreads); +OpenCLFFT3D::OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize, bool realToComplex) : + context(context), xsize(xsize), ysize(ysize), zsize(zsize), realToComplex(realToComplex) { + zkernel = createKernel(xsize, ysize, zsize, zthreads, 0, true); + xkernel = createKernel(ysize, zsize, xsize, xthreads, 1, true); + ykernel = createKernel(zsize, xsize, ysize, ythreads, 2, true); + invzkernel = createKernel(xsize, ysize, zsize, zthreads, 0, false); + invxkernel = createKernel(ysize, zsize, xsize, xthreads, 1, false); + invykernel = createKernel(zsize, xsize, ysize, ythreads, 2, false); } void OpenCLFFT3D::execFFT(OpenCLArray& in, OpenCLArray& out, bool forward) { - zkernel.setArg(0, in.getDeviceBuffer()); - zkernel.setArg(1, out.getDeviceBuffer()); - zkernel.setArg(2, forward ? 1 : -1); - context.executeKernel(zkernel, xsize*ysize*zsize, zthreads); - xkernel.setArg(0, out.getDeviceBuffer()); - xkernel.setArg(1, in.getDeviceBuffer()); - xkernel.setArg(2, forward ? 1 : -1); - context.executeKernel(xkernel, xsize*ysize*zsize, xthreads); - ykernel.setArg(0, in.getDeviceBuffer()); - ykernel.setArg(1, out.getDeviceBuffer()); - ykernel.setArg(2, forward ? 1 : -1); - context.executeKernel(ykernel, xsize*ysize*zsize, ythreads); + cl::Kernel kernel1 = (forward ? zkernel : invzkernel); + cl::Kernel kernel2 = (forward ? xkernel : invxkernel); + cl::Kernel kernel3 = (forward ? ykernel : invykernel); + kernel1.setArg(0, in.getDeviceBuffer()); + kernel1.setArg(1, out.getDeviceBuffer()); + context.executeKernel(kernel1, xsize*ysize*zsize, zthreads); + kernel2.setArg(0, out.getDeviceBuffer()); + kernel2.setArg(1, in.getDeviceBuffer()); + context.executeKernel(kernel2, xsize*ysize*zsize, xthreads); + kernel3.setArg(0, in.getDeviceBuffer()); + kernel3.setArg(1, out.getDeviceBuffer()); + context.executeKernel(kernel3, xsize*ysize*zsize, ythreads); } int OpenCLFFT3D::findLegalDimension(int minimum) { @@ -73,7 +77,7 @@ int OpenCLFFT3D::findLegalDimension(int minimum) { } } -cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threads) { +cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threads, int axis, bool forward) { int maxThreads = std::min(256, (int) context.getDevice().getInfo()); bool isCPU = context.getDevice().getInfo() == CL_DEVICE_TYPE_CPU; while (true) { @@ -137,10 +141,10 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa source<<"real2 b2 = "< replacements; replacements["XSIZE"] = context.intToString(xsize); @@ -242,6 +248,10 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa replacements["M_PI"] = context.doubleToString(M_PI); replacements["COMPUTE_FFT"] = source.str(); replacements["LOOP_REQUIRED"] = (loopRequired ? "1" : "0"); + replacements["SIGN"] = (forward ? "1" : "-1"); + replacements["INPUT_TYPE"] = (realToComplex && axis == 0 && forward ? "real" : "real2"); + replacements["OUTPUT_TYPE"] = (outputIsReal ? "real" : "real2"); + replacements["INPUT_IS_REAL"] = (realToComplex && axis == 0 && forward ? "1" : "0"); cl::Program program = context.createProgram(context.replaceStrings(OpenCLKernelSources::fft, replacements)); cl::Kernel kernel(program, "execFFT"); threads = (isCPU ? 1 : blocksPerGroup*zsize); @@ -253,9 +263,9 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa continue; } int bufferSize = blocksPerGroup*zsize*(context.getUseDoublePrecision() ? sizeof(mm_double2) : sizeof(mm_float2)); + kernel.setArg(2, bufferSize, NULL); kernel.setArg(3, bufferSize, NULL); kernel.setArg(4, bufferSize, NULL); - kernel.setArg(5, bufferSize, NULL); return kernel; } } diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 90782ad0c..56d9a0685 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1661,7 +1661,7 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb pmeAtomRange = OpenCLArray::create(cl, gridSizeX*gridSizeY*gridSizeZ+1, "pmeAtomRange"); pmeAtomGridIndex = OpenCLArray::create(cl, numParticles, "pmeAtomGridIndex"); sort = new OpenCLSort(cl, new SortTrait(), cl.getNumAtoms()); - fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ); + fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ, true); string vendor = cl.getDevice().getInfo(); usePmeQueue = (vendor.size() >= 6 && vendor.substr(0, 6) == "NVIDIA"); if (usePmeQueue) { diff --git a/platforms/opencl/src/kernels/fft.cl b/platforms/opencl/src/kernels/fft.cl index 71577ee5a..71ebd7c88 100644 --- a/platforms/opencl/src/kernels/fft.cl +++ b/platforms/opencl/src/kernels/fft.cl @@ -6,10 +6,10 @@ real2 multiplyComplex(real2 c1, real2 c2) { * Perform a 1D FFT on each row along one axis. */ -__kernel void execFFT(__global const real2* restrict in, __global real2* restrict out, int sign, __local real2* restrict w, +__kernel void execFFT(__global const INPUT_TYPE* restrict in, __global OUTPUT_TYPE* restrict out, __local real2* restrict w, __local real2* restrict data0, __local real2* restrict data1) { for (int i = get_local_id(0); i < ZSIZE; i += get_local_size(0)) - w[i] = (real2) (cos(-sign*i*2*M_PI/ZSIZE), sin(-sign*i*2*M_PI/ZSIZE)); + w[i] = (real2) (cos(-(SIGN)*i*2*M_PI/ZSIZE), sin(-(SIGN)*i*2*M_PI/ZSIZE)); barrier(CLK_LOCAL_MEM_FENCE); for (int baseIndex = get_group_id(0)*BLOCKS_PER_GROUP; baseIndex < XSIZE*YSIZE; baseIndex += get_num_groups(0)*BLOCKS_PER_GROUP) { @@ -18,10 +18,18 @@ __kernel void execFFT(__global const real2* restrict in, __global real2* restric int y = index-x*YSIZE; #if LOOP_REQUIRED for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0)) + #if INPUT_IS_REAL + data0[z] = (real2) (in[x*(YSIZE*ZSIZE)+y*ZSIZE+z], 0); + #else data0[z] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+z]; + #endif #else if (index < XSIZE*YSIZE) + #if INPUT_IS_REAL + data0[get_local_id(0)] = (real2) (in[x*(YSIZE*ZSIZE)+y*ZSIZE+get_local_id(0)%ZSIZE], 0); + #else data0[get_local_id(0)] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+get_local_id(0)%ZSIZE]; + #endif #endif barrier(CLK_LOCAL_MEM_FENCE); COMPUTE_FFT diff --git a/platforms/opencl/src/kernels/pme.cl b/platforms/opencl/src/kernels/pme.cl index 563a53492..1da66cd52 100644 --- a/platforms/opencl/src/kernels/pme.cl +++ b/platforms/opencl/src/kernels/pme.cl @@ -139,9 +139,10 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con int index = xindex*GRID_SIZE_Y*GRID_SIZE_Z + yindex*GRID_SIZE_Z + zindex; real add = pos.w*data[ix].x*data[iy].y*data[iz].z; #ifdef USE_DOUBLE_PRECISION - atom_add(&pmeGrid[2*index], (long) (add*0x100000000)); -#else atom_add(&pmeGrid[index], (long) (add*0x100000000)); +#else + int gridIndex = (index%2 == 0 ? index/2 : (index+GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z)/2); + atom_add(&pmeGrid[gridIndex], (long) (add*0x100000000)); #endif } @@ -151,22 +152,21 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con } __kernel void finishSpreadCharge(__global long* restrict pmeGrid) { - __global real2* realGrid = (__global real2*) pmeGrid; + __global real* realGrid = (__global real*) pmeGrid; const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; real scale = EPSILON_FACTOR/(real) 0x100000000; for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { #ifdef USE_DOUBLE_PRECISION - long value = pmeGrid[2*index]; -#else long value = pmeGrid[index]; +#else + long value = pmeGrid[index%2 == 0 ? index/2 : (index+gridSize)/2]; #endif - real2 realValue = (real2) ((real) (value*scale), 0); - realGrid[index] = realValue; + realGrid[index] = (real) (value*scale); } } #elif defined(DEVICE_IS_CPU) __kernel void gridSpreadCharge(__global const real4* restrict posq, __global const int2* restrict pmeAtomGridIndex, __global const int* restrict pmeAtomRange, - __global real2* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta, real4 periodicBoxSize, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) { + __global real* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta, real4 periodicBoxSize, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) { const int firstx = get_global_id(0)*GRID_SIZE_X/get_global_size(0); const int lastx = (get_global_id(0)+1)*GRID_SIZE_X/get_global_size(0); if (firstx == lastx) @@ -230,7 +230,7 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con int zindex = gridIndex.z+iz; zindex -= (zindex >= GRID_SIZE_Z ? GRID_SIZE_Z : 0); int index = xindex*GRID_SIZE_Y*GRID_SIZE_Z + yindex*GRID_SIZE_Z + zindex; - pmeGrid[index].x += EPSILON_FACTOR*pos.w*data[ix].x*data[iy].y*data[iz].z; + pmeGrid[index] += EPSILON_FACTOR*pos.w*data[ix].x*data[iy].y*data[iz].z; } } } @@ -238,7 +238,7 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con } #else __kernel void gridSpreadCharge(__global const real4* restrict posq, __global const int2* restrict pmeAtomGridIndex, __global const int* restrict pmeAtomRange, - __global real2* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta) { + __global real* restrict pmeGrid, __global const real4* restrict pmeBsplineTheta) { unsigned int numGridPoints = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; for (int gridIndex = get_global_id(0); gridIndex < numGridPoints; gridIndex += get_global_size(0)) { // Compute the charge on a grid point. @@ -290,7 +290,7 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con } } } - pmeGrid[gridIndex] = (real2) (result*EPSILON_FACTOR, 0); + pmeGrid[gridIndex] = result*EPSILON_FACTOR; } } #endif @@ -325,7 +325,7 @@ __kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global r energyBuffer[get_global_id(0)] += 0.5f*energy; } -__kernel void gridInterpolateForce(__global const real4* restrict posq, __global real4* restrict forceBuffers, __global const real2* restrict pmeGrid, +__kernel void gridInterpolateForce(__global const real4* restrict posq, __global real4* restrict forceBuffers, __global const real* restrict pmeGrid, real4 periodicBoxSize, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ, __global int2* restrict pmeAtomGridIndex) { const real4 scale = 1/(real) (PME_ORDER-1); real4 data[PME_ORDER]; @@ -385,7 +385,7 @@ __kernel void gridInterpolateForce(__global const real4* restrict posq, __global int zindex = gridIndex.z+iz; zindex -= (zindex >= GRID_SIZE_Z ? GRID_SIZE_Z : 0); int index = xindex*GRID_SIZE_Y*GRID_SIZE_Z + yindex*GRID_SIZE_Z + zindex; - real gridvalue = pmeGrid[index].x; + real gridvalue = pmeGrid[index]; force.x += ddata[ix].x*data[iy].y*data[iz].z*gridvalue; force.y += data[ix].x*ddata[iy].y*data[iz].z*gridvalue; force.z += data[ix].x*data[iy].y*ddata[iz].z*gridvalue; diff --git a/platforms/opencl/tests/TestOpenCLFFT.cpp b/platforms/opencl/tests/TestOpenCLFFT.cpp index 34b020486..38b9f6002 100644 --- a/platforms/opencl/tests/TestOpenCLFFT.cpp +++ b/platforms/opencl/tests/TestOpenCLFFT.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2011 Stanford University and the Authors. * + * Portions copyright (c) 2011-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -51,7 +51,7 @@ using namespace std; static OpenCLPlatform platform; template -void testTransform() { +void testTransform(bool realToComplex) { System system; system.addParticle(0.0); OpenCLPlatform::PlatformData platformData(system, "", "", platform.getPropertyDefaultValue("OpenCLPrecision"), "false"); @@ -67,10 +67,16 @@ void testTransform() { original[i] = value; reference[i] = t_complex(value.x, value.y); } + for (int i = 0; i < (int) reference.size(); i++) { + if (realToComplex) + reference[i] = t_complex(i%2 == 0 ? original[i/2].x : original[i/2].y, 0); + else + reference[i] = t_complex(original[i].x, original[i].y); + } OpenCLArray grid1(context, original.size(), sizeof(Real2), "grid1"); OpenCLArray grid2(context, original.size(), sizeof(Real2), "grid2"); grid1.upload(original); - OpenCLFFT3D fft(context, xsize, ysize, zsize); + OpenCLFFT3D fft(context, xsize, ysize, zsize, realToComplex); // Perform a forward FFT, then verify the result is correct. @@ -91,7 +97,8 @@ void testTransform() { fft.execFFT(grid2, grid1, false); grid1.download(result); double scale = 1.0/(xsize*ysize*zsize); - for (int i = 0; i < (int) result.size(); ++i) { + int valuesToCheck = (realToComplex ? original.size()/2 : original.size()); + for (int i = 0; i < valuesToCheck; ++i) { ASSERT_EQUAL_TOL(original[i].x, scale*result[i].x, 1e-4); ASSERT_EQUAL_TOL(original[i].y, scale*result[i].y, 1e-4); } @@ -101,10 +108,14 @@ int main(int argc, char* argv[]) { try { if (argc > 1) platform.setPropertyDefaultValue("OpenCLPrecision", string(argv[1])); - if (platform.getPropertyDefaultValue("OpenCLPrecision") == "double") - testTransform(); - else - testTransform(); + if (platform.getPropertyDefaultValue("OpenCLPrecision") == "double") { + testTransform(false); + testTransform(true); + } + else { + testTransform(false); + testTransform(true); + } } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From 4959bb9cebe5138905338191e8f6fbfdb9ed0baf Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 3 Apr 2015 15:41:57 -0700 Subject: [PATCH 326/338] Simplified charge spreading kernel --- platforms/opencl/src/OpenCLKernels.cpp | 13 ++++++++++--- platforms/opencl/src/kernels/pme.cl | 15 ++------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 56d9a0685..7e01e3d23 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1652,8 +1652,11 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb int elementSize = (cl.getUseDoublePrecision() ? sizeof(double) : sizeof(float)); pmeGrid = new OpenCLArray(cl, gridSizeX*gridSizeY*gridSizeZ, 2*elementSize, "pmeGrid"); - cl.addAutoclearBuffer(*pmeGrid); pmeGrid2 = new OpenCLArray(cl, gridSizeX*gridSizeY*gridSizeZ, 2*elementSize, "pmeGrid2"); + if (cl.getSupports64BitGlobalAtomics()) + cl.addAutoclearBuffer(*pmeGrid2); + else + cl.addAutoclearBuffer(*pmeGrid); pmeBsplineModuliX = new OpenCLArray(cl, gridSizeX, elementSize, "pmeBsplineModuliX"); pmeBsplineModuliY = new OpenCLArray(cl, gridSizeY, elementSize, "pmeBsplineModuliY"); pmeBsplineModuliZ = new OpenCLArray(cl, gridSizeZ, elementSize, "pmeBsplineModuliZ"); @@ -1814,7 +1817,10 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ pmeSpreadChargeKernel.setArg(0, cl.getPosq().getDeviceBuffer()); pmeSpreadChargeKernel.setArg(1, pmeAtomGridIndex->getDeviceBuffer()); pmeSpreadChargeKernel.setArg(2, pmeAtomRange->getDeviceBuffer()); - pmeSpreadChargeKernel.setArg(3, pmeGrid->getDeviceBuffer()); + if (cl.getSupports64BitGlobalAtomics()) + pmeSpreadChargeKernel.setArg(3, pmeGrid2->getDeviceBuffer()); + else + pmeSpreadChargeKernel.setArg(3, pmeGrid->getDeviceBuffer()); pmeSpreadChargeKernel.setArg(4, pmeBsplineTheta->getDeviceBuffer()); pmeConvolutionKernel.setArg(0, pmeGrid2->getDeviceBuffer()); pmeConvolutionKernel.setArg(1, cl.getEnergyBuffer().getDeviceBuffer()); @@ -1827,7 +1833,8 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ pmeInterpolateForceKernel.setArg(7, pmeAtomGridIndex->getDeviceBuffer()); if (cl.getSupports64BitGlobalAtomics()) { pmeFinishSpreadChargeKernel = cl::Kernel(program, "finishSpreadCharge"); - pmeFinishSpreadChargeKernel.setArg(0, pmeGrid->getDeviceBuffer()); + pmeFinishSpreadChargeKernel.setArg(0, pmeGrid2->getDeviceBuffer()); + pmeFinishSpreadChargeKernel.setArg(1, pmeGrid->getDeviceBuffer()); } } } diff --git a/platforms/opencl/src/kernels/pme.cl b/platforms/opencl/src/kernels/pme.cl index 1da66cd52..356bc387c 100644 --- a/platforms/opencl/src/kernels/pme.cl +++ b/platforms/opencl/src/kernels/pme.cl @@ -138,29 +138,18 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con zindex -= (zindex >= GRID_SIZE_Z ? GRID_SIZE_Z : 0); int index = xindex*GRID_SIZE_Y*GRID_SIZE_Z + yindex*GRID_SIZE_Z + zindex; real add = pos.w*data[ix].x*data[iy].y*data[iz].z; -#ifdef USE_DOUBLE_PRECISION atom_add(&pmeGrid[index], (long) (add*0x100000000)); -#else - int gridIndex = (index%2 == 0 ? index/2 : (index+GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z)/2); - atom_add(&pmeGrid[gridIndex], (long) (add*0x100000000)); -#endif - } } } } } -__kernel void finishSpreadCharge(__global long* restrict pmeGrid) { - __global real* realGrid = (__global real*) pmeGrid; +__kernel void finishSpreadCharge(__global long* restrict fixedGrid, __global real* restrict realGrid) { const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; real scale = EPSILON_FACTOR/(real) 0x100000000; for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { -#ifdef USE_DOUBLE_PRECISION - long value = pmeGrid[index]; -#else - long value = pmeGrid[index%2 == 0 ? index/2 : (index+gridSize)/2]; -#endif + long value = fixedGrid[index]; realGrid[index] = (real) (value*scale); } } -- GitLab From 99ed3ba783d67b5680a23729209812cdc3d9c2dd Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Fri, 3 Apr 2015 16:46:39 -0700 Subject: [PATCH 327/338] Optimization for Nvidia --- platforms/opencl/src/OpenCLKernels.cpp | 5 ++++- platforms/opencl/src/kernels/pme.cl | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 7e01e3d23..357b5a93b 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1666,7 +1666,10 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb sort = new OpenCLSort(cl, new SortTrait(), cl.getNumAtoms()); fft = new OpenCLFFT3D(cl, gridSizeX, gridSizeY, gridSizeZ, true); string vendor = cl.getDevice().getInfo(); - usePmeQueue = (vendor.size() >= 6 && vendor.substr(0, 6) == "NVIDIA"); + bool isNvidia = (vendor.size() >= 6 && vendor.substr(0, 6) == "NVIDIA"); + if (isNvidia) + pmeDefines["USE_ALTERNATE_MEMORY_ACCESS_PATTERN"] = "1"; + usePmeQueue = isNvidia; if (usePmeQueue) { pmeQueue = cl::CommandQueue(cl.getContext(), cl.getDevice()); int recipForceGroup = force.getReciprocalSpaceForceGroup(); diff --git a/platforms/opencl/src/kernels/pme.cl b/platforms/opencl/src/kernels/pme.cl index 356bc387c..44650ba47 100644 --- a/platforms/opencl/src/kernels/pme.cl +++ b/platforms/opencl/src/kernels/pme.cl @@ -138,7 +138,13 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con zindex -= (zindex >= GRID_SIZE_Z ? GRID_SIZE_Z : 0); int index = xindex*GRID_SIZE_Y*GRID_SIZE_Z + yindex*GRID_SIZE_Z + zindex; real add = pos.w*data[ix].x*data[iy].y*data[iz].z; +#ifdef USE_ALTERNATE_MEMORY_ACCESS_PATTERN + // On Nvidia devices (at least Maxwell anyway), this split ordering produces much higher performance. Why? + // I have no idea! And of course on AMD it produces slower performance. GPUs are not meant to be understood. + atom_add(&pmeGrid[index%2 == 0 ? index/2 : (index+GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z)/2], (long) (add*0x100000000)); +#else atom_add(&pmeGrid[index], (long) (add*0x100000000)); +#endif } } } @@ -149,7 +155,11 @@ __kernel void finishSpreadCharge(__global long* restrict fixedGrid, __global rea const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; real scale = EPSILON_FACTOR/(real) 0x100000000; for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { +#ifdef USE_ALTERNATE_MEMORY_ACCESS_PATTERN + long value = fixedGrid[index%2 == 0 ? index/2 : (index+gridSize)/2]; +#else long value = fixedGrid[index]; +#endif realGrid[index] = (real) (value*scale); } } -- GitLab From 9c7898e0c6eca6e8f896c986a8142ecc36e3b0d8 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 8 Apr 2015 13:44:03 -0700 Subject: [PATCH 328/338] Implemented an optimized real-to-complex FFT --- platforms/opencl/include/OpenCLFFT3D.h | 10 +- platforms/opencl/src/OpenCLFFT3D.cpp | 125 ++++++++++++++++--- platforms/opencl/src/kernels/fftR2C.cl | 149 +++++++++++++++++++++++ platforms/opencl/tests/TestOpenCLFFT.cpp | 21 +++- 4 files changed, 278 insertions(+), 27 deletions(-) create mode 100644 platforms/opencl/src/kernels/fftR2C.cl diff --git a/platforms/opencl/include/OpenCLFFT3D.h b/platforms/opencl/include/OpenCLFFT3D.h index fbec32bb3..f28cf00ae 100644 --- a/platforms/opencl/include/OpenCLFFT3D.h +++ b/platforms/opencl/include/OpenCLFFT3D.h @@ -9,7 +9,7 @@ * 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. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -61,8 +61,9 @@ public: * @param xsize the first dimension of the data sets on which FFTs will be performed * @param ysize the second dimension of the data sets on which FFTs will be performed * @param zsize the third dimension of the data sets on which FFTs will be performed + * @param realToComplex if true, a real-to-complex transform will be done. Otherwise, it is complex-to-complex. */ - OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize); + OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize, bool realToComplex=false); /** * Perform a Fourier transform. The transform cannot be done in-place: the input and output * arrays must be different. Also, the input array is used as workspace, so its contents @@ -81,11 +82,14 @@ public: */ static int findLegalDimension(int minimum); private: - cl::Kernel createKernel(int xsize, int ysize, int zsize, int& threads); + cl::Kernel createKernel(int xsize, int ysize, int zsize, int& threads, int axis, bool forward, bool inputIsReal); int xsize, ysize, zsize; int xthreads, ythreads, zthreads; + bool packRealAsComplex; OpenCLContext& context; cl::Kernel xkernel, ykernel, zkernel; + cl::Kernel invxkernel, invykernel, invzkernel; + cl::Kernel packForwardKernel, unpackForwardKernel, packBackwardKernel, unpackBackwardKernel; }; } // namespace OpenMM diff --git a/platforms/opencl/src/OpenCLFFT3D.cpp b/platforms/opencl/src/OpenCLFFT3D.cpp index 7847a06e2..e01af4088 100644 --- a/platforms/opencl/src/OpenCLFFT3D.cpp +++ b/platforms/opencl/src/OpenCLFFT3D.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2009-2012 Stanford University and the Authors. * + * Portions copyright (c) 2009-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -35,25 +35,108 @@ using namespace OpenMM; using namespace std; -OpenCLFFT3D::OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize) : context(context), xsize(xsize), ysize(ysize), zsize(zsize) { - zkernel = createKernel(xsize, ysize, zsize, zthreads); - xkernel = createKernel(ysize, zsize, xsize, xthreads); - ykernel = createKernel(zsize, xsize, ysize, ythreads); +OpenCLFFT3D::OpenCLFFT3D(OpenCLContext& context, int xsize, int ysize, int zsize, bool realToComplex) : + context(context), xsize(xsize), ysize(ysize), zsize(zsize) { + packRealAsComplex = false; + int packedXSize = xsize; + int packedYSize = ysize; + int packedZSize = zsize; + if (realToComplex) { + // If any axis size is even, we can pack the real values into a complex grid that is only half as large. + // Look for an appropriate axis. + + packRealAsComplex = true; + int packedAxis, bufferSize; + if (xsize%2 == 0) { + packedAxis = 0; + packedXSize /= 2; + bufferSize = packedXSize; + } + else if (ysize%2 == 0) { + packedAxis = 1; + packedYSize /= 2; + bufferSize = packedYSize; + } + else if (zsize%2 == 0) { + packedAxis = 2; + packedZSize /= 2; + bufferSize = packedZSize; + } + else + packRealAsComplex = false; + if (packRealAsComplex) { + // Build the kernels for packing and unpacking the data. + + map defines; + defines["XSIZE"] = context.intToString(xsize); + defines["YSIZE"] = context.intToString(ysize); + defines["ZSIZE"] = context.intToString(zsize); + defines["PACKED_AXIS"] = context.intToString(packedAxis); + defines["PACKED_XSIZE"] = context.intToString(packedXSize); + defines["PACKED_YSIZE"] = context.intToString(packedYSize); + defines["PACKED_ZSIZE"] = context.intToString(packedZSize); + cl::Program program = context.createProgram(OpenCLKernelSources::fftR2C, defines); + packForwardKernel = cl::Kernel(program, "packForwardData"); + unpackForwardKernel = cl::Kernel(program, "unpackForwardData"); + unpackForwardKernel.setArg(2, bufferSize*(context.getUseDoublePrecision() ? sizeof(mm_double2) : sizeof(mm_float2)), NULL); + packBackwardKernel = cl::Kernel(program, "packBackwardData"); + packBackwardKernel.setArg(2, bufferSize*(context.getUseDoublePrecision() ? sizeof(mm_double2) : sizeof(mm_float2)), NULL); + unpackBackwardKernel = cl::Kernel(program, "unpackBackwardData"); + } + } + bool inputIsReal = (realToComplex && !packRealAsComplex); + zkernel = createKernel(packedXSize, packedYSize, packedZSize, zthreads, 0, true, inputIsReal); + xkernel = createKernel(packedYSize, packedZSize, packedXSize, xthreads, 1, true, inputIsReal); + ykernel = createKernel(packedZSize, packedXSize, packedYSize, ythreads, 2, true, inputIsReal); + invzkernel = createKernel(packedXSize, packedYSize, packedZSize, zthreads, 0, false, inputIsReal); + invxkernel = createKernel(packedYSize, packedZSize, packedXSize, xthreads, 1, false, inputIsReal); + invykernel = createKernel(packedZSize, packedXSize, packedYSize, ythreads, 2, false, inputIsReal); } void OpenCLFFT3D::execFFT(OpenCLArray& in, OpenCLArray& out, bool forward) { - zkernel.setArg(0, in.getDeviceBuffer()); - zkernel.setArg(1, out.getDeviceBuffer()); - zkernel.setArg(2, forward ? 1 : -1); - context.executeKernel(zkernel, xsize*ysize*zsize, zthreads); - xkernel.setArg(0, out.getDeviceBuffer()); - xkernel.setArg(1, in.getDeviceBuffer()); - xkernel.setArg(2, forward ? 1 : -1); - context.executeKernel(xkernel, xsize*ysize*zsize, xthreads); - ykernel.setArg(0, in.getDeviceBuffer()); - ykernel.setArg(1, out.getDeviceBuffer()); - ykernel.setArg(2, forward ? 1 : -1); - context.executeKernel(ykernel, xsize*ysize*zsize, ythreads); + cl::Kernel kernel1 = (forward ? zkernel : invzkernel); + cl::Kernel kernel2 = (forward ? xkernel : invxkernel); + cl::Kernel kernel3 = (forward ? ykernel : invykernel); + if (packRealAsComplex) { + cl::Kernel packKernel = (forward ? packForwardKernel : packBackwardKernel); + cl::Kernel unpackKernel = (forward ? unpackForwardKernel : unpackBackwardKernel); + int gridSize = xsize*ysize*zsize/2; + + // Pack the data into a half sized grid. + + packKernel.setArg(0, in.getDeviceBuffer()); + packKernel.setArg(1, out.getDeviceBuffer()); + context.executeKernel(packKernel, gridSize); + + // Perform the FFT. + + kernel1.setArg(0, out.getDeviceBuffer()); + kernel1.setArg(1, in.getDeviceBuffer()); + context.executeKernel(kernel1, gridSize, zthreads); + kernel2.setArg(0, in.getDeviceBuffer()); + kernel2.setArg(1, out.getDeviceBuffer()); + context.executeKernel(kernel2, gridSize, xthreads); + kernel3.setArg(0, out.getDeviceBuffer()); + kernel3.setArg(1, in.getDeviceBuffer()); + context.executeKernel(kernel3, gridSize, ythreads); + + // Unpack the data. + + unpackKernel.setArg(0, in.getDeviceBuffer()); + unpackKernel.setArg(1, out.getDeviceBuffer()); + context.executeKernel(unpackKernel, gridSize); + } + else { + kernel1.setArg(0, in.getDeviceBuffer()); + kernel1.setArg(1, out.getDeviceBuffer()); + context.executeKernel(kernel1, xsize*ysize*zsize, zthreads); + kernel2.setArg(0, out.getDeviceBuffer()); + kernel2.setArg(1, in.getDeviceBuffer()); + context.executeKernel(kernel2, xsize*ysize*zsize, xthreads); + kernel3.setArg(0, in.getDeviceBuffer()); + kernel3.setArg(1, out.getDeviceBuffer()); + context.executeKernel(kernel3, xsize*ysize*zsize, ythreads); + } } int OpenCLFFT3D::findLegalDimension(int minimum) { @@ -73,7 +156,7 @@ int OpenCLFFT3D::findLegalDimension(int minimum) { } } -cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threads) { +cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threads, int axis, bool forward, bool inputIsReal) { int maxThreads = std::min(256, (int) context.getDevice().getInfo()); bool isCPU = context.getDevice().getInfo() == CL_DEVICE_TYPE_CPU; while (true) { @@ -226,6 +309,8 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa // Create the kernel. + bool outputIsReal = (inputIsReal && axis == 2 && !forward); + string outputSuffix = (outputIsReal ? ".x" : ""); if (loopRequired) { source<<"for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0))\n"; source<<"out[y*(ZSIZE*XSIZE)+z*XSIZE+x] = data"<<(stage%2)<<"[z];\n"; @@ -242,6 +327,10 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa replacements["M_PI"] = context.doubleToString(M_PI); replacements["COMPUTE_FFT"] = source.str(); replacements["LOOP_REQUIRED"] = (loopRequired ? "1" : "0"); + replacements["SIGN"] = (forward ? "1" : "-1"); + replacements["INPUT_TYPE"] = (inputIsReal && axis == 0 && forward ? "real" : "real2"); + replacements["OUTPUT_TYPE"] = (outputIsReal ? "real" : "real2"); + replacements["INPUT_IS_REAL"] = (inputIsReal && axis == 0 && forward ? "1" : "0"); cl::Program program = context.createProgram(context.replaceStrings(OpenCLKernelSources::fft, replacements)); cl::Kernel kernel(program, "execFFT"); threads = (isCPU ? 1 : blocksPerGroup*zsize); diff --git a/platforms/opencl/src/kernels/fftR2C.cl b/platforms/opencl/src/kernels/fftR2C.cl new file mode 100644 index 000000000..6ec3af73a --- /dev/null +++ b/platforms/opencl/src/kernels/fftR2C.cl @@ -0,0 +1,149 @@ +/** + * Combine the two halves of a real grid into a complex grid that is half as large. + */ +__kernel void packForwardData(__global const real* restrict in, __global real2* restrict out) { + const int gridSize = PACKED_XSIZE*PACKED_YSIZE*PACKED_ZSIZE; + for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { + int x = index/(PACKED_YSIZE*PACKED_ZSIZE); + int remainder = index-x*(PACKED_YSIZE*PACKED_ZSIZE); + int y = remainder/PACKED_ZSIZE; + int z = remainder-y*PACKED_ZSIZE; +#if PACKED_AXIS == 0 + real2 value = (real2) (in[2*x*YSIZE*ZSIZE+y*ZSIZE+z], in[(2*x+1)*YSIZE*ZSIZE+y*ZSIZE+z]); +#elif PACKED_AXIS == 1 + real2 value = (real2) (in[x*YSIZE*ZSIZE+2*y*ZSIZE+z], in[x*YSIZE*ZSIZE+(2*y+1)*ZSIZE+z]); +#else + real2 value = (real2) (in[x*YSIZE*ZSIZE+y*ZSIZE+2*z], in[x*YSIZE*ZSIZE+y*ZSIZE+(2*z+1)]); +#endif + out[index] = value; + } +} + +/** + * Split the transformed data back into a full sized, symmetric grid. + */ +__kernel void unpackForwardData(__global const real2* restrict in, __global real2* restrict out, __local real2* restrict w) { + // Compute the phase factors. + +#if PACKED_AXIS == 0 + for (int i = get_local_id(0); i < PACKED_XSIZE; i += get_local_size(0)) + w[i] = (real2) (sin(i*2*M_PI/XSIZE), cos(i*2*M_PI/XSIZE)); +#elif PACKED_AXIS == 1 + for (int i = get_local_id(0); i < PACKED_YSIZE; i += get_local_size(0)) + w[i] = (real2) (sin(i*2*M_PI/YSIZE), cos(i*2*M_PI/YSIZE)); +#else + for (int i = get_local_id(0); i < PACKED_ZSIZE; i += get_local_size(0)) + w[i] = (real2) (sin(i*2*M_PI/ZSIZE), cos(i*2*M_PI/ZSIZE)); +#endif + barrier(CLK_LOCAL_MEM_FENCE); + + // Transform the data. + + const int gridSize = PACKED_XSIZE*PACKED_YSIZE*PACKED_ZSIZE; + for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { + int x = index/(PACKED_YSIZE*PACKED_ZSIZE); + int remainder = index-x*(PACKED_YSIZE*PACKED_ZSIZE); + int y = remainder/PACKED_ZSIZE; + int z = remainder-y*PACKED_ZSIZE; + int xp = (x == 0 ? x : PACKED_XSIZE-x); + int yp = (y == 0 ? y : PACKED_YSIZE-y); + int zp = (z == 0 ? z : PACKED_ZSIZE-z); + real2 z1 = in[x*PACKED_YSIZE*PACKED_ZSIZE+y*PACKED_ZSIZE+z]; + real2 z2 = in[xp*PACKED_YSIZE*PACKED_ZSIZE+yp*PACKED_ZSIZE+zp]; +#if PACKED_AXIS == 0 + real2 wfac = w[x]; +#elif PACKED_AXIS == 1 + real2 wfac = w[y]; +#else + real2 wfac = w[z]; +#endif + real2 output = (real2) ((z1.x+z2.x - wfac.x*(z1.x-z2.x) + wfac.y*(z1.y+z2.y))/2, (z1.y-z2.y - wfac.y*(z1.x-z2.x) - wfac.x*(z1.y+z2.y))/2); + out[x*YSIZE*ZSIZE+y*ZSIZE+z] = output; + xp = (x == 0 ? x : XSIZE-x); + yp = (y == 0 ? y : YSIZE-y); + zp = (z == 0 ? z : ZSIZE-z); +#if PACKED_AXIS == 0 + if (x == 0) + out[PACKED_XSIZE*YSIZE*ZSIZE+yp*ZSIZE+zp] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); +#elif PACKED_AXIS == 1 + if (y == 0) + out[xp*YSIZE*ZSIZE+PACKED_YSIZE*ZSIZE+zp] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); +#else + if (z == 0) + out[xp*YSIZE*ZSIZE+yp*ZSIZE+PACKED_ZSIZE] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); +#endif + else + out[xp*YSIZE*ZSIZE+yp*ZSIZE+zp] = (real2) (output.x, -output.y); + } +} + +/** + * Repack the symmetric complex grid into one half as large in preparation for doing an inverse complex-to-real transform. + */ +__kernel void packBackwardData(__global const real2* restrict in, __global real2* restrict out, __local real2* restrict w) { + // Compute the phase factors. + +#if PACKED_AXIS == 0 + for (int i = get_local_id(0); i < PACKED_XSIZE; i += get_local_size(0)) + w[i] = (real2) (cos(i*2*M_PI/XSIZE), sin(i*2*M_PI/XSIZE)); +#elif PACKED_AXIS == 1 + for (int i = get_local_id(0); i < PACKED_YSIZE; i += get_local_size(0)) + w[i] = (real2) (cos(i*2*M_PI/YSIZE), sin(i*2*M_PI/YSIZE)); +#else + for (int i = get_local_id(0); i < PACKED_ZSIZE; i += get_local_size(0)) + w[i] = (real2) (cos(i*2*M_PI/ZSIZE), sin(i*2*M_PI/ZSIZE)); +#endif + barrier(CLK_LOCAL_MEM_FENCE); + + // Transform the data. + + const int gridSize = PACKED_XSIZE*PACKED_YSIZE*PACKED_ZSIZE; + for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { + int x = index/(PACKED_YSIZE*PACKED_ZSIZE); + int remainder = index-x*(PACKED_YSIZE*PACKED_ZSIZE); + int y = remainder/PACKED_ZSIZE; + int z = remainder-y*PACKED_ZSIZE; + int xp = (x == 0 ? x : PACKED_XSIZE-x); + int yp = (y == 0 ? y : PACKED_YSIZE-y); + int zp = (z == 0 ? z : PACKED_ZSIZE-z); + real2 z1 = in[x*YSIZE*ZSIZE+y*ZSIZE+z]; +#if PACKED_AXIS == 0 + real2 wfac = w[x]; + real2 z2 = in[(PACKED_XSIZE-x)*YSIZE*ZSIZE+yp*ZSIZE+zp]; +#elif PACKED_AXIS == 1 + real2 wfac = w[y]; + real2 z2 = in[xp*YSIZE*ZSIZE+(PACKED_YSIZE-y)*ZSIZE+zp]; +#else + real2 wfac = w[z]; + real2 z2 = in[xp*YSIZE*ZSIZE+yp*ZSIZE+(PACKED_ZSIZE-z)]; +#endif + real2 even = (real2) ((z1.x+z2.x)/2, (z1.y-z2.y)/2); + real2 odd = (real2) ((z1.x-z2.x)/2, (z1.y+z2.y)/2); + odd = (real2) (odd.x*wfac.x-odd.y*wfac.y, odd.y*wfac.x+odd.x*wfac.y); + out[x*PACKED_YSIZE*PACKED_ZSIZE+y*PACKED_ZSIZE+z] = (real2) (even.x-odd.y, even.y+odd.x); + } +} + +/** + * Split the data back into a full sized, real grid after an inverse transform. + */ +__kernel void unpackBackwardData(__global const real2* restrict in, __global real* restrict out) { + const int gridSize = PACKED_XSIZE*PACKED_YSIZE*PACKED_ZSIZE; + for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { + int x = index/(PACKED_YSIZE*PACKED_ZSIZE); + int remainder = index-x*(PACKED_YSIZE*PACKED_ZSIZE); + int y = remainder/PACKED_ZSIZE; + int z = remainder-y*PACKED_ZSIZE; + real2 value = 2*in[index]; +#if PACKED_AXIS == 0 + out[2*x*YSIZE*ZSIZE+y*ZSIZE+z] = value.x; + out[(2*x+1)*YSIZE*ZSIZE+y*ZSIZE+z] = value.y; +#elif PACKED_AXIS == 1 + out[x*YSIZE*ZSIZE+2*y*ZSIZE+z] = value.x; + out[x*YSIZE*ZSIZE+(2*y+1)*ZSIZE+z] = value.y; +#else + out[x*YSIZE*ZSIZE+y*ZSIZE+2*z] = value.x; + out[x*YSIZE*ZSIZE+y*ZSIZE+(2*z+1)] = value.y; +#endif + } +} diff --git a/platforms/opencl/tests/TestOpenCLFFT.cpp b/platforms/opencl/tests/TestOpenCLFFT.cpp index 34b020486..1d47fdb1f 100644 --- a/platforms/opencl/tests/TestOpenCLFFT.cpp +++ b/platforms/opencl/tests/TestOpenCLFFT.cpp @@ -51,7 +51,7 @@ using namespace std; static OpenCLPlatform platform; template -void testTransform() { +void testTransform(bool realToComplex, int xsize, int ysize, int zsize) { System system; system.addParticle(0.0); OpenCLPlatform::PlatformData platformData(system, "", "", platform.getPropertyDefaultValue("OpenCLPrecision"), "false"); @@ -59,7 +59,6 @@ void testTransform() { context.initialize(); OpenMM_SFMT::SFMT sfmt; init_gen_rand(0, sfmt); - int xsize = 28, ysize = 25, zsize = 30; vector original(xsize*ysize*zsize); vector reference(original.size()); for (int i = 0; i < (int) original.size(); i++) { @@ -101,10 +100,20 @@ int main(int argc, char* argv[]) { try { if (argc > 1) platform.setPropertyDefaultValue("OpenCLPrecision", string(argv[1])); - if (platform.getPropertyDefaultValue("OpenCLPrecision") == "double") - testTransform(); - else - testTransform(); + if (platform.getPropertyDefaultValue("OpenCLPrecision") == "double") { + testTransform(false, 28, 25, 30); + testTransform(true, 28, 25, 25); + testTransform(true, 25, 28, 25); + testTransform(true, 25, 25, 28); + testTransform(true, 21, 25, 27); + } + else { + testTransform(false, 28, 25, 30); + testTransform(true, 28, 25, 25); + testTransform(true, 25, 28, 25); + testTransform(true, 25, 25, 28); + testTransform(true, 21, 25, 27); + } } catch(const exception& e) { cout << "exception: " << e.what() << endl; -- GitLab From 803fe4338acc1af72e0f59a05c8d63dd30619133 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 8 Apr 2015 16:47:28 -0700 Subject: [PATCH 329/338] Very minor optimization to FFT --- platforms/opencl/src/kernels/fftR2C.cl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/platforms/opencl/src/kernels/fftR2C.cl b/platforms/opencl/src/kernels/fftR2C.cl index 6ec3af73a..c887f5714 100644 --- a/platforms/opencl/src/kernels/fftR2C.cl +++ b/platforms/opencl/src/kernels/fftR2C.cl @@ -45,9 +45,9 @@ __kernel void unpackForwardData(__global const real2* restrict in, __global real int remainder = index-x*(PACKED_YSIZE*PACKED_ZSIZE); int y = remainder/PACKED_ZSIZE; int z = remainder-y*PACKED_ZSIZE; - int xp = (x == 0 ? x : PACKED_XSIZE-x); - int yp = (y == 0 ? y : PACKED_YSIZE-y); - int zp = (z == 0 ? z : PACKED_ZSIZE-z); + int xp = (x == 0 ? 0 : PACKED_XSIZE-x); + int yp = (y == 0 ? 0 : PACKED_YSIZE-y); + int zp = (z == 0 ? 0 : PACKED_ZSIZE-z); real2 z1 = in[x*PACKED_YSIZE*PACKED_ZSIZE+y*PACKED_ZSIZE+z]; real2 z2 = in[xp*PACKED_YSIZE*PACKED_ZSIZE+yp*PACKED_ZSIZE+zp]; #if PACKED_AXIS == 0 @@ -59,9 +59,9 @@ __kernel void unpackForwardData(__global const real2* restrict in, __global real #endif real2 output = (real2) ((z1.x+z2.x - wfac.x*(z1.x-z2.x) + wfac.y*(z1.y+z2.y))/2, (z1.y-z2.y - wfac.y*(z1.x-z2.x) - wfac.x*(z1.y+z2.y))/2); out[x*YSIZE*ZSIZE+y*ZSIZE+z] = output; - xp = (x == 0 ? x : XSIZE-x); - yp = (y == 0 ? y : YSIZE-y); - zp = (z == 0 ? z : ZSIZE-z); + xp = (x == 0 ? 0 : XSIZE-x); + yp = (y == 0 ? 0 : YSIZE-y); + zp = (z == 0 ? 0 : ZSIZE-z); #if PACKED_AXIS == 0 if (x == 0) out[PACKED_XSIZE*YSIZE*ZSIZE+yp*ZSIZE+zp] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); @@ -103,9 +103,9 @@ __kernel void packBackwardData(__global const real2* restrict in, __global real2 int remainder = index-x*(PACKED_YSIZE*PACKED_ZSIZE); int y = remainder/PACKED_ZSIZE; int z = remainder-y*PACKED_ZSIZE; - int xp = (x == 0 ? x : PACKED_XSIZE-x); - int yp = (y == 0 ? y : PACKED_YSIZE-y); - int zp = (z == 0 ? z : PACKED_ZSIZE-z); + int xp = (x == 0 ? 0 : PACKED_XSIZE-x); + int yp = (y == 0 ? 0 : PACKED_YSIZE-y); + int zp = (z == 0 ? 0 : PACKED_ZSIZE-z); real2 z1 = in[x*YSIZE*ZSIZE+y*ZSIZE+z]; #if PACKED_AXIS == 0 real2 wfac = w[x]; -- GitLab From 3a4154862b7e2552de78e0a91bce2bf36b62c16d Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 10 Apr 2015 12:20:17 -0700 Subject: [PATCH 330/338] Optimizations to CpuNonbondedForce --- openmmapi/include/openmm/internal/vectorize8.h | 12 ++++++++++++ openmmapi/include/openmm/internal/vectorize_neon.h | 8 ++++++-- openmmapi/include/openmm/internal/vectorize_pnacl.h | 8 ++++++-- openmmapi/include/openmm/internal/vectorize_sse.h | 12 ++++++++++++ platforms/cpu/src/CpuNonbondedForceVec4.cpp | 8 ++++---- platforms/cpu/src/CpuNonbondedForceVec8.cpp | 8 ++++---- 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/openmmapi/include/openmm/internal/vectorize8.h b/openmmapi/include/openmm/internal/vectorize8.h index 38206fffe..5b4e1cc79 100644 --- a/openmmapi/include/openmm/internal/vectorize8.h +++ b/openmmapi/include/openmm/internal/vectorize8.h @@ -191,6 +191,18 @@ static inline fvec8 sqrt(const fvec8& v) { return fvec8(_mm256_sqrt_ps(v.val)); } +static inline fvec8 rsqrt(const fvec8& v) { + // Initial estimate of rsqrt(). + + fvec8 y(_mm256_rsqrt_ps(v.val)); + + // Perform an iteration of Newton refinement. + + fvec8 x2 = v*0.5f; + y *= fvec8(1.5f)-x2*y*y; + return y; +} + static inline float dot8(const fvec8& v1, const fvec8& v2) { fvec8 result = _mm256_dp_ps(v1, v2, 0xF1); return _mm_cvtss_f32(result.lowerVec())+_mm_cvtss_f32(result.upperVec()); diff --git a/openmmapi/include/openmm/internal/vectorize_neon.h b/openmmapi/include/openmm/internal/vectorize_neon.h index cb708ee7d..380658c01 100644 --- a/openmmapi/include/openmm/internal/vectorize_neon.h +++ b/openmmapi/include/openmm/internal/vectorize_neon.h @@ -251,11 +251,15 @@ static inline fvec4 abs(const fvec4& v) { return vabsq_f32(v); } -static inline fvec4 sqrt(const fvec4& v) { +static inline fvec4 rsqrt(const fvec4& v) { float32x4_t recipSqrt = vrsqrteq_f32(v); recipSqrt = vmulq_f32(recipSqrt, vrsqrtsq_f32(vmulq_f32(recipSqrt, v), recipSqrt)); recipSqrt = vmulq_f32(recipSqrt, vrsqrtsq_f32(vmulq_f32(recipSqrt, v), recipSqrt)); - return vmulq_f32(v, recipSqrt); + return recipSqrt; +} + +static inline fvec4 sqrt(const fvec4& v) { + return rsqrt(v)*v; } static inline float dot3(const fvec4& v1, const fvec4& v2) { diff --git a/openmmapi/include/openmm/internal/vectorize_pnacl.h b/openmmapi/include/openmm/internal/vectorize_pnacl.h index 97f366327..d8b3c0094 100644 --- a/openmmapi/include/openmm/internal/vectorize_pnacl.h +++ b/openmmapi/include/openmm/internal/vectorize_pnacl.h @@ -330,7 +330,7 @@ static inline fvec4 ceil(const fvec4& v) { return truncated + blend(0.0f, 1.0f, truncatedswitchingDistance); fvec4 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); fvec4 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; @@ -212,8 +212,8 @@ void CpuNonbondedForceVec4::calculateBlockEwaldIxnImpl(int blockIndex, float* fo // Compute the interactions. - fvec4 r = sqrt(r2); - fvec4 inverseR = fvec4(1.0f)/r; + fvec4 inverseR = rsqrt(r2); + fvec4 r = r2*inverseR; fvec4 energy, dEdR; float atomEpsilon = atomParameters[atom].second; if (atomEpsilon != 0.0f) { diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index 6567f8cc0..7520159af 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -126,8 +126,7 @@ void CpuNonbondedForceVec8::calculateBlockIxnImpl(int blockIndex, float* forces, // Compute the interactions. - fvec8 r = sqrt(r2); - fvec8 inverseR = fvec8(1.0f)/r; + fvec8 inverseR = rsqrt(r2); fvec8 energy, dEdR; float atomEpsilon = atomParameters[atom].second; if (atomEpsilon != 0.0f) { @@ -139,6 +138,7 @@ void CpuNonbondedForceVec8::calculateBlockIxnImpl(int blockIndex, float* forces, dEdR = epsSig6*(12.0f*sig6 - 6.0f); energy = epsSig6*(sig6-1.0f); if (useSwitch) { + fvec8 r = r2*inverseR; fvec8 t = (r>switchingDistance) & ((r-switchingDistance)*invSwitchingInterval); fvec8 switchValue = 1+t*t*t*(-10.0f+t*(15.0f-t*6.0f)); fvec8 switchDeriv = t*t*(-30.0f+t*(60.0f-t*30.0f))*invSwitchingInterval; @@ -242,8 +242,8 @@ void CpuNonbondedForceVec8::calculateBlockEwaldIxnImpl(int blockIndex, float* fo // Compute the interactions. - fvec8 r = sqrt(r2); - fvec8 inverseR = fvec8(1.0f)/r; + fvec8 inverseR = rsqrt(r2); + fvec8 r = r2*inverseR; fvec8 energy, dEdR; float atomEpsilon = atomParameters[atom].second; if (atomEpsilon != 0.0f) { -- GitLab From 95423468ab958e4e71851a75b42182595e7e8643 Mon Sep 17 00:00:00 2001 From: peastman Date: Fri, 10 Apr 2015 12:35:39 -0700 Subject: [PATCH 331/338] Optimizations to neighbor list construction --- platforms/cpu/include/CpuNeighborList.h | 3 +- platforms/cpu/src/CpuNeighborList.cpp | 112 +++++++++++++++--------- 2 files changed, 73 insertions(+), 42 deletions(-) diff --git a/platforms/cpu/include/CpuNeighborList.h b/platforms/cpu/include/CpuNeighborList.h index 0ffcf3806..2430f5f13 100644 --- a/platforms/cpu/include/CpuNeighborList.h +++ b/platforms/cpu/include/CpuNeighborList.h @@ -9,7 +9,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2013 Stanford University and the Authors. * + * Portions copyright (c) 2013-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -61,6 +61,7 @@ public: private: int blockSize; std::vector sortedAtoms; + std::vector sortedPositions; std::vector > blockNeighbors; std::vector > blockExclusions; // The following variables are used to make information accessible to the individual threads. diff --git a/platforms/cpu/src/CpuNeighborList.cpp b/platforms/cpu/src/CpuNeighborList.cpp index a41d402d7..27eeb302a 100644 --- a/platforms/cpu/src/CpuNeighborList.cpp +++ b/platforms/cpu/src/CpuNeighborList.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2013 Stanford University and the Authors. * + * Portions copyright (c) 2013-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -164,8 +164,8 @@ public: return VoxelIndex(y, z); } - - void getNeighbors(vector& neighbors, int blockIndex, const fvec4& blockCenter, const fvec4& blockWidth, const vector& sortedAtoms, vector& exclusions, float maxDistance, const vector& blockAtoms, const float* atomLocations, const vector& atomVoxelIndex) const { + + void getNeighbors(vector& neighbors, int blockIndex, const fvec4& blockCenter, const fvec4& blockWidth, const vector& sortedAtoms, vector& exclusions, float maxDistance, const vector& blockAtoms, const vector& blockAtomX, const vector& blockAtomY, const vector& blockAtomZ, const vector& sortedPositions, const vector& atomVoxelIndex) const { neighbors.resize(0); exclusions.resize(0); fvec4 boxSize(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2], 0); @@ -233,24 +233,34 @@ public: float minx = centerPos[0]; float maxx = centerPos[0]; - fvec4 offset(-xoffset, -yoffset+voxelSizeY*y+(usePeriodic ? 0.0f : miny), voxelSizeZ*z+(usePeriodic ? 0.0f : minz), 0); - for (int k = 0; k < (int) blockAtoms.size(); k++) { - const float* atomPos = &atomLocations[4*blockAtoms[k]]; - fvec4 posVec(atomPos); - fvec4 delta1 = offset-posVec; - fvec4 delta2 = delta1+fvec4(0, voxelSizeY, voxelSizeZ, 0); - if (usePeriodic) { - delta1 -= round(delta1*invBoxSize)*boxSize; - delta2 -= round(delta2*invBoxSize)*boxSize; + float offset[3] = {-xoffset, -yoffset+voxelSizeY*y+(usePeriodic ? 0.0f : miny), voxelSizeZ*z+(usePeriodic ? 0.0f : minz)}; + for (int k = 0; k < (int) blockAtoms.size(); k += 4) { + fvec4 dist2 = maxDistanceSquared; + if (y != atomVoxelIndex[k].y) { + fvec4 dy1 = offset[1]-fvec4(&blockAtomY[k]); + fvec4 dy2 = dy1+voxelSizeY; + if (usePeriodic) { + dy1 -= round(dy1*invBoxSize[1])*boxSize[1]; + dy2 -= round(dy2*invBoxSize[1])*boxSize[1]; + } + fvec4 dy = min(abs(dy1), abs(dy2)); + dist2 -= dy*dy; + } + if (z != atomVoxelIndex[k].z) { + fvec4 dz1 = offset[2]-fvec4(&blockAtomZ[k]); + fvec4 dz2 = dz1+voxelSizeZ; + if (usePeriodic) { + dz1 -= round(dz1*invBoxSize[2])*boxSize[2]; + dz2 -= round(dz2*invBoxSize[2])*boxSize[2]; + } + fvec4 dz = min(abs(dz1), abs(dz2)); + dist2 -= dz*dz; } - fvec4 delta = min(abs(delta1), abs(delta2)); - float dy = (y == atomVoxelIndex[k].y ? 0.0f : delta[1]); - float dz = (z == atomVoxelIndex[k].z ? 0.0f : delta[2]); - float dist2 = maxDistanceSquared-dy*dy-dz*dz; - if (dist2 > 0) { - float dist = sqrtf(dist2); - minx = min(minx, atomPos[0]-dist-xoffset); - maxx = max(maxx, atomPos[0]+dist-xoffset); + fvec4 dist = sqrt(dist2); + int numToCheck = min(4, (int) (blockAtoms.size()-k)); + for (int m = 0; m < numToCheck; m++) { + minx = min(minx, blockAtomX[k+m]-dist[m]-xoffset); + maxx = max(maxx, blockAtomX[k+m]+dist[m]-xoffset); } } if (minx == maxx) @@ -290,12 +300,10 @@ public: if (sortedIndex >= lastSortedIndex) continue; - fvec4 atomPos(atomLocations+4*sortedAtoms[sortedIndex]); + fvec4 atomPos(&sortedPositions[4*sortedIndex]); fvec4 delta = atomPos-centerPos; - if (periodicRectangular) { - fvec4 base = round(delta*invBoxSize)*boxSize; - delta = delta-base; - } + if (periodicRectangular) + delta -= round(delta*invBoxSize)*boxSize; else if (needPeriodic) { delta -= periodicBoxVec4[2]*floorf(delta[2]*recipBoxSize[2]+0.5f); delta -= periodicBoxVec4[1]*floorf(delta[1]*recipBoxSize[1]+0.5f); @@ -310,26 +318,34 @@ public: // The distance is large enough that there might not be any actual interactions. // Check individual atom pairs to be sure. - bool any = false; - for (int k = 0; k < (int) blockAtoms.size(); k++) { - fvec4 pos1(&atomLocations[4*blockAtoms[k]]); - delta = atomPos-pos1; + bool anyInteraction = false; + for (int k = 0; k < (int) blockAtoms.size(); k += 4) { + fvec4 dx = fvec4(&blockAtomX[k])-atomPos[0]; + fvec4 dy = fvec4(&blockAtomY[k])-atomPos[1]; + fvec4 dz = fvec4(&blockAtomZ[k])-atomPos[2]; if (periodicRectangular) { - fvec4 base = round(delta*invBoxSize)*boxSize; - delta = delta-base; + dx -= round(dx*invBoxSize[0])*boxSize[0]; + dy -= round(dy*invBoxSize[1])*boxSize[1]; + dz -= round(dz*invBoxSize[2])*boxSize[2]; } else if (needPeriodic) { - delta -= periodicBoxVec4[2]*floorf(delta[2]*recipBoxSize[2]+0.5f); - delta -= periodicBoxVec4[1]*floorf(delta[1]*recipBoxSize[1]+0.5f); - delta -= periodicBoxVec4[0]*floorf(delta[0]*recipBoxSize[0]+0.5f); + fvec4 scale3 = floor(dz*recipBoxSize[2]+0.5f); + dx -= scale3*periodicBoxVectors[2][0]; + dy -= scale3*periodicBoxVectors[2][1]; + dz -= scale3*periodicBoxVectors[2][2]; + fvec4 scale2 = floor(dy*recipBoxSize[1]+0.5f); + dx -= scale2*periodicBoxVectors[1][0]; + dy -= scale2*periodicBoxVectors[1][1]; + fvec4 scale1 = floor(dx*recipBoxSize[0]+0.5f); + dx -= scale1*periodicBoxVectors[0][0]; } - float r2 = dot3(delta, delta); - if (r2 < maxDistanceSquared) { - any = true; + fvec4 r2 = dx*dx + dy*dy + dz*dz; + if (any(r2 < maxDistanceSquared)) { + anyInteraction = true; break; } } - if (!any) + if (!anyInteraction) continue; } @@ -379,6 +395,7 @@ void CpuNeighborList::computeNeighborList(int numAtoms, const AlignedArray blockAtoms; + vector blockAtomX(blockSize), blockAtomY(blockSize), blockAtomZ(blockSize); vector atomVoxelIndex; for (int i = threadIndex; i < numBlocks; i += numThreads) { // Find the atoms in this block and compute their bounding box. @@ -501,14 +521,24 @@ void CpuNeighborList::threadComputeNeighborList(ThreadPool& threads, int threadI blockAtoms[j] = sortedAtoms[firstIndex+j]; atomVoxelIndex[j] = voxels->getVoxelIndex(&atomLocations[4*blockAtoms[j]]); } - fvec4 minPos(&atomLocations[4*sortedAtoms[firstIndex]]); + fvec4 minPos(&sortedPositions[4*firstIndex]); fvec4 maxPos = minPos; for (int j = 1; j < atomsInBlock; j++) { - fvec4 pos(&atomLocations[4*sortedAtoms[firstIndex+j]]); + fvec4 pos(&sortedPositions[4*(firstIndex+j)]); minPos = min(minPos, pos); maxPos = max(maxPos, pos); } - voxels->getNeighbors(blockNeighbors[i], i, (maxPos+minPos)*0.5f, (maxPos-minPos)*0.5f, sortedAtoms, blockExclusions[i], maxDistance, blockAtoms, atomLocations, atomVoxelIndex); + for (int j = 0; j < atomsInBlock; j++) { + blockAtomX[j] = sortedPositions[4*(firstIndex+j)]; + blockAtomY[j] = sortedPositions[4*(firstIndex+j)+1]; + blockAtomZ[j] = sortedPositions[4*(firstIndex+j)+2]; + } + for (int j = atomsInBlock; j < blockSize; j++) { + blockAtomX[j] = 1e10; + blockAtomY[j] = 1e10; + blockAtomZ[j] = 1e10; + } + voxels->getNeighbors(blockNeighbors[i], i, (maxPos+minPos)*0.5f, (maxPos-minPos)*0.5f, sortedAtoms, blockExclusions[i], maxDistance, blockAtoms, blockAtomX, blockAtomY, blockAtomZ, sortedPositions, atomVoxelIndex); // Record the exclusions for this block. -- GitLab From 5e1f7d39c99e843b420c3eb6f166bd27ca77a2af Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 13 Apr 2015 16:31:24 -0700 Subject: [PATCH 332/338] Added a test for rsqrt() --- tests/TestVectorize.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/TestVectorize.cpp b/tests/TestVectorize.cpp index 94ce01b4c..04fcd91b6 100644 --- a/tests/TestVectorize.cpp +++ b/tests/TestVectorize.cpp @@ -6,7 +6,7 @@ * Biological Structures at Stanford, funded under the NIH Roadmap for * * Medical Research, grant U54 GM072970. See https://simtk.org. * * * - * Portions copyright (c) 2014 Stanford University and the Authors. * + * Portions copyright (c) 2014-2015 Stanford University and the Authors. * * Authors: Peter Eastman * * Contributors: * * * @@ -148,6 +148,7 @@ void testMathFunctions() { ASSERT_VEC4_EQUAL(min(f1, f2), 0.4, 1.2, -1.2, -5.0); ASSERT_VEC4_EQUAL(max(f1, f2), 1.1, 1.9, 1.3, -3.8); ASSERT_VEC4_EQUAL(sqrt(fvec4(1.5, 3.1, 4.0, 15.0)), sqrt(1.5), sqrt(3.1), sqrt(4.0), sqrt(15.0)); + ASSERT_VEC4_EQUAL(rsqrt(fvec4(1.5, 3.1, 4.0, 15.0)), 1.0/sqrt(1.5), 1.0/sqrt(3.1), 1.0/sqrt(4.0), 1.0/sqrt(15.0)); ASSERT_EQUAL_TOL(f1[0]*f2[0]+f1[1]*f2[1]+f1[2]*f2[2], dot3(f1, f2), 1e-6); ASSERT_EQUAL_TOL(f1[0]*f2[0]+f1[1]*f2[1]+f1[2]*f2[2]+f1[3]*f2[3], dot4(f1, f2), 1e-6); ASSERT(any(f1 > 0.5)); -- GitLab From 1129599e468e3ded8ab8f88539148e91394c0983 Mon Sep 17 00:00:00 2001 From: peastman Date: Mon, 13 Apr 2015 17:03:24 -0700 Subject: [PATCH 333/338] Fixed some compilation errors --- CMakeLists.txt | 4 +++- platforms/cpu/src/CpuCustomManyParticleForce.cpp | 2 +- platforms/reference/src/SimTKReference/ObcParameters.cpp | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5102c6dc1..e6fb64fba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -296,7 +296,9 @@ SET(OPENMM_BUILD_SHARED_LIB ON CACHE BOOL "Whether to build shared OpenMM librar SET(EXTRA_LINK_FLAGS ${EXTRA_COMPILE_FLAGS}) IF (CMAKE_SYSTEM_NAME MATCHES "Linux") - SET(EXTRA_LINK_FLAGS "${EXTRA_LINK_FLAGS} -Wl,--no-as-needed -lrt") + IF (NOT ANDROID) + SET(EXTRA_LINK_FLAGS "${EXTRA_LINK_FLAGS} -Wl,--no-as-needed -lrt") + ENDIF (NOT ANDROID) ENDIF (CMAKE_SYSTEM_NAME MATCHES "Linux") IF(OPENMM_BUILD_SHARED_LIB) diff --git a/platforms/cpu/src/CpuCustomManyParticleForce.cpp b/platforms/cpu/src/CpuCustomManyParticleForce.cpp index c7f253624..553d6c2e4 100644 --- a/platforms/cpu/src/CpuCustomManyParticleForce.cpp +++ b/platforms/cpu/src/CpuCustomManyParticleForce.cpp @@ -199,7 +199,7 @@ void CpuCustomManyParticleForce::setUseCutoff(RealOpenMM distance) { } void CpuCustomManyParticleForce::setPeriodic(RealVec* periodicBoxVectors) { - assert(cutoff); + assert(useCutoff); assert(periodicBoxVectors[0][0] >= 2.0*cutoffDistance); assert(periodicBoxVectors[1][1] >= 2.0*cutoffDistance); assert(periodicBoxVectors[2][2] >= 2.0*cutoffDistance); diff --git a/platforms/reference/src/SimTKReference/ObcParameters.cpp b/platforms/reference/src/SimTKReference/ObcParameters.cpp index 5537f51f3..dadf90e49 100644 --- a/platforms/reference/src/SimTKReference/ObcParameters.cpp +++ b/platforms/reference/src/SimTKReference/ObcParameters.cpp @@ -382,9 +382,9 @@ void ObcParameters::setPeriodic(OpenMM::RealVec* vectors) { assert(_cutoff); - assert(boxSize[0][0] >= 2.0*_cutoffDistance); - assert(boxSize[1][1] >= 2.0*_cutoffDistance); - assert(boxSize[2][2] >= 2.0*_cutoffDistance); + assert(vectors[0][0] >= 2.0*_cutoffDistance); + assert(vectors[1][1] >= 2.0*_cutoffDistance); + assert(vectors[2][2] >= 2.0*_cutoffDistance); _periodic = true; _periodicBoxVectors[0] = vectors[0]; -- GitLab From 05381ef1eaa110f4a48600ff75881152dc34d26a Mon Sep 17 00:00:00 2001 From: peastman Date: Tue, 14 Apr 2015 12:55:31 -0700 Subject: [PATCH 334/338] Optimization to CPU nonbonded forces --- platforms/cpu/include/CpuNonbondedForceVec4.h | 12 +- platforms/cpu/include/CpuNonbondedForceVec8.h | 12 +- platforms/cpu/src/CpuNonbondedForceVec4.cpp | 172 +++++++++++++---- platforms/cpu/src/CpuNonbondedForceVec8.cpp | 176 ++++++++++++++---- 4 files changed, 280 insertions(+), 92 deletions(-) diff --git a/platforms/cpu/include/CpuNonbondedForceVec4.h b/platforms/cpu/include/CpuNonbondedForceVec4.h index 14c66f0a9..a5563dade 100644 --- a/platforms/cpu/include/CpuNonbondedForceVec4.h +++ b/platforms/cpu/include/CpuNonbondedForceVec4.h @@ -56,8 +56,8 @@ protected: /** * Templatized implementation of calculateBlockIxn. */ - template - void calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + template + void calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter); /**--------------------------------------------------------------------------------------- @@ -74,15 +74,15 @@ protected: /** * Templatized implementation of calculateBlockEwaldIxn. */ - template - void calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + template + void calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter); /** * Compute the displacement and squared distance between a collection of points, optionally using * periodic boundary conditions. */ - template - void getDeltaR(const float* posI, const fvec4& x, const fvec4& y, const fvec4& z, fvec4& dx, fvec4& dy, fvec4& dz, fvec4& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const; + template + void getDeltaR(const fvec4& posI, const fvec4& x, const fvec4& y, const fvec4& z, fvec4& dx, fvec4& dy, fvec4& dz, fvec4& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const; /** * Compute a fast approximation to erfc(x). diff --git a/platforms/cpu/include/CpuNonbondedForceVec8.h b/platforms/cpu/include/CpuNonbondedForceVec8.h index cd1b1b923..d3ec2cf6e 100644 --- a/platforms/cpu/include/CpuNonbondedForceVec8.h +++ b/platforms/cpu/include/CpuNonbondedForceVec8.h @@ -55,8 +55,8 @@ protected: /** * Templatized implementation of calculateBlockIxn. */ - template - void calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + template + void calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter); /**--------------------------------------------------------------------------------------- @@ -73,15 +73,15 @@ protected: /** * Templatized implementation of calculateBlockEwaldIxn. */ - template - void calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize); + template + void calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter); /** * Compute the displacement and squared distance between a collection of points, optionally using * periodic boundary conditions. */ - template - void getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const; + template + void getDeltaR(const fvec4& posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const; /** * Compute a fast approximation to erfc(x). diff --git a/platforms/cpu/src/CpuNonbondedForceVec4.cpp b/platforms/cpu/src/CpuNonbondedForceVec4.cpp index 69f383f58..b60aa4371 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec4.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec4.cpp @@ -44,30 +44,76 @@ CpuNonbondedForce* createCpuNonbondedForceVec4() { CpuNonbondedForceVec4::CpuNonbondedForceVec4() { } +enum PeriodicType {NoPeriodic, PeriodicPerAtom, PeriodicPerInteraction, PeriodicTriclinic}; + void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - if (triclinic) - calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); - else - calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + // Determine whether we need to apply periodic boundary conditions. + + PeriodicType periodicType; + fvec4 blockCenter; + if (!periodic) { + periodicType = NoPeriodic; + blockCenter = 0.0f; + } + else { + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; + float minx, maxx, miny, maxy, minz, maxz; + minx = maxx = posq[4*blockAtom[0]]; + miny = maxy = posq[4*blockAtom[0]+1]; + minz = maxz = posq[4*blockAtom[0]+2]; + for (int i = 1; i < 4; i++) { + minx = min(minx, posq[4*blockAtom[i]]); + maxx = max(maxx, posq[4*blockAtom[i]]); + miny = min(miny, posq[4*blockAtom[i]+1]); + maxy = max(maxy, posq[4*blockAtom[i]+1]); + minz = min(minz, posq[4*blockAtom[i]+2]); + maxz = max(maxz, posq[4*blockAtom[i]+2]); + } + blockCenter = fvec4(0.5f*(minx+maxx), 0.5f*(miny+maxy), 0.5f*(minz+maxz), 0.0f); + if (!(minx < cutoffDistance || miny < cutoffDistance || minz < cutoffDistance || + maxx > boxSize[0]-cutoffDistance || maxy > boxSize[1]-cutoffDistance || maxz > boxSize[2]-cutoffDistance)) + periodicType = NoPeriodic; + else if (triclinic) + periodicType = PeriodicTriclinic; + else if (0.5f*(boxSize[0]-(maxx-minx)) >= cutoffDistance && + 0.5f*(boxSize[1]-(maxy-miny)) >= cutoffDistance && + 0.5f*(boxSize[2]-(maxz-minz)) >= cutoffDistance) + periodicType = PeriodicPerAtom; + else + periodicType = PeriodicPerInteraction; + } + + // Call the appropriate version depending on what calculation is required for periodic boundary conditions. + + if (periodicType == NoPeriodic) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerAtom) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerInteraction) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicTriclinic) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); } -template -void CpuNonbondedForceVec4::calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { +template +void CpuNonbondedForceVec4::calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; fvec4 blockAtomPosq[4]; fvec4 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - for (int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + if (PERIODIC_TYPE == PeriodicPerAtom) + blockAtomPosq[i] -= floor((blockAtomPosq[i]-blockCenter)*invBoxSize+0.5f)*boxSize; + } fvec4 blockAtomX = fvec4(blockAtomPosq[0][0], blockAtomPosq[1][0], blockAtomPosq[2][0], blockAtomPosq[3][0]); fvec4 blockAtomY = fvec4(blockAtomPosq[0][1], blockAtomPosq[1][1], blockAtomPosq[2][1], blockAtomPosq[3][1]); fvec4 blockAtomZ = fvec4(blockAtomPosq[0][2], blockAtomPosq[1][2], blockAtomPosq[2][2], blockAtomPosq[3][2]); fvec4 blockAtomCharge = fvec4(ONE_4PI_EPS0)*fvec4(blockAtomPosq[0][3], blockAtomPosq[1][3], blockAtomPosq[2][3], blockAtomPosq[3][3]); fvec4 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first); fvec4 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const bool needPeriodic = (PERIODIC_TYPE == PeriodicPerInteraction || PERIODIC_TYPE == PeriodicTriclinic); const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); // Loop over neighbors for this block. @@ -82,7 +128,10 @@ void CpuNonbondedForceVec4::calculateBlockIxnImpl(int blockIndex, float* forces, // Compute the distances to the block atoms. fvec4 dx, dy, dz, r2; - getDeltaR(posq+4*atom, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + fvec4 atomPos(posq+4*atom); + if (PERIODIC_TYPE == PeriodicPerAtom) + atomPos -= floor((atomPos-blockCenter)*invBoxSize+0.5f)*boxSize; + getDeltaR(atomPos, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec4 include; char excl = exclusions[i]; if (excl == 0) @@ -162,29 +211,73 @@ void CpuNonbondedForceVec4::calculateBlockIxnImpl(int blockIndex, float* forces, } void CpuNonbondedForceVec4::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - if (triclinic) - calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); - else - calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + // Determine whether we need to apply periodic boundary conditions. + + PeriodicType periodicType; + fvec4 blockCenter; + if (!periodic) { + periodicType = NoPeriodic; + blockCenter = 0.0f; + } + else { + const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; + float minx, maxx, miny, maxy, minz, maxz; + minx = maxx = posq[4*blockAtom[0]]; + miny = maxy = posq[4*blockAtom[0]+1]; + minz = maxz = posq[4*blockAtom[0]+2]; + for (int i = 1; i < 4; i++) { + minx = min(minx, posq[4*blockAtom[i]]); + maxx = max(maxx, posq[4*blockAtom[i]]); + miny = min(miny, posq[4*blockAtom[i]+1]); + maxy = max(maxy, posq[4*blockAtom[i]+1]); + minz = min(minz, posq[4*blockAtom[i]+2]); + maxz = max(maxz, posq[4*blockAtom[i]+2]); + } + blockCenter = fvec4(0.5f*(minx+maxx), 0.5f*(miny+maxy), 0.5f*(minz+maxz), 0.0f); + if (!(minx < cutoffDistance || miny < cutoffDistance || minz < cutoffDistance || + maxx > boxSize[0]-cutoffDistance || maxy > boxSize[1]-cutoffDistance || maxz > boxSize[2]-cutoffDistance)) + periodicType = NoPeriodic; + else if (triclinic) + periodicType = PeriodicTriclinic; + else if (0.5f*(boxSize[0]-(maxx-minx)) >= cutoffDistance && + 0.5f*(boxSize[1]-(maxy-miny)) >= cutoffDistance && + 0.5f*(boxSize[2]-(maxz-minz)) >= cutoffDistance) + periodicType = PeriodicPerAtom; + else + periodicType = PeriodicPerInteraction; + } + + // Call the appropriate version depending on what calculation is required for periodic boundary conditions. + + if (periodicType == NoPeriodic) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerAtom) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerInteraction) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicTriclinic) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); } -template -void CpuNonbondedForceVec4::calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { +template +void CpuNonbondedForceVec4::calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex]; fvec4 blockAtomPosq[4]; fvec4 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); - for (int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + if (PERIODIC_TYPE == PeriodicPerAtom) + blockAtomPosq[i] -= floor((blockAtomPosq[i]-blockCenter)*invBoxSize+0.5f)*boxSize; + } fvec4 blockAtomX = fvec4(blockAtomPosq[0][0], blockAtomPosq[1][0], blockAtomPosq[2][0], blockAtomPosq[3][0]); fvec4 blockAtomY = fvec4(blockAtomPosq[0][1], blockAtomPosq[1][1], blockAtomPosq[2][1], blockAtomPosq[3][1]); fvec4 blockAtomZ = fvec4(blockAtomPosq[0][2], blockAtomPosq[1][2], blockAtomPosq[2][2], blockAtomPosq[3][2]); fvec4 blockAtomCharge = fvec4(ONE_4PI_EPS0)*fvec4(blockAtomPosq[0][3], blockAtomPosq[1][3], blockAtomPosq[2][3], blockAtomPosq[3][3]); fvec4 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first); fvec4 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const bool needPeriodic = (PERIODIC_TYPE == PeriodicPerInteraction || PERIODIC_TYPE == PeriodicTriclinic); const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); // Loop over neighbors for this block. @@ -199,7 +292,10 @@ void CpuNonbondedForceVec4::calculateBlockEwaldIxnImpl(int blockIndex, float* fo // Compute the distances to the block atoms. fvec4 dx, dy, dz, r2; - getDeltaR(posq+4*atom, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + fvec4 atomPos(posq+4*atom); + if (PERIODIC_TYPE == PeriodicPerAtom) + atomPos -= floor((atomPos-blockCenter)*invBoxSize+0.5f)*boxSize; + getDeltaR(atomPos, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec4 include; char excl = exclusions[i]; if (excl == 0) @@ -272,28 +368,26 @@ void CpuNonbondedForceVec4::calculateBlockEwaldIxnImpl(int blockIndex, float* fo (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); } -template -void CpuNonbondedForceVec4::getDeltaR(const float* posI, const fvec4& x, const fvec4& y, const fvec4& z, fvec4& dx, fvec4& dy, fvec4& dz, fvec4& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { +template +void CpuNonbondedForceVec4::getDeltaR(const fvec4& posI, const fvec4& x, const fvec4& y, const fvec4& z, fvec4& dx, fvec4& dy, fvec4& dz, fvec4& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { dx = x-posI[0]; dy = y-posI[1]; dz = z-posI[2]; - if (periodic) { - if (TRICLINIC) { - fvec4 scale3 = floor(dz*recipBoxSize[2]+0.5f); - dx -= scale3*periodicBoxVectors[2][0]; - dy -= scale3*periodicBoxVectors[2][1]; - dz -= scale3*periodicBoxVectors[2][2]; - fvec4 scale2 = floor(dy*recipBoxSize[1]+0.5f); - dx -= scale2*periodicBoxVectors[1][0]; - dy -= scale2*periodicBoxVectors[1][1]; - fvec4 scale1 = floor(dx*recipBoxSize[0]+0.5f); - dx -= scale1*periodicBoxVectors[0][0]; - } - else { - dx -= round(dx*invBoxSize[0])*boxSize[0]; - dy -= round(dy*invBoxSize[1])*boxSize[1]; - dz -= round(dz*invBoxSize[2])*boxSize[2]; - } + if (PERIODIC_TYPE == PeriodicTriclinic) { + fvec4 scale3 = floor(dz*recipBoxSize[2]+0.5f); + dx -= scale3*periodicBoxVectors[2][0]; + dy -= scale3*periodicBoxVectors[2][1]; + dz -= scale3*periodicBoxVectors[2][2]; + fvec4 scale2 = floor(dy*recipBoxSize[1]+0.5f); + dx -= scale2*periodicBoxVectors[1][0]; + dy -= scale2*periodicBoxVectors[1][1]; + fvec4 scale1 = floor(dx*recipBoxSize[0]+0.5f); + dx -= scale1*periodicBoxVectors[0][0]; + } + else if (PERIODIC_TYPE == PeriodicPerInteraction) { + dx -= round(dx*invBoxSize[0])*boxSize[0]; + dy -= round(dy*invBoxSize[1])*boxSize[1]; + dz -= round(dz*invBoxSize[2])*boxSize[2]; } r2 = dx*dx + dy*dy + dz*dz; } diff --git a/platforms/cpu/src/CpuNonbondedForceVec8.cpp b/platforms/cpu/src/CpuNonbondedForceVec8.cpp index 7520159af..0eb614373 100644 --- a/platforms/cpu/src/CpuNonbondedForceVec8.cpp +++ b/platforms/cpu/src/CpuNonbondedForceVec8.cpp @@ -50,7 +50,7 @@ CpuNonbondedForce* createCpuNonbondedForceVec8() { */ bool isVec8Supported() { // Make sure the CPU supports AVX. - + int cpuInfo[4]; cpuid(cpuInfo, 0); if (cpuInfo[0] >= 1) { @@ -76,29 +76,75 @@ CpuNonbondedForce* createCpuNonbondedForceVec8() { CpuNonbondedForceVec8::CpuNonbondedForceVec8() { } +enum PeriodicType {NoPeriodic, PeriodicPerAtom, PeriodicPerInteraction, PeriodicTriclinic}; + void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - if (triclinic) - calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); - else - calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + // Determine whether we need to apply periodic boundary conditions. + + PeriodicType periodicType; + fvec4 blockCenter; + if (!periodic) { + periodicType = NoPeriodic; + blockCenter = 0.0f; + } + else { + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; + float minx, maxx, miny, maxy, minz, maxz; + minx = maxx = posq[4*blockAtom[0]]; + miny = maxy = posq[4*blockAtom[0]+1]; + minz = maxz = posq[4*blockAtom[0]+2]; + for (int i = 1; i < 8; i++) { + minx = min(minx, posq[4*blockAtom[i]]); + maxx = max(maxx, posq[4*blockAtom[i]]); + miny = min(miny, posq[4*blockAtom[i]+1]); + maxy = max(maxy, posq[4*blockAtom[i]+1]); + minz = min(minz, posq[4*blockAtom[i]+2]); + maxz = max(maxz, posq[4*blockAtom[i]+2]); + } + blockCenter = fvec4(0.5f*(minx+maxx), 0.5f*(miny+maxy), 0.5f*(minz+maxz), 0.0f); + if (!(minx < cutoffDistance || miny < cutoffDistance || minz < cutoffDistance || + maxx > boxSize[0]-cutoffDistance || maxy > boxSize[1]-cutoffDistance || maxz > boxSize[2]-cutoffDistance)) + periodicType = NoPeriodic; + else if (triclinic) + periodicType = PeriodicTriclinic; + else if (0.5f*(boxSize[0]-(maxx-minx)) >= cutoffDistance && + 0.5f*(boxSize[1]-(maxy-miny)) >= cutoffDistance && + 0.5f*(boxSize[2]-(maxz-minz)) >= cutoffDistance) + periodicType = PeriodicPerAtom; + else + periodicType = PeriodicPerInteraction; + } + + // Call the appropriate version depending on what calculation is required for periodic boundary conditions. + + if (periodicType == NoPeriodic) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerAtom) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerInteraction) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicTriclinic) + calculateBlockIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); } -template -void CpuNonbondedForceVec8::calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { +template +void CpuNonbondedForceVec8::calculateBlockIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; fvec4 blockAtomPosq[8]; fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + if (PERIODIC_TYPE == PeriodicPerAtom) + blockAtomPosq[i] -= floor((blockAtomPosq[i]-blockCenter)*invBoxSize+0.5f)*boxSize; + } transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); blockAtomCharge *= ONE_4PI_EPS0; fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const bool needPeriodic = (PERIODIC_TYPE == PeriodicPerInteraction || PERIODIC_TYPE == PeriodicTriclinic); const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); // Loop over neighbors for this block. @@ -113,7 +159,10 @@ void CpuNonbondedForceVec8::calculateBlockIxnImpl(int blockIndex, float* forces, // Compute the distances to the block atoms. fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + fvec4 atomPos(posq+4*atom); + if (PERIODIC_TYPE == PeriodicPerAtom) + atomPos -= floor((atomPos-blockCenter)*invBoxSize+0.5f)*boxSize; + getDeltaR(atomPos, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec8 include; char excl = exclusions[i]; if (excl == 0) @@ -193,28 +242,72 @@ void CpuNonbondedForceVec8::calculateBlockIxnImpl(int blockIndex, float* forces, } void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { - if (triclinic) - calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); - else - calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize); + // Determine whether we need to apply periodic boundary conditions. + + PeriodicType periodicType; + fvec4 blockCenter; + if (!periodic) { + periodicType = NoPeriodic; + blockCenter = 0.0f; + } + else { + const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; + float minx, maxx, miny, maxy, minz, maxz; + minx = maxx = posq[4*blockAtom[0]]; + miny = maxy = posq[4*blockAtom[0]+1]; + minz = maxz = posq[4*blockAtom[0]+2]; + for (int i = 1; i < 8; i++) { + minx = min(minx, posq[4*blockAtom[i]]); + maxx = max(maxx, posq[4*blockAtom[i]]); + miny = min(miny, posq[4*blockAtom[i]+1]); + maxy = max(maxy, posq[4*blockAtom[i]+1]); + minz = min(minz, posq[4*blockAtom[i]+2]); + maxz = max(maxz, posq[4*blockAtom[i]+2]); + } + blockCenter = fvec4(0.5f*(minx+maxx), 0.5f*(miny+maxy), 0.5f*(minz+maxz), 0.0f); + if (!(minx < cutoffDistance || miny < cutoffDistance || minz < cutoffDistance || + maxx > boxSize[0]-cutoffDistance || maxy > boxSize[1]-cutoffDistance || maxz > boxSize[2]-cutoffDistance)) + periodicType = NoPeriodic; + else if (triclinic) + periodicType = PeriodicTriclinic; + else if (0.5f*(boxSize[0]-(maxx-minx)) >= cutoffDistance && + 0.5f*(boxSize[1]-(maxy-miny)) >= cutoffDistance && + 0.5f*(boxSize[2]-(maxz-minz)) >= cutoffDistance) + periodicType = PeriodicPerAtom; + else + periodicType = PeriodicPerInteraction; + } + + // Call the appropriate version depending on what calculation is required for periodic boundary conditions. + + if (periodicType == NoPeriodic) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerAtom) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicPerInteraction) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); + else if (periodicType == PeriodicTriclinic) + calculateBlockEwaldIxnImpl(blockIndex, forces, totalEnergy, boxSize, invBoxSize, blockCenter); } -template -void CpuNonbondedForceVec8::calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) { +template +void CpuNonbondedForceVec8::calculateBlockEwaldIxnImpl(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize, const fvec4& blockCenter) { // Load the positions and parameters of the atoms in the block. const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex]; fvec4 blockAtomPosq[8]; fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f); fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge; - for (int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]); + if (PERIODIC_TYPE == PeriodicPerAtom) + blockAtomPosq[i] -= floor((blockAtomPosq[i]-blockCenter)*invBoxSize+0.5f)*boxSize; + } transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge); blockAtomCharge *= ONE_4PI_EPS0; fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first); fvec8 blockAtomEpsilon(atomParameters[blockAtom[0]].second, atomParameters[blockAtom[1]].second, atomParameters[blockAtom[2]].second, atomParameters[blockAtom[3]].second, atomParameters[blockAtom[4]].second, atomParameters[blockAtom[5]].second, atomParameters[blockAtom[6]].second, atomParameters[blockAtom[7]].second); - bool needPeriodic = (periodic && (any(blockAtomX < cutoffDistance) || any(blockAtomY < cutoffDistance) || any(blockAtomZ < cutoffDistance) || - any(blockAtomX > boxSize[0]-cutoffDistance) || any(blockAtomY > boxSize[1]-cutoffDistance) || any(blockAtomZ > boxSize[2]-cutoffDistance))); + const bool needPeriodic = (PERIODIC_TYPE == PeriodicPerInteraction || PERIODIC_TYPE == PeriodicTriclinic); const float invSwitchingInterval = 1/(cutoffDistance-switchingDistance); // Loop over neighbors for this block. @@ -229,7 +322,10 @@ void CpuNonbondedForceVec8::calculateBlockEwaldIxnImpl(int blockIndex, float* fo // Compute the distances to the block atoms. fvec8 dx, dy, dz, r2; - getDeltaR(&posq[4*atom], blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); + fvec4 atomPos(posq+4*atom); + if (PERIODIC_TYPE == PeriodicPerAtom) + atomPos -= floor((atomPos-blockCenter)*invBoxSize+0.5f)*boxSize; + getDeltaR(atomPos, blockAtomX, blockAtomY, blockAtomZ, dx, dy, dz, r2, needPeriodic, boxSize, invBoxSize); ivec8 include; char excl = exclusions[i]; if (excl == 0) @@ -268,7 +364,7 @@ void CpuNonbondedForceVec8::calculateBlockEwaldIxnImpl(int blockIndex, float* fo } fvec8 chargeProd = blockAtomCharge*posq[4*atom+3]; dEdR += chargeProd*inverseR*ewaldScaleFunction(r); - dEdR *= inverseR*inverseR; + dEdR *= inverseR*inverseR; // Accumulate energies. @@ -302,28 +398,26 @@ void CpuNonbondedForceVec8::calculateBlockEwaldIxnImpl(int blockIndex, float* fo (fvec4(forces+4*blockAtom[j])+f[j]).store(forces+4*blockAtom[j]); } -template -void CpuNonbondedForceVec8::getDeltaR(const float* posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { +template +void CpuNonbondedForceVec8::getDeltaR(const fvec4& posI, const fvec8& x, const fvec8& y, const fvec8& z, fvec8& dx, fvec8& dy, fvec8& dz, fvec8& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const { dx = x-posI[0]; dy = y-posI[1]; dz = z-posI[2]; - if (periodic) { - if (TRICLINIC) { - fvec8 scale3 = floor(dz*recipBoxSize[2]+0.5f); - dx -= scale3*periodicBoxVectors[2][0]; - dy -= scale3*periodicBoxVectors[2][1]; - dz -= scale3*periodicBoxVectors[2][2]; - fvec8 scale2 = floor(dy*recipBoxSize[1]+0.5f); - dx -= scale2*periodicBoxVectors[1][0]; - dy -= scale2*periodicBoxVectors[1][1]; - fvec8 scale1 = floor(dx*recipBoxSize[0]+0.5f); - dx -= scale1*periodicBoxVectors[0][0]; - } - else { - dx -= round(dx*invBoxSize[0])*boxSize[0]; - dy -= round(dy*invBoxSize[1])*boxSize[1]; - dz -= round(dz*invBoxSize[2])*boxSize[2]; - } + if (PERIODIC_TYPE == PeriodicTriclinic) { + fvec8 scale3 = floor(dz*recipBoxSize[2]+0.5f); + dx -= scale3*periodicBoxVectors[2][0]; + dy -= scale3*periodicBoxVectors[2][1]; + dz -= scale3*periodicBoxVectors[2][2]; + fvec8 scale2 = floor(dy*recipBoxSize[1]+0.5f); + dx -= scale2*periodicBoxVectors[1][0]; + dy -= scale2*periodicBoxVectors[1][1]; + fvec8 scale1 = floor(dx*recipBoxSize[0]+0.5f); + dx -= scale1*periodicBoxVectors[0][0]; + } + else if (PERIODIC_TYPE == PeriodicPerInteraction) { + dx -= round(dx*invBoxSize[0])*boxSize[0]; + dy -= round(dy*invBoxSize[1])*boxSize[1]; + dz -= round(dz*invBoxSize[2])*boxSize[2]; } r2 = dx*dx + dy*dy + dz*dz; } -- GitLab From ad62d81e24538192dd84b00af848820f98701554 Mon Sep 17 00:00:00 2001 From: Peter Eastman Date: Wed, 15 Apr 2015 12:35:11 -0700 Subject: [PATCH 335/338] OpenCL FFT stores only non-redundant elements --- platforms/opencl/include/OpenCLFFT3D.h | 3 ++ platforms/opencl/include/OpenCLKernels.h | 1 + platforms/opencl/src/OpenCLFFT3D.cpp | 8 ++- platforms/opencl/src/OpenCLKernels.cpp | 40 +++++++++------ platforms/opencl/src/kernels/fft.cl | 21 ++++++++ platforms/opencl/src/kernels/fftR2C.cl | 43 +++++++++++----- platforms/opencl/src/kernels/pme.cl | 65 +++++++++++++++++++----- platforms/opencl/tests/TestOpenCLFFT.cpp | 13 +++-- 8 files changed, 149 insertions(+), 45 deletions(-) diff --git a/platforms/opencl/include/OpenCLFFT3D.h b/platforms/opencl/include/OpenCLFFT3D.h index 88c91e00c..37420c25a 100644 --- a/platforms/opencl/include/OpenCLFFT3D.h +++ b/platforms/opencl/include/OpenCLFFT3D.h @@ -69,6 +69,9 @@ public: * arrays must be different. Also, the input array is used as workspace, so its contents * are destroyed. This also means that both arrays must be large enough to hold complex values, * even when performing a real-to-complex transform. + *

+ * When performing a real-to-complex transform, the output data is of size xsize*ysize*(zsize/2+1) + * and contains only the non-redundant elements. * * @param in the data to transform, ordered such that in[x*ysize*zsize + y*zsize + z] contains element (x, y, z) * @param out on exit, this contains the transformed data diff --git a/platforms/opencl/include/OpenCLKernels.h b/platforms/opencl/include/OpenCLKernels.h index 72f4f0072..9b13e8b48 100644 --- a/platforms/opencl/include/OpenCLKernels.h +++ b/platforms/opencl/include/OpenCLKernels.h @@ -639,6 +639,7 @@ private: cl::Kernel pmeSpreadChargeKernel; cl::Kernel pmeFinishSpreadChargeKernel; cl::Kernel pmeConvolutionKernel; + cl::Kernel pmeEvalEnergyKernel; cl::Kernel pmeInterpolateForceKernel; std::map pmeDefines; std::vector > exceptionAtoms; diff --git a/platforms/opencl/src/OpenCLFFT3D.cpp b/platforms/opencl/src/OpenCLFFT3D.cpp index c01f300fb..2ca5077cf 100644 --- a/platforms/opencl/src/OpenCLFFT3D.cpp +++ b/platforms/opencl/src/OpenCLFFT3D.cpp @@ -310,6 +310,7 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa // Create the kernel. bool outputIsReal = (inputIsReal && axis == 2 && !forward); + bool outputIsPacked = (inputIsReal && axis == 2 && forward); string outputSuffix = (outputIsReal ? ".x" : ""); if (loopRequired) { source<<"for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0))\n"; @@ -317,7 +318,10 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa } else { source<<"if (index < XSIZE*YSIZE)\n"; - source<<"out[y*(ZSIZE*XSIZE)+(get_local_id(0)%ZSIZE)*XSIZE+x] = data"<<(stage%2)<<"[get_local_id(0)]"< replacements; replacements["XSIZE"] = context.intToString(xsize); @@ -331,6 +335,8 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa replacements["INPUT_TYPE"] = (inputIsReal && axis == 0 && forward ? "real" : "real2"); replacements["OUTPUT_TYPE"] = (outputIsReal ? "real" : "real2"); replacements["INPUT_IS_REAL"] = (inputIsReal && axis == 0 && forward ? "1" : "0"); + replacements["INPUT_IS_PACKED"] = (inputIsReal && axis == 0 && !forward ? "1" : "0"); + replacements["OUTPUT_IS_PACKED"] = (outputIsPacked ? "1" : "0"); cl::Program program = context.createProgram(context.replaceStrings(OpenCLKernelSources::fft, replacements)); cl::Kernel kernel(program, "execFFT"); threads = (isCPU ? 1 : blocksPerGroup*zsize); diff --git a/platforms/opencl/src/OpenCLKernels.cpp b/platforms/opencl/src/OpenCLKernels.cpp index 357b5a93b..da3460d2b 100644 --- a/platforms/opencl/src/OpenCLKernels.cpp +++ b/platforms/opencl/src/OpenCLKernels.cpp @@ -1806,6 +1806,7 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ pmeZIndexKernel = cl::Kernel(program, "recordZIndex"); pmeSpreadChargeKernel = cl::Kernel(program, "gridSpreadCharge"); pmeConvolutionKernel = cl::Kernel(program, "reciprocalConvolution"); + pmeEvalEnergyKernel = cl::Kernel(program, "gridEvaluateEnergy"); pmeInterpolateForceKernel = cl::Kernel(program, "gridInterpolateForce"); int elementSize = (cl.getUseDoublePrecision() ? sizeof(mm_double4) : sizeof(mm_float4)); pmeUpdateBsplinesKernel.setArg(0, cl.getPosq().getDeviceBuffer()); @@ -1826,10 +1827,14 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ pmeSpreadChargeKernel.setArg(3, pmeGrid->getDeviceBuffer()); pmeSpreadChargeKernel.setArg(4, pmeBsplineTheta->getDeviceBuffer()); pmeConvolutionKernel.setArg(0, pmeGrid2->getDeviceBuffer()); - pmeConvolutionKernel.setArg(1, cl.getEnergyBuffer().getDeviceBuffer()); - pmeConvolutionKernel.setArg(2, pmeBsplineModuliX->getDeviceBuffer()); - pmeConvolutionKernel.setArg(3, pmeBsplineModuliY->getDeviceBuffer()); - pmeConvolutionKernel.setArg(4, pmeBsplineModuliZ->getDeviceBuffer()); + pmeConvolutionKernel.setArg(1, pmeBsplineModuliX->getDeviceBuffer()); + pmeConvolutionKernel.setArg(2, pmeBsplineModuliY->getDeviceBuffer()); + pmeConvolutionKernel.setArg(3, pmeBsplineModuliZ->getDeviceBuffer()); + pmeEvalEnergyKernel.setArg(0, pmeGrid2->getDeviceBuffer()); + pmeEvalEnergyKernel.setArg(1, cl.getEnergyBuffer().getDeviceBuffer()); + pmeEvalEnergyKernel.setArg(2, pmeBsplineModuliX->getDeviceBuffer()); + pmeEvalEnergyKernel.setArg(3, pmeBsplineModuliY->getDeviceBuffer()); + pmeEvalEnergyKernel.setArg(4, pmeBsplineModuliZ->getDeviceBuffer()); pmeInterpolateForceKernel.setArg(0, cl.getPosq().getDeviceBuffer()); pmeInterpolateForceKernel.setArg(1, cl.getForceBuffers().getDeviceBuffer()); pmeInterpolateForceKernel.setArg(2, pmeGrid->getDeviceBuffer()); @@ -1861,7 +1866,7 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ cl.executeKernel(ewaldForcesKernel, cl.getNumAtoms()); } if (pmeGrid != NULL && includeReciprocal) { - if (usePmeQueue) + if (usePmeQueue && !includeEnergy) cl.setQueue(pmeQueue); // Invert the periodic box vectors. @@ -1936,19 +1941,24 @@ double OpenCLCalcNonbondedForceKernel::execute(ContextImpl& context, bool includ } fft->execFFT(*pmeGrid, *pmeGrid2, true); mm_double4 boxSize = cl.getPeriodicBoxSizeDouble(); - double scaleFactor = 1.0/(M_PI*boxSize.x*boxSize.y*boxSize.z); if (cl.getUseDoublePrecision()) { - pmeConvolutionKernel.setArg(5, recipBoxVectors[0]); - pmeConvolutionKernel.setArg(6, recipBoxVectors[1]); - pmeConvolutionKernel.setArg(7, recipBoxVectors[2]); - pmeConvolutionKernel.setArg(8, scaleFactor); + pmeConvolutionKernel.setArg(4, recipBoxVectors[0]); + pmeConvolutionKernel.setArg(5, recipBoxVectors[1]); + pmeConvolutionKernel.setArg(6, recipBoxVectors[2]); + pmeEvalEnergyKernel.setArg(5, recipBoxVectors[0]); + pmeEvalEnergyKernel.setArg(6, recipBoxVectors[1]); + pmeEvalEnergyKernel.setArg(7, recipBoxVectors[2]); } else { - pmeConvolutionKernel.setArg(5, recipBoxVectorsFloat[0]); - pmeConvolutionKernel.setArg(6, recipBoxVectorsFloat[1]); - pmeConvolutionKernel.setArg(7, recipBoxVectorsFloat[2]); - pmeConvolutionKernel.setArg(8, (float) scaleFactor); - } + pmeConvolutionKernel.setArg(4, recipBoxVectorsFloat[0]); + pmeConvolutionKernel.setArg(5, recipBoxVectorsFloat[1]); + pmeConvolutionKernel.setArg(6, recipBoxVectorsFloat[2]); + pmeEvalEnergyKernel.setArg(5, recipBoxVectorsFloat[0]); + pmeEvalEnergyKernel.setArg(6, recipBoxVectorsFloat[1]); + pmeEvalEnergyKernel.setArg(7, recipBoxVectorsFloat[2]); + } + if (includeEnergy) + cl.executeKernel(pmeEvalEnergyKernel, cl.getNumAtoms()); cl.executeKernel(pmeConvolutionKernel, cl.getNumAtoms()); fft->execFFT(*pmeGrid2, *pmeGrid, false); setPeriodicBoxSizeArg(cl, pmeInterpolateForceKernel, 3); diff --git a/platforms/opencl/src/kernels/fft.cl b/platforms/opencl/src/kernels/fft.cl index 71ebd7c88..a454805f4 100644 --- a/platforms/opencl/src/kernels/fft.cl +++ b/platforms/opencl/src/kernels/fft.cl @@ -2,6 +2,19 @@ real2 multiplyComplex(real2 c1, real2 c2) { return (real2) (c1.x*c2.x-c1.y*c2.y, c1.x*c2.y+c1.y*c2.x); } +/** + * Load a value from the half-complex grid produces by a real-to-complex transform. + */ +real2 loadComplexValue(__global const real2* restrict in, int x, int y, int z) { + const int inputZSize = ZSIZE/2+1; + if (z < inputZSize) + return in[x*YSIZE*inputZSize+y*inputZSize+z]; + int xp = (x == 0 ? 0 : XSIZE-x); + int yp = (y == 0 ? 0 : YSIZE-y); + real2 value = in[xp*YSIZE*inputZSize+yp*inputZSize+(ZSIZE-z)]; + return (real2) (value.x, -value.y); +} + /** * Perform a 1D FFT on each row along one axis. */ @@ -16,10 +29,16 @@ __kernel void execFFT(__global const INPUT_TYPE* restrict in, __global OUTPUT_TY int index = baseIndex+get_local_id(0)/ZSIZE; int x = index/YSIZE; int y = index-x*YSIZE; +#if OUTPUT_IS_PACKED + if (x >= XSIZE/2+1) + continue; +#endif #if LOOP_REQUIRED for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0)) #if INPUT_IS_REAL data0[z] = (real2) (in[x*(YSIZE*ZSIZE)+y*ZSIZE+z], 0); + #elif INPUT_IS_PACKED + data0[z] = loadComplexValue(in, x, y, z); #else data0[z] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+z]; #endif @@ -27,6 +46,8 @@ __kernel void execFFT(__global const INPUT_TYPE* restrict in, __global OUTPUT_TY if (index < XSIZE*YSIZE) #if INPUT_IS_REAL data0[get_local_id(0)] = (real2) (in[x*(YSIZE*ZSIZE)+y*ZSIZE+get_local_id(0)%ZSIZE], 0); + #elif INPUT_IS_PACKED + data0[get_local_id(0)] = loadComplexValue(in, x, y, get_local_id(0)%ZSIZE); #else data0[get_local_id(0)] = in[x*(YSIZE*ZSIZE)+y*ZSIZE+get_local_id(0)%ZSIZE]; #endif diff --git a/platforms/opencl/src/kernels/fftR2C.cl b/platforms/opencl/src/kernels/fftR2C.cl index c887f5714..9a0c814d3 100644 --- a/platforms/opencl/src/kernels/fftR2C.cl +++ b/platforms/opencl/src/kernels/fftR2C.cl @@ -40,6 +40,7 @@ __kernel void unpackForwardData(__global const real2* restrict in, __global real // Transform the data. const int gridSize = PACKED_XSIZE*PACKED_YSIZE*PACKED_ZSIZE; + const int outputZSize = ZSIZE/2+1; for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { int x = index/(PACKED_YSIZE*PACKED_ZSIZE); int remainder = index-x*(PACKED_YSIZE*PACKED_ZSIZE); @@ -58,25 +59,41 @@ __kernel void unpackForwardData(__global const real2* restrict in, __global real real2 wfac = w[z]; #endif real2 output = (real2) ((z1.x+z2.x - wfac.x*(z1.x-z2.x) + wfac.y*(z1.y+z2.y))/2, (z1.y-z2.y - wfac.y*(z1.x-z2.x) - wfac.x*(z1.y+z2.y))/2); - out[x*YSIZE*ZSIZE+y*ZSIZE+z] = output; + if (z < outputZSize) + out[x*YSIZE*outputZSize+y*outputZSize+z] = output; xp = (x == 0 ? 0 : XSIZE-x); yp = (y == 0 ? 0 : YSIZE-y); zp = (z == 0 ? 0 : ZSIZE-z); + if (zp < outputZSize) { #if PACKED_AXIS == 0 - if (x == 0) - out[PACKED_XSIZE*YSIZE*ZSIZE+yp*ZSIZE+zp] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); + if (x == 0) + out[PACKED_XSIZE*YSIZE*outputZSize+yp*outputZSize+zp] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); #elif PACKED_AXIS == 1 - if (y == 0) - out[xp*YSIZE*ZSIZE+PACKED_YSIZE*ZSIZE+zp] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); + if (y == 0) + out[xp*YSIZE*outputZSize+PACKED_YSIZE*outputZSize+zp] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); #else - if (z == 0) - out[xp*YSIZE*ZSIZE+yp*ZSIZE+PACKED_ZSIZE] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); + if (z == 0) + out[xp*YSIZE*outputZSize+yp*outputZSize+PACKED_ZSIZE] = (real2) ((z1.x-z1.y+z2.x-z2.y)/2, (-z1.x-z1.y+z2.x+z2.y)/2); #endif - else - out[xp*YSIZE*ZSIZE+yp*ZSIZE+zp] = (real2) (output.x, -output.y); + else + out[xp*YSIZE*outputZSize+yp*outputZSize+zp] = (real2) (output.x, -output.y); + } } } +/** + * Load a value from the half-complex grid produced by a real-to-complex transform. + */ +real2 loadComplexValue(__global const real2* restrict in, int x, int y, int z) { + const int inputZSize = ZSIZE/2+1; + if (z < inputZSize) + return in[x*YSIZE*inputZSize+y*inputZSize+z]; + int xp = (x == 0 ? 0 : XSIZE-x); + int yp = (y == 0 ? 0 : YSIZE-y); + real2 value = in[xp*YSIZE*inputZSize+yp*inputZSize+(ZSIZE-z)]; + return (real2) (value.x, -value.y); +} + /** * Repack the symmetric complex grid into one half as large in preparation for doing an inverse complex-to-real transform. */ @@ -106,16 +123,16 @@ __kernel void packBackwardData(__global const real2* restrict in, __global real2 int xp = (x == 0 ? 0 : PACKED_XSIZE-x); int yp = (y == 0 ? 0 : PACKED_YSIZE-y); int zp = (z == 0 ? 0 : PACKED_ZSIZE-z); - real2 z1 = in[x*YSIZE*ZSIZE+y*ZSIZE+z]; + real2 z1 = loadComplexValue(in, x, y, z); #if PACKED_AXIS == 0 real2 wfac = w[x]; - real2 z2 = in[(PACKED_XSIZE-x)*YSIZE*ZSIZE+yp*ZSIZE+zp]; + real2 z2 = loadComplexValue(in, PACKED_XSIZE-x, yp, zp); #elif PACKED_AXIS == 1 real2 wfac = w[y]; - real2 z2 = in[xp*YSIZE*ZSIZE+(PACKED_YSIZE-y)*ZSIZE+zp]; + real2 z2 = loadComplexValue(in, xp, PACKED_YSIZE-y, zp); #else real2 wfac = w[z]; - real2 z2 = in[xp*YSIZE*ZSIZE+yp*ZSIZE+(PACKED_ZSIZE-z)]; + real2 z2 = loadComplexValue(in, xp, yp, PACKED_ZSIZE-z); #endif real2 even = (real2) ((z1.x+z2.x)/2, (z1.y-z2.y)/2); real2 odd = (real2) ((z1.x-z2.x)/2, (z1.y+z2.y)/2); diff --git a/platforms/opencl/src/kernels/pme.cl b/platforms/opencl/src/kernels/pme.cl index 44650ba47..1dc407932 100644 --- a/platforms/opencl/src/kernels/pme.cl +++ b/platforms/opencl/src/kernels/pme.cl @@ -294,17 +294,18 @@ __kernel void gridSpreadCharge(__global const real4* restrict posq, __global con } #endif -__kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global real* restrict energyBuffer, __global const real* restrict pmeBsplineModuliX, - __global const real* restrict pmeBsplineModuliY, __global const real* restrict pmeBsplineModuliZ, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ, real recipScaleFactor) { - const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; - real energy = 0.0f; +__kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global const real* restrict pmeBsplineModuliX, + __global const real* restrict pmeBsplineModuliY, __global const real* restrict pmeBsplineModuliZ, real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) { + // R2C stores into a half complex matrix where the last dimension is cut by half + const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*(GRID_SIZE_Z/2+1); + const real recipScaleFactor = (1.0f/M_PI)*recipBoxVecX.x*recipBoxVecY.y*recipBoxVecZ.z; + for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { - int kx = index/(GRID_SIZE_Y*GRID_SIZE_Z); - int remainder = index-kx*GRID_SIZE_Y*GRID_SIZE_Z; - int ky = remainder/GRID_SIZE_Z; - int kz = remainder-ky*GRID_SIZE_Z; - if (kx == 0 && ky == 0 && kz == 0) - continue; + // real indices + int kx = index/(GRID_SIZE_Y*(GRID_SIZE_Z/2+1)); + int remainder = index-kx*GRID_SIZE_Y*(GRID_SIZE_Z/2+1); + int ky = remainder/(GRID_SIZE_Z/2+1); + int kz = remainder-ky*(GRID_SIZE_Z/2+1); int mx = (kx < (GRID_SIZE_X+1)/2) ? kx : (kx-GRID_SIZE_X); int my = (ky < (GRID_SIZE_Y+1)/2) ? ky : (ky-GRID_SIZE_Y); int mz = (kz < (GRID_SIZE_Z+1)/2) ? kz : (kz-GRID_SIZE_Z); @@ -318,8 +319,48 @@ __kernel void reciprocalConvolution(__global real2* restrict pmeGrid, __global r real m2 = mhx*mhx+mhy*mhy+mhz*mhz; real denom = m2*bx*by*bz; real eterm = recipScaleFactor*EXP(-RECIP_EXP_FACTOR*m2)/denom; - pmeGrid[index] = (real2) (grid.x*eterm, grid.y*eterm); - energy += eterm*(grid.x*grid.x + grid.y*grid.y); + if (kx != 0 || ky != 0 || kz != 0) { + pmeGrid[index] = (real2) (grid.x*eterm, grid.y*eterm); + } + } +} + +__kernel void gridEvaluateEnergy(__global real2* restrict pmeGrid, __global real* restrict energyBuffer, + __global const real* restrict pmeBsplineModuliX, __global const real* restrict pmeBsplineModuliY, __global const real* restrict pmeBsplineModuliZ, + real4 recipBoxVecX, real4 recipBoxVecY, real4 recipBoxVecZ) { + // R2C stores into a half complex matrix where the last dimension is cut by half + const unsigned int gridSize = GRID_SIZE_X*GRID_SIZE_Y*GRID_SIZE_Z; + const real recipScaleFactor = (1.0f/M_PI)*recipBoxVecX.x*recipBoxVecY.y*recipBoxVecZ.z; + + real energy = 0; + for (int index = get_global_id(0); index < gridSize; index += get_global_size(0)) { + // real indices + int kx = index/(GRID_SIZE_Y*(GRID_SIZE_Z)); + int remainder = index-kx*GRID_SIZE_Y*(GRID_SIZE_Z); + int ky = remainder/(GRID_SIZE_Z); + int kz = remainder-ky*(GRID_SIZE_Z); + int mx = (kx < (GRID_SIZE_X+1)/2) ? kx : (kx-GRID_SIZE_X); + int my = (ky < (GRID_SIZE_Y+1)/2) ? ky : (ky-GRID_SIZE_Y); + int mz = (kz < (GRID_SIZE_Z+1)/2) ? kz : (kz-GRID_SIZE_Z); + real mhx = mx*recipBoxVecX.x; + real mhy = mx*recipBoxVecY.x+my*recipBoxVecY.y; + real mhz = mx*recipBoxVecZ.x+my*recipBoxVecZ.y+mz*recipBoxVecZ.z; + real m2 = mhx*mhx+mhy*mhy+mhz*mhz; + real bx = pmeBsplineModuliX[kx]; + real by = pmeBsplineModuliY[ky]; + real bz = pmeBsplineModuliZ[kz]; + real denom = m2*bx*by*bz; + real eterm = recipScaleFactor*EXP(-RECIP_EXP_FACTOR*m2)/denom; + if (kz >= (GRID_SIZE_Z/2+1)) { + kx = ((kx == 0) ? kx : GRID_SIZE_X-kx); + ky = ((ky == 0) ? ky : GRID_SIZE_Y-ky); + kz = GRID_SIZE_Z-kz; + } + int indexInHalfComplexGrid = kz + ky*(GRID_SIZE_Z/2+1)+kx*(GRID_SIZE_Y*(GRID_SIZE_Z/2+1)); + real2 grid = pmeGrid[indexInHalfComplexGrid]; + if (kx != 0 || ky != 0 || kz != 0) { + energy += eterm*(grid.x*grid.x + grid.y*grid.y); + } } energyBuffer[get_global_id(0)] += 0.5f*energy; } diff --git a/platforms/opencl/tests/TestOpenCLFFT.cpp b/platforms/opencl/tests/TestOpenCLFFT.cpp index aa6884d5f..0d953a6cd 100644 --- a/platforms/opencl/tests/TestOpenCLFFT.cpp +++ b/platforms/opencl/tests/TestOpenCLFFT.cpp @@ -85,10 +85,15 @@ void testTransform(bool realToComplex, int xsize, int ysize, int zsize) { fftpack_t plan; fftpack_init_3d(&plan, xsize, ysize, zsize); fftpack_exec_3d(plan, FFTPACK_FORWARD, &reference[0], &reference[0]); - for (int i = 0; i < (int) result.size(); ++i) { - ASSERT_EQUAL_TOL(reference[i].re, result[i].x, 1e-3); - ASSERT_EQUAL_TOL(reference[i].im, result[i].y, 1e-3); - } + int outputZSize = (realToComplex ? zsize/2+1 : zsize); + for (int x = 0; x < xsize; x++) + for (int y = 0; y < ysize; y++) + for (int z = 0; z < outputZSize; z++) { + int index1 = x*ysize*zsize + y*zsize + z; + int index2 = x*ysize*outputZSize + y*outputZSize + z; + ASSERT_EQUAL_TOL(reference[index1].re, result[index2].x, 1e-3); + ASSERT_EQUAL_TOL(reference[index1].im, result[index2].y, 1e-3); + } fftpack_destroy(plan); // Perform a backward transform and see if we get the original values. -- GitLab From 63722d0ae0af674fe9857fd75a458f0689272ff8 Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 15 Apr 2015 14:03:29 -0700 Subject: [PATCH 336/338] Bug fixes to real-to-complex FFT --- platforms/opencl/src/OpenCLFFT3D.cpp | 16 ++++++++++++---- platforms/opencl/src/kernels/fft.cl | 6 ++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/platforms/opencl/src/OpenCLFFT3D.cpp b/platforms/opencl/src/OpenCLFFT3D.cpp index 2ca5077cf..48946323e 100644 --- a/platforms/opencl/src/OpenCLFFT3D.cpp +++ b/platforms/opencl/src/OpenCLFFT3D.cpp @@ -313,15 +313,23 @@ cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threa bool outputIsPacked = (inputIsReal && axis == 2 && forward); string outputSuffix = (outputIsReal ? ".x" : ""); if (loopRequired) { + if (outputIsPacked) + source<<"if (x < XSIZE/2+1)\n"; source<<"for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0))\n"; - source<<"out[y*(ZSIZE*XSIZE)+z*XSIZE+x] = data"<<(stage%2)<<"[z]"< replacements; replacements["XSIZE"] = context.intToString(xsize); diff --git a/platforms/opencl/src/kernels/fft.cl b/platforms/opencl/src/kernels/fft.cl index a454805f4..cbbe7b40f 100644 --- a/platforms/opencl/src/kernels/fft.cl +++ b/platforms/opencl/src/kernels/fft.cl @@ -30,8 +30,7 @@ __kernel void execFFT(__global const INPUT_TYPE* restrict in, __global OUTPUT_TY int x = index/YSIZE; int y = index-x*YSIZE; #if OUTPUT_IS_PACKED - if (x >= XSIZE/2+1) - continue; + if (x < XSIZE/2+1) { #endif #if LOOP_REQUIRED for (int z = get_local_id(0); z < ZSIZE; z += get_local_size(0)) @@ -53,6 +52,9 @@ __kernel void execFFT(__global const INPUT_TYPE* restrict in, __global OUTPUT_TY #endif #endif barrier(CLK_LOCAL_MEM_FENCE); +#if OUTPUT_IS_PACKED + } +#endif COMPUTE_FFT } } -- GitLab From 783cb61a55833b1a6ab8c1c1b97cc86f370ef98b Mon Sep 17 00:00:00 2001 From: peastman Date: Wed, 15 Apr 2015 14:37:10 -0700 Subject: [PATCH 337/338] Fixed compilation error with latest version of SWIG --- wrappers/python/src/swig_doxygen/swig_lib/python/extend.i | 1 - 1 file changed, 1 deletion(-) diff --git a/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i b/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i index 21615bcac..2aa11fb31 100644 --- a/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i +++ b/wrappers/python/src/swig_doxygen/swig_lib/python/extend.i @@ -417,7 +417,6 @@ Parameters: @staticmethod def deserialize(inputString): """Reconstruct an object that has been serialized as XML.""" - # Look for the first tag to figure out what type of object it is. import re match = re.search("<([^?]\S*)", inputString) if match is None: -- GitLab From 42089cac7b7a04dbb6cfe0bb8372d4a3f5000751 Mon Sep 17 00:00:00 2001 From: peastman Date: Thu, 16 Apr 2015 10:53:05 -0700 Subject: [PATCH 338/338] Optimization to OpenCL FFT --- platforms/opencl/src/OpenCLFFT3D.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platforms/opencl/src/OpenCLFFT3D.cpp b/platforms/opencl/src/OpenCLFFT3D.cpp index 48946323e..49f3ca473 100644 --- a/platforms/opencl/src/OpenCLFFT3D.cpp +++ b/platforms/opencl/src/OpenCLFFT3D.cpp @@ -158,6 +158,8 @@ int OpenCLFFT3D::findLegalDimension(int minimum) { cl::Kernel OpenCLFFT3D::createKernel(int xsize, int ysize, int zsize, int& threads, int axis, bool forward, bool inputIsReal) { int maxThreads = std::min(256, (int) context.getDevice().getInfo()); + while (maxThreads > 128 && maxThreads-64 >= zsize) + maxThreads -= 64; bool isCPU = context.getDevice().getInfo() == CL_DEVICE_TYPE_CPU; while (true) { bool loopRequired = (zsize > maxThreads || isCPU); -- GitLab